1
0
Files
irix-657m-src/eoe/cmd/whereis/whereis.c
2022-09-29 17:59:04 +03:00

561 lines
9.2 KiB
C

char _Origin_[] = "UC Berkeley";
#include <sys/types.h>
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <dirent.h>
#include <stdlib.h>
#include <locale.h>
#include <fmtmsg.h>
#include <unistd.h>
#include <sgi_nl.h>
#include <msgs/uxsgicore.h>
static char *bindirs[] = {
"/usr/bin",
"/usr/sbin",
"/usr/bsd",
"/etc",
"/usr/etc",
"/usr/ucb",
"/usr/games",
"/usr/demos",
"/sbin",
"/lib",
"/lib32",
"/lib64",
"/usr/lib",
"/usr/lib32",
"/usr/lib64",
"/usr/lbin",
"/usr/local/bin",
"/usr/local/etc",
"/usr/local/lib",
"/usr/bin/X11",
"/usr/freeware/bin",
"/usr/freeware/lib",
0
};
static char *mandirs[] = {
#ifdef sgi
"/usr/share/catman/a_man/cat1",
"/usr/share/catman/a_man/cat7",
"/usr/share/catman/g_man/cat3",
"/usr/share/catman/p_man/cat1",
"/usr/share/catman/p_man/cat2",
"/usr/share/catman/p_man/cat3",
"/usr/share/catman/p_man/cat3c",
"/usr/share/catman/p_man/cat3g",
"/usr/share/catman/p_man/cat3n",
"/usr/share/catman/p_man/cat3p",
"/usr/share/catman/p_man/cat3s",
"/usr/share/catman/p_man/cat3t",
"/usr/share/catman/p_man/cat3w",
"/usr/share/catman/p_man/cat3x",
"/usr/share/catman/p_man/cat4",
"/usr/share/catman/p_man/cat5",
"/usr/share/catman/p_man/catD",
"/usr/share/catman/u_man/cat1",
"/usr/share/catman/u_man/cat3",
"/usr/share/catman/u_man/cat6",
"/usr/share/man/a_man/cat1",
"/usr/share/man/a_man/cat7",
"/usr/share/man/g_man/cat3",
"/usr/share/man/p_man/cat1",
"/usr/share/man/p_man/cat2",
"/usr/share/man/p_man/cat3",
"/usr/share/man/p_man/cat3c",
"/usr/share/man/p_man/cat3g",
"/usr/share/man/p_man/cat3n",
"/usr/share/man/p_man/cat3p",
"/usr/share/man/p_man/cat3s",
"/usr/share/man/p_man/cat3t",
"/usr/share/man/p_man/cat3w",
"/usr/share/man/p_man/cat3x",
"/usr/share/man/p_man/cat4",
"/usr/share/man/p_man/cat5",
"/usr/share/man/u_man/cat1",
"/usr/share/man/u_man/cat3",
"/usr/catman/a_man/cat1",
"/usr/catman/a_man/cat7",
"/usr/catman/g_man/cat3",
"/usr/catman/p_man/cat1",
"/usr/catman/p_man/cat2",
"/usr/catman/p_man/cat3",
"/usr/catman/p_man/cat3c",
"/usr/catman/p_man/cat3g",
"/usr/catman/p_man/cat3n",
"/usr/catman/p_man/cat3p",
"/usr/catman/p_man/cat3s",
"/usr/catman/p_man/cat3t",
"/usr/catman/p_man/cat3w",
"/usr/catman/p_man/cat3x",
"/usr/catman/p_man/cat4",
"/usr/catman/p_man/cat5",
"/usr/catman/u_man/cat1",
"/usr/catman/u_man/cat3",
"/usr/catman/u_man/cat6",
"/usr/freeware/catman/a_man/cat1",
"/usr/freeware/catman/a_man/cat7",
"/usr/freeware/catman/g_man/cat3",
"/usr/freeware/catman/p_man/cat1",
"/usr/freeware/catman/p_man/cat2",
"/usr/freeware/catman/p_man/cat3",
"/usr/freeware/catman/p_man/cat4",
"/usr/freeware/catman/p_man/cat5",
"/usr/freeware/catman/u_man/cat1",
"/usr/freeware/catman/u_man/cat3",
"/usr/freeware/catman/u_man/cat6",
#endif
"/usr/man/u_man/man1",
"/usr/man/a_man/man1",
"/usr/man/u_man/man2",
"/usr/man/u_man/man3",
"/usr/man/u_man/man4",
"/usr/man/u_man/man5",
"/usr/man/u_man/man6",
"/usr/man/a_man/man7",
"/usr/man/a_man/man8",
0
};
static char *mansubdirs[] = {
"a_man/cat1",
"a_man/cat7",
"g_man/cat3",
"p_man/cat1",
"p_man/cat2",
"p_man/cat3",
"p_man/cat3c",
"p_man/cat3g",
"p_man/cat3n",
"p_man/cat3p",
"p_man/cat3s",
"p_man/cat3t",
"p_man/cat3w",
"p_man/cat3x",
"p_man/cat4",
"p_man/cat5",
"p_man/catD",
"u_man/cat1",
"u_man/cat3",
"u_man/cat6",
"cat1",
"cat2",
"cat3",
"cat3g",
"cat3n",
"cat3p",
"cat3s",
"cat3t",
"cat3w",
"cat3x",
"cat4",
"cat5",
"cat6",
"cat7",
"cat8",
"man1",
"man2",
"man3",
"man4",
"man5",
"man6",
"man7",
"man8",
0
};
static char *srcdirs[] = {
"/usr/src/cmd",
0
};
char sflag = 1;
char bflag = 1;
char mflag = 1;
char **Sflag;
int Scnt;
char **Bflag;
int Bcnt;
char **Mflag;
int Mcnt;
char **Pflag; /* envariable PATH */
int Pcnt;
char **MPflag; /* envariable MANPATH */
int MPcnt;
char uflag;
int count;
int print;
int exit_ok=0;
char cmd_label[] = "UX:whereis";
/*
* some message prints
*/
static void
usage(void)
{
_sgi_nl_usage(SGINL_USAGE, cmd_label,
gettxt(_SGI_DMMX_whereis_usage,
"whereis [ -sbmuP ] [ -SBM dir ... -f ] name ..."));
exit(1);
}
/*
* error handling
*/
static void
err_nomem(void)
{
_sgi_nl_error(SGINL_NOSYSERR, cmd_label,
gettxt(_SGI_DMMX_outofmem, "Out of memory"));
}
/*
* get a directory list from command line
*/
static void
getlist(int *argcp, char ***argvp, char ***flagp, int *cntp)
{
(*argvp)++;
*flagp = *argvp;
*cntp = 0;
for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
(*cntp)++, (*argvp)++;
(*argcp)++;
(*argvp)--;
}
/*
* check if name is already in bin path
*/
int
isinbin(char *p)
{
register char **s;
for(s = bindirs; *s; s++) {
if( !strcmp(*s, p))
return(1);
}
return(0);
}
/*
* make a directory list from PATH/MANPATH environment variable
*/
static void
getenvpath(char ***flagp, int *cntp, char *envname)
{
register char *s, *p;
register char **pp;
register int npath;
*flagp = 0;
*cntp = 0;
if( !(s = getenv(envname)))
return;
if( !(p = malloc(strlen(s) + 1))) {
err_nomem();
return;
}
(void)strcpy(p, s); /* save env string */
for(npath = 0, s = p; *s; s++) {
if(*s == ':')
npath++;
}
if( !(pp = (char **)calloc(npath + 1, sizeof(char *)))) {
err_nomem();
return;
}
for(*flagp = pp, npath = 0, s = p;; s++) {
if( !*s)
npath++;
if(npath || (*s == ':')) {
*s = 0;
if( !isinbin(p)) {
*pp++ = p; /* make list of char ** */
(*cntp)++;
}
p = s + 1; /* next name of path */
}
if(npath)
break; /* end of path */
}
*pp = 0;
}
/*
* clear the flags
*/
static void
zerof(void)
{
if (sflag && bflag && mflag)
sflag = bflag = mflag = 0;
}
int
itsit(char *cp, char *dp)
{
register int i = 14;
if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
return (1);
while(*cp && *dp && (*cp == *dp))
cp++, dp++, i--;
if(*cp == 0 && *dp == 0)
return (1);
while (isdigit(*dp))
dp++;
if (*cp == 0 && *dp++ == '.') {
--i;
while (i > 0 && *dp)
#ifdef sgi
if (--i, *dp++ == '.' && *dp != 'z')
#else
if (--i, *dp++ == '.' )
#endif
return (*dp++ == 'C' && *dp++ == 0);
return (1);
}
return (0);
}
/*
* scan directory dir for name cp
*/
void
findin(char *dir, char *cp)
{
register DIR *d;
register struct dirent64 *ep;
if( !(d = opendir(dir)))
return;
while(ep = readdir64(d)) {
if( !ep->d_ino)
continue;
if(itsit(cp, ep->d_name)) {
count++;
exit_ok++;
if(print)
printf(" %s/%s", dir, ep->d_name);
}
}
closedir(d);
}
/*
* search for man page in the standard man subdirectories.
*/
void
findvman(char **dirv, int dirc, char *cp)
{
char buf[100];
char **subdir;
for ( ; dirc > 0; dirv++, dirc--) {
subdir = mansubdirs;
while (*subdir) {
sprintf(buf, "%s/%s", *dirv, *subdir++);
findin(buf, cp);
}
}
}
/*
* two search routines
*/
void
findv(char **dirv, int dirc, char *cp)
{
while (dirc > 0)
findin(*dirv++, cp), dirc--;
}
void
find(char **dirs, char *cp)
{
while (*dirs)
findin(*dirs++, cp);
}
/*
* search src, bin, manual or path lists
*/
void
looksrc(char *cp)
{
if( !Sflag) {
find(srcdirs, cp);
} else
findv(Sflag, Scnt, cp);
}
void
lookbin(char *cp)
{
if( !Bflag)
find(bindirs, cp);
else
findv(Bflag, Bcnt, cp);
}
void
lookman(char *cp)
{
if( !Mflag) {
find(mandirs, cp);
} else
findv(Mflag, Mcnt, cp);
}
/*ARGSUSED*/
void
lookpath(char *cp)
{
}
/*
* search for name
*/
void
lookup(char *cp)
{
register char *dp;
for (dp = cp; *dp; dp++)
continue;
for (; dp > cp; dp--) {
if (*dp == '.') {
*dp = 0;
break;
}
}
for (dp = cp; *dp; dp++)
if (*dp == '/')
cp = dp + 1;
if (uflag) {
print = 0;
count = 0;
} else
print = 1;
again:
if (print)
printf("%s:", cp);
if (sflag) {
looksrc(cp);
if (uflag && print == 0 && count != 1) {
print = 1;
goto again;
}
}
count = 0;
if (bflag) {
lookbin(cp);
if (uflag && print == 0 && count != 1) {
print = 1;
goto again;
}
}
count = 0;
if (mflag) {
lookman(cp);
if (uflag && print == 0 && count != 1) {
print = 1;
goto again;
}
}
if(Pflag)
findv(Pflag, Pcnt, cp);
if(MPflag)
findvman(MPflag, MPcnt, cp);
if (print)
printf("\n");
}
/*
* whereis name
* look for source, documentation and binaries
*/
int
main(int argc, char *argv[])
{
/*
* intnl support
*/
(void)setlocale(LC_ALL, "");
(void)setcat("uxsgicore");
(void)setlabel(cmd_label);
argc--, argv++;
if (argc == 0) {
usage();
}
do
if (argv[0][0] == '-') {
register char *cp = argv[0] + 1;
while (*cp) switch (*cp++) {
case 'f':
break;
case 'S':
getlist(&argc, &argv, &Sflag, &Scnt);
break;
case 'B':
getlist(&argc, &argv, &Bflag, &Bcnt);
break;
case 'M':
getlist(&argc, &argv, &Mflag, &Mcnt);
break;
case 'P' : /* XXX can be broken into 2 options */
getenvpath(&Pflag, &Pcnt, "PATH");
getenvpath(&MPflag, &MPcnt, "MANPATH");
continue;
case 's':
zerof();
sflag++;
continue;
case 'u':
uflag++;
continue;
case 'b':
zerof();
bflag++;
continue;
case 'm':
zerof();
mflag++;
continue;
default:
usage();
}
argv++;
} else
lookup(*argv++);
while (--argc > 0);
if (exit_ok)
exit(0);
else exit(1);
/*NOTREACHED*/
}