[Top][All Lists]
[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);
}
}
- [Bug-tar] [PATCH] New feature: Strip leading path,
Mikko Käär <=