From flz@xbsd.org  Mon Feb  7 15:31:58 2005
Return-Path: <flz@xbsd.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 3C11A16A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  7 Feb 2005 15:31:58 +0000 (GMT)
Received: from gate.xbsd.org (xbsd.org [82.233.2.192])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 440C643D3F
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  7 Feb 2005 15:31:57 +0000 (GMT)
	(envelope-from flz@xbsd.org)
Received: from localhost (localhost.xbsd.org [127.0.0.1])
	by gate.xbsd.org (Postfix) with ESMTP id 105F9119F9
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  7 Feb 2005 16:34:36 +0100 (CET)
Received: from gate.xbsd.org ([127.0.0.1])
 by localhost (gate.xbsd.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP
 id 82906-09 for <FreeBSD-gnats-submit@freebsd.org>;
 Mon,  7 Feb 2005 16:34:31 +0100 (CET)
Received: by gate.xbsd.org (Postfix, from userid 2001)
	id 8D9DA119E0; Mon,  7 Feb 2005 16:34:31 +0100 (CET)
Message-Id: <20050207153431.8D9DA119E0@gate.xbsd.org>
Date: Mon,  7 Feb 2005 16:34:31 +0100 (CET)
From: Florent Thoumie <flz@xbsd.org>
Reply-To: Florent Thoumie <flz@xbsd.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: src/usr.sbin/pkg_install - make directory argument for @cwd optional
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         77212
>Category:       bin
>Synopsis:       src/usr.sbin/pkg_install - make directory argument for @cwd optional
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    krion
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Feb 07 15:40:11 GMT 2005
>Closed-Date:    Sat Jan 07 22:11:15 GMT 2006
>Last-Modified:  Sat Jan 07 22:11:15 GMT 2006
>Originator:     Florent Thoumie
>Release:        FreeBSD 5.3-RELEASE i386
>Organization:
Xbsd.org
>Environment:
System: FreeBSD gate.xbsd.org 5.3-RELEASE FreeBSD 5.3-RELEASE #2: Wed Nov 24 16:35:34 CET 2004 root@gate.xbsd.org:/usr/src/sys/i386/compile/GATE i386

>Description:

When using @cwd %%FOO%%, we must ensure to return in the original prefix later,
but doing so with @cwd %%OLDPREFIX%% (having PLIST_SUB+="OLDPREFIX=${PREFIX}")
hardcodes the value in the packing list. That's not really a problem when dealing
with ports but that's a problem with packages since pkg_add -p option only
overrides the first @cwd occurrence.

This patch allow us to use @cwd without any argument. If no directory argument
is given, it will set current working directory to the first prefix given by
the @cwd command.

>How-To-Repeat:
	
>Fix:

	

--- pkginstall-cwd.diff begins here ---
diff -ruN pkg_install.orig/add/extract.c pkg_install/add/extract.c
--- pkg_install.orig/add/extract.c	Wed Jul 28 09:19:15 2004
+++ pkg_install/add/extract.c	Mon Feb  7 15:40:56 2005
@@ -56,6 +56,7 @@
     PackingList q;
     char try[FILENAME_MAX], bup[FILENAME_MAX];
     const char *dir;
+    char *prefix = NULL;
 
     dir = home;
     for (q = start; q != stop; q = q->next) {
@@ -69,7 +70,11 @@
 	    }
 	}
 	else if (q->type == PLIST_CWD) {
-	    if (strcmp(q->name, "."))
+	    if (!prefix)
+		prefix = q->name;
+	    if (q->name == NULL)
+		q->name = prefix;
+	    else if (strcmp(q->name, "."))
 		dir = q->name;
 	    else
 		dir = home;
@@ -103,7 +108,7 @@
 extract_plist(const char *home, Package *pkg)
 {
     PackingList p = pkg->head;
-    char *last_file;
+    char *last_file, *prefix = NULL;
     char *where_args, *perm_args, *last_chdir;
     int maxargs, where_count = 0, perm_count = 0, add_count;
     Boolean preserve;
@@ -212,6 +217,10 @@
 	    break;
 
 	case PLIST_CWD:
+	    if (!prefix)
+		prefix = p->name;
+	    if (p->name == NULL)
+		p->name = strdup(prefix);
 	    if (Verbose)
 		printf("extract: CWD to %s\n", p->name);
 	    PUSHOUT(Directory);
Binary files pkg_install.orig/create/.pkg_create.1.swp and pkg_install/create/.pkg_create.1.swp differ
diff -ruN pkg_install.orig/create/perform.c pkg_install/create/perform.c
--- pkg_install.orig/create/perform.c	Wed Jul 28 09:19:15 2004
+++ pkg_install/create/perform.c	Mon Feb  7 16:12:59 2005
@@ -310,6 +310,8 @@
     FILE *totar;
     pid_t pid;
     const char *cname;
+    char *prefix = NULL;
+
 
     args[nargs++] = "tar";	/* argv[0] */
 
@@ -395,10 +397,15 @@
 	    fprintf(totar, "%s\n", p->name);
 	else if (p->type == PLIST_CWD && BaseDir && p->name && p->name[0] == '/')
 	    fprintf(totar, "-C\n%s%s\n", BaseDir, p->name);
+	else if (p->type == PLIST_CWD && BaseDir && p->name == NULL)
+	    fprintf(totar, "-C\n%s%s\n", BaseDir, prefix);
 	else if (p->type == PLIST_CWD || p->type == PLIST_SRC)
 	    fprintf(totar, "-C\n%s\n", p->name);
 	else if (p->type == PLIST_IGNORE)
 	     p = p->next;
+	if (p->type == PLIST_CWD && !prefix)
+	    prefix = p->name;
+
     }
 
     fclose(totar);
diff -ruN pkg_install.orig/create/pkg_create.1 pkg_install/create/pkg_create.1
--- pkg_install.orig/create/pkg_create.1	Sat Jul  3 01:12:52 2004
+++ pkg_install/create/pkg_create.1	Mon Feb  7 16:21:40 2005
@@ -353,10 +353,14 @@
 in the packing list.
 Briefly described, these sequences are:
 .Bl -tag -width indent -compact
-.It Cm @cwd Ar directory
+.It Cm @cwd Op Ar directory
 Set the internal directory pointer to point to
 .Ar directory .
 All subsequent filenames will be assumed relative to this directory.
+If no
+.Ar directory
+argument is given, it will set the internal directory pointer to the
+first prefix value.
 Note:
 .Cm @cd
 is also an alias for this command.
diff -ruN pkg_install.orig/create/pl.c pkg_install/create/pl.c
--- pkg_install.orig/create/pl.c	Tue Jun 29 21:06:41 2004
+++ pkg_install/create/pl.c	Mon Feb  7 15:32:03 2005
@@ -64,12 +64,17 @@
     const char *where = home;
     const char *there = NULL;
     char name[FILENAME_MAX];
+    char *prefix = NULL;
     PackingList p;
 
     for (p = pkg->head; p != NULL; p = p->next)
 	switch (p->type) {
 	case PLIST_CWD:
-	    where = p->name;
+	    if (!prefix)
+		prefix = p->name;
+	    if (p->name == NULL)
+		where = prefix;
+	    else where = p->name;
 	    break;
 
 	case PLIST_IGNORE:
diff -ruN pkg_install.orig/info/show.c pkg_install/info/show.c
--- pkg_install.orig/info/show.c	Mon May 26 19:06:05 2003
+++ pkg_install/info/show.c	Mon Feb  7 15:38:51 2005
@@ -86,6 +86,7 @@
 {
     PackingList p;
     Boolean ign = FALSE;
+    char *prefix = NULL;
 
     if (!Quiet)
 	printf("%s%s", InfoPrefix, title);
@@ -106,7 +107,9 @@
 	    break;
 
 	case PLIST_CWD:
-	    printf(Quiet ? "@cwd %s\n" : "\tCWD to %s\n", p->name);
+	    if (!prefix)
+		prefix = p->name;
+	    printf(Quiet ? "@cwd %s\n" : "\tCWD to %s\n", (p->name == NULL) ? prefix : p->name);
 	    break;
 
 	case PLIST_SRC:
diff -ruN pkg_install.orig/lib/plist.c pkg_install/lib/plist.c
--- pkg_install.orig/lib/plist.c	Wed Jul 28 09:19:15 2004
+++ pkg_install/lib/plist.c	Mon Feb  7 15:38:22 2005
@@ -310,6 +310,7 @@
 write_plist(Package *pkg, FILE *fp)
 {
     PackingList plist = pkg->head;
+    char *prefix = NULL;
 
     while (plist) {
 	switch(plist->type) {
@@ -318,7 +319,9 @@
 	    break;
 
 	case PLIST_CWD:
-	    fprintf(fp, "%ccwd %s\n", CMD_CHAR, plist->name);
+	    if (!prefix)
+		prefix = plist->name;
+	    fprintf(fp, "%ccwd %s\n", CMD_CHAR, (plist->name == NULL) ? prefix : plist->name);
 	    break;
 
 	case PLIST_SRC:
@@ -414,6 +417,7 @@
     Boolean fail = SUCCESS;
     Boolean preserve;
     char tmp[FILENAME_MAX], *name = NULL;
+    char *prefix = NULL;
 
     preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE;
     for (p = pkg->head; p; p = p->next) {
@@ -427,7 +431,9 @@
 	    break;
 
 	case PLIST_CWD:
-	    Where = p->name;
+	    if (!prefix)
+		prefix = p->name;
+	    Where = (p->name == NULL) ? prefix : p->name;
 	    if (Verbose)
 		printf("Change working directory to %s\n", Where);
 	    break;
--- pkginstall-cwd.diff ends here ---
>Release-Note:
>Audit-Trail:

From: Boris Kovalenko <boris@ntmk.ru>
To: freebsd-gnats-submit@FreeBSD.org, flz@xbsd.org
Cc:  
Subject: Re: bin/77212: src/usr.sbin/pkg_install - make directory argument
 for @cwd optional
Date: Tue, 08 Feb 2005 09:02:56 +0500

 Hello!
 
 	It does not work. Applied patch successfully, make, make install, cd 
 /usr/ports/net/quagga, make package
 
 ===>  Building package for quagga-0.98.2_1
 Creating package /usr/ports/net/quagga.new/quagga-0.98.2_1.tbz
 Registering depends: net-snmp-5.2.1 perl-5.8.6_2.
 Registering conflicts: zebra-devel-[0-9]* zebra-0*.
 Creating bzip'd tar ball in '/usr/ports/net/quagga.new/quagga-0.98.2_1.tbz'
 tar: could not chdir to '(null)'
 
 pkg_create: make_dist: tar command failed with code 256
 *** Error code 1
 
 My code looks like:
 @cwd %%RC_DIR%%
 quagga%%RC_SUFX%%
 watchquagga%%RC_SUFX%%
 @cwd
 
 -- 
 Regards,
 	Boris

From: Florent Thoumie <flz@xbsd.org>
To: Boris Kovalenko <boris@ntmk.ru>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: bin/77212: src/usr.sbin/pkg_install - make directory argument
 for @cwd optional
Date: Tue, 08 Feb 2005 06:34:27 +0100

 This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
 --------------enig55D679A6EF01EF029902289F
 Content-Type: text/plain; charset=KOI8-R; format=flowed
 Content-Transfer-Encoding: 7bit
 
 Boris Kovalenko wrote:
 > Hello!
 >
 >     It does not work. Applied patch successfully, make, make install, cd
 > /usr/ports/net/quagga, make package
 >
 > ===>  Building package for quagga-0.98.2_1
 > Creating package /usr/ports/net/quagga.new/quagga-0.98.2_1.tbz
 > Registering depends: net-snmp-5.2.1 perl-5.8.6_2.
 > Registering conflicts: zebra-devel-[0-9]* zebra-0*.
 > Creating bzip'd tar ball in '/usr/ports/net/quagga.new/quagga-0.98.2_1.tbz'
 > tar: could not chdir to '(null)'
 >
 > pkg_create: make_dist: tar command failed with code 256
 > *** Error code 1
 >
 > My code looks like:
 > @cwd %%RC_DIR%%
 > quagga%%RC_SUFX%%
 > watchquagga%%RC_SUFX%%
 > @cwd
 
 	Weird, I got this message once because I forgot one part of the patch
 	but the one I sent should be good. Make sure your installed all binaries
 	from src/usr.sbin/pkg_install and try make deinstall clean all package in
 	net/quagga to ensure there is no temporary packing list remaining.
 
 	How does your current version of net/quagga differ from the one on
 	FreeBSD CVS Server ?
 
 --
 Florent Thoumie
 flz@xbsd.org
 
 --------------enig55D679A6EF01EF029902289F
 Content-Type: application/pgp-signature; name="signature.asc"
 Content-Description: OpenPGP digital signature
 Content-Disposition: attachment; filename="signature.asc"
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.0 (FreeBSD)
 Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
 
 iD8DBQFCCE9qMxEkbVFH3PQRAk2RAJ42kC1LwDJ8Kly25Hxu3M1qRsUwiQCeICDa
 W9tHQK57kxQWqr5dhhdJr2U=
 =0mWY
 -----END PGP SIGNATURE-----
 
 --------------enig55D679A6EF01EF029902289F--

From: Florent Thoumie <flz@xbsd.org>
To: Boris Kovalenko <boris@ntmk.ru>, FreeBSD-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: bin/77212: src/usr.sbin/pkg_install - make directory argument
 for @cwd optional
Date: Tue, 08 Feb 2005 07:46:05 +0100

 This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
 --------------enigB739B6CC2182B52359FE6A0A
 Content-Type: multipart/mixed;
  boundary="------------000308030009060202020702"
 
 This is a multi-part message in MIME format.
 --------------000308030009060202020702
 Content-Type: text/plain; charset=KOI8-R; format=flowed
 Content-Transfer-Encoding: 7bit
 
 Ok, looks like I broke it between my last test and the PR
 submission. Here is the good diff.
 
 --------------000308030009060202020702
 Content-Type: text/plain;
  name="pkginstall-cwd-v2.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="pkginstall-cwd-v2.diff"
 
 diff -ruN pkg_install.orig/add/extract.c pkg_install/add/extract.c
 --- pkg_install.orig/add/extract.c	Wed Jul 28 09:19:15 2004
 +++ pkg_install/add/extract.c	Mon Feb  7 15:40:56 2005
 @@ -56,6 +56,7 @@
      PackingList q;
      char try[FILENAME_MAX], bup[FILENAME_MAX];
      const char *dir;
 +    char *prefix = NULL;
 
      dir = home;
      for (q = start; q != stop; q = q->next) {
 @@ -69,7 +70,11 @@
  	    }
  	}
  	else if (q->type == PLIST_CWD) {
 -	    if (strcmp(q->name, "."))
 +	    if (!prefix)
 +		prefix = q->name;
 +	    if (q->name == NULL)
 +		q->name = prefix;
 +	    else if (strcmp(q->name, "."))
  		dir = q->name;
  	    else
  		dir = home;
 @@ -103,7 +108,7 @@
  extract_plist(const char *home, Package *pkg)
  {
      PackingList p = pkg->head;
 -    char *last_file;
 +    char *last_file, *prefix = NULL;
      char *where_args, *perm_args, *last_chdir;
      int maxargs, where_count = 0, perm_count = 0, add_count;
      Boolean preserve;
 @@ -212,6 +217,10 @@
  	    break;
 
  	case PLIST_CWD:
 +	    if (!prefix)
 +		prefix = p->name;
 +	    if (p->name == NULL)
 +		p->name = strdup(prefix);
  	    if (Verbose)
  		printf("extract: CWD to %s\n", p->name);
  	    PUSHOUT(Directory);
 diff -ruN pkg_install.orig/create/perform.c pkg_install/create/perform.c
 --- pkg_install.orig/create/perform.c	Wed Jul 28 09:19:15 2004
 +++ pkg_install/create/perform.c	Tue Feb  8 07:39:48 2005
 @@ -310,6 +310,8 @@
      FILE *totar;
      pid_t pid;
      const char *cname;
 +    char *prefix = NULL;
 +
 
      args[nargs++] = "tar";	/* argv[0] */
 
 @@ -393,12 +395,17 @@
      for (p = plist->head; p; p = p->next) {
  	if (p->type == PLIST_FILE)
  	    fprintf(totar, "%s\n", p->name);
 +	else if (p->type == PLIST_CWD && p->name == NULL)
 +	    fprintf(totar, "-C\n%s\n", prefix);
  	else if (p->type == PLIST_CWD && BaseDir && p->name && p->name[0] == '/')
  	    fprintf(totar, "-C\n%s%s\n", BaseDir, p->name);
  	else if (p->type == PLIST_CWD || p->type == PLIST_SRC)
  	    fprintf(totar, "-C\n%s\n", p->name);
  	else if (p->type == PLIST_IGNORE)
  	     p = p->next;
 +	if (p->type == PLIST_CWD && !prefix)
 +	    prefix = p->name;
 +
      }
 
      fclose(totar);
 diff -ruN pkg_install.orig/create/pkg_create.1 pkg_install/create/pkg_create.1
 --- pkg_install.orig/create/pkg_create.1	Sat Jul  3 01:12:52 2004
 +++ pkg_install/create/pkg_create.1	Mon Feb  7 16:21:40 2005
 @@ -353,10 +353,14 @@
  in the packing list.
  Briefly described, these sequences are:
  .Bl -tag -width indent -compact
 -.It Cm @cwd Ar directory
 +.It Cm @cwd Op Ar directory
  Set the internal directory pointer to point to
  .Ar directory .
  All subsequent filenames will be assumed relative to this directory.
 +If no
 +.Ar directory
 +argument is given, it will set the internal directory pointer to the
 +first prefix value.
  Note:
  .Cm @cd
  is also an alias for this command.
 diff -ruN pkg_install.orig/create/pl.c pkg_install/create/pl.c
 --- pkg_install.orig/create/pl.c	Tue Jun 29 21:06:41 2004
 +++ pkg_install/create/pl.c	Mon Feb  7 15:32:03 2005
 @@ -64,12 +64,17 @@
      const char *where = home;
      const char *there = NULL;
      char name[FILENAME_MAX];
 +    char *prefix = NULL;
      PackingList p;
 
      for (p = pkg->head; p != NULL; p = p->next)
  	switch (p->type) {
  	case PLIST_CWD:
 -	    where = p->name;
 +	    if (!prefix)
 +		prefix = p->name;
 +	    if (p->name == NULL)
 +		where = prefix;
 +	    else where = p->name;
  	    break;
 
  	case PLIST_IGNORE:
 diff -ruN pkg_install.orig/info/show.c pkg_install/info/show.c
 --- pkg_install.orig/info/show.c	Mon May 26 19:06:05 2003
 +++ pkg_install/info/show.c	Mon Feb  7 15:38:51 2005
 @@ -86,6 +86,7 @@
  {
      PackingList p;
      Boolean ign = FALSE;
 +    char *prefix = NULL;
 
      if (!Quiet)
  	printf("%s%s", InfoPrefix, title);
 @@ -106,7 +107,9 @@
  	    break;
 
  	case PLIST_CWD:
 -	    printf(Quiet ? "@cwd %s\n" : "\tCWD to %s\n", p->name);
 +	    if (!prefix)
 +		prefix = p->name;
 +	    printf(Quiet ? "@cwd %s\n" : "\tCWD to %s\n", (p->name == NULL) ? prefix : p->name);
  	    break;
 
  	case PLIST_SRC:
 diff -ruN pkg_install.orig/lib/plist.c pkg_install/lib/plist.c
 --- pkg_install.orig/lib/plist.c	Wed Jul 28 09:19:15 2004
 +++ pkg_install/lib/plist.c	Mon Feb  7 15:38:22 2005
 @@ -310,6 +310,7 @@
  write_plist(Package *pkg, FILE *fp)
  {
      PackingList plist = pkg->head;
 +    char *prefix = NULL;
 
      while (plist) {
  	switch(plist->type) {
 @@ -318,7 +319,9 @@
  	    break;
 
  	case PLIST_CWD:
 -	    fprintf(fp, "%ccwd %s\n", CMD_CHAR, plist->name);
 +	    if (!prefix)
 +		prefix = plist->name;
 +	    fprintf(fp, "%ccwd %s\n", CMD_CHAR, (plist->name == NULL) ? prefix : plist->name);
  	    break;
 
  	case PLIST_SRC:
 @@ -414,6 +417,7 @@
      Boolean fail = SUCCESS;
      Boolean preserve;
      char tmp[FILENAME_MAX], *name = NULL;
 +    char *prefix = NULL;
 
      preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE;
      for (p = pkg->head; p; p = p->next) {
 @@ -427,7 +431,9 @@
  	    break;
 
  	case PLIST_CWD:
 -	    Where = p->name;
 +	    if (!prefix)
 +		prefix = p->name;
 +	    Where = (p->name == NULL) ? prefix : p->name;
  	    if (Verbose)
  		printf("Change working directory to %s\n", Where);
  	    break;
 
 --------------000308030009060202020702--
 
 --------------enigB739B6CC2182B52359FE6A0A
 Content-Type: application/pgp-signature; name="signature.asc"
 Content-Description: OpenPGP digital signature
 Content-Disposition: attachment; filename="signature.asc"
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.0 (FreeBSD)
 Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
 
 iD8DBQFCCGA0MxEkbVFH3PQRApT0AJ9byLWBdWVAIO+5UmO5KbhUdINKZQCggIJ7
 3XMONYbdffQK9KXrl5ivtjo=
 =esiR
 -----END PGP SIGNATURE-----
 
 --------------enigB739B6CC2182B52359FE6A0A--

From: Florent Thoumie <flz@xbsd.org>
To: Boris Kovalenko <boris@ntmk.ru>, FreeBSD-gnats-submit@FreeBSD.org
Cc: eik@FreeBSD.org
Subject: Re: bin/77212: src/usr.sbin/pkg_install - make directory argument
 for @cwd optional
Date: Tue, 08 Feb 2005 14:59:02 +0100

 This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
 --------------enig2F04D11FFA6F2D60FEA92DED
 Content-Type: multipart/mixed;
  boundary="------------040905070306010406050105"
 
 This is a multi-part message in MIME format.
 --------------040905070306010406050105
 Content-Type: text/plain; charset=KOI8-R; format=flowed
 Content-Transfer-Encoding: 7bit
 
 Boris Kovalenko wrote:
 
 >     Yeah, now patch is working, but not as expected. pkg_add -p changes
 > only the first occurence of @cwd. So, in the last of the +INSTALL file I
 > see:
 > @cwd /etc/rc.d
 > ....
 > @cwd /usr/local <--- !!!
 >
 > When installing with pkg_add -p all files after this line (info files
 > for example) are going to wrong place. So @pushwd and @popwd, imho, will
 > be better choise.
 
 	Here is the new diff. I patched too much and there was no "@cwd"
 	(without dir argument) command anymore in the resulting package.
 
 	This one should work fine, unless I overlooked something (which
 	is more than possible).
 
 	I'm CC'ing eik, just in case he could help us reviewing this
 	patch.
 
 --
 Florent Thoumie
 flz@xbsd.org
 
 --------------040905070306010406050105
 Content-Type: text/plain;
  name="pkginstall-cwd-v3.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="pkginstall-cwd-v3.diff"
 
 diff -ruN pkg_install.orig/add/extract.c pkg_install/add/extract.c
 --- pkg_install.orig/add/extract.c	Wed Jul 28 09:19:15 2004
 +++ pkg_install/add/extract.c	Tue Feb  8 14:28:39 2005
 @@ -56,6 +56,7 @@
      PackingList q;
      char try[FILENAME_MAX], bup[FILENAME_MAX];
      const char *dir;
 +    char *prefix = NULL;
 
      dir = home;
      for (q = start; q != stop; q = q->next) {
 @@ -69,7 +70,11 @@
  	    }
  	}
  	else if (q->type == PLIST_CWD) {
 -	    if (strcmp(q->name, "."))
 +	    if (!prefix)
 +		prefix = q->name;
 +	    if (q->name == NULL)
 +		q->name = prefix;
 +	    else if (strcmp(q->name, "."))
  		dir = q->name;
  	    else
  		dir = home;
 @@ -103,7 +108,7 @@
  extract_plist(const char *home, Package *pkg)
  {
      PackingList p = pkg->head;
 -    char *last_file;
 +    char *last_file, *prefix = NULL;
      char *where_args, *perm_args, *last_chdir;
      int maxargs, where_count = 0, perm_count = 0, add_count;
      Boolean preserve;
 @@ -212,6 +217,10 @@
  	    break;
 
  	case PLIST_CWD:
 +	    if (!prefix)
 +		prefix = p->name;
 +	    if (p->name == NULL)
 +		p->name = strdup(prefix);
  	    if (Verbose)
  		printf("extract: CWD to %s\n", p->name);
  	    PUSHOUT(Directory);
 diff -ruN pkg_install.orig/create/perform.c pkg_install/create/perform.c
 --- pkg_install.orig/create/perform.c	Wed Jul 28 09:19:15 2004
 +++ pkg_install/create/perform.c	Tue Feb  8 07:43:01 2005
 @@ -310,6 +310,8 @@
      FILE *totar;
      pid_t pid;
      const char *cname;
 +    char *prefix = NULL;
 +
 
      args[nargs++] = "tar";	/* argv[0] */
 
 @@ -393,12 +395,17 @@
      for (p = plist->head; p; p = p->next) {
  	if (p->type == PLIST_FILE)
  	    fprintf(totar, "%s\n", p->name);
 +	else if (p->type == PLIST_CWD && p->name == NULL)
 +	    fprintf(totar, "-C\n%s\n", prefix);
  	else if (p->type == PLIST_CWD && BaseDir && p->name && p->name[0] == '/')
  	    fprintf(totar, "-C\n%s%s\n", BaseDir, p->name);
  	else if (p->type == PLIST_CWD || p->type == PLIST_SRC)
  	    fprintf(totar, "-C\n%s\n", p->name);
  	else if (p->type == PLIST_IGNORE)
  	     p = p->next;
 +	if (p->type == PLIST_CWD && !prefix)
 +	    prefix = p->name;
 +
      }
 
      fclose(totar);
 diff -ruN pkg_install.orig/create/pkg_create.1 pkg_install/create/pkg_create.1
 --- pkg_install.orig/create/pkg_create.1	Sat Jul  3 01:12:52 2004
 +++ pkg_install/create/pkg_create.1	Tue Feb  8 07:43:01 2005
 @@ -353,10 +353,14 @@
  in the packing list.
  Briefly described, these sequences are:
  .Bl -tag -width indent -compact
 -.It Cm @cwd Ar directory
 +.It Cm @cwd Op Ar directory
  Set the internal directory pointer to point to
  .Ar directory .
  All subsequent filenames will be assumed relative to this directory.
 +If no
 +.Ar directory
 +argument is given, it will set the internal directory pointer to the
 +first prefix value.
  Note:
  .Cm @cd
  is also an alias for this command.
 diff -ruN pkg_install.orig/create/pl.c pkg_install/create/pl.c
 --- pkg_install.orig/create/pl.c	Tue Jun 29 21:06:41 2004
 +++ pkg_install/create/pl.c	Tue Feb  8 14:42:49 2005
 @@ -64,12 +64,15 @@
      const char *where = home;
      const char *there = NULL;
      char name[FILENAME_MAX];
 +    char *prefix = NULL;
      PackingList p;
 
      for (p = pkg->head; p != NULL; p = p->next)
  	switch (p->type) {
  	case PLIST_CWD:
 -	    where = p->name;
 +	    if (!prefix)
 +		prefix = p->name;
 +	    where = (p->name == NULL) ? prefix : p->name;
  	    break;
 
  	case PLIST_IGNORE:
 @@ -135,7 +138,7 @@
      PackingList p = plist->head;
      const char *where = home;
      const char *there = NULL, *mythere;
 -    char *where_args;
 +    char *where_args, *prefix = NULL;
      const char *last_chdir, *root = "/";
      int maxargs, where_count = 0, add_count;
      struct stat stb;
 @@ -168,7 +171,11 @@
 
      while (p) {
  	if (p->type == PLIST_CWD)
 -	    where = p->name;
 +	{
 +	    if (!prefix)
 +		prefix = p->name;
 +	    where = p->name == NULL ? prefix : p->name;
 +	}
  	else if (p->type == PLIST_SRC)
  	    there = p->name;
  	else if (p->type == PLIST_IGNORE)
 diff -ruN pkg_install.orig/info/show.c pkg_install/info/show.c
 --- pkg_install.orig/info/show.c	Mon May 26 19:06:05 2003
 +++ pkg_install/info/show.c	Tue Feb  8 14:41:44 2005
 @@ -86,6 +86,7 @@
  {
      PackingList p;
      Boolean ign = FALSE;
 +    char *prefix = NULL;
 
      if (!Quiet)
  	printf("%s%s", InfoPrefix, title);
 @@ -106,7 +107,9 @@
  	    break;
 
  	case PLIST_CWD:
 -	    printf(Quiet ? "@cwd %s\n" : "\tCWD to %s\n", p->name);
 +	    if (!prefix)
 +		prefix = p->name;
 +	    printf(Quiet ? "@cwd %s\n" : "\tCWD to %s\n", (p->name == NULL) ? prefix : p->name);
  	    break;
 
  	case PLIST_SRC:
 diff -ruN pkg_install.orig/lib/plist.c pkg_install/lib/plist.c
 --- pkg_install.orig/lib/plist.c	Wed Jul 28 09:19:15 2004
 +++ pkg_install/lib/plist.c	Tue Feb  8 14:43:55 2005
 @@ -318,7 +318,7 @@
  	    break;
 
  	case PLIST_CWD:
 -	    fprintf(fp, "%ccwd %s\n", CMD_CHAR, plist->name);
 +	    fprintf(fp, "%ccwd %s\n", CMD_CHAR, (plist->name == NULL) ? "" : plist->name);
  	    break;
 
  	case PLIST_SRC:
 @@ -414,6 +414,7 @@
      Boolean fail = SUCCESS;
      Boolean preserve;
      char tmp[FILENAME_MAX], *name = NULL;
 +    char *prefix = NULL;
 
      preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE;
      for (p = pkg->head; p; p = p->next) {
 @@ -427,7 +428,9 @@
  	    break;
 
  	case PLIST_CWD:
 -	    Where = p->name;
 +	    if (!prefix)
 +		prefix = p->name;
 +	    Where = (p->name == NULL) ? prefix : p->name;
  	    if (Verbose)
  		printf("Change working directory to %s\n", Where);
  	    break;
 
 --------------040905070306010406050105--
 
 --------------enig2F04D11FFA6F2D60FEA92DED
 Content-Type: application/pgp-signature; name="signature.asc"
 Content-Description: OpenPGP digital signature
 Content-Disposition: attachment; filename="signature.asc"
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.0 (FreeBSD)
 Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
 
 iD8DBQFCCMWtMxEkbVFH3PQRAkYAAJ9vtf4Ncarx2w61xFVTN6sAoHhssQCdE6l/
 vYfMdfhHLLH0pMrQ6EpBUZs=
 =E8T2
 -----END PGP SIGNATURE-----
 
 --------------enig2F04D11FFA6F2D60FEA92DED--
Responsible-Changed-From-To: freebsd-bugs->krion 
Responsible-Changed-By: arved 
Responsible-Changed-When: Tue Jun 7 17:57:11 GMT 2005 
Responsible-Changed-Why:  
krion got an src commit bit for playing with pkg_tools. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=77212 
State-Changed-From-To: open->closed 
State-Changed-By: krion 
State-Changed-When: Sat Jan 7 22:11:13 UTC 2006 
State-Changed-Why:  
The patch is committed, thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=77212 
>Unformatted:
