diff options
Diffstat (limited to 'usr.bin/whereis')
-rw-r--r-- | usr.bin/whereis/Makefile | 7 | ||||
-rw-r--r-- | usr.bin/whereis/whereis.1 | 137 | ||||
-rw-r--r-- | usr.bin/whereis/whereis.pl | 243 |
3 files changed, 387 insertions, 0 deletions
diff --git a/usr.bin/whereis/Makefile b/usr.bin/whereis/Makefile new file mode 100644 index 0000000..b4a4df1 --- /dev/null +++ b/usr.bin/whereis/Makefile @@ -0,0 +1,7 @@ +MAN1= whereis.1 + +beforeinstall: + ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ + ${.CURDIR}/whereis.pl ${DESTDIR}${BINDIR}/whereis + +.include <bsd.prog.mk> diff --git a/usr.bin/whereis/whereis.1 b/usr.bin/whereis/whereis.1 new file mode 100644 index 0000000..6c5a4f7 --- /dev/null +++ b/usr.bin/whereis/whereis.1 @@ -0,0 +1,137 @@ +.\" Copyright (c) 1993 +.\" 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. +.\" +.\" @(#)whereis.1 8.2 (Berkeley) 12/30/93 +.\" +.\" $Id$ +.\" +.Dd June 15, 1996 +.Dt WHEREIS 1 +.Os FreeBSD +.Sh NAME +.Nm whereis +.Nd locate programs +.Sh SYNOPSIS +.Nm whereis +.Op Fl bms +.Op Fl u +.Op Fl BMS dir ... Fl f +.Ar program ... +.Sh DESCRIPTION +The +.Nm whereis +utility checks the standard binary, manual page, and source +directories for the specified programs, printing out the paths of any +it finds. The supplied names are first stripped of leading path name +components, any single trailing extension of the form +.Ql .ext , +and the leading +.Ql s. +or trailing +.Ql ,v +from a source code control system. +.Pp +The default path searched is the string returned by the +.Xr sysctl 8 +utility for the +.Dq user.cs_path +string, with +.Pa /usr/libexec +and the current user's +.Ev $PATH +appended. Manual pages are searched by default along the +.Ev $MANPATH . +Program sources are located in a list of known standard places, +including all the subdirectories of +.Pa /usr/src +and +.Pa /usr/ports . +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl B +Specify directories to search for binaries. Requires the +.Fl f +option. +.It Fl M +Specify directories to search for manual pages. Requires the +.Fl f +option. +.It Fl S +Specify directories to search for program sources. Requires the +.Fl f +option. +.It Fl b +Search for binaries. +.It Fl f +Delimits the list of directories after the +.Fl B , +.Fl M , +or +.Fl S +options, and indicates the beginning of the +.Ar name +list. +.It Fl m +Search for manual pages. +.It Fl s +Search for source directories. +.It Fl u +Search for +.Dq unusual +entries. A file is said to be unusual if it does not have one entry +of each requested type. +.El +.Sh EXAMPLE +The following finds all utilities under +.Pa /usr/bin +that do not have documentation: +.Dl whereis -m -u /usr/bin/* +.Sh SEE ALSO +.Xr locate 1 , +.Xr man 1 , +.Xr sysctl 8 +.Sh BUGS +The search for sources is implemented as a quick search as the +first-level subdirectory of each element of the list of source +directories first. If this didn't succeed, the utility +.Xr locate 1 +is requested to do the search in deeper nested subdirectories. This +might take some time, and will only succeed if the locate database is +up-to-date. +.Sh HISTORY +The +.Nm whereis +command appeared in +.Bx 3.0 . +This version re-implements the historical +functionality that was lost in +.Bx 4.4 . diff --git a/usr.bin/whereis/whereis.pl b/usr.bin/whereis/whereis.pl new file mode 100644 index 0000000..12b3997 --- /dev/null +++ b/usr.bin/whereis/whereis.pl @@ -0,0 +1,243 @@ +#!/usr/bin/perl +# +# Copyright © 1995, 1996 Jörg Wunsch +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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. +# +# whereis -- search for binaries, man pages and source directories. +# +# Rewritten from scratch for FreeBSD after the 4.3BSD manual page. +# +# $Id$ +# + +sub usage +{ + print STDERR "usage: $0 [-bms] [-u] [-BMS dir... -f] name ...\n"; + exit 1; +} + +sub scanopts +{ + local($i, $j); + arg: + while ($ARGV[$i] =~ /^-/) { + opt: + for ($j = 1; $j < length($ARGV[$i]); $j++) { + local($_) = substr($ARGV[$i], $j, 1); + local($what, @list); + $opt_b++, next opt if /b/; + $opt_m++, next opt if /m/; + $opt_s++, next opt if /s/; + $opt_u++, next opt if /u/; + &usage unless /[BMS]/; + + # directory list processing + $what = $_; @list = (); + push(@list, substr($ARGV[$i], $j+1)) if $j+1 < length($ARGV[$i]); + $i++; + while ($i <= $#ARGV && $ARGV[$i] !~ /^-/) { + push(@list, $ARGV[$i++]); + } + if ($what eq "B") {@binaries = @list;} + elsif ($what eq "M") {@manuals = @list;} + elsif ($what eq "S") {@sources = @list;} + + $i++, last arg if $ARGV[$i] =~ /^-f$/; + next arg; + } + $i++; + } + &usage if $i > $#ARGV; + + while ($ARGV[$i]) { + push(@names, $ARGV[$i++]); + } +} + + +sub decolonify +{ + local($list) = @_; + local($_, @rv); + foreach(split(/:/, $list)) { + push(@rv, $_); + } + return @rv; +} + + +&scanopts; + +# default to all if no type requested +if ($opt_b + $opt_m + $opt_s == 0) {$opt_b = $opt_m = $opt_s = 1;} + +if (!defined(@binaries)) { + # + # first, use default path, then append /usr/libexec and the user's path + # + local($cs_path) = `/usr/sbin/sysctl -n user.cs_path`; + local(@list, %path); + + chop($cs_path); + + @list = &decolonify($cs_path); + push(@list, "/usr/libexec"); + push(@list, &decolonify($ENV{'PATH'})); + + # resolve ~, remove duplicates + foreach (@list) { + s/^~/$ENV{'HOME'}/ if /^~/; + push(@binaries, $_) if !$path{$_}; + $path{$_}++; + } +} + +if (!defined(@manuals)) { + # + # first, use default manpath, then append user's $MANPATH + # + local($usermanpath) = $ENV{'MANPATH'}; + delete $ENV{'MANPATH'}; + local($manpath) = `/usr/bin/manpath`; + local(@list, %path, $i); + + chop($manpath); + + @list = &decolonify($manpath); + push(@list, &decolonify($usermanpath)); + + # remove duplicates + foreach (@list) { + push(@manuals, $_) if !$path{$_}; + $path{$_}++; + } +} + +if (!defined(@sources)) { + # + # default command sources + # + local($_); + + @sources = ("/usr/src/bin", "/usr/src/usr.bin", "/usr/src/sbin", + "/usr/src/usr.sbin", "/usr/src/libexec", + "/usr/src/gnu/bin", "/usr/src/gnu/usr.bin", + "/usr/src/gnu/sbin", "/usr/src/gnu/usr.sbin", + "/usr/src/gnu/libexec"); + + # + # if /usr/ports exists, look in all its subdirs, too + # + if (-d "/usr/ports" && opendir(PORTS, "/usr/ports")) { + while ($_ = readdir(PORTS)) { + next if /^\.\.?$/; + next if /^distfiles$/; # magic + next if ! -d "/usr/ports/$_"; + push(@sources, "/usr/ports/$_"); + } + closedir(PORTS); + } +} + +if ($opt_m) { + # construct a new MANPATH + foreach (@manuals) { + next if ! -d $_; + if ($manpath) { $manpath .= ":$_"; } + else { $manpath = $_; } + } +} + +# +# main loop +# +foreach $name (@names) { + $name =~ s|^.*/||; # strip leading path name component + $name =~ s/,v$//; $name =~ s/^s\.//; # RCS or SCCS suffix/prefix + $name =~ s/\.(Z|z|gz)$//; # compression suffix + $name =~ s/\.[^.]+//; # any other suffix + + $line = ""; + $unusual = 0; + + if ($opt_b) { + # + # Binaries have to match exactly, and must be regular executable + # files. + # + $unusual++; + foreach (@binaries) { + $line .= " $_/$name", $unusual--, last if -f "$_/$name" && -x _; + } + } + + if ($opt_m) { + # + # Ask the man command to do the search for us. + # + $unusual++; + chop($result = `man -S 1:8 -M $manpath -w $name 2> /dev/null`); + if ($result ne '') { + $unusual--; + ($cat, $junk, $src) = split(/[() \t\n]+/, $result); + if ($src ne '') { $line .= " $src"; } + else { $line .= " $cat"; } + } + } + + if ($opt_s) { + # + # Sources match if a subdir with the exact name is found. + # + $found = 0; + $unusual++; + foreach (@sources) { + $line .= " $_/$name", $unusual--, $found++, last if -d "$_/$name"; + } + # + # If not yet found, ask locate(1) to do the search for us. + # This will find sources for things like lpr, but take longer. + # Do only match locate output that starts with one of our + # source directories, and at least one further level of + # subdirectories. + # + if (!$found && open(LOCATE, "locate */$name 2>/dev/null |")) { + locate_item: + while (chop($loc = <LOCATE>)) { + foreach (@sources) { + $line .= " $loc", $unusual--, last locate_item + if $loc =~ m|^$_/[^/]+/|; + } + } + close(LOCATE); + } + } + + if ($opt_u) { + print "$name:\n" if $unusual; + } else { + print "$name:$line\n"; + } +} + |