]> Dogcows Code - chaz/tar/blobdiff - src/create.c
Lint cleanup.
[chaz/tar] / src / create.c
index 1ca34a62100fbf26b54aca228f621c299c8c5830..450da32d1f90013b893151d5457a588548255989 100644 (file)
@@ -53,145 +53,248 @@ 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
-
-/*------------------------------------------------------------------------.
-| Convert VALUE (with substitute SUBSTITUTE if VALUE is out of range)    |
-| into a size-SIZE field at WHERE, including a                           |
-| trailing space.  For example, 3 for SIZE means two digits and a space.  |
-|                                                                         |
-| We assume the trailing NUL is already there and don't fill it in.  This |
-| fact is used by start_header and finish_header, so don't change it!     |
-`------------------------------------------------------------------------*/
-
-/* Output VALUE in octal, using SUBSTITUTE if value won't fit.
+/* Base 64 digits; see Internet RFC 2045 Table 1.  */
+char const base_64_digits[64] =
+{
+  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+  'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+  'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+};
+#define base_8_digits (base_64_digits + 26 * 2)
+
+/* The maximum uintmax_t value that can be represented with DIGITS digits,
+   assuming that each digit is BITS_PER_DIGIT wide.  */
+#define MAX_VAL_WITH_DIGITS(digits, bits_per_digit) \
+   ((digits) * (bits_per_digit) < sizeof (uintmax_t) * CHAR_BIT \
+    ? ((uintmax_t) 1 << ((digits) * (bits_per_digit))) - 1 \
+    : (uintmax_t) -1)
+
+/* Convert VALUE to a representation suitable for tar headers,
+   using base 1 << BITS_PER_DIGIT.
+   Use the digits in DIGIT_CHAR[0] ... DIGIT_CHAR[base - 1].
    Output to buffer WHERE with size SIZE.
-   TYPE is the kind of value being output (useful for diagnostics).
-   Prefer SIZE - 1 octal digits (with leading '0's), followed by '\0';
-   but if SIZE octal digits would fit, omit the '\0'.  */
+   The result is undefined if SIZE is 0 or if VALUE is too large to fit.  */
 
 static void
-to_oct (uintmax_t value, uintmax_t substitute, char *where, size_t size, const char *type)
+to_base (uintmax_t value, int bits_per_digit, char const *digit_char,
+        char *where, size_t size)
 {
   uintmax_t v = value;
   size_t i = size;
+  unsigned digit_mask = (1 << bits_per_digit) - 1;
 
-# define MAX_OCTAL_VAL_WITH_DIGITS(digits) \
-    ((digits) * 3 < sizeof (uintmax_t) * CHAR_BIT \
-     ? ((uintmax_t) 1 << ((digits) * 3)) - 1 \
-     : (uintmax_t) -1)
+  do
+    {
+      where[--i] = digit_char[v & digit_mask];
+      v >>= bits_per_digit;
+    }
+  while (i);
+}
 
-  /* Output a trailing NUL unless the value is too large.  */
-  if (value <= MAX_OCTAL_VAL_WITH_DIGITS (size - 1))
-    where[--i] = '\0';
+/* NEGATIVE is nonzero if VALUE was negative before being cast to
+   uintmax_t; its original bitpattern can be deduced from VALSIZE, its
+   original size before casting.  Convert VALUE to external form,
+   using SUBSTITUTE (...)  if VALUE won't fit.  Output to buffer WHERE
+   with size SIZE.  TYPE is the kind of value being output (useful for
+   diagnostics).  Prefer the POSIX format of SIZE - 1 octal digits
+   (with leading zero digits), followed by '\0'.  If this won't work,
+   and if GNU format is allowed, use '+' or '-' followed by SIZE - 1
+   base-64 digits.  If neither format works, use SUBSTITUTE (...)
+   instead.  Pass to SUBSTITUTE the address of an 0-or-1 flag
+   recording whether the substitute value is negative.  */
 
-  /* Produce the digits -- at least one.  */
+static void
+to_chars (int negative, uintmax_t value, size_t valsize,
+         uintmax_t (*substitute) PARAMS ((int *)),
+         char *where, size_t size, const char *type)
+{
+  uintmax_t v = negative ? -value : value;
 
-  do
+  /* Generate the POSIX octal representation if the number fits.  */
+  if (! negative && v <= MAX_VAL_WITH_DIGITS (size - 1, LG_8))
     {
-      where[--i] = '0' + (int) (v & 7);        /* one octal digit */
-      v >>= 3;
+      where[size - 1] = '\0';
+      to_base (v, LG_8, base_8_digits, where, size - 1);
     }
-  while (i != 0 && v != 0);
 
-  /* Leading zeros, if necessary.  */
-  while (i != 0)
-    where[--i] = '0';
+  /* 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 == OLDGNU_FORMAT))
+    {
+      where[0] = negative ? '-' : '+';
+      to_base (v, LG_64, base_64_digits, where + 1, size - 1);
+    }
 
-  if (v != 0)
+  /* 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 = MAX_OCTAL_VAL_WITH_DIGITS (size);
-      char buf1[UINTMAX_STRSIZE_BOUND];
-      char buf2[UINTMAX_STRSIZE_BOUND];
-      char buf3[UINTMAX_STRSIZE_BOUND];
-      char *value_string = STRINGIFY_BIGINT (value, buf1);
-      char *maxval_string = STRINGIFY_BIGINT (maxval, buf2);
+      uintmax_t maxval = (archive_format == GNU_FORMAT
+                         ? MAX_VAL_WITH_DIGITS (size - 1, LG_64)
+                         : MAX_VAL_WITH_DIGITS (size - 1, LG_8));
+      char buf1[UINTMAX_STRSIZE_BOUND + 1];
+      char buf2[UINTMAX_STRSIZE_BOUND + 1];
+      char buf3[UINTMAX_STRSIZE_BOUND + 1];
+      char *value_string = STRINGIFY_BIGINT (v, buf1 + 1);
+      char *maxval_string = STRINGIFY_BIGINT (maxval, buf2 + 1);
+      char const *minval_string =
+       (archive_format == GNU_FORMAT
+        ? "0"
+        : (maxval_string[-1] = '-', maxval_string - 1));
+      if (negative)
+       *--value_string = '-';
       if (substitute)
        {
-         substitute &= maxval;
-         WARN ((0, 0, _("%s value %s too large (max=%s); substituting %s"),
-                type, value_string, maxval_string,
-                STRINGIFY_BIGINT (substitute, buf3)));
-         to_oct (substitute, (uintmax_t) 0, where, size, type);
+         int negsub;
+         uintmax_t sub = substitute (&negsub) & maxval;
+         uintmax_t s = (negsub &= archive_format == GNU_FORMAT) ? -sub : sub;
+         char *sub_string = STRINGIFY_BIGINT (s, buf3 + 1);
+         if (negsub)
+           *--sub_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, 0, where, size, type);
        }
       else
-       ERROR ((0, 0, _("%s value %s too large (max=%s)"),
-               type, value_string, maxval_string));
+       ERROR ((0, 0, _("value %s out of %s range %s..%s"),
+               value_string, type, minval_string, maxval_string));
     }
 }
-#ifndef GID_NOBODY
-#define GID_NOBODY 0
+
+static uintmax_t
+gid_substitute (int *negative)
+{
+  gid_t r;
+#ifdef GID_NOBODY
+  r = GID_NOBODY;
+#else
+  static gid_t gid_nobody;
+  if (!gid_nobody && !gname_to_gid ("nobody", &gid_nobody))
+    gid_nobody = -2;
+  r = gid_nobody;
 #endif
+  *negative = r < 0;
+  return r;
+}
+
 void
-gid_to_oct (gid_t v, char *p, size_t s)
+gid_to_chars (gid_t v, char *p, size_t s)
 {
-  to_oct ((uintmax_t) v, (uintmax_t) GID_NOBODY, p, s, "gid_t");
+  to_chars (v < 0, (uintmax_t) v, sizeof v, gid_substitute, p, s, "gid_t");
 }
+
 void
-major_to_oct (major_t v, char *p, size_t s)
+major_to_chars (major_t v, char *p, size_t s)
 {
-  to_oct ((uintmax_t) v, (uintmax_t) 0, p, s, "major_t");
+  to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "major_t");
 }
+
 void
-minor_to_oct (minor_t v, char *p, size_t s)
+minor_to_chars (minor_t v, char *p, size_t s)
 {
-  to_oct ((uintmax_t) v, (uintmax_t) 0, p, s, "minor_t");
+  to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "minor_t");
 }
+
 void
-mode_to_oct (mode_t v, char *p, size_t s)
+mode_to_chars (mode_t v, char *p, size_t s)
 {
   /* In the common case where the internal and external mode bits are the same,
      propagate all unknown bits to the external mode.
      This matches historical practice.
      Otherwise, just copy the bits we know about.  */
-  uintmax_t u =
-    ((S_ISUID == TSUID && S_ISGID == TSGID && S_ISVTX == TSVTX
+  int negative;
+  uintmax_t u;
+  if (S_ISUID == TSUID && S_ISGID == TSGID && S_ISVTX == TSVTX
       && S_IRUSR == TUREAD && S_IWUSR == TUWRITE && S_IXUSR == TUEXEC
       && S_IRGRP == TGREAD && S_IWGRP == TGWRITE && S_IXGRP == TGEXEC
       && S_IROTH == TOREAD && S_IWOTH == TOWRITE && S_IXOTH == TOEXEC)
-     ? v
-     : ((v & S_ISUID ? TSUID : 0)
-       | (v & S_ISGID ? TSGID : 0)
-       | (v & S_ISVTX ? TSVTX : 0)
-       | (v & S_IRUSR ? TUREAD : 0)
-       | (v & S_IWUSR ? TUWRITE : 0)
-       | (v & S_IXUSR ? TUEXEC : 0)
-       | (v & S_IRGRP ? TGREAD : 0)
-       | (v & S_IWGRP ? TGWRITE : 0)
-       | (v & S_IXGRP ? TGEXEC : 0)
-       | (v & S_IROTH ? TOREAD : 0)
-       | (v & S_IWOTH ? TOWRITE : 0)
-       | (v & S_IXOTH ? TOEXEC : 0)));
-  to_oct (u, (uintmax_t) 0, p, s, "mode_t");
+    {
+      negative = v < 0;
+      u = v;
+    }
+  else
+    {
+      negative = 0;
+      u = ((v & S_ISUID ? TSUID : 0)
+          | (v & S_ISGID ? TSGID : 0)
+          | (v & S_ISVTX ? TSVTX : 0)
+          | (v & S_IRUSR ? TUREAD : 0)
+          | (v & S_IWUSR ? TUWRITE : 0)
+          | (v & S_IXUSR ? TUEXEC : 0)
+          | (v & S_IRGRP ? TGREAD : 0)
+          | (v & S_IWGRP ? TGWRITE : 0)
+          | (v & S_IXGRP ? TGEXEC : 0)
+          | (v & S_IROTH ? TOREAD : 0)
+          | (v & S_IWOTH ? TOWRITE : 0)
+          | (v & S_IXOTH ? TOEXEC : 0));
+    }
+  to_chars (negative, u, sizeof v, 0, p, s, "mode_t");
 }
+
 void
-off_to_oct (off_t v, char *p, size_t s)
+off_to_chars (off_t v, char *p, size_t s)
 {
-  to_oct ((uintmax_t) v, (uintmax_t) 0, p, s, "off_t");
+  to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "off_t");
 }
+
 void
-size_to_oct (size_t v, char *p, size_t s)
+size_to_chars (size_t v, char *p, size_t s)
 {
-  to_oct ((uintmax_t) v, (uintmax_t) 0, p, s, "size_t");
+  to_chars (0, (uintmax_t) v, sizeof v, 0, p, s, "size_t");
 }
+
 void
-time_to_oct (time_t v, char *p, size_t s)
+time_to_chars (time_t v, char *p, size_t s)
 {
-  to_oct ((uintmax_t) v, (uintmax_t) 0, p, s, "time_t");
+  to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "time_t");
 }
-#ifndef UID_NOBODY
-#define UID_NOBODY 0
+
+static uintmax_t
+uid_substitute (int *negative)
+{
+  uid_t r;
+#ifdef UID_NOBODY
+  r = UID_NOBODY;
+#else
+  static uid_t uid_nobody;
+  if (!uid_nobody && !uname_to_uid ("nobody", &uid_nobody))
+    uid_nobody = -2;
+  r = uid_nobody;
 #endif
+  *negative = r < 0;
+  return r;
+}
+
 void
-uid_to_oct (uid_t v, char *p, size_t s)
+uid_to_chars (uid_t v, char *p, size_t s)
 {
-  to_oct ((uintmax_t) v, (uintmax_t) UID_NOBODY, p, s, "uid_t");
+  to_chars (v < 0, (uintmax_t) v, sizeof v, uid_substitute, p, s, "uid_t");
 }
