bug-tar
[Top][All Lists]
Advanced

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

[Bug-tar] [PATCH] New feature: Strip leading path


From: Mikko Käär
Subject: [Bug-tar] [PATCH] New feature: Strip leading path
Date: Wed, 11 Apr 2007 20:56:01 +0300
User-agent: Thunderbird 1.5.0.10 (Windows/20070221)

Attached is a patch which implements --strip-leading-path
Basically, running

tar --strip-leading-path -cf archive.tar /home/mikko /var/www/www-root

will create an archive with directories mikko and www-root in it. There
had been a request for a feature like this earlier this year and it was
suggested that the same could be achieved using -C, but this one works
with --files-from too.

The patch is against 1.16.1

Now, I'm not completely sure how this works with multivolumes or sparse
files etc. Could someone more familiar with the code look into that?

--
Mikko Käär <address@hidden>
diff -Naur tar-1.16.1-orig/doc/tar.texi tar-1.16.1/doc/tar.texi
--- tar-1.16.1-orig/doc/tar.texi        2006-12-07 15:53:30.000000000 +0200
+++ tar-1.16.1/doc/tar.texi     2007-04-11 20:06:15.000000000 +0300
@@ -3103,6 +3103,17 @@
 @noindent
 would extract this file to file @file{name}.
 
address@hidden
address@hidden --strip-leading-path
+Strip leading path from targets before archiving. For example,
+
address@hidden
+tar --strip-leading-path -cf archive.tar /home/mikko /var/www/www-root
address@hidden smallexample
+
address@hidden
+would create an archive with directories mikko and www-root in it.
+
 @opsummary{suffix}, summary
 @item address@hidden
 
diff -Naur tar-1.16.1-orig/src/common.h tar-1.16.1/src/common.h
--- tar-1.16.1-orig/src/common.h        2006-12-05 09:37:59.000000000 +0200
+++ tar-1.16.1/src/common.h     2007-04-11 20:06:15.000000000 +0300
@@ -249,6 +249,8 @@
    before extracting */
 GLOBAL size_t strip_name_components;
 
+GLOBAL bool strip_leading_path_option;
+
 GLOBAL bool show_omitted_dirs_option;
 
 GLOBAL bool sparse_option;
@@ -420,7 +422,7 @@
 bool file_dumpable_p (struct tar_stat_info *st);
 void create_archive (void);
 void pad_archive (off_t size_left);
-void dump_file (const char *st, int top_level, dev_t parent_device);
+void dump_file (const char *st, int leading_path_len, int top_level, dev_t 
parent_device);
 union block *start_header (struct tar_stat_info *st);
 void finish_header (struct tar_stat_info *st, union block *header,
                    off_t block_ordinal);
diff -Naur tar-1.16.1-orig/src/create.c tar-1.16.1/src/create.c
--- tar-1.16.1-orig/src/create.c        2006-12-07 15:49:48.000000000 +0200
+++ tar-1.16.1/src/create.c     2007-04-11 20:06:15.000000000 +0300
@@ -1194,7 +1194,7 @@
          }
        strcpy (name_buf + name_len, entry);
        if (!excluded_name (name_buf))
-         dump_file (name_buf, 0, our_device);
+         dump_file (name_buf, st->leading_path_len, 0, our_device);
       }
 
     free (name_buf);
@@ -1251,7 +1251,7 @@
 
       while ((p = name_from_list ()) != NULL)
        if (!excluded_name (p))
-         dump_file (p, -1, (dev_t) 0);
+         dump_file (p, 0, -1, (dev_t) 0);
 
       blank_name_list ();
       while ((p = name_from_list ()) != NULL)
@@ -1281,7 +1281,7 @@
                          buffer = xrealloc (buffer, buffer_size);
                        }
                      strcpy (buffer + plen, q + 1);
-                     dump_file (buffer, -1, (dev_t) 0);
+                     dump_file (buffer, 0, -1, (dev_t) 0);
                    }
                  q += qlen + 1;
                }
@@ -1292,7 +1292,7 @@
     {
       while ((p = name_next (1)) != NULL)
        if (!excluded_name (p))
-         dump_file (p, 1, (dev_t) 0);
+         dump_file (p, 0, 1, (dev_t) 0);
     }
 
   write_eot ();
