119814Sdist /* 235464Sbostic * Copyright (c) 1983 The Regents of the University of California. 335464Sbostic * All rights reserved. 435464Sbostic * 542770Sbostic * %sccs.include.redist.c% 619814Sdist */ 719814Sdist 813277Ssam #ifndef lint 9*55792Smarc static char sccsid[] = "@(#)cmds.c 5.17 (Berkeley) 07/30/92"; 1035464Sbostic #endif /* not lint */ 1113277Ssam 123688Sroot #include "tip.h" 1337857Sbostic #include "pathnames.h" 1437857Sbostic 153688Sroot /* 163688Sroot * tip 173688Sroot * 183688Sroot * miscellaneous commands 193688Sroot */ 203688Sroot 213688Sroot int quant[] = { 60, 60, 24 }; 223688Sroot 233688Sroot char null = '\0'; 243688Sroot char *sep[] = { "second", "minute", "hour" }; 253688Sroot static char *argv[10]; /* argument vector for take and put */ 263688Sroot 2739254Sbostic void timeout(); /* timeout function called on alarm */ 2839254Sbostic void stopsnd(); /* SIGINT handler during file transfers */ 2939254Sbostic void intcopy(); /* interrupt routine for file transfers */ 303688Sroot 313688Sroot /* 323688Sroot * FTP - remote ==> local 333688Sroot * get a file from the remote host 343688Sroot */ 353688Sroot getfl(c) 363688Sroot char c; 373688Sroot { 3813277Ssam char buf[256], *cp, *expand(); 393688Sroot 403688Sroot putchar(c); 413688Sroot /* 423688Sroot * get the UNIX receiving file's name 433688Sroot */ 443688Sroot if (prompt("Local file name? ", copyname)) 453688Sroot return; 4613277Ssam cp = expand(copyname); 4713277Ssam if ((sfd = creat(cp, 0666)) < 0) { 483688Sroot printf("\r\n%s: cannot creat\r\n", copyname); 493688Sroot return; 503688Sroot } 513688Sroot 523688Sroot /* 533688Sroot * collect parameters 543688Sroot */ 553688Sroot if (prompt("List command for remote system? ", buf)) { 563688Sroot unlink(copyname); 573688Sroot return; 583688Sroot } 593688Sroot transfer(buf, sfd, value(EOFREAD)); 603688Sroot } 613688Sroot 623688Sroot /* 633688Sroot * Cu-like take command 643688Sroot */ 653688Sroot cu_take(cc) 663688Sroot char cc; 673688Sroot { 683688Sroot int fd, argc; 6913277Ssam char line[BUFSIZ], *expand(), *cp; 703688Sroot 713688Sroot if (prompt("[take] ", copyname)) 723688Sroot return; 733688Sroot if ((argc = args(copyname, argv)) < 1 || argc > 2) { 743688Sroot printf("usage: <take> from [to]\r\n"); 753688Sroot return; 763688Sroot } 773688Sroot if (argc == 1) 783688Sroot argv[1] = argv[0]; 7913277Ssam cp = expand(argv[1]); 8013277Ssam if ((fd = creat(cp, 0666)) < 0) { 813688Sroot printf("\r\n%s: cannot create\r\n", argv[1]); 823688Sroot return; 833688Sroot } 8413137Sralph sprintf(line, "cat %s;echo \01", argv[0]); 853688Sroot transfer(line, fd, "\01"); 863688Sroot } 873688Sroot 8813277Ssam static jmp_buf intbuf; 893688Sroot /* 903688Sroot * Bulk transfer routine -- 913688Sroot * used by getfl(), cu_take(), and pipefile() 923688Sroot */ 933688Sroot transfer(buf, fd, eofchars) 943688Sroot char *buf, *eofchars; 953688Sroot { 963688Sroot register int ct; 973688Sroot char c, buffer[BUFSIZ]; 983688Sroot register char *p = buffer; 993688Sroot register int cnt, eof; 1003688Sroot time_t start; 10139254Sbostic sig_t f; 10250714Sbostic char r; 1033688Sroot 10413137Sralph pwrite(FD, buf, size(buf)); 1053688Sroot quit = 0; 1063688Sroot kill(pid, SIGIOT); 1073688Sroot read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ 1083688Sroot 1093688Sroot /* 1103688Sroot * finish command 1113688Sroot */ 11250714Sbostic r = '\r'; 11350714Sbostic pwrite(FD, &r, 1); 1143688Sroot do 1153688Sroot read(FD, &c, 1); 1163688Sroot while ((c&0177) != '\n'); 1173688Sroot ioctl(0, TIOCSETC, &defchars); 1183688Sroot 11917186Sralph (void) setjmp(intbuf); 12013277Ssam f = signal(SIGINT, intcopy); 1213688Sroot start = time(0); 1223688Sroot for (ct = 0; !quit;) { 1233688Sroot eof = read(FD, &c, 1) <= 0; 1243688Sroot c &= 0177; 1253688Sroot if (quit) 1263688Sroot continue; 1273688Sroot if (eof || any(c, eofchars)) 1283688Sroot break; 1293688Sroot if (c == 0) 1303688Sroot continue; /* ignore nulls */ 1313688Sroot if (c == '\r') 1323688Sroot continue; 1333688Sroot *p++ = c; 1343688Sroot 1353688Sroot if (c == '\n' && boolean(value(VERBOSE))) 1363688Sroot printf("\r%d", ++ct); 1373688Sroot if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) { 1383688Sroot if (write(fd, buffer, cnt) != cnt) { 1393688Sroot printf("\r\nwrite error\r\n"); 1403688Sroot quit = 1; 1413688Sroot } 1423688Sroot p = buffer; 1433688Sroot } 1443688Sroot } 1453688Sroot if (cnt = (p-buffer)) 1463688Sroot if (write(fd, buffer, cnt) != cnt) 1473688Sroot printf("\r\nwrite error\r\n"); 1483688Sroot 1493688Sroot if (boolean(value(VERBOSE))) 1503688Sroot prtime(" lines transferred in ", time(0)-start); 1513688Sroot ioctl(0, TIOCSETC, &tchars); 1523688Sroot write(fildes[1], (char *)&ccc, 1); 15317186Sralph signal(SIGINT, f); 1543688Sroot close(fd); 1553688Sroot } 1563688Sroot 1573688Sroot /* 1583688Sroot * FTP - remote ==> local process 1593688Sroot * send remote input to local process via pipe 1603688Sroot */ 1613688Sroot pipefile() 1623688Sroot { 1633688Sroot int cpid, pdes[2]; 1643688Sroot char buf[256]; 1653688Sroot int status, p; 1663688Sroot extern int errno; 1673688Sroot 1683688Sroot if (prompt("Local command? ", buf)) 1693688Sroot return; 1703688Sroot 1713688Sroot if (pipe(pdes)) { 1723688Sroot printf("can't establish pipe\r\n"); 1733688Sroot return; 1743688Sroot } 1753688Sroot 1763688Sroot if ((cpid = fork()) < 0) { 1773688Sroot printf("can't fork!\r\n"); 1783688Sroot return; 1793688Sroot } else if (cpid) { 1803688Sroot if (prompt("List command for remote system? ", buf)) { 1813688Sroot close(pdes[0]), close(pdes[1]); 1823688Sroot kill (cpid, SIGKILL); 1833688Sroot } else { 1843688Sroot close(pdes[0]); 1853688Sroot signal(SIGPIPE, intcopy); 1863688Sroot transfer(buf, pdes[1], value(EOFREAD)); 1873688Sroot signal(SIGPIPE, SIG_DFL); 1883688Sroot while ((p = wait(&status)) > 0 && p != cpid) 1893688Sroot ; 1903688Sroot } 1913688Sroot } else { 1923688Sroot register int f; 1933688Sroot 1943688Sroot dup2(pdes[0], 0); 1953688Sroot close(pdes[0]); 1963688Sroot for (f = 3; f < 20; f++) 1973688Sroot close(f); 1983688Sroot execute(buf); 1993688Sroot printf("can't execl!\r\n"); 2003688Sroot exit(0); 2013688Sroot } 2023688Sroot } 2033688Sroot 2043688Sroot /* 2053688Sroot * Interrupt service routine for FTP 2063688Sroot */ 20739254Sbostic void 2083688Sroot stopsnd() 2093688Sroot { 21013277Ssam 2113688Sroot stop = 1; 2123688Sroot signal(SIGINT, SIG_IGN); 2133688Sroot } 2143688Sroot 2153688Sroot /* 2163688Sroot * FTP - local ==> remote 2173688Sroot * send local file to remote host 2183688Sroot * terminate transmission with pseudo EOF sequence 2193688Sroot */ 2203688Sroot sendfile(cc) 2213688Sroot char cc; 2223688Sroot { 2233688Sroot FILE *fd; 22413137Sralph char *fnamex; 22513137Sralph char *expand(); 2263688Sroot 2273688Sroot putchar(cc); 2283688Sroot /* 2293688Sroot * get file name 2303688Sroot */ 2313688Sroot if (prompt("Local file name? ", fname)) 2323688Sroot return; 2333688Sroot 2343688Sroot /* 2353688Sroot * look up file 2363688Sroot */ 23713137Sralph fnamex = expand(fname); 23813137Sralph if ((fd = fopen(fnamex, "r")) == NULL) { 2393688Sroot printf("%s: cannot open\r\n", fname); 2403688Sroot return; 2413688Sroot } 2423688Sroot transmit(fd, value(EOFWRITE), NULL); 2433843Ssam if (!boolean(value(ECHOCHECK))) { 2443843Ssam struct sgttyb buf; 2453843Ssam 2463843Ssam ioctl(FD, TIOCGETP, &buf); /* this does a */ 2473843Ssam ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 2483843Ssam } 2493688Sroot } 2503688Sroot 2513688Sroot /* 2523688Sroot * Bulk transfer routine to remote host -- 2533688Sroot * used by sendfile() and cu_put() 2543688Sroot */ 2553688Sroot transmit(fd, eofchars, command) 2563688Sroot FILE *fd; 2573688Sroot char *eofchars, *command; 2583688Sroot { 25913137Sralph char *pc, lastc; 2603688Sroot int c, ccount, lcount; 2613688Sroot time_t start_t, stop_t; 26239254Sbostic sig_t f; 2633688Sroot 2643688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 2653688Sroot stop = 0; 26617186Sralph f = signal(SIGINT, stopsnd); 2673688Sroot ioctl(0, TIOCSETC, &defchars); 2683688Sroot read(repdes[0], (char *)&ccc, 1); 2693688Sroot if (command != NULL) { 2703688Sroot for (pc = command; *pc; pc++) 2713688Sroot send(*pc); 2723843Ssam if (boolean(value(ECHOCHECK))) 2733843Ssam read(FD, (char *)&c, 1); /* trailing \n */ 2743843Ssam else { 2753843Ssam struct sgttyb buf; 2763843Ssam 2773843Ssam ioctl(FD, TIOCGETP, &buf); /* this does a */ 2783843Ssam ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 2793843Ssam sleep(5); /* wait for remote stty to take effect */ 2803843Ssam } 2813688Sroot } 2823688Sroot lcount = 0; 2833688Sroot lastc = '\0'; 2843688Sroot start_t = time(0); 2855133Ssam while (1) { 2863688Sroot ccount = 0; 2873688Sroot do { 2883688Sroot c = getc(fd); 2893688Sroot if (stop) 2903688Sroot goto out; 2913688Sroot if (c == EOF) 2923688Sroot goto out; 29313137Sralph if (c == 0177 && !boolean(value(RAWFTP))) 2943688Sroot continue; 2953688Sroot lastc = c; 2963688Sroot if (c < 040) { 29713137Sralph if (c == '\n') { 29813137Sralph if (!boolean(value(RAWFTP))) 29913137Sralph c = '\r'; 30013137Sralph } 3013688Sroot else if (c == '\t') { 30213137Sralph if (!boolean(value(RAWFTP))) { 30313137Sralph if (boolean(value(TABEXPAND))) { 3043688Sroot send(' '); 30513137Sralph while ((++ccount % 8) != 0) 30613137Sralph send(' '); 30713137Sralph continue; 30813137Sralph } 30913137Sralph } 31013137Sralph } else 31146976Sbostic if (!boolean(value(RAWFTP))) 3123688Sroot continue; 3133688Sroot } 3143688Sroot send(c); 31513137Sralph } while (c != '\r' && !boolean(value(RAWFTP))); 3163688Sroot if (boolean(value(VERBOSE))) 3173688Sroot printf("\r%d", ++lcount); 3183843Ssam if (boolean(value(ECHOCHECK))) { 31917186Sralph timedout = 0; 32046864Sbostic alarm((int)value(ETIMEOUT)); 3213843Ssam do { /* wait for prompt */ 32213137Sralph read(FD, (char *)&c, 1); 3233843Ssam if (timedout || stop) { 3243843Ssam if (timedout) 3253843Ssam printf("\r\ntimed out at eol\r\n"); 3263843Ssam alarm(0); 3273843Ssam goto out; 3283843Ssam } 32913137Sralph } while ((c&0177) != character(value(PROMPT))); 3303843Ssam alarm(0); 3313843Ssam } 3323688Sroot } 3333688Sroot out: 33413137Sralph if (lastc != '\n' && !boolean(value(RAWFTP))) 3353688Sroot send('\r'); 3363688Sroot for (pc = eofchars; *pc; pc++) 3373688Sroot send(*pc); 3383688Sroot stop_t = time(0); 3393688Sroot fclose(fd); 34017186Sralph signal(SIGINT, f); 3413688Sroot if (boolean(value(VERBOSE))) 34213137Sralph if (boolean(value(RAWFTP))) 34313137Sralph prtime(" chars transferred in ", stop_t-start_t); 34413137Sralph else 34513137Sralph prtime(" lines transferred in ", stop_t-start_t); 3463688Sroot write(fildes[1], (char *)&ccc, 1); 3473688Sroot ioctl(0, TIOCSETC, &tchars); 3483688Sroot } 3493688Sroot 3503688Sroot /* 3513688Sroot * Cu-like put command 3523688Sroot */ 3533688Sroot cu_put(cc) 3543688Sroot char cc; 3553688Sroot { 3563688Sroot FILE *fd; 3573688Sroot char line[BUFSIZ]; 3583688Sroot int argc; 35913137Sralph char *expand(); 36013137Sralph char *copynamex; 3613688Sroot 3623688Sroot if (prompt("[put] ", copyname)) 3633688Sroot return; 3643688Sroot if ((argc = args(copyname, argv)) < 1 || argc > 2) { 3653688Sroot printf("usage: <put> from [to]\r\n"); 3663688Sroot return; 3673688Sroot } 3683688Sroot if (argc == 1) 3693688Sroot argv[1] = argv[0]; 37013137Sralph copynamex = expand(argv[0]); 37113137Sralph if ((fd = fopen(copynamex, "r")) == NULL) { 37213137Sralph printf("%s: cannot open\r\n", copynamex); 3733688Sroot return; 3743688Sroot } 3753843Ssam if (boolean(value(ECHOCHECK))) 37613137Sralph sprintf(line, "cat>%s\r", argv[1]); 3773843Ssam else 37813137Sralph sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]); 3793688Sroot transmit(fd, "\04", line); 3803688Sroot } 3813688Sroot 3823688Sroot /* 3833688Sroot * FTP - send single character 3843688Sroot * wait for echo & handle timeout 3853688Sroot */ 3863688Sroot send(c) 3873688Sroot char c; 3883688Sroot { 3897588Sshannon char cc; 3903688Sroot int retry = 0; 3913688Sroot 3923688Sroot cc = c; 39313137Sralph pwrite(FD, &cc, 1); 39413137Sralph #ifdef notdef 39513137Sralph if (number(value(CDELAY)) > 0 && c != '\r') 39613137Sralph nap(number(value(CDELAY))); 39713137Sralph #endif 39813137Sralph if (!boolean(value(ECHOCHECK))) { 39913137Sralph #ifdef notdef 40013137Sralph if (number(value(LDELAY)) > 0 && c == '\r') 40113137Sralph nap(number(value(LDELAY))); 40213137Sralph #endif 4033843Ssam return; 40413137Sralph } 4053688Sroot tryagain: 4063688Sroot timedout = 0; 40746864Sbostic alarm((int)value(ETIMEOUT)); 40813137Sralph read(FD, &cc, 1); 4093688Sroot alarm(0); 4103688Sroot if (timedout) { 4113688Sroot printf("\r\ntimeout error (%s)\r\n", ctrl(c)); 4123688Sroot if (retry++ > 3) 4133688Sroot return; 41413137Sralph pwrite(FD, &null, 1); /* poke it */ 4153688Sroot goto tryagain; 4163688Sroot } 4173688Sroot } 4183688Sroot 41939254Sbostic void 4203688Sroot timeout() 4213688Sroot { 4223688Sroot signal(SIGALRM, timeout); 4233688Sroot timedout = 1; 4243688Sroot } 4253688Sroot 42625548Sdonn /* 42725548Sdonn * Stolen from consh() -- puts a remote file on the output of a local command. 42825548Sdonn * Identical to consh() except for where stdout goes. 42925548Sdonn */ 43025548Sdonn pipeout(c) 43125548Sdonn { 43225548Sdonn char buf[256]; 43325548Sdonn int cpid, status, p; 43425548Sdonn time_t start; 43525548Sdonn 43625548Sdonn putchar(c); 43725548Sdonn if (prompt("Local command? ", buf)) 43825548Sdonn return; 43925548Sdonn kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 44025548Sdonn signal(SIGINT, SIG_IGN); 44125548Sdonn signal(SIGQUIT, SIG_IGN); 44225548Sdonn ioctl(0, TIOCSETC, &defchars); 44325548Sdonn read(repdes[0], (char *)&ccc, 1); 44425548Sdonn /* 44525548Sdonn * Set up file descriptors in the child and 44625548Sdonn * let it go... 44725548Sdonn */ 44825548Sdonn if ((cpid = fork()) < 0) 44925548Sdonn printf("can't fork!\r\n"); 45025548Sdonn else if (cpid) { 45125548Sdonn start = time(0); 45225548Sdonn while ((p = wait(&status)) > 0 && p != cpid) 45325548Sdonn ; 45425548Sdonn } else { 45525548Sdonn register int i; 45625548Sdonn 45725548Sdonn dup2(FD, 1); 45825548Sdonn for (i = 3; i < 20; i++) 45925548Sdonn close(i); 46025548Sdonn signal(SIGINT, SIG_DFL); 46125548Sdonn signal(SIGQUIT, SIG_DFL); 46225548Sdonn execute(buf); 46325548Sdonn printf("can't find `%s'\r\n", buf); 46425548Sdonn exit(0); 46525548Sdonn } 46625548Sdonn if (boolean(value(VERBOSE))) 46725548Sdonn prtime("away for ", time(0)-start); 46825548Sdonn write(fildes[1], (char *)&ccc, 1); 46925548Sdonn ioctl(0, TIOCSETC, &tchars); 47025548Sdonn signal(SIGINT, SIG_DFL); 47125548Sdonn signal(SIGQUIT, SIG_DFL); 47225548Sdonn } 47325548Sdonn 4743688Sroot #ifdef CONNECT 4753688Sroot /* 4763688Sroot * Fork a program with: 477*55792Smarc * 0 <-> remote tty in 478*55792Smarc * 1 <-> remote tty out 4793688Sroot * 2 <-> local tty out 4803688Sroot */ 4813688Sroot consh(c) 4823688Sroot { 4833688Sroot char buf[256]; 4843688Sroot int cpid, status, p; 4853688Sroot time_t start; 4863688Sroot 4873688Sroot putchar(c); 4883688Sroot if (prompt("Local command? ", buf)) 4893688Sroot return; 4903688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 4913688Sroot signal(SIGINT, SIG_IGN); 4923688Sroot signal(SIGQUIT, SIG_IGN); 4933688Sroot ioctl(0, TIOCSETC, &defchars); 4943688Sroot read(repdes[0], (char *)&ccc, 1); 4953688Sroot /* 4963688Sroot * Set up file descriptors in the child and 4973688Sroot * let it go... 4983688Sroot */ 4993688Sroot if ((cpid = fork()) < 0) 5003688Sroot printf("can't fork!\r\n"); 5013688Sroot else if (cpid) { 5023688Sroot start = time(0); 5033688Sroot while ((p = wait(&status)) > 0 && p != cpid) 5043688Sroot ; 5053688Sroot } else { 5063688Sroot register int i; 5073688Sroot 508*55792Smarc dup2(FD, 0); 509*55792Smarc dup2(3, 1); 510*55792Smarc for (i = 3; i < 20; i++) 5113688Sroot close(i); 5123688Sroot signal(SIGINT, SIG_DFL); 5133688Sroot signal(SIGQUIT, SIG_DFL); 5143688Sroot execute(buf); 5153688Sroot printf("can't find `%s'\r\n", buf); 5163688Sroot exit(0); 5173688Sroot } 5183688Sroot if (boolean(value(VERBOSE))) 5193688Sroot prtime("away for ", time(0)-start); 5203688Sroot write(fildes[1], (char *)&ccc, 1); 5213688Sroot ioctl(0, TIOCSETC, &tchars); 5223688Sroot signal(SIGINT, SIG_DFL); 5233688Sroot signal(SIGQUIT, SIG_DFL); 5243688Sroot } 5253688Sroot #endif 5263688Sroot 5273688Sroot /* 5283688Sroot * Escape to local shell 5293688Sroot */ 5303688Sroot shell() 5313688Sroot { 5323688Sroot int shpid, status; 5333688Sroot extern char **environ; 5343688Sroot char *cp; 5353688Sroot 5363688Sroot printf("[sh]\r\n"); 5373688Sroot signal(SIGINT, SIG_IGN); 5383688Sroot signal(SIGQUIT, SIG_IGN); 5393688Sroot unraw(); 5403688Sroot if (shpid = fork()) { 5413688Sroot while (shpid != wait(&status)); 5423688Sroot raw(); 5433688Sroot printf("\r\n!\r\n"); 5443688Sroot signal(SIGINT, SIG_DFL); 5453688Sroot signal(SIGQUIT, SIG_DFL); 5463688Sroot return; 5473688Sroot } else { 5483688Sroot signal(SIGQUIT, SIG_DFL); 5493688Sroot signal(SIGINT, SIG_DFL); 5503688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 5513688Sroot cp = value(SHELL); 5523688Sroot else 5533688Sroot cp++; 55430458Skarels shell_uid(); 5553688Sroot execl(value(SHELL), cp, 0); 5563688Sroot printf("\r\ncan't execl!\r\n"); 5573688Sroot exit(1); 5583688Sroot } 5593688Sroot } 5603688Sroot 5613688Sroot /* 5623688Sroot * TIPIN portion of scripting 5633688Sroot * initiate the conversation with TIPOUT 5643688Sroot */ 5653688Sroot setscript() 5663688Sroot { 5673688Sroot char c; 5683688Sroot /* 5693688Sroot * enable TIPOUT side for dialogue 5703688Sroot */ 5713688Sroot kill(pid, SIGEMT); 5723688Sroot if (boolean(value(SCRIPT))) 5733688Sroot write(fildes[1], value(RECORD), size(value(RECORD))); 5743688Sroot write(fildes[1], "\n", 1); 5753688Sroot /* 5763688Sroot * wait for TIPOUT to finish 5773688Sroot */ 5783688Sroot read(repdes[0], &c, 1); 5793688Sroot if (c == 'n') 5803688Sroot printf("can't create %s\r\n", value(RECORD)); 5813688Sroot } 5823688Sroot 5833688Sroot /* 5843688Sroot * Change current working directory of 5853688Sroot * local portion of tip 5863688Sroot */ 5873688Sroot chdirectory() 5883688Sroot { 58913277Ssam char dirname[80]; 5903688Sroot register char *cp = dirname; 5913688Sroot 59213277Ssam if (prompt("[cd] ", dirname)) { 5933688Sroot if (stoprompt) 5943688Sroot return; 59513277Ssam cp = value(HOME); 59613277Ssam } 5973688Sroot if (chdir(cp) < 0) 5983688Sroot printf("%s: bad directory\r\n", cp); 5993688Sroot printf("!\r\n"); 6003688Sroot } 6013688Sroot 60246261Storek tipabort(msg) 60315187Ssam char *msg; 6043688Sroot { 60513137Sralph 6063688Sroot kill(pid, SIGTERM); 60715187Ssam disconnect(msg); 60815187Ssam if (msg != NOSTR) 60915187Ssam printf("\r\n%s", msg); 6103688Sroot printf("\r\n[EOT]\r\n"); 61130458Skarels daemon_uid(); 61235460Sbostic (void)uu_unlock(uucplock); 6133688Sroot unraw(); 6143688Sroot exit(0); 6153688Sroot } 6163688Sroot 61715187Ssam finish() 61815187Ssam { 61915187Ssam char *dismsg; 62015187Ssam 62115187Ssam if ((dismsg = value(DISCONNECT)) != NOSTR) { 62215187Ssam write(FD, dismsg, strlen(dismsg)); 62315187Ssam sleep(5); 62415187Ssam } 62546261Storek tipabort(NOSTR); 62615187Ssam } 62715187Ssam 62839254Sbostic void 6293688Sroot intcopy() 6303688Sroot { 6313688Sroot raw(); 6323688Sroot quit = 1; 63313277Ssam longjmp(intbuf, 1); 6343688Sroot } 6353688Sroot 6363688Sroot execute(s) 6373688Sroot char *s; 6383688Sroot { 6393688Sroot register char *cp; 6403688Sroot 6413688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 6423688Sroot cp = value(SHELL); 6433688Sroot else 6443688Sroot cp++; 64535777Sbostic shell_uid(); 6463688Sroot execl(value(SHELL), cp, "-c", s, 0); 6473688Sroot } 6483688Sroot 6493688Sroot args(buf, a) 6503688Sroot char *buf, *a[]; 6513688Sroot { 6523688Sroot register char *p = buf, *start; 6533688Sroot register char **parg = a; 6543688Sroot register int n = 0; 6553688Sroot 6563688Sroot do { 6573688Sroot while (*p && (*p == ' ' || *p == '\t')) 6583688Sroot p++; 6593688Sroot start = p; 6603688Sroot if (*p) 6613688Sroot *parg = p; 6623688Sroot while (*p && (*p != ' ' && *p != '\t')) 6633688Sroot p++; 6643688Sroot if (p != start) 6653688Sroot parg++, n++; 6663688Sroot if (*p) 6673688Sroot *p++ = '\0'; 6683688Sroot } while (*p); 6693688Sroot 6703688Sroot return(n); 6713688Sroot } 6723688Sroot 6733688Sroot prtime(s, a) 6743688Sroot char *s; 6753688Sroot time_t a; 6763688Sroot { 6773688Sroot register i; 6783688Sroot int nums[3]; 6793688Sroot 6803688Sroot for (i = 0; i < 3; i++) { 6813688Sroot nums[i] = (int)(a % quant[i]); 6823688Sroot a /= quant[i]; 6833688Sroot } 6843688Sroot printf("%s", s); 6853688Sroot while (--i >= 0) 68617186Sralph if (nums[i] || i == 0 && nums[1] == 0 && nums[2] == 0) 6873688Sroot printf("%d %s%c ", nums[i], sep[i], 6883688Sroot nums[i] == 1 ? '\0' : 's'); 6893688Sroot printf("\r\n!\r\n"); 6903688Sroot } 6913688Sroot 6923688Sroot variable() 6933688Sroot { 6943688Sroot char buf[256]; 6953688Sroot 6963688Sroot if (prompt("[set] ", buf)) 6973688Sroot return; 6983688Sroot vlex(buf); 6993688Sroot if (vtable[BEAUTIFY].v_access&CHANGED) { 7003688Sroot vtable[BEAUTIFY].v_access &= ~CHANGED; 7015333Sshannon kill(pid, SIGSYS); 7023688Sroot } 7033688Sroot if (vtable[SCRIPT].v_access&CHANGED) { 7043688Sroot vtable[SCRIPT].v_access &= ~CHANGED; 7053688Sroot setscript(); 7063865Ssam /* 7073865Ssam * So that "set record=blah script" doesn't 7083865Ssam * cause two transactions to occur. 7093865Ssam */ 7103865Ssam if (vtable[RECORD].v_access&CHANGED) 7113865Ssam vtable[RECORD].v_access &= ~CHANGED; 7123688Sroot } 7133688Sroot if (vtable[RECORD].v_access&CHANGED) { 7143688Sroot vtable[RECORD].v_access &= ~CHANGED; 7153688Sroot if (boolean(value(SCRIPT))) 7163688Sroot setscript(); 7173688Sroot } 71813137Sralph if (vtable[TAND].v_access&CHANGED) { 71913137Sralph vtable[TAND].v_access &= ~CHANGED; 72013137Sralph if (boolean(value(TAND))) 72113137Sralph tandem("on"); 72213137Sralph else 72313137Sralph tandem("off"); 72413137Sralph } 72513137Sralph if (vtable[LECHO].v_access&CHANGED) { 72613137Sralph vtable[LECHO].v_access &= ~CHANGED; 72713137Sralph HD = boolean(value(LECHO)); 72813137Sralph } 72913137Sralph if (vtable[PARITY].v_access&CHANGED) { 73013137Sralph vtable[PARITY].v_access &= ~CHANGED; 73113137Sralph setparity(); 73213137Sralph } 7333688Sroot } 7343822Ssam 7353822Ssam /* 73613277Ssam * Turn tandem mode on or off for remote tty. 73713137Sralph */ 73813137Sralph tandem(option) 73913277Ssam char *option; 74013137Sralph { 74113137Sralph struct sgttyb rmtty; 74213137Sralph 74313137Sralph ioctl(FD, TIOCGETP, &rmtty); 74413137Sralph if (strcmp(option,"on") == 0) { 74513137Sralph rmtty.sg_flags |= TANDEM; 74613137Sralph arg.sg_flags |= TANDEM; 74713277Ssam } else { 74813137Sralph rmtty.sg_flags &= ~TANDEM; 74913137Sralph arg.sg_flags &= ~TANDEM; 75013137Sralph } 75113137Sralph ioctl(FD, TIOCSETP, &rmtty); 75213137Sralph ioctl(0, TIOCSETP, &arg); 75313137Sralph } 75413137Sralph 75513137Sralph /* 7563822Ssam * Send a break. 7573822Ssam */ 7583822Ssam genbrk() 7593822Ssam { 76013277Ssam 7613822Ssam ioctl(FD, TIOCSBRK, NULL); 7623822Ssam sleep(1); 7633822Ssam ioctl(FD, TIOCCBRK, NULL); 7643822Ssam } 7655133Ssam 7665133Ssam /* 7675133Ssam * Suspend tip 7685133Ssam */ 76927702Ssam suspend(c) 77027702Ssam char c; 7715133Ssam { 77213277Ssam 7735133Ssam unraw(); 77433119Sbostic kill(c == CTRL('y') ? getpid() : 0, SIGTSTP); 7755133Ssam raw(); 7765133Ssam } 77713137Sralph 77813137Sralph /* 77913137Sralph * expand a file name if it includes shell meta characters 78013137Sralph */ 78113137Sralph 78213137Sralph char * 78313137Sralph expand(name) 78413137Sralph char name[]; 78513137Sralph { 78613137Sralph static char xname[BUFSIZ]; 78713137Sralph char cmdbuf[BUFSIZ]; 78813137Sralph register int pid, l, rc; 78913137Sralph register char *cp, *Shell; 79013137Sralph int s, pivec[2], (*sigint)(); 79113137Sralph 79213137Sralph if (!anyof(name, "~{[*?$`'\"\\")) 79313137Sralph return(name); 79413137Sralph /* sigint = signal(SIGINT, SIG_IGN); */ 79513137Sralph if (pipe(pivec) < 0) { 79613137Sralph perror("pipe"); 79713137Sralph /* signal(SIGINT, sigint) */ 79813137Sralph return(name); 79913137Sralph } 80013137Sralph sprintf(cmdbuf, "echo %s", name); 80113137Sralph if ((pid = vfork()) == 0) { 80213137Sralph Shell = value(SHELL); 80313137Sralph if (Shell == NOSTR) 80437857Sbostic Shell = _PATH_BSHELL; 80513137Sralph close(pivec[0]); 80613137Sralph close(1); 80713137Sralph dup(pivec[1]); 80813137Sralph close(pivec[1]); 80913137Sralph close(2); 81030458Skarels shell_uid(); 81113137Sralph execl(Shell, Shell, "-c", cmdbuf, 0); 81213137Sralph _exit(1); 81313137Sralph } 81413137Sralph if (pid == -1) { 81513137Sralph perror("fork"); 81613137Sralph close(pivec[0]); 81713137Sralph close(pivec[1]); 81813137Sralph return(NOSTR); 81913137Sralph } 82013137Sralph close(pivec[1]); 82113137Sralph l = read(pivec[0], xname, BUFSIZ); 82213137Sralph close(pivec[0]); 82313137Sralph while (wait(&s) != pid); 82413137Sralph ; 82513137Sralph s &= 0377; 82613137Sralph if (s != 0 && s != SIGPIPE) { 82713137Sralph fprintf(stderr, "\"Echo\" failed\n"); 82813137Sralph return(NOSTR); 82913137Sralph } 83013137Sralph if (l < 0) { 83113137Sralph perror("read"); 83213137Sralph return(NOSTR); 83313137Sralph } 83413137Sralph if (l == 0) { 83513137Sralph fprintf(stderr, "\"%s\": No match\n", name); 83613137Sralph return(NOSTR); 83713137Sralph } 83813137Sralph if (l == BUFSIZ) { 83913137Sralph fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name); 84013137Sralph return(NOSTR); 84113137Sralph } 84213137Sralph xname[l] = 0; 84313137Sralph for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) 84413137Sralph ; 84513137Sralph *++cp = '\0'; 84613137Sralph return(xname); 84713137Sralph } 84813137Sralph 84913137Sralph /* 85013137Sralph * Are any of the characters in the two strings the same? 85113137Sralph */ 85213137Sralph 85313137Sralph anyof(s1, s2) 85413137Sralph register char *s1, *s2; 85513137Sralph { 85613137Sralph register int c; 85713137Sralph 85813137Sralph while (c = *s1++) 85913137Sralph if (any(c, s2)) 86013137Sralph return(1); 86113137Sralph return(0); 86213137Sralph } 863