From f651787785c0a8f2884e254723eeb26512a76e2a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 12:33:34 +0000 Subject: added lseek() support for directories (This used to be commit 67ca971b0b00b5256b0af2c1c5777c393f9cef0b) --- source3/include/proto.h | 2 +- source3/smbwrapper/lseek.c | 35 ++++++++++++++++++++++++++++++ source3/smbwrapper/realcalls.h | 1 + source3/smbwrapper/smbw.c | 49 +++++++++++++++++++++++++++++++++++++++--- source3/utils/torture.c | 4 ++-- 5 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 source3/smbwrapper/lseek.c (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index f2324fda47..7eb3e1abc2 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -286,7 +286,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout); BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout); BOOL send_smb(int fd,char *buffer); int name_extract(char *buf,int ofs,char *name); -int name_len( char *s ); +int name_len(unsigned char *s); BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type); void msleep(int t); BOOL in_list(char *s,char *list,BOOL casesensitive); diff --git a/source3/smbwrapper/lseek.c b/source3/smbwrapper/lseek.c new file mode 100644 index 0000000000..3507dab690 --- /dev/null +++ b/source3/smbwrapper/lseek.c @@ -0,0 +1,35 @@ +/* + 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" + +#ifdef linux +__asm__(".globl __lseek; __lseek = lseek"); +#endif + + ssize_t lseek(int fd, off_t offset, int whence) +{ + if (smbw_fd(fd)) { + return smbw_lseek(fd, offset, whence); + } + + return real_lseek(fd, offset, whence); +} diff --git a/source3/smbwrapper/realcalls.h b/source3/smbwrapper/realcalls.h index ef173c8964..898a94eeb4 100644 --- a/source3/smbwrapper/realcalls.h +++ b/source3/smbwrapper/realcalls.h @@ -32,6 +32,7 @@ struct dirent *__libc_readdir(DIR * dir); #define real_stat(fn, buf ) (syscall(SYS_stat, (fn), (buf))) #define real_fstat(fd, buf ) (syscall(SYS_fstat, (fd), (buf))) #define real_read(fd, buf, count ) (syscall(SYS_read, (fd), (buf), (count))) +#define real_lseek(fd, offset, whence) (syscall(SYS_lseek, (fd), (offset), (whence))) #define real_write(fd, buf, count ) (syscall(SYS_write, (fd), (buf), (count))) #define real_close(fd) (syscall(SYS_close, (fd))) #define real_fcntl(fd,cmd,arg) (syscall(SYS_fcntl, (fd), (cmd), (arg))) diff --git a/source3/smbwrapper/smbw.c b/source3/smbwrapper/smbw.c index 5392cf1abc..d77f33c97e 100644 --- a/source3/smbwrapper/smbw.c +++ b/source3/smbwrapper/smbw.c @@ -654,6 +654,8 @@ int smbw_dir_open(const char *fname, int flags) dir->fd = fd + SMBW_FD_OFFSET; + DEBUG(4,(" -> %d\n", dir->count)); + return dir->fd; failed: @@ -1053,6 +1055,9 @@ int smbw_getdents(unsigned int fd, struct dirent *dirp, int count) sizeof(dirp->d_name)-1); dir->offset++; count -= dirp->d_reclen; + if (dir->offset == dir->count) { + dirp->d_off = -1; + } dirp++; n++; } @@ -1410,10 +1415,48 @@ int smbw_chmod(const char *fname, mode_t newmode) return -1; } + +/***************************************************** +a wrapper for lseek() on directories +*******************************************************/ +off_t smbw_dir_lseek(int fd, off_t offset, int whence) +{ + struct smbw_dir *dir; + off_t ret; + + DEBUG(4,("%s offset=%d whence=%d\n", __FUNCTION__, + (int)offset, whence)); + + dir = smbw_dir(fd); + if (!dir) { + errno = EBADF; + return -1; + } + + switch (whence) { + case SEEK_SET: + dir->offset = offset/sizeof(struct dirent); + break; + case SEEK_CUR: + dir->offset += offset/sizeof(struct dirent); + break; + case SEEK_END: + dir->offset = (dir->count * sizeof(struct dirent)) + offset; + dir->offset /= sizeof(struct dirent); + break; + } + + ret = dir->offset * sizeof(struct dirent); + + DEBUG(4,(" -> %d\n", (int)ret)); + + return ret; +} + /***************************************************** a wrapper for lseek() *******************************************************/ -ssize_t smbw_lseek(int fd, off_t offset, int whence) +off_t smbw_lseek(int fd, off_t offset, int whence) { struct smbw_file *file; uint32 size; @@ -1424,9 +1467,9 @@ ssize_t smbw_lseek(int fd, off_t offset, int whence) file = smbw_file(fd); if (!file) { - errno = EBADF; + off_t ret = smbw_dir_lseek(fd, offset, whence); smbw_busy--; - return -1; + return ret; } switch (whence) { diff --git a/source3/utils/torture.c b/source3/utils/torture.c index 1cf1f2fe4d..e7bd347993 100644 --- a/source3/utils/torture.c +++ b/source3/utils/torture.c @@ -758,7 +758,7 @@ static void run_trans2test(void) { static struct cli_state cli; int fnum; - uint32 size; + size_t size; time_t c_time, a_time, m_time, w_time, m_time2; char *fname = "\\trans2.tst"; char *dname = "\\trans2"; @@ -773,7 +773,7 @@ static void run_trans2test(void) cli_unlink(&cli, fname); fnum = cli_open(&cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE); - if (!cli_qfileinfo(&cli, fnum, &c_time, &a_time, &m_time, &size, NULL)) { + if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time)) { printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli)); } cli_close(&cli, fnum); -- cgit