@@ -1451,13 +1451,26 @@
   struct timespec restore_times[2];
   off_t block_ordinal = -1;
   bool is_dir;
+  char *t;
+  char *s;
 
   if (interactive_option && !confirm ("add", p))
     return;
 
+  s = safer_name_suffix (p, false, absolute_names_option);
+
+  if ((top_level || top_level == -1) && strip_leading_path_option)
+  {
+    /* find the last component of s separated by slashes */
+    for ( t=s ; *t ; t++ )
+    {
+      if (ISSLASH (t[0]) && t[1])
+        st->leading_path_len = t-s + 1;
+    }
+  }
+
   assign_string (&st->orig_file_name, p);
-  assign_string (&st->file_name,
-                 safer_name_suffix (p, false, absolute_names_option));
+  assign_string (&st->file_name, s + st->leading_path_len);
 
   transform_name (&st->file_name);
 
@@ -1745,10 +1758,11 @@
 }
 
 void
-dump_file (const char *p, int top_level, dev_t parent_device)
+dump_file (const char *p, int leading_path_len, int top_level, dev_t 
parent_device)
 {
   struct tar_stat_info st;
   tar_stat_init (&st);
+  st.leading_path_len = leading_path_len;
   dump_file0 (&st, p, top_level, parent_device);
   if (listed_incremental_option)
     update_parent_directory (p);
diff -Naur tar-1.16.1-orig/src/tar.c tar-1.16.1/src/tar.c
--- tar-1.16.1-orig/src/tar.c   2006-12-05 09:37:59.000000000 +0200
+++ tar-1.16.1/src/tar.c        2007-04-11 20:06:15.000000000 +0300
@@ -305,6 +305,7 @@
   SHOW_TRANSFORMED_NAMES_OPTION,
   SPARSE_VERSION_OPTION,
   STRIP_COMPONENTS_OPTION,
+  STRIP_LEADING_PATH_OPTION,
   SUFFIX_OPTION,
   TEST_LABEL_OPTION,
   TOTALS_OPTION,
@@ -636,6 +637,8 @@
   {"strip-components", STRIP_COMPONENTS_OPTION, N_("NUMBER"), 0,
    N_("strip NUMBER leading components from file names on extraction"),
    GRID+1 },
+  {"strip-leading-path", STRIP_LEADING_PATH_OPTION, 0, 0,
+   N_("strip leading path from targets"), GRID+1 },
   {"transform", TRANSFORM_OPTION, N_("EXPRESSION"), 0,
    N_("use sed replace EXPRESSION to transform file names"), GRID+1 },
 #undef GRID
@@ -1713,6 +1716,10 @@
       }
       break;
 
+    case STRIP_LEADING_PATH_OPTION:
+      strip_leading_path_option = true;
+      break;
+
     case SHOW_OMITTED_DIRS_OPTION:
       show_omitted_dirs_option = true;
       break;
diff -Naur tar-1.16.1-orig/src/tar.h tar-1.16.1/src/tar.h
--- tar-1.16.1-orig/src/tar.h   2006-12-05 09:37:59.000000000 +0200
+++ tar-1.16.1/src/tar.h        2007-04-11 20:07:17.000000000 +0300
@@ -275,6 +275,8 @@
                               after being normalized.  */
   bool had_trailing_slash;  /* true if the current archive entry had a
                               trailing slash before it was normalized. */
+  int leading_path_len;     /* nonzero if there is a leading path which
+                              should be stripped */
   char *link_name;          /* name of link for the current archive entry.  */
 
   char          *uname;     /* user name of owner */
diff -Naur tar-1.16.1-orig/src/update.c tar-1.16.1/src/update.c
--- tar-1.16.1-orig/src/update.c        2006-06-20 14:42:24.000000000 +0300
+++ tar-1.16.1/src/update.c     2007-04-11 20:06:15.000000000 +0300
@@ -201,7 +201,7 @@
        if (subcommand_option == CAT_SUBCOMMAND)
          append_file (file_name);
        else
-         dump_file (file_name, 1, (dev_t) 0);
+         dump_file (file_name, 0, 1, (dev_t) 0);
       }
   }
 

reply via email to

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