119814Sdist /* 219814Sdist * Copyright (c) 1983 Regents of the University of California. 319814Sdist * All rights reserved. The Berkeley software License Agreement 419814Sdist * specifies the terms and conditions for redistribution. 519814Sdist */ 619814Sdist 713277Ssam #ifndef lint 8*30458Skarels static char sccsid[] = "@(#)cmds.c 5.5 (Berkeley) 02/09/87"; 919814Sdist #endif not lint 1013277Ssam 113688Sroot #include "tip.h" 123688Sroot /* 133688Sroot * tip 143688Sroot * 153688Sroot * miscellaneous commands 163688Sroot */ 173688Sroot 183688Sroot int quant[] = { 60, 60, 24 }; 193688Sroot 203688Sroot char null = '\0'; 213688Sroot char *sep[] = { "second", "minute", "hour" }; 223688Sroot static char *argv[10]; /* argument vector for take and put */ 233688Sroot 243688Sroot int timeout(); /* timeout function called on alarm */ 253688Sroot int stopsnd(); /* SIGINT handler during file transfers */ 263688Sroot int intprompt(); /* used in handling SIG_INT during prompt */ 273688Sroot int intcopy(); /* interrupt routine for file transfers */ 283688Sroot 293688Sroot /* 303688Sroot * FTP - remote ==> local 313688Sroot * get a file from the remote host 323688Sroot */ 333688Sroot getfl(c) 343688Sroot char c; 353688Sroot { 3613277Ssam char buf[256], *cp, *expand(); 373688Sroot 383688Sroot putchar(c); 393688Sroot /* 403688Sroot * get the UNIX receiving file's name 413688Sroot */ 423688Sroot if (prompt("Local file name? ", copyname)) 433688Sroot return; 4413277Ssam cp = expand(copyname); 4513277Ssam if ((sfd = creat(cp, 0666)) < 0) { 463688Sroot printf("\r\n%s: cannot creat\r\n", copyname); 473688Sroot return; 483688Sroot } 493688Sroot 503688Sroot /* 513688Sroot * collect parameters 523688Sroot */ 533688Sroot if (prompt("List command for remote system? ", buf)) { 543688Sroot unlink(copyname); 553688Sroot return; 563688Sroot } 573688Sroot transfer(buf, sfd, value(EOFREAD)); 583688Sroot } 593688Sroot 603688Sroot /* 613688Sroot * Cu-like take command 623688Sroot */ 633688Sroot cu_take(cc) 643688Sroot char cc; 653688Sroot { 663688Sroot int fd, argc; 6713277Ssam char line[BUFSIZ], *expand(), *cp; 683688Sroot 693688Sroot if (prompt("[take] ", copyname)) 703688Sroot return; 713688Sroot if ((argc = args(copyname, argv)) < 1 || argc > 2) { 723688Sroot printf("usage: <take> from [to]\r\n"); 733688Sroot return; 743688Sroot } 753688Sroot if (argc == 1) 763688Sroot argv[1] = argv[0]; 7713277Ssam cp = expand(argv[1]); 7813277Ssam if ((fd = creat(cp, 0666)) < 0) { 793688Sroot printf("\r\n%s: cannot create\r\n", argv[1]); 803688Sroot return; 813688Sroot } 8213137Sralph sprintf(line, "cat %s;echo \01", argv[0]); 833688Sroot transfer(line, fd, "\01"); 843688Sroot } 853688Sroot 8613277Ssam static jmp_buf intbuf; 873688Sroot /* 883688Sroot * Bulk transfer routine -- 893688Sroot * used by getfl(), cu_take(), and pipefile() 903688Sroot */ 913688Sroot transfer(buf, fd, eofchars) 923688Sroot char *buf, *eofchars; 933688Sroot { 943688Sroot register int ct; 953688Sroot char c, buffer[BUFSIZ]; 963688Sroot register char *p = buffer; 973688Sroot register int cnt, eof; 983688Sroot time_t start; 9913277Ssam int (*f)(); 1003688Sroot 10113137Sralph pwrite(FD, buf, size(buf)); 1023688Sroot quit = 0; 1033688Sroot kill(pid, SIGIOT); 1043688Sroot read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ 1053688Sroot 1063688Sroot /* 1073688Sroot * finish command 1083688Sroot */ 10913137Sralph pwrite(FD, "\r", 1); 1103688Sroot do 1113688Sroot read(FD, &c, 1); 1123688Sroot while ((c&0177) != '\n'); 1133688Sroot ioctl(0, TIOCSETC, &defchars); 1143688Sroot 11517186Sralph (void) setjmp(intbuf); 11613277Ssam f = signal(SIGINT, intcopy); 1173688Sroot start = time(0); 1183688Sroot for (ct = 0; !quit;) { 1193688Sroot eof = read(FD, &c, 1) <= 0; 1203688Sroot c &= 0177; 1213688Sroot if (quit) 1223688Sroot continue; 1233688Sroot if (eof || any(c, eofchars)) 1243688Sroot break; 1253688Sroot if (c == 0) 1263688Sroot continue; /* ignore nulls */ 1273688Sroot if (c == '\r') 1283688Sroot continue; 1293688Sroot *p++ = c; 1303688Sroot 1313688Sroot if (c == '\n' && boolean(value(VERBOSE))) 1323688Sroot printf("\r%d", ++ct); 1333688Sroot if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) { 1343688Sroot if (write(fd, buffer, cnt) != cnt) { 1353688Sroot printf("\r\nwrite error\r\n"); 1363688Sroot quit = 1; 1373688Sroot } 1383688Sroot p = buffer; 1393688Sroot } 1403688Sroot } 1413688Sroot if (cnt = (p-buffer)) 1423688Sroot if (write(fd, buffer, cnt) != cnt) 1433688Sroot printf("\r\nwrite error\r\n"); 1443688Sroot 1453688Sroot if (boolean(value(VERBOSE))) 1463688Sroot prtime(" lines transferred in ", time(0)-start); 1473688Sroot ioctl(0, TIOCSETC, &tchars); 1483688Sroot write(fildes[1], (char *)&ccc, 1); 14917186Sralph signal(SIGINT, f); 1503688Sroot close(fd); 1513688Sroot } 1523688Sroot 1533688Sroot /* 1543688Sroot * FTP - remote ==> local process 1553688Sroot * send remote input to local process via pipe 1563688Sroot */ 1573688Sroot pipefile() 1583688Sroot { 1593688Sroot int cpid, pdes[2]; 1603688Sroot char buf[256]; 1613688Sroot int status, p; 1623688Sroot extern int errno; 1633688Sroot 1643688Sroot if (prompt("Local command? ", buf)) 1653688Sroot return; 1663688Sroot 1673688Sroot if (pipe(pdes)) { 1683688Sroot printf("can't establish pipe\r\n"); 1693688Sroot return; 1703688Sroot } 1713688Sroot 1723688Sroot if ((cpid = fork()) < 0) { 1733688Sroot printf("can't fork!\r\n"); 1743688Sroot return; 1753688Sroot } else if (cpid) { 1763688Sroot if (prompt("List command for remote system? ", buf)) { 1773688Sroot close(pdes[0]), close(pdes[1]); 1783688Sroot kill (cpid, SIGKILL); 1793688Sroot } else { 1803688Sroot close(pdes[0]); 1813688Sroot signal(SIGPIPE, intcopy); 1823688Sroot transfer(buf, pdes[1], value(EOFREAD)); 1833688Sroot signal(SIGPIPE, SIG_DFL); 1843688Sroot while ((p = wait(&status)) > 0 && p != cpid) 1853688Sroot ; 1863688Sroot } 1873688Sroot } else { 1883688Sroot register int f; 1893688Sroot 1903688Sroot dup2(pdes[0], 0); 1913688Sroot close(pdes[0]); 1923688Sroot for (f = 3; f < 20; f++) 1933688Sroot close(f); 1943688Sroot execute(buf); 1953688Sroot printf("can't execl!\r\n"); 1963688Sroot exit(0); 1973688Sroot } 1983688Sroot } 1993688Sroot 2003688Sroot /* 2013688Sroot * Interrupt service routine for FTP 2023688Sroot */ 2033688Sroot stopsnd() 2043688Sroot { 20513277Ssam 2063688Sroot stop = 1; 2073688Sroot signal(SIGINT, SIG_IGN); 2083688Sroot } 2093688Sroot 2103688Sroot /* 2113688Sroot * FTP - local ==> remote 2123688Sroot * send local file to remote host 2133688Sroot * terminate transmission with pseudo EOF sequence 2143688Sroot */ 2153688Sroot sendfile(cc) 2163688Sroot char cc; 2173688Sroot { 2183688Sroot FILE *fd; 21913137Sralph char *fnamex; 22013137Sralph char *expand(); 2213688Sroot 2223688Sroot putchar(cc); 2233688Sroot /* 2243688Sroot * get file name 2253688Sroot */ 2263688Sroot if (prompt("Local file name? ", fname)) 2273688Sroot return; 2283688Sroot 2293688Sroot /* 2303688Sroot * look up file 2313688Sroot */ 23213137Sralph fnamex = expand(fname); 23313137Sralph if ((fd = fopen(fnamex, "r")) == NULL) { 2343688Sroot printf("%s: cannot open\r\n", fname); 2353688Sroot return; 2363688Sroot } 2373688Sroot transmit(fd, value(EOFWRITE), NULL); 2383843Ssam if (!boolean(value(ECHOCHECK))) { 2393843Ssam struct sgttyb buf; 2403843Ssam 2413843Ssam ioctl(FD, TIOCGETP, &buf); /* this does a */ 2423843Ssam ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 2433843Ssam } 2443688Sroot } 2453688Sroot 2463688Sroot /* 2473688Sroot * Bulk transfer routine to remote host -- 2483688Sroot * used by sendfile() and cu_put() 2493688Sroot */ 2503688Sroot transmit(fd, eofchars, command) 2513688Sroot FILE *fd; 2523688Sroot char *eofchars, *command; 2533688Sroot { 25413137Sralph char *pc, lastc; 2553688Sroot int c, ccount, lcount; 2563688Sroot time_t start_t, stop_t; 25717186Sralph int (*f)(); 2583688Sroot 2593688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 2603688Sroot stop = 0; 26117186Sralph f = signal(SIGINT, stopsnd); 2623688Sroot ioctl(0, TIOCSETC, &defchars); 2633688Sroot read(repdes[0], (char *)&ccc, 1); 2643688Sroot if (command != NULL) { 2653688Sroot for (pc = command; *pc; pc++) 2663688Sroot send(*pc); 2673843Ssam if (boolean(value(ECHOCHECK))) 2683843Ssam read(FD, (char *)&c, 1); /* trailing \n */ 2693843Ssam else { 2703843Ssam struct sgttyb buf; 2713843Ssam 2723843Ssam ioctl(FD, TIOCGETP, &buf); /* this does a */ 2733843Ssam ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 2743843Ssam sleep(5); /* wait for remote stty to take effect */ 2753843Ssam } 2763688Sroot } 2773688Sroot lcount = 0; 2783688Sroot lastc = '\0'; 2793688Sroot start_t = time(0); 2805133Ssam while (1) { 2813688Sroot ccount = 0; 2823688Sroot do { 2833688Sroot c = getc(fd); 2843688Sroot if (stop) 2853688Sroot goto out; 2863688Sroot if (c == EOF) 2873688Sroot goto out; 28813137Sralph if (c == 0177 && !boolean(value(RAWFTP))) 2893688Sroot continue; 2903688Sroot lastc = c; 2913688Sroot if (c < 040) { 29213137Sralph if (c == '\n') { 29313137Sralph if (!boolean(value(RAWFTP))) 29413137Sralph c = '\r'; 29513137Sralph } 2963688Sroot else if (c == '\t') { 29713137Sralph if (!boolean(value(RAWFTP))) { 29813137Sralph if (boolean(value(TABEXPAND))) { 2993688Sroot send(' '); 30013137Sralph while ((++ccount % 8) != 0) 30113137Sralph send(' '); 30213137Sralph continue; 30313137Sralph } 30413137Sralph } 30513137Sralph } else 30613137Sralph if (!boolean(value(RAWFTP))) 3073688Sroot continue; 3083688Sroot } 3093688Sroot send(c); 31013137Sralph } while (c != '\r' && !boolean(value(RAWFTP))); 3113688Sroot if (boolean(value(VERBOSE))) 3123688Sroot printf("\r%d", ++lcount); 3133843Ssam if (boolean(value(ECHOCHECK))) { 31417186Sralph timedout = 0; 31513137Sralph alarm(value(ETIMEOUT)); 3163843Ssam do { /* wait for prompt */ 31713137Sralph read(FD, (char *)&c, 1); 3183843Ssam if (timedout || stop) { 3193843Ssam if (timedout) 3203843Ssam printf("\r\ntimed out at eol\r\n"); 3213843Ssam alarm(0); 3223843Ssam goto out; 3233843Ssam } 32413137Sralph } while ((c&0177) != character(value(PROMPT))); 3253843Ssam alarm(0); 3263843Ssam } 3273688Sroot } 3283688Sroot out: 32913137Sralph if (lastc != '\n' && !boolean(value(RAWFTP))) 3303688Sroot send('\r'); 3313688Sroot for (pc = eofchars; *pc; pc++) 3323688Sroot send(*pc); 3333688Sroot stop_t = time(0); 3343688Sroot fclose(fd); 33517186Sralph signal(SIGINT, f); 3363688Sroot if (boolean(value(VERBOSE))) 33713137Sralph if (boolean(value(RAWFTP))) 33813137Sralph prtime(" chars transferred in ", stop_t-start_t); 33913137Sralph else 34013137Sralph prtime(" lines transferred in ", stop_t-start_t); 3413688Sroot write(fildes[1], (char *)&ccc, 1); 3423688Sroot ioctl(0, TIOCSETC, &tchars); 3433688Sroot } 3443688Sroot 3453688Sroot /* 3463688Sroot * Cu-like put command 3473688Sroot */ 3483688Sroot cu_put(cc) 3493688Sroot char cc; 3503688Sroot { 3513688Sroot FILE *fd; 3523688Sroot char line[BUFSIZ]; 3533688Sroot int argc; 35413137Sralph char *expand(); 35513137Sralph char *copynamex; 3563688Sroot 3573688Sroot if (prompt("[put] ", copyname)) 3583688Sroot return; 3593688Sroot if ((argc = args(copyname, argv)) < 1 || argc > 2) { 3603688Sroot printf("usage: <put> from [to]\r\n"); 3613688Sroot return; 3623688Sroot } 3633688Sroot if (argc == 1) 3643688Sroot argv[1] = argv[0]; 36513137Sralph copynamex = expand(argv[0]); 36613137Sralph if ((fd = fopen(copynamex, "r")) == NULL) { 36713137Sralph printf("%s: cannot open\r\n", copynamex); 3683688Sroot return; 3693688Sroot } 3703843Ssam if (boolean(value(ECHOCHECK))) 37113137Sralph sprintf(line, "cat>%s\r", argv[1]); 3723843Ssam else 37313137Sralph sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]); 3743688Sroot transmit(fd, "\04", line); 3753688Sroot } 3763688Sroot 3773688Sroot /* 3783688Sroot * FTP - send single character 3793688Sroot * wait for echo & handle timeout 3803688Sroot */ 3813688Sroot send(c) 3823688Sroot char c; 3833688Sroot { 3847588Sshannon char cc; 3853688Sroot int retry = 0; 3863688Sroot 3873688Sroot cc = c; 38813137Sralph pwrite(FD, &cc, 1); 38913137Sralph #ifdef notdef 39013137Sralph if (number(value(CDELAY)) > 0 && c != '\r') 39113137Sralph nap(number(value(CDELAY))); 39213137Sralph #endif 39313137Sralph if (!boolean(value(ECHOCHECK))) { 39413137Sralph #ifdef notdef 39513137Sralph if (number(value(LDELAY)) > 0 && c == '\r') 39613137Sralph nap(number(value(LDELAY))); 39713137Sralph #endif 3983843Ssam return; 39913137Sralph } 4003688Sroot tryagain: 4013688Sroot timedout = 0; 40213137Sralph alarm(value(ETIMEOUT)); 40313137Sralph read(FD, &cc, 1); 4043688Sroot alarm(0); 4053688Sroot if (timedout) { 4063688Sroot printf("\r\ntimeout error (%s)\r\n", ctrl(c)); 4073688Sroot if (retry++ > 3) 4083688Sroot return; 40913137Sralph pwrite(FD, &null, 1); /* poke it */ 4103688Sroot goto tryagain; 4113688Sroot } 4123688Sroot } 4133688Sroot 4143688Sroot timeout() 4153688Sroot { 4163688Sroot signal(SIGALRM, timeout); 4173688Sroot timedout = 1; 4183688Sroot } 4193688Sroot 42025548Sdonn /* 42125548Sdonn * Stolen from consh() -- puts a remote file on the output of a local command. 42225548Sdonn * Identical to consh() except for where stdout goes. 42325548Sdonn */ 42425548Sdonn pipeout(c) 42525548Sdonn { 42625548Sdonn char buf[256]; 42725548Sdonn int cpid, status, p; 42825548Sdonn time_t start; 42925548Sdonn 43025548Sdonn putchar(c); 43125548Sdonn if (prompt("Local command? ", buf)) 43225548Sdonn return; 43325548Sdonn kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 43425548Sdonn signal(SIGINT, SIG_IGN); 43525548Sdonn signal(SIGQUIT, SIG_IGN); 43625548Sdonn ioctl(0, TIOCSETC, &defchars); 43725548Sdonn read(repdes[0], (char *)&ccc, 1); 43825548Sdonn /* 43925548Sdonn * Set up file descriptors in the child and 44025548Sdonn * let it go... 44125548Sdonn */ 44225548Sdonn if ((cpid = fork()) < 0) 44325548Sdonn printf("can't fork!\r\n"); 44425548Sdonn else if (cpid) { 44525548Sdonn start = time(0); 44625548Sdonn while ((p = wait(&status)) > 0 && p != cpid) 44725548Sdonn ; 44825548Sdonn } else { 44925548Sdonn register int i; 45025548Sdonn 45125548Sdonn dup2(FD, 1); 45225548Sdonn for (i = 3; i < 20; i++) 45325548Sdonn close(i); 45425548Sdonn signal(SIGINT, SIG_DFL); 45525548Sdonn signal(SIGQUIT, SIG_DFL); 45625548Sdonn execute(buf); 45725548Sdonn printf("can't find `%s'\r\n", buf); 45825548Sdonn exit(0); 45925548Sdonn } 46025548Sdonn if (boolean(value(VERBOSE))) 46125548Sdonn prtime("away for ", time(0)-start); 46225548Sdonn write(fildes[1], (char *)&ccc, 1); 46325548Sdonn ioctl(0, TIOCSETC, &tchars); 46425548Sdonn signal(SIGINT, SIG_DFL); 46525548Sdonn signal(SIGQUIT, SIG_DFL); 46625548Sdonn } 46725548Sdonn 4683688Sroot #ifdef CONNECT 4693688Sroot /* 4703688Sroot * Fork a program with: 4713688Sroot * 0 <-> local tty in 4723688Sroot * 1 <-> local tty out 4733688Sroot * 2 <-> local tty out 4743688Sroot * 3 <-> remote tty in 4753688Sroot * 4 <-> remote tty out 4763688Sroot */ 4773688Sroot consh(c) 4783688Sroot { 4793688Sroot char buf[256]; 4803688Sroot int cpid, status, p; 4813688Sroot time_t start; 4823688Sroot 4833688Sroot putchar(c); 4843688Sroot if (prompt("Local command? ", buf)) 4853688Sroot return; 4863688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 4873688Sroot signal(SIGINT, SIG_IGN); 4883688Sroot signal(SIGQUIT, SIG_IGN); 4893688Sroot ioctl(0, TIOCSETC, &defchars); 4903688Sroot read(repdes[0], (char *)&ccc, 1); 4913688Sroot /* 4923688Sroot * Set up file descriptors in the child and 4933688Sroot * let it go... 4943688Sroot */ 4953688Sroot if ((cpid = fork()) < 0) 4963688Sroot printf("can't fork!\r\n"); 4973688Sroot else if (cpid) { 4983688Sroot start = time(0); 4993688Sroot while ((p = wait(&status)) > 0 && p != cpid) 5003688Sroot ; 5013688Sroot } else { 5023688Sroot register int i; 5033688Sroot 5043688Sroot dup2(FD, 3); 5053688Sroot dup2(3, 4); 5063688Sroot for (i = 5; i < 20; i++) 5073688Sroot close(i); 5083688Sroot signal(SIGINT, SIG_DFL); 5093688Sroot signal(SIGQUIT, SIG_DFL); 5103688Sroot execute(buf); 5113688Sroot printf("can't find `%s'\r\n", buf); 5123688Sroot exit(0); 5133688Sroot } 5143688Sroot if (boolean(value(VERBOSE))) 5153688Sroot prtime("away for ", time(0)-start); 5163688Sroot write(fildes[1], (char *)&ccc, 1); 5173688Sroot ioctl(0, TIOCSETC, &tchars); 5183688Sroot signal(SIGINT, SIG_DFL); 5193688Sroot signal(SIGQUIT, SIG_DFL); 5203688Sroot } 5213688Sroot #endif 5223688Sroot 5233688Sroot /* 5243688Sroot * Escape to local shell 5253688Sroot */ 5263688Sroot shell() 5273688Sroot { 5283688Sroot int shpid, status; 5293688Sroot extern char **environ; 5303688Sroot char *cp; 5313688Sroot 5323688Sroot printf("[sh]\r\n"); 5333688Sroot signal(SIGINT, SIG_IGN); 5343688Sroot signal(SIGQUIT, SIG_IGN); 5353688Sroot unraw(); 5363688Sroot if (shpid = fork()) { 5373688Sroot while (shpid != wait(&status)); 5383688Sroot raw(); 5393688Sroot printf("\r\n!\r\n"); 5403688Sroot signal(SIGINT, SIG_DFL); 5413688Sroot signal(SIGQUIT, SIG_DFL); 5423688Sroot return; 5433688Sroot } else { 5443688Sroot signal(SIGQUIT, SIG_DFL); 5453688Sroot signal(SIGINT, SIG_DFL); 5463688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 5473688Sroot cp = value(SHELL); 5483688Sroot else 5493688Sroot cp++; 550*30458Skarels shell_uid(); 5513688Sroot execl(value(SHELL), cp, 0); 5523688Sroot printf("\r\ncan't execl!\r\n"); 5533688Sroot exit(1); 5543688Sroot } 5553688Sroot } 5563688Sroot 5573688Sroot /* 5583688Sroot * TIPIN portion of scripting 5593688Sroot * initiate the conversation with TIPOUT 5603688Sroot */ 5613688Sroot setscript() 5623688Sroot { 5633688Sroot char c; 5643688Sroot /* 5653688Sroot * enable TIPOUT side for dialogue 5663688Sroot */ 5673688Sroot kill(pid, SIGEMT); 5683688Sroot if (boolean(value(SCRIPT))) 5693688Sroot write(fildes[1], value(RECORD), size(value(RECORD))); 5703688Sroot write(fildes[1], "\n", 1); 5713688Sroot /* 5723688Sroot * wait for TIPOUT to finish 5733688Sroot */ 5743688Sroot read(repdes[0], &c, 1); 5753688Sroot if (c == 'n') 5763688Sroot printf("can't create %s\r\n", value(RECORD)); 5773688Sroot } 5783688Sroot 5793688Sroot /* 5803688Sroot * Change current working directory of 5813688Sroot * local portion of tip 5823688Sroot */ 5833688Sroot chdirectory() 5843688Sroot { 58513277Ssam char dirname[80]; 5863688Sroot register char *cp = dirname; 5873688Sroot 58813277Ssam if (prompt("[cd] ", dirname)) { 5893688Sroot if (stoprompt) 5903688Sroot return; 59113277Ssam cp = value(HOME); 59213277Ssam } 5933688Sroot if (chdir(cp) < 0) 5943688Sroot printf("%s: bad directory\r\n", cp); 5953688Sroot printf("!\r\n"); 5963688Sroot } 5973688Sroot 59815187Ssam abort(msg) 59915187Ssam char *msg; 6003688Sroot { 60113137Sralph 6023688Sroot kill(pid, SIGTERM); 60315187Ssam disconnect(msg); 60415187Ssam if (msg != NOSTR) 60515187Ssam printf("\r\n%s", msg); 6063688Sroot printf("\r\n[EOT]\r\n"); 607*30458Skarels daemon_uid(); 6083688Sroot delock(uucplock); 6093688Sroot unraw(); 6103688Sroot exit(0); 6113688Sroot } 6123688Sroot 61315187Ssam finish() 61415187Ssam { 61515187Ssam char *dismsg; 61615187Ssam 61715187Ssam if ((dismsg = value(DISCONNECT)) != NOSTR) { 61815187Ssam write(FD, dismsg, strlen(dismsg)); 61915187Ssam sleep(5); 62015187Ssam } 62115187Ssam abort(NOSTR); 62215187Ssam } 62315187Ssam 6243688Sroot intcopy() 6253688Sroot { 62613277Ssam 6273688Sroot raw(); 6283688Sroot quit = 1; 62913277Ssam longjmp(intbuf, 1); 6303688Sroot } 6313688Sroot 6323688Sroot execute(s) 6333688Sroot char *s; 6343688Sroot { 6353688Sroot register char *cp; 6363688Sroot 6373688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 6383688Sroot cp = value(SHELL); 6393688Sroot else 6403688Sroot cp++; 641*30458Skarels user_uid(); 6423688Sroot execl(value(SHELL), cp, "-c", s, 0); 6433688Sroot } 6443688Sroot 6453688Sroot args(buf, a) 6463688Sroot char *buf, *a[]; 6473688Sroot { 6483688Sroot register char *p = buf, *start; 6493688Sroot register char **parg = a; 6503688Sroot register int n = 0; 6513688Sroot 6523688Sroot do { 6533688Sroot while (*p && (*p == ' ' || *p == '\t')) 6543688Sroot p++; 6553688Sroot start = p; 6563688Sroot if (*p) 6573688Sroot *parg = p; 6583688Sroot while (*p && (*p != ' ' && *p != '\t')) 6593688Sroot p++; 6603688Sroot if (p != start) 6613688Sroot parg++, n++; 6623688Sroot if (*p) 6633688Sroot *p++ = '\0'; 6643688Sroot } while (*p); 6653688Sroot 6663688Sroot return(n); 6673688Sroot } 6683688Sroot 6693688Sroot prtime(s, a) 6703688Sroot char *s; 6713688Sroot time_t a; 6723688Sroot { 6733688Sroot register i; 6743688Sroot int nums[3]; 6753688Sroot 6763688Sroot for (i = 0; i < 3; i++) { 6773688Sroot nums[i] = (int)(a % quant[i]); 6783688Sroot a /= quant[i]; 6793688Sroot } 6803688Sroot printf("%s", s); 6813688Sroot while (--i >= 0) 68217186Sralph if (nums[i] || i == 0 && nums[1] == 0 && nums[2] == 0) 6833688Sroot printf("%d %s%c ", nums[i], sep[i], 6843688Sroot nums[i] == 1 ? '\0' : 's'); 6853688Sroot printf("\r\n!\r\n"); 6863688Sroot } 6873688Sroot 6883688Sroot variable() 6893688Sroot { 6903688Sroot char buf[256]; 6913688Sroot 6923688Sroot if (prompt("[set] ", buf)) 6933688Sroot return; 6943688Sroot vlex(buf); 6953688Sroot if (vtable[BEAUTIFY].v_access&CHANGED) { 6963688Sroot vtable[BEAUTIFY].v_access &= ~CHANGED; 6975333Sshannon kill(pid, SIGSYS); 6983688Sroot } 6993688Sroot if (vtable[SCRIPT].v_access&CHANGED) { 7003688Sroot vtable[SCRIPT].v_access &= ~CHANGED; 7013688Sroot setscript(); 7023865Ssam /* 7033865Ssam * So that "set record=blah script" doesn't 7043865Ssam * cause two transactions to occur. 7053865Ssam */ 7063865Ssam if (vtable[RECORD].v_access&CHANGED) 7073865Ssam vtable[RECORD].v_access &= ~CHANGED; 7083688Sroot } 7093688Sroot if (vtable[RECORD].v_access&CHANGED) { 7103688Sroot vtable[RECORD].v_access &= ~CHANGED; 7113688Sroot if (boolean(value(SCRIPT))) 7123688Sroot setscript(); 7133688Sroot } 71413137Sralph if (vtable[TAND].v_access&CHANGED) { 71513137Sralph vtable[TAND].v_access &= ~CHANGED; 71613137Sralph if (boolean(value(TAND))) 71713137Sralph tandem("on"); 71813137Sralph else 71913137Sralph tandem("off"); 72013137Sralph } 72113137Sralph if (vtable[LECHO].v_access&CHANGED) { 72213137Sralph vtable[LECHO].v_access &= ~CHANGED; 72313137Sralph HD = boolean(value(LECHO)); 72413137Sralph } 72513137Sralph if (vtable[PARITY].v_access&CHANGED) { 72613137Sralph vtable[PARITY].v_access &= ~CHANGED; 72713137Sralph setparity(); 72813137Sralph } 7293688Sroot } 7303822Ssam 7313822Ssam /* 73213277Ssam * Turn tandem mode on or off for remote tty. 73313137Sralph */ 73413137Sralph tandem(option) 73513277Ssam char *option; 73613137Sralph { 73713137Sralph struct sgttyb rmtty; 73813137Sralph 73913137Sralph ioctl(FD, TIOCGETP, &rmtty); 74013137Sralph if (strcmp(option,"on") == 0) { 74113137Sralph rmtty.sg_flags |= TANDEM; 74213137Sralph arg.sg_flags |= TANDEM; 74313277Ssam } else { 74413137Sralph rmtty.sg_flags &= ~TANDEM; 74513137Sralph arg.sg_flags &= ~TANDEM; 74613137Sralph } 74713137Sralph ioctl(FD, TIOCSETP, &rmtty); 74813137Sralph ioctl(0, TIOCSETP, &arg); 74913137Sralph } 75013137Sralph 75113137Sralph /* 7523822Ssam * Send a break. 7533822Ssam */ 7543822Ssam genbrk() 7553822Ssam { 75613277Ssam 7573822Ssam ioctl(FD, TIOCSBRK, NULL); 7583822Ssam sleep(1); 7593822Ssam ioctl(FD, TIOCCBRK, NULL); 7603822Ssam } 7615133Ssam 7625133Ssam /* 7635133Ssam * Suspend tip 7645133Ssam */ 76527702Ssam suspend(c) 76627702Ssam char c; 7675133Ssam { 76813277Ssam 7695133Ssam unraw(); 77027702Ssam kill(c == CTRL(y) ? getpid() : 0, SIGTSTP); 7715133Ssam raw(); 7725133Ssam } 77313137Sralph 77413137Sralph /* 77513137Sralph * expand a file name if it includes shell meta characters 77613137Sralph */ 77713137Sralph 77813137Sralph char * 77913137Sralph expand(name) 78013137Sralph char name[]; 78113137Sralph { 78213137Sralph static char xname[BUFSIZ]; 78313137Sralph char cmdbuf[BUFSIZ]; 78413137Sralph register int pid, l, rc; 78513137Sralph register char *cp, *Shell; 78613137Sralph int s, pivec[2], (*sigint)(); 78713137Sralph 78813137Sralph if (!anyof(name, "~{[*?$`'\"\\")) 78913137Sralph return(name); 79013137Sralph /* sigint = signal(SIGINT, SIG_IGN); */ 79113137Sralph if (pipe(pivec) < 0) { 79213137Sralph perror("pipe"); 79313137Sralph /* signal(SIGINT, sigint) */ 79413137Sralph return(name); 79513137Sralph } 79613137Sralph sprintf(cmdbuf, "echo %s", name); 79713137Sralph if ((pid = vfork()) == 0) { 79813137Sralph Shell = value(SHELL); 79913137Sralph if (Shell == NOSTR) 80013137Sralph Shell = "/bin/sh"; 80113137Sralph close(pivec[0]); 80213137Sralph close(1); 80313137Sralph dup(pivec[1]); 80413137Sralph close(pivec[1]); 80513137Sralph close(2); 806*30458Skarels shell_uid(); 80713137Sralph execl(Shell, Shell, "-c", cmdbuf, 0); 80813137Sralph _exit(1); 80913137Sralph } 81013137Sralph if (pid == -1) { 81113137Sralph perror("fork"); 81213137Sralph close(pivec[0]); 81313137Sralph close(pivec[1]); 81413137Sralph return(NOSTR); 81513137Sralph } 81613137Sralph close(pivec[1]); 81713137Sralph l = read(pivec[0], xname, BUFSIZ); 81813137Sralph close(pivec[0]); 81913137Sralph while (wait(&s) != pid); 82013137Sralph ; 82113137Sralph s &= 0377; 82213137Sralph if (s != 0 && s != SIGPIPE) { 82313137Sralph fprintf(stderr, "\"Echo\" failed\n"); 82413137Sralph return(NOSTR); 82513137Sralph } 82613137Sralph if (l < 0) { 82713137Sralph perror("read"); 82813137Sralph return(NOSTR); 82913137Sralph } 83013137Sralph if (l == 0) { 83113137Sralph fprintf(stderr, "\"%s\": No match\n", name); 83213137Sralph return(NOSTR); 83313137Sralph } 83413137Sralph if (l == BUFSIZ) { 83513137Sralph fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name); 83613137Sralph return(NOSTR); 83713137Sralph } 83813137Sralph xname[l] = 0; 83913137Sralph for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) 84013137Sralph ; 84113137Sralph *++cp = '\0'; 84213137Sralph return(xname); 84313137Sralph } 84413137Sralph 84513137Sralph /* 84613137Sralph * Are any of the characters in the two strings the same? 84713137Sralph */ 84813137Sralph 84913137Sralph anyof(s1, s2) 85013137Sralph register char *s1, *s2; 85113137Sralph { 85213137Sralph register int c; 85313137Sralph 85413137Sralph while (c = *s1++) 85513137Sralph if (any(c, s2)) 85613137Sralph return(1); 85713137Sralph return(0); 85813137Sralph } 859