]> Dogcows Code - chaz/tar/blobdiff - src/create.c
(first_mangle, mangled_num): Remove.
[chaz/tar] / src / create.c
index c6d78b280e9399f45881a8ac93e4230c62670b93..450da32d1f90013b893151d5457a588548255989 100644 (file)
@@ -53,7 +53,7 @@ struct link
     char name[1];
   };
 
-struct link *linklist = NULL;  /* points to first link in list */
+static struct link *linklist;  /* points to first link in list */
 \f
 /* Base 64 digits; see Internet RFC 2045 Table 1.  */
 char const base_64_digits[64] =
@@ -114,25 +114,38 @@ to_chars (int negative, uintmax_t value, size_t valsize,
 {
   uintmax_t v = negative ? -value : value;
 
+  /* Generate the POSIX octal representation if the number fits.  */
   if (! negative && v <= MAX_VAL_WITH_DIGITS (size - 1, LG_8))
     {
       where[size - 1] = '\0';
       to_base (v, LG_8, base_8_digits, where, size - 1);
     }
+
+  /* Otherwise, generate the GNU base-64 representation if we are
+     generating an old or new GNU format and if the number fits.  */
   else if (v <= MAX_VAL_WITH_DIGITS (size - 1, LG_64)
-          && archive_format == GNU_FORMAT)
+          && (archive_format == GNU_FORMAT
+              || archive_format == OLDGNU_FORMAT))
     {
       where[0] = negative ? '-' : '+';
       to_base (v, LG_64, base_64_digits, where + 1, size - 1);
     }
-  else if (negative
-          && archive_format != GNU_FORMAT
-          && valsize * CHAR_BIT <= (size - 1) * LG_8)
+
+  /* Otherwise, if the number is negative, and if it would not cause
+     ambiguity on this host by confusing positive with negative
+     values, then generate the POSIX octal representation of the value
+     modulo 2**(field bits).  The resulting tar file is
+     machine-dependent, since it depends on the host word size.  Yuck!
+     But this is the traditional behavior.  */
+  else if (negative && valsize * CHAR_BIT <= (size - 1) * LG_8)
     {
       where[size - 1] = '\0';
       to_base (value & MAX_VAL_WITH_DIGITS (valsize * CHAR_BIT, 1),
               LG_8, base_8_digits, where, size - 1);
     }
+
+  /* Otherwise, output a substitute value if possible (with a
+     warning), and an error message if not.  */
   else
     {
       uintmax_t maxval = (archive_format == GNU_FORMAT
@@ -157,14 +170,14 @@ to_chars (int negative, uintmax_t value, size_t valsize,
          char *sub_string = STRINGIFY_BIGINT (s, buf3 + 1);
          if (negsub)
            *--sub_string = '-';
-         WARN ((0, 0, _("%s value %s out of range %s..%s; substituting %s"),
-                type, value_string, minval_string, maxval_string,
+         WARN ((0, 0, _("value %s out of %s range %s..%s; substituting %s"),
+                value_string, type, minval_string, maxval_string,
                 sub_string));
-         to_chars (negsub, s, valsize, NULL, where, size, type);
+         to_chars (negsub, s, valsize, 0, where, size, type);
        }
       else
-       ERROR ((0, 0, _("%s value %s out of range %s..%s"),
-               type, value_string, minval_string, maxval_string));
+       ERROR ((0, 0, _("value %s out of %s range %s..%s"),
+               value_string, type, minval_string, maxval_string));
     }
 }
 
@@ -193,13 +206,13 @@ gid_to_chars (gid_t v, char *p, size_t s)
 void
 major_to_chars (major_t v, char *p, size_t s)
 {
-  to_chars (v < 0, (uintmax_t) v, sizeof v, NULL, p, s, "major_t");
+  to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "major_t");
 }
 
 void
 minor_to_chars (minor_t v, char *p, size_t s)
 {
-  to_chars (v < 0, (uintmax_t) v, sizeof v, NULL, p, s, "minor_t");
+  to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "minor_t");
 }
 
 void
@@ -235,25 +248,25 @@ mode_to_chars (mode_t v, char *p, size_t s)
           | (v & S_IWOTH ? TOWRITE : 0)
           | (v & S_IXOTH ? TOEXEC : 0));
     }
