From 7bb86c1b132bce31a006ea9768a54db7a45fe1a5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Sep 1998 18:40:31 +0000 Subject: Ok - this is the 64 bit widening check in. It changes the configure to check for stat64 and friends, and then changes much of Samba to use the data type SMB_OFF_T for file size information. stat/fstat/lstat/lseek/ftruncate have now become sys_stat etc. to hide the 64 bit calls if needed. Note that this still does not expose 64 bit functionality to the client, as the changes to the reply_xxx smb's are not yet done. This code change should make these changes possible. Still to do before full 64 bit-ness to the client: fcntl lock code. statfs code widening of dev_t and ino_t (now possible due to SMB_DEV_T and SMB_OFF_T types being in place). Let me know if wierd things happen after this check-in and I'll fix them :-). Jeremy. (This used to be commit 14500936c321d15995c963766aac67bf1f4e3824) --- source3/lib/charset.c | 9 ++- source3/lib/debug.c | 2 +- source3/lib/netatalk.c | 2 +- source3/lib/replace.c | 2 +- source3/lib/smbrun.c | 2 +- source3/lib/system.c | 171 +++++++++++++++++++++++++++++++------------------ source3/lib/util.c | 114 +++++++++++++++++---------------- 7 files changed, 176 insertions(+), 126 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/charset.c b/source3/lib/charset.c index 55b76f2667..08d7726e3b 100644 --- a/source3/lib/charset.c +++ b/source3/lib/charset.c @@ -189,7 +189,7 @@ static codepage_p load_client_codepage( int client_codepage ) pstring codepage_file_name; unsigned char buf[8]; FILE *fp = NULL; - unsigned int size; + SMB_OFF_T size; codepage_p cp_p = NULL; SMB_STRUCT_STAT st; @@ -221,7 +221,7 @@ static codepage_p load_client_codepage( int client_codepage ) plus zero or more bytes of data. Note that the data cannot be more than 4 * MAXCODEPAGELINES bytes. */ - size = (unsigned int)st.st_size; + size = st.st_size; if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 4 * MAXCODEPAGELINES)) { @@ -270,11 +270,10 @@ Needed %hu, got %hu.\n", } /* Check the length is correct. */ - if(IVAL(buf,CODEPAGE_LENGTH_OFFSET) != - (unsigned int)(size - CODEPAGE_HEADER_SIZE)) + if(IVAL(buf,CODEPAGE_LENGTH_OFFSET) != (size - CODEPAGE_HEADER_SIZE)) { DEBUG(0,("load_client_codepage: filename %s has incorrect size headers. \ -Needed %u, got %u.\n", codepage_file_name, size - CODEPAGE_HEADER_SIZE, +Needed %u, got %u.\n", codepage_file_name, (uint32)(size - CODEPAGE_HEADER_SIZE), IVAL(buf,CODEPAGE_LENGTH_OFFSET))); goto clean_and_exit; } diff --git a/source3/lib/debug.c b/source3/lib/debug.c index f5a0eadb96..5f6ad5273a 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -258,7 +258,7 @@ static void check_log_size( void ) if( !dbf || maxlog <= 0 ) return; - if( fstat( fileno( dbf ), &st ) == 0 && st.st_size > maxlog ) + if( sys_fstat( fileno( dbf ), &st ) == 0 && st.st_size > maxlog ) { (void)fclose( dbf ); dbf = NULL; diff --git a/source3/lib/netatalk.c b/source3/lib/netatalk.c index 421d74f3c5..ae0a57154e 100644 --- a/source3/lib/netatalk.c +++ b/source3/lib/netatalk.c @@ -94,7 +94,7 @@ int ntalk_mkresdir(const char *fname) } lastslash++; fdir[lastslash] = 0; - lstat(fdir, &dirstats); + sys_lstat(fdir, &dirstats); /* append .AppleDouble */ for (i = 0; (appledouble[i] != 0) && (lastslash <= 254); i++) { diff --git a/source3/lib/replace.c b/source3/lib/replace.c index 1421233c1e..6441efe44c 100644 --- a/source3/lib/replace.c +++ b/source3/lib/replace.c @@ -32,7 +32,7 @@ extern int DEBUGLEVEL; /******************************************************************* ftruncate for operating systems that don't have it ********************************************************************/ - int ftruncate(int f,long l) + int ftruncate(int f,SMB_OFF_T l) { struct flock fl; diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c index 56fcd68ec1..d2abf0e952 100644 --- a/source3/lib/smbrun.c +++ b/source3/lib/smbrun.c @@ -50,7 +50,7 @@ static BOOL setup_stdout_file(char *outfile,BOOL shared) #endif } - if(stat(outfile, &st) == 0) { + if(sys_stat(outfile, &st) == 0) { /* Check we're not deleting a device file. */ if(st.st_mode & S_IFREG) unlink(outfile); diff --git a/source3/lib/system.c b/source3/lib/system.c index bc8860cdb9..b6a59e8648 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -139,6 +139,70 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval) #endif /* USE_POLL */ #endif /* NO_SELECT */ +/******************************************************************* +A stat() wrapper that will deal with 64 bit filesizes. +********************************************************************/ + +int sys_stat(char *fname,SMB_STRUCT_STAT *sbuf) +{ +#if defined(HAVE_OFF64_T) && defined(HAVE_STAT64) + return stat64(fname, sbuf); +#else + return stat(fname, sbuf); +#endif +} + +/******************************************************************* + An fstat() wrapper that will deal with 64 bit filesizes. +********************************************************************/ + +int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf) +{ +#if defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64) + return fstat64(fd, sbuf); +#else + return fstat(fd, sbuf); +#endif +} + +/******************************************************************* + An lstat() wrapper that will deal with 64 bit filesizes. +********************************************************************/ + +int sys_lstat(char *fname,SMB_STRUCT_STAT *sbuf) +{ +#if defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64) + return lstat64(fname, sbuf); +#else + return lstat(fname, sbuf); +#endif +} + +/******************************************************************* + An ftruncate() wrapper that will deal with 64 bit filesizes. +********************************************************************/ + +int sys_ftruncate(int fd, SMB_OFF_T offset) +{ +#if defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64) + return ftruncate64(fd, offset); +#else + return ftruncate(fd, offset); +#endif +} + +/******************************************************************* + An lseek() wrapper that will deal with 64 bit filesizes. +********************************************************************/ + +int sys_lseek(int fd, SMB_OFF_T offset, int whence) +{ +#if defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64) + return lseek64(fd, offset, whence); +#else + return lseek(fd, offset, whence); +#endif +} /******************************************************************* just a unlink wrapper that calls dos_to_unix. @@ -166,13 +230,12 @@ DIR *dos_opendir(char *dname) return(opendir(dos_to_unix(dname,False))); } - /******************************************************************* and a stat() wrapper that calls dos_to_unix. ********************************************************************/ int dos_stat(char *fname,SMB_STRUCT_STAT *sbuf) { - return(stat(dos_to_unix(fname,False),sbuf)); + return(sys_stat(dos_to_unix(fname,False),sbuf)); } /******************************************************************* @@ -192,10 +255,9 @@ don't forget lstat() that calls dos_to_unix. ********************************************************************/ int dos_lstat(char *fname,SMB_STRUCT_STAT *sbuf) { - return(lstat(dos_to_unix(fname,False),sbuf)); + return(sys_lstat(dos_to_unix(fname,False),sbuf)); } - /******************************************************************* mkdir() gets a wrapper that calls dos_to_unix. ********************************************************************/ @@ -204,7 +266,6 @@ int dos_mkdir(char *dname,int mode) return(mkdir(dos_to_unix(dname,False),mode)); } - /******************************************************************* do does rmdir() - call dos_to_unix ********************************************************************/ @@ -213,7 +274,6 @@ int dos_rmdir(char *dname) return(rmdir(dos_to_unix(dname,False))); } - /******************************************************************* I almost forgot chdir() - call dos_to_unix. ********************************************************************/ @@ -222,7 +282,6 @@ int dos_chdir(char *dname) return(chdir(dos_to_unix(dname,False))); } - /******************************************************************* now for utime() - call dos_to_unix. ********************************************************************/ @@ -253,64 +312,57 @@ static int copy_reg(char *source, const char *dest) char *buf; int len; /* Number of bytes read into `buf'. */ - lstat (source, &source_stats); + sys_lstat (source, &source_stats); if (!S_ISREG (source_stats.st_mode)) - { - return 1; - } + return 1; if (unlink (dest) && errno != ENOENT) - { - return 1; - } + return 1; if((ifd = open (source, O_RDONLY, 0)) < 0) - { - return 1; - } + return 1; + if((ofd = open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 ) - { - close (ifd); - return 1; - } + { + close (ifd); + return 1; + } if((buf = malloc( COPYBUF_SIZE )) == NULL) - { - close (ifd); - close (ofd); - unlink (dest); - return 1; - } + { + close (ifd); + close (ofd); + unlink (dest); + return 1; + } while ((len = read(ifd, buf, COPYBUF_SIZE)) > 0) - { - if (write_data(ofd, buf, len) < 0) - { - close (ifd); - close (ofd); - unlink (dest); - free(buf); - return 1; - } - } - free(buf); - if (len < 0) + { + if (write_data(ofd, buf, len) < 0) { close (ifd); close (ofd); unlink (dest); + free(buf); return 1; } + } + free(buf); + if (len < 0) + { + close (ifd); + close (ofd); + unlink (dest); + return 1; + } if (close (ifd) < 0) - { - close (ofd); - return 1; - } + { + close (ofd); + return 1; + } if (close (ofd) < 0) - { - return 1; - } + return 1; /* chown turns off set[ug]id bits for non-root, so do the chmod last. */ @@ -322,23 +374,18 @@ static int copy_reg(char *source, const char *dest) tv.actime = source_stats.st_atime; tv.modtime = source_stats.st_mtime; if (utime (dest, &tv)) - { - return 1; - } + return 1; } /* Try to preserve ownership. For non-root it might fail, but that's ok. But root probably wants to know, e.g. if NFS disallows it. */ if (chown (dest, source_stats.st_uid, source_stats.st_gid) && (errno != EPERM)) - { - return 1; - } + return 1; if (chmod (dest, source_stats.st_mode & 07777)) - { - return 1; - } + return 1; + unlink (source); return 0; } @@ -356,10 +403,10 @@ int dos_rename(char *from, char *to) rcode = rename (zfrom, zto); if (errno == EXDEV) - { - /* Rename across filesystems needed. */ - rcode = copy_reg (zfrom, zto); - } + { + /* Rename across filesystems needed. */ + rcode = copy_reg (zfrom, zto); + } return rcode; } @@ -372,9 +419,10 @@ int dos_chmod(char *fname,int mode) } /******************************************************************* -for getwd +for getwd - takes a UNIX directory name and returns the name +in dos format. ********************************************************************/ -char *sys_getwd(char *s) +char *dos_getwd(char *s) { char *wd; #ifdef HAVE_GETCWD @@ -459,4 +507,3 @@ struct hostent *sys_gethostbyname(char *name) return(gethostbyname(name)); #endif /* REDUCE_ROOT_DNS_LOOKUPS */ } - diff --git a/source3/lib/util.c b/source3/lib/util.c index 8b10939a97..891b11facc 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -566,7 +566,7 @@ BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st) /******************************************************************* returns the size in bytes of the named file ********************************************************************/ -uint32 file_size(char *file_name) +SMB_OFF_T file_size(char *file_name) { SMB_STRUCT_STAT buf; buf.st_size = 0; @@ -1218,15 +1218,15 @@ struct { SMB_DEV_T dev; /* These *must* be compatible with the types returned in a stat() call. */ SMB_INO_T inode; /* These *must* be compatible with the types returned in a stat() call. */ - char *text; + char *text; /* The pathname in DOS format. */ BOOL valid; } ino_list[MAX_GETWDCACHE]; BOOL use_getwd_cache=True; /******************************************************************* - return the absolute current directory path - Note that this path is returned in UNIX format, not DOS + return the absolute current directory path - given a UNIX pathname. + Note that this path is returned in DOS format, not UNIX format. ********************************************************************/ char *GetWd(char *str) @@ -1239,7 +1239,7 @@ char *GetWd(char *str) *s = 0; if (!use_getwd_cache) - return(sys_getwd(str)); + return(dos_getwd(str)); /* init the cache */ if (!getwd_cache_init) @@ -1255,10 +1255,10 @@ char *GetWd(char *str) /* Get the inode of the current directory, if this doesn't work we're in trouble :-) */ - if (stat(".",&st) == -1) + if (dos_stat(".",&st) == -1) { DEBUG(0,("Very strange, couldn't stat \".\"\n")); - return(sys_getwd(str)); + return(dos_getwd(str)); } @@ -1275,7 +1275,7 @@ char *GetWd(char *str) if (st.st_ino == ino_list[i].inode && st.st_dev == ino_list[i].dev) { - if (stat(ino_list[i].text,&st2) == 0) + if (dos_stat(ino_list[i].text,&st2) == 0) { if (st.st_ino == st2.st_ino && st.st_dev == st2.st_dev && @@ -1302,7 +1302,7 @@ char *GetWd(char *str) The very slow getcwd, which spawns a process on some systems, or the not quite so bad getwd. */ - if (!sys_getwd(s)) + if (!dos_getwd(s)) { DEBUG(0,("Getwd failed, errno %s\n",strerror(errno))); return (NULL); @@ -1692,7 +1692,7 @@ int count_chars(char *s,char c) /**************************************************************************** make a dir struct ****************************************************************************/ -void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date) +void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date) { char *p; pstring mask2; @@ -1717,7 +1717,7 @@ void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode CVAL(buf,21) = mode; put_dos_date(buf,22,date); SSVAL(buf,26,size & 0xFFFF); - SSVAL(buf,28,size >> 16); + SSVAL(buf,28,(size >> 16)&0xFFFF); StrnCpy(buf+30,fname,12); if (!case_sensitive) strupper(buf+30); @@ -2054,14 +2054,18 @@ int write_data(int fd,char *buffer,int N) /**************************************************************************** transfer some data between two fd's ****************************************************************************/ -int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align) +SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align) { static char *buf=NULL; static int size=0; char *buf1,*abuf; - int total = 0; + SMB_OFF_T total = 0; - DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen)); +#ifdef LARGE_SMB_OFF_T + DEBUG(4,("transfer_file n=%.0f (head=%d) called\n",(double)n,headlen)); +#else /* LARGE_SMB_OFF_T */ + DEBUG(4,("transfer_file n=%d (head=%d) called\n",n,headlen)); +#endif /* LARGE_SMB_OFF_T */ if (size == 0) { size = lp_readsize(); @@ -2084,46 +2088,46 @@ int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align) n += headlen; while (n > 0) - { - int s = MIN(n,size); - int ret,ret2=0; + { + int s = (int)MIN(n,(SMB_OFF_T)size); + int ret,ret2=0; - ret = 0; + ret = 0; - if (header && (headlen >= MIN(s,1024))) { - buf1 = header; - s = headlen; - ret = headlen; - headlen = 0; - header = NULL; - } else { - buf1 = abuf; - } + if (header && (headlen >= MIN(s,1024))) { + buf1 = header; + s = headlen; + ret = headlen; + headlen = 0; + header = NULL; + } else { + buf1 = abuf; + } - if (header && headlen > 0) - { - ret = MIN(headlen,size); - memcpy(buf1,header,ret); - headlen -= ret; - header += ret; - if (headlen <= 0) header = NULL; - } + if (header && headlen > 0) + { + ret = MIN(headlen,size); + memcpy(buf1,header,ret); + headlen -= ret; + header += ret; + if (headlen <= 0) header = NULL; + } - if (s > ret) - ret += read(infd,buf1+ret,s-ret); + if (s > ret) + ret += read(infd,buf1+ret,s-ret); - if (ret > 0) - { - ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret); - if (ret2 > 0) total += ret2; - /* if we can't write then dump excess data */ - if (ret2 != ret) - transfer_file(infd,-1,n-(ret+headlen),NULL,0,0); - } - if (ret <= 0 || ret2 != ret) - return(total); - n -= ret; + if (ret > 0) + { + ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret); + if (ret2 > 0) total += ret2; + /* if we can't write then dump excess data */ + if (ret2 != ret) + transfer_file(infd,-1,n-(ret+headlen),NULL,0,0); } + if (ret <= 0 || ret2 != ret) + return(total); + n -= ret; + } return(total); } @@ -3261,18 +3265,18 @@ char *fgets_slash(char *s2,int maxlen,FILE *f) set the length of a file from a filedescriptor. Returns 0 on success, -1 on failure. ****************************************************************************/ -int set_filelen(int fd, long len) +int set_filelen(int fd, SMB_OFF_T len) { /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot extend a file with ftruncate. Provide alternate implementation for this */ #ifdef HAVE_FTRUNCATE_EXTEND - return ftruncate(fd, len); + return sys_ftruncate(fd, len); #else SMB_STRUCT_STAT st; char c = 0; - long currpos = lseek(fd, 0L, SEEK_CUR); + SMB_OFF_T currpos = sys_lseek(fd, (SMB_OFF_T)0, SEEK_CUR); if(currpos < 0) return -1; @@ -3280,7 +3284,7 @@ int set_filelen(int fd, long len) the requested size (call ftruncate), or shorter, in which case seek to len - 1 and write 1 byte of zero */ - if(fstat(fd, &st)<0) + if(sys_fstat(fd, &st)<0) return -1; #ifdef S_ISFIFO @@ -3290,14 +3294,14 @@ int set_filelen(int fd, long len) if(st.st_size == len) return 0; if(st.st_size > len) - return ftruncate(fd, len); + return sys_ftruncate(fd, len); - if(lseek(fd, len-1, SEEK_SET) != len -1) + if(sys_lseek(fd, len-1, SEEK_SET) != len -1) return -1; if(write(fd, &c, 1)!=1) return -1; /* Seek to where we were */ - lseek(fd, currpos, SEEK_SET); + sys_lseek(fd, currpos, SEEK_SET); return 0; #endif } -- cgit