tests: Check symlinks are readable as reparse points
[samba.git] / source3 / libsmb / libsmb_compat.c
blob465bb3c70ee4f0cf69413e8db261e7cd445663a7
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
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.
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.
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/>.
25 #include "includes.h"
26 #include "libsmb_internal.h"
28 struct smbc_compat_fdlist {
29 SMBCFILE * file;
30 int fd;
31 struct smbc_compat_fdlist *next, *prev;
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;
40 /* Find an fd and return the SMBCFILE * or NULL on failure */
41 static SMBCFILE *
42 find_fd(int fd)
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;
50 return NULL;
53 /* Add an fd, returns 0 on success, -1 on error with errno set */
54 static int
55 add_fd(SMBCFILE * file)
57 struct smbc_compat_fdlist * f = smbc_compat_fd_avail;
59 if (f) {
60 /* We found one that's available */
61 DLIST_REMOVE(smbc_compat_fd_avail, f);
62 } else {
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.
70 if (smbc_compat_nextfd >= FD_SETSIZE) {
71 errno = EMFILE;
72 return -1;
75 f = SMB_MALLOC_P(struct smbc_compat_fdlist);
76 if (!f) {
77 errno = ENOMEM;
78 return -1;
81 f->fd = SMBC_BASE_FD + smbc_compat_nextfd++;
84 f->file = file;
85 DLIST_ADD(smbc_compat_fd_in_use, f);
87 return f->fd;
92 /* Delete an fd, returns 0 on success */
93 static int
94 del_fd(int fd)
96 struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
98 while (f) {
99 if (f->fd == fd)
100 break;
101 f = f->next;
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;
111 return 1;
117 smbc_init(smbc_get_auth_data_fn fn,
118 int debug)
120 if (smbc_compat_initialized) {
121 return 0;
124 statcont = smbc_new_context();
125 if (!statcont)
126 return -1;
128 smbc_setDebug(statcont, debug);
129 smbc_setFunctionAuthData(statcont, fn);
131 if (!smbc_init_context(statcont)) {
132 smbc_free_context(statcont, False);
133 return -1;
136 smbc_compat_initialized = 1;
138 return 0;
142 SMBCCTX *
143 smbc_set_context(SMBCCTX * context)
145 SMBCCTX *old_context = statcont;
147 if (context) {
148 /* Save provided context. It must have been initialized! */
149 statcont = context;
151 /* You'd better know what you're doing. We won't help you. */
152 smbc_compat_initialized = 1;
155 return old_context;
160 smbc_open(const char *furl,
161 int flags,
162 mode_t mode)
164 SMBCFILE * file;
165 int fd;
167 file = smbc_getFunctionOpen(statcont)(statcont, furl, flags, mode);
168 if (!file)
169 return -1;
171 fd = add_fd(file);
172 if (fd == -1)
173 smbc_getFunctionClose(statcont)(statcont, file);
174 return fd;
179 smbc_creat(const char *furl,
180 mode_t mode)
182 SMBCFILE * file;
183 int fd;
185 file = smbc_getFunctionCreat(statcont)(statcont, furl, mode);
186 if (!file)
187 return -1;
189 fd = add_fd(file);
190 if (fd == -1) {
191 /* Hmm... should we delete the file too ? I guess we could try */
192 smbc_getFunctionClose(statcont)(statcont, file);
193 smbc_getFunctionUnlink(statcont)(statcont, furl);
195 return fd;
199 ssize_t
200 smbc_read(int fd,
201 void *buf,
202 size_t bufsize)
204 SMBCFILE * file = find_fd(fd);
205 return smbc_getFunctionRead(statcont)(statcont, file, buf, bufsize);
208 ssize_t
209 smbc_write(int fd,
210 const void *buf,
211 size_t bufsize)
213 SMBCFILE * file = find_fd(fd);
214 return smbc_getFunctionWrite(statcont)(statcont, file, buf, bufsize);
217 off_t
218 smbc_lseek(int fd,
219 off_t offset,
220 int whence)
222 SMBCFILE * file = find_fd(fd);
223 return smbc_getFunctionLseek(statcont)(statcont, file, offset, whence);
227 smbc_close(int fd)
229 SMBCFILE * file = find_fd(fd);
230 del_fd(fd);
231 return smbc_getFunctionClose(statcont)(statcont, file);
235 smbc_unlink(const char *fname)
237 return smbc_getFunctionUnlink(statcont)(statcont, fname);
241 smbc_rename(const char *ourl,
242 const char *nurl)
244 return smbc_getFunctionRename(statcont)(statcont, ourl,
245 statcont, nurl);
249 smbc_opendir(const char *durl)
251 SMBCFILE * file;
252 int fd;
254 file = smbc_getFunctionOpendir(statcont)(statcont, durl);
255 if (!file)
256 return -1;
258 fd = add_fd(file);
259 if (fd == -1)
260 smbc_getFunctionClosedir(statcont)(statcont, file);
262 return fd;
266 smbc_closedir(int dh)
268 SMBCFILE * file = find_fd(dh);
269 del_fd(dh);
270 return smbc_getFunctionClosedir(statcont)(statcont, file);
274 smbc_getdents(unsigned int dh,
275 struct smbc_dirent *dirp,
276 int count)
278 SMBCFILE * file = find_fd(dh);
279 return smbc_getFunctionGetdents(statcont)(statcont, file, dirp, count);
282 struct smbc_dirent *
283 smbc_readdir(unsigned int dh)
285 SMBCFILE * file = find_fd(dh);
286 return smbc_getFunctionReaddir(statcont)(statcont, file);
289 const struct libsmb_file_info *smbc_readdirplus(unsigned int dh)
291 SMBCFILE * file = find_fd(dh);
292 return smbc_getFunctionReaddirPlus(statcont)(statcont, file);
295 const struct libsmb_file_info *smbc_readdirplus2(unsigned int dh,
296 struct stat *st)
298 SMBCFILE *file = find_fd(dh);
299 return smbc_getFunctionReaddirPlus2(statcont)(statcont, file, st);
302 off_t
303 smbc_telldir(int dh)
305 SMBCFILE * file = find_fd(dh);
306 return smbc_getFunctionTelldir(statcont)(statcont, file);
310 smbc_lseekdir(int fd,
311 off_t offset)
313 SMBCFILE * file = find_fd(fd);
314 return smbc_getFunctionLseekdir(statcont)(statcont, file, offset);
318 smbc_mkdir(const char *durl,
319 mode_t mode)
321 return smbc_getFunctionMkdir(statcont)(statcont, durl, mode);
325 smbc_rmdir(const char *durl)
327 return smbc_getFunctionRmdir(statcont)(statcont, durl);
331 smbc_notify(int dh, smbc_bool recursive, uint32_t completion_filter,
332 unsigned callback_timeout_ms,
333 smbc_notify_callback_fn cb, void *private_data)
335 SMBCFILE *dir = find_fd(dh);
336 return smbc_getFunctionNotify(statcont)(
337 statcont, dir, recursive, completion_filter,
338 callback_timeout_ms, cb, private_data);
342 smbc_stat(const char *url,
343 struct stat *st)
345 return smbc_getFunctionStat(statcont)(statcont, url, st);
349 smbc_fstat(int fd,
350 struct stat *st)
352 SMBCFILE * file = find_fd(fd);
353 return smbc_getFunctionFstat(statcont)(statcont, file, st);
357 smbc_statvfs(char *path,
358 struct statvfs *st)
360 return smbc_getFunctionStatVFS(statcont)(statcont, path, st);
364 smbc_fstatvfs(int fd,
365 struct statvfs *st)
367 SMBCFILE * file = find_fd(fd);
368 return smbc_getFunctionFstatVFS(statcont)(statcont, file, st);
372 smbc_ftruncate(int fd,
373 off_t size)
375 SMBCFILE * file = find_fd(fd);
376 return smbc_getFunctionFtruncate(statcont)(statcont, file, size);
380 smbc_chmod(const char *url,
381 mode_t mode)
383 return smbc_getFunctionChmod(statcont)(statcont, url, mode);
387 smbc_utimes(const char *fname,
388 struct timeval *tbuf)
390 return smbc_getFunctionUtimes(statcont)(statcont, fname, tbuf);
393 #ifdef HAVE_UTIME_H
395 smbc_utime(const char *fname,
396 struct utimbuf *utbuf)
398 struct timeval tv[2];
400 if (utbuf == NULL)
401 return smbc_getFunctionUtimes(statcont)(statcont, fname, NULL);
403 tv[0].tv_sec = utbuf->actime;
404 tv[1].tv_sec = utbuf->modtime;
405 tv[0].tv_usec = tv[1].tv_usec = 0;
407 return smbc_getFunctionUtimes(statcont)(statcont, fname, tv);
409 #endif
412 smbc_setxattr(const char *fname,
413 const char *name,
414 const void *value,
415 size_t size,
416 int flags)
418 return smbc_getFunctionSetxattr(statcont)(statcont,
419 fname, name,
420 value, size, flags);
424 smbc_lsetxattr(const char *fname,
425 const char *name,
426 const void *value,
427 size_t size,
428 int flags)
430 return smbc_getFunctionSetxattr(statcont)(statcont,
431 fname, name,
432 value, size, flags);
436 smbc_fsetxattr(int fd,
437 const char *name,
438 const void *value,
439 size_t size,
440 int flags)
442 SMBCFILE * file = find_fd(fd);
443 if (file == NULL) {
444 errno = EBADF;
445 return -1;
447 return smbc_getFunctionSetxattr(statcont)(statcont,
448 file->fname, name,
449 value, size, flags);
453 smbc_getxattr(const char *fname,
454 const char *name,
455 const void *value,
456 size_t size)
458 return smbc_getFunctionGetxattr(statcont)(statcont,
459 fname, name,
460 value, size);
464 smbc_lgetxattr(const char *fname,
465 const char *name,
466 const void *value,
467 size_t size)
469 return smbc_getFunctionGetxattr(statcont)(statcont,
470 fname, name,
471 value, size);
475 smbc_fgetxattr(int fd,
476 const char *name,
477 const void *value,
478 size_t size)
480 SMBCFILE * file = find_fd(fd);
481 if (file == NULL) {
482 errno = EBADF;
483 return -1;
485 return smbc_getFunctionGetxattr(statcont)(statcont,
486 file->fname, name,
487 value, size);
491 smbc_removexattr(const char *fname,
492 const char *name)
494 return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name);
498 smbc_lremovexattr(const char *fname,
499 const char *name)
501 return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name);
505 smbc_fremovexattr(int fd,
506 const char *name)
508 SMBCFILE * file = find_fd(fd);
509 if (file == NULL) {
510 errno = EBADF;
511 return -1;
513 return smbc_getFunctionRemovexattr(statcont)(statcont,
514 file->fname, name);
518 smbc_listxattr(const char *fname,
519 char *list,
520 size_t size)
522 return smbc_getFunctionListxattr(statcont)(statcont,
523 fname, list, size);
527 smbc_llistxattr(const char *fname,
528 char *list,
529 size_t size)
531 return smbc_getFunctionListxattr(statcont)(statcont,
532 fname, list, size);
536 smbc_flistxattr(int fd,
537 char *list,
538 size_t size)
540 SMBCFILE * file = find_fd(fd);
541 if (file == NULL) {
542 errno = EBADF;
543 return -1;
545 return smbc_getFunctionListxattr(statcont)(statcont,
546 file->fname, list, size);
550 smbc_print_file(const char *fname,
551 const char *printq)
553 return smbc_getFunctionPrintFile(statcont)(statcont, fname,
554 statcont, printq);
558 smbc_open_print_job(const char *fname)
560 SMBCFILE * file;
562 file = smbc_getFunctionOpenPrintJob(statcont)(statcont, fname);
563 if (!file) return -1;
564 return file->cli_fd;
568 smbc_list_print_jobs(const char *purl,
569 smbc_list_print_job_fn fn)
571 return smbc_getFunctionListPrintJobs(statcont)(statcont, purl, fn);
575 smbc_unlink_print_job(const char *purl,
576 int id)
578 return smbc_getFunctionUnlinkPrintJob(statcont)(statcont, purl, id);