[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.7

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