s3:wscript_build - fix TDB dependency for source3/lib/util.c
[nivanova/samba-autobuild/.git] / source3 / libsmb / libsmb_compat.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB client library implementation (Old interface compatibility)
4    Copyright (C) Andrew Tridgell 1998
5    Copyright (C) Richard Sharpe 2000
6    Copyright (C) John Terpstra 2000
7    Copyright (C) Tom Jansen (Ninja ISD) 2002 
8    Copyright (C) Derrell Lipman 2003, 2008
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24
25 #include "includes.h"
26 #include "libsmb_internal.h"
27
28 struct smbc_compat_fdlist {
29         SMBCFILE * file;
30         int fd;
31         struct smbc_compat_fdlist *next, *prev;
32 };
33
34 static SMBCCTX * statcont = NULL;
35 static int smbc_compat_initialized = 0;
36 static int smbc_compat_nextfd = 0;
37 static struct smbc_compat_fdlist * smbc_compat_fd_in_use = NULL;
38 static struct smbc_compat_fdlist * smbc_compat_fd_avail = NULL;
39
40 /* Find an fd and return the SMBCFILE * or NULL on failure */
41 static SMBCFILE *
42 find_fd(int fd)
43 {
44         struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
45         while (f) {
46                 if (f->fd == fd) 
47                         return f->file;
48                 f = f->next;
49         }
50         return NULL;
51 }
52
53 /* Add an fd, returns 0 on success, -1 on error with errno set */
54 static int
55 add_fd(SMBCFILE * file)
56 {
57         struct smbc_compat_fdlist * f = smbc_compat_fd_avail;
58
59         if (f) {
60                 /* We found one that's available */
61                 DLIST_REMOVE(smbc_compat_fd_avail, f);
62         } else {
63                 /*
64                  * None were available, so allocate one.  Keep the number of
65                  * file descriptors determinate.  This allows the application
66                  * to allocate bitmaps or mapping of file descriptors based on
67                  * a known maximum number of file descriptors that will ever
68                  * be returned.
69                  */
70                 if (smbc_compat_nextfd >= FD_SETSIZE) {
71                         errno = EMFILE;
72                         return -1;
73                 }
74
75                 f = SMB_MALLOC_P(struct smbc_compat_fdlist);
76                 if (!f) {
77                         errno = ENOMEM;
78                         return -1;
79                 }
80
81                 f->fd = SMBC_BASE_FD + smbc_compat_nextfd++;
82         }
83
84         f->file = file;
85         DLIST_ADD(smbc_compat_fd_in_use, f);
86
87         return f->fd;
88 }
89
90
91
92 /* Delete an fd, returns 0 on success */
93 static int
94 del_fd(int fd)
95 {
96         struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
97
98         while (f) {
99                 if (f->fd == fd) 
100                         break;
101                 f = f->next;
102         }
103
104         if (f) {
105                 /* found */
106                 DLIST_REMOVE(smbc_compat_fd_in_use, f);
107                 f->file = NULL;
108                 DLIST_ADD(smbc_compat_fd_avail, f);
109                 return 0;
110         }
111         return 1;
112 }
113
114
115
116 int
117 smbc_init(smbc_get_auth_data_fn fn,
118           int debug)
119 {
120         if (!smbc_compat_initialized) {
121                 statcont = smbc_new_context();
122                 if (!statcont) 
123                         return -1;
124
125                 smbc_setDebug(statcont, debug);
126                 smbc_setFunctionAuthData(statcont, fn);
127
128                 if (!smbc_init_context(statcont)) {
129                         smbc_free_context(statcont, False);
130                         return -1;
131                 }
132
133                 smbc_compat_initialized = 1;
134
135                 return 0;
136         }
137         return 0;
138 }
139
140
141 SMBCCTX *
142 smbc_set_context(SMBCCTX * context)
143 {
144         SMBCCTX *old_context = statcont;
145
146         if (context) {
147                 /* Save provided context.  It must have been initialized! */
148                 statcont = context;
149
150                 /* You'd better know what you're doing.  We won't help you. */
151                 smbc_compat_initialized = 1;
152         }
153
154         return old_context;
155 }
156
157
158 int
159 smbc_open(const char *furl,
160           int flags,
161           mode_t mode)
162 {
163         SMBCFILE * file;
164         int fd;
165
166         file = smbc_getFunctionOpen(statcont)(statcont, furl, flags, mode);
167         if (!file)
168                 return -1;
169
170         fd = add_fd(file);
171         if (fd == -1) 
172                 smbc_getFunctionClose(statcont)(statcont, file);
173         return fd;
174 }
175
176
177 int
178 smbc_creat(const char *furl,
179            mode_t mode)
180 {
181         SMBCFILE * file;
182         int fd;
183
184         file = smbc_getFunctionCreat(statcont)(statcont, furl, mode);
185         if (!file)
186                 return -1;
187
188         fd = add_fd(file);
189         if (fd == -1) {
190                 /* Hmm... should we delete the file too ? I guess we could try */
191                 smbc_getFunctionClose(statcont)(statcont, file);
192                 smbc_getFunctionUnlink(statcont)(statcont, furl);
193         }
194         return fd;
195 }
196
197
198 ssize_t
199 smbc_read(int fd,
200           void *buf,
201           size_t bufsize)
202 {
203         SMBCFILE * file = find_fd(fd);
204         return smbc_getFunctionRead(statcont)(statcont, file, buf, bufsize);
205 }
206
207 ssize_t
208 smbc_write(int fd,
209            const void *buf,
210            size_t bufsize)
211 {
212         SMBCFILE * file = find_fd(fd);
213         return smbc_getFunctionWrite(statcont)(statcont, file, buf, bufsize);
214 }
215
216 off_t
217 smbc_lseek(int fd,
218            off_t offset,
219            int whence)
220 {
221         SMBCFILE * file = find_fd(fd);
222         return smbc_getFunctionLseek(statcont)(statcont, file, offset, whence);
223 }
224
225 int
226 smbc_close(int fd)
227 {
228         SMBCFILE * file = find_fd(fd);
229         del_fd(fd);
230         return smbc_getFunctionClose(statcont)(statcont, file);
231 }
232
233 int
234 smbc_unlink(const char *fname)
235 {
236         return smbc_getFunctionUnlink(statcont)(statcont, fname);
237 }
238
239 int
240 smbc_rename(const char *ourl,
241             const char *nurl)
242 {
243         return smbc_getFunctionRename(statcont)(statcont, ourl,
244                                                 statcont, nurl);
245 }
246
247 int
248 smbc_opendir(const char *durl)
249 {
250         SMBCFILE * file;
251         int fd;
252
253         file = smbc_getFunctionOpendir(statcont)(statcont, durl);
254         if (!file)
255                 return -1;
256
257         fd = add_fd(file);
258         if (fd == -1) 
259                 smbc_getFunctionClosedir(statcont)(statcont, file);
260
261         return fd;
262 }
263
264 int
265 smbc_closedir(int dh) 
266 {
267         SMBCFILE * file = find_fd(dh);
268         del_fd(dh);
269         return smbc_getFunctionClosedir(statcont)(statcont, file);
270 }
271
272 int
273 smbc_getdents(unsigned int dh,
274               struct smbc_dirent *dirp,
275               int count)
276 {
277         SMBCFILE * file = find_fd(dh);
278         return smbc_getFunctionGetdents(statcont)(statcont, file, dirp, count);
279 }
280
281 struct smbc_dirent *
282 smbc_readdir(unsigned int dh)
283 {
284         SMBCFILE * file = find_fd(dh);
285         return smbc_getFunctionReaddir(statcont)(statcont, file);
286 }
287
288 off_t
289 smbc_telldir(int dh)
290 {
291         SMBCFILE * file = find_fd(dh);
292         return smbc_getFunctionTelldir(statcont)(statcont, file);
293 }
294
295 int
296 smbc_lseekdir(int fd,
297               off_t offset)
298 {
299         SMBCFILE * file = find_fd(fd);
300         return smbc_getFunctionLseekdir(statcont)(statcont, file, offset);
301 }
302
303 int
304 smbc_mkdir(const char *durl,
305            mode_t mode)
306 {
307         return smbc_getFunctionMkdir(statcont)(statcont, durl, mode);
308 }
309
310 int
311 smbc_rmdir(const char *durl)
312 {
313         return smbc_getFunctionRmdir(statcont)(statcont, durl);
314 }
315
316 int
317 smbc_stat(const char *url,
318           struct stat *st)
319 {
320         return smbc_getFunctionStat(statcont)(statcont, url, st);
321 }
322
323 int
324 smbc_fstat(int fd,
325            struct stat *st)
326 {
327         SMBCFILE * file = find_fd(fd);
328         return smbc_getFunctionFstat(statcont)(statcont, file, st);
329 }
330
331 int
332 smbc_statvfs(char *path,
333              struct statvfs *st)
334 {
335         return smbc_getFunctionStatVFS(statcont)(statcont, path, st);
336 }
337
338 int
339 smbc_fstatvfs(int fd,
340               struct statvfs *st)
341 {
342         SMBCFILE * file = find_fd(fd);
343         return smbc_getFunctionFstatVFS(statcont)(statcont, file, st);
344 }
345
346 int
347 smbc_ftruncate(int fd,
348                off_t size)
349 {
350         SMBCFILE * file = find_fd(fd);
351         return smbc_getFunctionFtruncate(statcont)(statcont, file, size);
352 }
353
354 int
355 smbc_chmod(const char *url,
356            mode_t mode)
357 {
358         return smbc_getFunctionChmod(statcont)(statcont, url, mode);
359 }
360
361 int
362 smbc_utimes(const char *fname,
363             struct timeval *tbuf)
364 {
365         return smbc_getFunctionUtimes(statcont)(statcont, fname, tbuf);
366 }
367
368 #ifdef HAVE_UTIME_H
369 int
370 smbc_utime(const char *fname,
371            struct utimbuf *utbuf)
372 {
373         struct timeval tv[2];
374
375         if (utbuf == NULL)
376                 return smbc_getFunctionUtimes(statcont)(statcont, fname, NULL);
377
378         tv[0].tv_sec = utbuf->actime;
379         tv[1].tv_sec = utbuf->modtime;
380         tv[0].tv_usec = tv[1].tv_usec = 0;
381
382         return smbc_getFunctionUtimes(statcont)(statcont, fname, tv);
383 }
384 #endif
385
386 int
387 smbc_setxattr(const char *fname,
388               const char *name,
389               const void *value,
390               size_t size,
391               int flags)
392 {
393         return smbc_getFunctionSetxattr(statcont)(statcont,
394                                                   fname, name,
395                                                   value, size, flags);
396 }
397
398 int
399 smbc_lsetxattr(const char *fname,
400                const char *name,
401                const void *value,
402                size_t size,
403                int flags)
404 {
405         return smbc_getFunctionSetxattr(statcont)(statcont,
406                                                   fname, name,
407                                                   value, size, flags);
408 }
409
410 int
411 smbc_fsetxattr(int fd,
412                const char *name,
413                const void *value,
414                size_t size,
415                int flags)
416 {
417         SMBCFILE * file = find_fd(fd);
418         if (file == NULL) {
419                 errno = EBADF;
420                 return -1;
421         }
422         return smbc_getFunctionSetxattr(statcont)(statcont,
423                                                   file->fname, name,
424                                                   value, size, flags);
425 }
426
427 int
428 smbc_getxattr(const char *fname,
429               const char *name,
430               const void *value,
431               size_t size)
432 {
433         return smbc_getFunctionGetxattr(statcont)(statcont,
434                                                   fname, name,
435                                                   value, size);
436 }
437
438 int
439 smbc_lgetxattr(const char *fname,
440                const char *name,
441                const void *value,
442                size_t size)
443 {
444         return smbc_getFunctionGetxattr(statcont)(statcont,
445                                                   fname, name,
446                                                   value, size);
447 }
448
449 int
450 smbc_fgetxattr(int fd,
451                const char *name,
452                const void *value,
453                size_t size)
454 {
455         SMBCFILE * file = find_fd(fd);
456         if (file == NULL) {
457                 errno = EBADF;
458                 return -1;
459         }
460         return smbc_getFunctionGetxattr(statcont)(statcont,
461                                                   file->fname, name,
462                                                   value, size);
463 }
464
465 int
466 smbc_removexattr(const char *fname,
467                  const char *name)
468 {
469         return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name);
470 }
471
472 int
473 smbc_lremovexattr(const char *fname,
474                   const char *name)
475 {
476         return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name);
477 }
478
479 int
480 smbc_fremovexattr(int fd,
481                   const char *name)
482 {
483         SMBCFILE * file = find_fd(fd);
484         if (file == NULL) {
485                 errno = EBADF;
486                 return -1;
487         }
488         return smbc_getFunctionRemovexattr(statcont)(statcont,
489                                                      file->fname, name);
490 }
491
492 int
493 smbc_listxattr(const char *fname,
494                char *list,
495                size_t size)
496 {
497         return smbc_getFunctionListxattr(statcont)(statcont,
498                                                    fname, list, size);
499 }
500
501 int
502 smbc_llistxattr(const char *fname,
503                 char *list,
504                 size_t size)
505 {
506         return smbc_getFunctionListxattr(statcont)(statcont,
507                                                    fname, list, size);
508 }
509
510 int
511 smbc_flistxattr(int fd,
512                 char *list,
513                 size_t size)
514 {
515         SMBCFILE * file = find_fd(fd);
516         if (file == NULL) {
517                 errno = EBADF;
518                 return -1;
519         }
520         return smbc_getFunctionListxattr(statcont)(statcont,
521                                                    file->fname, list, size);
522 }
523
524 int
525 smbc_print_file(const char *fname,
526                 const char *printq)
527 {
528         return smbc_getFunctionPrintFile(statcont)(statcont, fname,
529                                                    statcont, printq);
530 }
531
532 int
533 smbc_open_print_job(const char *fname)
534 {
535         SMBCFILE * file;
536
537         file = smbc_getFunctionOpenPrintJob(statcont)(statcont, fname);
538         if (!file) return -1;
539         return file->cli_fd;
540 }
541
542 int
543 smbc_list_print_jobs(const char *purl,
544                      smbc_list_print_job_fn fn)
545 {
546         return smbc_getFunctionListPrintJobs(statcont)(statcont, purl, fn);
547 }
548
549 int
550 smbc_unlink_print_job(const char *purl,
551                       int id)
552 {
553         return smbc_getFunctionUnlinkPrintJob(statcont)(statcont, purl, id);
554 }
555
556