Subject: bin/36274: pkg_add(8) -t option broken
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <j+nbsd@2007.salmi.ch>
List: netbsd-bugs
Date: 05/04/2007 09:05:00
>Number:         36274
>Category:       bin
>Synopsis:       pkg_add(8) -t option broken
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri May 04 09:05:00 +0000 2007
>Originator:     Jukka Salmi
>Release:        NetBSD 4.99.18
>Environment:
System: NetBSD moray.salmi.ch 4.99.18 NetBSD 4.99.18 (MORAY.APM) #0: Thu Apr 26 01:13:24 CEST 2007 build@moray.salmi.ch:/b/build/nbsd/c/i386/sys/arch/i386/compile/MORAY.APM i386
Architecture: i386
Machine: i386
>Description:
Specifying a mktemp(3) template name with pkg_add's -t option doesn't work.
>How-To-Repeat:
Try to use a staging area other than the default /var/tmp when
installing a package using the -t option:

$ pkg_add -v -t /a/tmp/dir.XXXXXX .../SomePackage-0.1.tgz
[...]
Requested space: 20975752 bytes, free space: 808001536 bytes in /var/tmp/instmp.02275a
[...]

pkg_add(8) falls back to the default directory even if /a/tmp has
enough free space...

>Fix:
Change the pkg_install library not to stat(2) a nonexisting directory
and expect it to succeed...

The patch is also available from
http://salmi.ch/~jukka/patches/nbsd/HEAD/usr.sbin/pkg_install/template.patch

Index: usr.sbin/pkg_install/lib/pen.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/pkg_install/lib/pen.c,v
retrieving revision 1.36
diff -u -p -r1.36 pen.c
--- usr.sbin/pkg_install/lib/pen.c	17 Mar 2006 01:58:25 -0000	1.36
+++ usr.sbin/pkg_install/lib/pen.c	3 May 2007 22:24:33 -0000
@@ -102,6 +102,7 @@ find_play_pen(char *pen, size_t pensize,
 {
 	char   *cp;
 	struct stat sb;
+	char   *r;
 
 	if (pen == NULL) {
 		cleanup(0);
@@ -111,8 +112,12 @@ find_play_pen(char *pen, size_t pensize,
 		return NULL;
 	}
 	
-	if (pen[0] && stat(pen, &sb) != FAIL && (min_free(pen) >= sz))
-		return pen;
+	if (pen[0] && (r = rindex(pen, '/')) != NULL) {
+		char pendir[r-pen+1];
+		strlcpy(pendir, pen, sizeof(pendir));
+		if (stat(pendir, &sb) != FAIL && (min_free(pendir) >= sz))
+			return pen;
+	}
 	else if ((cp = getenv("PKG_TMPDIR")) != NULL && stat(cp, &sb) != FAIL && (min_free(cp) >= sz))
 		(void) snprintf(pen, pensize, "%s/instmp.XXXXXX", cp);
 	else if ((cp = getenv("TMPDIR")) != NULL && stat(cp, &sb) != FAIL && (min_free(cp) >= sz))