+
 void
-uintmax_to_oct (uintmax_t v, char *p, size_t s)
+uintmax_to_chars (uintmax_t v, char *p, size_t s)
 {
-  to_oct (v, (uintmax_t) 0, p, s, "uintmax_t");
+  to_chars (0, v, sizeof v, 0, p, s, "uintmax_t");
 }
 \f
 /* Writing routines.  */
@@ -208,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.                                        |
 `-------------------------------------------------------------------------*/
@@ -217,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);
 }
 
 /*-----------------------------------------------------.
@@ -272,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 *
@@ -282,35 +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 MSDOS
-      if (name[1] == ':')
+      if (prefix_len)
        {
-         name += 2;
+         static int warned_once;
          if (!warned_once)
            {
              warned_once = 1;
-             WARN ((0, 0, _("Removing drive spec from names in the archive")));
+             WARN ((0, 0, _("Removing `%.*s' prefix from archive names"),
+                    (int) prefix_len, name));
            }
+         name += prefix_len;
        }
-#endif
 
       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));
@@ -354,27 +454,26 @@ Removing leading `/' from absolute path names in the archive")));
      acceptor for Paul's test.  */
 
   if (archive_format == V7_FORMAT)
-    MODE_TO_OCT (st->st_mode & MODE_ALL, header->header.mode);
+    MODE_TO_CHARS (st->st_mode & MODE_ALL, header->header.mode);
   else
-    MODE_TO_OCT (st->st_mode, header->header.mode);
+    MODE_TO_CHARS (st->st_mode, header->header.mode);
 
-  UID_TO_OCT (st->st_uid, header->header.uid);
-  GID_TO_OCT (st->st_gid, header->header.gid);
-  OFF_TO_OCT (st->st_size, header->header.size);
-  TIME_TO_OCT (st->st_mtime, header->header.mtime);
+  UID_TO_CHARS (st->st_uid, header->header.uid);
+  GID_TO_CHARS (st->st_gid, header->header.gid);
+  OFF_TO_CHARS (st->st_size, header->header.size);
+  TIME_TO_CHARS (st->st_mtime, header->header.mtime);
 
   if (incremental_option)
     if (archive_format == OLDGNU_FORMAT)
       {
-       TIME_TO_OCT (st->st_atime, header->oldgnu_header.atime);
-       TIME_TO_OCT (st->st_ctime, header->oldgnu_header.ctime);
+       TIME_TO_CHARS (st->st_atime, header->oldgnu_header.atime);
+       TIME_TO_CHARS (st->st_ctime, header->oldgnu_header.ctime);
       }
 
   header->header.typeflag = archive_format == V7_FORMAT ? AREGTYPE : REGTYPE;
 
   switch (archive_format)
     {
-    case DEFAULT_FORMAT:
     case V7_FORMAT:
       break;
 
@@ -388,6 +487,9 @@ Removing leading `/' from absolute path names in the archive")));
       strncpy (header->header.magic, TMAGIC, TMAGLEN);
       strncpy (header->header.version, TVERSION, TVERSLEN);
       break;
+
+    default:
+      abort ();
     }
 
   if (archive_format == V7_FORMAT || numeric_owner_option)
@@ -415,25 +517,25 @@ 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++;
 
   /* Fill in the checksum field.  It's formatted differently from the
      other fields: it has [6] digits, a null, then a space -- rather than
-     digits, then a null.  We use to_oct.
+     digits, then a null.  We use to_chars.
      The final space is already there, from
-     checksumming, and to_oct doesn't modify it.
+     checksumming, and to_chars doesn't modify it.
 
      This is a fast way to do:
 
      sprintf(header->header.chksum, "%6o", sum);  */
 
-  uintmax_to_oct ((uintmax_t) sum, header->header.chksum, 7);
+  uintmax_to_chars ((uintmax_t) sum, header->header.chksum, 7);
 
   set_next_block_after (header);
 
