diff --git a/configure.ac b/configure.ac index 4623100..06b3bb9 100644 --- a/configure.ac +++ b/configure.ac @@ -49,6 +49,10 @@ so your version of libtar will not be thread-safe. fi +dnl ### Eable large file support. ################################## +AC_SYS_LARGEFILE + + dnl ### Checks for header files. ################################### AC_HEADER_STDC AC_CHECK_HEADERS([unistd.h]) diff --git a/lib/libtar.h b/lib/libtar.h index cf3fd70..97de493 100644 --- a/lib/libtar.h +++ b/lib/libtar.h @@ -16,9 +16,14 @@ #include #include #include +#include #include +#if (defined(_POSIX_V6_ILP32_OFF32) || defined(_POSIX_V7_ILP32_OFF32)) && _FILE_OFFSET_BITS != 64 + #warning _FILE_OFFSET_BITS is not set to 64. libtar may demonstrate errors. +#endif + #ifdef __cplusplus extern "C" { @@ -277,15 +282,15 @@ int th_signed_crc_calc(TAR *t); #define th_crc_ok(t) (th_get_crc(t) == th_crc_calc(t) || th_get_crc(t) == th_signed_crc_calc(t)) /* string-octal to integer conversion */ -int oct_to_int(char *oct); -size_t oct_to_size(char *oct); +#define oct_to_int(value) oct_to_int_bounds(value, sizeof(value), 0, ~0 ^ (int)1<= min && i <= max) ? i : 0; } -/* string-octal to size_t conversion */ -size_t -oct_to_size(char *oct) +/* integer to NULL-terminated string-octal conversion */ +void +int_to_oct(off_t num, char * oct, int octlen) { - size_t i; - - return sscanf(oct, "%zo", &i) == 1 ? i : 0; + int_to_oct_nonull(num, oct, octlen - 1); + oct[octlen - 1] = '\0'; } /* integer to string-octal conversion, no NULL */ void -int_to_oct_nonull(int num, char *oct, size_t octlen) +int_to_oct_nonull(off_t num, char *oct, size_t octlen) { - snprintf(oct, octlen, "%*lo", (int)(octlen - 1), (unsigned long)num); - oct[octlen - 1] = ' '; + if (num >= 0 && num <= 077777777777) { + snprintf(oct, octlen, "%*llo", (int)(octlen - 1), (unsigned long long)num); + oct[octlen - 1] = ' '; + } else { + // common base 256 extension + while (octlen) { + octlen --; + oct[octlen] = num & 0xff; + num >>= 8; + } + oct[0] |= 0x80; + } }