113277Ssam #ifndef lint 2*17186Sralph static char sccsid[] = "@(#)cmds.c 4.14 (Berkeley) 09/12/84"; 313277Ssam #endif 413277Ssam 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 { 3013277Ssam 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; 3813277Ssam cp = expand(copyname); 3913277Ssam 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; 6113277Ssam 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]; 7113277Ssam cp = expand(argv[1]); 7213277Ssam 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 8013277Ssam 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; 9313277Ssam 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*17186Sralph (void) setjmp(intbuf); 11013277Ssam f = signal(SIGINT, intcopy); 1113688Sroot start = time(0); 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); 143*17186Sralph signal(SIGINT, f); 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 { 19913277Ssam 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; 251*17186Sralph int (*f)(); 2523688Sroot 2533688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 2543688Sroot stop = 0; 255*17186Sralph f = signal(SIGINT, stopsnd); 2563688Sroot ioctl(0, TIOCSETC, &defchars); 2573688Sroot read(repdes[0], (char *)&ccc, 1); 2583688Sroot if (command != NULL) { 2593688Sroot for (pc = command; *pc; pc++) 2603688Sroot send(*pc); 2613843Ssam if (boolean(value(ECHOCHECK))) 2623843Ssam read(FD, (char *)&c, 1); /* trailing \n */ 2633843Ssam else { 2643843Ssam struct sgttyb buf; 2653843Ssam 2663843Ssam ioctl(FD, TIOCGETP, &buf); /* this does a */ 2673843Ssam ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 2683843Ssam sleep(5); /* wait for remote stty to take effect */ 2693843Ssam } 2703688Sroot } 2713688Sroot lcount = 0; 2723688Sroot lastc = '\0'; 2733688Sroot start_t = time(0); 2745133Ssam while (1) { 2753688Sroot ccount = 0; 2763688Sroot do { 2773688Sroot c = getc(fd); 2783688Sroot if (stop) 2793688Sroot goto out; 2803688Sroot if (c == EOF) 2813688Sroot goto out; 28213137Sralph if (c == 0177 && !boolean(value(RAWFTP))) 2833688Sroot continue; 2843688Sroot lastc = c; 2853688Sroot if (c < 040) { 28613137Sralph if (c == '\n') { 28713137Sralph if (!boolean(value(RAWFTP))) 28813137Sralph c = '\r'; 28913137Sralph } 2903688Sroot else if (c == '\t') { 29113137Sralph if (!boolean(value(RAWFTP))) { 29213137Sralph if (boolean(value(TABEXPAND))) { 2933688Sroot send(' '); 29413137Sralph while ((++ccount % 8) != 0) 29513137Sralph send(' '); 29613137Sralph continue; 29713137Sralph } 29813137Sralph } 29913137Sralph } else 30013137Sralph if (!boolean(value(RAWFTP))) 3013688Sroot continue; 3023688Sroot } 3033688Sroot send(c); 30413137Sralph } while (c != '\r' && !boolean(value(RAWFTP))); 3053688Sroot if (boolean(value(VERBOSE))) 3063688Sroot printf("\r%d", ++lcount); 3073843Ssam if (boolean(value(ECHOCHECK))) { 308*17186Sralph timedout = 0; 30913137Sralph alarm(value(ETIMEOUT)); 3103843Ssam do { /* wait for prompt */ 31113137Sralph read(FD, (char *)&c, 1); 3123843Ssam if (timedout || stop) { 3133843Ssam if (timedout) 3143843Ssam printf("\r\ntimed out at eol\r\n"); 3153843Ssam alarm(0); 3163843Ssam goto out; 3173843Ssam } 31813137Sralph } while ((c&0177) != character(value(PROMPT))); 3193843Ssam alarm(0); 3203843Ssam } 3213688Sroot } 3223688Sroot out: 32313137Sralph if (lastc != '\n' && !boolean(value(RAWFTP))) 3243688Sroot send('\r'); 3253688Sroot for (pc = eofchars; *pc; pc++) 3263688Sroot send(*pc); 3273688Sroot stop_t = time(0); 3283688Sroot fclose(fd); 329*17186Sralph signal(SIGINT, f); 3303688Sroot if (boolean(value(VERBOSE))) 33113137Sralph if (boolean(value(RAWFTP))) 33213137Sralph prtime(" chars transferred in ", stop_t-start_t); 33313137Sralph else 33413137Sralph prtime(" lines transferred in ", stop_t-start_t); 3353688Sroot write(fildes[1], (char *)&ccc, 1); 3363688Sroot ioctl(0, TIOCSETC, &tchars); 3373688Sroot } 3383688Sroot 3393688Sroot /* 3403688Sroot * Cu-like put command 3413688Sroot */ 3423688Sroot cu_put(cc) 3433688Sroot char cc; 3443688Sroot { 3453688Sroot FILE *fd; 3463688Sroot char line[BUFSIZ]; 3473688Sroot int argc; 34813137Sralph char *expand(); 34913137Sralph char *copynamex; 3503688Sroot 3513688Sroot if (prompt("[put] ", copyname)) 3523688Sroot return; 3533688Sroot if ((argc = args(copyname, argv)) < 1 || argc > 2) { 3543688Sroot printf("usage: <put> from [to]\r\n"); 3553688Sroot return; 3563688Sroot } 3573688Sroot if (argc == 1) 3583688Sroot argv[1] = argv[0]; 35913137Sralph copynamex = expand(argv[0]); 36013137Sralph if ((fd = fopen(copynamex, "r")) == NULL) { 36113137Sralph printf("%s: cannot open\r\n", copynamex); 3623688Sroot return; 3633688Sroot } 3643843Ssam if (boolean(value(ECHOCHECK))) 36513137Sralph sprintf(line, "cat>%s\r", argv[1]); 3663843Ssam else 36713137Sralph sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]); 3683688Sroot transmit(fd, "\04", line); 3693688Sroot } 3703688Sroot 3713688Sroot /* 3723688Sroot * FTP - send single character 3733688Sroot * wait for echo & handle timeout 3743688Sroot */ 3753688Sroot send(c) 3763688Sroot char c; 3773688Sroot { 3787588Sshannon char cc; 3793688Sroot int retry = 0; 3803688Sroot 3813688Sroot cc = c; 38213137Sralph pwrite(FD, &cc, 1); 38313137Sralph #ifdef notdef 38413137Sralph if (number(value(CDELAY)) > 0 && c != '\r') 38513137Sralph nap(number(value(CDELAY))); 38613137Sralph #endif 38713137Sralph if (!boolean(value(ECHOCHECK))) { 38813137Sralph #ifdef notdef 38913137Sralph if (number(value(LDELAY)) > 0 && c == '\r') 39013137Sralph nap(number(value(LDELAY))); 39113137Sralph #endif 3923843Ssam return; 39313137Sralph } 3943688Sroot tryagain: 3953688Sroot timedout = 0; 39613137Sralph alarm(value(ETIMEOUT)); 39713137Sralph read(FD, &cc, 1); 3983688Sroot alarm(0); 3993688Sroot if (timedout) { 4003688Sroot printf("\r\ntimeout error (%s)\r\n", ctrl(c)); 4013688Sroot if (retry++ > 3) 4023688Sroot return; 40313137Sralph pwrite(FD, &null, 1); /* poke it */ 4043688Sroot goto tryagain; 4053688Sroot } 4063688Sroot } 4073688Sroot 4083688Sroot timeout() 4093688Sroot { 4103688Sroot signal(SIGALRM, timeout); 4113688Sroot timedout = 1; 4123688Sroot } 4133688Sroot 4143688Sroot #ifdef CONNECT 4153688Sroot /* 4163688Sroot * Fork a program with: 4173688Sroot * 0 <-> local tty in 4183688Sroot * 1 <-> local tty out 4193688Sroot * 2 <-> local tty out 4203688Sroot * 3 <-> remote tty in 4213688Sroot * 4 <-> remote tty out 4223688Sroot */ 4233688Sroot consh(c) 4243688Sroot { 4253688Sroot char buf[256]; 4263688Sroot int cpid, status, p; 4273688Sroot time_t start; 4283688Sroot 4293688Sroot putchar(c); 4303688Sroot if (prompt("Local command? ", buf)) 4313688Sroot return; 4323688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 4333688Sroot signal(SIGINT, SIG_IGN); 4343688Sroot signal(SIGQUIT, SIG_IGN); 4353688Sroot ioctl(0, TIOCSETC, &defchars); 4363688Sroot read(repdes[0], (char *)&ccc, 1); 4373688Sroot /* 4383688Sroot * Set up file descriptors in the child and 4393688Sroot * let it go... 4403688Sroot */ 4413688Sroot if ((cpid = fork()) < 0) 4423688Sroot printf("can't fork!\r\n"); 4433688Sroot else if (cpid) { 4443688Sroot start = time(0); 4453688Sroot while ((p = wait(&status)) > 0 && p != cpid) 4463688Sroot ; 4473688Sroot } else { 4483688Sroot register int i; 4493688Sroot 4503688Sroot dup2(FD, 3); 4513688Sroot dup2(3, 4); 4523688Sroot for (i = 5; i < 20; i++) 4533688Sroot close(i); 4543688Sroot signal(SIGINT, SIG_DFL); 4553688Sroot signal(SIGQUIT, SIG_DFL); 4563688Sroot execute(buf); 4573688Sroot printf("can't find `%s'\r\n", buf); 4583688Sroot exit(0); 4593688Sroot } 4603688Sroot if (boolean(value(VERBOSE))) 4613688Sroot prtime("away for ", time(0)-start); 4623688Sroot write(fildes[1], (char *)&ccc, 1); 4633688Sroot ioctl(0, TIOCSETC, &tchars); 4643688Sroot signal(SIGINT, SIG_DFL); 4653688Sroot signal(SIGQUIT, SIG_DFL); 4663688Sroot } 4673688Sroot #endif 4683688Sroot 4693688Sroot /* 4703688Sroot * Escape to local shell 4713688Sroot */ 4723688Sroot shell() 4733688Sroot { 4743688Sroot int shpid, status; 4753688Sroot extern char **environ; 4763688Sroot char *cp; 4773688Sroot 4783688Sroot printf("[sh]\r\n"); 4793688Sroot signal(SIGINT, SIG_IGN); 4803688Sroot signal(SIGQUIT, SIG_IGN); 4813688Sroot unraw(); 4823688Sroot if (shpid = fork()) { 4833688Sroot while (shpid != wait(&status)); 4843688Sroot raw(); 4853688Sroot printf("\r\n!\r\n"); 4863688Sroot signal(SIGINT, SIG_DFL); 4873688Sroot signal(SIGQUIT, SIG_DFL); 4883688Sroot return; 4893688Sroot } else { 4903688Sroot signal(SIGQUIT, SIG_DFL); 4913688Sroot signal(SIGINT, SIG_DFL); 4923688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 4933688Sroot cp = value(SHELL); 4943688Sroot else 4953688Sroot cp++; 4963688Sroot execl(value(SHELL), cp, 0); 4973688Sroot printf("\r\ncan't execl!\r\n"); 4983688Sroot exit(1); 4993688Sroot } 5003688Sroot } 5013688Sroot 5023688Sroot /* 5033688Sroot * TIPIN portion of scripting 5043688Sroot * initiate the conversation with TIPOUT 5053688Sroot */ 5063688Sroot setscript() 5073688Sroot { 5083688Sroot char c; 5093688Sroot /* 5103688Sroot * enable TIPOUT side for dialogue 5113688Sroot */ 5123688Sroot kill(pid, SIGEMT); 5133688Sroot if (boolean(value(SCRIPT))) 5143688Sroot write(fildes[1], value(RECORD), size(value(RECORD))); 5153688Sroot write(fildes[1], "\n", 1); 5163688Sroot /* 5173688Sroot * wait for TIPOUT to finish 5183688Sroot */ 5193688Sroot read(repdes[0], &c, 1); 5203688Sroot if (c == 'n') 5213688Sroot printf("can't create %s\r\n", value(RECORD)); 5223688Sroot } 5233688Sroot 5243688Sroot /* 5253688Sroot * Change current working directory of 5263688Sroot * local portion of tip 5273688Sroot */ 5283688Sroot chdirectory() 5293688Sroot { 53013277Ssam char dirname[80]; 5313688Sroot register char *cp = dirname; 5323688Sroot 53313277Ssam if (prompt("[cd] ", dirname)) { 5343688Sroot if (stoprompt) 5353688Sroot return; 53613277Ssam cp = value(HOME); 53713277Ssam } 5383688Sroot if (chdir(cp) < 0) 5393688Sroot printf("%s: bad directory\r\n", cp); 5403688Sroot printf("!\r\n"); 5413688Sroot } 5423688Sroot 54315187Ssam abort(msg) 54415187Ssam char *msg; 5453688Sroot { 54613137Sralph 5473688Sroot kill(pid, SIGTERM); 54815187Ssam disconnect(msg); 54915187Ssam if (msg != NOSTR) 55015187Ssam printf("\r\n%s", msg); 5513688Sroot printf("\r\n[EOT]\r\n"); 5523688Sroot delock(uucplock); 5533688Sroot unraw(); 5543688Sroot exit(0); 5553688Sroot } 5563688Sroot 55715187Ssam finish() 55815187Ssam { 55915187Ssam char *dismsg; 56015187Ssam 56115187Ssam if ((dismsg = value(DISCONNECT)) != NOSTR) { 56215187Ssam write(FD, dismsg, strlen(dismsg)); 56315187Ssam sleep(5); 56415187Ssam } 56515187Ssam abort(NOSTR); 56615187Ssam } 56715187Ssam 5683688Sroot intcopy() 5693688Sroot { 57013277Ssam 5713688Sroot raw(); 5723688Sroot quit = 1; 57313277Ssam longjmp(intbuf, 1); 5743688Sroot } 5753688Sroot 5763688Sroot execute(s) 5773688Sroot char *s; 5783688Sroot { 5793688Sroot register char *cp; 5803688Sroot 5813688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 5823688Sroot cp = value(SHELL); 5833688Sroot else 5843688Sroot cp++; 5853688Sroot execl(value(SHELL), cp, "-c", s, 0); 5863688Sroot } 5873688Sroot 5883688Sroot args(buf, a) 5893688Sroot char *buf, *a[]; 5903688Sroot { 5913688Sroot register char *p = buf, *start; 5923688Sroot register char **parg = a; 5933688Sroot register int n = 0; 5943688Sroot 5953688Sroot do { 5963688Sroot while (*p && (*p == ' ' || *p == '\t')) 5973688Sroot p++; 5983688Sroot start = p; 5993688Sroot if (*p) 6003688Sroot *parg = p; 6013688Sroot while (*p && (*p != ' ' && *p != '\t')) 6023688Sroot p++; 6033688Sroot if (p != start) 6043688Sroot parg++, n++; 6053688Sroot if (*p) 6063688Sroot *p++ = '\0'; 6073688Sroot } while (*p); 6083688Sroot 6093688Sroot return(n); 6103688Sroot } 6113688Sroot 6123688Sroot prtime(s, a) 6133688Sroot char *s; 6143688Sroot time_t a; 6153688Sroot { 6163688Sroot register i; 6173688Sroot int nums[3]; 6183688Sroot 6193688Sroot for (i = 0; i < 3; i++) { 6203688Sroot nums[i] = (int)(a % quant[i]); 6213688Sroot a /= quant[i]; 6223688Sroot } 6233688Sroot printf("%s", s); 6243688Sroot while (--i >= 0) 625*17186Sralph if (nums[i] || i == 0 && nums[1] == 0 && nums[2] == 0) 6263688Sroot printf("%d %s%c ", nums[i], sep[i], 6273688Sroot nums[i] == 1 ? '\0' : 's'); 6283688Sroot printf("\r\n!\r\n"); 6293688Sroot } 6303688Sroot 6313688Sroot variable() 6323688Sroot { 6333688Sroot char buf[256]; 6343688Sroot 6353688Sroot if (prompt("[set] ", buf)) 6363688Sroot return; 6373688Sroot vlex(buf); 6383688Sroot if (vtable[BEAUTIFY].v_access&CHANGED) { 6393688Sroot vtable[BEAUTIFY].v_access &= ~CHANGED; 6405333Sshannon kill(pid, SIGSYS); 6413688Sroot } 6423688Sroot if (vtable[SCRIPT].v_access&CHANGED) { 6433688Sroot vtable[SCRIPT].v_access &= ~CHANGED; 6443688Sroot setscript(); 6453865Ssam /* 6463865Ssam * So that "set record=blah script" doesn't 6473865Ssam * cause two transactions to occur. 6483865Ssam */ 6493865Ssam if (vtable[RECORD].v_access&CHANGED) 6503865Ssam vtable[RECORD].v_access &= ~CHANGED; 6513688Sroot } 6523688Sroot if (vtable[RECORD].v_access&CHANGED) { 6533688Sroot vtable[RECORD].v_access &= ~CHANGED; 6543688Sroot if (boolean(value(SCRIPT))) 6553688Sroot setscript(); 6563688Sroot } 65713137Sralph if (vtable[TAND].v_access&CHANGED) { 65813137Sralph vtable[TAND].v_access &= ~CHANGED; 65913137Sralph if (boolean(value(TAND))) 66013137Sralph tandem("on"); 66113137Sralph else 66213137Sralph tandem("off"); 66313137Sralph } 66413137Sralph if (vtable[LECHO].v_access&CHANGED) { 66513137Sralph vtable[LECHO].v_access &= ~CHANGED; 66613137Sralph HD = boolean(value(LECHO)); 66713137Sralph } 66813137Sralph if (vtable[PARITY].v_access&CHANGED) { 66913137Sralph vtable[PARITY].v_access &= ~CHANGED; 67013137Sralph setparity(); 67113137Sralph } 6723688Sroot } 6733822Ssam 6743822Ssam /* 67513277Ssam * Turn tandem mode on or off for remote tty. 67613137Sralph */ 67713137Sralph tandem(option) 67813277Ssam char *option; 67913137Sralph { 68013137Sralph struct sgttyb rmtty; 68113137Sralph 68213137Sralph ioctl(FD, TIOCGETP, &rmtty); 68313137Sralph if (strcmp(option,"on") == 0) { 68413137Sralph rmtty.sg_flags |= TANDEM; 68513137Sralph arg.sg_flags |= TANDEM; 68613277Ssam } else { 68713137Sralph rmtty.sg_flags &= ~TANDEM; 68813137Sralph arg.sg_flags &= ~TANDEM; 68913137Sralph } 69013137Sralph ioctl(FD, TIOCSETP, &rmtty); 69113137Sralph ioctl(0, TIOCSETP, &arg); 69213137Sralph } 69313137Sralph 69413137Sralph /* 6953822Ssam * Send a break. 6963822Ssam */ 6973822Ssam genbrk() 6983822Ssam { 69913277Ssam 7003822Ssam ioctl(FD, TIOCSBRK, NULL); 7013822Ssam sleep(1); 7023822Ssam ioctl(FD, TIOCCBRK, NULL); 7033822Ssam } 7045133Ssam 7055133Ssam /* 7065133Ssam * Suspend tip 7075133Ssam */ 7085133Ssam suspend() 7095133Ssam { 71013277Ssam 7115133Ssam unraw(); 7125133Ssam kill(0, SIGTSTP); 7135133Ssam raw(); 7145133Ssam } 71513137Sralph 71613137Sralph /* 71713137Sralph * expand a file name if it includes shell meta characters 71813137Sralph */ 71913137Sralph 72013137Sralph char * 72113137Sralph expand(name) 72213137Sralph char name[]; 72313137Sralph { 72413137Sralph static char xname[BUFSIZ]; 72513137Sralph char cmdbuf[BUFSIZ]; 72613137Sralph register int pid, l, rc; 72713137Sralph register char *cp, *Shell; 72813137Sralph int s, pivec[2], (*sigint)(); 72913137Sralph 73013137Sralph if (!anyof(name, "~{[*?$`'\"\\")) 73113137Sralph return(name); 73213137Sralph /* sigint = signal(SIGINT, SIG_IGN); */ 73313137Sralph if (pipe(pivec) < 0) { 73413137Sralph perror("pipe"); 73513137Sralph /* signal(SIGINT, sigint) */ 73613137Sralph return(name); 73713137Sralph } 73813137Sralph sprintf(cmdbuf, "echo %s", name); 73913137Sralph if ((pid = vfork()) == 0) { 74013137Sralph Shell = value(SHELL); 74113137Sralph if (Shell == NOSTR) 74213137Sralph Shell = "/bin/sh"; 74313137Sralph close(pivec[0]); 74413137Sralph close(1); 74513137Sralph dup(pivec[1]); 74613137Sralph close(pivec[1]); 74713137Sralph close(2); 74813137Sralph execl(Shell, Shell, "-c", cmdbuf, 0); 74913137Sralph _exit(1); 75013137Sralph } 75113137Sralph if (pid == -1) { 75213137Sralph perror("fork"); 75313137Sralph close(pivec[0]); 75413137Sralph close(pivec[1]); 75513137Sralph return(NOSTR); 75613137Sralph } 75713137Sralph close(pivec[1]); 75813137Sralph l = read(pivec[0], xname, BUFSIZ); 75913137Sralph close(pivec[0]); 76013137Sralph while (wait(&s) != pid); 76113137Sralph ; 76213137Sralph s &= 0377; 76313137Sralph if (s != 0 && s != SIGPIPE) { 76413137Sralph fprintf(stderr, "\"Echo\" failed\n"); 76513137Sralph return(NOSTR); 76613137Sralph } 76713137Sralph if (l < 0) { 76813137Sralph perror("read"); 76913137Sralph return(NOSTR); 77013137Sralph } 77113137Sralph if (l == 0) { 77213137Sralph fprintf(stderr, "\"%s\": No match\n", name); 77313137Sralph return(NOSTR); 77413137Sralph } 77513137Sralph if (l == BUFSIZ) { 77613137Sralph fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name); 77713137Sralph return(NOSTR); 77813137Sralph } 77913137Sralph xname[l] = 0; 78013137Sralph for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) 78113137Sralph ; 78213137Sralph *++cp = '\0'; 78313137Sralph return(xname); 78413137Sralph } 78513137Sralph 78613137Sralph /* 78713137Sralph * Are any of the characters in the two strings the same? 78813137Sralph */ 78913137Sralph 79013137Sralph anyof(s1, s2) 79113137Sralph register char *s1, *s2; 79213137Sralph { 79313137Sralph register int c; 79413137Sralph 79513137Sralph while (c = *s1++) 79613137Sralph if (any(c, s2)) 79713137Sralph return(1); 79813137Sralph return(0); 79913137Sralph } 800