home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / tar-1.11.8-src.tgz / tar.out / fsf / tar / src / tar.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  44KB  |  1,694 lines

  1. /* Tar -- a tape archiver.
  2.    Copyright (C) 1988, 1992, 1993, 1994 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GNU Tar.
  5.  
  6.    GNU Tar is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    GNU Tar is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with GNU Tar; see the file COPYING.  If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* A tar (tape archiver) program.
  21.    Written by John Gilmore, starting 25 Aug 85.  */
  22.  
  23. #include "system.h"
  24.  
  25. #ifndef FNM_LEADING_DIR
  26. # include <fnmatch.h>
  27. #endif
  28.  
  29. #ifndef S_ISLNK
  30. # define lstat stat
  31. #endif
  32.  
  33. #if WITH_REGEX
  34. # include <regex.h>
  35. #else
  36. # include <rx.h>
  37. #endif
  38.  
  39. /* The following causes "tar.h" to produce definitions of all the global
  40.    variables, rather than just "extern" declarations of them.  */
  41. #define GLOBAL
  42. #include "tar.h"
  43.  
  44. /* We should use a conversion routine that does reasonable error checking
  45.    -- atoi doesn't.  For now, punt.  FIXME.  */
  46.  
  47. #define intconv    atoi
  48.  
  49. time_t get_date ();
  50.  
  51. /* Local declarations.  */
  52.  
  53. #ifndef DEFAULT_ARCHIVE
  54. # define DEFAULT_ARCHIVE "tar.out"
  55. #endif
  56.  
  57. #ifndef DEFAULT_BLOCKING
  58. # define DEFAULT_BLOCKING 20
  59. #endif
  60.  
  61. time_t new_time;
  62.  
  63. /* Miscellaneous.  */
  64.  
  65. /*-------------------------------------------------------------------------.
  66. | Assign STRING to a copy of VALUE if not NULL, or to NULL.  If STRING was |
  67. | not NULL, it is freed first.                           |
  68. `-------------------------------------------------------------------------*/
  69.  
  70. void
  71. assign_string (char **string, const char *value)
  72. {
  73.   if (*string)
  74.     free (*string);
  75.   *string = value ? xstrdup (value) : NULL;
  76. }
  77.  
  78. /*-----------------------------------------------------------------.
  79. | Returns non-zero if the luser typed 'y' or 'Y', zero otherwise.  |
  80. `-----------------------------------------------------------------*/
  81.  
  82. int
  83. confirm (const char *action, const char *file)
  84. {
  85.   int c, nl;
  86.   static FILE *confirm_file = 0;
  87.  
  88.   fprintf (stdlis, "%s %s?", action, file);
  89.   fflush (stdlis);
  90.   if (!confirm_file)
  91.     {
  92.       confirm_file = (archive == 0) ? fopen (TTY_NAME, "r") : stdin;
  93.       if (!confirm_file)
  94.     ERROR ((TAREXIT_FAILURE, 0, _("Cannot read confirmation from user")));
  95.     }
  96.   c = getc (confirm_file);
  97.   for (nl = c; nl != '\n' && nl != EOF; nl = getc (confirm_file))
  98.     ;
  99.   return c == 'y' || c == 'Y';
  100. }
  101.  
  102. /* Names from the command call.  */
  103.  
  104. static const char **name_array;    /* store an array of names */
  105. static int allocated_names;    /* how big is the array? */
  106. static int names;        /* how many entries does it have? */
  107. static int name_index = 0;    /* how many of the entries have we scanned? */
  108.  
  109. /*--------------------------------------------------------------.
  110. | Add NAME at end of name_array, reallocating it as necessary.  |
  111. `--------------------------------------------------------------*/
  112.  
  113. static void
  114. name_add (const char *name)
  115. {
  116.   if (names == allocated_names)
  117.     {
  118.       allocated_names *= 2;
  119.       name_array = (const char **)
  120.     xrealloc (name_array, sizeof (const char *) * allocated_names);
  121.     }
  122.   name_array[names++] = name;
  123. }
  124.  
  125. /* Names from external name file.  */
  126.  
  127. static FILE *name_file;        /* file to read names from */
  128. static char *const *names_argv;    /* argv used by name routines */
  129. static int names_argc;        /* argc used by name routines */
  130.  
  131. static char *name_buffer;    /* buffer to hold the current file name */
  132. static size_t name_buffer_length; /* allocated length of name_buffer */
  133.  
  134. /*-------------------------------------------------------------------------.
  135. | Set up to gather file names for tar.  They can either come from stdin or |
  136. | from argv.                                   |
  137. `-------------------------------------------------------------------------*/
  138.  
  139. static void
  140. name_init (int argc, char *const *argv)
  141. {
  142.   if (flag_namefile)
  143.     {
  144.       if (optind < argc)
  145.     ERROR ((TAREXIT_FAILURE, 0, _("Too many args with -T option")));
  146.  
  147.       if (!strcmp (namefile_name, "-"))
  148.     name_file = stdin;
  149.       else if (name_file = fopen (namefile_name, "r"), !name_file)
  150.     ERROR ((TAREXIT_FAILURE, errno, _("Cannot open file %s"), name_file));
  151.     }
  152.   else
  153.     {
  154.  
  155.       /* Get file names from argv, after options. */
  156.  
  157.       names_argc = argc;
  158.       names_argv = argv;
  159.     }
  160. }
  161.  
  162. /*---------------------------------------------------------------------.
  163. | Read the next filename from name_file and null-terminate it.  Put it |
  164. | into name_buffer, reallocating and adjusting name_buffer_length if   |
  165. | necessary.  Return 0 at end of file, 1 otherwise.               |
  166. `---------------------------------------------------------------------*/
  167.  
  168. static int
  169. read_name_from_file (void)
  170. {
  171.   register int c;
  172.   register int counter = 0;
  173.  
  174.   /* FIXME: getc may be called even if c was EOF the last time here.  */
  175.  
  176.   /* FIXME: This + 2 allocation might serve no purpose.  */
  177.  
  178.   while (c = getc (name_file), c != EOF && c != filename_terminator)
  179.     {
  180.       if (counter == name_buffer_length)
  181.     {
  182.       name_buffer_length += NAMSIZ;
  183.       name_buffer = xrealloc (name_buffer, name_buffer_length + 2);
  184.     }
  185.       name_buffer[counter++] = c;
  186.     }
  187.   if (counter == 0 && c == EOF)
  188.     return 0;
  189.   if (counter == name_buffer_length)
  190.     {
  191.       name_buffer_length += NAMSIZ;
  192.       name_buffer = xrealloc (name_buffer, name_buffer_length + 2);
  193.     }
  194.   name_buffer[counter] = '\0';
  195.   return 1;
  196. }
  197.  
  198. /*-------------------------------------------------------------------------.
  199. | Get the next name from argv or the name file.  Result is in static       |
  200. | storage and can't be relied upon across two calls.               |
  201. |                                        |
  202. | If CHANGE_DIRS is non-zero, treat a filename of the form "-C" as meaning |
  203. | that the next filename is the name of a directory to change to.  If       |
  204. | `filename_terminator' is '\0', CHANGE_DIRS is effectively always 0.       |
  205. `-------------------------------------------------------------------------*/
  206.  
  207. char *
  208. name_next (int change_dirs)
  209. {
  210.   const char *source;
  211.   char *cursor;
  212.   int chdir_flag = 0;
  213.  
  214.   if (filename_terminator == '\0')
  215.     change_dirs = 0;
  216.  
  217.   if (name_file)
  218.     {
  219.  
  220.       /* Read from file.  */
  221.  
  222.       while (read_name_from_file ())
  223.     if (*name_buffer)    /* ignore emtpy lines */
  224.       {
  225.  
  226.         /* Zap trailing slashes.  */
  227.  
  228.         cursor = name_buffer + strlen (name_buffer) - 1;
  229.         while (cursor > name_buffer && *cursor == '/')
  230.           *cursor-- = '\0';
  231.  
  232.         if (chdir_flag)
  233.           {
  234.         if (chdir (name_buffer) < 0)
  235.           ERROR ((TAREXIT_FAILURE, errno,
  236.               _("Cannot change to directory %s"), name_buffer));
  237.         chdir_flag = 0;
  238.           }
  239.         else if (change_dirs && strcmp (name_buffer, "-C") == 0)
  240.           chdir_flag = 1;
  241.         else
  242. #if 0
  243.           if (!flag_exclude || !check_exclude (name_buffer))
  244. #endif
  245.         return un_quote_string (name_buffer);
  246.       }
  247.  
  248.       /* No more names in file.  */
  249.  
  250.     }
  251.   else
  252.     {
  253.  
  254.       /* Read from argv, after options.  */
  255.  
  256.       while (1)
  257.     {
  258.       if (name_index < names)
  259.         source = name_array[name_index++];
  260.       else if (optind < names_argc)
  261.         source = names_argv[optind++];
  262.       else
  263.         break;
  264.  
  265.       if (strlen (source) > name_buffer_length)
  266.         {
  267.           free (name_buffer);
  268.           name_buffer_length = strlen (source);
  269.           name_buffer = xmalloc (name_buffer_length + 2);
  270.         }
  271.       strcpy (name_buffer, source);
  272.  
  273.       /* Zap trailing slashes.  */
  274.  
  275.       cursor = name_buffer + strlen (name_buffer) - 1;
  276.       while (cursor > name_buffer && *cursor == '/')
  277.         *cursor-- = '\0';
  278.  
  279.       if (chdir_flag)
  280.         {
  281.           if (chdir (name_buffer) < 0)
  282.         ERROR ((TAREXIT_FAILURE, errno,
  283.             _("Cannot chdir to %s"), name_buffer));
  284.           chdir_flag = 0;
  285.         }
  286.       else if (change_dirs && strcmp (name_buffer, "-C") == 0)
  287.         chdir_flag = 1;
  288.       else
  289. #if 0
  290.         if (!flag_exclude || !check_exclude (name_buffer))
  291. #endif
  292.           return un_quote_string (name_buffer);
  293.     }
  294.     }
  295.  
  296.   if (chdir_flag)
  297.     ERROR ((TAREXIT_FAILURE, 0, _("Missing filename after -C")));
  298.   return NULL;
  299. }
  300.  
  301. /*------------------------------.
  302. | Close the name file, if any.  |
  303. `------------------------------*/
  304.  
  305. void
  306. name_close (void)
  307. {
  308.   if (name_file != NULL && name_file != stdin)
  309.     fclose (name_file);
  310. }
  311.  
  312. /*-------------------------------------------------------------------------.
  313. | Gather names in a list for scanning.  Could hash them later if we really |
  314. | care.                                       |
  315. |                                        |
  316. | If the names are already sorted to match the archive, we just read them  |
  317. | one by one.  name_gather reads the first one, and it is called by       |
  318. | name_match as appropriate to read the next ones.  At EOF, the last name  |
  319. | read is just left in the buffer.  This option lets users of small       |
  320. | machines extract an arbitrary number of files by doing "tar t" and       |
  321. | editing down the list of files.                       |
  322. `-------------------------------------------------------------------------*/
  323.  
  324. void
  325. name_gather (void)
  326. {
  327.   register char *p;
  328.   static struct name *namebuf;    /* one-name buffer */
  329.   static namelen;
  330.   static char *chdir_name = NULL;
  331.  
  332.   if (flag_sorted_names)
  333.     {
  334.       if (!namelen)
  335.     {
  336.       namelen = NAMSIZ;
  337.       namebuf = (struct name *) xmalloc (sizeof (struct name) + NAMSIZ);
  338.     }
  339.       p = name_next (0);
  340.       if (p)
  341.     {
  342.       if (strcmp (p, "-C") == 0)
  343.         {
  344.           chdir_name = xstrdup (name_next (0));
  345.           p = name_next (0);
  346.           if (!p)
  347.         ERROR ((TAREXIT_FAILURE, 0, _("Missing file name after -C")));
  348.           namebuf->change_dir = chdir_name;
  349.         }
  350.       namebuf->length = strlen (p);
  351.       if (namebuf->length >= namelen)
  352.         {
  353.           namebuf = (struct name *)
  354.         xrealloc (namebuf, sizeof (struct name) + namebuf->length);
  355.           namelen = namebuf->length;
  356.         }
  357.       strncpy (namebuf->name, p, (size_t) namebuf->length);
  358.       namebuf->name[namebuf->length] = 0;
  359.       namebuf->next = (struct name *) NULL;
  360.       namebuf->found = 0;
  361.       namelist = namebuf;
  362.       namelast = namelist;
  363.     }
  364.       return;
  365.     }
  366.  
  367.   /* Non sorted names -- read them all in.  */
  368.  
  369.   while (p = name_next (0), p)
  370.     addname (p);
  371. }
  372.  
  373. /*-----------------------------.
  374. | Add a name to the namelist.  |
  375. `-----------------------------*/
  376.  
  377. void
  378. addname (const char *name)
  379. {
  380.   register int i;        /* length of string */
  381.   register struct name *p;    /* current struct pointer */
  382.   static char *chdir_name = NULL;
  383.  
  384.   if (strcmp (name, "-C") == 0)
  385.     {
  386.       chdir_name = xstrdup (name_next (0));
  387.       name = name_next (0);
  388.       if (!chdir_name)
  389.     ERROR ((TAREXIT_FAILURE, 0, _("Missing file name after -C")));
  390.       if (chdir_name[0] != '/')
  391.     {
  392.       char *path = xmalloc (PATH_MAX);
  393. #ifdef HAVE_GETCWD
  394.       if (!getcwd (path, PATH_MAX))
  395.         ERROR ((TAREXIT_FAILURE, 0, _("Could not get current directory")));
  396. #else
  397.       char *getwd ();
  398.  
  399.       if (!getwd (path))
  400.         ERROR ((TAREXIT_FAILURE, 0,
  401.             _("Could not get current directory: %s"), path));
  402. #endif
  403.       chdir_name = xstrdup (new_name (path, chdir_name));
  404.       free (path);
  405.     }
  406.     }
  407.  
  408.   i = name ? strlen (name) : 0;
  409.   p = (struct name *) xmalloc ((unsigned) (sizeof (struct name) + i));
  410.   p->next = (struct name *) NULL;
  411.   if (name)
  412.     {
  413.       p->fake = 0;
  414.       p->length = i;
  415.       strncpy (p->name, name, (size_t) i);
  416.       p->name[i] = '\0';    /* null term */
  417.     }
  418.   else
  419.     p->fake = 1;
  420.   p->found = 0;
  421.   p->regexp = 0;        /* assume not a regular expression */
  422.   p->firstch = 1;        /* assume first char is literal */
  423.   p->change_dir = chdir_name;
  424.   p->dir_contents = 0;        /* JF */
  425.   if (name)
  426.     {
  427.       if (strchr (name, '*') || strchr (name, '[') || strchr (name, '?'))
  428.     {
  429.       p->regexp = 1;    /* no, it's a regexp */
  430.       if (name[0] == '*' || name[0] == '[' || name[0] == '?')
  431.         p->firstch = 0;    /* not even 1st char literal */
  432.     }
  433.     }
  434.  
  435.   if (namelast)
  436.     namelast->next = p;
  437.   namelast = p;
  438.   if (!namelist)
  439.     namelist = p;
  440. }
  441.  
  442. /*---------------------------------------------------------------------.
  443. | Return nonzero if name P (from an archive) matches any name from the |
  444. | namelist, zero if not.                           |
  445. `---------------------------------------------------------------------*/
  446.  
  447. int
  448. name_match (register const char *p)
  449. {
  450.   register struct name *nlp;
  451.   register int len;
  452.  
  453. again:
  454.   if (nlp = namelist, !nlp)    /* empty namelist is easy */
  455.     return 1;
  456.   if (nlp->fake)
  457.     {
  458.       if (nlp->change_dir && chdir (nlp->change_dir))
  459.     ERROR ((TAREXIT_FAILURE, errno,
  460.         _("Cannot change to directory %s"), nlp->change_dir));
  461.       namelist = 0;
  462.       return 1;
  463.     }
  464.   len = strlen (p);
  465.   for (; nlp != 0; nlp = nlp->next)
  466.     {
  467.  
  468.       /* If first chars don't match, quick skip.  */
  469.  
  470.       if (nlp->firstch && nlp->name[0] != p[0])
  471.     continue;
  472.  
  473.       /* Regular expressions (shell globbing, actually).  */
  474.  
  475.       if (nlp->regexp)
  476.     {
  477.       if (fnmatch (nlp->name, p, FNM_LEADING_DIR) == 0)
  478.         {
  479.           nlp->found = 1;    /* remember it matched */
  480.           if (flag_startfile)
  481.         {
  482.           free ((void *) namelist);
  483.           namelist = 0;
  484.         }
  485.           if (nlp->change_dir && chdir (nlp->change_dir))
  486.         ERROR ((TAREXIT_FAILURE, errno,
  487.             _("Cannot change to directory %s"), nlp->change_dir));
  488.  
  489.           /* We got a match.  */
  490.           return 1;    
  491.         }
  492.       continue;
  493.     }
  494.  
  495.       /* Plain Old Strings.  */
  496.  
  497.       if (nlp->length <= len    /* archive len >= specified */
  498.       && (p[nlp->length] == '\0' || p[nlp->length] == '/')
  499.                 /* full match on file/dirname */
  500.       && strncmp (p, nlp->name, (size_t) nlp->length) == 0)
  501.                 /* name compare */
  502.     {
  503.       nlp->found = 1;    /* remember it matched */
  504.       if (flag_startfile)
  505.         {
  506.           free ((void *) namelist);
  507.           namelist = 0;
  508.         }
  509.       if (nlp->change_dir && chdir (nlp->change_dir))
  510.         ERROR ((TAREXIT_FAILURE, errno,
  511.             _("Cannot change to directory %s"), nlp->change_dir));
  512.  
  513.       /* We got a match.  */
  514.       return 1;
  515.     }
  516.     }
  517.  
  518.   /* Filename from archive not found in namelist.  If we have the whole
  519.      namelist here, just return 0.  Otherwise, read the next name in and
  520.      compare it.  If this was the last name, namelist->found will remain
  521.      on.  If not, we loop to compare the newly read name.  */
  522.  
  523.   if (flag_sorted_names && namelist->found)
  524.     {
  525.       name_gather ();        /* read one more */
  526.       if (!namelist->found)
  527.     goto again;
  528.     }
  529.   return 0;
  530. }
  531.  
  532. /*------------------------------------------------------------------.
  533. | Print the names of things in the namelist that were not matched.  |
  534. `------------------------------------------------------------------*/
  535.  
  536. void
  537. names_notfound (void)
  538. {
  539.   register struct name *nlp, *next;
  540.   register char *p;
  541.  
  542.   for (nlp = namelist; nlp != 0; nlp = next)
  543.     {
  544.       next = nlp->next;
  545.       if (!nlp->found)
  546.     ERROR ((0, 0, _("%s: Not found in archive"), nlp->name));
  547.  
  548.       /* We could free() the list, but the process is about to die
  549.      anyway, so save some CPU time.  Amigas and other similarly
  550.      broken software will need to waste the time, though.  */
  551.  
  552. #ifdef amiga
  553.       if (!flag_sorted_names)
  554.     free (nlp);
  555. #endif
  556.     }
  557.   namelist = (struct name *) NULL;
  558.   namelast = (struct name *) NULL;
  559.  
  560.   if (flag_sorted_names)
  561.     {
  562.       while (p = name_next (1), p)
  563.     ERROR ((0, 0, _("%s: Not found in archive"), p));
  564.     }
  565. }
  566.  
  567. /* These next routines were created by JF */
  568.  
  569. /*---.
  570. | ?  |
  571. `---*/
  572.  
  573. void
  574. name_expand (void)
  575. {
  576.   ;
  577. }
  578.  
  579. /*------------------------------------------------------------------------.
  580. | This is like name_match(), except that it returns a pointer to the name |
  581. | it matched, and doesn't set ->found The caller will have to do that if  |
  582. | it wants to.  Oh, and if the namelist is empty, it returns 0, unlike      |
  583. | name_match(), which returns TRUE                      |
  584. `------------------------------------------------------------------------*/
  585.  
  586. struct name *
  587. name_scan (register const char *p)
  588. {
  589.   register struct name *nlp;
  590.   register int len;
  591.  
  592. again:
  593.   if (nlp = namelist, !nlp)    /* empty namelist is easy */
  594.     return 0;
  595.   len = strlen (p);
  596.   for (; nlp != 0; nlp = nlp->next)
  597.     {
  598.  
  599.       /* If first chars don't match, quick skip.  */
  600.  
  601.       if (nlp->firstch && nlp->name[0] != p[0])
  602.     continue;
  603.  
  604.       /* Regular expressions.  */
  605.  
  606.       if (nlp->regexp)
  607.     {
  608.       if (fnmatch (nlp->name, p, FNM_LEADING_DIR) == 0)
  609.         return nlp;        /* we got a match */
  610.       continue;
  611.     }
  612.  
  613.       /* Plain Old Strings.  */
  614.  
  615.       if (nlp->length <= len    /* archive len >= specified */
  616.       && (p[nlp->length] == '\0' || p[nlp->length] == '/')
  617.                 /* full match on file/dirname */
  618.       && strncmp (p, nlp->name, (size_t) nlp->length) == 0)
  619.                 /* name compare */
  620.     return nlp;        /* we got a match */
  621.     }
  622.  
  623.   /* Filename from archive not found in namelist.  If we have the whole
  624.      namelist here, just return 0.  Otherwise, read the next name in and
  625.      compare it.  If this was the last name, namelist->found will remain
  626.      on.  If not, we loop to compare the newly read name.  */
  627.  
  628.   if (flag_sorted_names && namelist->found)
  629.     {
  630.       name_gather ();        /* read one more */
  631.       if (!namelist->found)
  632.     goto again;
  633.     }
  634.   return NULL;
  635. }
  636.  
  637. /*-----------------------------------------------------------------------.
  638. | This returns a name from the namelist which doesn't have ->found set.     |
  639. | It sets ->found before returning, so successive calls will find and     |
  640. | return all the non-found names in the namelist             |
  641. `-----------------------------------------------------------------------*/
  642.  
  643. struct name *gnu_list_name;
  644.  
  645. char *
  646. name_from_list (void)
  647. {
  648.   if (!gnu_list_name)
  649.     gnu_list_name = namelist;
  650.   while (gnu_list_name && gnu_list_name->found)
  651.     gnu_list_name = gnu_list_name->next;
  652.   if (gnu_list_name)
  653.     {
  654.       gnu_list_name->found++;
  655.       if (gnu_list_name->change_dir)
  656.     if (chdir (gnu_list_name->change_dir) < 0)
  657.       ERROR ((TAREXIT_FAILURE, errno, _("Cannot chdir to %s"),
  658.           gnu_list_name->change_dir));
  659.       return gnu_list_name->name;
  660.     }
  661.   return NULL;
  662. }
  663.  
  664. /*---.
  665. | ?  |
  666. `---*/
  667.  
  668. void
  669. blank_name_list (void)
  670. {
  671.   struct name *n;
  672.  
  673.   gnu_list_name = 0;
  674.   for (n = namelist; n; n = n->next)
  675.     n->found = 0;
  676. }
  677.  
  678. /*---.
  679. | ?  |
  680. `---*/
  681.  
  682. char *
  683. new_name (char *path, char *name)
  684. {
  685.   char *path_buf;
  686.  
  687.   path_buf = (char *) xmalloc (strlen (path) + strlen (name) + 2);
  688.   sprintf (path_buf, "%s/%s", path, name);
  689.   return path_buf;
  690. }
  691.  
  692. /* Excludes.  */
  693.  
  694. char *x_buffer = NULL;
  695. int size_x_buffer;
  696. int free_x_buffer;
  697.  
  698. char **exclude = NULL;
  699. int size_exclude = 0;
  700. int free_exclude = 0;
  701.  
  702. char **re_exclude = NULL;
  703. int size_re_exclude = 0;
  704. int free_re_exclude = 0;
  705.  
  706. /*---.
  707. | ?  |
  708. `---*/
  709.  
  710. static int
  711. is_regex (const char *str)
  712. {
  713.   return strchr (str, '*') || strchr (str, '[') || strchr (str, '?');
  714. }
  715.  
  716. /*---.
  717. | ?  |
  718. `---*/
  719.  
  720. static void
  721. add_exclude (char *name)
  722. {
  723.   int size_buf;
  724.  
  725.   un_quote_string (name);
  726.   size_buf = strlen (name);
  727.  
  728.   if (x_buffer == 0)
  729.     {
  730.       x_buffer = (char *) xmalloc ((size_t) (size_buf + 1024));
  731.       free_x_buffer = 1024;
  732.     }
  733.   else if (free_x_buffer <= size_buf)
  734.     {
  735.       char *old_x_buffer;
  736.       char **tmp_ptr;
  737.  
  738.       old_x_buffer = x_buffer;
  739.       x_buffer = (char *) xrealloc (x_buffer, (size_t) (size_x_buffer + 1024));
  740.       free_x_buffer = 1024;
  741.       for (tmp_ptr = exclude; tmp_ptr < exclude + size_exclude; tmp_ptr++)
  742.     *tmp_ptr = x_buffer + ((*tmp_ptr) - old_x_buffer);
  743.       for (tmp_ptr = re_exclude;
  744.        tmp_ptr < re_exclude + size_re_exclude;
  745.        tmp_ptr++)
  746.     *tmp_ptr = x_buffer + ((*tmp_ptr) - old_x_buffer);
  747.     }
  748.  
  749.   if (is_regex (name))
  750.     {
  751.       if (free_re_exclude == 0)
  752.     {
  753.       re_exclude = (char **)
  754.         xrealloc (re_exclude, (size_re_exclude + 32) * sizeof (char *));
  755.       free_re_exclude += 32;
  756.     }
  757.       re_exclude[size_re_exclude] = x_buffer + size_x_buffer;
  758.       size_re_exclude++;
  759.       free_re_exclude--;
  760.     }
  761.   else
  762.     {
  763.       if (free_exclude == 0)
  764.     {
  765.       exclude = (char **)
  766.         xrealloc (exclude, (size_exclude + 32) * sizeof (char *));
  767.       free_exclude += 32;
  768.     }
  769.       exclude[size_exclude] = x_buffer + size_x_buffer;
  770.       size_exclude++;
  771.       free_exclude--;
  772.     }
  773.   strcpy (x_buffer + size_x_buffer, name);
  774.   size_x_buffer += size_buf + 1;
  775.   free_x_buffer -= size_buf + 1;
  776. }
  777.  
  778. /*---.
  779. | ?  |
  780. `---*/
  781.  
  782. static void
  783. add_exclude_file (char *file)
  784. {
  785.   FILE *fp;
  786.   char buf[1024];
  787.  
  788.   if (strcmp (file, "-"))
  789.     fp = fopen (file, "r");
  790.   else
  791.  
  792.     /* Let's hope the person knows what they're doing.  Using -X - -T -
  793.        -f - will get you *really* strange results.  */
  794.  
  795.     fp = stdin;
  796.  
  797.   if (!fp)
  798.     ERROR ((TAREXIT_FAILURE, errno, _("Cannot open %s"), file));
  799.  
  800.   while (fgets (buf, 1024, fp))
  801.     {
  802. #if 0
  803.       int size_buf;
  804. #endif
  805.       char *end_str;
  806.  
  807.       end_str = strrchr (buf, '\n');
  808.       if (end_str)
  809.     *end_str = '\0';
  810.       add_exclude (buf);
  811.  
  812.     }
  813.   fclose (fp);
  814. }
  815.  
  816. /*--------------------------------------------------------------------.
  817. | Returns non-zero if the file 'name' should not be added/extracted.  |
  818. `--------------------------------------------------------------------*/
  819.  
  820. int
  821. check_exclude (const char *name)
  822. {
  823.   int n;
  824.   char *str;
  825.  
  826.   for (n = 0; n < size_re_exclude; n++)
  827.     {
  828.       if (fnmatch (re_exclude[n], name, FNM_LEADING_DIR) == 0)
  829.     return 1;
  830.     }
  831.   for (n = 0; n < size_exclude; n++)
  832.     {
  833.  
  834.       /* Accept the output from strstr only if it is the last part of the
  835.      string.  There is certainly a faster way to do this.  */
  836.  
  837.       if (str = strstr (name, exclude[n]),
  838.       (str && (str == name || str[-1] == '/')
  839.        && str[strlen (exclude[n])] == '\0'))
  840.     return 1;
  841.     }
  842.   return 0;
  843. }
  844.  
  845.  
  846. /* Options.  */
  847.  
  848. /* For long options that unconditionally set a single flag, we have getopt
  849.    do it.  For the others, we share the code for the equivalent short
  850.    named option, the name of which is stored in the otherwise-unused `val'
  851.    field of the `struct option'; for long options that have no equivalent
  852.    short option, we use nongraphic characters as pseudo short option
  853.    characters, starting (for no particular reason) with character 10. */
  854.  
  855. #define OPTION_PRESERVE        10
  856. #define OPTION_NEWER_MTIME    11
  857. #define OPTION_DELETE        12
  858. #define OPTION_EXCLUDE        13
  859. #define OPTION_NULL        14
  860. #define OPTION_VOLNO_FILE    15
  861. #define OPTION_COMPRESS_PROG    16
  862. #define OPTION_RSH_COMMAND    17
  863.  
  864. /* Some cleanup is made in GNU tar long options.  Using old names will send
  865.    a warning to stderr.  */
  866.  
  867. #define OBSOLETE_ABSOLUTE_NAMES    20 /* take it out in 1.14 */
  868.  
  869. /* If non-zero, display usage information and exit.  */
  870. static int show_help = 0;
  871.  
  872. /* If non-zero, print the version on standard output and exit.  */
  873. static int show_version = 0;
  874.  
  875. struct option long_options[] =
  876. {
  877.   {"absolute-names", no_argument, NULL, 'P'},
  878.   {"absolute-paths", no_argument, NULL, OBSOLETE_ABSOLUTE_NAMES},
  879.   {"after-date", required_argument, NULL, 'N'},
  880.   {"append", no_argument, NULL, 'r'},
  881.   {"atime-preserve", no_argument, &flag_atime_preserve, 1},
  882.   {"block-compress", no_argument, &flag_compress_block, 1},
  883.   {"block-size", required_argument, NULL, 'b'},
  884.   {"catenate", no_argument, NULL, 'A'},
  885.   {"checkpoint", no_argument, &flag_checkpoint, 1},
  886.   {"compare", no_argument, NULL, 'd'},
  887.   {"compress", no_argument, NULL, 'Z'},
  888.   {"concatenate", no_argument, NULL, 'A'},
  889.   {"confirmation", no_argument, NULL, 'w'},
  890.   {"create", no_argument, NULL, 'c'},
  891.   {"delete", no_argument, NULL, OPTION_DELETE},
  892.   {"dereference", no_argument, NULL, 'h'},
  893.   {"diff", no_argument, NULL, 'd'},
  894.   {"directory", required_argument, NULL, 'C'},
  895.   {"exclude", required_argument, NULL, OPTION_EXCLUDE},
  896.   {"exclude-from", required_argument, NULL, 'X'},
  897.   {"extract", no_argument, NULL, 'x'},
  898.   {"file", required_argument, NULL, 'f'},
  899.   {"files-from", required_argument, NULL, 'T'},
  900.   {"force-local", no_argument, &flag_force_local, 1},
  901.   {"get", no_argument, NULL, 'x'},
  902.   {"gunzip", no_argument, NULL, 'z'},
  903.   {"gzip", no_argument, NULL, 'z'},
  904.   {"help", no_argument, &show_help, 1},
  905.   {"ignore-failed-read", no_argument, &flag_ignore_failed_read, 1},
  906.   {"ignore-zeros", no_argument, NULL, 'i'},
  907.   {"incremental", no_argument, NULL, 'G'},
  908.   {"info-script", required_argument, NULL, 'F'},
  909.   {"interactive", no_argument, NULL, 'w'},
  910.   {"keep-old-files", no_argument, NULL, 'k'},
  911.   {"label", required_argument, NULL, 'V'},
  912.   {"list", no_argument, NULL, 't'},
  913.   {"listed-incremental", required_argument, NULL, 'g'},
  914.   {"modification-time", no_argument, NULL, 'm'},
  915.   {"multi-volume", no_argument, NULL, 'M'},
  916.   {"new-volume-script", required_argument, NULL, 'F'},
  917.   {"newer", required_argument, NULL, 'N'},
  918.   {"newer-mtime", required_argument, NULL, OPTION_NEWER_MTIME},
  919.   {"null", no_argument, NULL, OPTION_NULL},
  920.   {"old-archive", no_argument, NULL, 'o'},
  921.   {"one-file-system", no_argument, NULL, 'l'},
  922.   {"portability", no_argument, NULL, 'o'},
  923.   {"preserve", no_argument, NULL, OPTION_PRESERVE},
  924.   {"preserve-order", no_argument, NULL, 's'},
  925.   {"preserve-permissions", no_argument, NULL, 'p'},
  926.   {"read-full-blocks", no_argument, NULL, 'B'},
  927.   {"record-number", no_argument, NULL, 'R'},
  928.   {"remove-files", no_argument, &flag_remove_files, 1},
  929.   {"rsh-command", required_argument, NULL, OPTION_RSH_COMMAND},
  930.   {"same-order", no_argument, NULL, 's'},
  931.   {"same-owner", no_argument, &flag_do_chown, 1},
  932.   {"same-permissions", no_argument, NULL, 'p'},
  933.   {"show-omitted-dirs", no_argument, &flag_show_omitted_dirs, 1},
  934.   {"sparse", no_argument, NULL, 'S'},
  935.   {"starting-file", required_argument, NULL, 'K'},
  936.   {"tape-length", required_argument, NULL, 'L'},
  937.   {"to-stdout", no_argument, NULL, 'O'},
  938.   {"totals", no_argument, &flag_totals, 1},
  939.   {"uncompress", no_argument, NULL, 'Z'},
  940.   {"ungzip", no_argument, NULL, 'z'},
  941.   {"update", no_argument, NULL, 'u'},
  942.   {"use-compress-program", required_argument, NULL, OPTION_COMPRESS_PROG},
  943.   {"verbose", no_argument, NULL, 'v'},
  944.   {"verify", no_argument, NULL, 'W'},
  945.   {"version", no_argument, &show_version, 1},
  946.   {"volno-file", required_argument, NULL, OPTION_VOLNO_FILE},
  947.  
  948.   {0, 0, 0, 0}
  949. };
  950.  
  951. /*---------------------------------------------.
  952. | Print a usage message and exit with STATUS.  |
  953. `---------------------------------------------*/
  954.  
  955. static void
  956. usage (int status)
  957. {
  958.   if (status != TAREXIT_SUCCESS)
  959.     fprintf (stderr, _("Try `%s --help' for more information.\n"),
  960.          program_name);
  961.   else
  962.     {
  963.       printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);
  964.       fputs (_("\
  965. Mandatory or optional arguments to long options are mandatory or optional\n\
  966. for short options too.\n"),
  967.          stdout);
  968.       fputs(_("\
  969. \n\
  970. Main operation mode:\n\
  971.   -t, --list              list the contents of an archive\n\
  972.   -x, --extract, --get    extract files from an archive\n\
  973.   -c, --create            create a new archive\n\
  974.   -d, --diff, --compare   find differences between archive and file system\n\
  975.   -r, --append            append files to the end of an archive\n\
  976.   -u, --update            only append files newer than copy in archive\n\
  977.   -A, --catenate          append tar files to an archive\n\
  978.       --concatenate       same as -A\n\
  979.       --delete            delete from the archive (not on mag tapes!)\n"),
  980.         stdout);
  981.       fputs (_("\
  982. \n\
  983. Operation mode modificators:\n\
  984.   -W, --verify               attempt to verify the archive after writing it\n\
  985.       --remove-files         remove files after adding them to the archive\n\
  986.   -k, --keep-old-files       don't overwrite existing files from archive\n\
  987.   -S, --sparse               handle sparse files efficiently\n\
  988.   -O, --to-stdout            extract files to standard output\n\
  989.   -G, --incremental          handle old GNU-format incremental backup\n\
  990.   -g, --listed-incremental   handle new GNU-format incremental backup\n\
  991.       --ignore-failed-read   do not exit with non-zero on unreadable files\n"),
  992.          stdout);
  993.       fputs (_("\
  994. \n\
  995. Handling of file attributes:\n\
  996.       --atime-preserve         don't change access times on dumped files\n\
  997.   -m, --modification-time      don't extract file modified time\n\
  998.       --same-owner             create extracted files with the same ownership \n\
  999.   -p, --same-permissions       extract all protection information\n\
  1000.       --preserve-permissions   same as -p\n\
  1001.   -s, --same-order             sort names to extract to match archive\n\
  1002.       --preserve-order         same as -s\n\
  1003.       --preserve               same as both -p and -s\n"),
  1004.          stdout);
  1005.       fputs (_("\
  1006. \n\
  1007. Device selection and switching:\n\
  1008.   -f, --file=[HOSTNAME:]FILE     use archive file or device FILE on HOSTNAME\n\
  1009.       --force-local              archive file is local even if has a colon\n\
  1010.       --rsh-command=COMMAND      use remote COMMAND instead of rsh\n\
  1011.   -[0-7][lmh]                    specify drive and density\n\
  1012.   -M, --multi-volume             create/list/extract multi-volume archive\n\
  1013.   -L, --tape-length=NUM          change tape after writing NUM x 1024 bytes\n\
  1014.   -F, --info-script=FILE         run script at end of each tape (implies -M)\n\
  1015.       --new-volume-script=FILE   same as -F FILE\n"),
  1016.          stdout);
  1017.       fputs (_("\
  1018. \n\
  1019. Device blocking:\n\
  1020.   -b, --block-size=BLOCKS    block size of BLOCKS x 512 bytes\n\
  1021.       --block-compress       block the output of compression for tapes\n\
  1022.   -i, --ignore-zeros         ignore blocks of zeros in archive (means EOF)\n\
  1023.   -B, --read-full-blocks     reblock as we read (for reading 4.2BSD pipes)\n"),
  1024.          stdout);
  1025.       fputs (_("\
  1026. \n\
  1027. Archive format selection:\n\
  1028.   -V, --label=NAME                   create archive with volume name NAME\n\
  1029.   -o, --old-archive, --portability   write a V7 format archive (not ANSI)\n\
  1030.   -z, --gzip, --ungzip               filter the archive through gzip\n\
  1031.   -Z, --compress, --uncompress       filter the archive through compress\n\
  1032.       --use-compress-program=PROG    filter through PROG (must accept -d)\n"),
  1033.          stdout);
  1034.       fputs (_("\
  1035. \n\
  1036. Local file selection:\n\
  1037.   -C, --directory DIR        change to directory DIR\n\
  1038.   -T, --files-from=NAME      get names to extract or create from file NAME\n\
  1039.       --null                 -T reads null-terminated names, disable -C\n\
  1040.       --exclude=FILE         exclude file FILE\n\
  1041.   -X, --exclude-from=FILE    exclude files listed in FILE\n\
  1042.   -P, --absolute-paths       don't strip leading `/'s from file names\n\
  1043.   -h, --dereference          dump instead the files symlinks point to\n\
  1044.   -l, --one-file-system      stay in local file system when creating archive\n\
  1045.   -K, --starting-file=NAME   begin at file NAME in the archive\n"),
  1046.          stdout);
  1047. #ifndef MSDOS
  1048.       fputs (_("\
  1049.   -N, --newer=DATE           only store files newer than DATE\n\
  1050.       --after-date=DATE      same as -N\n"),
  1051.          stdout);
  1052. #endif
  1053.       fputs (_("\
  1054. \n\
  1055. Informative output:\n\
  1056.       --help            print this help, then exit\n\
  1057.       --version         print tar program version number, then exit\n\
  1058.   -v, --verbose         verbosely list files processed\n\
  1059.       --checkpoint      print directory names while reading the archive\n\
  1060.       --totals          print total bytes written while creating archive\n\
  1061.   -R, --record-number   show record number within archive with each message\n\
  1062.   -w, --interactive     ask for confirmation for every action\n\
  1063.       --confirmation    same as -w\n"),
  1064.          stdout);
  1065.       printf (_("\
  1066. \n\
  1067. On *this* particular tar, the defaults are -f %s and -b %d.\n"),
  1068.           DEFAULT_ARCHIVE, DEFAULT_BLOCKING);
  1069.     }
  1070.   exit (status);
  1071. }
  1072.  
  1073. /*----------------------------.
  1074. | Parse the options for tar.  |
  1075. `----------------------------*/
  1076.  
  1077. #define OPTION_STRING \
  1078.   "-01234567ABC:F:GK:L:MN:OPRST:V:WX:Zb:cdf:g:hiklmoprstuvwxz"
  1079.  
  1080. #define SET_COMMAND_MODE(Mode) \
  1081.   (command_mode = command_mode == COMMAND_NONE ? (Mode) : COMMAND_TOO_MANY)
  1082.  
  1083. static void
  1084. decode_options (int argc, char *const *argv)
  1085. {
  1086.   int optchar;            /* option letter */
  1087.  
  1088.   /* Set some default option values.  */
  1089.  
  1090.   blocking = DEFAULT_BLOCKING;
  1091.   flag_rsh_command = NULL;
  1092.  
  1093.   /* Convert old-style tar call by exploding option element and rearranging
  1094.      options accordingly.  */
  1095.  
  1096.   if (argc > 1 && argv[1][0] != '-')
  1097.     {
  1098.       int new_argc;        /* argc value for rearranged arguments */
  1099.       char **new_argv;        /* argv value for rearranged arguments */
  1100.       char *const *in;        /* cursor into original argv */
  1101.       char **out;        /* cursor into rearranged argv */
  1102.       const char *letter;    /* cursor into old option letters */
  1103.       char buffer[3];        /* constructed option buffer */
  1104.       const char *cursor;    /* cursor in OPTION_STRING */
  1105.  
  1106.       /* Initialize a constructed option.  */
  1107.  
  1108.       buffer[0] = '-';
  1109.       buffer[2] = '\0';
  1110.       
  1111.       /* Allocate a new argument array, and copy program name in it.  */
  1112.  
  1113.       new_argc = argc - 1 + strlen (argv[1]);
  1114.       new_argv = (char **) xmalloc (new_argc * sizeof (char *));
  1115.       in = argv;
  1116.       out = new_argv;
  1117.       *out++ = *in++;
  1118.  
  1119.       /* Copy each old letter option as a separate option, and have the
  1120.      corresponding argument moved next to it.  */
  1121.  
  1122.       for (letter = *in++; *letter; letter++)
  1123.     {
  1124.       buffer[1] = *letter;
  1125.       *out++ = xstrdup (buffer);
  1126.       cursor = strchr (OPTION_STRING, *letter);
  1127.       if (cursor && cursor[1] == ':')
  1128.         *out++ = *in++;
  1129.     }
  1130.  
  1131.       /* Copy all remaining options.  */
  1132.  
  1133.       while (in < argv + argc)
  1134.     *out++ = *in++;
  1135.  
  1136.       /* Replace the old option list by the new one.  */
  1137.  
  1138.       argc = new_argc;
  1139.       argv = new_argv;
  1140.     }
  1141.  
  1142.   /* Parse all options and non-options as they appear.  */
  1143.  
  1144.   while (optchar = getopt_long (argc, argv, OPTION_STRING, long_options, NULL),
  1145.      optchar != EOF)
  1146.     switch (optchar)
  1147.       {
  1148.       case '?':
  1149.     usage (TAREXIT_FAILURE);
  1150.  
  1151.       case 0:
  1152.     break;
  1153.  
  1154.       case 'C':
  1155.     name_add ("-C");
  1156.     /* Fall through.  */
  1157.  
  1158.       case 1:
  1159.     /* File name or non-parsed option, because of RETURN_IN_ORDER
  1160.        ordering triggerred by the leading dash in OPTION_STRING.  */
  1161.  
  1162.     name_add (optarg);
  1163.     break;
  1164.  
  1165.       case OPTION_PRESERVE:
  1166.     flag_use_protection = 1;
  1167.     flag_sorted_names = 1;
  1168.     break;
  1169.  
  1170. #ifndef MSDOS
  1171.       case OPTION_NEWER_MTIME:
  1172.     flag_new_files++;
  1173.     /* Fall through.  */
  1174.     /* FIXME: Something is wrong here!  */
  1175.  
  1176.       case 'N':
  1177.     /* Only write files newer than X.  */
  1178.  
  1179.     flag_new_files++;
  1180.     new_time = get_date (optarg, (voidstar) 0);
  1181.     if (new_time == (time_t) -1)
  1182.       ERROR ((TAREXIT_FAILURE, 0, _("Invalid date format `%s'"),
  1183.           optarg));
  1184.     break;
  1185. #endif /* not MSDOS */
  1186.  
  1187.       case OPTION_DELETE:
  1188.     SET_COMMAND_MODE (COMMAND_DELETE);
  1189.     break;
  1190.  
  1191.       case OPTION_EXCLUDE:
  1192.     flag_exclude++;
  1193.     add_exclude (optarg);
  1194.     break;
  1195.  
  1196.       case OPTION_NULL:
  1197.     filename_terminator = '\0';
  1198.     break;
  1199.  
  1200.       case OPTION_VOLNO_FILE:
  1201.     flag_volno_file = optarg;
  1202.     break;
  1203.  
  1204.       case OPTION_COMPRESS_PROG:
  1205.     if (flag_compressprog)
  1206.       ERROR ((TAREXIT_FAILURE, 0,
  1207.           _("Only one compression option permitted")));
  1208.     flag_compressprog = optarg;
  1209.     break;
  1210.  
  1211.       case OPTION_RSH_COMMAND:
  1212.     flag_rsh_command = optarg;
  1213.     break;
  1214.  
  1215.       case 'g':
  1216.     /* We are making a GNU dump; save directories at the beginning
  1217.        of the archive, and include in each directory its contents.  */
  1218.  
  1219.     if (flag_oldarch)
  1220.       usage (TAREXIT_FAILURE);
  1221.     flag_gnudump++;
  1222.     gnu_dumpfile = optarg;
  1223.     break;
  1224.  
  1225.       case '0':
  1226.       case '1':
  1227.       case '2':
  1228.       case '3':
  1229.       case '4':
  1230.       case '5':
  1231.       case '6':
  1232.       case '7':
  1233.  
  1234. #ifdef DEVICE_PREFIX
  1235.     {
  1236.       int device = optchar - '0';
  1237.       int density;
  1238.       static char buf[sizeof DEVICE_PREFIX + 10];
  1239.       char *cursor;
  1240.  
  1241.       density = getopt_long (argc, argv, "lmh", NULL, NULL);
  1242.       strcpy (buf, DEVICE_PREFIX);
  1243.       cursor = buf + strlen (buf);
  1244.  
  1245. #ifdef DENSITY_LETTER
  1246.  
  1247.       sprintf (cursor, "%d%c", device, density);
  1248.  
  1249. #else /* not DENSITY_LETTER */
  1250.  
  1251.       switch (density)
  1252.         {
  1253.         case 'l':
  1254. #ifdef LOW_NUM
  1255.           device += LOW_NUM;
  1256. #endif
  1257.           break;
  1258.  
  1259.         case 'm':
  1260. #ifdef MID_NUM
  1261.           device += MID_NUM;
  1262. #else
  1263.           device += 8;
  1264. #endif
  1265.           break;
  1266.  
  1267.         case 'h':
  1268. #ifdef HGH_NUM
  1269.           device += HGH_NUM;
  1270. #else
  1271.           device += 16;
  1272. #endif
  1273.           break;
  1274.  
  1275.         default:
  1276.           usage (TAREXIT_FAILURE);
  1277.         }
  1278.       sprintf (cursor, "%d", device);
  1279.  
  1280. #endif /* not DENSITY_LETTER */
  1281.  
  1282.       if (archive_names == allocated_archive_names)
  1283.         {
  1284.           allocated_archive_names *= 2;
  1285.           archive_name_array = (const char **)
  1286.         xrealloc (archive_name_array,
  1287.               sizeof (const char *) * allocated_archive_names);
  1288.         }
  1289.       archive_name_array[archive_names++] = buf;
  1290.       /* FIXME: How comes this works for many archives when buf is
  1291.          not xstrdup'ed?  */
  1292.     }
  1293.     break;
  1294.  
  1295. #else /* not DEVICE_PREFIX */
  1296.  
  1297.     ERROR ((0, 0, _("Options [0-7][lmh] not supported by *this* tar")));
  1298.     usage (TAREXIT_FAILURE);
  1299.  
  1300. #endif /* not DEVICE_PREFIX */
  1301.  
  1302.       case 'A':
  1303.     SET_COMMAND_MODE (COMMAND_CAT);
  1304.     break;
  1305.  
  1306.       case 'b':
  1307.     /* Set blocking factor.  */
  1308.  
  1309.     blocking = intconv (optarg);
  1310.     break;
  1311.  
  1312.       case 'B':
  1313.     /* Try to reblock input.  For reading 4.2BSD pipes.  */
  1314.  
  1315.     flag_reblock++;
  1316.     break;
  1317.  
  1318.       case 'c':
  1319.     SET_COMMAND_MODE (COMMAND_CREATE);
  1320.     break;
  1321.  
  1322. #if 0
  1323.       case 'C':
  1324.     if (chdir (optarg) < 0)
  1325.       ERROR ((TAREXIT_FAILURE, errno,
  1326.           _("Cannot change directory to %d"), optarg));
  1327.     break;
  1328. #endif
  1329.  
  1330.       case 'd':
  1331.     SET_COMMAND_MODE (COMMAND_DIFF);
  1332.     break;
  1333.  
  1334.       case 'f':
  1335.     if (archive_names == allocated_archive_names)
  1336.       {
  1337.         allocated_archive_names *= 2;
  1338.         archive_name_array = (const char **)
  1339.           xrealloc (archive_name_array,
  1340.             sizeof (const char *) * allocated_archive_names);
  1341.       }
  1342.     archive_name_array[archive_names++] = optarg;
  1343.     break;
  1344.  
  1345.       case 'F':
  1346.     /* Since -F is only useful with -M, make it implied.  Run this
  1347.        script at the end of each tape.  */
  1348.  
  1349.     flag_run_script_at_end++;
  1350.     info_script = optarg;
  1351.     flag_multivol++;
  1352.     break;
  1353.  
  1354.       case 'G':
  1355.     /* We are making a GNU dump; save directories at the beginning
  1356.        of the archive, and include in each directory its contents  */
  1357.  
  1358.     if (flag_oldarch)
  1359.       usage (TAREXIT_FAILURE);
  1360.     flag_gnudump++;
  1361.     gnu_dumpfile = 0;
  1362.     break;
  1363.  
  1364.       case 'h':
  1365.     /* Follow symbolic links.  */
  1366.  
  1367.     flag_follow_links++;
  1368.     break;
  1369.  
  1370.       case 'i':
  1371.     /* Ignore zero records (eofs).  This can't be the default,
  1372.        because Unix tar writes two records of zeros, then pads out
  1373.        the block with garbage.  */
  1374.  
  1375.     flag_ignorez++;
  1376.     break;
  1377.  
  1378.       case 'k':
  1379.     /* Don't overwrite files.  */
  1380.  
  1381. #ifdef NO_OPEN3
  1382.     ERROR ((TAREXIT_FAILURE, 0,
  1383.         _("Cannot keep old files on this system")));
  1384. #else
  1385.     flag_keep++;
  1386. #endif
  1387.     break;
  1388.  
  1389.       case 'K':
  1390.     flag_startfile++;
  1391.     addname (optarg);
  1392.     break;
  1393.  
  1394.       case 'l':
  1395.     /* When dumping directories, don't dump files/subdirectories
  1396.        that are on other filesystems.  */
  1397.  
  1398.     flag_local_filesys++;
  1399.     break;
  1400.  
  1401.       case 'L':
  1402.     tape_length = intconv (optarg);
  1403.     flag_multivol++;
  1404.     break;
  1405.  
  1406.       case 'm':
  1407.     flag_modified++;
  1408.     break;
  1409.  
  1410.       case 'M':
  1411.     /* Make multivolume archive: when we can't write any more into
  1412.        the archive, re-open it, and continue writing.  */
  1413.  
  1414.     flag_multivol++;
  1415.     break;
  1416.  
  1417.       case 'o':
  1418.     /* Generate old archive.  */
  1419.  
  1420.     if (flag_gnudump
  1421. #if 0
  1422.         || flag_dironly
  1423. #endif
  1424.       )
  1425.       usage (TAREXIT_FAILURE);
  1426.     flag_oldarch++;
  1427.     break;
  1428.  
  1429.       case 'O':
  1430.     flag_exstdout++;
  1431.     break;
  1432.  
  1433.       case 'p':
  1434.     flag_use_protection++;
  1435.     break;
  1436.  
  1437.       case OBSOLETE_ABSOLUTE_NAMES:
  1438.     WARN ((0, 0, _("Obsolete option name replaced by --absolute-names")));
  1439.     /* Fall through.  */
  1440.  
  1441.       case 'P':
  1442.     flag_absolute_names++;
  1443.     break;
  1444.  
  1445.       case 'r':
  1446.     SET_COMMAND_MODE (COMMAND_APPEND);
  1447.     break;
  1448.  
  1449.       case 'R':
  1450.     /* Print block numbers for debug of bad tar archives.  */
  1451.  
  1452.     flag_sayblock++;
  1453.     break;
  1454.  
  1455.       case 's':
  1456.     /* Names to extr are sorted.  */
  1457.  
  1458.     flag_sorted_names++;
  1459.     break;
  1460.  
  1461.       case 'S':
  1462.     /* Deal with sparse files.  */
  1463.  
  1464.     flag_sparse_files++;
  1465.     break;
  1466.  
  1467.       case 't':
  1468.     SET_COMMAND_MODE (COMMAND_LIST);
  1469.  
  1470.     /* "t" output == "cv" or "xv".  */
  1471.  
  1472.     flag_verbose++;
  1473.     break;
  1474.  
  1475.       case 'T':
  1476.     namefile_name = optarg;
  1477.     flag_namefile++;
  1478.     break;
  1479.  
  1480.       case 'u':
  1481.     SET_COMMAND_MODE (COMMAND_UPDATE);
  1482.     break;
  1483.  
  1484.       case 'v':
  1485.     flag_verbose++;
  1486.     break;
  1487.  
  1488.       case 'V':
  1489.     flag_volhdr = optarg;
  1490.     break;
  1491.  
  1492.       case 'w':
  1493.     flag_confirm++;
  1494.     break;
  1495.  
  1496.       case 'W':
  1497.     flag_verify++;
  1498.     break;
  1499.  
  1500.       case 'x':
  1501.     SET_COMMAND_MODE (COMMAND_EXTRACT);
  1502.     break;
  1503.  
  1504.       case 'X':
  1505.     flag_exclude++;
  1506.     add_exclude_file (optarg);
  1507.     break;
  1508.  
  1509.       case 'z':
  1510.     if (flag_compressprog)
  1511.       ERROR ((TAREXIT_FAILURE, 0,
  1512.           _("Only one compression option permitted")));
  1513.     flag_compressprog = "gzip";
  1514.     break;
  1515.  
  1516.       case 'Z':
  1517.     if (flag_compressprog)
  1518.       ERROR ((TAREXIT_FAILURE, 0,
  1519.           _("Only one compression option permitted")));
  1520.     flag_compressprog = "compress";
  1521.     break;
  1522.       }
  1523.  
  1524.   /* Process trivial options.  */
  1525.  
  1526.   if (show_version)
  1527.     {
  1528.       printf ("GNU %s %s\n", PACKAGE, VERSION);
  1529.       exit (TAREXIT_SUCCESS);
  1530.     }
  1531.  
  1532.   if (show_help)
  1533.     usage (TAREXIT_SUCCESS);
  1534.  
  1535.   /* Derive option values and check option consistency.  */
  1536.  
  1537.   blocksize = blocking * RECORDSIZE;
  1538.  
  1539.   if (archive_names == 0)
  1540.     {
  1541.  
  1542.       /* If no archive file name given, try TAPE from the environment, or
  1543.      else, DEFAULT_ARCHIVE from the configuration process.  */
  1544.  
  1545.       archive_names = 1;
  1546.       archive_name_array[0] = getenv ("TAPE");
  1547.       if (archive_name_array[0] == NULL)
  1548.     archive_name_array[0] = DEFAULT_ARCHIVE;
  1549.     }
  1550.  
  1551.   archive_name_cursor = archive_name_array;
  1552.   if (archive_names > 1 && !flag_multivol)
  1553.     ERROR ((TAREXIT_FAILURE, 0,
  1554.         _("Multiple archive files requires --multi-volume")));
  1555.  
  1556.   if (flag_compress_block && !flag_compressprog)
  1557.     ERROR ((TAREXIT_FAILURE, 0, _("\
  1558. You must use a compression option (--gzip, --compress\n\
  1559. or --use-compress-program) with --block-compress")));
  1560. }
  1561.  
  1562. #undef SET_COMMAND_MODE
  1563.  
  1564. /*-----------------------.
  1565. | Main routine for tar.     |
  1566. `-----------------------*/
  1567.  
  1568. int
  1569. main (int argc, char *const *argv)
  1570. {
  1571.   program_name = argv[0];
  1572.   setlocale (LC_ALL, "");
  1573.   textdomain (PACKAGE);
  1574.  
  1575.   exit_status = TAREXIT_SUCCESS;
  1576.   filename_terminator = '\n';
  1577.  
  1578.   /* Pre-allocate a few structures.  */
  1579.  
  1580.   allocated_archive_names = 10;
  1581.   archive_name_array = (const char **)
  1582.     xmalloc (sizeof (const char *) * allocated_archive_names);
  1583.   archive_names = 0;
  1584.  
  1585.   allocated_names = 10;
  1586.   name_array = (const char **)
  1587.     xmalloc (sizeof (const char *) * allocated_names);
  1588.   names = 0;
  1589.  
  1590.   name_buffer = xmalloc (NAMSIZ + 2);
  1591.   name_buffer_length = NAMSIZ;
  1592.  
  1593.   /* Decode options.  */
  1594.  
  1595.   decode_options (argc, argv);
  1596.  
  1597.   if (!names_argv)
  1598.     name_init (argc, argv);
  1599.  
  1600.   /* Main command execution.  */
  1601.  
  1602.   if (flag_volno_file)
  1603.     init_volume_number ();
  1604.  
  1605.   switch (command_mode)
  1606.     {
  1607.  
  1608.     case COMMAND_NONE:
  1609.       WARN ((0, 0, _("\
  1610. You must specify one of the r, c, t, x, or d options")));
  1611.       usage (TAREXIT_FAILURE);
  1612.  
  1613.     case COMMAND_TOO_MANY:
  1614.       WARN ((0, 0, _("\
  1615. You may not specify more than one of the r, c, t, x, or d options")));
  1616.       usage (TAREXIT_FAILURE);
  1617.  
  1618.     case COMMAND_CAT:
  1619.     case COMMAND_UPDATE:
  1620.     case COMMAND_APPEND:
  1621.       update_archive ();
  1622.       break;
  1623.  
  1624.     case COMMAND_DELETE:
  1625.       junk_archive ();
  1626.       break;
  1627.  
  1628.     case COMMAND_CREATE:
  1629.       create_archive ();
  1630.       if (flag_totals)
  1631.     fprintf (stderr, _("Total bytes written: %d\n"), tot_written);
  1632.       break;
  1633.  
  1634.     case COMMAND_EXTRACT:
  1635.       if (flag_volhdr)
  1636.     {
  1637.       const char *err;
  1638.  
  1639.       label_pattern = (struct re_pattern_buffer *)
  1640.         xmalloc (sizeof *label_pattern);
  1641.        memset (label_pattern, 0, sizeof *label_pattern);
  1642.       err = re_compile_pattern (flag_volhdr, (int) strlen (flag_volhdr),
  1643.                     label_pattern);
  1644.       if (err)
  1645.         {
  1646.           ERROR ((0, 0, _("Bad regular expression: %s"), err));
  1647.           break;
  1648.         }
  1649.     }
  1650.       extr_init ();
  1651.       read_and (extract_archive);
  1652.       break;
  1653.  
  1654.     case COMMAND_LIST:
  1655.       if (flag_volhdr)
  1656.     {
  1657.       const char *err;
  1658.  
  1659.       label_pattern = (struct re_pattern_buffer *)
  1660.         xmalloc (sizeof *label_pattern);
  1661.        memset (label_pattern, 0, sizeof *label_pattern);
  1662.       err = re_compile_pattern (flag_volhdr, (int) strlen (flag_volhdr),
  1663.                     label_pattern);
  1664.       if (err)
  1665.         {
  1666.           ERROR ((0, 0, _("Bad regular expression: %s"), err));
  1667.           break;
  1668.         }
  1669.     }
  1670.       read_and (list_archive);
  1671. #if 0
  1672.       if (!errors)
  1673.     errors = different;
  1674. #endif
  1675.       break;
  1676.  
  1677.     case COMMAND_DIFF:
  1678.       diff_init ();
  1679.       read_and (diff_archive);
  1680.       break;
  1681.     }
  1682.  
  1683.   if (flag_volno_file)
  1684.     closeout_volume_number ();
  1685.  
  1686.   /* Dispose of allocated memory, and return.  */
  1687.  
  1688.   free (name_buffer);
  1689.   free (name_array);
  1690.   free (archive_name_array);
  1691.  
  1692.   exit (exit_status);
  1693. }
  1694.