X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/96ad7152ff38166136d9b8d8569cdae888375e2f..bc258617f323d737755d6043c64ffea2c59b69d4:/usr/src/usr.bin/tip/cmds.c diff --git a/usr/src/usr.bin/tip/cmds.c b/usr/src/usr.bin/tip/cmds.c index b6aa514e5b..58ea92e76d 100644 --- a/usr/src/usr.bin/tip/cmds.c +++ b/usr/src/usr.bin/tip/cmds.c @@ -1,4 +1,24 @@ -/* cmds.c 4.9 82/07/29 */ +/* + * Copyright (c) 1983 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static char sccsid[] = "@(#)cmds.c 5.9 (Berkeley) %G%"; +#endif /* not lint */ + #include "tip.h" /* * tip @@ -24,7 +44,7 @@ int intcopy(); /* interrupt routine for file transfers */ getfl(c) char c; { - char buf[256]; + char buf[256], *cp, *expand(); putchar(c); /* @@ -32,7 +52,8 @@ getfl(c) */ if (prompt("Local file name? ", copyname)) return; - if ((sfd = creat(copyname, 0666)) < 0) { + cp = expand(copyname); + if ((sfd = creat(cp, 0666)) < 0) { printf("\r\n%s: cannot creat\r\n", copyname); return; } @@ -54,7 +75,7 @@ cu_take(cc) char cc; { int fd, argc; - char line[BUFSIZ]; + char line[BUFSIZ], *expand(), *cp; if (prompt("[take] ", copyname)) return; @@ -64,14 +85,16 @@ cu_take(cc) } if (argc == 1) argv[1] = argv[0]; - if ((fd = creat(argv[1], 0666)) < 0) { + cp = expand(argv[1]); + if ((fd = creat(cp, 0666)) < 0) { printf("\r\n%s: cannot create\r\n", argv[1]); return; } - sprintf(line, "cat '%s';echo \01", argv[0]); + sprintf(line, "cat %s;echo \01", argv[0]); transfer(line, fd, "\01"); } +static jmp_buf intbuf; /* * Bulk transfer routine -- * used by getfl(), cu_take(), and pipefile() @@ -84,22 +107,24 @@ transfer(buf, fd, eofchars) register char *p = buffer; register int cnt, eof; time_t start; + int (*f)(); - write(FD, buf, size(buf)); + pwrite(FD, buf, size(buf)); quit = 0; - signal(SIGINT, intcopy); kill(pid, SIGIOT); read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ /* * finish command */ - write(FD, "\r", 1); + pwrite(FD, "\r", 1); do read(FD, &c, 1); while ((c&0177) != '\n'); ioctl(0, TIOCSETC, &defchars); + (void) setjmp(intbuf); + f = signal(SIGINT, intcopy); start = time(0); for (ct = 0; !quit;) { eof = read(FD, &c, 1) <= 0; @@ -132,7 +157,7 @@ transfer(buf, fd, eofchars) prtime(" lines transferred in ", time(0)-start); ioctl(0, TIOCSETC, &tchars); write(fildes[1], (char *)&ccc, 1); - signal(SIGINT, SIG_DFL); + signal(SIGINT, f); close(fd); } @@ -188,6 +213,7 @@ pipefile() */ stopsnd() { + stop = 1; signal(SIGINT, SIG_IGN); } @@ -201,6 +227,8 @@ sendfile(cc) char cc; { FILE *fd; + char *fnamex; + char *expand(); putchar(cc); /* @@ -212,7 +240,8 @@ sendfile(cc) /* * look up file */ - if ((fd = fopen(fname, "r")) == NULL) { + fnamex = expand(fname); + if ((fd = fopen(fnamex, "r")) == NULL) { printf("%s: cannot open\r\n", fname); return; } @@ -233,13 +262,14 @@ transmit(fd, eofchars, command) FILE *fd; char *eofchars, *command; { - char *pc, lastc, rc; + char *pc, lastc; int c, ccount, lcount; time_t start_t, stop_t; + int (*f)(); kill(pid, SIGIOT); /* put TIPOUT into a wait state */ - signal(SIGINT, stopsnd); stop = 0; + f = signal(SIGINT, stopsnd); ioctl(0, TIOCSETC, &defchars); read(repdes[0], (char *)&ccc, 1); if (command != NULL) { @@ -266,51 +296,59 @@ transmit(fd, eofchars, command) goto out; if (c == EOF) goto out; - if (c == 0177) + if (c == 0177 && !boolean(value(RAWFTP))) continue; lastc = c; if (c < 040) { - if (c == '\n') - c = '\r'; + if (c == '\n') { + if (!boolean(value(RAWFTP))) + c = '\r'; + } else if (c == '\t') { - if (boolean(value(TABEXPAND))) { - send(' '); - while ((++ccount % 8) != 0) + if (!boolean(value(RAWFTP))) { + if (boolean(value(TABEXPAND))) { send(' '); - continue; + while ((++ccount % 8) != 0) + send(' '); + continue; + } } - } else if (!any(c, value(EXCEPTIONS))) - continue; + } else + if (!boolean(value(RAWFTP))) + continue; } send(c); - } while (c != '\r'); + } while (c != '\r' && !boolean(value(RAWFTP))); if (boolean(value(VERBOSE))) printf("\r%d", ++lcount); if (boolean(value(ECHOCHECK))) { - alarm(10); timedout = 0; + alarm(value(ETIMEOUT)); do { /* wait for prompt */ - read(FD, (char *)&rc, 1); + read(FD, (char *)&c, 1); if (timedout || stop) { if (timedout) printf("\r\ntimed out at eol\r\n"); alarm(0); goto out; } - } while ((rc&0177) != character(value(PROMPT))); + } while ((c&0177) != character(value(PROMPT))); alarm(0); } } out: - if (lastc != '\n') + if (lastc != '\n' && !boolean(value(RAWFTP))) send('\r'); for (pc = eofchars; *pc; pc++) send(*pc); stop_t = time(0); fclose(fd); - signal(SIGINT, SIG_DFL); + signal(SIGINT, f); if (boolean(value(VERBOSE))) - prtime(" lines transferred in ", stop_t-start_t); + if (boolean(value(RAWFTP))) + prtime(" chars transferred in ", stop_t-start_t); + else + prtime(" lines transferred in ", stop_t-start_t); write(fildes[1], (char *)&ccc, 1); ioctl(0, TIOCSETC, &tchars); } @@ -324,6 +362,8 @@ cu_put(cc) FILE *fd; char line[BUFSIZ]; int argc; + char *expand(); + char *copynamex; if (prompt("[put] ", copyname)) return; @@ -333,14 +373,15 @@ cu_put(cc) } if (argc == 1) argv[1] = argv[0]; - if ((fd = fopen(argv[0], "r")) == NULL) { - printf("%s: cannot open\r\n", argv[0]); + copynamex = expand(argv[0]); + if ((fd = fopen(copynamex, "r")) == NULL) { + printf("%s: cannot open\r\n", copynamex); return; } if (boolean(value(ECHOCHECK))) - sprintf(line, "cat>'%s'\r", argv[1]); + sprintf(line, "cat>%s\r", argv[1]); else - sprintf(line, "stty -echo;cat>'%s';stty echo\r", argv[1]); + sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]); transmit(fd, "\04", line); } @@ -355,19 +396,28 @@ send(c) int retry = 0; cc = c; - write(FD, (char *)&cc, 1); - if (!boolean(value(ECHOCHECK))) + pwrite(FD, &cc, 1); +#ifdef notdef + if (number(value(CDELAY)) > 0 && c != '\r') + nap(number(value(CDELAY))); +#endif + if (!boolean(value(ECHOCHECK))) { +#ifdef notdef + if (number(value(LDELAY)) > 0 && c == '\r') + nap(number(value(LDELAY))); +#endif return; + } tryagain: timedout = 0; - alarm(10); - read(FD, (char *)&cc, 1); + alarm(value(ETIMEOUT)); + read(FD, &cc, 1); alarm(0); if (timedout) { printf("\r\ntimeout error (%s)\r\n", ctrl(c)); if (retry++ > 3) return; - write(FD, &null, 1); /* poke it */ + pwrite(FD, &null, 1); /* poke it */ goto tryagain; } } @@ -378,6 +428,54 @@ timeout() timedout = 1; } +/* + * Stolen from consh() -- puts a remote file on the output of a local command. + * Identical to consh() except for where stdout goes. + */ +pipeout(c) +{ + char buf[256]; + int cpid, status, p; + time_t start; + + putchar(c); + if (prompt("Local command? ", buf)) + return; + kill(pid, SIGIOT); /* put TIPOUT into a wait state */ + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + ioctl(0, TIOCSETC, &defchars); + read(repdes[0], (char *)&ccc, 1); + /* + * Set up file descriptors in the child and + * let it go... + */ + if ((cpid = fork()) < 0) + printf("can't fork!\r\n"); + else if (cpid) { + start = time(0); + while ((p = wait(&status)) > 0 && p != cpid) + ; + } else { + register int i; + + dup2(FD, 1); + for (i = 3; i < 20; i++) + close(i); + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + execute(buf); + printf("can't find `%s'\r\n", buf); + exit(0); + } + if (boolean(value(VERBOSE))) + prtime("away for ", time(0)-start); + write(fildes[1], (char *)&ccc, 1); + ioctl(0, TIOCSETC, &tchars); + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); +} + #ifdef CONNECT /* * Fork a program with: @@ -460,6 +558,7 @@ shell() cp = value(SHELL); else cp++; + shell_uid(); execl(value(SHELL), cp, 0); printf("\r\ncan't execl!\r\n"); exit(1); @@ -494,33 +593,51 @@ setscript() */ chdirectory() { - char dirname[80]; + char dirname[80]; register char *cp = dirname; - if (prompt("[cd] ", dirname)) + if (prompt("[cd] ", dirname)) { if (stoprompt) return; - else - cp = value(HOME); + cp = value(HOME); + } if (chdir(cp) < 0) printf("%s: bad directory\r\n", cp); printf("!\r\n"); } -finish() +abort(msg) + char *msg; { + kill(pid, SIGTERM); - disconnect(); + disconnect(msg); + if (msg != NOSTR) + printf("\r\n%s", msg); printf("\r\n[EOT]\r\n"); - delock(uucplock); + daemon_uid(); + (void)uu_unlock(uucplock); unraw(); exit(0); } +finish() +{ + char *dismsg; + + if ((dismsg = value(DISCONNECT)) != NOSTR) { + write(FD, dismsg, strlen(dismsg)); + sleep(5); + } + abort(NOSTR); +} + intcopy() { + raw(); quit = 1; + longjmp(intbuf, 1); } execute(s) @@ -532,6 +649,7 @@ execute(s) cp = value(SHELL); else cp++; + shell_uid(); execl(value(SHELL), cp, "-c", s, 0); } @@ -572,7 +690,7 @@ prtime(s, a) } printf("%s", s); while (--i >= 0) - if (nums[i]) + if (nums[i] || i == 0 && nums[1] == 0 && nums[2] == 0) printf("%d %s%c ", nums[i], sep[i], nums[i] == 1 ? '\0' : 's'); printf("\r\n!\r\n"); @@ -604,41 +722,148 @@ variable() if (boolean(value(SCRIPT))) setscript(); } + if (vtable[TAND].v_access&CHANGED) { + vtable[TAND].v_access &= ~CHANGED; + if (boolean(value(TAND))) + tandem("on"); + else + tandem("off"); + } + if (vtable[LECHO].v_access&CHANGED) { + vtable[LECHO].v_access &= ~CHANGED; + HD = boolean(value(LECHO)); + } + if (vtable[PARITY].v_access&CHANGED) { + vtable[PARITY].v_access &= ~CHANGED; + setparity(); + } +} + +/* + * Turn tandem mode on or off for remote tty. + */ +tandem(option) + char *option; +{ + struct sgttyb rmtty; + + ioctl(FD, TIOCGETP, &rmtty); + if (strcmp(option,"on") == 0) { + rmtty.sg_flags |= TANDEM; + arg.sg_flags |= TANDEM; + } else { + rmtty.sg_flags &= ~TANDEM; + arg.sg_flags &= ~TANDEM; + } + ioctl(FD, TIOCSETP, &rmtty); + ioctl(0, TIOCSETP, &arg); } /* * Send a break. - * If we can't do it directly (as on VMUNIX), then simulate it. */ genbrk() { -#ifdef VMUNIX + ioctl(FD, TIOCSBRK, NULL); sleep(1); ioctl(FD, TIOCCBRK, NULL); -#else - struct sgttyb ttbuf; - int sospeed; - - ioctl(FD, TIOCGETP, &ttbuf); - sospeed = ttbuf.sg_ospeed; - ttbuf.sg_ospeed = B150; - ioctl(FD, TIOCSETP, &ttbuf); - write(FD, "\0\0\0\0\0\0\0\0\0\0", 10); - ttbuf.sg_ospeed = sospeed; - ioctl(FD, TIOCSETP, &ttbuf); - write(FD, "@", 1); -#endif } -#ifdef SIGTSTP /* * Suspend tip */ -suspend() +suspend(c) + char c; { + unraw(); - kill(0, SIGTSTP); + kill(c == CTRL('y') ? getpid() : 0, SIGTSTP); raw(); } -#endif + +/* + * expand a file name if it includes shell meta characters + */ + +char * +expand(name) + char name[]; +{ + static char xname[BUFSIZ]; + char cmdbuf[BUFSIZ]; + register int pid, l, rc; + register char *cp, *Shell; + int s, pivec[2], (*sigint)(); + + if (!anyof(name, "~{[*?$`'\"\\")) + return(name); + /* sigint = signal(SIGINT, SIG_IGN); */ + if (pipe(pivec) < 0) { + perror("pipe"); + /* signal(SIGINT, sigint) */ + return(name); + } + sprintf(cmdbuf, "echo %s", name); + if ((pid = vfork()) == 0) { + Shell = value(SHELL); + if (Shell == NOSTR) + Shell = "/bin/sh"; + close(pivec[0]); + close(1); + dup(pivec[1]); + close(pivec[1]); + close(2); + shell_uid(); + execl(Shell, Shell, "-c", cmdbuf, 0); + _exit(1); + } + if (pid == -1) { + perror("fork"); + close(pivec[0]); + close(pivec[1]); + return(NOSTR); + } + close(pivec[1]); + l = read(pivec[0], xname, BUFSIZ); + close(pivec[0]); + while (wait(&s) != pid); + ; + s &= 0377; + if (s != 0 && s != SIGPIPE) { + fprintf(stderr, "\"Echo\" failed\n"); + return(NOSTR); + } + if (l < 0) { + perror("read"); + return(NOSTR); + } + if (l == 0) { + fprintf(stderr, "\"%s\": No match\n", name); + return(NOSTR); + } + if (l == BUFSIZ) { + fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name); + return(NOSTR); + } + xname[l] = 0; + for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) + ; + *++cp = '\0'; + return(xname); +} + +/* + * Are any of the characters in the two strings the same? + */ + +anyof(s1, s2) + register char *s1, *s2; +{ + register int c; + + while (c = *s1++) + if (any(c, s2)) + return(1); + return(0); +}