]> Dogcows Code - chaz/tar/blobdiff - src/incremen.c
(checkout): Use URL of the gnulib CVS mirror.
[chaz/tar] / src / incremen.c
index c412290a7abd5bed784c9c936f91f923ce2d6ff9..d570082e2bf8055ad9df6aa844a80d3dfe77ff71 100644 (file)
@@ -5,7 +5,7 @@
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 2, or (at your option) any later
+   Free Software Foundation; either version 3, or (at your option) any later
    version.
 
    This program is distributed in the hope that it will be useful, but
    version.
 
    This program is distributed in the hope that it will be useful, but
@@ -18,9 +18,7 @@
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 #include <system.h>
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 #include <system.h>
-#include <getline.h>
 #include <hash.h>
 #include <hash.h>
-#include <mkdtemp.h>
 #include <quotearg.h>
 #include "common.h"
 
 #include <quotearg.h>
 #include "common.h"
 
@@ -64,6 +62,8 @@ struct directory
     unsigned flags;             /* See DIRF_ macros above */
     struct directory *orig;     /* If the directory was renamed, points to
                                   the original directory structure */
     unsigned flags;             /* See DIRF_ macros above */
     struct directory *orig;     /* If the directory was renamed, points to
                                   the original directory structure */
+    const char *tagfile;        /* Tag file, if the directory falls under
+                                  exclusion_tag_under */
     char name[1];              /* file name of directory */
   };
 
     char name[1];              /* file name of directory */
   };
 
@@ -126,6 +126,7 @@ make_directory (const char *name)
   strcpy (directory->name, name);
   if (ISSLASH (directory->name[namelen-1]))
     directory->name[namelen-1] = 0;
   strcpy (directory->name, name);
   if (ISSLASH (directory->name[namelen-1]))
     directory->name[namelen-1] = 0;
+  directory->tagfile = NULL;
   return directory;
 }
 
   return directory;
 }
 
