Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8225f274ff | ||
|
|
e439c9fe36 | ||
|
|
88711e3972 | ||
|
|
06384f1def | ||
|
|
bab605d5bd | ||
|
|
9c93a32114 | ||
|
|
7f1bf2e09f | ||
|
|
3847d0f51f | ||
|
|
dd83d5dd9d | ||
|
|
1735867f56 | ||
|
|
fb1c65e512 | ||
|
|
1a9ace4d99 | ||
|
|
1ad624bbbc | ||
|
|
02a275c6ac | ||
|
|
61170ee840 | ||
|
|
f42a0e5af3 | ||
|
|
e6e72bf7ed | ||
|
|
1b10ab140f | ||
|
|
9a15fcf491 | ||
|
|
e2b5f1e918 | ||
|
|
4dbeac6c7f | ||
|
|
63db9071d2 | ||
|
|
5a5f4d06e7 | ||
|
|
ec63030958 | ||
|
|
0e041a7bfe | ||
|
|
85f651c8c6 | ||
|
|
6c9e824ce5 | ||
|
|
95a4feb37b | ||
|
|
06e4c77310 | ||
|
|
a942967415 | ||
|
|
92734c1511 | ||
|
|
4b5d60ef38 | ||
|
|
7a1b6cfa67 | ||
|
|
cc818a584f | ||
|
|
45bf6a9089 |
9
NEWS
9
NEWS
@@ -1,5 +1,14 @@
|
||||
GNU tar NEWS - User visible changes.
|
||||
|
||||
version 1.13.25 - Paul Eggert, 2001-09-26
|
||||
|
||||
* Bug fixes.
|
||||
|
||||
version 1.13.24 - Paul Eggert, 2001-09-22
|
||||
|
||||
* New option --overwrite-dir.
|
||||
* Fixes for buffer overrun, porting, and copyright notice problems.
|
||||
|
||||
version 1.13.23 - Paul Eggert, 2001-09-13
|
||||
|
||||
* Bug, porting, and copyright notice fixes.
|
||||
|
||||
130
README-alpha
130
README-alpha
@@ -2,8 +2,33 @@ This is a test release of GNU tar.
|
||||
|
||||
Please send comments and problem reports to <bug-tar@gnu.org>.
|
||||
|
||||
Copyright 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
GNU tar is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU tar is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with tar; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
This release was built with GNU automake 1.5 patched as follows:
|
||||
|
||||
2001-09-24 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* m4/header.m4 (_AM_Config_Header_Index): Remove.
|
||||
(AM_CONFIG_HEADER): Don't use it. It wasn't working, and was
|
||||
causing needless rebuilds.
|
||||
|
||||
2001-09-14 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* lib/am/distdir.am (REMOVE_DISTDIR):
|
||||
@@ -110,3 +135,108 @@ diff -pu -r1.5 -r1.5.0.1
|
||||
@echo "$(distdir).tar.gz is ready for distribution" | \
|
||||
sed 'h;s/./=/g;p;x;p;x'
|
||||
endif %?TOPDIR_P%
|
||||
===================================================================
|
||||
RCS file: m4/header.m4,v
|
||||
retrieving revision 1.5
|
||||
retrieving revision 1.5.0.1
|
||||
diff -pu -r1.5 -r1.5.0.1
|
||||
--- m4/header.m4 2001/07/21 05:27:26 1.5
|
||||
+++ m4/header.m4 2001/09/24 18:29:30 1.5.0.1
|
||||
@@ -11,18 +11,16 @@ AC_PREREQ([2.12])
|
||||
|
||||
AC_DEFUN([AM_CONFIG_HEADER],
|
||||
[ifdef([AC_FOREACH],dnl
|
||||
- [dnl init our file count if it isn't already
|
||||
- m4_ifndef([_AM_Config_Header_Index], m4_define([_AM_Config_Header_Index], [0]))
|
||||
+ [
|
||||
dnl prepare to store our destination file list for use in config.status
|
||||
AC_FOREACH([_AM_File], [$1],
|
||||
[m4_pushdef([_AM_Dest], m4_patsubst(_AM_File, [:.*]))
|
||||
- m4_define([_AM_Config_Header_Index], m4_incr(_AM_Config_Header_Index))
|
||||
dnl and add it to the list of files AC keeps track of, along
|
||||
dnl with our hook
|
||||
AC_CONFIG_HEADERS(_AM_File,
|
||||
dnl COMMANDS, [, INIT-CMDS]
|
||||
[# update the timestamp
|
||||
-echo timestamp >"AS_ESCAPE(_AM_DIRNAME(]_AM_Dest[))/stamp-h]_AM_Config_Header_Index["
|
||||
+echo timestamp >"AS_ESCAPE(_AM_DIRNAME(]_AM_Dest[))/stamp-h"
|
||||
][$2]m4_ifval([$3], [, [$3]]))dnl AC_CONFIG_HEADERS
|
||||
m4_popdef([_AM_Dest])])],dnl
|
||||
[AC_CONFIG_HEADER([$1])
|
||||
|
||||
|
||||
|
||||
and with GNU autoconf 2.52 patched as follows:
|
||||
|
||||
2001-09-15 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
Fix bug reported by Paul Townsend on AIX 4.3.3.0 with
|
||||
CFLAGS=-O4 or CFLAGS=-O5. In that case, the linker has a
|
||||
relaxed view of fatal errors, and AC_CHECK_LIB causes it to
|
||||
include libraries even when they don't exist.
|
||||
|
||||
* acheaders.m4 (AC_HEADER_DIRENT): Use AC_SEARCH_LIBS, not
|
||||
AC_CHECK_LIB, so that we don't use -ldir or -lx if we don't
|
||||
need it.
|
||||
|
||||
* acspecific.m4 (AC_ISC_POSIX): Replace the old, crufty
|
||||
version with the version used by fileutils 4.1, except use
|
||||
AC_SEARCH_LIBS, not AC_CHECK_LIB, so that we don't use
|
||||
-lcposix if we don't need it.
|
||||
|
||||
===================================================================
|
||||
RCS file: acheaders.m4,v
|
||||
retrieving revision 2.52
|
||||
retrieving revision 2.52.0.1
|
||||
diff -pu -r2.52 -r2.52.0.1
|
||||
--- acheaders.m4 2001/07/03 14:19:09 2.52
|
||||
+++ acheaders.m4 2001/09/16 02:53:51 2.52.0.1
|
||||
@@ -158,9 +158,9 @@ ac_header_dirent=$ac_hdr; break])
|
||||
done
|
||||
# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
|
||||
if test $ac_header_dirent = dirent.h; then
|
||||
- AC_CHECK_LIB(dir, opendir, LIBS="$LIBS -ldir")
|
||||
+ AC_SEARCH_LIBS(opendir, dir)
|
||||
else
|
||||
- AC_CHECK_LIB(x, opendir, LIBS="$LIBS -lx")
|
||||
+ AC_SEARCH_LIBS(opendir, x)
|
||||
fi
|
||||
])# AC_HEADER_DIRENT
|
||||
|
||||
===================================================================
|
||||
RCS file: acspecific.m4,v
|
||||
retrieving revision 2.52
|
||||
retrieving revision 2.52.0.1
|
||||
diff -pu -r2.52 -r2.52.0.1
|
||||
--- acspecific.m4 2001/06/15 17:46:01 2.52
|
||||
+++ acspecific.m4 2001/09/16 02:53:51 2.52.0.1
|
||||
@@ -993,28 +993,7 @@ fi
|
||||
# AC_ISC_POSIX
|
||||
# ------------
|
||||
AC_DEFUN([AC_ISC_POSIX],
|
||||
-[AC_REQUIRE([AC_PROG_CC])dnl
|
||||
-AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl
|
||||
-AC_BEFORE([$0], [AC_RUN_IFELSE])dnl
|
||||
-AC_MSG_CHECKING([for POSIXized ISC])
|
||||
-if test -d /etc/conf/kconfig.d &&
|
||||
- grep _POSIX_VERSION [/usr/include/sys/unistd.h] >/dev/null 2>&1
|
||||
-then
|
||||
- AC_MSG_RESULT([yes])
|
||||
- ISC=yes # If later tests want to check for ISC.
|
||||
- AC_DEFINE(_POSIX_SOURCE, 1,
|
||||
- [Define if you need to in order for stat and other things to
|
||||
- work.])
|
||||
- if test "$GCC" = yes; then
|
||||
- CC="$CC -posix"
|
||||
- else
|
||||
- CC="$CC -Xp"
|
||||
- fi
|
||||
-else
|
||||
- AC_MSG_RESULT([no])
|
||||
- ISC=
|
||||
-fi
|
||||
-])# AC_ISC_POSIX
|
||||
+[AC_SEARCH_LIBS(strerror, cposix)])
|
||||
|
||||
|
||||
# AC_XENIX_DIR
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
@node Date input formats
|
||||
@chapter Date input formats
|
||||
|
||||
@c Copyright 1994, 1995, 1996, 1997, 1999, 2000, 2001 Free Software
|
||||
@c Foundation, Inc.
|
||||
|
||||
@c Permission is granted to copy, distribute and/or modify this document
|
||||
@c under the terms of the GNU Free Documentation License, Version 1.1
|
||||
@c or any later version published by the Free Software Foundation;
|
||||
@c with no Invariant Sections, with no
|
||||
@c Front-Cover Texts, and with no Back-Cover Texts.
|
||||
@c A copy of the license is included in the section entitled ``GNU
|
||||
@c Free Documentation License''.
|
||||
|
||||
@cindex date input formats
|
||||
@findex getdate
|
||||
|
||||
|
||||
18
doc/tar.texi
18
doc/tar.texi
@@ -1864,6 +1864,10 @@ specify @w{@kbd{tar --extract --file=bfiles.tar ./birds}}. To find the
|
||||
exact member names of the members of an archive, use @value{op-list}
|
||||
(@pxref{list}).
|
||||
|
||||
You can extract a file to standard output by combining the above options
|
||||
with the @option{--to-stdout} option (@pxref{Writing to Standard
|
||||
Output}).
|
||||
|
||||
If you give the @value{op-verbose} option, then @value{op-extract} will
|
||||
print the names of the archive members as it extracts them.
|
||||
|
||||
@@ -2799,6 +2803,11 @@ directory. @FIXME-xref{}
|
||||
Overwrite existing files and directory metadata when extracting files
|
||||
from an archive. @xref{Overwrite Old Files}.
|
||||
|
||||
@item --overwrite-dir
|
||||
|
||||
Overwrite the metadata of existing directories when extracting files
|
||||
from an archive. @xref{Overwrite Old Files}.
|
||||
|
||||
@item --owner=@var{user}
|
||||
|
||||
Specifies that @command{tar} should use @var{user} as the owner of members
|
||||
@@ -4171,6 +4180,9 @@ member. Instead, it reports an error.
|
||||
To be more aggressive about altering existing files, use the
|
||||
@value{op-overwrite} option. It causes @command{tar} to overwrite
|
||||
existing files and to follow existing symbolic links when extracting.
|
||||
The @option{--overwrite-dir} option is somewhat more conservative than
|
||||
@value{op-overwrite}: it overwrites metadata (ownership, permission,
|
||||
etc.) for directories, but removes other files before extracting them.
|
||||
|
||||
Some people argue that @sc{gnu} @command{tar} should not hesitate to overwrite
|
||||
files with other files when extracting. When extracting a @command{tar}
|
||||
@@ -4217,6 +4229,10 @@ combined with the @value{op-absolute-names} option, as this combination
|
||||
can change the contents, ownership or permissions of any file on your
|
||||
system. Also, many systems do not take kindly to overwriting files that
|
||||
are currently being executed.
|
||||
|
||||
@item --overwrite-dir
|
||||
Overwrite the metadata of directories when extracting files from an
|
||||
archive, but remove other files before extracting.
|
||||
@end table
|
||||
|
||||
@node Keep Old Files
|
||||
@@ -7353,7 +7369,7 @@ from the archive, or you should either use the @value{op-absolute-names}
|
||||
option, or use the command @samp{tar -C / @dots{}}.
|
||||
|
||||
@cindex Ultrix 3.1 and write failure
|
||||
Some versions of Unix (Ultrix 3.1 is know to have this problem),
|
||||
Some versions of Unix (Ultrix 3.1 is known to have this problem),
|
||||
can claim that a short write near the end of a tape succeeded,
|
||||
when it actually failed. This will result in the -M option not
|
||||
working correctly. The best workaround at the moment is to use a
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* copysym.c -- Return a copyright symbol suitable for the current locale.
|
||||
/* Print a copyright notice suitable for the current locale.
|
||||
Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@@ -21,65 +21,32 @@
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "unicodeio.h"
|
||||
#include "print-copyr.h"
|
||||
|
||||
#if HAVE_ICONV
|
||||
# include <iconv.h>
|
||||
#include <stdio.h>
|
||||
|
||||
# if ! USE_INCLUDED_LIBINTL && HAVE_LANGINFO_CODESET
|
||||
# include <langinfo.h>
|
||||
# endif
|
||||
#define COPYRIGHT_SIGN 0x00A9
|
||||
|
||||
# if HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
# endif
|
||||
#endif
|
||||
/* Print "(C)". */
|
||||
|
||||
#include "copysym.h"
|
||||
|
||||
/* Store into BUF (of size BUFSIZE) a representation of the copyright
|
||||
symbol (C-in-a-circle) that is a valid text string for the current
|
||||
locale. Return BUF if successful, and a pointer to some other
|
||||
string otherwise. */
|
||||
|
||||
char const *
|
||||
copyright_symbol (char *buf, size_t bufsize)
|
||||
static int
|
||||
print_parenthesized_c (unsigned int code, void *callback_arg)
|
||||
{
|
||||
#if HAVE_ICONV
|
||||
char const *outcharset = getenv ("OUTPUT_CHARSET");
|
||||
|
||||
if (! (outcharset && *outcharset))
|
||||
{
|
||||
#if USE_INCLUDED_LIBINTL
|
||||
extern char const *locale_charset (void);
|
||||
outcharset = locale_charset ();
|
||||
#else
|
||||
# if HAVE_LANGINFO_CODESET
|
||||
outcharset = nl_langinfo (CODESET);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
if (*outcharset)
|
||||
{
|
||||
iconv_t conv = iconv_open (outcharset, "UTF-8");
|
||||
|
||||
if (conv != (iconv_t) -1)
|
||||
{
|
||||
static char const copyright_utf_8[] = "\302\251";
|
||||
char ICONV_CONST *inptr = (char ICONV_CONST *) ©right_utf_8;
|
||||
size_t inleft = sizeof copyright_utf_8;
|
||||
char *outptr = buf;
|
||||
size_t chars = iconv (conv, &inptr, &inleft, &outptr, &bufsize);
|
||||
|
||||
iconv_close (conv);
|
||||
|
||||
if (chars != (size_t) -1)
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* "(C)" is the best we can do in ASCII. */
|
||||
return "(C)";
|
||||
FILE *stream = callback_arg;
|
||||
return fputs ("(C)", stream);
|
||||
}
|
||||
|
||||
/* Print "Copyright (C) " followed by NOTICE and then a newline,
|
||||
transliterating "(C)" to an actual copyright sign (C-in-a-circle)
|
||||
if possible. */
|
||||
|
||||
void
|
||||
print_copyright (char const *notice)
|
||||
{
|
||||
fputs ("Copyright ", stdout);
|
||||
unicode_to_mb (COPYRIGHT_SIGN, print_unicode_success, print_parenthesized_c,
|
||||
stdout);
|
||||
fputc (' ', stdout);
|
||||
puts (notice);
|
||||
}
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
# endif
|
||||
# endif
|
||||
|
||||
char const *copyright_symbol PARAMS((char *, size_t));
|
||||
void print_copyright PARAMS((char const *));
|
||||
|
||||
117
lib/unicodeio.c
117
lib/unicodeio.c
@@ -2,20 +2,19 @@
|
||||
|
||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
by the Free Software Foundation; either version 2, or (at your option)
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
USA. */
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Written by Bruno Haible <haible@clisp.cons.org>. */
|
||||
|
||||
@@ -43,13 +42,18 @@ extern int errno;
|
||||
# include <iconv.h>
|
||||
#endif
|
||||
|
||||
#include <error.h>
|
||||
/* Some systems, like SunOS 4, don't have EILSEQ. On these systems,
|
||||
define EILSEQ to some value other than EINVAL, because our invokers
|
||||
may want to distinguish EINVAL from EILSEQ. */
|
||||
#ifndef EILSEQ
|
||||
# define EILSEQ ENOENT
|
||||
#endif
|
||||
#ifndef ENOTSUP
|
||||
# define ENOTSUP EINVAL
|
||||
#endif
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(Text) gettext (Text)
|
||||
#else
|
||||
# define _(Text) Text
|
||||
#if HAVE_LANGINFO_CODESET && ! USE_INCLUDED_LIBINTL
|
||||
# include <langinfo.h>
|
||||
#endif
|
||||
|
||||
#include "unicodeio.h"
|
||||
@@ -106,13 +110,17 @@ utf8_wctomb (unsigned char *r, unsigned int wc)
|
||||
#define UTF8_NAME "UTF-8"
|
||||
|
||||
/* Converts the Unicode character CODE to its multibyte representation
|
||||
in the current locale and calls the CALLBACK on the resulting byte
|
||||
sequence.
|
||||
Assumes that the locale doesn't change between two calls. */
|
||||
void
|
||||
in the current locale and calls SUCCESS on the resulting byte
|
||||
sequence. If an error occurs, invoke FAILURE instead,
|
||||
passing it CODE with errno set appropriately.
|
||||
Assumes that the locale doesn't change between two calls.
|
||||
Return whatever the SUCCESS or FAILURE returns. */
|
||||
int
|
||||
unicode_to_mb (unsigned int code,
|
||||
void (*callback) PARAMS((const char *buf, size_t buflen,
|
||||
void *callback_arg)),
|
||||
int (*success) PARAMS((const char *buf, size_t buflen,
|
||||
void *callback_arg)),
|
||||
int (*failure) PARAMS((unsigned int code,
|
||||
void *callback_arg)),
|
||||
void *callback_arg)
|
||||
{
|
||||
static int initialized;
|
||||
@@ -126,8 +134,18 @@ unicode_to_mb (unsigned int code,
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
const char *charset;
|
||||
|
||||
#if USE_INCLUDED_LIBINTL
|
||||
extern const char *locale_charset PARAMS ((void));
|
||||
const char *charset = locale_charset ();
|
||||
charset = locale_charset ();
|
||||
#else
|
||||
# if HAVE_LANGINFO_CODESET
|
||||
charset = nl_langinfo (CODESET);
|
||||
# else
|
||||
charset = "";
|
||||
# endif
|
||||
#endif
|
||||
|
||||
is_utf8 = !strcmp (charset, UTF8_NAME);
|
||||
#if HAVE_ICONV
|
||||
@@ -139,9 +157,7 @@ unicode_to_mb (unsigned int code,
|
||||
/* For an unknown encoding, assume ASCII. */
|
||||
utf8_to_local = iconv_open ("ASCII", UTF8_NAME);
|
||||
if (utf8_to_local == (iconv_t)(-1))
|
||||
error (1, 0,
|
||||
_("cannot convert U+%04X to local character set: iconv function not usable"),
|
||||
code);
|
||||
return failure (code, callback_arg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -151,11 +167,14 @@ unicode_to_mb (unsigned int code,
|
||||
/* Convert the character to UTF-8. */
|
||||
count = utf8_wctomb ((unsigned char *) inbuf, code);
|
||||
if (count < 0)
|
||||
error (1, 0, _("U+%04X: character out of range"), code);
|
||||
{
|
||||
errno = EILSEQ;
|
||||
return failure (code, callback_arg);
|
||||
}
|
||||
|
||||
if (is_utf8)
|
||||
{
|
||||
callback (inbuf, count, callback_arg);
|
||||
return success (inbuf, count, callback_arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -182,8 +201,11 @@ unicode_to_mb (unsigned int code,
|
||||
|| (res > 0 && code != 0 && outptr - outbuf == 1 && *outbuf == '\0')
|
||||
# endif
|
||||
)
|
||||
error (1, res == (size_t)(-1) ? errno : 0,
|
||||
_("cannot convert U+%04X to local character set"), code);
|
||||
{
|
||||
if (res != (size_t)(-1))
|
||||
errno = EILSEQ;
|
||||
return failure (code, callback_arg);
|
||||
}
|
||||
|
||||
/* Avoid glibc-2.1 bug and Solaris 2.7 bug. */
|
||||
# if defined _LIBICONV_VERSION \
|
||||
@@ -192,33 +214,46 @@ unicode_to_mb (unsigned int code,
|
||||
/* Get back to the initial shift state. */
|
||||
res = iconv (utf8_to_local, NULL, NULL, &outptr, &outbytesleft);
|
||||
if (res == (size_t)(-1))
|
||||
error (1, errno, _("cannot convert U+%04X to local character set"),
|
||||
code);
|
||||
return failure (code, callback_arg);
|
||||
# endif
|
||||
|
||||
callback (outbuf, outptr - outbuf, callback_arg);
|
||||
return success (outbuf, outptr - outbuf, callback_arg);
|
||||
#else
|
||||
error (1, 0,
|
||||
_("cannot convert U+%04X to local character set: iconv function not available"),
|
||||
code);
|
||||
errno = ENOTSUP;
|
||||
return failure (code, callback_arg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Simple callback that outputs the converted string.
|
||||
/* Simple success callback that outputs the converted string.
|
||||
The STREAM is passed as callback_arg. */
|
||||
static void
|
||||
fprintf_callback (const char *buf, size_t buflen, void *callback_arg)
|
||||
int
|
||||
print_unicode_success (const char *buf, size_t buflen, void *callback_arg)
|
||||
{
|
||||
FILE *stream = (FILE *) callback_arg;
|
||||
|
||||
fwrite (buf, 1, buflen, stream);
|
||||
return fwrite (buf, 1, buflen, stream) == 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
/* Simple failure callback that prints an ASCII representation, using
|
||||
the same notation as C99 strings. */
|
||||
int
|
||||
print_unicode_failure (unsigned int code, void *callback_arg)
|
||||
{
|
||||
int e = errno;
|
||||
FILE *stream = callback_arg;
|
||||
|
||||
fprintf (stream, code < 0x10000 ? "\\u%04X" : "\\U%08X", code);
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Outputs the Unicode character CODE to the output stream STREAM.
|
||||
Returns zero if successful, -1 (setting errno) otherwise.
|
||||
Assumes that the locale doesn't change between two calls. */
|
||||
void
|
||||
int
|
||||
print_unicode_char (FILE *stream, unsigned int code)
|
||||
{
|
||||
unicode_to_mb (code, fprintf_callback, stream);
|
||||
return unicode_to_mb (code, print_unicode_success, print_unicode_failure,
|
||||
stream);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/* Unicode character output to streams with locale dependent encoding.
|
||||
|
||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef UNICODEIO_H
|
||||
# define UNICODEIO_H
|
||||
|
||||
@@ -13,14 +31,27 @@
|
||||
|
||||
/* Converts the Unicode character CODE to its multibyte representation
|
||||
in the current locale and calls the CALLBACK on the resulting byte
|
||||
sequence. */
|
||||
extern void unicode_to_mb
|
||||
sequence. If an error occurs, invokes ERROR_CALLBACK instead,
|
||||
passing it CODE with errno set appropriately. Returns whatever the
|
||||
callback returns. */
|
||||
extern int unicode_to_mb
|
||||
PARAMS ((unsigned int code,
|
||||
void (*callback) PARAMS ((const char *buf, size_t buflen,
|
||||
void *callback_arg)),
|
||||
int (*callback) PARAMS ((const char *buf, size_t buflen,
|
||||
void *callback_arg)),
|
||||
int (*error_callback) PARAMS ((unsigned int code,
|
||||
void * callback_arg)),
|
||||
void *callback_arg));
|
||||
|
||||
/* Outputs the Unicode character CODE to the output stream STREAM. */
|
||||
extern void print_unicode_char PARAMS((FILE *stream, unsigned int code));
|
||||
/* Success callback that outputs the conversion of the character. */
|
||||
extern int print_unicode_success PARAMS((const char *buf, size_t buflen,
|
||||
void *callback_arg));
|
||||
|
||||
/* Failure callback that outputs an ASCII representation. */
|
||||
extern int print_unicode_failure PARAMS((unsigned int code,
|
||||
void *callback_arg));
|
||||
|
||||
/* Outputs the Unicode character CODE to the output stream STREAM.
|
||||
Returns -1 (setting errno) if unsuccessful. */
|
||||
extern int print_unicode_char PARAMS((FILE *stream, unsigned int code));
|
||||
|
||||
#endif
|
||||
|
||||
@@ -78,19 +78,19 @@ extern int errno;
|
||||
|
||||
#include "xstrtol.h"
|
||||
|
||||
#ifndef strtol
|
||||
#if !HAVE_DECL_STRTOL && !defined strtol
|
||||
long int strtol ();
|
||||
#endif
|
||||
|
||||
#ifndef strtoul
|
||||
#if !HAVE_DECL_STRTOUL && !defined strtoul
|
||||
unsigned long int strtoul ();
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_STRTOIMAX
|
||||
#if !HAVE_DECL_STRTOIMAX && !defined strtoimax
|
||||
intmax_t strtoimax ();
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_STRTOUMAX
|
||||
#if !HAVE_DECL_STRTOUMAX && !defined strtoumax
|
||||
uintmax_t strtoumax ();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ gettext.m4 \
|
||||
glibc21.m4 \
|
||||
iconv.m4 \
|
||||
inttypes.m4 \
|
||||
isc-posix.m4 \
|
||||
jm-mktime.m4 \
|
||||
lcmessage.m4 \
|
||||
longlong.m4 \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#serial 3
|
||||
#serial 4
|
||||
|
||||
dnl FIXME: put these prerequisite-only *.m4 files in a separate
|
||||
dnl directory -- otherwise, they'll conflict with existing files.
|
||||
@@ -6,7 +6,8 @@ dnl directory -- otherwise, they'll conflict with existing files.
|
||||
dnl These are the prerequisite macros for GNU's error.c file.
|
||||
AC_DEFUN([jm_PREREQ_ERROR],
|
||||
[
|
||||
AC_CHECK_FUNCS(strerror strerror_r vprintf doprnt)
|
||||
AC_CHECK_FUNCS(strerror vprintf doprnt)
|
||||
AC_CHECK_DECLS([strerror])
|
||||
AC_FUNC_STRERROR_R
|
||||
AC_HEADER_STDC
|
||||
])
|
||||
|
||||
@@ -1,9 +1,23 @@
|
||||
#serial 1002
|
||||
#serial 1003
|
||||
# Experimental replacement for the function in the latest CVS autoconf.
|
||||
# If the compile-test says strerror_r doesn't work, then resort to a
|
||||
# `run'-test that works on BeOS and segfaults on DEC Unix.
|
||||
# Use with the error.c file in ../lib.
|
||||
|
||||
# Copyright 2001 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
undefine([AC_FUNC_STRERROR_R])
|
||||
|
||||
# AC_FUNC_STRERROR_R
|
||||
@@ -11,56 +25,35 @@ undefine([AC_FUNC_STRERROR_R])
|
||||
AC_DEFUN([AC_FUNC_STRERROR_R],
|
||||
[AC_CHECK_DECLS([strerror_r])
|
||||
AC_CHECK_FUNCS([strerror_r])
|
||||
if test $ac_cv_func_strerror_r = yes; then
|
||||
AC_CHECK_HEADERS(string.h)
|
||||
AC_CACHE_CHECK([for working strerror_r],
|
||||
ac_cv_func_strerror_r_works,
|
||||
AC_CACHE_CHECK([whether strerror_r returns char *],
|
||||
ac_cv_func_strerror_r_char_p,
|
||||
[
|
||||
AC_TRY_COMPILE(
|
||||
[
|
||||
# include <stdio.h>
|
||||
# if HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# endif
|
||||
],
|
||||
[
|
||||
char buf[100];
|
||||
char x = *strerror_r (0, buf, sizeof buf);
|
||||
],
|
||||
ac_cv_func_strerror_r_works=yes,
|
||||
ac_cv_func_strerror_r_works=no
|
||||
)
|
||||
if test $ac_cv_func_strerror_r_works = no; then
|
||||
# strerror_r seems not to work, but now we have to choose between
|
||||
ac_cv_func_strerror_r_char_p=no
|
||||
if test $ac_cv_have_decl_strerror_r = yes; then
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
|
||||
[[
|
||||
char buf[100];
|
||||
char x = *strerror_r (0, buf, sizeof buf);
|
||||
char *p = strerror_r (0, buf, sizeof buf);
|
||||
]])],
|
||||
ac_cv_func_strerror_r_char_p=yes)
|
||||
else
|
||||
# strerror_r is not declared. Choose between
|
||||
# systems that have relatively inaccessible declarations for the
|
||||
# function. BeOS and DEC UNIX 4.0 fall in this category, but the
|
||||
# former has a strerror_r that returns char*, while the latter
|
||||
# has a strerror_r that returns `int'.
|
||||
# This test should segfault on the DEC system.
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <ctype.h>
|
||||
|
||||
extern char *strerror_r ();
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
char buf[100];
|
||||
AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
|
||||
extern char *strerror_r ();],
|
||||
[[char buf[100];
|
||||
char x = *strerror_r (0, buf, sizeof buf);
|
||||
exit (!isalpha (x));
|
||||
}
|
||||
],
|
||||
ac_cv_func_strerror_r_works=yes,
|
||||
ac_cv_func_strerror_r_works=no,
|
||||
ac_cv_func_strerror_r_works=no)
|
||||
exit (!isalpha (x));]])],
|
||||
ac_cv_func_strerror_r_char_p=yes, , :)
|
||||
fi
|
||||
])
|
||||
if test $ac_cv_func_strerror_r_works = yes; then
|
||||
AC_DEFINE(HAVE_WORKING_STRERROR_R, 1,
|
||||
[Define to 1 if `strerror_r' returns a string.])
|
||||
fi
|
||||
if test $ac_cv_func_strerror_r_char_p = yes; then
|
||||
AC_DEFINE([STRERROR_R_CHAR_P], 1,
|
||||
[Define to 1 if strerror_r returns char *.])
|
||||
fi
|
||||
])# AC_FUNC_STRERROR_R
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#serial 1
|
||||
#serial 2
|
||||
dnl Cloned from xstrtoumax.m4. Keep these files in sync.
|
||||
|
||||
# autoconf tests required for use of xstrtoimax.c
|
||||
@@ -9,7 +9,7 @@ AC_DEFUN([jm_AC_PREREQ_XSTRTOIMAX],
|
||||
AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])
|
||||
AC_REQUIRE([jm_AC_TYPE_LONG_LONG])
|
||||
AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG])
|
||||
AC_CHECK_DECLS([strtol, strtoll, strtoimax])
|
||||
AC_CHECK_DECLS([strtol, strtoul, strtoll, strtoimax, strtoumax])
|
||||
AC_CHECK_HEADERS(limits.h stdlib.h inttypes.h)
|
||||
|
||||
AC_CACHE_CHECK([whether <inttypes.h> defines strtoimax as a macro],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#serial 3
|
||||
#serial 4
|
||||
|
||||
# autoconf tests required for use of xstrtoumax.c
|
||||
|
||||
@@ -8,7 +8,7 @@ AC_DEFUN([jm_AC_PREREQ_XSTRTOUMAX],
|
||||
AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])
|
||||
AC_REQUIRE([jm_AC_TYPE_LONG_LONG])
|
||||
AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG])
|
||||
AC_CHECK_DECLS([strtoul, strtoull, strtoumax])
|
||||
AC_CHECK_DECLS([strtol, strtoul, strtoull, strtoimax, strtoumax])
|
||||
AC_CHECK_HEADERS(limits.h stdlib.h inttypes.h)
|
||||
|
||||
AC_CACHE_CHECK([whether <inttypes.h> defines strtoumax as a macro],
|
||||
|
||||
40
src/buffer.c
40
src/buffer.c
@@ -52,14 +52,16 @@
|
||||
static tarlong prev_written; /* bytes written on previous volumes */
|
||||
static tarlong bytes_written; /* bytes written on this volume */
|
||||
|
||||
/* FIXME: The following four variables should ideally be static to this
|
||||
module. However, this cannot be done yet, as update.c uses the first
|
||||
three a lot, and compare.c uses the fourth. The cleanup continues! */
|
||||
/* FIXME: The following variables should ideally be static to this
|
||||
module. However, this cannot be done yet. The cleanup continues! */
|
||||
|
||||
union block *record_start; /* start of record of archive */
|
||||
union block *record_end; /* last+1 block of archive record */
|
||||
union block *current_block; /* current block of archive */
|
||||
enum access_mode access_mode; /* how do we handle the archive */
|
||||
off_t records_read; /* number of records read from this archive */
|
||||
off_t records_written; /* likewise, for records written */
|
||||
|
||||
static struct stat archive_stat; /* stat block for archive file */
|
||||
|
||||
static off_t record_start_block; /* block ordinal at record_start */
|
||||
@@ -117,7 +119,7 @@ off_t save_totsize; /* total size of file we are writing, only
|
||||
off_t save_sizeleft; /* where we are in the file we are writing,
|
||||
only valid if save_name is nonzero */
|
||||
|
||||
int write_archive_to_stdout;
|
||||
bool write_archive_to_stdout;
|
||||
|
||||
/* Used by flush_read and flush_write to store the real info about saved
|
||||
names. */
|
||||
@@ -299,7 +301,9 @@ write_archive_buffer (void)
|
||||
{
|
||||
written += status;
|
||||
if (written == record_size
|
||||
|| _isrmt (archive) || ! S_ISFIFO (archive_stat.st_mode))
|
||||
|| _isrmt (archive)
|
||||
|| ! (S_ISFIFO (archive_stat.st_mode)
|
||||
|| S_ISSOCK (archive_stat.st_mode)))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -804,8 +808,10 @@ open_archive (enum access_mode wanted_access)
|
||||
|
||||
switch (wanted_access)
|
||||
{
|
||||
case ACCESS_READ:
|
||||
case ACCESS_UPDATE:
|
||||
records_written = 0;
|
||||
case ACCESS_READ:
|
||||
records_read = 0;
|
||||
record_end = record_start; /* set up for 1st record = # 0 */
|
||||
find_next_block (); /* read it in, check for EOF */
|
||||
|
||||
@@ -824,6 +830,7 @@ open_archive (enum access_mode wanted_access)
|
||||
break;
|
||||
|
||||
case ACCESS_WRITE:
|
||||
records_written = 0;
|
||||
if (volume_label_option)
|
||||
{
|
||||
memset (record_start, 0, BLOCKSIZE);
|
||||
@@ -869,7 +876,10 @@ flush_write (void)
|
||||
archive_write_error (status);
|
||||
|
||||
if (status > 0)
|
||||
bytes_written += status;
|
||||
{
|
||||
records_written++;
|
||||
bytes_written += status;
|
||||
}
|
||||
|
||||
if (status == record_size)
|
||||
{
|
||||
@@ -1078,7 +1088,10 @@ flush_read (void)
|
||||
error_loop:
|
||||
status = rmtread (archive, record_start->buffer, record_size);
|
||||
if (status == record_size)
|
||||
return;
|
||||
{
|
||||
records_read++;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((status == 0
|
||||
|| (status < 0 && errno == ENOSPC)
|
||||
@@ -1176,6 +1189,7 @@ flush_read (void)
|
||||
cursor++;
|
||||
}
|
||||
current_block = cursor;
|
||||
records_read++;
|
||||
return;
|
||||
}
|
||||
else if (status < 0)
|
||||
@@ -1196,12 +1210,7 @@ flush_read (void)
|
||||
archive_read_error ();
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
if (left % BLOCKSIZE != 0)
|
||||
ERROR ((0, 0, _("%d garbage bytes ignored at end of archive"),
|
||||
(int) ((record_size - left) % BLOCKSIZE)));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
if (! read_full_records_option)
|
||||
FATAL_ERROR ((0, 0, _("Unaligned block (%lu bytes) in archive"),
|
||||
@@ -1222,6 +1231,7 @@ flush_read (void)
|
||||
(unsigned long) ((record_size - left) / BLOCKSIZE)));
|
||||
|
||||
record_end = record_start + (record_size - left) / BLOCKSIZE;
|
||||
records_read++;
|
||||
}
|
||||
|
||||
/* Flush the current buffer to/from the archive. */
|
||||
@@ -1322,7 +1332,7 @@ close_archive (void)
|
||||
|
||||
if (access_mode == ACCESS_READ
|
||||
&& ! _isrmt (archive)
|
||||
&& S_ISFIFO (archive_stat.st_mode))
|
||||
&& (S_ISFIFO (archive_stat.st_mode) || S_ISSOCK (archive_stat.st_mode)))
|
||||
while (rmtread (archive, record_start->buffer, record_size) > 0)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
@@ -454,6 +454,7 @@ maybe_recoverable (char *file_name, int *interdir_made)
|
||||
return 0;
|
||||
|
||||
case DEFAULT_OLD_FILES:
|
||||
case OVERWRITE_OLD_DIRS:
|
||||
case OVERWRITE_OLD_FILES:
|
||||
{
|
||||
int r = remove_any_file (file_name, 0);
|
||||
@@ -972,15 +973,19 @@ extract_archive (void)
|
||||
&& (base_name (CURRENT_FILE_NAME)
|
||||
== CURRENT_FILE_NAME + h->file_name_len + 1))
|
||||
{
|
||||
h->after_symlinks = 1;
|
||||
|
||||
if (stat (h->file_name, &st) != 0)
|
||||
stat_error (h->file_name);
|
||||
else
|
||||
do
|
||||
{
|
||||
h->stat_info.st_dev = st.st_dev;
|
||||
h->stat_info.st_ino = st.st_ino;
|
||||
h->after_symlinks = 1;
|
||||
|
||||
if (stat (h->file_name, &st) != 0)
|
||||
stat_error (h->file_name);
|
||||
else
|
||||
{
|
||||
h->stat_info.st_dev = st.st_dev;
|
||||
h->stat_info.st_ino = st.st_ino;
|
||||
}
|
||||
}
|
||||
while ((h = h->next) && ! h->after_symlinks);
|
||||
}
|
||||
|
||||
status = 0;
|
||||
@@ -1144,7 +1149,9 @@ extract_archive (void)
|
||||
if (status != 0)
|
||||
{
|
||||
if (errno == EEXIST
|
||||
&& (interdir_made || old_files_option == OVERWRITE_OLD_FILES))
|
||||
&& (interdir_made
|
||||
|| old_files_option == OVERWRITE_OLD_DIRS
|
||||
|| old_files_option == OVERWRITE_OLD_FILES))
|
||||
{
|
||||
struct stat st;
|
||||
if (stat (CURRENT_FILE_NAME, &st) == 0)
|
||||
@@ -1177,6 +1184,7 @@ extract_archive (void)
|
||||
|
||||
directory_exists:
|
||||
if (status == 0
|
||||
|| old_files_option == OVERWRITE_OLD_DIRS
|
||||
|| old_files_option == OVERWRITE_OLD_FILES)
|
||||
delay_set_stat (CURRENT_FILE_NAME, ¤t_stat,
|
||||
MODE_RWX & (mode ^ current_stat.st_mode),
|
||||
|
||||
95
src/list.c
95
src/list.c
@@ -32,6 +32,10 @@
|
||||
union block *current_header; /* points to current archive header */
|
||||
struct stat current_stat; /* stat struct corresponding */
|
||||
enum archive_format current_format; /* recognized format */
|
||||
union block *recent_long_name; /* recent long name header and contents */
|
||||
union block *recent_long_link; /* likewise, for long link */
|
||||
size_t recent_long_name_blocks; /* number of blocks in recent_long_name */
|
||||
size_t recent_long_link_blocks; /* likewise, for long link */
|
||||
|
||||
static uintmax_t from_header PARAMS ((const char *, size_t, const char *,
|
||||
uintmax_t, uintmax_t));
|
||||
@@ -73,7 +77,7 @@ read_and (void (*do_something) ())
|
||||
while (1)
|
||||
{
|
||||
prev_status = status;
|
||||
status = read_header ();
|
||||
status = read_header (0);
|
||||
switch (status)
|
||||
{
|
||||
case HEADER_STILL_UNREAD:
|
||||
@@ -239,6 +243,9 @@ list_archive (void)
|
||||
Return 1 for success, 0 if the checksum is bad, EOF on eof, 2 for a
|
||||
block full of zeros (EOF marker).
|
||||
|
||||
If RAW_EXTENDED_HEADERS is nonzero, do not automagically fold the
|
||||
GNU long name and link headers into later headers.
|
||||
|
||||
You must always set_next_block_after(current_header) to skip past
|
||||
the header which this routine reads. */
|
||||
|
||||
@@ -252,7 +259,7 @@ list_archive (void)
|
||||
computes two checksums -- signed and unsigned. */
|
||||
|
||||
enum read_header
|
||||
read_header (void)
|
||||
read_header (bool raw_extended_headers)
|
||||
{
|
||||
size_t i;
|
||||
int unsigned_sum; /* the POSIX one :-) */
|
||||
@@ -261,11 +268,14 @@ read_header (void)
|
||||
uintmax_t parsed_sum;
|
||||
char *p;
|
||||
union block *header;
|
||||
char **longp;
|
||||
union block *header_copy;
|
||||
char *bp;
|
||||
union block *data_block;
|
||||
size_t size, written;
|
||||
static char *next_long_name, *next_long_link;
|
||||
union block *next_long_name = 0;
|
||||
union block *next_long_link = 0;
|
||||
size_t next_long_name_blocks;
|
||||
size_t next_long_link_blocks;
|
||||
|
||||
while (1)
|
||||
{
|
||||
@@ -318,19 +328,38 @@ read_header (void)
|
||||
if (header->header.typeflag == GNUTYPE_LONGNAME
|
||||
|| header->header.typeflag == GNUTYPE_LONGLINK)
|
||||
{
|
||||
longp = ((header->header.typeflag == GNUTYPE_LONGNAME)
|
||||
? &next_long_name
|
||||
: &next_long_link);
|
||||
if (raw_extended_headers)
|
||||
return HEADER_SUCCESS_EXTENDED;
|
||||
else
|
||||
{
|
||||
size_t name_size = current_stat.st_size;
|
||||
size = name_size - name_size % BLOCKSIZE + 2 * BLOCKSIZE;
|
||||
if (name_size != current_stat.st_size || size < name_size)
|
||||
xalloc_die ();
|
||||
}
|
||||
|
||||
header_copy = xmalloc (size + 1);
|
||||
|
||||
if (header->header.typeflag == GNUTYPE_LONGNAME)
|
||||
{
|
||||
if (next_long_name)
|
||||
free (next_long_name);
|
||||
next_long_name = header_copy;
|
||||
next_long_name_blocks = size / BLOCKSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (next_long_link)
|
||||
free (next_long_link);
|
||||
next_long_link = header_copy;
|
||||
next_long_link_blocks = size / BLOCKSIZE;
|
||||
}
|
||||
|
||||
set_next_block_after (header);
|
||||
if (*longp)
|
||||
free (*longp);
|
||||
size = current_stat.st_size;
|
||||
if (size != current_stat.st_size)
|
||||
xalloc_die ();
|
||||
bp = *longp = xmalloc (size);
|
||||
*header_copy = *header;
|
||||
bp = header_copy->buffer + BLOCKSIZE;
|
||||
|
||||
for (; size > 0; size -= written)
|
||||
for (size -= BLOCKSIZE; size > 0; size -= written)
|
||||
{
|
||||
data_block = find_next_block ();
|
||||
if (! data_block)
|
||||
@@ -348,6 +377,8 @@ read_header (void)
|
||||
(data_block->buffer + written - 1));
|
||||
}
|
||||
|
||||
*bp = '\0';
|
||||
|
||||
/* Loop! */
|
||||
|
||||
}
|
||||
@@ -357,8 +388,16 @@ read_header (void)
|
||||
struct posix_header const *h = ¤t_header->header;
|
||||
char namebuf[sizeof h->prefix + 1 + NAME_FIELD_SIZE + 1];
|
||||
|
||||
name = next_long_name;
|
||||
if (! name)
|
||||
if (recent_long_name)
|
||||
free (recent_long_name);
|
||||
|
||||
if (next_long_name)
|
||||
{
|
||||
name = next_long_name->buffer + BLOCKSIZE;
|
||||
recent_long_name = next_long_name;
|
||||
recent_long_name_blocks = next_long_name_blocks;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Accept file names as specified by POSIX.1-1996
|
||||
section 10.1.1. */
|
||||
@@ -379,27 +418,29 @@ read_header (void)
|
||||
memcpy (np, h->name, sizeof h->name);
|
||||
np[sizeof h->name] = '\0';
|
||||
name = namebuf;
|
||||
recent_long_name = 0;
|
||||
recent_long_name_blocks = 0;
|
||||
}
|
||||
assign_string (¤t_file_name, name);
|
||||
if (next_long_name)
|
||||
|
||||
if (recent_long_link)
|
||||
free (recent_long_link);
|
||||
|
||||
if (next_long_link)
|
||||
{
|
||||
free (next_long_name);
|
||||
next_long_name = 0;
|
||||
name = next_long_link->buffer + BLOCKSIZE;
|
||||
recent_long_link = next_long_link;
|
||||
recent_long_link_blocks = next_long_link_blocks;
|
||||
}
|
||||
|
||||
name = next_long_link;
|
||||
if (! name)
|
||||
else
|
||||
{
|
||||
memcpy (namebuf, h->linkname, sizeof h->linkname);
|
||||
namebuf[sizeof h->linkname] = '\0';
|
||||
name = namebuf;
|
||||
recent_long_link = 0;
|
||||
recent_long_link_blocks = 0;
|
||||
}
|
||||
assign_string (¤t_link_name, name);
|
||||
if (next_long_link)
|
||||
{
|
||||
free (next_long_link);
|
||||
next_long_link = 0;
|
||||
}
|
||||
|
||||
return HEADER_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
|
||||
|
||||
#include "system.h"
|
||||
#include <copysym.h>
|
||||
#include <print-copyr.h>
|
||||
#include <localedir.h>
|
||||
#include <safe-read.h>
|
||||
#include <full-write.h>
|
||||
@@ -294,10 +294,8 @@ main (int argc, char *const *argv)
|
||||
|
||||
case 'v':
|
||||
{
|
||||
char buf[MB_LEN_MAX + 1];
|
||||
printf ("rmt (GNU %s) %s\n", PACKAGE, VERSION);
|
||||
printf ("Copyright %s 2001 Free Software Foundation, Inc.\n",
|
||||
copyright_symbol (buf, sizeof buf));
|
||||
print_copyright ("2001 Free Software Foundation, Inc.");
|
||||
puts (_("\
|
||||
This program comes with NO WARRANTY, to the extent permitted by law.\n\
|
||||
You may redistribute it under the terms of the GNU General Public License;\n\
|
||||
|
||||
13
src/tar.c
13
src/tar.c
@@ -36,7 +36,7 @@
|
||||
#define GLOBAL
|
||||
#include "common.h"
|
||||
|
||||
#include <copysym.h>
|
||||
#include <print-copyr.h>
|
||||
#include <localedir.h>
|
||||
#include <prepargs.h>
|
||||
#include <quotearg.h>
|
||||
@@ -140,6 +140,7 @@ enum
|
||||
NO_WILDCARDS_MATCH_SLASH_OPTION,
|
||||
NULL_OPTION,
|
||||
OVERWRITE_OPTION,
|
||||
OVERWRITE_DIR_OPTION,
|
||||
OWNER_OPTION,
|
||||
POSIX_OPTION,
|
||||
PRESERVE_OPTION,
|
||||
@@ -236,6 +237,7 @@ static struct option long_options[] =
|
||||
{"old-archive", no_argument, 0, 'o'},
|
||||
{"one-file-system", no_argument, 0, 'l'},
|
||||
{"overwrite", no_argument, 0, OVERWRITE_OPTION},
|
||||
{"overwrite-dir", no_argument, 0, OVERWRITE_DIR_OPTION},
|
||||
{"owner", required_argument, 0, OWNER_OPTION},
|
||||
{"portability", no_argument, 0, 'o'},
|
||||
{"posix", no_argument, 0, POSIX_OPTION},
|
||||
@@ -323,6 +325,7 @@ Operation modifiers:\n\
|
||||
--remove-files remove files after adding them to the archive\n\
|
||||
-k, --keep-old-files don't replace existing files when extracting\n\
|
||||
--overwrite overwrite existing files when extracting\n\
|
||||
--overwrite-dir overwrite directory metadata when extracting\n\
|
||||
-U, --unlink-first remove each file prior to extracting over it\n\
|
||||
--recursive-unlink empty hierarchies prior to extracting directory\n\
|
||||
-S, --sparse handle sparse files efficiently\n\
|
||||
@@ -960,6 +963,10 @@ decode_options (int argc, char **argv)
|
||||
old_files_option = OVERWRITE_OLD_FILES;
|
||||
break;
|
||||
|
||||
case OVERWRITE_DIR_OPTION:
|
||||
old_files_option = OVERWRITE_OLD_DIRS;
|
||||
break;
|
||||
|
||||
case OWNER_OPTION:
|
||||
if (! (strlen (optarg) < UNAME_FIELD_SIZE
|
||||
&& uname_to_uid (optarg, &owner_option)))
|
||||
@@ -1123,10 +1130,8 @@ decode_options (int argc, char **argv)
|
||||
|
||||
if (show_version)
|
||||
{
|
||||
char buf[MB_LEN_MAX + 1];
|
||||
printf ("tar (GNU %s) %s\n", PACKAGE, VERSION);
|
||||
printf ("Copyright %s 2001 Free Software Foundation, Inc.\n",
|
||||
copyright_symbol (buf, sizeof buf));
|
||||
print_copyright ("2001 Free Software Foundation, Inc.");
|
||||
puts (_("\
|
||||
This program comes with NO WARRANTY, to the extent permitted by law.\n\
|
||||
You may redistribute it under the terms of the GNU General Public License;\n\
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/* Format of tar archives.
|
||||
Copyright (C) 1988, 92, 93, 94, 96, 97 Free Software Foundation, Inc.
|
||||
/* GNU tar Archive Format description.
|
||||
|
||||
Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996,
|
||||
1997, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
@@ -15,8 +17,6 @@
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* GNU tar Archive Format description. */
|
||||
|
||||
/* If OLDGNU_COMPATIBILITY is not zero, tar produces archives which, by
|
||||
default, are readable by older versions of GNU tar. This can be
|
||||
overriden by using --posix; in this case, POSIXLY_CORRECT in environment
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/* Update a tar archive.
|
||||
Copyright 1988, 92, 94, 96, 97, 99, 2000 Free Software Foundation, Inc.
|
||||
|
||||
Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
@@ -106,7 +108,7 @@ update_archive (void)
|
||||
|
||||
while (!found_end)
|
||||
{
|
||||
enum read_header status = read_header ();
|
||||
enum read_header status = read_header (0);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
|
||||
45
tests/delete03.sh
Executable file
45
tests/delete03.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#! /bin/sh
|
||||
# Deleting members with long file names.
|
||||
|
||||
# Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
# 02111-1307, USA.
|
||||
|
||||
. ./preset
|
||||
. $srcdir/before
|
||||
|
||||
set -e
|
||||
prefix=This_is_a_very_long_file_name_prefix_that_is_designed_to_cause_problems_with_file_names_that_run_into_a_limit_of_the_posix_tar_formatXX
|
||||
rm -f $prefix*
|
||||
for i in 1 2 3 4 5 6 7 8 9
|
||||
do touch $prefix$i
|
||||
done
|
||||
tar -cf archive ./$prefix*
|
||||
tar --delete -f archive ./${prefix}5
|
||||
tar -tf archive
|
||||
|
||||
out="\
|
||||
./${prefix}1
|
||||
./${prefix}2
|
||||
./${prefix}3
|
||||
./${prefix}4
|
||||
./${prefix}6
|
||||
./${prefix}7
|
||||
./${prefix}8
|
||||
./${prefix}9
|
||||
"
|
||||
|
||||
. $srcdir/after
|
||||
Reference in New Issue
Block a user