]> Dogcows Code - chaz/tar/blobdiff - src/create.c
Remove autogenerated files
[chaz/tar] / src / create.c
index 827342794151553a3dc5214d021c8624036b1230..23e9efdbd302f8537c872d4561b69280ae04fa54 100644 (file)
@@ -33,6 +33,65 @@ struct link
     size_t nlink;
     char name[1];
   };
+
+struct exclude_tag
+{
+  const char *name;
+  size_t length;
+  struct exclude_tag *next;
+};
+
+static struct exclude_tag *exclude_tags;
+
+void
+add_exclude_tag (const char *name)
+{
+  struct exclude_tag *tag = xmalloc (sizeof tag[0]);
+  tag->next = exclude_tags;
+  tag->name = name;
+  tag->length = strlen (name);
+  exclude_tags = tag;
+}
+
+static bool
+check_exclude_tags (char *dirname)
+{
+  static char *tagname;
+  static size_t tagsize;
+  struct exclude_tag *tag;
+  size_t dlen = strlen (dirname);
+  char *nptr = NULL;
+  char *ret = NULL;
+  
+  for (tag = exclude_tags; tag; tag = tag->next)
+    {
+      size_t size = dlen + tag->length + 1;
+      if (size > tagsize)
+       {
+         tagsize = size;
+         tagname = xrealloc (tagname, tagsize);
+       }
+
+      if (!nptr)
+       {
+         strcpy (tagname, dirname);
+         nptr = tagname + dlen;
+       }
+      strcpy (nptr, tag->name);
+      if (access (tagname, F_OK) == 0)
+       {
+         if (verbose_option)
+           WARN ((0, 0,
+                  _("%s: contains a cache directory tag %s; not dumped"),
+                  quotearg_colon (dirname),
+                  quotearg_n (1, tag->name)));
+         return true;
+       }
+    }
+
+  return false;
+}
+
 \f
 /* The maximum uintmax_t value that can be represented with DIGITS digits,
    assuming that each digit is BITS_PER_DIGIT wide.  */
@@ -742,7 +801,7 @@ start_header (struct tar_stat_info *st)
       {
        if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec
            || mtime.tv_nsec != 0)
-         xheader_store ("mtime", st, NULL);
+         xheader_store ("mtime", st, &mtime);
        if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec)
          mtime.tv_sec = 0;
       }
@@ -974,8 +1033,8 @@ dump_regular_file (int fd, struct tar_stat_info *st)
                           size_left),
                 quotearg_colon (st->orig_file_name),
                 STRINGIFY_BIGINT (size_left, buf)));
-         if (! ignore_failed_read_option)
-           exit_status = TAREXIT_FAILURE;
+         if (! ignore_failed_read_option) 
+           exit_status = TAREXIT_DIFFERS;
          pad_archive (size_left - (bufsize-count));
          return dump_status_short;
        }
@@ -983,6 +1042,7 @@ dump_regular_file (int fd, struct tar_stat_info *st)
   return dump_status_ok;
 }
 
+\f
 /* Look in directory DIRNAME for a cache directory tag file
    with the magic name "CACHEDIR.TAG" and a standard header,
    as described at:
@@ -1000,7 +1060,7 @@ check_cache_directory (char *dirname)
   static char tagname[] = "CACHEDIR.TAG";
   char *tagpath;
   int fd;
-  int tag_present = false;
+  bool tag_present = false;
 
   tagpath = xmalloc (strlen (dirname) + strlen (tagname) + 1);
   strcpy (tagpath, dirname);
@@ -1113,17 +1173,7 @@ dump_dir0 (char *directory,
               quotearg_colon (st->orig_file_name)));
       return;
     }
-
-  if (exclude_caches_option
-      && check_cache_directory(st->orig_file_name))
-    {
-      if (verbose_option)
-       WARN ((0, 0,
-              _("%s: contains a cache directory tag; not dumped"),
-              quotearg_colon (st->orig_file_name)));
-      return;
-    }
-
+  
   {
     char const *entry;
     size_t entry_len;
@@ -1174,9 +1224,6 @@ dump_dir (int fd, struct tar_stat_info *st, int top_level, dev_t parent_device)
       return false;
     }
 
-  ensure_slash (&st->orig_file_name);
-  ensure_slash (&st->file_name);
-
   dump_dir0 (directory, st, top_level, parent_device);
 
   free (directory);
@@ -1399,6 +1446,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
 {
   union block *header;
   char type;
+  off_t original_size;
   struct timespec original_ctime;
   struct timespec restore_times[2];
   off_t block_ordinal = -1;
@@ -1418,7 +1466,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
       stat_diag (p);
       return;
     }
-  st->archive_file_size = st->stat.st_size;
+  st->archive_file_size = original_size = st->stat.st_size;
   st->atime = restore_times[0] = get_stat_atime (&st->stat);
   st->mtime = restore_times[1] = get_stat_mtime (&st->stat);
   st->ctime = original_ctime = get_stat_ctime (&st->stat);
@@ -1496,6 +1544,22 @@ dump_file0 (struct tar_stat_info *st, const char *p,
 
       if (is_dir)
        {
+         ensure_slash (&st->orig_file_name);
+         ensure_slash (&st->file_name);
+
+         if (exclude_caches_option
+             && check_cache_directory (st->orig_file_name))
+           {
+             if (verbose_option)
+               WARN ((0, 0,
+                      _("%s: contains a cache directory tag; not dumped"),
+                      quotearg_colon (st->orig_file_name)));
+             return;
+           }
+         
+         if (check_exclude_tags (st->orig_file_name))
+           return;
+
          ok = dump_dir (fd, st, top_level, parent_device);
 
          /* dump_dir consumes FD if successful.  */
@@ -1555,9 +1619,14 @@ dump_file0 (struct tar_stat_info *st, const char *p,
 
       if (ok)
        {
-         if (timespec_cmp (get_stat_ctime (&final_stat), original_ctime) != 0)
-           WARN ((0, 0, _("%s: file changed as we read it"),
-                  quotearg_colon (p)));
+         if (timespec_cmp (get_stat_ctime (&final_stat), original_ctime) != 0
+             || original_size < final_stat.st_size)
+           {
+             WARN ((0, 0, _("%s: file changed as we read it"),
+                    quotearg_colon (p)));
+             if (exit_status == TAREXIT_SUCCESS)
+               exit_status = TAREXIT_DIFFERS;
+           }
          else if (atime_preserve_option == replace_atime_preserve
                   && set_file_atime (fd, p, restore_times) != 0)
            utime_error (p);
This page took 0.02441 seconds and 4 git commands to generate.