Subject: bin/3563: making install more non-root friendly
To: None <gnats-bugs@gnats.netbsd.org>
From: Michael C. Richardson <mcr@sandelman.ottawa.on.ca>
List: netbsd-bugs
Date: 04/30/1997 21:17:02
>Number:         3563
>Category:       bin
>Synopsis:       install causes make to fail
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Apr 30 18:20:01 1997
>Last-Modified:
>Originator:     Michael C. Richardson
>Organization:
Sandelman Software Works
>Release:        1.2
>Environment:
	
System: NetBSD istari.sandelman.ottawa.on.ca 1.2D NetBSD 1.2D (SSW) #5: Wed Apr 16 15:33:15 EDT 1997 mcr@istari.sandelman.ottawa.on.ca:/j/netbsd/src/sys/arch/i386/compile/SSW i386
Architecture: i386

>Description:
	If one wants to install a binary for a NetBSD source tree in
	a directory structure other than / (for which isn't required, or
	desirable, or allowed (e.g. NFS)), it would be nice to have
	install optionally fail gracefully when it can't chown.
>How-To-Repeat:
	as non-root do:
	cd /usr/src/usr.bin/more; make DESTDIR=$HOME/export install

>Fix:
	Apply this patch, install install.
	setenv INSTALL_QUIET
	cd /usr/src/usr.bin/more; make DESTDIR=$HOME/export install

diff -c /w/netbsd/src/usr.bin/xinstall/install.1 ./install.1
*** /w/netbsd/src/usr.bin/xinstall/install.1	Thu Apr 17 07:25:01 1997
--- ./install.1	Wed Apr 30 20:57:54 1997
***************
*** 1,4 ****
! .\"	$NetBSD: install.1,v 1.8 1997/04/17 07:56:55 thorpej Exp $
  .\"
  .\" Copyright (c) 1987, 1990, 1993
  .\"	The Regents of the University of California.  All rights reserved.
--- 1,4 ----
! .\"	$NetBSD: install.1,v 1.7 1997/04/03 15:28:06 christos Exp $
  .\"
  .\" Copyright (c) 1987, 1990, 1993
  .\"	The Regents of the University of California.  All rights reserved.
***************
*** 41,47 ****
  .Nd install binaries
  .Sh SYNOPSIS
  .Nm install
! .Op Fl cs
  .Op Fl f Ar flags
  .Op Fl g Ar group
  .Op Fl l Ar linkflags
--- 41,47 ----
  .Nd install binaries
  .Sh SYNOPSIS
  .Nm install
! .Op Fl csQ
  .Op Fl f Ar flags
  .Op Fl g Ar group
  .Op Fl l Ar linkflags
***************
*** 49,55 ****
  .Op Fl o Ar owner
  .Ar file1 file2
  .Nm install
! .Op Fl cs
  .Op Fl f Ar flags
  .Op Fl g Ar group
  .Op Fl l Ar linkflags
--- 49,55 ----
  .Op Fl o Ar owner
  .Ar file1 file2
  .Nm install
! .Op Fl csQ
  .Op Fl f Ar flags
  .Op Fl g Ar group
  .Op Fl l Ar linkflags
***************
*** 123,136 ****
  exec's the command
  .Xr strip  1
  to strip binaries so that install can be portable over a large
! number of systems and binary types.  If the environment variable
! .Nm STRIP
! is set, it is used as the
! .Xr strip 1
! program.
  .It Fl d
  Create directories. 
  Missing parent directories are created as required.
  .El
  .Pp
  By default,
--- 123,140 ----
  exec's the command
  .Xr strip  1
  to strip binaries so that install can be portable over a large
! number of systems and binary types.
  .It Fl d
  Create directories. 
  Missing parent directories are created as required.
+ .It Fl Q
+ Be quiet about chown operations that fail. This option is also set
+ when the environment variable 
+ .Pa INSTALL_QUIET
+ is set. This option is useful when installing a binary as non
+ root. (Such as when using 
+ .Pa DESTDIR=/some/other/place
+ from a source distribution directory).
  .El
  .Pp
  By default,
diff -c /w/netbsd/src/usr.bin/xinstall/xinstall.c ./xinstall.c
*** /w/netbsd/src/usr.bin/xinstall/xinstall.c	Sat Apr 19 07:25:05 1997
--- ./xinstall.c	Wed Apr 30 21:01:30 1997
***************
*** 90,95 ****
--- 90,97 ----
  void	strip __P((char *));
  void	usage __P((void));
  
+ int quiet_about_nonroot = 0;
+ 
  int
  main(argc, argv)
  	int argc;
***************
*** 103,110 ****
  	char *p;
  	char *flags = NULL, *to_name, *group = NULL, *owner = NULL;
  
  	iflags = 0;
! 	while ((ch = getopt(argc, argv, "cf:g:l:m:o:sd")) != EOF)
  		switch((char)ch) {
  		case 'c':
  			docopy = 1;
--- 105,116 ----
  	char *p;
  	char *flags = NULL, *to_name, *group = NULL, *owner = NULL;
  
+ 	if(getenv("INSTALL_QUIET")) {
+ 		quiet_about_nonroot=1;
+ 	}
+ 
  	iflags = 0;
! 	while ((ch = getopt(argc, argv, "cf:g:l:m:o:sdQ")) != EOF)
  		switch((char)ch) {
  		case 'c':
  			docopy = 1;
***************
*** 160,165 ****
--- 166,174 ----
  					break;
  				}
  			break;
+ 		case 'Q':
+ 			quiet_about_nonroot=1;
+ 			break;
  		case '?':
  		default:
  			usage();
***************
*** 373,381 ****
  	 * chown may lose the setuid bits.
  	 */
  	if ((gid != -1 || uid != -1) && fchown(to_fd, uid, gid)) {
! 		serrno = errno;
! 		(void)unlink(to_name);
! 		errx(1, "%s: chown/chgrp: %s", to_name, strerror(serrno));
  	}
  	if (fchmod(to_fd, mode)) {
  		serrno = errno;
--- 382,392 ----
  	 * chown may lose the setuid bits.
  	 */
  	if ((gid != -1 || uid != -1) && fchown(to_fd, uid, gid)) {
! 	        if(!quiet_about_nonroot) {
! 		  serrno = errno;
! 		  (void)unlink(to_name);
! 		  errx(1, "%s: chown/chgrp: %s", to_name, strerror(serrno));
! 		}
  	}
  	if (fchmod(to_fd, mode)) {
  		serrno = errno;
***************
*** 508,515 ****
  usage()
  {
  	(void)fprintf(stderr, "\
! usage: install [-cs] [-f flags] [-g group] [-m mode] [-o owner] file1 file2\n\
!        install [-cs] [-f flags] [-g group] [-m mode] [-o owner] file1 ... fileN directory\n\
         install  -d   [-g group] [-m mode] [-o owner] directory ...\n");
  	exit(1);
  }
--- 519,526 ----
  usage()
  {
  	(void)fprintf(stderr, "\
! usage: install [-csQ] [-f flags] [-g group] [-m mode] [-o owner] file1 file2\n\
!        install [-csQ] [-f flags] [-g group] [-m mode] [-o owner] file1 ... fileN directory\n\
         install  -d   [-g group] [-m mode] [-o owner] directory ...\n");
  	exit(1);
  }
>Audit-Trail:
>Unformatted: