~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to examples/libsmbclient/smbwrapper/smbw.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

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