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

unix.superglobalmegacorp.com

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