]> Dogcows Code - chaz/tar/blobdiff - src/tar.c
Avoid installation glitches on Solaris 8 with Sun C 5.4.
[chaz/tar] / src / tar.c
index ddea61d1c7b6a5f534ce69ab50e9a60635e4dde6..e859f49b2573f67b149596a0f538f9a8d16fa565 100644 (file)
--- a/src/tar.c
+++ b/src/tar.c
@@ -1,7 +1,7 @@
 /* A tar (tape archiver) program.
 
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
-   2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+   2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
    Written by John Gilmore, starting 1985-08-25.
 
@@ -22,7 +22,9 @@
 #include <system.h>
 
 #include <fnmatch.h>
+#include <getline.h>
 #include <argp.h>
+#include <argp-namefrob.h>
 
 #include <signal.h>
 #if ! defined SIGCHLD && defined SIGCLD
 #include "common.h"
 
 #include <argmatch.h>
+#include <closeout.h>
+#include <exitfail.h>
 #include <getdate.h>
 #include <localedir.h>
 #include <rmt.h>
 #include <prepargs.h>
 #include <quotearg.h>
+#include <version-etc.h>
 #include <xstrtol.h>
 #include <stdopen.h>
 
@@ -187,16 +192,16 @@ subcommand_string (enum subcommand c)
 
     case CAT_SUBCOMMAND:
       return "-A";
-      
+
     case CREATE_SUBCOMMAND:
       return "-c";
-      
+
     case DELETE_SUBCOMMAND:
       return "-D";
 
     case DIFF_SUBCOMMAND:
       return "-d";
-      
+
     case EXTRACT_SUBCOMMAND:
       return "-x";
 
@@ -211,6 +216,30 @@ subcommand_string (enum subcommand c)
     }
 }
 
+void
+tar_list_quoting_styles (FILE *fp, char *prefix)
+{
+  int i;
+
+  for (i = 0; quoting_style_args[i]; i++)
+    fprintf (fp, "%s%s\n", prefix, quoting_style_args[i]);
+}
+
+void
+tar_set_quoting_style (char *arg)
+{
+  int i;
+
+  for (i = 0; quoting_style_args[i]; i++)
+    if (strcmp (arg, quoting_style_args[i]) == 0)
+      {
+       set_quoting_style (NULL, i);
+       return;
+      }
+  FATAL_ERROR ((0, 0,
+               _("Unknown quoting style `%s'. Try `%s --quoting-style=help' to get a list."), arg, program_invocation_short_name));
+}
+
 \f
 /* Options.  */
 
@@ -233,7 +262,6 @@ enum
   IGNORE_FAILED_READ_OPTION,
   INDEX_FILE_OPTION,
   KEEP_NEWER_FILES_OPTION,
-  LICENSE_OPTION,
   MODE_OPTION,
   NEWER_MTIME_OPTION,
   NO_ANCHORED_OPTION,
@@ -241,6 +269,7 @@ enum
   NO_IGNORE_CASE_OPTION,
   NO_IGNORE_COMMAND_ERROR_OPTION,
   NO_OVERWRITE_DIR_OPTION,
+  NO_QUOTE_CHARS_OPTION,
   NO_RECURSION_OPTION,
   NO_SAME_OWNER_OPTION,
   NO_SAME_PERMISSIONS_OPTION,
@@ -257,6 +286,8 @@ enum
   PAX_OPTION,
   POSIX_OPTION,
   PRESERVE_OPTION,
+  QUOTE_CHARS_OPTION,
+  QUOTING_STYLE_OPTION,
   RECORD_SIZE_OPTION,
   RECURSION_OPTION,
   RECURSIVE_UNLINK_OPTION,
@@ -342,7 +373,7 @@ static struct argp_option options[] = {
    N_("Test archive volume label and exit"), GRID+1 },
 #undef GRID
 
