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