bug-tar
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug-tar] Excluding directories based on content


From: Sergey Poznyakoff
Subject: Re: [Bug-tar] Excluding directories based on content
Date: Sun, 19 Nov 2006 22:31:19 +0200

Hi Dave,

Please try the included patch. It adds new option --exclude-tag=FILE.
The invocation `tar -c --exclude-tag=FILE' will exclude from the dump
the directories that contain FILE.

Multiple --exclude-tag options accumulate.

The patch is against the CVS head, but it should apply to 1.16 cleanly.

Regards,
Sergey

Index: src/create.c
===================================================================
RCS file: /cvsroot/tar/tar/src/create.c,v
retrieving revision 1.121
diff -p -u -r1.121 create.c
--- src/create.c        13 Nov 2006 10:39:51 -0000      1.121
+++ src/create.c        19 Nov 2006 20:23:52 -0000
@@ -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;
+}
+
 
 /* The maximum uintmax_t value that can be represented with DIGITS digits,
    assuming that each digit is BITS_PER_DIGIT wide.  */
@@ -983,6 +1042,7 @@ dump_regular_file (int fd, struct tar_st
   return dump_status_ok;
 }
 
+
 /* 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);
@@ -1124,6 +1184,9 @@ dump_dir0 (char *directory,
       return;
     }
 
+  if (check_exclude_tags (st->orig_file_name))
+    return;
+
   {
     char const *entry;
     size_t entry_len;
Index: src/tar.c
===================================================================
RCS file: /cvsroot/tar/tar/src/tar.c,v
retrieving revision 1.161
diff -p -u -r1.161 tar.c
--- src/tar.c   1 Nov 2006 00:23:24 -0000       1.161
+++ src/tar.c   19 Nov 2006 20:23:58 -0000
@@ -254,6 +254,7 @@ enum
   DELETE_OPTION,
   EXCLUDE_CACHES_OPTION,
   EXCLUDE_OPTION,
+  EXCLUDE_TAG_OPTION,
   FORCE_LOCAL_OPTION,
   GROUP_OPTION,
   HANG_OPTION,
@@ -603,6 +604,8 @@ static struct argp_option options[] = {
    N_("exclude patterns listed in FILE"), GRID+1 },
   {"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0,
    N_("exclude directories containing a cache tag"), GRID+1 },
+  {"exclude-tag", EXCLUDE_TAG_OPTION, N_("FILE"), 0,
+   N_("exclude directories containing FILE"), GRID+1 }, 
   {"no-recursion", NO_RECURSION_OPTION, 0, 0,
    N_("avoid descending automatically in directories"), GRID+1 },
   {"one-file-system", ONE_FILE_SYSTEM_OPTION, 0, 0,
@@ -1506,6 +1509,10 @@ parse_opt (int key, char *arg, struct ar
       exclude_caches_option = true;
       break;
 
+    case EXCLUDE_TAG_OPTION:
+      add_exclude_tag (arg);
+      break;
+      
     case FORCE_LOCAL_OPTION:
       force_local_option = true;
       break;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]