Date: Fri, 18 Feb 2005 08:07:46 GMT From: Sangwoo Shim <ssw@neo.redjade.org> To: freebsd-gnats-submit@FreeBSD.org Subject: bin/77666: Implement GNU tar's --strip-components option to bsdtar. Message-ID: <200502180807.j1I87kB4040109@www.freebsd.org> Resent-Message-ID: <200502180810.j1I8ATW1024367@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200502180807.j1I87kB4040109>