Subject: bin/8233: pax should ignore leading /'s by default
To: None <gnats-bugs@gnats.netbsd.org>
From: Seebs <seebs@lobe.fleet.plethora.net>
List: netbsd-bugs
Date: 08/18/1999 22:50:04
>Number:         8233
>Category:       bin
>Synopsis:       pax is mean to me and overwrites files gratuitously
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Aug 18 22:20:01 1999
>Last-Modified:
>Originator:     Seebs
>Organization:

>Release:        Aug 19 1999
>Environment:
System: NetBSD lobe.fleet.plethora.net 1.4J NetBSD 1.4J (LOBE) #0: Tue Aug 17 10:44:59 PDT 1999 seebs@lobe.fleet.plethora.net:/usr/src/sys/arch/i386/compile/LOBE i386

>Description:
	pax honors leading /'s on archives.  This is the wrong default,
	because it is much easier to 'cd /; pax -r -f ...' than it is to
	remember how '-s' works.

	Note also that our tar (GNU tar) disagrees.
>How-To-Repeat:
	Restore an archive that you didn't realize used '/home' and which
	has six-month-older versions of important data.
>Fix:
	This "fix" adds a flag "-A" (works in all modes) which makes leading
	slashes work.  If the flag is not present, upon encountering a name
	with a leading slash, pax removes the leading slash.  The first time
	it does this during a given invocation, it prints a warning message.

