summaryrefslogtreecommitdiff
path: root/source3/libsmb/libsmb_compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb/libsmb_compat.c')
-rw-r--r--source3/libsmb/libsmb_compat.c190
1 files changed, 173 insertions, 17 deletions
diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c
index 27b274953a..4c96c41c56 100644
--- a/source3/libsmb/libsmb_compat.c
+++ b/source3/libsmb/libsmb_compat.c
@@ -5,6 +5,7 @@
Copyright (C) Richard Sharpe 2000
Copyright (C) John Terpstra 2000
Copyright (C) Tom Jansen (Ninja ISD) 2002
+ Copyright (C) Derrell Lipman 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -34,14 +35,14 @@ struct smbc_compat_fdlist {
static SMBCCTX * statcont = NULL;
static int smbc_compat_initialized = 0;
-static int smbc_currentfd = 10000;
-static struct smbc_compat_fdlist * smbc_compat_fdlist = NULL;
-
+static int smbc_compat_nextfd = 0;
+static struct smbc_compat_fdlist * smbc_compat_fd_in_use = NULL;
+static struct smbc_compat_fdlist * smbc_compat_fd_avail = NULL;
/* Find an fd and return the SMBCFILE * or NULL on failure */
static SMBCFILE * find_fd(int fd)
{
- struct smbc_compat_fdlist * f = smbc_compat_fdlist;
+ struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
while (f) {
if (f->fd == fd)
return f->file;
@@ -53,16 +54,36 @@ static SMBCFILE * find_fd(int fd)
/* Add an fd, returns 0 on success, -1 on error with errno set */
static int add_fd(SMBCFILE * file)
{
- struct smbc_compat_fdlist * f = malloc(sizeof(struct smbc_compat_fdlist));
- if (!f) {
- errno = ENOMEM;
- return -1;
- }
+ struct smbc_compat_fdlist * f = smbc_compat_fd_avail;
+
+ if (f) {
+ /* We found one that's available */
+ DLIST_REMOVE(smbc_compat_fd_avail, f);
+
+ } else {
+ /*
+ * None were available, so allocate one. Keep the number of
+ * file descriptors determinate. This allows the application
+ * to allocate bitmaps or mapping of file descriptors based on
+ * a known maximum number of file descriptors that will ever
+ * be returned.
+ */
+ if (smbc_compat_nextfd >= FD_SETSIZE) {
+ errno = EMFILE;
+ return -1;
+ }
+
+ f = malloc(sizeof(struct smbc_compat_fdlist));
+ if (!f) {
+ errno = ENOMEM;
+ return -1;
+ }
- f->fd = smbc_currentfd++;
+ f->fd = SMBC_BASE_FD + smbc_compat_nextfd++;
+ }
+
f->file = file;
-
- DLIST_ADD(smbc_compat_fdlist, f);
+ DLIST_ADD(smbc_compat_fd_in_use, f);
return f->fd;
}
@@ -72,16 +93,19 @@ static int add_fd(SMBCFILE * file)
/* Delete an fd, returns 0 on success */
static int del_fd(int fd)
{
- struct smbc_compat_fdlist * f = smbc_compat_fdlist;
+ struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
+
while (f) {
if (f->fd == fd)
break;
f = f->next;
}
+
if (f) {
/* found */
- DLIST_REMOVE(smbc_compat_fdlist, f);
- SAFE_FREE(f);
+ DLIST_REMOVE(smbc_compat_fd_in_use, f);
+ f->file = NULL;
+ DLIST_ADD(smbc_compat_fd_avail, f);
return 0;
}
return 1;
@@ -91,6 +115,9 @@ static int del_fd(int fd)
int smbc_init(smbc_get_auth_data_fn fn, int debug)
{
+ int i;
+ struct smbc_compat_fdlist * f;
+
if (!smbc_compat_initialized) {
statcont = smbc_new_context();
if (!statcont)
@@ -112,6 +139,22 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug)
}
+SMBCCTX *smbc_set_context(SMBCCTX * context)
+{
+ SMBCCTX *old_context = statcont;
+
+ if (context) {
+ /* Save provided context. It must have been initialized! */
+ statcont = context;
+
+ /* You'd better know what you're doing. We won't help you. */
+ smbc_compat_initialized = 1;
+ }
+
+ return old_context;
+}
+
+
int smbc_open(const char *furl, int flags, mode_t mode)
{
SMBCFILE * file;
@@ -252,8 +295,121 @@ int smbc_fstat(int fd, struct stat *st)
int smbc_chmod(const char *url, mode_t mode)
{
- /* NOT IMPLEMENTED IN LIBSMBCLIENT YET */
- return -1;
+ return statcont->chmod(statcont, url, mode);
+}
+
+int smbc_utimes(const char *fname, struct timeval *tbuf)
+{
+ return statcont->utimes(statcont, fname, tbuf);
+}
+
+#ifdef HAVE_UTIME_H
+int smbc_utime(const char *fname, struct utimbuf *utbuf)
+{
+ struct timeval tv;
+
+ if (utbuf == NULL)
+ return statcont->utimes(statcont, fname, NULL);
+
+ tv.tv_sec = utbuf->modtime;
+ tv.tv_usec = 0;
+ return statcont->utimes(statcont, fname, &tv);
+}
+#endif
+
+int smbc_setxattr(const char *fname,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags)
+{
+ return statcont->setxattr(statcont, fname, name, value, size, flags);
+}
+
+int smbc_lsetxattr(const char *fname,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags)
+{
+ return statcont->setxattr(statcont, fname, name, value, size, flags);
+}
+
+int smbc_fsetxattr(int fd,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags)
+{
+ SMBCFILE * file = find_fd(fd);
+ return statcont->setxattr(statcont, file->fname,
+ name, value, size, flags);
+}
+
+int smbc_getxattr(const char *fname,
+ const char *name,
+ const void *value,
+ size_t size)
+{
+ return statcont->getxattr(statcont, fname, name, value, size);
+}
+
+int smbc_lgetxattr(const char *fname,
+ const char *name,
+ const void *value,
+ size_t size)
+{
+ return statcont->getxattr(statcont, fname, name, value, size);
+}
+
+int smbc_fgetxattr(int fd,
+ const char *name,
+ const void *value,
+ size_t size)
+{
+ SMBCFILE * file = find_fd(fd);
+ return statcont->getxattr(statcont, file->fname, name, value, size);
+}
+
+int smbc_removexattr(const char *fname,
+ const char *name)
+{
+ return statcont->removexattr(statcont, fname, name);
+}
+
+int smbc_lremovexattr(const char *fname,
+ const char *name)
+{
+ return statcont->removexattr(statcont, fname, name);
+}
+
+int smbc_fremovexattr(int fd,
+ const char *name)
+{
+ SMBCFILE * file = find_fd(fd);
+ return statcont->removexattr(statcont, file->fname, name);
+}
+
+int smbc_listxattr(const char *fname,
+ char *list,
+ size_t size)
+{
+ return statcont->listxattr(statcont, fname, list, size);
+}
+
+int smbc_llistxattr(const char *fname,
+ char *list,
+ size_t size)
+{
+ return statcont->listxattr(statcont, fname, list, size);
+}
+
+int smbc_flistxattr(int fd,
+ char *list,
+ size_t size)
+{
+ SMBCFILE * file = find_fd(fd);
+ return statcont->listxattr(statcont, file->fname, list, size);
}
int smbc_print_file(const char *fname, const char *printq)