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*35777Sbostic static char sccsid[] = "@(#)cmds.c 5.9 (Berkeley) 10/10/88"; 2035464Sbostic #endif /* not lint */ 2113277Ssam 223688Sroot #include "tip.h" 233688Sroot /* 243688Sroot * tip 253688Sroot * 263688Sroot * miscellaneous commands 273688Sroot */ 283688Sroot 293688Sroot int quant[] = { 60, 60, 24 }; 303688Sroot 313688Sroot char null = '\0'; 323688Sroot char *sep[] = { "second", "minute", "hour" }; 333688Sroot static char *argv[10]; /* argument vector for take and put */ 343688Sroot 353688Sroot int timeout(); /* timeout function called on alarm */ 363688Sroot int stopsnd(); /* SIGINT handler during file transfers */ 373688Sroot int intprompt(); /* used in handling SIG_INT during prompt */ 383688Sroot int intcopy(); /* interrupt routine for file transfers */ 393688Sroot 403688Sroot /* 413688Sroot * FTP - remote ==> local 423688Sroot * get a file from the remote host 433688Sroot */ 443688Sroot getfl(c) 453688Sroot char c; 463688Sroot { 4713277Ssam char buf[256], *cp, *expand(); 483688Sroot 493688Sroot putchar(c); 503688Sroot /* 513688Sroot * get the UNIX receiving file's name 523688Sroot */ 533688Sroot if (prompt("Local file name? ", copyname)) 543688Sroot return; 5513277Ssam cp = expand(copyname); 5613277Ssam if ((sfd = creat(cp, 0666)) < 0) { 573688Sroot printf("\r\n%s: cannot creat\r\n", copyname); 583688Sroot return; 593688Sroot } 603688Sroot 613688Sroot /* 623688Sroot * collect parameters 633688Sroot */ 643688Sroot if (prompt("List command for remote system? ", buf)) { 653688Sroot unlink(copyname); 663688Sroot return; 673688Sroot } 683688Sroot transfer(buf, sfd, value(EOFREAD)); 693688Sroot } 703688Sroot 713688Sroot /* 723688Sroot * Cu-like take command 733688Sroot */ 743688Sroot cu_take(cc) 753688Sroot char cc; 763688Sroot { 773688Sroot int fd, argc; 7813277Ssam char line[BUFSIZ], *expand(), *cp; 793688Sroot 803688Sroot if (prompt("[take] ", copyname)) 813688Sroot return; 823688Sroot if ((argc = args(copyname, argv)) < 1 || argc > 2) { 833688Sroot printf("usage: <take> from [to]\r\n"); 843688Sroot return; 853688Sroot } 863688Sroot if (argc == 1) 873688Sroot argv[1] = argv[0]; 8813277Ssam cp = expand(argv[1]); 8913277Ssam if ((fd = creat(cp, 0666)) < 0) { 903688Sroot printf("\r\n%s: cannot create\r\n", argv[1]); 913688Sroot return; 923688Sroot } 9313137Sralph sprintf(line, "cat %s;echo \01", argv[0]); 943688Sroot transfer(line, fd, "\01"); 953688Sroot } 963688Sroot 9713277Ssam static jmp_buf intbuf; 983688Sroot /* 993688Sroot * Bulk transfer routine -- 1003688Sroot * used by getfl(), cu_take(), and pipefile() 1013688Sroot */ 1023688Sroot transfer(buf, fd, eofchars) 1033688Sroot char *buf, *eofchars; 1043688Sroot { 1053688Sroot register int ct; 1063688Sroot char c, buffer[BUFSIZ]; 1073688Sroot register char *p = buffer; 1083688Sroot register int cnt, eof; 1093688Sroot time_t start; 11013277Ssam int (*f)(); 1113688Sroot 11213137Sralph pwrite(FD, buf, size(buf)); 1133688Sroot quit = 0; 1143688Sroot kill(pid, SIGIOT); 1153688Sroot read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ 1163688Sroot 1173688Sroot /* 1183688Sroot * finish command 1193688Sroot */ 12013137Sralph pwrite(FD, "\r", 1); 1213688Sroot do 1223688Sroot read(FD, &c, 1); 1233688Sroot while ((c&0177) != '\n'); 1243688Sroot ioctl(0, TIOCSETC, &defchars); 1253688Sroot 12617186Sralph (void) setjmp(intbuf); 12713277Ssam f = signal(SIGINT, intcopy); 1283688Sroot start = time(0); 1293688Sroot for (ct = 0; !quit;) { 1303688Sroot eof = read(FD, &c, 1) <= 0; 1313688Sroot c &= 0177; 1323688Sroot if (quit) 1333688Sroot continue; 1343688Sroot if (eof || any(c, eofchars)) 1353688Sroot break; 1363688Sroot if (c == 0) 1373688Sroot continue; /* ignore nulls */ 1383688Sroot if (c == '\r') 1393688Sroot continue; 1403688Sroot *p++ = c; 1413688Sroot 1423688Sroot if (c == '\n' && boolean(value(VERBOSE))) 1433688Sroot printf("\r%d", ++ct); 1443688Sroot if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) { 1453688Sroot if (write(fd, buffer, cnt) != cnt) { 1463688Sroot printf("\r\nwrite error\r\n"); 1473688Sroot quit = 1; 1483688Sroot } 1493688Sroot p = buffer; 1503688Sroot } 1513688Sroot } 1523688Sroot if (cnt = (p-buffer)) 1533688Sroot if (write(fd, buffer, cnt) != cnt) 1543688Sroot printf("\r\nwrite error\r\n"); 1553688Sroot 1563688Sroot if (boolean(value(VERBOSE))) 1573688Sroot prtime(" lines transferred in ", time(0)-start); 1583688Sroot ioctl(0, TIOCSETC, &tchars); 1593688Sroot write(fildes[1], (char *)&ccc, 1); 16017186Sralph signal(SIGINT, f); 1613688Sroot close(fd); 1623688Sroot } 1633688Sroot 1643688Sroot /* 1653688Sroot * FTP - remote ==> local process 1663688Sroot * send remote input to local process via pipe 1673688Sroot */ 1683688Sroot pipefile() 1693688Sroot { 1703688Sroot int cpid, pdes[2]; 1713688Sroot char buf[256]; 1723688Sroot int status, p; 1733688Sroot extern int errno; 1743688Sroot 1753688Sroot if (prompt("Local command? ", buf)) 1763688Sroot return; 1773688Sroot 1783688Sroot if (pipe(pdes)) { 1793688Sroot printf("can't establish pipe\r\n"); 1803688Sroot return; 1813688Sroot } 1823688Sroot 1833688Sroot if ((cpid = fork()) < 0) { 1843688Sroot printf("can't fork!\r\n"); 1853688Sroot return; 1863688Sroot } else if (cpid) { 1873688Sroot if (prompt("List command for remote system? ", buf)) { 1883688Sroot close(pdes[0]), close(pdes[1]); 1893688Sroot kill (cpid, SIGKILL); 1903688Sroot } else { 1913688Sroot close(pdes[0]); 1923688Sroot signal(SIGPIPE, intcopy); 1933688Sroot transfer(buf, pdes[1], value(EOFREAD)); 1943688Sroot signal(SIGPIPE, SIG_DFL); 1953688Sroot while ((p = wait(&status)) > 0 && p != cpid) 1963688Sroot ; 1973688Sroot } 1983688Sroot } else { 1993688Sroot register int f; 2003688Sroot 2013688Sroot dup2(pdes[0], 0); 2023688Sroot close(pdes[0]); 2033688Sroot for (f = 3; f < 20; f++) 2043688Sroot close(f); 2053688Sroot execute(buf); 2063688Sroot printf("can't execl!\r\n"); 2073688Sroot exit(0); 2083688Sroot } 2093688Sroot } 2103688Sroot 2113688Sroot /* 2123688Sroot * Interrupt service routine for FTP 2133688Sroot */ 2143688Sroot stopsnd() 2153688Sroot { 21613277Ssam 2173688Sroot stop = 1; 2183688Sroot signal(SIGINT, SIG_IGN); 2193688Sroot } 2203688Sroot 2213688Sroot /* 2223688Sroot * FTP - local ==> remote 2233688Sroot * send local file to remote host 2243688Sroot * terminate transmission with pseudo EOF sequence 2253688Sroot */ 2263688Sroot sendfile(cc) 2273688Sroot char cc; 2283688Sroot { 2293688Sroot FILE *fd; 23013137Sralph char *fnamex; 23113137Sralph char *expand(); 2323688Sroot 2333688Sroot putchar(cc); 2343688Sroot /* 2353688Sroot * get file name 2363688Sroot */ 2373688Sroot if (prompt("Local file name? ", fname)) 2383688Sroot return; 2393688Sroot 2403688Sroot /* 2413688Sroot * look up file 2423688Sroot */ 24313137Sralph fnamex = expand(fname); 24413137Sralph if ((fd = fopen(fnamex, "r")) == NULL) { 2453688Sroot printf("%s: cannot open\r\n", fname); 2463688Sroot return; 2473688Sroot } 2483688Sroot transmit(fd, value(EOFWRITE), NULL); 2493843Ssam if (!boolean(value(ECHOCHECK))) { 2503843Ssam struct sgttyb buf; 2513843Ssam 2523843Ssam ioctl(FD, TIOCGETP, &buf); /* this does a */ 2533843Ssam ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 2543843Ssam } 2553688Sroot } 2563688Sroot 2573688Sroot /* 2583688Sroot * Bulk transfer routine to remote host -- 2593688Sroot * used by sendfile() and cu_put() 2603688Sroot */ 2613688Sroot transmit(fd, eofchars, command) 2623688Sroot FILE *fd; 2633688Sroot char *eofchars, *command; 2643688Sroot { 26513137Sralph char *pc, lastc; 2663688Sroot int c, ccount, lcount; 2673688Sroot time_t start_t, stop_t; 26817186Sralph int (*f)(); 2693688Sroot 2703688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 2713688Sroot stop = 0; 27217186Sralph f = signal(SIGINT, stopsnd); 2733688Sroot ioctl(0, TIOCSETC, &defchars); 2743688Sroot read(repdes[0], (char *)&ccc, 1); 2753688Sroot if (command != NULL) { 2763688Sroot for (pc = command; *pc; pc++) 2773688Sroot send(*pc); 2783843Ssam if (boolean(value(ECHOCHECK))) 2793843Ssam read(FD, (char *)&c, 1); /* trailing \n */ 2803843Ssam else { 2813843Ssam struct sgttyb buf; 2823843Ssam 2833843Ssam ioctl(FD, TIOCGETP, &buf); /* this does a */ 2843843Ssam ioctl(FD, TIOCSETP, &buf); /* wflushtty */ 2853843Ssam sleep(5); /* wait for remote stty to take effect */ 2863843Ssam } 2873688Sroot } 2883688Sroot lcount = 0; 2893688Sroot lastc = '\0'; 2903688Sroot start_t = time(0); 2915133Ssam while (1) { 2923688Sroot ccount = 0; 2933688Sroot do { 2943688Sroot c = getc(fd); 2953688Sroot if (stop) 2963688Sroot goto out; 2973688Sroot if (c == EOF) 2983688Sroot goto out; 29913137Sralph if (c == 0177 && !boolean(value(RAWFTP))) 3003688Sroot continue; 3013688Sroot lastc = c; 3023688Sroot if (c < 040) { 30313137Sralph if (c == '\n') { 30413137Sralph if (!boolean(value(RAWFTP))) 30513137Sralph c = '\r'; 30613137Sralph } 3073688Sroot else if (c == '\t') { 30813137Sralph if (!boolean(value(RAWFTP))) { 30913137Sralph if (boolean(value(TABEXPAND))) { 3103688Sroot send(' '); 31113137Sralph while ((++ccount % 8) != 0) 31213137Sralph send(' '); 31313137Sralph continue; 31413137Sralph } 31513137Sralph } 31613137Sralph } else 31713137Sralph if (!boolean(value(RAWFTP))) 3183688Sroot continue; 3193688Sroot } 3203688Sroot send(c); 32113137Sralph } while (c != '\r' && !boolean(value(RAWFTP))); 3223688Sroot if (boolean(value(VERBOSE))) 3233688Sroot printf("\r%d", ++lcount); 3243843Ssam if (boolean(value(ECHOCHECK))) { 32517186Sralph timedout = 0; 32613137Sralph alarm(value(ETIMEOUT)); 3273843Ssam do { /* wait for prompt */ 32813137Sralph read(FD, (char *)&c, 1); 3293843Ssam if (timedout || stop) { 3303843Ssam if (timedout) 3313843Ssam printf("\r\ntimed out at eol\r\n"); 3323843Ssam alarm(0); 3333843Ssam goto out; 3343843Ssam } 33513137Sralph } while ((c&0177) != character(value(PROMPT))); 3363843Ssam alarm(0); 3373843Ssam } 3383688Sroot } 3393688Sroot out: 34013137Sralph if (lastc != '\n' && !boolean(value(RAWFTP))) 3413688Sroot send('\r'); 3423688Sroot for (pc = eofchars; *pc; pc++) 3433688Sroot send(*pc); 3443688Sroot stop_t = time(0); 3453688Sroot fclose(fd); 34617186Sralph signal(SIGINT, f); 3473688Sroot if (boolean(value(VERBOSE))) 34813137Sralph if (boolean(value(RAWFTP))) 34913137Sralph prtime(" chars transferred in ", stop_t-start_t); 35013137Sralph else 35113137Sralph prtime(" lines transferred in ", stop_t-start_t); 3523688Sroot write(fildes[1], (char *)&ccc, 1); 3533688Sroot ioctl(0, TIOCSETC, &tchars); 3543688Sroot } 3553688Sroot 3563688Sroot /* 3573688Sroot * Cu-like put command 3583688Sroot */ 3593688Sroot cu_put(cc) 3603688Sroot char cc; 3613688Sroot { 3623688Sroot FILE *fd; 3633688Sroot char line[BUFSIZ]; 3643688Sroot int argc; 36513137Sralph char *expand(); 36613137Sralph char *copynamex; 3673688Sroot 3683688Sroot if (prompt("[put] ", copyname)) 3693688Sroot return; 3703688Sroot if ((argc = args(copyname, argv)) < 1 || argc > 2) { 3713688Sroot printf("usage: <put> from [to]\r\n"); 3723688Sroot return; 3733688Sroot } 3743688Sroot if (argc == 1) 3753688Sroot argv[1] = argv[0]; 37613137Sralph copynamex = expand(argv[0]); 37713137Sralph if ((fd = fopen(copynamex, "r")) == NULL) { 37813137Sralph printf("%s: cannot open\r\n", copynamex); 3793688Sroot return; 3803688Sroot } 3813843Ssam if (boolean(value(ECHOCHECK))) 38213137Sralph sprintf(line, "cat>%s\r", argv[1]); 3833843Ssam else 38413137Sralph sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]); 3853688Sroot transmit(fd, "\04", line); 3863688Sroot } 3873688Sroot 3883688Sroot /* 3893688Sroot * FTP - send single character 3903688Sroot * wait for echo & handle timeout 3913688Sroot */ 3923688Sroot send(c) 3933688Sroot char c; 3943688Sroot { 3957588Sshannon char cc; 3963688Sroot int retry = 0; 3973688Sroot 3983688Sroot cc = c; 39913137Sralph pwrite(FD, &cc, 1); 40013137Sralph #ifdef notdef 40113137Sralph if (number(value(CDELAY)) > 0 && c != '\r') 40213137Sralph nap(number(value(CDELAY))); 40313137Sralph #endif 40413137Sralph if (!boolean(value(ECHOCHECK))) { 40513137Sralph #ifdef notdef 40613137Sralph if (number(value(LDELAY)) > 0 && c == '\r') 40713137Sralph nap(number(value(LDELAY))); 40813137Sralph #endif 4093843Ssam return; 41013137Sralph } 4113688Sroot tryagain: 4123688Sroot timedout = 0; 41313137Sralph alarm(value(ETIMEOUT)); 41413137Sralph read(FD, &cc, 1); 4153688Sroot alarm(0); 4163688Sroot if (timedout) { 4173688Sroot printf("\r\ntimeout error (%s)\r\n", ctrl(c)); 4183688Sroot if (retry++ > 3) 4193688Sroot return; 42013137Sralph pwrite(FD, &null, 1); /* poke it */ 4213688Sroot goto tryagain; 4223688Sroot } 4233688Sroot } 4243688Sroot 4253688Sroot timeout() 4263688Sroot { 4273688Sroot signal(SIGALRM, timeout); 4283688Sroot timedout = 1; 4293688Sroot } 4303688Sroot 43125548Sdonn /* 43225548Sdonn * Stolen from consh() -- puts a remote file on the output of a local command. 43325548Sdonn * Identical to consh() except for where stdout goes. 43425548Sdonn */ 43525548Sdonn pipeout(c) 43625548Sdonn { 43725548Sdonn char buf[256]; 43825548Sdonn int cpid, status, p; 43925548Sdonn time_t start; 44025548Sdonn 44125548Sdonn putchar(c); 44225548Sdonn if (prompt("Local command? ", buf)) 44325548Sdonn return; 44425548Sdonn kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 44525548Sdonn signal(SIGINT, SIG_IGN); 44625548Sdonn signal(SIGQUIT, SIG_IGN); 44725548Sdonn ioctl(0, TIOCSETC, &defchars); 44825548Sdonn read(repdes[0], (char *)&ccc, 1); 44925548Sdonn /* 45025548Sdonn * Set up file descriptors in the child and 45125548Sdonn * let it go... 45225548Sdonn */ 45325548Sdonn if ((cpid = fork()) < 0) 45425548Sdonn printf("can't fork!\r\n"); 45525548Sdonn else if (cpid) { 45625548Sdonn start = time(0); 45725548Sdonn while ((p = wait(&status)) > 0 && p != cpid) 45825548Sdonn ; 45925548Sdonn } else { 46025548Sdonn register int i; 46125548Sdonn 46225548Sdonn dup2(FD, 1); 46325548Sdonn for (i = 3; i < 20; i++) 46425548Sdonn close(i); 46525548Sdonn signal(SIGINT, SIG_DFL); 46625548Sdonn signal(SIGQUIT, SIG_DFL); 46725548Sdonn execute(buf); 46825548Sdonn printf("can't find `%s'\r\n", buf); 46925548Sdonn exit(0); 47025548Sdonn } 47125548Sdonn if (boolean(value(VERBOSE))) 47225548Sdonn prtime("away for ", time(0)-start); 47325548Sdonn write(fildes[1], (char *)&ccc, 1); 47425548Sdonn ioctl(0, TIOCSETC, &tchars); 47525548Sdonn signal(SIGINT, SIG_DFL); 47625548Sdonn signal(SIGQUIT, SIG_DFL); 47725548Sdonn } 47825548Sdonn 4793688Sroot #ifdef CONNECT 4803688Sroot /* 4813688Sroot * Fork a program with: 4823688Sroot * 0 <-> local tty in 4833688Sroot * 1 <-> local tty out 4843688Sroot * 2 <-> local tty out 4853688Sroot * 3 <-> remote tty in 4863688Sroot * 4 <-> remote tty out 4873688Sroot */ 4883688Sroot consh(c) 4893688Sroot { 4903688Sroot char buf[256]; 4913688Sroot int cpid, status, p; 4923688Sroot time_t start; 4933688Sroot 4943688Sroot putchar(c); 4953688Sroot if (prompt("Local command? ", buf)) 4963688Sroot return; 4973688Sroot kill(pid, SIGIOT); /* put TIPOUT into a wait state */ 4983688Sroot signal(SIGINT, SIG_IGN); 4993688Sroot signal(SIGQUIT, SIG_IGN); 5003688Sroot ioctl(0, TIOCSETC, &defchars); 5013688Sroot read(repdes[0], (char *)&ccc, 1); 5023688Sroot /* 5033688Sroot * Set up file descriptors in the child and 5043688Sroot * let it go... 5053688Sroot */ 5063688Sroot if ((cpid = fork()) < 0) 5073688Sroot printf("can't fork!\r\n"); 5083688Sroot else if (cpid) { 5093688Sroot start = time(0); 5103688Sroot while ((p = wait(&status)) > 0 && p != cpid) 5113688Sroot ; 5123688Sroot } else { 5133688Sroot register int i; 5143688Sroot 5153688Sroot dup2(FD, 3); 5163688Sroot dup2(3, 4); 5173688Sroot for (i = 5; i < 20; i++) 5183688Sroot close(i); 5193688Sroot signal(SIGINT, SIG_DFL); 5203688Sroot signal(SIGQUIT, SIG_DFL); 5213688Sroot execute(buf); 5223688Sroot printf("can't find `%s'\r\n", buf); 5233688Sroot exit(0); 5243688Sroot } 5253688Sroot if (boolean(value(VERBOSE))) 5263688Sroot prtime("away for ", time(0)-start); 5273688Sroot write(fildes[1], (char *)&ccc, 1); 5283688Sroot ioctl(0, TIOCSETC, &tchars); 5293688Sroot signal(SIGINT, SIG_DFL); 5303688Sroot signal(SIGQUIT, SIG_DFL); 5313688Sroot } 5323688Sroot #endif 5333688Sroot 5343688Sroot /* 5353688Sroot * Escape to local shell 5363688Sroot */ 5373688Sroot shell() 5383688Sroot { 5393688Sroot int shpid, status; 5403688Sroot extern char **environ; 5413688Sroot char *cp; 5423688Sroot 5433688Sroot printf("[sh]\r\n"); 5443688Sroot signal(SIGINT, SIG_IGN); 5453688Sroot signal(SIGQUIT, SIG_IGN); 5463688Sroot unraw(); 5473688Sroot if (shpid = fork()) { 5483688Sroot while (shpid != wait(&status)); 5493688Sroot raw(); 5503688Sroot printf("\r\n!\r\n"); 5513688Sroot signal(SIGINT, SIG_DFL); 5523688Sroot signal(SIGQUIT, SIG_DFL); 5533688Sroot return; 5543688Sroot } else { 5553688Sroot signal(SIGQUIT, SIG_DFL); 5563688Sroot signal(SIGINT, SIG_DFL); 5573688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 5583688Sroot cp = value(SHELL); 5593688Sroot else 5603688Sroot cp++; 56130458Skarels shell_uid(); 5623688Sroot execl(value(SHELL), cp, 0); 5633688Sroot printf("\r\ncan't execl!\r\n"); 5643688Sroot exit(1); 5653688Sroot } 5663688Sroot } 5673688Sroot 5683688Sroot /* 5693688Sroot * TIPIN portion of scripting 5703688Sroot * initiate the conversation with TIPOUT 5713688Sroot */ 5723688Sroot setscript() 5733688Sroot { 5743688Sroot char c; 5753688Sroot /* 5763688Sroot * enable TIPOUT side for dialogue 5773688Sroot */ 5783688Sroot kill(pid, SIGEMT); 5793688Sroot if (boolean(value(SCRIPT))) 5803688Sroot write(fildes[1], value(RECORD), size(value(RECORD))); 5813688Sroot write(fildes[1], "\n", 1); 5823688Sroot /* 5833688Sroot * wait for TIPOUT to finish 5843688Sroot */ 5853688Sroot read(repdes[0], &c, 1); 5863688Sroot if (c == 'n') 5873688Sroot printf("can't create %s\r\n", value(RECORD)); 5883688Sroot } 5893688Sroot 5903688Sroot /* 5913688Sroot * Change current working directory of 5923688Sroot * local portion of tip 5933688Sroot */ 5943688Sroot chdirectory() 5953688Sroot { 59613277Ssam char dirname[80]; 5973688Sroot register char *cp = dirname; 5983688Sroot 59913277Ssam if (prompt("[cd] ", dirname)) { 6003688Sroot if (stoprompt) 6013688Sroot return; 60213277Ssam cp = value(HOME); 60313277Ssam } 6043688Sroot if (chdir(cp) < 0) 6053688Sroot printf("%s: bad directory\r\n", cp); 6063688Sroot printf("!\r\n"); 6073688Sroot } 6083688Sroot 60915187Ssam abort(msg) 61015187Ssam char *msg; 6113688Sroot { 61213137Sralph 6133688Sroot kill(pid, SIGTERM); 61415187Ssam disconnect(msg); 61515187Ssam if (msg != NOSTR) 61615187Ssam printf("\r\n%s", msg); 6173688Sroot printf("\r\n[EOT]\r\n"); 61830458Skarels daemon_uid(); 61935460Sbostic (void)uu_unlock(uucplock); 6203688Sroot unraw(); 6213688Sroot exit(0); 6223688Sroot } 6233688Sroot 62415187Ssam finish() 62515187Ssam { 62615187Ssam char *dismsg; 62715187Ssam 62815187Ssam if ((dismsg = value(DISCONNECT)) != NOSTR) { 62915187Ssam write(FD, dismsg, strlen(dismsg)); 63015187Ssam sleep(5); 63115187Ssam } 63215187Ssam abort(NOSTR); 63315187Ssam } 63415187Ssam 6353688Sroot intcopy() 6363688Sroot { 63713277Ssam 6383688Sroot raw(); 6393688Sroot quit = 1; 64013277Ssam longjmp(intbuf, 1); 6413688Sroot } 6423688Sroot 6433688Sroot execute(s) 6443688Sroot char *s; 6453688Sroot { 6463688Sroot register char *cp; 6473688Sroot 6483688Sroot if ((cp = rindex(value(SHELL), '/')) == NULL) 6493688Sroot cp = value(SHELL); 6503688Sroot else 6513688Sroot cp++; 652*35777Sbostic shell_uid(); 6533688Sroot execl(value(SHELL), cp, "-c", s, 0); 6543688Sroot } 6553688Sroot 6563688Sroot args(buf, a) 6573688Sroot char *buf, *a[]; 6583688Sroot { 6593688Sroot register char *p = buf, *start; 6603688Sroot register char **parg = a; 6613688Sroot register int n = 0; 6623688Sroot 6633688Sroot do { 6643688Sroot while (*p && (*p == ' ' || *p == '\t')) 6653688Sroot p++; 6663688Sroot start = p; 6673688Sroot if (*p) 6683688Sroot *parg = p; 6693688Sroot while (*p && (*p != ' ' && *p != '\t')) 6703688Sroot p++; 6713688Sroot if (p != start) 6723688Sroot parg++, n++; 6733688Sroot if (*p) 6743688Sroot *p++ = '\0'; 6753688Sroot } while (*p); 6763688Sroot 6773688Sroot return(n); 6783688Sroot } 6793688Sroot 6803688Sroot prtime(s, a) 6813688Sroot char *s; 6823688Sroot time_t a; 6833688Sroot { 6843688Sroot register i; 6853688Sroot int nums[3]; 6863688Sroot 6873688Sroot for (i = 0; i < 3; i++) { 6883688Sroot nums[i] = (int)(a % quant[i]); 6893688Sroot a /= quant[i]; 6903688Sroot } 6913688Sroot printf("%s", s); 6923688Sroot while (--i >= 0) 69317186Sralph if (nums[i] || i == 0 && nums[1] == 0 && nums[2] == 0) 6943688Sroot printf("%d %s%c ", nums[i], sep[i], 6953688Sroot nums[i] == 1 ? '\0' : 's'); 6963688Sroot printf("\r\n!\r\n"); 6973688Sroot } 6983688Sroot 6993688Sroot variable() 7003688Sroot { 7013688Sroot char buf[256]; 7023688Sroot 7033688Sroot if (prompt("[set] ", buf)) 7043688Sroot return; 7053688Sroot vlex(buf); 7063688Sroot if (vtable[BEAUTIFY].v_access&CHANGED) { 7073688Sroot vtable[BEAUTIFY].v_access &= ~CHANGED; 7085333Sshannon kill(pid, SIGSYS); 7093688Sroot } 7103688Sroot if (vtable[SCRIPT].v_access&CHANGED) { 7113688Sroot vtable[SCRIPT].v_access &= ~CHANGED; 7123688Sroot setscript(); 7133865Ssam /* 7143865Ssam * So that "set record=blah script" doesn't 7153865Ssam * cause two transactions to occur. 7163865Ssam */ 7173865Ssam if (vtable[RECORD].v_access&CHANGED) 7183865Ssam vtable[RECORD].v_access &= ~CHANGED; 7193688Sroot } 7203688Sroot if (vtable[RECORD].v_access&CHANGED) { 7213688Sroot vtable[RECORD].v_access &= ~CHANGED; 7223688Sroot if (boolean(value(SCRIPT))) 7233688Sroot setscript(); 7243688Sroot } 72513137Sralph if (vtable[TAND].v_access&CHANGED) { 72613137Sralph vtable[TAND].v_access &= ~CHANGED; 72713137Sralph if (boolean(value(TAND))) 72813137Sralph tandem("on"); 72913137Sralph else 73013137Sralph tandem("off"); 73113137Sralph } 73213137Sralph if (vtable[LECHO].v_access&CHANGED) { 73313137Sralph vtable[LECHO].v_access &= ~CHANGED; 73413137Sralph HD = boolean(value(LECHO)); 73513137Sralph } 73613137Sralph if (vtable[PARITY].v_access&CHANGED) { 73713137Sralph vtable[PARITY].v_access &= ~CHANGED; 73813137Sralph setparity(); 73913137Sralph } 7403688Sroot } 7413822Ssam 7423822Ssam /* 74313277Ssam * Turn tandem mode on or off for remote tty. 74413137Sralph */ 74513137Sralph tandem(option) 74613277Ssam char *option; 74713137Sralph { 74813137Sralph struct sgttyb rmtty; 74913137Sralph 75013137Sralph ioctl(FD, TIOCGETP, &rmtty); 75113137Sralph if (strcmp(option,"on") == 0) { 75213137Sralph rmtty.sg_flags |= TANDEM; 75313137Sralph arg.sg_flags |= TANDEM; 75413277Ssam } else { 75513137Sralph rmtty.sg_flags &= ~TANDEM; 75613137Sralph arg.sg_flags &= ~TANDEM; 75713137Sralph } 75813137Sralph ioctl(FD, TIOCSETP, &rmtty); 75913137Sralph ioctl(0, TIOCSETP, &arg); 76013137Sralph } 76113137Sralph 76213137Sralph /* 7633822Ssam * Send a break. 7643822Ssam */ 7653822Ssam genbrk() 7663822Ssam { 76713277Ssam 7683822Ssam ioctl(FD, TIOCSBRK, NULL); 7693822Ssam sleep(1); 7703822Ssam ioctl(FD, TIOCCBRK, NULL); 7713822Ssam } 7725133Ssam 7735133Ssam /* 7745133Ssam * Suspend tip 7755133Ssam */ 77627702Ssam suspend(c) 77727702Ssam char c; 7785133Ssam { 77913277Ssam 7805133Ssam unraw(); 78133119Sbostic kill(c == CTRL('y') ? getpid() : 0, SIGTSTP); 7825133Ssam raw(); 7835133Ssam } 78413137Sralph 78513137Sralph /* 78613137Sralph * expand a file name if it includes shell meta characters 78713137Sralph */ 78813137Sralph 78913137Sralph char * 79013137Sralph expand(name) 79113137Sralph char name[]; 79213137Sralph { 79313137Sralph static char xname[BUFSIZ]; 79413137Sralph char cmdbuf[BUFSIZ]; 79513137Sralph register int pid, l, rc; 79613137Sralph register char *cp, *Shell; 79713137Sralph int s, pivec[2], (*sigint)(); 79813137Sralph 79913137Sralph if (!anyof(name, "~{[*?$`'\"\\")) 80013137Sralph return(name); 80113137Sralph /* sigint = signal(SIGINT, SIG_IGN); */ 80213137Sralph if (pipe(pivec) < 0) { 80313137Sralph perror("pipe"); 80413137Sralph /* signal(SIGINT, sigint) */ 80513137Sralph return(name); 80613137Sralph } 80713137Sralph sprintf(cmdbuf, "echo %s", name); 80813137Sralph if ((pid = vfork()) == 0) { 80913137Sralph Shell = value(SHELL); 81013137Sralph if (Shell == NOSTR) 81113137Sralph Shell = "/bin/sh"; 81213137Sralph close(pivec[0]); 81313137Sralph close(1); 81413137Sralph dup(pivec[1]); 81513137Sralph close(pivec[1]); 81613137Sralph close(2); 81730458Skarels shell_uid(); 81813137Sralph execl(Shell, Shell, "-c", cmdbuf, 0); 81913137Sralph _exit(1); 82013137Sralph } 82113137Sralph if (pid == -1) { 82213137Sralph perror("fork"); 82313137Sralph close(pivec[0]); 82413137Sralph close(pivec[1]); 82513137Sralph return(NOSTR); 82613137Sralph } 82713137Sralph close(pivec[1]); 82813137Sralph l = read(pivec[0], xname, BUFSIZ); 82913137Sralph close(pivec[0]); 83013137Sralph while (wait(&s) != pid); 83113137Sralph ; 83213137Sralph s &= 0377; 83313137Sralph if (s != 0 && s != SIGPIPE) { 83413137Sralph fprintf(stderr, "\"Echo\" failed\n"); 83513137Sralph return(NOSTR); 83613137Sralph } 83713137Sralph if (l < 0) { 83813137Sralph perror("read"); 83913137Sralph return(NOSTR); 84013137Sralph } 84113137Sralph if (l == 0) { 84213137Sralph fprintf(stderr, "\"%s\": No match\n", name); 84313137Sralph return(NOSTR); 84413137Sralph } 84513137Sralph if (l == BUFSIZ) { 84613137Sralph fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name); 84713137Sralph return(NOSTR); 84813137Sralph } 84913137Sralph xname[l] = 0; 85013137Sralph for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) 85113137Sralph ; 85213137Sralph *++cp = '\0'; 85313137Sralph return(xname); 85413137Sralph } 85513137Sralph 85613137Sralph /* 85713137Sralph * Are any of the characters in the two strings the same? 85813137Sralph */ 85913137Sralph 86013137Sralph anyof(s1, s2) 86113137Sralph register char *s1, *s2; 86213137Sralph { 86313137Sralph register int c; 86413137Sralph 86513137Sralph while (c = *s1++) 86613137Sralph if (any(c, s2)) 86713137Sralph return(1); 86813137Sralph return(0); 86913137Sralph } 870