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