root/examples/libsmbclient/smbwrapper/smbw.c

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

DEFINITIONS

This source file includes following definitions.
  1. smbw_ref
  2. get_envvar_auth_data
  3. smbw_set_auth_data_fn
  4. do_shutdown
  5. do_init
  6. smbw_init
  7. smbw_fd
  8. smbw_path
  9. smbw_clean_fname
  10. smbw_fix_path
  11. smbw_open
  12. smbw_pread
  13. smbw_read
  14. smbw_write
  15. smbw_pwrite
  16. smbw_close
  17. smbw_fcntl
  18. smbw_access
  19. smbw_readlink
  20. smbw_unlink
  21. smbw_rename
  22. smbw_utimes
  23. smbw_utime
  24. smbw_chown
  25. smbw_chmod
  26. smbw_lseek
  27. smbw_dup
  28. smbw_dup2
  29. smbw_fork
  30. smbw_setxattr
  31. smbw_lsetxattr
  32. smbw_fsetxattr
  33. smbw_getxattr
  34. smbw_lgetxattr
  35. smbw_fgetxattr
  36. smbw_removexattr
  37. smbw_lremovexattr
  38. smbw_fremovexattr
  39. smbw_listxattr
  40. smbw_llistxattr
  41. smbw_flistxattr

   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 2003-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 #include <stdio.h>
  23 #include <stdlib.h>
  24 #include <unistd.h>
  25 #include <stdarg.h>
  26 #include <assert.h>
  27 #include "smbw.h"
  28 #include "bsd-strlfunc.h"
  29 
  30 typedef enum StartupType
  31 {
  32         StartupType_Fake,
  33         StartupType_Real
  34 } StartupType;
  35 
  36 int smbw_fd_map[__FD_SETSIZE];
  37 int smbw_ref_count[__FD_SETSIZE];
  38 char smbw_cwd[PATH_MAX];
  39 char smbw_prefix[] = SMBW_PREFIX;
  40 
  41 /* needs to be here because of dumb include files on some systems */
  42 int creat_bits = O_WRONLY|O_CREAT|O_TRUNC;
  43 
  44 int smbw_initialized = 0;
  45 
  46 static int debug_level = 0;
  47 
  48 static SMBCCTX *smbw_ctx;
  49 
  50 extern int smbw_debug;
  51 
  52 
  53 /*****************************************************
  54 smbw_ref -- manipulate reference counts
  55 ******************************************************/
  56 int smbw_ref(int client_fd, Ref_Count_Type type, ...)
     /* [<][>][^][v][top][bottom][index][help] */
  57 {
  58         va_list ap;
  59 
  60         /* client id values begin at SMBC_BASE_FC. */
  61         client_fd -= SMBC_BASE_FD;
  62 
  63         va_start(ap, type);
  64         switch(type)
  65         {
  66         case SMBW_RCT_Increment:
  67                 return ++smbw_ref_count[client_fd];
  68 
  69         case SMBW_RCT_Decrement:
  70                 return --smbw_ref_count[client_fd];
  71 
  72         case SMBW_RCT_Get:
  73                 return smbw_ref_count[client_fd];
  74 
  75         case SMBW_RCT_Set:
  76                 return (smbw_ref_count[client_fd] = va_arg(ap, int));
  77         }
  78         va_end(ap);
  79 
  80         /* never gets here */
  81         return -1;
  82 }
  83 
  84 
  85 /*
  86  * Return a username and password given a server and share name
  87  *
  88  * Returns 0 upon success;
  89  * non-zero otherwise, and errno is set to indicate the error.
  90  */
  91 static void get_envvar_auth_data(const char *srv, 
     /* [<][>][^][v][top][bottom][index][help] */
  92                                  const char *shr,
  93                                  char *wg, int wglen, 
  94                                  char *un, int unlen,
  95                                  char *pw, int pwlen)
  96 {
  97         char *u;
  98         char *p;
  99         char *w;
 100 
 101         /* Fall back to environment variables */
 102 
 103         w = getenv("WORKGROUP");
 104         if (w == NULL) w = "";
 105 
 106         u = getenv("USER");
 107         if (u == NULL) u = "";
 108 
 109         p = getenv("PASSWORD");
 110         if (p == NULL) p = "";
 111 
 112         smbw_strlcpy(wg, w, wglen);
 113         smbw_strlcpy(un, u, unlen);
 114         smbw_strlcpy(pw, p, pwlen);
 115 }
 116 
 117 static smbc_get_auth_data_fn get_auth_data_fn = get_envvar_auth_data;
 118 
 119 /*****************************************************
 120 set the get auth data function
 121 ******************************************************/
 122 void smbw_set_auth_data_fn(smbc_get_auth_data_fn fn)
     /* [<][>][^][v][top][bottom][index][help] */
 123 {
 124         get_auth_data_fn = fn;
 125 }
 126 
 127 
 128 /*****************************************************
 129 ensure that all connections are terminated upon exit
 130 ******************************************************/
 131 static void do_shutdown(void)
     /* [<][>][^][v][top][bottom][index][help] */
 132 {
 133         if (smbw_ctx != NULL) {
 134                 smbc_free_context(smbw_ctx, 1);
 135         }
 136 }
 137 
 138 
 139 /***************************************************** 
 140 initialise structures
 141 *******************************************************/
 142 static void do_init(StartupType startupType)
     /* [<][>][^][v][top][bottom][index][help] */
 143 {
 144         int i;
 145         char *p;
 146 
 147         smbw_initialized = 1;   /* this must be first to avoid recursion! */
 148 
 149         smbw_ctx = NULL;        /* don't free context until it's established */
 150 
 151         /* initially, no file descriptors are mapped */
 152         for (i = 0; i < __FD_SETSIZE; i++) {
 153                 smbw_fd_map[i] = -1;
 154                 smbw_ref_count[i] = 0;
 155         }
 156 
 157         /* See if we've been told to start in a particular directory */
 158         if ((p=getenv("SMBW_DIR")) != NULL) {
 159                 smbw_strlcpy(smbw_cwd, p, PATH_MAX);
 160 
 161                 /* we don't want the old directory to be busy */
 162                 (* smbw_libc.chdir)("/");
 163                 
 164         } else {
 165                 *smbw_cwd = '\0';
 166         }
 167 
 168         if ((p=getenv("DEBUG"))) {
 169                 debug_level = atoi(p);
 170         }
 171 
 172         if ((smbw_ctx = smbc_new_context()) == NULL) {
 173                 fprintf(stderr, "Could not create a context.\n");
 174                 exit(1);
 175         }
 176         
 177         smbc_setDebug(smbw_ctx, debug_level);
 178         smbc_setFunctionAuthData(smbw_ctx, get_auth_data_fn);
 179         smbc_setOptionBrowseMaxLmbCount(smbw_ctx, 0);
 180         smbc_setOptionUrlEncodeReaddirEntries(smbw_ctx, 1);
 181         smbc_setOptionOneSharePerServer(smbw_ctx, 1);
 182         
 183         if (smbc_init_context(smbw_ctx) == NULL) {
 184                 fprintf(stderr, "Could not initialize context.\n");
 185                 exit(1);
 186         }
 187                 
 188         smbc_set_context(smbw_ctx);
 189 
 190         /* if not real startup, exit handler has already been established */
 191         if (startupType == StartupType_Real) {
 192             atexit(do_shutdown);
 193         }
 194 }
 195 
 196 /***************************************************** 
 197 initialise structures, real start up vs a fork()
 198 *******************************************************/
 199 void smbw_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 200 {
 201     do_init(StartupType_Real);
 202 }
 203 
 204 
 205 /***************************************************** 
 206 determine if a file descriptor is a smb one
 207 *******************************************************/
 208 int smbw_fd(int smbw_fd)
     /* [<][>][^][v][top][bottom][index][help] */
 209 {
 210         SMBW_INIT();
 211 
 212         return (smbw_fd >= 0 &&
 213                 smbw_fd < __FD_SETSIZE &&
 214                 smbw_fd_map[smbw_fd] >= SMBC_BASE_FD); /* minimum smbc_ fd */
 215 }
 216 
 217 
 218 /***************************************************** 
 219 determine if a path is a smb one
 220 *******************************************************/
 221 int smbw_path(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 222 {
 223         int len;
 224         int ret;
 225         int saved_errno;
 226 
 227         saved_errno = errno;
 228 
 229         SMBW_INIT();
 230 
 231         len = strlen(smbw_prefix);
 232 
 233         ret = ((strncmp(name, smbw_prefix, len) == 0 &&
 234                 (name[len] == '\0' || name[len] == '/')) ||
 235                (*name != '/' && *smbw_cwd != '\0'));
 236 
 237         errno = saved_errno;
 238         return ret;
 239 }
 240 
 241 
 242 /***************************************************** 
 243 remove redundent stuff from a filename
 244 *******************************************************/
 245 void smbw_clean_fname(char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 246 {
 247         char *p, *p2;
 248         int l;
 249         int modified = 1;
 250 
 251         if (!name) return;
 252 
 253         DEBUG(10, ("Clean [%s]...\n", name));
 254 
 255         while (modified) {
 256                 modified = 0;
 257 
 258                 if ((p=strstr(name,"/./"))) {
 259                         modified = 1;
 260                         while (*p) {
 261                                 p[0] = p[2];
 262                                 p++;
 263                         }
 264                         DEBUG(10, ("\tclean 1 (/./) produced [%s]\n", name));
 265                 }
 266 
 267                 if ((p=strstr(name,"//"))) {
 268                         modified = 1;
 269                         while (*p) {
 270                                 p[0] = p[1];
 271                                 p++;
 272                         }
 273                         DEBUG(10, ("\tclean 2 (//) produced [%s]\n", name));
 274                 }
 275 
 276                 if (strcmp(name,"/../")==0) {
 277                         modified = 1;
 278                         name[1] = 0;
 279                         DEBUG(10,("\tclean 3 (^/../$) produced [%s]\n", name));
 280                 }
 281 
 282                 if ((p=strstr(name,"/../"))) {
 283                         modified = 1;
 284                         for (p2 = (p > name ? p-1 : p); p2 > name; p2--) {
 285                                 if (p2[0] == '/') break;
 286                         }
 287                         if (p2 > name) p2++;
 288                         while (*p2) {
 289                                 p2[0] = p[3];
 290                                 p2++;
 291                                 p++;
 292                         }
 293                         DEBUG(10, ("\tclean 4 (/../) produced [%s]\n", name));
 294                 }
 295 
 296                 if (strcmp(name,"/..")==0) {
 297                         modified = 1;
 298                         name[1] = 0;
 299                         DEBUG(10, ("\tclean 5 (^/..$) produced [%s]\n", name));
 300                 }
 301 
 302                 l = strlen(name);
 303                 p = l>=3?(name+l-3):name;
 304                 if (strcmp(p,"/..")==0) {
 305                         modified = 1;
 306                         for (p2=p-1;p2>name;p2--) {
 307                                 if (p2[0] == '/') break;
 308                         }
 309                         if (p2==name) {
 310                                 p[0] = '/';
 311                                 p[1] = 0;
 312                         } else {
 313                                 p2[0] = 0;
 314                         }
 315                         DEBUG(10, ("\tclean 6 (/..) produced [%s]\n", name));
 316                 }
 317 
 318                 l = strlen(name);
 319                 p = l>=2?(name+l-2):name;
 320                 if (strcmp(p,"/.")==0) {
 321                         modified = 1;
 322                         if (p == name) {
 323                                 p[1] = 0;
 324                         } else {
 325                                 p[0] = 0;
 326                         }
 327                         DEBUG(10, ("\tclean 7 (/.) produced [%s]\n", name));
 328                 }
 329 
 330                 if (strncmp(p=name,"./",2) == 0) {      
 331                         modified = 1;
 332                         do {
 333                                 p[0] = p[2];
 334                         } while (*p++);
 335                         DEBUG(10, ("\tclean 8 (^./) produced [%s]\n", name));
 336                 }
 337 
 338                 l = strlen(p=name);
 339                 if (l > 1 && p[l-1] == '/') {
 340                         modified = 1;
 341                         p[l-1] = 0;
 342                         DEBUG(10, ("\tclean 9 (/) produced [%s]\n", name));
 343                 }
 344         }
 345 }
 346 
 347 void smbw_fix_path(const char *src, char *dest)
     /* [<][>][^][v][top][bottom][index][help] */
 348 {
 349         const char *p;
 350         int len = strlen(smbw_prefix);
 351 
 352         if (*src == '/') {
 353                 for (p = src + len; *p == '/'; p++)
 354                         ;
 355                 snprintf(dest, PATH_MAX, "smb://%s", p);
 356         } else {
 357                 snprintf(dest, PATH_MAX, "%s/%s", smbw_cwd, src);
 358         }
 359 
 360         smbw_clean_fname(dest + 5);
 361 
 362         DEBUG(10, ("smbw_fix_path(%s) returning [%s]\n", src, dest));
 363 }
 364 
 365 
 366 
 367 /***************************************************** 
 368 a wrapper for open()
 369 *******************************************************/
 370 int smbw_open(const char *fname, int flags, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
 371 {
 372         int client_fd;
 373         int smbw_fd;
 374         char path[PATH_MAX];
 375 
 376         SMBW_INIT();
 377 
 378         if (!fname) {
 379                 errno = EINVAL;
 380                 return -1;
 381         }
 382 
 383         smbw_fd = (smbw_libc.open)(SMBW_DUMMY, O_WRONLY, 0200);
 384         if (smbw_fd == -1) {
 385                 errno = EMFILE;
 386                 return -1;
 387         }
 388 
 389         smbw_fix_path(fname, path);
 390         if (flags == creat_bits) {
 391                 client_fd =  smbc_creat(path, mode);
 392         } else {
 393                 client_fd = smbc_open(path, flags, mode);
 394         }
 395 
 396         if (client_fd < 0) {
 397                 (* smbw_libc.close)(smbw_fd);
 398                 return -1;
 399         }
 400 
 401         smbw_fd_map[smbw_fd] = client_fd;
 402         smbw_ref(client_fd, SMBW_RCT_Increment);
 403         return smbw_fd;
 404 }
 405 
 406 
 407 /***************************************************** 
 408 a wrapper for pread()
 409 
 410 there should really be an smbc_pread() to avoid the two
 411 lseek()s required in this kludge.
 412 *******************************************************/
 413 ssize_t smbw_pread(int smbw_fd, void *buf, size_t count, SMBW_OFF_T ofs)
     /* [<][>][^][v][top][bottom][index][help] */
 414 {
 415         int client_fd;
 416         ssize_t ret;
 417         int saved_errno;
 418         SMBW_OFF_T old_ofs;
 419         
 420         if (count == 0) {
 421                 return 0;
 422         }
 423 
 424         client_fd = smbw_fd_map[smbw_fd];
 425 
 426         if ((old_ofs = smbc_lseek(client_fd, 0, SEEK_CUR)) < 0 ||
 427             smbc_lseek(client_fd, ofs, SEEK_SET) < 0) {
 428                 return -1;
 429         }
 430 
 431         if ((ret = smbc_read(client_fd, buf, count)) < 0) {
 432                 saved_errno = errno;
 433                 (void) smbc_lseek(client_fd, old_ofs, SEEK_SET);
 434                 errno = saved_errno;
 435                 return -1;
 436         }
 437 
 438         return ret;
 439 }
 440 
 441 /***************************************************** 
 442 a wrapper for read()
 443 *******************************************************/
 444 ssize_t smbw_read(int smbw_fd, void *buf, size_t count)
     /* [<][>][^][v][top][bottom][index][help] */
 445 {
 446         int client_fd;
 447         
 448         client_fd = smbw_fd_map[smbw_fd];
 449 
 450         return smbc_read(client_fd, buf, count);
 451 }
 452 
 453         
 454 
 455 /***************************************************** 
 456 a wrapper for write()
 457 *******************************************************/
 458 ssize_t smbw_write(int smbw_fd, void *buf, size_t count)
     /* [<][>][^][v][top][bottom][index][help] */
 459 {
 460         int client_fd;
 461 
 462         client_fd = smbw_fd_map[smbw_fd];
 463 
 464         return smbc_write(client_fd, buf, count);
 465 }
 466 
 467 /***************************************************** 
 468 a wrapper for pwrite()
 469 *******************************************************/
 470 ssize_t smbw_pwrite(int smbw_fd, void *buf, size_t count, SMBW_OFF_T ofs)
     /* [<][>][^][v][top][bottom][index][help] */
 471 {
 472         int saved_errno;
 473         int client_fd;
 474         ssize_t ret;
 475         SMBW_OFF_T old_ofs;
 476         
 477         if (count == 0) {
 478                 return 0;
 479         }
 480 
 481         client_fd = smbw_fd_map[smbw_fd];
 482 
 483         if ((old_ofs = smbc_lseek(client_fd, 0, SEEK_CUR)) < 0 ||
 484             smbc_lseek(client_fd, ofs, SEEK_SET) < 0) {
 485                 return -1;
 486         }
 487 
 488         if ((ret = smbc_write(client_fd, buf, count)) < 0) {
 489                 saved_errno = errno;
 490                 (void) smbc_lseek(client_fd, old_ofs, SEEK_SET);
 491                 errno = saved_errno;
 492                 return -1;
 493         }
 494 
 495         return ret;
 496 }
 497 
 498 /***************************************************** 
 499 a wrapper for close()
 500 *******************************************************/
 501 int smbw_close(int smbw_fd)
     /* [<][>][^][v][top][bottom][index][help] */
 502 {
 503         int client_fd;
 504 
 505         client_fd = smbw_fd_map[smbw_fd];
 506 
 507         if (smbw_ref(client_fd, SMBW_RCT_Decrement) > 0) {
 508                 return 0;
 509         }
 510         
 511         (* smbw_libc.close)(smbw_fd);
 512         smbw_fd_map[smbw_fd] = -1;
 513         return smbc_close(client_fd);
 514 }
 515 
 516 
 517 /***************************************************** 
 518 a wrapper for fcntl()
 519 *******************************************************/
 520 int smbw_fcntl(int smbw_fd, int cmd, long arg)
     /* [<][>][^][v][top][bottom][index][help] */
 521 {
 522         return 0;
 523 }
 524 
 525 
 526 /***************************************************** 
 527 a wrapper for access()
 528 *******************************************************/
 529 int smbw_access(const char *name, int mode)
     /* [<][>][^][v][top][bottom][index][help] */
 530 {
 531         struct SMBW_stat st;
 532 
 533         SMBW_INIT();
 534 
 535         if (smbw_stat(name, &st)) return -1;
 536 
 537         if (((mode & R_OK) && !(st.s_mode & S_IRUSR)) ||
 538             ((mode & W_OK) && !(st.s_mode & S_IWUSR)) ||
 539             ((mode & X_OK) && !(st.s_mode & S_IXUSR))) {
 540                 errno = EACCES;
 541                 return -1;
 542         }
 543         
 544         return 0;
 545 }
 546 
 547 /***************************************************** 
 548 a wrapper for readlink() - needed for correct errno setting
 549 *******************************************************/
 550 int smbw_readlink(const char *fname, char *buf, size_t bufsize)
     /* [<][>][^][v][top][bottom][index][help] */
 551 {
 552         struct SMBW_stat st;
 553         int ret;
 554 
 555         SMBW_INIT();
 556 
 557         ret = smbw_stat(fname, &st);
 558         if (ret != 0) {
 559                 return -1;
 560         }
 561         
 562         /* it exists - say it isn't a link */
 563         errno = EINVAL;
 564         return -1;
 565 }
 566 
 567 
 568 /***************************************************** 
 569 a wrapper for unlink()
 570 *******************************************************/
 571 int smbw_unlink(const char *fname)
     /* [<][>][^][v][top][bottom][index][help] */
 572 {
 573         char path[PATH_MAX];
 574         
 575         SMBW_INIT();
 576 
 577         smbw_fix_path(fname, path);
 578         return smbc_unlink(path);
 579 }
 580 
 581 
 582 /***************************************************** 
 583 a wrapper for rename()
 584 *******************************************************/
 585 int smbw_rename(const char *oldname, const char *newname)
     /* [<][>][^][v][top][bottom][index][help] */
 586 {
 587         char path_old[PATH_MAX];
 588         char path_new[PATH_MAX];
 589 
 590         SMBW_INIT();
 591 
 592         smbw_fix_path(oldname, path_old);
 593         smbw_fix_path(newname, path_new);
 594         return smbc_rename(path_old, path_new);
 595 }
 596 
 597 
 598 /***************************************************** 
 599 a wrapper for utimes
 600 *******************************************************/
 601 int smbw_utimes(const char *fname, void *buf)
     /* [<][>][^][v][top][bottom][index][help] */
 602 {
 603         char path[PATH_MAX];
 604 
 605         smbw_fix_path(fname, path);
 606         return smbc_utimes(path, buf);
 607 }
 608 
 609 
 610 /***************************************************** 
 611 a wrapper for utime 
 612 *******************************************************/
 613 int smbw_utime(const char *fname, void *buf)
     /* [<][>][^][v][top][bottom][index][help] */
 614 {
 615         char path[PATH_MAX];
 616 
 617         smbw_fix_path(fname, path);
 618         return smbc_utime(path, buf);
 619 }
 620 
 621 /***************************************************** 
 622 a wrapper for chown()
 623 *******************************************************/
 624 int smbw_chown(const char *fname, uid_t owner, gid_t group)
     /* [<][>][^][v][top][bottom][index][help] */
 625 {
 626         /* always indiciate that this is not supported. */
 627         errno = ENOTSUP;
 628         return -1;
 629 }
 630 
 631 /***************************************************** 
 632 a wrapper for chmod()
 633 *******************************************************/
 634 int smbw_chmod(const char *fname, mode_t newmode)
     /* [<][>][^][v][top][bottom][index][help] */
 635 {
 636         char path[PATH_MAX];
 637 
 638         smbw_fix_path(fname, path);
 639         return smbc_chmod(path, newmode);
 640 }
 641 
 642 
 643 /***************************************************** 
 644 a wrapper for lseek()
 645 *******************************************************/
 646 SMBW_OFF_T smbw_lseek(int smbw_fd,
     /* [<][>][^][v][top][bottom][index][help] */
 647                       SMBW_OFF_T offset,
 648                       int whence)
 649 {
 650         int client_fd;
 651         SMBW_OFF_T ret;
 652         
 653         client_fd = smbw_fd_map[smbw_fd];
 654 
 655         ret = smbc_lseek(client_fd, offset, whence);
 656         if (smbw_debug)
 657         {
 658                 printf("smbw_lseek(%d/%d, 0x%llx) returned 0x%llx\n",
 659                        smbw_fd, client_fd,
 660                        (unsigned long long) offset,
 661                        (unsigned long long) ret);
 662         }
 663         return ret;
 664 }
 665 
 666 /***************************************************** 
 667 a wrapper for dup()
 668 *******************************************************/
 669 int smbw_dup(int smbw_fd)
     /* [<][>][^][v][top][bottom][index][help] */
 670 {
 671         int fd2;
 672 
 673         fd2 = (smbw_libc.dup)(smbw_fd);
 674         if (fd2 == -1) {
 675                 return -1;
 676         }
 677 
 678         smbw_fd_map[fd2] = smbw_fd_map[smbw_fd];
 679         smbw_ref(smbw_fd_map[smbw_fd], SMBW_RCT_Increment);
 680         return fd2;
 681 }
 682 
 683 
 684 /***************************************************** 
 685 a wrapper for dup2()
 686 *******************************************************/
 687 int smbw_dup2(int smbw_fd, int fd2)
     /* [<][>][^][v][top][bottom][index][help] */
 688 {
 689         if ((* smbw_libc.dup2)(smbw_fd, fd2) != fd2) {
 690                 return -1;
 691         }
 692 
 693         smbw_fd_map[fd2] = smbw_fd_map[smbw_fd];
 694         smbw_ref(smbw_fd_map[smbw_fd], SMBW_RCT_Increment);
 695         return fd2;
 696 }
 697 
 698 
 699 /***************************************************** 
 700 when we fork we have to close all connections and files
 701 in the child
 702 *******************************************************/
 703 int smbw_fork(void)
     /* [<][>][^][v][top][bottom][index][help] */
 704 {
 705         int i;
 706         pid_t child_pid;
 707         int p[2];
 708         char c = 0;
 709 
 710         SMBW_INIT();
 711 
 712         if (pipe(p)) return (* smbw_libc.fork)();
 713 
 714         child_pid = (* smbw_libc.fork)();
 715 
 716         if (child_pid) {
 717                 /* block the parent for a moment until the sockets are
 718                    closed */
 719                 (* smbw_libc.close)(p[1]);
 720                 (* smbw_libc.read)(p[0], &c, 1);
 721                 (* smbw_libc.close)(p[0]);
 722                 return child_pid;
 723         }
 724 
 725         (* smbw_libc.close)(p[0]);
 726 
 727         /* close all server connections and locally-opened files */
 728         for (i = 0; i < __FD_SETSIZE; i++) {
 729                 if (smbw_fd_map[i] > 0 &&
 730                     smbw_ref(smbw_fd_map[i], SMBW_RCT_Get) > 0) {
 731                         
 732                         smbc_close(smbw_fd_map[i]);
 733                         smbw_ref(smbw_fd_map[i], SMBW_RCT_Set, 0);
 734                         (* smbw_libc.close)(i);
 735                 }
 736 
 737                 smbw_fd_map[i] = -1;
 738         }
 739 
 740         /* unblock the parent */
 741         write(p[1], &c, 1);
 742         (* smbw_libc.close)(p[1]);
 743 
 744         /* specify directory to start in, if it's simulated smb */
 745         if (*smbw_cwd != '\0') {
 746                 setenv("SMBW_DIR", smbw_cwd, 1);
 747         } else {
 748                 unsetenv("SMBW_DIR");
 749         }
 750 
 751         /* Re-initialize this library for the child */
 752         do_init(StartupType_Fake);
 753 
 754         /* and continue in the child */
 755         return 0;
 756 }
 757 
 758 int smbw_setxattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
 759                   const char *name,
 760                   const void *value,
 761                   size_t size,
 762                   int flags)
 763 {
 764         char path[PATH_MAX];
 765 
 766         if (strcmp(name, "system.posix_acl_access") == 0)
 767         {
 768                 name = "system.*";
 769         }
 770 
 771         smbw_fix_path(fname, path);
 772         return smbc_setxattr(path, name, value, size, flags);
 773 }
 774 
 775 int smbw_lsetxattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
 776                    const char *name,
 777                    const void *value,
 778                    size_t size,
 779                    int flags)
 780 {
 781         char path[PATH_MAX];
 782 
 783         if (strcmp(name, "system.posix_acl_access") == 0)
 784         {
 785                 name = "system.*";
 786         }
 787 
 788         smbw_fix_path(fname, path);
 789         return smbc_lsetxattr(path, name, value, size, flags);
 790 }
 791 
 792 int smbw_fsetxattr(int smbw_fd,
     /* [<][>][^][v][top][bottom][index][help] */
 793                    const char *name,
 794                    const void *value,
 795                    size_t size,
 796                    int flags)
 797 {
 798         int client_fd;
 799         
 800         if (strcmp(name, "system.posix_acl_access") == 0)
 801         {
 802                 name = "system.*";
 803         }
 804 
 805         client_fd = smbw_fd_map[smbw_fd];
 806         return smbc_fsetxattr(client_fd, name, value, size, flags);
 807 }
 808 
 809 int smbw_getxattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
 810                   const char *name,
 811                   const void *value,
 812                   size_t size)
 813 {
 814         char path[PATH_MAX];
 815 
 816         if (strcmp(name, "system.posix_acl_access") == 0)
 817         {
 818                 name = "system.*";
 819         }
 820 
 821         smbw_fix_path(fname, path);
 822 
 823         return smbc_getxattr(path, name, value, size);
 824 }
 825 
 826 int smbw_lgetxattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
 827                    const char *name,
 828                    const void *value,
 829                    size_t size)
 830 {
 831         char path[PATH_MAX];
 832 
 833         if (strcmp(name, "system.posix_acl_access") == 0)
 834         {
 835                 name = "system.*";
 836         }
 837 
 838         smbw_fix_path(fname, path);
 839         return smbc_lgetxattr(path, name, value, size);
 840 }
 841 
 842 int smbw_fgetxattr(int smbw_fd,
     /* [<][>][^][v][top][bottom][index][help] */
 843                    const char *name,
 844                    const void *value,
 845                    size_t size)
 846 {
 847         int client_fd;
 848         
 849         if (strcmp(name, "system.posix_acl_access") == 0)
 850         {
 851                 name = "system.*";
 852         }
 853 
 854         client_fd = smbw_fd_map[smbw_fd];
 855         return smbc_fgetxattr(client_fd, name, value, size);
 856 }
 857 
 858 int smbw_removexattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
 859                      const char *name)
 860 {
 861         char path[PATH_MAX];
 862 
 863         if (strcmp(name, "system.posix_acl_access") == 0)
 864         {
 865                 name = "system.*";
 866         }
 867 
 868         smbw_fix_path(fname, path);
 869         return smbc_removexattr(path, name);
 870 }
 871 
 872 int smbw_lremovexattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
 873                       const char *name)
 874 {
 875         char path[PATH_MAX];
 876 
 877         if (strcmp(name, "system.posix_acl_access") == 0)
 878         {
 879                 name = "system.*";
 880         }
 881 
 882         smbw_fix_path(fname, path);
 883         return smbc_lremovexattr(path, name);
 884 }
 885 
 886 int smbw_fremovexattr(int smbw_fd,
     /* [<][>][^][v][top][bottom][index][help] */
 887                       const char *name)
 888 {
 889         int client_fd;
 890         
 891         if (strcmp(name, "system.posix_acl_access") == 0)
 892         {
 893                 name = "system.*";
 894         }
 895 
 896         client_fd = smbw_fd_map[smbw_fd];
 897         return smbc_fremovexattr(client_fd, name);
 898 }
 899 
 900 int smbw_listxattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
 901                    char *list,
 902                    size_t size)
 903 {
 904         char path[PATH_MAX];
 905 
 906         smbw_fix_path(fname, path);
 907         return smbc_listxattr(path, list, size);
 908 }
 909 
 910 int smbw_llistxattr(const char *fname,
     /* [<][>][^][v][top][bottom][index][help] */
 911                     char *list,
 912                     size_t size)
 913 {
 914         char path[PATH_MAX];
 915 
 916         smbw_fix_path(fname, path);
 917         return smbc_llistxattr(path, list, size);
 918 }
 919 
 920 int smbw_flistxattr(int smbw_fd,
     /* [<][>][^][v][top][bottom][index][help] */
 921                     char *list,
 922                     size_t size)
 923 {
 924         int client_fd;
 925         
 926         client_fd = smbw_fd_map[smbw_fd];
 927         return smbc_flistxattr(client_fd, list, size);
 928 }

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