]> Dogcows Code - chaz/tar/blobdiff - src/create.c
(finish_sparse_file): Use excluded_filename instead of check_exclude.
[chaz/tar] / src / create.c
index 3a7e56a4645dfb694d753f9fd49af4ab3e2a111f..fdfc6d3b64fd0f61f161a3af057073523736ae44 100644 (file)
@@ -14,7 +14,7 @@
 
    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
-   59 Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "system.h"
 
@@ -141,7 +141,29 @@ minor_to_oct (minor_t v, char *p, size_t s)
 void
 mode_to_oct (mode_t v, char *p, size_t s)
 {
-  to_oct ((uintmax_t) v, (uintmax_t) 0, p, s, "mode_t");
+  /* 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
+      && 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");
 }
 void
 off_to_oct (off_t v, char *p, size_t s)
@@ -332,7 +354,7 @@ 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 & 07777, header->header.mode);
+    MODE_TO_OCT (st->st_mode & MODE_ALL, header->header.mode);
   else
     MODE_TO_OCT (st->st_mode, header->header.mode);
 
@@ -404,8 +426,8 @@ finish_header (union block *header)
   /* 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.
-     The final space is already there, from checksumming,
-     and to_oct doesn't modify it.
+     The final space is already there, from
+     checksumming, and to_oct doesn't modify it.
 
      This is a fast way to do:
 
@@ -518,7 +540,7 @@ deal_with_sparse (char *name, union block *header)
   init_sparsearray ();
   clear_buffer (buffer);
 
-  while (count = read (file, buffer, sizeof buffer), count != 0)
+  while (count = safe_read (file, buffer, sizeof buffer), count != 0)
     {
       /* Realloc the scratch area as necessary.  FIXME: should reallocate
         only at beginning of a new instance of non-zero data.  */
@@ -620,7 +642,7 @@ finish_sparse_file (int file, off_t *sizeleft, off_t fullsize, char *name)
          break;
        }
 
-      if (lseek (file, sparsearray[sparse_index++].offset, 0) < 0)
+      if (lseek (file, sparsearray[sparse_index++].offset, SEEK_SET) < 0)
        {
          char buf[UINTMAX_STRSIZE_BOUND];
          ERROR ((0, errno, _("lseek error at byte %s in file %s"),
@@ -637,8 +659,8 @@ finish_sparse_file (int file, off_t *sizeleft, off_t fullsize, char *name)
 #if 0
          if (amount_read)
            {
-             count = read (file, start->buffer + amount_read,
-                           BLOCKSIZE - amount_read);
+             count = safe_read (file, start->buffer + amount_read,
+                                BLOCKSIZE - amount_read);
              bufsize -= BLOCKSIZE - amount_read;
              amount_read = 0;
              set_next_block_after (start);
@@ -648,7 +670,7 @@ finish_sparse_file (int file, off_t *sizeleft, off_t fullsize, char *name)
 #endif
          /* Store the data.  */
 
-         count = read (file, start->buffer, BLOCKSIZE);
+         count = safe_read (file, start->buffer, BLOCKSIZE);
          if (count < 0)
            {
              char buf[UINTMAX_STRSIZE_BOUND];
@@ -669,7 +691,7 @@ Read error at byte %s, reading %lu bytes, in file %s"),
        char buffer[BLOCKSIZE];
 
        clear_buffer (buffer);
-       count = read (file, buffer, bufsize);
+       count = safe_read (file, buffer, bufsize);
        memcpy (start->buffer, buffer, BLOCKSIZE);
       }
 
@@ -1061,7 +1083,8 @@ Removing leading `/' from absolute links")));
         files when archive is meant for /dev/null.  */
 
       if (dev_null_output
-         || (sizeleft == 0 && 0444 == (0444 & current_stat.st_mode)))
+         || (sizeleft == 0
+             && MODE_R == (MODE_R & current_stat.st_mode)))
        f = -1;
       else
        {
@@ -1144,7 +1167,8 @@ Removing leading `/' from absolute links")));
        }
       if (save_typeflag == GNUTYPE_SPARSE)
        {
-         if (finish_sparse_file (f, &sizeleft, current_stat.st_size, p))
+         if (f < 0
+             || finish_sparse_file (f, &sizeleft, current_stat.st_size, p))
            goto padit;
        }
       else
@@ -1173,7 +1197,7 @@ Removing leading `/' from absolute links")));
            if (f < 0)
              count = bufsize;
            else
-             count = read (f, start->buffer, bufsize);
+             count = safe_read (f, start->buffer, bufsize);
            if (count < 0)
              {
                char buf[UINTMAX_STRSIZE_BOUND];
@@ -1454,9 +1478,10 @@ Read error at byte %s, reading %lu bytes, in file %s"),
 
       while (entry = readdir (directory), entry)
        {
-         /* Skip `.' and `..'.  */
+         /* Skip `.', `..', and excluded file names.  */
 
-         if (is_dot_or_dotdot (entry->d_name))
+         if (is_dot_or_dotdot (entry->d_name)
+             || excluded_filename (excluded, entry->d_name))
            continue;
 
          if ((int) NAMLEN (entry) + len >= buflen)
@@ -1471,8 +1496,6 @@ Read error at byte %s, reading %lu bytes, in file %s"),
 #endif
            }
          strcpy (namebuf + len, entry->d_name);
-         if (exclude_option && check_exclude (namebuf))
-           continue;
          dump_file (namebuf, our_device, 0);
        }
 
This page took 0.025243 seconds and 4 git commands to generate.