From fbc611f431db443c23486f768ca5e2bc4db95c24 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Tue, 29 Mar 2005 00:42:51 +0000 Subject: r6108: Added smbsh/smbwrapper for Linux to example/libsmbclient tree; provided more complete libsmbclient testbrowse utility (This used to be commit 15736b97c837a16d9c009b8bff18b31429ccbe83) --- examples/libsmbclient/smbwrapper/smbw_dir.c | 355 ++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 examples/libsmbclient/smbwrapper/smbw_dir.c (limited to 'examples/libsmbclient/smbwrapper/smbw_dir.c') diff --git a/examples/libsmbclient/smbwrapper/smbw_dir.c b/examples/libsmbclient/smbwrapper/smbw_dir.c new file mode 100644 index 0000000000..f3ec03e5a8 --- /dev/null +++ b/examples/libsmbclient/smbwrapper/smbw_dir.c @@ -0,0 +1,355 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + SMB wrapper directory functions + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Derrell Lipman 2003-2005 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "smbw.h" + +/***************************************************** +determine if a directory handle is a smb one +*******************************************************/ +int smbw_dirp(DIR * dirp) +{ + return ((char *) dirp >= (char *) smbw_fd_map && + (char *) dirp < (char *) &smbw_fd_map[__FD_SETSIZE] && + *(int *) dirp != -1); +} + + +/***************************************************** +a wrapper for getdents() +*******************************************************/ +int smbw_getdents(unsigned int fd_smbw, + struct SMBW_dirent *dirent_external, + int count) +{ + int remaining; + int fd_client = smbw_fd_map[fd_smbw]; + struct smbc_dirent *dirent_internal; + + + for (remaining = count; + remaining > sizeof(struct SMBW_dirent); + dirent_external++) { + + /* + * We do these one at a time because there's otherwise no way + * to limit how many smbc_getdents() will return for us, and + * if it returns too many, it also doesn't give us offsets to + * be able to seek back to where we need to be. In practice, + * this one-at-a-time retrieval isn't a problem because the + * time-consuming network transaction is all done at + * smbc_opendir() time. + */ + dirent_internal = smbc_readdir(fd_client); + if (dirent_internal == NULL) { + break; + } + + remaining -= sizeof(struct SMBW_dirent); + + dirent_external->d_ino = -1; /* not supported */ + dirent_external->d_off = smbc_telldir(fd_client); + dirent_external->d_reclen = sizeof(struct SMBW_dirent); + dirent_external->d_type = dirent_internal->smbc_type; + + strncpy(dirent_external->d_name, + dirent_internal->name, + sizeof(dirent_external->d_name) - 1); + strncpy(dirent_external->d_comment, + dirent_internal->comment, + sizeof(dirent_external->d_comment) - 1); + } + + return(count - remaining); +} + + +/***************************************************** +a wrapper for chdir() +*******************************************************/ +int smbw_chdir(const char *name) +{ + int simulate; + struct stat statbuf; + char path[PATH_MAX]; + char *p; + + SMBW_INIT(); + + if (!name) { + errno = EINVAL; + return -1; + } + + if (! smbw_path((char *) name)) { + if ((* smbw_libc.chdir)(name) == 0) { + *smbw_cwd = '\0'; + return 0; + } + + return -1; + } + + smbw_fix_path(name, path); + + /* ensure it exists */ + p = path + 6; /* look just past smb:// */ + simulate = (strchr(p, '/') == NULL); + + /* special case for full-network scan, workgroups, and servers */ + if (! simulate) { + + if (smbc_stat(path, &statbuf) < 0) { + return -1; + } + + /* ensure it's a directory */ + if (! S_ISDIR(statbuf.st_mode)) { + errno = ENOTDIR; + return -1; + } + } + + strncpy(smbw_cwd, path, PATH_MAX); + + /* we don't want the old directory to be busy */ + (* smbw_libc.chdir)("/"); + + return 0; +} + + +/***************************************************** +a wrapper for mkdir() +*******************************************************/ +int smbw_mkdir(const char *fname, mode_t mode) +{ + char path[PATH_MAX]; + + if (!fname) { + errno = EINVAL; + return -1; + } + + SMBW_INIT(); + + smbw_fix_path(fname, path); + return smbc_mkdir(path, mode); +} + +/***************************************************** +a wrapper for rmdir() +*******************************************************/ +int smbw_rmdir(const char *fname) +{ + char path[PATH_MAX]; + + if (!fname) { + errno = EINVAL; + return -1; + } + + SMBW_INIT(); + + smbw_fix_path(fname, path); + return smbc_rmdir(path); +} + + +/***************************************************** +a wrapper for getcwd() +*******************************************************/ +char *smbw_getcwd(char *buf, size_t size) +{ + SMBW_INIT(); + + if (*smbw_cwd == '\0') { + return (* smbw_libc.getcwd)(buf, size); + } + + if (buf == NULL) { + if (size == 0) { + size = strlen(smbw_cwd) + 1; + } + buf = malloc(size); + if (buf == NULL) { + errno = ENOMEM; + return NULL; + } + } + + strncpy(buf, smbw_cwd, size); + buf[size-1] = '\0'; + return buf; +} + +/***************************************************** +a wrapper for fchdir() +*******************************************************/ +int smbw_fchdir(int fd_smbw) +{ + int ret; + + SMBW_INIT(); + + if (! smbw_fd(fd_smbw)) { + ret = (* smbw_libc.fchdir)(fd_smbw); + (void) (* smbw_libc.getcwd)(smbw_cwd, PATH_MAX); + return ret; + } + + errno = EACCES; + return -1; +} + +/***************************************************** +open a directory on the server +*******************************************************/ +DIR *smbw_opendir(const char *fname) +{ + int fd_client; + int fd_smbw; + char path[PATH_MAX]; + DIR * dirp; + + SMBW_INIT(); + + if (!fname) { + errno = EINVAL; + return NULL; + } + + fd_smbw = (smbw_libc.open)(SMBW_DUMMY, O_WRONLY, 0200); + if (fd_smbw == -1) { + errno = EMFILE; + return NULL; + } + + smbw_fix_path(fname, path); + fd_client = smbc_opendir(path); + + if (fd_client < 0) { + (* smbw_libc.close)(fd_smbw); + return NULL; + } + + smbw_fd_map[fd_smbw] = fd_client; + smbw_ref(fd_client, SMBW_RCT_Increment); + dirp = (DIR *) &smbw_fd_map[fd_smbw]; + return dirp; +} + +/***************************************************** +read one entry from a directory +*******************************************************/ +struct SMBW_dirent *smbw_readdir(DIR *dirp) +{ + int fd_smbw; + int fd_client; + struct smbc_dirent *dirent_internal; + static struct SMBW_dirent dirent_external; + + fd_smbw = (int *) dirp - smbw_fd_map; + fd_client = smbw_fd_map[fd_smbw]; + + if ((dirent_internal = smbc_readdir(fd_client)) == NULL) { + return NULL; + } + + dirent_external.d_ino = -1; /* not supported */ + dirent_external.d_off = smbc_telldir(fd_client); + dirent_external.d_reclen = sizeof(struct SMBW_dirent); + dirent_external.d_type = dirent_internal->smbc_type; + strncpy(dirent_external.d_name, + dirent_internal->name, + sizeof(dirent_external.d_name) - 1); + strncpy(dirent_external.d_comment, + dirent_internal->comment, + sizeof(dirent_external.d_comment) - 1); + + return &dirent_external; +} + +/***************************************************** +read one entry from a directory in a reentrant fashion +ha! samba is not re-entrant, and neither is the +libsmbclient library +*******************************************************/ +int smbw_readdir_r(DIR *dirp, + struct SMBW_dirent *__restrict entry, + struct SMBW_dirent **__restrict result) +{ + SMBW_dirent *dirent; + + dirent = smbw_readdir(dirp); + + if (dirent != NULL) { + *entry = *dirent; + if (result != NULL) { + *result = entry; + } + return 0; + } + + if (result != NULL) { + *result = NULL; + } + return EBADF; +} + + +/***************************************************** +close a DIR* +*******************************************************/ +int smbw_closedir(DIR *dirp) +{ + int fd_smbw = (int *) dirp - smbw_fd_map; + int fd_client = smbw_fd_map[fd_smbw]; + + (* smbw_libc.close)(fd_smbw); + if (smbw_ref(fd_client, SMBW_RCT_Decrement) > 0) { + return 0; + } + smbw_fd_map[fd_smbw] = -1; + return smbc_closedir(fd_client); +} + +/***************************************************** +seek in a directory +*******************************************************/ +void smbw_seekdir(DIR *dirp, long long offset) +{ + int fd_smbw = (int *) dirp - smbw_fd_map; + int fd_client = smbw_fd_map[fd_smbw]; + + smbc_lseekdir(fd_client, offset); +} + +/***************************************************** +current loc in a directory +*******************************************************/ +long long smbw_telldir(DIR *dirp) +{ + int fd_smbw = (int *) dirp - smbw_fd_map; + int fd_client = smbw_fd_map[fd_smbw]; + + return (long long) smbc_telldir(fd_client); +} -- cgit From 96d0d186db42c61fa907b9b24f412b834359e2d8 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sat, 7 Jan 2006 20:43:36 +0000 Subject: r12759: r12128@cabra: derrell | 2006-01-07 15:34:01 -0500 Incorporate a number of changes suggested by David Collier-Brown Thanks, David! (This used to be commit 0ae65b9af566e02eece9bb7865047c037468d470) --- examples/libsmbclient/smbwrapper/smbw_dir.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'examples/libsmbclient/smbwrapper/smbw_dir.c') diff --git a/examples/libsmbclient/smbwrapper/smbw_dir.c b/examples/libsmbclient/smbwrapper/smbw_dir.c index f3ec03e5a8..986b7f8220 100644 --- a/examples/libsmbclient/smbwrapper/smbw_dir.c +++ b/examples/libsmbclient/smbwrapper/smbw_dir.c @@ -21,6 +21,7 @@ */ #include "smbw.h" +#include "bsd-strlfunc.h" /***************************************************** determine if a directory handle is a smb one @@ -70,12 +71,12 @@ int smbw_getdents(unsigned int fd_smbw, dirent_external->d_reclen = sizeof(struct SMBW_dirent); dirent_external->d_type = dirent_internal->smbc_type; - strncpy(dirent_external->d_name, - dirent_internal->name, - sizeof(dirent_external->d_name) - 1); - strncpy(dirent_external->d_comment, - dirent_internal->comment, - sizeof(dirent_external->d_comment) - 1); + smbw_strlcpy(dirent_external->d_name, + dirent_internal->name, + sizeof(dirent_external->d_name) - 1); + smbw_strlcpy(dirent_external->d_comment, + dirent_internal->comment, + sizeof(dirent_external->d_comment) - 1); } return(count - remaining); @@ -128,7 +129,7 @@ int smbw_chdir(const char *name) } } - strncpy(smbw_cwd, path, PATH_MAX); + smbw_strlcpy(smbw_cwd, path, PATH_MAX); /* we don't want the old directory to be busy */ (* smbw_libc.chdir)("/"); @@ -196,7 +197,7 @@ char *smbw_getcwd(char *buf, size_t size) } } - strncpy(buf, smbw_cwd, size); + smbw_strlcpy(buf, smbw_cwd, size); buf[size-1] = '\0'; return buf; } @@ -278,12 +279,12 @@ struct SMBW_dirent *smbw_readdir(DIR *dirp) dirent_external.d_off = smbc_telldir(fd_client); dirent_external.d_reclen = sizeof(struct SMBW_dirent); dirent_external.d_type = dirent_internal->smbc_type; - strncpy(dirent_external.d_name, - dirent_internal->name, - sizeof(dirent_external.d_name) - 1); - strncpy(dirent_external.d_comment, - dirent_internal->comment, - sizeof(dirent_external.d_comment) - 1); + smbw_strlcpy(dirent_external.d_name, + dirent_internal->name, + sizeof(dirent_external.d_name) - 1); + smbw_strlcpy(dirent_external.d_comment, + dirent_internal->comment, + sizeof(dirent_external.d_comment) - 1); return &dirent_external; } -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- examples/libsmbclient/smbwrapper/smbw_dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples/libsmbclient/smbwrapper/smbw_dir.c') diff --git a/examples/libsmbclient/smbwrapper/smbw_dir.c b/examples/libsmbclient/smbwrapper/smbw_dir.c index 986b7f8220..be734c21af 100644 --- a/examples/libsmbclient/smbwrapper/smbw_dir.c +++ b/examples/libsmbclient/smbwrapper/smbw_dir.c @@ -7,7 +7,7 @@ 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 - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 58e9534300430fa4f2bcb50fb2d1d2990bdbe636 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:57:11 +0000 Subject: r23785: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit d0e89d246d8e5e64196d6c1d16d39a70579ca42f) --- examples/libsmbclient/smbwrapper/smbw_dir.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'examples/libsmbclient/smbwrapper/smbw_dir.c') diff --git a/examples/libsmbclient/smbwrapper/smbw_dir.c b/examples/libsmbclient/smbwrapper/smbw_dir.c index be734c21af..6e473bf0a3 100644 --- a/examples/libsmbclient/smbwrapper/smbw_dir.c +++ b/examples/libsmbclient/smbwrapper/smbw_dir.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "smbw.h" -- cgit