Annotation of 42BSD/usr.bin/tip/cmds.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)cmds.c     4.12 (Berkeley) 6/25/83";
                      3: #endif
                      4: 
                      5: #include "tip.h"
                      6: /*
                      7:  * tip
                      8:  *
                      9:  * miscellaneous commands
                     10:  */
                     11: 
                     12: int    quant[] = { 60, 60, 24 };
                     13: 
                     14: char   null = '\0';
                     15: char   *sep[] = { "second", "minute", "hour" };
                     16: static char *argv[10];         /* argument vector for take and put */
                     17: 
                     18: int    timeout();              /* timeout function called on alarm */
                     19: int    stopsnd();              /* SIGINT handler during file transfers */
                     20: int    intprompt();            /* used in handling SIG_INT during prompt */
                     21: int    intcopy();              /* interrupt routine for file transfers */
                     22: 
                     23: /*
                     24:  * FTP - remote ==> local
                     25:  *  get a file from the remote host
                     26:  */
                     27: getfl(c)
                     28:        char c;
                     29: {
                     30:        char buf[256], *cp, *expand();
                     31:        
                     32:        putchar(c);
                     33:        /*
                     34:         * get the UNIX receiving file's name
                     35:         */
                     36:        if (prompt("Local file name? ", copyname))
                     37:                return;
                     38:        cp = expand(copyname);
                     39:        if ((sfd = creat(cp, 0666)) < 0) {
                     40:                printf("\r\n%s: cannot creat\r\n", copyname);
                     41:                return;
                     42:        }
                     43:        
                     44:        /*
                     45:         * collect parameters
                     46:         */
                     47:        if (prompt("List command for remote system? ", buf)) {
                     48:                unlink(copyname);
                     49:                return;
                     50:        }
                     51:        transfer(buf, sfd, value(EOFREAD));
                     52: }
                     53: 
                     54: /*
                     55:  * Cu-like take command
                     56:  */
                     57: cu_take(cc)
                     58:        char cc;
                     59: {
                     60:        int fd, argc;
                     61:        char line[BUFSIZ], *expand(), *cp;
                     62: 
                     63:        if (prompt("[take] ", copyname))
                     64:                return;
                     65:        if ((argc = args(copyname, argv)) < 1 || argc > 2) {
                     66:                printf("usage: <take> from [to]\r\n");
                     67:                return;
                     68:        }
                     69:        if (argc == 1)
                     70:                argv[1] = argv[0];
                     71:        cp = expand(argv[1]);
                     72:        if ((fd = creat(cp, 0666)) < 0) {
                     73:                printf("\r\n%s: cannot create\r\n", argv[1]);
                     74:                return;
                     75:        }
                     76:        sprintf(line, "cat %s;echo \01", argv[0]);
                     77:        transfer(line, fd, "\01");
                     78: }
                     79: 
                     80: static jmp_buf intbuf;
                     81: /*
                     82:  * Bulk transfer routine --
                     83:  *  used by getfl(), cu_take(), and pipefile()
                     84:  */
                     85: transfer(buf, fd, eofchars)
                     86:        char *buf, *eofchars;
                     87: {
                     88:        register int ct;
                     89:        char c, buffer[BUFSIZ];
                     90:        register char *p = buffer;
                     91:        register int cnt, eof;
                     92:        time_t start;
                     93:        int (*f)();
                     94: 
                     95:        pwrite(FD, buf, size(buf));
                     96:        quit = 0;
                     97:        kill(pid, SIGIOT);
                     98:        read(repdes[0], (char *)&ccc, 1);  /* Wait until read process stops */
                     99:        
                    100:        /*
                    101:         * finish command
                    102:         */
                    103:        pwrite(FD, "\r", 1);
                    104:        do
                    105:                read(FD, &c, 1); 
                    106:        while ((c&0177) != '\n');
                    107:        ioctl(0, TIOCSETC, &defchars);
                    108:        
                    109:        f = signal(SIGINT, intcopy);
                    110:        start = time(0);
                    111:        (void) setjmp(intbuf);
                    112:        for (ct = 0; !quit;) {
                    113:                eof = read(FD, &c, 1) <= 0;
                    114:                c &= 0177;
                    115:                if (quit)
                    116:                        continue;
                    117:                if (eof || any(c, eofchars))
                    118:                        break;
                    119:                if (c == 0)
                    120:                        continue;       /* ignore nulls */
                    121:                if (c == '\r')
                    122:                        continue;
                    123:                *p++ = c;
                    124: 
                    125:                if (c == '\n' && boolean(value(VERBOSE)))
                    126:                        printf("\r%d", ++ct);
                    127:                if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) {
                    128:                        if (write(fd, buffer, cnt) != cnt) {
                    129:                                printf("\r\nwrite error\r\n");
                    130:                                quit = 1;
                    131:                        }
                    132:                        p = buffer;
                    133:                }
                    134:        }
                    135:        if (cnt = (p-buffer))
                    136:                if (write(fd, buffer, cnt) != cnt)
                    137:                        printf("\r\nwrite error\r\n");
                    138: 
                    139:        if (boolean(value(VERBOSE)))
                    140:                prtime(" lines transferred in ", time(0)-start);
                    141:        ioctl(0, TIOCSETC, &tchars);
                    142:        write(fildes[1], (char *)&ccc, 1);
                    143:        signal(SIGINT, SIG_DFL);
                    144:        close(fd);
                    145: }
                    146: 
                    147: /*
                    148:  * FTP - remote ==> local process
                    149:  *   send remote input to local process via pipe
                    150:  */
                    151: pipefile()
                    152: {
                    153:        int cpid, pdes[2];
                    154:        char buf[256];
                    155:        int status, p;
                    156:        extern int errno;
                    157: 
                    158:        if (prompt("Local command? ", buf))
                    159:                return;
                    160: 
                    161:        if (pipe(pdes)) {
                    162:                printf("can't establish pipe\r\n");
                    163:                return;
                    164:        }
                    165: 
                    166:        if ((cpid = fork()) < 0) {
                    167:                printf("can't fork!\r\n");
                    168:                return;
                    169:        } else if (cpid) {
                    170:                if (prompt("List command for remote system? ", buf)) {
                    171:                        close(pdes[0]), close(pdes[1]);
                    172:                        kill (cpid, SIGKILL);
                    173:                } else {
                    174:                        close(pdes[0]);
                    175:                        signal(SIGPIPE, intcopy);
                    176:                        transfer(buf, pdes[1], value(EOFREAD));
                    177:                        signal(SIGPIPE, SIG_DFL);
                    178:                        while ((p = wait(&status)) > 0 && p != cpid)
                    179:                                ;
                    180:                }
                    181:        } else {
                    182:                register int f;
                    183: 
                    184:                dup2(pdes[0], 0);
                    185:                close(pdes[0]);
                    186:                for (f = 3; f < 20; f++)
                    187:                        close(f);
                    188:                execute(buf);
                    189:                printf("can't execl!\r\n");
                    190:                exit(0);
                    191:        }
                    192: }
                    193: 
                    194: /*
                    195:  * Interrupt service routine for FTP
                    196:  */
                    197: stopsnd()
                    198: {
                    199: 
                    200:        stop = 1;
                    201:        signal(SIGINT, SIG_IGN);
                    202: }
                    203: 
                    204: /*
                    205:  * FTP - local ==> remote
                    206:  *  send local file to remote host
                    207:  *  terminate transmission with pseudo EOF sequence
                    208:  */
                    209: sendfile(cc)
                    210:        char cc;
                    211: {
                    212:        FILE *fd;
                    213:        char *fnamex;
                    214:        char *expand();
                    215: 
                    216:        putchar(cc);
                    217:        /*
                    218:         * get file name
                    219:         */
                    220:        if (prompt("Local file name? ", fname))
                    221:                return;
                    222: 
                    223:        /*
                    224:         * look up file
                    225:         */
                    226:        fnamex = expand(fname);
                    227:        if ((fd = fopen(fnamex, "r")) == NULL) {
                    228:                printf("%s: cannot open\r\n", fname);
                    229:                return;
                    230:        }
                    231:        transmit(fd, value(EOFWRITE), NULL);
                    232:        if (!boolean(value(ECHOCHECK))) {
                    233:                struct sgttyb buf;
                    234: 
                    235:                ioctl(FD, TIOCGETP, &buf);      /* this does a */
                    236:                ioctl(FD, TIOCSETP, &buf);      /*   wflushtty */
                    237:        }
                    238: }
                    239: 
                    240: /*
                    241:  * Bulk transfer routine to remote host --
                    242:  *   used by sendfile() and cu_put()
                    243:  */
                    244: transmit(fd, eofchars, command)
                    245:        FILE *fd;
                    246:        char *eofchars, *command;
                    247: {
                    248:        char *pc, lastc;
                    249:        int c, ccount, lcount;
                    250:        time_t start_t, stop_t;
                    251: 
                    252:        kill(pid, SIGIOT);      /* put TIPOUT into a wait state */
                    253:        signal(SIGINT, stopsnd);
                    254:        stop = 0;
                    255:        ioctl(0, TIOCSETC, &defchars);
                    256:        read(repdes[0], (char *)&ccc, 1);
                    257:        if (command != NULL) {
                    258:                for (pc = command; *pc; pc++)
                    259:                        send(*pc);
                    260:                if (boolean(value(ECHOCHECK)))
                    261:                        read(FD, (char *)&c, 1);        /* trailing \n */
                    262:                else {
                    263:                        struct sgttyb buf;
                    264: 
                    265:                        ioctl(FD, TIOCGETP, &buf);      /* this does a */
                    266:                        ioctl(FD, TIOCSETP, &buf);      /*   wflushtty */
                    267:                        sleep(5); /* wait for remote stty to take effect */
                    268:                }
                    269:        }
                    270:        lcount = 0;
                    271:        lastc = '\0';
                    272:        start_t = time(0);
                    273:        while (1) {
                    274:                ccount = 0;
                    275:                do {
                    276:                        c = getc(fd);
                    277:                        if (stop)
                    278:                                goto out;
                    279:                        if (c == EOF)
                    280:                                goto out;
                    281:                        if (c == 0177 && !boolean(value(RAWFTP)))
                    282:                                continue;
                    283:                        lastc = c;
                    284:                        if (c < 040) {
                    285:                                if (c == '\n') {
                    286:                                        if (!boolean(value(RAWFTP)))
                    287:                                                c = '\r';
                    288:                                }
                    289:                                else if (c == '\t') {
                    290:                                        if (!boolean(value(RAWFTP))) {
                    291:                                                if (boolean(value(TABEXPAND))) {
                    292:                                                        send(' ');
                    293:                                                        while ((++ccount % 8) != 0)
                    294:                                                                send(' ');
                    295:                                                        continue;
                    296:                                                }
                    297:                                        }
                    298:                                } else
                    299:                                        if (!boolean(value(RAWFTP)))
                    300:                                                continue;
                    301:                        }
                    302:                        send(c);
                    303:                } while (c != '\r' && !boolean(value(RAWFTP)));
                    304:                if (boolean(value(VERBOSE)))
                    305:                        printf("\r%d", ++lcount);
                    306:                if (boolean(value(ECHOCHECK))) {
                    307:                        alarm(value(ETIMEOUT));
                    308:                        timedout = 0;
                    309:                        do {    /* wait for prompt */
                    310:                                read(FD, (char *)&c, 1);
                    311:                                if (timedout || stop) {
                    312:                                        if (timedout)
                    313:                                                printf("\r\ntimed out at eol\r\n");
                    314:                                        alarm(0);
                    315:                                        goto out;
                    316:                                }
                    317:                        } while ((c&0177) != character(value(PROMPT)));
                    318:                        alarm(0);
                    319:                }
                    320:        }
                    321: out:
                    322:        if (lastc != '\n' && !boolean(value(RAWFTP)))
                    323:                send('\r');
                    324:        for (pc = eofchars; *pc; pc++)
                    325:                send(*pc);
                    326:        stop_t = time(0);
                    327:        fclose(fd);
                    328:        signal(SIGINT, SIG_DFL);
                    329:        if (boolean(value(VERBOSE)))
                    330:                if (boolean(value(RAWFTP)))
                    331:                        prtime(" chars transferred in ", stop_t-start_t);
                    332:                else
                    333:                        prtime(" lines transferred in ", stop_t-start_t);
                    334:        write(fildes[1], (char *)&ccc, 1);
                    335:        ioctl(0, TIOCSETC, &tchars);
                    336: }
                    337: 
                    338: /*
                    339:  * Cu-like put command
                    340:  */
                    341: cu_put(cc)
                    342:        char cc;
                    343: {
                    344:        FILE *fd;
                    345:        char line[BUFSIZ];
                    346:        int argc;
                    347:        char *expand();
                    348:        char *copynamex;
                    349: 
                    350:        if (prompt("[put] ", copyname))
                    351:                return;
                    352:        if ((argc = args(copyname, argv)) < 1 || argc > 2) {
                    353:                printf("usage: <put> from [to]\r\n");
                    354:                return;
                    355:        }
                    356:        if (argc == 1)
                    357:                argv[1] = argv[0];
                    358:        copynamex = expand(argv[0]);
                    359:        if ((fd = fopen(copynamex, "r")) == NULL) {
                    360:                printf("%s: cannot open\r\n", copynamex);
                    361:                return;
                    362:        }
                    363:        if (boolean(value(ECHOCHECK)))
                    364:                sprintf(line, "cat>%s\r", argv[1]);
                    365:        else
                    366:                sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]);
                    367:        transmit(fd, "\04", line);
                    368: }
                    369: 
                    370: /*
                    371:  * FTP - send single character
                    372:  *  wait for echo & handle timeout
                    373:  */
                    374: send(c)
                    375:        char c;
                    376: {
                    377:        char cc;
                    378:        int retry = 0;
                    379: 
                    380:        cc = c;
                    381:        pwrite(FD, &cc, 1);
                    382: #ifdef notdef
                    383:        if (number(value(CDELAY)) > 0 && c != '\r')
                    384:                nap(number(value(CDELAY)));
                    385: #endif
                    386:        if (!boolean(value(ECHOCHECK))) {
                    387: #ifdef notdef
                    388:                if (number(value(LDELAY)) > 0 && c == '\r')
                    389:                        nap(number(value(LDELAY)));
                    390: #endif
                    391:                return;
                    392:        }
                    393: tryagain:
                    394:        timedout = 0;
                    395:        alarm(value(ETIMEOUT));
                    396:        read(FD, &cc, 1);
                    397:        alarm(0);
                    398:        if (timedout) {
                    399:                printf("\r\ntimeout error (%s)\r\n", ctrl(c));
                    400:                if (retry++ > 3)
                    401:                        return;
                    402:                pwrite(FD, &null, 1); /* poke it */
                    403:                goto tryagain;
                    404:        }
                    405: }
                    406: 
                    407: timeout()
                    408: {
                    409:        signal(SIGALRM, timeout);
                    410:        timedout = 1;
                    411: }
                    412: 
                    413: #ifdef CONNECT
                    414: /*
                    415:  * Fork a program with:
                    416:  *  0 <-> local tty in
                    417:  *  1 <-> local tty out
                    418:  *  2 <-> local tty out
                    419:  *  3 <-> remote tty in
                    420:  *  4 <-> remote tty out
                    421:  */
                    422: consh(c)
                    423: {
                    424:        char buf[256];
                    425:        int cpid, status, p;
                    426:        time_t start;
                    427: 
                    428:        putchar(c);
                    429:        if (prompt("Local command? ", buf))
                    430:                return;
                    431:        kill(pid, SIGIOT);      /* put TIPOUT into a wait state */
                    432:        signal(SIGINT, SIG_IGN);
                    433:        signal(SIGQUIT, SIG_IGN);
                    434:        ioctl(0, TIOCSETC, &defchars);
                    435:        read(repdes[0], (char *)&ccc, 1);
                    436:        /*
                    437:         * Set up file descriptors in the child and
                    438:         *  let it go...
                    439:         */
                    440:        if ((cpid = fork()) < 0)
                    441:                printf("can't fork!\r\n");
                    442:        else if (cpid) {
                    443:                start = time(0);
                    444:                while ((p = wait(&status)) > 0 && p != cpid)
                    445:                        ;
                    446:        } else {
                    447:                register int i;
                    448: 
                    449:                dup2(FD, 3);
                    450:                dup2(3, 4);
                    451:                for (i = 5; i < 20; i++)
                    452:                        close(i);
                    453:                signal(SIGINT, SIG_DFL);
                    454:                signal(SIGQUIT, SIG_DFL);
                    455:                execute(buf);
                    456:                printf("can't find `%s'\r\n", buf);
                    457:                exit(0);
                    458:        }
                    459:        if (boolean(value(VERBOSE)))
                    460:                prtime("away for ", time(0)-start);
                    461:        write(fildes[1], (char *)&ccc, 1);
                    462:        ioctl(0, TIOCSETC, &tchars);
                    463:        signal(SIGINT, SIG_DFL);
                    464:        signal(SIGQUIT, SIG_DFL);
                    465: }
                    466: #endif
                    467: 
                    468: /*
                    469:  * Escape to local shell
                    470:  */
                    471: shell()
                    472: {
                    473:        int shpid, status;
                    474:        extern char **environ;
                    475:        char *cp;
                    476: 
                    477:        printf("[sh]\r\n");
                    478:        signal(SIGINT, SIG_IGN);
                    479:        signal(SIGQUIT, SIG_IGN);
                    480:        unraw();
                    481:        if (shpid = fork()) {
                    482:                while (shpid != wait(&status));
                    483:                raw();
                    484:                printf("\r\n!\r\n");
                    485:                signal(SIGINT, SIG_DFL);
                    486:                signal(SIGQUIT, SIG_DFL);
                    487:                return;
                    488:        } else {
                    489:                signal(SIGQUIT, SIG_DFL);
                    490:                signal(SIGINT, SIG_DFL);
                    491:                if ((cp = rindex(value(SHELL), '/')) == NULL)
                    492:                        cp = value(SHELL);
                    493:                else
                    494:                        cp++;
                    495:                execl(value(SHELL), cp, 0);
                    496:                printf("\r\ncan't execl!\r\n");
                    497:                exit(1);
                    498:        }
                    499: }
                    500: 
                    501: /*
                    502:  * TIPIN portion of scripting
                    503:  *   initiate the conversation with TIPOUT
                    504:  */
                    505: setscript()
                    506: {
                    507:        char c;
                    508:        /*
                    509:         * enable TIPOUT side for dialogue
                    510:         */
                    511:        kill(pid, SIGEMT);
                    512:        if (boolean(value(SCRIPT)))
                    513:                write(fildes[1], value(RECORD), size(value(RECORD)));
                    514:        write(fildes[1], "\n", 1);
                    515:        /*
                    516:         * wait for TIPOUT to finish
                    517:         */
                    518:        read(repdes[0], &c, 1);
                    519:        if (c == 'n')
                    520:                printf("can't create %s\r\n", value(RECORD));
                    521: }
                    522: 
                    523: /*
                    524:  * Change current working directory of
                    525:  *   local portion of tip
                    526:  */
                    527: chdirectory()
                    528: {
                    529:        char dirname[80];
                    530:        register char *cp = dirname;
                    531: 
                    532:        if (prompt("[cd] ", dirname)) {
                    533:                if (stoprompt)
                    534:                        return;
                    535:                cp = value(HOME);
                    536:        }
                    537:        if (chdir(cp) < 0)
                    538:                printf("%s: bad directory\r\n", cp);
                    539:        printf("!\r\n");
                    540: }
                    541: 
                    542: finish()
                    543: {
                    544:        char *dismsg;
                    545: 
                    546:        if ((dismsg = value(DISCONNECT)) != NOSTR) {
                    547:                write(FD,dismsg,strlen(dismsg));
                    548:                sleep(5);
                    549:        }
                    550:        kill(pid, SIGTERM);
                    551:        disconnect();
                    552:        printf("\r\n[EOT]\r\n");
                    553:        delock(uucplock);
                    554:        unraw();
                    555:        exit(0);
                    556: }
                    557: 
                    558: intcopy()
                    559: {
                    560: 
                    561:        raw();
                    562:        quit = 1;
                    563:        longjmp(intbuf, 1);
                    564: }
                    565: 
                    566: execute(s)
                    567:        char *s;
                    568: {
                    569:        register char *cp;
                    570: 
                    571:        if ((cp = rindex(value(SHELL), '/')) == NULL)
                    572:                cp = value(SHELL);
                    573:        else
                    574:                cp++;
                    575:        execl(value(SHELL), cp, "-c", s, 0);
                    576: }
                    577: 
                    578: args(buf, a)
                    579:        char *buf, *a[];
                    580: {
                    581:        register char *p = buf, *start;
                    582:        register char **parg = a;
                    583:        register int n = 0;
                    584: 
                    585:        do {
                    586:                while (*p && (*p == ' ' || *p == '\t'))
                    587:                        p++;
                    588:                start = p;
                    589:                if (*p)
                    590:                        *parg = p;
                    591:                while (*p && (*p != ' ' && *p != '\t'))
                    592:                        p++;
                    593:                if (p != start)
                    594:                        parg++, n++;
                    595:                if (*p)
                    596:                        *p++ = '\0';
                    597:        } while (*p);
                    598: 
                    599:        return(n);
                    600: }
                    601: 
                    602: prtime(s, a)
                    603:        char *s;
                    604:        time_t a;
                    605: {
                    606:        register i;
                    607:        int nums[3];
                    608: 
                    609:        for (i = 0; i < 3; i++) {
                    610:                nums[i] = (int)(a % quant[i]);
                    611:                a /= quant[i];
                    612:        }
                    613:        printf("%s", s);
                    614:        while (--i >= 0)
                    615:                if (nums[i])
                    616:                        printf("%d %s%c ", nums[i], sep[i],
                    617:                                nums[i] == 1 ? '\0' : 's');
                    618:        printf("\r\n!\r\n");
                    619: }
                    620: 
                    621: variable()
                    622: {
                    623:        char    buf[256];
                    624: 
                    625:        if (prompt("[set] ", buf))
                    626:                return;
                    627:        vlex(buf);
                    628:        if (vtable[BEAUTIFY].v_access&CHANGED) {
                    629:                vtable[BEAUTIFY].v_access &= ~CHANGED;
                    630:                kill(pid, SIGSYS);
                    631:        }
                    632:        if (vtable[SCRIPT].v_access&CHANGED) {
                    633:                vtable[SCRIPT].v_access &= ~CHANGED;
                    634:                setscript();
                    635:                /*
                    636:                 * So that "set record=blah script" doesn't
                    637:                 *  cause two transactions to occur.
                    638:                 */
                    639:                if (vtable[RECORD].v_access&CHANGED)
                    640:                        vtable[RECORD].v_access &= ~CHANGED;
                    641:        }
                    642:        if (vtable[RECORD].v_access&CHANGED) {
                    643:                vtable[RECORD].v_access &= ~CHANGED;
                    644:                if (boolean(value(SCRIPT)))
                    645:                        setscript();
                    646:        }
                    647:        if (vtable[TAND].v_access&CHANGED) {
                    648:                vtable[TAND].v_access &= ~CHANGED;
                    649:                if (boolean(value(TAND)))
                    650:                        tandem("on");
                    651:                else
                    652:                        tandem("off");
                    653:        }
                    654:        if (vtable[LECHO].v_access&CHANGED) {
                    655:                vtable[LECHO].v_access &= ~CHANGED;
                    656:                HD = boolean(value(LECHO));
                    657:        }
                    658:        if (vtable[PARITY].v_access&CHANGED) {
                    659:                vtable[PARITY].v_access &= ~CHANGED;
                    660:                setparity();
                    661:        }
                    662: }
                    663: 
                    664: /*
                    665:  * Turn tandem mode on or off for remote tty.
                    666:  */
                    667: tandem(option)
                    668:        char *option;
                    669: {
                    670:        struct sgttyb rmtty;
                    671: 
                    672:        ioctl(FD, TIOCGETP, &rmtty);
                    673:        if (strcmp(option,"on") == 0) {
                    674:                rmtty.sg_flags |= TANDEM;
                    675:                arg.sg_flags |= TANDEM;
                    676:        } else {
                    677:                rmtty.sg_flags &= ~TANDEM;
                    678:                arg.sg_flags &= ~TANDEM;
                    679:        }
                    680:        ioctl(FD, TIOCSETP, &rmtty);
                    681:        ioctl(0,  TIOCSETP, &arg);
                    682: }
                    683: 
                    684: /*
                    685:  * Send a break.
                    686:  */
                    687: genbrk()
                    688: {
                    689: 
                    690:        ioctl(FD, TIOCSBRK, NULL);
                    691:        sleep(1);
                    692:        ioctl(FD, TIOCCBRK, NULL);
                    693: }
                    694: 
                    695: /*
                    696:  * Suspend tip
                    697:  */
                    698: suspend()
                    699: {
                    700: 
                    701:        unraw();
                    702:        kill(0, SIGTSTP);
                    703:        raw();
                    704: }
                    705: 
                    706: /*
                    707:  *     expand a file name if it includes shell meta characters
                    708:  */
                    709: 
                    710: char *
                    711: expand(name)
                    712:        char name[];
                    713: {
                    714:        static char xname[BUFSIZ];
                    715:        char cmdbuf[BUFSIZ];
                    716:        register int pid, l, rc;
                    717:        register char *cp, *Shell;
                    718:        int s, pivec[2], (*sigint)();
                    719: 
                    720:        if (!anyof(name, "~{[*?$`'\"\\"))
                    721:                return(name);
                    722:        /* sigint = signal(SIGINT, SIG_IGN); */
                    723:        if (pipe(pivec) < 0) {
                    724:                perror("pipe");
                    725:                /* signal(SIGINT, sigint) */
                    726:                return(name);
                    727:        }
                    728:        sprintf(cmdbuf, "echo %s", name);
                    729:        if ((pid = vfork()) == 0) {
                    730:                Shell = value(SHELL);
                    731:                if (Shell == NOSTR)
                    732:                        Shell = "/bin/sh";
                    733:                close(pivec[0]);
                    734:                close(1);
                    735:                dup(pivec[1]);
                    736:                close(pivec[1]);
                    737:                close(2);
                    738:                execl(Shell, Shell, "-c", cmdbuf, 0);
                    739:                _exit(1);
                    740:        }
                    741:        if (pid == -1) {
                    742:                perror("fork");
                    743:                close(pivec[0]);
                    744:                close(pivec[1]);
                    745:                return(NOSTR);
                    746:        }
                    747:        close(pivec[1]);
                    748:        l = read(pivec[0], xname, BUFSIZ);
                    749:        close(pivec[0]);
                    750:        while (wait(&s) != pid);
                    751:                ;
                    752:        s &= 0377;
                    753:        if (s != 0 && s != SIGPIPE) {
                    754:                fprintf(stderr, "\"Echo\" failed\n");
                    755:                return(NOSTR);
                    756:        }
                    757:        if (l < 0) {
                    758:                perror("read");
                    759:                return(NOSTR);
                    760:        }
                    761:        if (l == 0) {
                    762:                fprintf(stderr, "\"%s\": No match\n", name);
                    763:                return(NOSTR);
                    764:        }
                    765:        if (l == BUFSIZ) {
                    766:                fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name);
                    767:                return(NOSTR);
                    768:        }
                    769:        xname[l] = 0;
                    770:        for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--)
                    771:                ;
                    772:        *++cp = '\0';
                    773:        return(xname);
                    774: }
                    775: 
                    776: /*
                    777:  * Are any of the characters in the two strings the same?
                    778:  */
                    779: 
                    780: anyof(s1, s2)
                    781:        register char *s1, *s2;
                    782: {
                    783:        register int c;
                    784: 
                    785:        while (c = *s1++)
                    786:                if (any(c, s2))
                    787:                        return(1);
                    788:        return(0);
                    789: }

unix.superglobalmegacorp.com

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