-#define GRID 20  
+#define GRID 20
   {NULL, 0, NULL, 0,
    N_("Operation modifiers:"), GRID },
 
@@ -360,7 +391,7 @@ static struct argp_option options[] = {
    N_("archive is seekable"), GRID+1 },
 #undef GRID
 
-#define GRID 30  
+#define GRID 30
   {NULL, 0, NULL, 0,
    N_("Overwrite control:\n"), GRID+1 },
 
@@ -382,7 +413,7 @@ static struct argp_option options[] = {
    N_("preserve metadata of existing directories"), GRID+1 },
 #undef GRID
 
-#define GRID 40  
+#define GRID 40
   {NULL, 0, NULL, 0,
    N_("Select output stream:"), GRID },
 
@@ -396,7 +427,7 @@ static struct argp_option options[] = {
    N_("treat non-zero exit codes of children as error"), GRID+1 },
 #undef GRID
 
-#define GRID 50  
+#define GRID 50
   {NULL, 0, NULL, 0,
    N_("Handling of file attributes:"), GRID },
 
@@ -436,7 +467,7 @@ static struct argp_option options[] = {
    N_("Cancel the effect of --delay-directory-restore option."), GRID+1 },
 #undef GRID
 
-#define GRID 60  
+#define GRID 60
   {NULL, 0, NULL, 0,
    N_("Device selection and switching:\n"), GRID+1 },
 
@@ -475,7 +506,7 @@ static struct argp_option options[] = {
    N_("use/update the volume number in FILE"), GRID+1 },
 #undef GRID
 
-#define GRID 70  
+#define GRID 70
   {NULL, 0, NULL, 0,
    N_("Device blocking:"), GRID+1 },
 
@@ -489,7 +520,7 @@ static struct argp_option options[] = {
    N_("reblock as we read (for 4.2BSD pipes)"), GRID+1 },
 #undef GRID
 
-#define GRID 80  
+#define GRID 80
   {NULL, 0, NULL, 0,
    N_("Archive format selection:"), GRID },
 
@@ -531,7 +562,7 @@ static struct argp_option options[] = {
    N_("filter through PROG (must accept -d)"), GRID+8 },
 #undef GRID
 
-#define GRID 90  
+#define GRID 90
   {NULL, 0, NULL, 0,
    N_("Local file selection:"), GRID },
 
@@ -596,7 +627,7 @@ static struct argp_option options[] = {
    N_("exclude pattern wildcards match `/' (default)"), GRID+1 },
 #undef GRID
 
-#define GRID 100  
+#define GRID 100
   {NULL, 0, NULL, 0,
    N_("Informative output:"), GRID },
 
