Subject: bin/3191: which should be removed or replaced
To: None <gnats-bugs@gnats.netbsd.org>
From: Arne Henrik Juul <arnej@imf.unit.no>
List: netbsd-bugs
Date: 02/05/1997 17:04:14
>Number:         3191
>Category:       bin
>Synopsis:       which should be removed or replaced
>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 Feb  5 08:20:01 1997
>Last-Modified:
>Originator:     
>Organization:
	Norwegian University of Technology and Science
>Release:        1.2
>Environment:

System: NetBSD chur.imf.unit.no 1.2 NetBSD 1.2 (CHUR) #2: Tue Oct 22 13:25:57 MET DST 1996 arnej@chur.imf.unit.no:/usr/src/sys/arch/sparc/compile/CHUR sparc

>Description:
	The installed which csh script is both wrong and un-intuitive,
especially for non-csh users.  See lengthy discussion on netbsd-bugs
with subject "bin/3138: [dM] mkdep(1) always uses /usr/bin/gcc".
>How-To-Repeat:
	Inspect /usr/bin/which.  Note that it will probably reset the
path from .cshrc (because it doesn't use -f option).  So you may get a
different program than what you actually get if you give the command.
This is even worse for non-csh users, since their .cshrc will probably
set a different path from their .profile or whatever, aliases are
irrelevant, etc.
>Fix:
	Remove /usr/bin/which (since csh now has a built-in which
that's much better).  If one wants to keep a which program for use
in Makefiles, for sh users, etc., replace it using for example
the following patch.

diff -ruN which.orig/Makefile which/Makefile
--- which.orig/Makefile	Fri Jan 10 13:26:55 1997
+++ which/Makefile	Mon Feb  3 13:53:51 1997
@@ -1,10 +1,6 @@
 #	$NetBSD: Makefile,v 1.5 1997/01/09 20:23:23 tls Exp $
 #	from: @(#)Makefile	5.5 (Berkeley) 7/1/90
 
-MAN=	which.1
-
-beforeinstall:
-	${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
-	    ${.CURDIR}/which.csh ${DESTDIR}${BINDIR}/which
+PROG=	which
 
 .include <bsd.prog.mk>
diff -ruN which.orig/which.1 which/which.1
--- which.orig/which.1	Fri Jan 10 13:26:55 1997
+++ which/which.1	Wed Feb  5 16:46:11 1997
@@ -34,40 +34,48 @@
 .\"     from: @(#)which.1	6.3 (Berkeley) 4/23/91
 .\"	$NetBSD: which.1,v 1.3 1997/01/09 20:23:24 tls Exp $
 .\"
-.Dd April 23, 1991
+.Dd Feb 3, 1997
 .Dt WHICH 1
-.Os BSD 3
+.Os BSD 4.4
 .Sh NAME
 .Nm which
-.Nd "locate a program file including aliases and paths"
-.Pq Xr csh 1
-only)
+.Nd "locate a program file"
 .Sh SYNOPSIS
-.Nm which
-.Op Ar name
-.Ar ...
+.Nm
+.Ar name
 .Sh DESCRIPTION
-.Nm Which
-takes a list of names and looks for the files which would be
-executed had these names been given as commands.
-Each argument is expanded if it is aliased,
-and searched for along the user's path.
-Both aliases and path are taken from the user's
-.Pa \&.cshrc
-file.
-.Sh FILES
-.Bl -tag -width ~/\&.cshrc
-.It Pa ~/\&.cshrc
-source of aliases and path values
-.El
+.Nm
+exists in two variants:  A stand-alone program, and a csh built-in.
+.Pp
+It takes a command name and looks for the file that would
+be executed had this name been given as a command, using the
+.Ev PATH
+variable.
+.Pp
+The csh built-in also handles the current csh aliases and built-ins.
+It also accepts several command names as arguments.
 .Sh DIAGNOSTICS
-A diagnostic is given for names which are aliased to more than a single
-word,
-or if an executable file with the argument name was not found in the path.
+A diagnostic is given if an executable file with the argument name
+was not found in the path, or if the 
+.Ev PATH
+variable was not set.
 .Sh BUGS
-Must be executed by a
+The 
+.Nm
+binary is only provided as a fallback for sh users.
+For interactive users, a shell built-in that handles shell aliases,
+built-ins, and other shell-special functions should be used.
+Compare bash
+.Dq type
+and ksh
+.Dq whence .
+.Pp
+The 
+.Nm
+binary has no options and handles one command name only.
+.Sh SEE ALSO
 .Xr csh 1 ,
-or some other shell which knows about aliases.
+.Xr sh 1
 .Sh HISTORY
 The
 .Nm
diff -ruN which.orig/which.c which/which.c
--- which.orig/which.c	Thu Jan  1 01:00:00 1970
+++ which/which.c	Wed Feb  5 16:44:26 1997
@@ -0,0 +1,138 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Arne H. Juul.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD 
+ *	  Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its 
+ *    contributors may be used to endorse or promote products derived 
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1997\n\
+	The NetBSD Foundation.  All rights reserved.\n";
+
+static char rcsid[] = "$NetBSD$";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static void usage();
+/*
+ * which --
+ *	This which is different from historic which.  But then historic
+ *	which never was sane, even for csh users.
+ */
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	unsigned int len, maxlen, comlen, tplen;
+	struct stat s;
+	char *path, *p, *try, *trypath, *command;
+
+	setlocale(LC_ALL, "");
+
+	if (argc != 2) usage();
+
+	setuid(geteuid()); /* for sanity of access(2) */
+	command = argv[1];
+	comlen = strlen(command);
+	if (strchr(command, '/')) {
+		if ((stat(command, &s) == 0) &&
+		    S_ISREG(s.st_mode) && !access(command, X_OK)) {
+			printf("%s\n", command);
+			exit(0);
+		} else {
+			fprintf(stderr, "%s not found\n", command);
+			exit(1);
+		}
+	}
+	path = getenv("PATH");
+	if (!path) {
+		fprintf(stderr, "which: no PATH in environment\n");
+		exit(1);
+	}
+	p = malloc(1+strlen(path));
+	try = malloc(MAXPATHLEN);
+	if (!(p && try)) {
+		perror("which: malloc failed");
+		exit(1);
+	}
+	strcpy(p, path);
+	maxlen = 0;
+	while (p) {
+		trypath = p;
+		p = strchr(p, ':');
+		if (p)
+			*p++ = '\0' ;
+		if (!*trypath)
+			trypath = ".";
+		tplen = strlen(trypath);
+		len = tplen + 1 + comlen + 1;
+		if (len > maxlen) {
+			maxlen = len;
+			try = realloc(try, maxlen);
+			if (!try) {
+				perror("which: malloc failed");
+				exit(1);
+			}
+		}
+		strcpy(try, trypath);
+		try[tplen] = '/';
+		strcpy(try+tplen+1, command);
+		if ((stat(try, &s) == 0) &&
+		    S_ISREG(s.st_mode) && !access(try, X_OK)) {
+			printf("%s\n", try);
+			exit(0);
+		}
+	}
+	fprintf(stderr, "no %s in path\n", command);
+	exit(1);
+	/* NOTREACHED */
+}
+
+static void
+usage()
+{
+	fprintf(stderr, "usage: which command\n");
+	exit(1);
+}
diff -ruN which.orig/which.csh which/which.csh
--- which.orig/which.csh	Sat Oct 14 04:39:21 1995
+++ which/which.csh	Thu Jan  1 01:00:00 1970
@@ -1,75 +0,0 @@
-#!/bin/csh
-#
-# DO NOT USE "csh -f"
-#
-# Copyright (c) 1983 The Regents of the University of California.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-#    notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-# 3. All advertising materials mentioning features or use of this software
-#    must display the following acknowledgement:
-#	This product includes software developed by the University of
-#	California, Berkeley and its contributors.
-# 4. Neither the name of the University nor the names of its contributors
-#    may be used to endorse or promote products derived from this software
-#    without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-#
-#	@(#)which.csh	5.5 (Berkeley) 4/18/91
-#
-
-#	which : tells you which program you get
-#
-set prompt = "% "
-set noglob
-foreach arg ( $argv )
-    set alius = `alias $arg`
-    switch ( $#alius )
-	case 0 :
-	    breaksw
-	case 1 :
-	    set arg = $alius[1]
-	    breaksw
-        default :
-	    echo ${arg}: "	" aliased to $alius
-	    continue
-    endsw
-    unset found
-    if ( $arg:h != $arg:t ) then
-	if ( -e $arg ) then
-	    echo $arg
-	else
-	    echo $arg not found
-	endif
-	continue
-    else
-	foreach i ( $path )
-	    if ( -x $i/$arg && ! -d $i/$arg ) then
-		echo $i/$arg
-		set found
-		break
-	    endif
-	end
-    endif
-    if ( ! $?found ) then
-	echo no $arg in $path
-    endif
-end
>Audit-Trail:
>Unformatted: