1*13277Ssam #ifndef lint 2*13277Ssam static char sccsid[] = "@(#)cmds.c 4.12 (Berkeley) 06/25/83"; 3*13277Ssam #endif 4*13277Ssam 53688Sroot #include "tip.h" 63688Sroot /* 73688Sroot * tip 83688Sroot * 93688Sroot * miscellaneous commands 103688Sroot */ 113688Sroot 123688Sroot int quant[] = { 60, 60, 24 }; 133688Sroot 143688Sroot char null = '\0'; 153688Sroot char *sep[] = { "second", "minute", "hour" }; 163688Sroot static char *argv[10]; /* argument vector for take and put */ 173688Sroot 183688Sroot int timeout(); /* timeout function called on alarm */ 193688Sroot int stopsnd(); /* SIGINT handler during file transfers */ 203688Sroot int intprompt(); /* used in handling SIG_INT during prompt */ 213688Sroot int intcopy(); /* interrupt routine for file transfers */ 223688Sroot 233688Sroot /* 243688Sroot * FTP - remote ==> local 253688Sroot * get a file from the remote host 263688Sroot */ 273688Sroot getfl(c) 283688Sroot char c; 293688Sroot { 30*13277Ssam char buf[256], *cp, *expand(); 313688Sroot 323688Sroot putchar(c); 333688Sroot /* 343688Sroot * get the UNIX receiving file's name 353688Sroot */ 363688Sroot if (prompt("Local file name? ", copyname)) 373688Sroot return; 38*13277Ssam cp = expand(copyname); 39*13277Ssam if ((sfd = creat(cp, 0666)) < 0) { 403688Sroot printf("\r\n%s: cannot creat\r\n", copyname); 413688Sroot return; 423688Sroot } 433688Sroot 443688Sroot /* 453688Sroot * collect parameters 463688Sroot */ 473688Sroot if (prompt("List command for remote system? ", buf)) { 483688Sroot unlink(copyname); 493688Sroot return; 503688Sroot } 513688Sroot transfer(buf, sfd, value(EOFREAD)); 523688Sroot } 533688Sroot 543688Sroot /* 553688Sroot * Cu-like take command 563688Sroot */ 573688Sroot cu_take(cc) 583688Sroot char cc; 593688Sroot { 603688Sroot int fd, argc; 61*13277Ssam char line[BUFSIZ], *expand(), *cp; 623688Sroot 633688Sroot if (prompt("[take] ", copyname)) 643688Sroot return; 653688Sroot if ((argc = args(copyname, argv)) < 1 || argc > 2) { 663688Sroot printf("usage: <take> from [to]\r\n"); 673688Sroot return; 683688Sroot } 693688Sroot if (argc == 1) 703688Sroot argv[1] = argv[0]; 71*13277Ssam cp = expand(argv[1]); 72*13277Ssam if ((fd = creat(cp, 0666)) < 0) { 733688Sroot printf("\r\n%s: cannot create\r\n", argv[1]); 743688Sroot return; 753688Sroot } 7613137Sralph sprintf(line, "cat %s;echo \01", argv[0]); 773688Sroot transfer(line, fd, "\01"); 783688Sroot } 793688Sroot 80*13277Ssam static jmp_buf intbuf; 813688Sroot /* 823688Sroot * Bulk transfer routine -- 833688Sroot * used by getfl(), cu_take(), and pipefile() 843688Sroot */ 853688Sroot transfer(buf, fd, eofchars) 863688Sroot char *buf, *eofchars; 873688Sroot { 883688Sroot register int ct; 893688Sroot char c, buffer[BUFSIZ]; 903688Sroot register char *p = buffer; 913688Sroot register int cnt, eof; 923688Sroot time_t start; 93*13277Ssam int (*f)(); 943688Sroot 9513137Sralph pwrite(FD, buf, size(buf)); 963688Sroot quit = 0; 973688Sroot kill(pid, SIGIOT); 983688Sroot read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ 993688Sroot 1003688Sroot /* 1013688Sroot * finish command 1023688Sroot */ 10313137Sralph pwrite(FD, "\r", 1); 1043688Sroot do 1053688Sroot read(FD, &c, 1); 1063688Sroot while ((c&0177) != '\n'); 1073688Sroot ioctl(0, TIOCSETC, &defchars); 1083688Sroot 109*13277Ssam f = signal(SIGINT, intcopy); 1103688Sroot start = time(0); 111*13277Ssam (void) setjmp(intbuf); 1123688Sroot for (ct = 0; !quit;) { 1133688Sroot eof = read(FD, &c, 1) <= 0; 1143688Sroot c &= 0177; 1153688Sroot if (quit) 1163688Sroot continue; 1173688Sroot if (eof || any(c, eofchars)) 1183688Sroot break; 1193688Sroot if (c == 0) 1203688Sroot continue; /* ignore nulls */ 1213688Sroot if (c == '\r') 1223688Sroot continue; 1233688Sroot *p++ = c; 1243688Sroot 1253688Sroot if (c == '\n' && boolean(value(VERBOSE))) 1263688Sroot printf("\r%d", ++ct); 1273688Sroot if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) { 1283688Sroot if (write(fd, buffer, cnt) != cnt) { 1293688Sroot printf("\r\nwrite error\r\n"); 1303688Sroot quit = 1; 1313688Sroot } 1323688Sroot p = buffer; 1333688Sroot } 1343688Sroot } 1353688Sroot if (cnt = (p-buffer)) 1363688Sroot if (write(fd, buffer, cnt) != cnt) 1373688Sroot printf("\r\nwrite error\r\n"); 1383688Sroot 1393688Sroot if (boolean(value(VERBOSE))) 1403688Sroot prtime(" lines transferred in ", time(0)-start); 1413688Sroot ioctl(0, TIOCSETC, &tchars); 1423688Sroot write(fildes[1], (char *)&ccc, 1); 1433688Sroot signal(SIGINT, SIG_DFL); 1443688Sroot close(fd); 1453688Sroot } 1463688Sroot 1473688Sroot /* 1483688Sroot * FTP - remote ==> local process 1493688Sroot * send remote input to local process via pipe 1503688Sroot */ 1513688Sroot pipefile() 1523688Sroot { 1533688Sroot int cpid, pdes[2]; 1543688Sroot char buf[256]; 1553688Sroot int status, p; 1563688Sroot extern int errno; 1573688Sroot 1583688Sroot if (prompt("Local command? ", buf)) 1593688Sroot return; 1603688Sroot 1613688Sroot if (pipe(pdes)) { 1623688Sroot printf("can't establish pipe\r\n"); 1633688Sroot return; 1643688Sroot } 1653688Sroot 1663688Sroot if ((cpid = fork()) < 0) { 1673688Sroot printf("can't fork!\r\n"); 1683688Sroot return; 1693688Sroot } else if (cpid) { 1703688Sroot if (prompt("List command for remote system? ", buf)) { 1713688Sroot close(pdes[0]), close(pdes[1]); 1723688Sroot kill (cpid, SIGKILL); 1733688Sroot } else { 1743688Sroot close(pdes[0]); 1753688Sroot signal(SIGPIPE, intcopy); 1763688Sroot transfer(buf, pdes[1], value(EOFREAD)); 1773688Sroot signal(SIGPIPE, SIG_DFL); 1783688Sroot while ((p = wait(&status)) > 0 && p != cpid) 1793688Sroot ; 1803688Sroot } 1813688Sroot } else { 1823688Sroot register int f; 1833688Sroot 1843688Sroot dup2(pdes[0], 0); 1853688Sroot close(pdes[0]); 1863688Sroot for (f = 3; f < 20; f++) 1873688Sroot close(f); 1883688Sroot execute(buf); 1893688Sroot printf("can't execl!\r\n"); 1903688Sroot exit(0); 1913688Sroot } 1923688Sroot } 1933688Sroot 1943688Sroot /* 1953688Sroot * Interrupt service routine for FTP 1963688Sroot */ 1973688Sroot stopsnd() 1983688Sroot { 199*13277Ssam 2003688Sroot stop = 1; 2013688Sroot signal(SIGINT, SIG_IGN); 2023688Sroot } 2033688Sroot 2043688Sroot /* 2053688Sroot * FTP - local ==> remote 2063688Sroot * send local file to remote host 2073688Sroot * terminate transmission with pseudo EOF sequence 2083688Sroot */ 2093688Sroot sendfile(cc) 2103688Sroot char cc; 2113688Sroot { 2123688Sroot FILE *fd; 21313137Sralph char *fnamex; 21413137Sralph char *expand(); 2153688Sroot 2163688Sroot putchar(cc); 2173688Sroot /* 2183688Sroot * get file name 2193688Sroot */ 2203688Sroot if (prompt("Local file name? ", fname)) 2213688Sroot return; 2223688Sroot 2233688Sroot /* 2243688Sroot * look up file 2253688Sroot */ 22613137Sralph fnamex = expand(fname); 22713137Sralph if ((fd = fopen(fnamex, "r")) == NULL) { 2283688Sroot printf("%s: cannot open\r\n", fname); 2293688Sroot return; 2303688Sroot } 2313688Sroot transmit(fd, value(EOFWRITE), NULL); 2323843Ssam if (!boolean(value(ECHOCHECK))) { 2333843Ssam struct sgttyb buf; 2343843Ssam 2353843Ssam ioctl(FD, TIOCGETP, &buf); /* this does a */ 2363843Ssam ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 2373843Ssam } 2383688Sroot } 2393688Sroot 2403688Sroot /* 2413688Sroot * Bulk transfer routine to remote host -- 2423688Sroot * used by sendfile() and cu_put() 2433688Sroot */ 2443688Sroot transmit(fd, eofchars, command) 2453688Sroot FILE *fd; 2463688Sroot char *eofchars, *command; 2473688Sroot { 24813137Sralph char *pc, lastc; 2493688Sroot int c, ccount, lcount; 2503688Sroot time_t start_t, stop_t; 2513688Sroot 2523688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 2533688Sroot signal(SIGINT, stopsnd); 2543688Sroot stop = 0; 2553688Sroot ioctl(0, TIOCSETC, &defchars); 2563688Sroot read(repdes[0], (char *)&ccc, 1); 2573688Sroot if (command != NULL) { 2583688Sroot for (pc = command; *pc; pc++) 2593688Sroot send(*pc); 2603843Ssam if (boolean(value(ECHOCHECK))) 2613843Ssam read(FD, (char *)&c, 1); /* trailing \n */ 2623843Ssam else { 2633843Ssam struct sgttyb buf; 2643843Ssam 2653843Ssam ioctl(FD, TIOCGETP, &buf); /* this does a */ 2663843Ssam ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 2673843Ssam sleep(5); /* wait for remote stty to take effect */ 2683843Ssam } 2693688Sroot } 2703688Sroot lcount = 0; 2713688Sroot lastc = '\0'; 2723688Sroot start_t = time(0); 2735133Ssam while (1) { 2743688Sroot ccount = 0; 2753688Sroot do { 2763688Sroot c = getc(fd); 2773688Sroot if (stop) 2783688Sroot goto out; 2793688Sroot if (c == EOF) 2803688Sroot goto out; 28113137Sralph if (c == 0177 && !boolean(value(RAWFTP))) 2823688Sroot continue; 2833688Sroot lastc = c; 2843688Sroot if (c < 040) { 28513137Sralph if (c == '\n') { 28613137Sralph if (!boolean(value(RAWFTP))) 28713137Sralph c = '\r'; 28813137Sralph } 2893688Sroot else if (c == '\t') { 29013137Sralph if (!boolean(value(RAWFTP))) { 29113137Sralph if (boolean(value(TABEXPAND))) { 2923688Sroot send(' '); 29313137Sralph while ((++ccount % 8) != 0) 29413137Sralph send(' '); 29513137Sralph continue; 29613137Sralph } 29713137Sralph } 29813137Sralph } else 29913137Sralph if (!boolean(value(RAWFTP))) 3003688Sroot continue; 3013688Sroot } 3023688Sroot send(c); 30313137Sralph } while (c != '\r' && !boolean(value(RAWFTP))); 3043688Sroot if (boolean(value(VERBOSE))) 3053688Sroot printf("\r%d", ++lcount); 3063843Ssam if (boolean(value(ECHOCHECK))) { 30713137Sralph alarm(value(ETIMEOUT)); 3083843Ssam timedout = 0; 3093843Ssam do { /* wait for prompt */ 31013137Sralph read(FD, (char *)&c, 1); 3113843Ssam if (timedout || stop) { 3123843Ssam if (timedout) 3133843Ssam printf("\r\ntimed out at eol\r\n"); 3143843Ssam alarm(0); 3153843Ssam goto out; 3163843Ssam } 31713137Sralph } while ((c&0177) != character(value(PROMPT))); 3183843Ssam alarm(0); 3193843Ssam } 3203688Sroot } 3213688Sroot out: 32213137Sralph if (lastc != '\n' && !boolean(value(RAWFTP))) 3233688Sroot send('\r'); 3243688Sroot for (pc = eofchars; *pc; pc++) 3253688Sroot send(*pc); 3263688Sroot stop_t = time(0); 3273688Sroot fclose(fd); 3283688Sroot signal(SIGINT, SIG_DFL); 3293688Sroot if (boolean(value(VERBOSE))) 33013137Sralph if (boolean(value(RAWFTP))) 33113137Sralph prtime(" chars transferred in ", stop_t-start_t); 33213137Sralph else 33313137Sralph prtime(" lines transferred in ", stop_t-start_t); 3343688Sroot write(fildes[1], (char *)&ccc, 1); 3353688Sroot ioctl(0, TIOCSETC, &tchars); 3363688Sroot } 3373688Sroot 3383688Sroot /* 3393688Sroot * Cu-like put command 3403688Sroot */ 3413688Sroot cu_put(cc) 3423688Sroot char cc; 3433688Sroot { 3443688Sroot FILE *fd; 3453688Sroot char line[BUFSIZ]; 3463688Sroot int argc; 34713137Sralph char *expand(); 34813137Sralph char *copynamex; 3493688Sroot 3503688Sroot if (prompt("[put] ", copyname)) 3513688Sroot return; 3523688Sroot if ((argc = args(copyname, argv)) < 1 || argc > 2) { 3533688Sroot printf("usage: <put> from [to]\r\n"); 3543688Sroot return; 3553688Sroot } 3563688Sroot if (argc == 1) 3573688Sroot argv[1] = argv[0]; 35813137Sralph copynamex = expand(argv[0]); 35913137Sralph if ((fd = fopen(copynamex, "r")) == NULL) { 36013137Sralph printf("%s: cannot open\r\n", copynamex); 3613688Sroot return; 3623688Sroot } 3633843Ssam if (boolean(value(ECHOCHECK))) 36413137Sralph sprintf(line, "cat>%s\r", argv[1]); 3653843Ssam else 36613137Sralph sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]); 3673688Sroot transmit(fd, "\04", line); 3683688Sroot } 3693688Sroot 3703688Sroot /* 3713688Sroot * FTP - send single character 3723688Sroot * wait for echo & handle timeout 3733688Sroot */ 3743688Sroot send(c) 3753688Sroot char c; 3763688Sroot { 3777588Sshannon char cc; 3783688Sroot int retry = 0; 3793688Sroot 3803688Sroot cc = c; 38113137Sralph pwrite(FD, &cc, 1); 38213137Sralph #ifdef notdef 38313137Sralph if (number(value(CDELAY)) > 0 && c != '\r') 38413137Sralph nap(number(value(CDELAY))); 38513137Sralph #endif 38613137Sralph if (!boolean(value(ECHOCHECK))) { 38713137Sralph #ifdef notdef 38813137Sralph if (number(value(LDELAY)) > 0 && c == '\r') 38913137Sralph nap(number(value(LDELAY))); 39013137Sralph #endif 3913843Ssam return; 39213137Sralph } 3933688Sroot tryagain: 3943688Sroot timedout = 0; 39513137Sralph alarm(value(ETIMEOUT)); 39613137Sralph read(FD, &cc, 1); 3973688Sroot alarm(0); 3983688Sroot if (timedout) { 3993688Sroot printf("\r\ntimeout error (%s)\r\n", ctrl(c)); 4003688Sroot if (retry++ > 3) 4013688Sroot return; 40213137Sralph pwrite(FD, &null, 1); /* poke it */ 4033688Sroot goto tryagain; 4043688Sroot } 4053688Sroot } 4063688Sroot 4073688Sroot timeout() 4083688Sroot { 4093688Sroot signal(SIGALRM, timeout); 4103688Sroot timedout = 1; 4113688Sroot } 4123688Sroot 4133688Sroot #ifdef CONNECT 4143688Sroot /* 4153688Sroot * Fork a program with: 4163688Sroot * 0 <-> local tty in 4173688Sroot * 1 <-> local tty out 4183688Sroot * 2 <-> local tty out 4193688Sroot * 3 <-> remote tty in 4203688Sroot * 4 <-> remote tty out 4213688Sroot */ 4223688Sroot consh(c) 4233688Sroot { 4243688Sroot char buf[256]; 4253688Sroot int cpid, status, p; 4263688Sroot time_t start; 4273688Sroot 4283688Sroot putchar(c); 4293688Sroot if (prompt("Local command? ", buf)) 4303688Sroot return; 4313688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 4323688Sroot signal(SIGINT, SIG_IGN); 4333688Sroot signal(SIGQUIT, SIG_IGN); 4343688Sroot ioctl(0, TIOCSETC, &defchars); 4353688Sroot read(repdes[0], (char *)&ccc, 1); 4363688Sroot /* 4373688Sroot * Set up file descriptors in the child and 4383688Sroot * let it go... 4393688Sroot */ 4403688Sroot if ((cpid = fork()) < 0) 4413688Sroot printf("can't fork!\r\n"); 4423688Sroot else if (cpid) { 4433688Sroot start = time(0); 4443688Sroot while ((p = wait(&status)) > 0 && p != cpid) 4453688Sroot ; 4463688Sroot } else { 4473688Sroot register int i; 4483688Sroot 4493688Sroot dup2(FD, 3); 4503688Sroot dup2(3, 4); 4513688Sroot for (i = 5; i < 20; i++) 4523688Sroot close(i); 4533688Sroot signal(SIGINT, SIG_DFL); 4543688Sroot signal(SIGQUIT, SIG_DFL); 4553688Sroot execute(buf); 4563688Sroot printf("can't find `%s'\r\n", buf); 4573688Sroot exit(0); 4583688Sroot } 4593688Sroot if (boolean(value(VERBOSE))) 4603688Sroot prtime("away for ", time(0)-start); 4613688Sroot write(fildes[1], (char *)&ccc, 1); 4623688Sroot ioctl(0, TIOCSETC, &tchars); 4633688Sroot signal(SIGINT, SIG_DFL); 4643688Sroot signal(SIGQUIT, SIG_DFL); 4653688Sroot } 4663688Sroot #endif 4673688Sroot 4683688Sroot /* 4693688Sroot * Escape to local shell 4703688Sroot */ 4713688Sroot shell() 4723688Sroot { 4733688Sroot int shpid, status; 4743688Sroot extern char **environ; 4753688Sroot char *cp; 4763688Sroot 4773688Sroot printf("[sh]\r\n"); 4783688Sroot signal(SIGINT, SIG_IGN); 4793688Sroot signal(SIGQUIT, SIG_IGN); 4803688Sroot unraw(); 4813688Sroot if (shpid = fork()) { 4823688Sroot while (shpid != wait(&status)); 4833688Sroot raw(); 4843688Sroot printf("\r\n!\r\n"); 4853688Sroot signal(SIGINT, SIG_DFL); 4863688Sroot signal(SIGQUIT, SIG_DFL); 4873688Sroot return; 4883688Sroot } else { 4893688Sroot signal(SIGQUIT, SIG_DFL); 4903688Sroot signal(SIGINT, SIG_DFL); 4913688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 4923688Sroot cp = value(SHELL); 4933688Sroot else 4943688Sroot cp++; 4953688Sroot execl(value(SHELL), cp, 0); 4963688Sroot printf("\r\ncan't execl!\r\n"); 4973688Sroot exit(1); 4983688Sroot } 4993688Sroot } 5003688Sroot 5013688Sroot /* 5023688Sroot * TIPIN portion of scripting 5033688Sroot * initiate the conversation with TIPOUT 5043688Sroot */ 5053688Sroot setscript() 5063688Sroot { 5073688Sroot char c; 5083688Sroot /* 5093688Sroot * enable TIPOUT side for dialogue 5103688Sroot */ 5113688Sroot kill(pid, SIGEMT); 5123688Sroot if (boolean(value(SCRIPT))) 5133688Sroot write(fildes[1], value(RECORD), size(value(RECORD))); 5143688Sroot write(fildes[1], "\n", 1); 5153688Sroot /* 5163688Sroot * wait for TIPOUT to finish 5173688Sroot */ 5183688Sroot read(repdes[0], &c, 1); 5193688Sroot if (c == 'n') 5203688Sroot printf("can't create %s\r\n", value(RECORD)); 5213688Sroot } 5223688Sroot 5233688Sroot /* 5243688Sroot * Change current working directory of 5253688Sroot * local portion of tip 5263688Sroot */ 5273688Sroot chdirectory() 5283688Sroot { 529*13277Ssam char dirname[80]; 5303688Sroot register char *cp = dirname; 5313688Sroot 532*13277Ssam if (prompt("[cd] ", dirname)) { 5333688Sroot if (stoprompt) 5343688Sroot return; 535*13277Ssam cp = value(HOME); 536*13277Ssam } 5373688Sroot if (chdir(cp) < 0) 5383688Sroot printf("%s: bad directory\r\n", cp); 5393688Sroot printf("!\r\n"); 5403688Sroot } 5413688Sroot 5423688Sroot finish() 5433688Sroot { 54413137Sralph char *dismsg; 54513137Sralph 54613137Sralph if ((dismsg = value(DISCONNECT)) != NOSTR) { 54713137Sralph write(FD,dismsg,strlen(dismsg)); 54813137Sralph sleep(5); 54913137Sralph } 5503688Sroot kill(pid, SIGTERM); 5513688Sroot disconnect(); 5523688Sroot printf("\r\n[EOT]\r\n"); 5533688Sroot delock(uucplock); 5543688Sroot unraw(); 5553688Sroot exit(0); 5563688Sroot } 5573688Sroot 5583688Sroot intcopy() 5593688Sroot { 560*13277Ssam 5613688Sroot raw(); 5623688Sroot quit = 1; 563*13277Ssam longjmp(intbuf, 1); 5643688Sroot } 5653688Sroot 5663688Sroot execute(s) 5673688Sroot char *s; 5683688Sroot { 5693688Sroot register char *cp; 5703688Sroot 5713688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 5723688Sroot cp = value(SHELL); 5733688Sroot else 5743688Sroot cp++; 5753688Sroot execl(value(SHELL), cp, "-c", s, 0); 5763688Sroot } 5773688Sroot 5783688Sroot args(buf, a) 5793688Sroot char *buf, *a[]; 5803688Sroot { 5813688Sroot register char *p = buf, *start; 5823688Sroot register char **parg = a; 5833688Sroot register int n = 0; 5843688Sroot 5853688Sroot do { 5863688Sroot while (*p && (*p == ' ' || *p == '\t')) 5873688Sroot p++; 5883688Sroot start = p; 5893688Sroot if (*p) 5903688Sroot *parg = p; 5913688Sroot while (*p && (*p != ' ' && *p != '\t')) 5923688Sroot p++; 5933688Sroot if (p != start) 5943688Sroot parg++, n++; 5953688Sroot if (*p) 5963688Sroot *p++ = '\0'; 5973688Sroot } while (*p); 5983688Sroot 5993688Sroot return(n); 6003688Sroot } 6013688Sroot 6023688Sroot prtime(s, a) 6033688Sroot char *s; 6043688Sroot time_t a; 6053688Sroot { 6063688Sroot register i; 6073688Sroot int nums[3]; 6083688Sroot 6093688Sroot for (i = 0; i < 3; i++) { 6103688Sroot nums[i] = (int)(a % quant[i]); 6113688Sroot a /= quant[i]; 6123688Sroot } 6133688Sroot printf("%s", s); 6143688Sroot while (--i >= 0) 6153688Sroot if (nums[i]) 6163688Sroot printf("%d %s%c ", nums[i], sep[i], 6173688Sroot nums[i] == 1 ? '\0' : 's'); 6183688Sroot printf("\r\n!\r\n"); 6193688Sroot } 6203688Sroot 6213688Sroot variable() 6223688Sroot { 6233688Sroot char buf[256]; 6243688Sroot 6253688Sroot if (prompt("[set] ", buf)) 6263688Sroot return; 6273688Sroot vlex(buf); 6283688Sroot if (vtable[BEAUTIFY].v_access&CHANGED) { 6293688Sroot vtable[BEAUTIFY].v_access &= ~CHANGED; 6305333Sshannon kill(pid, SIGSYS); 6313688Sroot } 6323688Sroot if (vtable[SCRIPT].v_access&CHANGED) { 6333688Sroot vtable[SCRIPT].v_access &= ~CHANGED; 6343688Sroot setscript(); 6353865Ssam /* 6363865Ssam * So that "set record=blah script" doesn't 6373865Ssam * cause two transactions to occur. 6383865Ssam */ 6393865Ssam if (vtable[RECORD].v_access&CHANGED) 6403865Ssam vtable[RECORD].v_access &= ~CHANGED; 6413688Sroot } 6423688Sroot if (vtable[RECORD].v_access&CHANGED) { 6433688Sroot vtable[RECORD].v_access &= ~CHANGED; 6443688Sroot if (boolean(value(SCRIPT))) 6453688Sroot setscript(); 6463688Sroot } 64713137Sralph if (vtable[TAND].v_access&CHANGED) { 64813137Sralph vtable[TAND].v_access &= ~CHANGED; 64913137Sralph if (boolean(value(TAND))) 65013137Sralph tandem("on"); 65113137Sralph else 65213137Sralph tandem("off"); 65313137Sralph } 65413137Sralph if (vtable[LECHO].v_access&CHANGED) { 65513137Sralph vtable[LECHO].v_access &= ~CHANGED; 65613137Sralph HD = boolean(value(LECHO)); 65713137Sralph } 65813137Sralph if (vtable[PARITY].v_access&CHANGED) { 65913137Sralph vtable[PARITY].v_access &= ~CHANGED; 66013137Sralph setparity(); 66113137Sralph } 6623688Sroot } 6633822Ssam 6643822Ssam /* 665*13277Ssam * Turn tandem mode on or off for remote tty. 66613137Sralph */ 66713137Sralph tandem(option) 668*13277Ssam char *option; 66913137Sralph { 67013137Sralph struct sgttyb rmtty; 67113137Sralph 67213137Sralph ioctl(FD, TIOCGETP, &rmtty); 67313137Sralph if (strcmp(option,"on") == 0) { 67413137Sralph rmtty.sg_flags |= TANDEM; 67513137Sralph arg.sg_flags |= TANDEM; 676*13277Ssam } else { 67713137Sralph rmtty.sg_flags &= ~TANDEM; 67813137Sralph arg.sg_flags &= ~TANDEM; 67913137Sralph } 68013137Sralph ioctl(FD, TIOCSETP, &rmtty); 68113137Sralph ioctl(0, TIOCSETP, &arg); 68213137Sralph } 68313137Sralph 68413137Sralph /* 6853822Ssam * Send a break. 6863822Ssam */ 6873822Ssam genbrk() 6883822Ssam { 689*13277Ssam 6903822Ssam ioctl(FD, TIOCSBRK, NULL); 6913822Ssam sleep(1); 6923822Ssam ioctl(FD, TIOCCBRK, NULL); 6933822Ssam } 6945133Ssam 6955133Ssam /* 6965133Ssam * Suspend tip 6975133Ssam */ 6985133Ssam suspend() 6995133Ssam { 700*13277Ssam 7015133Ssam unraw(); 7025133Ssam kill(0, SIGTSTP); 7035133Ssam raw(); 7045133Ssam } 70513137Sralph 70613137Sralph /* 70713137Sralph * expand a file name if it includes shell meta characters 70813137Sralph */ 70913137Sralph 71013137Sralph char * 71113137Sralph expand(name) 71213137Sralph char name[]; 71313137Sralph { 71413137Sralph static char xname[BUFSIZ]; 71513137Sralph char cmdbuf[BUFSIZ]; 71613137Sralph register int pid, l, rc; 71713137Sralph register char *cp, *Shell; 71813137Sralph int s, pivec[2], (*sigint)(); 71913137Sralph 72013137Sralph if (!anyof(name, "~{[*?$`'\"\\")) 72113137Sralph return(name); 72213137Sralph /* sigint = signal(SIGINT, SIG_IGN); */ 72313137Sralph if (pipe(pivec) < 0) { 72413137Sralph perror("pipe"); 72513137Sralph /* signal(SIGINT, sigint) */ 72613137Sralph return(name); 72713137Sralph } 72813137Sralph sprintf(cmdbuf, "echo %s", name); 72913137Sralph if ((pid = vfork()) == 0) { 73013137Sralph Shell = value(SHELL); 73113137Sralph if (Shell == NOSTR) 73213137Sralph Shell = "/bin/sh"; 73313137Sralph close(pivec[0]); 73413137Sralph close(1); 73513137Sralph dup(pivec[1]); 73613137Sralph close(pivec[1]); 73713137Sralph close(2); 73813137Sralph execl(Shell, Shell, "-c", cmdbuf, 0); 73913137Sralph _exit(1); 74013137Sralph } 74113137Sralph if (pid == -1) { 74213137Sralph perror("fork"); 74313137Sralph close(pivec[0]); 74413137Sralph close(pivec[1]); 74513137Sralph return(NOSTR); 74613137Sralph } 74713137Sralph close(pivec[1]); 74813137Sralph l = read(pivec[0], xname, BUFSIZ); 74913137Sralph close(pivec[0]); 75013137Sralph while (wait(&s) != pid); 75113137Sralph ; 75213137Sralph s &= 0377; 75313137Sralph if (s != 0 && s != SIGPIPE) { 75413137Sralph fprintf(stderr, "\"Echo\" failed\n"); 75513137Sralph return(NOSTR); 75613137Sralph } 75713137Sralph if (l < 0) { 75813137Sralph perror("read"); 75913137Sralph return(NOSTR); 76013137Sralph } 76113137Sralph if (l == 0) { 76213137Sralph fprintf(stderr, "\"%s\": No match\n", name); 76313137Sralph return(NOSTR); 76413137Sralph } 76513137Sralph if (l == BUFSIZ) { 76613137Sralph fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name); 76713137Sralph return(NOSTR); 76813137Sralph } 76913137Sralph xname[l] = 0; 77013137Sralph for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) 77113137Sralph ; 77213137Sralph *++cp = '\0'; 77313137Sralph return(xname); 77413137Sralph } 77513137Sralph 77613137Sralph /* 77713137Sralph * Are any of the characters in the two strings the same? 77813137Sralph */ 77913137Sralph 78013137Sralph anyof(s1, s2) 78113137Sralph register char *s1, *s2; 78213137Sralph { 78313137Sralph register int c; 78413137Sralph 78513137Sralph while (c = *s1++) 78613137Sralph if (any(c, s2)) 78713137Sralph return(1); 78813137Sralph return(0); 78913137Sralph } 790