From owner-freebsd-bugs@FreeBSD.ORG Fri Feb 18 08:10:30 2005 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 09B2316A4CE for ; Fri, 18 Feb 2005 08:10:30 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id B20AA43D4C for ; Fri, 18 Feb 2005 08:10:29 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.1/8.13.1) with ESMTP id j1I8ATrZ024368 for ; Fri, 18 Feb 2005 08:10:29 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.1/8.13.1/Submit) id j1I8ATW1024367; Fri, 18 Feb 2005 08:10:29 GMT (envelope-from gnats) Resent-Date: Fri, 18 Feb 2005 08:10:29 GMT Resent-Message-Id: <200502180810.j1I8ATW1024367@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Sangwoo Shim Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2BA8D16A4CE for ; Fri, 18 Feb 2005 08:07:47 +0000 (GMT) Received: from www.freebsd.org (www.freebsd.org [216.136.204.117]) by mx1.FreeBSD.org (Postfix) with ESMTP id ED51A43D55 for ; Fri, 18 Feb 2005 08:07:46 +0000 (GMT) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id j1I87kf6040110 for ; Fri, 18 Feb 2005 08:07:46 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id j1I87kB4040109; Fri, 18 Feb 2005 08:07:46 GMT (envelope-from nobody) Message-Id: <200502180807.j1I87kB4040109@www.freebsd.org> Date: Fri, 18 Feb 2005 08:07:46 GMT From: Sangwoo Shim To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-2.3 Subject: bin/77666: Implement GNU tar's --strip-components option to bsdtar. X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Feb 2005 08:10:30 -0000 >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: