[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug-tar] tar -T option
From: |
Sergey Poznyakoff |
Subject: |
[Bug-tar] tar -T option |
Date: |
Sun, 04 Aug 2013 18:47:34 +0300 |
Hello,
I have installed the following patch, which fixes both the bugs in
-T handling discovered by Michal and reduces the memory consuption to
an acceptable level (the bug was reported by Christian).
Regards,
Sergey
diff --git a/THANKS b/THANKS
index 6459157..c30df33 100644
--- a/THANKS
+++ b/THANKS
@@ -91,6 +91,7 @@ Christian Kirsch address@hidden
Christian Laubscher address@hidden
Christian T. Dum address@hidden
Christian von Roques address@hidden
+Christian Wetzel address@hidden
Christoph Litauer address@hidden
Christophe Colle address@hidden
Christophe Kalt address@hidden
@@ -350,6 +351,7 @@ Michael P Urban address@hidden
Michael Schmidt address@hidden
Michael Schwingen address@hidden
Michael Smolsky address@hidden
+Michal Žejdl address@hidden
Mike Muuss address@hidden
Mike Nolan address@hidden
Mike Rogers address@hidden
diff --git a/src/common.h b/src/common.h
index 9ac22b8..21df8c1 100644
--- a/src/common.h
+++ b/src/common.h
@@ -704,6 +704,7 @@ int uname_to_uid (char const *uname, uid_t *puid);
void name_init (void);
void name_add_name (const char *name, int matching_flags);
void name_add_dir (const char *name);
+void name_add_file (const char *name, int term);
void name_term (void);
const char *name_next (int change_dirs);
void name_gather (void);
@@ -748,6 +749,9 @@ const char *archive_format_string (enum archive_format fmt);
const char *subcommand_string (enum subcommand c);
void set_exit_status (int val);
+void request_stdin (const char *option);
+void more_options (int argc, char **argv);
+
/* Module update.c. */
extern char *output_start;
diff --git a/src/names.c b/src/names.c
index 32bd8e6..4710848 100644
--- a/src/names.c
+++ b/src/names.c
@@ -21,6 +21,7 @@
#include <fnmatch.h>
#include <hash.h>
#include <quotearg.h>
+#include <wordsplit.h>
#include "common.h"
@@ -211,7 +212,8 @@ static struct name *nametail; /* end of name list */
#define NELT_NAME 0 /* File name */
#define NELT_CHDIR 1 /* Change directory request */
#define NELT_FMASK 2 /* Change fnmatch options request */
-
+#define NELT_FILE 3 /* Read file names from that file */
+
struct name_elt /* A name_array element. */
{
char type; /* Element type, see NELT_* constants above */
@@ -219,6 +221,12 @@ struct name_elt /* A name_array element. */
{
const char *name; /* File or directory name */
int matching_flags;/* fnmatch options if type == NELT_FMASK */
+ struct
+ {
+ const char *name;/* File name */
+ int term; /* File name terminator in the list */
+ FILE *fp;
+ } file;
} v;
};
@@ -274,6 +282,16 @@ name_add_dir (const char *name)
ep->v.name = name;
}
+void
+name_add_file (const char *name, int term)
+{
+ struct name_elt *ep;
+ check_name_alloc ();
+ ep = &name_array[entries++];
+ ep->type = NELT_FILE;
+ ep->v.file.name = name;
+ ep->v.file.term = term;
+}
/* Names from external name file. */
@@ -295,7 +313,184 @@ name_term (void)
free (name_buffer);
free (name_array);
}
+
+/* Prevent recursive inclusion of the same file */
+struct file_id_list
+{
+ struct file_id_list *next;
+ ino_t ino;
+ dev_t dev;
+};
+
+static struct file_id_list *file_id_list;
+
+static void
+add_file_id (const char *filename)
+{
+ struct file_id_list *p;
+ struct stat st;
+
+ if (stat (filename, &st))
+ stat_fatal (filename);
+ for (p = file_id_list; p; p = p->next)
+ if (p->ino == st.st_ino && p->dev == st.st_dev)
+ {
+ FATAL_ERROR ((0, 0, _("%s: file list already read"),
+ quotearg_colon (filename)));
+ }
+ p = xmalloc (sizeof *p);
+ p->next = file_id_list;
+ p->ino = st.st_ino;
+ p->dev = st.st_dev;
+ file_id_list = p;
+}
+
+enum read_file_list_state /* Result of reading file name from the list file */
+ {
+ file_list_success, /* OK, name read successfully */
+ file_list_end, /* End of list file */
+ file_list_zero, /* Zero separator encountered where it should not */
+ file_list_skip /* Empty (zero-length) entry encountered, skip it */
+ };
+
+/* Read from FP a sequence of characters up to TERM and put them
+ into STK.
+ */
+static enum read_file_list_state
+read_name_from_file (struct name_elt *ent)
+{
+ int c;
+ size_t counter = 0;
+ FILE *fp = ent->v.file.fp;
+ int term = ent->v.file.term;
+
+ for (c = getc (fp); c != EOF && c != term; c = getc (fp))
+ {
+ if (counter == name_buffer_length)
+ name_buffer = x2realloc (name_buffer, &name_buffer_length);
+ name_buffer[counter++] = c;
+ if (c == 0)
+ {
+ /* We have read a zero separator. The file possibly is
+ zero-separated */
+ return file_list_zero;
+ }
+ }
+
+ if (counter == 0 && c != EOF)
+ return file_list_skip;
+
+ if (counter == name_buffer_length)
+ name_buffer = x2realloc (name_buffer, &name_buffer_length);
+ name_buffer[counter] = 0;
+
+ return (counter == 0 && c == EOF) ? file_list_end : file_list_success;
+}
+static int
+handle_option (const char *str)
+{
+ struct wordsplit ws;
+ int i;
+
+ while (*str && isspace (*str))
+ ;
+ if (*str != '-')
+ return 1;
+
+ ws.ws_offs = 1;
+ if (wordsplit (str, &ws, WRDSF_DEFFLAGS|WRDSF_DOOFFS))
+ FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
+ str, wordsplit_strerror (&ws)));
+ ws.ws_wordv[0] = "tar";
+ more_options (ws.ws_wordc+ws.ws_offs, ws.ws_wordv);
+ for (i = 0; i < ws.ws_wordc+ws.ws_offs; i++)
+ ws.ws_wordv[i] = NULL;
+
+ wordsplit_free (&ws);
+ return 0;
+}
+
+static int
+read_next_name (struct name_elt *ent, struct name_elt *ret)
+{
+ enum read_file_list_state read_state;
+
+ if (!ent->v.file.fp)
+ {
+ if (!strcmp (ent->v.file.name, "-"))
+ {
+ request_stdin ("-T");
+ ent->v.file.fp = stdin;
+ }
+ else
+ {
+ add_file_id (ent->v.file.name);
+ if ((ent->v.file.fp = fopen (ent->v.file.name, "r")) == NULL)
+ open_fatal (ent->v.file.name);
+ }
+ }
+
+ while (1)
+ {
+ switch (read_name_from_file (ent))
+ {
+ case file_list_skip:
+ continue;
+
+ case file_list_zero:
+ WARNOPT (WARN_FILENAME_WITH_NULS,
+ (0, 0, N_("%s: file name read contains nul character"),
+ quotearg_colon (ent->v.file.name)));
+ ent->v.file.term = 0;
+ /* fall through */
+ case file_list_success:
+ if (handle_option (name_buffer) == 0)
+ continue;
+ ret->type = NELT_NAME;
+ ret->v.name = name_buffer;
+ return 0;
+
+ case file_list_end:
+ if (strcmp (ent->v.file.name, "-"))
+ fclose (ent->v.file.fp);
+ ent->v.file.fp = NULL;
+ return 1;
+ }
+ }
+}
+
+static void
+copy_name (struct name_elt *ep)
+{
+ const char *source;
+ size_t source_len;
+ char *cursor;
+
+ source = ep->v.name;
+ source_len = strlen (source);
+ if (name_buffer_length < source_len)
+ {
+ do
+ {
+ name_buffer_length *= 2;
+ if (! name_buffer_length)
+ xalloc_die ();
+ }
+ while (name_buffer_length < source_len);
+
+ free (name_buffer);
+ name_buffer = xmalloc(name_buffer_length + 2);
+ }
+ strcpy (name_buffer, source);
+
+ /* Zap trailing slashes. */
+ cursor = name_buffer + strlen (name_buffer) - 1;
+ while (cursor > name_buffer && ISSLASH (*cursor))
+ *cursor-- = '\0';
+}
+
+
static int matching_flags; /* exclude_fnmatch options */
/* Get the next NELT_NAME element from name_array. Result is in
@@ -310,51 +505,40 @@ static struct name_elt *
name_next_elt (int change_dirs)
{
static struct name_elt entry;
- const char *source;
- char *cursor;
while (scanned != entries)
{
struct name_elt *ep;
- size_t source_len;
- ep = &name_array[scanned++];
+ ep = &name_array[scanned];
if (ep->type == NELT_FMASK)
{
matching_flags = ep->v.matching_flags;
+ ++scanned;
continue;
}
- source = ep->v.name;
- source_len = strlen (source);
- if (name_buffer_length < source_len)
+ switch (ep->type)
{
- do
+ case NELT_FILE:
+ if (read_next_name (ep, &entry) == 0)
+ return &entry;
+ ++scanned;
+ continue;
+
+ case NELT_CHDIR:
+ if (change_dirs)
{
- name_buffer_length *= 2;
- if (! name_buffer_length)
- xalloc_die ();
+ ++scanned;
+ copy_name (ep);
+ if (chdir (name_buffer) < 0)
+ chdir_fatal (name_buffer);
+ break;
}
- while (name_buffer_length < source_len);
-
- free (name_buffer);
- name_buffer = xmalloc (name_buffer_length + 2);
- }
- strcpy (name_buffer, source);
-
- /* Zap trailing slashes. */
-
- cursor = name_buffer + strlen (name_buffer) - 1;
- while (cursor > name_buffer && ISSLASH (*cursor))
- *cursor-- = '\0';
-
- if (change_dirs && ep->type == NELT_CHDIR)
- {
- if (chdir (name_buffer) < 0)
- chdir_fatal (name_buffer);
- }
- else
- {
+ /* fall trhough */
+ case NELT_NAME:
+ ++scanned;
+ copy_name (ep);
if (unquote_option)
unquote_string (name_buffer);
entry.type = ep->type;
diff --git a/src/tar.c b/src/tar.c
index 9111433..c3c2459 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -79,7 +79,7 @@ static size_t allocated_archive_names;
static const char *stdin_used_by;
/* Doesn't return if stdin already requested. */
-static void
+void
request_stdin (const char *option)
{
if (stdin_used_by)
@@ -1107,83 +1107,8 @@ report_textual_dates (struct tar_args *args)
}
-
-/* Either NL or NUL, as decided by the --null option. */
-static char filename_terminator;
-
-enum read_file_list_state /* Result of reading file name from the list file */
- {
- file_list_success, /* OK, name read successfully */
- file_list_end, /* End of list file */
- file_list_zero, /* Zero separator encountered where it should not */
- file_list_skip /* Empty (zero-length) entry encountered, skip it */
- };
-
-/* Read from FP a sequence of characters up to TERM and put them
- into STK.
- */
-static enum read_file_list_state
-read_name_from_file (FILE *fp, struct obstack *stk, int term)
-{
- int c;
- size_t counter = 0;
-
- for (c = getc (fp); c != EOF && c != term; c = getc (fp))
- {
- if (c == 0)
- {
- /* We have read a zero separator. The file possibly is
- zero-separated */
- return file_list_zero;
- }
- obstack_1grow (stk, c);
- counter++;
- }
-
- if (counter == 0 && c != EOF)
- return file_list_skip;
-
- obstack_1grow (stk, 0);
-
- return (counter == 0 && c == EOF) ? file_list_end : file_list_success;
-}
-
-
static bool files_from_option; /* When set, tar will not refuse to create
empty archives */
-static struct obstack argv_stk; /* Storage for additional command line options
- read using -T option */
-
-/* Prevent recursive inclusion of the same file */
-struct file_id_list
-{
- struct file_id_list *next;
- ino_t ino;
- dev_t dev;
-};
-
-static struct file_id_list *file_id_list;
-
-static void
-add_file_id (const char *filename)
-{
- struct file_id_list *p;
- struct stat st;
-
- if (stat (filename, &st))
- stat_fatal (filename);
- for (p = file_id_list; p; p = p->next)
- if (p->ino == st.st_ino && p->dev == st.st_dev)
- {
- FATAL_ERROR ((0, 0, _("%s: file list already read"),
- quotearg_colon (filename)));
- }
- p = xmalloc (sizeof *p);
- p->next = file_id_list;
- p->ino = st.st_ino;
- p->dev = st.st_dev;
- file_id_list = p;
-}
/* Default density numbers for [0-9][lmh] device specifications */
@@ -1201,101 +1126,6 @@ add_file_id (const char *filename)
# endif
#endif
-static void
-update_argv (const char *filename, struct argp_state *state)
-{
- FILE *fp;
- size_t count = 0, i;
- char *start, *p;
- char **new_argv;
- size_t new_argc;
- bool is_stdin = false;
- enum read_file_list_state read_state;
- int term = filename_terminator;
-
- if (!strcmp (filename, "-"))
- {
- is_stdin = true;
- request_stdin ("-T");
- fp = stdin;
- }
- else
- {
- add_file_id (filename);
- if ((fp = fopen (filename, "r")) == NULL)
- open_fatal (filename);
- }
-
- while ((read_state = read_name_from_file (fp, &argv_stk, term))
- != file_list_end)
- {
- switch (read_state)
- {
- 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);
- for (; size > 0; size--, p++)
- if (*p)
- obstack_1grow (&argv_stk, *p);
- else
- obstack_1grow (&argv_stk, '\n');
- obstack_1grow (&argv_stk, 0);
- count = 1;
- /* Read rest of files using new filename terminator */
- 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] == '-')
- state->argv[i++] = (char *) "--add-file";
- state->argv[i] = p;
- }
-}
-
static char *
tar_help_filter (int key, const char *text, void *input)
@@ -1462,6 +1292,9 @@ parse_owner_group (char *arg, uintmax_t field_max, char
const **name_option)
#define TAR_SIZE_SUFFIXES "bBcGgkKMmPTtw"
+/* Either NL or NUL, as decided by the --null option. */
+static char filename_terminator;
+
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
@@ -1745,7 +1578,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'T':
- update_argv (arg, state);
+ name_add_file (arg, filename_terminator);
/* Indicate we've been given -T option. This is for backward
compatibility only, so that `tar cfT archive /dev/null will
succeed */
@@ -2371,11 +2204,12 @@ static int subcommand_class[] = {
/* Return t if the subcommand_option is in class(es) f */
#define IS_SUBCOMMAND_CLASS(f) (subcommand_class[subcommand_option] & (f))
+static struct tar_args args;
+
static void
decode_options (int argc, char **argv)
{
int idx;
- struct tar_args args;
argp_version_setup ("tar", tar_authors);
@@ -2476,7 +2310,6 @@ decode_options (int argc, char **argv)
if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &idx, &args))
exit (TAREXIT_FAILURE);
-
/* Special handling for 'o' option:
GNU tar used to say "output old format".
@@ -2742,6 +2575,14 @@ decode_options (int argc, char **argv)
report_textual_dates (&args);
}
+void
+more_options (int argc, char **argv)
+{
+ int idx;
+ if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER,
+ &idx, &args))
+ exit (TAREXIT_FAILURE);
+}
/* Tar proper. */
@@ -2771,8 +2612,6 @@ main (int argc, char **argv)
xmalloc (sizeof (const char *) * allocated_archive_names);
archive_names = 0;
- obstack_init (&argv_stk);
-
/* System V fork+wait does not work if SIGCHLD is ignored. */
signal (SIGCHLD, SIG_DFL);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8b7acb1..e13b079 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -44,6 +44,8 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
TESTSUITE_AT = \
T-empty.at\
T-null.at\
+ T-zfile.at\
+ T-nonl.at\
testsuite.at\
append.at\
append01.at\
diff --git a/tests/T-empty.at b/tests/T-empty.at
index d3b28df..5261445 100644
--- a/tests/T-empty.at
+++ b/tests/T-empty.at
@@ -23,8 +23,8 @@
# Reported by: Karl Berry <address@hidden>
# References: <address@hidden>
-AT_SETUP([files-from: empty entries])
-AT_KEYWORDS([files-from empty])
+AT_SETUP([empty entries])
+AT_KEYWORDS([files-from empty-line])
AT_DATA([file-list],
[jeden
@@ -34,17 +34,16 @@ trzy
])
AT_TAR_CHECK([
-AT_SORT_PREREQ
genfile --file jeden
genfile --file dwa
genfile --file trzy
-tar cfvT archive ../file-list | sort
+tar cfvT archive ../file-list
],
[0],
-[dwa
-jeden
+[jeden
+dwa
trzy
],
[],[],[],[ustar]) # Testing one format is enough
diff --git a/tests/T-nonl.at b/tests/T-nonl.at
new file mode 100644
index 0000000..a694155
--- /dev/null
+++ b/tests/T-nonl.at
@@ -0,0 +1,62 @@
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+#
+# Test suite for GNU tar.
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU tar.
+#
+# GNU tar is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# GNU tar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Tar malfunctioned when given a file list with the last line not ending
+# in a newline.
+#
+# Reported by: Michal Žejdl <address@hidden>
+# References: <http://lists.gnu.org/archive/html/bug-tar/2013-07/msg00009.html>
+
+AT_SETUP([entries with missing newlines])
+AT_KEYWORDS([files-from nonewline nonl T-nonl])
+
+AT_TAR_CHECK([
+genfile --length=0 --file empty
+AS_ECHO_N(c) > 1.nonl
+echo d > 2.nonl
+AS_ECHO_N(e) >> 2.nonl
+touch a b c d e
+AT_DATA([filelist],[a
+b
+])
+
+tar cf archive -T empty -T 1.nonl -T 2.nonl -T filelist
+tar tf archive
+echo ==
+tar cf archive -T 2.nonl -T empty -T filelist -T 1.nonl
+tar tf archive
+],
+[0],
+[c
+d
+e
+a
+b
+==
+d
+e
+a
+b
+c
+],
+[],[],[],[ustar])
+
+AT_CLEANUP
+
diff --git a/tests/T-null.at b/tests/T-null.at
index 8f42e5b..5db5cf4 100644
--- a/tests/T-null.at
+++ b/tests/T-null.at
@@ -18,30 +18,28 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-AT_SETUP([files-from: 0-separated file without -0])
+AT_SETUP([0-separated file without -0])
AT_KEYWORDS([files-from null T-null])
-AT_DATA([expout],[jeden\ndwa
-trzy
-])
-
AT_TAR_CHECK([
AT_SORT_PREREQ
-echo dwa > temp
+echo jeden > temp
+echo dwa >> temp
echo trzy >> temp
-cat temp | tr '\n' '\0' > temp1
-echo jeden > file-list
-cat temp1 >> file-list
+cat temp | tr '\n' '\0' > file-list
-genfile -f "jeden
-dwa" || AT_SKIP_TEST
+genfile -f jeden
+genfile -f dwa
genfile -f trzy
-tar cfTv archive file-list | sort
+tar cfTv archive file-list
],
[0],
-[expout],
+[jeden
+dwa
+trzy
+],
[tar: file-list: file name read contains nul character
],[],[],[ustar]) # Testing one format is enough
diff --git a/tests/T-zfile.at b/tests/T-zfile.at
new file mode 100644
index 0000000..8761c7c
--- /dev/null
+++ b/tests/T-zfile.at
@@ -0,0 +1,52 @@
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+#
+# Test suite for GNU tar.
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU tar.
+#
+# GNU tar is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# GNU tar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Tar malfunctioned when given empty file as an argument to -T.
+#
+# Reported by: Michal Žejdl <address@hidden>
+# References: <http://lists.gnu.org/archive/html/bug-tar/2013-07/msg00009.html>
+
+AT_SETUP([empty file])
+AT_KEYWORDS([files-from empty-file])
+
+AT_TAR_CHECK([
+genfile --length=0 --file empty
+genfile --file a
+genfile --file b
+AT_DATA([valid],[a
+b
+])
+
+tar cf archive -T empty -T valid
+tar tf archive
+echo "=="
+tar cf archive -T valid -T empty
+tar tf archive
+],
+[0],
+[a
+b
+==
+a
+b
+],
+[],[],[],[ustar]) # Testing one format is enough
+
+AT_CLEANUP
diff --git a/tests/testsuite.at b/tests/testsuite.at
index d3fabe5..f1b6cc3 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -199,6 +199,8 @@ m4_include([opcomp06.at])
AT_BANNER([The -T option])
m4_include([T-empty.at])
m4_include([T-null.at])
+m4_include([T-zfile.at])
+m4_include([T-nonl.at])
AT_BANNER([Various options])
m4_include([indexfile.at])
- [Bug-tar] tar -T option,
Sergey Poznyakoff <=
- Re: [Bug-tar] tar -T option, Pavel Raiskup, 2013/08/05
- Re: [Bug-tar] tar -T option, Sergey Poznyakoff, 2013/08/05
- Re: [Bug-tar] tar -T option, Pavel Raiskup, 2013/08/15
- Re: [Bug-tar] tar -T option, Sergey Poznyakoff, 2013/08/15
- Re: [Bug-tar] tar -T option, Pavel Raiskup, 2013/08/15
- Re: [Bug-tar] tar -T option, Christian Wetzel, 2013/08/15
- Re: [Bug-tar] tar -T option, Pavel Raiskup, 2013/08/15
- Re: [Bug-tar] tar -T option, Sergey Poznyakoff, 2013/08/15
- Re: [Bug-tar] tar -T option, Pavel Raiskup, 2013/08/16
- Re: [Bug-tar] tar -T option, Sergey Poznyakoff, 2013/08/16