Annotation of 43BSDReno/usr.bin/tip/cmds.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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