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*37857Sbostic static char sccsid[] = "@(#)cmds.c 5.10 (Berkeley) 05/11/89"; 2035464Sbostic #endif /* not lint */ 2113277Ssam 223688Sroot #include "tip.h" 23*37857Sbostic #include "pathnames.h" 24*37857Sbostic 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 373688Sroot int timeout(); /* timeout function called on alarm */ 383688Sroot int stopsnd(); /* SIGINT handler during file transfers */ 393688Sroot int intprompt(); /* used in handling SIG_INT during prompt */ 403688Sroot int intcopy(); /* interrupt routine for file transfers */ 413688Sroot 423688Sroot /* 433688Sroot * FTP - remote ==> local 443688Sroot * get a file from the remote host 453688Sroot */ 463688Sroot getfl(c) 473688Sroot char c; 483688Sroot { 4913277Ssam char buf[256], *cp, *expand(); 503688Sroot 513688Sroot putchar(c); 523688Sroot /* 533688Sroot * get the UNIX receiving file's name 543688Sroot */ 553688Sroot if (prompt("Local file name? ", copyname)) 563688Sroot return; 5713277Ssam cp = expand(copyname); 5813277Ssam if ((sfd = creat(cp, 0666)) < 0) { 593688Sroot printf("\r\n%s: cannot creat\r\n", copyname); 603688Sroot return; 613688Sroot } 623688Sroot 633688Sroot /* 643688Sroot * collect parameters 653688Sroot */ 663688Sroot if (prompt("List command for remote system? ", buf)) { 673688Sroot unlink(copyname); 683688Sroot return; 693688Sroot } 703688Sroot transfer(buf, sfd, value(EOFREAD)); 713688Sroot } 723688Sroot 733688Sroot /* 743688Sroot * Cu-like take command 753688Sroot */ 763688Sroot cu_take(cc) 773688Sroot char cc; 783688Sroot { 793688Sroot int fd, argc; 8013277Ssam char line[BUFSIZ], *expand(), *cp; 813688Sroot 823688Sroot if (prompt("[take] ", copyname)) 833688Sroot return; 843688Sroot if ((argc = args(copyname, argv)) < 1 || argc > 2) { 853688Sroot printf("usage: <take> from [to]\r\n"); 863688Sroot return; 873688Sroot } 883688Sroot if (argc == 1) 893688Sroot argv[1] = argv[0]; 9013277Ssam cp = expand(argv[1]); 9113277Ssam if ((fd = creat(cp, 0666)) < 0) { 923688Sroot printf("\r\n%s: cannot create\r\n", argv[1]); 933688Sroot return; 943688Sroot } 9513137Sralph sprintf(line, "cat %s;echo \01", argv[0]); 963688Sroot transfer(line, fd, "\01"); 973688Sroot } 983688Sroot 9913277Ssam static jmp_buf intbuf; 1003688Sroot /* 1013688Sroot * Bulk transfer routine -- 1023688Sroot * used by getfl(), cu_take(), and pipefile() 1033688Sroot */ 1043688Sroot transfer(buf, fd, eofchars) 1053688Sroot char *buf, *eofchars; 1063688Sroot { 1073688Sroot register int ct; 1083688Sroot char c, buffer[BUFSIZ]; 1093688Sroot register char *p = buffer; 1103688Sroot register int cnt, eof; 1113688Sroot time_t start; 11213277Ssam int (*f)(); 1133688Sroot 11413137Sralph pwrite(FD, buf, size(buf)); 1153688Sroot quit = 0; 1163688Sroot kill(pid, SIGIOT); 1173688Sroot read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ 1183688Sroot 1193688Sroot /* 1203688Sroot * finish command 1213688Sroot */ 12213137Sralph pwrite(FD, "\r", 1); 1233688Sroot do 1243688Sroot read(FD, &c, 1); 1253688Sroot while ((c&0177) != '\n'); 1263688Sroot ioctl(0, TIOCSETC, &defchars); 1273688Sroot 12817186Sralph (void) setjmp(intbuf); 12913277Ssam f = signal(SIGINT, intcopy); 1303688Sroot start = time(0); 1313688Sroot for (ct = 0; !quit;) { 1323688Sroot eof = read(FD, &c, 1) <= 0; 1333688Sroot c &= 0177; 1343688Sroot if (quit) 1353688Sroot continue; 1363688Sroot if (eof || any(c, eofchars)) 1373688Sroot break; 1383688Sroot if (c == 0) 1393688Sroot continue; /* ignore nulls */ 1403688Sroot if (c == '\r') 1413688Sroot continue; 1423688Sroot *p++ = c; 1433688Sroot 1443688Sroot if (c == '\n' && boolean(value(VERBOSE))) 1453688Sroot printf("\r%d", ++ct); 1463688Sroot if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) { 1473688Sroot if (write(fd, buffer, cnt) != cnt) { 1483688Sroot printf("\r\nwrite error\r\n"); 1493688Sroot quit = 1; 1503688Sroot } 1513688Sroot p = buffer; 1523688Sroot } 1533688Sroot } 1543688Sroot if (cnt = (p-buffer)) 1553688Sroot if (write(fd, buffer, cnt) != cnt) 1563688Sroot printf("\r\nwrite error\r\n"); 1573688Sroot 1583688Sroot if (boolean(value(VERBOSE))) 1593688Sroot prtime(" lines transferred in ", time(0)-start); 1603688Sroot ioctl(0, TIOCSETC, &tchars); 1613688Sroot write(fildes[1], (char *)&ccc, 1); 16217186Sralph signal(SIGINT, f); 1633688Sroot close(fd); 1643688Sroot } 1653688Sroot 1663688Sroot /* 1673688Sroot * FTP - remote ==> local process 1683688Sroot * send remote input to local process via pipe 1693688Sroot */ 1703688Sroot pipefile() 1713688Sroot { 1723688Sroot int cpid, pdes[2]; 1733688Sroot char buf[256]; 1743688Sroot int status, p; 1753688Sroot extern int errno; 1763688Sroot 1773688Sroot if (prompt("Local command? ", buf)) 1783688Sroot return; 1793688Sroot 1803688Sroot if (pipe(pdes)) { 1813688Sroot printf("can't establish pipe\r\n"); 1823688Sroot return; 1833688Sroot } 1843688Sroot 1853688Sroot if ((cpid = fork()) < 0) { 1863688Sroot printf("can't fork!\r\n"); 1873688Sroot return; 1883688Sroot } else if (cpid) { 1893688Sroot if (prompt("List command for remote system? ", buf)) { 1903688Sroot close(pdes[0]), close(pdes[1]); 1913688Sroot kill (cpid, SIGKILL); 1923688Sroot } else { 1933688Sroot close(pdes[0]); 1943688Sroot signal(SIGPIPE, intcopy); 1953688Sroot transfer(buf, pdes[1], value(EOFREAD)); 1963688Sroot signal(SIGPIPE, SIG_DFL); 1973688Sroot while ((p = wait(&status)) > 0 && p != cpid) 1983688Sroot ; 1993688Sroot } 2003688Sroot } else { 2013688Sroot register int f; 2023688Sroot 2033688Sroot dup2(pdes[0], 0); 2043688Sroot close(pdes[0]); 2053688Sroot for (f = 3; f < 20; f++) 2063688Sroot close(f); 2073688Sroot execute(buf); 2083688Sroot printf("can't execl!\r\n"); 2093688Sroot exit(0); 2103688Sroot } 2113688Sroot } 2123688Sroot 2133688Sroot /* 2143688Sroot * Interrupt service routine for FTP 2153688Sroot */ 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; 27017186Sralph int (*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 4273688Sroot timeout() 4283688Sroot { 4293688Sroot signal(SIGALRM, timeout); 4303688Sroot timedout = 1; 4313688Sroot } 4323688Sroot 43325548Sdonn /* 43425548Sdonn * Stolen from consh() -- puts a remote file on the output of a local command. 43525548Sdonn * Identical to consh() except for where stdout goes. 43625548Sdonn */ 43725548Sdonn pipeout(c) 43825548Sdonn { 43925548Sdonn char buf[256]; 44025548Sdonn int cpid, status, p; 44125548Sdonn time_t start; 44225548Sdonn 44325548Sdonn putchar(c); 44425548Sdonn if (prompt("Local command? ", buf)) 44525548Sdonn return; 44625548Sdonn kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 44725548Sdonn signal(SIGINT, SIG_IGN); 44825548Sdonn signal(SIGQUIT, SIG_IGN); 44925548Sdonn ioctl(0, TIOCSETC, &defchars); 45025548Sdonn read(repdes[0], (char *)&ccc, 1); 45125548Sdonn /* 45225548Sdonn * Set up file descriptors in the child and 45325548Sdonn * let it go... 45425548Sdonn */ 45525548Sdonn if ((cpid = fork()) < 0) 45625548Sdonn printf("can't fork!\r\n"); 45725548Sdonn else if (cpid) { 45825548Sdonn start = time(0); 45925548Sdonn while ((p = wait(&status)) > 0 && p != cpid) 46025548Sdonn ; 46125548Sdonn } else { 46225548Sdonn register int i; 46325548Sdonn 46425548Sdonn dup2(FD, 1); 46525548Sdonn for (i = 3; i < 20; i++) 46625548Sdonn close(i); 46725548Sdonn signal(SIGINT, SIG_DFL); 46825548Sdonn signal(SIGQUIT, SIG_DFL); 46925548Sdonn execute(buf); 47025548Sdonn printf("can't find `%s'\r\n", buf); 47125548Sdonn exit(0); 47225548Sdonn } 47325548Sdonn if (boolean(value(VERBOSE))) 47425548Sdonn prtime("away for ", time(0)-start); 47525548Sdonn write(fildes[1], (char *)&ccc, 1); 47625548Sdonn ioctl(0, TIOCSETC, &tchars); 47725548Sdonn signal(SIGINT, SIG_DFL); 47825548Sdonn signal(SIGQUIT, SIG_DFL); 47925548Sdonn } 48025548Sdonn 4813688Sroot #ifdef CONNECT 4823688Sroot /* 4833688Sroot * Fork a program with: 4843688Sroot * 0 <-> local tty in 4853688Sroot * 1 <-> local tty out 4863688Sroot * 2 <-> local tty out 4873688Sroot * 3 <-> remote tty in 4883688Sroot * 4 <-> remote tty out 4893688Sroot */ 4903688Sroot consh(c) 4913688Sroot { 4923688Sroot char buf[256]; 4933688Sroot int cpid, status, p; 4943688Sroot time_t start; 4953688Sroot 4963688Sroot putchar(c); 4973688Sroot if (prompt("Local command? ", buf)) 4983688Sroot return; 4993688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 5003688Sroot signal(SIGINT, SIG_IGN); 5013688Sroot signal(SIGQUIT, SIG_IGN); 5023688Sroot ioctl(0, TIOCSETC, &defchars); 5033688Sroot read(repdes[0], (char *)&ccc, 1); 5043688Sroot /* 5053688Sroot * Set up file descriptors in the child and 5063688Sroot * let it go... 5073688Sroot */ 5083688Sroot if ((cpid = fork()) < 0) 5093688Sroot printf("can't fork!\r\n"); 5103688Sroot else if (cpid) { 5113688Sroot start = time(0); 5123688Sroot while ((p = wait(&status)) > 0 && p != cpid) 5133688Sroot ; 5143688Sroot } else { 5153688Sroot register int i; 5163688Sroot 5173688Sroot dup2(FD, 3); 5183688Sroot dup2(3, 4); 5193688Sroot for (i = 5; i < 20; i++) 5203688Sroot close(i); 5213688Sroot signal(SIGINT, SIG_DFL); 5223688Sroot signal(SIGQUIT, SIG_DFL); 5233688Sroot execute(buf); 5243688Sroot printf("can't find `%s'\r\n", buf); 5253688Sroot exit(0); 5263688Sroot } 5273688Sroot if (boolean(value(VERBOSE))) 5283688Sroot prtime("away for ", time(0)-start); 5293688Sroot write(fildes[1], (char *)&ccc, 1); 5303688Sroot ioctl(0, TIOCSETC, &tchars); 5313688Sroot signal(SIGINT, SIG_DFL); 5323688Sroot signal(SIGQUIT, SIG_DFL); 5333688Sroot } 5343688Sroot #endif 5353688Sroot 5363688Sroot /* 5373688Sroot * Escape to local shell 5383688Sroot */ 5393688Sroot shell() 5403688Sroot { 5413688Sroot int shpid, status; 5423688Sroot extern char **environ; 5433688Sroot char *cp; 5443688Sroot 5453688Sroot printf("[sh]\r\n"); 5463688Sroot signal(SIGINT, SIG_IGN); 5473688Sroot signal(SIGQUIT, SIG_IGN); 5483688Sroot unraw(); 5493688Sroot if (shpid = fork()) { 5503688Sroot while (shpid != wait(&status)); 5513688Sroot raw(); 5523688Sroot printf("\r\n!\r\n"); 5533688Sroot signal(SIGINT, SIG_DFL); 5543688Sroot signal(SIGQUIT, SIG_DFL); 5553688Sroot return; 5563688Sroot } else { 5573688Sroot signal(SIGQUIT, SIG_DFL); 5583688Sroot signal(SIGINT, SIG_DFL); 5593688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 5603688Sroot cp = value(SHELL); 5613688Sroot else 5623688Sroot cp++; 56330458Skarels shell_uid(); 5643688Sroot execl(value(SHELL), cp, 0); 5653688Sroot printf("\r\ncan't execl!\r\n"); 5663688Sroot exit(1); 5673688Sroot } 5683688Sroot } 5693688Sroot 5703688Sroot /* 5713688Sroot * TIPIN portion of scripting 5723688Sroot * initiate the conversation with TIPOUT 5733688Sroot */ 5743688Sroot setscript() 5753688Sroot { 5763688Sroot char c; 5773688Sroot /* 5783688Sroot * enable TIPOUT side for dialogue 5793688Sroot */ 5803688Sroot kill(pid, SIGEMT); 5813688Sroot if (boolean(value(SCRIPT))) 5823688Sroot write(fildes[1], value(RECORD), size(value(RECORD))); 5833688Sroot write(fildes[1], "\n", 1); 5843688Sroot /* 5853688Sroot * wait for TIPOUT to finish 5863688Sroot */ 5873688Sroot read(repdes[0], &c, 1); 5883688Sroot if (c == 'n') 5893688Sroot printf("can't create %s\r\n", value(RECORD)); 5903688Sroot } 5913688Sroot 5923688Sroot /* 5933688Sroot * Change current working directory of 5943688Sroot * local portion of tip 5953688Sroot */ 5963688Sroot chdirectory() 5973688Sroot { 59813277Ssam char dirname[80]; 5993688Sroot register char *cp = dirname; 6003688Sroot 60113277Ssam if (prompt("[cd] ", dirname)) { 6023688Sroot if (stoprompt) 6033688Sroot return; 60413277Ssam cp = value(HOME); 60513277Ssam } 6063688Sroot if (chdir(cp) < 0) 6073688Sroot printf("%s: bad directory\r\n", cp); 6083688Sroot printf("!\r\n"); 6093688Sroot } 6103688Sroot 61115187Ssam abort(msg) 61215187Ssam char *msg; 6133688Sroot { 61413137Sralph 6153688Sroot kill(pid, SIGTERM); 61615187Ssam disconnect(msg); 61715187Ssam if (msg != NOSTR) 61815187Ssam printf("\r\n%s", msg); 6193688Sroot printf("\r\n[EOT]\r\n"); 62030458Skarels daemon_uid(); 62135460Sbostic (void)uu_unlock(uucplock); 6223688Sroot unraw(); 6233688Sroot exit(0); 6243688Sroot } 6253688Sroot 62615187Ssam finish() 62715187Ssam { 62815187Ssam char *dismsg; 62915187Ssam 63015187Ssam if ((dismsg = value(DISCONNECT)) != NOSTR) { 63115187Ssam write(FD, dismsg, strlen(dismsg)); 63215187Ssam sleep(5); 63315187Ssam } 63415187Ssam abort(NOSTR); 63515187Ssam } 63615187Ssam 6373688Sroot intcopy() 6383688Sroot { 63913277Ssam 6403688Sroot raw(); 6413688Sroot quit = 1; 64213277Ssam longjmp(intbuf, 1); 6433688Sroot } 6443688Sroot 6453688Sroot execute(s) 6463688Sroot char *s; 6473688Sroot { 6483688Sroot register char *cp; 6493688Sroot 6503688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 6513688Sroot cp = value(SHELL); 6523688Sroot else 6533688Sroot cp++; 65435777Sbostic shell_uid(); 6553688Sroot execl(value(SHELL), cp, "-c", s, 0); 6563688Sroot } 6573688Sroot 6583688Sroot args(buf, a) 6593688Sroot char *buf, *a[]; 6603688Sroot { 6613688Sroot register char *p = buf, *start; 6623688Sroot register char **parg = a; 6633688Sroot register int n = 0; 6643688Sroot 6653688Sroot do { 6663688Sroot while (*p && (*p == ' ' || *p == '\t')) 6673688Sroot p++; 6683688Sroot start = p; 6693688Sroot if (*p) 6703688Sroot *parg = p; 6713688Sroot while (*p && (*p != ' ' && *p != '\t')) 6723688Sroot p++; 6733688Sroot if (p != start) 6743688Sroot parg++, n++; 6753688Sroot if (*p) 6763688Sroot *p++ = '\0'; 6773688Sroot } while (*p); 6783688Sroot 6793688Sroot return(n); 6803688Sroot } 6813688Sroot 6823688Sroot prtime(s, a) 6833688Sroot char *s; 6843688Sroot time_t a; 6853688Sroot { 6863688Sroot register i; 6873688Sroot int nums[3]; 6883688Sroot 6893688Sroot for (i = 0; i < 3; i++) { 6903688Sroot nums[i] = (int)(a % quant[i]); 6913688Sroot a /= quant[i]; 6923688Sroot } 6933688Sroot printf("%s", s); 6943688Sroot while (--i >= 0) 69517186Sralph if (nums[i] || i == 0 && nums[1] == 0 && nums[2] == 0) 6963688Sroot printf("%d %s%c ", nums[i], sep[i], 6973688Sroot nums[i] == 1 ? '\0' : 's'); 6983688Sroot printf("\r\n!\r\n"); 6993688Sroot } 7003688Sroot 7013688Sroot variable() 7023688Sroot { 7033688Sroot char buf[256]; 7043688Sroot 7053688Sroot if (prompt("[set] ", buf)) 7063688Sroot return; 7073688Sroot vlex(buf); 7083688Sroot if (vtable[BEAUTIFY].v_access&CHANGED) { 7093688Sroot vtable[BEAUTIFY].v_access &= ~CHANGED; 7105333Sshannon kill(pid, SIGSYS); 7113688Sroot } 7123688Sroot if (vtable[SCRIPT].v_access&CHANGED) { 7133688Sroot vtable[SCRIPT].v_access &= ~CHANGED; 7143688Sroot setscript(); 7153865Ssam /* 7163865Ssam * So that "set record=blah script" doesn't 7173865Ssam * cause two transactions to occur. 7183865Ssam */ 7193865Ssam if (vtable[RECORD].v_access&CHANGED) 7203865Ssam vtable[RECORD].v_access &= ~CHANGED; 7213688Sroot } 7223688Sroot if (vtable[RECORD].v_access&CHANGED) { 7233688Sroot vtable[RECORD].v_access &= ~CHANGED; 7243688Sroot if (boolean(value(SCRIPT))) 7253688Sroot setscript(); 7263688Sroot } 72713137Sralph if (vtable[TAND].v_access&CHANGED) { 72813137Sralph vtable[TAND].v_access &= ~CHANGED; 72913137Sralph if (boolean(value(TAND))) 73013137Sralph tandem("on"); 73113137Sralph else 73213137Sralph tandem("off"); 73313137Sralph } 73413137Sralph if (vtable[LECHO].v_access&CHANGED) { 73513137Sralph vtable[LECHO].v_access &= ~CHANGED; 73613137Sralph HD = boolean(value(LECHO)); 73713137Sralph } 73813137Sralph if (vtable[PARITY].v_access&CHANGED) { 73913137Sralph vtable[PARITY].v_access &= ~CHANGED; 74013137Sralph setparity(); 74113137Sralph } 7423688Sroot } 7433822Ssam 7443822Ssam /* 74513277Ssam * Turn tandem mode on or off for remote tty. 74613137Sralph */ 74713137Sralph tandem(option) 74813277Ssam char *option; 74913137Sralph { 75013137Sralph struct sgttyb rmtty; 75113137Sralph 75213137Sralph ioctl(FD, TIOCGETP, &rmtty); 75313137Sralph if (strcmp(option,"on") == 0) { 75413137Sralph rmtty.sg_flags |= TANDEM; 75513137Sralph arg.sg_flags |= TANDEM; 75613277Ssam } else { 75713137Sralph rmtty.sg_flags &= ~TANDEM; 75813137Sralph arg.sg_flags &= ~TANDEM; 75913137Sralph } 76013137Sralph ioctl(FD, TIOCSETP, &rmtty); 76113137Sralph ioctl(0, TIOCSETP, &arg); 76213137Sralph } 76313137Sralph 76413137Sralph /* 7653822Ssam * Send a break. 7663822Ssam */ 7673822Ssam genbrk() 7683822Ssam { 76913277Ssam 7703822Ssam ioctl(FD, TIOCSBRK, NULL); 7713822Ssam sleep(1); 7723822Ssam ioctl(FD, TIOCCBRK, NULL); 7733822Ssam } 7745133Ssam 7755133Ssam /* 7765133Ssam * Suspend tip 7775133Ssam */ 77827702Ssam suspend(c) 77927702Ssam char c; 7805133Ssam { 78113277Ssam 7825133Ssam unraw(); 78333119Sbostic kill(c == CTRL('y') ? getpid() : 0, SIGTSTP); 7845133Ssam raw(); 7855133Ssam } 78613137Sralph 78713137Sralph /* 78813137Sralph * expand a file name if it includes shell meta characters 78913137Sralph */ 79013137Sralph 79113137Sralph char * 79213137Sralph expand(name) 79313137Sralph char name[]; 79413137Sralph { 79513137Sralph static char xname[BUFSIZ]; 79613137Sralph char cmdbuf[BUFSIZ]; 79713137Sralph register int pid, l, rc; 79813137Sralph register char *cp, *Shell; 79913137Sralph int s, pivec[2], (*sigint)(); 80013137Sralph 80113137Sralph if (!anyof(name, "~{[*?$`'\"\\")) 80213137Sralph return(name); 80313137Sralph /* sigint = signal(SIGINT, SIG_IGN); */ 80413137Sralph if (pipe(pivec) < 0) { 80513137Sralph perror("pipe"); 80613137Sralph /* signal(SIGINT, sigint) */ 80713137Sralph return(name); 80813137Sralph } 80913137Sralph sprintf(cmdbuf, "echo %s", name); 81013137Sralph if ((pid = vfork()) == 0) { 81113137Sralph Shell = value(SHELL); 81213137Sralph if (Shell == NOSTR) 813*37857Sbostic Shell = _PATH_BSHELL; 81413137Sralph close(pivec[0]); 81513137Sralph close(1); 81613137Sralph dup(pivec[1]); 81713137Sralph close(pivec[1]); 81813137Sralph close(2); 81930458Skarels shell_uid(); 82013137Sralph execl(Shell, Shell, "-c", cmdbuf, 0); 82113137Sralph _exit(1); 82213137Sralph } 82313137Sralph if (pid == -1) { 82413137Sralph perror("fork"); 82513137Sralph close(pivec[0]); 82613137Sralph close(pivec[1]); 82713137Sralph return(NOSTR); 82813137Sralph } 82913137Sralph close(pivec[1]); 83013137Sralph l = read(pivec[0], xname, BUFSIZ); 83113137Sralph close(pivec[0]); 83213137Sralph while (wait(&s) != pid); 83313137Sralph ; 83413137Sralph s &= 0377; 83513137Sralph if (s != 0 && s != SIGPIPE) { 83613137Sralph fprintf(stderr, "\"Echo\" failed\n"); 83713137Sralph return(NOSTR); 83813137Sralph } 83913137Sralph if (l < 0) { 84013137Sralph perror("read"); 84113137Sralph return(NOSTR); 84213137Sralph } 84313137Sralph if (l == 0) { 84413137Sralph fprintf(stderr, "\"%s\": No match\n", name); 84513137Sralph return(NOSTR); 84613137Sralph } 84713137Sralph if (l == BUFSIZ) { 84813137Sralph fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name); 84913137Sralph return(NOSTR); 85013137Sralph } 85113137Sralph xname[l] = 0; 85213137Sralph for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) 85313137Sralph ; 85413137Sralph *++cp = '\0'; 85513137Sralph return(xname); 85613137Sralph } 85713137Sralph 85813137Sralph /* 85913137Sralph * Are any of the characters in the two strings the same? 86013137Sralph */ 86113137Sralph 86213137Sralph anyof(s1, s2) 86313137Sralph register char *s1, *s2; 86413137Sralph { 86513137Sralph register int c; 86613137Sralph 86713137Sralph while (c = *s1++) 86813137Sralph if (any(c, s2)) 86913137Sralph return(1); 87013137Sralph return(0); 87113137Sralph } 872