*** ar_subs.c.orig	Thu Aug 19 00:02:28 1999
--- ar_subs.c	Thu Aug 19 00:02:26 1999
***************
*** 112,117 ****
--- 112,120 ----
  	 * step through the archive until the format says it is done
  	 */
  	while (next_head(arcn) == 0) {
+ 		if (arcn->name[0] == '/' && !check_Aflag()) {
+ 			memmove(arcn->name, arcn->name + 1, strlen(arcn->name));
+ 		}
  		/*
  		 * check for pattern, and user specified options match.
  		 * When all patterns are matched we are done.
***************
*** 197,202 ****
--- 200,208 ----
  	 */
  	while (next_head(arcn) == 0) {
  
+ 		if (arcn->name[0] == '/' && !check_Aflag()) {
+ 			memmove(arcn->name, arcn->name + 1, strlen(arcn->name));
+ 		}
  		/*
  		 * check for pattern, and user specified options match. When
  		 * all the patterns are matched we are done
***************
*** 435,440 ****
--- 441,449 ----
  			}
  		}
  
+ 		if (arcn->name[0] == '/' && !check_Aflag()) {
+ 			memmove(arcn->name, arcn->name + 1, strlen(arcn->name));
+ 		}
  		/*
  		 * Now modify the name as requested by the user
  		 */
*** extern.h.orig	Thu Mar  4 06:04:32 1999
--- extern.h	Wed Aug 18 23:53:09 1999
***************
*** 167,172 ****
--- 167,173 ----
  u_quad_t asc_uqd __P((char *, int, int));
  int uqd_asc __P((u_quad_t, char *, int, int));
  #endif
+ int check_Aflag __P((void));
  
  /* 
   * getoldopt.c
***************
*** 201,206 ****
--- 202,208 ----
   */
  extern int act;
  extern FSUB *frmt;
+ extern int Aflag;
  extern int cflag;
  extern int dflag;
  extern int iflag;
*** gen_subs.c.orig	Thu Aug 19 00:02:28 1999
--- gen_subs.c	Thu Aug 19 00:02:26 1999
***************
*** 504,506 ****
--- 504,517 ----
  	return(0);
  }
  #endif
+ 
+ int
+ check_Aflag(void) {
+ 	if (Aflag > 0)
+ 		return 1;
+ 	if (Aflag == 0) {
+ 		Aflag = -1;
+ 		fprintf(stderr, "warning!  stripping '/' from absolute paths\n");
+ 	}
+ 	return 0;
+ }
*** options.c.orig	Thu Aug 19 00:02:29 1999
--- options.c	Thu Aug 19 00:02:26 1999
***************
*** 207,213 ****
  	/*
  	 * process option flags
  	 */
! 	while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:zB:DE:G:HLPT:U:XYZ"))
  	    != -1) {
  		switch (c) {
  		case 'a':
--- 207,213 ----
  	/*
  	 * process option flags
  	 */
! 	while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:zAB:DE:G:HLPT:U:XYZ"))
  	    != -1) {
  		switch (c) {
  		case 'a':
***************
*** 400,405 ****
--- 400,409 ----
  			zflag = 1;
  			gzip_program = GZIP_CMD;
  			break;
+ 		case 'A':
+ 			Aflag = 1;
+ 			flg |= CAF;
+ 			break;
  		case 'B':
  			/*
  			 * non-standard option on number of bytes written on a
***************
*** 729,734 ****
--- 733,741 ----
  			 * write an archive
  			 */
  			act = EXTRACT;
+ 			break;
+ 		case 'A':
+ 			Aflag = 1;
  			break;
  		case 'z':
  			/*
*** options.h.orig	Fri Oct 13 18:43:11 1995
--- options.h	Wed Aug 18 23:53:10 1999
***************
*** 75,98 ****
  #define	VF	0x00008000
  #define	WF	0x00010000
  #define	XF	0x00020000
! #define	CBF	0x00040000	/* nonstandard extension */
! #define	CDF	0x00080000	/* nonstandard extension */
! #define	CEF	0x00100000	/* nonstandard extension */
! #define	CGF	0x00200000	/* nonstandard extension */
! #define	CHF	0x00400000	/* nonstandard extension */
! #define	CLF	0x00800000	/* nonstandard extension */
! #define	CPF	0x01000000	/* nonstandard extension */
! #define	CTF	0x02000000	/* nonstandard extension */
! #define	CUF	0x04000000	/* nonstandard extension */
! #define	CXF	0x08000000
! #define	CYF	0x10000000	/* nonstandard extension */
! #define	CZF	0x20000000	/* nonstandard extension */
  
  /*
   * ascii string indexed by bit position above (alter the above and you must
   * alter this string) used to tell the user what flags caused us to complain
   */
! #define FLGCH	"abcdfiklnoprstuvwxBDEGHLPTUXYZ"
  
  /*
   * legal pax operation bit patterns
--- 75,99 ----
  #define	VF	0x00008000
  #define	WF	0x00010000
  #define	XF	0x00020000
! #define	CAF	0x00040000	/* nonstandard extension */
! #define	CBF	0x00080000	/* nonstandard extension */
! #define	CDF	0x00100000	/* nonstandard extension */
! #define	CEF	0x00200000	/* nonstandard extension */
! #define	CGF	0x00400000	/* nonstandard extension */
! #define	CHF	0x00800000	/* nonstandard extension */
! #define	CLF	0x01000000	/* nonstandard extension */
! #define	CPF	0x02000000	/* nonstandard extension */
! #define	CTF	0x04000000	/* nonstandard extension */
! #define	CUF	0x08000000	/* nonstandard extension */
! #define	CXF	0x10000000
! #define	CYF	0x20000000	/* nonstandard extension */
! #define	CZF	0x40000000	/* nonstandard extension */
  
  /*
   * ascii string indexed by bit position above (alter the above and you must
   * alter this string) used to tell the user what flags caused us to complain
   */
! #define FLGCH	"abcdfiklnoprstuvwxABDEGHLPTUXYZ"
  
  /*
   * legal pax operation bit patterns
*** pax.c.orig	Thu Aug 19 00:02:29 1999
--- pax.c	Thu Aug 19 00:02:27 1999
***************
*** 84,89 ****
--- 84,90 ----
  int	uflag;			/* ignore older modification time files */
  int	vflag;			/* produce verbose output */
  int	zflag;			/* use gzip */
+ int	Aflag;			/* honor absolute path */
  int	Dflag;			/* same as uflag except inode change time */
  int	Hflag;			/* follow command line symlinks (write only) */
  int	Lflag;			/* follow symlinks when writing */
>Audit-Trail:
>Unformatted: