~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

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

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

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 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, ...)
 
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, 
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
521
{
 
522
        return 0;
 
523
}
 
524
 
 
525
 
 
526
/***************************************************** 
 
527
a wrapper for access()
 
528
*******************************************************/
 
529
int smbw_access(const char *name, int mode)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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)
 
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,
 
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)
 
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)
 
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)
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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,
 
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
}