@@ -482,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;
@@ -547,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;
@@ -674,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;
@@ -755,32 +855,33 @@ create_archive (void)
       collect_and_sort_names ();
 
       while (p = name_from_list (), p)
-       dump_file (p, (dev_t) -1, 1);
+       if (!excluded_name (p))
+         dump_file (p, (dev_t) -1, 1);
 
       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
     {
       while (p = name_next (1), p)
-       dump_file (p, (dev_t) -1, 1);
+       if (!excluded_name (p))
+         dump_file (p, (dev_t) -1, 1);
     }
 
   write_eot ();
@@ -842,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);
@@ -852,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;
@@ -883,19 +985,10 @@ dump_file (char *p, dev_t parent_device, int top_level)
 
   if (current_stat.st_nlink > 1
       && (S_ISREG (current_stat.st_mode)
-#ifdef S_ISCTG
          || S_ISCTG (current_stat.st_mode)
-#endif
-#ifdef S_ISCHR
          || S_ISCHR (current_stat.st_mode)
-#endif
-#ifdef S_ISBLK
          || S_ISBLK (current_stat.st_mode)
-#endif
-#ifdef S_ISFIFO
-         || S_ISFIFO (current_stat.st_mode)
-#endif
-      ))
+         || S_ISFIFO (current_stat.st_mode)))
     {
       struct link *lp;
 
@@ -910,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++;
              }
@@ -926,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;
@@ -953,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);
@@ -965,10 +1055,7 @@ Removing leading `/' from absolute links")));
   /* This is not a link to a previously dumped file, so dump it.  */
 
   if (S_ISREG (current_stat.st_mode)
-#ifdef S_ISCTG
-      || S_ISCTG (current_stat.st_mode)
-#endif
-      )
+      || S_ISCTG (current_stat.st_mode))
     {
       int f;                   /* file descriptor */
       size_t bufsize;
@@ -978,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;
 
@@ -1025,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;
@@ -1050,8 +1134,8 @@ Removing leading `/' from absolute links")));
                 <file>.  It might be kind of disconcerting if the
                 shrunken file size was the one that showed up.  */
 
-             OFF_TO_OCT (current_stat.st_size,
-                         header->oldgnu_header.realsize);
+             OFF_TO_CHARS (current_stat.st_size,
+                           header->oldgnu_header.realsize);
 
              /* This will be the new "size" of the file, i.e., the size
                 of the file minus the blocks of holes that we're
@@ -1059,17 +1143,17 @@ Removing leading `/' from absolute links")));
 
              find_new_file_size (&filesize, upperbound);
              current_stat.st_size = filesize;
-             OFF_TO_OCT (filesize, header->header.size);
+             OFF_TO_CHARS (filesize, header->header.size);
 
              for (counter = 0; counter < SPARSES_IN_OLDGNU_HEADER; counter++)
                {
                  if (!sparsearray[counter].numbytes)
                    break;
 
-                 OFF_TO_OCT (sparsearray[counter].offset,
-                             header->oldgnu_header.sp[counter].offset);
-                 SIZE_TO_OCT (sparsearray[counter].numbytes,
-                              header->oldgnu_header.sp[counter].numbytes);
+                 OFF_TO_CHARS (sparsearray[counter].offset,
+                               header->oldgnu_header.sp[counter].offset);
+                 SIZE_TO_CHARS (sparsearray[counter].numbytes,
+                                header->oldgnu_header.sp[counter].numbytes);
                }
 
            }
@@ -1103,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);
@@ -1111,12 +1195,12 @@ Removing leading `/' from absolute links")));
              return;
            }
        }
-#ifdef S_ISCTG
+
       /* Mark contiguous files, if we support them.  */
 
       if (archive_format != V7_FORMAT && S_ISCTG (current_stat.st_mode))
        header->header.typeflag = CONTTYPE;
-#endif
+
       isextended = header->oldgnu_header.isextended;
       save_typeflag = header->header.typeflag;
       finish_header (header);
@@ -1134,8 +1218,7 @@ Removing leading `/' from absolute links")));
 
        extend:
          exhdr = find_next_block ();
-
-         if (exhdr == NULL)
+         if (! exhdr)
            {
              exit_status = TAREXIT_FAILURE;
              return;
@@ -1146,10 +1229,10 @@ Removing leading `/' from absolute links")));
              if (counter + index_offset > upperbound)
                break;
 