@@ -624,9 +655,15 @@ static struct argp_option options[] = {
   {"show-stored-names", SHOW_STORED_NAMES_OPTION, 0, 0,
    N_("When creating archive in verbose mode, list member names as stored in the archive"),
    GRID+1 },
+  {"quoting-style", QUOTING_STYLE_OPTION, N_("STYLE"), 0,
+   N_("Set name quoting style. See below for valid STYLE values."), GRID+1 },
+  {"quote-chars", QUOTE_CHARS_OPTION, N_("STRING"), 0,
+   N_("Additionally quote characters from STRING"), GRID+1 },
+  {"no-quote-chars", NO_QUOTE_CHARS_OPTION, N_("STRING"), 0,
+   N_("Disable quoting for characters from STRING"), GRID+1 },
 #undef GRID
 
-#define GRID 110  
+#define GRID 110
   {NULL, 0, NULL, 0,
    N_("Compatibility options:"), GRID },
 
@@ -634,23 +671,22 @@ static struct argp_option options[] = {
    N_("when creating, same as --old-archive. When extracting, same as --no-same-owner"), GRID+1 },
 #undef GRID
 
-#define GRID 120  
+#define GRID 120
   {NULL, 0, NULL, 0,
    N_("Other options:"), GRID },
 
-  {"restrict", RESTRICT_OPTION, 0, 0, 
+  {"restrict", RESTRICT_OPTION, 0, 0,
    N_("Restrict use of some potentially harmful options"), -1 },
-   
+
   {"help",  '?', 0, 0,  N_("Give this help list"), -1},
   {"usage", USAGE_OPTION, 0, 0,  N_("Give a short usage message"), -1},
-  {"license", LICENSE_OPTION, 0, 0, N_("Print license and exit"), -1},
   {"version", VERSION_OPTION, 0, 0,  N_("Print program version"), -1},
   /* FIXME -V (--label) conflicts with the default short option for
      --version */
   {"HANG",       HANG_OPTION,    "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
    N_("Hang for SECS seconds (default 3600)"), 0},
 #undef GRID
-  
+
   {0, 0, 0, 0, 0, 0}
 };
 
@@ -679,9 +715,10 @@ static void
 show_default_settings (FILE *stream)
 {
   fprintf (stream,
-          "--format=%s -f%s -b%d --rmt-command=%s",
+          "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s",
           archive_format_string (DEFAULT_ARCHIVE_FORMAT),
           DEFAULT_ARCHIVE, DEFAULT_BLOCKING,
+          quoting_style_args[DEFAULT_QUOTING_STYLE],
           DEFAULT_RMT_COMMAND);
 #ifdef REMOTE_SHELL
   fprintf (stream, " --rsh-command=%s", REMOTE_SHELL);
@@ -710,30 +747,6 @@ set_use_compress_program_option (const char *string)
   use_compress_program_option = string;
 }
 
-void
-license ()
-{
-  printf ("tar (%s) %s\n%s\n", PACKAGE_NAME, PACKAGE_VERSION,
-         "Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, \n\
-2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.\n");
-  puts (_("Based on the work of John Gilmore and Jay Fenlason. See AUTHORS\n\
-for complete list of authors.\n"));
-  printf (_("   GNU tar is free software; you can redistribute it and/or modify\n"
-    "   it under the terms of the GNU General Public License as published by\n"
-    "   the Free Software Foundation; either version 2 of the License, or\n"
-    "   (at your option) any later version.\n"
-    "\n"
-    "   GNU tar is distributed in the hope that it will be useful,\n"
-    "   but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-    "   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
-    "   GNU General Public License for more details.\n"
-    "\n"
-    "   You should have received a copy of the GNU General Public License\n"
-    "   along with GNU tar; if not, write to the Free Software Foundation,\n"
-    "   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA\n\n"));
-  exit (0);
-}
-
 static volatile int _argp_hang;
 
 enum read_file_list_state  /* Result of reading file name from the list file */
@@ -1240,7 +1253,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
     case NO_DELAY_DIRECTORY_RESTORE_OPTION:
       delay_directory_restore_option = false;
       break;
-      
+
     case DELETE_OPTION:
       set_subcommand_option (DELETE_SUBCOMMAND);
       break;
@@ -1319,6 +1332,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
       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->exclude_options &= ~ EXCLUDE_WILDCARDS;
       break;
@@ -1367,6 +1385,15 @@ parse_opt (int key, char *arg, struct argp_state *state)
        }
       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:
       args->pax_option++;
       xheader_set_option (arg);
@@ -1407,7 +1434,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
     case RESTRICT_OPTION:
       restrict_option = true;
       break;
-      
+
     case RMT_COMMAND_OPTION:
       rmt_command = arg;
       break;
@@ -1418,7 +1445,8 @@ parse_opt (int key, char *arg, struct argp_state *state)
 
     case SHOW_DEFAULTS_OPTION:
       show_default_settings (stdout);
