# /* * glob1 libs command arg ... * * Modified by: Bill Joy (UCB) Oct 1976 * * takes library name string from the shell * allows patterns to match directory names, i.e. "/mnt/c*?/.q" * knows about pascal object and forks px's */ char usagestr[] "usage: glob2 libs command arg ..."; char shell[] "/bin/sh"; char px[] "/bin/px"; #define PCXN 0404 #define E2BIG 7 #define ENOEXEC 8 #define ENOENT 2 #define STRSIZ 522 #define PTHSIZ 100 char *lib; char ab[STRSIZ]; char *ava[200]; char **av &ava[1]; char *string ab; int ncoll; char path[100]; char *pathp path; int globbed; char *entp; int errno; int stbuff[18]; main(argc, argv) char *argv[]; { register char *cp1, *cp2, *cpl; if (argc < 4) panic(usagestr); argv++; argc--; lib = *argv++; argc--; *av++ = *argv++; argc--; while (argc) { collect(*argv++); argc--; } if (ncoll==0) panic("No match"); cp1 = ava[1]; while(*cp1 && *cp1 != '/') cp1++; if (*cp1 || getuid()) execute(ava[1], &ava[1]); if (!*cp1) { if (cpl = lib) for(;;) { while ((*cpl & 0177) == ' ') cpl++; if (!*cpl) break; cp1 = path; while (*cpl =& 0177) if (*cpl == ' ') break; else if (cp1 >= &path[PTHSIZ-2]) patherr(); else *cp1++ = *cpl++; *cp1++ = '/'; cp2 = ava[1]; while(*cp1++ = *cp2++) if (cp1 >= &path[PTHSIZ]) patherr(); execute(path, &ava[1]); } cp1 = path; cp2 = "/usr/bin/"; while(*cp1++ = *cp2++) ; cp1--; cp2 = ava[1]; while(*cp1++ = *cp2++) if (cp1 >= &path[PTHSIZ]) patherr(); execute(path+4, &ava[1]); execute(path, &ava[1]); } prs(ava[1]); panic(": not found"); } execute(afile, aarg) char *afile; char **aarg; { register char *file, **arg; register i; int w; arg = aarg; file = afile; execv(file, arg); if (errno==ENOEXEC) { arg[0] = file; *--arg = shell; i = open(file, 0); if (i >= 0) { if (read(i, &w, 2) == 2 && w == PCXN) *arg = px; close(i); } execv(*arg, arg); prs("no "); prs(*arg); panic("!!"); } else if (errno==E2BIG) toolong(); } collect(as) { char **oav; oav = av; globbed = 0; expand(as); sort(oav); } sort(oav) char **oav; { register char **p1, **p2, **c; p1 = oav; while (p1 < av-1) { p2 = p1; while(++p2 < av) { if (compar(*p1, *p2) > 0) { c = *p1; *p1 = *p2; *p2 = c; } } p1++; } } expand(as) char *as; { register char *cs; char *spathp; register int dirf; static struct { int ino; char name[16]; } entry; spathp = pathp; cs = as; while (*cs != '*' && *cs != '?' && *cs != '[') { if (pathp >= &path[PTHSIZ]) patherr(); else if ((*pathp++ = *cs++) == 0) { if (!globbed) *av++ = cat(as, ""); else if (stat(path, &stbuff) >= 0) { *av++ = cat(path, ""); ncoll++; } goto endit; } } pathp = spathp; cs--; while (cs >= as && *cs != '/') cs--; while (as <= cs) if (pathp >= &path[PTHSIZ]) patherr(); else *pathp++ = *as++; *pathp = 0; dirf = open(path, 0); if (dirf<0) if (globbed) goto endit; else { prs(path); panic(": cannot open"); } globbed++; cs++; while (read(dirf, &entry, 16) == 16) { if (entry.ino==0) continue; if (match(entry.name, cs)) { *av++ = cat(path, entry.name); ncoll++; } } close(dirf); endit: pathp = spathp; *pathp = 0; } toolong() { panic("Arg list too long"); } patherr() { prs("Path too long: "); panic(path); } match(s, p) char *s, *p; { register c, sentp; if (*s == '.' && *p != '.') return(0); sentp = entp; entp = s; c = amatch(s, p); entp = sentp; return(c); } amatch(as, ap) char *as, *ap; { register char *s, *p; register scc; int c, cc, ok, lc; char *spathp; s = as; p = ap; nextc: if(scc = *s++ & 0177) if ((scc =& 0177) == 0) scc = 0200; switch (c = *p++) { case '[': ok = 0; lc = 077777; while (cc = *p++) { if (cc == ']') { if (ok) goto nextc; else return(0); } else if (cc == '-') { if (lc <= scc && scc <= *p++) ok++; } else if (scc == (lc = cc)) ok++; } panic("missing ]"); case '*': if(*p == '\0') return(1); else if (*p == '/') { p++; goto slash; } s--; while(*s) if (amatch(s, p)) return(1); else s++; return(0); case '\0': return(scc == '\0'); default: if (c == scc) goto nextc; else return(0); case '?': if (scc != '\0') goto nextc; else return(0); case '/': if (scc == '\0') { slash: s = entp; spathp = pathp; while (*pathp = *s++) pathp++; *pathp++ = '/'; *pathp = 0; if (stat(path, &stbuff) == 0) if ((stbuff[2] & 060000) == 040000) if (*p == 0) { *av++ = cat(path, ""); ncoll++; } else expand(p); pathp = spathp; *pathp = 0; } return(0); } } compar(as1, as2) char *as1, *as2; { register char *s1, *s2; s1 = as1; s2 = as2; while (*s1++ == *s2) if (*s2++ == 0) return(0); if (*--s1 == '/') return(-1); else if (*s2 == '/') return(1); else return (*s1 - *s2); } cat(as1, as2) char *as1, *as2; { register char *s1, *s2; s2 = string; s1 = as1; while (*s2++ = (*s1++ & 0177)) if (s2 >= &ab[STRSIZ]) toolong(); s1 = as2; s2--; while (*s2++ = *s1++) if (s2 > &ab[STRSIZ]) toolong(); s1 = string; string = s2; return(s1); } prs(str) char *str; { register char *cp; cp = str; while(*cp) cp++; write(2, str, cp-str); } panic(str) { prs(str); write(2, &"\n", 1); exit(1); }