/* List a tar archive, with support routines for reading a tar archive.
- Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2013
- Free Software Foundation, Inc.
+ Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2016 Free
+ Software Foundation, Inc.
This file is part of GNU tar.
return transform_name_fp (pinput, type, decode_xform, &type);
}
+static void
+enforce_one_top_level (char **pfile_name)
+{
+ char *file_name = *pfile_name;
+ char *p;
+
+ for (p = file_name; *p && (ISSLASH (*p) || *p == '.'); p++)
+ ;
+
+ if (*p)
+ {
+ int pos = strlen (one_top_level_dir);
+ if (strncmp (p, one_top_level_dir, pos) == 0)
+ {
+ if (ISSLASH (p[pos]) || p[pos] == 0)
+ return;
+ }
+
+ *pfile_name = make_file_name (one_top_level_dir, file_name);
+ normalize_filename_x (*pfile_name);
+ }
+ else
+ *pfile_name = xstrdup (one_top_level_dir);
+ free (file_name);
+}
+
void
transform_stat_info (int typeflag, struct tar_stat_info *stat_info)
{
case LNKTYPE:
transform_member_name (&stat_info->link_name, XFORM_LINK);
}
+
+ if (one_top_level_option)
+ enforce_one_top_level (¤t_stat_info.file_name);
}
/* Main loop for reading an archive. */
decode_header (current_header, ¤t_stat_info,
¤t_format, 1);
if (! name_match (current_stat_info.file_name)
- || (NEWER_OPTION_INITIALIZED (newer_mtime_option)
+ || (TIME_OPTION_INITIALIZED (newer_mtime_option)
/* FIXME: We get mtime now, and again later; this causes
duplicate diagnostics if header.mtime is bogus. */
&& ((mtime.tv_sec
mtime.tv_nsec = 0,
current_stat_info.mtime = mtime,
OLDER_TAR_STAT_TIME (current_stat_info, m)))
- || excluded_name (current_stat_info.file_name))
+ || excluded_name (current_stat_info.file_name,
+ current_stat_info.parent))
{
switch (current_header->header.typeflag)
{
continue;
}
}
+
transform_stat_info (current_header->header.typeflag,
¤t_stat_info);
(*do_something) ();
}
}
- stat_info->archive_file_size = stat_info->stat.st_size;
xheader_decode (stat_info);
if (sparse_member_p (stat_info))
type));
return -1;
}
- if (!ISSPACE ((unsigned char) *where))
+ if (!isspace ((unsigned char) *where))
break;
where++;
}
value = -value;
}
- if (where != lim && *where && !ISSPACE ((unsigned char) *where))
+ if (where != lim && *where && !isspace ((unsigned char) *where))
{
if (type)
{
if (verbose_option <= 1)
{
/* Just the fax, mam. */
- fprintf (stdlis, "%s\n", quotearg (temp_name));
+ fputs (quotearg (temp_name), stdlis);
+ if (show_transformed_names_option && st->had_trailing_slash)
+ fputc ('/', stdlis);
+ fputc ('\n', stdlis);
}
else
{
case GNUTYPE_SPARSE:
case REGTYPE:
case AREGTYPE:
- modes[0] = '-';
- if (temp_name[strlen (temp_name) - 1] == '/')
- modes[0] = 'd';
+ modes[0] = st->had_trailing_slash ? 'd' : '-';
break;
case LNKTYPE:
modes[0] = 'h';
&& !numeric_owner_option)
user = st->uname;
else
- {
- /* Try parsing it as an unsigned integer first, and as a
- uid_t if that fails. This method can list positive user
- ids that are too large to fit in a uid_t. */
- uintmax_t u = from_header (blk->header.uid,
- sizeof blk->header.uid, 0,
- 0, UINTMAX_MAX,
- false, false);
- user = (u != -1
- ? STRINGIFY_BIGINT (u, uform)
- : imaxtostr (UID_FROM_HEADER (blk->header.uid), uform));
- }
+ user = STRINGIFY_BIGINT (st->stat.st_uid, uform);
if (st->gname
&& st->gname[0]
&& !numeric_owner_option)
group = st->gname;
else
- {
- /* Try parsing it as an unsigned integer first, and as a
- gid_t if that fails. This method can list positive group
- ids that are too large to fit in a gid_t. */
- uintmax_t g = from_header (blk->header.gid,
- sizeof blk->header.gid, 0,
- 0, UINTMAX_MAX,
- false, false);
- group = (g != -1
- ? STRINGIFY_BIGINT (g, gform)
- : imaxtostr (GID_FROM_HEADER (blk->header.gid), gform));
- }
+ group = STRINGIFY_BIGINT (st->stat.st_gid, gform);
/* Format the file size or major/minor device numbers. */
datewidth, time_stamp);
fprintf (stdlis, " %s", quotearg (temp_name));
+ if (show_transformed_names_option && st->had_trailing_slash)
+ fputc ('/', stdlis);
switch (blk->header.typeflag)
{