From 8f8b7c5f573b2a354311c9bb021511a19c4095ed Mon Sep 17 00:00:00 2001 From: 0xloem <0xloem@gmail.com> Date: Sat, 20 Feb 2021 03:59:19 -0500 Subject: [PATCH 1/2] changes for large file support on 32 bit systems --- configure.ac | 4 ++++ lib/libtar.h | 11 ++++++++--- lib/output.c | 2 +- lib/util.c | 12 ++++++------ 4 files changed, 19 insertions(+), 10 deletions(-) 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..d41715b 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" { @@ -278,14 +283,14 @@ int th_signed_crc_calc(TAR *t); /* string-octal to integer conversion */ int oct_to_int(char *oct); -size_t oct_to_size(char *oct); +off_t oct_to_size(char *oct); /* integer to NULL-terminated string-octal conversion */ #define int_to_oct(num, oct, octlen) \ - snprintf((oct), (octlen), "%*lo ", (octlen) - 2, (unsigned long)(num)) + snprintf((oct), (octlen), "%*llo ", (octlen) - 2, (unsigned long long)(num)) /* integer to string-octal conversion, no NULL */ -void int_to_oct_nonull(int num, char *oct, size_t octlen); +void int_to_oct_nonull(off_t num, char *oct, size_t octlen); /***** wrapper.c **********************************************************/ diff --git a/lib/output.c b/lib/output.c index af754f1..9ce35a0 100644 --- a/lib/output.c +++ b/lib/output.c @@ -102,7 +102,7 @@ th_print_long_ls(TAR *t) if (TH_ISCHR(t) || TH_ISBLK(t)) printf(" %3d, %3d ", th_get_devmajor(t), th_get_devminor(t)); else - printf("%9ld ", (long)th_get_size(t)); + printf("%9llu ", (unsigned long long)th_get_size(t)); mtime = th_get_mtime(t); mtm = localtime(&mtime); diff --git a/lib/util.c b/lib/util.c index 9823cab..b385cb4 100644 --- a/lib/util.c +++ b/lib/util.c @@ -151,21 +151,21 @@ oct_to_int(char *oct) return sscanf(oct, "%o", &i) == 1 ? i : 0; } -/* string-octal to size_t conversion */ -size_t +/* string-octal to filesize conversion */ +off_t oct_to_size(char *oct) { - size_t i; + unsigned long long i; - return sscanf(oct, "%zo", &i) == 1 ? i : 0; + return sscanf(oct, "%llo", &i) == 1 ? i : 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); + snprintf(oct, octlen, "%*llo", (int)(octlen - 1), (unsigned long long)num); oct[octlen - 1] = ' '; } From 45ef6279323ff63f3edf91236b5646ed936e74d1 Mon Sep 17 00:00:00 2001 From: xloem <0xloem@gmail.com> Date: Sun, 20 Jun 2021 16:59:18 +0000 Subject: [PATCH 2/2] Support for base256 extension provides for file sizes > 8GB --- lib/libtar.h | 8 ++++---- lib/util.c | 50 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/lib/libtar.h b/lib/libtar.h index d41715b..97de493 100644 --- a/lib/libtar.h +++ b/lib/libtar.h @@ -282,12 +282,12 @@ 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); -off_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 filesize conversion */ -off_t -oct_to_size(char *oct) +/* integer to NULL-terminated string-octal conversion */ +void +int_to_oct(off_t num, char * oct, int octlen) { - unsigned long long i; - - return sscanf(oct, "%llo", &i) == 1 ? i : 0; + int_to_oct_nonull(num, oct, octlen - 1); + oct[octlen - 1] = '\0'; } @@ -165,8 +179,18 @@ oct_to_size(char *oct) void int_to_oct_nonull(off_t num, char *oct, size_t octlen) { - snprintf(oct, octlen, "%*llo", (int)(octlen - 1), (unsigned long 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; + } }