smbd: reject FILE_ATTRIBUTE_TEMPORARY on directories
[Samba.git] / source3 / libsmb / libsmb_compat.c
blobc916122d0b82d1ce2de389f80171249abfb8c036
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 statcont = smbc_new_context();
122 if (!statcont)
123 return -1;
125 smbc_setDebug(statcont, debug);
126 smbc_setFunctionAuthData(statcont, fn);
128 if (!smbc_init_context(statcont)) {
129 smbc_free_context(statcont, False);
130 return -1;
133 smbc_compat_initialized = 1;
135 return 0;
137 return 0;
141 SMBCCTX *
142 smbc_set_context(SMBCCTX * context)
144 SMBCCTX *old_context = statcont;
146 if (context) {
147 /* Save provided context. It must have been initialized! */
148 statcont = context;
150 /* You'd better know what you're doing. We won't help you. */
151 smbc_compat_initialized = 1;
154 return old_context;
159 smbc_open(const char *furl,
160 int flags,
161 mode_t mode)
163 SMBCFILE * file;
164 int fd;
166 file = smbc_getFunctionOpen(statcont)(statcont, furl, flags, mode);
167 if (!file)
168 return -1;
170 fd = add_fd(file);
171 if (fd == -1)
172 smbc_getFunctionClose(statcont)(statcont, file);
173 return fd;
178 smbc_creat(const char *furl,
179 mode_t mode)
181 SMBCFILE * file;
182 int fd;
184 file = smbc_getFunctionCreat(statcont)(statcont, furl, mode);
185 if (!file)
186 return -1;
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);
194 return fd;
198 ssize_t
199 smbc_read(int fd,
200 void *buf,
201 size_t bufsize)
203 SMBCFILE * file = find_fd(fd);
204 return smbc_getFunctionRead(statcont)(statcont, file, buf, bufsize);
207 ssize_t
208 smbc_write(int fd,
209 const void *buf,
210 size_t bufsize)
212 SMBCFILE * file = find_fd(fd);
213 return smbc_getFunctionWrite(statcont)(statcont, file, buf, bufsize);
216 off_t
217 smbc_lseek(int fd,
218 off_t offset,
219 int whence)
221 SMBCFILE * file = find_fd(fd);
222 return smbc_getFunctionLseek(statcont)(statcont, file, offset, whence);
226 smbc_close(int fd)
228 SMBCFILE * file = find_fd(fd);
229 del_fd(fd);
230 return smbc_getFunctionClose(statcont)(statcont, file);
234 smbc_unlink(const char *fname)
236 return smbc_getFunctionUnlink(statcont)(statcont, fname);
240 smbc_rename(const char *ourl,
241 const char *nurl)
243 return smbc_getFunctionRename(statcont)(statcont, ourl,
244 statcont, nurl);
248 smbc_opendir(const char *durl)
250 SMBCFILE * file;
251 int fd;
253 file = smbc_getFunctionOpendir(statcont)(statcont, durl);
254 if (!file)
255 return -1;
257 fd = add_fd(file);
258 if (fd == -1)
259 smbc_getFunctionClosedir(statcont)(statcont, file);
261 return fd;
265 smbc_closedir(int dh)
267 SMBCFILE * file = find_fd(dh);
268 del_fd(dh);
269 return smbc_getFunctionClosedir(statcont)(statcont, file);
273 smbc_getdents(unsigned int dh,
274 struct smbc_dirent *dirp,
275 int count)
277 SMBCFILE * file = find_fd(dh);
278 return smbc_getFunctionGetdents(statcont)(statcont, file, dirp, count);
281 struct smbc_dirent *
282 smbc_readdir(unsigned int dh)
284 SMBCFILE * file = find_fd(dh);
285 return smbc_getFunctionReaddir(statcont)(statcont, file);
288 const struct libsmb_file_info *smbc_readdirplus(unsigned int dh)
290 SMBCFILE * file = find_fd(dh);
291 return smbc_getFunctionReaddirPlus(statcont)(statcont, file);
294 const struct libsmb_file_info *smbc_readdirplus2(unsigned int dh,
295 struct stat *st)
297 SMBCFILE *file = find_fd(dh);
298 return smbc_getFunctionReaddirPlus2(statcont)(statcont, file, st);
301 off_t
302 smbc_telldir(int dh)
304 SMBCFILE * file = find_fd(dh);
305 return smbc_getFunctionTelldir(statcont)(statcont, file);
309 smbc_lseekdir(int fd,
310 off_t offset)
312 SMBCFILE * file = find_fd(fd);
313 return smbc_getFunctionLseekdir(statcont)(statcont, file, offset);
317 smbc_mkdir(const char *durl,
318 mode_t mode)
320 return smbc_getFunctionMkdir(statcont)(statcont, durl, mode);
324 smbc_rmdir(const char *durl)
326 return smbc_getFunctionRmdir(statcont)(statcont, durl);
330 smbc_notify(int dh, smbc_bool recursive, uint32_t completion_filter,
331 unsigned callback_timeout_ms,
332 smbc_notify_callback_fn cb, void *private_data)
334 SMBCFILE *dir = find_fd(dh);
335 return smbc_getFunctionNotify(statcont)(
336 statcont, dir, recursive, completion_filter,
337 callback_timeout_ms, cb, private_data);
341 smbc_stat(const char *url,
342 struct stat *st)
344 return smbc_getFunctionStat(statcont)(statcont, url, st);
348 smbc_fstat(int fd,
349 struct stat *st)
351 SMBCFILE * file = find_fd(fd);
352 return smbc_getFunctionFstat(statcont)(statcont, file, st);
356 smbc_statvfs(char *path,
357 struct statvfs *st)
359 return smbc_getFunctionStatVFS(statcont)(statcont, path, st);
363 smbc_fstatvfs(int fd,
364 struct statvfs *st)
366 SMBCFILE * file = find_fd(fd);
367 return smbc_getFunctionFstatVFS(statcont)(statcont, file, st);
371 smbc_ftruncate(int fd,
372 off_t size)
374 SMBCFILE * file = find_fd(fd);
375 return smbc_getFunctionFtruncate(statcont)(statcont, file, size);
379 smbc_chmod(const char *url,
380 mode_t mode)
382 return smbc_getFunctionChmod(statcont)(statcont, url, mode);
386 smbc_utimes(const char *fname,
387 struct timeval *tbuf)
389 return smbc_getFunctionUtimes(statcont)(statcont, fname, tbuf);
392 #ifdef HAVE_UTIME_H
394 smbc_utime(const char *fname,
395 struct utimbuf *utbuf)
397 struct timeval tv[2];
399 if (utbuf == NULL)
400 return smbc_getFunctionUtimes(statcont)(statcont, fname, NULL);
402 tv[0].tv_sec = utbuf->actime;
403 tv[1].tv_sec = utbuf->modtime;
404 tv[0].tv_usec = tv[1].tv_usec = 0;
406 return smbc_getFunctionUtimes(statcont)(statcont, fname, tv);
408 #endif
411 smbc_setxattr(const char *fname,
412 const char *name,
413 const void *value,
414 size_t size,
415 int flags)
417 return smbc_getFunctionSetxattr(statcont)(statcont,
418 fname, name,
419 value, size, flags);
423 smbc_lsetxattr(const char *fname,
424 const char *name,
425 const void *value,
426 size_t size,
427 int flags)
429 return smbc_getFunctionSetxattr(statcont)(statcont,
430 fname, name,
431 value, size, flags);
435 smbc_fsetxattr(int fd,
436 const char *name,
437 const void *value,
438 size_t size,
439 int flags)
441 SMBCFILE * file = find_fd(fd);
442 if (file == NULL) {
443 errno = EBADF;
444 return -1;
446 return smbc_getFunctionSetxattr(statcont)(statcont,
447 file->fname, name,
448 value, size, flags);
452 smbc_getxattr(const char *fname,
453 const char *name,
454 const void *value,
455 size_t size)
457 return smbc_getFunctionGetxattr(statcont)(statcont,
458 fname, name,
459 value, size);
463 smbc_lgetxattr(const char *fname,
464 const char *name,
465 const void *value,
466 size_t size)
468 return smbc_getFunctionGetxattr(statcont)(statcont,
469 fname, name,
470 value, size);
474 smbc_fgetxattr(int fd,
475 const char *name,
476 const void *value,
477 size_t size)
479 SMBCFILE * file = find_fd(fd);
480 if (file == NULL) {
481 errno = EBADF;
482 return -1;
484 return smbc_getFunctionGetxattr(statcont)(statcont,
485 file->fname, name,
486 value, size);
490 smbc_removexattr(const char *fname,
491 const char *name)
493 return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name);
497 smbc_lremovexattr(const char *fname,
498 const char *name)
500 return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name);
504 smbc_fremovexattr(int fd,
505 const char *name)
507 SMBCFILE * file = find_fd(fd);
508 if (file == NULL) {
509 errno = EBADF;
510 return -1;
512 return smbc_getFunctionRemovexattr(statcont)(statcont,
513 file->fname, name);
517 smbc_listxattr(const char *fname,
518 char *list,
519 size_t size)
521 return smbc_getFunctionListxattr(statcont)(statcont,
522 fname, list, size);
526 smbc_llistxattr(const char *fname,
527 char *list,
528 size_t size)
530 return smbc_getFunctionListxattr(statcont)(statcont,
531 fname, list, size);
535 smbc_flistxattr(int fd,
536 char *list,
537 size_t size)
539 SMBCFILE * file = find_fd(fd);
540 if (file == NULL) {
541 errno = EBADF;
542 return -1;
544 return smbc_getFunctionListxattr(statcont)(statcont,
545 file->fname, list, size);
549 smbc_print_file(const char *fname,
550 const char *printq)
552 return smbc_getFunctionPrintFile(statcont)(statcont, fname,
553 statcont, printq);
557 smbc_open_print_job(const char *fname)
559 SMBCFILE * file;
561 file = smbc_getFunctionOpenPrintJob(statcont)(statcont, fname);
562 if (!file) return -1;
563 return file->cli_fd;
567 smbc_list_print_jobs(const char *purl,
568 smbc_list_print_job_fn fn)
570 return smbc_getFunctionListPrintJobs(statcont)(statcont, purl, fn);
574 smbc_unlink_print_job(const char *purl,
575 int id)
577 return smbc_getFunctionUnlinkPrintJob(statcont)(statcont, purl, id);