-      exit(0);
+      close_stdout ();
+      exit (0);
 
     case STRIP_COMPONENTS_OPTION:
       {
@@ -1573,26 +1601,29 @@ parse_opt (int key, char *arg, struct argp_state *state)
       state->flags |= ARGP_NO_EXIT;
       argp_state_help (state, state->out_stream,
                       ARGP_HELP_STD_HELP & ~ARGP_HELP_BUG_ADDR);
+      fprintf (state->out_stream, "\n%s\n\n",
+              _("Valid arguments for --quoting-style options are:"));
+      tar_list_quoting_styles (state->out_stream, "  ");
+
       fprintf (state->out_stream, _("\n*This* tar defaults to:\n"));
       show_default_settings (state->out_stream);
       fprintf (state->out_stream, "\n");
       fprintf (state->out_stream, _("Report bugs to %s.\n"),
               argp_program_bug_address);
+      close_stdout ();
       exit (0);
 
     case USAGE_OPTION:
-      argp_state_help (state, state->out_stream,
-                      ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
-      break;
+      argp_state_help (state, state->out_stream, ARGP_HELP_USAGE);
+      close_stdout ();
+      exit (0);
 
     case VERSION_OPTION:
-      fprintf (state->out_stream, "%s\n", argp_program_version);
+      version_etc (state->out_stream, "tar", PACKAGE_NAME, VERSION,
+                  "John Gilmore", "Jay Fenlason", (char *) NULL);
+      close_stdout ();
       exit (0);
 
-    case LICENSE_OPTION:
-      license ();
-      break;
-
     case HANG_OPTION:
       _argp_hang = atoi (arg ? arg : "3600");
       while (_argp_hang-- > 0)
@@ -1619,6 +1650,7 @@ void
 usage (int status)
 {
   argp_help (&argp, stderr, ARGP_HELP_SEE, (char*) program_name);
+  close_stdout ();
   exit (status);
 }
 
@@ -1729,7 +1761,7 @@ decode_options (int argc, char **argv)
 
   if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP,
                  &index, &args))
-    exit (1);
+    exit (TAREXIT_FAILURE);
 
 
   /* Special handling for 'o' option:
@@ -1786,7 +1818,7 @@ decode_options (int argc, char **argv)
       && !tape_length_option)
     USAGE_ERROR ((0, 0,
                  _("creating multi-volume archives in posix format requires using --tape-length (-L) option")));
-  
+
   if (occurrence_option)
     {
       if (!args.input_files)
@@ -1872,7 +1904,8 @@ decode_options (int argc, char **argv)
       if (multi_volume_option)
        USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives")));
       if (subcommand_option == UPDATE_SUBCOMMAND
-         || subcommand_option == APPEND_SUBCOMMAND)
+         || subcommand_option == APPEND_SUBCOMMAND
+         || subcommand_option == DELETE_SUBCOMMAND)
        USAGE_ERROR ((0, 0, _("Cannot update compressed archives")));
       if (subcommand_option == CAT_SUBCOMMAND)
        USAGE_ERROR ((0, 0, _("Cannot concatenate compressed archives")));
@@ -1978,9 +2011,10 @@ main (int argc, char **argv)
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
 
+  exit_failure = TAREXIT_FAILURE;
   exit_status = TAREXIT_SUCCESS;
   filename_terminator = '\n';
-  set_quoting_style (0, escape_quoting_style);
+  set_quoting_style (0, DEFAULT_QUOTING_STYLE);
 
   /* Make sure we have first three descriptors available */
   stdopen ();
@@ -2064,8 +2098,9 @@ main (int argc, char **argv)
   free (archive_name_array);
   name_term ();
 
-  if (stdlis != stderr && (ferror (stdlis) || fclose (stdlis) != 0))
-    FATAL_ERROR ((0, 0, _("Error in writing to standard output")));
+  if (stdlis == stdout)
+    close_stdout ();
+
   if (exit_status == TAREXIT_FAILURE)
     error (0, 0, _("Error exit delayed from previous errors"));
   if (ferror (stderr) || fclose (stderr) != 0)
This page took 0.032809 seconds and 4 git commands to generate.