root/examples/libsmbclient/smbwrapper/wrapper.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smbw_initialize
  2. initialize
  3. stat_convert
  4. stat64_convert
  5. dirent_convert
  6. dirent64_convert
  7. openx
  8. closex
  9. fcntlx
  10. getdentsx
  11. lseekx
  12. lseek64x
  13. readx
  14. writex
  15. open
  16. _open
  17. __open
  18. open64
  19. _open64
  20. __open64
  21. pread
  22. pread64
  23. pwrite
  24. pwrite64
  25. chdir
  26. __chdir
  27. _chdir
  28. close
  29. __close
  30. _close
  31. fchdir
  32. __fchdir
  33. _fchdir
  34. fcntl
  35. __fcntl
  36. _fcntl
  37. getdents
  38. __getdents
  39. _getdents
  40. getdents64
  41. lseek
  42. __lseek
  43. _lseek
  44. lseek64
  45. __lseek64
  46. _lseek64
  47. read
  48. __read
  49. _read
  50. write
  51. __write
  52. _write
  53. access
  54. chmod
  55. fchmod
  56. chown
  57. fchown
  58. getcwd
  59. mkdir
  60. __fxstat
  61. __xstat
  62. __lxstat
  63. stat
  64. lstat
  65. fstat
  66. unlink
  67. utime
  68. utimes
  69. readlink
  70. rename
  71. rmdir
  72. symlink
  73. dup
  74. dup2
  75. opendir
  76. readdir
  77. closedir
  78. telldir
  79. seekdir
  80. creat
  81. creat64
  82. __xstat64
  83. stat64
  84. __fxstat64
  85. fstat64
  86. __lxstat64
  87. lstat64
  88. _llseek
  89. readdir64
  90. readdir_r
  91. readdir64_r
  92. fork
  93. setxattr
  94. lsetxattr
  95. fsetxattr
  96. getxattr
  97. lgetxattr
  98. fgetxattr
  99. removexattr
  100. lremovexattr
  101. fremovexattr
  102. listxattr
  103. llistxattr
  104. flistxattr
  105. malloc
  106. calloc
  107. realloc
  108. free
  109. smbw_sigaction_handler
  110. do_select
  111. select
  112. _select
  113. __select

   1 /* 
   2    Unix SMB/Netbios implementation.
   3    Version 2.0
   4    SMB wrapper functions
   5    Copyright (C) Andrew Tridgell 1998
   6    Copyright (C) Derrell Lipman 2002-2005
   7    
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 /*
  23  * This is a rewrite of the original wrapped.c file, using libdl to obtain
  24  * pointers into the C library rather than attempting to find undocumented
  25  * functions in the C library to call for native file access.  The problem
  26  * with the original implementation's paradigm is that samba manipulates
  27  * defines such that it gets the sizes of structures that it wants
  28  * (e.g. mapping 32-bit functions to 64-bit functions with their associated
  29  * 64-bit structure fields), but programs run under smbsh or using
  30  * smbwrapper.so were not necessarily compiled with the same flags.  As an
  31  * example of the problem, a program calling stat() passes a pointer to a
  32  * "struct stat" but the fields in that structure are different in samba than
  33  * they are in the calling program if the calling program was not compiled to
  34  * force stat() to be mapped to stat64().
  35  *
  36  * In this version, we provide an interface to each of the native functions,
  37  * not just the ones that samba is compiled to map to.  We obtain the function
  38  * pointers from the C library using dlsym(), and for native file operations,
  39  * directly call the same function that the calling application was
  40  * requesting.  Since the size of the calling application's structures vary
  41  * depending on what function was called, we use our own internal structures
  42  * for passing information to/from the SMB equivalent functions, and map them
  43  * back to the native structures before returning the result to the caller.
  44  *
  45  * This implementation was completed 25 December 2002.
  46  * Derrell Lipman
  47  */
  48 
  49 /* We do not want auto munging of 32->64 bit names in this file (only) */
  50 #undef _FILE_OFFSET_BITS
  51 #undef _GNU_SOURCE
  52 
  53 #include <sys/types.h>
  54 #include <sys/stat.h>
  55 #include <sys/time.h>
  56 #include <stdlib.h>
  57 #include <fcntl.h>
  58 #include <unistd.h>
  59 #include <utime.h>
  60 #include <stdio.h>
  61 #include <dirent.h>
  62 #include <signal.h>
  63 #include <stdarg.h>
  64 #include <string.h>
  65 #ifdef __USE_GNU
  66 # define SMBW_USE_GNU
  67 #endif
  68 #define __USE_GNU             /* need this to have RTLD_NEXT defined */
  69 #include <dlfcn.h>
  70 #ifndef SMBW_USE_GNU
  71 # undef __USE_GNU
  72 #endif
  73 #include <errno.h>
  74 #include "libsmbclient.h"
  75 #include "bsd-strlfunc.h"
  76 #include "wrapper.h"
  77 
  78 /*
  79  * Debug bits:
  80  * 0x0 = none
  81  * 0x1 = display symbol definitions not found in C library
  82  * 0x2 = show wrapper functions being called
  83  * 0x4 = log to file SMBW_DEBUG_FILE instead of stderr
  84  */
  85 #define SMBW_DEBUG      0x0
  86 #define SMBW_DEBUG_FILE "/tmp/smbw.log"
  87 
  88 int      smbw_debug = 0;
  89 
  90 #if SMBW_DEBUG & 0x2
  91 static int      debugFd = 2;
  92 #endif
  93 
  94 #ifndef ENOTSUP
  95 #define ENOTSUP EOPNOTSUPP
  96 #endif
  97 
  98 /*
  99  * None of the methods of having the initialization function called
 100  * automatically upon shared library startup are effective in all situations.
 101  * We provide the "-init" parameter to the linker which is effective most of
 102  * the time, but fails for applications that provide their own shared
 103  * libraries with _init() functions (e.g. ps).  We can't use "-z initfirst"
 104  * because the environment isn't yet set up at that point, so we can't find
 105  * our shared memory identifier (see shared.c).  We therefore must resort to
 106  * this tried-and-true method of keeping an "initialized" flag.  We check it
 107  * prior to calling the initialize() function to save a function call (a slow
 108  * operation on x86).
 109  */
 110 #if SMBW_DEBUG & 0x2
 111 #  define check_init(buf)                                               \
 112         do {                                                            \
 113                 int saved_errno = errno;                                \
 114                 if (! initialized) initialize();                        \
 115                 (* smbw_libc.write)(debugFd, "["buf"]", sizeof(buf)+1); \
 116                 errno = saved_errno;                                    \
 117         } while (0)
 118 #else
 119 #  define check_init(buf)                               \
 120         do {                                            \
 121                 if (! initialized) smbw_initialize();   \
 122         } while (0)
 123 #endif
 124 
 125 static void initialize(void);
 126 
 127 static int initialized = 0;
 128 
 129 SMBW_libc_pointers smbw_libc;
 130 
 131 /*
 132  * A public entry point used by the "-init" option to the linker.
 133  */
 134 void smbw_initialize(void)
     /* [<][>][^][v][top][bottom][index][help] */
 135 {
 136         initialize();
 137 }
 138 
 139 static void initialize(void)
     /* [<][>][^][v][top][bottom][index][help] */
 140 {
 141         int saved_errno;
 142 #if SMBW_DEBUG & 0x1
 143         char *error;
 144 #endif
 145         
 146         saved_errno = errno;
 147         
 148         if (initialized) {
 149                 return;
 150         }
 151         initialized = 1;
 152         
 153 #if SMBW_DEBUG & 0x1
 154 # define GETSYM(symname, symstring)                                      \
 155         if ((smbw_libc.symname = dlsym(RTLD_NEXT, symstring)) == NULL) { \
 156                 if (smbw_libc.write != NULL &&                           \
 157                     (error = dlerror()) != NULL) {                       \
 158                         (* smbw_libc.write)(1, error, strlen(error));    \
 159                         (* smbw_libc.write)(1, "\n", 1);                 \
 160                 }                                                        \
 161         }
 162 #else
 163 # define GETSYM(symname, symstring)                     \
 164         smbw_libc.symname = dlsym(RTLD_NEXT, symstring);
 165 #endif
 166         
 167         /*
 168          * Get pointers to each of the symbols we'll need, from the C library
 169          *
 170          * Some of these symbols may not be found in the C library.  That's
 171          * fine.  We declare all of them here, and if the C library supports
 172          * them, they may be called so we have the wrappers for them.  If the
 173          * C library doesn't support them, then the wrapper function will
 174          * never be called, and the null pointer will never be dereferenced.
 175          */
 176         GETSYM(write, "write"); /* first, to allow debugging */
 177         GETSYM(open, "open");
 178         GETSYM(_open, "_open");
 179         GETSYM(__open, "__open");
 180         GETSYM(open64, "open64");
 181         GETSYM(_open64, "_open64");
 182         GETSYM(__open64, "__open64");
 183         GETSYM(pread, "pread");
 184         GETSYM(pread64, "pread64");
 185         GETSYM(pwrite, "pwrite");
 186         GETSYM(pwrite64, "pwrite64");
 187         GETSYM(close, "close");
 188         GETSYM(__close, "__close");
 189         GETSYM(_close, "_close");
 190         GETSYM(fcntl, "fcntl");
 191         GETSYM(__fcntl, "__fcntl");
 192         GETSYM(_fcntl, "_fcntl");
 193         GETSYM(getdents, "getdents");
 194         GETSYM(__getdents, "__getdents");
 195         GETSYM(_getdents, "_getdents");
 196         GETSYM(getdents64, "getdents64");
 197         GETSYM(lseek, "lseek");
 198         GETSYM(__lseek, "__lseek");
 199         GETSYM(_lseek, "_lseek");
 200         GETSYM(lseek64, "lseek64");
 201         GETSYM(__lseek64, "__lseek64");
 202         GETSYM(_lseek64, "_lseek64");
 203         GETSYM(read, "read");
 204         GETSYM(__read, "__read");
 205         GETSYM(_read, "_read");
 206         GETSYM(__write, "__write");
 207         GETSYM(_write, "_write");
 208         GETSYM(access, "access");
 209         GETSYM(chmod, "chmod");
 210         GETSYM(fchmod, "fchmod");
 211         GETSYM(chown, "chown");
 212         GETSYM(fchown, "fchown");
 213         GETSYM(__xstat, "__xstat");
 214         GETSYM(getcwd, "getcwd");
 215         GETSYM(mkdir, "mkdir");
 216         GETSYM(__fxstat, "__fxstat");
 217         GETSYM(__lxstat, "__lxstat");
 218         GETSYM(stat, "stat");
 219         GETSYM(lstat, "lstat");
 220         GETSYM(fstat, "fstat");
 221         GETSYM(unlink, "unlink");
 222         GETSYM(utime, "utime");
 223         GETSYM(utimes, "utimes");
 224         GETSYM(readlink, "readlink");
 225         GETSYM(rename, "rename");
 226         GETSYM(rmdir, "rmdir");
 227         GETSYM(symlink, "symlink");
 228         GETSYM(dup, "dup");
 229         GETSYM(dup2, "dup2");
 230         GETSYM(opendir, "opendir");
 231         GETSYM(readdir, "readdir");
 232         GETSYM(closedir, "closedir");
 233         GETSYM(telldir, "telldir");
 234         GETSYM(seekdir, "seekdir");
 235         GETSYM(creat, "creat");
 236         GETSYM(creat64, "creat64");
 237         GETSYM(__xstat64, "__xstat64");
 238         GETSYM(stat64, "stat64");
 239         GETSYM(__fxstat64, "__fxstat64");
 240         GETSYM(fstat64, "fstat64");
 241         GETSYM(__lxstat64, "__lxstat64");
 242         GETSYM(lstat64, "lstat64");
 243         GETSYM(_llseek, "_llseek");
 244         GETSYM(readdir64, "readdir64");
 245         GETSYM(readdir_r, "readdir_r");
 246         GETSYM(readdir64_r, "readdir64_r");
 247         GETSYM(setxattr, "setxattr");
 248         GETSYM(lsetxattr, "lsetxattr");
 249         GETSYM(fsetxattr, "fsetxattr");
 250         GETSYM(getxattr, "getxattr");
 251         GETSYM(lgetxattr, "lgetxattr");
 252         GETSYM(fgetxattr, "fgetxattr");
 253         GETSYM(removexattr, "removexattr");
 254         GETSYM(lremovexattr, "lremovexattr");
 255         GETSYM(fremovexattr, "fremovexattr");
 256         GETSYM(listxattr, "listxattr");
 257         GETSYM(llistxattr, "llistxattr");
 258         GETSYM(flistxattr, "flistxattr");
 259         GETSYM(chdir, "chdir");
 260         GETSYM(fchdir, "fchdir");
 261         GETSYM(fork, "fork");
 262         GETSYM(select, "select");
 263         GETSYM(_select, "_select");
 264         GETSYM(__select, "__select");
 265         
 266 #if SMBW_DEBUG & 4
 267         {
 268                 if ((debugFd =
 269                      open(SMBW_DEBUG_FILE, O_WRONLY | O_CREAT | O_APPEND)) < 0)
 270                 {
 271 #               define SMBW_MESSAGE    "Could not create " SMBW_DEBUG_FILE "\n" 
 272                         (* smbw_libc.write)(1, SMBW_MESSAGE, sizeof(SMBW_MESSAGE));
 273 #               undef SMBW_MESSAGE
 274                         exit(1);
 275                 }
 276         }
 277 #endif
 278         
 279         errno = saved_errno;
 280 }
 281 
 282 /**
 283  ** Static Functions
 284  **/
 285 
 286 static void stat_convert(struct SMBW_stat *src, struct stat *dest)
     /* [<][>][^][v][top][bottom][index][help] */
 287 {
 288         memset(dest, '\0', sizeof(*dest));
 289         dest->st_size = src->s_size;
 290         dest->st_mode = src->s_mode;
 291         dest->st_ino = src->s_ino;
 292         dest->st_dev = src->s_dev;
 293         dest->st_rdev = src->s_rdev;
 294         dest->st_nlink = src->s_nlink;
 295         dest->st_uid = src->s_uid;
 296         dest->st_gid = src->s_gid;
 297         dest->st_atime = src->s_atime;
 298         dest->st_mtime = src->s_mtime;
 299         dest->st_ctime = src->s_ctime;
 300         dest->st_blksize = src->s_blksize;
 301         dest->st_blocks = src->s_blocks;
 302 }
 303 
 304 static void stat64_convert(struct SMBW_stat *src, struct stat64 *dest)
     /* [<][>][^][v][top][bottom][index][help] */
 305 {
 306         memset(dest, '\0', sizeof(*dest));
 307         dest->st_size = src->s_size;
 308         dest->st_mode = src->s_mode;
 309         dest->st_ino = src->s_ino;
 310         dest->st_dev = src->s_dev;
 311         dest->st_rdev = src->s_rdev;
 312         dest->st_nlink = src->s_nlink;
 313         dest->st_uid = src->s_uid;
 314         dest->st_gid = src->s_gid;
 315         dest->st_atime = src->s_atime;
 316         dest->st_mtime = src->s_mtime;
 317         dest->st_ctime = src->s_ctime;
 318         dest->st_blksize = src->s_blksize;
 319         dest->st_blocks = src->s_blocks;
 320 }
 321 
 322 static void dirent_convert(struct SMBW_dirent *src, struct dirent *dest)
     /* [<][>][^][v][top][bottom][index][help] */
 323 {
 324         char *p;
 325         
 326         memset(dest, '\0', sizeof(*dest));
 327         dest->d_ino = src->d_ino;
 328         dest->d_off = src->d_off;
 329         
 330         switch(src->d_type)
 331         {
 332         case SMBC_WORKGROUP:
 333         case SMBC_SERVER:
 334         case SMBC_FILE_SHARE:
 335         case SMBC_DIR:
 336                 dest->d_type = DT_DIR;
 337                 break;
 338                 
 339         case SMBC_FILE:
 340                 dest->d_type = DT_REG;
 341                 break;
 342                 
 343         case SMBC_PRINTER_SHARE:
 344                 dest->d_type = DT_CHR;
 345                 break;
 346                 
 347         case SMBC_COMMS_SHARE:
 348                 dest->d_type = DT_SOCK;
 349                 break;
 350                 
 351         case SMBC_IPC_SHARE:
 352                 dest->d_type = DT_FIFO;
 353                 break;
 354                 
 355         case SMBC_LINK:
 356                 dest->d_type = DT_LNK;
 357                 break;
 358         }
 359         
 360         dest->d_reclen = src->d_reclen;
 361         smbw_strlcpy(dest->d_name, src->d_name, sizeof(dest->d_name));
 362         p = dest->d_name + strlen(dest->d_name) + 1;
 363         smbw_strlcpy(p,
 364                      src->d_comment,
 365                      sizeof(dest->d_name) - (p - dest->d_name));
 366 }
 367 
 368 static void dirent64_convert(struct SMBW_dirent *src, struct dirent64 *dest)
     /* [<][>][^][v][top][bottom][index][help] */
 369 {
 370         char *p;
 371         
 372         memset(dest, '\0', sizeof(*dest));
 373         dest->d_ino = src->d_ino;
 374         dest->d_off = src->d_off;
 375         
 376         switch(src->d_type)
 377         {
 378         case SMBC_WORKGROUP:
 379         case SMBC_SERVER:
 380         case SMBC_FILE_SHARE:
 381         case SMBC_DIR:
 382                 dest->d_type = DT_DIR;
 383                 break;
 384                 
 385         case SMBC_FILE:
 386                 dest->d_type = DT_REG;
 387                 break;
 388                 
 389         case SMBC_PRINTER_SHARE:
 390                 dest->d_type = DT_CHR;
 391                 break;
 392                 
 393         case SMBC_COMMS_SHARE:
 394                 dest->d_type = DT_SOCK;
 395                 break;
 396                 
 397         case SMBC_IPC_SHARE:
 398                 dest->d_type = DT_FIFO;
 399                 break;
 400                 
 401         case SMBC_LINK:
 402                 dest->d_type = DT_LNK;
 403                 break;
 404         }
 405         
 406         dest->d_reclen = src->d_reclen;
 407         smbw_strlcpy(dest->d_name, src->d_name, sizeof(dest->d_name));
 408         p = dest->d_name + strlen(dest->d_name) + 1;
 409         smbw_strlcpy(p,
 410                      src->d_comment,
 411                      sizeof(dest->d_name) - (p - dest->d_name));
 412 }
 413 
 414 static int openx(char *name, int flags, mode_t mode, int (* f)(char *, int, mode_t))
     /* [<][>][^][v][top][bottom][index][help] */
 415 {
 416         if (smbw_path(name)) {
 417                 return smbw_open(name, flags, mode);
 418         }
 419         
 420         return (* f)(name, flags, mode);
 421 }
 422 
 423 static int closex(int fd, int (* f)(int fd))
     /* [<][>][^][v][top][bottom][index][help] */
 424 {
 425         if (smbw_fd(fd)) {
 426                 return smbw_close(fd);
 427         }
 428         
 429         return (* f)(fd);
 430 }
 431 
 432 static int fcntlx(int fd, int cmd, long arg, int (* f)(int, int, long))
     /* [<][>][^][v][top][bottom][index][help] */
 433 {
 434         if (smbw_fd(fd)) {
 435                 return smbw_fcntl(fd, cmd, arg);
 436         }
 437         
 438         return (* f)(fd, cmd, arg);
 439 }
 440 
 441 static int getdentsx(int fd, struct dirent *external, unsigned int count, int (* f)(int, struct dirent *, unsigned int))
     /* [<][>][^][v][top][bottom][index][help] */
 442 {
 443         if (smbw_fd(fd)) {
 444                 int i;
 445                 int internal_count;
 446                 struct SMBW_dirent *internal;
 447                 int ret;
 448                 int n;
 449                 
 450                 /*
 451                  * LIMITATION: If they pass a count which is not a multiple of
 452                  * the size of struct dirent, they will not get a partial
 453                  * structure; we ignore the excess count.
 454                  */
 455                 n = (count / sizeof(struct dirent));
 456                 
 457                 internal_count = sizeof(struct SMBW_dirent) * n;
 458                 internal = malloc(internal_count);
 459                 if (internal == NULL) {
 460                         errno = ENOMEM;
 461                         return -1;
 462                 }
 463                 ret = smbw_getdents(fd, internal, internal_count);
 464                 if (ret <= 0)
 465                         return ret;
 466                 
 467                 ret = sizeof(struct dirent) * n;
 468                 
 469                 for (i = 0; i < n; i++)
 470                         dirent_convert(&internal[i], &external[i]);
 471                 
 472                 return ret;
 473         }
 474         
 475         return (* f)(fd, external, count);
 476 }
 477 
 478 static off_t lseekx(int fd,
     /* [<][>][^][v][top][bottom][index][help] */
 479                     off_t offset,
 480                     int whence,
 481                     off_t (* f)(int, off_t, int))
 482 {
 483         off_t           ret;
 484         
 485         /*
 486          * We have left the definitions of the smbw_ functions undefined,
 487          * because types such as off_t can differ in meaning betweent his
 488          * function and smbw.c et al.  Functions that return other than an
 489          * integer value, however, MUST have their return value defined.
 490          */
 491         off64_t         smbw_lseek();
 492         
 493         if (smbw_fd(fd)) {
 494                 return (off_t) smbw_lseek(fd, offset, whence);
 495         }
 496         
 497         ret = (* f)(fd, offset, whence);
 498         if (smbw_debug)
 499         {
 500                 printf("lseekx(%d, 0x%llx) returned 0x%llx\n",
 501                        fd,
 502                        (unsigned long long) offset,
 503                        (unsigned long long) ret);
 504         }
 505         return ret;
 506 }
 507 
 508 static off64_t lseek64x(int fd,
     /* [<][>][^][v][top][bottom][index][help] */
 509                         off64_t offset,
 510                         int whence,
 511                         off64_t (* f)(int, off64_t, int))
 512 {
 513         off64_t         ret;
 514         
 515         /*
 516          * We have left the definitions of the smbw_ functions undefined,
 517          * because types such as off_t can differ in meaning betweent his
 518          * function and smbw.c et al.  Functions that return other than an
 519          * integer value, however, MUST have their return value defined.
 520          */
 521         off64_t         smbw_lseek();
 522         
 523         if (smbw_fd(fd))
 524                 ret = smbw_lseek(fd, offset, whence);
 525         else
 526                 ret = (* f)(fd, offset, whence);
 527         if (smbw_debug)
 528         {
 529                 printf("lseek64x(%d, 0x%llx) returned 0x%llx\n",
 530                        fd,
 531                        (unsigned long long) offset,
 532                        (unsigned long long) ret);
 533         }
 534         return ret;
 535 }
 536 
 537 static ssize_t readx(int fd, void *buf, size_t count, ssize_t (* f)(int, void *, size_t))
     /* [<][>][^][v][top][bottom][index][help] */
 538 {
 539         if (smbw_fd(fd)) {
 540                 return smbw_read(fd, buf, count);
 541         }
 542         
 543         return (* f)(fd, buf, count);
 544 }
 545 
 546 static ssize_t writex(int fd, void *buf, size_t count, ssize_t (* f)(int, void *, size_t))
     /* [<][>][^][v][top][bottom][index][help] */
 547 {
 548         if (smbw_fd(fd)) {
 549                 return smbw_write(fd, buf, count);
 550         }
 551         
 552         return (* f)(fd, buf, count);
 553 }
 554 
 555 
 556 /**
 557  ** Wrapper Functions
 558  **/
 559 
 560 int open(__const char *name, int flags, ...)
     /* [<][>][^][v][top][bottom][index][help] */
 561 {
 562         va_list ap;
 563         mode_t mode;
 564         
 565         va_start(ap, flags);
 566         mode = va_arg(ap, mode_t);
 567         va_end(ap);
 568         
 569         check_init("open");
 570         
 571         return openx((char *) name, flags, mode, smbw_libc.open);
 572 }
 573 
 574 int _open(char *name, int flags, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
 575 {
 576         check_init("open");
 577         
 578         return openx(name, flags, mode, smbw_libc._open);
 579 }
 580 
 581 int __open(char *name, int flags, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
 582 {
 583         check_init("open");
 584         
 585         return openx(name, flags, mode, smbw_libc.__open);
 586 }
 587 
 588 int open64 (__const char *name, int flags, ...)
     /* [<][>][^][v][top][bottom][index][help] */
 589 {
 590         va_list ap;
 591         mode_t mode;
 592         
 593         va_start(ap, flags);
 594         mode = va_arg(ap, mode_t);
 595         va_end(ap);
 596         
 597         check_init("open64");
 598         return openx((char *) name, flags, mode, smbw_libc.open64);
 599 }
 600 
 601 int _open64(char *name, int flags, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
 602 {
 603         check_init("_open64");
 604         return openx(name, flags, mode, smbw_libc._open64);
 605 }
 606 
 607 int __open64(char *name, int flags, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
 608 {
 609         check_init("__open64");
 610         return openx(name, flags, mode, smbw_libc.__open64);
 611 }
 612 
 613 ssize_t pread(int fd, void *buf, size_t size, off_t ofs)
     /* [<][>][^][v][top][bottom][index][help] */
 614 {
 615         check_init("pread");
 616         
 617         if (smbw_fd(fd)) {
 618                 return smbw_pread(fd, buf, size, ofs);
 619         }
 620         
 621         return (* smbw_libc.pread)(fd, buf, size, ofs);
 622 }
 623 
 624 ssize_t pread64(int fd, void *buf, size_t size, off64_t ofs)
     /* [<][>][^][v][top][bottom][index][help] */
 625 {
 626         check_init("pread64");
 627         
 628         if (smbw_fd(fd)) {
 629                 return smbw_pread(fd, buf, size, (off_t) ofs);
 630         }
 631         
 632         return (* smbw_libc.pread64)(fd, buf, size, ofs);
 633 }
 634 
 635 ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs)
     /* [<][>][^][v][top][bottom][index][help] */
 636 {
 637         check_init("pwrite");
 638         
 639         if (smbw_fd(fd)) {
 640                 return smbw_pwrite(fd, (void *) buf, size, ofs);
 641         }
 642         
 643         return (* smbw_libc.pwrite)(fd, (void *) buf, size, ofs);
 644 }
 645 
 646 ssize_t pwrite64(int fd,  const void *buf, size_t size, off64_t ofs)
     /* [<][>][^][v][top][bottom][index][help] */
 647 {
 648         check_init("pwrite64");
 649         
 650         if (smbw_fd(fd)) {
 651                 return smbw_pwrite(fd, (void *) buf, size, (off_t) ofs);
 652         }
 653         
 654         return (* smbw_libc.pwrite64)(fd, (void *) buf, size, ofs);
 655 }
 656 
 657 int chdir(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 658 {
 659         check_init("chdir");
 660         return smbw_chdir((char *) name);;
 661 }
 662 
 663 int __chdir(char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 664 {
 665         check_init("__chdir");
 666         return smbw_chdir(name);
 667 }
 668 
 669 int _chdir(char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 670 {
 671         check_init("_chdir");
 672         return smbw_chdir(name);
 673 }
 674 
 675 int close(int fd)
     /* [<][>][^][v][top][bottom][index][help] */
 676 {
 677         check_init("close");
 678         return closex(fd, smbw_libc.close);
 679 }
 680 
 681 int __close(int fd)
     /* [<][>][^][v][top][bottom][index][help] */
 682 {
 683         check_init("__close");
 684         return closex(fd, smbw_libc.__close);
 685 }
 686 
 687 int _close(int fd)
     /* [<][>][^][v][top][bottom][index][help] */
 688 {
 689         check_init("_close");
 690         return closex(fd, smbw_libc._close);
 691 }
 692 
 693 int fchdir(int fd)
     /* [<][>][^][v][top][bottom][index][help] */
 694 {
 695         check_init("fchdir");
 696         return smbw_fchdir(fd);
 697 }
 698 
 699 int __fchdir(int fd)
     /* [<][>][^][v][top][bottom][index][help] */
 700 {
 701         check_init("__fchdir");
 702         return fchdir(fd);
 703 }
 704 
 705 int _fchdir(int fd)
     /* [<][>][^][v][top][bottom][index][help] */
 706 {
 707         check_init("_fchdir");
 708         return fchdir(fd);
 709 }
 710 
 711 int fcntl (int fd, int cmd, ...)
     /* [<][>][^][v][top][bottom][index][help] */
 712 {
 713         va_list ap;
 714         long arg;
 715         
 716         va_start(ap, cmd);
 717         arg = va_arg(ap, long);
 718         va_end(ap);
 719         
 720         check_init("fcntl");
 721         return fcntlx(fd, cmd, arg, smbw_libc.fcntl);
 722 }
 723 
 724 int __fcntl(int fd, int cmd, ...)
     /* [<][>][^][v][top][bottom][index][help] */
 725 {
 726         va_list ap;
 727         long arg;
 728         
 729         va_start(ap, cmd);
 730         arg = va_arg(ap, long);
 731         va_end(ap);
 732         
 733         check_init("__fcntl");
 734         return fcntlx(fd, cmd, arg, smbw_libc.__fcntl);
 735 }
 736 
 737 int _fcntl(int fd, int cmd, ...)
     /* [<][>][^][v][top][bottom][index][help] */
 738 {
 739         va_list ap;
 740         long arg;
 741         
 742         va_start(ap, cmd);
 743         arg = va_arg(ap, long);
 744         va_end(ap);
 745         
 746         check_init("_fcntl");
 747         return fcntlx(fd, cmd, arg, smbw_libc._fcntl);
 748 }
 749 
 750 int getdents(int fd, struct dirent *dirp, unsigned int count)
     /* [<][>][^][v][top][bottom][index][help] */
 751 {
 752         check_init("getdents");
 753         return getdentsx(fd, dirp, count, smbw_libc.getdents);
 754 }
 755 
 756 int __getdents(int fd, struct dirent *dirp, unsigned int count)
     /* [<][>][^][v][top][bottom][index][help] */
 757 {
 758         check_init("__getdents");
 759         return getdentsx(fd, dirp, count, smbw_libc.__getdents);
 760 }
 761 
 762 int _getdents(int fd, struct dirent *dirp, unsigned int count)
     /* [<][>][^][v][top][bottom][index][help] */
 763 {
 764         check_init("_getdents");
 765         return getdentsx(fd, dirp, count, smbw_libc._getdents);
 766 }
 767 
 768 int getdents64(int fd, struct dirent64 *external, unsigned int count)
     /* [<][>][^][v][top][bottom][index][help] */
 769 {
 770         check_init("getdents64");
 771         if (smbw_fd(fd)) {
 772                 int i;
 773                 struct SMBW_dirent *internal;
 774                 int ret;
 775                 int n;
 776                 
 777                 /*
 778                  * LIMITATION: If they pass a count which is not a multiple of
 779                  * the size of struct dirent, they will not get a partial
 780                  * structure; we ignore the excess count.
 781                  */
 782                 n = (count / sizeof(struct dirent64));
 783                 
 784                 internal = malloc(sizeof(struct SMBW_dirent) * n);
 785                 if (internal == NULL) {
 786                         errno = ENOMEM;
 787                         return -1;
 788                 }
 789                 ret = smbw_getdents(fd, internal, count);
 790                 if (ret <= 0)
 791                         return ret;
 792                 
 793                 ret = sizeof(struct dirent) * count;
 794                 
 795                 for (i = 0; count; i++, count--)
 796                         dirent64_convert(&internal[i], &external[i]);
 797                 
 798                 return ret;
 799         }
 800         
 801         return (* smbw_libc.getdents64)(fd, external, count);
 802 }
 803 
 804 off_t lseek(int fd, off_t offset, int whence)
     /* [<][>][^][v][top][bottom][index][help] */
 805 {
 806         off_t           ret;
 807         check_init("lseek");
 808         ret = lseekx(fd, offset, whence, smbw_libc.lseek);
 809         if (smbw_debug)
 810         {
 811                 printf("lseek(%d, 0x%llx) returned 0x%llx\n",
 812                        fd,
 813                        (unsigned long long) offset,
 814                        (unsigned long long) ret);
 815         }
 816         return ret;
 817 }
 818 
 819 off_t __lseek(int fd, off_t offset, int whence)
     /* [<][>][^][v][top][bottom][index][help] */
 820 {
 821         off_t           ret;
 822         check_init("__lseek");
 823         ret = lseekx(fd, offset, whence, smbw_libc.__lseek);
 824         if (smbw_debug)
 825         {
 826                 printf("__lseek(%d, 0x%llx) returned 0x%llx\n",
 827                        fd,
 828                        (unsigned long long) offset,
 829                        (unsigned long long) ret);
 830         }
 831         return ret;
 832 }
 833 
 834 off_t _lseek(int fd, off_t offset, int whence)
     /* [<][>][^][v][top][bottom][index][help] */
 835 {
 836         off_t           ret;
 837         check_init("_lseek");
 838         ret = lseekx(fd, offset, whence, smbw_libc._lseek);
 839         if (smbw_debug)
 840         {
 841                 printf("_lseek(%d, 0x%llx) returned 0x%llx\n",
 842                        fd,
 843                        (unsigned long long) offset,
 844                        (unsigned long long) ret);
 845         }
 846         return ret;
 847 }
 848 
 849 off64_t lseek64(int fd, off64_t offset, int whence)
     /* [<][>][^][v][top][bottom][index][help] */
 850 {
 851         off64_t         ret;
 852         check_init("lseek64");
 853         ret = lseek64x(fd, offset, whence, smbw_libc.lseek64);
 854         if (smbw_debug)
 855         {
 856                 printf("lseek64(%d, 0x%llx) returned 0x%llx\n",
 857                        fd,
 858                        (unsigned long long) offset,
 859                        (unsigned long long) ret);
 860         }
 861         return ret;
 862 }
 863 
 864 off64_t __lseek64(int fd, off64_t offset, int whence)
     /* [<][>][^][v][top][bottom][index][help] */
 865 {
 866         check_init("__lseek64");
 867         return lseek64x(fd, offset, whence, smbw_libc.__lseek64);
 868 }
 869 
 870 off64_t _lseek64(int fd, off64_t offset, int whence)
     /* [<][>][^][v][top][bottom][index][help] */
 871 {
 872         off64_t         ret;
 873         check_init("_lseek64");
 874         ret = lseek64x(fd, offset, whence, smbw_libc._lseek64);
 875         if (smbw_debug)
 876         {
 877                 printf("_lseek64(%d, 0x%llx) returned 0x%llx\n",
 878                        fd,
 879                        (unsigned long long) offset,
 880                        (unsigned long long) ret);
 881         }
 882         return ret;
 883 }
 884 
 885 ssize_t read(int fd, void *buf, size_t count)
     /* [<][>][^][v][top][bottom][index][help] */
 886 {
 887         check_init("read");
 888         return readx(fd, buf, count, smbw_libc.read);
 889 }
 890 
 891 ssize_t __read(int fd, void *buf, size_t count)
     /* [<][>][^][v][top][bottom][index][help] */
 892 {
 893         check_init("__read");
 894         return readx(fd, buf, count, smbw_libc.__read);
 895 }
 896 
 897 ssize_t _read(int fd, void *buf, size_t count)
     /* [<][>][^][v][top][bottom][index][help] */
 898 {
 899         check_init("_read");
 900         return readx(fd, buf, count, smbw_libc._read);
 901 }
 902 
 903 ssize_t write(int fd, const void *buf, size_t count)
     /* [<][>][^][v][top][bottom][index][help] */
 904 {
 905         check_init("write");
 906         return writex(fd, (void *) buf, count, smbw_libc.write);
 907 }
 908 
 909 ssize_t __write(int fd, const void *buf, size_t count)
     /* [<][>][^][v][top][bottom][index][help] */
 910 {
 911         check_init("__write");
 912         return writex(fd, (void *) buf, count, smbw_libc.__write);
 913 }
 914 
 915 ssize_t _write(int fd, const void *buf, size_t count)
     /* [<][>][^][v][top][bottom][index][help] */
 916 {
 917         check_init("_write");
 918         return writex(fd, (void *) buf, count, smbw_libc._write);
 919 }
 920 
 921 int access(const char *name, int mode)
     /* [<][>][^][v][top][bottom][index][help] */
 922 {
 923         check_init("access");
 924         
 925         if (smbw_path((char *) name)) {
 926                 return smbw_access((char *) name, mode);
 927         }
 928         
 929         return (* smbw_libc.access)((char *) name, mode);
 930 }
 931 
 932 int chmod(const char *name, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
 933 {
 934         check_init("chmod");
 935         
 936         if (smbw_path((char *) name)) {
 937                 return smbw_chmod((char *) name, mode);
 938         }
 939         
 940         return (* smbw_libc.chmod)((char *) name, mode);
 941 }
 942 
 943 int fchmod(int fd, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
 944 {
 945         check_init("fchmod");
 946         
 947         if (smbw_fd(fd)) {
 948                 /* Not yet implemented in libsmbclient */
 949                 return ENOTSUP;
 950         }
 951         
 952         return (* smbw_libc.fchmod)(fd, mode);
 953 }
 954 
 955 int chown(const char *name, uid_t owner, gid_t group)
     /* [<][>][^][v][top][bottom][index][help] */
 956 {
 957         check_init("chown");
 958         
 959         if (smbw_path((char *) name)) {
 960                 return smbw_chown((char *) name, owner, group);
 961         }
 962         
 963         return (* smbw_libc.chown)((char *) name, owner, group);
 964 }
 965 
 966 int fchown(int fd, uid_t owner, gid_t group)
     /* [<][>][^][v][top][bottom][index][help] */
 967 {
 968         check_init("fchown");
 969         
 970         if (smbw_fd(fd)) {
 971                 /* Not yet implemented in libsmbclient */
 972                 return ENOTSUP;
 973         }
 974         
 975         return (* smbw_libc.fchown)(fd, owner, group);
 976 }
 977 
 978 char *getcwd(char *buf, size_t size)
     /* [<][>][^][v][top][bottom][index][help] */
 979 {
 980         check_init("getcwd");
 981         return (char *)smbw_getcwd(buf, size);
 982 }
 983 
 984 int mkdir(const char *name, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
 985 {
 986         check_init("mkdir");
 987         
 988         if (smbw_path((char *) name)) {
 989                 return smbw_mkdir((char *) name, mode);
 990         }
 991         
 992         return (* smbw_libc.mkdir)((char *) name, mode);
 993 }
 994 
 995 int __fxstat(int vers, int fd, struct stat *st)
     /* [<][>][^][v][top][bottom][index][help] */
 996 {
 997         check_init("__fxstat");
 998         
 999         if (smbw_fd(fd)) {
1000                 struct SMBW_stat statbuf;
1001                 int ret = smbw_fstat(fd, &statbuf);
1002                 stat_convert(&statbuf, st);
1003                 return ret;
1004         }
1005         
1006         return (* smbw_libc.__fxstat)(vers, fd, st);
1007 }
1008 
1009 int __xstat(int vers, const char *name, struct stat *st)
     /* [<][>][^][v][top][bottom][index][help] */
1010 {
1011         check_init("__xstat");
1012         
1013         if (smbw_path((char *) name)) {
1014                 struct SMBW_stat statbuf;
1015                 int ret = smbw_stat((char *) name, &statbuf);
1016                 stat_convert(&statbuf, st);
1017                 return ret;
1018         }
1019         
1020         return (* smbw_libc.__xstat)(vers, (char *) name, st);
1021 }
1022 
1023 int __lxstat(int vers, const char *name, struct stat *st)
     /* [<][>][^][v][top][bottom][index][help] */
1024 {
1025         check_init("__lxstat");
1026         
1027         if (smbw_path((char *) name)) {
1028                 struct SMBW_stat statbuf;
1029                 int ret = smbw_stat((char *) name, &statbuf);
1030                 stat_convert(&statbuf, st);
1031                 return ret;
1032         }
1033         
1034         return (* smbw_libc.__lxstat)(vers, (char *) name, st);
1035 }
1036 
1037 int stat(const char *name, struct stat *st)
     /* [<][>][^][v][top][bottom][index][help] */
1038 {
1039         check_init("stat");
1040         
1041         if (smbw_path((char *) name)) {
1042                 struct SMBW_stat statbuf;
1043                 int ret = smbw_stat((char *) name, &statbuf);
1044                 stat_convert(&statbuf, st);
1045                 return ret;
1046         }
1047         
1048         return (* smbw_libc.stat)((char *) name, st);
1049 }
1050 
1051 int lstat(const char *name, struct stat *st)
     /* [<][>][^][v][top][bottom][index][help] */
1052 {
1053         check_init("lstat");
1054         
1055         if (smbw_path((char *) name)) {
1056                 struct SMBW_stat statbuf;
1057                 int ret = smbw_stat((char *) name, &statbuf);
1058                 stat_convert(&statbuf, st);
1059                 return ret;
1060         }
1061         
1062         return (* smbw_libc.lstat)((char *) name, st);
1063 }
1064 
1065 int fstat(int fd, struct stat *st)
     /* [<][>][^][v][top][bottom][index][help] */
1066 {
1067         check_init("fstat");
1068         
1069         if (smbw_fd(fd)) {
1070                 struct SMBW_stat statbuf;
1071                 int ret = smbw_fstat(fd, &statbuf);
1072                 stat_convert(&statbuf, st);
1073                 return ret;
1074         }
1075         
1076         return (* smbw_libc.fstat)(fd, st);
1077 }
1078 
1079 int unlink(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
1080 {
1081         check_init("unlink");
1082         
1083         if (smbw_path((char *) name)) {
1084                 return smbw_unlink((char *) name);
1085         }
1086         
1087         return (* smbw_libc.unlink)((char *) name);
1088 }
1089 
1090 int utime(const char *name, const struct utimbuf *tvp)
     /* [<][>][^][v][top][bottom][index][help] */
1091 {
1092         check_init("utime");
1093         
1094         if (smbw_path(name)) {
1095                 return smbw_utime(name, (struct utimbuf *) tvp);
1096         }
1097         
1098         return (* smbw_libc.utime)((char *) name, (struct utimbuf *) tvp);
1099 }
1100 
1101 int utimes(const char *name, const struct timeval *tvp)
     /* [<][>][^][v][top][bottom][index][help] */
1102 {
1103         check_init("utimes");
1104         
1105         if (smbw_path(name)) {
1106                 return smbw_utimes(name, (struct timeval *) tvp);
1107         }
1108         
1109         return (* smbw_libc.utimes)((char *) name, (struct timeval *) tvp);
1110 }
1111 
1112 ssize_t readlink(const char *path, char *buf, size_t bufsize)
     /* [<][>][^][v][top][bottom][index][help] */
1113 {
1114         check_init("readlink");
1115         
1116         if (smbw_path((char *) path)) {
1117                 return smbw_readlink(path, (char *) buf, bufsize);
1118         }
1119         
1120         return (* smbw_libc.readlink)((char *) path, buf, bufsize);
1121 }
1122 
1123 int rename(const char *oldname, const char *newname)
     /* [<][>][^][v][top][bottom][index][help] */
1124 {
1125         int p1, p2;
1126         
1127         check_init("rename");
1128         
1129         p1 = smbw_path((char *) oldname); 
1130         p2 = smbw_path((char *) newname); 
1131         if (p1 ^ p2) {
1132                 /* can't cross filesystem boundaries */
1133                 errno = EXDEV;
1134                 return -1;
1135         }
1136         if (p1 && p2) {
1137                 return smbw_rename((char *) oldname, (char *) newname);
1138         }
1139         
1140         return (* smbw_libc.rename)((char *) oldname, (char *) newname);
1141 }
1142 
1143 int rmdir(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
1144 {
1145         check_init("rmdir");
1146         
1147         if (smbw_path((char *) name)) {
1148                 return smbw_rmdir((char *) name);
1149         }
1150         
1151         return (* smbw_libc.rmdir)((char *) name);
1152 }
1153 
1154 int symlink(const char *topath, const char *frompath)
     /* [<][>][^][v][top][bottom][index][help] */
1155 {
1156         int p1, p2;
1157         
1158         check_init("symlink");
1159         
1160         p1 = smbw_path((char *) topath); 
1161         p2 = smbw_path((char *) frompath); 
1162         if (p1 || p2) {
1163                 /* can't handle symlinks */
1164                 errno = EPERM;
1165                 return -1;
1166         }
1167         
1168         return (* smbw_libc.symlink)((char *) topath, (char *) frompath);
1169 }
1170 
1171 int dup(int fd)
     /* [<][>][^][v][top][bottom][index][help] */
1172 {
1173         check_init("dup");
1174         
1175         if (smbw_fd(fd)) {
1176                 return smbw_dup(fd);
1177         }
1178         
1179         return (* smbw_libc.dup)(fd);
1180 }
1181 
1182 int dup2(int oldfd, int newfd)
     /* [<][>][^][v][top][bottom][index][help] */
1183 {
1184         check_init("dup2");
1185         
1186         if (smbw_fd(newfd)) {
1187                 (* smbw_libc.close)(newfd);
1188         }
1189         
1190         if (smbw_fd(oldfd)) {
1191                 return smbw_dup2(oldfd, newfd);
1192         }
1193         
1194         return (* smbw_libc.dup2)(oldfd, newfd);
1195 }
1196 
1197 
1198 DIR *opendir(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
1199 {
1200         check_init("opendir");
1201         
1202         if (smbw_path((char *) name)) {
1203                 return (void *)smbw_opendir((char *) name);
1204         }
1205         
1206         return (* smbw_libc.opendir)((char *) name);
1207 }
1208 
1209 struct dirent *readdir(DIR *dir)
     /* [<][>][^][v][top][bottom][index][help] */
1210 {
1211         check_init("readdir");
1212         
1213         if (smbw_dirp(dir)) {
1214                 static struct dirent external;
1215                 struct SMBW_dirent * internal = (void *)smbw_readdir(dir);
1216                 if (internal != NULL) {
1217                         dirent_convert(internal, &external);
1218                         return &external;
1219                 }
1220                 return NULL;
1221         }
1222         return (* smbw_libc.readdir)(dir);
1223 }
1224 
1225 int closedir(DIR *dir)
     /* [<][>][^][v][top][bottom][index][help] */
1226 {
1227         check_init("closedir");
1228         
1229         if (smbw_dirp(dir)) {
1230                 return smbw_closedir(dir);
1231         }
1232         
1233         return (* smbw_libc.closedir)(dir);
1234 }
1235 
1236 long telldir(DIR *dir)
     /* [<][>][^][v][top][bottom][index][help] */
1237 {
1238         check_init("telldir");
1239         
1240         if (smbw_dirp(dir)) {
1241                 return (long) smbw_telldir(dir);
1242         }
1243         
1244         return (* smbw_libc.telldir)(dir);
1245 }
1246 
1247 void seekdir(DIR *dir, long offset)
     /* [<][>][^][v][top][bottom][index][help] */
1248 {
1249         check_init("seekdir");
1250         
1251         if (smbw_dirp(dir)) {
1252                 smbw_seekdir(dir, (long long) offset);
1253                 return;
1254         }
1255         
1256         (* smbw_libc.seekdir)(dir, offset);
1257 }
1258 
1259 int creat(const char *path, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
1260 {
1261         extern int creat_bits;
1262         
1263         check_init("creat");
1264         return openx((char *) path, creat_bits, mode, smbw_libc.open);
1265 }
1266 
1267 int creat64(const char *path, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
1268 {
1269         extern int creat_bits;
1270         
1271         check_init("creat64");
1272         return openx((char *) path, creat_bits, mode, smbw_libc.open64);
1273 }
1274 
1275 int __xstat64 (int ver, const char *name, struct stat64 *st64)
     /* [<][>][^][v][top][bottom][index][help] */
1276 {
1277         check_init("__xstat64");
1278         
1279         if (smbw_path((char *) name)) {
1280                 struct SMBW_stat statbuf;
1281                 int ret = smbw_stat((char *) name, &statbuf);
1282                 stat64_convert(&statbuf, st64);
1283                 return ret;
1284         }
1285         
1286         return (* smbw_libc.__xstat64)(ver, (char *) name, st64);
1287 }
1288 
1289 int stat64(const char *name, struct stat64 *st64)
     /* [<][>][^][v][top][bottom][index][help] */
1290 {
1291         check_init("stat64");
1292         
1293         if (smbw_path((char *) name)) {
1294                 struct SMBW_stat statbuf;
1295                 int ret = smbw_stat((char *) name, &statbuf);
1296                 stat64_convert(&statbuf, st64);
1297                 return ret;
1298         }
1299         
1300         return (* smbw_libc.stat64)((char *) name, st64);
1301 }
1302 
1303 int __fxstat64(int ver, int fd, struct stat64 *st64)
     /* [<][>][^][v][top][bottom][index][help] */
1304 {
1305         check_init("__fxstat64");
1306         
1307         if (smbw_fd(fd)) {
1308                 struct SMBW_stat statbuf;
1309                 int ret = smbw_fstat(fd, &statbuf);
1310                 stat64_convert(&statbuf, st64);
1311                 return ret;
1312         }
1313         
1314         return (* smbw_libc.__fxstat64)(ver, fd, st64);
1315 }
1316 
1317 int fstat64(int fd, struct stat64 *st64)
     /* [<][>][^][v][top][bottom][index][help] */
1318 {
1319         check_init("fstat64");
1320         
1321         if (smbw_fd(fd)) {
1322                 struct SMBW_stat statbuf;
1323                 int ret = smbw_fstat(fd, &statbuf);
1324                 stat64_convert(&statbuf, st64);
1325                 return ret;
1326         }
1327         
1328         return (* smbw_libc.fstat64)(fd, st64);
1329 }
1330 
1331 int __lxstat64(int ver, const char *name, struct stat64 *st64)
     /* [<][>][^][v][top][bottom][index][help] */
1332 {
1333         check_init("__lxstat64");
1334         
1335         if (smbw_path((char *) name)) {
1336                 struct SMBW_stat statbuf;
1337                 int ret = smbw_stat(name, &statbuf);
1338                 stat64_convert(&statbuf, st64);
1339                 return ret;
1340         }
1341         
1342         return (* smbw_libc.__lxstat64)(ver, (char *) name, st64);
1343 }
1344 
1345 int lstat64(const char *name, struct stat64 *st64)
     /* [<][>][^][v][top][bottom][index][help] */
1346 {
1347         check_init("lstat64");
1348         
1349         if (smbw_path((char *) name)) {
1350                 struct SMBW_stat statbuf;
1351                 int ret = smbw_stat((char *) name, &statbuf);
1352                 stat64_convert(&statbuf, st64);
1353                 return ret;
1354         }
1355         
1356         return (* smbw_libc.lstat64)((char *) name, st64);
1357 }
1358 
1359 int _llseek(unsigned int fd,  unsigned  long  offset_high, unsigned  long  offset_low,  loff_t  *result, unsigned int whence)
     /* [<][>][^][v][top][bottom][index][help] */
1360 {
1361         check_init("_llseek");
1362         
1363         if (smbw_fd(fd)) {
1364                 *result = lseek(fd, offset_low, whence);
1365                 return (*result < 0 ? -1 : 0);
1366         }
1367         
1368         return (* smbw_libc._llseek)(fd, offset_high, offset_low, result, whence);
1369 }
1370 
1371 struct dirent64 *readdir64(DIR *dir)
     /* [<][>][^][v][top][bottom][index][help] */
1372 {
1373         check_init("readdir64");
1374         
1375         if (smbw_dirp(dir)) {
1376                 static struct dirent64 external;
1377                 struct SMBW_dirent * internal = (void *)smbw_readdir(dir);
1378                 if (internal != NULL) {
1379                         dirent64_convert(internal, &external);
1380                         return &external;
1381                 }
1382                 return NULL;
1383         }
1384         
1385         return (* smbw_libc.readdir64)(dir);
1386 }
1387 
1388 int readdir_r(DIR *dir, struct dirent *external, struct dirent **result)
     /* [<][>][^][v][top][bottom][index][help] */
1389 {
1390         check_init("readdir_r");
1391         
1392         if (smbw_dirp(dir)) {
1393                 struct SMBW_dirent internal;
1394                 int ret = smbw_readdir_r(dir, &internal, NULL);
1395                 if (ret == 0) {
1396                         dirent_convert(&internal, external);
1397                         *result = external;
1398                 }
1399                 return ret;
1400         }
1401         
1402         return (* smbw_libc.readdir_r)(dir, external, result);
1403 }
1404 
1405 int readdir64_r(DIR *dir, struct dirent64 *external, struct dirent64 **result)
     /* [<][>][^][v][top][bottom][index][help] */
1406 {
1407         check_init("readdir64_r");
1408         
1409         if (smbw_dirp(dir)) {
1410                 struct SMBW_dirent internal;
1411                 int ret = smbw_readdir_r(dir, &internal, NULL);
1412                 if (ret == 0) {
1413                         dirent64_convert(&internal, external);
1414                         *result = external;
1415                 }
1416                 return ret;
1417         }
1418         
1419         return (* smbw_libc.readdir64_r)(dir, external, result);
1420 }
1421 
1422 int fork(void)
     /* [<][>][^][v][top][bottom][index][help] */
1423 {
1424         check_init("fork");
1425         return smbw_fork();
1426 }
1427 
1428 int setxattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
1429              const char *name,
1430              const void *value,
1431              size_t size,
1432              int flags)
1433 {
1434         if (smbw_path(fname)) {
1435                 return smbw_setxattr(fname, name, value, size, flags);
1436         }
1437         
1438         return (* smbw_libc.setxattr)(fname, name, value, size, flags);
1439 }
1440 
1441 int lsetxattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
1442               const char *name,
1443               const void *value,
1444               size_t size,
1445               int flags)
1446 {
1447         if (smbw_path(fname)) {
1448                 return smbw_lsetxattr(fname, name, value, size, flags);
1449         }
1450         
1451         return (* smbw_libc.lsetxattr)(fname, name, value, size, flags);
1452 }
1453 
1454 int fsetxattr(int fd,
     /* [<][>][^][v][top][bottom][index][help] */
1455               const char *name,
1456               const void *value,
1457               size_t size,
1458               int flags)
1459 {
1460         if (smbw_fd(fd)) {
1461                 return smbw_fsetxattr(fd, name, value, size, flags);
1462         }
1463         
1464         return (* smbw_libc.fsetxattr)(fd, name, value, size, flags);
1465 }
1466 
1467 int getxattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
1468              const char *name,
1469              const void *value,
1470              size_t size)
1471 {
1472         if (smbw_path(fname)) {
1473                 return smbw_getxattr(fname, name, value, size);
1474         }
1475         
1476         return (* smbw_libc.getxattr)(fname, name, value, size);
1477 }
1478 
1479 int lgetxattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
1480               const char *name,
1481               const void *value,
1482               size_t size)
1483 {
1484         if (smbw_path(fname)) {
1485                 return smbw_lgetxattr(fname, name, value, size);
1486         }
1487         
1488         return (* smbw_libc.lgetxattr)(fname, name, value, size);
1489 }
1490 
1491 int fgetxattr(int fd,
     /* [<][>][^][v][top][bottom][index][help] */
1492               const char *name,
1493               const void *value,
1494               size_t size)
1495 {
1496         if (smbw_fd(fd)) {
1497                 return smbw_fgetxattr(fd, name, value, size);
1498         }
1499         
1500         return (* smbw_libc.fgetxattr)(fd, name, value, size);
1501 }
1502 
1503 int removexattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
1504                 const char *name)
1505 {
1506         if (smbw_path(fname)) {
1507                 return smbw_removexattr(fname, name);
1508         }
1509         
1510         return (* smbw_libc.removexattr)(fname, name);
1511 }
1512 
1513 int lremovexattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
1514                  const char *name)
1515 {
1516         if (smbw_path(fname)) {
1517                 return smbw_lremovexattr(fname, name);
1518         }
1519         
1520         return (* smbw_libc.lremovexattr)(fname, name);
1521 }
1522 
1523 int fremovexattr(int fd,
     /* [<][>][^][v][top][bottom][index][help] */
1524                  const char *name)
1525 {
1526         if (smbw_fd(fd)) {
1527                 return smbw_fremovexattr(fd, name);
1528         }
1529         
1530         return (* smbw_libc.fremovexattr)(fd, name);
1531 }
1532 
1533 int listxattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
1534               char *list,
1535               size_t size)
1536 {
1537         if (smbw_path(fname)) {
1538                 return smbw_listxattr(fname, list, size);
1539         }
1540         
1541         return (* smbw_libc.listxattr)(fname, list, size);
1542 }
1543 
1544 int llistxattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
1545                char *list,
1546                size_t size)
1547 {
1548         if (smbw_path(fname)) {
1549                 return smbw_llistxattr(fname, list, size);
1550         }
1551         
1552         return (* smbw_libc.llistxattr)(fname, list, size);
1553 }
1554 
1555 int flistxattr(int fd,
     /* [<][>][^][v][top][bottom][index][help] */
1556                char *list,
1557                size_t size)
1558 {
1559         if (smbw_fd(fd)) {
1560                 return smbw_flistxattr(fd, list, size);
1561         }
1562         
1563         return (* smbw_libc.flistxattr)(fd, list, size);
1564 }
1565 
1566 
1567 /*
1568  * We're ending up with a different implementation of malloc() with smbwrapper
1569  * than without it.  The one with it does not support returning a non-NULL
1570  * pointer from a call to malloc(0), and many apps depend on getting a valid
1571  * pointer when requesting zero length (e.g. df, emacs).
1572  *
1573  * Unfortunately, initializing the smbw_libc[] array via the dynamic link
1574  * library (libdl) requires malloc so we can't just do the same type of
1575  * mapping to the C library as we do with everything else.  We need to
1576  * implement a different way of allocating memory that ensures that the C
1577  * library version of malloc() gets used.  This is the only place where we
1578  * kludge the code to use an undocumented interface to the C library.
1579  *
1580  * If anyone can come up with a way to dynamically link to the C library
1581  * rather than using this undocumented interface, I'd sure love to hear about
1582  * it.  Better yet, if you can figure out where the alternate malloc()
1583  * functions are coming from and arrange for them not to be called, that would
1584  * be even better.  We should try to avoid wrapping functions that don't
1585  * really require it.
1586  */
1587 
1588 void *malloc(size_t size)
     /* [<][>][^][v][top][bottom][index][help] */
1589 {
1590         void *__libc_malloc(size_t size);
1591         return __libc_malloc(size);
1592 }
1593 
1594 void *calloc(size_t nmemb, size_t size)
     /* [<][>][^][v][top][bottom][index][help] */
1595 {
1596         void *__libc_calloc(size_t nmemb, size_t size);
1597         return __libc_calloc(nmemb, size);
1598 }
1599 
1600 void *realloc(void *ptr, size_t size)
     /* [<][>][^][v][top][bottom][index][help] */
1601 {
1602         void *__libc_realloc(void *ptr, size_t size);
1603         return __libc_realloc(ptr, size);
1604 }
1605 
1606 void free(void *ptr)
     /* [<][>][^][v][top][bottom][index][help] */
1607 {
1608         static int      in_progress = 0;
1609         void __libc_free(void *ptr);
1610         
1611         if (in_progress) return;
1612         in_progress = 1;
1613         __libc_free(ptr);
1614         in_progress = 0;
1615 }
1616 
1617 
1618 #if 0                           /* SELECT */
1619 
1620 static struct sigaction user_action[_NSIG];
1621 
1622 static void
1623 smbw_sigaction_handler(int signum,
     /* [<][>][^][v][top][bottom][index][help] */
1624                        siginfo_t *info,
1625                        void *context)
1626 {
1627         /* Our entire purpose for trapping signals is to call this! */
1628         sys_select_signal();
1629         
1630         /* Call the user's handler */
1631         if (user_action[signum].sa_handler != SIG_IGN &&
1632             user_action[signum].sa_handler != SIG_DFL &&
1633             user_action[signum].sa_handler != SIG_ERR) {
1634                 (* user_action[signum].sa_sigaction)(signum, info, context);
1635         }
1636 }
1637 
1638 
1639 /*
1640  * Every Samba signal handler must call sys_select_signal() to avoid a race
1641  * condition, so we'll take whatever signal handler is currently assigned,
1642  * call call sys_select_signal() in addition to their call.
1643  */
1644 static int
1645 do_select(int n,
     /* [<][>][^][v][top][bottom][index][help] */
1646           fd_set *readfds,
1647           fd_set *writefds,
1648           fd_set *exceptfds,
1649           struct timeval *timeout,
1650           int (* select_fn)(int n,
1651                             fd_set *readfds,
1652                             fd_set *writefds,
1653                             fd_set *exceptfds,
1654                             struct timeval *timeout))
1655 {
1656         int i;
1657         int ret;
1658         int saved_errno;
1659         sigset_t sigset;
1660         struct sigaction new_action;
1661         
1662         saved_errno = errno;
1663         for (i=1; i<_NSIG; i++) {
1664                 sigemptyset(&sigset);
1665                 new_action.sa_mask = sigset;
1666                 new_action.sa_flags = SA_SIGINFO;
1667                 new_action.sa_sigaction = smbw_sigaction_handler;
1668                 
1669                 if (sigaction(i, &new_action, &user_action[i]) < 0) {
1670                         if (errno != EINVAL) {
1671                                 return -1;
1672                         }
1673                 }
1674         }
1675         errno = saved_errno;
1676         
1677         ret = (* select_fn)(n, readfds, writefds, exceptfds, timeout);
1678         saved_errno = errno;
1679         
1680         for (i=0; i<_NSIG; i++) {
1681                 (void) sigaction(i, &user_action[i], NULL);
1682         }
1683         
1684         errno = saved_errno;
1685         return ret;
1686 }
1687 
1688 int
1689 select(int n,
     /* [<][>][^][v][top][bottom][index][help] */
1690        fd_set *readfds,
1691        fd_set *writefds,
1692        fd_set *exceptfds,
1693        struct timeval *timeout)
1694 {
1695         check_init("select");
1696         
1697         return do_select(n, readfds, writefds, exceptfds,
1698                          timeout, smbw_libc.select);
1699 }
1700 
1701 int
1702 _select(int n,
     /* [<][>][^][v][top][bottom][index][help] */
1703         fd_set *readfds,
1704         fd_set *writefds,
1705         fd_set *exceptfds,
1706         struct timeval *timeout)
1707 {
1708         check_init("_select");
1709         
1710         return do_select(n, readfds, writefds, exceptfds,
1711                          timeout, smbw_libc._select);
1712 }
1713 
1714 int
1715 __select(int n,
     /* [<][>][^][v][top][bottom][index][help] */
1716          fd_set *readfds,
1717          fd_set *writefds,
1718          fd_set *exceptfds,
1719          struct timeval *timeout)
1720 {
1721         check_init("__select");
1722         
1723         return do_select(n, readfds, writefds, exceptfds,
1724                          timeout, smbw_libc.__select);
1725 }
1726 
1727 #endif

/* [<][>][^][v][top][bottom][index][help] */