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