home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / unix / b073_1 / c / whereis
Encoding:
Text File  |  1993-08-25  |  10.4 KB  |  360 lines

  1. #include <stdio.h>            /* standard I/O */
  2. #include <stdlib.h>            /* standard library */
  3. #include <string.h>            /* standard string library */
  4.  
  5. #include "unistd.h"            /* UNIX system calls */
  6. #include "dirent.h"            /* directory handling functions */
  7. #include "sys/stat.h"            /* file status */
  8.  
  9. #include "sys/trap.h"                   /* define SWIs */
  10. #include "sys/os.h"                     /* define os_swi */
  11. #undef debug
  12.  
  13. int verbose=0;
  14. int fcount=0;
  15.  
  16. /* ---------------------------- moduletest() ------------------------------*/
  17. /* -----------------------------------------------------------------------*/
  18.  
  19. void moduletest(char *filename)      /* provide 'unix-which' functionality */
  20. {
  21.  int r[10];
  22.  register int i;
  23.  int clr;
  24.  int *point;
  25.  char *namepoint;
  26.  register char *compoint;
  27.  char buf[256];
  28.  char commn[256];
  29.  char name[256];
  30.  os_error *e = 0;
  31.  
  32.  strcpy(commn,filename);
  33.  if (commn[strlen(commn)-1] == '*')
  34.     commn[strlen(commn)-1]='\0';
  35.     /* we won't do wildcards in shell commands,strip the '*'  */
  36.  
  37.  r[0]=12;
  38.  r[1]=0;
  39.  r[2]=0;
  40.  
  41.  do
  42.  {
  43.   clr=0;
  44.   if (e = os_swi(OS_Module,r))
  45.      break; /* bang,end of modules */
  46.  
  47.   point = (int *)(r[3] + 0x18) ;
  48.   compoint = (char *)(*point + r[3]) ; /* points to start of commands in module */
  49.   if (!(*compoint))
  50.    continue ; /* caught a 0-word at pointer: this module has no commands */
  51.  
  52.   point = (int *)(r[3] + 0x10) ;
  53.   namepoint = (char *)(*point + r[3]) ;/* word at module base+&10 points to modulename */
  54.   strcpy(name,namepoint) ; /* modulename */
  55.   if (verbose)
  56.    printf("searching %s Module",name);
  57.  
  58.     do
  59.     {
  60.      strcpy(buf,compoint);
  61.      if (buf[0]=='\0')
  62.        break; /* caught trailing \0 after the last command, go on to next module */
  63.               /* this is do..while's only exit */
  64.  
  65.      fcount+=1 ;  /* count number of *commands */
  66.  
  67.      if (!stricmp(buf,commn)) /* compare ,ignoring case */
  68.         {
  69.          if (!clr && verbose)
  70.          {
  71.           for (i=0;i < (strlen(name)+17);i++)
  72.            printf("\b \b");
  73.           clr=1;
  74.          }
  75.          printf("*%s: %s Module\n",buf,name); /* print command/module name as found */
  76.           /* we could break here,but that would complicate things with erasing
  77.              the 'search Module' message,as we never reach the statement
  78.              BEFORE while(1) */
  79.         }
  80.  
  81.      /* calculate start of next command in module */
  82.   
  83.      compoint += strlen(buf)+17 ;
  84.      if ((int)compoint&3) /* check if last 2 LSb are zero (would mean it's already aligned)*/
  85.        compoint += (4-((int)compoint&3)) ; /* what a horrible code */
  86.       /* ugh: discovered that the FIRST command(block) in modules is NOT
  87.          required to be word aligned. what a shit: they save 3 bytes/module,
  88.          and I have to tweak code here  */
  89.      /*  command length + \0 byte, plus word aligned, plus skip 4 words,ref: PRM p.636 */
  90.      /*  here +17 is \0 byte plus 4 words,THEN world aligned (same result) */
  91.     }
  92.     while(1);  /* only break will exit */
  93.  
  94.   if (!clr && verbose)   /*  found nothing ? clear 'searching' msg */
  95.    for (i=0;i < (strlen(name)+17);i++)
  96.     printf("\b \b") ;
  97.  
  98.  }
  99.  while(1);
  100. }
  101.  
  102.  
  103. /* ---------------------------- aliastest() ------------------------------*/
  104. /* -----------------------------------------------------------------------*/
  105.  
  106. void aliastest(char *filename)      /* provide 'unix-which' functionality */
  107. {
  108.  char *alias;
  109.  static char buf[256] = "Alias$" ;
  110.  
  111.  strcpy(&buf[strlen(buf)],filename);
  112.  /* this \0-termiates the string,too */
  113.  
  114.  if (buf[strlen(buf)-1] == '*')
  115.    buf[strlen(buf)-1]='\0';
  116.             /* we won't do wildcards in aliases. after all: this is 'unix-which' */
  117.             /* functionality,which doesn't do wildcards ,strip '*' */
  118.  
  119.  alias = getenv(buf);
  120.  if (!alias) /* 0-pointer returned */
  121.     return;  /* variable does not exist */
  122.  
  123.  printf("%s : %s\n",buf,alias);
  124.  
  125. }
  126.  
  127.  
  128. /* ------------------------------- hunt() --------------------------------*/
  129. /* -----------------------------------------------------------------------*/
  130.  
  131. void hunt(char *runpath ,char *filename)
  132. {
  133.  void search(char *,char *);
  134.  static char hunt[256]= '\0\0' ;
  135.  char *huntpath;
  136.  int a,len,c=0;
  137.  
  138.  huntpath = getenv(runpath);
  139.  len = strlen (huntpath);
  140.  
  141.  for (a=0;a<=len;a++)
  142.   {
  143.    if (huntpath[a] != ',' && a!=len )
  144.       {
  145.       hunt[c] = huntpath[a];
  146.       c++;
  147.       }
  148.    else
  149.     {
  150.       hunt[c]=0 ;
  151.       search(hunt,filename) ;
  152.       c=0 ;
  153.     }
  154.   }
  155. }
  156.  
  157.  
  158. /* ------------------------------- search() ------------------------------*/
  159. /* -----------------------------------------------------------------------*/
  160.  
  161.  
  162. void search(char *huntdir, char *filename)
  163. {
  164.  DIR *dirp;                /* directory pointer */
  165.  struct direct *d;            /* directory entry structure */
  166.  struct stat s[1];            /* file status structure */
  167.  static char buf[256];            /* buffer */
  168.  char a[256];
  169.  char huntd[256],filen[256];
  170.  register int i;
  171.  int clr=0,wild=0;
  172.  
  173.  strcpy(huntd,huntdir);
  174.  strcpy(filen,filename);
  175. #ifdef debug
  176.  printf("search called with:%s (length %d) %s\n", huntd, strlen(huntd),filen);
  177. #endif
  178.  if (huntd[strlen(huntd)-1] == ':')
  179.     {
  180.      strcpy(&huntd[strlen(huntd)-1],"$Path");
  181.      hunt(huntd,filen);
  182.      return;
  183.     }
  184.   /* search recursively into path,if atomic element of Run$Path
  185.       is a pathvariable such as C: (= C$Path) ,Lib$Path ,etc. */
  186.   /* strange: strcpy seems to append a '\0' to the target string,after copying,
  187.      which is not really ANSI,so I could theoretically write '$Path' ,here */
  188.  
  189.  if (huntd[0] == '\0') strcpy(huntd,"@");
  190.       /* an empty entry in/or no Run$Path ? search CWD : A.Oliver */
  191.  if (huntd[strlen(huntd)-1] == '.')
  192.      huntd[strlen(huntd)-1] = '\0' ;
  193.      /* kill trailing '.' from path (if it has one: bugfix A.Oliver)
  194.      /* gee. but only if strlen() !=0 ,otherwise we look/corrupt huntd[-1] !*/
  195.      /* cure: check for empty string first,take @ for CWD then */
  196.  if (filen[strlen(filen)-1]=='*')
  197.     {
  198.     wild=1;
  199.     filen[strlen(filen)-1]='\0';
  200.     }
  201.  
  202.  for (i=0; filen[i];i++)
  203.   filen[i]=tolower(filen[i]);   /* make searched-for name lowercase */
  204.  
  205.  if (!(dirp = opendir(huntd)))     /* open directory */
  206.     {
  207.      printf("whereis: could not open directory %s\n",huntd);
  208.      return;
  209.     }
  210.  
  211.  if (verbose)
  212.    printf("searching %s",huntd);
  213.  
  214.  while (d = readdir(dirp))        /* read directory entry */
  215.      {
  216.      sprintf(buf,"%s/%s",huntd,d->d_name);
  217.      stat(buf,s);            /* get file status */
  218.      strcpy(a,(d->d_name));
  219.      for (i=0; a[i];i++)
  220.       a[i]=tolower(a[i]);
  221.      fcount+=1 ;  /* Global */
  222.      if ( ( !strcmp(a,filen)) || (strstr(a,filen) && wild) )
  223.         {
  224.          if (!clr && verbose)
  225.          {
  226.           for (i=0;i < (strlen(huntd)+10);i++)
  227.            printf("\b \b");
  228.           clr=1;
  229.          }
  230.          printf("%s: %s.%s\n",filen,huntd,d->d_name); /* print file name */
  231.         }
  232.      }
  233.      if (!clr && verbose)
  234.       for (i=0;i < (strlen(huntd)+10);i++)
  235.        printf("\b \b");
  236.    closedir(dirp);            /* close directory */
  237. }
  238.  
  239. /*-------------------------main--------------------------*/
  240. /*-------------------------------------------------------*/
  241.  
  242. int main(argc,argv)
  243. int argc;
  244. char **argv;
  245. {
  246.  void hunt(char *,char *);
  247.  extern char *getenv(const char *);
  248.  int bad=0,warn=0;
  249.  register int i,j;
  250.  int files=0 ,gotfilen=0 ,help=0;
  251.  char v[256];
  252.  static char filename[256]= '\0';
  253.  
  254.  if (argc>1)
  255.   for (i=1;i<argc;i++)
  256.      {
  257.      strcpy(v,argv[i]);
  258.  
  259.      if (!strcmp(v,"-"))    /* strcmp() becomes 0 when equal */
  260.       {
  261.       if (gotfilen || !gotfilen&&warn)
  262.        { bad=1; break;} /* who is pulling a joke on us with several '-' or filenames ? */
  263.       else
  264.        { warn=1; continue;}      /* filename starting with '-' follows */
  265.       }
  266.  
  267.      if ( v[0]=='-' && !warn)
  268.        {
  269.         for (j=1;j<strlen(v);j++) /* we might get several switches at once */
  270.         {
  271.         switch (v[j])
  272.          {
  273.           case 'v': case 'V' : verbose=1; break;
  274.           case 'f': case 'F' : files=1; break;
  275.           case 'h': case 'H' : case '?': help=1; break;
  276.           default: bad=1; /* printf("Unknown switch: -%c\n",v[j]); */
  277.          }
  278.         }
  279.        }
  280.      else
  281.        {
  282.         if (gotfilen)
  283.          bad=1;  /* two filenames ? no way */
  284.         else
  285.          {
  286.           strcpy(filename,v);
  287.           gotfilen=1;
  288.           warn=0; /* if we received filename,delete the warn switch,so we can read */
  289.          }        /* possible switches following the filename */
  290.        }
  291.      }
  292.  
  293.  if ((!gotfilen || filename[0]=='\0') && !verbose)
  294.    bad=1; /* got no filename,and no -v switch ? error */
  295.           /* check for filename[0] is to detect "" argument */
  296.           
  297.  if (help)
  298.     {
  299.     printf("Archimedes whereis 1.20 (C)1993 Kai Schlichting (kai@phantom.com)\n");
  300.     printf("Usage: whereis [-vfh?] <name>|<- -name> \n");
  301.     printf("Displays all matches for <name> in the order of execution when given\n");
  302.     printf("as *command in shell:\n");
  303.     printf("1) CLI *commands that match <name> exactly ,including the adjacent module name.\n");
  304.     printf("2) Alias$<name> definitions that match <name> exactly are returned. \n");
  305.     printf("3) filenames in the Run$Path which's leafname matches <name> exactly \n");
  306.     printf(" <name> can also be <name*>, here, then all leafnames which match *name*\n");
  307.     printf(" are returned.\n");
  308.     printf(" If <name> begins with a '-' a '-' must be the argument before\n");
  309.     printf(" <name> (e.g. 'whereis - -v' to search for file '-v').\n");
  310.     printf(" If no name is given, the -v switch will report the number of\n");
  311.     printf(" *commands/files alone. (-f switch is valid,then)\n");
  312.     printf(" The case of -v -f or -h does not matter.\n");
  313.     printf("-v switch: be verbose when searching and report number of *commands and files.\n");
  314.     printf("-f switch: search File$Path,too,in addition to Run$Path.\n");
  315.     printf("-h or -? switch: Display this help screen.\n");
  316.     exit(1);
  317.     }
  318.  else
  319.   {
  320.    if (argc==1 || bad )
  321.      {
  322.       printf("No output generated.\n");
  323.       printf("Usage: whereis [-vfh?] <name>|<- -name> \n");
  324.       printf("whereis -h for help.\n");
  325.       exit(1);
  326.      }
  327.   }
  328.  
  329.  if (!gotfilen)
  330.   {
  331.     printf("Counting *commands");
  332.    if (files)
  333.     printf(" ,files on Run$Path and files in File$Path.\n");
  334.    else
  335.     printf(" and files on Run$Path.\n");
  336.   }
  337.  else
  338.   if (verbose)
  339.    printf("Processing name: %s\n",filename);
  340.  
  341.  fcount=0; moduletest(filename);
  342.   if (verbose)
  343.    printf("(Found %d commands in Modules)\n",fcount);
  344.  
  345.  aliastest(filename);
  346.  
  347.  fcount=0; hunt("Run$Path",filename);
  348.   if (verbose)
  349.    printf("(Found %d files/dirs in Run$Path)\n",fcount);
  350.  
  351.  if (files)
  352.   {
  353.   fcount=0; hunt("File$Path",filename);
  354.    if (verbose)
  355.     printf("(Found %d files/dirs in File$Path)\n",fcount);
  356.   }
  357.  
  358.  exit(0);
  359. }
  360.