[BACK]Return to cmds.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tip

Annotation of src/usr.bin/tip/cmds.c, Revision 1.17

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