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: }

Defined functions

amatch defined in line 156; used 4 times
cat defined in line 229; used 3 times
compar defined in line 216; used 1 times
execute defined in line 124; used 3 times
expand defined in line 57; used 1 times
  • in line 45
main defined in line 33; never used
match defined in line 148; used 1 times
  • in line 96
sort defined in line 105; used 1 times
toolong defined in line 142; used 3 times
umatch defined in line 205; used 1 times

Defined variables

ab defined in line 29; used 2 times
av defined in line 28; used 6 times
ava defined in line 28; used 5 times
errno defined in line 30; used 2 times
ncoll defined in line 31; used 2 times
string defined in line 29; used 3 times

Defined macros

E2BIG defined in line 21; used 1 times
ENOENT defined in line 23; never used
ENOEXEC defined in line 22; used 1 times
STRSIZ defined in line 25; used 3 times
Last modified: 1975-05-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 946
Valid CSS Valid XHTML 1.0 Strict