Commit Derrell's changes to libsmbclient plus a small change to configure.in
[samba.git] / source / libsmb / libsmb_compat.c
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
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 2 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, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25
26 #include "includes.h"
27
28 #include "../include/libsmb_internal.h"
29
30 struct smbc_compat_fdlist {
31         SMBCFILE * file;
32         int fd;
33         struct smbc_compat_fdlist *next, *prev;
34 };
35
36 static SMBCCTX * statcont = NULL;
37 static int smbc_compat_initialized = 0;
38 static int smbc_compat_nextfd = 0;
39 static struct smbc_compat_fdlist * smbc_compat_fd_in_use = NULL;
40 static struct smbc_compat_fdlist * smbc_compat_fd_avail = NULL;
41
42 /* Find an fd and return the SMBCFILE * or NULL on failure */
43 static SMBCFILE * find_fd(int fd)
44 {
45         struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
46         while (f) {
47                 if (f->fd == fd) 
48                         return f->file;
49                 f = f->next;
50         }
51         return NULL;
52 }
53
54 /* Add an fd, returns 0 on success, -1 on error with errno set */
55 static int add_fd(SMBCFILE * file)
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 = malloc(sizeof(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 del_fd(int fd)
95 {
96         struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
97
98         while (f) {
99                 if (f->fd == fd) 
100                         break;
101                 f = f->next;
102         }
103
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;
110         }
111         return 1;
112 }
113  
114
115
116 int smbc_init(smbc_get_auth_data_fn fn, int debug)
117 {
118         int i;
119         struct smbc_compat_fdlist * f;
120         
121         if (!smbc_compat_initialized) {
122                 statcont = smbc_new_context();
123                 if (!statcont) 
124                         return -1;
125
126                 statcont->debug = debug;
127                 statcont->callbacks.auth_fn = 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 *smbc_set_context(SMBCCTX * context)
143 {
144         SMBCCTX *old_context = statcont;
145
146         if (context) {
147                 /* Save provided context.  It must have been initialized! */
148                 statcont = context;
149
150                 /* You'd better know what you're doing.  We won't help you. */
151                 smbc_compat_initialized = 1;
152         }
153         
154         return old_context;
155 }
156
157
158 int smbc_open(const char *furl, int flags, mode_t mode)
159 {
160         SMBCFILE * file;
161         int fd;
162
163         file = statcont->open(statcont, furl, flags, mode);
164         if (!file)
165                 return -1;
166
167         fd = add_fd(file);
168         if (fd == -1) 
169                 statcont->close(statcont, file);
170         return fd;
171 }
172
173
174 int smbc_creat(const char *furl, mode_t mode)
175 {
176         SMBCFILE * file;
177         int fd;
178
179         file = statcont->creat(statcont, furl, mode);
180         if (!file)
181                 return -1;
182
183         fd = add_fd(file);
184         if (fd == -1) {
185                 /* Hmm... should we delete the file too ? I guess we could try */
186                 statcont->close(statcont, file);
187                 statcont->unlink(statcont, furl);
188         }
189         return fd;
190 }
191
192
193 ssize_t smbc_read(int fd, void *buf, size_t bufsize)
194 {
195         SMBCFILE * file = find_fd(fd);
196         return statcont->read(statcont, file, buf, bufsize);
197 }
198
199 ssize_t smbc_write(int fd, void *buf, size_t bufsize)
200 {
201         SMBCFILE * file = find_fd(fd);
202         return statcont->write(statcont, file, buf, bufsize);
203 }
204
205 off_t smbc_lseek(int fd, off_t offset, int whence)
206 {
207         SMBCFILE * file = find_fd(fd);
208         return statcont->lseek(statcont, file, offset, whence);
209 }
210
211 int smbc_close(int fd)
212 {
213         SMBCFILE * file = find_fd(fd);
214         del_fd(fd);
215         return statcont->close(statcont, file);
216 }
217
218 int smbc_unlink(const char *fname)
219 {
220         return statcont->unlink(statcont, fname);
221 }
222
223 int smbc_rename(const char *ourl, const char *nurl)
224 {
225         return statcont->rename(statcont, ourl, statcont, nurl);
226 }
227
228 int smbc_opendir(const char *durl)
229 {
230         SMBCFILE * file;
231         int fd;
232
233         file = statcont->opendir(statcont, durl);
234         if (!file)
235                 return -1;
236
237         fd = add_fd(file);
238         if (fd == -1) 
239                 statcont->closedir(statcont, file);
240
241         return fd;
242 }
243
244 int smbc_closedir(int dh) 
245 {
246         SMBCFILE * file = find_fd(dh);
247         del_fd(dh);
248         return statcont->closedir(statcont, file);
249 }
250
251 int smbc_getdents(unsigned int dh, struct smbc_dirent *dirp, int count)
252 {
253         SMBCFILE * file = find_fd(dh);
254         return statcont->getdents(statcont, file,dirp, count);
255 }
256
257 struct smbc_dirent* smbc_readdir(unsigned int dh)
258 {
259         SMBCFILE * file = find_fd(dh);
260         return statcont->readdir(statcont, file);
261 }
262
263 off_t smbc_telldir(int dh)
264 {
265         SMBCFILE * file = find_fd(dh);
266         return statcont->telldir(statcont, file);
267 }
268
269 int smbc_lseekdir(int fd, off_t offset)
270 {
271         SMBCFILE * file = find_fd(fd);
272         return statcont->lseekdir(statcont, file, offset);
273 }
274
275 int smbc_mkdir(const char *durl, mode_t mode)
276 {
277         return statcont->mkdir(statcont, durl, mode);
278 }
279
280 int smbc_rmdir(const char *durl)
281 {
282         return statcont->rmdir(statcont, durl);
283 }
284
285 int smbc_stat(const char *url, struct stat *st)
286 {
287         return statcont->stat(statcont, url, st);
288 }
289
290 int smbc_fstat(int fd, struct stat *st)
291 {
292         SMBCFILE * file = find_fd(fd);
293         return statcont->fstat(statcont, file, st);
294 }
295
296 int smbc_chmod(const char *url, mode_t mode)
297 {
298         return statcont->chmod(statcont, url, mode);
299 }
300
301 int smbc_utimes(const char *fname, struct timeval *tbuf)
302 {
303         return statcont->utimes(statcont, fname, tbuf);
304 }
305
306 #ifdef HAVE_UTIME_H
307 int smbc_utime(const char *fname, struct utimbuf *utbuf)
308 {
309         struct timeval tv;
310
311         if (utbuf == NULL)
312                 return statcont->utimes(statcont, fname, NULL);
313
314         tv.tv_sec = utbuf->modtime;
315         tv.tv_usec = 0;
316         return statcont->utimes(statcont, fname, &tv);
317 }
318 #endif
319
320 int smbc_setxattr(const char *fname,
321                   const char *name,
322                   const void *value,
323                   size_t size,
324                   int flags)
325 {
326         return statcont->setxattr(statcont, fname, name, value, size, flags);
327 }
328
329 int smbc_lsetxattr(const char *fname,
330                    const char *name,
331                    const void *value,
332                    size_t size,
333                    int flags)
334 {
335         return statcont->setxattr(statcont, fname, name, value, size, flags);
336 }
337
338 int smbc_fsetxattr(int fd,
339                    const char *name,
340                    const void *value,
341                    size_t size,
342                    int flags)
343 {
344         SMBCFILE * file = find_fd(fd);
345         return statcont->setxattr(statcont, file->fname,
346                                   name, value, size, flags);
347 }
348
349 int smbc_getxattr(const char *fname,
350                   const char *name,
351                   const void *value,
352                   size_t size)
353 {
354         return statcont->getxattr(statcont, fname, name, value, size);
355 }
356
357 int smbc_lgetxattr(const char *fname,
358                    const char *name,
359                    const void *value,
360                    size_t size)
361 {
362         return statcont->getxattr(statcont, fname, name, value, size);
363 }
364
365 int smbc_fgetxattr(int fd,
366                    const char *name,
367                    const void *value,
368                    size_t size)
369 {
370         SMBCFILE * file = find_fd(fd);
371         return statcont->getxattr(statcont, file->fname, name, value, size);
372 }
373
374 int smbc_removexattr(const char *fname,
375                      const char *name)
376 {
377         return statcont->removexattr(statcont, fname, name);
378 }
379
380 int smbc_lremovexattr(const char *fname,
381                       const char *name)
382 {
383         return statcont->removexattr(statcont, fname, name);
384 }
385
386 int smbc_fremovexattr(int fd,
387                       const char *name)
388 {
389         SMBCFILE * file = find_fd(fd);
390         return statcont->removexattr(statcont, file->fname, name);
391 }
392
393 int smbc_listxattr(const char *fname,
394                    char *list,
395                    size_t size)
396 {
397         return statcont->listxattr(statcont, fname, list, size);
398 }
399
400 int smbc_llistxattr(const char *fname,
401                     char *list,
402                     size_t size)
403 {
404         return statcont->listxattr(statcont, fname, list, size);
405 }
406
407 int smbc_flistxattr(int fd,
408                     char *list,
409                     size_t size)
410 {
411         SMBCFILE * file = find_fd(fd);
412         return statcont->listxattr(statcont, file->fname, list, size);
413 }
414
415 int smbc_print_file(const char *fname, const char *printq)
416 {
417         return statcont->print_file(statcont, fname, statcont, printq);
418 }
419
420 int smbc_open_print_job(const char *fname)
421 {
422         SMBCFILE * file = statcont->open_print_job(statcont, fname);
423         if (!file) return -1;
424         return (int) file;
425 }
426
427 int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn)
428 {
429         return statcont->list_print_jobs(statcont, purl, fn);
430 }
431
432 int smbc_unlink_print_job(const char *purl, int id)
433 {
434         return statcont->unlink_print_job(statcont, purl, id);
435 }
436
437