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*46261Storek static char sccsid[] = "@(#)cmds.c 5.13 (Berkeley) 02/04/91"; 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; 1023688Sroot 10313137Sralph pwrite(FD, buf, size(buf)); 1043688Sroot quit = 0; 1053688Sroot kill(pid, SIGIOT); 1063688Sroot read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ 1073688Sroot 1083688Sroot /* 1093688Sroot * finish command 1103688Sroot */ 11113137Sralph pwrite(FD, "\r", 1); 1123688Sroot do 1133688Sroot read(FD, &c, 1); 1143688Sroot while ((c&0177) != '\n'); 1153688Sroot ioctl(0, TIOCSETC, &defchars); 1163688Sroot 11717186Sralph (void) setjmp(intbuf); 11813277Ssam f = signal(SIGINT, intcopy); 1193688Sroot start = time(0); 1203688Sroot for (ct = 0; !quit;) { 1213688Sroot eof = read(FD, &c, 1) <= 0; 1223688Sroot c &= 0177; 1233688Sroot if (quit) 1243688Sroot continue; 1253688Sroot if (eof || any(c, eofchars)) 1263688Sroot break; 1273688Sroot if (c == 0) 1283688Sroot continue; /* ignore nulls */ 1293688Sroot if (c == '\r') 1303688Sroot continue; 1313688Sroot *p++ = c; 1323688Sroot 1333688Sroot if (c == '\n' && boolean(value(VERBOSE))) 1343688Sroot printf("\r%d", ++ct); 1353688Sroot if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) { 1363688Sroot if (write(fd, buffer, cnt) != cnt) { 1373688Sroot printf("\r\nwrite error\r\n"); 1383688Sroot quit = 1; 1393688Sroot } 1403688Sroot p = buffer; 1413688Sroot } 1423688Sroot } 1433688Sroot if (cnt = (p-buffer)) 1443688Sroot if (write(fd, buffer, cnt) != cnt) 1453688Sroot printf("\r\nwrite error\r\n"); 1463688Sroot 1473688Sroot if (boolean(value(VERBOSE))) 1483688Sroot prtime(" lines transferred in ", time(0)-start); 1493688Sroot ioctl(0, TIOCSETC, &tchars); 1503688Sroot write(fildes[1], (char *)&ccc, 1); 15117186Sralph signal(SIGINT, f); 1523688Sroot close(fd); 1533688Sroot } 1543688Sroot 1553688Sroot /* 1563688Sroot * FTP - remote ==> local process 1573688Sroot * send remote input to local process via pipe 1583688Sroot */ 1593688Sroot pipefile() 1603688Sroot { 1613688Sroot int cpid, pdes[2]; 1623688Sroot char buf[256]; 1633688Sroot int status, p; 1643688Sroot extern int errno; 1653688Sroot 1663688Sroot if (prompt("Local command? ", buf)) 1673688Sroot return; 1683688Sroot 1693688Sroot if (pipe(pdes)) { 1703688Sroot printf("can't establish pipe\r\n"); 1713688Sroot return; 1723688Sroot } 1733688Sroot 1743688Sroot if ((cpid = fork()) < 0) { 1753688Sroot printf("can't fork!\r\n"); 1763688Sroot return; 1773688Sroot } else if (cpid) { 1783688Sroot if (prompt("List command for remote system? ", buf)) { 1793688Sroot close(pdes[0]), close(pdes[1]); 1803688Sroot kill (cpid, SIGKILL); 1813688Sroot } else { 1823688Sroot close(pdes[0]); 1833688Sroot signal(SIGPIPE, intcopy); 1843688Sroot transfer(buf, pdes[1], value(EOFREAD)); 1853688Sroot signal(SIGPIPE, SIG_DFL); 1863688Sroot while ((p = wait(&status)) > 0 && p != cpid) 1873688Sroot ; 1883688Sroot } 1893688Sroot } else { 1903688Sroot register int f; 1913688Sroot 1923688Sroot dup2(pdes[0], 0); 1933688Sroot close(pdes[0]); 1943688Sroot for (f = 3; f < 20; f++) 1953688Sroot close(f); 1963688Sroot execute(buf); 1973688Sroot printf("can't execl!\r\n"); 1983688Sroot exit(0); 1993688Sroot } 2003688Sroot } 2013688Sroot 2023688Sroot /* 2033688Sroot * Interrupt service routine for FTP 2043688Sroot */ 20539254Sbostic void 2063688Sroot stopsnd() 2073688Sroot { 20813277Ssam 2093688Sroot stop = 1; 2103688Sroot signal(SIGINT, SIG_IGN); 2113688Sroot } 2123688Sroot 2133688Sroot /* 2143688Sroot * FTP - local ==> remote 2153688Sroot * send local file to remote host 2163688Sroot * terminate transmission with pseudo EOF sequence 2173688Sroot */ 2183688Sroot sendfile(cc) 2193688Sroot char cc; 2203688Sroot { 2213688Sroot FILE *fd; 22213137Sralph char *fnamex; 22313137Sralph char *expand(); 2243688Sroot 2253688Sroot putchar(cc); 2263688Sroot /* 2273688Sroot * get file name 2283688Sroot */ 2293688Sroot if (prompt("Local file name? ", fname)) 2303688Sroot return; 2313688Sroot 2323688Sroot /* 2333688Sroot * look up file 2343688Sroot */ 23513137Sralph fnamex = expand(fname); 23613137Sralph if ((fd = fopen(fnamex, "r")) == NULL) { 2373688Sroot printf("%s: cannot open\r\n", fname); 2383688Sroot return; 2393688Sroot } 2403688Sroot transmit(fd, value(EOFWRITE), NULL); 2413843Ssam if (!boolean(value(ECHOCHECK))) { 2423843Ssam struct sgttyb buf; 2433843Ssam 2443843Ssam ioctl(FD, TIOCGETP, &buf); /* this does a */ 2453843Ssam ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 2463843Ssam } 2473688Sroot } 2483688Sroot 2493688Sroot /* 2503688Sroot * Bulk transfer routine to remote host -- 2513688Sroot * used by sendfile() and cu_put() 2523688Sroot */ 2533688Sroot transmit(fd, eofchars, command) 2543688Sroot FILE *fd; 2553688Sroot char *eofchars, *command; 2563688Sroot { 25713137Sralph char *pc, lastc; 2583688Sroot int c, ccount, lcount; 2593688Sroot time_t start_t, stop_t; 26039254Sbostic sig_t f; 2613688Sroot 2623688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 2633688Sroot stop = 0; 26417186Sralph f = signal(SIGINT, stopsnd); 2653688Sroot ioctl(0, TIOCSETC, &defchars); 2663688Sroot read(repdes[0], (char *)&ccc, 1); 2673688Sroot if (command != NULL) { 2683688Sroot for (pc = command; *pc; pc++) 2693688Sroot send(*pc); 2703843Ssam if (boolean(value(ECHOCHECK))) 2713843Ssam read(FD, (char *)&c, 1); /* trailing \n */ 2723843Ssam else { 2733843Ssam struct sgttyb buf; 2743843Ssam 2753843Ssam ioctl(FD, TIOCGETP, &buf); /* this does a */ 2763843Ssam ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 2773843Ssam sleep(5); /* wait for remote stty to take effect */ 2783843Ssam } 2793688Sroot } 2803688Sroot lcount = 0; 2813688Sroot lastc = '\0'; 2823688Sroot start_t = time(0); 2835133Ssam while (1) { 2843688Sroot ccount = 0; 2853688Sroot do { 2863688Sroot c = getc(fd); 2873688Sroot if (stop) 2883688Sroot goto out; 2893688Sroot if (c == EOF) 2903688Sroot goto out; 29113137Sralph if (c == 0177 && !boolean(value(RAWFTP))) 2923688Sroot continue; 2933688Sroot lastc = c; 2943688Sroot if (c < 040) { 29513137Sralph if (c == '\n') { 29613137Sralph if (!boolean(value(RAWFTP))) 29713137Sralph c = '\r'; 29813137Sralph } 2993688Sroot else if (c == '\t') { 30013137Sralph if (!boolean(value(RAWFTP))) { 30113137Sralph if (boolean(value(TABEXPAND))) { 3023688Sroot send(' '); 30313137Sralph while ((++ccount % 8) != 0) 30413137Sralph send(' '); 30513137Sralph continue; 30613137Sralph } 30713137Sralph } 30813137Sralph } else 30913137Sralph if (!boolean(value(RAWFTP))) 3103688Sroot continue; 3113688Sroot } 3123688Sroot send(c); 31313137Sralph } while (c != '\r' && !boolean(value(RAWFTP))); 3143688Sroot if (boolean(value(VERBOSE))) 3153688Sroot printf("\r%d", ++lcount); 3163843Ssam if (boolean(value(ECHOCHECK))) { 31717186Sralph timedout = 0; 31813137Sralph alarm(value(ETIMEOUT)); 3193843Ssam do { /* wait for prompt */ 32013137Sralph read(FD, (char *)&c, 1); 3213843Ssam if (timedout || stop) { 3223843Ssam if (timedout) 3233843Ssam printf("\r\ntimed out at eol\r\n"); 3243843Ssam alarm(0); 3253843Ssam goto out; 3263843Ssam } 32713137Sralph } while ((c&0177) != character(value(PROMPT))); 3283843Ssam alarm(0); 3293843Ssam } 3303688Sroot } 3313688Sroot out: 33213137Sralph if (lastc != '\n' && !boolean(value(RAWFTP))) 3333688Sroot send('\r'); 3343688Sroot for (pc = eofchars; *pc; pc++) 3353688Sroot send(*pc); 3363688Sroot stop_t = time(0); 3373688Sroot fclose(fd); 33817186Sralph signal(SIGINT, f); 3393688Sroot if (boolean(value(VERBOSE))) 34013137Sralph if (boolean(value(RAWFTP))) 34113137Sralph prtime(" chars transferred in ", stop_t-start_t); 34213137Sralph else 34313137Sralph prtime(" lines transferred in ", stop_t-start_t); 3443688Sroot write(fildes[1], (char *)&ccc, 1); 3453688Sroot ioctl(0, TIOCSETC, &tchars); 3463688Sroot } 3473688Sroot 3483688Sroot /* 3493688Sroot * Cu-like put command 3503688Sroot */ 3513688Sroot cu_put(cc) 3523688Sroot char cc; 3533688Sroot { 3543688Sroot FILE *fd; 3553688Sroot char line[BUFSIZ]; 3563688Sroot int argc; 35713137Sralph char *expand(); 35813137Sralph char *copynamex; 3593688Sroot 3603688Sroot if (prompt("[put] ", copyname)) 3613688Sroot return; 3623688Sroot if ((argc = args(copyname, argv)) < 1 || argc > 2) { 3633688Sroot printf("usage: <put> from [to]\r\n"); 3643688Sroot return; 3653688Sroot } 3663688Sroot if (argc == 1) 3673688Sroot argv[1] = argv[0]; 36813137Sralph copynamex = expand(argv[0]); 36913137Sralph if ((fd = fopen(copynamex, "r")) == NULL) { 37013137Sralph printf("%s: cannot open\r\n", copynamex); 3713688Sroot return; 3723688Sroot } 3733843Ssam if (boolean(value(ECHOCHECK))) 37413137Sralph sprintf(line, "cat>%s\r", argv[1]); 3753843Ssam else 37613137Sralph sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]); 3773688Sroot transmit(fd, "\04", line); 3783688Sroot } 3793688Sroot 3803688Sroot /* 3813688Sroot * FTP - send single character 3823688Sroot * wait for echo & handle timeout 3833688Sroot */ 3843688Sroot send(c) 3853688Sroot char c; 3863688Sroot { 3877588Sshannon char cc; 3883688Sroot int retry = 0; 3893688Sroot 3903688Sroot cc = c; 39113137Sralph pwrite(FD, &cc, 1); 39213137Sralph #ifdef notdef 39313137Sralph if (number(value(CDELAY)) > 0 && c != '\r') 39413137Sralph nap(number(value(CDELAY))); 39513137Sralph #endif 39613137Sralph if (!boolean(value(ECHOCHECK))) { 39713137Sralph #ifdef notdef 39813137Sralph if (number(value(LDELAY)) > 0 && c == '\r') 39913137Sralph nap(number(value(LDELAY))); 40013137Sralph #endif 4013843Ssam return; 40213137Sralph } 4033688Sroot tryagain: 4043688Sroot timedout = 0; 40513137Sralph alarm(value(ETIMEOUT)); 40613137Sralph read(FD, &cc, 1); 4073688Sroot alarm(0); 4083688Sroot if (timedout) { 4093688Sroot printf("\r\ntimeout error (%s)\r\n", ctrl(c)); 4103688Sroot if (retry++ > 3) 4113688Sroot return; 41213137Sralph pwrite(FD, &null, 1); /* poke it */ 4133688Sroot goto tryagain; 4143688Sroot } 4153688Sroot } 4163688Sroot 41739254Sbostic void 4183688Sroot timeout() 4193688Sroot { 4203688Sroot signal(SIGALRM, timeout); 4213688Sroot timedout = 1; 4223688Sroot } 4233688Sroot 42425548Sdonn /* 42525548Sdonn * Stolen from consh() -- puts a remote file on the output of a local command. 42625548Sdonn * Identical to consh() except for where stdout goes. 42725548Sdonn */ 42825548Sdonn pipeout(c) 42925548Sdonn { 43025548Sdonn char buf[256]; 43125548Sdonn int cpid, status, p; 43225548Sdonn time_t start; 43325548Sdonn 43425548Sdonn putchar(c); 43525548Sdonn if (prompt("Local command? ", buf)) 43625548Sdonn return; 43725548Sdonn kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 43825548Sdonn signal(SIGINT, SIG_IGN); 43925548Sdonn signal(SIGQUIT, SIG_IGN); 44025548Sdonn ioctl(0, TIOCSETC, &defchars); 44125548Sdonn read(repdes[0], (char *)&ccc, 1); 44225548Sdonn /* 44325548Sdonn * Set up file descriptors in the child and 44425548Sdonn * let it go... 44525548Sdonn */ 44625548Sdonn if ((cpid = fork()) < 0) 44725548Sdonn printf("can't fork!\r\n"); 44825548Sdonn else if (cpid) { 44925548Sdonn start = time(0); 45025548Sdonn while ((p = wait(&status)) > 0 && p != cpid) 45125548Sdonn ; 45225548Sdonn } else { 45325548Sdonn register int i; 45425548Sdonn 45525548Sdonn dup2(FD, 1); 45625548Sdonn for (i = 3; i < 20; i++) 45725548Sdonn close(i); 45825548Sdonn signal(SIGINT, SIG_DFL); 45925548Sdonn signal(SIGQUIT, SIG_DFL); 46025548Sdonn execute(buf); 46125548Sdonn printf("can't find `%s'\r\n", buf); 46225548Sdonn exit(0); 46325548Sdonn } 46425548Sdonn if (boolean(value(VERBOSE))) 46525548Sdonn prtime("away for ", time(0)-start); 46625548Sdonn write(fildes[1], (char *)&ccc, 1); 46725548Sdonn ioctl(0, TIOCSETC, &tchars); 46825548Sdonn signal(SIGINT, SIG_DFL); 46925548Sdonn signal(SIGQUIT, SIG_DFL); 47025548Sdonn } 47125548Sdonn 4723688Sroot #ifdef CONNECT 4733688Sroot /* 4743688Sroot * Fork a program with: 4753688Sroot * 0 <-> local tty in 4763688Sroot * 1 <-> local tty out 4773688Sroot * 2 <-> local tty out 4783688Sroot * 3 <-> remote tty in 4793688Sroot * 4 <-> remote 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 5083688Sroot dup2(FD, 3); 5093688Sroot dup2(3, 4); 5103688Sroot for (i = 5; 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 602*46261Storek 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 } 625*46261Storek 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