Blob Blame History Raw
The first hunk in this file was submitted by Craig Wiegert
<wiegert@quintessence.uchicago.edu>.  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.

Patch follows.

--- 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 <stdio.h>
+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
--- tar-1.12/configure
+++ tar-1.12/configure
@@ -1,2 +1,4 @@
 #! /bin/sh
+echo You must run autoheader and autoconf after installing this patch
+exit 1