-  to_chars (negative, u, sizeof v, NULL, p, s, "mode_t");
+  to_chars (negative, u, sizeof v, 0, p, s, "mode_t");
 }
 
 void
 off_to_chars (off_t v, char *p, size_t s)
 {
-  to_chars (v < 0, (uintmax_t) v, sizeof v, NULL, p, s, "off_t");
+  to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "off_t");
 }
 
 void
 size_to_chars (size_t v, char *p, size_t s)
 {
-  to_chars (0, (uintmax_t) v, sizeof v, NULL, p, s, "size_t");
+  to_chars (0, (uintmax_t) v, sizeof v, 0, p, s, "size_t");
 }
 
 void
 time_to_chars (time_t v, char *p, size_t s)
 {
-  to_chars (v < 0, (uintmax_t) v, sizeof v, NULL, p, s, "time_t");
+  to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "time_t");
 }
 
 static uintmax_t
@@ -281,7 +294,7 @@ uid_to_chars (uid_t v, char *p, size_t s)
 void
 uintmax_to_chars (uintmax_t v, char *p, size_t s)
 {
-  to_chars (0, v, sizeof v, NULL, p, s, "uintmax_t");
+  to_chars (0, v, sizeof v, 0, p, s, "uintmax_t");
 }
 \f
 /* Writing routines.  */
@@ -298,7 +311,7 @@ clear_buffer (char *buffer)
 }
 
 /*-------------------------------------------------------------------------.
-| Write the EOT block(s).  We actually zero at least one block, through           |
+| Write the EOT block(s).  We zero at least two blocks, through                   |
 | the end of the record.  Old tar, as previous versions of GNU tar, writes |
 | garbage after two zeroed blocks.                                        |
 `-------------------------------------------------------------------------*/
@@ -307,14 +320,11 @@ void
 write_eot (void)
 {
   union block *pointer = find_next_block ();
-
-  if (pointer)
-    {
-      size_t space = available_space_after (pointer);
-
-      memset (pointer->buffer, 0, space);
-      set_next_block_after (pointer);
-    }
+  memset (pointer->buffer, 0, BLOCKSIZE);
+  set_next_block_after (pointer);
+  pointer = find_next_block ();
+  memset (pointer->buffer, 0, available_space_after (pointer));
+  set_next_block_after (pointer);
 }
 
 /*-----------------------------------------------------.
@@ -362,7 +372,7 @@ write_long (const char *p, char type)
 
 /*---------------------------------------------------------------------.
 | Make a header block for the file name whose stat info is st.  Return |
-| header pointer for success, NULL if the name is too long.           |
+| header pointer for success, zero if the name is too long.           |
 `---------------------------------------------------------------------*/
 
 static union block *
@@ -372,34 +382,35 @@ start_header (const char *name, struct stat *st)
 
   if (!absolute_names_option)
     {
-      static int warned_once = 0;
       size_t prefix_len = FILESYSTEM_PREFIX_LEN (name);
 
       if (prefix_len)
        {
-         name += prefix_len;
+         static int warned_once;
          if (!warned_once)
            {
              warned_once = 1;
-             WARN ((0, 0, _("Removing filesystem prefix from names in the archive")));
+             WARN ((0, 0, _("Removing `%.*s' prefix from archive names"),
+                    (int) prefix_len, name));
            }
+         name += prefix_len;
        }
 
       while (*name == '/')
        {
-         name++;               /* force relative path */
+         static int warned_once;
          if (!warned_once)
            {
              warned_once = 1;
-             WARN ((0, 0, _("\
-Removing leading `/' from absolute path names in the archive")));
+             WARN ((0, 0, _("Removing leading `/' from archive names")));
            }
+         name++;
        }
     }
 
   /* Check the file name and put it in the block.  */
 
