Compare commits
26 Commits
release_1_
...
release_1_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0836a51147 | ||
|
|
afa743ac23 | ||
|
|
01dd89c121 | ||
|
|
1263f9bc1d | ||
|
|
1ff0b63f48 | ||
|
|
34d15af170 | ||
|
|
63712973c7 | ||
|
|
d9ec6f04e2 | ||
|
|
b5418cd393 | ||
|
|
615732a804 | ||
|
|
dd1a6bd37a | ||
|
|
41654f91f0 | ||
|
|
8d90723d30 | ||
|
|
14d8fc718f | ||
|
|
883cc555df | ||
|
|
e1005b385d | ||
|
|
14f00a2c7a | ||
|
|
f122fc94a7 | ||
|
|
b31afe7cf0 | ||
|
|
ea6f84dd40 | ||
|
|
2d3396c3ea | ||
|
|
d70b8b3b39 | ||
|
|
c445d99d4f | ||
|
|
2c9730357f | ||
|
|
ef0f882382 | ||
|
|
66162927eb |
@@ -1,6 +1,6 @@
|
||||
# Main Makefile for GNU tar.
|
||||
|
||||
# Copyright 1994-2019 Free Software Foundation, Inc.
|
||||
# Copyright 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
35
NEWS
35
NEWS
@@ -1,5 +1,36 @@
|
||||
GNU tar NEWS - User visible changes. 2019-02-23
|
||||
GNU tar NEWS - User visible changes. 2021-01-07
|
||||
Please send GNU tar bug reports to <bug-tar@gnu.org>
|
||||
|
||||
version 1.33 - Sergey Poznyakoff, 2021-01-07
|
||||
|
||||
* POSIX extended format headers do not include PID by default
|
||||
|
||||
The intent is to make binary-equivalent PAX archives easy to create. If
|
||||
POSIXLY_CORRECT is set, the POSIX standard default is used, which embeds
|
||||
the pid.
|
||||
|
||||
* --delay-directory-restore works for archives with reversed member ordering
|
||||
|
||||
* Fix extraction of a symbolic link hardlinked to another symbolic link
|
||||
|
||||
* Wildcards in exclude-vcs-ignore mode don't match slash
|
||||
|
||||
* Fix the --no-overwrite-dir option
|
||||
|
||||
Given this option, previous versions of tar failed to preserve
|
||||
permissions of empty directories and to create files under directories
|
||||
owned by the current user that did not have the S_IWUSR bit set.
|
||||
|
||||
* Fix handling of chained renames in incremental backups
|
||||
|
||||
* Link counting works for file names supplied with -T
|
||||
|
||||
* Accept only position-sensitive (file-selection) options in file list files.
|
||||
|
||||
Using such options as -f, -z, etc. is senseless in a file list file and
|
||||
bypasses option consistency checks in decode_options. Therefore,
|
||||
only options related to file selection (a.k.a position-sensitive options)
|
||||
are allowed in file list files.
|
||||
|
||||
|
||||
version 1.32 - Sergey Poznyakoff, 2019-02-23
|
||||
@@ -1687,7 +1718,7 @@ Versions 1.07 back to 1.00 by Jay Fenlason.
|
||||
|
||||
|
||||
|
||||
Copyright 1994-2019 Free Software Foundation, Inc.
|
||||
Copyright 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
2
README
2
README
@@ -221,7 +221,7 @@ and share your findings by writing to <bug-tar@gnu.org>.
|
||||
|
||||
* Copying
|
||||
|
||||
Copyright 1990-2019 Free Software Foundation, Inc.
|
||||
Copyright 1990-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ behavior. Run 'bootstrap --help' for a list.
|
||||
|
||||
|
||||
|
||||
Copyright 2001-2019 Free Software Foundation, Inc.
|
||||
Copyright 2001-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ See 'bootstrap --help' for a detailed list.
|
||||
|
||||
* Copyright information
|
||||
|
||||
Copyright 2007-2019 Free Software Foundation, Inc.
|
||||
Copyright 2007-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
2
TODO
2
TODO
@@ -45,7 +45,7 @@ Suggestions for improving GNU tar.
|
||||
|
||||
* Copyright notice
|
||||
|
||||
Copyright 2003-2019 Free Software Foundation, Inc.
|
||||
Copyright 2003-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
dnl Special Autoconf macros for GNU tar -*- autoconf -*-
|
||||
|
||||
dnl Copyright 2009-2019 Free Software Foundation, Inc.
|
||||
dnl Copyright 2009-2021 Free Software Foundation, Inc.
|
||||
dnl
|
||||
dnl This file is part of GNU tar.
|
||||
dnl
|
||||
|
||||
@@ -4,7 +4,7 @@ scriptversion=2015-08-24.08; # UTC
|
||||
|
||||
# Bootstrap this package from checked-out sources.
|
||||
|
||||
# Copyright (C) 2003-2019 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2003-2021 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Bootstrap configuration for GNU tar.
|
||||
|
||||
# Copyright 2006-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2006-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Configure template for GNU tar. -*- autoconf -*-
|
||||
|
||||
# Copyright 1991, 1994-2010, 2013-2019 Free Software Foundation, Inc.
|
||||
# Copyright 1991, 1994-2010, 2013-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AC_INIT([GNU tar], [1.32], [bug-tar@gnu.org])
|
||||
AC_INIT([GNU tar], [1.33], [bug-tar@gnu.org])
|
||||
AC_CONFIG_SRCDIR([src/tar.c])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_PREREQ([2.63])
|
||||
AM_INIT_AUTOMAKE([1.11 gnits tar-ustar dist-bzip2 dist-xz std-options silent-rules])
|
||||
AC_PREREQ([2.64])
|
||||
AM_INIT_AUTOMAKE([1.15 gnits tar-ustar dist-bzip2 dist-xz std-options silent-rules])
|
||||
|
||||
# Enable silent rules by default:
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
%%comments:
|
||||
Copyright 2004-2019 Free Software Foundation, Inc.
|
||||
Copyright 2004-2021 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Makefile for GNU tar documentation.
|
||||
|
||||
# Copyright 1994-2019 Free Software Foundation, Inc.
|
||||
# Copyright 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
@@ -22,7 +22,6 @@ tar_TEXINFOS = \
|
||||
dumpdir.texi\
|
||||
tar-snapshot-edit.texi\
|
||||
fdl.texi\
|
||||
freemanuals.texi\
|
||||
genfile.texi\
|
||||
header.texi\
|
||||
intern.texi\
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of the paxutils manual.
|
||||
@c Copyright (C) 2006-2019 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 2006--2021 Free Software Foundation, Inc.
|
||||
@c Written by Sergey Poznyakoff
|
||||
@c This file is distributed under GFDL 1.1 or any later version
|
||||
@c published by the Free Software Foundation.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
@c hence no sectioning command or @node.
|
||||
|
||||
@display
|
||||
Copyright @copyright{} 2000-2019 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 2000--2021 Free Software Foundation, Inc.
|
||||
@uref{http://fsf.org/}
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
@cindex free documentation
|
||||
|
||||
The biggest deficiency in the free software community today is not in
|
||||
the software---it is the lack of good free documentation that we can
|
||||
include with the free software. Many of our most important
|
||||
programs do not come with free reference manuals and free introductory
|
||||
texts. Documentation is an essential part of any software package;
|
||||
when an important free software package does not come with a free
|
||||
manual and a free tutorial, that is a major gap. We have many such
|
||||
gaps today.
|
||||
|
||||
Consider Perl, for instance. The tutorial manuals that people
|
||||
normally use are non-free. How did this come about? Because the
|
||||
authors of those manuals published them with restrictive terms---no
|
||||
copying, no modification, source files not available---which exclude
|
||||
them from the free software world.
|
||||
|
||||
That wasn't the first time this sort of thing happened, and it was far
|
||||
from the last. Many times we have heard a GNU user eagerly describe a
|
||||
manual that he is writing, his intended contribution to the community,
|
||||
only to learn that he had ruined everything by signing a publication
|
||||
contract to make it non-free.
|
||||
|
||||
Free documentation, like free software, is a matter of freedom, not
|
||||
price. The problem with the non-free manual is not that publishers
|
||||
charge a price for printed copies---that in itself is fine. (The Free
|
||||
Software Foundation sells printed copies of manuals, too.) The
|
||||
problem is the restrictions on the use of the manual. Free manuals
|
||||
are available in source code form, and give you permission to copy and
|
||||
modify. Non-free manuals do not allow this.
|
||||
|
||||
The criteria of freedom for a free manual are roughly the same as for
|
||||
free software. Redistribution (including the normal kinds of
|
||||
commercial redistribution) must be permitted, so that the manual can
|
||||
accompany every copy of the program, both on-line and on paper.
|
||||
|
||||
Permission for modification of the technical content is crucial too.
|
||||
When people modify the software, adding or changing features, if they
|
||||
are conscientious they will change the manual too---so they can
|
||||
provide accurate and clear documentation for the modified program. A
|
||||
manual that leaves you no choice but to write a new manual to document
|
||||
a changed version of the program is not really available to our
|
||||
community.
|
||||
|
||||
Some kinds of limits on the way modification is handled are
|
||||
acceptable. For example, requirements to preserve the original
|
||||
author's copyright notice, the distribution terms, or the list of
|
||||
authors, are ok. It is also no problem to require modified versions
|
||||
to include notice that they were modified. Even entire sections that
|
||||
may not be deleted or changed are acceptable, as long as they deal
|
||||
with nontechnical topics (like this one). These kinds of restrictions
|
||||
are acceptable because they don't obstruct the community's normal use
|
||||
of the manual.
|
||||
|
||||
However, it must be possible to modify all the @emph{technical}
|
||||
content of the manual, and then distribute the result in all the usual
|
||||
media, through all the usual channels. Otherwise, the restrictions
|
||||
obstruct the use of the manual, it is not free, and we need another
|
||||
manual to replace it.
|
||||
|
||||
Please spread the word about this issue. Our community continues to
|
||||
lose manuals to proprietary publishing. If we spread the word that
|
||||
free software needs free reference manuals and free tutorials, perhaps
|
||||
the next person who wants to contribute by writing documentation will
|
||||
realize, before it is too late, that only free manuals contribute to
|
||||
the free software community.
|
||||
|
||||
If you are writing documentation, please insist on publishing it under
|
||||
the GNU Free Documentation License or another free documentation
|
||||
license. Remember that this decision requires your approval---you
|
||||
don't have to let the publisher decide. Some commercial publishers
|
||||
will use a free license if you insist, but they will not propose the
|
||||
option; it is up to you to raise the issue and say firmly that this is
|
||||
what you want. If the publisher you are dealing with refuses, please
|
||||
try other publishers. If you're not sure whether a proposed license
|
||||
is free, write to @email{licensing@@gnu.org}.
|
||||
|
||||
You can encourage commercial publishers to sell more free, copylefted
|
||||
manuals and tutorials by buying them, and particularly by buying
|
||||
copies from the publishers that paid for their writing or for major
|
||||
improvements. Meanwhile, try to avoid buying non-free documentation
|
||||
at all. Check the distribution terms of a manual before you buy it,
|
||||
and insist that whoever seeks your business must respect your freedom.
|
||||
Check the history of the book, and try reward the publishers that have
|
||||
paid or pay the authors to work on it.
|
||||
|
||||
The Free Software Foundation maintains a list of free documentation
|
||||
published by other publishers, at
|
||||
@url{http://www.fsf.org/doc/other-free-books.html}.
|
||||
@@ -106,7 +106,7 @@ Please send broken links and other corrections (or suggestions) to
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Copyright 2004-2019 Free Software Foundation, Inc.,
|
||||
Copyright 2004-2021 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02111, USA
|
||||
<br />
|
||||
Verbatim copying and distribution of this entire article is
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of the paxutils manual.
|
||||
@c Copyright (C) 2006-2019 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 2006--2021 Free Software Foundation, Inc.
|
||||
@c This file is distributed under GFDL 1.1 or any later version
|
||||
@c published by the Free Software Foundation.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;;; mastermenu.el --- Redefinition of texinfo-master-menu-list
|
||||
|
||||
;; Copyright 2006-2019 Free Software Foundation, Inc.
|
||||
;; Copyright 2006-2021 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Sergey Poznyakoff
|
||||
;; Maintainer: bug-tar@gnu.org
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of the GNU tar manual.
|
||||
@c Copyright (C) 2017-2019 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 2017--2021 Free Software Foundation, Inc.
|
||||
@c This file is distributed under GFDL 1.3 or any later version
|
||||
@c published by the Free Software Foundation.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of GNU tar manual.
|
||||
@c Copyright 1992-2019 Free Software Foundation, Inc.
|
||||
@c Copyright 1992--2021 Free Software Foundation, Inc.
|
||||
@c See file tar.texi for copying conditions.
|
||||
|
||||
@c This file contains support for 'renditions' by Fran@,{c}ois Pinard
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of the paxutils manual.
|
||||
@c Copyright (C) 2005-2019 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 2005--2021 Free Software Foundation, Inc.
|
||||
@c Written by Sergey Poznyakoff
|
||||
@c This file is distributed under GFDL 1.1 or any later version
|
||||
@c published by the Free Software Foundation.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of the paxutils manual.
|
||||
@c Copyright (C) 2006-2019 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 2006--2021 Free Software Foundation, Inc.
|
||||
@c This file is distributed under GFDL 1.1 or any later version
|
||||
@c published by the Free Software Foundation.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of the paxutils manual.
|
||||
@c Copyright (C) 2007-2019 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 2007--2021 Free Software Foundation, Inc.
|
||||
@c This file is distributed under GFDL 1.1 or any later version
|
||||
@c published by the Free Software Foundation.
|
||||
|
||||
|
||||
24
doc/tar.1
24
doc/tar.1
@@ -1,5 +1,5 @@
|
||||
.\" This file is part of GNU tar. -*- nroff -*-
|
||||
.\" Copyright 2013-2019 Free Software Foundation, Inc.
|
||||
.\" Copyright 2013-2021 Free Software Foundation, Inc.
|
||||
.\"
|
||||
.\" 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
|
||||
@@ -13,7 +13,7 @@
|
||||
.\"
|
||||
.\" You should have received a copy of the GNU General Public License
|
||||
.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
.TH TAR 1 "February 4, 2019" "TAR" "GNU TAR Manual"
|
||||
.TH TAR 1 "July 13, 2020" "TAR" "GNU TAR Manual"
|
||||
.SH NAME
|
||||
tar \- an archiving utility
|
||||
.SH SYNOPSIS
|
||||
@@ -111,7 +111,7 @@ into the archive file
|
||||
verbosely listing the files being archived:
|
||||
.PP
|
||||
.EX
|
||||
.B tar cfv etc.tar /etc
|
||||
tar cfv etc.tar /etc
|
||||
.EE
|
||||
.PP
|
||||
In
|
||||
@@ -133,9 +133,11 @@ The example command above written in the
|
||||
could look like:
|
||||
.PP
|
||||
.EX
|
||||
.B tar -cvf etc.tar /etc
|
||||
tar -cvf etc.tar /etc
|
||||
.EE
|
||||
or
|
||||
.B tar -c -v -f etc.tar /etc
|
||||
.EX
|
||||
tar -c -v -f etc.tar /etc
|
||||
.EE
|
||||
.PP
|
||||
In
|
||||
@@ -152,11 +154,11 @@ method.
|
||||
Here are several ways of writing the example command in this style:
|
||||
.PP
|
||||
.EX
|
||||
.B tar --create --file etc.tar --verbose /etc
|
||||
tar --create --file etc.tar --verbose /etc
|
||||
.EE
|
||||
or (abbreviating some options):
|
||||
.EX
|
||||
.B tar --cre --file=etc.tar --verb /etc
|
||||
tar --cre --file=etc.tar --verb /etc
|
||||
.EE
|
||||
.PP
|
||||
The options in all three styles can be intermixed, although doing so
|
||||
@@ -463,6 +465,7 @@ Format of the archive being processed. One of:
|
||||
.BR posix ,
|
||||
.BR ustar ,
|
||||
.BR v7 .
|
||||
.TP
|
||||
.B TAR_SUBCOMMAND
|
||||
A short option (with a leading dash) describing the operation \fBtar\fR is
|
||||
executing.
|
||||
@@ -780,7 +783,8 @@ Same as \fB\-\-format=v7\fR.
|
||||
\fB\-\-pax\-option\fR=\fIkeyword\fR[[:]=\fIvalue\fR][,\fIkeyword\fR[[:]=\fIvalue\fR]]...
|
||||
Control pax keywords when creating \fBPAX\fR archives (\fB\-H
|
||||
pax\fR). This option is equivalent to the \fB\-o\fR option of the
|
||||
.BR pax (1) utility.
|
||||
.BR pax (1)
|
||||
utility.
|
||||
.TP
|
||||
\fB\-\-posix\fR
|
||||
Same as \fB\-\-format=posix\fR.
|
||||
@@ -960,7 +964,7 @@ See also \fB\-\-verbatim\-files\-from\fR.
|
||||
.TP
|
||||
\fB\-N\fR, \fB\-\-newer\fR=\fIDATE\fR, \fB\-\-after\-date\fR=\fIDATE\fR
|
||||
Only store files newer than DATE. If \fIDATE\fR starts with \fB/\fR
|
||||
or \fB.\fR it is taken to be a file name; the ctime of that file is
|
||||
or \fB.\fR it is taken to be a file name; the mtime of that file is
|
||||
used as the date.
|
||||
.TP
|
||||
\fB\-\-one\-file\-system\fR
|
||||
@@ -1318,7 +1322,7 @@ found at:
|
||||
.SH "BUG REPORTS"
|
||||
Report bugs to <bug\-tar@gnu.org>.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2013 Free Software Foundation, Inc.
|
||||
Copyright \(co 2013-2019 Free Software Foundation, Inc.
|
||||
.br
|
||||
.na
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||
|
||||
88
doc/tar.texi
88
doc/tar.texi
@@ -36,8 +36,8 @@ This manual is for @acronym{GNU} @command{tar} (version
|
||||
@value{VERSION}, @value{UPDATED}), which creates and extracts files
|
||||
from archives.
|
||||
|
||||
Copyright @copyright{} 1992, 1994--1997, 1999--2001, 2003--2017 Free
|
||||
Software Foundation, Inc.
|
||||
Copyright @copyright{} 1992, 1994--1997, 1999--2001, 2003--2017, 2021
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
@@ -116,7 +116,6 @@ Appendices
|
||||
* Fixing Snapshot Files::
|
||||
* Tar Internals::
|
||||
* Genfile::
|
||||
* Free Software Needs Free Documentation::
|
||||
* GNU Free Documentation License::
|
||||
* Index of Command Line Options::
|
||||
* Index::
|
||||
@@ -3977,7 +3976,7 @@ successfully. For example, @w{@samp{tar --version}} might print:
|
||||
|
||||
@smallexample
|
||||
tar (GNU tar) @value{VERSION}
|
||||
Copyright (C) 2013-2019 Free Software Foundation, Inc.
|
||||
Copyright (C) 2013-2020 Free Software Foundation, Inc.
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
@@ -5726,7 +5725,7 @@ Disable POSIX ACLs support. This is the default.
|
||||
|
||||
When listing the archive, if both @option{--acls} and
|
||||
@option{--verbose} options are given, files that have ACLs are marked
|
||||
with a plus sing following their permission mask. For example:
|
||||
with a plus sign following their permission mask. For example:
|
||||
|
||||
@example
|
||||
-rw-r--r--+ smith/users 110 2016-03-16 16:07 file
|
||||
@@ -7731,9 +7730,12 @@ any leading and trailing whitespace. If the resulting string begins
|
||||
with @samp{-} character, it is considered a @command{tar} option and is
|
||||
processed accordingly@footnote{Versions of @GNUTAR{} up to 1.15.1
|
||||
recognized only @option{-C} option in file lists, and only if the
|
||||
option and its argument occupied two consecutive lines.}. For example,
|
||||
the common use of this feature is to change to another directory by
|
||||
specifying @option{-C} option:
|
||||
option and its argument occupied two consecutive lines.}. Only a
|
||||
subset of @GNUTAR{} options is allowed for use in file lists. For
|
||||
a list of such options, @ref{Position-Sensitive Options}.
|
||||
|
||||
For example, the common use of this feature is to change to another
|
||||
directory by specifying @option{-C} option:
|
||||
|
||||
@smallexample
|
||||
@group
|
||||
@@ -10458,9 +10460,16 @@ If no option @samp{exthdr.name=string} is specified, @command{tar}
|
||||
will use the following default value:
|
||||
|
||||
@smallexample
|
||||
%d/PaxHeaders.%p/%f
|
||||
%d/PaxHeaders/%f
|
||||
@end smallexample
|
||||
|
||||
This default is selected to ensure the reproducibility of the
|
||||
archive. @acronym{POSIX} standard recommends to use
|
||||
@samp{%d/PaxHeaders.%p/%f} instead, which means the two archives
|
||||
created with the same set of options and containing the same set
|
||||
of files will be byte-to-byte different. This default will be used
|
||||
if the environment variable @env{POSIXLY_CORRECT} is set.
|
||||
|
||||
@item exthdr.mtime=@var{value}
|
||||
|
||||
This keyword defines the value of the @samp{mtime} field that
|
||||
@@ -10489,12 +10498,18 @@ Any other @samp{%} characters in @var{string} produce undefined results.
|
||||
If no option @samp{globexthdr.name=string} is specified, @command{tar}
|
||||
will use the following default value:
|
||||
|
||||
@smallexample
|
||||
$TMPDIR/GlobalHead.%n
|
||||
@end smallexample
|
||||
|
||||
If the environment variable @env{POSIXLY_CORRECT} is set, the
|
||||
following value is used instead:
|
||||
|
||||
@smallexample
|
||||
$TMPDIR/GlobalHead.%p.%n
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
where @samp{$TMPDIR} represents the value of the @var{TMPDIR}
|
||||
In both cases, @samp{$TMPDIR} stands for the value of the @var{TMPDIR}
|
||||
environment variable. If @var{TMPDIR} is not set, @command{tar}
|
||||
uses @samp{/tmp}.
|
||||
|
||||
@@ -10557,7 +10572,7 @@ archives created using it, will be binary equivalent if they have the
|
||||
same contents:
|
||||
|
||||
@smallexample
|
||||
--pax-option=exthdr.name=%d/PaxHeaders/%f,atime:=0
|
||||
--pax-option=atime:=0
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
@@ -10566,14 +10581,27 @@ from them, you will also need to eliminate changes due to ctime, as
|
||||
shown in examples below:
|
||||
|
||||
@smallexample
|
||||
--pax-option=exthdr.name=%d/PaxHeaders/%f,atime:=0,ctime:=0
|
||||
--pax-option=atime:=0,ctime:=0
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
or
|
||||
|
||||
@smallexample
|
||||
--pax-option=exthdr.name=%d/PaxHeaders/%f,atime:=0,delete=ctime
|
||||
--pax-option=atime:=0,delete=ctime
|
||||
@end smallexample
|
||||
|
||||
Notice, that if you create an archive in POSIX format (@pxref{posix})
|
||||
and the environment variable @env{POSIXLY_CORRECT} is set, then the
|
||||
two archives created using the same options on the same set of files
|
||||
will not be byte-to-byte equivalent even with the above option. This
|
||||
is because the posix default for extended header names includes the
|
||||
PID of the tar process, which is different at each run. To produce
|
||||
byte-to-byte equivalent archives in this case, either unset
|
||||
@env{POSIXLY_CORRECT}, or use the following option:
|
||||
|
||||
@smallexample
|
||||
---pax-option=exthdr.name=%d/PaxHeaders/%f,atime:=0,ctime:=0
|
||||
@end smallexample
|
||||
|
||||
@node Checksumming
|
||||
@@ -10699,7 +10727,7 @@ GNU extensions. More specifically, the very first part retains its
|
||||
original name, and all subsequent parts are named using the pattern:
|
||||
|
||||
@smallexample
|
||||
%d/GNUFileParts.%p/%f.%n
|
||||
%d/GNUFileParts/%f.%n
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
@@ -10718,13 +10746,12 @@ created the archive.
|
||||
@end multitable
|
||||
|
||||
For example, if the file @file{var/longfile} was split during archive
|
||||
creation between three volumes, and the creator @command{tar} process
|
||||
had process @acronym{ID} @samp{27962}, then the member names will be:
|
||||
creation between three volumes, then the member names will be:
|
||||
|
||||
@smallexample
|
||||
var/longfile
|
||||
var/GNUFileParts.27962/longfile.1
|
||||
var/GNUFileParts.27962/longfile.2
|
||||
var/GNUFileParts/longfile.1
|
||||
var/GNUFileParts/longfile.2
|
||||
@end smallexample
|
||||
|
||||
When you extract your archive using a third-party @command{tar}, these
|
||||
@@ -10735,9 +10762,9 @@ the proper order, for example:
|
||||
@smallexample
|
||||
@group
|
||||
$ @kbd{cd var}
|
||||
$ @kbd{cat GNUFileParts.27962/longfile.1 \
|
||||
GNUFileParts.27962/longfile.2 >> longfile}
|
||||
$ rm -f GNUFileParts.27962
|
||||
$ @kbd{cat GNUFileParts/longfile.1 \
|
||||
GNUFileParts/longfile.2 >> longfile}
|
||||
$ rm -f GNUFileParts
|
||||
@end group
|
||||
@end smallexample
|
||||
|
||||
@@ -10763,12 +10790,12 @@ more warnings and more files generated on your disk, e.g.:
|
||||
@smallexample
|
||||
@group
|
||||
$ @kbd{tar xf vol-1.tar}
|
||||
var/PaxHeaders.27962/longfile: Unknown file type 'x', extracted as
|
||||
var/PaxHeaders/longfile: Unknown file type 'x', extracted as
|
||||
normal file
|
||||
Unexpected EOF in archive
|
||||
$ @kbd{tar xf vol-2.tar}
|
||||
tmp/GlobalHead.27962.1: Unknown file type 'g', extracted as normal file
|
||||
GNUFileParts.27962/PaxHeaders.27962/sparsefile.1: Unknown file type
|
||||
tmp/GlobalHead.1: Unknown file type 'g', extracted as normal file
|
||||
GNUFileParts/PaxHeaders/sparsefile.1: Unknown file type
|
||||
'x', extracted as normal file
|
||||
@end group
|
||||
@end smallexample
|
||||
@@ -10884,8 +10911,8 @@ use. Continuing our example:
|
||||
|
||||
@smallexample
|
||||
@group
|
||||
$ @kbd{xsparse -v -x /home/gray/PaxHeaders.6058/sparsefile \
|
||||
/home/gray/GNUSparseFile.6058/sparsefile}
|
||||
$ @kbd{xsparse -v -x /home/gray/PaxHeaders/sparsefile \
|
||||
/home/gray/GNUSparseFile/sparsefile}
|
||||
Reading extended header file
|
||||
Found variable GNU.sparse.major = 1
|
||||
Found variable GNU.sparse.minor = 0
|
||||
@@ -10915,8 +10942,7 @@ If you use a @command{tar} implementation that does not support PAX
|
||||
format, extended headers for each member will be extracted as a
|
||||
separate file. If we represent the member name as
|
||||
@file{@var{dir}/@var{name}}, then the extended header file will be
|
||||
named @file{@var{dir}/@/PaxHeaders.@var{n}/@/@var{name}}, where
|
||||
@var{n} is an integer number.
|
||||
named @file{@var{dir}/@/PaxHeaders/@/@var{name}}.
|
||||
|
||||
Things become more difficult if your @command{tar} implementation
|
||||
does support PAX headers, because in this case you will have to
|
||||
@@ -13230,10 +13256,6 @@ Right margin of the text output. Used for wrapping.
|
||||
@appendix Genfile
|
||||
@include genfile.texi
|
||||
|
||||
@node Free Software Needs Free Documentation
|
||||
@appendix Free Software Needs Free Documentation
|
||||
@include freemanuals.texi
|
||||
|
||||
@node GNU Free Documentation License
|
||||
@appendix GNU Free Documentation License
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2006-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2006-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of GNU tar manual.
|
||||
@c Copyright 1992-2019 Free Software Foundation, Inc.
|
||||
@c Copyright 1992--2021 Free Software Foundation, Inc.
|
||||
@c See file tar.texi for copying conditions.
|
||||
|
||||
@macro GNUTAR
|
||||
|
||||
2
gnulib
2
gnulib
Submodule gnulib updated: 4652c7bafa...30820c2d7c
@@ -1,7 +1,7 @@
|
||||
# List of gnulib modules needed for GNU tar.
|
||||
# A module name per line. Empty lines and comments are ignored.
|
||||
|
||||
# Copyright 2005-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2005-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Makefile for GNU tar library. -*- Makefile -*-
|
||||
|
||||
# Copyright 1994-2019 Free Software Foundation, Inc.
|
||||
# Copyright 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Replacement <attr/xattr.h> for platforms that lack it.
|
||||
Copyright 2012-2019 Free Software Foundation, Inc.
|
||||
Copyright 2012-2021 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* stdopen.c - ensure that the three standard file descriptors are in use
|
||||
|
||||
Copyright 2005-2019 Free Software Foundation, Inc.
|
||||
Copyright 2005-2021 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* openat-style fd-relative functions for operating with extended file
|
||||
attributes.
|
||||
|
||||
Copyright 2012-2019 Free Software Foundation, Inc.
|
||||
Copyright 2012-2021 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Prototypes for openat-style fd-relative functions for operating with
|
||||
extended file attributes.
|
||||
|
||||
Copyright 2012-2019 Free Software Foundation, Inc.
|
||||
Copyright 2012-2021 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# List of files which contain translatable strings.
|
||||
|
||||
# Copyright 1996-2019 Free Software Foundation, Inc.
|
||||
# Copyright 1996-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Make GNU tar scripts.
|
||||
|
||||
# Copyright 2004-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2004-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ SLEEP_MESSAGE="`awk '
|
||||
}' /dev/null`"
|
||||
|
||||
|
||||
# Copyright 2004-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2004-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#! /bin/sh
|
||||
# Make backups.
|
||||
|
||||
# Copyright 2004-2006, 2013 Free Software Foundation
|
||||
# Copyright 2004-2006, 2013, 2019 Free Software Foundation
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
@@ -149,7 +149,7 @@ message 20 "Variables:"
|
||||
message 20 "BACKUP_DIRS=$BACKUP_DIRS"
|
||||
message 20 "BACKUP_FILES=$BACKUP_FILES"
|
||||
|
||||
# The buch of commands below is run in a subshell for which all output is
|
||||
# The bunch of commands below is run in a subshell for which all output is
|
||||
# piped through 'tee' to the logfile. Doing this, instead of having
|
||||
# multiple pipelines all over the place, is cleaner and allows access to
|
||||
# the exit value from various commands more easily.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#! /bin/sh
|
||||
# Make backups.
|
||||
|
||||
# Copyright 2004-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2004-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# interested parties that a tape for the next volume of the backup needs to
|
||||
# be put in the tape drive.
|
||||
|
||||
# Copyright 2004-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2004-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#! /bin/sh
|
||||
# Restore backups.
|
||||
|
||||
# Copyright 2004-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2004-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /usr/bin/perl -w
|
||||
# Display and edit the 'dev' field in tar's snapshots
|
||||
# Copyright 2007-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2007-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# concatenates a GNU tar multi-volume archive into a single tar archive.
|
||||
# Author: Bruno Haible <bruno@clisp.org>, Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
# Copyright 2004-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2004-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* xsparse - expands compressed sparse file images extracted from GNU tar
|
||||
archives.
|
||||
|
||||
Copyright 2006-2019 Free Software Foundation, Inc.
|
||||
Copyright 2006-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Makefile for GNU tar sources.
|
||||
|
||||
# Copyright 1994-2019 Free Software Foundation, Inc.
|
||||
# Copyright 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Long integers, for GNU tar.
|
||||
Copyright 1999-2019 Free Software Foundation, Inc.
|
||||
Copyright 1999-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Buffer management for tar.
|
||||
|
||||
Copyright 1988-2019 Free Software Foundation, Inc.
|
||||
Copyright 1988-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -1731,7 +1731,7 @@ add_chunk_header (struct bufmap *map)
|
||||
st.stat.st_uid = getuid ();
|
||||
st.stat.st_gid = getgid ();
|
||||
st.orig_file_name = xheader_format_name (&st,
|
||||
"%d/GNUFileParts.%p/%f.%n",
|
||||
"%d/GNUFileParts/%f.%n",
|
||||
volno);
|
||||
st.file_name = st.orig_file_name;
|
||||
st.archive_file_size = st.stat.st_size = map->sizeleft;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Checkpoint management for tar.
|
||||
|
||||
Copyright 2007-2019 Free Software Foundation, Inc.
|
||||
Copyright 2007-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
39
src/common.h
39
src/common.h
@@ -1,6 +1,6 @@
|
||||
/* Common declarations for the tar program.
|
||||
|
||||
Copyright 1988-2019 Free Software Foundation, Inc.
|
||||
Copyright 1988-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -340,6 +340,9 @@ GLOBAL const char *volume_label_option;
|
||||
|
||||
/* Other global variables. */
|
||||
|
||||
/* Force POSIX-compliance */
|
||||
GLOBAL bool posixly_correct;
|
||||
|
||||
/* File descriptor for archive file. */
|
||||
GLOBAL int archive;
|
||||
|
||||
@@ -739,7 +742,21 @@ int set_file_atime (int fd, int parentfd, char const *file,
|
||||
|
||||
/* Module names.c. */
|
||||
|
||||
extern size_t name_count;
|
||||
enum files_count
|
||||
{
|
||||
FILES_NONE,
|
||||
FILES_ONE,
|
||||
FILES_MANY
|
||||
};
|
||||
extern enum files_count filename_args;
|
||||
|
||||
/* Return true if there are file names in the list */
|
||||
static inline bool
|
||||
name_more_files (void)
|
||||
{
|
||||
return filename_args != FILES_NONE;
|
||||
}
|
||||
|
||||
extern struct name *gnu_list_name;
|
||||
|
||||
void gid_to_gname (gid_t gid, char **gname);
|
||||
@@ -817,6 +834,24 @@ struct option_locus
|
||||
class */
|
||||
};
|
||||
|
||||
struct tar_args /* Variables used during option parsing */
|
||||
{
|
||||
struct option_locus *loc;
|
||||
|
||||
struct textual_date *textual_date; /* Keeps the arguments to --newer-mtime
|
||||
and/or --date option if they are
|
||||
textual dates */
|
||||
bool o_option; /* True if -o option was given */
|
||||
bool pax_option; /* True if --pax-option was given */
|
||||
bool compress_autodetect; /* True if compression autodetection should
|
||||
be attempted when creating archives */
|
||||
char const *backup_suffix_string; /* --suffix option argument */
|
||||
char const *version_control_string; /* --backup option argument */
|
||||
};
|
||||
|
||||
#define TAR_ARGS_INITIALIZER(loc) \
|
||||
{ loc, NULL, false, false, false, NULL, NULL }
|
||||
|
||||
void more_options (int argc, char **argv, struct option_locus *loc);
|
||||
|
||||
/* Module update.c. */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Diff files from a tar archive.
|
||||
|
||||
Copyright 1988-2019 Free Software Foundation, Inc.
|
||||
Copyright 1988-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
24
src/create.c
24
src/create.c
@@ -1,6 +1,6 @@
|
||||
/* Create a tar archive.
|
||||
|
||||
Copyright 1985-2019 Free Software Foundation, Inc.
|
||||
Copyright 1985-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -1348,15 +1348,15 @@ create_archive (void)
|
||||
{
|
||||
struct name const *p;
|
||||
|
||||
trivial_link_count = name_count <= 1 && ! dereference_option;
|
||||
trivial_link_count = filename_args != FILES_MANY && ! dereference_option;
|
||||
|
||||
open_archive (ACCESS_WRITE);
|
||||
buffer_write_global_xheader ();
|
||||
|
||||
if (incremental_option)
|
||||
{
|
||||
size_t buffer_size = 1000;
|
||||
char *buffer = xmalloc (buffer_size);
|
||||
size_t buffer_size = 0;
|
||||
char *buffer = NULL;
|
||||
const char *q;
|
||||
|
||||
collect_and_sort_names ();
|
||||
@@ -1371,12 +1371,8 @@ create_archive (void)
|
||||
{
|
||||
struct tar_stat_info st;
|
||||
size_t plen = strlen (p->name);
|
||||
if (buffer_size <= plen)
|
||||
{
|
||||
while ((buffer_size *= 2) <= plen)
|
||||
continue;
|
||||
buffer = xrealloc (buffer, buffer_size);
|
||||
}
|
||||
while (buffer_size <= plen)
|
||||
buffer = x2realloc (buffer, &buffer_size);
|
||||
memcpy (buffer, p->name, plen);
|
||||
if (! ISSLASH (buffer[plen - 1]))
|
||||
buffer[plen++] = DIRECTORY_SEPARATOR;
|
||||
@@ -1407,12 +1403,8 @@ create_archive (void)
|
||||
}
|
||||
st.orig_file_name = xstrdup (p->name);
|
||||
}
|
||||
if (buffer_size < plen + qlen)
|
||||
{
|
||||
while ((buffer_size *=2 ) < plen + qlen)
|
||||
continue;
|
||||
buffer = xrealloc (buffer, buffer_size);
|
||||
}
|
||||
while (buffer_size < plen + qlen)
|
||||
buffer = x2realloc (buffer, &buffer_size);
|
||||
strcpy (buffer + plen, q + 1);
|
||||
dump_file (&st, q + 1, buffer);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Delete entries from a tar archive.
|
||||
|
||||
Copyright 1988-2019 Free Software Foundation, Inc.
|
||||
Copyright 1988-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Per-directory exclusion files for tar.
|
||||
|
||||
Copyright 2014-2019 Free Software Foundation, Inc.
|
||||
Copyright 2014-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -104,7 +104,8 @@ info_attach_exclist (struct tar_stat_info *dir)
|
||||
vcsfile->data = vcsfile->initfn (vcsfile->data);
|
||||
|
||||
if (add_exclude_fp (vcsfile->addfn, ex, fp,
|
||||
EXCLUDE_WILDCARDS|EXCLUDE_ANCHORED, '\n',
|
||||
FNM_FILE_NAME|EXCLUDE_WILDCARDS|EXCLUDE_ANCHORED,
|
||||
'\n',
|
||||
vcsfile->data))
|
||||
{
|
||||
int e = errno;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Exit from GNU tar.
|
||||
|
||||
Copyright 2009-2019 Free Software Foundation, Inc.
|
||||
Copyright 2009-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
386
src/extract.c
386
src/extract.c
@@ -1,6 +1,6 @@
|
||||
/* Extract files from a tar archive.
|
||||
|
||||
Copyright 1988-2019 Free Software Foundation, Inc.
|
||||
Copyright 1988-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -194,7 +194,7 @@ extr_init (void)
|
||||
|
||||
/* Use fchmod if possible, fchmodat otherwise. */
|
||||
static int
|
||||
fd_chmod (int fd, char const *file, mode_t mode, int atflag)
|
||||
fd_i_chmod (int fd, char const *file, mode_t mode, int atflag)
|
||||
{
|
||||
if (0 <= fd)
|
||||
{
|
||||
@@ -205,6 +205,42 @@ fd_chmod (int fd, char const *file, mode_t mode, int atflag)
|
||||
return fchmodat (chdir_fd, file, mode, atflag);
|
||||
}
|
||||
|
||||
/* A version of fd_i_chmod which gracefully handles several common error
|
||||
conditions. Additional argument TYPEFLAG is the type of file in tar
|
||||
notation.
|
||||
*/
|
||||
static int
|
||||
fd_chmod(int fd, char const *file_name, int mode, int atflag, int typeflag)
|
||||
{
|
||||
int chmod_errno = fd_i_chmod (fd, file_name, mode, atflag) == 0 ? 0 : errno;
|
||||
|
||||
/* On Solaris, chmod may fail if we don't have PRIV_ALL, because
|
||||
setuid-root files would otherwise be a backdoor. See
|
||||
http://opensolaris.org/jive/thread.jspa?threadID=95826
|
||||
(2009-09-03). */
|
||||
if (chmod_errno == EPERM && (mode & S_ISUID)
|
||||
&& priv_set_restore_linkdir () == 0)
|
||||
{
|
||||
chmod_errno = fd_i_chmod (fd, file_name, mode, atflag) == 0 ? 0 : errno;
|
||||
priv_set_remove_linkdir ();
|
||||
}
|
||||
|
||||
/* Linux fchmodat does not support AT_SYMLINK_NOFOLLOW, and
|
||||
returns ENOTSUP even when operating on non-symlinks, try
|
||||
again with the flag disabled if it does not appear to be
|
||||
supported and if the file is not a symlink. This
|
||||
introduces a race, alas. */
|
||||
if (atflag && typeflag != SYMTYPE && ! implemented (chmod_errno))
|
||||
chmod_errno = fd_i_chmod (fd, file_name, mode, 0) == 0 ? 0 : errno;
|
||||
|
||||
if (chmod_errno && (typeflag != SYMTYPE || implemented (chmod_errno)))
|
||||
{
|
||||
errno = chmod_errno;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use fchown if possible, fchownat otherwise. */
|
||||
static int
|
||||
fd_chown (int fd, char const *file, uid_t uid, gid_t gid, int atflag)
|
||||
@@ -259,35 +295,8 @@ set_mode (char const *file_name,
|
||||
|
||||
if (current_mode != mode)
|
||||
{
|
||||
int chmod_errno =
|
||||
fd_chmod (fd, file_name, mode, atflag) == 0 ? 0 : errno;
|
||||
|
||||
/* On Solaris, chmod may fail if we don't have PRIV_ALL, because
|
||||
setuid-root files would otherwise be a backdoor. See
|
||||
http://opensolaris.org/jive/thread.jspa?threadID=95826
|
||||
(2009-09-03). */
|
||||
if (chmod_errno == EPERM && (mode & S_ISUID)
|
||||
&& priv_set_restore_linkdir () == 0)
|
||||
{
|
||||
chmod_errno =
|
||||
fd_chmod (fd, file_name, mode, atflag) == 0 ? 0 : errno;
|
||||
priv_set_remove_linkdir ();
|
||||
}
|
||||
|
||||
/* Linux fchmodat does not support AT_SYMLINK_NOFOLLOW, and
|
||||
returns ENOTSUP even when operating on non-symlinks, try
|
||||
again with the flag disabled if it does not appear to be
|
||||
supported and if the file is not a symlink. This
|
||||
introduces a race, alas. */
|
||||
if (atflag && typeflag != SYMTYPE && ! implemented (chmod_errno))
|
||||
chmod_errno = fd_chmod (fd, file_name, mode, 0) == 0 ? 0 : errno;
|
||||
|
||||
if (chmod_errno
|
||||
&& (typeflag != SYMTYPE || implemented (chmod_errno)))
|
||||
{
|
||||
errno = chmod_errno;
|
||||
chmod_error_details (file_name, mode);
|
||||
}
|
||||
if (fd_chmod (fd, file_name, mode, atflag, typeflag))
|
||||
chmod_error_details (file_name, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -400,7 +409,7 @@ find_direct_ancestor (char const *file_name)
|
||||
struct delayed_set_stat *h = delayed_set_stat_head;
|
||||
while (h)
|
||||
{
|
||||
if (h && ! h->after_links
|
||||
if (! h->after_links
|
||||
&& strncmp (file_name, h->file_name, h->file_name_len) == 0
|
||||
&& ISSLASH (file_name[h->file_name_len])
|
||||
&& (last_component (file_name) == file_name + h->file_name_len + 1))
|
||||
@@ -458,25 +467,56 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
|
||||
mode_t mode, int atflag)
|
||||
{
|
||||
size_t file_name_len = strlen (file_name);
|
||||
struct delayed_set_stat *data = xmalloc (sizeof (*data));
|
||||
data->next = delayed_set_stat_head;
|
||||
struct delayed_set_stat *data;
|
||||
|
||||
for (data = delayed_set_stat_head; data; data = data->next)
|
||||
if (strcmp (data->file_name, file_name) == 0)
|
||||
break;
|
||||
|
||||
if (data)
|
||||
{
|
||||
if (data->interdir)
|
||||
{
|
||||
struct stat real_st;
|
||||
if (fstatat (chdir_fd, data->file_name,
|
||||
&real_st, data->atflag) != 0)
|
||||
{
|
||||
stat_error (data->file_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
data->dev = real_st.st_dev;
|
||||
data->ino = real_st.st_ino;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data = xmalloc (sizeof (*data));
|
||||
data->next = delayed_set_stat_head;
|
||||
delayed_set_stat_head = data;
|
||||
data->file_name_len = file_name_len;
|
||||
data->file_name = xstrdup (file_name);
|
||||
data->after_links = false;
|
||||
if (st)
|
||||
{
|
||||
data->dev = st->stat.st_dev;
|
||||
data->ino = st->stat.st_ino;
|
||||
}
|
||||
}
|
||||
|
||||
data->mode = mode;
|
||||
if (st)
|
||||
{
|
||||
data->dev = st->stat.st_dev;
|
||||
data->ino = st->stat.st_ino;
|
||||
data->uid = st->stat.st_uid;
|
||||
data->gid = st->stat.st_gid;
|
||||
data->atime = st->atime;
|
||||
data->mtime = st->mtime;
|
||||
}
|
||||
data->file_name_len = file_name_len;
|
||||
data->file_name = xstrdup (file_name);
|
||||
data->current_mode = current_mode;
|
||||
data->current_mode_mask = current_mode_mask;
|
||||
data->interdir = ! st;
|
||||
data->atflag = atflag;
|
||||
data->after_links = 0;
|
||||
data->change_dir = chdir_current;
|
||||
data->cntx_name = NULL;
|
||||
if (st)
|
||||
@@ -508,8 +548,6 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
|
||||
data->xattr_map = NULL;
|
||||
data->xattr_map_size = 0;
|
||||
}
|
||||
strcpy (data->file_name, file_name);
|
||||
delayed_set_stat_head = data;
|
||||
if (must_be_dot_or_slash (file_name))
|
||||
mark_after_links (data);
|
||||
}
|
||||
@@ -523,7 +561,7 @@ repair_delayed_set_stat (char const *dir,
|
||||
struct stat const *dir_stat_info)
|
||||
{
|
||||
struct delayed_set_stat *data;
|
||||
for (data = delayed_set_stat_head; data; data = data->next)
|
||||
for (data = delayed_set_stat_head; data; data = data->next)
|
||||
{
|
||||
struct stat st;
|
||||
if (fstatat (chdir_fd, data->file_name, &st, data->atflag) != 0)
|
||||
@@ -946,6 +984,26 @@ is_directory_link (const char *file_name)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Given struct stat of a directory (or directory member) whose ownership
|
||||
or permissions of will be restored later, return the temporary permissions
|
||||
for that directory, sufficiently restrictive so that in the meantime
|
||||
processes owned by other users do not inadvertently create files under this
|
||||
directory that inherit the wrong owner, group, or permissions from the
|
||||
directory.
|
||||
|
||||
If not root, though, make the directory writeable and searchable at first,
|
||||
so that files can be created under it.
|
||||
*/
|
||||
static inline int
|
||||
safe_dir_mode (struct stat const *st)
|
||||
{
|
||||
return ((st->st_mode
|
||||
& (0 < same_owner_option || 0 < same_permissions_option
|
||||
? S_IRWXU
|
||||
: MODE_RWX))
|
||||
| (we_are_root ? 0 : MODE_WXUSR));
|
||||
}
|
||||
|
||||
/* Extractor functions for various member types */
|
||||
|
||||
static int
|
||||
@@ -975,18 +1033,7 @@ extract_dir (char *file_name, int typeflag)
|
||||
else if (typeflag == GNUTYPE_DUMPDIR)
|
||||
skip_member ();
|
||||
|
||||
/* If ownership or permissions will be restored later, create the
|
||||
directory with restrictive permissions at first, so that in the
|
||||
meantime processes owned by other users do not inadvertently
|
||||
create files under this directory that inherit the wrong owner,
|
||||
group, or permissions from the directory. If not root, though,
|
||||
make the directory writeable and searchable at first, so that
|
||||
files can be created under it. */
|
||||
mode = ((current_stat_info.stat.st_mode
|
||||
& (0 < same_owner_option || 0 < same_permissions_option
|
||||
? S_IRWXU
|
||||
: MODE_RWX))
|
||||
| (we_are_root ? 0 : MODE_WXUSR));
|
||||
mode = safe_dir_mode (¤t_stat_info.stat);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@@ -1002,6 +1049,7 @@ extract_dir (char *file_name, int typeflag)
|
||||
if (errno == EEXIST
|
||||
&& (interdir_made
|
||||
|| keep_directory_symlink_option
|
||||
|| old_files_option == NO_OVERWRITE_DIR_OLD_FILES
|
||||
|| old_files_option == DEFAULT_OLD_FILES
|
||||
|| old_files_option == OVERWRITE_OLD_FILES))
|
||||
{
|
||||
@@ -1022,6 +1070,31 @@ extract_dir (char *file_name, int typeflag)
|
||||
repair_delayed_set_stat (file_name, &st);
|
||||
return 0;
|
||||
}
|
||||
else if (old_files_option == NO_OVERWRITE_DIR_OLD_FILES)
|
||||
{
|
||||
/* Temporarily change the directory mode to a safe
|
||||
value, to be able to create files in it, should
|
||||
the need be.
|
||||
*/
|
||||
mode = safe_dir_mode (&st);
|
||||
status = fd_chmod(-1, file_name, mode,
|
||||
AT_SYMLINK_NOFOLLOW, DIRTYPE);
|
||||
if (status == 0)
|
||||
{
|
||||
/* Store the actual directory mode, to be restored
|
||||
later.
|
||||
*/
|
||||
current_stat_info.stat = st;
|
||||
current_mode = mode & ~ current_umask;
|
||||
current_mode_mask = MODE_RWX;
|
||||
atflag = AT_SYMLINK_NOFOLLOW;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
chmod_error_details (file_name, mode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1254,10 +1327,15 @@ extract_file (char *file_name, int typeflag)
|
||||
replaced after other extraction is done by a symbolic link if
|
||||
IS_SYMLINK is true, and by a hard link otherwise. Set
|
||||
*INTERDIR_MADE if an intermediate directory is made in the
|
||||
process. */
|
||||
process.
|
||||
Install the created struct delayed_link after PREV, unless the
|
||||
latter is NULL, in which case insert it at the head of the delayed
|
||||
link list.
|
||||
*/
|
||||
|
||||
static int
|
||||
create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
|
||||
create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made,
|
||||
struct delayed_link *prev)
|
||||
{
|
||||
int fd;
|
||||
struct stat st;
|
||||
@@ -1292,8 +1370,16 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
|
||||
xmalloc (offsetof (struct delayed_link, target)
|
||||
+ strlen (current_stat_info.link_name)
|
||||
+ 1);
|
||||
p->next = delayed_link_head;
|
||||
delayed_link_head = p;
|
||||
if (prev)
|
||||
{
|
||||
p->next = prev->next;
|
||||
prev->next = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->next = delayed_link_head;
|
||||
delayed_link_head = p;
|
||||
}
|
||||
p->dev = st.st_dev;
|
||||
p->ino = st.st_ino;
|
||||
p->birthtime = get_stat_birthtime (&st);
|
||||
@@ -1308,7 +1394,7 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
|
||||
}
|
||||
p->change_dir = chdir_current;
|
||||
p->sources = xmalloc (offsetof (struct string_list, string)
|
||||
+ strlen (file_name) + 1);
|
||||
+ strlen (file_name) + 1);
|
||||
p->sources->next = 0;
|
||||
strcpy (p->sources->string, file_name);
|
||||
p->cntx_name = NULL;
|
||||
@@ -1317,7 +1403,8 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
|
||||
p->acls_a_len = 0;
|
||||
p->acls_d_ptr = NULL;
|
||||
p->acls_d_len = 0;
|
||||
xheader_xattr_copy (¤t_stat_info, &p->xattr_map, &p->xattr_map_size);
|
||||
xheader_xattr_copy (¤t_stat_info, &p->xattr_map,
|
||||
&p->xattr_map_size);
|
||||
strcpy (p->target, current_stat_info.link_name);
|
||||
|
||||
if ((h = find_direct_ancestor (file_name)) != NULL)
|
||||
@@ -1329,18 +1416,57 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find a delayed_link structure corresponding to the source NAME.
|
||||
Such a structure exists in the delayed link list only if the link
|
||||
placeholder file has been created. Therefore, try to stat the NAME
|
||||
first. If it doesn't exist, there is no matching entry in the list.
|
||||
Otherwise, look for the entry in list which has the matching dev
|
||||
and ino numbers.
|
||||
|
||||
This approach avoids scanning the singly-linked list in obvious cases
|
||||
and does not rely on comparing file names, which may differ for
|
||||
various reasons (e.g. relative vs. absolute file names).
|
||||
*/
|
||||
static struct delayed_link *
|
||||
find_delayed_link_source (char const *name)
|
||||
{
|
||||
struct delayed_link *dl;
|
||||
struct stat st;
|
||||
|
||||
if (!delayed_link_head)
|
||||
return NULL;
|
||||
|
||||
if (fstatat (chdir_fd, name, &st, AT_SYMLINK_NOFOLLOW))
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
stat_error (name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (dl = delayed_link_head; dl; dl = dl->next)
|
||||
{
|
||||
if (dl->dev == st.st_dev && dl->ino == st.st_ino)
|
||||
break;
|
||||
}
|
||||
return dl;
|
||||
}
|
||||
|
||||
static int
|
||||
extract_link (char *file_name, int typeflag)
|
||||
{
|
||||
bool interdir_made = false;
|
||||
char const *link_name;
|
||||
int rc;
|
||||
|
||||
struct delayed_link *dl;
|
||||
|
||||
link_name = current_stat_info.link_name;
|
||||
|
||||
if (! absolute_names_option && contains_dot_dot (link_name))
|
||||
return create_placeholder_file (file_name, false, &interdir_made);
|
||||
|
||||
return create_placeholder_file (file_name, false, &interdir_made, NULL);
|
||||
dl = find_delayed_link_source (link_name);
|
||||
if (dl)
|
||||
return create_placeholder_file (file_name, false, &interdir_made, dl);
|
||||
|
||||
do
|
||||
{
|
||||
struct stat st1, st2;
|
||||
@@ -1402,7 +1528,7 @@ extract_symlink (char *file_name, int typeflag)
|
||||
if (! absolute_names_option
|
||||
&& (IS_ABSOLUTE_FILE_NAME (current_stat_info.link_name)
|
||||
|| contains_dot_dot (current_stat_info.link_name)))
|
||||
return create_placeholder_file (file_name, true, &interdir_made);
|
||||
return create_placeholder_file (file_name, true, &interdir_made, NULL);
|
||||
|
||||
while (symlinkat (current_stat_info.link_name, chdir_fd, file_name) != 0)
|
||||
switch (maybe_recoverable (file_name, false, &interdir_made))
|
||||
@@ -1495,47 +1621,23 @@ extract_fifo (char *file_name, int typeflag)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
extract_volhdr (char *file_name, int typeflag)
|
||||
{
|
||||
skip_member ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
extract_failure (char *file_name, int typeflag)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
extract_skip (char *file_name, int typeflag)
|
||||
{
|
||||
skip_member ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef int (*tar_extractor_t) (char *file_name, int typeflag);
|
||||
|
||||
|
||||
|
||||
/* Prepare to extract a file. Find extractor function.
|
||||
Return zero if extraction should not proceed. */
|
||||
Return true to proceed with the extraction, false to skip the current
|
||||
member. */
|
||||
|
||||
static int
|
||||
static bool
|
||||
prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
|
||||
{
|
||||
int rc = 1;
|
||||
|
||||
if (EXTRACT_OVER_PIPE)
|
||||
rc = 0;
|
||||
tar_extractor_t extractor = NULL;
|
||||
|
||||
/* Select the extractor */
|
||||
switch (typeflag)
|
||||
{
|
||||
case GNUTYPE_SPARSE:
|
||||
*fun = extract_file;
|
||||
rc = 1;
|
||||
extractor = extract_file;
|
||||
break;
|
||||
|
||||
case AREGTYPE:
|
||||
@@ -1544,106 +1646,101 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
|
||||
/* Appears to be a file. But BSD tar uses the convention that a slash
|
||||
suffix means a directory. */
|
||||
if (current_stat_info.had_trailing_slash)
|
||||
*fun = extract_dir;
|
||||
extractor = extract_dir;
|
||||
else
|
||||
{
|
||||
*fun = extract_file;
|
||||
rc = 1;
|
||||
}
|
||||
extractor = extract_file;
|
||||
break;
|
||||
|
||||
case SYMTYPE:
|
||||
*fun = extract_symlink;
|
||||
extractor = extract_symlink;
|
||||
break;
|
||||
|
||||
case LNKTYPE:
|
||||
*fun = extract_link;
|
||||
extractor = extract_link;
|
||||
break;
|
||||
|
||||
#if S_IFCHR
|
||||
case CHRTYPE:
|
||||
current_stat_info.stat.st_mode |= S_IFCHR;
|
||||
*fun = extract_node;
|
||||
extractor = extract_node;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if S_IFBLK
|
||||
case BLKTYPE:
|
||||
current_stat_info.stat.st_mode |= S_IFBLK;
|
||||
*fun = extract_node;
|
||||
extractor = extract_node;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAVE_MKFIFO || defined mkfifo
|
||||
case FIFOTYPE:
|
||||
*fun = extract_fifo;
|
||||
extractor = extract_fifo;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case DIRTYPE:
|
||||
case GNUTYPE_DUMPDIR:
|
||||
*fun = extract_dir;
|
||||
extractor = extract_dir;
|
||||
if (current_stat_info.is_dumpdir)
|
||||
delay_directory_restore_option = true;
|
||||
break;
|
||||
|
||||
case GNUTYPE_VOLHDR:
|
||||
*fun = extract_volhdr;
|
||||
break;
|
||||
|
||||
return false;
|
||||
|
||||
case GNUTYPE_MULTIVOL:
|
||||
ERROR ((0, 0,
|
||||
_("%s: Cannot extract -- file is continued from another volume"),
|
||||
quotearg_colon (current_stat_info.file_name)));
|
||||
*fun = extract_skip;
|
||||
break;
|
||||
return false;
|
||||
|
||||
case GNUTYPE_LONGNAME:
|
||||
case GNUTYPE_LONGLINK:
|
||||
ERROR ((0, 0, _("Unexpected long name header")));
|
||||
*fun = extract_failure;
|
||||
break;
|
||||
return false;
|
||||
|
||||
default:
|
||||
WARNOPT (WARN_UNKNOWN_CAST,
|
||||
(0, 0,
|
||||
_("%s: Unknown file type '%c', extracted as normal file"),
|
||||
quotearg_colon (file_name), typeflag));
|
||||
*fun = extract_file;
|
||||
extractor = extract_file;
|
||||
}
|
||||
|
||||
/* Determine whether the extraction should proceed */
|
||||
if (rc == 0)
|
||||
return 0;
|
||||
|
||||
switch (old_files_option)
|
||||
if (!EXTRACT_OVER_PIPE)
|
||||
{
|
||||
case UNLINK_FIRST_OLD_FILES:
|
||||
if (!remove_any_file (file_name,
|
||||
recursive_unlink_option ? RECURSIVE_REMOVE_OPTION
|
||||
: ORDINARY_REMOVE_OPTION)
|
||||
&& errno && errno != ENOENT)
|
||||
switch (old_files_option)
|
||||
{
|
||||
unlink_error (file_name);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case UNLINK_FIRST_OLD_FILES:
|
||||
if (!remove_any_file (file_name,
|
||||
recursive_unlink_option
|
||||
? RECURSIVE_REMOVE_OPTION
|
||||
: ORDINARY_REMOVE_OPTION)
|
||||
&& errno && errno != ENOENT)
|
||||
{
|
||||
unlink_error (file_name);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEEP_NEWER_FILES:
|
||||
if (file_newer_p (file_name, 0, ¤t_stat_info))
|
||||
{
|
||||
WARNOPT (WARN_IGNORE_NEWER,
|
||||
(0, 0, _("Current %s is newer or same age"),
|
||||
quote (file_name)));
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case KEEP_NEWER_FILES:
|
||||
if (file_newer_p (file_name, 0, ¤t_stat_info))
|
||||
{
|
||||
WARNOPT (WARN_IGNORE_NEWER,
|
||||
(0, 0, _("Current %s is newer or same age"),
|
||||
quote (file_name)));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
*fun = extractor;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Extract a file from the archive. */
|
||||
@@ -1706,13 +1803,14 @@ extract_archive (void)
|
||||
|
||||
if (prepare_to_extract (current_stat_info.file_name, typeflag, &fun))
|
||||
{
|
||||
if (fun && (*fun) (current_stat_info.file_name, typeflag)
|
||||
&& backup_option)
|
||||
undo_last_backup ();
|
||||
if (fun (current_stat_info.file_name, typeflag) == 0)
|
||||
return;
|
||||
}
|
||||
else
|
||||
skip_member ();
|
||||
|
||||
if (backup_option)
|
||||
undo_last_backup ();
|
||||
}
|
||||
|
||||
/* Extract the links whose final extraction were delayed. */
|
||||
@@ -1785,8 +1883,8 @@ apply_delayed_links (void)
|
||||
sources = next;
|
||||
}
|
||||
|
||||
xheader_xattr_free (ds->xattr_map, ds->xattr_map_size);
|
||||
free (ds->cntx_name);
|
||||
xheader_xattr_free (ds->xattr_map, ds->xattr_map_size);
|
||||
free (ds->cntx_name);
|
||||
|
||||
{
|
||||
struct delayed_link *next = ds->next;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* GNU dump extensions to tar.
|
||||
|
||||
Copyright 1988-2019 Free Software Foundation, Inc.
|
||||
Copyright 1988-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -38,7 +38,15 @@ enum children
|
||||
#define DIRF_FOUND 0x0004 /* directory is found on fs */
|
||||
#define DIRF_NEW 0x0008 /* directory is new (not found
|
||||
in the previous dump) */
|
||||
#define DIRF_RENAMED 0x0010 /* directory is renamed */
|
||||
#define DIRF_RENAMED 0x0010 /* Last target in a chain of renames */
|
||||
/* A directory which is renamed from another one is recognized by its
|
||||
orig member, which is not-NULL. This directory may eventually be
|
||||
the source for another rename, in which case it will be pointed to by
|
||||
the orig member of another directory structure. The last directory
|
||||
in such a chain of renames (the one which is not pointed to by any
|
||||
other orig) is marked with the DIRF_RENAMED flag. This marks a starting
|
||||
point from which append_incremental_renames starts encoding renames for
|
||||
this chain. */
|
||||
|
||||
#define DIR_IS_INITED(d) ((d)->flags & DIRF_INIT)
|
||||
#define DIR_IS_NFS(d) ((d)->flags & DIRF_NFS)
|
||||
@@ -495,6 +503,7 @@ procdir (const char *name_buffer, struct tar_stat_info *st,
|
||||
quote_n (1, d->name)));
|
||||
directory->orig = d;
|
||||
DIR_SET_FLAG (directory, DIRF_RENAMED);
|
||||
DIR_CLEAR_FLAG (d, DIRF_RENAMED);
|
||||
dirlist_replace_prefix (d->name, name_buffer);
|
||||
}
|
||||
directory->children = CHANGED_CHILDREN;
|
||||
@@ -537,6 +546,7 @@ procdir (const char *name_buffer, struct tar_stat_info *st,
|
||||
quote_n (1, d->name)));
|
||||
directory->orig = d;
|
||||
DIR_SET_FLAG (directory, DIRF_RENAMED);
|
||||
DIR_CLEAR_FLAG (d, DIRF_RENAMED);
|
||||
dirlist_replace_prefix (d->name, name_buffer);
|
||||
}
|
||||
directory->children = CHANGED_CHILDREN;
|
||||
@@ -649,7 +659,7 @@ makedumpdir (struct directory *directory, const char *dir)
|
||||
|
||||
if (directory->children == ALL_CHILDREN)
|
||||
dump = NULL;
|
||||
else if (DIR_IS_RENAMED (directory))
|
||||
else if (directory->orig)
|
||||
dump = directory->orig->idump ?
|
||||
directory->orig->idump : directory->orig->dump;
|
||||
else
|
||||
@@ -878,44 +888,36 @@ obstack_code_rename (struct obstack *stk, char const *from, char const *to)
|
||||
static void
|
||||
store_rename (struct directory *dir, struct obstack *stk)
|
||||
{
|
||||
if (DIR_IS_RENAMED (dir))
|
||||
struct directory *prev, *p;
|
||||
|
||||
/* Detect eventual cycles. If the chain forms a cycle, prev points to
|
||||
the entry DIR is renamed from.*/
|
||||
for (prev = dir; prev && prev->orig != dir; prev = prev->orig)
|
||||
;
|
||||
|
||||
if (prev == NULL)
|
||||
{
|
||||
struct directory *prev, *p;
|
||||
|
||||
/* Detect eventual cycles and clear DIRF_RENAMED flag, so these entries
|
||||
are ignored when hit by this function next time.
|
||||
If the chain forms a cycle, prev points to the entry DIR is renamed
|
||||
from. In this case it still retains DIRF_RENAMED flag, which will be
|
||||
cleared in the 'else' branch below */
|
||||
for (prev = dir; prev && prev->orig != dir; prev = prev->orig)
|
||||
DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
|
||||
|
||||
if (prev == NULL)
|
||||
{
|
||||
for (p = dir; p && p->orig; p = p->orig)
|
||||
obstack_code_rename (stk, p->orig->name, p->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *temp_name;
|
||||
|
||||
DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
|
||||
|
||||
/* Break the cycle by using a temporary name for one of its
|
||||
elements.
|
||||
First, create a temp name stub entry. */
|
||||
temp_name = dir_name (dir->name);
|
||||
obstack_1grow (stk, 'X');
|
||||
obstack_grow (stk, temp_name, strlen (temp_name) + 1);
|
||||
|
||||
obstack_code_rename (stk, dir->name, "");
|
||||
|
||||
for (p = dir; p != prev; p = p->orig)
|
||||
obstack_code_rename (stk, p->orig->name, p->name);
|
||||
|
||||
obstack_code_rename (stk, "", prev->name);
|
||||
free (temp_name);
|
||||
}
|
||||
for (p = dir; p && p->orig; p = p->orig)
|
||||
obstack_code_rename (stk, p->orig->name, p->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *temp_name;
|
||||
|
||||
/* Break the cycle by using a temporary name for one of its
|
||||
elements.
|
||||
First, create a temp name stub entry. */
|
||||
temp_name = dir_name (dir->name);
|
||||
obstack_1grow (stk, 'X');
|
||||
obstack_grow (stk, temp_name, strlen (temp_name) + 1);
|
||||
|
||||
obstack_code_rename (stk, dir->name, "");
|
||||
|
||||
for (p = dir; p != prev; p = p->orig)
|
||||
obstack_code_rename (stk, p->orig->name, p->name);
|
||||
|
||||
obstack_code_rename (stk, "", prev->name);
|
||||
free (temp_name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -941,7 +943,8 @@ append_incremental_renames (struct directory *dir)
|
||||
size = 0;
|
||||
|
||||
for (dp = dirhead; dp; dp = dp->next)
|
||||
store_rename (dp, &stk);
|
||||
if (DIR_IS_RENAMED (dp))
|
||||
store_rename (dp, &stk);
|
||||
|
||||
/* FIXME: Is this the right thing to do when DIR is null? */
|
||||
if (dir && obstack_object_size (&stk) != size)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* List a tar archive, with support routines for reading a tar archive.
|
||||
|
||||
Copyright 1988-2019 Free Software Foundation, Inc.
|
||||
Copyright 1988-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Owner/group mapping for tar
|
||||
|
||||
Copyright 2015-2019 Free Software Foundation, Inc.
|
||||
Copyright 2015-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
12
src/misc.c
12
src/misc.c
@@ -1,6 +1,6 @@
|
||||
/* Miscellaneous functions, not really specific to GNU tar.
|
||||
|
||||
Copyright 1988-2019 Free Software Foundation, Inc.
|
||||
Copyright 1988-2021 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
|
||||
@@ -314,8 +314,6 @@ normalize_filename (int cdidx, const char *name)
|
||||
size_t copylen;
|
||||
bool need_separator;
|
||||
|
||||
if (!cdpath)
|
||||
call_arg_fatal ("getcwd", ".");
|
||||
copylen = strlen (cdpath);
|
||||
need_separator = ! (DOUBLE_SLASH_IS_DISTINCT_ROOT
|
||||
&& copylen == 2 && ISSLASH (cdpath[1]));
|
||||
@@ -922,6 +920,8 @@ chdir_arg (char const *dir)
|
||||
{
|
||||
wd[wd_count].name = ".";
|
||||
wd[wd_count].abspath = xgetcwd ();
|
||||
if (!wd[wd_count].abspath)
|
||||
call_arg_fatal ("getcwd", ".");
|
||||
wd[wd_count].fd = AT_FDCWD;
|
||||
wd_count++;
|
||||
}
|
||||
@@ -1047,7 +1047,11 @@ tar_getcdpath (int idx)
|
||||
{
|
||||
static char *cwd;
|
||||
if (!cwd)
|
||||
cwd = xgetcwd ();
|
||||
{
|
||||
cwd = xgetcwd ();
|
||||
if (!cwd)
|
||||
call_arg_fatal ("getcwd", ".");
|
||||
}
|
||||
return cwd;
|
||||
}
|
||||
return wd[idx].abspath;
|
||||
|
||||
172
src/names.c
172
src/names.c
@@ -1,6 +1,6 @@
|
||||
/* Various processing of names.
|
||||
|
||||
Copyright 1988-2019 Free Software Foundation, Inc.
|
||||
Copyright 1988-2021 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
|
||||
@@ -62,89 +62,93 @@ enum
|
||||
WILDCARDS_OPTION
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GRH_LOCAL,
|
||||
GRID_LOCAL,
|
||||
GRH_MATCH,
|
||||
GRID_MATCH,
|
||||
};
|
||||
|
||||
static struct argp_option names_options[] = {
|
||||
#define GRID 100
|
||||
{NULL, 0, NULL, 0,
|
||||
N_("Local file name selection:"), GRID },
|
||||
N_("Local file name selection:"), GRH_LOCAL },
|
||||
|
||||
{"add-file", ADD_FILE_OPTION, N_("FILE"), 0,
|
||||
N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID+1 },
|
||||
N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID_LOCAL },
|
||||
{"directory", 'C', N_("DIR"), 0,
|
||||
N_("change to directory DIR"), GRID+1 },
|
||||
N_("change to directory DIR"), GRID_LOCAL },
|
||||
{"files-from", 'T', N_("FILE"), 0,
|
||||
N_("get names to extract or create from FILE"), GRID+1 },
|
||||
N_("get names to extract or create from FILE"), GRID_LOCAL },
|
||||
{"null", NULL_OPTION, 0, 0,
|
||||
N_("-T reads null-terminated names; implies --verbatim-files-from"),
|
||||
GRID+1 },
|
||||
GRID_LOCAL },
|
||||
{"no-null", NO_NULL_OPTION, 0, 0,
|
||||
N_("disable the effect of the previous --null option"), GRID+1 },
|
||||
N_("disable the effect of the previous --null option"), GRID_LOCAL },
|
||||
{"unquote", UNQUOTE_OPTION, 0, 0,
|
||||
N_("unquote input file or member names (default)"), GRID+1 },
|
||||
N_("unquote input file or member names (default)"), GRID_LOCAL },
|
||||
{"no-unquote", NO_UNQUOTE_OPTION, 0, 0,
|
||||
N_("do not unquote input file or member names"), GRID+1 },
|
||||
N_("do not unquote input file or member names"), GRID_LOCAL },
|
||||
{"verbatim-files-from", VERBATIM_FILES_FROM_OPTION, 0, 0,
|
||||
N_("-T reads file names verbatim (no escape or option handling)"), GRID+1 },
|
||||
N_("-T reads file names verbatim (no escape or option handling)"), GRID_LOCAL },
|
||||
{"no-verbatim-files-from", NO_VERBATIM_FILES_FROM_OPTION, 0, 0,
|
||||
N_("-T treats file names starting with dash as options (default)"),
|
||||
GRID+1 },
|
||||
GRID_LOCAL },
|
||||
{"exclude", EXCLUDE_OPTION, N_("PATTERN"), 0,
|
||||
N_("exclude files, given as a PATTERN"), GRID+1 },
|
||||
N_("exclude files, given as a PATTERN"), GRID_LOCAL },
|
||||
{"exclude-from", 'X', N_("FILE"), 0,
|
||||
N_("exclude patterns listed in FILE"), GRID+1 },
|
||||
N_("exclude patterns listed in FILE"), GRID_LOCAL },
|
||||
{"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0,
|
||||
N_("exclude contents of directories containing CACHEDIR.TAG, "
|
||||
"except for the tag file itself"), GRID+1 },
|
||||
"except for the tag file itself"), GRID_LOCAL },
|
||||
{"exclude-caches-under", EXCLUDE_CACHES_UNDER_OPTION, 0, 0,
|
||||
N_("exclude everything under directories containing CACHEDIR.TAG"),
|
||||
GRID+1 },
|
||||
GRID_LOCAL },
|
||||
{"exclude-caches-all", EXCLUDE_CACHES_ALL_OPTION, 0, 0,
|
||||
N_("exclude directories containing CACHEDIR.TAG"), GRID+1 },
|
||||
N_("exclude directories containing CACHEDIR.TAG"), GRID_LOCAL },
|
||||
{"exclude-tag", EXCLUDE_TAG_OPTION, N_("FILE"), 0,
|
||||
N_("exclude contents of directories containing FILE, except"
|
||||
" for FILE itself"), GRID+1 },
|
||||
" for FILE itself"), GRID_LOCAL },
|
||||
{"exclude-ignore", EXCLUDE_IGNORE_OPTION, N_("FILE"), 0,
|
||||
N_("read exclude patterns for each directory from FILE, if it exists"),
|
||||
GRID+1 },
|
||||
GRID_LOCAL },
|
||||
{"exclude-ignore-recursive", EXCLUDE_IGNORE_RECURSIVE_OPTION, N_("FILE"), 0,
|
||||
N_("read exclude patterns for each directory and its subdirectories "
|
||||
"from FILE, if it exists"), GRID+1 },
|
||||
"from FILE, if it exists"), GRID_LOCAL },
|
||||
{"exclude-tag-under", EXCLUDE_TAG_UNDER_OPTION, N_("FILE"), 0,
|
||||
N_("exclude everything under directories containing FILE"), GRID+1 },
|
||||
N_("exclude everything under directories containing FILE"), GRID_LOCAL },
|
||||
{"exclude-tag-all", EXCLUDE_TAG_ALL_OPTION, N_("FILE"), 0,
|
||||
N_("exclude directories containing FILE"), GRID+1 },
|
||||
N_("exclude directories containing FILE"), GRID_LOCAL },
|
||||
{"exclude-vcs", EXCLUDE_VCS_OPTION, NULL, 0,
|
||||
N_("exclude version control system directories"), GRID+1 },
|
||||
N_("exclude version control system directories"), GRID_LOCAL },
|
||||
{"exclude-vcs-ignores", EXCLUDE_VCS_IGNORES_OPTION, NULL, 0,
|
||||
N_("read exclude patterns from the VCS ignore files"), GRID+1 },
|
||||
N_("read exclude patterns from the VCS ignore files"), GRID_LOCAL },
|
||||
{"exclude-backups", EXCLUDE_BACKUPS_OPTION, NULL, 0,
|
||||
N_("exclude backup and lock files"), GRID+1 },
|
||||
N_("exclude backup and lock files"), GRID_LOCAL },
|
||||
{"recursion", RECURSION_OPTION, 0, 0,
|
||||
N_("recurse into directories (default)"), GRID+1 },
|
||||
N_("recurse into directories (default)"), GRID_LOCAL },
|
||||
{"no-recursion", NO_RECURSION_OPTION, 0, 0,
|
||||
N_("avoid descending automatically in directories"), GRID+1 },
|
||||
#undef GRID
|
||||
N_("avoid descending automatically in directories"), GRID_LOCAL },
|
||||
|
||||
#define GRID 120
|
||||
{NULL, 0, NULL, 0,
|
||||
N_("File name matching options (affect both exclude and include patterns):"),
|
||||
GRID },
|
||||
GRH_MATCH },
|
||||
{"anchored", ANCHORED_OPTION, 0, 0,
|
||||
N_("patterns match file name start"), GRID+1 },
|
||||
N_("patterns match file name start"), GRID_MATCH },
|
||||
{"no-anchored", NO_ANCHORED_OPTION, 0, 0,
|
||||
N_("patterns match after any '/' (default for exclusion)"), GRID+1 },
|
||||
N_("patterns match after any '/' (default for exclusion)"), GRID_MATCH },
|
||||
{"ignore-case", IGNORE_CASE_OPTION, 0, 0,
|
||||
N_("ignore case"), GRID+1 },
|
||||
N_("ignore case"), GRID_MATCH },
|
||||
{"no-ignore-case", NO_IGNORE_CASE_OPTION, 0, 0,
|
||||
N_("case sensitive matching (default)"), GRID+1 },
|
||||
N_("case sensitive matching (default)"), GRID_MATCH },
|
||||
{"wildcards", WILDCARDS_OPTION, 0, 0,
|
||||
N_("use wildcards (default for exclusion)"), GRID+1 },
|
||||
N_("use wildcards (default for exclusion)"), GRID_MATCH },
|
||||
{"no-wildcards", NO_WILDCARDS_OPTION, 0, 0,
|
||||
N_("verbatim string matching"), GRID+1 },
|
||||
N_("verbatim string matching"), GRID_MATCH },
|
||||
{"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
|
||||
N_("wildcards match '/' (default for exclusion)"), GRID+1 },
|
||||
N_("wildcards match '/' (default for exclusion)"), GRID_MATCH },
|
||||
{"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
|
||||
N_("wildcards do not match '/'"), GRID+1 },
|
||||
#undef GRID
|
||||
N_("wildcards do not match '/'"), GRID_MATCH },
|
||||
|
||||
{NULL}
|
||||
};
|
||||
@@ -195,12 +199,25 @@ names_parse_opt (int key, char *arg, struct argp_state *state)
|
||||
case ADD_FILE_OPTION:
|
||||
name_add_name (arg);
|
||||
break;
|
||||
|
||||
case ARGP_KEY_ERROR:
|
||||
{
|
||||
struct tar_args *args = state->input;
|
||||
if (args->loc->source == OPTS_FILE)
|
||||
{
|
||||
error (0, 0, _("%s:%lu: unrecognized option"), args->loc->name,
|
||||
(unsigned long) args->loc->line);
|
||||
set_exit_status (TAREXIT_FAILURE);
|
||||
}
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
default:
|
||||
if (is_file_selection_option (key))
|
||||
name_add_option (key, arg);
|
||||
else
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -419,7 +436,7 @@ handle_file_selection_option (int key, const char *arg)
|
||||
}
|
||||
}
|
||||
|
||||
static struct argp names_argp = {
|
||||
struct argp names_argp = {
|
||||
names_options,
|
||||
names_parse_opt,
|
||||
NULL,
|
||||
@@ -429,10 +446,6 @@ static struct argp names_argp = {
|
||||
NULL
|
||||
};
|
||||
|
||||
struct argp_child names_argp_children[] = {
|
||||
{ &names_argp, 0, "", 0 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* User and group names. */
|
||||
|
||||
@@ -651,8 +664,10 @@ struct name_elt /* A name_array element. */
|
||||
} v;
|
||||
};
|
||||
|
||||
static struct name_elt *name_head;/* store a list of names */
|
||||
size_t name_count; /* how many of the entries are file names? */
|
||||
static struct name_elt *name_head; /* store a list of names */
|
||||
|
||||
/* how many of the entries are file names? */
|
||||
enum files_count filename_args = FILES_NONE;
|
||||
|
||||
static struct name_elt *
|
||||
name_elt_alloc (void)
|
||||
@@ -784,13 +799,6 @@ name_list_advance (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if there are names or options in the list */
|
||||
bool
|
||||
name_more_files (void)
|
||||
{
|
||||
return name_count > 0;
|
||||
}
|
||||
|
||||
/* Add to name_array the file NAME with fnmatch options MATFLAGS */
|
||||
void
|
||||
name_add_name (const char *name)
|
||||
@@ -799,7 +807,20 @@ name_add_name (const char *name)
|
||||
|
||||
ep->type = NELT_NAME;
|
||||
ep->v.name = name;
|
||||
name_count++;
|
||||
|
||||
switch (filename_args)
|
||||
{
|
||||
case FILES_NONE:
|
||||
filename_args = FILES_ONE;
|
||||
break;
|
||||
|
||||
case FILES_ONE:
|
||||
filename_args = FILES_MANY;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -829,7 +850,10 @@ name_add_file (const char *name)
|
||||
ep->v.file.name = name;
|
||||
ep->v.file.line = 0;
|
||||
ep->v.file.fp = NULL;
|
||||
name_count++;
|
||||
|
||||
/* We don't know beforehand how many files are listed.
|
||||
Assume more than one. */
|
||||
filename_args = FILES_MANY;
|
||||
}
|
||||
|
||||
/* Names from external name file. */
|
||||
@@ -1058,19 +1082,8 @@ copy_name (struct name_elt *ep)
|
||||
|
||||
source = ep->v.name;
|
||||
source_len = strlen (source);
|
||||
if (name_buffer_length < source_len)
|
||||
{
|
||||
do
|
||||
{
|
||||
name_buffer_length *= 2;
|
||||
if (! name_buffer_length)
|
||||
xalloc_die ();
|
||||
}
|
||||
while (name_buffer_length < source_len);
|
||||
|
||||
free (name_buffer);
|
||||
name_buffer = xmalloc(name_buffer_length + 2);
|
||||
}
|
||||
while (name_buffer_length <= source_len)
|
||||
name_buffer = x2realloc(name_buffer, &name_buffer_length);
|
||||
strcpy (name_buffer, source);
|
||||
chopslash (name_buffer);
|
||||
}
|
||||
@@ -1591,9 +1604,8 @@ add_hierarchy_to_namelist (struct tar_stat_info *st, struct name *name)
|
||||
size_t name_length = name->length;
|
||||
size_t allocated_length = (name_length >= NAME_FIELD_SIZE
|
||||
? name_length + NAME_FIELD_SIZE
|
||||
: NAME_FIELD_SIZE);
|
||||
char *namebuf = xmalloc (allocated_length + 1);
|
||||
/* FIXME: + 2 above? */
|
||||
: NAME_FIELD_SIZE) + 2;
|
||||
char *namebuf = xmalloc (allocated_length);
|
||||
const char *string;
|
||||
size_t string_length;
|
||||
int change_dir = name->change_dir;
|
||||
@@ -1614,18 +1626,10 @@ add_hierarchy_to_namelist (struct tar_stat_info *st, struct name *name)
|
||||
struct tar_stat_info subdir;
|
||||
int subfd;
|
||||
|
||||
if (allocated_length <= name_length + string_length)
|
||||
{
|
||||
do
|
||||
{
|
||||
allocated_length *= 2;
|
||||
if (! allocated_length)
|
||||
xalloc_die ();
|
||||
}
|
||||
while (allocated_length <= name_length + string_length);
|
||||
|
||||
namebuf = xrealloc (namebuf, allocated_length + 1);
|
||||
}
|
||||
/* need to have at least string_length bytes above the
|
||||
name_length, this includes the trailing null character */
|
||||
while (allocated_length < name_length + string_length)
|
||||
namebuf = x2realloc (namebuf, &allocated_length);
|
||||
strcpy (namebuf + name_length, string + 1);
|
||||
np = addname (namebuf, change_dir, false, name);
|
||||
if (!child_head)
|
||||
@@ -1826,7 +1830,7 @@ collect_and_sort_names (void)
|
||||
{
|
||||
if (p->child)
|
||||
rebase_child_list (p->child, name);
|
||||
hash_delete (nametab, name);
|
||||
hash_remove (nametab, name);
|
||||
/* FIXME: remove_directory (p->caname); ? */
|
||||
remname (p);
|
||||
free_name (p);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Functions for dealing with sparse files
|
||||
|
||||
Copyright 2003-2019 Free Software Foundation, Inc.
|
||||
Copyright 2003-2021 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
|
||||
@@ -684,7 +684,7 @@ check_data_region (struct tar_sparse_file *file, size_t i)
|
||||
}
|
||||
size_left -= bytes_read;
|
||||
mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
|
||||
if (memcmp (blk->buffer, diff_buffer, rdsize))
|
||||
if (memcmp (blk->buffer, diff_buffer, bytes_read))
|
||||
{
|
||||
report_difference (file->stat_info, _("Contents differ"));
|
||||
return false;
|
||||
@@ -702,7 +702,7 @@ sparse_diff_file (int fd, struct tar_stat_info *st)
|
||||
off_t offset = 0;
|
||||
|
||||
if (!tar_sparse_init (&file))
|
||||
return dump_status_not_implemented;
|
||||
return false;
|
||||
|
||||
file.stat_info = st;
|
||||
file.fd = fd;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* This file is part of GNU tar.
|
||||
Copyright 2007-2019 Free Software Foundation, Inc.
|
||||
Copyright 2007-2021 Free Software Foundation, Inc.
|
||||
|
||||
Written by Sergey Poznyakoff.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* System-dependent calls for tar.
|
||||
|
||||
Copyright 2003-2019 Free Software Foundation, Inc.
|
||||
Copyright 2003-2021 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* GNU tar Archive Format description.
|
||||
|
||||
Copyright 1988-2019 Free Software Foundation, Inc.
|
||||
Copyright 1988-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* This file is part of GNU tar.
|
||||
Copyright 2006-2019 Free Software Foundation, Inc.
|
||||
Copyright 2006-2021 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
|
||||
@@ -208,6 +208,8 @@ parse_transform_expr (const char *expr)
|
||||
}
|
||||
|
||||
delim = expr[1];
|
||||
if (!delim)
|
||||
USAGE_ERROR ((0, 0, _("Invalid transform expression")));
|
||||
|
||||
/* Scan regular expression */
|
||||
for (i = 2; expr[i] && expr[i] != delim; i++)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Unlink files.
|
||||
|
||||
Copyright 2009-2019 Free Software Foundation, Inc.
|
||||
Copyright 2009-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Update a tar archive.
|
||||
|
||||
Copyright 1988-2019 Free Software Foundation, Inc.
|
||||
Copyright 1988-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Charset handling for GNU tar.
|
||||
|
||||
Copyright 2004-2019 Free Software Foundation, Inc.
|
||||
Copyright 2004-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Warnings for GNU tar.
|
||||
|
||||
Copyright 2009-2019 Free Software Foundation, Inc.
|
||||
Copyright 2009-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Support for extended attributes.
|
||||
|
||||
Copyright (C) 2006-2019 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Support for extended attributes.
|
||||
|
||||
Copyright (C) 2006-2019 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* POSIX extended headers for tar.
|
||||
|
||||
Copyright (C) 2003-2019 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -369,29 +369,46 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Table of templates for the names of POSIX extended headers.
|
||||
Indexed by the the type of the header (per-file or global)
|
||||
and POSIX compliance mode (0 or q depending on whether
|
||||
POSIXLY_CORRECT environment variable is set. */
|
||||
static const char *header_template[][2] = {
|
||||
/* Individual header templates: */
|
||||
{ "%d/PaxHeaders/%f", "%d/PaxHeaders.%p/%f" },
|
||||
/* Global header templates: */
|
||||
{ "/GlobalHead.%n", "/GlobalHead.%p.%n" }
|
||||
};
|
||||
/* Indices to the above table */
|
||||
enum {
|
||||
pax_file_header,
|
||||
pax_global_header
|
||||
};
|
||||
/* Return the name for the POSIX extended header T */
|
||||
#define HEADER_TEMPLATE(t) header_template[t][posixly_correct]
|
||||
|
||||
char *
|
||||
xheader_xhdr_name (struct tar_stat_info *st)
|
||||
{
|
||||
if (!exthdr_name)
|
||||
assign_string (&exthdr_name, "%d/PaxHeaders.%p/%f");
|
||||
assign_string (&exthdr_name, HEADER_TEMPLATE (pax_file_header));
|
||||
return xheader_format_name (st, exthdr_name, 0);
|
||||
}
|
||||
|
||||
#define GLOBAL_HEADER_TEMPLATE "/GlobalHead.%p.%n"
|
||||
|
||||
char *
|
||||
xheader_ghdr_name (void)
|
||||
{
|
||||
if (!globexthdr_name)
|
||||
{
|
||||
size_t len;
|
||||
const char *global_header_template = HEADER_TEMPLATE (pax_global_header);
|
||||
const char *tmp = getenv ("TMPDIR");
|
||||
if (!tmp)
|
||||
tmp = "/tmp";
|
||||
len = strlen (tmp) + sizeof (GLOBAL_HEADER_TEMPLATE); /* Includes nul */
|
||||
len = strlen (tmp) + strlen (global_header_template) + 1;
|
||||
globexthdr_name = xmalloc (len);
|
||||
strcpy(globexthdr_name, tmp);
|
||||
strcat(globexthdr_name, GLOBAL_HEADER_TEMPLATE);
|
||||
strcat(globexthdr_name, global_header_template);
|
||||
}
|
||||
|
||||
return xheader_format_name (NULL, globexthdr_name, global_header_count + 1);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Makefile for GNU tar regression tests.
|
||||
|
||||
# Copyright 1996-2019 Free Software Foundation, Inc.
|
||||
# Copyright 1996-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
@@ -120,6 +120,8 @@ TESTSUITE_AT = \
|
||||
extrac19.at\
|
||||
extrac20.at\
|
||||
extrac21.at\
|
||||
extrac22.at\
|
||||
extrac23.at\
|
||||
filerem01.at\
|
||||
filerem02.at\
|
||||
dirrem01.at\
|
||||
@@ -198,6 +200,7 @@ TESTSUITE_AT = \
|
||||
rename03.at\
|
||||
rename04.at\
|
||||
rename05.at\
|
||||
rename06.at\
|
||||
remfiles01.at\
|
||||
remfiles02.at\
|
||||
remfiles03.at\
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2014-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2014-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2014-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2014-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2006-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2006-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2006-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2006-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# This file is part of test suite for GNU tar. -*- Autotest -*-
|
||||
# Copyright 2015-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2015-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2015-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2015-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2011-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2011-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2011-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2011-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2016-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2016-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2004-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2004-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2005-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2005-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2006-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2006-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2010-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2010-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2016-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2016-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# @configure_input@ -*- shell-script -*-
|
||||
# Configurable variable values for tar test suite.
|
||||
# Copyright 2004-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2004-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2009-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2009-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2012-2019 Free Software Foundation, Inc.
|
||||
# Copyright 2012-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# This file is part of GNU tar test suite. -*- Autotest -*-
|
||||
# Copyright 2019 Free Software Foundation, Inc.
|
||||
# Copyright 2019-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# 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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user