-             SIZE_TO_OCT (sparsearray[counter + index_offset].numbytes,
-                          exhdr->sparse_header.sp[counter].numbytes);
-             OFF_TO_OCT (sparsearray[counter + index_offset].offset,
-                         exhdr->sparse_header.sp[counter].offset);
+             SIZE_TO_CHARS (sparsearray[counter + index_offset].numbytes,
+                            exhdr->sparse_header.sp[counter].numbytes);
+             OFF_TO_CHARS (sparsearray[counter + index_offset].offset,
+                           exhdr->sparse_header.sp[counter].offset);
            }
          set_next_block_after (exhdr);
 #if 0
@@ -1191,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;
@@ -1201,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));
@@ -1227,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)
        {
@@ -1262,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);
@@ -1272,11 +1354,11 @@ Read error at byte %s, reading %lu bytes, in file %s"),
       return;
     }
 
-#ifdef S_ISLNK
+#ifdef HAVE_READLINK
   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)
@@ -1293,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;
@@ -1309,7 +1391,7 @@ Read error at byte %s, reading %lu bytes, in file %s"),
        }
       return;
     }
-#endif /* S_ISLNK */
+#endif
 
   else if (S_ISDIR (current_stat.st_mode))
     {
@@ -1370,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 */
@@ -1407,7 +1489,7 @@ Read error at byte %s, reading %lu bytes, in file %s"),
              p_buffer += tmp;
            }
          totsize++;
-         OFF_TO_OCT (totsize, header->header.size);
+         OFF_TO_CHARS (totsize, header->header.size);
          finish_header (header);
          p_buffer = buffer;
          sizeleft = totsize;
@@ -1426,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;
@@ -1435,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;
@@ -1469,25 +1550,19 @@ 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)
        {
          /* Skip `.', `..', and excluded file names.  */
 
-         if (is_dot_or_dotdot (entry->d_name)
-             || excluded_filename (excluded, entry->d_name))
+         if (is_dot_or_dotdot (entry->d_name))
            continue;
 
          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"),
@@ -1496,7 +1571,8 @@ Read error at byte %s, reading %lu bytes, in file %s"),
 #endif
            }
          strcpy (namebuf + len, entry->d_name);
-         dump_file (namebuf, our_device, 0);
+         if (!excluded_name (namebuf))
+           dump_file (namebuf, our_device, 0);
        }
 
       closedir (directory);
@@ -1506,26 +1582,13 @@ Read error at byte %s, reading %lu bytes, in file %s"),
       return;
     }
 
-#ifdef S_ISCHR
   else if (S_ISCHR (current_stat.st_mode))
     type = CHRTYPE;
-#endif
-
-#ifdef S_ISBLK
   else if (S_ISBLK (current_stat.st_mode))
     type = BLKTYPE;
-#endif
-
-#ifdef S_ISFIFO
-  else if (S_ISFIFO (current_stat.st_mode))
-    type = FIFOTYPE;
-#endif
-
-#ifdef S_ISSOCK
-  else if (S_ISSOCK (current_stat.st_mode))
+  else if (S_ISFIFO (current_stat.st_mode)
+          || S_ISSOCK (current_stat.st_mode))
     type = FIFOTYPE;
-#endif
-
   else
     goto unknown;
 
@@ -1534,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 */
@@ -1542,13 +1605,11 @@ Read error at byte %s, reading %lu bytes, in file %s"),
 
   header->header.typeflag = type;
 
-#if defined S_ISBLK || defined S_ISCHR
   if (type != FIFOTYPE)
     {
-      MAJOR_TO_OCT (major (current_stat.st_rdev), header->header.devmajor);
-      MINOR_TO_OCT (minor (current_stat.st_rdev), header->header.devminor);
+      MAJOR_TO_CHARS (major (current_stat.st_rdev), header->header.devmajor);
+      MINOR_TO_CHARS (minor (current_stat.st_rdev), header->header.devminor);
     }
-#endif
 
   finish_header (header);
   if (remove_files_option)
This page took 0.045999 seconds and 4 git commands to generate.