You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* Define to non-zero for forcing old ctime format instead of ISO format. */
#undef USE_OLD_CTIME
size_t recent_long_link_blocks; /* likewise, for long link */
static uintmax_t from_header (const char *, size_t, const char *,
- uintmax_t, uintmax_t, bool);
+ uintmax_t, uintmax_t, bool, bool);
/* Base 64 digits; see Internet RFC 2045 Table 1. */
static char const base_64_digits[64] =
set_next_block_after (current_header);
if (multi_volume_option)
{
- assign_string (&save_name, current_stat_info.file_name);
+ assign_string (&save_name, current_stat_info.orig_file_name);
save_totsize = current_stat_info.stat.st_size;
}
for (size = current_stat_info.stat.st_size; size > 0; size -= written)
}
if (multi_volume_option)
- assign_string (&save_name, current_stat_info.file_name);
+ assign_string (&save_name, current_stat_info.orig_file_name);
skip_member ();
int recorded_sum;
uintmax_t parsed_sum;
char *p;
-
+
p = header->buffer;
for (i = sizeof *header; i-- != 0;)
{
parsed_sum = from_header (header->header.chksum,
sizeof header->header.chksum, 0,
(uintmax_t) 0,
- (uintmax_t) TYPE_MAXIMUM (int), silent);
+ (uintmax_t) TYPE_MAXIMUM (int), true, silent);
if (parsed_sum == (uintmax_t) -1)
return HEADER_FAILURE;
recorded_sum = parsed_sum;
-
+
if (unsigned_sum != recorded_sum && signed_sum != recorded_sum)
return HEADER_FAILURE;
enum read_header
read_header (bool raw_extended_headers)
{
- char *p;
union block *header;
union block *header_copy;
char *bp;
while (1)
{
enum read_header status;
-
+
header = find_next_block ();
current_header = header;
if (!header)
if (header->header.typeflag == GNUTYPE_LONGNAME
|| header->header.typeflag == GNUTYPE_LONGLINK
|| header->header.typeflag == XHDTYPE
- || header->header.typeflag == XGLTYPE)
+ || header->header.typeflag == XGLTYPE
+ || header->header.typeflag == SOLARIS_XHDTYPE)
{
if (raw_extended_headers)
return HEADER_SUCCESS_EXTENDED;
size = name_size + BLOCKSIZE;
if (n)
size += BLOCKSIZE - n;
-
+
if (name_size != current_stat_info.stat.st_size
|| size < name_size)
xalloc_die ();
*bp = '\0';
}
- else if (header->header.typeflag == XHDTYPE)
+ else if (header->header.typeflag == XHDTYPE
+ || header->header.typeflag == SOLARIS_XHDTYPE)
xheader_read (header, OFF_FROM_HEADER (header->header.size));
else if (header->header.typeflag == XGLTYPE)
{
np[sizeof h->prefix] = '\0';
np += strlen (np);
*np++ = '/';
-
- /* Prevent later references to current_header from
- mistakenly treating this as an old GNU header.
- This assignment invalidates h->prefix. */
- current_header->oldgnu_header.isextended = 0;
}
memcpy (np, h->name, sizeof h->name);
np[sizeof h->name] = '\0';
}
/* Convert buffer at WHERE0 of size DIGS from external format to
- uintmax_t. The data is of type TYPE. The buffer must represent a
- value in the range -MINUS_MINVAL through MAXVAL. DIGS must be
- positive. SILENT=true inhibits printing diagnostic messages.
- Return -1 on error, diagnosing the error if TYPE is
- nonzero. */
+ uintmax_t. DIGS must be positive. If TYPE is nonnull, the data
+ are of type TYPE. The buffer must represent a value in the range
+ -MINUS_MINVAL through MAXVAL. If OCTAL_ONLY, allow only octal
+ numbers instead of the other GNU extensions. Return -1 on error,
+ diagnosing the error if TYPE is nonnull and if !SILENT. */
static uintmax_t
from_header (char const *where0, size_t digs, char const *type,
- uintmax_t minus_minval, uintmax_t maxval, bool silent)
+ uintmax_t minus_minval, uintmax_t maxval,
+ bool octal_only, bool silent)
{
uintmax_t value;
char const *where = where0;
return -1;
}
}
+ else if (octal_only)
+ {
+ /* Suppress the following extensions. */
+ }
else if (*where == '-' || *where == '+')
{
/* Parse base-64 output produced only by tar test versions
1.13.6 (1999-08-11) through 1.13.11 (1999-08-23).
Support for this will be withdrawn in future releases. */
int dig;
- static int warned_once;
- if (! warned_once)
+ if (!silent)
{
- warned_once = 1;
- if (!silent)
- WARN ((0, 0,
- _("Archive contains obsolescent base-64 headers")));
+ static bool warned_once;
+ if (! warned_once)
+ {
+ warned_once = true;
+ WARN ((0, 0, _("Archive contains obsolescent base-64 headers")));
+ }
}
negative = *where++ == '-';
while (where != lim
return from_header (p, s, "gid_t",
- (uintmax_t) TYPE_MINIMUM (gid_t),
(uintmax_t) TYPE_MAXIMUM (gid_t),
- false);
+ false, false);
}
major_t
{
return from_header (p, s, "major_t",
- (uintmax_t) TYPE_MINIMUM (major_t),
- (uintmax_t) TYPE_MAXIMUM (major_t), false);
+ (uintmax_t) TYPE_MAXIMUM (major_t), false, false);
}
minor_t
{
return from_header (p, s, "minor_t",
- (uintmax_t) TYPE_MINIMUM (minor_t),
- (uintmax_t) TYPE_MAXIMUM (minor_t), false);
+ (uintmax_t) TYPE_MAXIMUM (minor_t), false, false);
}
mode_t
/* Do not complain about unrecognized mode bits. */
unsigned u = from_header (p, s, "mode_t",
- (uintmax_t) TYPE_MINIMUM (mode_t),
- TYPE_MAXIMUM (uintmax_t), false);
+ TYPE_MAXIMUM (uintmax_t), false, false);
return ((u & TSUID ? S_ISUID : 0)
| (u & TSGID ? S_ISGID : 0)
| (u & TSVTX ? S_ISVTX : 0)
/* Negative offsets are not allowed in tar files, so invoke
from_header with minimum value 0, not TYPE_MINIMUM (off_t). */
return from_header (p, s, "off_t", (uintmax_t) 0,
- (uintmax_t) TYPE_MAXIMUM (off_t), false);
+ (uintmax_t) TYPE_MAXIMUM (off_t), false, false);
}
size_t
size_from_header (const char *p, size_t s)
{
return from_header (p, s, "size_t", (uintmax_t) 0,
- (uintmax_t) TYPE_MAXIMUM (size_t), false);
+ (uintmax_t) TYPE_MAXIMUM (size_t), false, false);
}
time_t
{
return from_header (p, s, "time_t",
- (uintmax_t) TYPE_MINIMUM (time_t),
- (uintmax_t) TYPE_MAXIMUM (time_t), false);
+ (uintmax_t) TYPE_MAXIMUM (time_t), false, false);
}
uid_t
{
return from_header (p, s, "uid_t",
- (uintmax_t) TYPE_MINIMUM (uid_t),
- (uintmax_t) TYPE_MAXIMUM (uid_t), false);
+ (uintmax_t) TYPE_MAXIMUM (uid_t), false, false);
}
uintmax_t
uintmax_from_header (const char *p, size_t s)
{
return from_header (p, s, "uintmax_t", (uintmax_t) 0,
- TYPE_MAXIMUM (uintmax_t), false);
+ TYPE_MAXIMUM (uintmax_t), false, false);
}
-/* Format O as a null-terminated decimal string into BUF _backwards_;
- return pointer to start of result. */
-char *
-stringify_uintmax_t_backwards (uintmax_t o, char *buf)
-{
- *--buf = '\0';
- do
- *--buf = '0' + (int) (o % 10);
- while ((o /= 10) != 0);
- return buf;
-}
-
/* Return a printable representation of T. The result points to
static storage that can be reused in the next call to this
function, to ctime, or to asctime. */
break;
}
- decode_mode (st->stat.st_mode, modes + 1);
+ pax_decode_mode (st->stat.st_mode, modes + 1);
/* Time stamp. */
/* User and group names. */
- if (st->uname && current_format != V7_FORMAT
+ if (st->uname
+ && st->uname[0]
+ && current_format != V7_FORMAT
&& !numeric_owner_option)
user = st->uname;
else
sizeof current_header->header.uid, 0,
(uintmax_t) 0,
(uintmax_t) TYPE_MAXIMUM (uintmax_t),
- false);
+ false, false);
if (u != -1)
user = STRINGIFY_BIGINT (u, uform);
else
}
}
- if (st->gname && current_format != V7_FORMAT
+ if (st->gname
+ && st->gname[0]
+ && current_format != V7_FORMAT
&& !numeric_owner_option)
group = st->gname;
else
sizeof current_header->header.gid, 0,
(uintmax_t) 0,
(uintmax_t) TYPE_MAXIMUM (uintmax_t),
- false);
+ false, false);
if (g != -1)
group = STRINGIFY_BIGINT (g, gform);
else
/* File type and modes. */
modes[0] = 'd';
- decode_mode (mode, modes + 1);
+ pax_decode_mode (mode, modes + 1);
if (block_number_option)
{
else
seekable_archive = false;
}
-
+
while (size > 0)
{
x = find_next_block ();
{
char save_typeflag = current_header->header.typeflag;
set_next_block_after (current_header);
-
- assign_string (&save_name, current_stat_info.file_name);
+
+ assign_string (&save_name, current_stat_info.orig_file_name);
if (current_stat_info.is_sparse)
sparse_skip_file (¤t_stat_info);