add support for dup() and dup2()
[kai/samba.git] / source / smbwrapper / wrapped.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.0
4    SMB wrapper functions
5    Copyright (C) Andrew Tridgell 1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22
23 #include "wrapper.h"
24
25 #ifdef linux
26 __asm__(".globl __open; __open = open");
27 #endif
28
29  int open(const char *name, int flags, mode_t mode)
30 {
31         if (smbw_path(name)) {
32                 return smbw_open(name, flags, mode);
33         }
34
35         return real_open(name, flags, mode);
36 }
37
38
39 #ifdef linux
40 __asm__(".globl __chdir; __chdir = chdir");
41 #endif
42
43  int chdir(const char *name)
44 {
45         return smbw_chdir(name);
46 }
47
48
49
50 #ifdef linux
51 __asm__(".globl __close; __close = close");
52 #endif
53
54  ssize_t close(int fd)
55 {
56         if (smbw_fd(fd)) {
57                 return smbw_close(fd);
58         }
59
60         return real_close(fd);
61 }
62
63
64 #ifdef linux
65 __asm__(".globl __fchdir; __fchdir = fchdir");
66 #endif
67
68  int fchdir(int fd)
69 {
70         if (smbw_fd(fd)) {
71                 return smbw_fchdir(fd);
72         }
73
74         return real_fchdir(fd);
75 }
76
77
78 #ifdef linux
79 __asm__(".globl __fcntl; __fcntl = fcntl");
80 #endif
81
82  int fcntl(int fd, int cmd, long arg)
83 {
84         if (smbw_fd(fd)) {
85                 return smbw_fcntl(fd, cmd, arg);
86         }
87
88         return real_fcntl(fd, cmd, arg);
89 }
90
91
92
93 #ifdef linux
94 __asm__(".globl __getdents; __getdents = getdents");
95 #endif
96
97  int getdents(unsigned int fd, struct dirent *dirp, unsigned int count)
98 {
99         if (smbw_fd(fd)) {
100                 return smbw_getdents(fd, dirp, count);
101         }
102
103         return real_getdents(fd, dirp, count);
104 }
105
106
107 #ifdef linux
108 __asm__(".globl __lseek; __lseek = lseek");
109 #endif
110
111  ssize_t lseek(int fd, off_t offset, int whence)
112 {
113         if (smbw_fd(fd)) {
114                 return smbw_lseek(fd, offset, whence);
115         }
116
117         return real_lseek(fd, offset, whence);
118 }
119
120
121
122 #ifdef linux
123 __asm__(".globl __read; __read = read");
124 #endif
125
126  ssize_t read(int fd, void *buf, size_t count)
127 {
128         if (smbw_fd(fd)) {
129                 return smbw_read(fd, buf, count);
130         }
131
132         return real_read(fd, buf, count);
133 }
134
135
136 #ifdef linux
137 __asm__(".globl __write; __write = write");
138 #endif
139
140  ssize_t write(int fd, void *buf, size_t count)
141 {
142         if (smbw_fd(fd)) {
143                 return smbw_write(fd, buf, count);
144         }
145
146         return real_write(fd, buf, count);
147 }
148
149
150  int access(const char *name, int mode)
151 {
152         if (smbw_path(name)) {
153                 return smbw_access(name, mode);
154         }
155
156         return real_access(name, mode);
157 }
158
159
160
161  int chmod(const char *name,mode_t mode)
162 {
163         if (smbw_path(name)) {
164                 return smbw_chmod(name, mode);
165         }
166
167         return real_chmod(name, mode);
168 }
169
170
171
172  int chown(const char *name,uid_t owner, gid_t group)
173 {
174         if (smbw_path(name)) {
175                 return smbw_chown(name, owner, group);
176         }
177
178         return real_chown(name, owner, group);
179 }
180
181  int closedir(DIR *dir)
182 {
183         if (smbw_dirp(dir)) {
184                 return smbw_closedir(dir);
185         }
186
187         return real_closedir(dir);
188 }
189
190
191  int __fxstat(int vers, int fd, struct stat *st)
192 {
193         struct kernel_stat kbuf;
194         int ret;
195
196         if (smbw_fd(fd)) {
197                 return smbw_fstat(fd, st);
198         }
199
200         switch (vers) {
201         case _STAT_VER_LINUX_OLD:
202                 /* Nothing to do.  The struct is in the form the kernel expects
203                    it to be.  */
204                 return real_fstat(fd, (struct kernel_stat *)st);
205                 break;
206
207         case _STAT_VER_LINUX:
208                 /* Do the system call.  */
209                 ret = real_fstat(fd, &kbuf);
210
211                 st->st_dev = kbuf.st_dev;
212 #ifdef _HAVE___PAD1
213                 st->__pad1 = 0;
214 #endif
215                 st->st_ino = kbuf.st_ino;
216                 st->st_mode = kbuf.st_mode;
217                 st->st_nlink = kbuf.st_nlink;
218                 st->st_uid = kbuf.st_uid;
219                 st->st_gid = kbuf.st_gid;
220                 st->st_rdev = kbuf.st_rdev;
221 #ifdef _HAVE___PAD2
222                 st->__pad2 = 0;
223 #endif
224                 st->st_size = kbuf.st_size;
225                 st->st_blksize = kbuf.st_blksize;
226                 st->st_blocks = kbuf.st_blocks;
227                 st->st_atime = kbuf.st_atime;
228 #ifdef _HAVE___UNUSED1
229                 st->__unused1 = 0;
230 #endif
231                 st->st_mtime = kbuf.st_mtime;
232 #ifdef _HAVE___UNUSED2
233                 st->__unused2 = 0;
234 #endif
235                 st->st_ctime = kbuf.st_ctime;
236 #ifdef _HAVE___UNUSED3
237                 st->__unused3 = 0;
238 #endif
239 #ifdef _HAVE___UNUSED4
240                 st->__unused4 = 0;
241 #endif
242 #ifdef _HAVE___UNUSED5
243                 st->__unused5 = 0;
244 #endif
245                 return ret;
246
247         default:
248                 errno = EINVAL;
249                 return -1;
250         }
251 }
252
253
254  char *getcwd(char *buf, size_t size)
255 {
256         return smbw_getcwd(buf, size);
257 }
258
259
260
261  int __lxstat(int vers, const char *name, struct stat *st)
262 {
263         struct kernel_stat kbuf;
264         int ret;
265
266         if (smbw_path(name)) {
267                 return smbw_stat(name, st);
268         }
269
270         switch (vers) {
271         case _STAT_VER_LINUX_OLD:
272                 /* Nothing to do.  The struct is in the form the kernel expects
273                    it to be.  */
274                 return real_lstat(name, (struct kernel_stat *)st);
275                 break;
276
277         case _STAT_VER_LINUX:
278                 /* Do the system call.  */
279                 ret = real_lstat(name, &kbuf);
280
281                 st->st_dev = kbuf.st_dev;
282 #ifdef _HAVE___PAD1
283                 st->__pad1 = 0;
284 #endif
285                 st->st_ino = kbuf.st_ino;
286                 st->st_mode = kbuf.st_mode;
287                 st->st_nlink = kbuf.st_nlink;
288                 st->st_uid = kbuf.st_uid;
289                 st->st_gid = kbuf.st_gid;
290                 st->st_rdev = kbuf.st_rdev;
291 #ifdef _HAVE___PAD2
292                 st->__pad2 = 0;
293 #endif
294                 st->st_size = kbuf.st_size;
295                 st->st_blksize = kbuf.st_blksize;
296                 st->st_blocks = kbuf.st_blocks;
297                 st->st_atime = kbuf.st_atime;
298 #ifdef _HAVE___UNUSED1
299                 st->__unused1 = 0;
300 #endif
301                 st->st_mtime = kbuf.st_mtime;
302 #ifdef _HAVE___UNUSED2
303                 st->__unused2 = 0;
304 #endif
305                 st->st_ctime = kbuf.st_ctime;
306 #ifdef _HAVE___UNUSED3
307                 st->__unused3 = 0;
308 #endif
309 #ifdef _HAVE___UNUSED4
310                 st->__unused4 = 0;
311 #endif
312 #ifdef _HAVE___UNUSED5
313                 st->__unused5 = 0;
314 #endif
315                 return ret;
316
317         default:
318                 errno = EINVAL;
319                 return -1;
320         }
321 }
322
323
324
325  int mkdir(const char *name, mode_t mode)
326 {
327         if (smbw_path(name)) {
328                 return smbw_mkdir(name, mode);
329         }
330
331         return real_mkdir(name, mode);
332 }
333
334
335  void seekdir(DIR *dir, off_t offset)
336 {
337         if (smbw_dirp(dir)) {
338                 smbw_seekdir(dir, offset);
339                 return;
340         }
341
342         real_seekdir(dir, offset);
343 }
344
345
346  int __xstat(int vers, const char *name, struct stat *st)
347 {
348         struct kernel_stat kbuf;
349         int ret;
350
351         if (smbw_path(name)) {
352                 return smbw_stat(name, st);
353         }
354
355         switch (vers) {
356         case _STAT_VER_LINUX_OLD:
357                 /* Nothing to do.  The struct is in the form the kernel expects
358                    it to be.  */
359                 return real_stat(name, (struct kernel_stat *)st);
360                 break;
361
362         case _STAT_VER_LINUX:
363                 /* Do the system call.  */
364                 ret = real_stat(name, &kbuf);
365
366                 st->st_dev = kbuf.st_dev;
367 #ifdef _HAVE___PAD1
368                 st->__pad1 = 0;
369 #endif
370                 st->st_ino = kbuf.st_ino;
371                 st->st_mode = kbuf.st_mode;
372                 st->st_nlink = kbuf.st_nlink;
373                 st->st_uid = kbuf.st_uid;
374                 st->st_gid = kbuf.st_gid;
375                 st->st_rdev = kbuf.st_rdev;
376 #ifdef _HAVE___PAD2
377                 st->__pad2 = 0;
378 #endif
379                 st->st_size = kbuf.st_size;
380                 st->st_blksize = kbuf.st_blksize;
381                 st->st_blocks = kbuf.st_blocks;
382                 st->st_atime = kbuf.st_atime;
383 #ifdef _HAVE___UNUSED1
384                 st->__unused1 = 0;
385 #endif
386                 st->st_mtime = kbuf.st_mtime;
387 #ifdef _HAVE___UNUSED2
388                 st->__unused2 = 0;
389 #endif
390                 st->st_ctime = kbuf.st_ctime;
391 #ifdef _HAVE___UNUSED3
392                 st->__unused3 = 0;
393 #endif
394 #ifdef _HAVE___UNUSED4
395                 st->__unused4 = 0;
396 #endif
397 #ifdef _HAVE___UNUSED5
398                 st->__unused5 = 0;
399 #endif
400                 return ret;
401
402         default:
403                 errno = EINVAL;
404                 return -1;
405         }
406 }
407
408  int stat(const char *name, struct stat *st)
409 {
410         return __xstat(_STAT_VER, name, st);
411 }
412
413
414  off_t telldir(DIR *dir)
415 {
416         if (smbw_dirp(dir)) {
417                 return smbw_telldir(dir);
418         }
419
420         return real_telldir(dir);
421 }
422
423
424  int unlink(const char *name)
425 {
426         if (smbw_path(name)) {
427                 return smbw_unlink(name);
428         }
429
430         return real_unlink(name);
431 }
432
433
434  int utime(const char *name,void *tvp)
435 {
436         if (smbw_path(name)) {
437                 return smbw_utime(name, tvp);
438         }
439
440         return real_utime(name, tvp);
441 }
442
443  DIR *opendir(const char *name)
444 {
445         if (smbw_path(name)) {
446                 return smbw_opendir(name);
447         }
448
449         return real_opendir(name);
450 }
451
452
453  struct dirent *readdir(DIR *dir)
454 {
455         if (smbw_dirp(dir)) {
456                 return smbw_readdir(dir);
457         }
458
459         return real_readdir(dir);
460 }
461
462  int readlink(char *path, char *buf, size_t bufsize)
463 {
464         if (smbw_path(path)) {
465                 return smbw_readlink(path, buf, bufsize);
466         }
467
468         return real_readlink(path, buf, bufsize);
469 }
470
471
472  int rename(const char *oldname,const char *newname)
473 {
474         int p1, p2;
475         p1 = smbw_path(oldname); 
476         p2 = smbw_path(newname); 
477         if (p1 ^ p2) {
478                 /* can't cross filesystem boundaries */
479                 errno = EXDEV;
480                 return -1;
481         }
482         if (p1 && p2) {
483                 return smbw_rename(oldname, newname);
484         }
485
486         return real_rename(oldname, newname);
487 }
488
489  int rmdir(const char *name)
490 {
491         if (smbw_path(name)) {
492                 return smbw_rmdir(name);
493         }
494
495         return real_rmdir(name);
496 }
497
498
499  int symlink(const char *topath,const char *frompath)
500 {
501         int p1, p2;
502         p1 = smbw_path(topath); 
503         p2 = smbw_path(frompath); 
504         if (p1 || p2) {
505                 /* can't handle symlinks */
506                 errno = EPERM;
507                 return -1;
508         }
509
510         return real_symlink(topath, frompath);
511 }
512
513  int dup(int fd)
514 {
515         if (smbw_fd(fd)) {
516                 return smbw_dup(fd);
517         }
518
519         return real_dup(fd);
520 }
521
522  int dup2(int oldfd, int newfd)
523 {
524         if (smbw_fd(newfd)) {
525                 close(newfd);
526         }
527
528         if (smbw_fd(oldfd)) {
529                 return smbw_dup2(oldfd, newfd);
530         }
531
532         return real_dup2(oldfd, newfd);
533 }