* src/common.h (label_notfound): New decl.
* src/buffer.c (set_volume_start_time, compress_type):
(guess_seekable_archive, open_compressed_archive, init_buffer):
(_flush_write, archive_is-dev, increase_volume_number):
(change_tape_menu, try_new_volume, add_chunk_header):
(multi_volume_sync):
Declare as 'static' if it's not exported.
Use function prototype (void) rather than old-style ().
* src/checkpoint.c (expand_checkpoint_string): Likewise.
* src/incremen.c (dirlist_replace_prefix, makedumpdir, read_incr_db_2):
Likewise.
* src/list.c (print_volume_label): Likewise.
* src/misc.c (normalize_filename_x): Likewise.
* src/names.c (make_name, free_name, check_name_alloc, name_next_elt):
Likewise.
* src/tar.c (tar_list_quoting_style, add_exclude_array):
(set_stat_signal): Likewise.
* src/transform.c (new_transform, _single_transform_name_to_obstack):
(_transform_name_to_obstack): Likewise.
* src/unlink.c (dunlink_alloc): Likewise.
* src/buffer.c (struct zip_magic): Use const when appropriate.
* src/incremen.c (obstack_code_rename, write_directory_file_entry):
Likewise.
* src/sparse.c (COPY_STRING): Likewise.
* src/system.c (dec_to_env, time_to_env, oct_to_env, str_to_env):
(chr_to_env): Likewise.
* src/tar.c (tar_list_quoting_style, set_stat_signal): Likewise.
* src/extract.c (extract_node): Don't return garbage.
* src/names.c: Remove old-style declarations of getgrnam etc.
All modern systems declare these, and it's not worth the hassle
of ignoring the warnings on modern systems for old-style decls.
off_t records_read; /* number of records read from this archive */
off_t records_written; /* likewise, for records written */
extern off_t records_skipped; /* number of records skipped at the start
- of the archive, defined in delete.c */
+ of the archive, defined in delete.c */
static off_t record_start_block; /* block ordinal at record_start */
last_stat_time = start_time;
}
-void
-set_volume_start_time ()
+static void
+set_volume_start_time (void)
{
gettime (&volume_start_time);
last_stat_time = volume_start_time;
{
enum compress_type type;
size_t length;
- char *magic;
- char *program;
- char *option;
+ char const *magic;
+ char const *program;
+ char const *option;
};
static struct zip_magic const magic[] = {
#define compress_program(t) magic[t].program
/* Check if the file ARCHIVE is a compressed archive. */
-enum compress_type
+static enum compress_type
check_compressed_archive (bool *pshort)
{
struct zip_magic const *p;
if (!pshort)
pshort = &temp;
-
+
/* Prepare global data needed for find_next_block: */
record_end = record_start; /* set up for 1st record = # 0 */
sfr = read_full_records;
read_full_records = true; /* Suppress fatal error on reading a partial
record */
*pshort = find_next_block () == 0;
-
+
/* Restore global values */
read_full_records = sfr;
/* Guess if the archive is seekable. */
static void
-guess_seekable_archive ()
+guess_seekable_archive (void)
{
struct stat st;
seekable_archive = !!seek_option;
return;
}
-
+
if (!multi_volume_option && !use_compress_program_option
&& fstat (archive, &st) == 0)
seekable_archive = S_ISREG (st.st_mode);
/* Open an archive named archive_name_array[0]. Detect if it is
a compressed archive of known type and use corresponding decompression
program if so */
-int
-open_compressed_archive ()
+static int
+open_compressed_archive (void)
{
archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
MODE_RW, rsh_command_option);
if (shortfile)
ERROR ((0, 0, _("This does not look like a tar archive")));
return archive;
-
+
case ct_none:
if (shortfile)
ERROR ((0, 0, _("This does not look like a tar archive")));
break;
}
}
-
+
/* FD is not needed any more */
rmtclose (archive);
-
+
hit_eof = false; /* It might have been set by find_next_block in
check_compressed_archive */
}
static void
-init_buffer ()
+init_buffer (void)
{
if (! record_buffer_aligned[record_index])
record_buffer_aligned[record_index] =
}
/* Perform a write to flush the buffer. */
-ssize_t
+static ssize_t
_flush_write (void)
{
ssize_t status;
status = record_size;
else
status = sys_write_archive_buffer ();
-
+
return status;
}
}
static bool
-archive_is_dev ()
+archive_is_dev (void)
{
struct stat st;
if (size <= skipped)
return 0;
-
+
/* Compute number of records to skip */
nrec = (size - skipped) / record_size;
if (nrec == 0)
\f
static void
-increase_volume_number ()
+increase_volume_number (void)
{
global_volno++;
if (global_volno < 0)
volno++;
}
-void
+static void
change_tape_menu (FILE *read_file)
{
char *input_buffer = NULL;
size_t size = 0;
bool stop = false;
-
+
while (!stop)
{
fputc ('\007', stderr);
assign_string (&continued_file_name, NULL);
continued_file_size = continued_file_offset = 0;
current_block = record_start;
-
+
if (rmtclose (archive) != 0)
close_error (*archive_name_cursor);
return false;
}
-bool
-try_new_volume ()
+static bool
+try_new_volume (void)
{
size_t status;
union block *header;
enum access_mode acc;
-
+
switch (subcommand_option)
{
case APPEND_SUBCOMMAND:
if (!new_volume (acc))
return true;
-
+
while ((status = rmtread (archive, record_start->buffer, record_size))
== SAFE_READ_ERROR)
archive_read_error ();
ERROR ((0, 0, _("This does not look like a tar archive")));
return false;
}
-
+
xheader_decode (&dummy); /* decodes values from the global header */
tar_stat_destroy (&dummy);
-
+
/* The initial global header must be immediately followed by
an extended PAX header for the first member in this volume.
However, in some cases tar may split volumes in the middle
HEADER_FAILURE, which is ignored.
See also tests/multiv07.at */
-
+
switch (read_header (&header, &dummy, read_header_auto))
{
case HEADER_SUCCESS:
STRINGIFY_BIGINT (real_s_totsize, totsizebuf),
STRINGIFY_BIGINT (real_s_sizeleft, s1buf),
STRINGIFY_BIGINT (continued_file_offset, s2buf)));
-
+
return false;
}
}
if (len < 1)
return NULL;
-
+
for (p = label + len - 1; p > label && isdigit ((unsigned char) *p); p--)
;
if (p > label && p - (VOLUME_TEXT_LEN - 1) > label)
return NULL;
}
-
+
/* Check LABEL against the volume label, seen as a globbing
pattern. Return true if the pattern matches. In case of failure,
retry matching a volume sequence number before giving up in
if (!volume_label)
{
union block *label = find_next_block ();
-
+
if (!label)
FATAL_ERROR ((0, 0, _("Archive not labeled to match %s"),
quote (volume_label_option)));
tar_stat_destroy (&st);
}
}
-
+
if (!volume_label)
FATAL_ERROR ((0, 0, _("Archive not labeled to match %s"),
quote (volume_label_option)));
-
+
if (!check_label_pattern (volume_label))
FATAL_ERROR ((0, 0, _("Volume %s does not match %s"),
quote_n (0, volume_label),
}
static void
-add_chunk_header ()
+add_chunk_header (void)
{
if (archive_format == POSIX_FORMAT)
{
/* Synchronize multi-volume globals */
static void
-multi_volume_sync ()
+multi_volume_sync (void)
{
if (multi_volume_option)
{
size_t status; /* result from system call */
checkpoint_run (false);
-
+
/* Clear the count of errors. This only applies to a single call to
flush_read. */
size_t status; /* result from system call */
checkpoint_run (false);
-
+
/* Clear the count of errors. This only applies to a single call to
flush_read. */
size_t copy_size;
size_t bufsize;
tarlong wrt;
-
+
status = _flush_write ();
if (status != record_size && !multi_volume_option)
archive_write_error (status);
else
{
if (status)
- records_written++;
+ records_written++;
bytes_written += status;
}
ERROR ((0, 0, _("write did not end on a block boundary")));
archive_write_error (status);
}
-
+
/* In multi-volume mode. */
/* ENXIO is for the UNIX PC. */
if (status < 0 && errno != ENOSPC && errno != EIO && errno != ENXIO)
copy_ptr = record_start->buffer + status;
copy_size = buffer_level - status;
-
+
/* Switch to the next buffer */
record_index = !record_index;
init_buffer ();
write_extended (true, &dummy, find_next_block ());
tar_stat_destroy (&dummy);
-
+
if (real_s_name)
add_chunk_header ();
wrt = bytes_written;
checkpoint_compile_action (const char *str)
{
struct checkpoint_action *act;
-
+
if (strcmp (str, ".") == 0 || strcmp (str, "dot") == 0)
alloc_action (cop_dot);
else if (strcmp (str, "bell") == 0)
{
if (!checkpoint_action)
/* Provide a historical default */
- checkpoint_compile_action ("echo");
+ checkpoint_compile_action ("echo");
}
else if (checkpoint_action)
/* Otherwise, set default checkpoint rate */
checkpoint_option = DEFAULT_CHECKPOINT;
}
-char *
+static char *
expand_checkpoint_string (const char *input, bool do_write, unsigned cpn)
{
const char *opstr = do_write ? gettext ("write") : gettext ("read");
case 'u':
outlen += cpslen - 2;
break;
-
+
case 's':
outlen += opstrlen - 2;
}
case 'u':
op = stpcpy (op, cps);
break;
-
+
case 's':
op = stpcpy (op, opstr);
break;
-
+
default:
*op++ = '%';
*op++ = *ip;
{
struct checkpoint_action *p;
FILE *tty = NULL;
-
+
for (p = checkpoint_action; p; p = p->next)
{
switch (p->opcode)
fflush (tty);
}
break;
-
+
case cop_echo:
{
char *tmp;
free (tmp);
}
break;
-
+
case cop_ttyout:
if (!tty)
tty = fopen ("/dev/tty", "w");
free (tmp);
}
break;
-
+
case cop_sleep:
sleep (p->v.time);
break;
-
+
case cop_exec:
sys_exec_checkpoint_script (p->v.command,
archive_name_cursor[0],
{
if (checkpoint_option && !(++checkpoint % checkpoint_option))
run_checkpoint_actions (do_write);
-}
-
+}
/* Common declarations for the tar program.
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
- 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
+ 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
Inc.
This program is free software; you can redistribute it and/or modify it
int matching_flags; /* wildcard flags if name is a pattern */
bool cmdline; /* true if this name was given in the
command line */
-
+
int 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 */
-
+
/* The following members are used for incremental dumps only,
if this struct name represents a directory;
see incremen.c */
const char *message);
enum exclusion_tag_type check_exclusion_tags (const char *dirname,
const char **tag_file_name);
-
+
#define GID_TO_CHARS(val, where) gid_to_chars (val, where, sizeof (where))
#define MAJOR_TO_CHARS(val, where) major_to_chars (val, where, sizeof (where))
#define MINOR_TO_CHARS(val, where) minor_to_chars (val, where, sizeof (where))
void remname (struct name *name);
bool name_match (const char *name);
void names_notfound (void);
+void label_notfound (void);
void collect_and_sort_names (void);
struct name *name_scan (const char *name);
struct name const *name_from_list (void);
/* Module exit.c */
extern void (*fatal_exit_hook) (void);
-
{
mode_t mode;
bool failed;
-
+
if (0 < same_permissions_option
&& permstatus != INTERDIR_PERMSTATUS)
{
{
case RECOVER_OK:
continue;
-
+
case RECOVER_SKIP:
return 0;
-
+
case RECOVER_NO:
open_error (file_name);
return -1;
int interdir_made = 0;
char const *link_name;
int rc;
-
+
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);
{
case RECOVER_OK:
continue;
-
+
case RECOVER_SKIP:
return 0;
-
+
case RECOVER_NO:
symlink_error (current_stat_info.link_name, file_name);
return -1;
}
-
+
set_stat (file_name, ¤t_stat_info, NULL, 0, 0, SYMTYPE);
return 0;
static int
extract_node (char *file_name, int typeflag)
{
- int status;
int interdir_made = 0;
mode_t mode = current_stat_info.stat.st_mode & ~ current_umask;
mode_t invert_permissions =
{
case RECOVER_OK:
continue;
-
+
case RECOVER_SKIP:
return 0;
-
+
case RECOVER_NO:
mknod_error (file_name);
return -1;
set_stat (file_name, ¤t_stat_info, NULL, invert_permissions,
ARCHIVED_PERMSTATUS, typeflag);
- return status;
+ return 0;
}
#endif
{
case RECOVER_OK:
continue;
-
+
case RECOVER_SKIP:
return 0;
-
+
case RECOVER_NO:
mkfifo_error (file_name);
return -1;
tar_extractor_t fun;
fatal_exit_hook = extract_finish;
-
+
/* Try to disable the ability to unlink a directory. */
priv_set_remove_linkdir ();
size_t i, total, ctsize, len;
char *p;
const char *q;
-
+
for (i = 0, total = 0, ctsize = 1, q = contents; *q; total++, q += len)
{
len = strlen (q) + 1;
struct dumpdir_iter
{
struct dumpdir *dump; /* Dumpdir being iterated */
- int all; /* Iterate over all entries, not only D/N/Y */
+ int all; /* Iterate over all entries, not only D/N/Y */
size_t next; /* Index of the next element */
};
{
size_t cur = itr->next;
char *ret = NULL;
-
+
if (itr->all)
{
ret = itr->dump->contents + cur;
dirtail = dir;
return dir;
}
-
+
\f
-void
+static void
dirlist_replace_prefix (const char *pref, const char *repl)
{
struct directory *dp;
struct stat st;
if (deref_stat (dereference_option, p, &st) != 0)
{
- if (errno != ENOENT)
+ if (errno != ENOENT)
stat_diag (directory->name);
/* else: should have been already reported */
}
*entry = 'N';
return directory;
}
-
+
/* With NFS, the same file can have two different devices
if an NFS directory is mounted in multiple locations,
which is relatively common when automounting.
To avoid spurious incremental redumping of
directories, consider all NFS devices as equal,
relying on the i-node to establish differences. */
-
+
if (! ((!check_device_option
|| (DIR_IS_NFS (directory) && nfs)
|| directory->device_number == stat_data->st_dev)
}
else
directory->children = CHANGED_CHILDREN;
-
+
DIR_SET_FLAG (directory, DIRF_FOUND);
}
else
{
struct directory *d = find_directory_meta (stat_data->st_dev,
stat_data->st_ino);
-
+
directory = note_directory (name_buffer,
get_stat_mtime(stat_data),
stat_data->st_dev,
if (one_file_system_option && device != stat_data->st_dev
/* ... except if it was explicitely given in the command line */
&& !is_individual_file (name_buffer))
- /* FIXME:
+ /* FIXME:
WARNOPT (WARN_XDEV,
(0, 0,
_("%s: directory is on a different filesystem; not dumped"),
if (directory->children == NO_CHILDREN)
*entry = 'N';
}
-
+
DIR_SET_FLAG (directory, DIRF_INIT);
if (directory->children != NO_CHILDREN)
_("contents not dumped"));
directory->children = NO_CHILDREN;
break;
-
+
case exclusion_tag_under:
exclusion_tag_warning (name_buffer, tag_file_name,
_("contents not dumped"));
directory->tagfile = tag_file_name;
break;
-
+
case exclusion_tag_none:
break;
}
DIRECTORY->dump is replaced with the created template. Each entry is
prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */
-void
+static void
makedumpdir (struct directory *directory, const char *dir)
{
size_t i,
struct stat stat_data;
struct directory *directory;
char ch;
-
+
if (! dirp)
savedir_error (dir);
tmp = xstrdup (dir);
zap_slashes (tmp);
-
+
if (deref_stat (dereference_option, tmp, &stat_data))
{
dir_removed_diag (tmp, cmdline, stat_diag);
directory = procdir (tmp, &stat_data, device,
(cmdline ? PD_FORCE_INIT : 0),
&ch);
-
+
free (tmp);
nbuf = namebuf_create (dir);
\f
static void
-obstack_code_rename (struct obstack *stk, char *from, char *to)
+obstack_code_rename (struct obstack *stk, char const *from, char const *to)
{
- char *s;
+ char const *s;
s = from[0] == 0 ? from :
safer_name_suffix (from, false, absolute_names_option);
size_t size;
struct directory *dp;
const char *dump;
-
+
if (dirhead == NULL)
return;
/* Read incremental snapshot format 2 */
static void
-read_incr_db_2 ()
+read_incr_db_2 (void)
{
uintmax_t u;
struct obstack stk;
which is necessary to recreate absolute file names. */
name_from_list ();
blank_name_list ();
-
+
if (0 < getline (&buf, &bufsize, listed_incremental_stream))
{
char *ebuf;
if (DIR_IS_FOUND (directory))
{
char buf[UINTMAX_STRSIZE_BOUND];
- char *s;
+ char const *s;
s = DIR_IS_NFS (directory) ? "1" : "0";
fwrite (s, 2, 1, fp);
}
free (p);
dumpdir_free (dump);
-
+
free (current_dir);
return true;
}
prev_status = status;
tar_stat_destroy (¤t_stat_info);
- status = read_header (¤t_header, ¤t_stat_info,
+ status = read_header (¤t_header, ¤t_stat_info,
read_header_auto);
switch (status)
{
{
char buf[UINTMAX_STRSIZE_BOUND];
- status = read_header (¤t_header, ¤t_stat_info,
+ status = read_header (¤t_header, ¤t_stat_info,
read_header_auto);
if (status == HEADER_ZERO_BLOCK)
break;
off_t block_ordinal = current_block_ordinal ();
/* Print the header block. */
-
+
decode_header (current_header, ¤t_stat_info, ¤t_format, 0);
if (verbose_option)
print_header (¤t_stat_info, current_header, block_ordinal);
links subject to filename transformation. In the absence of another
solution, symbolic links are exempt from component stripping and
name suffix normalization, but subject to filename transformation
- proper. */
+ proper. */
return file_name;
-
+
case XFORM_LINK:
file_name = safer_name_suffix (file_name, true, absolute_names_option);
break;
-
+
case XFORM_REGFILE:
file_name = safer_name_suffix (file_name, false, absolute_names_option);
break;
}
-
+
if (strip_name_components)
{
size_t prefix_len = stripped_prefix_len (file_name,
enum archive_format format;
unsigned hbits; /* high bits of the file mode. */
mode_t mode = MODE_FROM_HEADER (header->header.mode, &hbits);
-
+
if (strcmp (header->header.magic, TMAGIC) == 0)
{
if (header->star_header.prefix[130] == 0
case SYMTYPE:
transform_member_name (&stat_info->link_name, XFORM_SYMLINK);
break;
-
+
case LNKTYPE:
transform_member_name (&stat_info->link_name, XFORM_LINK);
}
}
-void
-print_volume_label ()
+static void
+print_volume_label (void)
{
struct tar_stat_info vstat;
union block vblk;
¤t_stat_info, ¤t_format, 0);
if (current_header->header.typeflag == GNUTYPE_VOLHDR)
assign_string (&volume_label, current_header->header.name);
-
+
if (volume_label)
{
if (verbose_option)
}
/* Normalize NAME by resolving any relative references and
- removing trailing slashes. Destructive version: modifies its argument. */
-int
+ removing trailing slashes. Destructive version: modifies its argument. */
+static int
normalize_filename_x (char *name)
{
char *p, *q;
/* Remove trailing slashes */
while (p - 1 > name && ISSLASH (p[-1]))
p--;
-
+
*p = 0;
return 0;
}
/* ignore invalid values of ns */
if (BILLION <= ns || ns < 0)
ns = 0;
-
+
if (negative && ns != 0)
{
s++;
(0, 0, _("%s: File removed before we read it"),
quotearg_colon (name)));
set_exit_status (TAREXIT_DIFFERS);
- }
+ }
else
diagfn (name);
}
strcpy (buf->buffer + buf->dir_length, name);
return buf->buffer;
}
-
\f
/* User and group names. */
-struct group *getgrnam ();
-struct passwd *getpwnam ();
-#if ! HAVE_DECL_GETPWUID
-struct passwd *getpwuid ();
-#endif
-#if ! HAVE_DECL_GETGRGID
-struct group *getgrgid ();
-#endif
-
/* Make sure you link with the proper libraries if you are running the
Yellow Peril (thanks for the good laugh, Ian J.!), or, euh... NIS.
This code should also be modified for non-UNIX systems to do something
}
\f
-struct name *
+static struct name *
make_name (const char *file_name)
{
struct name *p = xzalloc (sizeof (*p));
return p;
}
-void
+static void
free_name (struct name *p)
{
if (p)
static struct name *namelist; /* first name in list, if any */
static struct name *nametail; /* end of name list */
-/* File name arguments are processed in two stages: first a
+/* File name arguments are processed in two stages: first a
name_array (see below) is filled, then the names from it
are moved into the namelist.
which is meant to help process large archives on machines with
limited memory. With this option on, namelist contains at most one
entry, which diminishes the memory consumption.
-
+
However, I very much doubt if we still need this -- Sergey */
/* A name_array element contains entries of three types: */
union
{
const char *name; /* File or directory name */
- int matching_flags;/* fnmatch options if type == NELT_FMASK */
+ int matching_flags;/* fnmatch options if type == NELT_FMASK */
} v;
};
/* Check the size of name_array, reallocating it as necessary. */
static void
-check_name_alloc ()
+check_name_alloc (void)
{
if (names == allocated_names)
{
ep = &name_array[names++];
ep->type = NELT_CHDIR;
ep->v.name = name;
-}
+}
\f
/* Names from external name file. */
If CHANGE_DIRS is true, treat any entries of type NELT_CHDIR as
the request to change to the given directory.
-
+
Entries of type NELT_FMASK cause updates of the matching_flags
value. */
-struct name_elt *
+static struct name_elt *
name_next_elt (int change_dirs)
{
static struct name_elt entry;
{
struct name_elt *ep;
size_t source_len;
-
+
ep = &name_array[name_index++];
if (ep->type == NELT_FMASK)
{
matching_flags = ep->v.matching_flags;
continue;
}
-
+
source = ep->v.name;
source_len = strlen (source);
if (name_buffer_length < source_len)
buffer->directory = NULL;
buffer->parent = NULL;
buffer->cmdline = true;
-
+
namelist = nametail = buffer;
}
else if (change_dir)
if (!cursor)
return true;
-
+
if (cursor->name[0] == 0)
{
chdir_do (cursor->change_dir);
if (!WASFOUND (cursor) && cursor->name[0])
{
regex_usage_warning (cursor->name);
- ERROR ((0, 0,
+ ERROR ((0, 0,
(cursor->found_count == 0) ?
_("%s: Not found in archive") :
_("%s: Required occurrence not found in archive"),
if (!namelist)
return;
-
+
for (cursor = namelist; cursor; cursor = cursor->next)
if (WASFOUND (cursor))
return;
/* Sort *singly* linked LIST of names, of given LENGTH, using COMPARE
to order names. Return the sorted list. Note that after calling
this function, the `prev' links in list elements are messed up.
-
+
Apart from the type `struct name' and the definition of SUCCESSOR,
this is a generic list-sorting function, but it's too painful to
make it both generic and portable
add_hierarchy_to_namelist (struct name *name, dev_t device, bool cmdline)
{
const char *buffer;
-
+
name_fill_directory (name, device, cmdline);
buffer = directory_contents (name->directory);
if (buffer)
size_t old_prefix_len = child->parent->length;
size_t new_prefix_len = parent->length;
char *new_prefix = parent->name;
-
+
for (; child; child = child->sibling)
{
size_t size = child->length - old_prefix_len + new_prefix_len;
child->length = size;
rebase_directory (child->directory,
- child->parent->name, old_prefix_len,
+ child->parent->name, old_prefix_len,
new_prefix, new_prefix_len);
}
}
int num_names;
struct stat statbuf;
Hash_table *nametab;
-
+
name_gather ();
if (!namelist)
read_directory_file ();
}
-
+
num_names = 0;
for (name = namelist; name; name = name->next, num_names++)
{
register_individual_file (char const *name)
{
struct stat st;
-
+
if (deref_stat (dereference_option, name, &st) != 0)
return; /* Will be complained about later */
if (S_ISDIR (st.st_mode))
return;
-
+
hash_string_insert (&individual_file_table, name);
}
return false;
st->archive_file_size = 0;
-
+
if (!tar_sparse_scan (file, scan_begin, NULL))
return false;
return false;
size_left = file->stat_info->sparse_map[i].numbytes;
mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
-
+
while (size_left > 0)
{
size_t bytes_read;
file.stat_info = st;
file.fd = fd;
file.seekable = true; /* File *must* be seekable for compare to work */
-
+
rc = tar_sparse_decode_header (&file);
mv_begin (st);
for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++)
if (!rc)
skip_file (file.stat_info->archive_file_size - file.dumped_size);
mv_end ();
-
+
tar_sparse_done (&file);
return rc;
}
instances of GNU.sparse.offset/GNU.sparse.numbytes variables, whereas
POSIX requires the latest occurrence of the variable to override all
previous occurrences.
-
+
To avoid this incompatibility two following versions were introduced.
* 0.1
Used by tar 1.15.2 -- 1.15.91 (alpha releases).
-
+
The sparse file map is stored in
x header:
Starting from this version, the exact sparse format version is specified
explicitely in the header using the following variables:
- GNU.sparse.major Major version
+ GNU.sparse.major Major version
GNU.sparse.minor Minor version
X header keeps the following variables:
-
+
GNU.sparse.name Real file name of the sparse file
GNU.sparse.realsize Real size of the stored file (corresponds to the old
GNU.sparse.size variable)
The name field of the ustar header is constructed using the pattern
"%d/GNUSparseFile.%p/%f".
-
+
The sparse map itself is stored in the file data block, preceding the actual
file data. It consists of a series of octal numbers of arbitrary length,
delimited by newlines. The map is padded with nulls to the nearest block
char nbuf[UINTMAX_STRSIZE_BOUND];
struct sp_array *map = file->stat_info->sparse_map;
char *save_file_name = NULL;
-
+
/* Store the real file size */
xheader_store ("GNU.sparse.size", file->stat_info, NULL);
xheader_store ("GNU.sparse.numblocks", file->stat_info, NULL);
-
+
if (xheader_keyword_deleted_p ("GNU.sparse.map")
|| tar_sparse_minor == 0)
{
#define COPY_STRING(b,dst,src) do \
{ \
char *endp = b->buffer + BLOCKSIZE; \
- char *srcp = src; \
+ char const *srcp = src; \
while (*srcp) \
{ \
if (dst == endp) \
} \
*dst++ = *srcp++; \
} \
- } while (0)
+ } while (0)
/* Compute stored file size */
p = umaxtostr (file->stat_info->sparse_map_avail, nbuf);
size = (size + BLOCKSIZE - 1) / BLOCKSIZE;
file->stat_info->archive_file_size += size * BLOCKSIZE;
file->dumped_size += size * BLOCKSIZE;
-
+
/* Store sparse file identification */
xheader_store ("GNU.sparse.major", file->stat_info, NULL);
xheader_store ("GNU.sparse.minor", file->stat_info, NULL);
xheader_store ("GNU.sparse.name", file->stat_info, NULL);
xheader_store ("GNU.sparse.realsize", file->stat_info, NULL);
-
+
file->stat_info->file_name = xheader_format_name (file->stat_info,
"%d/GNUSparseFile.%p/%f", 0);
if (!ISDIGIT (*arg))
return false;
-
+
u = strtoumax (arg, &arg_lim, 10);
if (! (u <= maxval && errno != ERANGE) || *arg_lim)
return false;
-
+
*num = u;
return true;
}
} \
while (*dst++ != '\n'); \
dst[-1] = 0; \
- } while (0)
+ } while (0)
set_next_block_after (current_header);
file->dumped_size += BLOCKSIZE;
COPY_BUF (blk,nbuf,p);
if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size_t)))
{
- ERROR ((0, 0, _("%s: malformed sparse archive member"),
+ ERROR ((0, 0, _("%s: malformed sparse archive member"),
file->stat_info->orig_file_name));
return false;
}
for (i = 0; i < file->stat_info->sparse_map_size; i++)
{
struct sp_array sp;
-
+
COPY_BUF (blk,nbuf,p);
if (!decode_num (&u, nbuf, TYPE_MAXIMUM (off_t)))
{
- ERROR ((0, 0, _("%s: malformed sparse archive member"),
+ ERROR ((0, 0, _("%s: malformed sparse archive member"),
file->stat_info->orig_file_name));
return false;
}
COPY_BUF (blk,nbuf,p);
if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size_t)))
{
- ERROR ((0, 0, _("%s: malformed sparse archive member"),
+ ERROR ((0, 0, _("%s: malformed sparse archive member"),
file->stat_info->orig_file_name));
return false;
}
}
set_next_block_after (blk);
}
-
+
return true;
}
pax_sparse_member_p,
pax_dump_header,
NULL,
- pax_decode_header,
+ pax_decode_header,
NULL, /* No scan_block function */
sparse_dump_region,
sparse_extract_region,
{
int wait_status;
int exit_code = 0;
-
+
while (waitpid (pid, &wait_status, 0) == -1)
if (errno != EINTR)
{
raise (WTERMSIG (wait_status));
else if (WEXITSTATUS (wait_status) != 0)
exit_code = WEXITSTATUS (wait_status);
-
+
exit (exit_code);
}
set_program_name (_("tar (child)"));
signal (SIGPIPE, SIG_DFL);
-
+
xdup2 (parent_pipe[PREAD], STDIN_FILENO);
xclose (parent_pipe[PWRITE]);
set_program_name (_("tar (child)"));
signal (SIGPIPE, SIG_DFL);
-
+
xdup2 (parent_pipe[PWRITE], STDOUT_FILENO);
xclose (parent_pipe[PREAD]);
\f
static void
-dec_to_env (char *envar, uintmax_t num)
+dec_to_env (char const *envar, uintmax_t num)
{
char buf[UINTMAX_STRSIZE_BOUND];
char *numstr;
}
static void
-time_to_env (char *envar, struct timespec t)
+time_to_env (char const *envar, struct timespec t)
{
char buf[TIMESPEC_STRSIZE_BOUND];
if (setenv (envar, code_timespec (t, buf), 1) != 0)
}
static void
-oct_to_env (char *envar, unsigned long num)
+oct_to_env (char const *envar, unsigned long num)
{
char buf[1+1+(sizeof(unsigned long)*CHAR_BIT+2)/3];
}
static void
-str_to_env (char *envar, char const *str)
+str_to_env (char const *envar, char const *str)
{
if (str)
{
}
static void
-chr_to_env (char *envar, char c)
+chr_to_env (char const *envar, char c)
{
char buf[2];
buf[0] = c;
char uintbuf[UINTMAX_STRSIZE_BOUND];
int p[2];
static RETSIGTYPE (*saved_handler) (int sig);
-
+
xpipe (p);
saved_handler = signal (SIGPIPE, SIG_IGN);
}
signal (SIGPIPE, saved_handler);
-
+
if (WIFEXITED (status))
{
if (WEXITSTATUS (status) == 0 && rc > 0)
argv[0] = "/bin/sh";
argv[1] = "-c";
- argv[2] = (char*) info_script_option;
+ argv[2] = (char *) info_script_option;
argv[3] = NULL;
execv (argv[0], argv);
archive_format : current_format), 1);
argv[0] = "/bin/sh";
argv[1] = "-c";
- argv[2] = (char*) script_name;
+ argv[2] = (char *) script_name;
argv[3] = NULL;
execv (argv[0], argv);
abort ();
}
-void
-tar_list_quoting_styles (struct obstack *stk, char *prefix)
+static void
+tar_list_quoting_styles (struct obstack *stk, char const *prefix)
{
int i;
size_t prefixlen = strlen (prefix);
-
+
for (i = 0; quoting_style_args[i]; i++)
{
obstack_grow (stk, prefix, prefixlen);
}
}
-void
+static void
tar_set_quoting_style (char *arg)
{
int i;
UNQUOTE_OPTION,
UTC_OPTION,
VOLNO_FILE_OPTION,
- WARNING_OPTION,
+ WARNING_OPTION,
WILDCARDS_MATCH_SLASH_OPTION,
WILDCARDS_OPTION
};
{"lzop", LZOP_OPTION, 0, 0, NULL, GRID+1 },
{"xz", 'J', 0, 0, NULL, GRID+1 },
#undef GRID
-
+
#define GRID 100
{NULL, 0, NULL, 0,
N_("Local file selection:"), GRID },
NULL
};
-void
+static void
add_exclude_array (char const * const * fv)
{
int i;
" --rsh-command=%s"
#endif
,
- archive_format_string (DEFAULT_ARCHIVE_FORMAT),
- DEFAULT_ARCHIVE, DEFAULT_BLOCKING,
+ archive_format_string (DEFAULT_ARCHIVE_FORMAT),
+ DEFAULT_ARCHIVE, DEFAULT_BLOCKING,
quoting_style_args[DEFAULT_QUOTING_STYLE],
DEFAULT_RMT_COMMAND
#ifdef REMOTE_SHELL
&& subcommand_option != subcommand)
USAGE_ERROR ((0, 0,
_("You may not specify more than one `-Acdtrux' or `--test-label' option")));
-
+
subcommand_option = subcommand;
}
if (use_compress_program_option
&& strcmp (use_compress_program_option, string) != 0)
USAGE_ERROR ((0, 0, _("Conflicting compression options")));
-
+
use_compress_program_option = string;
}
\f
#endif
}
-void
+static void
set_stat_signal (const char *name)
{
static struct sigtab
{
- char *name;
+ char const *name;
int signo;
- } sigtab[] = {
+ } const sigtab[] = {
{ "SIGUSR1", SIGUSR1 },
{ "USR1", SIGUSR1 },
{ "SIGUSR2", SIGUSR2 },
{ "SIGQUIT", SIGQUIT },
{ "QUIT", SIGQUIT }
};
- struct sigtab *p;
+ struct sigtab const *p;
for (p = sigtab; p < sigtab + sizeof (sigtab) / sizeof (sigtab[0]); p++)
if (strcmp (p->name, name) == 0)
obstack_1grow (stk, c);
counter++;
}
-
+
if (counter == 0 && c != EOF)
return file_list_skip;
bool is_stdin = false;
enum read_file_list_state read_state;
int term = filename_terminator;
-
+
if (!strcmp (filename, "-"))
{
is_stdin = true;
if ((fp = fopen (filename, "r")) == NULL)
open_fatal (filename);
}
-
+
while ((read_state = read_name_from_file (fp, &argv_stk, term))
!= file_list_end)
{
case file_list_success:
count++;
break;
-
+
case file_list_end: /* won't happen, just to pacify gcc */
break;
-
+
case file_list_zero:
{
size_t size;
-
+
WARNOPT (WARN_FILENAME_WITH_NULS,
(0, 0, N_("%s: file name read contains nul character"),
quotearg_colon (filename)));
-
+
/* Prepare new stack contents */
size = obstack_object_size (&argv_stk);
p = obstack_finish (&argv_stk);
term = 0;
break;
}
-
+
case file_list_skip:
break;
}
}
-
+
if (!is_stdin)
fclose (fp);
-
+
if (count == 0)
return;
-
+
start = obstack_finish (&argv_stk);
-
+
if (term == 0)
for (p = start; *p; p += strlen (p) + 1)
if (p[0] == '-')
count++;
-
+
new_argc = state->argc + count;
new_argv = xmalloc (sizeof (state->argv[0]) * (new_argc + 1));
memcpy (new_argv, state->argv, sizeof (state->argv[0]) * (state->argc + 1));
state->argv = new_argv;
memmove (&state->argv[state->next + count], &state->argv[state->next],
(state->argc - state->next + 1) * sizeof (state->argv[0]));
-
+
state->argc = new_argc;
-
+
for (i = state->next, p = start; *p; p += strlen (p) + 1, i++)
{
if (term == 0 && p[0] == '-')
{
struct obstack stk;
char *s;
-
+
switch (key)
{
default:
s = (char*) text;
break;
-
+
case 'j':
s = xasprintf (_("filter the archive through %s"), BZIP2_PROGRAM);
break;
-
+
case 'z':
s = xasprintf (_("filter the archive through %s"), GZIP_PROGRAM);
break;
-
+
case 'Z':
s = xasprintf (_("filter the archive through %s"), COMPRESS_PROGRAM);
break;
case LZIP_OPTION:
s = xasprintf (_("filter the archive through %s"), LZIP_PROGRAM);
break;
-
+
case LZMA_OPTION:
s = xasprintf (_("filter the archive through %s"), LZMA_PROGRAM);
break;
-
+
case 'J':
s = xasprintf (_("filter the archive through %s"), XZ_PROGRAM);
break;
-
+
case ARGP_KEY_HELP_EXTRA:
{
const char *tstr;
{
struct obstack stk;
char *res;
-
+
obstack_init (&stk);
while (*arg)
{
name_add_name (arg, MAKE_INCL_OPTIONS (args));
args->input_files = true;
break;
-
+
case 'A':
set_subcommand_option (CAT_SUBCOMMAND);
break;
-
+
case 'a':
args->compress_autodetect = true;
break;
-
+
case NO_AUTO_COMPRESS_OPTION:
args->compress_autodetect = false;
break;
-
+
case 'b':
{
uintmax_t u;
_("Invalid blocking factor")));
}
break;
-
+
case 'B':
/* Try to reblock input records. For reading 4.2BSD pipes. */
-
+
/* It would surely make sense to exchange -B and -R, but it seems
that -B has been used for a long while in Sun tar and most
BSD-derived systems. This is a consequence of the block/record
terminology confusion. */
-
+
read_full_records_option = true;
break;
-
+
case 'c':
set_subcommand_option (CREATE_SUBCOMMAND);
break;
-
+
case 'C':
name_add_dir (arg);
break;
-
+
case 'd':
set_subcommand_option (DIFF_SUBCOMMAND);
break;
-
+
case 'f':
if (archive_names == allocated_archive_names)
archive_name_array = x2nrealloc (archive_name_array,
&allocated_archive_names,
sizeof (archive_name_array[0]));
-
+
archive_name_array[archive_names++] = arg;
break;
-
+
case 'F':
/* Since -F is only useful with -M, make it implied. Run this
script at the end of each tape. */
-
+
info_script_option = arg;
multi_volume_option = true;
break;
case FULL_TIME_OPTION:
full_time_option = true;
break;
-
+
case 'g':
listed_incremental_option = arg;
after_date_option = true;
/* Fall through. */
-
+
case 'G':
/* We are making an incremental dump (FIXME: are we?); save
directories at the beginning of the archive, and include in each
directory its contents. */
-
+
incremental_option = true;
break;
-
+
case 'h':
/* Follow symbolic links. */
dereference_option = true;
break;
-
+
case HARD_DEREFERENCE_OPTION:
hard_dereference_option = true;
break;
-
+
case 'i':
/* Ignore zero blocks (eofs). This can't be the default,
because Unix tar writes two blocks of zeros, then pads out
the record with garbage. */
-
+
ignore_zeros_option = true;
break;
-
+
case 'j':
set_use_compress_program_option (BZIP2_PROGRAM);
break;
-
+
case 'J':
set_use_compress_program_option (XZ_PROGRAM);
break;
-
+
case 'k':
/* Don't replace existing files. */
old_files_option = KEEP_OLD_FILES;
break;
-
+
case 'K':
starting_file_option = true;
addname (arg, 0, true, NULL);
break;
-
+
case ONE_FILE_SYSTEM_OPTION:
/* When dumping directories, don't dump files/subdirectories
that are on other filesystems. */
one_file_system_option = true;
break;
-
+
case 'l':
check_links_option = 1;
break;
-
+
case 'L':
{
uintmax_t u;
multi_volume_option = true;
}
break;
-
+
case LEVEL_OPTION:
{
char *p;
USAGE_ERROR ((0, 0, _("Invalid incremental level value")));
}
break;
-
+
case LZIP_OPTION:
set_use_compress_program_option (LZIP_PROGRAM);
break;
-
+
case LZMA_OPTION:
set_use_compress_program_option (LZMA_PROGRAM);
break;
-
+
case LZOP_OPTION:
set_use_compress_program_option (LZOP_PROGRAM);
break;
-
+
case 'm':
touch_option = true;
break;
-
+
case 'M':
/* Make multivolume archive: when we can't write any more into
the archive, re-open it, and continue writing. */
-
+
multi_volume_option = true;
break;
-
+
case MTIME_OPTION:
get_date_or_file (args, "--mtime", arg, &mtime_option);
set_mtime_option = true;
break;
-
+
case 'n':
seek_option = 1;
break;
-
+
case NO_SEEK_OPTION:
seek_option = 0;
break;
-
+
case 'N':
after_date_option = true;
/* Fall through. */
-
+
case NEWER_MTIME_OPTION:
if (NEWER_OPTION_INITIALIZED (newer_mtime_option))
USAGE_ERROR ((0, 0, _("More than one threshold date")));
key == NEWER_MTIME_OPTION ? "--newer-mtime"
: "--after-date", arg, &newer_mtime_option);
break;
-
+
case 'o':
args->o_option = true;
break;
-
+
case 'O':
to_stdout_option = true;
break;
-
+
case 'p':
same_permissions_option = true;
break;
-
+
case 'P':
absolute_names_option = true;
break;
-
+
case 'r':
set_subcommand_option (APPEND_SUBCOMMAND);
break;
-
+
case 'R':
/* Print block numbers for debugging bad tar archives. */
-
+
/* It would surely make sense to exchange -B and -R, but it seems
that -B has been used for a long while in Sun tar and most
BSD-derived systems. This is a consequence of the block/record
terminology confusion. */
-
+
block_number_option = true;
break;
-
+
case 's':
/* Names to extract are sorted. */
-
+
same_order_option = true;
break;
-
+
case 'S':
sparse_option = true;
break;
-
+
case SPARSE_VERSION_OPTION:
sparse_option = true;
{
}
}
break;
-
+
case 't':
set_subcommand_option (LIST_SUBCOMMAND);
verbose_option++;
break;
-
+
case TEST_LABEL_OPTION:
set_subcommand_option (TEST_LABEL_SUBCOMMAND);
break;
-
+
case 'T':
update_argv (arg, state);
/* Indicate we've been given -T option. This is for backward
succeed */
files_from_option = true;
break;
-
+
case 'u':
set_subcommand_option (UPDATE_SUBCOMMAND);
break;
-
+
case 'U':
old_files_option = UNLINK_FIRST_OLD_FILES;
break;
-
+
case UTC_OPTION:
utc_option = true;
break;
-
+
case 'v':
verbose_option++;
warning_option |= WARN_VERBOSE_WARNINGS;
break;
-
+
case 'V':
volume_label_option = arg;
break;
-
+
case 'w':
interactive_option = true;
break;
-
+
case 'W':
verify_option = true;
break;
-
+
case 'x':
set_subcommand_option (EXTRACT_SUBCOMMAND);
break;
-
+
case 'X':
if (add_exclude_file (add_exclude, excluded, arg,
MAKE_EXCL_OPTIONS (args), '\n')
FATAL_ERROR ((0, e, "%s", quotearg_colon (arg)));
}
break;
-
+
case 'z':
set_use_compress_program_option (GZIP_PROGRAM);
break;
-
+
case 'Z':
set_use_compress_program_option (COMPRESS_PROGRAM);
break;
-
+
case ANCHORED_OPTION:
args->matching_flags |= EXCLUDE_ANCHORED;
break;
-
+
case ATIME_PRESERVE_OPTION:
atime_preserve_option =
(arg
_("--atime-preserve='system' is not supported"
" on this platform")));
break;
-
+
case CHECK_DEVICE_OPTION:
check_device_option = true;
break;
-
+
case NO_CHECK_DEVICE_OPTION:
check_device_option = false;
break;
-
+
case CHECKPOINT_OPTION:
if (arg)
{
char *p;
-
+
if (*arg == '.')
{
checkpoint_compile_action (".");
else
checkpoint_option = DEFAULT_CHECKPOINT;
break;
-
+
case CHECKPOINT_ACTION_OPTION:
checkpoint_compile_action (arg);
break;
-
+
case BACKUP_OPTION:
backup_option = true;
if (arg)
args->version_control_string = arg;
break;
-
+
case DELAY_DIRECTORY_RESTORE_OPTION:
delay_directory_restore_option = true;
break;
-
+
case NO_DELAY_DIRECTORY_RESTORE_OPTION:
delay_directory_restore_option = false;
break;
-
+
case DELETE_OPTION:
set_subcommand_option (DELETE_SUBCOMMAND);
break;
-
+
case EXCLUDE_BACKUPS_OPTION:
add_exclude_array (backup_file_table);
break;
-
+
case EXCLUDE_OPTION:
add_exclude (excluded, arg, MAKE_EXCL_OPTIONS (args));
break;
-
+
case EXCLUDE_CACHES_OPTION:
add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_contents,
cachedir_file_p);
break;
-
+
case EXCLUDE_CACHES_UNDER_OPTION:
add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_under,
cachedir_file_p);
break;
-
+
case EXCLUDE_CACHES_ALL_OPTION:
add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_all,
cachedir_file_p);
break;
-
+
case EXCLUDE_TAG_OPTION:
add_exclusion_tag (arg, exclusion_tag_contents, NULL);
break;
-
+
case EXCLUDE_TAG_UNDER_OPTION:
add_exclusion_tag (arg, exclusion_tag_under, NULL);
break;
-
+
case EXCLUDE_TAG_ALL_OPTION:
add_exclusion_tag (arg, exclusion_tag_all, NULL);
break;
-
+
case EXCLUDE_VCS_OPTION:
add_exclude_array (vcs_file_table);
break;
-
+
case FORCE_LOCAL_OPTION:
force_local_option = true;
break;
-
+
case 'H':
set_archive_format (arg);
break;
-
+
case INDEX_FILE_OPTION:
index_file_name = arg;
break;
-
+
case IGNORE_CASE_OPTION:
args->matching_flags |= FNM_CASEFOLD;
break;
-
+
case IGNORE_COMMAND_ERROR_OPTION:
ignore_command_error_option = true;
break;
-
+
case IGNORE_FAILED_READ_OPTION:
ignore_failed_read_option = true;
break;
-
+
case KEEP_NEWER_FILES_OPTION:
old_files_option = KEEP_NEWER_FILES;
break;
-
+
case GROUP_OPTION:
if (! (strlen (arg) < GNAME_FIELD_SIZE
&& gname_to_gid (arg, &group_option)))
_("Invalid group")));
}
break;
-
+
case MODE_OPTION:
mode_option = mode_compile (arg);
if (!mode_option)
initial_umask = umask (0);
umask (initial_umask);
break;
-
+
case NO_ANCHORED_OPTION:
args->include_anchored = 0; /* Clear the default for comman line args */
args->matching_flags &= ~ EXCLUDE_ANCHORED;
break;
-
+
case NO_IGNORE_CASE_OPTION:
args->matching_flags &= ~ FNM_CASEFOLD;
break;
-
+
case NO_IGNORE_COMMAND_ERROR_OPTION:
ignore_command_error_option = false;
break;
-
+
case NO_OVERWRITE_DIR_OPTION:
old_files_option = NO_OVERWRITE_DIR_OLD_FILES;
break;
-
+
case NO_QUOTE_CHARS_OPTION:
for (;*arg; arg++)
set_char_quoting (NULL, *arg, 0);
break;
-
+
case NO_WILDCARDS_OPTION:
args->wildcards = disable_wildcards;
break;
-
+
case NO_WILDCARDS_MATCH_SLASH_OPTION:
args->matching_flags |= FNM_FILE_NAME;
break;
-
+
case NULL_OPTION:
filename_terminator = '\0';
break;
-
+
case NO_NULL_OPTION:
filename_terminator = '\n';
break;
-
+
case NUMERIC_OWNER_OPTION:
numeric_owner_option = true;
break;
-
+
case OCCURRENCE_OPTION:
if (!arg)
occurrence_option = 1;
_("Invalid number")));
}
break;
-
+
case OVERWRITE_DIR_OPTION:
old_files_option = DEFAULT_OLD_FILES;
break;
-
+
case OVERWRITE_OPTION:
old_files_option = OVERWRITE_OLD_FILES;
break;
-
+
case OWNER_OPTION:
if (! (strlen (arg) < UNAME_FIELD_SIZE
&& uname_to_uid (arg, &owner_option)))
_("Invalid owner")));
}
break;
-
+
case QUOTE_CHARS_OPTION:
for (;*arg; arg++)
set_char_quoting (NULL, *arg, 1);
break;
-
+
case QUOTING_STYLE_OPTION:
tar_set_quoting_style (arg);
break;
-
+
case PAX_OPTION:
{
char *tmp = expand_pax_option (args, arg);
free (tmp);
}
break;
-
+
case POSIX_OPTION:
set_archive_format ("posix");
break;
-
+
case PRESERVE_OPTION:
/* FIXME: What it is good for? */
same_permissions_option = true;
WARN ((0, 0, _("The --preserve option is deprecated, "
"use --preserve-permissions --preserve-order instead")));
break;
-
+
case RECORD_SIZE_OPTION:
{
uintmax_t u;
blocking_factor = record_size / BLOCKSIZE;
}
break;
-
+
case RECURSIVE_UNLINK_OPTION:
recursive_unlink_option = true;
break;
-
+
case REMOVE_FILES_OPTION:
remove_files_option = true;
break;
-
+
case RESTRICT_OPTION:
restrict_option = true;
break;
-
+
case RMT_COMMAND_OPTION:
rmt_command = arg;
break;
-
+
case RSH_COMMAND_OPTION:
rsh_command_option = arg;
break;
-
+
case SHOW_DEFAULTS_OPTION:
{
char *s = format_default_settings ();
free (s);
exit (0);
}
-
+
case STRIP_COMPONENTS_OPTION:
{
uintmax_t u;
case WARNING_OPTION:
set_warning_option (arg);
break;
-
+
case '0':
case '1':
case '2':
struct tar_args args;
argp_version_setup ("tar", tar_authors);
-
+
/* Set some default option values. */
args.textual_date = NULL;
args.wildcards = default_wildcards;
args.version_control_string = 0;
args.input_files = false;
args.compress_autodetect = false;
-
+
subcommand_option = UNKNOWN_SUBCOMMAND;
archive_format = DEFAULT_FORMAT;
blocking_factor = DEFAULT_BLOCKING;
incremental_level = -1;
seek_option = -1;
-
+
/* Convert old-style tar call by exploding option element and rearranging
options accordingly. */
if (incremental_level != -1 && !listed_incremental_option)
WARN ((0, 0,
_("--level is meaningless without --listed-incremental")));
-
+
if (volume_label_option)
{
if (archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
if (same_order_option && listed_incremental_option)
USAGE_ERROR ((0, 0, _("--preserve-order is not compatible with "
"--listed-incremental")));
-
+
/* Forbid using -c with no input files whatsoever. Check that `-f -',
explicit or implied, is used correctly. */
}
checkpoint_finish_compile ();
-
+
report_textual_dates (&args);
}
/* Try to disable the ability to unlink a directory. */
priv_set_remove_linkdir ();
-
+
/* Decode options. */
decode_options (argc, argv);
-/* This file is part of GNU tar.
+/* This file is part of GNU tar.
Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
enum case_ctl_type
{
- ctl_stop, /* Stop case conversion */
- ctl_upcase_next,/* Turn the next character to uppercase */
+ ctl_stop, /* Stop case conversion */
+ ctl_upcase_next,/* Turn the next character to uppercase */
ctl_locase_next,/* Turn the next character to lowercase */
ctl_upcase, /* Turn the replacement to uppercase until ctl_stop */
ctl_locase /* Turn the replacement to lowercase until ctl_stop */
{
char *ptr;
size_t size;
- } literal; /* type == segm_literal */
+ } literal; /* type == segm_literal */
size_t ref; /* type == segm_backref */
- enum case_ctl_type ctl; /* type == segm_case_ctl */
+ enum case_ctl_type ctl; /* type == segm_case_ctl */
} v;
};
static struct transform *transform_head, *transform_tail;
static struct transform *
-new_transform ()
+new_transform (void)
{
struct transform *p = xzalloc (sizeof *p);
if (transform_tail)
case 'R':
*pflags &= ~XFORM_REGFILE;
break;
-
+
case 'h':
*pflags |= XFORM_LINK;
break;
case 'H':
*pflags &= ~XFORM_LINK;
break;
-
+
case 's':
*pflags |= XFORM_SYMLINK;
break;
*expr));
}
return expr;
- }
+ }
USAGE_ERROR ((0, 0, _("Invalid transform expression")));
}
-
+
delim = expr[1];
/* Scan regular expression */
if (*p == ';')
p++;
-
+
/* Extract and compile regex */
str = xmalloc (i - 1);
memcpy (str, expr + 2, i - 2);
str[i - 2] = 0;
rc = regcomp (&tf->regex, str, cflags);
-
+
if (rc)
{
char errbuf[512];
if (str[0] == '^' || str[strlen (str) - 1] == '$')
tf->transform_type = transform_first;
-
+
free (str);
/* Extract and compile replacement expr */
if (*cur == '\\')
{
size_t n;
-
+
add_literal_segment (tf, beg, cur);
switch (*++cur)
{
add_char_segment (tf, '\a');
cur++;
break;
-
+
case 'b':
add_char_segment (tf, '\b');
cur++;
break;
-
+
case 'f':
add_char_segment (tf, '\f');
cur++;
break;
-
+
case 'n':
add_char_segment (tf, '\n');
cur++;
break;
-
+
case 'r':
add_char_segment (tf, '\r');
cur++;
break;
-
+
case 't':
add_char_segment (tf, '\t');
cur++;
break;
-
+
case 'v':
add_char_segment (tf, '\v');
cur++;
add_char_segment (tf, '&');
cur++;
break;
-
+
case 'L':
/* Turn the replacement to lowercase until a `\U' or `\E'
is found, */
add_case_ctl_segment (tf, ctl_locase);
cur++;
break;
-
+
case 'l':
/* Turn the next character to lowercase, */
add_case_ctl_segment (tf, ctl_locase_next);
cur++;
break;
-
+
case 'U':
/* Turn the replacement to uppercase until a `\L' or `\E'
is found, */
add_case_ctl_segment (tf, ctl_upcase);
cur++;
break;
-
+
case 'u':
/* Turn the next character to uppercase, */
add_case_ctl_segment (tf, ctl_upcase_next);
cur++;
break;
-
+
case 'E':
/* Stop case conversion started by `\L' or `\U'. */
add_case_ctl_segment (tf, ctl_stop);
cur++;
break;
-
+
default:
/* Try to be nice */
{
static char *case_ctl_buffer;
static size_t case_ctl_bufsize;
char *p;
-
+
if (case_ctl_bufsize < size)
{
case_ctl_bufsize = size;
case ctl_upcase_next:
case_ctl_buffer[0] = toupper ((unsigned char) case_ctl_buffer[0]);
break;
-
+
case ctl_locase_next:
case_ctl_buffer[0] = tolower ((unsigned char) case_ctl_buffer[0]);
break;
-
+
case ctl_upcase:
for (p = case_ctl_buffer; p < case_ctl_buffer + size; p++)
*p = toupper ((unsigned char) *p);
break;
-
+
case ctl_locase:
for (p = case_ctl_buffer; p < case_ctl_buffer + size; p++)
*p = tolower ((unsigned char) *p);
static struct obstack stk;
static bool stk_init;
-void
+static void
_single_transform_name_to_obstack (struct transform *tf, char *input)
{
regmatch_t *rmp;
size_t nmatches = 0;
enum case_ctl_type case_ctl = ctl_stop, /* Current case conversion op */
save_ctl = ctl_stop; /* Saved case_ctl for \u and \l */
-
+
/* Reset case conversion after a single-char operation */
#define CASE_CTL_RESET() if (case_ctl == ctl_upcase_next \
|| case_ctl == ctl_locase_next) \
case_ctl = save_ctl; \
save_ctl = ctl_stop; \
}
-
+
rmp = xmalloc ((tf->regex.re_nsub + 1) * sizeof (*rmp));
while (*input)
{
size_t disp;
char *ptr;
-
+
rc = regexec (&tf->regex, input, tf->regex.re_nsub + 1, rmp, 0);
-
+
if (rc == 0)
{
struct replace_segm *segm;
-
+
disp = rmp[0].rm_eo;
if (rmp[0].rm_so)
}
obstack_grow (&stk, ptr, segm->v.literal.size);
break;
-
+
case segm_backref: /* Back-reference segment */
if (rmp[segm->v.ref].rm_so != -1
&& rmp[segm->v.ref].rm_eo != -1)
ptr = run_case_conv (case_ctl, ptr, size);
CASE_CTL_RESET();
}
-
+
obstack_grow (&stk, ptr, size);
}
break;
break;
}
/*FALL THROUGH*/
-
+
case ctl_upcase:
case ctl_locase:
case ctl_stop:
free (rmp);
}
-bool
+static bool
_transform_name_to_obstack (int flags, char *input, char **output)
{
struct transform *tf;
bool alloced = false;
-
+
if (!stk_init)
{
obstack_init (&stk);
stk_init = true;
}
-
+
for (tf = transform_head; tf; tf = tf->next)
{
if (tf->flags & flags)
*output = input;
return alloced;
}
-
+
bool
transform_name_fp (char **pinput, int flags,
char *(*fun)(char *, void *), void *dat)
-/* This file is part of GNU tar.
+/* This file is part of GNU tar.
Copyright (C) 2009 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
size_t deferred_unlink_delay = 0;
static struct deferred_unlink *
-dunlink_alloc ()
+dunlink_alloc (void)
{
struct deferred_unlink *p;
if (dunlink_avail)
{
prev = p;
p = next;
- }
+ }
}
if (!dunlink_head)
dunlink_tail = NULL;
if (dunlink_head
&& records_written > dunlink_head->records_written + deferred_unlink_delay)
flush_deferred_unlinks (false);
-
+
p = dunlink_alloc ();
p->next = NULL;
p->file_name = normalize_filename (name);
p->is_dir = is_dir;
p->records_written = records_written;
-
+
if (dunlink_tail)
dunlink_tail->next = p;
else