Support >INT_MAX -C dirs
* src/extract.c (struct delayed_set_stat, struct delayed_link): * src/misc.c (normalize_filename, wd_count, chdir_count) (chdir_arg, tar_getcdpath): * src/names.c (name_gather, addname, add_hierarchy_to_namelist): * src/unlink.c (struct deferred_unlink, flush_deferred_unlinks): Use idx_t, not int, for directory indexes, so as to not limit their number to INT_MAX; this is theoretically possible if -T is used. * src/names.c (name_next_elt, name_next): Use bool for boolean.
This commit is contained in:
17
src/common.h
17
src/common.h
@@ -367,7 +367,7 @@ struct name
|
||||
bool cmdline; /* true if this name was given in the
|
||||
command line */
|
||||
|
||||
int change_dir; /* Number of the directory to change to.
|
||||
idx_t change_dir; /* Number of the directory to change to.
|
||||
Set with the -C option. */
|
||||
uintmax_t found_count; /* number of times a matching file has
|
||||
been found */
|
||||
@@ -650,7 +650,7 @@ void assign_string_n (char **string, const char *value, size_t n);
|
||||
#define ASSIGN_STRING_N(s,v) assign_string_n (s, v, sizeof (v))
|
||||
int unquote_string (char *str);
|
||||
char *zap_slashes (char *name);
|
||||
char *normalize_filename (int cdidx, const char *name);
|
||||
char *normalize_filename (idx_t, char const *);
|
||||
void normalize_filename_x (char *name);
|
||||
void replace_prefix (char **pname, const char *samp, size_t slen,
|
||||
const char *repl, size_t rlen);
|
||||
@@ -744,11 +744,11 @@ int deref_stat (char const *name, struct stat *buf);
|
||||
size_t blocking_read (int fd, void *buf, size_t count);
|
||||
size_t blocking_write (int fd, void const *buf, size_t count);
|
||||
|
||||
extern int chdir_current;
|
||||
extern idx_t chdir_current;
|
||||
extern int chdir_fd;
|
||||
int chdir_arg (char const *dir);
|
||||
void chdir_do (int dir);
|
||||
int chdir_count (void);
|
||||
idx_t chdir_arg (char const *dir);
|
||||
void chdir_do (idx_t dir);
|
||||
idx_t chdir_count (void);
|
||||
|
||||
void close_diag (char const *name);
|
||||
void open_diag (char const *name);
|
||||
@@ -794,10 +794,9 @@ int uname_to_uid (char const *uname, uid_t *puid);
|
||||
void name_init (void);
|
||||
void name_add_name (const char *name);
|
||||
void name_term (void);
|
||||
const char *name_next (int change_dirs);
|
||||
char const *name_next (bool);
|
||||
void name_gather (void);
|
||||
struct name *addname (char const *string, int change_dir,
|
||||
bool cmdline, struct name *parent);
|
||||
struct name *addname (char const *, idx_t, bool, struct name *);
|
||||
void add_starting_file (char const *file_name);
|
||||
void remname (struct name *name);
|
||||
bool name_match (const char *name);
|
||||
|
||||
@@ -1395,7 +1395,7 @@ create_archive (void)
|
||||
else
|
||||
{
|
||||
const char *name;
|
||||
while ((name = name_next (1)) != NULL)
|
||||
while ((name = name_next (true)))
|
||||
if (!excluded_name (name, NULL))
|
||||
dump_file (0, name, name);
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ struct delayed_set_stat
|
||||
bool after_links;
|
||||
|
||||
/* Directory that the name is relative to. */
|
||||
int change_dir;
|
||||
idx_t change_dir;
|
||||
|
||||
/* extended attributes*/
|
||||
char *cntx_name;
|
||||
@@ -165,7 +165,7 @@ struct delayed_link
|
||||
struct timespec mtime;
|
||||
|
||||
/* The directory that the sources and target are relative to. */
|
||||
int change_dir;
|
||||
idx_t change_dir;
|
||||
|
||||
/* A list of sources for this link. The sources are all to be
|
||||
hard-linked together. */
|
||||
@@ -1850,7 +1850,7 @@ extract_archive (void)
|
||||
(see NOTICE in the comment to delay_set_stat above) */
|
||||
if (!delay_directory_restore_option)
|
||||
{
|
||||
int dir = chdir_current;
|
||||
idx_t dir = chdir_current;
|
||||
apply_nonancestor_delayed_set_stat (current_stat_info.file_name, false);
|
||||
chdir_do (dir);
|
||||
}
|
||||
|
||||
31
src/misc.c
31
src/misc.c
@@ -31,7 +31,7 @@
|
||||
|
||||
static void namebuf_add_dir (namebuf_t, char const *);
|
||||
static char *namebuf_finish (namebuf_t);
|
||||
static const char *tar_getcdpath (int);
|
||||
static const char *tar_getcdpath (idx_t);
|
||||
|
||||
char const *
|
||||
quote_n_colon (int n, char const *arg)
|
||||
@@ -315,7 +315,7 @@ normalize_filename_x (char *file_name)
|
||||
Return a normalized newly-allocated copy. */
|
||||
|
||||
char *
|
||||
normalize_filename (int cdidx, const char *name)
|
||||
normalize_filename (idx_t cdidx, const char *name)
|
||||
{
|
||||
char *copy = NULL;
|
||||
|
||||
@@ -903,7 +903,7 @@ struct wd
|
||||
static struct wd *wd;
|
||||
|
||||
/* The number of working directories in the vector. */
|
||||
static size_t wd_count;
|
||||
static idx_t wd_count;
|
||||
|
||||
/* The allocated size of the vector. */
|
||||
static size_t wd_alloc;
|
||||
@@ -921,17 +921,15 @@ static int wdcache[CHDIR_CACHE_SIZE];
|
||||
/* Number of nonzero entries in WDCACHE. */
|
||||
static size_t wdcache_count;
|
||||
|
||||
int
|
||||
idx_t
|
||||
chdir_count (void)
|
||||
{
|
||||
if (wd_count == 0)
|
||||
return wd_count;
|
||||
return wd_count - 1;
|
||||
return wd_count - !!wd_count;
|
||||
}
|
||||
|
||||
/* DIR is the operand of a -C option; add it to vector of chdir targets,
|
||||
and return the index of its location. */
|
||||
int
|
||||
idx_t
|
||||
chdir_arg (char const *dir)
|
||||
{
|
||||
if (wd_count == wd_alloc)
|
||||
@@ -967,7 +965,7 @@ chdir_arg (char const *dir)
|
||||
}
|
||||
|
||||
/* Index of current directory. */
|
||||
int chdir_current;
|
||||
idx_t chdir_current;
|
||||
|
||||
/* Value suitable for use as the first argument to openat, and in
|
||||
similar locations for fstatat, etc. This is an open file
|
||||
@@ -981,7 +979,7 @@ int chdir_fd = AT_FDCWD;
|
||||
working directory; otherwise, I must be a value returned by
|
||||
chdir_arg. */
|
||||
void
|
||||
chdir_do (int i)
|
||||
chdir_do (idx_t i)
|
||||
{
|
||||
if (chdir_current != i)
|
||||
{
|
||||
@@ -1049,7 +1047,7 @@ tar_dirname (void)
|
||||
process's actual cwd. (Note that in this case IDX is ignored,
|
||||
since it should always be 0.) */
|
||||
static const char *
|
||||
tar_getcdpath (int idx)
|
||||
tar_getcdpath (idx_t idx)
|
||||
{
|
||||
if (!wd)
|
||||
{
|
||||
@@ -1065,14 +1063,11 @@ tar_getcdpath (int idx)
|
||||
|
||||
if (!wd[idx].abspath)
|
||||
{
|
||||
int i;
|
||||
int save_cwdi = chdir_current;
|
||||
idx_t save_cwdi = chdir_current, i = idx;
|
||||
while (0 < i && !wd[i - 1].abspath)
|
||||
i--;
|
||||
|
||||
for (i = idx; i >= 0; i--)
|
||||
if (wd[i].abspath)
|
||||
break;
|
||||
|
||||
while (++i <= idx)
|
||||
for (; i <= idx; i++)
|
||||
{
|
||||
chdir_do (i);
|
||||
if (i == 0)
|
||||
|
||||
23
src/names.c
23
src/names.c
@@ -1100,7 +1100,7 @@ copy_name (struct name_elt *ep)
|
||||
|
||||
*/
|
||||
static struct name_elt *
|
||||
name_next_elt (int change_dirs)
|
||||
name_next_elt (bool change_dirs)
|
||||
{
|
||||
static struct name_elt entry;
|
||||
struct name_elt *ep;
|
||||
@@ -1148,7 +1148,7 @@ name_next_elt (int change_dirs)
|
||||
}
|
||||
|
||||
const char *
|
||||
name_next (int change_dirs)
|
||||
name_next (bool change_dirs)
|
||||
{
|
||||
struct name_elt *nelt = name_next_elt (change_dirs);
|
||||
return nelt ? nelt->v.name : NULL;
|
||||
@@ -1181,9 +1181,9 @@ name_gather (void)
|
||||
|
||||
if (same_order_option)
|
||||
{
|
||||
static int change_dir;
|
||||
static idx_t change_dir;
|
||||
|
||||
while ((ep = name_next_elt (0)) && ep->type == NELT_CHDIR)
|
||||
while ((ep = name_next_elt (false)) && ep->type == NELT_CHDIR)
|
||||
change_dir = chdir_arg (xstrdup (ep->v.name));
|
||||
|
||||
if (ep)
|
||||
@@ -1207,12 +1207,12 @@ name_gather (void)
|
||||
else
|
||||
{
|
||||
/* Non sorted names -- read them all in. */
|
||||
int change_dir = 0;
|
||||
idx_t change_dir = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int change_dir0 = change_dir;
|
||||
while ((ep = name_next_elt (0)) && ep->type == NELT_CHDIR)
|
||||
idx_t change_dir0 = change_dir;
|
||||
while ((ep = name_next_elt (false)) && ep->type == NELT_CHDIR)
|
||||
change_dir = chdir_arg (xstrdup (ep->v.name));
|
||||
|
||||
if (ep)
|
||||
@@ -1229,7 +1229,8 @@ name_gather (void)
|
||||
|
||||
/* Add a name to the namelist. */
|
||||
struct name *
|
||||
addname (char const *string, int change_dir, bool cmdline, struct name *parent)
|
||||
addname (char const *string, idx_t change_dir, bool cmdline,
|
||||
struct name *parent)
|
||||
{
|
||||
struct name *name = make_name (string);
|
||||
|
||||
@@ -1443,7 +1444,7 @@ names_notfound (void)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
while ((name = name_next (1)) != NULL)
|
||||
while ((name = name_next (true)))
|
||||
{
|
||||
regex_usage_warning (name);
|
||||
ERROR ((0, 0, _("%s: Not found in archive"),
|
||||
@@ -1482,7 +1483,7 @@ label_notfound (void)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
while ((name = name_next (1)) != NULL
|
||||
while ((name = name_next (true))
|
||||
&& regex_usage_warning (name) == 0)
|
||||
;
|
||||
}
|
||||
@@ -1620,7 +1621,7 @@ add_hierarchy_to_namelist (struct tar_stat_info *st, struct name *name)
|
||||
char *namebuf = xmalloc (allocated_length);
|
||||
const char *string;
|
||||
size_t string_length;
|
||||
int change_dir = name->change_dir;
|
||||
idx_t change_dir = name->change_dir;
|
||||
|
||||
strcpy (namebuf, name->name);
|
||||
if (! ISSLASH (namebuf[name_length - 1]))
|
||||
|
||||
14
src/unlink.c
14
src/unlink.c
@@ -24,7 +24,7 @@
|
||||
struct deferred_unlink
|
||||
{
|
||||
struct deferred_unlink *next; /* Next unlink in the queue */
|
||||
int dir_idx; /* Directory index in wd */
|
||||
idx_t dir_idx; /* Directory index in wd */
|
||||
char *file_name; /* Name of the file to unlink, relative
|
||||
to dir_idx */
|
||||
bool is_dir; /* True if file_name is a directory */
|
||||
@@ -72,7 +72,7 @@ dunlink_insert (struct deferred_unlink *anchor, struct deferred_unlink *p)
|
||||
p->next = anchor->next;
|
||||
anchor->next = p;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
p->next = dunlink_head;
|
||||
dunlink_head = p;
|
||||
@@ -94,8 +94,8 @@ static void
|
||||
flush_deferred_unlinks (bool force)
|
||||
{
|
||||
struct deferred_unlink *p, *prev = NULL;
|
||||
int saved_chdir = chdir_current;
|
||||
|
||||
idx_t saved_chdir = chdir_current;
|
||||
|
||||
for (p = dunlink_head; p; )
|
||||
{
|
||||
struct deferred_unlink *next = p->next;
|
||||
@@ -188,8 +188,8 @@ flush_deferred_unlinks (bool force)
|
||||
p = next;
|
||||
}
|
||||
dunlink_head = dunlink_tail = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
chdir_do (saved_chdir);
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ void
|
||||
finish_deferred_unlinks (void)
|
||||
{
|
||||
flush_deferred_unlinks (true);
|
||||
|
||||
|
||||
while (dunlink_avail)
|
||||
{
|
||||
struct deferred_unlink *next = dunlink_avail->next;
|
||||
|
||||
Reference in New Issue
Block a user