bin/77666: Implement GNU tar's --strip-components option to bsdtar.
Sangwoo Shim
ssw at neo.redjade.org
Fri Feb 18 08:10:30 GMT 2005
>Number: 77666
>Category: bin
>Synopsis: Implement GNU tar's --strip-components option to bsdtar.
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Fri Feb 18 08:10:29 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator: Sangwoo Shim
>Release: 6-CURRENT (of Feb 10)
>Organization:
Seoul Natl' Univ.
>Environment:
FreeBSD swoo.org 6.0-CURRENT FreeBSD 6.0-CURRENT #1: Thu Feb 10 18:05:38 KST 2005 root at swoo.org:/usr/obj/usr/src/sys/SWOO amd64
>Description:
Implemented GNU tar's --strip-components option to bsdtar.
This is handy in some cases. The patch can be downloaded at http://swoo.org/~sangwoo/bsdtar.diff
>How-To-Repeat:
>Fix:
Index: bsdtar.c
===================================================================
--- bsdtar.c (revision 2)
+++ bsdtar.c (working copy)
@@ -89,7 +89,7 @@
* non-option. Otherwise, GNU getopt() permutes the arguments and
* screws up -C processing.
*/
-static const char *tar_opts = "+Bb:C:cF:f:HhI:jkLlmnOoPprtT:UuvW:wX:xyZz";
+static const char *tar_opts = "+Bb:C:cF:f:HhI:jkLlmnOoPprs:tT:UuvW:wX:xyZz";
/*
* Most of these long options are deliberately not documented. They
@@ -161,6 +161,7 @@
{ "preserve-permissions", no_argument, NULL, 'p' },
{ "read-full-blocks", no_argument, NULL, 'B' },
{ "same-permissions", no_argument, NULL, 'p' },
+ { "strip-components", required_argument, NULL, 's' },
{ "to-stdout", no_argument, NULL, 'O' },
{ "totals", no_argument, NULL, OPTION_TOTALS },
{ "unlink", no_argument, NULL, 'U' },
@@ -188,6 +189,7 @@
bsdtar = &bsdtar_storage;
memset(bsdtar, 0, sizeof(*bsdtar));
bsdtar->fd = -1; /* Mark as "unused" */
+ bsdtar->strip_components = 0; /* Reasonable default */
option_o = 0;
if (setlocale(LC_ALL, "") == NULL)
@@ -369,6 +371,9 @@
case 'r': /* SUSv2 */
set_mode(bsdtar, opt);
break;
+ case 's':
+ bsdtar->strip_components = atoi(optarg);
+ break;
case 'T': /* GNU tar */
bsdtar->names_from_file = optarg;
break;
Index: bsdtar.h
===================================================================
--- bsdtar.h (revision 2)
+++ bsdtar.h (working copy)
@@ -51,6 +51,7 @@
int bytes_per_block; /* -b block_size */
int verbose; /* -v */
int extract_flags; /* Flags for extract operation */
+ int strip_components; /* -s strip_components */
char mode; /* Program mode: 'c', 't', 'r', 'u', 'x' */
char symlink_mode; /* H or L, per BSD conventions */
char create_compression; /* j, y, or z */
Index: read.c
===================================================================
--- read.c (revision 2)
+++ read.c (working copy)
@@ -313,8 +313,12 @@
char *p;
int r;
- /* -P option forces us to just accept all pathnames. */
- if (bsdtar->option_absolute_paths)
+ /*
+ * -P option forces us to just accept all pathnames. But, if -s option
+ * with larger than 0 option argument is specified, strip leading
+ * pathnames appropriately following GNU tar's behavior.
+ */
+ if (bsdtar->option_absolute_paths && !bsdtar->strip_components)
return (0);
/* Strip leading '/'. */
@@ -331,6 +335,26 @@
archive_entry_set_pathname(entry, name);
}
+ /* Strip leading components. (-s option) */
+ r = bsdtar->strip_components;
+ if (r > 0) {
+ pn = name;
+ while (r > 0) {
+ if (*pn == '/') {
+ r--;
+ name = pn + 1;
+ }
+ pn++;
+ if (*pn == '\0') {
+ /* Overstripped, skip this entry. */
+ bsdtar_warnc(bsdtar, 0,
+ "Strip request exceeded the path depth.");
+ return (1);
+ }
+ }
+ archive_entry_set_pathname(entry, name);
+ }
+
/* Reject any archive entry with '..' as a path element. */
pn = name;
while (pn != NULL && pn[0] != '\0') {
Index: bsdtar.1
===================================================================
--- bsdtar.1 (revision 2)
+++ bsdtar.1 (working copy)
@@ -284,6 +284,12 @@
is being run by root, the default is to restore the owner unless the
.Fl o
option is also specified.
+.It Fl s Ar number
+(x mode only)
+Strip given number of leading components from the pathnames. This option is
+behaves like
+.Fl --strip-components
+option of GNU tar.
.It Fl T Ar filename
(c mode only)
Read names to be archived from
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list