char name[1];
};
-struct link *linklist = NULL; /* points to first link in list */
+static struct link *linklist; /* points to first link in list */
\f
/* Base 64 digits; see Internet RFC 2045 Table 1. */
char const base_64_digits[64] =
{
uintmax_t v = negative ? -value : value;
+ /* Generate the POSIX octal representation if the number fits. */
if (! negative && v <= MAX_VAL_WITH_DIGITS (size - 1, LG_8))
{
where[size - 1] = '\0';
to_base (v, LG_8, base_8_digits, where, size - 1);
}
+
+ /* Otherwise, generate the GNU base-64 representation if we are
+ generating an old or new GNU format and if the number fits. */
else if (v <= MAX_VAL_WITH_DIGITS (size - 1, LG_64)
- && archive_format == GNU_FORMAT)
+ && (archive_format == GNU_FORMAT
+ || archive_format == OLDGNU_FORMAT))
{
where[0] = negative ? '-' : '+';
to_base (v, LG_64, base_64_digits, where + 1, size - 1);
}
- else if (negative
- && archive_format != GNU_FORMAT
- && valsize * CHAR_BIT <= (size - 1) * LG_8)
+
+ /* Otherwise, if the number is negative, and if it would not cause
+ ambiguity on this host by confusing positive with negative
+ values, then generate the POSIX octal representation of the value
+ modulo 2**(field bits). The resulting tar file is
+ machine-dependent, since it depends on the host word size. Yuck!
+ But this is the traditional behavior. */
+ else if (negative && valsize * CHAR_BIT <= (size - 1) * LG_8)
{
where[size - 1] = '\0';
to_base (value & MAX_VAL_WITH_DIGITS (valsize * CHAR_BIT, 1),
LG_8, base_8_digits, where, size - 1);
}
+
+ /* Otherwise, output a substitute value if possible (with a
+ warning), and an error message if not. */
else
{
uintmax_t maxval = (archive_format == GNU_FORMAT
char *sub_string = STRINGIFY_BIGINT (s, buf3 + 1);
if (negsub)
*--sub_string = '-';
- WARN ((0, 0, _("%s value %s out of range %s..%s; substituting %s"),
- type, value_string, minval_string, maxval_string,
+ WARN ((0, 0, _("value %s out of %s range %s..%s; substituting %s"),
+ value_string, type, minval_string, maxval_string,
sub_string));
- to_chars (negsub, s, valsize, NULL, where, size, type);
+ to_chars (negsub, s, valsize, 0, where, size, type);
}
else
- ERROR ((0, 0, _("%s value %s out of range %s..%s"),
- type, value_string, minval_string, maxval_string));
+ ERROR ((0, 0, _("value %s out of %s range %s..%s"),
+ value_string, type, minval_string, maxval_string));
}
}
void
major_to_chars (major_t v, char *p, size_t s)
{
- to_chars (v < 0, (uintmax_t) v, sizeof v, NULL, p, s, "major_t");
+ to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "major_t");
}
void
minor_to_chars (minor_t v, char *p, size_t s)
{
- to_chars (v < 0, (uintmax_t) v, sizeof v, NULL, p, s, "minor_t");
+ to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "minor_t");
}
void
| (v & S_IWOTH ? TOWRITE : 0)
| (v & S_IXOTH ? TOEXEC : 0));
}
- to_chars (negative, u, sizeof v, NULL, p, s, "mode_t");
+ to_chars (negative, u, sizeof v, 0, p, s, "mode_t");
}
void
off_to_chars (off_t v, char *p, size_t s)
{
- to_chars (v < 0, (uintmax_t) v, sizeof v, NULL, p, s, "off_t");
+ to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "off_t");
}
void
size_to_chars (size_t v, char *p, size_t s)
{
- to_chars (0, (uintmax_t) v, sizeof v, NULL, p, s, "size_t");
+ to_chars (0, (uintmax_t) v, sizeof v, 0, p, s, "size_t");
}
void
time_to_chars (time_t v, char *p, size_t s)
{
- to_chars (v < 0, (uintmax_t) v, sizeof v, NULL, p, s, "time_t");
+ to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "time_t");
}
static uintmax_t
void
uintmax_to_chars (uintmax_t v, char *p, size_t s)
{
- to_chars (0, v, sizeof v, NULL, p, s, "uintmax_t");
+ to_chars (0, v, sizeof v, 0, p, s, "uintmax_t");
}
\f
/* Writing routines. */
}
/*-------------------------------------------------------------------------.
-| Write the EOT block(s). We actually zero at least one block, through |
+| Write the EOT block(s). We zero at least two blocks, through |
| the end of the record. Old tar, as previous versions of GNU tar, writes |
| garbage after two zeroed blocks. |
`-------------------------------------------------------------------------*/
write_eot (void)
{
union block *pointer = find_next_block ();
-
- if (pointer)
- {
- size_t space = available_space_after (pointer);
-
- memset (pointer->buffer, 0, space);
- set_next_block_after (pointer);
- }
+ memset (pointer->buffer, 0, BLOCKSIZE);
+ set_next_block_after (pointer);
+ pointer = find_next_block ();
+ memset (pointer->buffer, 0, available_space_after (pointer));
+ set_next_block_after (pointer);
}
/*-----------------------------------------------------.
/*---------------------------------------------------------------------.
| Make a header block for the file name whose stat info is st. Return |
-| header pointer for success, NULL if the name is too long. |
+| header pointer for success, zero if the name is too long. |
`---------------------------------------------------------------------*/
static union block *
if (!absolute_names_option)
{
- static int warned_once = 0;
size_t prefix_len = FILESYSTEM_PREFIX_LEN (name);
if (prefix_len)
{
- name += prefix_len;
+ static int warned_once;
if (!warned_once)
{
warned_once = 1;
- WARN ((0, 0, _("Removing filesystem prefix from names in the archive")));
+ WARN ((0, 0, _("Removing `%.*s' prefix from archive names"),
+ (int) prefix_len, name));
}
+ name += prefix_len;
}
while (*name == '/')
{
- name++; /* force relative path */
+ static int warned_once;
if (!warned_once)
{
warned_once = 1;
- WARN ((0, 0, _("\
-Removing leading `/' from absolute path names in the archive")));
+ WARN ((0, 0, _("Removing leading `/' from archive names")));
}
+ name++;
}
}
/* Check the file name and put it in the block. */
- if (strlen (name) >= (size_t) NAME_FIELD_SIZE)
+ if (sizeof header->header.name <= strlen (name))
write_long (name, GNUTYPE_LONGNAME);
header = find_next_block ();
memset (header->buffer, 0, sizeof (union block));
int sum;
char *p;
- memcpy (header->header.chksum, CHKBLANKS, sizeof (header->header.chksum));
+ memcpy (header->header.chksum, CHKBLANKS, sizeof header->header.chksum);
sum = 0;
p = header->buffer;
- for (i = sizeof (*header); i-- != 0; )
+ for (i = sizeof *header; i-- != 0; )
/* We can't use unsigned char here because of old compilers, e.g. V7. */
sum += 0xFF & *p++;
/* Make room for our scratch space -- initially is 10 elts long. */
- sparsearray = (struct sp_array *)
- xmalloc (sp_array_size * sizeof (struct sp_array));
+ sparsearray = xmalloc (sp_array_size * sizeof (struct sp_array));
for (counter = 0; counter < sp_array_size; counter++)
{
sparsearray[counter].offset = 0;
if (sparse_index > sp_array_size - 1)
{
-
- sparsearray = (struct sp_array *)
+ sparsearray =
xrealloc (sparsearray,
2 * sp_array_size * sizeof (struct sp_array));
sp_array_size *= 2;
if (count < 0)
{
char buf[UINTMAX_STRSIZE_BOUND];
- ERROR ((0, errno, _("\
-Read error at byte %s, reading %lu bytes, in file %s"),
+ ERROR ((0, errno,
+ _("Read error at byte %s, reading %lu bytes, in file %s"),
STRINGIFY_BIGINT (fullsize - *sizeleft, buf),
(unsigned long) bufsize, name));
return 1;
blank_name_list ();
while (p = name_from_list (), p)
- {
- strcpy (buffer, p);
- if (p[strlen (p) - 1] != '/')
- strcat (buffer, "/");
- bufp = buffer + strlen (buffer);
- for (q = gnu_list_name->dir_contents;
- q && *q;
- q += strlen (q) + 1)
- {
- if (*q == 'Y')
- {
- strcpy (bufp, q + 1);
- dump_file (buffer, (dev_t) -1, 1);
- }
- }
- }
+ if (!excluded_name (p))
+ {
+ strcpy (buffer, p);
+ if (p[strlen (p) - 1] != '/')
+ strcat (buffer, "/");
+ bufp = buffer + strlen (buffer);
+ q = gnu_list_name->dir_contents;
+ if (q)
+ for (; *q; q += strlen (q) + 1)
+ if (*q == 'Y')
+ {
+ strcpy (bufp, q + 1);
+ dump_file (buffer, (dev_t) -1, 1);
+ }
+ }
free (buffer);
}
else
#ifdef S_ISHIDDEN
if (S_ISHIDDEN (current_stat.st_mode))
{
- char *new = (char *) alloca (strlen (p) + 2);
+ char *new = alloca (strlen (p) + 2);
if (new)
{
strcpy (new, p);
}
#endif
- /* See if we only want new files, and check if this one is too old to
+ /* See if we want only new files, and check if this one is too old to
put in the archive. */
- if (!incremental_option && !S_ISDIR (current_stat.st_mode)
+ if ((!incremental_option || listed_incremental_option)
+ && !S_ISDIR (current_stat.st_mode)
&& current_stat.st_mtime < newer_mtime_option
&& (!after_date_option || current_stat.st_ctime < newer_ctime_option))
{
- if (parent_device == (dev_t) -1)
+ if (!listed_incremental_option && parent_device == (dev_t) -1)
WARN ((0, 0, _("%s: is unchanged; not dumped"), p));
/* FIXME: recheck this return. */
return;
while (!absolute_names_option && *link_name == '/')
{
- static int warned_once = 0;
-
+ static int warned_once;
if (!warned_once)
{
warned_once = 1;
- WARN ((0, 0, _("\
-Removing leading `/' from absolute links")));
+ WARN ((0, 0, _("Removing leading `/' from link names")));
}
link_name++;
}
current_stat.st_size = 0;
header = start_header (p, ¤t_stat);
- if (header == NULL)
+ if (! header)
{
exit_status = TAREXIT_FAILURE;
return;
/* Not found. Add it to the list of possible links. */
- lp = (struct link *)
- xmalloc ((size_t) (sizeof (struct link) + strlen (p)));
+ lp = xmalloc (sizeof (struct link) + strlen (p));
lp->ino = current_stat.st_ino;
lp->dev = current_stat.st_dev;
strcpy (lp->name, p);
int header_moved;
char isextended = 0;
int upperbound;
-#if 0
- static int cried_once = 0;
-#endif
header_moved = 0;
int counter;
header = start_header (p, ¤t_stat);
- if (header == NULL)
+ if (! header)
{
exit_status = TAREXIT_FAILURE;
return;
if (!header_moved)
{
header = start_header (p, ¤t_stat);
- if (header == NULL)
+ if (! header)
{
if (f >= 0)
close (f);
extend:
exhdr = find_next_block ();
-
- if (exhdr == NULL)
+ if (! exhdr)
{
exit_status = TAREXIT_FAILURE;
return;
bufsize = sizeleft;
count = bufsize % BLOCKSIZE;
if (count)
- memset (start->buffer + sizeleft, 0,
- (size_t) (BLOCKSIZE - count));
+ memset (start->buffer + sizeleft, 0, BLOCKSIZE - count);
}
if (f < 0)
count = bufsize;
if (count < 0)
{
char buf[UINTMAX_STRSIZE_BOUND];
- ERROR ((0, errno, _("\
-Read error at byte %s, reading %lu bytes, in file %s"),
+ ERROR ((0, errno,
+ _("Read error at byte %s, reading %lu bytes, in file %s"),
STRINGIFY_BIGINT (current_stat.st_size - sizeleft,
buf),
(unsigned long) bufsize, p));
}
if (multi_volume_option)
- assign_string (&save_name, NULL);
+ assign_string (&save_name, 0);
if (f >= 0)
{
sizeleft -= BLOCKSIZE;
}
if (multi_volume_option)
- assign_string (&save_name, NULL);
+ assign_string (&save_name, 0);
if (f >= 0)
{
close (f);
else if (S_ISLNK (current_stat.st_mode))
{
int size;
- char *buffer = (char *) alloca (PATH_MAX + 1);
+ char *buffer = alloca (PATH_MAX + 1);
size = readlink (p, buffer, PATH_MAX + 1);
if (size < 0)
current_stat.st_size = 0; /* force 0 size on symlink */
header = start_header (p, ¤t_stat);
- if (header == NULL)
+ if (! header)
{
exit_status = TAREXIT_FAILURE;
return;
files, we'd better put the / on the name. */
header = start_header (namebuf, ¤t_stat);
- if (header == NULL)
+ if (! header)
{
exit_status = TAREXIT_FAILURE;
return; /* eg name too long */
bufsize = sizeleft;
count = bufsize % BLOCKSIZE;
if (count)
- memset (start->buffer + sizeleft, 0,
- (size_t) (BLOCKSIZE - count));
+ memset (start->buffer + sizeleft, 0, BLOCKSIZE - count);
}
memcpy (start->buffer, p_buffer, bufsize);
sizeleft -= bufsize;
set_next_block_after (start + (bufsize - 1) / BLOCKSIZE);
}
if (multi_volume_option)
- assign_string (&save_name, NULL);
+ assign_string (&save_name, 0);
if (atime_preserve_option)
utime (p, &restore_times);
return;
return;
}
- /* Hack to remove "./" from the front of all the file names. */
-
- if (len == 2 && namebuf[0] == '.' && namebuf[1] == '/')
- len = 0;
-
/* FIXME: Should speed this up by cd-ing into the dir. */
while (entry = readdir (directory), entry)
if ((int) NAMLEN (entry) + len >= buflen)
{
buflen = len + NAMLEN (entry);
- namebuf = (char *) xrealloc (namebuf, buflen + 1);
+ namebuf = xrealloc (namebuf, buflen + 1);
#if 0
namebuf[len] = '\0';
ERROR ((0, 0, _("File name %s%s too long"),
current_stat.st_size = 0; /* force 0 size */
header = start_header (p, ¤t_stat);
- if (header == NULL)
+ if (! header)
{
exit_status = TAREXIT_FAILURE;
return; /* eg name too long */