diff options
Diffstat (limited to 'usr.bin')
28 files changed, 6859 insertions, 0 deletions
diff --git a/usr.bin/tip/libacu/biz22.c b/usr.bin/tip/libacu/biz22.c new file mode 100644 index 0000000..63fb11c --- /dev/null +++ b/usr.bin/tip/libacu/biz22.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)biz22.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "tipconf.h" +#include "tip.h" + +#define DISCONNECT_CMD "\20\04" /* disconnection string */ + +static void sigALRM(); +static int timeout = 0; +static jmp_buf timeoutbuf; + +/* + * Dial up on a BIZCOMP Model 1022 with either + * tone dialing (mod = "V") + * pulse dialing (mod = "W") + */ +static int +biz_dialer(num, mod) + char *num, *mod; +{ + register int connected = 0; + char cbuf[40]; + static int cmd(), detect(); + + if (boolean(value(VERBOSE))) + printf("\nstarting call..."); + /* + * Disable auto-answer and configure for tone/pulse + * dialing + */ + if (cmd("\02K\r")) { + printf("can't initialize bizcomp..."); + return (0); + } + strcpy(cbuf, "\02.\r"); + cbuf[1] = *mod; + if (cmd(cbuf)) { + printf("can't set dialing mode..."); + return (0); + } + strcpy(cbuf, "\02D"); + strcat(cbuf, num); + strcat(cbuf, "\r"); + write(FD, cbuf, strlen(cbuf)); + if (!detect("7\r")) { + printf("can't get dial tone..."); + return (0); + } + if (boolean(value(VERBOSE))) + printf("ringing..."); + /* + * The reply from the BIZCOMP should be: + * 2 \r or 7 \r failure + * 1 \r success + */ + connected = detect("1\r"); +#if ACULOG + if (timeout) { + char line[80]; + + sprintf(line, "%d second dial timeout", + number(value(DIALTIMEOUT))); + logent(value(HOST), num, "biz1022", line); + } +#endif + if (timeout) + biz22_disconnect(); /* insurance */ + return (connected); +} + +biz22w_dialer(num, acu) + char *num, *acu; +{ + + return (biz_dialer(num, "W")); +} + +biz22f_dialer(num, acu) + char *num, *acu; +{ + + return (biz_dialer(num, "V")); +} + +biz22_disconnect() +{ + int rw = 2; + + write(FD, DISCONNECT_CMD, 4); + sleep(2); + ioctl(FD, TIOCFLUSH, &rw); +} + +biz22_abort() +{ + + write(FD, "\02", 1); +} + +static void +sigALRM() +{ + + timeout = 1; + longjmp(timeoutbuf, 1); +} + +static int +cmd(s) + register char *s; +{ + sig_t f; + char c; + + write(FD, s, strlen(s)); + f = signal(SIGALRM, sigALRM); + if (setjmp(timeoutbuf)) { + biz22_abort(); + signal(SIGALRM, f); + return (1); + } + alarm(number(value(DIALTIMEOUT))); + read(FD, &c, 1); + alarm(0); + signal(SIGALRM, f); + c &= 0177; + return (c != '\r'); +} + +static int +detect(s) + register char *s; +{ + sig_t f; + char c; + + f = signal(SIGALRM, sigALRM); + timeout = 0; + while (*s) { + if (setjmp(timeoutbuf)) { + biz22_abort(); + break; + } + alarm(number(value(DIALTIMEOUT))); + read(FD, &c, 1); + alarm(0); + c &= 0177; + if (c != *s++) + return (0); + } + signal(SIGALRM, f); + return (timeout == 0); +} diff --git a/usr.bin/tip/libacu/biz31.c b/usr.bin/tip/libacu/biz31.c new file mode 100644 index 0000000..9553a6d --- /dev/null +++ b/usr.bin/tip/libacu/biz31.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)biz31.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "tipconf.h" +#include "tip.h" + +#define MAXRETRY 3 /* sync up retry count */ +#define DISCONNECT_CMD "\21\25\11\24" /* disconnection string */ + +static void sigALRM(); +static int timeout = 0; +static jmp_buf timeoutbuf; + +/* + * Dial up on a BIZCOMP Model 1031 with either + * tone dialing (mod = "f") + * pulse dialing (mod = "w") + */ +static int +biz_dialer(num, mod) + char *num, *mod; +{ + register int connected = 0; + + if (!bizsync(FD)) { + logent(value(HOST), "", "biz", "out of sync"); + printf("bizcomp out of sync\n"); + delock(uucplock); + exit(0); + } + if (boolean(value(VERBOSE))) + printf("\nstarting call..."); + echo("#\rk$\r$\n"); /* disable auto-answer */ + echo("$>$.$ #\r"); /* tone/pulse dialing */ + echo(mod); + echo("$\r$\n"); + echo("$>$.$ #\re$ "); /* disconnection sequence */ + echo(DISCONNECT_CMD); + echo("\r$\n$\r$\n"); + echo("$>$.$ #\rr$ "); /* repeat dial */ + echo(num); + echo("\r$\n"); + if (boolean(value(VERBOSE))) + printf("ringing..."); + /* + * The reply from the BIZCOMP should be: + * `^G NO CONNECTION\r\n^G\r\n' failure + * ` CONNECTION\r\n^G' success + */ + connected = detect(" "); +#if ACULOG + if (timeout) { + char line[80]; + + sprintf(line, "%d second dial timeout", + number(value(DIALTIMEOUT))); + logent(value(HOST), num, "biz", line); + } +#endif + if (!connected) + flush(" NO CONNECTION\r\n\07\r\n"); + else + flush("CONNECTION\r\n\07"); + if (timeout) + biz31_disconnect(); /* insurance */ + return (connected); +} + +biz31w_dialer(num, acu) + char *num, *acu; +{ + + return (biz_dialer(num, "w")); +} + +biz31f_dialer(num, acu) + char *num, *acu; +{ + + return (biz_dialer(num, "f")); +} + +biz31_disconnect() +{ + + write(FD, DISCONNECT_CMD, 4); + sleep(2); + ioctl(FD, TIOCFLUSH); +} + +biz31_abort() +{ + + write(FD, "\33", 1); +} + +static int +echo(s) + register char *s; +{ + char c; + + while (c = *s++) switch (c) { + + case '$': + read(FD, &c, 1); + s++; + break; + + case '#': + c = *s++; + write(FD, &c, 1); + break; + + default: + write(FD, &c, 1); + read(FD, &c, 1); + } +} + +static void +sigALRM() +{ + + timeout = 1; + longjmp(timeoutbuf, 1); +} + +static int +detect(s) + register char *s; +{ + sig_t f; + char c; + + f = signal(SIGALRM, sigALRM); + timeout = 0; + while (*s) { + if (setjmp(timeoutbuf)) { + printf("\07timeout waiting for reply\n"); + biz31_abort(); + break; + } + alarm(number(value(DIALTIMEOUT))); + read(FD, &c, 1); + alarm(0); + if (c != *s++) + break; + } + signal(SIGALRM, f); + return (timeout == 0); +} + +static int +flush(s) + register char *s; +{ + sig_t f; + char c; + + f = signal(SIGALRM, sigALRM); + while (*s++) { + if (setjmp(timeoutbuf)) + break; + alarm(10); + read(FD, &c, 1); + alarm(0); + } + signal(SIGALRM, f); + timeout = 0; /* guard against disconnection */ +} + +/* + * This convoluted piece of code attempts to get + * the bizcomp in sync. If you don't have the capacity or nread + * call there are gory ways to simulate this. + */ +static int +bizsync(fd) +{ +#ifdef FIOCAPACITY + struct capacity b; +# define chars(b) ((b).cp_nbytes) +# define IOCTL FIOCAPACITY +#endif +#ifdef FIONREAD + long b; +# define chars(b) (b) +# define IOCTL FIONREAD +#endif + register int already = 0; + char buf[10]; + +retry: + if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0 && chars(b) > 0) + ioctl(fd, TIOCFLUSH); + write(fd, "\rp>\r", 4); + sleep(1); + if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0) { + if (chars(b) != 10) { + nono: + if (already > MAXRETRY) + return (0); + write(fd, DISCONNECT_CMD, 4); + sleep(2); + already++; + goto retry; + } else { + read(fd, buf, 10); + if (strncmp(buf, "p >\r\n\r\n>", 8)) + goto nono; + } + } + return (1); +} diff --git a/usr.bin/tip/libacu/courier.c b/usr.bin/tip/libacu/courier.c new file mode 100644 index 0000000..f4aeab3 --- /dev/null +++ b/usr.bin/tip/libacu/courier.c @@ -0,0 +1,334 @@ +/* + * Copyright (c) 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)courier.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Routines for calling up on a Courier modem. + * Derived from Hayes driver. + */ +#include "tipconf.h" +#include "tip.h" +#include "acucommon.h" +#include <stdio.h> + +#define MAXRETRY 5 + +static void sigALRM(); +static int timeout = 0; +static int connected = 0; +static jmp_buf timeoutbuf, intbuf; +static int coursync(); + +cour_dialer(num, acu) + register char *num; + char *acu; +{ + register char *cp; +#if ACULOG + char line[80]; +#endif + static int cour_connect(), cour_swallow(); + + if (boolean(value(VERBOSE))) + printf("Using \"%s\"\n", acu); + + acu_hupcl (); + + /* + * Get in synch. + */ + if (!coursync()) { +badsynch: + printf("can't synchronize with courier\n"); +#if ACULOG + logent(value(HOST), num, "courier", "can't synch up"); +#endif + return (0); + } + cour_write(FD, "AT E0\r", 6); /* turn off echoing */ + sleep(1); +#ifdef DEBUG + if (boolean(value(VERBOSE))) + cour_verbose_read(); +#endif + ioctl(FD, TIOCFLUSH, 0); /* flush any clutter */ + cour_write(FD, "AT C1 E0 H0 Q0 X6 V1\r", 21); + if (!cour_swallow("\r\nOK\r\n")) + goto badsynch; + fflush(stdout); + cour_write(FD, "AT D", 4); + for (cp = num; *cp; cp++) + if (*cp == '=') + *cp = ','; + cour_write(FD, num, strlen(num)); + cour_write(FD, "\r", 1); + connected = cour_connect(); +#if ACULOG + if (timeout) { + sprintf(line, "%d second dial timeout", + number(value(DIALTIMEOUT))); + logent(value(HOST), num, "cour", line); + } +#endif + if (timeout) + cour_disconnect(); + return (connected); +} + +cour_disconnect() +{ + /* first hang up the modem*/ + ioctl(FD, TIOCCDTR, 0); + sleep(1); + ioctl(FD, TIOCSDTR, 0); + coursync(); /* reset */ + close(FD); +} + +cour_abort() +{ + cour_write(FD, "\r", 1); /* send anything to abort the call */ + cour_disconnect(); +} + +static void +sigALRM() +{ + printf("\07timeout waiting for reply\n"); + timeout = 1; + longjmp(timeoutbuf, 1); +} + +static int +cour_swallow(match) + register char *match; + { + sig_t f; + char c; + + f = signal(SIGALRM, sigALRM); + timeout = 0; + do { + if (*match =='\0') { + signal(SIGALRM, f); + return (1); + } + if (setjmp(timeoutbuf)) { + signal(SIGALRM, f); + return (0); + } + alarm(number(value(DIALTIMEOUT))); + read(FD, &c, 1); + alarm(0); + c &= 0177; +#ifdef DEBUG + if (boolean(value(VERBOSE))) + putchar(c); +#endif + } while (c == *match++); +#ifdef DEBUG + if (boolean(value(VERBOSE))) + fflush(stdout); +#endif + signal(SIGALRM, SIG_DFL); + return (0); +} + +struct baud_msg { + char *msg; + int baud; +} baud_msg[] = { + "", B300, + " 1200", B1200, + " 2400", B2400, + " 9600", B9600, + " 9600/ARQ", B9600, + 0, 0, +}; + +static int +cour_connect() +{ + char c; + int nc, nl, n; + char dialer_buf[64]; + struct baud_msg *bm; + sig_t f; + + if (cour_swallow("\r\n") == 0) + return (0); + f = signal(SIGALRM, sigALRM); +again: + nc = 0; nl = sizeof(dialer_buf)-1; + bzero(dialer_buf, sizeof(dialer_buf)); + timeout = 0; + for (nc = 0, nl = sizeof(dialer_buf)-1 ; nl > 0 ; nc++, nl--) { + if (setjmp(timeoutbuf)) + break; + alarm(number(value(DIALTIMEOUT))); + n = read(FD, &c, 1); + alarm(0); + if (n <= 0) + break; + c &= 0x7f; + if (c == '\r') { + if (cour_swallow("\n") == 0) + break; + if (!dialer_buf[0]) + goto again; + if (strcmp(dialer_buf, "RINGING") == 0 && + boolean(value(VERBOSE))) { +#ifdef DEBUG + printf("%s\r\n", dialer_buf); +#endif + goto again; + } + if (strncmp(dialer_buf, "CONNECT", + sizeof("CONNECT")-1) != 0) + break; + for (bm = baud_msg ; bm->msg ; bm++) + if (strcmp(bm->msg, + dialer_buf+sizeof("CONNECT")-1) == 0) { + if (!acu_setspeed(bm->baud)) + goto error; + signal(SIGALRM, f); +#ifdef DEBUG + if (boolean(value(VERBOSE))) + printf("%s\r\n", dialer_buf); +#endif + return (1); + } + break; + } + dialer_buf[nc] = c; +#ifdef notdef + if (boolean(value(VERBOSE))) + putchar(c); +#endif + } +error1: + printf("%s\r\n", dialer_buf); +error: + signal(SIGALRM, f); + return (0); +} + +/* + * This convoluted piece of code attempts to get + * the courier in sync. + */ +static int +coursync() +{ + int already = 0; + int len; + char buf[40]; + + while (already++ < MAXRETRY) { + ioctl(FD, TIOCFLUSH, 0); /* flush any clutter */ + cour_write(FD, "\rAT Z\r", 6); /* reset modem */ + bzero(buf, sizeof(buf)); + sleep(1); + ioctl(FD, FIONREAD, &len); + if (len) { + len = read(FD, buf, sizeof(buf)); +#ifdef DEBUG + buf[len] = '\0'; + printf("coursync: (\"%s\")\n\r", buf); +#endif + if (index(buf, '0') || + (index(buf, 'O') && index(buf, 'K'))) + return(1); + } + /* + * If not strapped for DTR control, + * try to get command mode. + */ + sleep(1); + cour_write(FD, "+++", 3); + sleep(1); + /* + * Toggle DTR to force anyone off that might have left + * the modem connected. + */ + ioctl(FD, TIOCCDTR, 0); + sleep(1); + ioctl(FD, TIOCSDTR, 0); + } + cour_write(FD, "\rAT Z\r", 6); + return (0); +} + +cour_write(fd, cp, n) +int fd; +char *cp; +int n; +{ +#ifdef notdef + if (boolean(value(VERBOSE))) + write(1, cp, n); +#endif + acu_flush (); + cour_nap(); + for ( ; n-- ; cp++) { + write(fd, cp, 1); + acu_flush (); + cour_nap(); + } +} + +#ifdef DEBUG +cour_verbose_read() +{ + int n = 0; + char buf[BUFSIZ]; + + if (ioctl(FD, FIONREAD, &n) < 0) + return; + if (n <= 0) + return; + if (read(FD, buf, n) != n) + return; + write(1, buf, n); +} +#endif + +cour_nap() +{ + acu_nap (50); +} + +/* end of courier.c */ diff --git a/usr.bin/tip/libacu/df.c b/usr.bin/tip/libacu/df.c new file mode 100644 index 0000000..fc60ad3 --- /dev/null +++ b/usr.bin/tip/libacu/df.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)df.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Dial the DF02-AC or DF03-AC + */ + +#include "tipconf.h" +#include "tip.h" + +static jmp_buf Sjbuf; +static void timeout(); + +df02_dialer(num, acu) + char *num, *acu; +{ + + return (df_dialer(num, acu, 0)); +} + +df03_dialer(num, acu) + char *num, *acu; +{ + + return (df_dialer(num, acu, 1)); +} + +df_dialer(num, acu, df03) + char *num, *acu; + int df03; +{ + register int f = FD; + int speed = 0, rw = 2; + char c = '\0'; + + acu_hupcl (); + + if (setjmp(Sjbuf)) { + printf("connection timed out\r\n"); + df_disconnect(); + return (0); + } + if (boolean(value(VERBOSE))) + printf("\ndialing..."); + fflush(stdout); +#ifdef TIOCMSET + if (df03) { + int st = TIOCM_ST; /* secondary Transmit flag */ + + if ((speed = acu_getspeed ()) != B1200) { /* must dial at 1200 baud */ + acu_setspeed (B1200); + ioctl(f, TIOCMBIC, &st); /* clear ST for 300 baud */ + } else + ioctl(f, TIOCMBIS, &st); /* set ST for 1200 baud */ + } +#endif + signal(SIGALRM, timeout); + alarm(5 * strlen(num) + 10); + ioctl(f, TIOCFLUSH, &rw); + write(f, "\001", 1); + sleep(1); + write(f, "\002", 1); + write(f, num, strlen(num)); + read(f, &c, 1); +#ifdef TIOCMSET + if (df03 && speed) { + acu_setspeed (speed); + } +#endif + return (c == 'A'); +} + +df_disconnect() +{ + int rw = 2; + + write(FD, "\001", 1); + sleep(1); + ioctl(FD, TIOCFLUSH, &rw); +} + + +df_abort() +{ + + df_disconnect(); +} + + +static void +timeout() +{ + + longjmp(Sjbuf, 1); +} diff --git a/usr.bin/tip/libacu/dn11.c b/usr.bin/tip/libacu/dn11.c new file mode 100644 index 0000000..52749da --- /dev/null +++ b/usr.bin/tip/libacu/dn11.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)dn11.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Routines for dialing up on DN-11 + */ +#include "tipconf.h" +#include "tip.h" + +int dn_abort(); +void alarmtr(); +static jmp_buf jmpbuf; +static int child = -1, dn; + +dn_dialer(num, acu) + char *num, *acu; +{ + extern errno; + char *p, *q, phone[40]; + int lt, nw, connected = 1; + register int timelim; + + if (boolean(value(VERBOSE))) + printf("\nstarting call..."); + if ((dn = open(acu, 1)) < 0) { + if (errno == EBUSY) + printf("line busy..."); + else + printf("acu open error..."); + return (0); + } + if (setjmp(jmpbuf)) { + kill(child, SIGKILL); + close(dn); + return (0); + } + signal(SIGALRM, alarmtr); + timelim = 5 * strlen(num); + alarm(timelim < 30 ? 30 : timelim); + if ((child = fork()) == 0) { + /* + * ignore this stuff for aborts + */ + signal(SIGALRM, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + sleep(2); + nw = write(dn, num, lt = strlen(num)); + exit(nw != lt); + } + /* + * open line - will return on carrier + */ + if ((FD = open(DV, 2)) < 0) { + if (errno == EIO) + printf("lost carrier..."); + else + printf("dialup line open failed..."); + alarm(0); + kill(child, SIGKILL); + close(dn); + return (0); + } + alarm(0); + +#if HAVE_TERMIOS + { + struct termios term; + tcgetattr (dn, &term); + term.c_cflag |= HUPCL; + tcsetattr (dn, TCSANOW, &term); + } +#elif defined(TIOCHPCL) + ioctl(dn, TIOCHPCL, 0); +#endif + + signal(SIGALRM, SIG_DFL); + while ((nw = wait(<)) != child && nw != -1) + ; + fflush(stdout); + close(dn); + if (lt != 0) { + close(FD); + return (0); + } + return (1); +} + +void +alarmtr() +{ + alarm(0); + longjmp(jmpbuf, 1); +} + +/* + * Insurance, for some reason we don't seem to be + * hanging up... + */ +dn_disconnect() +{ + + sleep(2); + if (FD > 0) + ioctl(FD, TIOCCDTR, 0); + close(FD); +} + +dn_abort() +{ + + sleep(2); + if (child > 0) + kill(child, SIGKILL); + if (dn > 0) + close(dn); + if (FD > 0) + ioctl(FD, TIOCCDTR, 0); + close(FD); +} diff --git a/usr.bin/tip/libacu/hayes.c b/usr.bin/tip/libacu/hayes.c new file mode 100644 index 0000000..6cc6c06 --- /dev/null +++ b/usr.bin/tip/libacu/hayes.c @@ -0,0 +1,306 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)hayes.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Routines for calling up on a Hayes Modem + * (based on the old VenTel driver). + * The modem is expected to be strapped for "echo". + * Also, the switches enabling the DTR and CD lines + * must be set correctly. + * NOTICE: + * The easy way to hang up a modem is always simply to + * clear the DTR signal. However, if the +++ sequence + * (which switches the modem back to local mode) is sent + * before modem is hung up, removal of the DTR signal + * has no effect (except that it prevents the modem from + * recognizing commands). + * (by Helge Skrivervik, Calma Company, Sunnyvale, CA. 1984) + */ +/* + * TODO: + * It is probably not a good idea to switch the modem + * state between 'verbose' and terse (status messages). + * This should be kicked out and we should use verbose + * mode only. This would make it consistent with normal + * interactive use thru the command 'tip dialer'. + */ +#include "tipconf.h" +#include "tip.h" + +#define min(a,b) ((a < b) ? a : b) + +static void sigALRM(); +static int timeout = 0; +static jmp_buf timeoutbuf; +static char gobble(); +#define DUMBUFLEN 40 +static char dumbuf[DUMBUFLEN]; + +#define DIALING 1 +#define IDLE 2 +#define CONNECTED 3 +#define FAILED 4 +static int state = IDLE; + +hay_dialer(num, acu) + register char *num; + char *acu; +{ + register char *cp; + register int connected = 0; + char dummy; +#if ACULOG + char line[80]; +#endif + if (hay_sync() == 0) /* make sure we can talk to the modem */ + return(0); + if (boolean(value(VERBOSE))) + printf("\ndialing..."); + fflush(stdout); + acu_hupcl (); + acu_flush (); + write(FD, "ATv0\r", 5); /* tell modem to use short status codes */ + gobble("\r"); + gobble("\r"); + write(FD, "ATTD", 4); /* send dial command */ + write(FD, num, strlen(num)); + state = DIALING; + write(FD, "\r", 1); + connected = 0; + if (gobble("\r")) { + if ((dummy = gobble("01234")) != '1') + error_rep(dummy); + else + connected = 1; + } + if (connected) + state = CONNECTED; + else { + state = FAILED; + return (connected); /* lets get out of here.. */ + } + ioctl(FD, TIOCFLUSH, 0); +#if ACULOG + if (timeout) { + sprintf(line, "%d second dial timeout", + number(value(DIALTIMEOUT))); + logent(value(HOST), num, "hayes", line); + } +#endif + if (timeout) + hay_disconnect(); /* insurance */ + return (connected); +} + + +hay_disconnect() +{ + char c; + int len, rlen; + + /* first hang up the modem*/ +#ifdef DEBUG + printf("\rdisconnecting modem....\n\r"); +#endif + ioctl(FD, TIOCCDTR, 0); + sleep(1); + ioctl(FD, TIOCSDTR, 0); + goodbye(); +} + +hay_abort() +{ + + char c; + + write(FD, "\r", 1); /* send anything to abort the call */ + hay_disconnect(); +} + +static void +sigALRM() +{ + + printf("\07timeout waiting for reply\n\r"); + timeout = 1; + longjmp(timeoutbuf, 1); +} + +static char +gobble(match) + register char *match; +{ + char c; + sig_t f; + int i, status = 0; + + f = signal(SIGALRM, sigALRM); + timeout = 0; +#ifdef DEBUG + printf("\ngobble: waiting for %s\n", match); +#endif + do { + if (setjmp(timeoutbuf)) { + signal(SIGALRM, f); + return (0); + } + alarm(number(value(DIALTIMEOUT))); + read(FD, &c, 1); + alarm(0); + c &= 0177; +#ifdef DEBUG + printf("%c 0x%x ", c, c); +#endif + for (i = 0; i < strlen(match); i++) + if (c == match[i]) + status = c; + } while (status == 0); + signal(SIGALRM, SIG_DFL); +#ifdef DEBUG + printf("\n"); +#endif + return (status); +} + +error_rep(c) + register char c; +{ + printf("\n\r"); + switch (c) { + + case '0': + printf("OK"); + break; + + case '1': + printf("CONNECT"); + break; + + case '2': + printf("RING"); + break; + + case '3': + printf("NO CARRIER"); + break; + + case '4': + printf("ERROR in input"); + break; + + case '5': + printf("CONNECT 1200"); + break; + + default: + printf("Unknown Modem error: %c (0x%x)", c, c); + } + printf("\n\r"); + return; +} + +/* + * set modem back to normal verbose status codes. + */ +goodbye() +{ + int len, rlen; + char c; + + ioctl(FD, TIOCFLUSH, &len); /* get rid of trash */ + if (hay_sync()) { + sleep(1); +#ifndef DEBUG + ioctl(FD, TIOCFLUSH, 0); +#endif + write(FD, "ATH0\r", 5); /* insurance */ +#ifndef DEBUG + c = gobble("03"); + if (c != '0' && c != '3') { + printf("cannot hang up modem\n\r"); + printf("please use 'tip dialer' to make sure the line is hung up\n\r"); + } +#endif + sleep(1); + ioctl(FD, FIONREAD, &len); +#ifdef DEBUG + printf("goodbye1: len=%d -- ", len); + rlen = read(FD, dumbuf, min(len, DUMBUFLEN)); + dumbuf[rlen] = '\0'; + printf("read (%d): %s\r\n", rlen, dumbuf); +#endif + write(FD, "ATv1\r", 5); + sleep(1); +#ifdef DEBUG + ioctl(FD, FIONREAD, &len); + printf("goodbye2: len=%d -- ", len); + rlen = read(FD, dumbuf, min(len, DUMBUFLEN)); + dumbuf[rlen] = '\0'; + printf("read (%d): %s\r\n", rlen, dumbuf); +#endif + } + ioctl(FD, TIOCFLUSH, 0); /* clear the input buffer */ + ioctl(FD, TIOCCDTR, 0); /* clear DTR (insurance) */ + close(FD); +} + +#define MAXRETRY 5 + +hay_sync() +{ + int len, retry = 0; + + while (retry++ <= MAXRETRY) { + write(FD, "AT\r", 3); + sleep(1); + ioctl(FD, FIONREAD, &len); + if (len) { + len = read(FD, dumbuf, min(len, DUMBUFLEN)); + if (index(dumbuf, '0') || + (index(dumbuf, 'O') && index(dumbuf, 'K'))) + return(1); +#ifdef DEBUG + dumbuf[len] = '\0'; + printf("hay_sync: (\"%s\") %d\n\r", dumbuf, retry); +#endif + } + ioctl(FD, TIOCCDTR, 0); + ioctl(FD, TIOCSDTR, 0); + } + printf("Cannot synchronize with hayes...\n\r"); + return(0); +} diff --git a/usr.bin/tip/libacu/t3000.c b/usr.bin/tip/libacu/t3000.c new file mode 100644 index 0000000..1f1a1f0 --- /dev/null +++ b/usr.bin/tip/libacu/t3000.c @@ -0,0 +1,350 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)t3000.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Routines for calling up on a Telebit T3000 modem. + * Derived from Courier driver. + */ +#include "tipconf.h" +#include "tip.h" +#include "acucommon.h" +#include <stdio.h> + +#define MAXRETRY 5 + +static void sigALRM(); +static int timeout = 0; +static int connected = 0; +static jmp_buf timeoutbuf, intbuf; +static int t3000_sync(); + +t3000_dialer(num, acu) + register char *num; + char *acu; +{ + register char *cp; +#if ACULOG + char line[80]; +#endif + static int t3000_connect(), t3000_swallow(); + + if (boolean(value(VERBOSE))) + printf("Using \"%s\"\n", acu); + + acu_hupcl (); + /* + * Get in synch. + */ + if (!t3000_sync()) { +badsynch: + printf("can't synchronize with t3000\n"); +#if ACULOG + logent(value(HOST), num, "t3000", "can't synch up"); +#endif + return (0); + } + t3000_write(FD, "AT E0\r", 6); /* turn off echoing */ + sleep(1); +#ifdef DEBUG + if (boolean(value(VERBOSE))) + t3000_verbose_read(); +#endif + ioctl(FD, TIOCFLUSH, 0); /* flush any clutter */ + t3000_write(FD, "AT E0 H0 Q0 X4 V1\r", 18); + if (!t3000_swallow("\r\nOK\r\n")) + goto badsynch; + fflush(stdout); + t3000_write(FD, "AT D", 4); + for (cp = num; *cp; cp++) + if (*cp == '=') + *cp = ','; + t3000_write(FD, num, strlen(num)); + t3000_write(FD, "\r", 1); + connected = t3000_connect(); +#if ACULOG + if (timeout) { + sprintf(line, "%d second dial timeout", + number(value(DIALTIMEOUT))); + logent(value(HOST), num, "t3000", line); + } +#endif + if (timeout) + t3000_disconnect(); + return (connected); +} + +t3000_disconnect() +{ + /* first hang up the modem*/ + ioctl(FD, TIOCCDTR, 0); + sleep(1); + ioctl(FD, TIOCSDTR, 0); + t3000_sync(); /* reset */ + close(FD); +} + +t3000_abort() +{ + t3000_write(FD, "\r", 1); /* send anything to abort the call */ + t3000_disconnect(); +} + +static void +sigALRM() +{ + printf("\07timeout waiting for reply\n"); + timeout = 1; + longjmp(timeoutbuf, 1); +} + +static int +t3000_swallow(match) + register char *match; + { + sig_t f; + char c; + + f = signal(SIGALRM, sigALRM); + timeout = 0; + do { + if (*match =='\0') { + signal(SIGALRM, f); + return (1); + } + if (setjmp(timeoutbuf)) { + signal(SIGALRM, f); + return (0); + } + alarm(number(value(DIALTIMEOUT))); + read(FD, &c, 1); + alarm(0); + c &= 0177; +#ifdef DEBUG + if (boolean(value(VERBOSE))) + putchar(c); +#endif + } while (c == *match++); +#ifdef DEBUG + if (boolean(value(VERBOSE))) + fflush(stdout); +#endif + signal(SIGALRM, SIG_DFL); + return (0); +} + +#ifndef B19200 /* XXX */ +#define B19200 EXTA +#define B38400 EXTB +#endif + +struct tbaud_msg { + char *msg; + int baud; + int baud2; +} tbaud_msg[] = { + "", B300, 0, + " 1200", B1200, 0, + " 2400", B2400, 0, + " 4800", B4800, 0, + " 9600", B9600, 0, + " 14400", B19200, B9600, + " 19200", B19200, B9600, + " 38400", B38400, B9600, + " 57600", B38400, B9600, + " 7512", B9600, 0, + " 1275", B2400, 0, + " 7200", B9600, 0, + " 12000", B19200, B9600, + 0, 0, 0, +}; + +static int +t3000_connect() +{ + char c; + int nc, nl, n; + char dialer_buf[64]; + struct tbaud_msg *bm; + sig_t f; + + if (t3000_swallow("\r\n") == 0) + return (0); + f = signal(SIGALRM, sigALRM); +again: + nc = 0; nl = sizeof(dialer_buf)-1; + bzero(dialer_buf, sizeof(dialer_buf)); + timeout = 0; + for (nc = 0, nl = sizeof(dialer_buf)-1 ; nl > 0 ; nc++, nl--) { + if (setjmp(timeoutbuf)) + break; + alarm(number(value(DIALTIMEOUT))); + n = read(FD, &c, 1); + alarm(0); + if (n <= 0) + break; + c &= 0x7f; + if (c == '\r') { + if (t3000_swallow("\n") == 0) + break; + if (!dialer_buf[0]) + goto again; + if (strcmp(dialer_buf, "RINGING") == 0 && + boolean(value(VERBOSE))) { +#ifdef DEBUG + printf("%s\r\n", dialer_buf); +#endif + goto again; + } + if (strncmp(dialer_buf, "CONNECT", + sizeof("CONNECT")-1) != 0) + break; + for (bm = tbaud_msg ; bm->msg ; bm++) + if (strcmp(bm->msg, + dialer_buf+sizeof("CONNECT")-1) == 0) { + if (!(acu_setspeed (bm->baud) || (bm->baud2 && acu_setspeed (bm->baud2)))) + goto error; + signal(SIGALRM, f); +#ifdef DEBUG + if (boolean(value(VERBOSE))) + printf("%s\r\n", dialer_buf); +#endif + return (1); + } + break; + } + dialer_buf[nc] = c; +#ifdef notdef + if (boolean(value(VERBOSE))) + putchar(c); +#endif + } +error1: + printf("%s\r\n", dialer_buf); +error: + signal(SIGALRM, f); + return (0); +} + +/* + * This convoluted piece of code attempts to get + * the t3000 in sync. + */ +static int +t3000_sync() +{ + int already = 0; + int len; + char buf[40]; + + while (already++ < MAXRETRY) { + ioctl(FD, TIOCFLUSH, 0); /* flush any clutter */ + t3000_write(FD, "\rAT Z\r", 6); /* reset modem */ + bzero(buf, sizeof(buf)); + sleep(2); + ioctl(FD, FIONREAD, &len); +#if 1 +if (len == 0) len = 1; +#endif + if (len) { + len = read(FD, buf, sizeof(buf)); +#ifdef DEBUG + buf[len] = '\0'; + printf("t3000_sync: (\"%s\")\n\r", buf); +#endif + if (index(buf, '0') || + (index(buf, 'O') && index(buf, 'K'))) + return(1); + } + /* + * If not strapped for DTR control, + * try to get command mode. + */ + sleep(1); + t3000_write(FD, "+++", 3); + sleep(1); + /* + * Toggle DTR to force anyone off that might have left + * the modem connected. + */ + ioctl(FD, TIOCCDTR, 0); + sleep(1); + ioctl(FD, TIOCSDTR, 0); + } + t3000_write(FD, "\rAT Z\r", 6); + return (0); +} + +t3000_write(fd, cp, n) +int fd; +char *cp; +int n; +{ +#ifdef notdef + if (boolean(value(VERBOSE))) + write(1, cp, n); +#endif + acu_flush (); + t3000_nap(); + for ( ; n-- ; cp++) { + write(fd, cp, 1); + acu_flush (); + t3000_nap(); + } +} + +#ifdef DEBUG +t3000_verbose_read() +{ + int n = 0; + char buf[BUFSIZ]; + + if (ioctl(FD, FIONREAD, &n) < 0) + return; + if (n <= 0) + return; + if (read(FD, buf, n) != n) + return; + write(1, buf, n); +} +#endif + +t3000_nap() +{ + acu_nap (50); +} + +/* end of t3000.c */ diff --git a/usr.bin/tip/libacu/v3451.c b/usr.bin/tip/libacu/v3451.c new file mode 100644 index 0000000..a98c4d4 --- /dev/null +++ b/usr.bin/tip/libacu/v3451.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)v3451.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Routines for calling up on a Vadic 3451 Modem + */ +#include "tipconf.h" +#include "tip.h" + +static jmp_buf Sjbuf; + +v3451_dialer(num, acu) + register char *num; + char *acu; +{ + sig_t func; + int ok; + int slow = number(value(BAUDRATE)) < 1200, rw = 2; + char phone[50]; +#if ACULOG + char line[80]; +#endif + static int expect(); + static void vawrite(); + + /* + * Get in synch + */ + vawrite("I\r", 1 + slow); + vawrite("I\r", 1 + slow); + vawrite("I\r", 1 + slow); + vawrite("\005\r", 2 + slow); + if (!expect("READY")) { + printf("can't synchronize with vadic 3451\n"); +#if ACULOG + logent(value(HOST), num, "vadic", "can't synch up"); +#endif + return (0); + } + acu_hupcl (); + sleep(1); + vawrite("D\r", 2 + slow); + if (!expect("NUMBER?")) { + printf("Vadic will not accept dial command\n"); +#if ACULOG + logent(value(HOST), num, "vadic", "will not accept dial"); +#endif + return (0); + } + strcpy(phone, num); + strcat(phone, "\r"); + vawrite(phone, 1 + slow); + if (!expect(phone)) { + printf("Vadic will not accept phone number\n"); +#if ACULOG + logent(value(HOST), num, "vadic", "will not accept number"); +#endif + return (0); + } + func = signal(SIGINT,SIG_IGN); + /* + * You cannot interrupt the Vadic when its dialing; + * even dropping DTR does not work (definitely a + * brain damaged design). + */ + vawrite("\r", 1 + slow); + vawrite("\r", 1 + slow); + if (!expect("DIALING:")) { + printf("Vadic failed to dial\n"); +#if ACULOG + logent(value(HOST), num, "vadic", "failed to dial"); +#endif + return (0); + } + if (boolean(value(VERBOSE))) + printf("\ndialing..."); + ok = expect("ON LINE"); + signal(SIGINT, func); + if (!ok) { + printf("call failed\n"); +#if ACULOG + logent(value(HOST), num, "vadic", "call failed"); +#endif + return (0); + } + ioctl(FD, TIOCFLUSH, &rw); + return (1); +} + +v3451_disconnect() +{ + + close(FD); +} + +v3451_abort() +{ + + close(FD); +} + +static void +vawrite(cp, delay) + register char *cp; + int delay; +{ + + for (; *cp; sleep(delay), cp++) + write(FD, cp, 1); +} + +static +expect(cp) + register char *cp; +{ + char buf[300]; + register char *rp = buf; + int timeout = 30, online = 0; + static int notin(); + static void alarmtr(); + + if (strcmp(cp, "\"\"") == 0) + return (1); + *rp = 0; + /* + * If we are waiting for the Vadic to complete + * dialing and get a connection, allow more time + * Unfortunately, the Vadic times out 24 seconds after + * the last digit is dialed + */ + online = strcmp(cp, "ON LINE") == 0; + if (online) + timeout = number(value(DIALTIMEOUT)); + signal(SIGALRM, alarmtr); + if (setjmp(Sjbuf)) + return (0); + alarm(timeout); + while (notin(cp, buf) && rp < buf + sizeof (buf) - 1) { + if (online && notin("FAILED CALL", buf) == 0) + return (0); + if (read(FD, rp, 1) < 0) { + alarm(0); + return (0); + } + if (*rp &= 0177) + rp++; + *rp = '\0'; + } + alarm(0); + return (1); +} + +static void +alarmtr() +{ + longjmp(Sjbuf, 1); +} + +static int +notin(sh, lg) + char *sh, *lg; +{ + static int prefix(); + + for (; *lg; lg++) + if (prefix(sh, lg)) + return (0); + return (1); +} + +static +prefix(s1, s2) + register char *s1, *s2; +{ + register char c; + + while ((c = *s1++) == *s2++) + if (c == '\0') + return (1); + return (c == '\0'); +} diff --git a/usr.bin/tip/libacu/v831.c b/usr.bin/tip/libacu/v831.c new file mode 100644 index 0000000..b670c2a --- /dev/null +++ b/usr.bin/tip/libacu/v831.c @@ -0,0 +1,272 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)v831.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Routines for dialing up on Vadic 831 + */ +#include "tipconf.h" +#include "tip.h" + +int v831_abort(); +static void alarmtr(); +extern int errno; + +static jmp_buf jmpbuf; +static int child = -1; + +v831_dialer(num, acu) + char *num, *acu; +{ + int status, pid, connected = 1; + register int timelim; + static int dialit(); + + if (boolean(value(VERBOSE))) + printf("\nstarting call..."); +#ifdef DEBUG + printf ("(acu=%s)\n", acu); +#endif + if ((AC = open(acu, O_RDWR)) < 0) { + if (errno == EBUSY) + printf("line busy..."); + else + printf("acu open error..."); + return (0); + } + if (setjmp(jmpbuf)) { + kill(child, SIGKILL); + close(AC); + return (0); + } + signal(SIGALRM, alarmtr); + timelim = 5 * strlen(num); + alarm(timelim < 30 ? 30 : timelim); + if ((child = fork()) == 0) { + /* + * ignore this stuff for aborts + */ + signal(SIGALRM, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + sleep(2); + exit(dialit(num, acu) != 'A'); + } + /* + * open line - will return on carrier + */ + if ((FD = open(DV, O_RDWR)) < 0) { +#ifdef DEBUG + printf("(after open, errno=%d)\n", errno); +#endif + if (errno == EIO) + printf("lost carrier..."); + else + printf("dialup line open failed..."); + alarm(0); + kill(child, SIGKILL); + close(AC); + return (0); + } + alarm(0); +#ifdef notdef + ioctl(AC, TIOCHPCL, 0); +#endif + signal(SIGALRM, SIG_DFL); + while ((pid = wait(&status)) != child && pid != -1) + ; + if (status) { + close(AC); + return (0); + } + return (1); +} + +static void +alarmtr() +{ + alarm(0); + longjmp(jmpbuf, 1); +} + +/* + * Insurance, for some reason we don't seem to be + * hanging up... + */ +v831_disconnect() +{ + sleep(2); +#ifdef DEBUG + printf("[disconnect: FD=%d]\n", FD); +#endif + if (FD > 0) { + ioctl(FD, TIOCCDTR, 0); + acu_setspeec (0); + ioctl(FD, TIOCNXCL, 0); + } + close(FD); +} + +v831_abort() +{ + +#ifdef DEBUG + printf("[abort: AC=%d]\n", AC); +#endif + sleep(2); + if (child > 0) + kill(child, SIGKILL); + if (AC > 0) + ioctl(FD, TIOCNXCL, 0); + close(AC); + if (FD > 0) + ioctl(FD, TIOCCDTR, 0); + close(FD); +} + +/* + * Sigh, this probably must be changed at each site. + */ +struct vaconfig { + char *vc_name; + char vc_rack; + char vc_modem; +} vaconfig[] = { + { "/dev/cua0",'4','0' }, + { "/dev/cua1",'4','1' }, + { 0 } +}; + +#define pc(x) (c = x, write(AC,&c,1)) +#define ABORT 01 +#define SI 017 +#define STX 02 +#define ETX 03 + +static int +dialit(phonenum, acu) + register char *phonenum; + char *acu; +{ + register struct vaconfig *vp; + char c; + int i, two = 2; + static char *sanitize(); + + phonenum = sanitize(phonenum); +#ifdef DEBUG + printf ("(dial phonenum=%s)\n", phonenum); +#endif + if (*phonenum == '<' && phonenum[1] == 0) + return ('Z'); + for (vp = vaconfig; vp->vc_name; vp++) + if (strcmp(vp->vc_name, acu) == 0) + break; + if (vp->vc_name == 0) { + printf("Unable to locate dialer (%s)\n", acu); + return ('K'); + } + { +#if HAVE_TERMIOS + struct termios termios; + tcgetattr (AC, &termios); + termios.c_iflag = 0; +#ifndef _POSIX_SOURCE + termios.c_lflag = (PENDIN|ECHOKE|ECHOE); +#else + termios.c_lflag = (PENDIN|ECHOE); +#endif + termios.c_cflag = (CLOCAL|HUPCL|CREAD|CS8); + termios.c_ispeed = termios.c_ospeed = B2400; + tcsetattr (AC, TCSANOW, &termios); +#else /* HAVE_TERMIOS */ + struct sgttyb cntrl; + ioctl(AC, TIOCGETP, &cntrl); + cntrl.sg_ispeed = cntrl.sg_ospeed = B2400; + cntrl.sg_flags = RAW | EVENP | ODDP; + ioctl(AC, TIOCSETP, &cntrl); + #endif + } + ioctl(AC, TIOCFLUSH, &two); + pc(STX); + pc(vp->vc_rack); + pc(vp->vc_modem); + while (*phonenum && *phonenum != '<') + pc(*phonenum++); + pc(SI); + pc(ETX); + sleep(1); + i = read(AC, &c, 1); +#ifdef DEBUG + printf("read %d chars, char=%c, errno %d\n", i, c, errno); +#endif + if (i != 1) + c = 'M'; + if (c == 'B' || c == 'G') { + char cc, oc = c; + + pc(ABORT); + read(AC, &cc, 1); +#ifdef DEBUG + printf("abort response=%c\n", cc); +#endif + c = oc; + v831_disconnect(); + } + close(AC); +#ifdef DEBUG + printf("dialit: returns %c\n", c); +#endif + return (c); +} + +static char * +sanitize(s) + register char *s; +{ + static char buf[128]; + register char *cp; + + for (cp = buf; *s; s++) { + if (!isdigit(*s) && *s == '<' && *s != '_') + continue; + if (*s == '_') + *s = '='; + *cp++ = *s; + } + *cp++ = 0; + return (buf); +} diff --git a/usr.bin/tip/libacu/ventel.c b/usr.bin/tip/libacu/ventel.c new file mode 100644 index 0000000..73733e5 --- /dev/null +++ b/usr.bin/tip/libacu/ventel.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)ventel.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Routines for calling up on a Ventel Modem + * The Ventel is expected to be strapped for local echo (just like uucp) + */ +#include "tipconf.h" +#include "tip.h" + +#define MAXRETRY 5 + +static void sigALRM(); +static int timeout = 0; +static jmp_buf timeoutbuf; + +/* + * some sleep calls have been replaced by this macro + * because some ventel modems require two <cr>s in less than + * a second in order to 'wake up'... yes, it is dirty... + */ +#define delay(num,denom) busyloop(CPUSPEED*num/denom) +#define CPUSPEED 1000000 /* VAX 780 is 1MIPS */ +#define DELAY(n) { register long N = (n); while (--N > 0); } +busyloop(n) { DELAY(n); } + +ven_dialer(num, acu) + register char *num; + char *acu; +{ + register char *cp; + register int connected = 0; + char *msg, *index(), line[80]; + static int gobble(), vensync(); + static void echo(); + + /* + * Get in synch with a couple of carriage returns + */ + if (!vensync(FD)) { + printf("can't synchronize with ventel\n"); +#if ACULOG + logent(value(HOST), num, "ventel", "can't synch up"); +#endif + return (0); + } + if (boolean(value(VERBOSE))) + printf("\ndialing..."); + fflush(stdout); + acu_hupcl (); + echo("#k$\r$\n$D$I$A$L$:$ "); + for (cp = num; *cp; cp++) { + delay(1, 10); + write(FD, cp, 1); + } + delay(1, 10); + write(FD, "\r", 1); + gobble('\n', line); + if (gobble('\n', line)) + connected = gobble('!', line); + acu_flush (); +#if ACULOG + if (timeout) { + sprintf(line, "%d second dial timeout", + number(value(DIALTIMEOUT))); + logent(value(HOST), num, "ventel", line); + } +#endif + if (timeout) + ven_disconnect(); /* insurance */ + if (connected || timeout || !boolean(value(VERBOSE))) + return (connected); + /* call failed, parse response for user */ + cp = index(line, '\r'); + if (cp) + *cp = '\0'; + for (cp = line; cp = index(cp, ' '); cp++) + if (cp[1] == ' ') + break; + if (cp) { + while (*cp == ' ') + cp++; + msg = cp; + while (*cp) { + if (isupper(*cp)) + *cp = tolower(*cp); + cp++; + } + printf("%s...", msg); + } + return (connected); +} + +ven_disconnect() +{ + + close(FD); +} + +ven_abort() +{ + + write(FD, "\03", 1); + close(FD); +} + +static void +echo(s) + register char *s; +{ + char c; + + while (c = *s++) switch (c) { + + case '$': + read(FD, &c, 1); + s++; + break; + + case '#': + c = *s++; + write(FD, &c, 1); + break; + + default: + write(FD, &c, 1); + read(FD, &c, 1); + } +} + +static void +sigALRM() +{ + printf("\07timeout waiting for reply\n"); + timeout = 1; + longjmp(timeoutbuf, 1); +} + +static int +gobble(match, response) + register char match; + char response[]; +{ + register char *cp = response; + sig_t f; + char c; + + f = signal(SIGALRM, sigALRM); + timeout = 0; + do { + if (setjmp(timeoutbuf)) { + signal(SIGALRM, f); + *cp = '\0'; + return (0); + } + alarm(number(value(DIALTIMEOUT))); + read(FD, cp, 1); + alarm(0); + c = (*cp++ &= 0177); +#ifdef notdef + if (boolean(value(VERBOSE))) + putchar(c); +#endif + } while (c != '\n' && c != match); + signal(SIGALRM, SIG_DFL); + *cp = '\0'; + return (c == match); +} + +#define min(a,b) ((a)>(b)?(b):(a)) +/* + * This convoluted piece of code attempts to get + * the ventel in sync. If you don't have FIONREAD + * there are gory ways to simulate this. + */ +static int +vensync(fd) +{ + int already = 0, nread; + char buf[60]; + + /* + * Toggle DTR to force anyone off that might have left + * the modem connected, and insure a consistent state + * to start from. + * + * If you don't have the ioctl calls to diddle directly + * with DTR, you can always try setting the baud rate to 0. + */ + ioctl(FD, TIOCCDTR, 0); + sleep(1); + ioctl(FD, TIOCSDTR, 0); + while (already < MAXRETRY) { + /* + * After reseting the modem, send it two \r's to + * autobaud on. Make sure to delay between them + * so the modem can frame the incoming characters. + */ + write(fd, "\r", 1); + delay(1,10); + write(fd, "\r", 1); + sleep(2); + if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) { + perror("tip: ioctl"); + continue; + } + while (nread > 0) { + read(fd, buf, min(nread, 60)); + if ((buf[nread - 1] & 0177) == '$') + return (1); + nread -= min(nread, 60); + } + sleep(1); + already++; + } + return (0); +} + diff --git a/usr.bin/tip/tip/Makefile b/usr.bin/tip/tip/Makefile new file mode 100644 index 0000000..39b89b0 --- /dev/null +++ b/usr.bin/tip/tip/Makefile @@ -0,0 +1,24 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 +# +# Files are: +# /etc/remote remote host description file +# /etc/phones phone number file, owned by ${OWNER} and +# mode 6?? +# /var/log/aculog ACU accounting file, owned by ${OWNER} and +# mode 6?? {if ACULOG defined} + +CFLAGS+=-g +LIBACU=../libacu/libacu.a +BINDIR=/usr/bin +BINOWN=uucp +BINGRP=dialer +BINMODE=4510 +LDADD+=$(LIBACU) +LINKS=${BINDIR}/tip +MAN1=tip.1 +MAN5=modems.5 +SRCS=acu.c acutab.c cmds.c cmdtab.c cu.c hunt.c log.c partab.c \ + remote.c tip.c tipout.c uucplock.c value.c vars.c +PROG=tip +$(OBJS): tipconf.h +.include <bsd.prog.mk> diff --git a/usr.bin/tip/tip/acu.c b/usr.bin/tip/tip/acu.c new file mode 100644 index 0000000..54ae4cd --- /dev/null +++ b/usr.bin/tip/tip/acu.c @@ -0,0 +1,206 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)acu.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "tipconf.h" +#include "tip.h" + +#if UNIDIALER +acu_t* unidialer_getmodem (const char *modem_name); +#endif + +static acu_t *acu = NOACU; +static int conflag; +static void acuabort(); +static acu_t *acutype(); +static jmp_buf jmpbuf; +/* + * Establish connection for tip + * + * If DU is true, we should dial an ACU whose type is AT. + * The phone numbers are in PN, and the call unit is in CU. + * + * If the PN is an '@', then we consult the PHONES file for + * the phone numbers. This file is /etc/phones, unless overriden + * by an exported shell variable. + * + * The data base files must be in the format: + * host-name[ \t]*phone-number + * with the possibility of multiple phone numbers + * for a single host acting as a rotary (in the order + * found in the file). + */ +char * +connect() +{ + register char *cp = PN; + char *phnum, string[256]; + FILE *fd; + int tried = 0; + + if (!DU) { /* regular connect message */ + if (CM != NOSTR) + pwrite(FD, CM, size(CM)); + logent(value(HOST), "", DV, "call completed"); + return (NOSTR); + } + /* + * @ =>'s use data base in PHONES environment variable + * otherwise, use /etc/phones + */ + signal(SIGINT, acuabort); + signal(SIGQUIT, acuabort); + if (setjmp(jmpbuf)) { + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + printf("\ncall aborted\n"); + logent(value(HOST), "", "", "call aborted"); + if (acu != NOACU) { + boolean(value(VERBOSE)) = FALSE; + if (conflag) + disconnect(NOSTR); + else + (*acu->acu_abort)(); + } + return ("interrupt"); + } + if ((acu = acutype(AT)) == NOACU) + return ("unknown ACU type"); + if (*cp != '@') { + while (*cp) { + for (phnum = cp; *cp && *cp != ','; cp++) + ; + if (*cp) + *cp++ = '\0'; + + if (conflag = (*acu->acu_dialer)(phnum, CU)) { + if (CM != NOSTR) + pwrite(FD, CM, size(CM)); + logent(value(HOST), phnum, acu->acu_name, + "call completed"); + return (NOSTR); + } else + logent(value(HOST), phnum, acu->acu_name, + "call failed"); + tried++; + } + } else { + if ((fd = fopen(PH, "r")) == NOFILE) { + printf("%s: ", PH); + return ("can't open phone number file"); + } + while (fgets(string, sizeof(string), fd) != NOSTR) { + for (cp = string; !any(*cp, " \t\n"); cp++) + ; + if (*cp == '\n') { + fclose(fd); + return ("unrecognizable host name"); + } + *cp++ = '\0'; + if (strcmp(string, value(HOST))) + continue; + while (any(*cp, " \t")) + cp++; + if (*cp == '\n') { + fclose(fd); + return ("missing phone number"); + } + for (phnum = cp; *cp && *cp != ',' && *cp != '\n'; cp++) + ; + if (*cp) + *cp++ = '\0'; + + if (conflag = (*acu->acu_dialer)(phnum, CU)) { + fclose(fd); + if (CM != NOSTR) + pwrite(FD, CM, size(CM)); + logent(value(HOST), phnum, acu->acu_name, + "call completed"); + return (NOSTR); + } else + logent(value(HOST), phnum, acu->acu_name, + "call failed"); + tried++; + } + fclose(fd); + } + if (!tried) + logent(value(HOST), "", acu->acu_name, "missing phone number"); + else + (*acu->acu_abort)(); + return (tried ? "call failed" : "missing phone number"); +} + +disconnect(reason) + char *reason; +{ + if (!conflag) { + logent(value(HOST), "", DV, "call terminated"); + return; + } + if (reason == NOSTR) { + logent(value(HOST), "", acu->acu_name, "call terminated"); + if (boolean(value(VERBOSE))) + printf("\r\ndisconnecting..."); + } else + logent(value(HOST), "", acu->acu_name, reason); + (*acu->acu_disconnect)(); +} + +static void +acuabort(s) +{ + signal(s, SIG_IGN); + longjmp(jmpbuf, 1); +} + +static acu_t * +acutype(s) + register char *s; +{ + register acu_t *p; + extern acu_t acutable[]; + + for (p = acutable; p->acu_name != '\0'; p++) + if (!strcmp(s, p->acu_name)) + return (p); + + #if UNIDIALER + return unidialer_getmodem (s); + #else + return (NOACU); + #endif +} diff --git a/usr.bin/tip/tip/acutab.c b/usr.bin/tip/tip/acutab.c new file mode 100644 index 0000000..3254e8a --- /dev/null +++ b/usr.bin/tip/tip/acutab.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)acutab.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "tipconf.h" +#include "tip.h" + +extern int df02_dialer(), df03_dialer(), + biz31f_dialer(), + biz31w_dialer(), + biz22f_dialer(), + biz22w_dialer(), + ven_dialer(), + hay_dialer(), + cour_dialer(), + multitech_dialer(), + t3000_dialer(), + v3451_dialer(), + v831_dialer(), + dn_dialer(); + +extern void df_disconnect(), df_abort(), + biz31_disconnect(), biz31_abort(), + biz22_disconnect(), biz22_abort(), + ven_disconnect(), ven_abort(), + hay_disconnect(), hay_abort(), + cour_disconnect(), cour_abort(), + multitech_disconnect(), multitech_abort(), + t3000_disconnect(), t3000_abort(), + v3451_disconnect(), v3451_abort(), + v831_disconnect(), v831_abort(), + dn_disconnect(), dn_abort(); + +acu_t acutable[] = { +#if BIZ1031 + "biz31f", biz31f_dialer, biz31_disconnect, biz31_abort, + "biz31w", biz31w_dialer, biz31_disconnect, biz31_abort, +#endif +#if BIZ1022 + "biz22f", biz22f_dialer, biz22_disconnect, biz22_abort, + "biz22w", biz22w_dialer, biz22_disconnect, biz22_abort, +#endif +#if DF02 + "df02", df02_dialer, df_disconnect, df_abort, +#endif +#if DF03 + "df03", df03_dialer, df_disconnect, df_abort, +#endif +#if DN11 + "dn11", dn_dialer, dn_disconnect, dn_abort, +#endif +#if VENTEL + "ventel",ven_dialer, ven_disconnect, ven_abort, +#endif +#if HAYES + "hayes",hay_dialer, hay_disconnect, hay_abort, +#endif +#if COURIER + "courier",cour_dialer, cour_disconnect, cour_abort, +#endif +#if MULTITECH + "multitech",multitech_dialer, multitech_disconnect, multitech_abort, +#endif +#if T3000 + "t3000",t3000_dialer, t3000_disconnect, t3000_abort, +#endif +#if V3451 +#if !V831 + "vadic",v3451_dialer, v3451_disconnect, v3451_abort, +#endif + "v3451",v3451_dialer, v3451_disconnect, v3451_abort, +#endif +#if V831 +#if !V3451 + "vadic",v831_dialer, v831_disconnect, v831_abort, +#endif + "v831",v831_dialer, v831_disconnect, v831_abort, +#endif + 0, 0, 0, 0 +}; + diff --git a/usr.bin/tip/tip/cmds.c b/usr.bin/tip/tip/cmds.c new file mode 100644 index 0000000..3e764a1 --- /dev/null +++ b/usr.bin/tip/tip/cmds.c @@ -0,0 +1,1042 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)cmds.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "tipconf.h" +#include "tip.h" +#include "pathnames.h" + +#include <stdio.h> + +/* + * tip + * + * miscellaneous commands + */ + +int quant[] = { 60, 60, 24 }; + +char null = '\0'; +char *sep[] = { "second", "minute", "hour" }; +static char *argv[10]; /* argument vector for take and put */ + +void timeout(); /* timeout function called on alarm */ +void stopsnd(); /* SIGINT handler during file transfers */ +void intcopy(); /* interrupt routine for file transfers */ + +void +usedefchars () +{ +#if HAVE_TERMIOS + int cnt; + struct termios ttermios; + ttermios = ctermios; + for (cnt = 0; cnt < NCCS; cnt++) + ttermios.c_cc [cnt] = otermios.c_cc [cnt]; + tcsetattr (0, TCSANOW, &ttermios); +#else + ioctl(0, TIOCSETC, &defchars); +#endif +} + +void +usetchars () +{ +#if HAVE_TERMIOS + tcsetattr (0, TCSANOW, &ctermios); +#else + ioctl(0, TIOCSETC, &tchars); +#endif +} + +void +flush_remote () +{ +#ifdef TIOCFLUSH + int cmd = 0; + ioctl (FD, TIOCFLUSH, &cmd); +#else + struct sgttyb buf; + ioctl (FD, TIOCGETP, &buf); /* this does a */ + ioctl (FD, TIOCSETP, &buf); /* wflushtty */ +#endif +} + +/* + * FTP - remote ==> local + * get a file from the remote host + */ +getfl(c) + char c; +{ + char buf[256], *cp, *expand(); + + putchar(c); + /* + * get the UNIX receiving file's name + */ + if (prompt("Local file name? ", copyname)) + return; + cp = expand(copyname); + if ((sfd = creat(cp, 0666)) < 0) { + printf("\r\n%s: cannot creat\r\n", copyname); + return; + } + + /* + * collect parameters + */ + if (prompt("List command for remote system? ", buf)) { + unlink(copyname); + return; + } + transfer(buf, sfd, value(EOFREAD)); +} + +/* + * Cu-like take command + */ +cu_take(cc) + char cc; +{ + int fd, argc; + char line[BUFSIZ], *expand(), *cp; + + if (prompt("[take] ", copyname)) + return; + if ((argc = args(copyname, argv)) < 1 || argc > 2) { + printf("usage: <take> from [to]\r\n"); + return; + } + if (argc == 1) + argv[1] = argv[0]; + cp = expand(argv[1]); + if ((fd = creat(cp, 0666)) < 0) { + printf("\r\n%s: cannot create\r\n", argv[1]); + return; + } + (void)sprintf(line, "cat %s ; echo \"\" ; echo ___tip_end_of_file_marker___", argv[0]); + xfer(line, fd, "\n___tip_end_of_file_marker___\n"); +} + +extern jmp_buf intbuf; + +xfer(buf, fd, eofchars) + char *buf, *eofchars; +{ + register int ct; + char c, *match; + register int cnt, eof, v; + time_t start; + sig_t f; + char r; + FILE *ff; + + v = boolean(value(VERBOSE)); + + if ((ff = fdopen (fd, "w")) == NULL) { + perror("file open"); + return; + } + if ((cnt = number(value(FRAMESIZE))) != BUFSIZ) + if (setvbuf(ff, NULL, _IOFBF, cnt) != 0) { + perror("file allocation"); + (void)fclose(ff); + return; + } + + pwrite(FD, buf, size(buf)); + quit = 0; + kill(pid, SIGIOT); + read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ + + /* + * finish command + */ + r = '\r'; + pwrite(FD, &r, 1); + do + read(FD, &c, 1); + while ((c&0177) != '\n'); + + usedefchars (); + + (void) setjmp(intbuf); + f = signal(SIGINT, intcopy); + start = time(0); + match = eofchars; + for (ct = 0; !quit;) { + eof = read(FD, &c, 1) <= 0; + c &= 0177; + if (quit) + continue; + if (eof) + break; + if (c == 0) + continue; /* ignore nulls */ + if (c == '\r') + continue; + if (c != *match && match > eofchars) { + register char *p = eofchars; + while (p < match) { + if (*p == '\n'&& v) + (void)printf("\r%d", ++ct); + fputc(*p++, ff); + } + match = eofchars; + } + if (c == *match) { + if (*++match == '\0') + break; + } else { + if (c == '\n' && v) + (void)printf("\r%d", ++ct); + fputc(c, ff); + } + } + if (v) + prtime(" lines transferred in ", time(0)-start); + usetchars (); + write(fildes[1], (char *)&ccc, 1); + signal(SIGINT, f); + (void)fclose(ff); +} + +static jmp_buf intbuf; +/* + * Bulk transfer routine -- + * used by getfl(), cu_take(), and pipefile() + */ +transfer(buf, fd, eofchars) + char *buf, *eofchars; +{ + register int ct; + char c, buffer[BUFSIZ]; + register char *p = buffer; + register int cnt, eof, v; + time_t start; + sig_t f; + char r; + FILE *ff; + + v = boolean(value(VERBOSE)); + + if ((ff = fdopen (fd, "w")) == NULL) { + perror("file open"); + return; + } + if ((cnt = number(value(FRAMESIZE))) != BUFSIZ) + if (setvbuf(ff, NULL, _IOFBF, cnt) != 0) { + perror("file allocation"); + (void)fclose(ff); + return; + } + + pwrite(FD, buf, size(buf)); + quit = 0; + kill(pid, SIGIOT); + read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ + + /* + * finish command + */ + r = '\r'; + pwrite(FD, &r, 1); + do + read(FD, &c, 1); + while ((c&0177) != '\n'); + usedefchars (); + (void) setjmp(intbuf); + f = signal(SIGINT, intcopy); + start = time(0); + for (ct = 0; !quit;) { + eof = read(FD, &c, 1) <= 0; + c &= 0177; + if (quit) + continue; + if (eof || any(c, eofchars)) + break; + if (c == 0) + continue; /* ignore nulls */ + if (c == '\r') + continue; + if (c == '\n' && v) + printf("\r%d", ++ct); + fputc(c, ff); + } + if (v) + prtime(" lines transferred in ", time(0)-start); + usetchars (); + write(fildes[1], (char *)&ccc, 1); + signal(SIGINT, f); + (void)fclose(ff); +} + +/* + * FTP - remote ==> local process + * send remote input to local process via pipe + */ +pipefile() +{ + int cpid, pdes[2]; + char buf[256]; + int status, p; + extern int errno; + + if (prompt("Local command? ", buf)) + return; + + if (pipe(pdes)) { + printf("can't establish pipe\r\n"); + return; + } + + if ((cpid = fork()) < 0) { + printf("can't fork!\r\n"); + return; + } else if (cpid) { + if (prompt("List command for remote system? ", buf)) { + close(pdes[0]), close(pdes[1]); + kill (cpid, SIGKILL); + } else { + close(pdes[0]); + signal(SIGPIPE, intcopy); + transfer(buf, pdes[1], value(EOFREAD)); + signal(SIGPIPE, SIG_DFL); + while ((p = wait(&status)) > 0 && p != cpid) + ; + } + } else { + register int f; + + dup2(pdes[0], 0); + close(pdes[0]); + for (f = 3; f < 20; f++) + close(f); + execute(buf); + printf("can't execl!\r\n"); + exit(0); + } +} + +/* + * Interrupt service routine for FTP + */ +void +stopsnd() +{ + + stop = 1; + signal(SIGINT, SIG_IGN); +} + +/* + * FTP - local ==> remote + * send local file to remote host + * terminate transmission with pseudo EOF sequence + */ +sendfile(cc) + char cc; +{ + FILE *fd; + char *fnamex; + char *expand(); + + putchar(cc); + /* + * get file name + */ + if (prompt("Local file name? ", fname)) + return; + + /* + * look up file + */ + fnamex = expand(fname); + if ((fd = fopen(fnamex, "r")) == NULL) { + printf("%s: cannot open\r\n", fname); + return; + } + transmit(fd, value(EOFWRITE), NULL); + if (!boolean(value(ECHOCHECK))) { + flush_remote (); + } +} + +/* + * Bulk transfer routine to remote host -- + * used by sendfile() and cu_put() + */ +transmit(fd, eofchars, command) + FILE *fd; + char *eofchars, *command; +{ + char *pc, lastc; + int c, ccount, lcount; + time_t start_t, stop_t; + sig_t f; + + kill(pid, SIGIOT); /* put TIPOUT into a wait state */ + stop = 0; + f = signal(SIGINT, stopsnd); + usedefchars (); + read(repdes[0], (char *)&ccc, 1); + if (command != NULL) { + for (pc = command; *pc; pc++) + send(*pc); + if (boolean(value(ECHOCHECK))) + read(FD, (char *)&c, 1); /* trailing \n */ + else { + flush_remote (); + sleep(5); /* wait for remote stty to take effect */ + } + } + lcount = 0; + lastc = '\0'; + start_t = time(0); + while (1) { + ccount = 0; + do { + c = getc(fd); + if (stop) + goto out; + if (c == EOF) + goto out; + if (c == 0177 && !boolean(value(RAWFTP))) + continue; + lastc = c; + if (c < 040) { + if (c == '\n') { + if (!boolean(value(RAWFTP))) + c = '\r'; + } + else if (c == '\t') { + if (!boolean(value(RAWFTP))) { + if (boolean(value(TABEXPAND))) { + send(' '); + while ((++ccount % 8) != 0) + send(' '); + continue; + } + } + } else + if (!boolean(value(RAWFTP))) + continue; + } + send(c); + } while (c != '\r' && !boolean(value(RAWFTP))); + if (boolean(value(VERBOSE))) + printf("\r%d", ++lcount); + if (boolean(value(ECHOCHECK))) { + timedout = 0; + alarm((int)value(ETIMEOUT)); + do { /* wait for prompt */ + read(FD, (char *)&c, 1); + if (timedout || stop) { + if (timedout) + printf("\r\ntimed out at eol\r\n"); + alarm(0); + goto out; + } + } while ((c&0177) != character(value(PROMPT))); + alarm(0); + } + } +out: + if (lastc != '\n' && !boolean(value(RAWFTP))) + send('\r'); + for (pc = eofchars; *pc; pc++) + send(*pc); + stop_t = time(0); + fclose(fd); + signal(SIGINT, f); + if (boolean(value(VERBOSE))) + 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); + usetchars (); +} + +/* + * Cu-like put command + */ +cu_put(cc) + char cc; +{ + FILE *fd; + char line[BUFSIZ]; + int argc; + char *expand(); + char *copynamex; + + if (prompt("[put] ", copyname)) + return; + if ((argc = args(copyname, argv)) < 1 || argc > 2) { + printf("usage: <put> from [to]\r\n"); + return; + } + if (argc == 1) + argv[1] = 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]); + else + sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]); + transmit(fd, "\04", line); +} + +/* + * FTP - send single character + * wait for echo & handle timeout + */ +send(c) + char c; +{ + char cc; + int retry = 0; + + cc = c; + 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((int)value(ETIMEOUT)); + read(FD, &cc, 1); + alarm(0); + if (timedout) { + printf("\r\ntimeout error (%s)\r\n", ctrl(c)); + if (retry++ > 3) + return; + pwrite(FD, &null, 1); /* poke it */ + goto tryagain; + } +} + +void +timeout() +{ + signal(SIGALRM, 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); + usedefchars (); + 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); + usetchars (); + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); +} + +#if CONNECT + +int +tiplink (char *cmd, unsigned int flags) +{ + int cpid, status, p; + time_t start; + + if (flags & TL_SIGNAL_TIPOUT) { + kill(pid, SIGIOT); /* put TIPOUT into a wait state */ + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + usedefchars (); + 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 fd; + + dup2(FD, 0); + dup2(3, 1); + for (fd = 3; fd < 20; fd++) + close (fd); + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + execute (cmd); + printf("can't find `%s'\r\n", cmd); + exit(0); + } + + if (flags & TL_VERBOSE && boolean(value(VERBOSE))) + prtime("away for ", time(0)-start); + + if (flags & TL_SIGNAL_TIPOUT) { + write(fildes[1], (char *)&ccc, 1); + usetchars (); + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + } + + return 0; +} + +/* + * Fork a program with: + * 0 <-> remote tty in + * 1 <-> remote tty out + * 2 <-> local tty out + */ +consh(c) +{ + char buf[256]; + putchar(c); + if (prompt("Local command? ", buf)) + return; + tiplink (buf, TL_SIGNAL_TIPOUT | TL_VERBOSE); +} +#endif + +/* + * Escape to local shell + */ +shell() +{ + int shpid, status; + extern char **environ; + char *cp; + + printf("[sh]\r\n"); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + unraw(); + if (shpid = fork()) { + while (shpid != wait(&status)); + raw(); + printf("\r\n!\r\n"); + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + return; + } else { + signal(SIGQUIT, SIG_DFL); + signal(SIGINT, SIG_DFL); + if ((cp = rindex(value(SHELL), '/')) == NULL) + cp = value(SHELL); + else + cp++; + shell_uid(); + execl(value(SHELL), cp, 0); + printf("\r\ncan't execl!\r\n"); + exit(1); + } +} + +/* + * TIPIN portion of scripting + * initiate the conversation with TIPOUT + */ +setscript() +{ + char c; + /* + * enable TIPOUT side for dialogue + */ + kill(pid, SIGEMT); + if (boolean(value(SCRIPT))) + write(fildes[1], value(RECORD), size(value(RECORD))); + write(fildes[1], "\n", 1); + /* + * wait for TIPOUT to finish + */ + read(repdes[0], &c, 1); + if (c == 'n') + printf("can't create %s\r\n", value(RECORD)); +} + +/* + * Change current working directory of + * local portion of tip + */ +chdirectory() +{ + char dirname[80]; + register char *cp = dirname; + + if (prompt("[cd] ", dirname)) { + if (stoprompt) + return; + cp = value(HOME); + } + if (chdir(cp) < 0) + printf("%s: bad directory\r\n", cp); + printf("!\r\n"); +} + +tipabort(msg) + char *msg; +{ + + kill(pid, SIGTERM); + disconnect(msg); + if (msg != NOSTR) + printf("\r\n%s", msg); + printf("\r\n[EOT]\r\n"); + daemon_uid(); + (void)uu_unlock(uucplock); + unraw(); + exit(0); +} + +finish() +{ + char *abortmsg = NOSTR, *dismsg; + + if (LO != NOSTR && tiplink (LO, TL_SIGNAL_TIPOUT) != 0) { + abortmsg = "logout failed"; + } + + if ((dismsg = value(DISCONNECT)) != NOSTR) { + write(FD, dismsg, strlen(dismsg)); + sleep (2); + } + tipabort(abortmsg); +} + +void +intcopy() +{ + raw(); + quit = 1; + longjmp(intbuf, 1); +} + +execute(s) + char *s; +{ + register char *cp; + + if ((cp = rindex(value(SHELL), '/')) == NULL) + cp = value(SHELL); + else + cp++; + shell_uid(); + execl(value(SHELL), cp, "-c", s, 0); +} + +args(buf, a) + char *buf, *a[]; +{ + register char *p = buf, *start; + register char **parg = a; + register int n = 0; + + do { + while (*p && (*p == ' ' || *p == '\t')) + p++; + start = p; + if (*p) + *parg = p; + while (*p && (*p != ' ' && *p != '\t')) + p++; + if (p != start) + parg++, n++; + if (*p) + *p++ = '\0'; + } while (*p); + + return(n); +} + +prtime(s, a) + char *s; + time_t a; +{ + register i; + int nums[3]; + + for (i = 0; i < 3; i++) { + nums[i] = (int)(a % quant[i]); + a /= quant[i]; + } + printf("%s", s); + while (--i >= 0) + 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"); +} + +variable() +{ + char buf[256]; + + if (prompt("[set] ", buf)) + return; + vlex(buf); + if (vtable[BEAUTIFY].v_access&CHANGED) { + vtable[BEAUTIFY].v_access &= ~CHANGED; + kill(pid, SIGSYS); + } + if (vtable[SCRIPT].v_access&CHANGED) { + vtable[SCRIPT].v_access &= ~CHANGED; + setscript(); + /* + * So that "set record=blah script" doesn't + * cause two transactions to occur. + */ + if (vtable[RECORD].v_access&CHANGED) + vtable[RECORD].v_access &= ~CHANGED; + } + if (vtable[RECORD].v_access&CHANGED) { + vtable[RECORD].v_access &= ~CHANGED; + 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; +{ +#if HAVE_TERMIOS + struct termios ttermios; + tcgetattr (FD, &ttermios); + if (strcmp(option,"on") == 0) { + ttermios.c_iflag |= IXOFF; + ctermios.c_iflag |= IXOFF; + } + else { + ttermios.c_iflag &= ~IXOFF; + ctermios.c_iflag &= ~IXOFF; + } + tcsetattr (FD, TCSANOW, &ttermios); + tcsetattr (0, TCSANOW, &ctermios); +#else /* HAVE_TERMIOS */ + 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); +#endif /* HAVE_TERMIOS */ +} + +/* + * Send a break. + */ +genbrk() +{ + + ioctl(FD, TIOCSBRK, NULL); + sleep(1); + ioctl(FD, TIOCCBRK, NULL); +} + +/* + * Suspend tip + */ +suspend(c) + char c; +{ + + unraw(); + kill(c == CTRL('y') ? getpid() : 0, SIGTSTP); + raw(); +} + +/* + * 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 = _PATH_BSHELL; + 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); +} diff --git a/usr.bin/tip/tip/cmdtab.c b/usr.bin/tip/tip/cmdtab.c new file mode 100644 index 0000000..12ecc07 --- /dev/null +++ b/usr.bin/tip/tip/cmdtab.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)cmdtab.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "tipconf.h" +#include "tip.h" + +extern int shell(), getfl(), sendfile(), chdirectory(); +extern int finish(), help(), pipefile(), pipeout(), consh(), variable(); +extern int cu_take(), cu_put(), dollar(), genbrk(), suspend(); + +esctable_t etable[] = { + { '!', NORM, "shell", shell }, + { '<', NORM, "receive file from remote host", getfl }, + { '>', NORM, "send file to remote host", sendfile }, + { 't', NORM, "take file from remote UNIX", cu_take }, + { 'p', NORM, "put file to remote UNIX", cu_put }, + { '|', NORM, "pipe remote file", pipefile }, + { '$', NORM, "pipe local command to remote host", pipeout }, +#if CONNECT + { 'C', NORM, "connect program to remote host",consh }, +#endif + { 'c', NORM, "change directory", chdirectory }, + { '.', NORM, "exit from tip", finish }, + {CTRL('d'),NORM,"exit from tip", finish }, + {CTRL('y'),NORM,"suspend tip (local+remote)", suspend }, + {CTRL('z'),NORM,"suspend tip (local only)", suspend }, + { 's', NORM, "set variable", variable }, + { '?', NORM, "get this summary", help }, + { '#', NORM, "send break", genbrk }, + { 0, 0, 0 } +}; diff --git a/usr.bin/tip/tip/cu.c b/usr.bin/tip/tip/cu.c new file mode 100644 index 0000000..bab8492 --- /dev/null +++ b/usr.bin/tip/tip/cu.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)cu.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "tipconf.h" +#include "tip.h" + +void cleanup(); + +#if INCLUDE_CU_INTERFACE + +/* + * Botch the interface to look like cu's + */ +cumain(argc, argv) + char *argv[]; +{ + register int i; + static char sbuf[12]; + + if (argc < 2) { + printf("usage: cu telno [-t] [-s speed] [-a acu] [-l line] [-#]\n"); + exit(8); + } + CU = DV = NOSTR; + BR = DEFBR; + for (; argc > 1; argv++, argc--) { + if (argv[1][0] != '-') + PN = argv[1]; + else switch (argv[1][1]) { + + case 't': + HW = 1, DU = -1; + --argc; + continue; + + case 'a': + CU = argv[2]; ++argv; --argc; + break; + + case 's': + if (argc < 3 || speed(atoi(argv[2])) == 0) { + fprintf(stderr, "cu: unsupported speed %s\n", + argv[2]); + exit(3); + } + BR = atoi(argv[2]); ++argv; --argc; + break; + + case 'l': + DV = argv[2]; ++argv; --argc; + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (CU) + CU[strlen(CU)-1] = argv[1][1]; + if (DV) + DV[strlen(DV)-1] = argv[1][1]; + break; + + default: + printf("Bad flag %s", argv[1]); + break; + } + } + signal(SIGINT, cleanup); + signal(SIGQUIT, cleanup); + signal(SIGHUP, cleanup); + signal(SIGTERM, cleanup); + + /* + * The "cu" host name is used to define the + * attributes of the generic dialer. + */ + (void)sprintf(sbuf, "cu%d", BR); + if ((i = hunt(sbuf)) == 0) { + printf("all ports busy\n"); + exit(3); + } + if (i == -1) { + printf("link down\n"); + (void)uu_unlock(uucplock); + exit(3); + } + setbuf(stdout, NULL); + loginit(); + user_uid(); + vinit(); + setparity("none"); + boolean(value(VERBOSE)) = 0; + if (HW) + ttysetup(speed(BR)); + if (connect()) { + printf("Connect failed\n"); + daemon_uid(); + (void)uu_unlock(uucplock); + exit(1); + } + if (!HW) + ttysetup(speed(BR)); +} +#endif /* INCLUDE_CU_INTERFACE */ diff --git a/usr.bin/tip/tip/hunt.c b/usr.bin/tip/tip/hunt.c new file mode 100644 index 0000000..97e3a6a --- /dev/null +++ b/usr.bin/tip/tip/hunt.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)hunt.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "tipconf.h" +#include "tip.h" + +extern char *getremote(); +extern char *rindex(); + +static jmp_buf deadline; +static int deadfl; + +void +dead() +{ + deadfl = 1; + longjmp(deadline, 1); +} + +hunt(name) + char *name; +{ + register char *cp; + sig_t f; + + f = signal(SIGALRM, dead); + while (cp = getremote(name)) { + deadfl = 0; + uucplock = rindex(cp, '/')+1; + if (uu_lock(uucplock) < 0) + continue; + /* + * Straight through call units, such as the BIZCOMP, + * VADIC and the DF, must indicate they're hardwired in + * order to get an open file descriptor placed in FD. + * Otherwise, as for a DN-11, the open will have to + * be done in the "open" routine. + */ + if (!HW) + break; + if (setjmp(deadline) == 0) { + alarm(10); + FD = open(cp, O_RDWR); + } + alarm(0); + if (FD < 0) { + perror(cp); + deadfl = 1; + } + if (!deadfl) { + ioctl(FD, TIOCEXCL, 0); +#if HAVE_TERMIOS + { + struct termios t; + if (tcgetattr(FD, &t) == 0) { + t.c_cflag |= HUPCL; + (void)tcsetattr(FD, TCSANOW, &t); + } + } +#else /* HAVE_TERMIOS */ +#ifdef TIOCHPCL + ioctl(FD, TIOCHPCL, 0); +#endif +#endif /* HAVE_TERMIOS */ + signal(SIGALRM, SIG_DFL); + return ((int)cp); + } + (void)uu_unlock(uucplock); + } + signal(SIGALRM, f); + return (deadfl ? -1 : (int)cp); +} diff --git a/usr.bin/tip/tip/log.c b/usr.bin/tip/tip/log.c new file mode 100644 index 0000000..16e918a --- /dev/null +++ b/usr.bin/tip/tip/log.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)log.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "tipconf.h" +#include "tip.h" + +#if ACULOG +static FILE *flog = NULL; + +/* + * Log file maintenance routines + */ + +logent(group, num, acu, message) + char *group, *num, *acu, *message; +{ + char *user, *timestamp; + struct passwd *pwd; + long t; + + if (flog == NULL) + return; + if (flock(fileno(flog), LOCK_EX) < 0) { + perror("tip: flock"); + return; + } + if ((user = getlogin()) == NOSTR) + if ((pwd = getpwuid(getuid())) == NOPWD) + user = "???"; + else + user = pwd->pw_name; + t = time(0); + timestamp = ctime(&t); + timestamp[24] = '\0'; + fprintf(flog, "%s (%s) <%s, %s, %s> %s\n", + user, timestamp, group, +#if PRISTINE + "", +#else + num, +#endif + acu, message); + (void) fflush(flog); + (void) flock(fileno(flog), LOCK_UN); +} + +loginit() +{ + flog = fopen(value(LOG), "a"); + if (flog == NULL) + fprintf(stderr, "can't open log file %s.\r\n", value(LOG)); +} +#endif diff --git a/usr.bin/tip/tip/partab.c b/usr.bin/tip/tip/partab.c new file mode 100644 index 0000000..1da4e23 --- /dev/null +++ b/usr.bin/tip/tip/partab.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)partab.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Even parity table for 0-0177 + */ +char evenpartab[] = { + 0000,0201,0202,0003,0204,0005,0006,0207, + 0210,0011,0012,0213,0014,0215,0216,0017, + 0220,0021,0022,0223,0024,0225,0226,0027, + 0030,0231,0232,0033,0234,0035,0036,0237, + 0240,0041,0042,0243,0044,0245,0246,0047, + 0050,0251,0252,0053,0254,0055,0056,0257, + 0060,0261,0262,0063,0264,0065,0066,0267, + 0270,0071,0072,0273,0074,0275,0276,0077, + 0300,0101,0102,0303,0104,0305,0306,0107, + 0110,0311,0312,0113,0314,0115,0116,0317, + 0120,0321,0322,0123,0324,0125,0126,0327, + 0330,0131,0132,0333,0134,0335,0336,0137, + 0140,0341,0342,0143,0344,0145,0146,0347, + 0350,0151,0152,0353,0154,0355,0356,0157, + 0360,0161,0162,0363,0164,0365,0366,0167, + 0170,0371,0372,0173,0374,0175,0176,0377, +}; diff --git a/usr.bin/tip/tip/pathnames.h b/usr.bin/tip/tip/pathnames.h new file mode 100644 index 0000000..89730a9 --- /dev/null +++ b/usr.bin/tip/tip/pathnames.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)pathnames.h 8.1 (Berkeley) 6/6/93 + */ + +#include <paths.h> + +/* + Specify path to ACU (modem) log +*/ +#define _PATH_ACULOG "/var/log/aculog" + +/* + Specify path and format of lock files +*/ +/* #define _PATH_LOCKDIRNAME "/usr/spool/uucp/LCK..%s" */ +/* #define _PATH_LOCKDIRNAME "/etc/locks/LCK..%s" */ +/* #define _PATH_LOCKDIRNAME "/usr/spool/locks/LCK..%s" */ +/* #define _PATH_LOCKDIRNAME "/usr/spool/uucp/LCK/LCK..%s" */ +#define _PATH_LOCKDIRNAME "/var/spool/lock/LCK..%s" + +/* + Specify location for system wide databases +*/ +#define _PATH_MODEMS "/etc/modems" +#define _PATH_PHONES "/etc/phones" +#define _PATH_REMOTE "/etc/remote" + diff --git a/usr.bin/tip/tip/remote.c b/usr.bin/tip/tip/remote.c new file mode 100644 index 0000000..333a915 --- /dev/null +++ b/usr.bin/tip/tip/remote.c @@ -0,0 +1,286 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1992, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)remote.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include <sys/syslimits.h> +#include <stdio.h> +#include <stdlib.h> + +#include "tipconf.h" +#include "tip.h" +#include "pathnames.h" + +/* + * Attributes to be gleened from remote host description + * data base. + */ +static char **caps[] = { + &AT, &DV, &CM, &CU, &EL, &IE, &OE, &PN, &PR, &DI, + &ES, &EX, &FO, &RC, &RE, &PA, &LI, &LO +}; + +static char *capstrings[] = { + "at", "dv", "cm", "cu", "el", "ie", "oe", "pn", "pr", + "di", "es", "ex", "fo", "rc", "re", "pa", "li", "lo", 0 +}; + +static char *db_array[3] = { _PATH_REMOTE, 0, 0 }; + +#define cgetflag(f) (cgetcap(bp, f, ':') != NULL) + +/* + Expand the start tilde sequence at the start of the + specified path. Optionally, free space allocated to + path before reinitializing it. +*/ +static int +expand_tilde (char **path, void (*free) (char *p)) +{ + int rc = 0; + char buffer [PATH_MAX]; + char *tailp; + if ((tailp = strchr (*path + 1, '/')) != NULL) + { + struct passwd *pwd; + *tailp++ = '\0'; + if (*(*path + 1) == '\0') + strcpy (buffer, getlogin ()); + else + strcpy (buffer, *path + 1); + if ((pwd = getpwnam (buffer)) != NULL) + { + strcpy (buffer, pwd->pw_dir); + strcat (buffer, "/"); + strcat (buffer, tailp); + if (free) + free (*path); + *path = strdup (buffer); + rc++; + } + return rc; + } +} + +static +getremcap(host) + register char *host; +{ + register char **p, ***q; + char *bp; + char *rempath; + int stat; + + rempath = getenv("REMOTE"); + if (rempath != NULL) + if (*rempath != '/') + /* we have an entry */ + cgetset(rempath); + else { /* we have a path */ + db_array[1] = rempath; + db_array[2] = _PATH_REMOTE; + } + + if ((stat = cgetent(&bp, db_array, host)) < 0) { + if (DV || + host[0] == '/' && access(DV = host, R_OK | W_OK) == 0) { + CU = DV; + HO = host; + HW = 1; + DU = 0; + if (!BR) + BR = DEFBR; + FS = DEFFS; + return; + } + switch(stat) { + case -1: + fprintf(stderr, "tip: unknown host %s\n", host); + break; + case -2: + fprintf(stderr, + "tip: can't open host description file\n"); + break; + case -3: + fprintf(stderr, + "tip: possible reference loop in host description file\n"); + break; + } + exit(3); + } + + for (p = capstrings, q = caps; *p != NULL; p++, q++) + if (**q == NULL) + cgetstr(bp, *p, *q); + if (!BR && (cgetnum(bp, "br", &BR) == -1)) + BR = DEFBR; + if (cgetnum(bp, "fs", &FS) == -1) + FS = DEFFS; + if (DU < 0) + DU = 0; + else + DU = cgetflag("du"); + if (DV == NOSTR) { + fprintf(stderr, "%s: missing device spec\n", host); + exit(3); + } + if (DU && CU == NOSTR) + CU = DV; + if (DU && PN == NOSTR) { + fprintf(stderr, "%s: missing phone number\n", host); + exit(3); + } + + HD = cgetflag("hd"); + + /* + * This effectively eliminates the "hw" attribute + * from the description file + */ + if (!HW) + HW = (CU == NOSTR) || (DU && equal(DV, CU)); + HO = host; + + /* + If login script, verify access + */ + if (LI != NOSTR) { + if (*LI == '~') + (void) expand_tilde (&LI, NULL); + if (access (LI, F_OK | X_OK) != 0) { + printf("tip (warning): can't open login script \"%s\"\n", LI); + LI = NOSTR; + } + } + + /* + If logout script, verify access + */ + if (LO != NOSTR) { + if (*LO == '~') + (void) expand_tilde (&LO, NULL); + if (access (LO, F_OK | X_OK) != 0) { + printf("tip (warning): can't open logout script \"%s\"\n", LO); + LO = NOSTR; + } + } + + /* + * see if uppercase mode should be turned on initially + */ + if (cgetflag("ra")) + boolean(value(RAISE)) = 1; + if (cgetflag("ec")) + boolean(value(ECHOCHECK)) = 1; + if (cgetflag("be")) + boolean(value(BEAUTIFY)) = 1; + if (cgetflag("nb")) + boolean(value(BEAUTIFY)) = 0; + if (cgetflag("sc")) + boolean(value(SCRIPT)) = 1; + if (cgetflag("tb")) + boolean(value(TABEXPAND)) = 1; + if (cgetflag("vb")) + boolean(value(VERBOSE)) = 1; + if (cgetflag("nv")) + boolean(value(VERBOSE)) = 0; + if (cgetflag("ta")) + boolean(value(TAND)) = 1; + if (cgetflag("nt")) + boolean(value(TAND)) = 0; + if (cgetflag("rw")) + boolean(value(RAWFTP)) = 1; + if (cgetflag("hd")) + boolean(value(HALFDUPLEX)) = 1; + if (RE == NOSTR) + RE = (char *)"tip.record"; + if (EX == NOSTR) + EX = (char *)"\t\n\b\f"; + if (ES != NOSTR) + vstring("es", ES); + if (FO != NOSTR) + vstring("fo", FO); + if (PR != NOSTR) + vstring("pr", PR); + if (RC != NOSTR) + vstring("rc", RC); + if (cgetnum(bp, "dl", &DL) == -1) + DL = 0; + if (cgetnum(bp, "cl", &CL) == -1) + CL = 0; + if (cgetnum(bp, "et", &ET) == -1) + ET = 10; +} + +char * +getremote(host) + char *host; +{ + register char *cp; + static char *next; + static int lookedup = 0; + + if (!lookedup) { + if (host == NOSTR && (host = getenv("HOST")) == NOSTR) { + fprintf(stderr, "tip: no host specified\n"); + exit(3); + } + getremcap(host); + next = DV; + lookedup++; + } + /* + * We return a new device each time we're called (to allow + * a rotary action to be simulated) + */ + if (next == NOSTR) + return (NOSTR); + if ((cp = index(next, ',')) == NULL) { + DV = next; + next = NOSTR; + } else { + *cp++ = '\0'; + DV = next; + next = cp; + } + return (DV); +} diff --git a/usr.bin/tip/tip/tip.1 b/usr.bin/tip/tip/tip.1 new file mode 100644 index 0000000..caae520 --- /dev/null +++ b/usr.bin/tip/tip/tip.1 @@ -0,0 +1,461 @@ +.\" Copyright (c) 1980, 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)tip.1 8.4 (Berkeley) 4/18/94 +.\" +.Dd April 18, 1994 +.Dt TIP 1 +.Os BSD 4 +.Sh NAME +.Nm tip , +.Nm cu +.Nd connect to a remote system +.Sh SYNOPSIS +.Nm tip +.Op Fl v +.Fl Ns Ns Ar speed +.Ar system\-name +.Nm tip +.Op Fl v +.Fl Ns Ns Ar speed +.Ar phone\-number +.Nm cu +.Ar phone\-number +.Op Fl t +.Op Fl s Ar speed +.Op Fl a Ar acu +.Op Fl l Ar line +.Op Fl # +.Sh DESCRIPTION +.Nm Tip +and +.Ar cu +establish a full-duplex connection to another machine, +giving the appearance of being logged in directly on the +remote cpu. It goes without saying that you must have a login +on the machine (or equivalent) to which you wish to connect. +The preferred interface is +.Nm tip . +The +.Ar cu +interface is included for those people attached to the +``call +.Ux Ns '' +command of version 7. This manual page +describes only +.Nm tip . +.Pp +Available Option: +.Bl -tag -width indent +.It Fl v +Set verbose mode. +.El +.Pp +Typed characters are normally transmitted directly to the remote +machine (which does the echoing as well). A tilde (`~') appearing +as the first character of a line is an escape signal; the following +are recognized: +.Bl -tag -width flag +.It Ic \&~^D No or Ic \&~ . +Drop the connection and exit +(you may still be logged in on the +remote machine). +.It Ic \&~c Op Ar name +Change directory to +.Ar name +(no argument +implies change to your home directory). +.It Ic \&~! +Escape to a shell (exiting the shell will +return you to tip). +.It Ic \&~> +Copy file from local to remote. +.Nm Tip +prompts for the name of a local file to transmit. +.It Ic \&~< +Copy file from remote to local. +.Nm Tip +prompts first for the name of the file to be sent, then for +a command to be executed on the remote machine. +.It Ic \&~p Ar from Op Ar to +Send a file to a remote +.Ux +host. The put command causes the remote +.Ux +system to run the command string ``cat > 'to''', while +.Nm tip +sends it the ``from'' +file. If the ``to'' file isn't specified the ``from'' file name is used. +This command is actually a +.Ux +specific version of the ``~>'' command. +.It Ic \&~t Ar from Op Ar to +Take a file from a remote +.Ux +host. +As in the put command the ``to'' file +defaults to the ``from'' file name if it isn't specified. +The remote host +executes the command string ``cat 'from';echo ^A'' to send the file to +.Nm tip . +.It Ic \&~| +Pipe the output from a remote command to a local +.Ux +process. +The command string sent to the local +.Ux +system is processed by the shell. +.It Ic \&~$ +Pipe the output from a local +.Ux +process to the remote host. +The command string sent to the local +.Ux +system is processed by the shell. +.It Ic \&~C +Fork a child process on the local system to perform special protocols +such as \s-1XMODEM\s+1. The child program will be run with the following +somewhat unusual arrangement of file descriptors: +.nf +.in +1i +0 <-> local tty in +1 <-> local tty out +2 <-> local tty out +3 <-> remote tty in +4 <-> remote tty out +.in -1i +.fi +.It Ic \&~# +Send a +.Dv BREAK +to the remote system. +For systems which don't support the +necessary +.Ar ioctl +call the break is simulated by a sequence of line speed changes +and +.Dv DEL +characters. +.It Ic \&~s +Set a variable (see the discussion below). +.It Ic \&~^Z +Stop +.Nm tip +(only available with job control). +.It Ic \&~^Y +Stop only the ``local side'' of +.Nm tip +(only available with job control); +the ``remote side'' of +.Nm tip , +the side that displays output from the remote host, is left running. +.It Ic \&~? +Get a summary of the tilde escapes +.El +.Pp +.Nm Tip +uses the file +.Pa /etc/remote +to find how to reach a particular +system and to find out how it should operate while talking +to the system; +refer to +.Xr remote 5 +for a full description. +Each system has a default baud rate with which to +establish a connection. If this value is not suitable, the baud rate +to be used may be specified on the command line, e.g. +.Ql "tip -300 mds" . +.Pp +When +.Nm tip +establishes a connection it sends out a +connection message to the remote system; the default value, if any, +is defined in +.Pa /etc/remote +(see +.Xr remote 5 ) . +.Pp +When +.Nm tip +prompts for an argument (e.g. during setup of +a file transfer) the line typed may be edited with the standard +erase and kill characters. A null line in response to a prompt, +or an interrupt, will abort the dialogue and return you to the +remote machine. +.Pp +.Nm Tip +guards against multiple users connecting to a remote system +by opening modems and terminal lines with exclusive access, +and by honoring the locking protocol used by +.Xr uucico 8 . +.Pp +During file transfers +.Nm tip +provides a running count of the number of lines transferred. +When using the ~> and ~< commands, the ``eofread'' and ``eofwrite'' +variables are used to recognize end-of-file when reading, and +specify end-of-file when writing (see below). File transfers +normally depend on tandem mode for flow control. If the remote +system does not support tandem mode, ``echocheck'' may be set +to indicate +.Nm tip +should synchronize with the remote system on the echo of each +transmitted character. +.Pp +When +.Nm tip +must dial a phone number to connect to a system it will print +various messages indicating its actions. +.Nm Tip +supports modems that use the AT command set. +.Nm Tip +uses the file +.Pa /etc/modems +to find out how to operate with a particular +modem; refer to +.Xr modems 5 +for a full description. +.Ss VARIABLES +.Nm Tip +maintains a set of +.Ar variables +which control its operation. +Some of these variables are read-only to normal users (root is allowed +to change anything of interest). Variables may be displayed +and set through the ``s'' escape. The syntax for variables is patterned +after +.Xr vi 1 +and +.Xr Mail 1 . +Supplying ``all'' +as an argument to the set command displays all variables readable by +the user. Alternatively, the user may request display of a particular +variable by attaching a `?' to the end. For example ``escape?'' +displays the current escape character. +.Pp +Variables are numeric, string, character, or boolean values. Boolean +variables are set merely by specifying their name; they may be reset +by prepending a `!' to the name. Other variable types are set by +concatenating an `=' and the value. The entire assignment must not +have any blanks in it. A single set command may be used to interrogate +as well as set a number of variables. +Variables may be initialized at run time by placing set commands +(without the ``~s'' prefix in a file +.Pa .tiprc +in one's home directory). The +.Fl v +option causes +.Nm tip +to display the sets as they are made. +Certain common variables have abbreviations. +The following is a list of common variables, +their abbreviations, and their default values. +.Bl -tag -width Ar +.It Ar beautify +(bool) Discard unprintable characters when a session is being scripted; +abbreviated +.Ar be . +.It Ar baudrate +(num) The baud rate at which the connection was established; +abbreviated +.Ar ba . +.It Ar dialtimeout +(num) When dialing a phone number, the time (in seconds) +to wait for a connection to be established; abbreviated +.Ar dial . +.It Ar echocheck +(bool) Synchronize with the remote host during file transfer by +waiting for the echo of the last character transmitted; default is +.Ar off . +.It Ar eofread +(str) The set of characters which signify an end-of-transmission +during a ~< file transfer command; abbreviated +.Ar eofr . +.It Ar eofwrite +(str) The string sent to indicate end-of-transmission during +a ~> file transfer command; abbreviated +.Ar eofw . +.It Ar eol +(str) The set of characters which indicate an end-of-line. +.Nm Tip +will recognize escape characters only after an end-of-line. +.It Ar escape +(char) The command prefix (escape) character; abbreviated +.Ar es ; +default value is `~'. +.It Ar exceptions +(str) The set of characters which should not be discarded +due to the beautification switch; abbreviated +.Ar ex ; +default value is ``\et\en\ef\eb''. +.It Ar force +(char) The character used to force literal data transmission; +abbreviated +.Ar fo ; +default value is `^P'. +.It Ar framesize +(num) The amount of data (in bytes) to buffer between file system +writes when receiving files; abbreviated +.Ar fr . +.It Ar host +(str) The name of the host to which you are connected; abbreviated +.Ar ho . +.It Ar login +(str) Pathname of a login shell script to run once connected; standard input +and output are redirected to the remote host. Leading tildes in the pathname +are expanded expansion; abbreviated +.Ar li . +.It Ar logout +(str) Pathname of a shell script to run before disconnecting; standard input +and output are redirected to the remote host. Leading tildes in the pathname +are expanded expansion; abbreviated +.Ar lo . +.It Ar prompt +(char) The character which indicates an end-of-line on the remote +host; abbreviated +.Ar pr ; +default value is `\en'. This value is used to synchronize during +data transfers. The count of lines transferred during a file transfer +command is based on receipt of this character. +.It Ar raise +(bool) Upper case mapping mode; abbreviated +.Ar ra ; +default value is +.Ar off . +When this mode is enabled, all lower case letters will be mapped to +upper case by +.Nm tip +for transmission to the remote machine. +.It Ar raisechar +(char) The input character used to toggle upper case mapping mode; +abbreviated +.Ar rc ; +default value is `^A'. +.It Ar record +(str) The name of the file in which a session script is recorded; +abbreviated +.Ar rec ; +default value is ``tip.record''. +.It Ar script +(bool) Session scripting mode; abbreviated +.Ar sc ; +default is +.Ar off . +When +.Ar script +is +.Li true , +.Nm tip +will record everything transmitted by the remote machine in +the script record file specified in +.Ar record . +If the +.Ar beautify +switch is on, only printable +.Tn ASCII +characters will be included in +the script file (those characters betwee 040 and 0177). The +variable +.Ar exceptions +is used to indicate characters which are an exception to the normal +beautification rules. +.It Ar tabexpand +(bool) Expand tabs to spaces during file transfers; abbreviated +.Ar tab ; +default value is +.Ar false . +Each tab is expanded to 8 spaces. +.It Ar verbose +(bool) Verbose mode; abbreviated +.Ar verb ; +default is +.Ar true . +When verbose mode is enabled, +.Nm tip +prints messages while dialing, shows the current number +of lines transferred during a file transfer operations, +and more. +.El +.Sh ENVIRONMENT +.Nm Tip +uses the following environment variables: +.Bl -tag -width Fl +.It Ev SHELL +(str) The name of the shell to use for the ~! command; default +value is ``/bin/sh'', or taken from the environment. +.It Ev HOME +(str) The home directory to use for the ~c command; default +value is taken from the environment. +.It Ev HOST +Check for a default host if none specified. +.El +.Pp +The variables +.Ev ${REMOTE} +and +.Ev ${PHONES} +are also exported. +.Sh FILES +.Bl -tag -width /var/spool/lock/LCK..* -compact +.It Pa /etc/modems +Global modem configuration data base. +.It Pa /etc/remote +Global system descriptions. +.It Pa /etc/phones +Global phone number data base. +.It ${REMOTE} +Private system descriptions. +.It ${PHONES} +Private phone numbers. +.It ~/.tiprc +Initialization file. +.It Pa tip.record +Record file. +.It /var/log/aculog +Line access log. +.It Pa /var/spool/lock/LCK..* +Lock file to avoid conflicts with +.Xr uucp . +.El +.Sh DIAGNOSTICS +Diagnostics are, hopefully, self explanatory. +.Sh SEE ALSO +.Xr remote 5 , +.Xr phones 5 +.Sh HISTORY +The +.Nm tip +appeared command in +.Bx 4.2 . +.Sh BUGS +The full set of variables is undocumented and should, probably, be +pared down. diff --git a/usr.bin/tip/tip/tip.c b/usr.bin/tip/tip/tip.c new file mode 100644 index 0000000..3482d00 --- /dev/null +++ b/usr.bin/tip/tip/tip.c @@ -0,0 +1,677 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)tip.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + Forward declarations +*/ +void ttysetup (int speed); + +/* + * tip - UNIX link to other systems + * tip [-v] [-speed] system-name + * or + * cu phone-number [-s speed] [-l line] [-a acu] + */ + +#include "tipconf.h" +#include "tip.h" +#include "pathnames.h" + +/* + * Baud rate mapping table + */ +#if !HAVE_TERMIOS +CONST int bauds[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, + 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, -1 +}; +#endif + +#if !HAVE_TERMIOS +int disc = OTTYDISC; /* tip normally runs this way */ +#endif + +void intprompt(); +void timeout(); +void cleanup(); +void tipdone(); +char *sname(); +char PNbuf[256]; /* This limits the size of a number */ + +void +main(argc, argv) + char *argv[]; +{ + char *system = NOSTR; + register int i; + register char *p; + char sbuf[12]; + + gid = getgid(); + egid = getegid(); + uid = getuid(); + euid = geteuid(); + +#if INCLUDE_CU_INTERFACE + if (equal(sname(argv[0]), "cu")) { + cumode = 1; + cumain(argc, argv); + goto cucommon; + } +#endif /* INCLUDE_CU_INTERFACE */ + + if (argc > 4) { + fprintf(stderr, "usage: tip [-v] [-speed] [system-name]\n"); + exit(1); + } + if (!isatty(0)) { + fprintf(stderr, "tip: must be interactive\n"); + exit(1); + } + + for (; argc > 1; argv++, argc--) { + if (argv[1][0] != '-') + system = argv[1]; + else switch (argv[1][1]) { + + case 'v': + vflag++; + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + BR = atoi(&argv[1][1]); + break; + + default: + fprintf(stderr, "tip: %s, unknown option\n", argv[1]); + break; + } + } + + if (system == NOSTR) + goto notnumber; + if (isalpha(*system)) + goto notnumber; + /* + * System name is really a phone number... + * Copy the number then stomp on the original (in case the number + * is private, we don't want 'ps' or 'w' to find it). + */ + if (strlen(system) > sizeof PNbuf - 1) { + fprintf(stderr, "tip: phone number too long (max = %d bytes)\n", + sizeof PNbuf - 1); + exit(1); + } + strncpy( PNbuf, system, sizeof PNbuf - 1 ); + for (p = system; *p; p++) + *p = '\0'; + PN = PNbuf; + (void)sprintf(sbuf, "tip%d", BR); + system = sbuf; + +notnumber: + (void)signal(SIGINT, cleanup); + (void)signal(SIGQUIT, cleanup); + (void)signal(SIGHUP, cleanup); + (void)signal(SIGTERM, cleanup); + (void)signal(SIGUSR1, tipdone); + + if ((i = hunt(system)) == 0) { + printf("all ports busy\n"); + exit(3); + } + if (i == -1) { + printf("link down\n"); + (void)uu_unlock(uucplock); + exit(3); + } + setbuf(stdout, NULL); + loginit(); + + /* + * Kludge, their's no easy way to get the initialization + * in the right order, so force it here + */ + if ((PH = getenv("PHONES")) == NOSTR) + PH = _PATH_PHONES; + vinit(); /* init variables */ + setparity("even"); /* set the parity table */ + if ((i = speed(number(value(BAUDRATE)))) == NULL) { + printf("tip: bad baud rate %d\n", number(value(BAUDRATE))); + (void)uu_unlock(uucplock); + exit(3); + } + + /* + * Now that we have the logfile and the ACU open + * return to the real uid and gid. These things will + * be closed on exit. Swap real and effective uid's + * so we can get the original permissions back + * for removing the uucp lock. + */ + user_uid(); + + /* + * Hardwired connections require the + * line speed set before they make any transmissions + * (this is particularly true of things like a DF03-AC) + */ + if (HW) + ttysetup(i); + if (p = connect()) { + printf("\07%s\n[EOT]\n", p); + daemon_uid(); + (void)uu_unlock(uucplock); + exit(1); + } + if (!HW) + ttysetup(i); +cucommon: + /* + * From here down the code is shared with + * the "cu" version of tip. + */ + +#if HAVE_TERMIOS + tcgetattr (0, &otermios); + ctermios = otermios; +#ifndef _POSIX_SOURCE + ctermios.c_iflag = (IMAXBEL|IXANY|ISTRIP|IXON|BRKINT); + ctermios.c_lflag = (PENDIN|IEXTEN|ISIG|ECHOCTL|ECHOE|ECHOKE); +#else + ctermios.c_iflag = (ISTRIP|IXON|BRKINT); + ctermios.c_lflag = (PENDIN|IEXTEN|ISIG|ECHOE); +#endif + ctermios.c_cflag = (CLOCAL|HUPCL|CREAD|CS8); + ctermios.c_cc[VINTR] = ctermios.c_cc[VQUIT] = -1; + ctermios.c_cc[VSUSP] = ctermios.c_cc[VDSUSP] = ctermios.c_cc[VDISCARD] = + ctermios.c_cc[VLNEXT] = -1; +#else /* HAVE_TERMIOS */ + ioctl(0, TIOCGETP, (char *)&defarg); + ioctl(0, TIOCGETC, (char *)&defchars); + ioctl(0, TIOCGLTC, (char *)&deflchars); + ioctl(0, TIOCGETD, (char *)&odisc); + arg = defarg; + arg.sg_flags = ANYP | CBREAK; + tchars = defchars; + tchars.t_intrc = tchars.t_quitc = -1; + ltchars = deflchars; + ltchars.t_suspc = ltchars.t_dsuspc = ltchars.t_flushc + = ltchars.t_lnextc = -1; +#endif /* HAVE_TERMIOS */ + raw(); + + pipe(fildes); pipe(repdes); + (void)signal(SIGALRM, timeout); + + /* + * Everything's set up now: + * connection established (hardwired or dialup) + * line conditioned (baud rate, mode, etc.) + * internal data structures (variables) + * so, fork one process for local side and one for remote. + */ + printf(cumode ? "Connected\r\n" : "\07connected\r\n"); + + if (LI != NOSTR && tiplink (LI, 0) != 0) { + tipabort ("login failed"); + } + + if (pid = fork()) + tipin(); + else + tipout(); + /*NOTREACHED*/ +} + +void +cleanup() +{ + + daemon_uid(); + (void)uu_unlock(uucplock); +#if !HAVE_TERMIOS + if (odisc) + ioctl(0, TIOCSETD, (char *)&odisc); +#endif + exit(0); +} + +void +tipdone() +{ + tipabort("Hangup."); +} +/* + * Muck with user ID's. We are setuid to the owner of the lock + * directory when we start. user_uid() reverses real and effective + * ID's after startup, to run with the user's permissions. + * daemon_uid() switches back to the privileged uid for unlocking. + * Finally, to avoid running a shell with the wrong real uid, + * shell_uid() sets real and effective uid's to the user's real ID. + */ +static int uidswapped; + +user_uid() +{ + if (uidswapped == 0) { + seteuid(uid); + uidswapped = 1; + } +} + +daemon_uid() +{ + + if (uidswapped) { + seteuid(euid); + uidswapped = 0; + } +} + +shell_uid() +{ + + seteuid(uid); +} + +/* + * put the controlling keyboard into raw mode + */ +void +raw () +{ +#if HAVE_TERMIOS + tcsetattr (0, TCSANOW, &ctermios); +#else /* HAVE_TERMIOS */ + + ioctl(0, TIOCSETP, &arg); + ioctl(0, TIOCSETC, &tchars); + ioctl(0, TIOCSLTC, <chars); + ioctl(0, TIOCSETD, (char *)&disc); +#endif /* HAVE_TERMIOS */ +} + + +/* + * return keyboard to normal mode + */ +unraw() +{ +#if HAVE_TERMIOS + tcsetattr (0, TCSANOW, &otermios); +#else /* HAVE_TERMIOS */ + + ioctl(0, TIOCSETD, (char *)&odisc); + ioctl(0, TIOCSETP, (char *)&defarg); + ioctl(0, TIOCSETC, (char *)&defchars); + ioctl(0, TIOCSLTC, (char *)&deflchars); +#endif /* HAVE_TERMIOS */ +} + +static jmp_buf promptbuf; + +/* + * Print string ``s'', then read a string + * in from the terminal. Handles signals & allows use of + * normal erase and kill characters. + */ +prompt(s, p) + char *s; + register char *p; +{ + register char *b = p; + sig_t oint, oquit; + + stoprompt = 0; + oint = signal(SIGINT, intprompt); + oquit = signal(SIGQUIT, SIG_IGN); + unraw(); + printf("%s", s); + if (setjmp(promptbuf) == 0) + while ((*p = getchar()) != EOF && *p != '\n') + p++; + *p = '\0'; + + raw(); + (void)signal(SIGINT, oint); + (void)signal(SIGQUIT, oquit); + return (stoprompt || p == b); +} + +/* + * Interrupt service routine during prompting + */ +void +intprompt() +{ + + (void)signal(SIGINT, SIG_IGN); + stoprompt = 1; + printf("\r\n"); + longjmp(promptbuf, 1); +} + +/* + * ****TIPIN TIPIN**** + */ +tipin() +{ + char gch, bol = 1; + + /* + * Kinda klugey here... + * check for scripting being turned on from the .tiprc file, + * but be careful about just using setscript(), as we may + * send a SIGEMT before tipout has a chance to set up catching + * it; so wait a second, then setscript() + */ + if (boolean(value(SCRIPT))) { + sleep(1); + setscript(); + } + + while (1) { + gch = getchar()&0177; + if ((gch == character(value(ESCAPE))) && bol) { + if (!(gch = escape())) + continue; + } else if (!cumode && gch == character(value(RAISECHAR))) { + boolean(value(RAISE)) = !boolean(value(RAISE)); + continue; + } else if (gch == '\r') { + bol = 1; + pwrite(FD, &gch, 1); + if (boolean(value(HALFDUPLEX))) + printf("\r\n"); + continue; + } else if (!cumode && gch == character(value(FORCE))) + gch = getchar()&0177; + bol = any(gch, value(EOL)); + if (boolean(value(RAISE)) && islower(gch)) + gch = toupper(gch); + pwrite(FD, &gch, 1); + if (boolean(value(HALFDUPLEX))) + printf("%c", gch); + } +} + +extern esctable_t etable[]; + +/* + * Escape handler -- + * called on recognition of ``escapec'' at the beginning of a line + */ +escape() +{ + register char gch; + register esctable_t *p; + char c = character(value(ESCAPE)); + + gch = (getchar()&0177); + for (p = etable; p->e_char; p++) + if (p->e_char == gch) { + if ((p->e_flags&PRIV) && uid) + continue; + printf("%s", ctrl(c)); + (*p->e_func)(gch); + return (0); + } + /* ESCAPE ESCAPE forces ESCAPE */ + if (c != gch) + pwrite(FD, &c, 1); + return (gch); +} + +speed(n) + int n; +{ +#if HAVE_TERMIOS + return (n); +#else + register CONST int *p; + + for (p = bauds; *p != -1; p++) + if (*p == n) + return (p - bauds); + return (NULL); +#endif +} + +any(c, p) + register char c, *p; +{ + while (p && *p) + if (*p++ == c) + return (1); + return (0); +} + +size(s) + register char *s; +{ + register int i = 0; + + while (s && *s++) + i++; + return (i); +} + +char * +interp(s) + register char *s; +{ + static char buf[256]; + register char *p = buf, c, *q; + + while (c = *s++) { + for (q = "\nn\rr\tt\ff\033E\bb"; *q; q++) + if (*q++ == c) { + *p++ = '\\'; *p++ = *q; + goto next; + } + if (c < 040) { + *p++ = '^'; *p++ = c + 'A'-1; + } else if (c == 0177) { + *p++ = '^'; *p++ = '?'; + } else + *p++ = c; + next: + ; + } + *p = '\0'; + return (buf); +} + +char * +ctrl(c) + char c; +{ + static char s[3]; + + if (c < 040 || c == 0177) { + s[0] = '^'; + s[1] = c == 0177 ? '?' : c+'A'-1; + s[2] = '\0'; + } else { + s[0] = c; + s[1] = '\0'; + } + return (s); +} + +/* + * Help command + */ +help(c) + char c; +{ + register esctable_t *p; + + printf("%c\r\n", c); + for (p = etable; p->e_char; p++) { + if ((p->e_flags&PRIV) && uid) + continue; + printf("%2s", ctrl(character(value(ESCAPE)))); + printf("%-2s %c %s\r\n", ctrl(p->e_char), + p->e_flags&EXP ? '*': ' ', p->e_help); + } +} + +/* + * Set up the "remote" tty's state + */ +void +ttysetup (int speed) +{ +#if HAVE_TERMIOS + struct termios termios; + tcgetattr (FD, &termios); + if (boolean(value(TAND))) + termios.c_iflag = IXOFF; + else + termios.c_iflag = 0; +#ifndef _POSIX_SOURCE + termios.c_lflag = (PENDIN|ECHOKE|ECHOE); +#else + termios.c_lflag = (PENDIN|ECHOE); +#endif + termios.c_cflag = (CLOCAL|HUPCL|CREAD|CS8); + termios.c_ispeed = termios.c_ospeed = speed; + tcsetattr (FD, TCSANOW, &termios); +#else /* HAVE_TERMIOS */ + unsigned bits = LDECCTQ; + + arg.sg_ispeed = arg.sg_ospeed = speed; + arg.sg_flags = RAW; + if (boolean(value(TAND))) + arg.sg_flags |= TANDEM; + ioctl(FD, TIOCSETP, (char *)&arg); + ioctl(FD, TIOCLBIS, (char *)&bits); +#endif /* HAVE_TERMIOS */ +} + +/* + * Return "simple" name from a file name, + * strip leading directories. + */ +char * +sname(s) + register char *s; +{ + register char *p = s; + + while (*s) + if (*s++ == '/') + p = s; + return (p); +} + +static char partab[0200]; +static int bits8; + +/* + * Do a write to the remote machine with the correct parity. + * We are doing 8 bit wide output, so we just generate a character + * with the right parity and output it. + */ +pwrite(fd, buf, n) + int fd; + char *buf; + register int n; +{ + register int i; + register char *bp; + extern int errno; + + bp = buf; + if (bits8 == 0) + for (i = 0; i < n; i++) { + *bp = partab[(*bp) & 0177]; + bp++; + } + if (write(fd, buf, n) < 0) { + if (errno == EIO) + tipabort("Lost carrier."); + if (errno == ENODEV) + tipabort("tty not available."); + /* this is questionable */ + perror("write"); + } +} + +/* + * Build a parity table with appropriate high-order bit. + */ +setparity(defparity) + char *defparity; +{ + register int i, flip, clr, set; + char *parity; + extern char evenpartab[]; + + if (value(PARITY) == NOSTR) + value(PARITY) = defparity; + parity = value(PARITY); + if (equal(parity, "none")) { + bits8 = 1; + return; + } + bits8 = 0; + flip = 0; + clr = 0377; + set = 0; + if (equal(parity, "odd")) + flip = 0200; /* reverse bit 7 */ + else if (equal(parity, "zero")) + clr = 0177; /* turn off bit 7 */ + else if (equal(parity, "one")) + set = 0200; /* turn on bit 7 */ + else if (!equal(parity, "even")) { + (void) fprintf(stderr, "%s: unknown parity value\r\n", parity); + (void) fflush(stderr); + } + for (i = 0; i < 0200; i++) + partab[i] = evenpartab[i] ^ flip | set & clr; +} diff --git a/usr.bin/tip/tip/tip.h b/usr.bin/tip/tip/tip.h new file mode 100644 index 0000000..fb45ce0 --- /dev/null +++ b/usr.bin/tip/tip/tip.h @@ -0,0 +1,308 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)tip.h 8.1 (Berkeley) 6/6/93 + */ + +/* + * tip - terminal interface program + */ + +#include <sys/types.h> +#include <machine/endian.h> +#include <sys/file.h> +#include <sys/time.h> + +#if HAVE_TERMIOS +#include <sys/ioctl.h> /* for TIOCHPCL */ +#include <sys/filio.h> /* for FIONREAD */ +#include <sys/termios.h> +#else +#include <sgtty.h> +#endif + +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <ctype.h> +#include <setjmp.h> +#include <unistd.h> +#include <errno.h> + +/* + * Remote host attributes + */ +char *DV; /* UNIX device(s) to open */ +char *EL; /* chars marking an EOL */ +char *CM; /* initial connection message */ +char *IE; /* EOT to expect on input */ +char *OE; /* EOT to send to complete FT */ +char *CU; /* call unit if making a phone call */ +char *AT; /* acu type */ +char *PN; /* phone number(s) */ +char *DI; /* disconnect string */ +char *PA; /* parity to be generated */ + +char *PH; /* phone number file */ +char *RM; /* remote file name */ +char *HO; /* host name */ + +char *LI; /* login script */ +char *LO; /* logout script */ + +long BR; /* line speed for conversation */ +long FS; /* frame size for transfers */ + +char DU; /* this host is dialed up */ +char HW; /* this device is hardwired, see hunt.c */ +char *ES; /* escape character */ +char *EX; /* exceptions */ +char *FO; /* force (literal next) char*/ +char *RC; /* raise character */ +char *RE; /* script record file */ +char *PR; /* remote prompt */ +long DL; /* line delay for file transfers to remote */ +long CL; /* char delay for file transfers to remote */ +long ET; /* echocheck timeout */ +char HD; /* this host is half duplex - do local echo */ + +/* + * String value table + */ +typedef + struct { + char *v_name; /* whose name is it */ + char v_type; /* for interpreting set's */ + char v_access; /* protection of touchy ones */ + char *v_abrev; /* possible abreviation */ + char *v_value; /* casted to a union later */ + } + value_t; + +#define STRING 01 /* string valued */ +#define BOOL 02 /* true-false value */ +#define NUMBER 04 /* numeric value */ +#define CHAR 010 /* character value */ + +#define WRITE 01 /* write access to variable */ +#define READ 02 /* read access */ + +#define CHANGED 01 /* low bit is used to show modification */ +#define PUBLIC 1 /* public access rights */ +#define PRIVATE 03 /* private to definer */ +#define ROOT 05 /* root defined */ + +#define TRUE 1 +#define FALSE 0 + +#define ENVIRON 020 /* initialize out of the environment */ +#define IREMOTE 040 /* initialize out of remote structure */ +#define INIT 0100 /* static data space used for initialization */ +#define TMASK 017 + +/* + * Definition of ACU line description + */ +typedef + struct { + char *acu_name; + int (*acu_dialer)(); + void (*acu_disconnect)(); + void (*acu_abort)(); + } + acu_t; + +#define equal(a, b) (strcmp(a,b)==0)/* A nice function to string compare */ + +/* + * variable manipulation stuff -- + * if we defined the value entry in value_t, then we couldn't + * initialize it in vars.c, so we cast it as needed to keep lint + * happy. + */ +typedef + union { + int zz_number; + short zz_boolean[2]; + char zz_character[4]; + int *zz_address; + } + zzhack; + +#define value(v) vtable[v].v_value + +#define number(v) ((((zzhack *)(&(v))))->zz_number) + +#if BYTE_ORDER == LITTLE_ENDIAN +#define boolean(v) ((((zzhack *)(&(v))))->zz_boolean[0]) +#define character(v) ((((zzhack *)(&(v))))->zz_character[0]) +#endif + +#if BYTE_ORDER == BIG_ENDIAN +#define boolean(v) ((((zzhack *)(&(v))))->zz_boolean[1]) +#define character(v) ((((zzhack *)(&(v))))->zz_character[3]) +#endif + +#define address(v) ((((zzhack *)(&(v))))->zz_address) + +/* + * Escape command table definitions -- + * lookup in this table is performed when ``escapec'' is recognized + * at the begining of a line (as defined by the eolmarks variable). +*/ + +typedef + struct { + char e_char; /* char to match on */ + char e_flags; /* experimental, priviledged */ + char *e_help; /* help string */ + int (*e_func)(); /* command */ + } + esctable_t; + +#define NORM 00 /* normal protection, execute anyone */ +#define EXP 01 /* experimental, mark it with a `*' on help */ +#define PRIV 02 /* priviledged, root execute only */ + +extern int vflag; /* verbose during reading of .tiprc file */ +extern value_t vtable[]; /* variable table */ + +#if !ACULOG +#define logent(a, b, c, d) +#define loginit() +#endif + +/* + * Definition of indices into variable table so + * value(DEFINE) turns into a static address. + */ + +/* +'a,.!awk '{ printf("\%s \%s \%d\n", $1, $2, NR - 1); }' +*/ + +#define BEAUTIFY 0 +#define BAUDRATE 1 +#define DIALTIMEOUT 2 +#define EOFREAD 3 +#define EOFWRITE 4 +#define EOL 5 +#define ESCAPE 6 +#define EXCEPTIONS 7 +#define FORCE 8 +#define FRAMESIZE 9 +#define HOST 10 +#define LOG 11 +#define LOGIN 12 +#define LOGOUT 13 +#define PHONES 14 +#define PROMPT 15 +#define RAISE 16 +#define RAISECHAR 17 +#define RECORD 18 +#define REMOTE 19 +#define SCRIPT 20 +#define TABEXPAND 21 +#define VERBOSE 22 +#define SHELL 23 +#define HOME 24 +#define ECHOCHECK 25 +#define DISCONNECT 26 +#define TAND 27 +#define LDELAY 28 +#define CDELAY 29 +#define ETIMEOUT 30 +#define RAWFTP 31 +#define HALFDUPLEX 32 +#define LECHO 33 +#define PARITY 34 +#define NOVAL ((value_t *)NULL) +#define NOACU ((acu_t *)NULL) +#define NOSTR ((char *)NULL) +#define NOFILE ((FILE *)NULL) +#define NOPWD ((struct passwd *)0) + +#if HAVE_TERMIOS +struct termios otermios; +struct termios ctermios; +#else /* HAVE_TERMIOS */ +struct sgttyb arg; /* current mode of local terminal */ +struct sgttyb defarg; /* initial mode of local terminal */ +struct tchars tchars; /* current state of terminal */ +struct tchars defchars; /* initial state of terminal */ +struct ltchars ltchars; /* current local characters of terminal */ +struct ltchars deflchars; /* initial local characters of terminal */ +#endif /* HAVE_TERMIOS */ + +FILE *fscript; /* FILE for scripting */ + +int fildes[2]; /* file transfer synchronization channel */ +int repdes[2]; /* read process sychronization channel */ +int FD; /* open file descriptor to remote host */ +int AC; /* open file descriptor to dialer (v831 only) */ +int vflag; /* print .tiprc initialization sequence */ +int sfd; /* for ~< operation */ +int pid; /* pid of tipout */ +uid_t uid, euid; /* real and effective user id's */ +gid_t gid, egid; /* real and effective group id's */ +int stop; /* stop transfer session flag */ +int quit; /* same; but on other end */ +int intflag; /* recognized interrupt */ +int stoprompt; /* for interrupting a prompt session */ +int timedout; /* ~> transfer timedout */ +int cumode; /* simulating the "cu" program */ + +char fname[80]; /* file name buffer for ~< */ +char copyname[80]; /* file name buffer for ~> */ +char ccc; /* synchronization character */ +char ch; /* for tipout */ +char *uucplock; /* name of lock file for uucp's */ + +int odisc; /* initial tty line discipline */ +extern int disc; /* current tty discpline */ + +extern char *ctrl(); +extern char *vinterp(); +extern char *connect(); + +int tipabort __P((char *)); + +#define TL_VERBOSE 0x00000001 +#define TL_SIGNAL_TIPOUT 0x00000002 + +int tiplink (char *cmd, unsigned int flags); +void raw (); + +/* end of tip.h */ diff --git a/usr.bin/tip/tip/tipout.c b/usr.bin/tip/tip/tipout.c new file mode 100644 index 0000000..246cfb7 --- /dev/null +++ b/usr.bin/tip/tip/tipout.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)tipout.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "tip.h" +/* + * tip + * + * lower fork of tip -- handles passive side + * reading from the remote host + */ + +static jmp_buf sigbuf; + +/* + * TIPOUT wait state routine -- + * sent by TIPIN when it wants to posses the remote host + */ +void +intIOT() +{ + + write(repdes[1],&ccc,1); + read(fildes[0], &ccc,1); + longjmp(sigbuf, 1); +} + +/* + * Scripting command interpreter -- + * accepts script file name over the pipe and acts accordingly + */ +void +intEMT() +{ + char c, line[256]; + register char *pline = line; + char reply; + + read(fildes[0], &c, 1); + while (c != '\n') { + *pline++ = c; + read(fildes[0], &c, 1); + } + *pline = '\0'; + if (boolean(value(SCRIPT)) && fscript != NULL) + fclose(fscript); + if (pline == line) { + boolean(value(SCRIPT)) = FALSE; + reply = 'y'; + } else { + if ((fscript = fopen(line, "a")) == NULL) + reply = 'n'; + else { + reply = 'y'; + boolean(value(SCRIPT)) = TRUE; + } + } + write(repdes[1], &reply, 1); + longjmp(sigbuf, 1); +} + +void +intTERM() +{ + + if (boolean(value(SCRIPT)) && fscript != NULL) + fclose(fscript); + exit(0); +} + +void +intSYS() +{ + + boolean(value(BEAUTIFY)) = !boolean(value(BEAUTIFY)); + longjmp(sigbuf, 1); +} + +/* + * ****TIPOUT TIPOUT**** + */ +tipout() +{ + char buf[BUFSIZ]; + register char *cp; + register int cnt; + extern int errno; + int omask; + + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGEMT, intEMT); /* attention from TIPIN */ + signal(SIGTERM, intTERM); /* time to go signal */ + signal(SIGIOT, intIOT); /* scripting going on signal */ + signal(SIGHUP, intTERM); /* for dial-ups */ + signal(SIGSYS, intSYS); /* beautify toggle */ + (void) setjmp(sigbuf); + for (omask = 0;; sigsetmask(omask)) { + cnt = read(FD, buf, BUFSIZ); + if (cnt <= 0) { + /* lost carrier */ + if (cnt < 0 && errno == EIO) { + sigblock(sigmask(SIGTERM)); + intTERM(); + /*NOTREACHED*/ + } else if (cnt == 0 && errno == ENOENT) { + kill(getppid(),SIGUSR1); + sigblock(sigmask(SIGTERM)); + intTERM(); + /*NOTREACHED*/ + } else { + printf("%d %d\r",cnt,errno); + fflush(stdout); + } + continue; + } +#define ALLSIGS sigmask(SIGEMT)|sigmask(SIGTERM)|sigmask(SIGIOT)|sigmask(SIGSYS) + omask = sigblock(ALLSIGS); + for (cp = buf; cp < buf + cnt; cp++) + *cp &= 0177; + write(1, buf, cnt); + if (boolean(value(SCRIPT)) && fscript != NULL) { + if (!boolean(value(BEAUTIFY))) { + fwrite(buf, 1, cnt, fscript); + continue; + } + for (cp = buf; cp < buf + cnt; cp++) + if ((*cp >= ' ' && *cp <= '~') || + any(*cp, value(EXCEPTIONS))) + putc(*cp, fscript); + } + } +} diff --git a/usr.bin/tip/tip/uucplock.c b/usr.bin/tip/tip/uucplock.c new file mode 100644 index 0000000..235f516 --- /dev/null +++ b/usr.bin/tip/tip/uucplock.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)uucplock.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/file.h> +#include <sys/dir.h> +#include <errno.h> + +#include "tipconf.h" +#include "pathnames.h" + +/* Forward declarations */ +static int put_pid (int fd, int pid); +static int get_pid (int fd); + +/* + * uucp style locking routines + * return: 0 - success + * -1 - failure + */ + +uu_lock (char *ttyname) +{ + int fd, pid; + char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN]; + off_t lseek(); + + (void)sprintf(tbuf, _PATH_LOCKDIRNAME, ttyname); + fd = open(tbuf, O_RDWR|O_CREAT|O_EXCL, 0660); + if (fd < 0) { + /* + * file is already locked + * check to see if the process holding the lock still exists + */ + fd = open(tbuf, O_RDWR, 0); + if (fd < 0) { + perror("lock open"); + return(-1); + } + if (get_pid (fd) == -1) { + (void)close(fd); + perror("lock read"); + return(-1); + } + + if (kill(pid, 0) == 0 || errno != ESRCH) { + (void)close(fd); /* process is still running */ + return(-1); + } + /* + * The process that locked the file isn't running, so + * we'll lock it ourselves + */ + if (lseek(fd, 0L, L_SET) < 0) { + (void)close(fd); + perror("lock lseek"); + return(-1); + } + /* fall out and finish the locking process */ + } + pid = getpid(); + if (!put_pid (fd, pid)) { + (void)close(fd); + (void)unlink(tbuf); + perror("lock write"); + return(-1); + } + (void)close(fd); + return(0); +} + +uu_unlock (char *ttyname) +{ + char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN]; + + (void)sprintf(tbuf, _PATH_LOCKDIRNAME, ttyname); + return(unlink(tbuf)); +} + +static int put_pid (int fd, int pid) +{ +#if HAVE_V2_LOCKFILES + return write (fd, (char *)&pid, sizeof (pid)) == sizeof (pid); +#else + char buf [32]; + int len; + len = sprintf (buf, "%10ld\n", (long) pid); + return write (fd, buf, len) == len; +#endif +} + +static int get_pid (int fd) +{ + int bytes_read, pid; +#if HAVE_V2_LOCKFILES + bytes_read = read (fd, &pid, sizeof (pid)); + if (bytes_read != sizeof (pid)) + pid = -1; +#else + char buf [32]; + bytes_read = read (fd, buf, sizeof (buf) - 1); + if (bytes_read > 0) { + buf [bytes_read] = '\0'; + pid = strtol (buf, (char **) NULL, 10); + } + else + pid = -1; +#endif + return pid; +} + +/* end of uucplock.c */ diff --git a/usr.bin/tip/tip/value.c b/usr.bin/tip/tip/value.c new file mode 100644 index 0000000..ce29a21 --- /dev/null +++ b/usr.bin/tip/tip/value.c @@ -0,0 +1,353 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)value.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "tip.h" + +#define MIDDLE 35 + +static value_t *vlookup(); +static int col = 0; + +/* + * Variable manipulation + */ +vinit() +{ + register value_t *p; + register char *cp; + FILE *f; + char file[256]; + + for (p = vtable; p->v_name != NULL; p++) { + if (p->v_type&ENVIRON) + if (cp = getenv(p->v_name)) + p->v_value = cp; + if (p->v_type&IREMOTE) + number(p->v_value) = *address(p->v_value); + } + /* + * Read the .tiprc file in the HOME directory + * for sets + */ + strcpy(file, value(HOME)); + strcat(file, "/.tiprc"); + if ((f = fopen(file, "r")) != NULL) { + register char *tp; + + while (fgets(file, sizeof(file)-1, f) != NULL) { + if (vflag) + printf("set %s", file); + if (tp = rindex(file, '\n')) + *tp = '\0'; + vlex(file); + } + fclose(f); + } + /* + * To allow definition of exception prior to fork + */ + vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC); +} + +static int vaccess(); + +/*VARARGS1*/ +vassign(p, v) + register value_t *p; + char *v; +{ + + if (!vaccess(p->v_access, WRITE)) { + printf("access denied\r\n"); + return; + } + switch (p->v_type&TMASK) { + + case STRING: + if (p->v_value && equal(p->v_value, v)) + return; + if (!(p->v_type&(ENVIRON|INIT))) + free(p->v_value); + if ((p->v_value = malloc(size(v)+1)) == NOSTR) { + printf("out of core\r\n"); + return; + } + p->v_type &= ~(ENVIRON|INIT); + strcpy(p->v_value, v); + break; + + case NUMBER: + if (number(p->v_value) == number(v)) + return; + number(p->v_value) = number(v); + break; + + case BOOL: + if (boolean(p->v_value) == (*v != '!')) + return; + boolean(p->v_value) = (*v != '!'); + break; + + case CHAR: + if (character(p->v_value) == *v) + return; + character(p->v_value) = *v; + } + p->v_access |= CHANGED; +} + +static void vprint(); + +vlex(s) + register char *s; +{ + register value_t *p; + static void vtoken(); + + if (equal(s, "all")) { + for (p = vtable; p->v_name; p++) + if (vaccess(p->v_access, READ)) + vprint(p); + } else { + register char *cp; + + do { + if (cp = vinterp(s, ' ')) + cp++; + vtoken(s); + s = cp; + } while (s); + } + if (col > 0) { + printf("\r\n"); + col = 0; + } +} + +static void +vtoken(s) + register char *s; +{ + register value_t *p; + register char *cp; + char *expand(); + + if (cp = index(s, '=')) { + *cp = '\0'; + if (p = vlookup(s)) { + cp++; + if (p->v_type&NUMBER) + vassign(p, atoi(cp)); + else { + if (strcmp(s, "record") == 0) + cp = expand(cp); + vassign(p, cp); + } + return; + } + } else if (cp = index(s, '?')) { + *cp = '\0'; + if ((p = vlookup(s)) && vaccess(p->v_access, READ)) { + vprint(p); + return; + } + } else { + if (*s != '!') + p = vlookup(s); + else + p = vlookup(s+1); + if (p != NOVAL) { + vassign(p, s); + return; + } + } + printf("%s: unknown variable\r\n", s); +} + +static void +vprint(p) + register value_t *p; +{ + register char *cp; + extern char *interp(), *ctrl(); + + if (col > 0 && col < MIDDLE) + while (col++ < MIDDLE) + putchar(' '); + col += size(p->v_name); + switch (p->v_type&TMASK) { + + case BOOL: + if (boolean(p->v_value) == FALSE) { + col++; + putchar('!'); + } + printf("%s", p->v_name); + break; + + case STRING: + printf("%s=", p->v_name); + col++; + if (p->v_value) { + cp = interp(p->v_value, NULL); + col += size(cp); + printf("%s", cp); + } + break; + + case NUMBER: + col += 6; + printf("%s=%-5d", p->v_name, number(p->v_value)); + break; + + case CHAR: + printf("%s=", p->v_name); + col++; + if (p->v_value) { + cp = ctrl(character(p->v_value)); + col += size(cp); + printf("%s", cp); + } + break; + } + if (col >= MIDDLE) { + col = 0; + printf("\r\n"); + return; + } +} + + +static int +vaccess(mode, rw) + register unsigned mode, rw; +{ + if (mode & (rw<<PUBLIC)) + return (1); + if (mode & (rw<<PRIVATE)) + return (1); + return ((mode & (rw<<ROOT)) && getuid() == 0); +} + +static value_t * +vlookup(s) + register char *s; +{ + register value_t *p; + + for (p = vtable; p->v_name; p++) + if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s))) + return (p); + return (NULL); +} + +char * +vinterp(s, stop) + register char *s; + char stop; +{ + register char *p = s, c; + int num; + + while ((c = *s++) && c != stop) + switch (c) { + + case '^': + if (*s) + *p++ = *s++ - 0100; + else + *p++ = c; + break; + + case '\\': + num = 0; + c = *s++; + if (c >= '0' && c <= '7') + num = (num<<3)+(c-'0'); + else { + register char *q = "n\nr\rt\tb\bf\f"; + + for (; *q; q++) + if (c == *q++) { + *p++ = *q; + goto cont; + } + *p++ = c; + cont: + break; + } + if ((c = *s++) >= '0' && c <= '7') { + num = (num<<3)+(c-'0'); + if ((c = *s++) >= '0' && c <= '7') + num = (num<<3)+(c-'0'); + else + s--; + } else + s--; + *p++ = num; + break; + + default: + *p++ = c; + } + *p = '\0'; + return (c == stop ? s-1 : NULL); +} + +/* + * assign variable s with value v (for NUMBER or STRING or CHAR types) + */ + +vstring(s,v) + register char *s; + register char *v; +{ + register value_t *p; + char *expand(); + + p = vlookup(s); + if (p == 0) + return (1); + if (p->v_type&NUMBER) + vassign(p, atoi(v)); + else { + if (strcmp(s, "record") == 0) + v = expand(v); + vassign(p, v); + } + return (0); +} diff --git a/usr.bin/tip/tip/vars.c b/usr.bin/tip/tip/vars.c new file mode 100644 index 0000000..5fad05a --- /dev/null +++ b/usr.bin/tip/tip/vars.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)vars.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "tipconf.h" +#include "tip.h" +#include "pathnames.h" + +/* + * Definition of variables + */ +value_t vtable[] = { + { "beautify", BOOL, (READ|WRITE)<<PUBLIC, + "be", (char *)TRUE }, + { "baudrate", NUMBER|IREMOTE|INIT, (READ<<PUBLIC)|(WRITE<<ROOT), + "ba", (char *)&BR }, + { "dialtimeout",NUMBER, (READ<<PUBLIC)|(WRITE<<ROOT), + "dial", (char *)60 }, + { "eofread", STRING|IREMOTE|INIT, (READ|WRITE)<<PUBLIC, + "eofr", (char *)&IE }, + { "eofwrite", STRING|IREMOTE|INIT, (READ|WRITE)<<PUBLIC, + "eofw", (char *)&OE }, + { "eol", STRING|IREMOTE|INIT, (READ|WRITE)<<PUBLIC, + NOSTR, (char *)&EL }, + { "escape", CHAR, (READ|WRITE)<<PUBLIC, + "es", (char *)'~' }, + { "exceptions", STRING|INIT|IREMOTE, (READ|WRITE)<<PUBLIC, + "ex", (char *)&EX }, + { "force", CHAR, (READ|WRITE)<<PUBLIC, + "fo", (char *)CTRL('p') }, + { "framesize", NUMBER|IREMOTE|INIT, (READ|WRITE)<<PUBLIC, + "fr", (char *)&FS }, + { "host", STRING|IREMOTE|INIT, READ<<PUBLIC, + "ho", (char *)&HO }, + { "log", STRING|INIT, (READ|WRITE)<<ROOT, + NOSTR, _PATH_ACULOG }, + { "login", STRING|IREMOTE|INIT, (READ|WRITE)<<PUBLIC, + "li", (char *)&LI }, + { "logout", STRING|IREMOTE|INIT, (READ|WRITE)<<PUBLIC, + "lo", (char *)&LO }, + { "phones", STRING|INIT|IREMOTE, READ<<PUBLIC, + NOSTR, (char *)&PH }, + { "prompt", CHAR, (READ|WRITE)<<PUBLIC, + "pr", (char *)'\n' }, + { "raise", BOOL, (READ|WRITE)<<PUBLIC, + "ra", (char *)FALSE }, + { "raisechar", CHAR, (READ|WRITE)<<PUBLIC, + "rc", (char *)CTRL('a') }, + { "record", STRING|INIT|IREMOTE, (READ|WRITE)<<PUBLIC, + "rec", (char *)&RE }, + { "remote", STRING|INIT|IREMOTE, READ<<PUBLIC, + NOSTR, (char *)&RM }, + { "script", BOOL, (READ|WRITE)<<PUBLIC, + "sc", (char *)FALSE }, + { "tabexpand", BOOL, (READ|WRITE)<<PUBLIC, + "tab", (char *)FALSE }, + { "verbose", BOOL, (READ|WRITE)<<PUBLIC, + "verb", (char *)TRUE }, + { "SHELL", STRING|ENVIRON|INIT, (READ|WRITE)<<PUBLIC, + NULL, _PATH_BSHELL }, + { "HOME", STRING|ENVIRON, (READ|WRITE)<<PUBLIC, + NOSTR, NOSTR }, + { "echocheck", BOOL, (READ|WRITE)<<PUBLIC, + "ec", (char *)FALSE }, + { "disconnect", STRING|IREMOTE|INIT, (READ|WRITE)<<PUBLIC, + "di", (char *)&DI }, + { "tandem", BOOL, (READ|WRITE)<<PUBLIC, + "ta", (char *)TRUE }, + { "linedelay", NUMBER|IREMOTE|INIT, (READ|WRITE)<<PUBLIC, + "ldelay", (char *)&DL }, + { "chardelay", NUMBER|IREMOTE|INIT, (READ|WRITE)<<PUBLIC, + "cdelay", (char *)&CL }, + { "etimeout", NUMBER|IREMOTE|INIT, (READ|WRITE)<<PUBLIC, + "et", (char *)&ET }, + { "rawftp", BOOL, (READ|WRITE)<<PUBLIC, + "raw", (char *)FALSE }, + { "halfduplex", BOOL, (READ|WRITE)<<PUBLIC, + "hdx", (char *)FALSE }, + { "localecho", BOOL, (READ|WRITE)<<PUBLIC, + "le", (char *)FALSE }, + { "parity", STRING|INIT|IREMOTE, (READ|WRITE)<<PUBLIC, + "par", (char *)&PA }, + { NOSTR, NULL, NULL, NOSTR, NOSTR } +}; |