From cce5f09a90b5027bafd22f42edab9c256789bce1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 09:39:11 +0000 Subject: added unlink() and rename() support to smbwrapper (This used to be commit b85d96144728e8a29c7c1114462e28bf3b144b80) --- source3/smbwrapper/access.c | 2 +- source3/smbwrapper/chdir.c | 2 +- source3/smbwrapper/lstat.c | 2 +- source3/smbwrapper/open.c | 2 +- source3/smbwrapper/rename.c | 39 +++++++++ source3/smbwrapper/smbw.c | 199 ++++++++++++++++++++++++++++++++----------- source3/smbwrapper/stat.c | 4 +- source3/smbwrapper/unlink.c | 31 +++++++ source3/smbwrapper/wrapper.h | 3 +- 9 files changed, 227 insertions(+), 57 deletions(-) create mode 100644 source3/smbwrapper/rename.c create mode 100644 source3/smbwrapper/unlink.c (limited to 'source3/smbwrapper') diff --git a/source3/smbwrapper/access.c b/source3/smbwrapper/access.c index 4e77113108..5194b32613 100644 --- a/source3/smbwrapper/access.c +++ b/source3/smbwrapper/access.c @@ -21,7 +21,7 @@ #include "wrapper.h" - int access(__const char *name, int mode) + int access(const char *name, int mode) { if (smbw_path(name)) { return smbw_access(name, mode); diff --git a/source3/smbwrapper/chdir.c b/source3/smbwrapper/chdir.c index 41b3772603..3648e4431f 100644 --- a/source3/smbwrapper/chdir.c +++ b/source3/smbwrapper/chdir.c @@ -25,7 +25,7 @@ __asm__(".globl __chdir; __chdir = chdir"); #endif - int chdir(__const char *name) + int chdir(const char *name) { return smbw_chdir(name); } diff --git a/source3/smbwrapper/lstat.c b/source3/smbwrapper/lstat.c index f6298f6e0b..9ddd14662f 100644 --- a/source3/smbwrapper/lstat.c +++ b/source3/smbwrapper/lstat.c @@ -21,7 +21,7 @@ #include "wrapper.h" - int __lxstat(int vers, __const char *name, struct stat *st) + int __lxstat(int vers, const char *name, struct stat *st) { struct kernel_stat kbuf; int ret; diff --git a/source3/smbwrapper/open.c b/source3/smbwrapper/open.c index 8a088eeb19..935e99ad79 100644 --- a/source3/smbwrapper/open.c +++ b/source3/smbwrapper/open.c @@ -26,7 +26,7 @@ __asm__(".globl __open; __open = open"); #endif - int open(__const char *name, int flags, mode_t mode) + int open(const char *name, int flags, mode_t mode) { if (smbw_path(name)) { return smbw_open(name, flags, mode); diff --git a/source3/smbwrapper/rename.c b/source3/smbwrapper/rename.c new file mode 100644 index 0000000000..76041f62eb --- /dev/null +++ b/source3/smbwrapper/rename.c @@ -0,0 +1,39 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + SMB wrapper functions + Copyright (C) Andrew Tridgell 1998 + + 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 "wrapper.h" + + int rename(const char *oldname,const char *newname) +{ + int p1, p2; + p1 = smbw_path(oldname); + p2 = smbw_path(newname); + if (p1 ^ p2) { + /* can't cross filesystem boundaries */ + errno = EXDEV; + return -1; + } + if (p1 && p2) { + return smbw_rename(oldname, newname); + } + + return real_rename(oldname, newname); +} diff --git a/source3/smbwrapper/smbw.c b/source3/smbwrapper/smbw.c index 6726a206b4..dc253d7c32 100644 --- a/source3/smbwrapper/smbw.c +++ b/source3/smbwrapper/smbw.c @@ -219,17 +219,12 @@ void clean_fname(char *name) /***************************************************** parse a smb path into its components. *******************************************************/ -char *smbw_parse_path(char *fname, char **server, char **share, char **path) +char *smbw_parse_path(const char *fname, char *server, char *share, char *path) { - static fstring rshare, rserver; - static pstring rpath, s; + static pstring s; char *p, *p2; int len; - (*server) = rserver; - (*share) = rshare; - (*path) = rpath; - if (fname[0] == '/') { pstrcpy(s, fname); } else { @@ -251,13 +246,15 @@ char *smbw_parse_path(char *fname, char **server, char **share, char **path) len = strlen(p); } - strncpy(rserver, p, len); - rserver[len] = 0; + len = MIN(len,sizeof(fstring)-1); + + strncpy(server, p, len); + server[len] = 0; p = p2; if (!p) { - fstrcpy(rshare,"IPC$"); - fstrcpy(rpath,""); + fstrcpy(share,"IPC$"); + pstrcpy(path,""); goto ok; } @@ -269,24 +266,26 @@ char *smbw_parse_path(char *fname, char **server, char **share, char **path) } else { len = strlen(p); } + + len = MIN(len,sizeof(fstring)-1); - fstrcpy(rshare, p); - rshare[len] = 0; + strncpy(share, p, len); + share[len] = 0; p = p2; if (!p) { - pstrcpy(rpath,"\\"); + pstrcpy(path,"\\"); goto ok; } - pstrcpy(rpath,p); + pstrcpy(path,p); - string_sub(rpath, "/", "\\"); + string_sub(path, "/", "\\"); ok: DEBUG(5,("parsed path name=%s cwd=%s [%s] [%s] [%s]\n", fname, smb_cwd, - *server, *share, *path)); + server, share, path)); return s; } @@ -295,9 +294,10 @@ char *smbw_parse_path(char *fname, char **server, char **share, char **path) determine if a path name (possibly relative) is in the smb name space *******************************************************/ -BOOL smbw_path(char *path) +BOOL smbw_path(const char *path) { - char *server, *share, *s; + fstring server, share; + pstring s; char *cwd; int l; @@ -307,7 +307,7 @@ BOOL smbw_path(char *path) DEBUG(3,("smbw_path(%s)\n", path)); - cwd = smbw_parse_path(path, &server, &share, &s); + cwd = smbw_parse_path(path, server, share, s); l = strlen(SMBW_PREFIX)-1; @@ -324,7 +324,17 @@ return a unix errno from a SMB error pair *******************************************************/ int smbw_errno(struct cli_state *c) { - return cli_error(c, NULL, NULL); + uint8 eclass; + uint32 ecode; + int ret; + + ret = cli_error(c, &eclass, &ecode); + + if (ret) { + DEBUG(3,("smbw_error %d %d (0x%x)\n", + (int)eclass, (int)ecode, (int)ecode)); + } + return ret; } /***************************************************** @@ -540,7 +550,7 @@ void smbw_dir_add(struct file_info *finfo) /***************************************************** add a entry to a directory listing *******************************************************/ -void smbw_share_add(char *share, uint32 type, char *comment) +void smbw_share_add(const char *share, uint32 type, const char *comment) { struct file_info finfo; @@ -556,10 +566,10 @@ void smbw_share_add(char *share, uint32 type, char *comment) /***************************************************** open a directory on the server *******************************************************/ -int smbw_dir_open(const char *fname1, int flags) +int smbw_dir_open(const char *fname, int flags) { - char *fname = strdup(fname1); - char *server, *share, *path; + fstring server, share; + pstring path; struct smbw_server *srv=NULL; struct smbw_dir *dir=NULL; pstring mask; @@ -575,7 +585,7 @@ int smbw_dir_open(const char *fname1, int flags) smbw_init(); /* work out what server they are after */ - smbw_parse_path(fname, &server, &share, &path); + smbw_parse_path(fname, server, share, path); DEBUG(4,("dir_open share=%s\n", share)); @@ -633,7 +643,6 @@ int smbw_dir_open(const char *fname1, int flags) if (dir) { free_dir(dir); } - if (fname) free(fname); return -1; } @@ -642,10 +651,10 @@ int smbw_dir_open(const char *fname1, int flags) /***************************************************** a wrapper for open() *******************************************************/ -int smbw_open(const char *fname1, int flags, mode_t mode) +int smbw_open(const char *fname, int flags, mode_t mode) { - char *fname = strdup(fname1); - char *server, *share, *path; + fstring server, share; + pstring path; struct smbw_server *srv=NULL; int eno, fd = -1; struct smbw_file *file=NULL; @@ -662,7 +671,7 @@ int smbw_open(const char *fname1, int flags, mode_t mode) smbw_busy++; /* work out what server they are after */ - smbw_parse_path(fname, &server, &share, &path); + smbw_parse_path(fname, server, share, path); /* get a connection to the server */ srv = smbw_server(server, share); @@ -677,9 +686,8 @@ int smbw_open(const char *fname1, int flags, mode_t mode) fd = cli_open(&srv->cli, path, flags, DENY_NONE); } if (fd == -1) { - if (fname) free(fname); /* it might be a directory. Maybe we should use chkpath? */ - fd = smbw_dir_open(fname1, flags); + fd = smbw_dir_open(fname, flags); smbw_busy--; return fd; } @@ -716,17 +724,12 @@ int smbw_open(const char *fname1, int flags, mode_t mode) DLIST_ADD(smbw_files, file); - DEBUG(4,("opened %s\n", fname1)); - - free(fname); + DEBUG(4,("opened %s\n", fname)); smbw_busy--; return file->fd; failed: - if (fname) { - free(fname); - } if (fd != -1) { cli_close(&srv->cli, fd); } @@ -809,16 +812,16 @@ int smbw_fstat(int fd, struct stat *st) /***************************************************** a wrapper for stat() *******************************************************/ -int smbw_stat(char *fname1, struct stat *st) +int smbw_stat(const char *fname, struct stat *st) { struct smbw_server *srv; - char *server, *share, *path; - char *fname = strdup(fname1); + fstring server, share; + pstring path; time_t m_time=0, a_time=0, c_time=0; size_t size=0; uint32 mode=0; - DEBUG(4,("%s (%s)\n", __FUNCTION__, fname1)); + DEBUG(4,("%s (%s)\n", __FUNCTION__, fname)); if (!fname) { errno = EINVAL; @@ -830,7 +833,7 @@ int smbw_stat(char *fname1, struct stat *st) smbw_busy++; /* work out what server they are after */ - smbw_parse_path(fname, &server, &share, &path); + smbw_parse_path(fname, server, share, path); /* get a connection to the server */ srv = smbw_server(server, share); @@ -859,7 +862,6 @@ int smbw_stat(char *fname1, struct stat *st) return 0; failed: - if (fname) free(fname); smbw_busy--; return -1; } @@ -1046,7 +1048,7 @@ int smbw_getdents(unsigned int fd, struct dirent *dirp, int count) /***************************************************** a wrapper for access() *******************************************************/ -int smbw_access(char *name, int mode) +int smbw_access(const char *name, int mode) { struct stat st; /* how do we map this properly ?? */ @@ -1056,7 +1058,7 @@ int smbw_access(char *name, int mode) /***************************************************** a wrapper for realink() - needed for correct errno setting *******************************************************/ -int smbw_readlink(char *path, char *buf, size_t bufsize) +int smbw_readlink(const char *path, char *buf, size_t bufsize) { struct stat st; int ret; @@ -1078,10 +1080,11 @@ int smbw_readlink(char *path, char *buf, size_t bufsize) /***************************************************** a wrapper for chdir() *******************************************************/ -int smbw_chdir(char *name) +int smbw_chdir(const char *name) { struct smbw_server *srv; - char *server, *share, *path; + fstring server, share; + pstring path; uint32 mode = aDIR; char *cwd; @@ -1099,7 +1102,7 @@ int smbw_chdir(char *name) DEBUG(4,("%s (%s)\n", __FUNCTION__, name)); /* work out what server they are after */ - cwd = smbw_parse_path(name, &server, &share, &path); + cwd = smbw_parse_path(name, server, share, path); if (strncmp(cwd,SMBW_PREFIX,strlen(SMBW_PREFIX))) { if (real_chdir(cwd) == 0) { @@ -1151,3 +1154,99 @@ int smbw_chdir(char *name) return -1; } + +/***************************************************** +a wrapper for unlink() +*******************************************************/ +int smbw_unlink(const char *fname) +{ + struct smbw_server *srv; + fstring server, share; + pstring path; + + DEBUG(4,("%s (%s)\n", __FUNCTION__, fname)); + + if (!fname) { + errno = EINVAL; + return -1; + } + + smbw_init(); + + smbw_busy++; + + /* work out what server they are after */ + smbw_parse_path(fname, server, share, path); + + /* get a connection to the server */ + srv = smbw_server(server, share); + if (!srv) { + /* smbw_server sets errno */ + goto failed; + } + + if (!cli_unlink(&srv->cli, path)) { + errno = smbw_errno(&srv->cli); + goto failed; + } + + smbw_busy--; + return 0; + + failed: + smbw_busy--; + return -1; +} + + +/***************************************************** +a wrapper for rename() +*******************************************************/ +int smbw_rename(const char *oldname, const char *newname) +{ + struct smbw_server *srv; + fstring server1, share1; + pstring path1; + fstring server2, share2; + pstring path2; + + DEBUG(4,("%s (%s, %s)\n", __FUNCTION__, oldname, newname)); + + if (!oldname || !newname) { + errno = EINVAL; + return -1; + } + + smbw_init(); + + smbw_busy++; + + /* work out what server they are after */ + smbw_parse_path(oldname, server1, share1, path1); + smbw_parse_path(newname, server2, share2, path2); + + if (strcmp(server1, server2) || strcmp(share1, share2)) { + /* can't cross filesystems */ + errno = EXDEV; + return -1; + } + + /* get a connection to the server */ + srv = smbw_server(server1, share1); + if (!srv) { + /* smbw_server sets errno */ + goto failed; + } + + if (!cli_rename(&srv->cli, path1, path2)) { + errno = smbw_errno(&srv->cli); + goto failed; + } + + smbw_busy--; + return 0; + + failed: + smbw_busy--; + return -1; +} diff --git a/source3/smbwrapper/stat.c b/source3/smbwrapper/stat.c index 8980f75f97..6721d41211 100644 --- a/source3/smbwrapper/stat.c +++ b/source3/smbwrapper/stat.c @@ -21,7 +21,7 @@ #include "wrapper.h" - int __xstat(int vers, __const char *name, struct stat *st) + int __xstat(int vers, const char *name, struct stat *st) { struct kernel_stat kbuf; int ret; @@ -83,7 +83,7 @@ } } - int stat(__const char *name, struct stat *st) + int stat(const char *name, struct stat *st) { return __xstat(_STAT_VER, name, st); } diff --git a/source3/smbwrapper/unlink.c b/source3/smbwrapper/unlink.c new file mode 100644 index 0000000000..827485c095 --- /dev/null +++ b/source3/smbwrapper/unlink.c @@ -0,0 +1,31 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + SMB wrapper functions + Copyright (C) Andrew Tridgell 1998 + + 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 "wrapper.h" + + int unlink(const char *name) +{ + if (smbw_path(name)) { + return smbw_unlink(name); + } + + return real_unlink(name); +} diff --git a/source3/smbwrapper/wrapper.h b/source3/smbwrapper/wrapper.h index 3c42c228e0..d2f52dbd6c 100644 --- a/source3/smbwrapper/wrapper.h +++ b/source3/smbwrapper/wrapper.h @@ -1,3 +1,5 @@ +#include "config.h" + #include #include #include @@ -6,4 +8,3 @@ #include #include "kernel_stat.h" #include "realcalls.h" - -- cgit