diff options
Diffstat (limited to 'util')
-rw-r--r-- | util/ChangeLog | 6 | ||||
-rw-r--r-- | util/fileutil.c | 3 | ||||
-rw-r--r-- | util/iobuf.c | 55 |
3 files changed, 56 insertions, 8 deletions
diff --git a/util/ChangeLog b/util/ChangeLog index be2e764fa..e4e8a83f0 100644 --- a/util/ChangeLog +++ b/util/ChangeLog @@ -1,3 +1,9 @@ +2005-09-22 Werner Koch <[email protected]> + + * iobuf.c (iobuf_get_filelength): New arg OVERFLOW. + (iobuf_get_filelength) [W32]: Use GetFileSizeEx if available. + * fileutil.c (is_file_compressed): Take care of the OVERFLOW + 2005-08-31 David Shaw <[email protected]> * fileutil.c (untilde): New. Expand ~/foo and ~username/foo diff --git a/util/fileutil.c b/util/fileutil.c index c956b4fec..5834e3d89 100644 --- a/util/fileutil.c +++ b/util/fileutil.c @@ -253,6 +253,7 @@ is_file_compressed( const char *s, int *ret_rc ) IOBUF a; byte buf[4]; int i, rc = 0; + int overflow; struct magic_compress_s { size_t len; @@ -272,7 +273,7 @@ is_file_compressed( const char *s, int *ret_rc ) return 0; } - if ( iobuf_get_filelength( a ) < 4 ) { + if ( iobuf_get_filelength( a, &overflow ) < 4 && !overflow) { *ret_rc = 0; goto leave; } diff --git a/util/iobuf.c b/util/iobuf.c index 2c6259449..0f534fadf 100644 --- a/util/iobuf.c +++ b/util/iobuf.c @@ -41,6 +41,7 @@ #include "memory.h" #include "util.h" +#include "dynload.h" #include "iobuf.h" #undef FILE_FILTER_USES_STDIO @@ -1830,14 +1831,17 @@ iobuf_set_limit( IOBUF a, off_t nlimit ) -/**************** - * Return the length of an open file - */ +/* Return the length of an open file A. IF OVERFLOW is not NULL it + will be set to true if the file is larger than what off_t can cope + with. The function return 0 on error or on overflow condition. */ off_t -iobuf_get_filelength( IOBUF a ) +iobuf_get_filelength (IOBUF a, int *overflow ) { struct stat st; + if (overflow) + *overflow = 0; + if( a->directfp ) { FILE *fp = a->directfp; @@ -1855,9 +1859,46 @@ iobuf_get_filelength( IOBUF a ) #if defined(HAVE_DOSISH_SYSTEM) && !defined(FILE_FILTER_USES_STDIO) ulong size; - - if ((size=GetFileSize (fp, NULL)) != 0xffffffff) - return size; + static int (* __stdcall get_file_size_ex) + (void *handle, LARGE_INTEGER *size); + static int get_file_size_ex_initialized; + + if (!get_file_size_ex_initialized) + { + void *handle; + + handle = dlopen ("kernel32.dll", RTLD_LAZY); + if (handle) + { + get_file_size_ex = dlsym (handle, "GetFileSizeEx"); + if (!get_file_size_ex) + dlclose (handle); + } + get_file_size_ex_initialized = 1; + } + + if (get_file_size_ex) + { + /* This is a newer system with GetFileSizeEx; we use + this then becuase it seem that GetFileSize won't + return a proper error in case a file is larger than + 4GB. */ + LARGE_INTEGER size; + + if (get_file_size_ex (fp, &size)) + { + if (!size.u.HighPart) + return size.u.LowPart; + if (overflow) + *overflow = 1; + return 0; + } + } + else + { + if ((size=GetFileSize (fp, NULL)) != 0xffffffff) + return size; + } log_error ("GetFileSize for handle %p failed: %s\n", fp, w32_strerror (0)); #else |