Commit | Line | Data |
---|---|---|
805e021f CE |
1 | /* |
2 | * Copyright 2010, Sine Nomine Associates. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * This software has been released under the terms of the IBM Public | |
6 | * License. For details, see the LICENSE file in the top-level source | |
7 | * directory or online at http://www.openafs.org/dl/license10.html | |
8 | */ | |
9 | ||
10 | /* | |
11 | * libuafs SWIG interface file | |
12 | * | |
13 | * This file specifies the libuafs interfaces for SWIG, which can then be | |
14 | * used to easily create libuafs bindings to other languages such as Perl. | |
15 | * | |
16 | * For each language you want a binding for, there are two typemaps you | |
17 | * must define for that language, since SWIG does not handle them natively. | |
18 | * These are the 'in' typemap for READBUF and LENGTH, and the 'argout' | |
19 | * typemap for READBUF. Search this file for 'SWIGPERL' to see existing ones | |
20 | * for the Perl bindings. | |
21 | */ | |
22 | ||
23 | %module "AFS::ukernel" | |
24 | ||
25 | %{ | |
26 | #include <afsconfig.h> | |
27 | #include <afs/param.h> | |
28 | ||
29 | #include <afs/afsutil.h> | |
30 | #include <afs/sysincludes.h> | |
31 | #include <afs_usrops.h> | |
32 | #include <afs/cmd.h> | |
33 | #include <afs/afs_args.h> | |
34 | %} | |
35 | ||
36 | %include "typemaps.i"; | |
37 | ||
38 | %apply long { off_t }; | |
39 | ||
40 | %rename (uafs_ParseArgs) swig_uafs_ParseArgs; | |
41 | %inline %{ | |
42 | /* SWIG doesn't handle argv-like string arrays too well, so instead have | |
43 | * a wrapper to convert a single string of all arguments into an argv-like | |
44 | * array. Conveniently, libcmd can do this. | |
45 | * | |
46 | * We could instead do this with SWIG typemaps, but writing this little | |
47 | * function instead is much more language-neutral. With typemaps, we'd have | |
48 | * to write the converting code for each target language. | |
49 | */ | |
50 | extern int | |
51 | swig_uafs_ParseArgs(char *line) | |
52 | { | |
53 | char *argv[1024]; | |
54 | int argc; | |
55 | int code; | |
56 | ||
57 | code = cmd_ParseLine(line, argv, &argc, sizeof(argv)/sizeof(argv[0])); | |
58 | if (code) { | |
59 | afs_com_err("AFS::ukernel", code, "parsing line: '%s'", line); | |
60 | return code; | |
61 | } | |
62 | ||
63 | code = uafs_ParseArgs(argc, argv); | |
64 | ||
65 | cmd_FreeArgv(argv); | |
66 | ||
67 | return code; | |
68 | } | |
69 | %} | |
70 | extern int uafs_Setup(const char *mount); | |
71 | extern int uafs_Run(void); | |
72 | ||
73 | /* | |
74 | * Define typemaps for binary read buffers. SWIG natively handles | |
75 | * NUL-terminated strings, but uafs_read could have NULs in the middle of the | |
76 | * string, so we need these typemaps to pay attention to the string length. | |
77 | * | |
78 | * (Reading in a binary buffer from e.g. uafs_write is already handled natively | |
79 | * by SWIG. Fancy that.) | |
80 | */ | |
81 | #if defined(SWIGPERL) | |
82 | %typemap(in, numinputs=1) (char *READBUF, int LENGTH) { | |
83 | if (!SvIOK($input)) { | |
84 | SWIG_croak("expected an integer"); | |
85 | } | |
86 | $2 = SvIV($input); | |
87 | Newx($1, $2, char); | |
88 | } | |
89 | %typemap(argout, numinputs=1) char *READBUF { | |
90 | /* some logic here copied from typemaps.i and/or SWIG itself, since I'm not | |
91 | * a perl dev */ | |
92 | ||
93 | if (argvi >= items) { | |
94 | EXTEND(sp, 1); | |
95 | } | |
96 | ||
97 | /* 'result' is the return value from the actual C function call; we assume | |
98 | * it is an int that represents how many bytes of data were actually read into | |
99 | * the buffer if nonnegative */ | |
100 | if (result < 0) { | |
101 | $result = &PL_sv_undef; | |
102 | } else { | |
103 | $result = sv_2mortal(newSVpvn($1, result)); | |
104 | } | |
105 | ||
106 | Safefree($1); | |
107 | argvi++; | |
108 | } | |
109 | #else | |
110 | # error No READBUF typemap defined for the given language | |
111 | #endif | |
112 | ||
113 | extern int uafs_mkdir(char *path, int mode); | |
114 | extern int uafs_chdir(char *path); | |
115 | extern int uafs_open(char *path, int flags, int mode=0); | |
116 | extern int uafs_creat(char *path, int mode); | |
117 | extern int uafs_write(int fd, char *STRING, int LENGTH); | |
118 | extern int uafs_pwrite(int fd, char *STRING, int LENGTH, off_t offset); | |
119 | extern int uafs_read(int fd, char *READBUF, int LENGTH); | |
120 | extern int uafs_pread(int fd, char *READBUF, int LENGTH, off_t offset); | |
121 | extern int uafs_fsync(int fd); | |
122 | extern int uafs_close(int fd); | |
123 | ||
124 | %{ | |
125 | #define STAT_TYPE long | |
126 | #define STAT_ARGS \ | |
127 | STAT_TYPE *adev, \ | |
128 | STAT_TYPE *aino, \ | |
129 | STAT_TYPE *amode, \ | |
130 | STAT_TYPE *anlink, \ | |
131 | STAT_TYPE *auid, \ | |
132 | STAT_TYPE *agid, \ | |
133 | STAT_TYPE *ardev, \ | |
134 | STAT_TYPE *asize, \ | |
135 | STAT_TYPE *aatime, \ | |
136 | STAT_TYPE *amtime, \ | |
137 | STAT_TYPE *actime, \ | |
138 | STAT_TYPE *ablksize, \ | |
139 | STAT_TYPE *ablocks | |
140 | ||
141 | #define STAT_COPYFROM(st) do { \ | |
142 | *adev = (st).st_dev; \ | |
143 | *aino = (st).st_ino; \ | |
144 | *amode = (st).st_mode; \ | |
145 | *anlink = (st).st_nlink; \ | |
146 | *auid = (st).st_uid; \ | |
147 | *agid = (st).st_gid; \ | |
148 | *ardev = (st).st_rdev; \ | |
149 | *asize = (st).st_size; \ | |
150 | *aatime = (st).st_atime; \ | |
151 | *amtime = (st).st_mtime; \ | |
152 | *actime = (st).st_ctime; \ | |
153 | *ablksize = (st).st_blksize; \ | |
154 | *ablocks = (st).st_blocks; \ | |
155 | } while (0) | |
156 | ||
157 | int | |
158 | swig_uafs_stat(char *path, STAT_ARGS) | |
159 | { | |
160 | int code; | |
161 | struct stat st; | |
162 | code = uafs_stat(path, &st); | |
163 | if (code == 0) { | |
164 | STAT_COPYFROM(st); | |
165 | } | |
166 | return code; | |
167 | } | |
168 | int | |
169 | swig_uafs_lstat(char *path, STAT_ARGS) | |
170 | { | |
171 | int code; | |
172 | struct stat st; | |
173 | code = uafs_lstat(path, &st); | |
174 | if (code == 0) { | |
175 | STAT_COPYFROM(st); | |
176 | } | |
177 | return code; | |
178 | } | |
179 | int | |
180 | swig_uafs_fstat(int fd, STAT_ARGS) | |
181 | { | |
182 | int code; | |
183 | struct stat st; | |
184 | code = uafs_fstat(fd, &st); | |
185 | if (code == 0) { | |
186 | STAT_COPYFROM(st); | |
187 | } | |
188 | return code; | |
189 | } | |
190 | ||
191 | #undef STAT_TYPE | |
192 | #undef STAT_ARGS | |
193 | #undef STAT_COPYFROM | |
194 | %} | |
195 | ||
196 | %define STAT_TYPE | |
197 | long | |
198 | %enddef | |
199 | %define STAT_OUT_ARGS | |
200 | STAT_TYPE *OUTPUT, | |
201 | STAT_TYPE *OUTPUT, | |
202 | STAT_TYPE *OUTPUT, | |
203 | STAT_TYPE *OUTPUT, | |
204 | STAT_TYPE *OUTPUT, | |
205 | STAT_TYPE *OUTPUT, | |
206 | STAT_TYPE *OUTPUT, | |
207 | STAT_TYPE *OUTPUT, | |
208 | STAT_TYPE *OUTPUT, | |
209 | STAT_TYPE *OUTPUT, | |
210 | STAT_TYPE *OUTPUT, | |
211 | STAT_TYPE *OUTPUT, | |
212 | STAT_TYPE *OUTPUT | |
213 | %enddef | |
214 | ||
215 | %rename (uafs_stat) swig_uafs_stat; | |
216 | %rename (uafs_lstat) swig_uafs_lstat; | |
217 | %rename (uafs_fstat) swig_uafs_fstat; | |
218 | ||
219 | extern int swig_uafs_stat(char *path, STAT_OUT_ARGS); | |
220 | extern int swig_uafs_lstat(char *path, STAT_OUT_ARGS); | |
221 | extern int swig_uafs_fstat(int fd, STAT_OUT_ARGS); | |
222 | ||
223 | extern int uafs_truncate(char *path, int len); | |
224 | extern int uafs_ftruncate(int fd, int len); | |
225 | extern int uafs_lseek(int fd, int offset, int whence); | |
226 | extern int uafs_chmod(char *path, int mode); | |
227 | extern int uafs_fchmod(int fd, int mode); | |
228 | extern int uafs_symlink(char *target, char *source); | |
229 | extern int uafs_unlink(char *path); | |
230 | extern int uafs_rmdir(char *path); | |
231 | extern int uafs_readlink(char *path, char *READBUF, int LENGTH); | |
232 | extern int uafs_link(char *existing, char *new); | |
233 | extern int uafs_rename(char *old, char *new); | |
234 | ||
235 | extern usr_DIR *uafs_opendir(char *path); | |
236 | ||
237 | %rename (uafs_readdir) swig_uafs_readdir; | |
238 | %{ | |
239 | /* | |
240 | * Language-neutral wrapper for uafs_readdir. Since the language won't know | |
241 | * what to do with a struct usr_dirent, we could either make a SWIG typemap, or | |
242 | * define a wrapper with multiple return arguments. Making a typemap is | |
243 | * language-specific, so we define a wrapper, and let the typemaps.i library | |
244 | * worry about the language-specific parts of getting multiple return values. | |
245 | */ | |
246 | char * | |
247 | swig_uafs_readdir(usr_DIR *dirp, unsigned long *d_ino, unsigned long *d_off, unsigned short *d_reclen) | |
248 | { | |
249 | struct usr_dirent *dentry; | |
250 | ||
251 | dentry = uafs_readdir(dirp); | |
252 | if (!dentry) { | |
253 | *d_ino = *d_off = *d_reclen = 0; | |
254 | return NULL; | |
255 | } | |
256 | ||
257 | *d_ino = dentry->d_ino; | |
258 | *d_off = dentry->d_off; | |
259 | *d_reclen = dentry->d_reclen; | |
260 | ||
261 | return strdup(dentry->d_name); | |
262 | } | |
263 | %} | |
264 | ||
265 | extern char * swig_uafs_readdir(usr_DIR *dirp, unsigned long *OUTPUT, unsigned long *OUTPUT, unsigned short *OUTPUT); | |
266 | extern int uafs_closedir(usr_DIR * dirp); | |
267 | extern void uafs_SetRxPort(int); | |
268 | extern void uafs_Shutdown(void); |