@@ -231,7 +232,8 @@ static struct directory *
 procdir (char *name_buffer, struct stat *stat_data,
         dev_t device,
         enum children children,
 procdir (char *name_buffer, struct stat *stat_data,
         dev_t device,
         enum children children,
-        bool verbose)
+        bool verbose,
+        char *entry)
 {
   struct directory *directory;
   bool nfs = NFS_FILE_STAT (*stat_data);
 {
   struct directory *directory;
   bool nfs = NFS_FILE_STAT (*stat_data);
@@ -332,6 +334,39 @@ procdir (char *name_buffer, struct stat *stat_data,
 
   DIR_SET_FLAG (directory, DIRF_INIT);
 
 
   DIR_SET_FLAG (directory, DIRF_INIT);
 
+  {
+    const char *tag_file_name;
+    
+    switch (check_exclusion_tags (name_buffer, &tag_file_name))
+      {
+      case exclusion_tag_all:
+       /* This warning can be duplicated by code in dump_file0, but only
+          in case when the topmost directory being archived contains
+          an exclusion tag. */
+       exclusion_tag_warning (name_buffer, tag_file_name,
+                              _("directory not dumped"));
+       if (entry)
+         *entry = 'N';
+       directory->children = NO_CHILDREN;
+       break;
+
+      case exclusion_tag_contents:
+       exclusion_tag_warning (name_buffer, tag_file_name,
+                              _("contents not dumped"));
+       directory->children = NO_CHILDREN;
+       break;
+       
+      case exclusion_tag_under:
+       exclusion_tag_warning (name_buffer, tag_file_name,
+                              _("contents not dumped"));
+       directory->tagfile = tag_file_name;
+       break;
+       
+      case exclusion_tag_none:
+       break;
+      }
+  }
+
   return directory;
 }
 
   return directory;
 }
 
@@ -438,9 +473,17 @@ makedumpdir (struct directory *directory, const char *dir)
       const char *loc = dumpdir_locate (dump, array[i]);
       if (loc)
        {
       const char *loc = dumpdir_locate (dump, array[i]);
       if (loc)
        {
-         *new_dump_ptr++ = ' ';
+         if (directory->tagfile)
+           *new_dump_ptr = strcmp (directory->tagfile, array[i]) == 0 ?
+                              ' ' : 'I';
+         else
+           *new_dump_ptr = ' ';
+         new_dump_ptr++;
          dump = loc + strlen (loc) + 1;
        }
          dump = loc + strlen (loc) + 1;
        }
+      else if (directory->tagfile)
+       *new_dump_ptr++ = strcmp (directory->tagfile, array[i]) == 0 ?
+                              ' ' : 'I';
       else
        *new_dump_ptr++ = 'Y'; /* New entry */
 
       else
        *new_dump_ptr++ = 'Y'; /* New entry */
 
@@ -456,22 +499,22 @@ makedumpdir (struct directory *directory, const char *dir)
 
 /* Recursively scan the given directory. */
 static char *
 
 /* Recursively scan the given directory. */
 static char *
-scan_directory (char *dir_name, dev_t device)
+scan_directory (char *dir, dev_t device)
 {
 {
-  char *dirp = savedir (dir_name);     /* for scanning directory */
+  char *dirp = savedir (dir);  /* for scanning directory */
   char *name_buffer;           /* directory, `/', and directory member */
   size_t name_buffer_size;     /* allocated size of name_buffer, minus 2 */
   size_t name_length;          /* used length in name_buffer */
   struct stat stat_data;
   struct directory *directory;
   char *name_buffer;           /* directory, `/', and directory member */
   size_t name_buffer_size;     /* allocated size of name_buffer, minus 2 */
   size_t name_length;          /* used length in name_buffer */
   struct stat stat_data;
   struct directory *directory;
-
+  
   if (! dirp)
   if (! dirp)
-    savedir_error (dir_name);
+    savedir_error (dir);
 
 
-  name_buffer_size = strlen (dir_name) + NAME_FIELD_SIZE;
+  name_buffer_size = strlen (dir) + NAME_FIELD_SIZE;
   name_buffer = xmalloc (name_buffer_size + 2);
   name_buffer = xmalloc (name_buffer_size + 2);
-  strcpy (name_buffer, dir_name);
-  if (! ISSLASH (dir_name[strlen (dir_name) - 1]))
+  strcpy (name_buffer, dir);
+  if (! ISSLASH (dir[strlen (dir) - 1]))
     strcat (name_buffer, "/");
   name_length = strlen (name_buffer);
 
     strcat (name_buffer, "/");
   name_length = strlen (name_buffer);
 
@@ -486,8 +529,9 @@ scan_directory (char *dir_name, dev_t device)
       return NULL;
     }
 
       return NULL;
     }
 
-  directory = procdir (name_buffer, &stat_data, device, NO_CHILDREN, false);
-
+  directory = procdir (name_buffer, &stat_data, device, NO_CHILDREN, false,
+                      NULL);
+  
   if (dirp && directory->children != NO_CHILDREN)
     {
       char  *entry;    /* directory entry being scanned */
   if (dirp && directory->children != NO_CHILDREN)
     {
       char  *entry;    /* directory entry being scanned */
@@ -508,7 +552,9 @@ scan_directory (char *dir_name, dev_t device)
            }
          strcpy (name_buffer + name_length, entry + 1);
 
            }
          strcpy (name_buffer + name_length, entry + 1);
 
-         if (excluded_name (name_buffer))
+         if (*entry == 'I') /* Ignored entry */
+           *entry = 'N';
+         else if (excluded_name (name_buffer))
            *entry = 'N';
          else
            {
            *entry = 'N';
          else
            {
@@ -521,10 +567,10 @@ scan_directory (char *dir_name, dev_t device)
 
              if (S_ISDIR (stat_data.st_mode))
                {
 
              if (S_ISDIR (stat_data.st_mode))
                {
+                 *entry = 'D';
                  procdir (name_buffer, &stat_data, device,
                           directory->children,
                  procdir (name_buffer, &stat_data, device,
                           directory->children,
-                          verbose_option);
-                 *entry = 'D';
+                          verbose_option, entry);
                }
 
              else if (one_file_system_option && device != stat_data.st_dev)
                }
 
              else if (one_file_system_option && device != stat_data.st_dev)
@@ -553,19 +599,26 @@ scan_directory (char *dir_name, dev_t device)
 }
 
 char *
 }
 
 char *
-get_directory_contents (char *dir_name, dev_t device)
+get_directory_contents (char *dir, dev_t device)
 {
 {
-  return scan_directory (dir_name, device);
+  return scan_directory (dir, device);
 }
 
 \f
 static void
 obstack_code_rename (struct obstack *stk, char *from, char *to)
 {
 }
 
 \f
 static void
 obstack_code_rename (struct obstack *stk, char *from, char *to)
 {
+  char *s;
+
+  s = from[0] == 0 ? from :
+                     safer_name_suffix (from, false, absolute_names_option);
   obstack_1grow (stk, 'R');
   obstack_1grow (stk, 'R');
-  obstack_grow (stk, from, strlen (from) + 1);
+  obstack_grow (stk, s, strlen (s) + 1);
+
+  s = to[0] == 0 ? to:
+                   safer_name_suffix (to, false, absolute_names_option);
   obstack_1grow (stk, 'T');
   obstack_1grow (stk, 'T');
-  obstack_grow (stk, to, strlen (to) + 1);
+  obstack_grow (stk, s, strlen (s) + 1);
 }
 
 static bool
 }
 
 static bool
@@ -1356,6 +1409,19 @@ try_purge_directory (char const *directory_name)
          arc += strlen (arc) + 1;
          dst = arc + 1;
 
          arc += strlen (arc) + 1;
          dst = arc + 1;
 
+         /* Ensure that neither source nor destination are absolute file
+            names (unless permitted by -P option), and that they do not
+            contain dubious parts (e.g. ../).
+
+            This is an extra safety precaution. Besides, it might be
+            necessary to extract from archives created with tar versions
+            prior to 1.19. */
+         
+         if (*src)
+           src = safer_name_suffix (src, false, absolute_names_option);
+         if (*dst)
+           dst = safer_name_suffix (dst, false, absolute_names_option);
+         
          if (*src == 0)
            src = temp_stub;
          else if (*dst == 0)
          if (*src == 0)
            src = temp_stub;
          else if (*dst == 0)
This page took 0.025358 seconds and 4 git commands to generate.