Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!hao!boulder!sunybcs!bingvaxu!leah!itsgw!batcomputer!hsgj From: hsgj@batcomputer.tn.cornell.edu (Dan Green) Newsgroups: comp.sys.amiga Subject: whereis utility Message-ID: <2490@batcomputer.tn.cornell.edu> Date: Mon, 28-Sep-87 20:36:42 EDT Article-I.D.: batcompu.2490 Posted: Mon Sep 28 20:36:42 1987 Date-Received: Wed, 30-Sep-87 00:43:11 EDT Distribution: comp Organization: Theory Center, Cornell U., Ithaca NY Lines: 568 A while ago I promised that I'd post a "whereis" utility to comp.sources.amiga. I posted it on Sept 7, 1987. Today is Sept 28 and it still hasn't shown up yet. Rather then trying again, I am simply going to send this to comp.sys.amiga. Hopefully this does not anger too many people. Please note that this whereis uses different option flags then the unix whereis, because I've noticed that few amiga programs use the rwx bits, so there is no point in checking them. -- Dan Green # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by tcgould.tn.cornell.edu!hsgj on Mon Sep 28 20:24:02 EDT 1987 # Contents: whereis.doc whereis.uue whereis.c echo x - whereis.doc sed 's/^@//' > "whereis.doc" <<'@//E*O*F whereis.doc//' NAME: Whereis Copyright 1987 Daniel Green. Freely Redistributable No warranty expressed or implied. Use at your own risk. SYNOPSIS: Prints the directory where a given filename resides SYNTAX: Whereis [-a] [-v] [-d device] filename Whereis with no arguments will display this syntax diagram. DISCUSSION: Whereis scans through all the directories on the current device, until it finds the 'filename' specified. When that is found, the path of directories leading to that file is printed. For example: 1> CD DF0: /* device searched will be df0: */ 1> WHEREIS mountlist /* Search for file 'mountlist' */ :devs/Mountlist /* Whereis prints path to the file */ 1> You can stop Whereis at any time by pressing Control-C, or by sending the BREAK command to the CLI that Whereis is running inside of. SWITCHES: None, any, or all of the switches may be specified. [-A] By default, Whereis exits after the file is found. If you use the -a (all) switch, then Whereis will scan through the entire device (disk). Thus, if you think there are several files with the same name, you can use the -a switch to show all of their paths. [-V] Whereis by default works silently. If you specify the -v (verify) switch, then Whereis will display in a CON: window the directories it is currently searching through. [-D DEVICE] Whereis only searches one device (disk drive) at a time. By default, Whereis searches the device containing the directory you are currently in. If you want to search a different device, you can specify it using the -d switch. For example, if you are in df0: but want to search on df1:, you can say: WHEREIS -D DF1: file. @//E*O*F whereis.doc// chmod u=rw,g=r,o=r whereis.doc echo x - whereis.uue sed 's/^@//' > "whereis.uue" <<'@//E*O*F whereis.uue//' begin 0 Whereis M #\P % 0 " '@ #\ 2 #E@ ^D M "3OD /L 0 0 " _( /I 'DCG M #HH;P 4(&\ &")O !Q%^@ Z3^__="9/+'D $3J[]]G#_2AM7R/_\1H!G M$B\ 2&\ !$A43KD P3^\ #$_O (Q,WUP 3G46P$YU2.< .B9O !0@;P 8 M0^\ '$7Z !(L>0 1.KOWV3-]< $YU%L!.=0 ^P ! @ #H M #\@ ^D _2.<@ BQY !S$SO 8 #$ZN_^),WT $3G4 "\. M+'D ',(B\ "$ZN_]PL7TYU2.
0 0 0@.0 3G5.5O_\+6X "/_\2JX $&\@(&X #! 0(F[_
M_!* 4JX #$H 9PQ2KO_\3G%3K@ 08-H@;O_\0A @+@ (3EY.=4Y6__Q"KO_\
M(&X "-'N__P0$$H 9P92KO_\8.P@+O_\3EY.=0 ^P $ 0 #-
M RN )< ") 4 @ "@8 F* *( "<8 E8 )#
M!R@ DV &? !.@ 36 &X@ !KH 8V %3@ !+0 22 $
M:@ *X "Z !P , FB %&@ "?H /^ '0 Z0 .$
M <0 0 U( -#@ #.P SR ,Y@ #,H HZ &_@ !?(
M << &$@ !3 1^ % !%8 :2 &; !$H 0X (O@
M"&X =N '5 !E8 76 %A !"@ HL *&@ "A( GL )
MW "< FX )J@ "6 E2 )2@ "3 D4 (^ "-H C&
M (N "&@ @T (* "!P >, 'A@ !X =X ': !UP
M =. '$ !B 7H %> !6@ 5$ $]@ !-X 3$ $J@
M!(@ 1D $% Y0 HT )T "68 D@ )!@ ".@ B& (
M3@ !V( <6 &A !@P 4J $> !$ 0> !- ,P &Z
M !J@ :0 %J !7@ 5 %" !(@ 1P $6 ]@ .0
M #4 Q@ , "T I@ '( !L 5 $X @ %
2 X ( @ /R
end
@//E*O*F whereis.uue//
chmod u=rw,g=r,o=r whereis.uue
echo x - whereis.c
sed 's/^@//' > "whereis.c" <<'@//E*O*F whereis.c//'
/* WHEREIS -> Report the path location to a given file */
/* Copyright 1987 Daniel Green. Freely Redistributable */
/* No warranty expressed or implied. Use at own risk */
/* Compile: with Lattice C version 3.03 */
/* Link: with AStartup.obj */
#include "exec/types.h"
#include "exec/memory.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"
/* Data Types */
struct dirnode {
struct dirnode *next; /* Next node in list */
int size; /* Size of this node (bytes) */
int type; /* File type */
char name[1]; /* File name */
};
/* Constants */
#define DIRNODESIZE sizeof(struct dirnode)
#define FIBSIZE sizeof(struct FileInfoBlock)
/* External routines returning non-ints */
extern char *AllocMem();
extern struct FileLock *Lock();
extern struct FileLock *CurrentDir();
extern long *Open();
/* Global Variables */
struct FileInfoBlock *fib; /* Used for reading directories */
char progname[80]; /* Name of this program (argv[0]) */
char searchname[80]; /* Filename to be searched for */
char device[80]; /* Alternate device to search */
int flag_first; /* TRUE -> exit after first match */
int flag_break; /* TRUE -> Ctrl-C pressed, so exit */
int flag_verbose; /* TRUE -> Print status messages */
int flag_device; /* TRUE -> Search other device */
long verbose_fp; /* File ptr for verbose output */
/*
* cbreak. Check for a BREAK. Returns TRUE if detected.
*/
int cbreak()
{
/* See if a control C pressed */
if (SetSignal(0L,0L) & SIGBREAKF_CTRL_C) {
flag_break = TRUE;
return(TRUE);
}
/* Otherwise reset break and continue */
SetSignal(0L,SIGBREAKF_CTRL_C);
return(FALSE);
}
/*
* Upcase. Convert a string inline to upper case
*/
Upcase(s1)
char *s1;
{
while (*s1 != '\0') {
if ((*s1 >= 'a') && (*s1 <= 'z'))
*s1 += ('A' - 'a');
s1++;
}
}
/*
* FreeList. DeAllocate a list of dirnodes
*/
FreeList(firstnode)
struct dirnode *firstnode;
{
struct dirnode *curnode, *nextnode;
/* For each node in the list */
nextnode = firstnode;
while ((curnode = nextnode) != NULL) {
nextnode = curnode->next;
FreeMem(curnode,curnode->size);
}
}
/*
* ReadDir. Recursive routine. Given a lock on the current directory
* and the path to that directory, this scans the dir. Any filenames
* are compared to the searchname and matches are printed. For each
* subdirectory, ReadDir is again evoked with a lock on the sub dir
* and an updated path. When all subdirectories are exhausted, this
* procedures UnLocks the lock that it was given, and then the
* procedure returns. Returns TRUE if no more directories should be
* read.
*/
int ReadDir(dirlock,pathname)
struct FileLock *dirlock;
char *pathname;
{
struct FileLock *newlock;
struct dirnode *firstnode, *lastnode, *tmpnode;
char tbuf[80];
char newpath[80];
int i;
/* If verbose mode on, write the path that is being searched */
if (flag_verbose == TRUE) {
strcpy(tbuf,"Scanning ");
strcat(tbuf,pathname);
strcat(tbuf,"...\n");
if (Write(verbose_fp,tbuf,strlen(tbuf)) == -1) {
/* Write i/o error [should never happen] */
printf("Write() Error (?)\n");
flag_first = TRUE;
UnLock(dirlock);
return(TRUE);
}
}
/* Check for break key */
if (cbreak() == TRUE) {
/* Simulate early exit condition */
flag_first = TRUE;
UnLock(dirlock);
return(TRUE);
}
/* Initialize dirnode list */
firstnode = NULL;
lastnode = NULL;
/* Read all file and subdirectory names in the current directory */
/* and store them in a list of dirnodes, pointed to by firstnode */
/* This must be done (as opposed to just checking each name made */
/* by ExNext) because of the recursiveness. If you use ExNext, */
/* and then skip to a subdir and use ExNext, and then return, */
/* the original ExNext gets very confused. Therefore, you have */
/* to read all directory names into memory first before you */
/* handle them. This necessitates the dirnode stuff. */
/* Get the first entry in directory */
/* Actually, this returns the NAME of the directory, and not its */
/* first content. It still must be called to initialize ExNext, */
/* which is the routine that actually returns the contents */
Examine(dirlock,fib);
/* While there are still things in the directory, do: */
while (ExNext(dirlock,fib) != 0) {
/* Allocate data storage for this element */
i = DIRNODESIZE + strlen(fib->fib_FileName);
if ((tmpnode = (struct dirnode *)
AllocMem(i,MEMF_CLEAR)) == NULL) {
/* Argh! Out of memory. Simulate exit condition */
printf("Out of memory error\n");
FreeList(firstnode);
flag_first = TRUE;
UnLock(dirlock);
return(TRUE);
}
/* Fill data storage node */
tmpnode->next = NULL;
tmpnode->size = i;
tmpnode->type = fib->fib_EntryType;
strcpy(tmpnode->name,fib->fib_FileName);
/* Add this node to the list of dirnodes */
if (lastnode == NULL) {
lastnode = tmpnode;
firstnode = tmpnode;
}
else {
lastnode->next = tmpnode;
lastnode = tmpnode;
}
}
/* For each dirnode, if it is a file then see if it is the */
/* one we are searching for. If it is a directory, then */
/* call ReadDir() to search the directory for the file. */
tmpnode = firstnode;
while (tmpnode != NULL) {
/* Is this a file? */
if (tmpnode->type < 0) {
/* Copy the file name into a buffer, and caps it */
strcpy(tbuf,tmpnode->name);
Upcase(tbuf);
/* Did we find the file? */
if (strcmp(tbuf,searchname) == 0) {
printf("%ls%ls\n",pathname,tmpnode->name);
/* If we're supposed to stop at first, */
/* then we can exit this sub here */
if (flag_first == TRUE) {
FreeList(firstnode);
UnLock(dirlock);
return(TRUE);
}
}
}
/* Is this a directory? */
if (tmpnode->type >= 0) {
/* Build the pathname to this subdir */
strcpy(newpath,pathname);
strcat(newpath,tmpnode->name);
/* Get a lock on this subdir */
newlock = (struct FileLock *)Lock(newpath,ACCESS_READ);
/* Complete the path specification */
strcat(newpath,"/");
/* Search this dir for the file in question */
if (ReadDir(newlock,newpath) == TRUE) {
/* If file was found, exit */
FreeList(firstnode);
UnLock(dirlock);
return(TRUE);
}
}
/* Examine the next dirnode */
tmpnode = tmpnode->next;
}
/* We didn't find anything. Cleanup and exit */
FreeList(firstnode);
UnLock(dirlock);
return(FALSE);
}
/*
* Leave if there is an error. First arg is optional error message.
* If second arg is TRUE, then usage information is given.
*/
leave(msg,usage)
char *msg;
int usage;
{
if (msg != NULL)
puts(msg);
if (usage == TRUE)
printf("Usage: %ls [-a] [-v] [-d device] filename\n",progname);
Exit(1);
}
/*
* Whereis.
*/
main(argc,argv)
int argc;
char *argv[];
{
struct FileLock *olddir, *dirlock;
char buf[80];
int i;
/* Set initial conditions */
SetSignal(0L,SIGBREAKF_CTRL_C);
strcpy(progname,argv[0]);
searchname[0] = '\0';
strcpy(device,":");
flag_first = TRUE;
flag_break = FALSE;
flag_verbose = FALSE;
flag_device = FALSE;
/* Check for valid arguments */
if (argc < 2)
leave(NULL,TRUE);
/* Parse args for flags and file */
i = 1;
while (i < argc) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'a':
case 'A':
flag_first = FALSE;
break;
case 'v':
case 'V':
flag_verbose = TRUE;
break;
case 'd':
case 'D':
flag_device = TRUE;
if (++i == argc)
leave("No device name specified", TRUE);
strcpy(device,argv[i]);
break;
default:
sprintf(buf,"Unknown switch '%ls'",argv[i]);
leave(buf, TRUE);
}
}
else {
/* Save the filename to be searched for */
strcpy(searchname,argv[i]);
Upcase(searchname);
}
i++;
}
/* Make sure a filename was given */
if (searchname[0] == '\0')
leave("No filename to search for specified", TRUE);
/* If in verbose mode, open up the verbose file */
if (flag_verbose == TRUE) {
if ((verbose_fp = (long)Open("CON:0/11/640/64/Whereis",MODE_NEWFILE)) == 0)
leave("Could not open verbose console window", FALSE);
}
/* Save the current directory position */
if ((dirlock = (struct FileLock *)Lock(device,ACCESS_READ)) == 0) {
if (flag_verbose == TRUE)
Close(verbose_fp);
sprintf(buf,"Could not access device '%ls'",device);
leave(buf,FALSE);
}
olddir = (struct FileLock *)CurrentDir(dirlock);
/* Allocate the file info block */
if ((fib = (struct FileInfoBlock *)AllocMem(FIBSIZE,MEMF_CLEAR)) == NULL) {
if (flag_verbose == TRUE)
Close(verbose_fp);
leave("Not enough memory to allocate fib", FALSE);
}
/* Scan the device root for the file */
ReadDir(dirlock,device);
/* Free the file info block */
FreeMem((char *)fib, FIBSIZE);
/* Return to the original directory */
CurrentDir(olddir);
/* Close the verbose window if it was opened */
if (flag_verbose == TRUE)
Close(verbose_fp);
/* Print break message if necessary */
if (flag_break == TRUE)
puts("Ctrl-C BREAK");
}
@//E*O*F whereis.c//
chmod u=rw,g=r,o=r whereis.c
echo Inspecting for damage in transit...
temp=/tmp/shar$$; dtemp=/tmp/.shar$$
trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
cat > $temp <<\!!!
45 280 1673 whereis.doc
114 869 6868 whereis.uue
358 1324 9087 whereis.c
517 2473 17628 total
!!!
wc whereis.doc whereis.uue whereis.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
if [ -s $dtemp ]
then echo "Ouch [diff of wc output]:" ; cat $dtemp
else echo "No problems found."
fi
exit 0
--
ARPA: hsgj@tcgould.tn.cornell.edu
UUCP: ihnp4!cornell!batcomputer!hsgj BITNET: hsgj@cornella
0 0 <@B;P (("\ #$ZN_RXL7TYU+PXL>0 @@>0 >P2&%. ;QX, 0 @;_12@B;*
M8 H2&%. # $ (&\$%,%@\D(:8-Q"&D*;( ),WPP$2'D 'P+P!.N0 $PC
MP =1.N0 %PCP =@CP =Q.N0 !S)P "YY !X$YU80 QF$
M + CP >1"IR\ )$ @*@ D9Q L>0