Annotation of researchv9/ipc/src/servers/ftpaux.c, revision 1.1.1.1

1.1       root        1: #include       <sys/types.h>
                      2: #include       <sys/stat.h>
                      3: #include       <errno.h>
                      4: 
                      5: extern int errno;
                      6: 
                      7: #define        U_MODE  (xstat.st_mode >> 6) & 7)
                      8: #define        G_MODE  (xstat.st_mode >> 3) & 7)
                      9: #define        O_MODE  (xstat.st_mode & 7)
                     10:  
                     11: static char *
                     12: dir(path)
                     13:        char *path;
                     14: {
                     15:        static char base[128];
                     16:        char *p;
                     17:        char *strrchr();
                     18: 
                     19:        strncpy(base, path, sizeof(base)-1);
                     20:        base[sizeof(base)-1] = '\0';
                     21:        p = strrchr(base, '/');
                     22:        if (p==0)
                     23:                return ".";
                     24:        *p = '\0';
                     25:        return base;
                     26: }
                     27: 
                     28: access2(name, mode, uid, gid)
                     29: char *name;
                     30: {
                     31:        struct stat xstat;
                     32: 
                     33:        if (-1 == stat(name, &xstat)) {
                     34:                if (!(mode&2) || -1==stat(dir(name), &xstat)) {
                     35:                        perror("stat");
                     36:                        return -1;
                     37:                }
                     38: 
                     39:                /* check ability to create file */
                     40:                if (xstat.st_uid == uid && (U_MODE & 2)
                     41:                        return 0;
                     42:                if (xstat.st_gid == gid && (G_MODE & 2)
                     43:                        return 0;
                     44:                if (xstat.st_uid != uid && xstat.st_gid != gid && O_MODE & 2)
                     45:                        return 0;
                     46:                errno = EACCES;
                     47:                return -1;
                     48:        }
                     49: 
                     50:        if (xstat.st_uid == uid && (U_MODE & mode)
                     51:                return 0;
                     52:        if (xstat.st_gid == gid && (G_MODE & mode)
                     53:                return 0;
                     54:        if (xstat.st_uid != uid && xstat.st_gid != gid && O_MODE & mode)
                     55:                return 0;
                     56:        errno = EACCES;
                     57:        return -1;
                     58: }
                     59: 
                     60: mkdir(f, mode)
                     61: char *f;
                     62: {
                     63:        int status, i, mode;
                     64:         struct stat st;
                     65: 
                     66:         if (!stat(f, &st))
                     67:                return(-1);
                     68:         while((i=fork()) == -1)
                     69:                sleep(3);
                     70:        if(i) {
                     71:                wait(&status);
                     72:                return(stat(f, &st));
                     73:        }
                     74:        execl("/bin/mkdir", "mkdir", f, 0);
                     75:        exit(1);
                     76: }
                     77: 
                     78: rmdir(f)
                     79: char *f;
                     80: {
                     81:        int status, i;
                     82:         struct stat st;
                     83: 
                     84:        if (-1 == stat(f, &st))
                     85:                return(-1);
                     86:         while((i=fork()) == -1)
                     87:                sleep(3);
                     88:        if(i) {
                     89:                wait(&status);
                     90:                if (stat(f, &st) == -1)
                     91:                      return(0);
                     92:                return(-1);
                     93: 
                     94:        }
                     95:        execl("/bin/rmdir", "rmdir", f, 0);
                     96:        exit(1);
                     97: }
                     98: 
                     99: /*
                    100:  * C-shell glob for random programs.
                    101:  */
                    102: 
                    103: #include <ndir.h>
                    104: #include <stdio.h>
                    105: #include <pwd.h>
                    106: 
                    107: #define        QUOTE 0200
                    108: #define        TRIM 0177
                    109: #define        eq(a,b)         (strcmp(a, b)==0)
                    110: #define        GAVSIZ          (NCARGS/6)
                    111: #define        isdir(d)        ((d.st_mode & S_IFMT) == S_IFDIR)
                    112: 
                    113: static char **gargv;           /* Pointer to the (stack) arglist */
                    114: static short gargc;            /* Number args in gargv */
                    115: static short gnleft;
                    116: static short gflag;
                    117: static int tglob();
                    118: char   **glob();
                    119: char   *globerr;
                    120: char   *home;
                    121: struct passwd *getpwnam();
                    122: extern int errno;
                    123: static char *strspl(), **copyblk(), *strend();
                    124: char   *malloc(), *strcpy(), *strcat();
                    125: 
                    126: static int globcnt;
                    127: 
                    128: char   *globchars = "`{[*?";
                    129: 
                    130: static char *gpath, *gpathp, *lastgpathp;
                    131: static int globbed;
                    132: static char *entp;
                    133: static char **sortbas;
                    134: 
                    135: char **
                    136: glob(v)
                    137:        register char *v;
                    138: {
                    139:        char agpath[BUFSIZ];
                    140:        char *agargv[GAVSIZ];
                    141:        char *vv[2];
                    142:        vv[0] = v;
                    143:        vv[1] = 0;
                    144:        gflag = 0;
                    145:        rscan(vv, tglob);
                    146:        if (gflag == 0)
                    147:                return (copyblk(vv));
                    148: 
                    149:        globerr = 0;
                    150:        gpath = agpath; gpathp = gpath; *gpathp = 0;
                    151:        lastgpathp = &gpath[sizeof agpath - 2];
                    152:        ginit(agargv); globcnt = 0;
                    153:        collect(v);
                    154:        if (globcnt == 0 && (gflag&1)) {
                    155:                blkfree(gargv), gargv = 0;
                    156:                return (0);
                    157:        } else
                    158:                return (gargv = copyblk(gargv));
                    159: }
                    160: 
                    161: static
                    162: ginit(agargv)
                    163:        char **agargv;
                    164: {
                    165: 
                    166:        agargv[0] = 0; gargv = agargv; sortbas = agargv; gargc = 0;
                    167:        gnleft = NCARGS - 4;
                    168: }
                    169: 
                    170: static
                    171: collect(as)
                    172:        register char *as;
                    173: {
                    174:        if (eq(as, "{") || eq(as, "{}")) {
                    175:                Gcat(as, "");
                    176:                sort();
                    177:        } else
                    178:                acollect(as);
                    179: }
                    180: 
                    181: static
                    182: acollect(as)
                    183:        register char *as;
                    184: {
                    185:        register int ogargc = gargc;
                    186: 
                    187:        gpathp = gpath; *gpathp = 0; globbed = 0;
                    188:        expand(as);
                    189:        if (gargc != ogargc)
                    190:                sort();
                    191: }
                    192: 
                    193: static
                    194: sort()
                    195: {
                    196:        register char **p1, **p2, *c;
                    197:        char **Gvp = &gargv[gargc];
                    198: 
                    199:        p1 = sortbas;
                    200:        while (p1 < Gvp-1) {
                    201:                p2 = p1;
                    202:                while (++p2 < Gvp)
                    203:                        if (strcmp(*p1, *p2) > 0)
                    204:                                c = *p1, *p1 = *p2, *p2 = c;
                    205:                p1++;
                    206:        }
                    207:        sortbas = Gvp;
                    208: }
                    209: 
                    210: static
                    211: expand(as)
                    212:        char *as;
                    213: {
                    214:        register char *cs;
                    215:        register char *sgpathp, *oldcs;
                    216:        struct stat stb;
                    217: 
                    218:        sgpathp = gpathp;
                    219:        cs = as;
                    220:        if (*cs == '~' && gpathp == gpath) {
                    221:                addpath('~');
                    222:                for (cs++; letter(*cs) || digit(*cs) || *cs == '-';)
                    223:                        addpath(*cs++);
                    224:                if (!*cs || *cs == '/') {
                    225:                        if (gpathp != gpath + 1) {
                    226:                                *gpathp = 0;
                    227:                                if (gethdir(gpath + 1))
                    228:                                        globerr = "Unknown user name after ~";
                    229:                                strcpy(gpath, gpath + 1);
                    230:                        } else
                    231:                                strcpy(gpath, home);
                    232:                        gpathp = strend(gpath);
                    233:                }
                    234:        }
                    235:        while (!any(*cs, globchars)) {
                    236:                if (*cs == 0) {
                    237:                        if (!globbed)
                    238:                                Gcat(gpath, "");
                    239:                        else if (stat(gpath, &stb) >= 0) {
                    240:                                Gcat(gpath, "");
                    241:                                globcnt++;
                    242:                        }
                    243:                        goto endit;
                    244:                }
                    245:                addpath(*cs++);
                    246:        }
                    247:        oldcs = cs;
                    248:        while (cs > as && *cs != '/')
                    249:                cs--, gpathp--;
                    250:        if (*cs == '/')
                    251:                cs++, gpathp++;
                    252:        *gpathp = 0;
                    253:        if (*oldcs == '{') {
                    254:                execbrc(cs, ((char *)0));
                    255:                return;
                    256:        }
                    257:        matchdir(cs);
                    258: endit:
                    259:        gpathp = sgpathp;
                    260:        *gpathp = 0;
                    261: }
                    262: 
                    263: static
                    264: matchdir(pattern)
                    265:        char *pattern;
                    266: {
                    267:        struct stat stb;
                    268:        register struct direct *dp;
                    269:        DIR *dirp;
                    270:        register int cnt;
                    271: 
                    272:        dirp = opendir(gpath);
                    273:        if (dirp == NULL) {
                    274:                if (globbed)
                    275:                        return;
                    276:                goto patherr2;
                    277:        }
                    278:        if (fstat(dirp->dd_fd, &stb) < 0)
                    279:                goto patherr1;
                    280:        if (!isdir(stb)) {
                    281:                errno = ENOTDIR;
                    282:                goto patherr1;
                    283:        }
                    284:        while ((dp = readdir(dirp)) != NULL) {
                    285:                if (dp->d_ino == 0)
                    286:                        continue;
                    287:                if (match(dp->d_name, pattern)) {
                    288:                        Gcat(gpath, dp->d_name);
                    289:                        globcnt++;
                    290:                }
                    291:        }
                    292:        closedir(dirp);
                    293:        return;
                    294: 
                    295: patherr1:
                    296:        closedir(dirp);
                    297: patherr2:
                    298:        globerr = "Bad directory components";
                    299: }
                    300: 
                    301: static
                    302: execbrc(p, s)
                    303:        char *p, *s;
                    304: {
                    305:        char restbuf[BUFSIZ + 2];
                    306:        register char *pe, *pm, *pl;
                    307:        int brclev = 0;
                    308:        char *lm, savec, *sgpathp;
                    309: 
                    310:        for (lm = restbuf; *p != '{'; *lm++ = *p++)
                    311:                continue;
                    312:        for (pe = ++p; *pe; pe++)
                    313:        switch (*pe) {
                    314: 
                    315:        case '{':
                    316:                brclev++;
                    317:                continue;
                    318: 
                    319:        case '}':
                    320:                if (brclev == 0)
                    321:                        goto pend;
                    322:                brclev--;
                    323:                continue;
                    324: 
                    325:        case '[':
                    326:                for (pe++; *pe && *pe != ']'; pe++)
                    327:                        continue;
                    328:                continue;
                    329:        }
                    330: pend:
                    331:        brclev = 0;
                    332:        for (pl = pm = p; pm <= pe; pm++)
                    333:        switch (*pm & (QUOTE|TRIM)) {
                    334: 
                    335:        case '{':
                    336:                brclev++;
                    337:                continue;
                    338: 
                    339:        case '}':
                    340:                if (brclev) {
                    341:                        brclev--;
                    342:                        continue;
                    343:                }
                    344:                goto doit;
                    345: 
                    346:        case ','|QUOTE:
                    347:        case ',':
                    348:                if (brclev)
                    349:                        continue;
                    350: doit:
                    351:                savec = *pm;
                    352:                *pm = 0;
                    353:                strcpy(lm, pl);
                    354:                strcat(restbuf, pe + 1);
                    355:                *pm = savec;
                    356:                if (s == 0) {
                    357:                        sgpathp = gpathp;
                    358:                        expand(restbuf);
                    359:                        gpathp = sgpathp;
                    360:                        *gpathp = 0;
                    361:                } else if (amatch(s, restbuf))
                    362:                        return (1);
                    363:                sort();
                    364:                pl = pm + 1;
                    365:                if (brclev)
                    366:                        return (0);
                    367:                continue;
                    368: 
                    369:        case '[':
                    370:                for (pm++; *pm && *pm != ']'; pm++)
                    371:                        continue;
                    372:                if (!*pm)
                    373:                        pm--;
                    374:                continue;
                    375:        }
                    376:        if (brclev)
                    377:                goto doit;
                    378:        return (0);
                    379: }
                    380: 
                    381: static
                    382: match(s, p)
                    383:        char *s, *p;
                    384: {
                    385:        register int c;
                    386:        register char *sentp;
                    387:        char sglobbed = globbed;
                    388: 
                    389:        if (*s == '.' && *p != '.')
                    390:                return (0);
                    391:        sentp = entp;
                    392:        entp = s;
                    393:        c = amatch(s, p);
                    394:        entp = sentp;
                    395:        globbed = sglobbed;
                    396:        return (c);
                    397: }
                    398: 
                    399: static
                    400: amatch(s, p)
                    401:        register char *s, *p;
                    402: {
                    403:        register int scc;
                    404:        int ok, lc;
                    405:        char *sgpathp;
                    406:        struct stat stb;
                    407:        int c, cc;
                    408: 
                    409:        globbed = 1;
                    410:        for (;;) {
                    411:                scc = *s++ & TRIM;
                    412:                switch (c = *p++) {
                    413: 
                    414:                case '{':
                    415:                        return (execbrc(p - 1, s - 1));
                    416: 
                    417:                case '[':
                    418:                        ok = 0;
                    419:                        lc = 077777;
                    420:                        while (cc = *p++) {
                    421:                                if (cc == ']') {
                    422:                                        if (ok)
                    423:                                                break;
                    424:                                        return (0);
                    425:                                }
                    426:                                if (cc == '-') {
                    427:                                        if (lc <= scc && scc <= *p++)
                    428:                                                ok++;
                    429:                                } else
                    430:                                        if (scc == (lc = cc))
                    431:                                                ok++;
                    432:                        }
                    433:                        if (cc == 0)
                    434:                                if (ok)
                    435:                                        p--;
                    436:                                else
                    437:                                        return 0;
                    438:                        continue;
                    439: 
                    440:                case '*':
                    441:                        if (!*p)
                    442:                                return (1);
                    443:                        if (*p == '/') {
                    444:                                p++;
                    445:                                goto slash;
                    446:                        }
                    447:                        s--;
                    448:                        do {
                    449:                                if (amatch(s, p))
                    450:                                        return (1);
                    451:                        } while (*s++);
                    452:                        return (0);
                    453: 
                    454:                case 0:
                    455:                        return (scc == 0);
                    456: 
                    457:                default:
                    458:                        if (c != scc)
                    459:                                return (0);
                    460:                        continue;
                    461: 
                    462:                case '?':
                    463:                        if (scc == 0)
                    464:                                return (0);
                    465:                        continue;
                    466: 
                    467:                case '/':
                    468:                        if (scc)
                    469:                                return (0);
                    470: slash:
                    471:                        s = entp;
                    472:                        sgpathp = gpathp;
                    473:                        while (*s)
                    474:                                addpath(*s++);
                    475:                        addpath('/');
                    476:                        if (stat(gpath, &stb) == 0 && isdir(stb))
                    477:                                if (*p == 0) {
                    478:                                        Gcat(gpath, "");
                    479:                                        globcnt++;
                    480:                                } else
                    481:                                        expand(p);
                    482:                        gpathp = sgpathp;
                    483:                        *gpathp = 0;
                    484:                        return (0);
                    485:                }
                    486:        }
                    487: }
                    488: 
                    489: static
                    490: Gmatch(s, p)
                    491:        register char *s, *p;
                    492: {
                    493:        register int scc;
                    494:        int ok, lc;
                    495:        int c, cc;
                    496: 
                    497:        for (;;) {
                    498:                scc = *s++ & TRIM;
                    499:                switch (c = *p++) {
                    500: 
                    501:                case '[':
                    502:                        ok = 0;
                    503:                        lc = 077777;
                    504:                        while (cc = *p++) {
                    505:                                if (cc == ']') {
                    506:                                        if (ok)
                    507:                                                break;
                    508:                                        return (0);
                    509:                                }
                    510:                                if (cc == '-') {
                    511:                                        if (lc <= scc && scc <= *p++)
                    512:                                                ok++;
                    513:                                } else
                    514:                                        if (scc == (lc = cc))
                    515:                                                ok++;
                    516:                        }
                    517:                        if (cc == 0)
                    518:                                if (ok)
                    519:                                        p--;
                    520:                                else
                    521:                                        return 0;
                    522:                        continue;
                    523: 
                    524:                case '*':
                    525:                        if (!*p)
                    526:                                return (1);
                    527:                        for (s--; *s; s++)
                    528:                                if (Gmatch(s, p))
                    529:                                        return (1);
                    530:                        return (0);
                    531: 
                    532:                case 0:
                    533:                        return (scc == 0);
                    534: 
                    535:                default:
                    536:                        if ((c & TRIM) != scc)
                    537:                                return (0);
                    538:                        continue;
                    539: 
                    540:                case '?':
                    541:                        if (scc == 0)
                    542:                                return (0);
                    543:                        continue;
                    544: 
                    545:                }
                    546:        }
                    547: }
                    548: 
                    549: static
                    550: Gcat(s1, s2)
                    551:        register char *s1, *s2;
                    552: {
                    553:        register int len = strlen(s1) + strlen(s2) + 1;
                    554: 
                    555:        if (len >= gnleft || gargc >= GAVSIZ - 1)
                    556:                globerr = "Arguments too long";
                    557:        else {
                    558:                gargc++;
                    559:                gnleft -= len;
                    560:                gargv[gargc] = 0;
                    561:                gargv[gargc - 1] = strspl(s1, s2);
                    562:        }
                    563: }
                    564: 
                    565: static
                    566: addpath(c)
                    567:        char c;
                    568: {
                    569: 
                    570:        if (gpathp >= lastgpathp)
                    571:                globerr = "Pathname too long";
                    572:        else {
                    573:                *gpathp++ = c;
                    574:                *gpathp = 0;
                    575:        }
                    576: }
                    577: 
                    578: static
                    579: rscan(t, f)
                    580:        register char **t;
                    581:        int (*f)();
                    582: {
                    583:        register char *p, c;
                    584: 
                    585:        while (p = *t++) {
                    586:                if (f == tglob)
                    587:                        if (*p == '~')
                    588:                                gflag |= 2;
                    589:                        else if (eq(p, "{") || eq(p, "{}"))
                    590:                                continue;
                    591:                while (c = *p++)
                    592:                        (*f)(c);
                    593:        }
                    594: }
                    595: 
                    596: static
                    597: scan(t, f)
                    598:        register char **t;
                    599:        int (*f)();
                    600: {
                    601:        register char *p, c;
                    602: 
                    603:        while (p = *t++)
                    604:                while (c = *p)
                    605:                        *p++ = (*f)(c);
                    606: }
                    607: 
                    608: static
                    609: tglob(c)
                    610:        register char c;
                    611: {
                    612: 
                    613:        if (any(c, globchars))
                    614:                gflag |= c == '{' ? 2 : 1;
                    615:        return (c);
                    616: }
                    617: 
                    618: static
                    619: trim(c)
                    620:        char c;
                    621: {
                    622: 
                    623:        return (c & TRIM);
                    624: }
                    625: 
                    626: 
                    627: letter(c)
                    628:        register char c;
                    629: {
                    630: 
                    631:        return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_');
                    632: }
                    633: 
                    634: digit(c)
                    635:        register char c;
                    636: {
                    637: 
                    638:        return (c >= '0' && c <= '9');
                    639: }
                    640: 
                    641: any(c, s)
                    642:        register int c;
                    643:        register char *s;
                    644: {
                    645: 
                    646:        while (*s)
                    647:                if (*s++ == c)
                    648:                        return(1);
                    649:        return(0);
                    650: }
                    651: blklen(av)
                    652:        register char **av;
                    653: {
                    654:        register int i = 0;
                    655: 
                    656:        while (*av++)
                    657:                i++;
                    658:        return (i);
                    659: }
                    660: 
                    661: char **
                    662: blkcpy(oav, bv)
                    663:        char **oav;
                    664:        register char **bv;
                    665: {
                    666:        register char **av = oav;
                    667: 
                    668:        while (*av++ = *bv++)
                    669:                continue;
                    670:        return (oav);
                    671: }
                    672: 
                    673: blkfree(av0)
                    674:        char **av0;
                    675: {
                    676:        register char **av = av0;
                    677: 
                    678:        while (*av)
                    679:                free(*av++);
                    680:        free((char *)av0);
                    681: }
                    682: 
                    683: static
                    684: char *
                    685: strspl(cp, dp)
                    686:        register char *cp, *dp;
                    687: {
                    688:        register char *ep = malloc((unsigned)(strlen(cp) + strlen(dp) + 1));
                    689: 
                    690:        if (ep == (char *)0)
                    691:                fatal("Out of memory");
                    692:        strcpy(ep, cp);
                    693:        strcat(ep, dp);
                    694:        return (ep);
                    695: }
                    696: 
                    697: static
                    698: char **
                    699: copyblk(v)
                    700:        register char **v;
                    701: {
                    702:        register char **nv = (char **)malloc((unsigned)((blklen(v) + 1) *
                    703:                                                sizeof(char **)));
                    704:        if (nv == (char **)0)
                    705:                fatal("Out of memory");
                    706: 
                    707:        return (blkcpy(nv, v));
                    708: }
                    709: 
                    710: static
                    711: char *
                    712: strend(cp)
                    713:        register char *cp;
                    714: {
                    715: 
                    716:        while (*cp)
                    717:                cp++;
                    718:        return (cp);
                    719: }
                    720: /*
                    721:  * Extract a home directory from the password file
                    722:  * The argument points to a buffer where the name of the
                    723:  * user whose home directory is sought is currently.
                    724:  * We write the home directory of the user back there.
                    725:  */
                    726: gethdir(home)
                    727:        char *home;
                    728: {
                    729:        register struct passwd *pp = getpwnam(home);
                    730: 
                    731:        if (pp == 0)
                    732:                return (1);
                    733:        strcpy(home, pp->pw_dir);
                    734:        return (0);
                    735: }
                    736: 
                    737: char version[] = "Version 4.7 Mon Sep 23 21:57:45 EDT 1985";

unix.superglobalmegacorp.com

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