The first hunk in this file was submitted by Craig Wiegert . It fixed a problem that causes GNUTAR to issue error messages like the following for sparse files: > /bin/tar: Read error at byte 0, reading 512 bytes, in file ./var/log/lastlog: Bad file number The others fix an estimate problem in GNUTAR on SunOS 4.1.3, HP/UX and other systems whose C libraries do not support "%lld" in printf format strings for printing long long integers. --- tar-1.12/src/create.c Mon Dec 15 17:26:47 1997 +++ tar-1.12/src/create.c Mon Dec 15 17:50:48 1997 @@ -1048,7 +1048,7 @@ } if (save_typeflag == GNUTYPE_SPARSE) { - if (finish_sparse_file (f, &sizeleft, current_stat.st_size, p)) + if (f < 0 || finish_sparse_file (f, &sizeleft, current_stat.st_size, p)) goto padit; } else --- tar-1.12/lib/Makefile.am Wed Apr 16 16:30:04 1997 +++ tar-1.12/lib/Makefile.am Mon Nov 17 06:45:43 1997 @@ -37,6 +37,9 @@ libtar_a_LIBADD = @ALLOCA@ @LIBOBJS@ libtar_a_DEPENDENCIES = $(libtar_a_LIBADD) +$(srcdir)/getdate.h: + touch $@ + # Say $(srcdir), so GNU make does not report an ambiguity with the .y.c rule. $(srcdir)/getdate.c: getdate.y @echo Expect 13 shift/reduce conflicts... --- tar-1.12/src/arith.h Wed Apr 16 18:02:57 1997 +++ tar-1.12/src/arith.h Mon Nov 17 05:47:33 1997 @@ -37,10 +37,10 @@ #if BITS_PER_BYTE * SIZEOF_UNSIGNED_LONG >= BITS_PER_TARLONG # define SUPERDIGIT 0 -# define TARLONG_FORMAT "%uld" +# define TARLONG_FORMAT "%lu" typedef unsigned long tarlong; #else -# if BITS_PER_BYTE * SIZEOF_LONG_LONG >= BITS_PER_TARLONG + 1 +# if PRINTF_LONG_LONG_WORKS && BITS_PER_BYTE * SIZEOF_LONG_LONG >= BITS_PER_TARLONG + 1 # define SUPERDIGIT 0 # define TARLONG_FORMAT "%lld" typedef long long tarlong; @@ -48,12 +48,12 @@ # if BITS_PER_BYTE * SIZEOF_UNSIGNED_LONG >= 64 # define SUPERDIGIT 1000000000L # define BITS_PER_SUPERDIGIT 29 -# define TARLONG_FORMAT "%09uld" +# define TARLONG_FORMAT "%09lu" # else # if BITS_PER_BYTE * SIZEOF_UNSIGNED_LONG >= 32 # define SUPERDIGIT 10000L # define BITS_PER_SUPERDIGIT 14 -# define TARLONG_FORMAT "%04uld" +# define TARLONG_FORMAT "%04lu" # endif # endif # endif --- tar-1.12/src/arith.c Wed Apr 23 23:25:57 1997 +++ tar-1.12/src/arith.c Mon Nov 17 08:11:11 1997 @@ -96,7 +96,7 @@ void add_to_tarlong_helper (unsigned long *accumulator, int value) { - int counter; + int counter, newvalue; if (value < 0) for (counter = 0; counter < LONGS_PER_TARLONG; counter++) @@ -106,8 +106,15 @@ accumulator[counter] += value; return; } - accumulator[counter] += value + SUPERDIGIT; - value = -1; + newvalue = - ((-value-1) / SUPERDIGIT) -1; + value = - ((-value) % SUPERDIGIT); + accumulator[counter] += SUPERDIGIT + value; + if (accumulator[counter] >= SUPERDIGIT) + { + accumulator[counter] -= SUPERDIGIT; + ++newvalue; + } + value = newvalue; } else for (counter = 0; counter < LONGS_PER_TARLONG; counter++) @@ -117,8 +124,15 @@ accumulator[counter] += value; return; } - accumulator[counter] += value - SUPERDIGIT; - value = 1; + newvalue = value / SUPERDIGIT; + value = value % SUPERDIGIT; + accumulator[counter] += value; + if (accumulator[counter] >= SUPERDIGIT) + { + accumulator[counter] -= SUPERDIGIT; + ++newvalue; + } + value = newvalue; } FATAL_ERROR ((0, 0, _("Arithmetic overflow"))); } @@ -155,7 +169,7 @@ while (counter > 0 && accumulator[counter] == 0) counter--; - fprintf (file, "%uld", accumulator[counter]); + fprintf (file, "%lu", accumulator[counter]); while (counter > 0) fprintf (file, TARLONG_FORMAT, accumulator[--counter]); } --- tar-1.12/configure.in Fri Apr 25 17:02:46 1997 +++ tar-1.12/configure.in Mon Nov 17 06:17:49 1997 @@ -26,6 +26,35 @@ AC_CHECK_SIZEOF(unsigned long, 4) AC_CHECK_SIZEOF(long long, 0) +# SunOS 4.1.3's printf treats %lld as %ld +AC_CACHE_CHECK([whether printf understands %lld], + tar_cv_printf_long_long_works, + AC_TRY_RUN([[ +#include +main() { + long long foo = 1; + char buf[1024]; + while(foo) { + long long bar = 0; + sprintf(buf, "%lld", foo); + sscanf(buf, "%lld", &bar); + if (foo != bar) + return 1; + foo <<= 1; + } + return 0; +} + ]], + tar_cv_printf_long_long_works=yes, + tar_cv_printf_long_long_works=no, + if test x"$tar_cv_printf_long_long_works" = x; then + tar_cv_printf_long_long_works=cross + fi) +) +if test x"$tar_cv_printf_long_long_works" = x"yes"; then + AC_DEFINE(PRINTF_LONG_LONG_WORKS) +fi + AC_CHECK_HEADERS(fcntl.h limits.h linux/fd.h memory.h net/errno.h poll.h \ sgtty.h string.h stropts.h \ sys/buf.h sys/device.h sys/gentape.h sys/inet.h sys/io/trioctl.h sys/ioccom.h \ --- tar-1.12/acconfig.h Thu Apr 10 11:37:02 1997 +++ tar-1.12/acconfig.h Mon Nov 17 05:53:38 1997 @@ -86,3 +86,6 @@ /* Define to 1 if GNU regex should be used instead of GNU rx. */ #undef WITH_REGEX + +/* Define to 1 if printf() supports "%lld" */ +#undef PRINTF_LONG_LONG_WORKS