Annotation of researchv8dc/cmd/sh/expand.c, revision 1.1.1.1

1.1       root        1: /*     @(#)expand.c    1.4     */
                      2: /*
                      3:  *     UNIX shell
                      4:  *
                      5:  *     Bell Telephone Laboratories
                      6:  *
                      7:  */
                      8: 
                      9: #include       "defs.h"
                     10: #include       <sys/types.h>
                     11: #include       <sys/stat.h>
                     12: #include       <ndir.h>
                     13: 
                     14: #ifdef BSD4_2
                     15: #define                DIRSIZE MAXNAMELEN
                     16: #else
                     17: #define                DIRSIZE 14
                     18: #endif
                     19: #ifndef        MAXNAMELEN
                     20: #define        MAXNAMELEN      255
                     21: #endif
                     22: 
                     23: 
                     24: static char            entry[DIRSIZE+1];
                     25: 
                     26: /*
                     27:  * globals (file name generation)
                     28:  *
                     29:  * "*" in params matches r.e ".*"
                     30:  * "?" in params matches r.e. "."
                     31:  * "[...]" in params matches character class
                     32:  * "[...a-z...]" in params matches a through z.
                     33:  *
                     34:  */
                     35: extern int     addg();
                     36: 
                     37: 
                     38: expand(as, rcnt)
                     39:        char    *as;
                     40: {
                     41:        int     count;
                     42:        DIR     *dirf;
                     43:        BOOL    dir = 0;
                     44:        char    *rescan = 0;
                     45:        register char   *s, *cs;
                     46:        struct argnod   *schain = gchain;
                     47:        BOOL    slash;
                     48: 
                     49:        if (trapnote & SIGSET)
                     50:                return(0);
                     51:        s = cs = as;
                     52: 
                     53:        /*
                     54:         * check for meta chars
                     55:         */
                     56:        {
                     57:                register BOOL open;
                     58: 
                     59:                slash = 0;
                     60:                open = 0;
                     61:                do
                     62:                {
                     63:                        switch (*cs++)
                     64:                        {
                     65:                        case 0:
                     66:                                if (rcnt && slash)
                     67:                                        break;
                     68:                                else
                     69:                                        return(0);
                     70: 
                     71:                        case '/':
                     72:                                slash++;
                     73:                                open = 0;
                     74:                                continue;
                     75: 
                     76:                        case '[':
                     77:                                open++;
                     78:                                continue;
                     79: 
                     80:                        case ']':
                     81:                                if (open == 0)
                     82:                                        continue;
                     83: 
                     84:                        case '?':
                     85:                        case '*':
                     86:                                if (rcnt > slash)
                     87:                                        continue;
                     88:                                else
                     89:                                        cs--;
                     90:                                break;
                     91: 
                     92: 
                     93:                        default:
                     94:                                continue;
                     95:                        }
                     96:                        break;
                     97:                } while (TRUE);
                     98:        }
                     99: 
                    100:        for (;;)
                    101:        {
                    102:                if (cs == s)
                    103:                {
                    104:                        s = nullstr;
                    105:                        break;
                    106:                }
                    107:                else if (*--cs == '/')
                    108:                {
                    109:                        *cs = 0;
                    110:                        if (s == cs)
                    111:                                s = "/";
                    112:                        break;
                    113:                }
                    114:        }
                    115: 
                    116:        if ((dirf = opendir(*s ? s : ".")) != 0)
                    117:                dir = TRUE;
                    118:        
                    119:        count = 0;
                    120:        if (*cs == 0)
                    121:                *cs++ = 0200;
                    122: 
                    123:        if(dir)
                    124:        {
                    125:                register char *rs;
                    126:                struct direct *e;
                    127: 
                    128:                rs = cs;
                    129:                do
                    130:                {
                    131:                        if (*rs == '/')
                    132:                        {
                    133:                                rescan = rs;
                    134:                                *rs = 0;
                    135:                                gchain = 0;
                    136:                        }
                    137:                } while (*rs++);
                    138: 
                    139:                while ((e = readdir(dirf)) && (trapnote & SIGSET) == 0)
                    140:                {
                    141:                        *(movstrn(e->d_name, entry, DIRSIZE)) = 0;
                    142: 
                    143:                        if (entry[0] == '.' && *cs != '.')
                    144:                        {
                    145:                                if (entry[1] == 0)
                    146:                                        continue;
                    147:                                if (entry[1] == '.' && entry[2] == 0)
                    148:                                        continue;
                    149:                        }
                    150: 
                    151:                        if (gmatch(entry, cs))
                    152:                        {
                    153:                                addg(s, entry, rescan);
                    154:                                count++;
                    155:                        }
                    156:                }
                    157:                closedir(dirf);
                    158: 
                    159:                if (rescan)
                    160:                {
                    161:                        register struct argnod  *rchain;
                    162: 
                    163:                        rchain = gchain;
                    164:                        gchain = schain;
                    165:                        if (count)
                    166:                        {
                    167:                                count = 0;
                    168:                                while (rchain)
                    169:                                {
                    170:                                        count += expand(rchain->argval, slash + 1);
                    171:                                        rchain = rchain->argnxt;
                    172:                                }
                    173:                        }
                    174:                        *rescan = '/';
                    175:                }
                    176:        }
                    177: 
                    178:        {
                    179:                register char   c;
                    180: 
                    181:                s = as;
                    182:                while (c = *s)
                    183:                        *s++ = (c & STRIP ? c : '/');
                    184:        }
                    185:        return(count);
                    186: }
                    187: 
                    188: 
                    189: 
                    190: gmatch(s, p)
                    191: register char  *s, *p;
                    192: {
                    193:        register int    scc;
                    194:        char            c;
                    195: 
                    196:        if (scc = *s++)
                    197:        {
                    198:                if ((scc &= STRIP) == 0)
                    199:                        scc=0200;
                    200:        }
                    201:        switch (c = *p++)
                    202:        {
                    203:        case '[':
                    204:                {
                    205:                        BOOL ok;
                    206:                        int lc;
                    207:                        int notflag = 0;
                    208: 
                    209:                        ok = 0;
                    210:                        lc = 077777;
                    211:                        if (*p == '^')
                    212:                        {
                    213:                                notflag = 1;
                    214:                                p++;
                    215:                        }
                    216:                        while (c = *p++)
                    217:                        {
                    218:                                if (c == ']')
                    219:                                        return(ok ? gmatch(s, p) : 0);
                    220:                                else if (c == MINUS)
                    221:                                {
                    222:                                        if (notflag)
                    223:                                        {
                    224:                                                if (scc < lc || scc > *(p++))
                    225:                                                        ok++;
                    226:                                                else
                    227:                                                        return(0);
                    228:                                        }
                    229:                                        else
                    230:                                        {
                    231:                                                if (lc <= scc && scc <= (*p++))
                    232:                                                        ok++;
                    233:                                        }
                    234:                                }
                    235:                                else
                    236:                                {
                    237:                                        lc = c & STRIP;
                    238:                                        if (notflag)
                    239:                                        {
                    240:                                                if (scc && scc != lc)
                    241:                                                        ok++;
                    242:                                                else
                    243:                                                        return(0);
                    244:                                        }
                    245:                                        else
                    246:                                        {
                    247:                                                if (scc == lc)
                    248:                                                        ok++;
                    249:                                        }
                    250:                                }
                    251:                        }
                    252:                        return(0);
                    253:                }
                    254: 
                    255:        default:
                    256:                if ((c & STRIP) != scc)
                    257:                        return(0);
                    258: 
                    259:        case '?':
                    260:                return(scc ? gmatch(s, p) : 0);
                    261: 
                    262:        case '*':
                    263:                while (*p == '*')
                    264:                        p++;
                    265: 
                    266:                if (*p == 0)
                    267:                        return(1);
                    268:                --s;
                    269:                while (*s)
                    270:                {
                    271:                        if (gmatch(s++, p))
                    272:                                return(1);
                    273:                }
                    274:                return(0);
                    275: 
                    276:        case 0:
                    277:                return(scc == 0);
                    278:        }
                    279: }
                    280: 
                    281: static int
                    282: addg(as1, as2, as3)
                    283: char   *as1, *as2, *as3;
                    284: {
                    285:        register char   *s1, *s2;
                    286:        register int    c;
                    287: 
                    288:        s2 = locstak() + BYTESPERWORD;
                    289:        s1 = as1;
                    290:        while (c = *s1++)
                    291:        {
                    292:                if ((c &= STRIP) == 0)
                    293:                {
                    294:                        *s2++ = '/';
                    295:                        break;
                    296:                }
                    297:                *s2++ = c;
                    298:        }
                    299:        s1 = as2;
                    300:        while (*s2 = *s1++)
                    301:                s2++;
                    302:        if (s1 = as3)
                    303:        {
                    304:                *s2++ = '/';
                    305:                while (*s2++ = *++s1);
                    306:        }
                    307:        makearg(endstak(s2));
                    308: }
                    309: 
                    310: makearg(args)
                    311:        register struct argnod *args;
                    312: {
                    313:        args->argnxt = gchain;
                    314:        gchain = args;
                    315: }
                    316: 
                    317: 
                    318: DIR *
                    319: opendir(name)
                    320: register char *name;
                    321: {
                    322:        DIR dirbuf, *dirp;
                    323:        struct stat statb;
                    324:        char buf[MAXNAMELEN+1];
                    325:        register char *s;
                    326: 
                    327:        *(movstrn(name, buf, MAXNAMELEN)) = 0;
                    328:        for (s=buf; *s; s++)
                    329:                *s &= STRIP;
                    330:        if ((dirbuf.dd_fd = open(buf, 0)) < 0)
                    331:                return(NULL);
                    332:        if (fstat(dirbuf.dd_fd, &statb)!=0 || (statb.st_mode & S_IFMT)!=S_IFDIR){
                    333:                close(dirbuf.dd_fd);
                    334:                return(NULL);
                    335:        }
                    336:        dirbuf.dd_loc = 0;
                    337:        dirp = (DIR *)alloc(sizeof(DIR));
                    338:        *dirp = dirbuf;
                    339:        return(dirp);
                    340: }
                    341: 
                    342: void
                    343: closedir(dirp)
                    344: DIR *dirp;
                    345: {
                    346:        close(dirp->dd_fd);
                    347:        free((char *)dirp);
                    348: }

unix.superglobalmegacorp.com

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