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

1.1       root        1: /*     @(#)service.c   1.11    */
                      2: /*
                      3:  * UNIX shell
                      4:  *
                      5:  * Bell Telephone Laboratories
                      6:  *
                      7:  */
                      8: 
                      9: #include       "defs.h"
                     10: #include       <errno.h>
                     11: 
                     12: #define ARGMK  01
                     13: 
                     14: extern int     gsort();
                     15: extern char    *sysmsg[];
                     16: extern short topfd;
                     17: 
                     18: 
                     19: 
                     20: /*
                     21:  * service routines for `execute'
                     22:  */
                     23: initio(iop, save)
                     24:        struct ionod    *iop;
                     25:        int             save;
                     26: {
                     27:        register char   *ion;
                     28:        register int    iof, fd;
                     29:        int             ioufd;
                     30:        short   lastfd;
                     31: 
                     32:        lastfd = topfd;
                     33:        while (iop)
                     34:        {
                     35:                iof = iop->iofile;
                     36:                ion = mactrim(iop->ioname);
                     37:                ioufd = iof & IOUFD;
                     38: 
                     39:                if (*ion && (flags&noexec) == 0)
                     40:                {
                     41:                        if (save)
                     42:                        {
                     43:                                fdmap[topfd].org_fd = ioufd;
                     44:                                fdmap[topfd++].dup_fd = savefd(ioufd);
                     45:                        }
                     46: 
                     47:                        if (iof & IODOC)
                     48:                        {
                     49:                                struct tempblk tb;
                     50: 
                     51:                                subst(chkopen(ion), (fd = tmpfil(&tb)));
                     52: 
                     53:                                poptemp();      /* pushed in tmpfil() --
                     54:                                                   bug fix for problem with
                     55:                                                   in-line scripts
                     56:                                                */
                     57: 
                     58:                                fd = chkopen(tmpout);
                     59:                                unlink(tmpout);
                     60:                        }
                     61:                        else if (iof & IOMOV)
                     62:                        {
                     63:                                if (eq(minus, ion))
                     64:                                {
                     65:                                        fd = -1;
                     66:                                        close(ioufd);
                     67:                                }
                     68:                                else if ((fd = stoi(ion)) >= USERIO)
                     69:                                        failed(ion, badfile);
                     70:                                else
                     71:                                        fd = dup(fd);
                     72:                        }
                     73:                        else if ((iof & IOPUT) == 0)
                     74:                                fd = chkopen(ion);
                     75:                        else if (iof & IOAPP && (fd = open(ion, 1)) >= 0)
                     76:                                lseek(fd, 0L, 2);
                     77:                        else
                     78:                                fd = create(ion);
                     79:                        if (fd >= 0)
                     80:                                rename(fd, ioufd);
                     81:                }
                     82: 
                     83:                iop = iop->ionxt;
                     84:        }
                     85:        if (histfd > 0) {
                     86:                close (histfd);
                     87:                histfd = 0;
                     88:        }
                     89:        return(lastfd);
                     90: }
                     91: 
                     92: char *
                     93: simple(s)
                     94: char   *s;
                     95: {
                     96:        char    *sname;
                     97: 
                     98:        sname = s;
                     99:        while (1)
                    100:        {
                    101:                if (any('/', sname))
                    102:                        while (*sname++ != '/')
                    103:                                ;
                    104:                else
                    105:                        return(sname);
                    106:        }
                    107: }
                    108: 
                    109: char *
                    110: getpath(s)
                    111:        char    *s;
                    112: {
                    113:        register char   *path;
                    114: 
                    115:        if (any('/', s) || any(('/' | QUOTE), s))
                    116:        {
                    117:                return(nullstr);
                    118:        }
                    119:        else if ((path = pathnod.namval.val) == 0)
                    120:                return(defpath);
                    121:        else
                    122:                return(cpystak(path));
                    123: }
                    124: 
                    125: pathopen(path, name)
                    126: register char *path, *name;
                    127: {
                    128:        register int    f;
                    129: 
                    130:        do
                    131:        {
                    132:                path = catpath(path, name);
                    133:        } while ((f = open(curstak(), 0)) < 0 && path);
                    134:        return(f);
                    135: }
                    136: 
                    137: char *
                    138: catpath(path, name)
                    139: register char  *path;
                    140: char   *name;
                    141: {
                    142:        /*
                    143:         * leaves result on top of stack
                    144:         */
                    145:        register char   *scanp = path;
                    146:        register char   *argp = locstak();
                    147: 
                    148:        while (*scanp && *scanp != COLON)
                    149:                *argp++ = *scanp++;
                    150:        if (scanp != path)
                    151:                *argp++ = '/';
                    152:        if (*scanp == COLON)
                    153:                scanp++;
                    154:        path = (*scanp ? scanp : 0);
                    155:        scanp = name;
                    156:        while ((*argp++ = *scanp++))
                    157:                ;
                    158:        return(path);
                    159: }
                    160: 
                    161: char *
                    162: nextpath(path)
                    163:        register char   *path;
                    164: {
                    165:        register char   *scanp = path;
                    166: 
                    167:        while (*scanp && *scanp != COLON)
                    168:                scanp++;
                    169: 
                    170:        if (*scanp == COLON)
                    171:                scanp++;
                    172: 
                    173:        return(*scanp ? scanp : 0);
                    174: }
                    175: 
                    176: static char    *xecmsg;
                    177: static char    **xecenv;
                    178: 
                    179: int    execa(at)
                    180:        char    *at[];
                    181: {
                    182:        register char   *path;
                    183:        register char   **t = at;
                    184:        int             cnt;
                    185: 
                    186:        if ((flags & noexec) == 0)
                    187:        {
                    188:                xecmsg = notfound;
                    189:                path = getpath(*t);
                    190:                xecenv = setenv();
                    191: 
                    192:                while (path = execs(path,t))
                    193:                        ;
                    194:                failed(*t, xecmsg);
                    195:        }
                    196: }
                    197: 
                    198: static char *
                    199: execs(ap, t)
                    200: char   *ap;
                    201: register char  *t[];
                    202: {
                    203:        register char *p, *prefix;
                    204: 
                    205:        prefix = catpath(ap, t[0]);
                    206:        trim(p = curstak());
                    207:        sigchk();
                    208:        
                    209:        execve(p, &t[0] ,xecenv);
                    210:        switch (errno)
                    211:        {
                    212:        case ENOEXEC:           /* could be a shell script */
                    213:                funcnt = 0;
                    214:                flags = 0;
                    215:                *flagadr = 0;
                    216:                comdiv = 0;
                    217:                ioset = 0;
                    218:                clearup();      /* remove open files and for loop junk */
                    219:                if (input)
                    220:                        close(input);
                    221:                input = chkopen(p);
                    222:        
                    223: #ifdef ACCT
                    224:                preacct(p);     /* reset accounting */
                    225: #endif
                    226: 
                    227:                /*
                    228:                 * set up new args
                    229:                 */
                    230:                
                    231:                setargs(t);
                    232:                longjmp(subshell, 1);
                    233: 
                    234:        case ENOMEM:
                    235:                failed(p, toobig);
                    236: 
                    237:        case E2BIG:
                    238:                failed(p, arglist);
                    239: 
                    240:        case ETXTBSY:
                    241:                failed(p, txtbsy);
                    242: 
                    243:        default:
                    244:                xecmsg = badexec;
                    245:        case ENOENT:
                    246:                return(prefix);
                    247:        }
                    248: }
                    249: 
                    250: 
                    251: /*
                    252:  * for processes to be waited for
                    253:  */
                    254: #define MAXP 20
                    255: static int     pwlist[MAXP];
                    256: static int     pwc;
                    257: 
                    258: postclr()
                    259: {
                    260:        register int    *pw = pwlist;
                    261: 
                    262:        while (pw <= &pwlist[pwc])
                    263:                *pw++ = 0;
                    264:        pwc = 0;
                    265: }
                    266: 
                    267: post(pcsid)
                    268: int    pcsid;
                    269: {
                    270:        register int    *pw = pwlist;
                    271: 
                    272:        if (pcsid)
                    273:        {
                    274:                while (*pw)
                    275:                        pw++;
                    276:                if (pwc >= MAXP - 1)
                    277:                        pw--;
                    278:                else
                    279:                        pwc++;
                    280:                *pw = pcsid;
                    281:        }
                    282: }
                    283: 
                    284: await(i, bckg)
                    285: int    i, bckg;
                    286: {
                    287:        int     rc = 0, wx = 0;
                    288:        int     w;
                    289:        int     ipwc = pwc;
                    290: 
                    291:        post(i);
                    292:        while (pwc)
                    293:        {
                    294:                register int    p;
                    295:                register int    sig;
                    296:                int             w_hi;
                    297:                int     found = 0;
                    298: 
                    299:                {
                    300:                        register int    *pw = pwlist;
                    301: 
                    302:                        p = wait(&w);
                    303:                        if (wasintr)
                    304:                        {
                    305:                                wasintr = 0;
                    306:                                if (bckg)
                    307:                                {
                    308:                                        break;
                    309:                                }
                    310:                        }
                    311:                        while (pw <= &pwlist[ipwc])
                    312:                        {
                    313:                                if (*pw == p)
                    314:                                {
                    315:                                        *pw = 0;
                    316:                                        pwc--;
                    317:                                        found++;
                    318:                                }
                    319:                                else
                    320:                                        pw++;
                    321:                        }
                    322:                }
                    323:                if (p == -1)
                    324:                {
                    325:                        if (bckg)
                    326:                        {
                    327:                                register int *pw = pwlist;
                    328: 
                    329:                                while (pw <= &pwlist[ipwc] && i != *pw)
                    330:                                        pw++;
                    331:                                if (i == *pw)
                    332:                                {
                    333:                                        *pw = 0;
                    334:                                        pwc--;
                    335:                                }
                    336:                        }
                    337:                        continue;
                    338:                }
                    339:                w_hi = (w >> 8) & LOBYTE;
                    340:                if (sig = w & 0177)
                    341:                {
                    342:                        if (sig == 0177)        /* ptrace! return */
                    343:                        {
                    344:                                prs("ptrace: ");
                    345:                                sig = w_hi;
                    346:                        }
                    347:                        if (sysmsg[sig])
                    348:                        {
                    349:                                if (i != p || (flags & prompt) == 0)
                    350:                                {
                    351:                                        prp();
                    352:                                        prn(p);
                    353:                                        blank();
                    354:                                }
                    355:                                prs(sysmsg[sig]);
                    356:                                if (w & 0200)
                    357:                                        prs(coredump);
                    358:                        }
                    359:                        newline();
                    360:                }
                    361:                if (rc == 0 && found != 0)
                    362:                        rc = (sig ? sig | SIGFLG : w_hi);
                    363:                wx |= w;
                    364:                if (p == i)
                    365:                {
                    366:                        break;
                    367:                }
                    368:        }
                    369:        if (wx && flags & errflg)
                    370:                exitsh(rc);
                    371:        flags |= eflag;
                    372:        exitval = rc;
                    373:        exitset();
                    374: }
                    375: 
                    376: BOOL           nosubst;
                    377: 
                    378: trim(at)
                    379: char   *at;
                    380: {
                    381:        register char   *p;
                    382:        register char   *ptr;
                    383:        register char   c;
                    384:        register char   q = 0;
                    385: 
                    386:        if (p = at)
                    387:        {
                    388:                ptr = p;
                    389:                while (c = *p++)
                    390:                {
                    391:                        if (*ptr = c & STRIP)
                    392:                                ++ptr;
                    393:                        q |= c;
                    394:                }
                    395: 
                    396:                *ptr = 0;
                    397:        }
                    398:        nosubst = q & QUOTE;
                    399: }
                    400: 
                    401: char *
                    402: mactrim(s)
                    403: char   *s;
                    404: {
                    405:        register char   *t = macro(s);
                    406: 
                    407:        trim(t);
                    408:        return(t);
                    409: }
                    410: 
                    411: char **
                    412: scan(argn)
                    413: int    argn;
                    414: {
                    415:        register struct argnod *argp = (struct argnod *)(Rcheat(gchain) & ~ARGMK);
                    416:        register char **comargn, **comargm;
                    417: 
                    418:        comargn = (char **)getstak(BYTESPERWORD * argn + BYTESPERWORD);
                    419:        comargm = comargn += argn;
                    420:        *comargn = ENDARGS;
                    421:        while (argp)
                    422:        {
                    423:                *--comargn = argp->argval;
                    424: 
                    425:                trim(*comargn);
                    426:                argp = argp->argnxt;
                    427: 
                    428:                if (argp == 0 || Rcheat(argp) & ARGMK)
                    429:                {
                    430:                        gsort(comargn, comargm);
                    431:                        comargm = comargn;
                    432:                }
                    433:                /* Lcheat(argp) &= ~ARGMK; */
                    434:                argp = (struct argnod *)(Rcheat(argp) & ~ARGMK);
                    435:        }
                    436:        return(comargn);
                    437: }
                    438: 
                    439: static int
                    440: gsort(from, to)
                    441: char   *from[], *to[];
                    442: {
                    443:        int     k, m, n;
                    444:        register int    i, j;
                    445: 
                    446:        if ((n = to - from) <= 1)
                    447:                return;
                    448:        for (j = 1; j <= n; j *= 2)
                    449:                ;
                    450:        for (m = 2 * j - 1; m /= 2; )
                    451:        {
                    452:                k = n - m;
                    453:                for (j = 0; j < k; j++)
                    454:                {
                    455:                        for (i = j; i >= 0; i -= m)
                    456:                        {
                    457:                                register char **fromi;
                    458: 
                    459:                                fromi = &from[i];
                    460:                                if (cf(fromi[m], fromi[0]) > 0)
                    461:                                {
                    462:                                        break;
                    463:                                }
                    464:                                else
                    465:                                {
                    466:                                        char *s;
                    467: 
                    468:                                        s = fromi[m];
                    469:                                        fromi[m] = fromi[0];
                    470:                                        fromi[0] = s;
                    471:                                }
                    472:                        }
                    473:                }
                    474:        }
                    475: }
                    476: 
                    477: /*
                    478:  * Argument list generation
                    479:  */
                    480: getarg(ac)
                    481: struct comnod  *ac;
                    482: {
                    483:        register struct argnod  *argp;
                    484:        register int            count = 0;
                    485:        register struct comnod  *c;
                    486: 
                    487:        if (c = ac)
                    488:        {
                    489:                argp = c->comarg;
                    490:                while (argp)
                    491:                {
                    492:                        count += split(macro(argp->argval));
                    493:                        argp = argp->argnxt;
                    494:                }
                    495:        }
                    496:        return(count);
                    497: }
                    498: 
                    499: static int
                    500: split(s)               /* blank interpretation routine */
                    501: register char  *s;
                    502: {
                    503:        register char   *argp;
                    504:        register int    c;
                    505:        int             count = 0;
                    506: 
                    507:        for (;;)
                    508:        {
                    509:                sigchk();
                    510:                argp = locstak() + BYTESPERWORD;
                    511:                while ((c = *s++, !any(c, ifsnod.namval.val) && c))
                    512:                        *argp++ = c;
                    513:                if (argp == staktop + BYTESPERWORD)
                    514:                {
                    515:                        if (c)
                    516:                        {
                    517:                                continue;
                    518:                        }
                    519:                        else
                    520:                        {
                    521:                                return(count);
                    522:                        }
                    523:                }
                    524:                else if (c == 0)
                    525:                        s--;
                    526:                /*
                    527:                 * file name generation
                    528:                 */
                    529: 
                    530:                argp = endstak(argp);
                    531: 
                    532:                if ((flags & nofngflg) == 0 && 
                    533:                        (c = expand(((struct argnod *)argp)->argval, 0)))
                    534:                        count += c;
                    535:                else
                    536:                {
                    537:                        makearg(argp);
                    538:                        count++;
                    539:                }
                    540:                gchain = (struct argnod *)((int)gchain | ARGMK);
                    541:        }
                    542: }
                    543: 
                    544: #ifdef ACCT
                    545: #include       <sys/types.h>
                    546: #include       "acctdef.h"
                    547: #include       <sys/acct.h>
                    548: #include       <sys/times.h>
                    549: 
                    550: struct acct sabuf;
                    551: struct tms buffer;
                    552: extern long times();
                    553: static long before;
                    554: static int shaccton;   /* 0 implies do not write record on exit
                    555:                           1 implies write acct record on exit
                    556:                        */
                    557: 
                    558: 
                    559: /*
                    560:  *     suspend accounting until turned on by preacct()
                    561:  */
                    562: 
                    563: suspacct()
                    564: {
                    565:        shaccton = 0;
                    566: }
                    567: 
                    568: preacct(cmdadr)
                    569:        char *cmdadr;
                    570: {
                    571:        char *simple();
                    572: 
                    573:        if (acctnod.namval.val && *acctnod.namval.val)
                    574:        {
                    575:                sabuf.ac_btime = time((long *)0);
                    576:                before = times(&buffer);
                    577:                sabuf.ac_uid = getuid();
                    578:                sabuf.ac_gid = getgid();
                    579:                movstrn(simple(cmdadr), sabuf.ac_comm, sizeof(sabuf.ac_comm));
                    580:                shaccton = 1;
                    581:        }
                    582: }
                    583: 
                    584: #include       <fcntl.h>
                    585: 
                    586: doacct()
                    587: {
                    588:        int fd;
                    589:        long int after;
                    590: 
                    591:        if (shaccton)
                    592:        {
                    593:                after = times(&buffer);
                    594:                sabuf.ac_utime = compress(buffer.tms_utime + buffer.tms_cutime);
                    595:                sabuf.ac_stime = compress(buffer.tms_stime + buffer.tms_cstime);
                    596:                sabuf.ac_etime = compress(after - before);
                    597: 
                    598:                if ((fd = open(acctnod.namval.val, O_WRONLY | O_APPEND | O_CREAT, 0666)) != -1)
                    599:                {
                    600:                        write(fd, &sabuf, sizeof(sabuf));
                    601:                        close(fd);
                    602:                }
                    603:        }
                    604: }
                    605: 
                    606: /*
                    607:  *     Produce a pseudo-floating point representation
                    608:  *     with 3 bits base-8 exponent, 13 bits fraction
                    609:  */
                    610: 
                    611: compress(t)
                    612:        register time_t t;
                    613: {
                    614:        register exp = 0;
                    615:        register rund = 0;
                    616: 
                    617:        while (t >= 8192)
                    618:        {
                    619:                exp++;
                    620:                rund = t & 04;
                    621:                t >>= 3;
                    622:        }
                    623: 
                    624:        if (rund)
                    625:        {
                    626:                t++;
                    627:                if (t >= 8192)
                    628:                {
                    629:                        t >>= 3;
                    630:                        exp++;
                    631:                }
                    632:        }
                    633: 
                    634:        return((exp << 13) + t);
                    635: }
                    636: #endif

unix.superglobalmegacorp.com

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