Line data Source code
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 3076 : find_fd(int fd)
43 : {
44 3076 : struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
45 3076 : while (f) {
46 3076 : if (f->fd == fd)
47 3076 : return f->file;
48 0 : f = f->next;
49 : }
50 0 : return NULL;
51 : }
52 :
53 : /* Add an fd, returns 0 on success, -1 on error with errno set */
54 : static int
55 542 : add_fd(SMBCFILE * file)
56 : {
57 542 : struct smbc_compat_fdlist * f = smbc_compat_fd_avail;
58 :
59 542 : if (f) {
60 : /* We found one that's available */
61 440 : 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 102 : if (smbc_compat_nextfd >= FD_SETSIZE) {
71 0 : errno = EMFILE;
72 0 : return -1;
73 : }
74 :
75 102 : f = SMB_MALLOC_P(struct smbc_compat_fdlist);
76 102 : if (!f) {
77 0 : errno = ENOMEM;
78 0 : return -1;
79 : }
80 :
81 102 : f->fd = SMBC_BASE_FD + smbc_compat_nextfd++;
82 : }
83 :
84 542 : f->file = file;
85 542 : DLIST_ADD(smbc_compat_fd_in_use, f);
86 :
87 542 : return f->fd;
88 : }
89 :
90 :
91 :
92 : /* Delete an fd, returns 0 on success */
93 : static int
94 540 : del_fd(int fd)
95 : {
96 540 : struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
97 :
98 540 : while (f) {
99 540 : if (f->fd == fd)
100 540 : break;
101 0 : f = f->next;
102 : }
103 :
104 540 : if (f) {
105 : /* found */
106 540 : DLIST_REMOVE(smbc_compat_fd_in_use, f);
107 540 : f->file = NULL;
108 540 : DLIST_ADD(smbc_compat_fd_avail, f);
109 540 : return 0;
110 : }
111 0 : return 1;
112 : }
113 :
114 :
115 :
116 : int
117 0 : smbc_init(smbc_get_auth_data_fn fn,
118 : int debug)
119 : {
120 0 : if (smbc_compat_initialized) {
121 0 : return 0;
122 : }
123 :
124 0 : statcont = smbc_new_context();
125 0 : if (!statcont)
126 0 : return -1;
127 :
128 0 : smbc_setDebug(statcont, debug);
129 0 : smbc_setFunctionAuthData(statcont, fn);
130 :
131 0 : if (!smbc_init_context(statcont)) {
132 0 : smbc_free_context(statcont, False);
133 0 : return -1;
134 : }
135 :
136 0 : smbc_compat_initialized = 1;
137 :
138 0 : return 0;
139 : }
140 :
141 :
142 : SMBCCTX *
143 90 : smbc_set_context(SMBCCTX * context)
144 : {
145 90 : SMBCCTX *old_context = statcont;
146 :
147 90 : if (context) {
148 : /* Save provided context. It must have been initialized! */
149 90 : statcont = context;
150 :
151 : /* You'd better know what you're doing. We won't help you. */
152 90 : smbc_compat_initialized = 1;
153 : }
154 :
155 90 : return old_context;
156 : }
157 :
158 :
159 : int
160 64 : smbc_open(const char *furl,
161 : int flags,
162 : mode_t mode)
163 : {
164 0 : SMBCFILE * file;
165 0 : int fd;
166 :
167 64 : file = smbc_getFunctionOpen(statcont)(statcont, furl, flags, mode);
168 64 : if (!file)
169 0 : return -1;
170 :
171 64 : fd = add_fd(file);
172 64 : if (fd == -1)
173 0 : smbc_getFunctionClose(statcont)(statcont, file);
174 64 : return fd;
175 : }
176 :
177 :
178 : int
179 420 : smbc_creat(const char *furl,
180 : mode_t mode)
181 : {
182 0 : SMBCFILE * file;
183 0 : int fd;
184 :
185 420 : file = smbc_getFunctionCreat(statcont)(statcont, furl, mode);
186 420 : if (!file)
187 0 : return -1;
188 :
189 420 : fd = add_fd(file);
190 420 : if (fd == -1) {
191 : /* Hmm... should we delete the file too ? I guess we could try */
192 0 : smbc_getFunctionClose(statcont)(statcont, file);
193 0 : smbc_getFunctionUnlink(statcont)(statcont, furl);
194 : }
195 420 : return fd;
196 : }
197 :
198 :
199 : ssize_t
200 402 : smbc_read(int fd,
201 : void *buf,
202 : size_t bufsize)
203 : {
204 402 : SMBCFILE * file = find_fd(fd);
205 402 : return smbc_getFunctionRead(statcont)(statcont, file, buf, bufsize);
206 : }
207 :
208 : ssize_t
209 0 : smbc_write(int fd,
210 : const void *buf,
211 : size_t bufsize)
212 : {
213 0 : SMBCFILE * file = find_fd(fd);
214 0 : return smbc_getFunctionWrite(statcont)(statcont, file, buf, bufsize);
215 : }
216 :
217 : off_t
218 2 : smbc_lseek(int fd,
219 : off_t offset,
220 : int whence)
221 : {
222 2 : SMBCFILE * file = find_fd(fd);
223 2 : return smbc_getFunctionLseek(statcont)(statcont, file, offset, whence);
224 : }
225 :
226 : int
227 484 : smbc_close(int fd)
228 : {
229 484 : SMBCFILE * file = find_fd(fd);
230 484 : del_fd(fd);
231 484 : return smbc_getFunctionClose(statcont)(statcont, file);
232 : }
233 :
234 : int
235 848 : smbc_unlink(const char *fname)
236 : {
237 848 : return smbc_getFunctionUnlink(statcont)(statcont, fname);
238 : }
239 :
240 : int
241 4 : smbc_rename(const char *ourl,
242 : const char *nurl)
243 : {
244 4 : return smbc_getFunctionRename(statcont)(statcont, ourl,
245 : statcont, nurl);
246 : }
247 :
248 : int
249 120 : smbc_opendir(const char *durl)
250 : {
251 0 : SMBCFILE * file;
252 0 : int fd;
253 :
254 120 : file = smbc_getFunctionOpendir(statcont)(statcont, durl);
255 120 : if (!file)
256 62 : return -1;
257 :
258 58 : fd = add_fd(file);
259 58 : if (fd == -1)
260 0 : smbc_getFunctionClosedir(statcont)(statcont, file);
261 :
262 58 : return fd;
263 : }
264 :
265 : int
266 56 : smbc_closedir(int dh)
267 : {
268 56 : SMBCFILE * file = find_fd(dh);
269 56 : del_fd(dh);
270 56 : return smbc_getFunctionClosedir(statcont)(statcont, file);
271 : }
272 :
273 : int
274 8 : smbc_getdents(unsigned int dh,
275 : struct smbc_dirent *dirp,
276 : int count)
277 : {
278 8 : SMBCFILE * file = find_fd(dh);
279 8 : return smbc_getFunctionGetdents(statcont)(statcont, file, dirp, count);
280 : }
281 :
282 : struct smbc_dirent *
283 1154 : smbc_readdir(unsigned int dh)
284 : {
285 1154 : SMBCFILE * file = find_fd(dh);
286 1154 : return smbc_getFunctionReaddir(statcont)(statcont, file);
287 : }
288 :
289 743 : const struct libsmb_file_info *smbc_readdirplus(unsigned int dh)
290 : {
291 743 : SMBCFILE * file = find_fd(dh);
292 743 : return smbc_getFunctionReaddirPlus(statcont)(statcont, file);
293 : }
294 :
295 131 : const struct libsmb_file_info *smbc_readdirplus2(unsigned int dh,
296 : struct stat *st)
297 : {
298 131 : SMBCFILE *file = find_fd(dh);
299 131 : return smbc_getFunctionReaddirPlus2(statcont)(statcont, file, st);
300 : }
301 :
302 : off_t
303 8 : smbc_telldir(int dh)
304 : {
305 8 : SMBCFILE * file = find_fd(dh);
306 8 : return smbc_getFunctionTelldir(statcont)(statcont, file);
307 : }
308 :
309 : int
310 20 : smbc_lseekdir(int fd,
311 : off_t offset)
312 : {
313 20 : SMBCFILE * file = find_fd(fd);
314 20 : return smbc_getFunctionLseekdir(statcont)(statcont, file, offset);
315 : }
316 :
317 : int
318 4 : smbc_mkdir(const char *durl,
319 : mode_t mode)
320 : {
321 4 : return smbc_getFunctionMkdir(statcont)(statcont, durl, mode);
322 : }
323 :
324 : int
325 8 : smbc_rmdir(const char *durl)
326 : {
327 8 : return smbc_getFunctionRmdir(statcont)(statcont, durl);
328 : }
329 :
330 : int
331 0 : 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)
334 : {
335 0 : SMBCFILE *dir = find_fd(dh);
336 0 : return smbc_getFunctionNotify(statcont)(
337 : statcont, dir, recursive, completion_filter,
338 : callback_timeout_ms, cb, private_data);
339 : }
340 :
341 : int
342 12 : smbc_stat(const char *url,
343 : struct stat *st)
344 : {
345 12 : return smbc_getFunctionStat(statcont)(statcont, url, st);
346 : }
347 :
348 : int
349 68 : smbc_fstat(int fd,
350 : struct stat *st)
351 : {
352 68 : SMBCFILE * file = find_fd(fd);
353 68 : return smbc_getFunctionFstat(statcont)(statcont, file, st);
354 : }
355 :
356 : int
357 0 : smbc_statvfs(char *path,
358 : struct statvfs *st)
359 : {
360 0 : return smbc_getFunctionStatVFS(statcont)(statcont, path, st);
361 : }
362 :
363 : int
364 0 : smbc_fstatvfs(int fd,
365 : struct statvfs *st)
366 : {
367 0 : SMBCFILE * file = find_fd(fd);
368 0 : return smbc_getFunctionFstatVFS(statcont)(statcont, file, st);
369 : }
370 :
371 : int
372 0 : smbc_ftruncate(int fd,
373 : off_t size)
374 : {
375 0 : SMBCFILE * file = find_fd(fd);
376 0 : return smbc_getFunctionFtruncate(statcont)(statcont, file, size);
377 : }
378 :
379 : int
380 0 : smbc_chmod(const char *url,
381 : mode_t mode)
382 : {
383 0 : return smbc_getFunctionChmod(statcont)(statcont, url, mode);
384 : }
385 :
386 : int
387 4 : smbc_utimes(const char *fname,
388 : struct timeval *tbuf)
389 : {
390 4 : return smbc_getFunctionUtimes(statcont)(statcont, fname, tbuf);
391 : }
392 :
393 : #ifdef HAVE_UTIME_H
394 : int
395 0 : smbc_utime(const char *fname,
396 : struct utimbuf *utbuf)
397 : {
398 0 : struct timeval tv[2];
399 :
400 0 : if (utbuf == NULL)
401 0 : return smbc_getFunctionUtimes(statcont)(statcont, fname, NULL);
402 :
403 0 : tv[0].tv_sec = utbuf->actime;
404 0 : tv[1].tv_sec = utbuf->modtime;
405 0 : tv[0].tv_usec = tv[1].tv_usec = 0;
406 :
407 0 : return smbc_getFunctionUtimes(statcont)(statcont, fname, tv);
408 : }
409 : #endif
410 :
411 : int
412 0 : smbc_setxattr(const char *fname,
413 : const char *name,
414 : const void *value,
415 : size_t size,
416 : int flags)
417 : {
418 0 : return smbc_getFunctionSetxattr(statcont)(statcont,
419 : fname, name,
420 : value, size, flags);
421 : }
422 :
423 : int
424 0 : smbc_lsetxattr(const char *fname,
425 : const char *name,
426 : const void *value,
427 : size_t size,
428 : int flags)
429 : {
430 0 : return smbc_getFunctionSetxattr(statcont)(statcont,
431 : fname, name,
432 : value, size, flags);
433 : }
434 :
435 : int
436 0 : smbc_fsetxattr(int fd,
437 : const char *name,
438 : const void *value,
439 : size_t size,
440 : int flags)
441 : {
442 0 : SMBCFILE * file = find_fd(fd);
443 0 : if (file == NULL) {
444 0 : errno = EBADF;
445 0 : return -1;
446 : }
447 0 : return smbc_getFunctionSetxattr(statcont)(statcont,
448 0 : file->fname, name,
449 : value, size, flags);
450 : }
451 :
452 : int
453 12 : smbc_getxattr(const char *fname,
454 : const char *name,
455 : const void *value,
456 : size_t size)
457 : {
458 12 : return smbc_getFunctionGetxattr(statcont)(statcont,
459 : fname, name,
460 : value, size);
461 : }
462 :
463 : int
464 0 : smbc_lgetxattr(const char *fname,
465 : const char *name,
466 : const void *value,
467 : size_t size)
468 : {
469 0 : return smbc_getFunctionGetxattr(statcont)(statcont,
470 : fname, name,
471 : value, size);
472 : }
473 :
474 : int
475 0 : smbc_fgetxattr(int fd,
476 : const char *name,
477 : const void *value,
478 : size_t size)
479 : {
480 0 : SMBCFILE * file = find_fd(fd);
481 0 : if (file == NULL) {
482 0 : errno = EBADF;
483 0 : return -1;
484 : }
485 0 : return smbc_getFunctionGetxattr(statcont)(statcont,
486 0 : file->fname, name,
487 : value, size);
488 : }
489 :
490 : int
491 0 : smbc_removexattr(const char *fname,
492 : const char *name)
493 : {
494 0 : return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name);
495 : }
496 :
497 : int
498 0 : smbc_lremovexattr(const char *fname,
499 : const char *name)
500 : {
501 0 : return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name);
502 : }
503 :
504 : int
505 0 : smbc_fremovexattr(int fd,
506 : const char *name)
507 : {
508 0 : SMBCFILE * file = find_fd(fd);
509 0 : if (file == NULL) {
510 0 : errno = EBADF;
511 0 : return -1;
512 : }
513 0 : return smbc_getFunctionRemovexattr(statcont)(statcont,
514 0 : file->fname, name);
515 : }
516 :
517 : int
518 0 : smbc_listxattr(const char *fname,
519 : char *list,
520 : size_t size)
521 : {
522 0 : return smbc_getFunctionListxattr(statcont)(statcont,
523 : fname, list, size);
524 : }
525 :
526 : int
527 0 : smbc_llistxattr(const char *fname,
528 : char *list,
529 : size_t size)
530 : {
531 0 : return smbc_getFunctionListxattr(statcont)(statcont,
532 : fname, list, size);
533 : }
534 :
535 : int
536 0 : smbc_flistxattr(int fd,
537 : char *list,
538 : size_t size)
539 : {
540 0 : SMBCFILE * file = find_fd(fd);
541 0 : if (file == NULL) {
542 0 : errno = EBADF;
543 0 : return -1;
544 : }
545 0 : return smbc_getFunctionListxattr(statcont)(statcont,
546 0 : file->fname, list, size);
547 : }
548 :
549 : int
550 0 : smbc_print_file(const char *fname,
551 : const char *printq)
552 : {
553 0 : return smbc_getFunctionPrintFile(statcont)(statcont, fname,
554 : statcont, printq);
555 : }
556 :
557 : int
558 0 : smbc_open_print_job(const char *fname)
559 : {
560 0 : SMBCFILE * file;
561 :
562 0 : file = smbc_getFunctionOpenPrintJob(statcont)(statcont, fname);
563 0 : if (!file) return -1;
564 0 : return file->cli_fd;
565 : }
566 :
567 : int
568 0 : smbc_list_print_jobs(const char *purl,
569 : smbc_list_print_job_fn fn)
570 : {
571 0 : return smbc_getFunctionListPrintJobs(statcont)(statcont, purl, fn);
572 : }
573 :
574 : int
575 0 : smbc_unlink_print_job(const char *purl,
576 : int id)
577 : {
578 0 : return smbc_getFunctionUnlinkPrintJob(statcont)(statcont, purl, id);
579 : }
580 :
581 :
|