diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/smb.h | 1 | ||||
-rw-r--r-- | source3/libsmb/clientgen.c | 6 | ||||
-rw-r--r-- | source3/smbd/reply.c | 2 | ||||
-rw-r--r-- | source3/smbwrapper/smbw.c | 30 | ||||
-rw-r--r-- | source3/smbwrapper/smbw_dir.c | 2 |
5 files changed, 34 insertions, 7 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h index 56b0e3bc24..05ea1bf7c7 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -216,6 +216,7 @@ implemented */ #define ERRfilexists 80 /* File in operation already exists */ #define ERRcannotopen 110 /* Cannot open the file specified */ #define ERRunknownlevel 124 +#define ERRrename 183 #define ERRbadpipe 230 /* Named pipe invalid */ #define ERRpipebusy 231 /* All instances of pipe are busy */ #define ERRpipeclosing 232 /* named pipe close in progress */ diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2d49144695..93f7a3d222 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1196,6 +1196,8 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t int mid; int blocks = (size + (block-1)) / block; + if (size == 0) return 0; + while (received < blocks) { int size2; @@ -1295,6 +1297,8 @@ size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ int mid; int blocks = (size + (block-1)) / block; + if (size == 0) return 0; + while (received < blocks) { int size2; @@ -2309,6 +2313,8 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case ERRbadfile: return ENOENT; case ERRbadpath: return ENOTDIR; case ERRnoaccess: return EACCES; + case ERRfilexists: return EEXIST; + case ERRrename: return EEXIST; } } if (rcls == ERRSRV) { diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 12a39589d6..6dfff54a0f 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3210,7 +3210,7 @@ int rename_internals(connection_struct *conn, if (!count) exists = file_exist(directory,NULL); if (!count && exists && file_exist(newname,NULL)) { exists = True; - error = 183; + error = ERRrename; } } else { /* diff --git a/source3/smbwrapper/smbw.c b/source3/smbwrapper/smbw.c index 6096f096a3..6b8796fb5d 100644 --- a/source3/smbwrapper/smbw.c +++ b/source3/smbwrapper/smbw.c @@ -647,6 +647,8 @@ ssize_t smbw_read(int fd, void *buf, size_t count) struct smbw_file *file; int ret; + DEBUG(4,("smbw_read(%d, %d)\n", fd, (int)count)); + smbw_busy++; file = smbw_file(fd); @@ -666,6 +668,8 @@ ssize_t smbw_read(int fd, void *buf, size_t count) } file->f->offset += ret; + + DEBUG(4,(" -> %d\n", ret)); smbw_busy--; return ret; @@ -793,8 +797,19 @@ a wrapper for access() int smbw_access(const char *name, int mode) { struct stat st; - /* how do we map this properly ?? */ - return smbw_stat(name, &st); + + DEBUG(4,("smbw_access(%s, 0x%x)\n", name, mode)); + + if (smbw_stat(name, &st)) return -1; + + if (((mode & R_OK) && !(st.st_mode & S_IRUSR)) || + ((mode & W_OK) && !(st.st_mode & S_IWUSR)) || + ((mode & X_OK) && !(st.st_mode & S_IXUSR))) { + errno = EACCES; + return -1; + } + + return 0; } /***************************************************** @@ -887,6 +902,8 @@ int smbw_rename(const char *oldname, const char *newname) smbw_init(); + DEBUG(4,("smbw_rename(%s,%s)\n", oldname, newname)); + smbw_busy++; /* work out what server they are after */ @@ -907,8 +924,13 @@ int smbw_rename(const char *oldname, const char *newname) } if (!cli_rename(&srv->cli, path1, path2)) { - errno = smbw_errno(&srv->cli); - goto failed; + int eno = smbw_errno(&srv->cli); + if (eno != EEXIST || + !cli_unlink(&srv->cli, path2) || + !cli_rename(&srv->cli, path1, path2)) { + errno = eno; + goto failed; + } } smbw_busy--; diff --git a/source3/smbwrapper/smbw_dir.c b/source3/smbwrapper/smbw_dir.c index 2c1b7ef9ec..f6d648b91f 100644 --- a/source3/smbwrapper/smbw_dir.c +++ b/source3/smbwrapper/smbw_dir.c @@ -320,8 +320,6 @@ int smbw_getdents(unsigned int fd, struct dirent *dirp, int count) return -1; } - DEBUG(4,("sizeof(*dirp)=%d\n", sizeof(*dirp))); - while (count>=DIRP_SIZE && (dir->offset < dir->count)) { dirp->d_off = (dir->offset+1)*DIRP_SIZE; dirp->d_reclen = DIRP_SIZE; |