-  if (strlen (name) >= (size_t) NAME_FIELD_SIZE)
+  if (sizeof header->header.name <= strlen (name))
     write_long (name, GNUTYPE_LONGNAME);
   header = find_next_block ();
   memset (header->buffer, 0, sizeof (union block));
@@ -506,11 +517,11 @@ finish_header (union block *header)
   int sum;
   char *p;
 
-  memcpy (header->header.chksum, CHKBLANKS, sizeof (header->header.chksum));
+  memcpy (header->header.chksum, CHKBLANKS, sizeof header->header.chksum);
 
   sum = 0;
   p = header->buffer;
-  for (i = sizeof (*header); i-- != 0; )
+  for (i = sizeof *header; i-- != 0; )
     /* We can't use unsigned char here because of old compilers, e.g. V7.  */
     sum += 0xFF & *p++;
 
@@ -573,8 +584,7 @@ init_sparsearray (void)
 
   /* Make room for our scratch space -- initially is 10 elts long.  */
 
-  sparsearray = (struct sp_array *)
-    xmalloc (sp_array_size * sizeof (struct sp_array));
+  sparsearray = xmalloc (sp_array_size * sizeof (struct sp_array));
   for (counter = 0; counter < sp_array_size; counter++)
     {
       sparsearray[counter].offset = 0;
@@ -638,8 +648,7 @@ deal_with_sparse (char *name, union block *header)
 
       if (sparse_index > sp_array_size - 1)
        {
-
-         sparsearray = (struct sp_array *)
+         sparsearray =
            xrealloc (sparsearray,
                      2 * sp_array_size * sizeof (struct sp_array));
          sp_array_size *= 2;
@@ -765,8 +774,8 @@ finish_sparse_file (int file, off_t *sizeleft, off_t fullsize, char *name)
          if (count < 0)
            {
              char buf[UINTMAX_STRSIZE_BOUND];
-             ERROR ((0, errno, _("\
-Read error at byte %s, reading %lu bytes, in file %s"),
+             ERROR ((0, errno,
+                     _("Read error at byte %s, reading %lu bytes, in file %s"),
                      STRINGIFY_BIGINT (fullsize - *sizeleft, buf),
                      (unsigned long) bufsize, name));
              return 1;
@@ -851,22 +860,21 @@ create_archive (void)
 
       blank_name_list ();
       while (p = name_from_list (), p)
-       {
-         strcpy (buffer, p);
-         if (p[strlen (p) - 1] != '/')
-           strcat (buffer, "/");
-         bufp = buffer + strlen (buffer);
-         for (q = gnu_list_name->dir_contents;
-              q && *q;
-              q += strlen (q) + 1)
-           {
-             if (*q == 'Y')
-               {
-                 strcpy (bufp, q + 1);
-                 dump_file (buffer, (dev_t) -1, 1);
-               }
-           }
-       }
+       if (!excluded_name (p))
+         {
+           strcpy (buffer, p);
+           if (p[strlen (p) - 1] != '/')
+             strcat (buffer, "/");
+           bufp = buffer + strlen (buffer);
+           q = gnu_list_name->dir_contents;
+           if (q)
+             for (; *q; q += strlen (q) + 1)
+               if (*q == 'Y')
+                 {
+                   strcpy (bufp, q + 1);
+                   dump_file (buffer, (dev_t) -1, 1);
+                 }
+         }
       free (buffer);
     }
   else
@@ -935,7 +943,7 @@ dump_file (char *p, dev_t parent_device, int top_level)
 #ifdef S_ISHIDDEN
   if (S_ISHIDDEN (current_stat.st_mode))
     {
-      char *new = (char *) alloca (strlen (p) + 2);
+      char *new = alloca (strlen (p) + 2);
       if (new)
        {
          strcpy (new, p);
@@ -945,14 +953,15 @@ dump_file (char *p, dev_t parent_device, int top_level)
     }
 #endif
 
-  /* See if we only want new files, and check if this one is too old to
+  /* See if we want only new files, and check if this one is too old to
      put in the archive.  */
 
-  if (!incremental_option && !S_ISDIR (current_stat.st_mode)
+  if ((!incremental_option || listed_incremental_option)
+      && !S_ISDIR (current_stat.st_mode)
       && current_stat.st_mtime < newer_mtime_option
       && (!after_date_option || current_stat.st_ctime < newer_ctime_option))
     {
-      if (parent_device == (dev_t) -1)
+      if (!listed_incremental_option && parent_device == (dev_t) -1)
        WARN ((0, 0, _("%s: is unchanged; not dumped"), p));
       /* FIXME: recheck this return.  */
       return;
@@ -994,13 +1003,11 @@ dump_file (char *p, dev_t parent_device, int top_level)
 
            while (!absolute_names_option && *link_name == '/')
              {
-               static int warned_once = 0;
-
+               static int warned_once;
                if (!warned_once)
                  {
                    warned_once = 1;
-                   WARN ((0, 0, _("\
-Removing leading `/' from absolute links")));
+                   WARN ((0, 0, _("Removing leading `/' from link names")));
                  }
                link_name++;
              }
@@ -1010,7 +1017,7 @@ Removing leading `/' from absolute links")));
 
            current_stat.st_size = 0;
            header = start_header (p, &current_stat);
-           if (header == NULL)
+           if (! header)
              {
                exit_status = TAREXIT_FAILURE;
                return;
@@ -1037,8 +1044,7 @@ Removing leading `/' from absolute links")));
 
       /* Not found.  Add it to the list of possible links.  */
 
-      lp = (struct link *)
-       xmalloc ((size_t) (sizeof (struct link) + strlen (p)));
+      lp = xmalloc (sizeof (struct link) + strlen (p));
       lp->ino = current_stat.st_ino;
       lp->dev = current_stat.st_dev;
       strcpy (lp->name, p);
@@ -1059,9 +1065,6 @@ Removing leading `/' from absolute links")));
       int header_moved;
       char isextended = 0;
       int upperbound;
-#if 0
-      static int cried_once = 0;
-#endif
 
       header_moved = 0;
 
@@ -1106,7 +1109,7 @@ Removing leading `/' from absolute links")));
              int counter;
 
              header = start_header (p, &current_stat);
-             if (header == NULL)
+             if (! header)
                {
                  exit_status = TAREXIT_FAILURE;
                  return;
@@ -1184,7 +1187,7 @@ Removing leading `/' from absolute links")));
       if (!header_moved)
        {
          header = start_header (p, &current_stat);
-         if (header == NULL)
+         if (! header)
            {
              if (f >= 0)
                close (f);
@@ -1215,8 +1218,7 @@ Removing leading `/' from absolute links")));
 
        extend:
          exhdr = find_next_block ();
-
-         if (exhdr == NULL)
+         if (! exhdr)
            {
              exit_status = TAREXIT_FAILURE;
              return;
@@ -1272,8 +1274,7 @@ Removing leading `/' from absolute links")));
                bufsize = sizeleft;
                count = bufsize % BLOCKSIZE;
                if (count)
-                 memset (start->buffer + sizeleft, 0,
-                         (size_t) (BLOCKSIZE - count));
+                 memset (start->buffer + sizeleft, 0, BLOCKSIZE - count);
              }
            if (f < 0)
              count = bufsize;
@@ -1282,8 +1283,8 @@ Removing leading `/' from absolute links")));
            if (count < 0)
              {
                char buf[UINTMAX_STRSIZE_BOUND];
-               ERROR ((0, errno, _("\
-Read error at byte %s, reading %lu bytes, in file %s"),
+               ERROR ((0, errno,
+                       _("Read error at byte %s, reading %lu bytes, in file %s"),
                        STRINGIFY_BIGINT (current_stat.st_size - sizeleft,
                                          buf),
                        (unsigned long) bufsize, p));
@@ -1308,7 +1309,7 @@ Read error at byte %s, reading %lu bytes, in file %s"),
          }
 
       if (multi_volume_option)
-       assign_string (&save_name, NULL);
+       assign_string (&save_name, 0);
 
       if (f >= 0)
        {
@@ -1343,7 +1344,7 @@ Read error at byte %s, reading %lu bytes, in file %s"),
          sizeleft -= BLOCKSIZE;
        }
       if (multi_volume_option)
-       assign_string (&save_name, NULL);
+       assign_string (&save_name, 0);
       if (f >= 0)
        {
          close (f);
@@ -1357,7 +1358,7 @@ Read error at byte %s, reading %lu bytes, in file %s"),
   else if (S_ISLNK (current_stat.st_mode))
     {
       int size;
-      char *buffer = (char *) alloca (PATH_MAX + 1);
+      char *buffer = alloca (PATH_MAX + 1);
 
       size = readlink (p, buffer, PATH_MAX + 1);
       if (size < 0)
@@ -1374,7 +1375,7 @@ Read error at byte %s, reading %lu bytes, in file %s"),
 
       current_stat.st_size = 0;        /* force 0 size on symlink */
       header = start_header (p, &current_stat);
-      if (header == NULL)
+      if (! header)
        {
          exit_status = TAREXIT_FAILURE;
          return;
@@ -1451,7 +1452,7 @@ Read error at byte %s, reading %lu bytes, in file %s"),
             files, we'd better put the / on the name.  */
 
          header = start_header (namebuf, &current_stat);
-         if (header == NULL)
+         if (! header)
            {
              exit_status = TAREXIT_FAILURE;
              return;   /* eg name too long */
@@ -1507,8 +1508,7 @@ Read error at byte %s, reading %lu bytes, in file %s"),
                  bufsize = sizeleft;
                  count = bufsize % BLOCKSIZE;
                  if (count)
-                   memset (start->buffer + sizeleft, 0,
-                          (size_t) (BLOCKSIZE - count));
+                   memset (start->buffer + sizeleft, 0, BLOCKSIZE - count);
                }
              memcpy (start->buffer, p_buffer, bufsize);
              sizeleft -= bufsize;
@@ -1516,7 +1516,7 @@ Read error at byte %s, reading %lu bytes, in file %s"),
              set_next_block_after (start + (bufsize - 1) / BLOCKSIZE);
            }
          if (multi_volume_option)
-           assign_string (&save_name, NULL);
+           assign_string (&save_name, 0);
          if (atime_preserve_option)
            utime (p, &restore_times);
          return;
@@ -1550,11 +1550,6 @@ Read error at byte %s, reading %lu bytes, in file %s"),
          return;
        }
 
-      /* Hack to remove "./" from the front of all the file names.  */
-
-      if (len == 2 && namebuf[0] == '.' && namebuf[1] == '/')
-       len = 0;
-
       /* FIXME: Should speed this up by cd-ing into the dir.  */
 
       while (entry = readdir (directory), entry)
@@ -1567,7 +1562,7 @@ Read error at byte %s, reading %lu bytes, in file %s"),
          if ((int) NAMLEN (entry) + len >= buflen)
            {
              buflen = len + NAMLEN (entry);
-             namebuf = (char *) xrealloc (namebuf, buflen + 1);
+             namebuf = xrealloc (namebuf, buflen + 1);
 #if 0
              namebuf[len] = '\0';
              ERROR ((0, 0, _("File name %s%s too long"),
@@ -1602,7 +1597,7 @@ Read error at byte %s, reading %lu bytes, in file %s"),
 
   current_stat.st_size = 0;    /* force 0 size */
   header = start_header (p, &current_stat);
-  if (header == NULL)
+  if (! header)
     {
       exit_status = TAREXIT_FAILURE;
       return;  /* eg name too long */
This page took 0.038604 seconds and 4 git commands to generate.