From c78356fedadbe36aae1e063c69d11636c86d35e6 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Wed, 24 Sep 2008 10:58:19 +0000 Subject: [PATCH] Implement --no-null option. * NEWS: Update. * doc/tar.texi: Update. * src/tar.c: New option --no-null. --- ChangeLog | 6 ++++++ NEWS | 11 ++++++++++- doc/tar.texi | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- src/tar.c | 25 +++++++++++++++++-------- 4 files changed, 79 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 722cff6..0c13aff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-09-24 Sergey Poznyakoff + + * NEWS: Update. + * doc/tar.texi: Update. + * src/tar.c: New option --no-null. + 2008-09-23 Sergey Poznyakoff * src/common.h (filename_terminator): Remove global. diff --git a/NEWS b/NEWS index 6284426..5767601 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -GNU tar NEWS - User visible changes. 2008-06-26 +GNU tar NEWS - User visible changes. 2008-09-24 Please send GNU tar bug reports to @@ -14,6 +14,10 @@ A shortcut for --lzma. Cancels the effect of previous --auto-compress (-a) option. +* New option --no-null + +Cancels the effect of previous --null option. + * Compressed format recognition If tar is unable to determine archive compression format, it falls @@ -24,6 +28,11 @@ back to using archive suffix to determine it. Using --exclude-vcs handles also files used internally by Bazaar, Mercurial and Darcs. +* Bugfixes + +** The --null option disabled handling of tar options in list files. This +is fixed. + version 1.20 - Sergey Poznyakoff, 2008-04-14 diff --git a/doc/tar.texi b/doc/tar.texi index 7739489..f86f077 100644 --- a/doc/tar.texi +++ b/doc/tar.texi @@ -2880,6 +2880,13 @@ Use case-sensitive matching. Print warnings about subprocesses that terminated with a nonzero exit code. @xref{Writing to an External Program}. +@opsummary{no-null} +@item --no-null + +If the @option{--null} option was given previously, this option +cancels its effect, so that any following @option{--files-from} +options will expect their file lists to be newline-terminated. + @opsummary{no-overwrite-dir} @item --no-overwrite-dir @@ -3901,15 +3908,15 @@ The name of the archive @command{tar} is processing. @vrindex TAR_BLOCKING_FACTOR, checkpoint script environment @item TAR_BLOCKING_FACTOR -Current blocking factor (@pxref{Blocking}. +Current blocking factor (@pxref{Blocking}). @vrindex TAR_CHECKPOINT, checkpoint script environment @item TAR_CHECKPOINT -The checkpoint number. +Number of the checkpoint. @vrindex TAR_SUBCOMMAND, checkpoint script environment @item TAR_SUBCOMMAND -A short option describing the operation @command{tar} is executing +A short option describing the operation @command{tar} is executing. @xref{Operations}, for a complete list of subcommand options. @vrindex TAR_FORMAT, checkpoint script environment @@ -6747,10 +6754,14 @@ files whose names contain newlines can be archived using @option{--files-from}. @table @option -@opindex null +@xopindex{null, described} @item --null Only consider @code{NUL} terminated file names, instead of files that terminate in a newline. + +@xopindex{no-null, described} +@item --no-null +Undo the effect of any previous @option{--null} option. @end table The @option{--null} option is just like the one in @acronym{GNU} @@ -6774,7 +6785,37 @@ $ @kbd{find . -size +800 -print0 > long-files} $ @kbd{tar -c -v --null --files-from=long-files --file=big.tar} @end smallexample -@FIXME{say anything else here to conclude the section?} +The @option{--no-null} option can be used if you need to read both +zero-terminated and newline-terminated files on the same command line. +For example, if @file{flist} is a newline-terminated file, then the +following command can be used to combine it with the above command: + +@smallexample +@group +$ @kbd{find . -size +800 -print0 | + tar -c -f big.tar --null -T - --no-null -T flist} +@end group +@end smallexample + +This example uses short options for typographic reasons, to avoid +very long lines. + +@GNUTAR is able to automatically detect null-terminated file lists, so +it is safe to use them even without the @option{--null} option. In +this case @command{tar} will print a warning and continue reading such +a file as if @option{--null} were actually given: + +@smallexample +@group +$ @kbd{find . -size +800 -print0 | tar -c -f big.tar -T -} +tar: -: file name read contains nul character +@end group +@end smallexample + +The null terminator, however, remains in effect only for this +particular file, any following @option{-T} options will assume +newline termination. Of course, the null autodetection applies +to these eventual surplus @option{-T} options as well. @node exclude @section Excluding Some Files diff --git a/src/tar.c b/src/tar.c index 67bb0be..24279c7 100644 --- a/src/tar.c +++ b/src/tar.c @@ -280,6 +280,7 @@ enum NO_DELAY_DIRECTORY_RESTORE_OPTION, NO_IGNORE_CASE_OPTION, NO_IGNORE_COMMAND_ERROR_OPTION, + NO_NULL_OPTION, NO_OVERWRITE_DIR_OPTION, NO_QUOTE_CHARS_OPTION, NO_RECURSION_OPTION, @@ -622,6 +623,8 @@ static struct argp_option options[] = { N_("get names to extract or create from FILE"), GRID+1 }, {"null", NULL_OPTION, 0, 0, N_("-T reads null-terminated names, disable -C"), GRID+1 }, + {"no-null", NO_NULL_OPTION, 0, 0, + N_("disable the effect of the previous --null option"), GRID+1 }, {"unquote", UNQUOTE_OPTION, 0, 0, N_("unquote filenames read with -T (default)"), GRID+1 }, {"no-unquote", NO_UNQUOTE_OPTION, 0, 0, @@ -1053,16 +1056,16 @@ enum read_file_list_state /* Result of reading file name from the list file */ file_list_skip /* Empty (zero-length) entry encountered, skip it */ }; -/* Read from FP a sequence of characters up to FILENAME_TERMINATOR and put them +/* 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) +read_name_from_file (FILE *fp, struct obstack *stk, int term) { int c; size_t counter = 0; - for (c = getc (fp); c != EOF && c != filename_terminator; c = getc (fp)) + for (c = getc (fp); c != EOF && c != term; c = getc (fp)) { if (c == 0) { @@ -1143,7 +1146,8 @@ update_argv (const char *filename, struct argp_state *state) 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; @@ -1157,7 +1161,8 @@ update_argv (const char *filename, struct argp_state *state) open_fatal (filename); } - while ((read_state = read_name_from_file (fp, &argv_stk)) != file_list_end) + while ((read_state = read_name_from_file (fp, &argv_stk, term)) + != file_list_end) { switch (read_state) { @@ -1186,7 +1191,7 @@ update_argv (const char *filename, struct argp_state *state) obstack_1grow (&argv_stk, 0); count = 1; /* Read rest of files using new filename terminator */ - filename_terminator = 0; + term = 0; break; } @@ -1203,7 +1208,7 @@ update_argv (const char *filename, struct argp_state *state) start = obstack_finish (&argv_stk); - if (filename_terminator == 0) + if (term == 0) for (p = start; *p; p += strlen (p) + 1) if (p[0] == '-') count++; @@ -1219,7 +1224,7 @@ update_argv (const char *filename, struct argp_state *state) for (i = state->next, p = start; *p; p += strlen (p) + 1, i++) { - if (filename_terminator == 0 && p[0] == '-') + if (term == 0 && p[0] == '-') state->argv[i++] = "--add-file"; state->argv[i] = p; } @@ -1741,6 +1746,10 @@ parse_opt (int key, char *arg, struct argp_state *state) filename_terminator = '\0'; break; + case NO_NULL_OPTION: + filename_terminator = '\n'; + break; + case NUMERIC_OWNER_OPTION: numeric_owner_option = true; break; -- 2.45.2