home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / 2014.11.minnie.tuhs.org.tar / minnie.tuhs.org / UnixArchive / PDP-11 / Trees / V6 / usr / source / s1 / glob.c < prev    next >
C/C++ Source or Header  |  1975-05-14  |  4KB  |  257 lines

  1. #
  2. /* global command --
  3.  
  4.    glob params
  5.  
  6.    "*" in params matches r.e ".*"
  7.    "?" in params matches r.e. "."
  8.    "[...]" in params matches character class
  9.    "[...a-z...]" in params matches a through z.
  10.  
  11.    perform command with argument list
  12.   constructed as follows:
  13.      if param does not contain "*", "[", or "?", use it as is
  14.      if it does, find all files in current directory
  15.      which match the param, sort them, and use them
  16.  
  17.    prepend the command name with "/bin" or "/usr/bin"
  18.    as required.
  19. */
  20.  
  21. #define    E2BIG    7
  22. #define    ENOEXEC    8
  23. #define    ENOENT    2
  24.  
  25. #define    STRSIZ    522
  26. char    ab[STRSIZ];        /* generated characters */
  27. char    *ava[200];        /* generated arguments */
  28. char    **av &ava[1];
  29. char    *string ab;
  30. int    errno;
  31. int    ncoll;
  32.  
  33. main(argc, argv)
  34. char *argv[];
  35. {
  36.     register char *cp;
  37.  
  38.     if (argc < 3) {
  39.         write(2, "Arg count\n", 10);
  40.         return;
  41.     }
  42.     argv++;
  43.     *av++ = *argv;
  44.     while (--argc >= 2)
  45.         expand(*++argv);
  46.     if (ncoll==0) {
  47.         write(2, "No match\n", 9);
  48.         return;
  49.     }
  50.     execute(ava[1], &ava[1]);
  51.     cp = cat("/usr/bin/", ava[1]);
  52.     execute(cp+4, &ava[1]);
  53.     execute(cp, &ava[1]);
  54.     write(2, "Command not found.\n", 19);
  55. }
  56.  
  57. expand(as)
  58. char *as;
  59. {
  60.     register char *s, *cs;
  61.     register int dirf;
  62.     char **oav;
  63.     static struct {
  64.         int    ino;
  65.         char    name[16];
  66.     } entry;
  67.  
  68.     s = cs = as;
  69.     while (*cs!='*' && *cs!='?' && *cs!='[') {
  70.         if (*cs++ == 0) {
  71.             *av++ = cat(s, "");
  72.             return;
  73.         }
  74.     }
  75.     for (;;) {
  76.         if (cs==s) {
  77.             dirf = open(".", 0);
  78.             s = "";
  79.             break;
  80.         }
  81.         if (*--cs == '/') {
  82.             *cs = 0;
  83.             dirf = open(s==cs? "/": s, 0);
  84.             *cs++ = 0200;
  85.             break;
  86.         }
  87.     }
  88.     if (dirf<0) {
  89.         write(2, "No directory\n", 13);
  90.         exit();
  91.     }
  92.     oav = av;
  93.     while (read(dirf, &entry, 16) == 16) {
  94.         if (entry.ino==0)
  95.             continue;
  96.         if (match(entry.name, cs)) {
  97.             *av++ = cat(s, entry.name);
  98.             ncoll++;
  99.         }
  100.     }
  101.     close(dirf);
  102.     sort(oav);
  103. }
  104.  
  105. sort(oav)
  106. char **oav;
  107. {
  108.     register char **p1, **p2, **c;
  109.  
  110.     p1 = oav;
  111.     while (p1 < av-1) {
  112.         p2 = p1;
  113.         while(++p2 < av) {
  114.             if (compar(*p1, *p2) > 0) {
  115.                 c = *p1;
  116.                 *p1 = *p2;
  117.                 *p2 = c;
  118.             }
  119.         }
  120.         p1++;
  121.     }
  122. }
  123.  
  124. execute(afile, aarg)
  125. char *afile;
  126. char **aarg;
  127. {
  128.     register char *file, **arg;
  129.  
  130.     arg = aarg;
  131.     file = afile;
  132.     execv(file, arg);
  133.     if (errno==ENOEXEC) {
  134.         arg[0] = file;
  135.         *--arg = "/bin/sh";
  136.         execv(*arg, arg);
  137.     }
  138.     if (errno==E2BIG)
  139.         toolong();
  140. }
  141.  
  142. toolong()
  143. {
  144.     write(2, "Arg list too long\n", 18);
  145.     exit();
  146. }
  147.  
  148. match(s, p)
  149. char *s, *p;
  150. {
  151.     if (*s=='.' && *p!='.')
  152.         return(0);
  153.     return(amatch(s, p));
  154. }
  155.  
  156. amatch(as, ap)
  157. char *as, *ap;
  158. {
  159.     register char *s, *p;
  160.     register scc;
  161.     int c, cc, ok, lc;
  162.  
  163.     s = as;
  164.     p = ap;
  165.     if (scc = *s++)
  166.         if ((scc =& 0177) == 0)
  167.             scc = 0200;
  168.     switch (c = *p++) {
  169.  
  170.     case '[':
  171.         ok = 0;
  172.         lc = 077777;
  173.         while (cc = *p++) {
  174.             if (cc==']') {
  175.                 if (ok)
  176.                     return(amatch(s, p));
  177.                 else
  178.                     return(0);
  179.             } else if (cc=='-') {
  180.                 if (lc<=scc && scc<=(c = *p++))
  181.                     ok++;
  182.             } else
  183.                 if (scc == (lc=cc))
  184.                     ok++;
  185.         }
  186.         return(0);
  187.  
  188.     default:
  189.         if (c!=scc)
  190.             return(0);
  191.  
  192.     case '?':
  193.         if (scc)
  194.             return(amatch(s, p));
  195.         return(0);
  196.  
  197.     case '*':
  198.         return(umatch(--s, p));
  199.  
  200.     case '\0':
  201.         return(!scc);
  202.     }
  203. }
  204.  
  205. umatch(s, p)
  206. char *s, *p;
  207. {
  208.     if(*p==0)
  209.         return(1);
  210.     while(*s)
  211.         if (amatch(s++,p))
  212.             return(1);
  213.     return(0);
  214. }
  215.  
  216. compar(as1, as2)
  217. char *as1, *as2;
  218. {
  219.     register char *s1, *s2;
  220.  
  221.     s1 = as1;
  222.     s2 = as2;
  223.     while (*s1++ ==  *s2)
  224.         if (*s2++ == 0)
  225.             return(0);
  226.     return (*--s1 - *s2);
  227. }
  228.  
  229. cat(as1, as2)
  230. char *as1, *as2;
  231. {
  232.     register char *s1, *s2;
  233.     register int c;
  234.  
  235.     s2 = string;
  236.     s1 = as1;
  237.     while (c = *s1++) {
  238.         if (s2 > &ab[STRSIZ])
  239.             toolong();
  240.         c =& 0177;
  241.         if (c==0) {
  242.             *s2++ = '/';
  243.             break;
  244.         }
  245.         *s2++ = c;
  246.     }
  247.     s1 = as2;
  248.     do {
  249.         if (s2 > &ab[STRSIZ])
  250.             toolong();
  251.         *s2++ = c = *s1++;
  252.     } while (c);
  253.     s1 = string;
  254.     string = s2;
  255.     return(s1);
  256. }
  257.