Annotation of coherent/d/bin/sh/glob.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * A shell.
                      3:  * Glob interpretation.
                      4:  */
                      5: #include "sh.h"
                      6: 
                      7: #include <sys/types.h>
                      8: #include <sys/dir.h>
                      9: #include <sys/stat.h>
                     10: 
                     11: #define isdir(s)       (((s)->st_mode&S_IFMT)==S_IFDIR)
                     12: 
                     13: struct nmlst {
                     14:        struct nmlst *g_next;
                     15:        char g_name[];
                     16: };
                     17: 
                     18: char *dirn = NULL;
                     19: int pref = 0;
                     20: 
                     21: struct nmlst *newnm();
                     22: char *gany();
                     23: char *dread();
                     24: int nmcmp();
                     25: 
                     26: /*
                     27:  * Initial glob driver, set up initial directory name, pattern, and
                     28:  * suffix; call glob2; sort the results.
                     29:  */
                     30: glob1(args)
                     31: char *args;
                     32: {
                     33:        register char *patt;
                     34:        register char *suff;
                     35:        register int nsep;
                     36:        int myargc;
                     37: 
                     38:        if (gany(args)==NULL) {
                     39:                /* Nothing to match */
                     40:                strip(args);
                     41:                newarg(args, 0);
                     42:        } else {
                     43:                if (dirn != NULL)
                     44:                        sfree(dirn);
                     45:                dirn = salloc(DIRSIZ);
                     46:                if (args[0]=='/') {
                     47:                        pref = 0;
                     48:                        strcpy(dirn, "/");
                     49:                        patt = args + 1;
                     50:                } else {
                     51:                        pref = 2;
                     52:                        strcpy(dirn, "./");
                     53:                        patt = args;
                     54:                }
                     55:        
                     56:                if ((suff=index(patt, '/')) != NULL)
                     57:                        for (nsep=0; *suff=='/'; nsep+=1)
                     58:                                *suff++ = '\0';
                     59:                else
                     60:                        nsep = 0;
                     61:                myargc = nargc;
                     62:                glob2(patt, nsep, suff);
                     63:                if (myargc != nargc)
                     64:                        qsort(&nargv[myargc], nargc-myargc,
                     65:                                sizeof(nargv[0]), nmcmp);
                     66:                else {
                     67:                        /* No match */
                     68:                        while (nsep-- > 0)
                     69:                                *--suff = '/';
                     70:                        strip(args);
                     71:                        newarg(args, 0);
                     72:                }
                     73:        }
                     74: }
                     75: 
                     76: nmcmp(cpp1, cpp2)
                     77: char **cpp1, **cpp2;
                     78: {
                     79:        return (strcmp(*cpp1, *cpp2));
                     80: }
                     81: 
                     82: glob2(patt, nsep, suff)
                     83: char *patt, *suff;
                     84: int nsep;
                     85: {
                     86:        register struct nmlst *nmlst = NULL;
                     87:        struct nmlst *np;
                     88:        register char *name;
                     89:        char *nsuff, *ndirn;
                     90:        int nnsep, dirp;
                     91: 
                     92:        if (gany(patt)==NULL) {
                     93:                nmlst = newnm(nmlst, patt);
                     94:                strip(nmlst->g_name);
                     95:        } else if (dopen(dirn) >= 0) {
                     96:                while ((name = dread()) != NULL) {
                     97:                        if (match(patt, name)
                     98:                         && (name[0]!='.' || patt[0]=='.')) {
                     99:                                nmlst = newnm(nmlst, name);
                    100:                        }
                    101:                }
                    102:        }
                    103:        if (nmlst!=NULL) {
                    104:                ndirn = salloc(strlen(dirn)+DIRSIZ+nsep+1);
                    105:                strcpy(ndirn, dirn);
                    106:                sfree(dirn);
                    107:                dirn = ndirn;
                    108:                dirp = strlen(dirn);
                    109:                if ((nsuff=suff)!=NULL && (nsuff=index(nsuff, '/'))!=NULL)
                    110:                        for (nnsep=0; *nsuff=='/'; nnsep+=1)
                    111:                                *nsuff++ = '\0';
                    112:                else
                    113:                        nnsep = 0;
                    114:                while (nmlst!=NULL) {
                    115:                        name = dirn + dirp;
                    116:                        strcpy(name, nmlst->g_name);
                    117:                        nmlst = (np = nmlst)->g_next;
                    118:                        sfree(np);
                    119:                        mksep(name, nsep);
                    120:                        if (suff!=NULL)
                    121:                                glob2(suff, nnsep, nsuff);
                    122:                        else
                    123:                                newarg(dirn + pref, 1);
                    124:                }
                    125:                while (nnsep-- > 0)
                    126:                        *--nsuff = '/';
                    127:                dirn[dirp] = '\0';
                    128:        }
                    129: }
                    130: 
                    131: /*
                    132:  * See if a pattern matches a string.
                    133:  * '\' escapes the next character.
                    134:  */
                    135: match(pp, sp)
                    136: register char *pp;
                    137: register char *sp;
                    138: {
                    139:        int c2;
                    140:        register int c1;
                    141: 
                    142:        while ((c1=*pp++)) {
                    143:                switch (c1) {
                    144:                case '?':
                    145:                        if (*sp++)
                    146:                                continue;
                    147:                        return (0);
                    148:                case '*':
                    149:                        do {
                    150:                                if (match(pp, sp))
                    151:                                        return (1);
                    152:                        } while (*sp++);
                    153:                        return (0);
                    154:                case '[':
                    155:                        if ((c2=*sp++) == '\0')
                    156:                                return (0);
                    157:                        for (;;) {
                    158:                                if ((c1=*pp++) == '\0' || c1 == ']')
                    159:                                        return (0);
                    160:                                if (c1 == '\\' && (c1=*pp++) == '\0')
                    161:                                        return (0);
                    162:                                if (c1 == c2)
                    163:                                        break;
                    164:                                if (*pp == '-') {
                    165:                                        pp += 1;
                    166:                                        if (c2 < c1)
                    167:                                                continue;
                    168:                                        if ((c1=*pp++) == '\0')
                    169:                                                return (0);
                    170:                                        if (c1 == '\\' && (c1=*pp++) == '\0')
                    171:                                                return (0);
                    172:                                        if (c2 <= c1)
                    173:                                                break;
                    174:                                }
                    175:                        }
                    176:                        while ((c1 = *pp++) != ']') {
                    177:                                if (c1 == '\0')
                    178:                                        return (0);
                    179:                                if (c1 == '\\' && *pp++ == '\0')
                    180:                                        return (0);
                    181:                        }
                    182:                        continue;
                    183:                case '\\':
                    184:                        if ((c1=*pp++) == '\0')
                    185:                                return (0);
                    186:                        /* fall through */
                    187:                default:
                    188:                        if (c1 == *sp++)
                    189:                                continue;
                    190:                        return (0);
                    191:                }
                    192:        }
                    193:        return (*sp=='\0');
                    194: }
                    195: 
                    196: struct nmlst *
                    197: newnm(olst, name)
                    198: struct nmlst *olst;
                    199: char *name;
                    200: {
                    201:        register struct nmlst *np;
                    202:        register int n;
                    203: 
                    204:        n = strlen(name)+1+sizeof(*np);
                    205:        np = (struct nmlst *) salloc(n);
                    206:        np->g_next = olst;
                    207:        strcpy(np->g_name, name);
                    208:        return (np);
                    209: }
                    210: 
                    211: mksep(cp, ns)
                    212: register char *cp;
                    213: register int ns;
                    214: {
                    215:        while (*cp != '\0')
                    216:                cp += 1;
                    217:        while (ns-- > 0)
                    218:                *cp++ = '/';
                    219:        *cp = '\0';
                    220: }
                    221: 
                    222: newarg(p, f)
                    223: char *p;
                    224: {
                    225:        struct stat s;
                    226: 
                    227:        if (f && stat(p, &s) < 0)
                    228:                return;
                    229:        nargc += 1;
                    230:        nargv = addargl(nargv, duplstr(p, 0));
                    231: }
                    232: 
                    233: /*
                    234:  * Returns the location of the next unescaped glob character.
                    235:  */
                    236: char *
                    237: gany(s)
                    238: register char *s;
                    239: {
                    240:        register int c;
                    241: 
                    242:        while (*s)
                    243:                if ((c=*s++) == '\\')
                    244:                        if (*s++ == '\0')
                    245:                                return (NULL);
                    246:                        else
                    247:                                continue;
                    248:                else if (c == '*' || c == '?' || c == '[')
                    249:                        return (--s);
                    250:        return (NULL);
                    251: }
                    252: 
                    253: /*
                    254:  * get rid of the glob escapes.
                    255:  */
                    256: strip(s)
                    257: register char *s;
                    258: {
                    259:        register char *p;
                    260: 
                    261:        p = s;
                    262:        while (*s)
                    263:                if ((*p = *s++) == '\\')
                    264:                        if (*p++ = *s++)
                    265:                                continue;
                    266:                        else
                    267:                                break;
                    268:                else
                    269:                        p++;
                    270:        *p = *s;
                    271: }
                    272: 
                    273: int dfd;
                    274: int dcnt;
                    275: struct direct *dptr;
                    276: struct direct *dbuf = strt;
                    277: char dtmp[DIRSIZ+2] = { 0 };
                    278: 
                    279: dopen(p)
                    280: char *p;
                    281: {
                    282:        struct stat s;
                    283: 
                    284:        dcnt = 0;
                    285:        if (stat(p, &s) < 0
                    286:         || ! isdir(&s)
                    287:         || (dfd = open(p, 0)) < 0)
                    288:                dfd = -1;
                    289:        return (dfd);
                    290: }
                    291: 
                    292: char *
                    293: dread()
                    294: {
                    295:        register struct direct *dp;
                    296: 
                    297:        while (dfd >= 0) {
                    298:                while (dcnt-- > 0) {
                    299:                        dp = dptr++;
                    300:                        if (dp->d_ino != 0)
                    301:                                return (strncpy(dtmp, dp->d_name, DIRSIZ));
                    302:                }
                    303:                dptr = dbuf;
                    304:                dcnt = read(dfd, (char *)dptr, 64*sizeof(dbuf[0]));
                    305:                dcnt /= sizeof(dbuf[0]);
                    306:                if (dcnt <= 0) {
                    307:                        close(dfd);
                    308:                        dfd = -1;
                    309:                }
                    310:        }
                    311:        return (NULL);
                    312: }
                    313: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.