aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Murray <markm@FreeBSD.org>2001-12-20 13:06:50 +0000
committerMark Murray <markm@FreeBSD.org>2001-12-20 13:06:50 +0000
commit0f3bdf5df978c1d74d4b5e0429ced9613debcc3c (patch)
tree099a823df2c50d4ed34ad966e48b0dc7deeff464
parentd1bbdb91ade866e9ff4ab65e0012fffb0fcd7913 (diff)
downloadsrc-0f3bdf5df978c1d74d4b5e0429ced9613debcc3c.tar.gz
src-0f3bdf5df978c1d74d4b5e0429ced9613debcc3c.zip
Import of OpenBSD's tip (which was the tip code of a month ago, modulo
OpenBSD commits).
Notes
Notes: svn path=/cvs2svn/branches/bsd/; revision=88273
-rw-r--r--usr.bin/tip/libacu/biz22.c195
-rw-r--r--usr.bin/tip/libacu/biz31.c254
-rw-r--r--usr.bin/tip/libacu/courier.c354
-rw-r--r--usr.bin/tip/libacu/df.c145
-rw-r--r--usr.bin/tip/libacu/dn11.c152
-rw-r--r--usr.bin/tip/libacu/hayes.c321
-rw-r--r--usr.bin/tip/libacu/t3000.c370
-rw-r--r--usr.bin/tip/libacu/v3451.c220
-rw-r--r--usr.bin/tip/libacu/v831.c268
-rw-r--r--usr.bin/tip/libacu/ventel.c266
-rw-r--r--usr.bin/tip/tip/Makefile49
-rw-r--r--usr.bin/tip/tip/acu.c198
-rw-r--r--usr.bin/tip/tip/acutab.c103
-rw-r--r--usr.bin/tip/tip/cmds.c952
-rw-r--r--usr.bin/tip/tip/cmdtab.c71
-rw-r--r--usr.bin/tip/tip/cu.c175
-rw-r--r--usr.bin/tip/tip/hunt.c110
-rw-r--r--usr.bin/tip/tip/log.c94
-rw-r--r--usr.bin/tip/tip/partab.c64
-rw-r--r--usr.bin/tip/tip/pathnames.h44
-rw-r--r--usr.bin/tip/tip/remote.c241
-rw-r--r--usr.bin/tip/tip/tip.1580
-rw-r--r--usr.bin/tip/tip/tip.c629
-rw-r--r--usr.bin/tip/tip/tip.h312
-rw-r--r--usr.bin/tip/tip/tipout.c172
-rw-r--r--usr.bin/tip/tip/uucplock.c132
-rw-r--r--usr.bin/tip/tip/value.c365
-rw-r--r--usr.bin/tip/tip/vars.c118
28 files changed, 6954 insertions, 0 deletions
diff --git a/usr.bin/tip/libacu/biz22.c b/usr.bin/tip/libacu/biz22.c
new file mode 100644
index 000000000000..cd5ca4acfcc8
--- /dev/null
+++ b/usr.bin/tip/libacu/biz22.c
@@ -0,0 +1,195 @@
+/* $OpenBSD: biz22.c,v 1.7 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: biz22.c,v 1.6 1997/02/11 09:24:11 mrg Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)biz22.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: biz22.c,v 1.7 2001/10/24 18:38:58 millert Exp $";
+#endif /* not lint */
+
+#include "tip.h"
+
+#define DISCONNECT_CMD "\20\04" /* disconnection string */
+
+static void sigALRM();
+static int timeout = 0;
+static jmp_buf timeoutbuf;
+
+static int cmd(), detect();
+void biz22_disconnect();
+
+/*
+ * 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;
+{
+ int connected = 0;
+ char cbuf[40];
+
+ 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);
+ }
+ (void)strcpy(cbuf, "\02.\r");
+ cbuf[1] = *mod;
+ if (cmd(cbuf)) {
+ printf("can't set dialing mode...");
+ return (0);
+ }
+ (void)snprintf(cbuf, sizeof(cbuf), "\02D%s\r", num);
+ 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");
+#ifdef ACULOG
+ if (timeout) {
+ char line[80];
+
+ (void)sprintf(line, "%ld second dial timeout",
+ number(value(DIALTIMEOUT)));
+ logent(value(HOST), num, "biz1022", line);
+ }
+#endif
+ if (timeout)
+ biz22_disconnect(); /* insurance */
+ return (connected);
+}
+
+int
+biz22w_dialer(num, acu)
+ char *num, *acu;
+{
+
+ return (biz_dialer(num, "W"));
+}
+
+int
+biz22f_dialer(num, acu)
+ char *num, *acu;
+{
+
+ return (biz_dialer(num, "V"));
+}
+
+void
+biz22_disconnect()
+{
+ write(FD, DISCONNECT_CMD, 4);
+ sleep(2);
+ tcflush(FD, TCIOFLUSH);
+}
+
+void
+biz22_abort()
+{
+
+ write(FD, "\02", 1);
+}
+
+static void
+sigALRM()
+{
+
+ timeout = 1;
+ longjmp(timeoutbuf, 1);
+}
+
+static int
+cmd(s)
+ 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)
+ 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 000000000000..5522d652aed0
--- /dev/null
+++ b/usr.bin/tip/libacu/biz31.c
@@ -0,0 +1,254 @@
+/* $OpenBSD: biz31.c,v 1.6 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: biz31.c,v 1.5 1997/02/11 09:24:14 mrg Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)biz31.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: biz31.c,v 1.6 2001/10/24 18:38:58 millert Exp $";
+#endif /* not lint */
+
+#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;
+{
+ 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(" ");
+#ifdef ACULOG
+ if (timeout) {
+ char line[80];
+
+ (void)sprintf(line, "%ld 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);
+ tcflush(FD, TCIOFLUSH);
+}
+
+biz31_abort()
+{
+
+ write(FD, "\33", 1);
+}
+
+static int
+echo(s)
+ 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)
+ 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)
+ 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
+ int already = 0;
+ char buf[10];
+
+retry:
+ if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0 && chars(b) > 0)
+ tcflush(FD, TCIOFLUSH);
+ 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 000000000000..728ccc9f4377
--- /dev/null
+++ b/usr.bin/tip/libacu/courier.c
@@ -0,0 +1,354 @@
+/* $OpenBSD: courier.c,v 1.9 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: courier.c,v 1.7 1997/02/11 09:24:16 mrg Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)courier.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: courier.c,v 1.9 2001/10/24 18:38:58 millert Exp $";
+#endif /* not lint */
+
+/*
+ * Routines for calling up on a Courier modem.
+ * Derived from Hayes driver.
+ */
+#include "tip.h"
+#include <sys/ioctl.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_connect(), cour_swallow();
+void cour_nap();
+
+void cour_disconnect __P((void));
+
+int
+cour_dialer(num, acu)
+ char *num;
+ char *acu;
+{
+ char *cp;
+#ifdef ACULOG
+ char line[80];
+#endif
+ struct termios cntrl;
+
+ if (boolean(value(VERBOSE)))
+ printf("Using \"%s\"\n", acu);
+
+ tcgetattr(FD, &cntrl);
+ cntrl.c_cflag |= HUPCL;
+ tcsetattr(FD, TCSAFLUSH, &cntrl);
+ /*
+ * Get in synch.
+ */
+ if (!coursync()) {
+badsynch:
+ printf("can't synchronize with courier\n");
+#ifdef 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
+ tcflush(FD, TCIOFLUSH);
+ 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();
+#ifdef ACULOG
+ if (timeout) {
+ (void)sprintf(line, "%ld second dial timeout",
+ number(value(DIALTIMEOUT)));
+ logent(value(HOST), num, "cour", line);
+ }
+#endif
+ if (timeout)
+ cour_disconnect();
+ return (connected);
+}
+
+void
+cour_disconnect()
+{
+ /* first hang up the modem*/
+ ioctl(FD, TIOCCDTR, 0);
+ sleep(1);
+ ioctl(FD, TIOCSDTR, 0);
+ coursync(); /* reset */
+ close(FD);
+}
+
+void
+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)
+ 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) {
+ struct termios cntrl;
+
+ tcgetattr(FD, &cntrl);
+ cfsetospeed(&cntrl, bm->baud);
+ cfsetispeed(&cntrl, bm->baud);
+ tcsetattr(FD, TCSAFLUSH, &cntrl);
+ 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
+ }
+ printf("%s\r\n", dialer_buf);
+ 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) {
+ tcflush(FD, TCIOFLUSH);
+ 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 (strchr(buf, '0') ||
+ (strchr(buf, 'O') && strchr(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);
+}
+
+static void
+cour_write(fd, cp, n)
+int fd;
+char *cp;
+int n;
+{
+#ifdef notdef
+ if (boolean(value(VERBOSE)))
+ write(1, cp, n);
+#endif
+ tcdrain(fd);
+ cour_nap();
+ for ( ; n-- ; cp++) {
+ write(fd, cp, 1);
+ tcdrain(fd);
+ 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
+
+/* Give the courier 50 milliseconds between characters */
+void
+cour_nap()
+{
+ struct timespec ts;
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 50 * 1000000;
+
+ nanosleep(&ts, NULL);
+}
diff --git a/usr.bin/tip/libacu/df.c b/usr.bin/tip/libacu/df.c
new file mode 100644
index 000000000000..2fa0a0b320a1
--- /dev/null
+++ b/usr.bin/tip/libacu/df.c
@@ -0,0 +1,145 @@
+/* $OpenBSD: df.c,v 1.5 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: df.c,v 1.4 1995/10/29 00:49:51 pk Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)df.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: df.c,v 1.5 2001/10/24 18:38:58 millert Exp $";
+#endif /* not lint */
+
+/*
+ * Dial the DF02-AC or DF03-AC
+ */
+
+#include "tip.h"
+
+static jmp_buf Sjbuf;
+static void timeout();
+
+int
+df02_dialer(num, acu)
+ char *num, *acu;
+{
+
+ return (df_dialer(num, acu, 0));
+}
+
+int
+df03_dialer(num, acu)
+ char *num, *acu;
+{
+
+ return (df_dialer(num, acu, 1));
+}
+
+int
+df_dialer(num, acu, df03)
+ char *num, *acu;
+ int df03;
+{
+ int f = FD;
+ struct termios cntrl;
+ int speed = 0;
+ char c = '\0';
+
+ tcgetattr(f, &cntrl);
+ cntrl.c_cflag |= HUPCL;
+ tcsetattr(f, TCSANOW, &cntrl);
+ 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 */
+
+ tcgetattr(f, &cntrl);
+ speed = cfgetospeed(&cntrl);
+ if (speed != B1200) { /* must dial at 1200 baud */
+ cfsetospeed(&cntrl, B1200);
+ cfsetispeed(&cntrl, B1200);
+ tcsetattr(f, TCSAFLUSH, &cntrl);
+ 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);
+ tcflush(f, TCIOFLUSH);
+ write(f, "\001", 1);
+ sleep(1);
+ write(f, "\002", 1);
+ write(f, num, strlen(num));
+ read(f, &c, 1);
+#ifdef TIOCMSET
+ if (df03 && speed != B1200) {
+ cfsetospeed(&cntrl, speed);
+ cfsetispeed(&cntrl, speed);
+ tcsetattr(f, TCSAFLUSH, &cntrl);
+ }
+#endif
+ return (c == 'A');
+}
+
+void
+df_disconnect()
+{
+ write(FD, "\001", 1);
+ sleep(1);
+ tcflush(FD, TCIOFLUSH);
+}
+
+
+void
+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 000000000000..3f3461594296
--- /dev/null
+++ b/usr.bin/tip/libacu/dn11.c
@@ -0,0 +1,152 @@
+/* $OpenBSD: dn11.c,v 1.5 2001/11/19 19:02:16 mpech Exp $ */
+/* $NetBSD: dn11.c,v 1.4 1995/10/29 00:49:53 pk Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)dn11.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: dn11.c,v 1.5 2001/11/19 19:02:16 mpech Exp $";
+#endif /* not lint */
+
+/*
+ * Routines for dialing up on DN-11
+ */
+#include "tip.h"
+
+void dn_abort();
+void alarmtr();
+static jmp_buf jmpbuf;
+static int child = -1, dn;
+
+int
+dn_dialer(num, acu)
+ char *num, *acu;
+{
+ int lt, nw;
+ int timelim;
+ struct termios cntrl;
+
+ 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);
+ tcgetattr(dn, &cntrl);
+ cntrl.c_cflag |= HUPCL;
+ tcsetattr(dn, TCSANOW, &cntrl);
+ signal(SIGALRM, SIG_DFL);
+ while ((nw = wait(&lt)) != 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...
+ */
+void
+dn_disconnect()
+{
+
+ sleep(2);
+ if (FD > 0)
+ ioctl(FD, TIOCCDTR, 0);
+ close(FD);
+}
+
+void
+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 000000000000..19ee8f80abe6
--- /dev/null
+++ b/usr.bin/tip/libacu/hayes.c
@@ -0,0 +1,321 @@
+/* $OpenBSD: hayes.c,v 1.8 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: hayes.c,v 1.6 1997/02/11 09:24:17 mrg Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)hayes.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: hayes.c,v 1.8 2001/10/24 18:38:58 millert Exp $";
+#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 "tip.h"
+
+#include <termios.h>
+#include <sys/ioctl.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;
+
+int
+hay_dialer(num, acu)
+ char *num;
+ char *acu;
+{
+ char *cp;
+ int connected = 0;
+ char dummy;
+ struct termios cntrl;
+#ifdef 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);
+ tcgetattr(FD, &cntrl);
+ cntrl.c_cflag |= HUPCL;
+ tcsetattr(FD, TCSANOW, &cntrl);
+ tcflush(FD, TCIOFLUSH);
+ write(FD, "ATv0\r", 5); /* tell modem to use short status codes */
+ gobble("\r");
+ gobble("\r");
+ write(FD, "ATTD", 4); /* send dial command */
+ for (cp = num; *cp; cp++)
+ if (*cp == '=')
+ *cp = ',';
+ 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.. */
+ }
+ tcflush(FD, TCIOFLUSH);
+#ifdef ACULOG
+ if (timeout) {
+ (void)sprintf(line, "%ld second dial timeout",
+ number(value(DIALTIMEOUT)));
+ logent(value(HOST), num, "hayes", line);
+ }
+#endif
+ if (timeout)
+ hay_disconnect(); /* insurance */
+ return (connected);
+}
+
+
+void
+hay_disconnect()
+{
+ /* first hang up the modem*/
+#ifdef DEBUG
+ printf("\rdisconnecting modem....\n\r");
+#endif
+ ioctl(FD, TIOCCDTR, 0);
+ sleep(1);
+ ioctl(FD, TIOCSDTR, 0);
+ goodbye();
+}
+
+void
+hay_abort()
+{
+
+ 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)
+ 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);
+}
+
+static void
+error_rep(c)
+ 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.
+ */
+void
+goodbye()
+{
+ int len;
+ char c;
+
+ tcflush(FD, TCIOFLUSH);
+ if (hay_sync()) {
+ sleep(1);
+#ifndef DEBUG
+ tcflush(FD, TCIOFLUSH);
+#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
+ }
+ tcflush(FD, TCIOFLUSH);
+ ioctl(FD, TIOCCDTR, 0); /* clear DTR (insurance) */
+ close(FD);
+}
+
+#define MAXRETRY 5
+
+int
+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 (strchr(dumbuf, '0') ||
+ (strchr(dumbuf, 'O') && strchr(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 000000000000..1f0509104475
--- /dev/null
+++ b/usr.bin/tip/libacu/t3000.c
@@ -0,0 +1,370 @@
+/* $OpenBSD: t3000.c,v 1.9 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: t3000.c,v 1.5 1997/02/11 09:24:18 mrg Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)t3000.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: t3000.c,v 1.9 2001/10/24 18:38:58 millert Exp $";
+#endif /* not lint */
+
+/*
+ * Routines for calling up on a Telebit T3000 modem.
+ * Derived from Courier driver.
+ */
+#include "tip.h"
+
+#include <sys/ioctl.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_connect(), t3000_swallow();
+static void t3000_nap();
+
+int
+t3000_dialer(num, acu)
+ char *num;
+ char *acu;
+{
+ char *cp;
+ struct termios cntrl;
+#ifdef ACULOG
+ char line[80];
+#endif
+
+ if (boolean(value(VERBOSE)))
+ printf("Using \"%s\"\n", acu);
+
+ tcgetattr(FD, &cntrl);
+ cntrl.c_cflag |= HUPCL;
+ tcsetattr(FD, TCSANOW, &cntrl);
+ /*
+ * Get in synch.
+ */
+ if (!t3000_sync()) {
+badsynch:
+ printf("can't synchronize with t3000\n");
+#ifdef 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
+ tcflush(FD, TCIOFLUSH);
+ 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();
+#ifdef ACULOG
+ if (timeout) {
+ (void)sprintf(line, "%ld second dial timeout",
+ number(value(DIALTIMEOUT)));
+ logent(value(HOST), num, "t3000", line);
+ }
+#endif
+ if (timeout)
+ t3000_disconnect();
+ return (connected);
+}
+
+void
+t3000_disconnect()
+{
+ /* first hang up the modem*/
+ ioctl(FD, TIOCCDTR, 0);
+ sleep(1);
+ ioctl(FD, TIOCSDTR, 0);
+ t3000_sync(); /* reset */
+ close(FD);
+}
+
+void
+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)
+ 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) {
+ struct termios cntrl;
+
+ tcgetattr(FD, &cntrl);
+ cfsetospeed(&cntrl, bm->baud);
+ cfsetispeed(&cntrl, bm->baud);
+ tcsetattr(FD, TCSAFLUSH, &cntrl);
+ 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
+ }
+ printf("%s\r\n", dialer_buf);
+ 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) {
+ tcflush(FD, TCIOFLUSH);
+ 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 (strchr(buf, '0') ||
+ (strchr(buf, 'O') && strchr(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);
+}
+
+static int
+t3000_write(fd, cp, n)
+int fd;
+char *cp;
+int n;
+{
+#ifdef notdef
+ if (boolean(value(VERBOSE)))
+ write(1, cp, n);
+#endif
+ tcdrain(fd);
+ t3000_nap();
+ for ( ; n-- ; cp++) {
+ write(fd, cp, 1);
+ tcdrain(fd);
+ 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
+
+/* Give the t3000 50 milliseconds between characters */
+void
+t3000_nap()
+{
+ struct timespec ts;
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 50 * 1000000;
+
+ nanosleep(&ts, NULL);
+}
diff --git a/usr.bin/tip/libacu/v3451.c b/usr.bin/tip/libacu/v3451.c
new file mode 100644
index 000000000000..1440c551e0e0
--- /dev/null
+++ b/usr.bin/tip/libacu/v3451.c
@@ -0,0 +1,220 @@
+/* $OpenBSD: v3451.c,v 1.6 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: v3451.c,v 1.6 1997/02/11 09:24:20 mrg Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)v3451.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: v3451.c,v 1.6 2001/10/24 18:38:58 millert Exp $";
+#endif /* not lint */
+
+/*
+ * Routines for calling up on a Vadic 3451 Modem
+ */
+#include "tip.h"
+
+static jmp_buf Sjbuf;
+
+static int expect(), notin(), prefix();
+static void vawrite(), alarmtr();
+
+int
+v3451_dialer(num, acu)
+ char *num;
+ char *acu;
+{
+ sig_t func;
+ int ok;
+ int slow = number(value(BAUDRATE)) < 1200;
+ char phone[50];
+ struct termios cntrl;
+
+ /*
+ * 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");
+#ifdef ACULOG
+ logent(value(HOST), num, "vadic", "can't synch up");
+#endif
+ return (0);
+ }
+ tcgetattr(FD, &cntrl);
+ term.c_cflag |= HUPCL;
+ tcsetattr(FD, TCSANOW, &cntrl);
+ sleep(1);
+ vawrite("D\r", 2 + slow);
+ if (!expect("NUMBER?")) {
+ printf("Vadic will not accept dial command\n");
+#ifdef ACULOG
+ logent(value(HOST), num, "vadic", "will not accept dial");
+#endif
+ return (0);
+ }
+ (void)snprintf(phone, sizeof phone, "%s\r", num);
+ vawrite(phone, 1 + slow);
+ if (!expect(phone)) {
+ printf("Vadic will not accept phone number\n");
+#ifdef 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");
+#ifdef 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");
+#ifdef ACULOG
+ logent(value(HOST), num, "vadic", "call failed");
+#endif
+ return (0);
+ }
+ tcflush(FD, TCIOFLUSH);
+ return (1);
+}
+
+void
+v3451_disconnect()
+{
+
+ close(FD);
+}
+
+void
+v3451_abort()
+{
+
+ close(FD);
+}
+
+static void
+vawrite(cp, delay)
+ char *cp;
+ int delay;
+{
+
+ for (; *cp; sleep(delay), cp++)
+ write(FD, cp, 1);
+}
+
+static int
+expect(cp)
+ char *cp;
+{
+ char buf[300];
+ char *rp = buf;
+ int timeout = 30, online = 0;
+
+ 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;
+{
+
+ for (; *lg; lg++)
+ if (prefix(sh, lg))
+ return (0);
+ return (1);
+}
+
+static int
+prefix(s1, s2)
+ char *s1, *s2;
+{
+ 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 000000000000..005e5d931e52
--- /dev/null
+++ b/usr.bin/tip/libacu/v831.c
@@ -0,0 +1,268 @@
+/* $OpenBSD: v831.c,v 1.6 2001/11/19 19:02:16 mpech Exp $ */
+/* $NetBSD: v831.c,v 1.5 1996/12/29 10:42:01 cgd Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)v831.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: v831.c,v 1.6 2001/11/19 19:02:16 mpech Exp $";
+#endif /* not lint */
+
+/*
+ * Routines for dialing up on Vadic 831
+ */
+#include "tip.h"
+#include <termios.h>
+
+void v831_abort();
+static void alarmtr();
+static int dialit();
+static char *sanitize();
+
+static jmp_buf jmpbuf;
+static int child = -1;
+
+int
+v831_dialer(num, acu)
+ char *num, *acu;
+{
+ int status, pid;
+ int timelim;
+
+ 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);
+ 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...
+ */
+void
+v831_disconnect()
+{
+ struct termios cntrl;
+
+ sleep(2);
+#ifdef DEBUG
+ printf("[disconnect: FD=%d]\n", FD);
+#endif
+ if (FD > 0) {
+ ioctl(FD, TIOCCDTR, 0);
+ tcgetattr(FD, &cntrl);
+ cfsetospeed(&cntrl, 0);
+ cfsetispeed(&cntrl, 0);
+ tcsetattr(FD, TCSAFLUSH, &cntrl);
+ ioctl(FD, TIOCNXCL, NULL);
+ }
+ close(FD);
+}
+
+void
+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, NULL);
+ 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)
+ char *phonenum;
+ char *acu;
+{
+ struct vaconfig *vp;
+ struct termios cntrl;
+ char c;
+ int i;
+
+ 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');
+ }
+ tcgetattr(AC, &cntrl);
+ cfsetospeed(&cntrl, B2400);
+ cfsetispeed(&cntrl, B2400);
+ cntrl.c_cflag |= PARODD | PARENB;
+ cntrl.c_lflag &= ~(ISIG | ICANON);
+ tcsetattr(AC, TCSANOW, &cntrl);
+ tcflush(AC, TCIOFLUSH);
+ 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)
+ char *s;
+{
+ static char buf[128];
+ 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 000000000000..48035c177d2d
--- /dev/null
+++ b/usr.bin/tip/libacu/ventel.c
@@ -0,0 +1,266 @@
+/* $OpenBSD: ventel.c,v 1.7 2001/11/19 19:02:16 mpech Exp $ */
+/* $NetBSD: ventel.c,v 1.6 1997/02/11 09:24:21 mrg Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)ventel.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: ventel.c,v 1.7 2001/11/19 19:02:16 mpech Exp $";
+#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 "tip.h"
+#include <termios.h>
+#include <sys/ioctl.h>
+
+#define MAXRETRY 5
+
+static void sigALRM();
+static int timeout = 0;
+static jmp_buf timeoutbuf;
+
+static int gobble(), vensync();
+static void echo();
+
+/*
+ * 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) do { long N = (n); while (--N > 0); } while (0)
+#define busyloop(n) do { DELAY(n); } while (0)
+
+int
+ven_dialer(num, acu)
+ char *num;
+ char *acu;
+{
+ char *cp;
+ int connected = 0;
+ char *msg, line[80];
+ struct termios cntrl;
+
+ /*
+ * Get in synch with a couple of carriage returns
+ */
+ if (!vensync(FD)) {
+ printf("can't synchronize with ventel\n");
+#ifdef ACULOG
+ logent(value(HOST), num, "ventel", "can't synch up");
+#endif
+ return (0);
+ }
+ if (boolean(value(VERBOSE)))
+ printf("\ndialing...");
+ fflush(stdout);
+ tcgetattr(FD, &cntrl);
+ cntrl.c_cflag |= HUPCL;
+ tcsetattr(FD, TCSANOW, &cntrl);
+ 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);
+ tcflush(FD, TCIOFLUSH);
+#ifdef ACULOG
+ if (timeout) {
+ (void)sprintf(line, "%ld 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 = strchr(line, '\r');
+ if (cp)
+ *cp = '\0';
+ for (cp = line; cp = strchr(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);
+}
+
+void
+ven_disconnect()
+{
+
+ close(FD);
+}
+
+void
+ven_abort()
+{
+
+ write(FD, "\03", 1);
+ close(FD);
+}
+
+static void
+echo(s)
+ 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)
+ char match;
+ char response[];
+{
+ 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 000000000000..8d269d65cbd3
--- /dev/null
+++ b/usr.bin/tip/tip/Makefile
@@ -0,0 +1,49 @@
+# $OpenBSD: Makefile,v 1.9 2001/09/23 06:15:30 pvalchev Exp $
+#
+# 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}
+# Presently supports:
+# BIZCOMP
+# DEC DF02-AC, DF03-AC
+# DEC DN-11/Able Quadracall
+# HAYES and Hayes emulators
+# USR COURIER (2400 baud)
+# VENTEL 212+
+# VADIC 831 RS232 adaptor
+# VADIC 3451
+# TELEBIT T3000
+#
+# Configuration defines:
+# DF02, DF03, DN11 ACU's supported
+# BIZ1031, BIZ1022, VENTEL, V831, V3451, HAYES, COURIER, T3000
+# ACULOG turn on tip logging of ACU use
+# PRISTINE no phone #'s put in ACU log file
+# CONNECT worthless command
+# DEFBR default baud rate to make connection at
+# DEFFS default frame size for FTP buffering of
+# writes on local side
+# BUFSIZ buffer sizing from stdio, must be fed
+# explicitly to remcap.c if not 1024
+# CONNECT enable ~C command (connect pgm to remote)
+
+PROG= tip
+LINKS= ${BINDIR}/tip ${BINDIR}/cu
+MLINKS= tip.1 cu.1
+CFLAGS+=-I${.CURDIR} -ansi -pedantic \
+ -DDEFBR=9600 -DDEFFS=BUFSIZ -DACULOG -DPRISTINE -DCONNECT \
+ -DV831 -DVENTEL -DHAYES -DCOURIER -DT3000
+.PATH: ${.CURDIR}/aculib
+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 \
+ biz22.c courier.c df.c dn11.c hayes.c t3000.c v3451.c v831.c ventel.c
+
+# -- acutab is configuration dependent, and so depends on the Makefile
+# -- remote.o depends on the Makefile because of DEFBR and DEFFS
+# -- log.o depends on the Makefile because of ACULOG
+acutab.o log.o remote.o: Makefile
+
+.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 000000000000..91549e917417
--- /dev/null
+++ b/usr.bin/tip/tip/acu.c
@@ -0,0 +1,198 @@
+/* $OpenBSD: acu.c,v 1.7 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: acu.c,v 1.4 1996/12/29 10:34:03 cgd Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)acu.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: acu.c,v 1.7 2001/10/24 18:38:58 millert Exp $";
+#endif /* not lint */
+
+#include "tip.h"
+
+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()
+{
+ char *cp = PN;
+ char *phnum, string[256];
+ FILE *fd;
+ volatile int tried = 0;
+
+ if (!DU) { /* regular connect message */
+ if (CM != NOSTR)
+ parwrite(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) {
+ setboolean(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) {
+ phnum = cp;
+ cp = strpbrk(cp, ",");
+ if (*cp != '\0')
+ *cp++ = '\0';
+
+ if (strlen(phnum) == 0)
+ continue;
+
+ conflag = (*acu->acu_dialer)(phnum, CU);
+ if (conflag)
+ break;
+
+ 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) {
+ cp = &string[strcspn(string, " \t\n")];
+ if (*cp != '\0')
+ *cp++ = '\0';
+
+ if (strcmp(string, value(HOST)) != 0)
+ continue;
+
+ cp += strspn(cp, " \t\n");
+ phnum = cp;
+ *(cp + strcspn(cp, ",\n")) = '\0';
+
+ if (strlen(phnum) == 0)
+ continue;
+
+ conflag = (*acu->acu_dialer)(phnum, CU);
+ if (conflag)
+ break;
+
+ logent(value(HOST), phnum, acu->acu_name, "call failed");
+ tried++;
+ }
+ fclose(fd);
+ }
+ if (conflag) {
+ if (CM != NOSTR)
+ parwrite(FD, CM, size(CM));
+ logent(value(HOST), phnum, acu->acu_name, "call completed");
+ return (NOSTR);
+ } else if (!tried) {
+ logent(value(HOST), "", acu->acu_name, "missing phone number");
+ return ("missing phone number");
+ } else {
+ (*acu->acu_abort)();
+ return ("call failed");
+ }
+}
+
+void
+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)
+ char *s;
+{
+ acu_t *p;
+ extern acu_t acutable[];
+
+ for (p = acutable; p->acu_name != '\0'; p++)
+ if (!strcmp(s, p->acu_name))
+ return (p);
+ return (NOACU);
+}
diff --git a/usr.bin/tip/tip/acutab.c b/usr.bin/tip/tip/acutab.c
new file mode 100644
index 000000000000..193b8cc70cac
--- /dev/null
+++ b/usr.bin/tip/tip/acutab.c
@@ -0,0 +1,103 @@
+/* $OpenBSD: acutab.c,v 1.2 1996/06/26 05:40:41 deraadt Exp $ */
+/* $NetBSD: acutab.c,v 1.3 1994/12/08 09:30:41 jtc Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)acutab.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: acutab.c,v 1.2 1996/06/26 05:40:41 deraadt Exp $";
+#endif /* not lint */
+
+#include "tip.h"
+
+extern int df02_dialer(), df03_dialer(), df_disconnect(), df_abort(),
+ biz31f_dialer(), biz31_disconnect(), biz31_abort(),
+ biz31w_dialer(),
+ biz22f_dialer(), biz22_disconnect(), biz22_abort(),
+ biz22w_dialer(),
+ ven_dialer(), ven_disconnect(), ven_abort(),
+ hay_dialer(), hay_disconnect(), hay_abort(),
+ cour_dialer(), cour_disconnect(), cour_abort(),
+ t3000_dialer(), t3000_disconnect(), t3000_abort(),
+ v3451_dialer(), v3451_disconnect(), v3451_abort(),
+ v831_dialer(), v831_disconnect(), v831_abort(),
+ dn_dialer(), 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
+#ifdef VENTEL
+ "ventel",ven_dialer, ven_disconnect, ven_abort,
+#endif
+#ifdef HAYES
+ "hayes",hay_dialer, hay_disconnect, hay_abort,
+#endif
+#ifdef COURIER
+ "courier",cour_dialer, cour_disconnect, cour_abort,
+#endif
+#ifdef T3000
+ "t3000",t3000_dialer, t3000_disconnect, t3000_abort,
+#endif
+#ifdef V3451
+#ifndef V831
+ "vadic",v3451_dialer, v3451_disconnect, v3451_abort,
+#endif
+ "v3451",v3451_dialer, v3451_disconnect, v3451_abort,
+#endif
+#ifdef V831
+#ifndef 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 000000000000..07d7f51f08d0
--- /dev/null
+++ b/usr.bin/tip/tip/cmds.c
@@ -0,0 +1,952 @@
+/* $OpenBSD: cmds.c,v 1.13 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: cmds.c,v 1.7 1997/02/11 09:24:03 mrg Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)cmds.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: cmds.c,v 1.13 2001/10/24 18:38:58 millert Exp $";
+#endif /* not lint */
+
+#include "tip.h"
+#include "pathnames.h"
+
+#include <vis.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 */
+
+/*
+ * FTP - remote ==> local
+ * get a file from the remote host
+ */
+void
+getfl(c)
+ char c;
+{
+ char buf[256], *cp, *expand();
+
+ putchar(c);
+ /*
+ * get the UNIX receiving file's name
+ */
+ if (prompt("Local file name? ", copyname, sizeof(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, sizeof(buf))) {
+ unlink(copyname);
+ return;
+ }
+ transfer(buf, sfd, value(EOFREAD));
+}
+
+/*
+ * Cu-like take command
+ */
+void
+cu_take(cc)
+ char cc;
+{
+ int fd, argc;
+ char line[BUFSIZ], *expand(), *cp;
+
+ if (prompt("[take] ", copyname, sizeof(copyname)))
+ return;
+ if ((argc = args(copyname, argv, sizeof(argv)/sizeof(argv[0]))) < 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)snprintf(line, sizeof(line), "cat %s;echo \01", argv[0]);
+ transfer(line, fd, "\01");
+}
+
+static jmp_buf intbuf;
+
+/*
+ * Bulk transfer routine --
+ * used by getfl(), cu_take(), and pipefile()
+ */
+void
+transfer(buf, fd, eofchars)
+ char *buf, *eofchars;
+ int fd;
+{
+ int ct;
+ char c, buffer[BUFSIZ];
+ char *p = buffer;
+ int cnt, eof;
+ time_t start;
+ sig_t f;
+ char r;
+
+ parwrite(FD, buf, size(buf));
+ quit = 0;
+ kill(pid, SIGIOT);
+ read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */
+
+ /*
+ * finish command
+ */
+ r = '\r';
+ parwrite(FD, &r, 1);
+ do
+ read(FD, &c, 1);
+ while ((c&STRIP_PAR) != '\n');
+ tcsetattr(0, TCSAFLUSH, &defchars);
+
+ (void) setjmp(intbuf);
+ f = signal(SIGINT, intcopy);
+ start = time(0);
+ for (ct = 0; !quit;) {
+ eof = read(FD, &c, 1) <= 0;
+ c &= STRIP_PAR;
+ if (quit)
+ continue;
+ if (eof || any(c, eofchars))
+ break;
+ if (c == 0)
+ continue; /* ignore nulls */
+ if (c == '\r')
+ continue;
+ *p++ = c;
+
+ if (c == '\n' && boolean(value(VERBOSE)))
+ printf("\r%d", ++ct);
+ if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) {
+ if (write(fd, buffer, cnt) != cnt) {
+ printf("\r\nwrite error\r\n");
+ quit = 1;
+ }
+ p = buffer;
+ }
+ }
+ if ((cnt = (p-buffer)))
+ if (write(fd, buffer, cnt) != cnt)
+ printf("\r\nwrite error\r\n");
+
+ if (boolean(value(VERBOSE)))
+ prtime(" lines transferred in ", time(0)-start);
+ tcsetattr(0, TCSAFLUSH, &term);
+ write(fildes[1], (char *)&ccc, 1);
+ signal(SIGINT, f);
+ close(fd);
+}
+
+/*
+ * FTP - remote ==> local process
+ * send remote input to local process via pipe
+ */
+void
+pipefile()
+{
+ int cpid, pdes[2];
+ char buf[256];
+ int status, p;
+
+ if (prompt("Local command? ", buf, sizeof(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, sizeof(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 {
+ 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
+ */
+void
+sendfile(cc)
+ char cc;
+{
+ FILE *fd;
+ char *fnamex;
+ char *expand();
+
+ putchar(cc);
+ /*
+ * get file name
+ */
+ if (prompt("Local file name? ", fname, sizeof(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)))
+ tcdrain(FD);
+}
+
+/*
+ * Bulk transfer routine to remote host --
+ * used by sendfile() and cu_put()
+ */
+void
+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);
+ tcsetattr(0, TCSAFLUSH, &defchars);
+ 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 {
+ tcdrain(FD);
+ 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((long)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&STRIP_PAR) != character(value(PROMPT)));
+ alarm(0);
+ }
+ }
+out:
+ if (lastc != '\n' && !boolean(value(RAWFTP)))
+ send('\r');
+ if (eofchars) {
+ 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);
+ tcsetattr(0, TCSAFLUSH, &term);
+}
+
+/*
+ * Cu-like put command
+ */
+void
+cu_put(cc)
+ char cc;
+{
+ FILE *fd;
+ char line[BUFSIZ];
+ int argc;
+ char *expand();
+ char *copynamex;
+
+ if (prompt("[put] ", copyname, sizeof(copyname)))
+ return;
+ if ((argc = args(copyname, argv, sizeof(argv)/sizeof(argv[0]))) < 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)))
+ (void)snprintf(line, sizeof(line), "cat>%s\r", argv[1]);
+ else
+ (void)snprintf(line, sizeof(line),
+ "stty -echo;cat>%s;stty echo\r", argv[1]);
+ transmit(fd, "\04", line);
+}
+
+/*
+ * FTP - send single character
+ * wait for echo & handle timeout
+ */
+void
+send(c)
+ int c;
+{
+ char cc;
+ int retry = 0;
+
+ cc = c;
+ parwrite(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((long)value(ETIMEOUT));
+ read(FD, &cc, 1);
+ alarm(0);
+ if (timedout) {
+ printf("\r\ntimeout error (%s)\r\n", ctrl(c));
+ if (retry++ > 3)
+ return;
+ parwrite(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.
+ */
+void
+pipeout(c)
+{
+ char buf[256];
+ int cpid, status, p;
+ time_t start = time(NULL);
+
+ putchar(c);
+ if (prompt("Local command? ", buf, sizeof(buf)))
+ return;
+ kill(pid, SIGIOT); /* put TIPOUT into a wait state */
+ signal(SIGINT, SIG_IGN);
+ signal(SIGQUIT, SIG_IGN);
+ tcsetattr(0, TCSAFLUSH, &defchars);
+ read(repdes[0], (char *)&ccc, 1);
+ /*
+ * Set up file descriptors in the child and
+ * let it go...
+ */
+ if ((cpid = fork()) < 0)
+ printf("can't fork!\r\n");
+ else if (cpid) {
+ start = time(NULL);
+ while ((p = wait(&status)) > 0 && p != cpid)
+ ;
+ } else {
+ 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);
+ tcsetattr(0, TCSAFLUSH, &term);
+ signal(SIGINT, SIG_DFL);
+ signal(SIGQUIT, SIG_DFL);
+}
+
+#ifdef CONNECT
+/*
+ * Fork a program with:
+ * 0 <-> remote tty in
+ * 1 <-> remote tty out
+ * 2 <-> local tty out
+ */
+void
+consh(c)
+{
+ char buf[256];
+ int cpid, status, p;
+ time_t start = time(NULL);
+
+ putchar(c);
+ if (prompt("Local command? ", buf, sizeof(buf)))
+ return;
+ kill(pid, SIGIOT); /* put TIPOUT into a wait state */
+ signal(SIGINT, SIG_IGN);
+ signal(SIGQUIT, SIG_IGN);
+ tcsetattr(0, TCSAFLUSH, &defchars);
+ read(repdes[0], (char *)&ccc, 1);
+ /*
+ * Set up file descriptors in the child and
+ * let it go...
+ */
+ if ((cpid = fork()) < 0)
+ printf("can't fork!\r\n");
+ else if (cpid) {
+ start = time(0);
+ while ((p = wait(&status)) > 0 && p != cpid)
+ ;
+ } else {
+ int i;
+
+ dup2(FD, 0);
+ dup2(3, 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);
+ tcsetattr(0, TCSAFLUSH, &term);
+ signal(SIGINT, SIG_DFL);
+ signal(SIGQUIT, SIG_DFL);
+}
+#endif
+
+/*
+ * Escape to local shell
+ */
+void
+shell()
+{
+ int shpid, status;
+ 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 = strrchr(value(SHELL), '/')) == NULL)
+ cp = value(SHELL);
+ else
+ cp++;
+ shell_uid();
+ execl(value(SHELL), cp, (char *)NULL);
+ printf("\r\ncan't execl!\r\n");
+ exit(1);
+ }
+}
+
+/*
+ * TIPIN portion of scripting
+ * initiate the conversation with TIPOUT
+ */
+void
+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
+ */
+void
+chdirectory()
+{
+ char dirname[PATH_MAX];
+ char *cp = dirname;
+
+ if (prompt("[cd] ", dirname, sizeof(dirname))) {
+ if (stoprompt)
+ return;
+ cp = value(HOME);
+ }
+ if (chdir(cp) < 0)
+ printf("%s: bad directory\r\n", cp);
+ printf("!\r\n");
+}
+
+void
+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);
+}
+
+void
+finish()
+{
+ char *dismsg;
+
+ if ((dismsg = value(DISCONNECT)) != NOSTR) {
+ write(FD, dismsg, strlen(dismsg));
+ sleep(5);
+ }
+ tipabort(NOSTR);
+}
+
+void
+intcopy()
+{
+ raw();
+ quit = 1;
+ longjmp(intbuf, 1);
+}
+
+void
+execute(s)
+ char *s;
+{
+ char *cp;
+
+ if ((cp = strrchr(value(SHELL), '/')) == NULL)
+ cp = value(SHELL);
+ else
+ cp++;
+ shell_uid();
+ execl(value(SHELL), cp, "-c", s, (char *)NULL);
+}
+
+int
+args(buf, a, num)
+ char *buf, *a[];
+ int num;
+{
+ char *p = buf, *start;
+ char **parg = a;
+ 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 && n < num);
+
+ return(n);
+}
+
+void
+prtime(s, a)
+ char *s;
+ time_t a;
+{
+ int 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");
+}
+
+void
+variable()
+{
+ char buf[256];
+
+ if (prompt("[set] ", buf, sizeof(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(NOSTR);
+ }
+}
+
+void
+listvariables()
+{
+ value_t *p;
+ char buf[BUFSIZ];
+
+ puts("v\r");
+ for (p = vtable; p->v_name; p++) {
+ fputs(p->v_name, stdout);
+ switch (p->v_type&TMASK) {
+ case STRING:
+ if (p->v_value) {
+ strnvis(buf, p->v_value, sizeof(buf),
+ VIS_WHITE|VIS_OCTAL);
+ printf(" %s", buf);
+ }
+ putchar('\r');
+ putchar('\n');
+ break;
+ case NUMBER:
+ printf(" %ld\r\n", number(p->v_value));
+ break;
+ case BOOL:
+ printf(" %s\r\n",
+ boolean(p->v_value) == '!' ? "false" : "true");
+ break;
+ case CHAR:
+ vis(buf, character(p->v_value), VIS_WHITE|VIS_OCTAL, 0);
+ printf(" %s\r\n", buf);
+ break;
+ }
+ }
+}
+
+/*
+ * Turn tandem mode on or off for remote tty.
+ */
+void
+tandem(option)
+ char *option;
+{
+ struct termios rmtty;
+
+ tcgetattr(FD, &rmtty);
+ if (strcmp(option, "on") == 0) {
+ rmtty.c_iflag |= IXOFF;
+ term.c_iflag |= IXOFF;
+ } else {
+ rmtty.c_iflag &= ~IXOFF;
+ term.c_iflag &= ~IXOFF;
+ }
+ tcsetattr(FD, TCSADRAIN, &rmtty);
+ tcsetattr(0, TCSADRAIN, &term);
+}
+
+/*
+ * Send a break.
+ */
+void
+genbrk()
+{
+
+ ioctl(FD, TIOCSBRK, NULL);
+ sleep(1);
+ ioctl(FD, TIOCCBRK, NULL);
+}
+
+/*
+ * Suspend tip
+ */
+void
+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];
+ int pid, l;
+ char *cp, *Shell;
+ int s, pivec[2];
+
+ if (!anyof(name, "~{[*?$`'\"\\"))
+ return(name);
+ /* sigint = signal(SIGINT, SIG_IGN); */
+ if (pipe(pivec) < 0) {
+ perror("pipe");
+ /* signal(SIGINT, sigint) */
+ return(name);
+ }
+ (void)snprintf(cmdbuf, sizeof(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, (char *)NULL);
+ _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?
+ */
+int
+anyof(s1, s2)
+ char *s1, *s2;
+{
+ 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 000000000000..7f77e2777749
--- /dev/null
+++ b/usr.bin/tip/tip/cmdtab.c
@@ -0,0 +1,71 @@
+/* $OpenBSD: cmdtab.c,v 1.3 2001/09/09 17:58:41 millert Exp $ */
+/* $NetBSD: cmdtab.c,v 1.3 1994/12/08 09:30:46 jtc Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)cmdtab.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: cmdtab.c,v 1.3 2001/09/09 17:58:41 millert Exp $";
+#endif /* not lint */
+
+#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(), listvariables();
+
+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 },
+#ifdef 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 },
+ { 'v', NORM, "list variables", listvariables },
+ { '?', 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 000000000000..8a44845b4269
--- /dev/null
+++ b/usr.bin/tip/tip/cu.c
@@ -0,0 +1,175 @@
+/* $OpenBSD: cu.c,v 1.10 2001/09/26 06:07:28 pvalchev Exp $ */
+/* $NetBSD: cu.c,v 1.5 1997/02/11 09:24:05 mrg Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)cu.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: cu.c,v 1.10 2001/09/26 06:07:28 pvalchev Exp $";
+#endif /* not lint */
+
+#include "tip.h"
+
+void cleanup();
+void cuusage();
+
+/*
+ * Botch the interface to look like cu's
+ */
+void
+cumain(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int ch, i;
+ long l;
+ char *cp;
+ static char sbuf[12];
+
+ if (argc < 2)
+ cuusage();
+ CU = DV = NOSTR;
+ BR = DEFBR;
+ while ((ch = getopt(argc, argv, "a:l:s:htoe0123456789")) != -1) {
+ switch(ch) {
+ case 'a':
+ CU = optarg;
+ break;
+ case 'l':
+ if (DV != NULL) {
+ fprintf(stderr,
+ "%s: cannot specificy multiple -l options\n",
+ __progname);
+ exit(3);
+ }
+ if (strchr(optarg, '/'))
+ DV = optarg;
+ else
+ asprintf(&DV, "/dev/%s", optarg);
+ break;
+ case 's':
+ l = strtol(optarg, &cp, 10);
+ if (*cp != '\0' || l < 0 || l >= INT_MAX ||
+ speed((int)l) == 0) {
+ fprintf(stderr, "%s: unsupported speed %s\n",
+ __progname, optarg);
+ exit(3);
+ }
+ BR = (int)l;
+ break;
+ case 'h':
+ setboolean(value(LECHO), TRUE);
+ HD = TRUE;
+ break;
+ case 't':
+ HW = 1, DU = -1;
+ break;
+ case 'o':
+ setparity("odd");
+ break;
+ case 'e':
+ setparity("even");
+ 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] = ch;
+ if (DV)
+ DV[strlen(DV)-1] = ch;
+ break;
+ default:
+ cuusage();
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ switch (argc) {
+ case 1:
+ PN = argv[0];
+ break;
+ case 0:
+ break;
+ default:
+ cuusage();
+ 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)snprintf(sbuf, sizeof(sbuf), "cu%ld", 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");
+ setboolean(value(VERBOSE), FALSE);
+ if (HW)
+ ttysetup(speed(BR));
+ if (connect()) {
+ printf("Connect failed\n");
+ daemon_uid();
+ (void)uu_unlock(uucplock);
+ exit(1);
+ }
+ if (!HW)
+ ttysetup(speed(BR));
+}
+
+void
+cuusage()
+{
+ fprintf(stderr, "usage: cu [-ehot] [-a acu] [-l line] [-s speed] [-#] "
+ "[phone-number]\n");
+ exit(8);
+}
diff --git a/usr.bin/tip/tip/hunt.c b/usr.bin/tip/tip/hunt.c
new file mode 100644
index 000000000000..60aaa2350957
--- /dev/null
+++ b/usr.bin/tip/tip/hunt.c
@@ -0,0 +1,110 @@
+/* $OpenBSD: hunt.c,v 1.8 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: hunt.c,v 1.6 1997/04/20 00:02:10 mellon Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)hunt.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: hunt.c,v 1.8 2001/10/24 18:38:58 millert Exp $";
+#endif /* not lint */
+
+#include "tip.h"
+
+extern char *getremote();
+
+static jmp_buf deadline;
+static int deadfl;
+
+void
+dead()
+{
+ deadfl = 1;
+ longjmp(deadline, 1);
+}
+
+long
+hunt(name)
+ char *name;
+{
+ char *cp;
+ sig_t f;
+
+ f = signal(SIGALRM, dead);
+ while ((cp = getremote(name))) {
+ deadfl = 0;
+ uucplock = strrchr(cp, '/');
+ if (uucplock == NULL)
+ uucplock = cp;
+ else
+ uucplock++;
+
+ 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 |
+ (boolean(value(DC)) ? O_NONBLOCK : 0)));
+ }
+ alarm(0);
+ if (FD < 0) {
+ perror(cp);
+ deadfl = 1;
+ }
+ if (!deadfl) {
+ struct termios cntrl;
+
+ tcgetattr(FD, &cntrl);
+ if (!boolean(value(DC)))
+ cntrl.c_cflag |= HUPCL;
+ tcsetattr(FD, TCSAFLUSH, &cntrl);
+ ioctl(FD, TIOCEXCL, 0);
+ signal(SIGALRM, SIG_DFL);
+ return ((long)cp);
+ }
+ (void)uu_unlock(uucplock);
+ }
+ signal(SIGALRM, f);
+ return (deadfl ? -1 : (long)cp);
+}
diff --git a/usr.bin/tip/tip/log.c b/usr.bin/tip/tip/log.c
new file mode 100644
index 000000000000..1a715c0d5f52
--- /dev/null
+++ b/usr.bin/tip/tip/log.c
@@ -0,0 +1,94 @@
+/* $OpenBSD: log.c,v 1.5 2001/09/09 19:30:49 millert Exp $ */
+/* $NetBSD: log.c,v 1.4 1994/12/24 17:56:28 cgd Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)log.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: log.c,v 1.5 2001/09/09 19:30:49 millert Exp $";
+#endif /* not lint */
+
+#include "tip.h"
+
+#ifdef ACULOG
+static FILE *flog = NULL;
+
+/*
+ * Log file maintenance routines
+ */
+void
+logent(group, num, acu, message)
+ char *group, *num, *acu, *message;
+{
+ char *user, *timestamp;
+ struct passwd *pwd;
+ time_t t;
+
+ if (flog == NULL)
+ return;
+ if (flock(fileno(flog), LOCK_EX) < 0) {
+ perror("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,
+#ifdef PRISTINE
+ "",
+#else
+ num,
+#endif
+ acu, message);
+ (void) fflush(flog);
+ (void) flock(fileno(flog), LOCK_UN);
+}
+
+void
+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 000000000000..b0e4dc2f732e
--- /dev/null
+++ b/usr.bin/tip/tip/partab.c
@@ -0,0 +1,64 @@
+/* $OpenBSD: partab.c,v 1.3 1997/04/02 01:47:02 millert Exp $ */
+/* $NetBSD: partab.c,v 1.4 1996/12/29 10:38:21 cgd Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)partab.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: partab.c,v 1.3 1997/04/02 01:47:02 millert Exp $";
+#endif /* not lint */
+
+/*
+ * Even parity table for 0-0177
+ */
+const unsigned 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 000000000000..cc7cbf4a7a2a
--- /dev/null
+++ b/usr.bin/tip/tip/pathnames.h
@@ -0,0 +1,44 @@
+/* $OpenBSD: pathnames.h,v 1.2 1996/06/26 05:40:45 deraadt Exp $ */
+/* $NetBSD: pathnames.h,v 1.3 1994/12/08 09:30:59 jtc Exp $ */
+
+/*
+ * 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>
+
+#define _PATH_ACULOG "/var/log/aculog"
+#define _PATH_LOCKDIRNAME "/var/spool/lock/LCK..%s"
+#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 000000000000..f2aaeb243523
--- /dev/null
+++ b/usr.bin/tip/tip/remote.c
@@ -0,0 +1,241 @@
+/* $OpenBSD: remote.c,v 1.10 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: remote.c,v 1.5 1997/04/20 00:02:45 mellon Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)remote.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: remote.c,v 1.10 2001/10/24 18:38:58 millert Exp $";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pathnames.h"
+#include "tip.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
+};
+
+static char *capstrings[] = {
+ "at", "dv", "cm", "cu", "el", "ie", "oe", "pn", "pr",
+ "di", "es", "ex", "fo", "rc", "re", "pa", 0
+};
+
+static char *db_array[3] = { _PATH_REMOTE, 0, 0 };
+
+#define cgetflag(f) (cgetcap(bp, f, ':') != NULL)
+
+static void
+getremcap(host)
+ char *host;
+{
+ 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, "%s: unknown host %s\n", __progname,
+ host);
+ break;
+ case -2:
+ fprintf(stderr,
+ "%s: can't open host description file\n",
+ __progname);
+ break;
+ case -3:
+ fprintf(stderr,
+ "%s: possible reference loop in host description file\n", __progname);
+ 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);
+ }
+ if (DU && AT == NOSTR) {
+ fprintf(stderr, "%s: missing acu type\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;
+ /*
+ * see if uppercase mode should be turned on initially
+ */
+ if (cgetflag("ra"))
+ setboolean(value(RAISE), 1);
+ if (cgetflag("ec"))
+ setboolean(value(ECHOCHECK), 1);
+ if (cgetflag("be"))
+ setboolean(value(BEAUTIFY), 1);
+ if (cgetflag("nb"))
+ setboolean(value(BEAUTIFY), 0);
+ if (cgetflag("sc"))
+ setboolean(value(SCRIPT), 1);
+ if (cgetflag("tb"))
+ setboolean(value(TABEXPAND), 1);
+ if (cgetflag("vb"))
+ setboolean(value(VERBOSE), 1);
+ if (cgetflag("nv"))
+ setboolean(value(VERBOSE), 0);
+ if (cgetflag("ta"))
+ setboolean(value(TAND), 1);
+ if (cgetflag("nt"))
+ setboolean(value(TAND), 0);
+ if (cgetflag("rw"))
+ setboolean(value(RAWFTP), 1);
+ if (cgetflag("hd"))
+ setboolean(value(HALFDUPLEX), 1);
+ if (cgetflag("dc"))
+ setboolean(value(DC), 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;
+{
+ char *cp;
+ static char *next;
+ static int lookedup = 0;
+
+ if (!lookedup) {
+ if (host == NOSTR && (host = getenv("HOST")) == NOSTR) {
+ fprintf(stderr, "%s: no host specified\n", __progname);
+ 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 = strchr(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 000000000000..805d77c4151c
--- /dev/null
+++ b/usr.bin/tip/tip/tip.1
@@ -0,0 +1,580 @@
+.\" $OpenBSD: tip.1,v 1.19 2001/09/23 06:15:30 pvalchev Exp $
+.\" $NetBSD: tip.1,v 1.7 1994/12/08 09:31:05 jtc Exp $
+.\"
+.\" 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 September 9, 2001
+.Dt TIP 1
+.Os
+.Sh NAME
+.Nm tip ,
+.Nm cu
+.Nd connect to a remote system
+.Sh SYNOPSIS
+.Nm tip
+.Op Fl nv
+.Op Fl Ar speed
+.Op Ar system\-name
+.Nm cu
+.Op Fl ehot
+.Op Fl a Ar acu
+.Op Fl l Ar line
+.Op Fl s Ar speed
+.Op Fl #
+.Op Ar phone\-number
+.Sh DESCRIPTION
+.Nm
+and
+.Nm 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
+.Nm cu
+interface is included for those people attached to the
+``call
+.Ux Ns ''
+command of
+.At v7 .
+This manual page
+describes only
+.Nm tip .
+.Pp
+The options are as follows:
+.Bl -tag -width 4n
+.It Fl a Ar acu
+Set the acu.
+.It Fl l Ar line
+For
+.Nm cu ,
+specify the line to use. Either of the forms like
+.Pa tty00
+or
+.Pa /dev/tty00
+are permitted.
+.It Fl n
+No escape (disable tilde).
+.It Fl s Ar speed
+For
+.Nm cu ,
+set the speed of the connection. Defaults to 9600.
+.It Fl v
+Set verbose mode.
+.El
+.Pp
+If
+.Ar speed
+is specified it will override any baudrate specified in the system
+description being used.
+.Pp
+If neither
+.Ar speed
+nor
+.Ar system-name
+are specified,
+.Ar system-name
+will be set to the value of the
+.Ev HOST
+environment variable.
+.Pp
+If
+.Ar speed
+is specified but
+.Ar system-name
+is not,
+.Ar system-name
+will be set to a value of 'tip' with
+.Ar speed
+appended.
+e.g.
+.Ic tip -1200
+will set
+.Ar system-name
+to 'tip1200'.
+.Pp
+Typed characters are normally transmitted directly to the remote
+machine (which does the echoing as well).
+A tilde
+.Pq Ql ~
+appearing as the first character of a line is an escape signal; the
+following are recognized:
+.Bl -tag -offset indent -width Fl
+.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
+.Nm tip Ns ).
+.It Ic \&~>
+Copy file from local to remote.
+.Nm
+prompts for the name of a local file to transmit.
+.It Ic \&~<
+Copy file from remote to local.
+.Nm
+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
+.Dq cat > 'to' ,
+while
+.Nm
+sends it the
+.Dq from
+file.
+If the
+.Dq to
+file isn't specified the
+.Dq from
+file name is used.
+this command is actually a
+.Ux
+specific version of the
+.Ic ~>
+command.
+.It Ic \&~t Ar from Op Ar to
+Take a file from a remote
+.Ux
+host.
+As in the put command the
+.Dq to
+file defaults to the
+.Dq from
+file name if it isn't specified.
+The remote host executes the command string
+.Dq 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:
+.Bd -literal -offset indent
+0 <-> local tty in
+1 <-> local tty out
+2 <-> local tty out
+3 <-> remote tty in
+4 <-> remote tty out
+.Ed
+.It Ic \&~#
+Send a
+.Dv BREAK
+to the remote system.
+For systems which don't support the necessary
+.Fn ioctl
+call the break is simulated by a sequence of line speed changes and
+DEL characters.
+.It Ic \&~s
+Set a variable (see the discussion below).
+.It Ic \&~v
+List all variables and their values (if set).
+.It Ic \&~^Z
+Stop
+.Nm
+(only available with job control).
+.It Ic \&~^Y
+Stop only the
+.Dq local side
+of
+.Nm
+(only available with job control); the
+.Dq 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
+To find the system description and thus the operating characteristics
+of
+.Ar system-name ,
+.Nm
+searches for a system description with a name identical to
+.Ar system-name .
+The search order is
+.Bl -enum -offset indent
+.It
+If the environment variable
+.Ev REMOTE
+does not start with a
+.Ql \&/
+it is assumed to be a system description, and is considered first.
+.It
+If the environment variable
+.Ev REMOTE
+begins with a
+.Ql \&/
+it is assumed to be a path to a
+.Xr remote 5
+database, and the specified database is searched.
+.It
+The default
+.Xr remote 5
+database,
+.Pa /etc/remote ,
+is searched.
+.El
+.Pp
+See
+.Xr remote 5
+for full documentation on system descriptions.
+.Pp
+The
+.Ar ba
+capability is used in system descriptions to specify the baud rate
+with which to establish a connection.
+If the value specified is not suitable, the baud rate to be used may
+be given on the command line, e.g.,
+.Ql "tip -300 mds" .
+.Pp
+When
+.Nm
+establishes a connection it sends out the connection message
+specified in the
+.Ar cm
+capability of the system description being used.
+.Pp
+When
+.Nm
+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
+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
+provides a running count of the number of lines transferred.
+When using the
+.Ic ~>
+and
+.Ic ~<
+commands, the
+.Dq eofread
+and
+.Dq 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,
+.Dq echocheck
+may be set to indicate
+.Nm
+should synchronize with the remote system on the echo of each
+transmitted character.
+.Pp
+When
+.Nm
+must dial a phone number to connect to a system it will print various
+messages indicating its actions.
+.Nm
+supports a variety of auto-call units and modems with the
+.Ar at
+capability in system descriptions.
+.Pp
+Support for Ventel 212+ (ventel), Hayes AT-style (hayes),
+USRobotics Courier (courier), Telebit T3000 (t3000) and
+Racal-Vadic 831 (vadic) units is enabled by default.
+.Pp
+Support for Bizcomp 1031[fw] (biz31[fw]), Bizcomp 1022[fw]
+(biz22[fw]), DEC DF0[23]-AC (df0[23]), DEC DN-11 (dn11) and
+Racal-Vadic 3451 (v3451) units can be added by recompiling
+.Xr tip 1
+with the appropriate defines.
+.Pp
+Note that if support for both the Racal-Vadic 831 and 3451 is enabled
+they are referred to as the v831 and v3451 respectively.
+If only one of the two is supported, it is referred to as vadic.
+.Ss VARIABLES
+.Nm
+maintains a set of 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
+.Sq s
+escape.
+The syntax for variables is patterned after
+.Xr vi 1
+and
+.Xr Mail 1 .
+Supplying
+.Dq 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
+.Ql ?
+to the end.
+For example,
+.Dq 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
+.Ql !
+to the name.
+Other variable types are set by concatenating an
+.Ql =
+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
+.Ql ~s
+prefix in a file
+.Pa .tiprc
+in one's home directory).
+The
+.Fl v
+option causes
+.Nm
+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
+.Ic ~<
+file transfer command; abbreviated
+.Ar eofr .
+.It Ar eofwrite
+(str) The string sent to indicate end-of-transmission during a
+.Ic ~>
+file transfer command; abbreviated
+.Ar eofw .
+.It Ar eol
+(str) The set of characters which indicate an end-of-line.
+.Nm
+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
+.Ql ~ .
+.It Ar exceptions
+(str) The set of characters which should not be discarded due to the
+beautification switch; abbreviated
+.Ar ex ;
+default value is
+.Dq \et\en\ef\eb .
+.It Ar force
+(char) The character used to force literal data transmission;
+abbreviated
+.Ar fo ;
+default value is
+.Ql ^P .
+.It Ar framesize
+(num) The amount of data (in bytes) to buffer between filesystem
+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 prompt
+(char) The character which indicates an end-of-line on the remote
+host; abbreviated
+.Ar pr ;
+default value is
+.Ql \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 lowercase letters will be mapped to
+uppercase by
+.Nm
+for transmission to the remote machine.
+.It Ar raisechar
+(char) The input character used to toggle uppercase mapping mode;
+abbreviated
+.Ar rc ;
+default value is
+.Ql ^A .
+.It Ar record
+(str) The name of the file in which a session script is recorded;
+abbreviated
+.Ar rec ;
+default value is
+.Dq tip.record .
+.It Ar script
+(bool) Session scripting mode; abbreviated
+.Ar sc ;
+default is
+.Ar off .
+When
+.Ar script
+is
+.Li true ,
+.Nm
+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
+between 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
+prints messages while dialing, shows the current number of lines
+transferred during a file transfer operations, and more.
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width Fl
+.It Ev SHELL
+The name of the shell to use for the
+.Ic ~!
+command; default value is
+.Dq /bin/sh .
+.It Ev HOME
+The home directory to use for the
+.Ic ~c
+command.
+.It Ev HOST
+The default value for
+.Ar system-name
+if none is specified via the command line.
+.It Ev REMOTE
+A system description, or an absolute path to a
+.Xr remote 5
+system description database.
+.It Ev PHONES
+A path to a
+.Xr phones 5
+database.
+.El
+.Sh FILES
+.Bl -tag -width "/var/spool/lock/LCK..*" -compact
+.It Pa /etc/remote
+global
+.Xr remote 5
+database
+.It Pa /etc/phones
+default
+.Xr phones 5
+file
+.It Pa ~/.tiprc
+initialization file
+.It Pa tip.record
+record file
+.It Pa /var/log/aculog
+line access log
+.It Pa /var/spool/lock/LCK..*
+lock file to avoid conflicts with
+.Xr uucp
+.El
+.Sh SEE ALSO
+.Xr phones 5 ,
+.Xr remote 5
+.Sh HISTORY
+The
+.Nm
+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 000000000000..64cd76021531
--- /dev/null
+++ b/usr.bin/tip/tip/tip.c
@@ -0,0 +1,629 @@
+/* $OpenBSD: tip.c,v 1.15 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: tip.c,v 1.13 1997/04/20 00:03:05 mellon Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)tip.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: tip.c,v 1.15 2001/10/24 18:38:58 millert Exp $";
+#endif /* not lint */
+
+/*
+ * tip - UNIX link to other systems
+ * tip [-v] [-speed] system-name
+ * or
+ * cu phone-number [-s speed] [-l line] [-a acu]
+ */
+#include "tip.h"
+#include "pathnames.h"
+
+/*
+ * Baud rate mapping table
+ */
+int rates[] = {
+ 0, 50, 75, 110, 134, 150, 200, 300, 600,
+ 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, -1
+};
+
+int disc = TTYDISC; /* tip normally runs this way */
+void intprompt();
+void timeout();
+void cleanup();
+char PNbuf[256]; /* This limits the size of a number */
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char *system = NOSTR;
+ int i;
+ char *p;
+ char sbuf[12];
+
+ gid = getgid();
+ egid = getegid();
+ uid = getuid();
+ euid = geteuid();
+ if (equal(__progname, "cu")) {
+ cumode = 1;
+ cumain(argc, argv);
+ goto cucommon;
+ }
+
+ if (argc > 4) {
+ fprintf(stderr, "usage: tip [-v] [-speed] [system-name]\n");
+ exit(1);
+ }
+ if (!isatty(0)) {
+ fprintf(stderr, "%s: must be interactive\n", __progname);
+ exit(1);
+ }
+
+ for (; argc > 1; argv++, argc--) {
+ if (argv[1][0] != '-')
+ system = argv[1];
+ else switch (argv[1][1]) {
+
+ case 'v':
+ vflag++;
+ break;
+
+ case 'n':
+ noesc++;
+ 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, "%s: %s, unknown option\n", __progname,
+ 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, "%s: phone number too long (max = %d bytes)\n",
+ __progname, (int)sizeof(PNbuf) - 1);
+ exit(1);
+ }
+ strncpy( PNbuf, system, sizeof PNbuf - 1 );
+ for (p = system; *p; p++)
+ *p = '\0';
+ PN = PNbuf;
+ (void)snprintf(sbuf, sizeof(sbuf), "tip%ld", BR);
+ system = sbuf;
+
+notnumber:
+ (void)signal(SIGINT, cleanup);
+ (void)signal(SIGQUIT, cleanup);
+ (void)signal(SIGHUP, cleanup);
+ (void)signal(SIGTERM, cleanup);
+
+ 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();
+
+ /*
+ * 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();
+
+ /*
+ * 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("none"); /* set the parity table */
+ if ((i = speed(number(value(BAUDRATE)))) == 0) {
+ printf("%s: bad baud rate %ld\n", __progname,
+ number(value(BAUDRATE)));
+ daemon_uid();
+ (void)uu_unlock(uucplock);
+ exit(3);
+ }
+
+ /*
+ * 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.
+ */
+
+ i = fcntl(FD, F_GETFL);
+ if (i == -1) {
+ perror("fcntl");
+ cleanup();
+ }
+ i = fcntl(FD, F_SETFL, i & ~O_NONBLOCK);
+ if (i == -1) {
+ perror("fcntl");
+ cleanup();
+ }
+
+ tcgetattr(0, &defterm);
+ term = defterm;
+ term.c_lflag &= ~(ICANON|IEXTEN|ECHO);
+ term.c_iflag &= ~(INPCK|ICRNL);
+ term.c_oflag &= ~OPOST;
+ term.c_cc[VMIN] = 1;
+ term.c_cc[VTIME] = 0;
+ defchars = term;
+ term.c_cc[VINTR] = term.c_cc[VQUIT] = term.c_cc[VSUSP] =
+ term.c_cc[VDSUSP] = term.c_cc[VDISCARD] =
+ term.c_cc[VLNEXT] = _POSIX_VDISABLE;
+ 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 ((pid = fork()))
+ tipin();
+ else
+ tipout();
+ /*NOTREACHED*/
+ exit(0);
+}
+
+void
+cleanup()
+{
+
+ daemon_uid();
+ (void)uu_unlock(uucplock);
+ if (odisc)
+ ioctl(0, TIOCSETD, (char *)&odisc);
+ exit(0);
+}
+
+/*
+ * 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;
+
+void
+user_uid()
+{
+ if (uidswapped == 0) {
+ seteuid(uid);
+ uidswapped = 1;
+ }
+}
+
+void
+daemon_uid()
+{
+
+ if (uidswapped) {
+ seteuid(euid);
+ uidswapped = 0;
+ }
+}
+
+void
+shell_uid()
+{
+ setegid(gid);
+ seteuid(uid);
+}
+
+/*
+ * put the controlling keyboard into raw mode
+ */
+void
+raw()
+{
+ tcsetattr(0, TCSADRAIN, &term);
+}
+
+
+/*
+ * return keyboard to normal mode
+ */
+void
+unraw()
+{
+ tcsetattr(0, TCSADRAIN, &defterm);
+}
+
+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.
+ */
+int
+prompt(s, p, sz)
+ char *s;
+ char *p;
+ size_t sz;
+{
+ int c;
+ 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 ((c = getchar()) != EOF && (*p = c) != '\n' && --sz > 0)
+ 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****
+ */
+void
+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()&STRIP_PAR;
+ if ((gch == character(value(ESCAPE))) && bol) {
+ if (!noesc) {
+ if (!(gch = escape()))
+ continue;
+ }
+ } else if (!cumode && gch == character(value(RAISECHAR))) {
+ setboolean(value(RAISE), !boolean(value(RAISE)));
+ continue;
+ } else if (gch == '\r') {
+ bol = 1;
+ parwrite(FD, &gch, 1);
+ if (boolean(value(HALFDUPLEX)))
+ printf("\r\n");
+ continue;
+ } else if (!cumode && gch == character(value(FORCE)))
+ gch = getchar()&STRIP_PAR;
+ bol = any(gch, value(EOL));
+ if (boolean(value(RAISE)) && islower(gch))
+ gch = toupper(gch);
+ parwrite(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
+ */
+int
+escape()
+{
+ char gch;
+ esctable_t *p;
+ char c = character(value(ESCAPE));
+
+ gch = (getchar()&STRIP_PAR);
+ 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)
+ parwrite(FD, &c, 1);
+ return (gch);
+}
+
+int
+speed(n)
+ int n;
+{
+ int *p;
+
+ for (p = rates; *p != -1; p++)
+ if (*p == n)
+ return n;
+ return 0;
+}
+
+int
+any(cc, p)
+ int cc;
+ char *p;
+{
+ char c = cc;
+ while (p && *p)
+ if (*p++ == c)
+ return (1);
+ return (0);
+}
+
+int
+size(s)
+ char *s;
+{
+ int i = 0;
+
+ while (s && *s++)
+ i++;
+ return (i);
+}
+
+char *
+interp(s)
+ char *s;
+{
+ static char buf[256];
+ 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
+ */
+void
+help(c)
+ char c;
+{
+ 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(speed)
+ int speed;
+{
+ struct termios cntrl;
+
+ tcgetattr(FD, &cntrl);
+ cfsetospeed(&cntrl, speed);
+ cfsetispeed(&cntrl, speed);
+ cntrl.c_cflag &= ~(CSIZE|PARENB);
+ cntrl.c_cflag |= CS8;
+ if (boolean(value(DC)))
+ cntrl.c_cflag |= CLOCAL;
+ cntrl.c_iflag &= ~(ISTRIP|ICRNL);
+ cntrl.c_oflag &= ~OPOST;
+ cntrl.c_lflag &= ~(ICANON|ISIG|IEXTEN|ECHO);
+ cntrl.c_cc[VMIN] = 1;
+ cntrl.c_cc[VTIME] = 0;
+ if (boolean(value(TAND)))
+ cntrl.c_iflag |= IXOFF;
+ tcsetattr(FD, TCSAFLUSH, &cntrl);
+}
+
+static char partab[0200];
+
+/*
+ * 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.
+ */
+void
+parwrite(fd, buf, n)
+ int fd;
+ char *buf;
+ int n;
+{
+ int i;
+ char *bp;
+
+ 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.");
+ /* this is questionable */
+ perror("write");
+ }
+}
+
+/*
+ * Build a parity table with appropriate high-order bit.
+ */
+void
+setparity(defparity)
+ char *defparity;
+{
+ int i, flip, clr, set;
+ char *parity;
+ extern const unsigned 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 000000000000..4c5ab2064eec
--- /dev/null
+++ b/usr.bin/tip/tip/tip.h
@@ -0,0 +1,312 @@
+/* $OpenBSD: tip.h,v 1.11 2001/09/09 19:30:49 millert Exp $ */
+/* $NetBSD: tip.h,v 1.7 1997/04/20 00:02:46 mellon Exp $ */
+
+/*
+ * 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 <sys/file.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+
+#include <termios.h>
+#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>
+#include <limits.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 */
+
+long BR; /* line speed for conversation */
+long FS; /* frame size for transfers */
+
+short DU; /* this host is dialed up */
+short 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 */
+short HD; /* this host is half duplex - do local echo */
+short DC; /* this host is directly connected. */
+
+/*
+ * 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)();
+ int (*acu_disconnect)();
+ int (*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.
+ */
+
+#define value(v) vtable[v].v_value
+
+#define number(v) ((long)(v))
+#define boolean(v) ((short)(long)(v))
+#define character(v) ((char)(long)(v))
+#define address(v) ((long *)(v))
+
+#define setnumber(v,n) do { (v) = (char *)(long)(n); } while (0)
+#define setboolean(v,n) do { (v) = (char *)(long)(n); } while (0)
+#define setcharacter(v,n) do { (v) = (char *)(long)(n); } while (0)
+#define setaddress(v,n) do { (v) = (char *)(n); } while (0)
+
+/*
+ * 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 int noesc; /* no escape `~' char */
+extern value_t vtable[]; /* variable table */
+
+#ifndef ACULOG
+#define logent(a, b, c, d)
+#define loginit()
+#endif
+
+/*
+ * Definition of indices into variable table so
+ * value(DEFINE) turns into a static address.
+ */
+
+#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 PHONES 12
+#define PROMPT 13
+#define RAISE 14
+#define RAISECHAR 15
+#define RECORD 16
+#define REMOTE 17
+#define SCRIPT 18
+#define TABEXPAND 19
+#define VERBOSE 20
+#define SHELL 21
+#define HOME 22
+#define ECHOCHECK 23
+#define DISCONNECT 24
+#define TAND 25
+#define LDELAY 26
+#define CDELAY 27
+#define ETIMEOUT 28
+#define RAWFTP 29
+#define HALFDUPLEX 30
+#define LECHO 31
+#define PARITY 32
+
+#define NOVAL ((value_t *)NULL)
+#define NOACU ((acu_t *)NULL)
+#define NOSTR ((char *)NULL)
+#define NOFILE ((FILE *)NULL)
+#define NOPWD ((struct passwd *)0)
+
+struct termios term; /* current mode of terminal */
+struct termios defterm; /* initial mode of terminal */
+struct termios defchars; /* current mode with initial chars */
+
+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 noesc; /* no `~' escape char */
+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 */
+int bits8; /* terminal is is 8-bit mode */
+#define STRIP_PAR (bits8 ? 0377 : 0177)
+
+char fname[PATH_MAX]; /* file name buffer for ~< */
+char copyname[PATH_MAX]; /* 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 *__progname; /* program name */
+
+extern char *ctrl();
+extern char *vinterp();
+extern char *connect();
+
+char *sname __P((char *s));
+int any __P((int cc, char *p));
+int anyof __P((char *s1, char *s2));
+int args __P((char *buf, char *a[], int num));
+int escape __P((void));
+int prompt __P((char *s, char *p, size_t sz));
+int size __P((char *s));
+int speed __P((int n));
+int uu_lock __P((char *ttyname));
+int uu_unlock __P((char *ttyname));
+int vstring __P((char *s, char *v));
+long hunt __P((char *name));
+void cumain __P((int argc, char *argv[]));
+void daemon_uid __P((void));
+void disconnect __P((char *reason));
+void execute __P((char *s));
+void logent __P((char *group, char *num, char *acu, char *message));
+void loginit __P((void));
+void prtime __P((char *s, time_t a));
+void parwrite __P((int fd, char *buf, int n));
+void raw __P((void));
+void send __P((int c));
+void setparity __P((char *defparity));
+void setscript __P((void));
+void shell_uid __P((void));
+void tandem __P((char *option));
+void tipabort __P((char *msg));
+void tipin __P((void));
+void tipout __P((void));
+void transfer __P((char *buf, int fd, char *eofchars));
+void transmit __P((FILE *fd, char *eofchars, char *command));
+void ttysetup __P((int speed));
+void unraw __P((void));
+void user_uid __P((void));
+void vinit __P((void));
+void vlex __P((char *s));
diff --git a/usr.bin/tip/tip/tipout.c b/usr.bin/tip/tip/tipout.c
new file mode 100644
index 000000000000..d1ff53cdc0bb
--- /dev/null
+++ b/usr.bin/tip/tip/tipout.c
@@ -0,0 +1,172 @@
+/* $OpenBSD: tipout.c,v 1.8 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: tipout.c,v 1.5 1996/12/29 10:34:12 cgd Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)tipout.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: tipout.c,v 1.8 2001/10/24 18:38:58 millert Exp $";
+#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];
+ char *pline = line;
+ char reply;
+
+ read(fildes[0], &c, 1);
+ while (c != '\n' && pline - line < sizeof(line)) {
+ *pline++ = c;
+ read(fildes[0], &c, 1);
+ }
+ *pline = '\0';
+ if (boolean(value(SCRIPT)) && fscript != NULL)
+ fclose(fscript);
+ if (pline == line) {
+ setboolean(value(SCRIPT), FALSE);
+ reply = 'y';
+ } else {
+ if ((fscript = fopen(line, "a")) == NULL)
+ reply = 'n';
+ else {
+ reply = 'y';
+ setboolean(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()
+{
+
+ setboolean(value(BEAUTIFY), !boolean(value(BEAUTIFY)));
+ longjmp(sigbuf, 1);
+}
+
+/*
+ * ****TIPOUT TIPOUT****
+ */
+void
+tipout()
+{
+ char buf[BUFSIZ];
+ char *cp;
+ int cnt;
+ sigset_t mask, 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);
+ sigprocmask(SIG_BLOCK, NULL, &omask);
+ for (;;) {
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+ cnt = read(FD, buf, BUFSIZ);
+ if (cnt <= 0) {
+ /* lost carrier */
+ if (cnt < 0 && errno == EIO) {
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGTERM);
+ sigprocmask(SIG_BLOCK, &mask, NULL);
+ intTERM();
+ /*NOTREACHED*/
+ }
+ continue;
+ }
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGEMT);
+ sigaddset(&mask, SIGTERM);
+ sigaddset(&mask, SIGIOT);
+ sigaddset(&mask, SIGSYS);
+ sigprocmask(SIG_BLOCK, &mask, NULL);
+ for (cp = buf; cp < buf + cnt; cp++)
+ *cp &= STRIP_PAR;
+ 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 000000000000..a2a703b9edbe
--- /dev/null
+++ b/usr.bin/tip/tip/uucplock.c
@@ -0,0 +1,132 @@
+/* $OpenBSD: uucplock.c,v 1.6 1998/07/13 02:11:44 millert Exp $ */
+/* $NetBSD: uucplock.c,v 1.7 1997/02/11 09:24:08 mrg Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)uucplock.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: uucplock.c,v 1.6 1998/07/13 02:11:44 millert Exp $";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/dir.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "pathnames.h"
+
+/*
+ * uucp style locking routines
+ * return: 0 - success
+ * -1 - failure
+ */
+
+int
+uu_lock(ttyname)
+ char *ttyname;
+{
+ int fd, pid;
+ char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN];
+ char text_pid[81];
+ int len;
+
+ (void)snprintf(tbuf, sizeof 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(tbuf);
+ fprintf(stderr, "Can't open lock file.\n");
+ return(-1);
+ }
+ len = read(fd, text_pid, sizeof(text_pid)-1);
+ if(len<=0) {
+ perror(tbuf);
+ (void)close(fd);
+ fprintf(stderr, "Can't read lock file.\n");
+ return(-1);
+ }
+ text_pid[len] = 0;
+ pid = atol(text_pid);
+
+ 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
+ */
+ fprintf(stderr, "Stale lock on %s PID=%d... overriding.\n",
+ ttyname, pid);
+ if (lseek(fd, (off_t)0, SEEK_SET) < 0) {
+ perror(tbuf);
+ (void)close(fd);
+ fprintf(stderr, "Can't seek lock file.\n");
+ return(-1);
+ }
+ /* fall out and finish the locking process */
+ }
+ pid = getpid();
+ (void)sprintf(text_pid, "%10d\n", pid);
+ len = strlen(text_pid);
+ if (write(fd, text_pid, len) != len) {
+ (void)close(fd);
+ (void)unlink(tbuf);
+ perror("lock write");
+ return(-1);
+ }
+ (void)close(fd);
+ return(0);
+}
+
+int
+uu_unlock(ttyname)
+ char *ttyname;
+{
+ char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN];
+
+ (void)snprintf(tbuf, sizeof tbuf, _PATH_LOCKDIRNAME, ttyname);
+ return(unlink(tbuf));
+}
diff --git a/usr.bin/tip/tip/value.c b/usr.bin/tip/tip/value.c
new file mode 100644
index 000000000000..20817e9cdffc
--- /dev/null
+++ b/usr.bin/tip/tip/value.c
@@ -0,0 +1,365 @@
+/* $OpenBSD: value.c,v 1.7 2001/10/24 18:38:58 millert Exp $ */
+/* $NetBSD: value.c,v 1.6 1997/02/11 09:24:09 mrg Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)value.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: value.c,v 1.7 2001/10/24 18:38:58 millert Exp $";
+#endif /* not lint */
+
+#include "tip.h"
+
+#define MIDDLE 35
+
+static value_t *vlookup();
+static int col = 0;
+
+/*
+ * Variable manipulation
+ */
+void
+vinit()
+{
+ value_t *p;
+ char *cp;
+ FILE *f;
+ char file[FILENAME_MAX];
+
+ 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)
+ setnumber(p->v_value, *address(p->v_value));
+ }
+ /*
+ * Read the .tiprc file in the HOME directory
+ * for sets
+ */
+ if (strlen(value(HOME)) + sizeof("/.tiprc") > sizeof(file)) {
+ (void)fprintf(stderr, "Home directory path too long: %s\n",
+ value(HOME));
+ } else {
+ snprintf(file, sizeof file, "%s/.tiprc", value(HOME));
+ if ((f = fopen(file, "r")) != NULL) {
+ char *tp;
+
+ while (fgets(file, sizeof(file)-1, f) != NULL) {
+ if (vflag)
+ printf("set %s", file);
+ if ((tp = strrchr(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*/
+void
+vassign(p, v)
+ 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 = strdup(v)) == NOSTR) {
+ printf("out of core\r\n");
+ return;
+ }
+ p->v_type &= ~(ENVIRON|INIT);
+ break;
+
+ case NUMBER:
+ if (number(p->v_value) == number(v))
+ return;
+ setnumber(p->v_value, number(v));
+ break;
+
+ case BOOL:
+ if (boolean(p->v_value) == (*v != '!'))
+ return;
+ setboolean(p->v_value, (*v != '!'));
+ break;
+
+ case CHAR:
+ if (character(p->v_value) == *v)
+ return;
+ setcharacter(p->v_value, *v);
+ }
+ p->v_access |= CHANGED;
+}
+
+static void vprint();
+static void vtoken();
+
+void
+vlex(s)
+ char *s;
+{
+ value_t *p;
+
+ if (equal(s, "all")) {
+ for (p = vtable; p->v_name; p++)
+ if (vaccess(p->v_access, READ))
+ vprint(p);
+ } else {
+ 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)
+ char *s;
+{
+ value_t *p;
+ char *cp;
+ char *expand();
+
+ if ((cp = strchr(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 = strchr(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)
+ value_t *p;
+{
+ 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=%-5ld", 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)
+ 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)
+ char *s;
+{
+ 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)
+ char *s;
+ char stop;
+{
+ 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 {
+ 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)
+ */
+int
+vstring(s,v)
+ char *s;
+ char *v;
+{
+ 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 000000000000..6131dd29f97d
--- /dev/null
+++ b/usr.bin/tip/tip/vars.c
@@ -0,0 +1,118 @@
+/* $OpenBSD: vars.c,v 1.2 1996/06/26 05:40:50 deraadt Exp $ */
+/* $NetBSD: vars.c,v 1.3 1994/12/08 09:31:19 jtc Exp $ */
+
+/*
+ * 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
+#if 0
+static char sccsid[] = "@(#)vars.c 8.1 (Berkeley) 6/6/93";
+#endif
+static char rcsid[] = "$OpenBSD: vars.c,v 1.2 1996/06/26 05:40:50 deraadt Exp $";
+#endif /* not lint */
+
+#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 },
+ { "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 }
+};