119814Sdist /* 235464Sbostic * Copyright (c) 1983 The Regents of the University of California. 335464Sbostic * All rights reserved. 435464Sbostic * 535464Sbostic * Redistribution and use in source and binary forms are permitted 635464Sbostic * provided that the above copyright notice and this paragraph are 735464Sbostic * duplicated in all such forms and that any documentation, 835464Sbostic * advertising materials, and other materials related to such 935464Sbostic * distribution and use acknowledge that the software was developed 1035464Sbostic * by the University of California, Berkeley. The name of the 1135464Sbostic * University may not be used to endorse or promote products derived 1235464Sbostic * from this software without specific prior written permission. 1335464Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1435464Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1535464Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1619814Sdist */ 1719814Sdist 1813277Ssam #ifndef lint 19*39254Sbostic static char sccsid[] = "@(#)cmds.c 5.11 (Berkeley) 10/03/89"; 2035464Sbostic #endif /* not lint */ 2113277Ssam 223688Sroot #include "tip.h" 2337857Sbostic #include "pathnames.h" 2437857Sbostic 253688Sroot /* 263688Sroot * tip 273688Sroot * 283688Sroot * miscellaneous commands 293688Sroot */ 303688Sroot 313688Sroot int quant[] = { 60, 60, 24 }; 323688Sroot 333688Sroot char null = '\0'; 343688Sroot char *sep[] = { "second", "minute", "hour" }; 353688Sroot static char *argv[10]; /* argument vector for take and put */ 363688Sroot 37*39254Sbostic void timeout(); /* timeout function called on alarm */ 38*39254Sbostic void stopsnd(); /* SIGINT handler during file transfers */ 39*39254Sbostic void intcopy(); /* interrupt routine for file transfers */ 403688Sroot 413688Sroot /* 423688Sroot * FTP - remote ==> local 433688Sroot * get a file from the remote host 443688Sroot */ 453688Sroot getfl(c) 463688Sroot char c; 473688Sroot { 4813277Ssam char buf[256], *cp, *expand(); 493688Sroot 503688Sroot putchar(c); 513688Sroot /* 523688Sroot * get the UNIX receiving file's name 533688Sroot */ 543688Sroot if (prompt("Local file name? ", copyname)) 553688Sroot return; 5613277Ssam cp = expand(copyname); 5713277Ssam if ((sfd = creat(cp, 0666)) < 0) { 583688Sroot printf("\r\n%s: cannot creat\r\n", copyname); 593688Sroot return; 603688Sroot } 613688Sroot 623688Sroot /* 633688Sroot * collect parameters 643688Sroot */ 653688Sroot if (prompt("List command for remote system? ", buf)) { 663688Sroot unlink(copyname); 673688Sroot return; 683688Sroot } 693688Sroot transfer(buf, sfd, value(EOFREAD)); 703688Sroot } 713688Sroot 723688Sroot /* 733688Sroot * Cu-like take command 743688Sroot */ 753688Sroot cu_take(cc) 763688Sroot char cc; 773688Sroot { 783688Sroot int fd, argc; 7913277Ssam char line[BUFSIZ], *expand(), *cp; 803688Sroot 813688Sroot if (prompt("[take] ", copyname)) 823688Sroot return; 833688Sroot if ((argc = args(copyname, argv)) < 1 || argc > 2) { 843688Sroot printf("usage: <take> from [to]\r\n"); 853688Sroot return; 863688Sroot } 873688Sroot if (argc == 1) 883688Sroot argv[1] = argv[0]; 8913277Ssam cp = expand(argv[1]); 9013277Ssam if ((fd = creat(cp, 0666)) < 0) { 913688Sroot printf("\r\n%s: cannot create\r\n", argv[1]); 923688Sroot return; 933688Sroot } 9413137Sralph sprintf(line, "cat %s;echo \01", argv[0]); 953688Sroot transfer(line, fd, "\01"); 963688Sroot } 973688Sroot 9813277Ssam static jmp_buf intbuf; 993688Sroot /* 1003688Sroot * Bulk transfer routine -- 1013688Sroot * used by getfl(), cu_take(), and pipefile() 1023688Sroot */ 1033688Sroot transfer(buf, fd, eofchars) 1043688Sroot char *buf, *eofchars; 1053688Sroot { 1063688Sroot register int ct; 1073688Sroot char c, buffer[BUFSIZ]; 1083688Sroot register char *p = buffer; 1093688Sroot register int cnt, eof; 1103688Sroot time_t start; 111*39254Sbostic sig_t f; 1123688Sroot 11313137Sralph pwrite(FD, buf, size(buf)); 1143688Sroot quit = 0; 1153688Sroot kill(pid, SIGIOT); 1163688Sroot read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ 1173688Sroot 1183688Sroot /* 1193688Sroot * finish command 1203688Sroot */ 12113137Sralph pwrite(FD, "\r", 1); 1223688Sroot do 1233688Sroot read(FD, &c, 1); 1243688Sroot while ((c&0177) != '\n'); 1253688Sroot ioctl(0, TIOCSETC, &defchars); 1263688Sroot 12717186Sralph (void) setjmp(intbuf); 12813277Ssam f = signal(SIGINT, intcopy); 1293688Sroot start = time(0); 1303688Sroot for (ct = 0; !quit;) { 1313688Sroot eof = read(FD, &c, 1) <= 0; 1323688Sroot c &= 0177; 1333688Sroot if (quit) 1343688Sroot continue; 1353688Sroot if (eof || any(c, eofchars)) 1363688Sroot break; 1373688Sroot if (c == 0) 1383688Sroot continue; /* ignore nulls */ 1393688Sroot if (c == '\r') 1403688Sroot continue; 1413688Sroot *p++ = c; 1423688Sroot 1433688Sroot if (c == '\n' && boolean(value(VERBOSE))) 1443688Sroot printf("\r%d", ++ct); 1453688Sroot if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) { 1463688Sroot if (write(fd, buffer, cnt) != cnt) { 1473688Sroot printf("\r\nwrite error\r\n"); 1483688Sroot quit = 1; 1493688Sroot } 1503688Sroot p = buffer; 1513688Sroot } 1523688Sroot } 1533688Sroot if (cnt = (p-buffer)) 1543688Sroot if (write(fd, buffer, cnt) != cnt) 1553688Sroot printf("\r\nwrite error\r\n"); 1563688Sroot 1573688Sroot if (boolean(value(VERBOSE))) 1583688Sroot prtime(" lines transferred in ", time(0)-start); 1593688Sroot ioctl(0, TIOCSETC, &tchars); 1603688Sroot write(fildes[1], (char *)&ccc, 1); 16117186Sralph signal(SIGINT, f); 1623688Sroot close(fd); 1633688Sroot } 1643688Sroot 1653688Sroot /* 1663688Sroot * FTP - remote ==> local process 1673688Sroot * send remote input to local process via pipe 1683688Sroot */ 1693688Sroot pipefile() 1703688Sroot { 1713688Sroot int cpid, pdes[2]; 1723688Sroot char buf[256]; 1733688Sroot int status, p; 1743688Sroot extern int errno; 1753688Sroot 1763688Sroot if (prompt("Local command? ", buf)) 1773688Sroot return; 1783688Sroot 1793688Sroot if (pipe(pdes)) { 1803688Sroot printf("can't establish pipe\r\n"); 1813688Sroot return; 1823688Sroot } 1833688Sroot 1843688Sroot if ((cpid = fork()) < 0) { 1853688Sroot printf("can't fork!\r\n"); 1863688Sroot return; 1873688Sroot } else if (cpid) { 1883688Sroot if (prompt("List command for remote system? ", buf)) { 1893688Sroot close(pdes[0]), close(pdes[1]); 1903688Sroot kill (cpid, SIGKILL); 1913688Sroot } else { 1923688Sroot close(pdes[0]); 1933688Sroot signal(SIGPIPE, intcopy); 1943688Sroot transfer(buf, pdes[1], value(EOFREAD)); 1953688Sroot signal(SIGPIPE, SIG_DFL); 1963688Sroot while ((p = wait(&status)) > 0 && p != cpid) 1973688Sroot ; 1983688Sroot } 1993688Sroot } else { 2003688Sroot register int f; 2013688Sroot 2023688Sroot dup2(pdes[0], 0); 2033688Sroot close(pdes[0]); 2043688Sroot for (f = 3; f < 20; f++) 2053688Sroot close(f); 2063688Sroot execute(buf); 2073688Sroot printf("can't execl!\r\n"); 2083688Sroot exit(0); 2093688Sroot } 2103688Sroot } 2113688Sroot 2123688Sroot /* 2133688Sroot * Interrupt service routine for FTP 2143688Sroot */ 215*39254Sbostic void 2163688Sroot stopsnd() 2173688Sroot { 21813277Ssam 2193688Sroot stop = 1; 2203688Sroot signal(SIGINT, SIG_IGN); 2213688Sroot } 2223688Sroot 2233688Sroot /* 2243688Sroot * FTP - local ==> remote 2253688Sroot * send local file to remote host 2263688Sroot * terminate transmission with pseudo EOF sequence 2273688Sroot */ 2283688Sroot sendfile(cc) 2293688Sroot char cc; 2303688Sroot { 2313688Sroot FILE *fd; 23213137Sralph char *fnamex; 23313137Sralph char *expand(); 2343688Sroot 2353688Sroot putchar(cc); 2363688Sroot /* 2373688Sroot * get file name 2383688Sroot */ 2393688Sroot if (prompt("Local file name? ", fname)) 2403688Sroot return; 2413688Sroot 2423688Sroot /* 2433688Sroot * look up file 2443688Sroot */ 24513137Sralph fnamex = expand(fname); 24613137Sralph if ((fd = fopen(fnamex, "r")) == NULL) { 2473688Sroot printf("%s: cannot open\r\n", fname); 2483688Sroot return; 2493688Sroot } 2503688Sroot transmit(fd, value(EOFWRITE), NULL); 2513843Ssam if (!boolean(value(ECHOCHECK))) { 2523843Ssam struct sgttyb buf; 2533843Ssam 2543843Ssam ioctl(FD, TIOCGETP, &buf); /* this does a */ 2553843Ssam ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 2563843Ssam } 2573688Sroot } 2583688Sroot 2593688Sroot /* 2603688Sroot * Bulk transfer routine to remote host -- 2613688Sroot * used by sendfile() and cu_put() 2623688Sroot */ 2633688Sroot transmit(fd, eofchars, command) 2643688Sroot FILE *fd; 2653688Sroot char *eofchars, *command; 2663688Sroot { 26713137Sralph char *pc, lastc; 2683688Sroot int c, ccount, lcount; 2693688Sroot time_t start_t, stop_t; 270*39254Sbostic sig_t f; 2713688Sroot 2723688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 2733688Sroot stop = 0; 27417186Sralph f = signal(SIGINT, stopsnd); 2753688Sroot ioctl(0, TIOCSETC, &defchars); 2763688Sroot read(repdes[0], (char *)&ccc, 1); 2773688Sroot if (command != NULL) { 2783688Sroot for (pc = command; *pc; pc++) 2793688Sroot send(*pc); 2803843Ssam if (boolean(value(ECHOCHECK))) 2813843Ssam read(FD, (char *)&c, 1); /* trailing \n */ 2823843Ssam else { 2833843Ssam struct sgttyb buf; 2843843Ssam 2853843Ssam ioctl(FD, TIOCGETP, &buf); /* this does a */ 2863843Ssam ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 2873843Ssam sleep(5); /* wait for remote stty to take effect */ 2883843Ssam } 2893688Sroot } 2903688Sroot lcount = 0; 2913688Sroot lastc = '\0'; 2923688Sroot start_t = time(0); 2935133Ssam while (1) { 2943688Sroot ccount = 0; 2953688Sroot do { 2963688Sroot c = getc(fd); 2973688Sroot if (stop) 2983688Sroot goto out; 2993688Sroot if (c == EOF) 3003688Sroot goto out; 30113137Sralph if (c == 0177 && !boolean(value(RAWFTP))) 3023688Sroot continue; 3033688Sroot lastc = c; 3043688Sroot if (c < 040) { 30513137Sralph if (c == '\n') { 30613137Sralph if (!boolean(value(RAWFTP))) 30713137Sralph c = '\r'; 30813137Sralph } 3093688Sroot else if (c == '\t') { 31013137Sralph if (!boolean(value(RAWFTP))) { 31113137Sralph if (boolean(value(TABEXPAND))) { 3123688Sroot send(' '); 31313137Sralph while ((++ccount % 8) != 0) 31413137Sralph send(' '); 31513137Sralph continue; 31613137Sralph } 31713137Sralph } 31813137Sralph } else 31913137Sralph if (!boolean(value(RAWFTP))) 3203688Sroot continue; 3213688Sroot } 3223688Sroot send(c); 32313137Sralph } while (c != '\r' && !boolean(value(RAWFTP))); 3243688Sroot if (boolean(value(VERBOSE))) 3253688Sroot printf("\r%d", ++lcount); 3263843Ssam if (boolean(value(ECHOCHECK))) { 32717186Sralph timedout = 0; 32813137Sralph alarm(value(ETIMEOUT)); 3293843Ssam do { /* wait for prompt */ 33013137Sralph read(FD, (char *)&c, 1); 3313843Ssam if (timedout || stop) { 3323843Ssam if (timedout) 3333843Ssam printf("\r\ntimed out at eol\r\n"); 3343843Ssam alarm(0); 3353843Ssam goto out; 3363843Ssam } 33713137Sralph } while ((c&0177) != character(value(PROMPT))); 3383843Ssam alarm(0); 3393843Ssam } 3403688Sroot } 3413688Sroot out: 34213137Sralph if (lastc != '\n' && !boolean(value(RAWFTP))) 3433688Sroot send('\r'); 3443688Sroot for (pc = eofchars; *pc; pc++) 3453688Sroot send(*pc); 3463688Sroot stop_t = time(0); 3473688Sroot fclose(fd); 34817186Sralph signal(SIGINT, f); 3493688Sroot if (boolean(value(VERBOSE))) 35013137Sralph if (boolean(value(RAWFTP))) 35113137Sralph prtime(" chars transferred in ", stop_t-start_t); 35213137Sralph else 35313137Sralph prtime(" lines transferred in ", stop_t-start_t); 3543688Sroot write(fildes[1], (char *)&ccc, 1); 3553688Sroot ioctl(0, TIOCSETC, &tchars); 3563688Sroot } 3573688Sroot 3583688Sroot /* 3593688Sroot * Cu-like put command 3603688Sroot */ 3613688Sroot cu_put(cc) 3623688Sroot char cc; 3633688Sroot { 3643688Sroot FILE *fd; 3653688Sroot char line[BUFSIZ]; 3663688Sroot int argc; 36713137Sralph char *expand(); 36813137Sralph char *copynamex; 3693688Sroot 3703688Sroot if (prompt("[put] ", copyname)) 3713688Sroot return; 3723688Sroot if ((argc = args(copyname, argv)) < 1 || argc > 2) { 3733688Sroot printf("usage: <put> from [to]\r\n"); 3743688Sroot return; 3753688Sroot } 3763688Sroot if (argc == 1) 3773688Sroot argv[1] = argv[0]; 37813137Sralph copynamex = expand(argv[0]); 37913137Sralph if ((fd = fopen(copynamex, "r")) == NULL) { 38013137Sralph printf("%s: cannot open\r\n", copynamex); 3813688Sroot return; 3823688Sroot } 3833843Ssam if (boolean(value(ECHOCHECK))) 38413137Sralph sprintf(line, "cat>%s\r", argv[1]); 3853843Ssam else 38613137Sralph sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]); 3873688Sroot transmit(fd, "\04", line); 3883688Sroot } 3893688Sroot 3903688Sroot /* 3913688Sroot * FTP - send single character 3923688Sroot * wait for echo & handle timeout 3933688Sroot */ 3943688Sroot send(c) 3953688Sroot char c; 3963688Sroot { 3977588Sshannon char cc; 3983688Sroot int retry = 0; 3993688Sroot 4003688Sroot cc = c; 40113137Sralph pwrite(FD, &cc, 1); 40213137Sralph #ifdef notdef 40313137Sralph if (number(value(CDELAY)) > 0 && c != '\r') 40413137Sralph nap(number(value(CDELAY))); 40513137Sralph #endif 40613137Sralph if (!boolean(value(ECHOCHECK))) { 40713137Sralph #ifdef notdef 40813137Sralph if (number(value(LDELAY)) > 0 && c == '\r') 40913137Sralph nap(number(value(LDELAY))); 41013137Sralph #endif 4113843Ssam return; 41213137Sralph } 4133688Sroot tryagain: 4143688Sroot timedout = 0; 41513137Sralph alarm(value(ETIMEOUT)); 41613137Sralph read(FD, &cc, 1); 4173688Sroot alarm(0); 4183688Sroot if (timedout) { 4193688Sroot printf("\r\ntimeout error (%s)\r\n", ctrl(c)); 4203688Sroot if (retry++ > 3) 4213688Sroot return; 42213137Sralph pwrite(FD, &null, 1); /* poke it */ 4233688Sroot goto tryagain; 4243688Sroot } 4253688Sroot } 4263688Sroot 427*39254Sbostic void 4283688Sroot timeout() 4293688Sroot { 4303688Sroot signal(SIGALRM, timeout); 4313688Sroot timedout = 1; 4323688Sroot } 4333688Sroot 43425548Sdonn /* 43525548Sdonn * Stolen from consh() -- puts a remote file on the output of a local command. 43625548Sdonn * Identical to consh() except for where stdout goes. 43725548Sdonn */ 43825548Sdonn pipeout(c) 43925548Sdonn { 44025548Sdonn char buf[256]; 44125548Sdonn int cpid, status, p; 44225548Sdonn time_t start; 44325548Sdonn 44425548Sdonn putchar(c); 44525548Sdonn if (prompt("Local command? ", buf)) 44625548Sdonn return; 44725548Sdonn kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 44825548Sdonn signal(SIGINT, SIG_IGN); 44925548Sdonn signal(SIGQUIT, SIG_IGN); 45025548Sdonn ioctl(0, TIOCSETC, &defchars); 45125548Sdonn read(repdes[0], (char *)&ccc, 1); 45225548Sdonn /* 45325548Sdonn * Set up file descriptors in the child and 45425548Sdonn * let it go... 45525548Sdonn */ 45625548Sdonn if ((cpid = fork()) < 0) 45725548Sdonn printf("can't fork!\r\n"); 45825548Sdonn else if (cpid) { 45925548Sdonn start = time(0); 46025548Sdonn while ((p = wait(&status)) > 0 && p != cpid) 46125548Sdonn ; 46225548Sdonn } else { 46325548Sdonn register int i; 46425548Sdonn 46525548Sdonn dup2(FD, 1); 46625548Sdonn for (i = 3; i < 20; i++) 46725548Sdonn close(i); 46825548Sdonn signal(SIGINT, SIG_DFL); 46925548Sdonn signal(SIGQUIT, SIG_DFL); 47025548Sdonn execute(buf); 47125548Sdonn printf("can't find `%s'\r\n", buf); 47225548Sdonn exit(0); 47325548Sdonn } 47425548Sdonn if (boolean(value(VERBOSE))) 47525548Sdonn prtime("away for ", time(0)-start); 47625548Sdonn write(fildes[1], (char *)&ccc, 1); 47725548Sdonn ioctl(0, TIOCSETC, &tchars); 47825548Sdonn signal(SIGINT, SIG_DFL); 47925548Sdonn signal(SIGQUIT, SIG_DFL); 48025548Sdonn } 48125548Sdonn 4823688Sroot #ifdef CONNECT 4833688Sroot /* 4843688Sroot * Fork a program with: 4853688Sroot * 0 <-> local tty in 4863688Sroot * 1 <-> local tty out 4873688Sroot * 2 <-> local tty out 4883688Sroot * 3 <-> remote tty in 4893688Sroot * 4 <-> remote tty out 4903688Sroot */ 4913688Sroot consh(c) 4923688Sroot { 4933688Sroot char buf[256]; 4943688Sroot int cpid, status, p; 4953688Sroot time_t start; 4963688Sroot 4973688Sroot putchar(c); 4983688Sroot if (prompt("Local command? ", buf)) 4993688Sroot return; 5003688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 5013688Sroot signal(SIGINT, SIG_IGN); 5023688Sroot signal(SIGQUIT, SIG_IGN); 5033688Sroot ioctl(0, TIOCSETC, &defchars); 5043688Sroot read(repdes[0], (char *)&ccc, 1); 5053688Sroot /* 5063688Sroot * Set up file descriptors in the child and 5073688Sroot * let it go... 5083688Sroot */ 5093688Sroot if ((cpid = fork()) < 0) 5103688Sroot printf("can't fork!\r\n"); 5113688Sroot else if (cpid) { 5123688Sroot start = time(0); 5133688Sroot while ((p = wait(&status)) > 0 && p != cpid) 5143688Sroot ; 5153688Sroot } else { 5163688Sroot register int i; 5173688Sroot 5183688Sroot dup2(FD, 3); 5193688Sroot dup2(3, 4); 5203688Sroot for (i = 5; i < 20; i++) 5213688Sroot close(i); 5223688Sroot signal(SIGINT, SIG_DFL); 5233688Sroot signal(SIGQUIT, SIG_DFL); 5243688Sroot execute(buf); 5253688Sroot printf("can't find `%s'\r\n", buf); 5263688Sroot exit(0); 5273688Sroot } 5283688Sroot if (boolean(value(VERBOSE))) 5293688Sroot prtime("away for ", time(0)-start); 5303688Sroot write(fildes[1], (char *)&ccc, 1); 5313688Sroot ioctl(0, TIOCSETC, &tchars); 5323688Sroot signal(SIGINT, SIG_DFL); 5333688Sroot signal(SIGQUIT, SIG_DFL); 5343688Sroot } 5353688Sroot #endif 5363688Sroot 5373688Sroot /* 5383688Sroot * Escape to local shell 5393688Sroot */ 5403688Sroot shell() 5413688Sroot { 5423688Sroot int shpid, status; 5433688Sroot extern char **environ; 5443688Sroot char *cp; 5453688Sroot 5463688Sroot printf("[sh]\r\n"); 5473688Sroot signal(SIGINT, SIG_IGN); 5483688Sroot signal(SIGQUIT, SIG_IGN); 5493688Sroot unraw(); 5503688Sroot if (shpid = fork()) { 5513688Sroot while (shpid != wait(&status)); 5523688Sroot raw(); 5533688Sroot printf("\r\n!\r\n"); 5543688Sroot signal(SIGINT, SIG_DFL); 5553688Sroot signal(SIGQUIT, SIG_DFL); 5563688Sroot return; 5573688Sroot } else { 5583688Sroot signal(SIGQUIT, SIG_DFL); 5593688Sroot signal(SIGINT, SIG_DFL); 5603688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 5613688Sroot cp = value(SHELL); 5623688Sroot else 5633688Sroot cp++; 56430458Skarels shell_uid(); 5653688Sroot execl(value(SHELL), cp, 0); 5663688Sroot printf("\r\ncan't execl!\r\n"); 5673688Sroot exit(1); 5683688Sroot } 5693688Sroot } 5703688Sroot 5713688Sroot /* 5723688Sroot * TIPIN portion of scripting 5733688Sroot * initiate the conversation with TIPOUT 5743688Sroot */ 5753688Sroot setscript() 5763688Sroot { 5773688Sroot char c; 5783688Sroot /* 5793688Sroot * enable TIPOUT side for dialogue 5803688Sroot */ 5813688Sroot kill(pid, SIGEMT); 5823688Sroot if (boolean(value(SCRIPT))) 5833688Sroot write(fildes[1], value(RECORD), size(value(RECORD))); 5843688Sroot write(fildes[1], "\n", 1); 5853688Sroot /* 5863688Sroot * wait for TIPOUT to finish 5873688Sroot */ 5883688Sroot read(repdes[0], &c, 1); 5893688Sroot if (c == 'n') 5903688Sroot printf("can't create %s\r\n", value(RECORD)); 5913688Sroot } 5923688Sroot 5933688Sroot /* 5943688Sroot * Change current working directory of 5953688Sroot * local portion of tip 5963688Sroot */ 5973688Sroot chdirectory() 5983688Sroot { 59913277Ssam char dirname[80]; 6003688Sroot register char *cp = dirname; 6013688Sroot 60213277Ssam if (prompt("[cd] ", dirname)) { 6033688Sroot if (stoprompt) 6043688Sroot return; 60513277Ssam cp = value(HOME); 60613277Ssam } 6073688Sroot if (chdir(cp) < 0) 6083688Sroot printf("%s: bad directory\r\n", cp); 6093688Sroot printf("!\r\n"); 6103688Sroot } 6113688Sroot 61215187Ssam abort(msg) 61315187Ssam char *msg; 6143688Sroot { 61513137Sralph 6163688Sroot kill(pid, SIGTERM); 61715187Ssam disconnect(msg); 61815187Ssam if (msg != NOSTR) 61915187Ssam printf("\r\n%s", msg); 6203688Sroot printf("\r\n[EOT]\r\n"); 62130458Skarels daemon_uid(); 62235460Sbostic (void)uu_unlock(uucplock); 6233688Sroot unraw(); 6243688Sroot exit(0); 6253688Sroot } 6263688Sroot 62715187Ssam finish() 62815187Ssam { 62915187Ssam char *dismsg; 63015187Ssam 63115187Ssam if ((dismsg = value(DISCONNECT)) != NOSTR) { 63215187Ssam write(FD, dismsg, strlen(dismsg)); 63315187Ssam sleep(5); 63415187Ssam } 63515187Ssam abort(NOSTR); 63615187Ssam } 63715187Ssam 638*39254Sbostic void 6393688Sroot intcopy() 6403688Sroot { 6413688Sroot raw(); 6423688Sroot quit = 1; 64313277Ssam longjmp(intbuf, 1); 6443688Sroot } 6453688Sroot 6463688Sroot execute(s) 6473688Sroot char *s; 6483688Sroot { 6493688Sroot register char *cp; 6503688Sroot 6513688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 6523688Sroot cp = value(SHELL); 6533688Sroot else 6543688Sroot cp++; 65535777Sbostic shell_uid(); 6563688Sroot execl(value(SHELL), cp, "-c", s, 0); 6573688Sroot } 6583688Sroot 6593688Sroot args(buf, a) 6603688Sroot char *buf, *a[]; 6613688Sroot { 6623688Sroot register char *p = buf, *start; 6633688Sroot register char **parg = a; 6643688Sroot register int n = 0; 6653688Sroot 6663688Sroot do { 6673688Sroot while (*p && (*p == ' ' || *p == '\t')) 6683688Sroot p++; 6693688Sroot start = p; 6703688Sroot if (*p) 6713688Sroot *parg = p; 6723688Sroot while (*p && (*p != ' ' && *p != '\t')) 6733688Sroot p++; 6743688Sroot if (p != start) 6753688Sroot parg++, n++; 6763688Sroot if (*p) 6773688Sroot *p++ = '\0'; 6783688Sroot } while (*p); 6793688Sroot 6803688Sroot return(n); 6813688Sroot } 6823688Sroot 6833688Sroot prtime(s, a) 6843688Sroot char *s; 6853688Sroot time_t a; 6863688Sroot { 6873688Sroot register i; 6883688Sroot int nums[3]; 6893688Sroot 6903688Sroot for (i = 0; i < 3; i++) { 6913688Sroot nums[i] = (int)(a % quant[i]); 6923688Sroot a /= quant[i]; 6933688Sroot } 6943688Sroot printf("%s", s); 6953688Sroot while (--i >= 0) 69617186Sralph if (nums[i] || i == 0 && nums[1] == 0 && nums[2] == 0) 6973688Sroot printf("%d %s%c ", nums[i], sep[i], 6983688Sroot nums[i] == 1 ? '\0' : 's'); 6993688Sroot printf("\r\n!\r\n"); 7003688Sroot } 7013688Sroot 7023688Sroot variable() 7033688Sroot { 7043688Sroot char buf[256]; 7053688Sroot 7063688Sroot if (prompt("[set] ", buf)) 7073688Sroot return; 7083688Sroot vlex(buf); 7093688Sroot if (vtable[BEAUTIFY].v_access&CHANGED) { 7103688Sroot vtable[BEAUTIFY].v_access &= ~CHANGED; 7115333Sshannon kill(pid, SIGSYS); 7123688Sroot } 7133688Sroot if (vtable[SCRIPT].v_access&CHANGED) { 7143688Sroot vtable[SCRIPT].v_access &= ~CHANGED; 7153688Sroot setscript(); 7163865Ssam /* 7173865Ssam * So that "set record=blah script" doesn't 7183865Ssam * cause two transactions to occur. 7193865Ssam */ 7203865Ssam if (vtable[RECORD].v_access&CHANGED) 7213865Ssam vtable[RECORD].v_access &= ~CHANGED; 7223688Sroot } 7233688Sroot if (vtable[RECORD].v_access&CHANGED) { 7243688Sroot vtable[RECORD].v_access &= ~CHANGED; 7253688Sroot if (boolean(value(SCRIPT))) 7263688Sroot setscript(); 7273688Sroot } 72813137Sralph if (vtable[TAND].v_access&CHANGED) { 72913137Sralph vtable[TAND].v_access &= ~CHANGED; 73013137Sralph if (boolean(value(TAND))) 73113137Sralph tandem("on"); 73213137Sralph else 73313137Sralph tandem("off"); 73413137Sralph } 73513137Sralph if (vtable[LECHO].v_access&CHANGED) { 73613137Sralph vtable[LECHO].v_access &= ~CHANGED; 73713137Sralph HD = boolean(value(LECHO)); 73813137Sralph } 73913137Sralph if (vtable[PARITY].v_access&CHANGED) { 74013137Sralph vtable[PARITY].v_access &= ~CHANGED; 74113137Sralph setparity(); 74213137Sralph } 7433688Sroot } 7443822Ssam 7453822Ssam /* 74613277Ssam * Turn tandem mode on or off for remote tty. 74713137Sralph */ 74813137Sralph tandem(option) 74913277Ssam char *option; 75013137Sralph { 75113137Sralph struct sgttyb rmtty; 75213137Sralph 75313137Sralph ioctl(FD, TIOCGETP, &rmtty); 75413137Sralph if (strcmp(option,"on") == 0) { 75513137Sralph rmtty.sg_flags |= TANDEM; 75613137Sralph arg.sg_flags |= TANDEM; 75713277Ssam } else { 75813137Sralph rmtty.sg_flags &= ~TANDEM; 75913137Sralph arg.sg_flags &= ~TANDEM; 76013137Sralph } 76113137Sralph ioctl(FD, TIOCSETP, &rmtty); 76213137Sralph ioctl(0, TIOCSETP, &arg); 76313137Sralph } 76413137Sralph 76513137Sralph /* 7663822Ssam * Send a break. 7673822Ssam */ 7683822Ssam genbrk() 7693822Ssam { 77013277Ssam 7713822Ssam ioctl(FD, TIOCSBRK, NULL); 7723822Ssam sleep(1); 7733822Ssam ioctl(FD, TIOCCBRK, NULL); 7743822Ssam } 7755133Ssam 7765133Ssam /* 7775133Ssam * Suspend tip 7785133Ssam */ 77927702Ssam suspend(c) 78027702Ssam char c; 7815133Ssam { 78213277Ssam 7835133Ssam unraw(); 78433119Sbostic kill(c == CTRL('y') ? getpid() : 0, SIGTSTP); 7855133Ssam raw(); 7865133Ssam } 78713137Sralph 78813137Sralph /* 78913137Sralph * expand a file name if it includes shell meta characters 79013137Sralph */ 79113137Sralph 79213137Sralph char * 79313137Sralph expand(name) 79413137Sralph char name[]; 79513137Sralph { 79613137Sralph static char xname[BUFSIZ]; 79713137Sralph char cmdbuf[BUFSIZ]; 79813137Sralph register int pid, l, rc; 79913137Sralph register char *cp, *Shell; 80013137Sralph int s, pivec[2], (*sigint)(); 80113137Sralph 80213137Sralph if (!anyof(name, "~{[*?$`'\"\\")) 80313137Sralph return(name); 80413137Sralph /* sigint = signal(SIGINT, SIG_IGN); */ 80513137Sralph if (pipe(pivec) < 0) { 80613137Sralph perror("pipe"); 80713137Sralph /* signal(SIGINT, sigint) */ 80813137Sralph return(name); 80913137Sralph } 81013137Sralph sprintf(cmdbuf, "echo %s", name); 81113137Sralph if ((pid = vfork()) == 0) { 81213137Sralph Shell = value(SHELL); 81313137Sralph if (Shell == NOSTR) 81437857Sbostic Shell = _PATH_BSHELL; 81513137Sralph close(pivec[0]); 81613137Sralph close(1); 81713137Sralph dup(pivec[1]); 81813137Sralph close(pivec[1]); 81913137Sralph close(2); 82030458Skarels shell_uid(); 82113137Sralph execl(Shell, Shell, "-c", cmdbuf, 0); 82213137Sralph _exit(1); 82313137Sralph } 82413137Sralph if (pid == -1) { 82513137Sralph perror("fork"); 82613137Sralph close(pivec[0]); 82713137Sralph close(pivec[1]); 82813137Sralph return(NOSTR); 82913137Sralph } 83013137Sralph close(pivec[1]); 83113137Sralph l = read(pivec[0], xname, BUFSIZ); 83213137Sralph close(pivec[0]); 83313137Sralph while (wait(&s) != pid); 83413137Sralph ; 83513137Sralph s &= 0377; 83613137Sralph if (s != 0 && s != SIGPIPE) { 83713137Sralph fprintf(stderr, "\"Echo\" failed\n"); 83813137Sralph return(NOSTR); 83913137Sralph } 84013137Sralph if (l < 0) { 84113137Sralph perror("read"); 84213137Sralph return(NOSTR); 84313137Sralph } 84413137Sralph if (l == 0) { 84513137Sralph fprintf(stderr, "\"%s\": No match\n", name); 84613137Sralph return(NOSTR); 84713137Sralph } 84813137Sralph if (l == BUFSIZ) { 84913137Sralph fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name); 85013137Sralph return(NOSTR); 85113137Sralph } 85213137Sralph xname[l] = 0; 85313137Sralph for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) 85413137Sralph ; 85513137Sralph *++cp = '\0'; 85613137Sralph return(xname); 85713137Sralph } 85813137Sralph 85913137Sralph /* 86013137Sralph * Are any of the characters in the two strings the same? 86113137Sralph */ 86213137Sralph 86313137Sralph anyof(s1, s2) 86413137Sralph register char *s1, *s2; 86513137Sralph { 86613137Sralph register int c; 86713137Sralph 86813137Sralph while (c = *s1++) 86913137Sralph if (any(c, s2)) 87013137Sralph return(1); 87113137Sralph return(0); 87213137Sralph } 873