home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h> /* standard I/O */
- #include <stdlib.h> /* standard library */
- #include <string.h> /* standard string library */
-
- #include "unistd.h" /* UNIX system calls */
- #include "dirent.h" /* directory handling functions */
- #include "sys/stat.h" /* file status */
-
- #include "sys/trap.h" /* define SWIs */
- #include "sys/os.h" /* define os_swi */
- #undef debug
-
- int verbose=0;
- int fcount=0;
-
- /* ---------------------------- moduletest() ------------------------------*/
- /* -----------------------------------------------------------------------*/
-
- void moduletest(char *filename) /* provide 'unix-which' functionality */
- {
- int r[10];
- register int i;
- int clr;
- int *point;
- char *namepoint;
- register char *compoint;
- char buf[256];
- char commn[256];
- char name[256];
- os_error *e = 0;
-
- strcpy(commn,filename);
- if (commn[strlen(commn)-1] == '*')
- commn[strlen(commn)-1]='\0';
- /* we won't do wildcards in shell commands,strip the '*' */
-
- r[0]=12;
- r[1]=0;
- r[2]=0;
-
- do
- {
- clr=0;
- if (e = os_swi(OS_Module,r))
- break; /* bang,end of modules */
-
- point = (int *)(r[3] + 0x18) ;
- compoint = (char *)(*point + r[3]) ; /* points to start of commands in module */
- if (!(*compoint))
- continue ; /* caught a 0-word at pointer: this module has no commands */
-
- point = (int *)(r[3] + 0x10) ;
- namepoint = (char *)(*point + r[3]) ;/* word at module base+&10 points to modulename */
- strcpy(name,namepoint) ; /* modulename */
- if (verbose)
- printf("searching %s Module",name);
-
- do
- {
- strcpy(buf,compoint);
- if (buf[0]=='\0')
- break; /* caught trailing \0 after the last command, go on to next module */
- /* this is do..while's only exit */
-
- fcount+=1 ; /* count number of *commands */
-
- if (!stricmp(buf,commn)) /* compare ,ignoring case */
- {
- if (!clr && verbose)
- {
- for (i=0;i < (strlen(name)+17);i++)
- printf("\b \b");
- clr=1;
- }
- printf("*%s: %s Module\n",buf,name); /* print command/module name as found */
- /* we could break here,but that would complicate things with erasing
- the 'search Module' message,as we never reach the statement
- BEFORE while(1) */
- }
-
- /* calculate start of next command in module */
-
- compoint += strlen(buf)+17 ;
- if ((int)compoint&3) /* check if last 2 LSb are zero (would mean it's already aligned)*/
- compoint += (4-((int)compoint&3)) ; /* what a horrible code */
- /* ugh: discovered that the FIRST command(block) in modules is NOT
- required to be word aligned. what a shit: they save 3 bytes/module,
- and I have to tweak code here */
- /* command length + \0 byte, plus word aligned, plus skip 4 words,ref: PRM p.636 */
- /* here +17 is \0 byte plus 4 words,THEN world aligned (same result) */
- }
- while(1); /* only break will exit */
-
- if (!clr && verbose) /* found nothing ? clear 'searching' msg */
- for (i=0;i < (strlen(name)+17);i++)
- printf("\b \b") ;
-
- }
- while(1);
- }
-
-
- /* ---------------------------- aliastest() ------------------------------*/
- /* -----------------------------------------------------------------------*/
-
- void aliastest(char *filename) /* provide 'unix-which' functionality */
- {
- char *alias;
- static char buf[256] = "Alias$" ;
-
- strcpy(&buf[strlen(buf)],filename);
- /* this \0-termiates the string,too */
-
- if (buf[strlen(buf)-1] == '*')
- buf[strlen(buf)-1]='\0';
- /* we won't do wildcards in aliases. after all: this is 'unix-which' */
- /* functionality,which doesn't do wildcards ,strip '*' */
-
- alias = getenv(buf);
- if (!alias) /* 0-pointer returned */
- return; /* variable does not exist */
-
- printf("%s : %s\n",buf,alias);
-
- }
-
-
- /* ------------------------------- hunt() --------------------------------*/
- /* -----------------------------------------------------------------------*/
-
- void hunt(char *runpath ,char *filename)
- {
- void search(char *,char *);
- static char hunt[256]= '\0\0' ;
- char *huntpath;
- int a,len,c=0;
-
- huntpath = getenv(runpath);
- len = strlen (huntpath);
-
- for (a=0;a<=len;a++)
- {
- if (huntpath[a] != ',' && a!=len )
- {
- hunt[c] = huntpath[a];
- c++;
- }
- else
- {
- hunt[c]=0 ;
- search(hunt,filename) ;
- c=0 ;
- }
- }
- }
-
-
- /* ------------------------------- search() ------------------------------*/
- /* -----------------------------------------------------------------------*/
-
-
- void search(char *huntdir, char *filename)
- {
- DIR *dirp; /* directory pointer */
- struct direct *d; /* directory entry structure */
- struct stat s[1]; /* file status structure */
- static char buf[256]; /* buffer */
- char a[256];
- char huntd[256],filen[256];
- register int i;
- int clr=0,wild=0;
-
- strcpy(huntd,huntdir);
- strcpy(filen,filename);
- #ifdef debug
- printf("search called with:%s (length %d) %s\n", huntd, strlen(huntd),filen);
- #endif
- if (huntd[strlen(huntd)-1] == ':')
- {
- strcpy(&huntd[strlen(huntd)-1],"$Path");
- hunt(huntd,filen);
- return;
- }
- /* search recursively into path,if atomic element of Run$Path
- is a pathvariable such as C: (= C$Path) ,Lib$Path ,etc. */
- /* strange: strcpy seems to append a '\0' to the target string,after copying,
- which is not really ANSI,so I could theoretically write '$Path' ,here */
-
- if (huntd[0] == '\0') strcpy(huntd,"@");
- /* an empty entry in/or no Run$Path ? search CWD : A.Oliver */
- if (huntd[strlen(huntd)-1] == '.')
- huntd[strlen(huntd)-1] = '\0' ;
- /* kill trailing '.' from path (if it has one: bugfix A.Oliver)
- /* gee. but only if strlen() !=0 ,otherwise we look/corrupt huntd[-1] !*/
- /* cure: check for empty string first,take @ for CWD then */
- if (filen[strlen(filen)-1]=='*')
- {
- wild=1;
- filen[strlen(filen)-1]='\0';
- }
-
- for (i=0; filen[i];i++)
- filen[i]=tolower(filen[i]); /* make searched-for name lowercase */
-
- if (!(dirp = opendir(huntd))) /* open directory */
- {
- printf("whereis: could not open directory %s\n",huntd);
- return;
- }
-
- if (verbose)
- printf("searching %s",huntd);
-
- while (d = readdir(dirp)) /* read directory entry */
- {
- sprintf(buf,"%s/%s",huntd,d->d_name);
- stat(buf,s); /* get file status */
- strcpy(a,(d->d_name));
- for (i=0; a[i];i++)
- a[i]=tolower(a[i]);
- fcount+=1 ; /* Global */
- if ( ( !strcmp(a,filen)) || (strstr(a,filen) && wild) )
- {
- if (!clr && verbose)
- {
- for (i=0;i < (strlen(huntd)+10);i++)
- printf("\b \b");
- clr=1;
- }
- printf("%s: %s.%s\n",filen,huntd,d->d_name); /* print file name */
- }
- }
- if (!clr && verbose)
- for (i=0;i < (strlen(huntd)+10);i++)
- printf("\b \b");
- closedir(dirp); /* close directory */
- }
-
- /*-------------------------main--------------------------*/
- /*-------------------------------------------------------*/
-
- int main(argc,argv)
- int argc;
- char **argv;
- {
- void hunt(char *,char *);
- extern char *getenv(const char *);
- int bad=0,warn=0;
- register int i,j;
- int files=0 ,gotfilen=0 ,help=0;
- char v[256];
- static char filename[256]= '\0';
-
- if (argc>1)
- for (i=1;i<argc;i++)
- {
- strcpy(v,argv[i]);
-
- if (!strcmp(v,"-")) /* strcmp() becomes 0 when equal */
- {
- if (gotfilen || !gotfilen&&warn)
- { bad=1; break;} /* who is pulling a joke on us with several '-' or filenames ? */
- else
- { warn=1; continue;} /* filename starting with '-' follows */
- }
-
- if ( v[0]=='-' && !warn)
- {
- for (j=1;j<strlen(v);j++) /* we might get several switches at once */
- {
- switch (v[j])
- {
- case 'v': case 'V' : verbose=1; break;
- case 'f': case 'F' : files=1; break;
- case 'h': case 'H' : case '?': help=1; break;
- default: bad=1; /* printf("Unknown switch: -%c\n",v[j]); */
- }
- }
- }
- else
- {
- if (gotfilen)
- bad=1; /* two filenames ? no way */
- else
- {
- strcpy(filename,v);
- gotfilen=1;
- warn=0; /* if we received filename,delete the warn switch,so we can read */
- } /* possible switches following the filename */
- }
- }
-
- if ((!gotfilen || filename[0]=='\0') && !verbose)
- bad=1; /* got no filename,and no -v switch ? error */
- /* check for filename[0] is to detect "" argument */
-
- if (help)
- {
- printf("Archimedes whereis 1.20 (C)1993 Kai Schlichting (kai@phantom.com)\n");
- printf("Usage: whereis [-vfh?] <name>|<- -name> \n");
- printf("Displays all matches for <name> in the order of execution when given\n");
- printf("as *command in shell:\n");
- printf("1) CLI *commands that match <name> exactly ,including the adjacent module name.\n");
- printf("2) Alias$<name> definitions that match <name> exactly are returned. \n");
- printf("3) filenames in the Run$Path which's leafname matches <name> exactly \n");
- printf(" <name> can also be <name*>, here, then all leafnames which match *name*\n");
- printf(" are returned.\n");
- printf(" If <name> begins with a '-' a '-' must be the argument before\n");
- printf(" <name> (e.g. 'whereis - -v' to search for file '-v').\n");
- printf(" If no name is given, the -v switch will report the number of\n");
- printf(" *commands/files alone. (-f switch is valid,then)\n");
- printf(" The case of -v -f or -h does not matter.\n");
- printf("-v switch: be verbose when searching and report number of *commands and files.\n");
- printf("-f switch: search File$Path,too,in addition to Run$Path.\n");
- printf("-h or -? switch: Display this help screen.\n");
- exit(1);
- }
- else
- {
- if (argc==1 || bad )
- {
- printf("No output generated.\n");
- printf("Usage: whereis [-vfh?] <name>|<- -name> \n");
- printf("whereis -h for help.\n");
- exit(1);
- }
- }
-
- if (!gotfilen)
- {
- printf("Counting *commands");
- if (files)
- printf(" ,files on Run$Path and files in File$Path.\n");
- else
- printf(" and files on Run$Path.\n");
- }
- else
- if (verbose)
- printf("Processing name: %s\n",filename);
-
- fcount=0; moduletest(filename);
- if (verbose)
- printf("(Found %d commands in Modules)\n",fcount);
-
- aliastest(filename);
-
- fcount=0; hunt("Run$Path",filename);
- if (verbose)
- printf("(Found %d files/dirs in Run$Path)\n",fcount);
-
- if (files)
- {
- fcount=0; hunt("File$Path",filename);
- if (verbose)
- printf("(Found %d files/dirs in File$Path)\n",fcount);
- }
-
- exit(0);
- }
-