aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/tip
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/tip')
-rw-r--r--usr.bin/tip/Makefile3
-rw-r--r--usr.bin/tip/Makefile.inc1
-rw-r--r--usr.bin/tip/README62
-rw-r--r--usr.bin/tip/TODO19
-rw-r--r--usr.bin/tip/libacu/biz22.c179
-rw-r--r--usr.bin/tip/libacu/biz31.c246
-rw-r--r--usr.bin/tip/libacu/courier.c346
-rw-r--r--usr.bin/tip/libacu/df.c129
-rw-r--r--usr.bin/tip/libacu/dn11.c141
-rw-r--r--usr.bin/tip/libacu/hayes.c312
-rw-r--r--usr.bin/tip/libacu/t3000.c364
-rw-r--r--usr.bin/tip/libacu/v3451.c204
-rw-r--r--usr.bin/tip/libacu/v831.c255
-rw-r--r--usr.bin/tip/libacu/ventel.c251
-rw-r--r--usr.bin/tip/tip/Makefile60
-rw-r--r--usr.bin/tip/tip/Makefile.depend15
-rw-r--r--usr.bin/tip/tip/acu.c187
-rw-r--r--usr.bin/tip/tip/acutab.c81
-rw-r--r--usr.bin/tip/tip/cmds.c991
-rw-r--r--usr.bin/tip/tip/cmdtab.c58
-rw-r--r--usr.bin/tip/tip/cu.1511
-rw-r--r--usr.bin/tip/tip/cu.c202
-rw-r--r--usr.bin/tip/tip/hunt.c101
-rw-r--r--usr.bin/tip/tip/log.c84
-rw-r--r--usr.bin/tip/tip/partab.c55
-rw-r--r--usr.bin/tip/tip/pathnames.h40
-rw-r--r--usr.bin/tip/tip/phones5
-rw-r--r--usr.bin/tip/tip/remote72
-rw-r--r--usr.bin/tip/tip/remote.c228
-rw-r--r--usr.bin/tip/tip/tip.1605
-rw-r--r--usr.bin/tip/tip/tip.c624
-rw-r--r--usr.bin/tip/tip/tip.h355
-rw-r--r--usr.bin/tip/tip/tipout.c180
-rw-r--r--usr.bin/tip/tip/uucplock.c123
-rw-r--r--usr.bin/tip/tip/value.c355
-rw-r--r--usr.bin/tip/tip/vars.c116
36 files changed, 7560 insertions, 0 deletions
diff --git a/usr.bin/tip/Makefile b/usr.bin/tip/Makefile
new file mode 100644
index 000000000000..f33bfe16f17e
--- /dev/null
+++ b/usr.bin/tip/Makefile
@@ -0,0 +1,3 @@
+SUBDIR=tip
+
+.include <bsd.subdir.mk>
diff --git a/usr.bin/tip/Makefile.inc b/usr.bin/tip/Makefile.inc
new file mode 100644
index 000000000000..01b5f23410c8
--- /dev/null
+++ b/usr.bin/tip/Makefile.inc
@@ -0,0 +1 @@
+.include "../Makefile.inc"
diff --git a/usr.bin/tip/README b/usr.bin/tip/README
new file mode 100644
index 000000000000..78f8ae8eafe9
--- /dev/null
+++ b/usr.bin/tip/README
@@ -0,0 +1,62 @@
+
+Tip can be configured in a number of ways:
+
+ACU's:
+-----
+
+ACU Define in makefile
+-------------------- ---------------
+BIZCOMP 1022, 1031 BIZ1022, BIZ1031
+DEC DF02-AC, DF03-AC DF02, DF03
+DEC DN-11/Able Quadracall DN11
+Ventel VENTEL
+Vadic 831 V831
+
+New ACU's may be added by editing the ACU description table
+in acutab.c and writing a ``driver''.
+
+ACU usage can be monitored by defining ACULOG in the makefile.
+If this is done and no phone numbers should appear in the
+log file, define PRISTINE in the makefile.
+
+Variables:
+---------
+
+Tip's internal workings revolve around a set of (possibly)
+user defined variables. These are statically initialized
+in vars.c, and from the remote file.
+
+Note that adding or deleting variables requires tip to be completedly
+recompiled, as indexes into the variable table are used to avoid
+expensive lookups. These defines are set in tip.h.
+
+Commands:
+--------
+
+The command dispatch table is defined in cmdtab.c. Commands
+may have attributes such as EXPerimental and PRIVileged (only
+root may execute).
+
+
+
+--------------------------------------------------------------------------
+
+Recent changes about Jan 82
+
+A new, improved version of tip is now available. The most important
+addition is the capacility to specify a phone number with tip. The
+default baud rate is 1200. To use it do:
+
+ tip phone-number
+or
+ tip -300 phone-number
+
+for 300 baud.
+
+A ~^Z command has been added to tip as well.
+
+A new cu program is available that interfaces to the tip program.
+It attempts to give the same user interface as cu but it is really
+the tip program so you have all the advantages of tip. This allows
+cu (actually tip) to search for a free ACU instead of having the
+user specify which one he wants.
diff --git a/usr.bin/tip/TODO b/usr.bin/tip/TODO
new file mode 100644
index 000000000000..b47e649a64ea
--- /dev/null
+++ b/usr.bin/tip/TODO
@@ -0,0 +1,19 @@
+
+1. Rethink protection glitches on REMOTE & PHONES
+ files (setuid/setgid??).
+
+2. Make clean fix for scripting being set in .tiprc
+
+3. change EOFREAD to recognize more general strings.
+
+4. add an option that returns an exit status based on
+ whether resources for the requested operation are available.
+
+5. write a program to list known systems (a quick shell script
+ should do it); people keep forgetting the names.
+
+6. change remote file descriptions so that acu attributes are
+ are attached to a device so that several different devices
+ can be used to get to the same system (perhaps hardwired
+ and phone line). got any ideas here? I'm looking at something
+ like dv=cua1,cul1,dn11;cua2,,df03.
diff --git a/usr.bin/tip/libacu/biz22.c b/usr.bin/tip/libacu/biz22.c
new file mode 100644
index 000000000000..6ef5b1861049
--- /dev/null
+++ b/usr.bin/tip/libacu/biz22.c
@@ -0,0 +1,179 @@
+/* $OpenBSD: biz22.c,v 1.13 2006/03/17 19:17:13 moritz Exp $ */
+/* $NetBSD: biz22.c,v 1.6 1997/02/11 09:24:11 mrg Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#include "tip.h"
+
+#define DISCONNECT_CMD "\20\04" /* disconnection string */
+
+static int dialtimeout = 0;
+static jmp_buf timeoutbuf;
+
+static int biz_dialer(char *, char *);
+static void sigALRM(int);
+static int cmd(char *);
+static int detect(char *);
+
+/*
+ * Dial up on a BIZCOMP Model 1022 with either
+ * tone dialing (mod = "V")
+ * pulse dialing (mod = "W")
+ */
+static int
+biz_dialer(char *num, char *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)strlcpy(cbuf, "\02.\r", sizeof cbuf);
+ 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 (dialtimeout) {
+ char line[80];
+
+ (void)snprintf(line, sizeof line, "%ld second dial timeout",
+ number(value(DIALTIMEOUT)));
+ logent(value(HOST), num, "biz1022", line);
+ }
+#endif
+ if (dialtimeout)
+ biz22_disconnect(); /* insurance */
+ return (connected);
+}
+
+int
+biz22w_dialer(char *num, char *acu)
+{
+ return (biz_dialer(num, "W"));
+}
+
+int
+biz22f_dialer(char *num, char *acu)
+{
+ return (biz_dialer(num, "V"));
+}
+
+void
+biz22_disconnect(void)
+{
+ write(FD, DISCONNECT_CMD, sizeof(DISCONNECT_CMD)-1);
+ sleep(2);
+ tcflush(FD, TCIOFLUSH);
+}
+
+void
+biz22_abort(void)
+{
+ write(FD, "\02", 1);
+}
+
+/*ARGSUSED*/
+static void
+sigALRM(int signo)
+{
+ dialtimeout = 1;
+ longjmp(timeoutbuf, 1);
+}
+
+static int
+cmd(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(char *s)
+{
+ sig_t f;
+ char c;
+
+ f = signal(SIGALRM, sigALRM);
+ dialtimeout = 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 (dialtimeout == 0);
+}
diff --git a/usr.bin/tip/libacu/biz31.c b/usr.bin/tip/libacu/biz31.c
new file mode 100644
index 000000000000..cd2cc0267b43
--- /dev/null
+++ b/usr.bin/tip/libacu/biz31.c
@@ -0,0 +1,246 @@
+/* $OpenBSD: biz31.c,v 1.10 2006/03/17 19:17:13 moritz Exp $ */
+/* $NetBSD: biz31.c,v 1.5 1997/02/11 09:24:14 mrg Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#include "tip.h"
+
+#define MAXRETRY 3 /* sync up retry count */
+#define DISCONNECT_CMD "\21\25\11\24" /* disconnection string */
+
+static int biz_dialer(char *, char *);
+static int bizsync(int);
+static int echo(char *);
+static void sigALRM(int);
+static int detect(char *);
+static int flush(char *);
+static int bizsync(int);
+
+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(char *num, char *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)snprintf(line, sizeof 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);
+}
+
+int
+biz31w_dialer(char *num, char *acu)
+{
+ return (biz_dialer(num, "w"));
+}
+
+int
+biz31f_dialer(char *num, char *acu)
+{
+ return (biz_dialer(num, "f"));
+}
+
+void
+biz31_disconnect(void)
+{
+ write(FD, DISCONNECT_CMD, sizeof(DISCONNECT_CMD)-1);
+ sleep(2);
+ tcflush(FD, TCIOFLUSH);
+}
+
+void
+biz31_abort(void)
+{
+ write(FD, "\33", 1);
+}
+
+static int
+echo(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);
+ }
+}
+
+/*ARGSUSED*/
+static void
+sigALRM(int signo)
+{
+ timeout = 1;
+ longjmp(timeoutbuf, 1);
+}
+
+static int
+detect(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(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(int 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..7ff0daa9d1db
--- /dev/null
+++ b/usr.bin/tip/libacu/courier.c
@@ -0,0 +1,346 @@
+/* $OpenBSD: courier.c,v 1.15 2006/03/17 19:17:13 moritz Exp $ */
+/* $NetBSD: courier.c,v 1.7 1997/02/11 09:24:16 mrg Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+/*
+ * 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 int dialtimeout = 0;
+static int connected = 0;
+static jmp_buf timeoutbuf;
+
+static void sigALRM(int);
+static int cour_swallow(char *);
+static int cour_connect(void);
+static int coursync(void);
+static void cour_write(int, char *, int);
+static void cour_nap(void);
+#ifdef DEBUG
+static void cour_verbose_read(void);
+#endif
+
+int
+cour_dialer(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 (dialtimeout) {
+ (void)snprintf(line, sizeof line, "%ld second dial timeout",
+ number(value(DIALTIMEOUT)));
+ logent(value(HOST), num, "cour", line);
+ }
+#endif
+ if (dialtimeout)
+ cour_disconnect();
+ return (connected);
+}
+
+void
+cour_disconnect(void)
+{
+ /* first hang up the modem*/
+ ioctl(FD, TIOCCDTR, 0);
+ sleep(1);
+ ioctl(FD, TIOCSDTR, 0);
+ coursync(); /* reset */
+ close(FD);
+}
+
+void
+cour_abort(void)
+{
+ cour_write(FD, "\r", 1); /* send anything to abort the call */
+ cour_disconnect();
+}
+
+/*ARGSUSED*/
+static void
+sigALRM(int signo)
+{
+ printf("\07timeout waiting for reply\n");
+ dialtimeout = 1;
+ longjmp(timeoutbuf, 1);
+}
+
+static int
+cour_swallow(char *match)
+{
+ sig_t f;
+ char c;
+
+ f = signal(SIGALRM, sigALRM);
+ dialtimeout = 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(void)
+{
+ 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));
+ dialtimeout = 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(void)
+{
+ 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(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
+static void
+cour_verbose_read(void)
+{
+ 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 */
+static void
+cour_nap(void)
+{
+ 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..5b9cf7186a69
--- /dev/null
+++ b/usr.bin/tip/libacu/df.c
@@ -0,0 +1,129 @@
+/* $OpenBSD: df.c,v 1.9 2006/03/17 19:17:13 moritz Exp $ */
+/* $NetBSD: df.c,v 1.4 1995/10/29 00:49:51 pk Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+/*
+ * Dial the DF02-AC or DF03-AC
+ */
+
+#include "tip.h"
+
+static jmp_buf Sjbuf;
+
+static int df_dialer(char *, char *, int);
+static void alrm_timeout(int);
+
+int
+df02_dialer(char *num, char *acu)
+{
+ return (df_dialer(num, acu, 0));
+}
+
+int
+df03_dialer(char *num, char *acu)
+{
+ return (df_dialer(num, acu, 1));
+}
+
+static int
+df_dialer(char *num, char *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, alrm_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(void)
+{
+ write(FD, "\001", 1);
+ sleep(1);
+ tcflush(FD, TCIOFLUSH);
+}
+
+void
+df_abort(void)
+{
+ df_disconnect();
+}
+
+/*ARGSUSED*/
+static void
+alrm_timeout(int signo)
+{
+ 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..8f9f47065d69
--- /dev/null
+++ b/usr.bin/tip/libacu/dn11.c
@@ -0,0 +1,141 @@
+/* $OpenBSD: dn11.c,v 1.9 2006/03/17 19:17:13 moritz Exp $ */
+/* $NetBSD: dn11.c,v 1.4 1995/10/29 00:49:53 pk Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+/*
+ * Routines for dialing up on DN-11
+ */
+#include "tip.h"
+
+static jmp_buf jmpbuf;
+static pid_t child = -1, dn;
+
+static void alarmtr(int);
+
+int
+dn_dialer(char *num, char *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);
+}
+
+/*ARGSUSED*/
+static void
+alarmtr(int signo)
+{
+ alarm(0);
+ longjmp(jmpbuf, 1);
+}
+
+/*
+ * Insurance, for some reason we don't seem to be
+ * hanging up...
+ */
+void
+dn_disconnect(void)
+{
+ sleep(2);
+ if (FD > 0)
+ ioctl(FD, TIOCCDTR, 0);
+ close(FD);
+}
+
+void
+dn_abort(void)
+{
+ 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..efdd7fc8b438
--- /dev/null
+++ b/usr.bin/tip/libacu/hayes.c
@@ -0,0 +1,312 @@
+/* $OpenBSD: hayes.c,v 1.13 2006/03/17 19:17:13 moritz Exp $ */
+/* $NetBSD: hayes.c,v 1.6 1997/02/11 09:24:17 mrg Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+/*
+ * 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 int dialtimeout = 0;
+static jmp_buf timeoutbuf;
+
+#define DUMBUFLEN 40
+static char dumbuf[DUMBUFLEN];
+
+#define DIALING 1
+#define IDLE 2
+#define CONNECTED 3
+#define FAILED 4
+static int state = IDLE;
+
+static void sigALRM(int);
+static char gobble(char *);
+static void error_rep(char);
+static void goodbye(void);
+static int hay_sync(void);
+
+int
+hay_dialer(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 (dialtimeout) {
+ (void)snprintf(line, sizeof line, "%ld second dial timeout",
+ number(value(DIALTIMEOUT)));
+ logent(value(HOST), num, "hayes", line);
+ }
+#endif
+ if (dialtimeout)
+ hay_disconnect(); /* insurance */
+ return (connected);
+}
+
+void
+hay_disconnect(void)
+{
+ /* 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(void)
+{
+ write(FD, "\r", 1); /* send anything to abort the call */
+ hay_disconnect();
+}
+
+/*ARGSUSED*/
+static void
+sigALRM(int signo)
+{
+ printf("\07timeout waiting for reply\n\r");
+ dialtimeout = 1;
+ longjmp(timeoutbuf, 1);
+}
+
+static char
+gobble(char *match)
+{
+ char c;
+ sig_t f;
+ size_t i;
+ int status = 0;
+
+ f = signal(SIGALRM, sigALRM);
+ dialtimeout = 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(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.
+ */
+static void
+goodbye(void)
+{
+ 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
+
+static int
+hay_sync(void)
+{
+ 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..9341430787da
--- /dev/null
+++ b/usr.bin/tip/libacu/t3000.c
@@ -0,0 +1,364 @@
+/* $OpenBSD: t3000.c,v 1.14 2006/03/17 19:17:13 moritz Exp $ */
+/* $NetBSD: t3000.c,v 1.5 1997/02/11 09:24:18 mrg Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+/*
+ * 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 int dialtimeout = 0;
+static int connected = 0;
+static jmp_buf timeoutbuf;
+
+static void sigALRM(int);
+static int t3000_swallow(char *);
+static int t3000_connect(void);
+static int t3000_sync(void);
+static void t3000_write(int, char *, int);
+static void t3000_nap(void);
+#ifdef DEBUG
+static void t3000_verbose_read(void);
+#endif
+
+int
+t3000_dialer(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 (dialtimeout) {
+ (void)snprintf(line, sizeof line, "%ld second dial timeout",
+ number(value(DIALTIMEOUT)));
+ logent(value(HOST), num, "t3000", line);
+ }
+#endif
+ if (dialtimeout)
+ t3000_disconnect();
+ return (connected);
+}
+
+void
+t3000_disconnect(void)
+{
+ /* first hang up the modem*/
+ ioctl(FD, TIOCCDTR, 0);
+ sleep(1);
+ ioctl(FD, TIOCSDTR, 0);
+ t3000_sync(); /* reset */
+ close(FD);
+}
+
+void
+t3000_abort(void)
+{
+ t3000_write(FD, "\r", 1); /* send anything to abort the call */
+ t3000_disconnect();
+}
+
+/*ARGSUSED*/
+static void
+sigALRM(int signo)
+{
+ printf("\07timeout waiting for reply\n");
+ dialtimeout = 1;
+ longjmp(timeoutbuf, 1);
+}
+
+static int
+t3000_swallow(char *match)
+{
+ sig_t f;
+ char c;
+
+ f = signal(SIGALRM, sigALRM);
+ dialtimeout = 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(void)
+{
+ 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));
+ dialtimeout = 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(void)
+{
+ 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 void
+t3000_write(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
+static void
+t3000_verbose_read(void)
+{
+ 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 */
+static void
+t3000_nap(void)
+{
+ 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..1f671b5bffd3
--- /dev/null
+++ b/usr.bin/tip/libacu/v3451.c
@@ -0,0 +1,204 @@
+/* $OpenBSD: v3451.c,v 1.9 2006/03/17 19:17:13 moritz Exp $ */
+/* $NetBSD: v3451.c,v 1.6 1997/02/11 09:24:20 mrg Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+/*
+ * Routines for calling up on a Vadic 3451 Modem
+ */
+#include "tip.h"
+
+static jmp_buf Sjbuf;
+
+static void vawrite(char *, int);
+static int expect(char *);
+static void alarmtr(int);
+static int notin(char *, char *);
+static int prefix(char *, char *);
+
+int
+v3451_dialer(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(void)
+{
+ close(FD);
+}
+
+void
+v3451_abort(void)
+{
+ close(FD);
+}
+
+static void
+vawrite(char *cp, int delay)
+{
+ for (; *cp; sleep(delay), cp++)
+ write(FD, cp, 1);
+}
+
+static int
+expect(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);
+}
+
+/*ARGSUSED*/
+static void
+alarmtr(int signo)
+{
+ longjmp(Sjbuf, 1);
+}
+
+static int
+notin(char *sh, char *lg)
+{
+ for (; *lg; lg++)
+ if (prefix(sh, lg))
+ return (0);
+ return (1);
+}
+
+static int
+prefix(char *s1, char *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..b233cf55c280
--- /dev/null
+++ b/usr.bin/tip/libacu/v831.c
@@ -0,0 +1,255 @@
+/* $OpenBSD: v831.c,v 1.11 2006/03/17 19:17:13 moritz Exp $ */
+/* $NetBSD: v831.c,v 1.5 1996/12/29 10:42:01 cgd Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+/*
+ * Routines for dialing up on Vadic 831
+ */
+#include "tip.h"
+#include <termios.h>
+
+static jmp_buf jmpbuf;
+static pid_t child = -1;
+
+static void alarmtr(int);
+static int dialit(char *, char *);
+static char * sanitize(char *);
+
+int
+v831_dialer(char *num, char *acu)
+{
+ int status;
+ int timelim;
+ pid_t pid;
+
+ 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);
+}
+
+/*ARGSUSED*/
+static void
+alarmtr(int signo)
+{
+ alarm(0);
+ longjmp(jmpbuf, 1);
+}
+
+/*
+ * Insurance, for some reason we don't seem to be
+ * hanging up...
+ */
+void
+v831_disconnect(void)
+{
+ 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(void)
+{
+#ifdef DEBUG
+ printf("[abort: AC=%d]\n", AC);
+#endif
+ sleep(2);
+ if (child > 0)
+ kill(child, SIGKILL);
+ if (FD > 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' },
+ { NULL, '\0', '\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(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(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..603c18e4b5ef
--- /dev/null
+++ b/usr.bin/tip/libacu/ventel.c
@@ -0,0 +1,251 @@
+/* $OpenBSD: ventel.c,v 1.12 2006/03/17 19:17:13 moritz Exp $ */
+/* $NetBSD: ventel.c,v 1.6 1997/02/11 09:24:21 mrg Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+/*
+ * 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 int dialtimeout = 0;
+static jmp_buf timeoutbuf;
+
+static void echo(char *);
+static void sigALRM(int);
+static int gobble(char, char *);
+static int vensync(int);
+
+/*
+ * 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(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 (dialtimeout) {
+ (void)snprintf(line, sizeof line, "%ld second dial timeout",
+ number(value(DIALTIMEOUT)));
+ logent(value(HOST), num, "ventel", line);
+ }
+#endif
+ if (dialtimeout)
+ ven_disconnect(); /* insurance */
+ if (connected || dialtimeout || !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, ' ')) != NULL; 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(void)
+{
+ close(FD);
+}
+
+void
+ven_abort(void)
+{
+ write(FD, "\03", 1);
+ close(FD);
+}
+
+static void
+echo(char *s)
+{
+ char c;
+
+ while ((c = *s++) != '\0')
+ 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);
+ }
+}
+
+/*ARGSUSED*/
+static void
+sigALRM(int signo)
+{
+ printf("\07timeout waiting for reply\n");
+ dialtimeout = 1;
+ longjmp(timeoutbuf, 1);
+}
+
+static int
+gobble(char match, char response[])
+{
+ char *cp = response;
+ sig_t f;
+ char c;
+
+ f = signal(SIGALRM, sigALRM);
+ dialtimeout = 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(int 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..85c9ea0c1c29
--- /dev/null
+++ b/usr.bin/tip/tip/Makefile
@@ -0,0 +1,60 @@
+# $OpenBSD: Makefile,v 1.11 2006/05/25 08:41:52 jmc 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)
+
+CONFS= phones remote
+PROG= tip
+LINKS= ${BINDIR}/tip ${BINDIR}/cu
+MAN= tip.1 cu.1
+CFLAGS+=-I${.CURDIR} -DDEFBR=9600 -DDEFFS=BUFSIZ -DACULOG -DPRISTINE \
+ -DCONNECT -DV831 -DVENTEL -DHAYES -DCOURIER -DT3000
+WARNS?= 2
+.PATH: ${.CURDIR}/../libacu
+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
+
+# Don't rebuild based on remote.c
+remote: .MADE
+
+.include <bsd.prog.mk>
+
+# Dirty, rotten hack. This can be removed when we are confident that there
+# is no cu(1) with the schg-bit set.
+beforeinstall:
+.if exists(${DESTDIR}${BINDIR}/cu)
+ -chflags noschg ${DESTDIR}${BINDIR}/cu
+.endif
diff --git a/usr.bin/tip/tip/Makefile.depend b/usr.bin/tip/tip/Makefile.depend
new file mode 100644
index 000000000000..6ef78fac5cbf
--- /dev/null
+++ b/usr.bin/tip/tip/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcompiler_rt \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/tip/tip/acu.c b/usr.bin/tip/tip/acu.c
new file mode 100644
index 000000000000..a2c672eb888c
--- /dev/null
+++ b/usr.bin/tip/tip/acu.c
@@ -0,0 +1,187 @@
+/* $OpenBSD: acu.c,v 1.12 2006/03/17 14:43:06 moritz Exp $ */
+/* $NetBSD: acu.c,v 1.4 1996/12/29 10:34:03 cgd Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#include "tip.h"
+
+static acu_t *acu = NOACU;
+static int conflag;
+static void acuabort(int);
+static acu_t *acutype(char *);
+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 overridden
+ * 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 *
+con(void)
+{
+ 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 += strcspn(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(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(int s)
+{
+ signal(s, SIG_IGN);
+ longjmp(jmpbuf, 1);
+}
+
+static acu_t *
+acutype(char *s)
+{
+ acu_t *p;
+ extern acu_t acutable[];
+
+ for (p = acutable; p->acu_name != NULL; 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..67cfad514731
--- /dev/null
+++ b/usr.bin/tip/tip/acutab.c
@@ -0,0 +1,81 @@
+/* $OpenBSD: acutab.c,v 1.5 2006/03/17 19:17:13 moritz Exp $ */
+/* $NetBSD: acutab.c,v 1.3 1994/12/08 09:30:41 jtc Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#include "tip.h"
+
+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..28135f5accbd
--- /dev/null
+++ b/usr.bin/tip/tip/cmds.c
@@ -0,0 +1,991 @@
+/* $OpenBSD: cmds.c,v 1.26 2006/06/06 23:24:52 deraadt Exp $ */
+/* $NetBSD: cmds.c,v 1.7 1997/02/11 09:24:03 mrg Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#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 */
+
+static void transfer(char *, int, char *);
+static void stopsnd(int); /* SIGINT handler during file transfers */
+static void intcopy(int); /* interrupt routine for file transfers */
+static void transmit(FILE *, char *, char *);
+static void send(int);
+static void execute(char *);
+static int args(char *, char **, int);
+static void prtime(char *, time_t);
+static void tandem(char *);
+static void hardwareflow(char *);
+void linedisc(char *);
+static int anyof(char *, char *);
+
+/*
+ * FTP - remote ==> local
+ * get a file from the remote host
+ */
+void
+getfl(int c)
+{
+ char buf[256], *cp;
+
+ 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(int c)
+{
+ int fd, argc;
+ char line[BUFSIZ], *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 ''|tr '\\012' '\\01'", argv[0]);
+ transfer(line, fd, "\01");
+}
+
+static jmp_buf intbuf;
+
+/*
+ * Bulk transfer routine --
+ * used by getfl(), cu_take(), and pipefile()
+ */
+static void
+transfer(char *buf, int fd, char *eofchars)
+{
+ int ct, eof;
+ char c, buffer[BUFSIZ];
+ char *p = buffer;
+ size_t cnt;
+ time_t start;
+ sig_t f;
+ char r;
+
+ if (number(value(FRAMESIZE)) > BUFSIZ || number(value(FRAMESIZE)) < 1) {
+ printf("framesize must be >= 1 and <= %d\r\n", BUFSIZ);
+ close(fd);
+ return;
+ }
+
+ parwrite(FD, buf, size(buf));
+ quit = 0;
+ kill(tipout_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)) == (size_t)number(value(FRAMESIZE))) {
+ if ((size_t)write(fd, buffer, cnt) != cnt) {
+ printf("\r\nwrite error\r\n");
+ quit = 1;
+ }
+ p = buffer;
+ }
+ }
+ if ((cnt = (p-buffer)))
+ if ((size_t)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
+ */
+/*ARGSUSED*/
+void
+pipefile(int c)
+{
+ int pdes[2];
+ char buf[256];
+ int status, p;
+ pid_t cpid;
+
+ 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
+ */
+/*ARGSUSED*/
+static void
+stopsnd(int signo)
+{
+ stop = 1;
+ signal(SIGINT, SIG_IGN);
+}
+
+/*
+ * FTP - local ==> remote
+ * send local file to remote host
+ * terminate transmission with pseudo EOF sequence
+ */
+void
+sendfile(int c)
+{
+ FILE *fp;
+ char *fnamex;
+
+ putchar(c);
+ /*
+ * get file name
+ */
+ if (prompt("Local file name? ", fname, sizeof(fname)))
+ return;
+
+ /*
+ * look up file
+ */
+ fnamex = expand(fname);
+ if ((fp = fopen(fnamex, "r")) == NULL) {
+ printf("%s: cannot open\r\n", fname);
+ return;
+ }
+ transmit(fp, value(EOFWRITE), NULL);
+ if (!boolean(value(ECHOCHECK)))
+ tcdrain(FD);
+}
+
+/*
+ * Bulk transfer routine to remote host --
+ * used by sendfile() and cu_put()
+ */
+static void
+transmit(FILE *fp, char *eofchars, char *command)
+{
+ char *pc, lastc;
+ int c, ccount, lcount;
+ time_t start_t, stop_t;
+ sig_t f;
+
+ kill(tipout_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(fp);
+ 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((unsigned int)lvalue(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(fp);
+ 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
+ */
+/*ARGSUSED*/
+void
+cu_put(int c)
+{
+ FILE *fp;
+ char line[BUFSIZ];
+ int argc;
+ 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 ((fp = 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(fp, "\04", line);
+}
+
+/*
+ * FTP - send single character
+ * wait for echo & handle timeout
+ */
+static void
+send(int c)
+{
+ char cc;
+ int retry = 0;
+
+ cc = c;
+ parwrite(FD, &cc, 1);
+ if (number(value(CDELAY)) > 0 && c != '\r')
+ usleep(number(value(CDELAY)));
+ if (!boolean(value(ECHOCHECK))) {
+ if (number(value(LDELAY)) > 0 && c == '\r')
+ usleep(number(value(LDELAY)));
+ return;
+ }
+tryagain:
+ timedout = 0;
+ alarm((unsigned int)lvalue(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;
+ }
+}
+
+/*ARGSUSED*/
+void
+timeout(int signo)
+{
+ 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(int c)
+{
+ char buf[256];
+ int status, p;
+ pid_t cpid;
+ time_t start = time(NULL);
+
+ putchar(c);
+ if (prompt("Local command? ", buf, sizeof(buf)))
+ return;
+ kill(tipout_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 stderr
+ */
+void
+consh(int c)
+{
+ char buf[256];
+ int status, p;
+ pid_t cpid;
+ time_t start = time(NULL);
+
+ putchar(c);
+ if (prompt("Local command? ", buf, sizeof(buf)))
+ return;
+ kill(tipout_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
+ */
+/*ARGSUSED*/
+void
+shell(int c)
+{
+ int status;
+ char *cp;
+ pid_t shpid;
+
+ 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(void)
+{
+ char c;
+
+ /*
+ * enable TIPOUT side for dialogue
+ */
+ kill(tipout_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
+ */
+/*ARGSUSED*/
+void
+chdirectory(int c)
+{
+ 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(char *msg)
+{
+
+ signal(SIGTERM, SIG_IGN);
+ kill(tipout_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();
+ unexcl();
+ exit(0);
+}
+
+/*ARGSUSED*/
+void
+finish(int c)
+{
+ char *dismsg;
+
+ if ((dismsg = value(DISCONNECT)) != NOSTR) {
+ write(FD, dismsg, strlen(dismsg));
+ sleep(5);
+ }
+ tipabort(NOSTR);
+}
+
+/*ARGSUSED*/
+static void
+intcopy(int signo)
+{
+ raw();
+ quit = 1;
+ longjmp(intbuf, 1);
+}
+
+static void
+execute(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);
+}
+
+static int
+args(char *buf, char *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);
+}
+
+static void
+prtime(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");
+}
+
+/*ARGSUSED*/
+void
+variable(int c)
+{
+ char buf[256];
+
+ if (prompt("[set] ", buf, sizeof(buf)))
+ return;
+ vlex(buf);
+ if (vtable[BEAUTIFY].v_access&CHANGED) {
+ vtable[BEAUTIFY].v_access &= ~CHANGED;
+ kill(tipout_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);
+ }
+ if (vtable[HARDWAREFLOW].v_access&CHANGED) {
+ vtable[HARDWAREFLOW].v_access &= ~CHANGED;
+ if (boolean(value(HARDWAREFLOW)))
+ hardwareflow("on");
+ else
+ hardwareflow("off");
+ }
+ if (vtable[LINEDISC].v_access&CHANGED) {
+ vtable[LINEDISC].v_access &= ~CHANGED;
+ linedisc(NOSTR);
+ }
+}
+
+/*ARGSUSED*/
+void
+listvariables(int c)
+{
+ value_t *p;
+ char *buf;
+ char charbuf[5]; /* for vis(3), 4 chars for encoding, plus nul */
+
+ 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) {
+ buf = malloc(4*strlen(p->v_value) + 1);
+ if (buf == NULL) {
+ fprintf(stderr, "Unable to malloc()\n");
+ abort();
+ }
+ strvis(buf, p->v_value, VIS_WHITE);
+ printf(" %s", buf);
+ free(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(charbuf, character(p->v_value), VIS_WHITE, 0);
+ printf(" %s\r\n", charbuf);
+ break;
+ }
+ }
+}
+
+/*
+ * Turn tandem mode on or off for remote tty.
+ */
+static void
+tandem(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);
+}
+
+/*
+ * Turn hardware flow control on or off for remote tty.
+ */
+static void
+hardwareflow(char *option)
+{
+ struct termios rmtty;
+
+ tcgetattr(FD, &rmtty);
+ if (strcmp(option, "on") == 0)
+ rmtty.c_iflag |= CRTSCTS;
+ else
+ rmtty.c_iflag &= ~CRTSCTS;
+ tcsetattr(FD, TCSADRAIN, &rmtty);
+}
+
+/*
+ * Change line discipline to the specified one.
+ */
+void
+linedisc(char *option)
+{
+ int ld = (int)(intptr_t)value(LINEDISC);
+
+ ioctl(FD, TIOCSETD, &ld);
+}
+
+/*
+ * Send a break.
+ */
+/*ARGSUSED*/
+void
+genbrk(int c)
+{
+ ioctl(FD, TIOCSBRK, NULL);
+ sleep(1);
+ ioctl(FD, TIOCCBRK, NULL);
+}
+
+/*
+ * Suspend tip
+ */
+void
+suspend(int c)
+{
+ unraw();
+ kill(c == CTRL('y') ? getpid() : 0, SIGTSTP);
+ raw();
+}
+
+/*
+ * expand a file name if it includes shell meta characters
+ */
+char *
+expand(char name[])
+{
+ static char xname[BUFSIZ];
+ char cmdbuf[BUFSIZ];
+ int l;
+ char *cp, *Shell;
+ int s, pivec[2];
+ pid_t pid;
+
+ 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?
+ */
+static int
+anyof(char *s1, char *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..7219a45355ff
--- /dev/null
+++ b/usr.bin/tip/tip/cmdtab.c
@@ -0,0 +1,58 @@
+/* $OpenBSD: cmdtab.c,v 1.7 2006/03/17 14:43:06 moritz Exp $ */
+/* $NetBSD: cmdtab.c,v 1.3 1994/12/08 09:30:46 jtc Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#include "tip.h"
+
+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, NULL, NULL }
+};
diff --git a/usr.bin/tip/tip/cu.1 b/usr.bin/tip/tip/cu.1
new file mode 100644
index 000000000000..5852a2a6e6d5
--- /dev/null
+++ b/usr.bin/tip/tip/cu.1
@@ -0,0 +1,511 @@
+.\"-
+.\" SPDX-License-Identifier: BSD-3-Clause
+.\"
+.\" $OpenBSD: cu.1,v 1.3 2006/06/07 06:35:59 mbalmer 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. 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.
+.\"
+.Dd April 22, 2017
+.Dt CU 1
+.Os
+.Sh NAME
+.Nm cu
+.Nd call UNIX over a serial line
+.Sh SYNOPSIS
+.Nm
+.Op Fl ehot
+.Op Fl a Ar acu
+.Op Fl l Ar line
+.Op Fl s Ar speed | Fl Ar speed
+.Op Ar phone-number
+.Sh DESCRIPTION
+The
+.Nm
+utility
+establishes 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.
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl a Ar acu
+Set the acu.
+.It Fl e
+Use even parity.
+If both
+.Fl e
+and
+.Fl o
+are given, then no parity is used
+(the default).
+.It Fl h
+Echo characters locally (half-duplex mode).
+.It Fl l Ar line
+Specify the line to use.
+Either of the forms like
+.Pa cuau0
+or
+.Pa /dev/cuau0
+are permitted.
+.It Fl o
+Use odd parity.
+If both
+.Fl e
+and
+.Fl o
+are given, then no parity is used
+(the default).
+.It Fl s Ar speed | Fl Ar speed
+Set the speed of the connection.
+The default is 9600.
+.It Fl t
+Connect via a hard-wired connection to a host on a dial-up line.
+.El
+.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 -width indent
+.It Ic ~^D No or Ic ~.
+Drop the connection and exit.
+Only the connection is dropped \(en the login session is not terminated.
+.It Ic ~c Op Ar name
+Change directory to
+.Ar name
+(no argument implies change to home directory).
+.It Ic ~!
+Escape to a shell (exiting the shell will return to
+.Nm ) .
+.It Ic ~>
+Copy file from local to remote.
+The
+.Nm
+utility
+prompts for the name of a local file to transmit.
+.It Ic ~<
+Copy file from remote to local.
+The
+.Nm
+utility
+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.
+This command causes the remote
+.Ux
+system to run the following command string,
+sending it the
+.Ar from
+file:
+.Pp
+.Dl "stty -echo; cat > 'to'; stty echo"
+.Pp
+If the
+.Ar to
+file is not specified, the
+.Ar 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
+.Ic ~p
+command, the
+.Ar to
+file defaults to the
+.Ar from
+file name if it is not specified.
+The remote host executes the following command string
+to send the file to
+.Nm :
+.Pp
+.Dl "cat 'from'; echo '' | tr '\e012' '\e01'"
+.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
+.Tn XMODEM .
+The child program will be run with the following arrangement of
+file descriptors:
+.Bd -literal -offset indent
+0 <-> remote tty in
+1 <-> remote tty out
+2 <-> local tty stderr
+.Ed
+.It Ic ~#
+Send a
+.Dv BREAK
+to the remote system.
+For systems which do not support the necessary
+.Fn ioctl
+call, the break is simulated by a sequence of line speed changes and
+.Dv DEL
+characters.
+.It Ic ~s
+Set a variable (see the discussion below).
+.It Ic ~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 ,
+the side that displays output from the remote host, is left running.
+.It Ic ~?
+Get a summary of the tilde escapes.
+.El
+.Pp
+When
+.Nm
+prompts for an argument, for example 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 the user to the remote machine.
+.Pp
+The
+.Nm
+utility
+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 Pq Pa ports/net/freebsd-uucp .
+.Pp
+During file transfers
+.Nm
+provides a running count of the number of lines transferred.
+When using the
+.Ic ~>
+and
+.Ic ~<
+commands, the
+.Va eofread
+and
+.Va 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 hardwareflow or tandem mode for flow control.
+If the remote system does not support hardwareflow or tandem mode,
+.Va echocheck
+may be set to indicate that
+.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.
+The
+.Nm
+utility
+supports a variety of auto-call units and modems with the
+.Va 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
+.Nm
+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
+The
+.Nm
+utility
+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
+.Ic ~s
+escape.
+The syntax for variables is patterned after
+.Xr vi 1
+and
+.Xr Mail 1 .
+Supplying
+.Dq Li 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 Li 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.
+Certain common variables have abbreviations.
+The following is a list of common variables, their abbreviations, and
+their default values:
+.Bl -tag -width indent
+.It Va baudrate
+.Pq Vt num
+The baud rate at which the connection was established;
+abbreviated
+.Va ba .
+.It Va beautify
+.Pq Vt bool
+Discard unprintable characters when a session is being
+scripted; abbreviated
+.Va be .
+.It Va dialtimeout
+.Pq Vt num
+When dialing a phone number, the time (in seconds) to wait for a
+connection to be established; abbreviated
+.Va dial .
+.It Va echocheck
+.Pq Vt bool
+Synchronize with the remote host during file transfer by
+waiting for the echo of the last character transmitted; default is
+.Cm off .
+.It Va eofread
+.Pq Vt str
+The set of characters which signify an end-of-transmission
+during a
+.Ic ~<
+file transfer command; abbreviated
+.Va eofr .
+.It Va eofwrite
+.Pq Vt str
+The string sent to indicate end-of-transmission during a
+.Ic ~>
+file transfer command; abbreviated
+.Va eofw .
+.It Va eol
+.Pq Vt str
+The set of characters which indicate an end-of-line.
+The
+.Nm
+utility
+will recognize escape characters only after an end-of-line.
+.It Va escape
+.Pq Vt char
+The command prefix (escape) character; abbreviated
+.Va es ;
+default value is
+.Ql ~ .
+.It Va exceptions
+.Pq Vt str
+The set of characters which should not be discarded due to the
+beautification switch; abbreviated
+.Va ex ;
+default value is
+.Dq Li \et\en\ef\eb .
+.It Va force
+.Pq Vt char
+The character used to force literal data transmission;
+abbreviated
+.Va fo ;
+default value is
+.Ql ^P .
+.It Va framesize
+.Pq Vt num
+The amount of data (in bytes) to buffer between file system
+writes when receiving files; abbreviated
+.Va fr .
+.It Va hardwareflow
+.Pq Vt bool
+Whether hardware flow control (CRTSCTS) is enabled for the
+connection; abbreviated
+.Va hf ;
+default value is
+.Cm off .
+.It Va host
+.Pq Vt str
+The name of the host to which you are connected; abbreviated
+.Va ho .
+.It Va linedisc
+.Pq Vt num
+The line discipline to use; abbreviated
+.Va ld .
+.It Va prompt
+.Pq Vt char
+The character which indicates an end-of-line on the remote
+host; abbreviated
+.Va 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 Va raise
+.Pq Vt bool
+Upper case mapping mode; abbreviated
+.Va ra ;
+default value is
+.Cm off .
+When this mode is enabled, all lowercase letters will be mapped to
+uppercase by
+.Nm
+for transmission to the remote machine.
+.It Va raisechar
+.Pq Vt char
+The input character used to toggle uppercase mapping mode;
+abbreviated
+.Va rc ;
+not set by default.
+.It Va record
+.Pq Vt str
+The name of the file in which a session script is recorded;
+abbreviated
+.Va rec .
+.It Va script
+.Pq Vt bool
+Session scripting mode; abbreviated
+.Va sc ;
+default is
+.Cm off .
+When
+.Va script
+is
+.Cm true ,
+.Nm
+will record everything transmitted by the remote machine in the script
+record file specified in
+.Va record .
+If the
+.Va beautify
+switch is on, only printable
+.Tn ASCII
+characters will be included in the script file (those characters
+between 040 and 0177).
+The variable
+.Va exceptions
+is used to indicate characters which are an exception to the normal
+beautification rules.
+.It Va tabexpand
+.Pq Vt bool
+Expand tabs to spaces during file transfers; abbreviated
+.Va tab ;
+default value is
+.Cm false .
+Each tab is expanded to 8 spaces.
+.It Va tandem
+.Pq Vt bool
+Use XON/XOFF flow control to throttle data from the remote host;
+abbreviated
+.Va ta .
+The default value is
+.Cm true .
+.It Va verbose
+.Pq Vt bool
+Verbose mode; abbreviated
+.Va verb ;
+default is
+.Cm 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 indent
+.It Ev HOME
+The home directory to use for the
+.Ic ~c
+command.
+.It Ev SHELL
+The name of the shell to use for the
+.Ic ~!
+command; default value is
+.Dq Li /bin/sh .
+.El
+.Sh FILES
+.Bl -tag -width ".Pa /var/spool/lock/LCK..*" -compact
+.It Pa /var/log/aculog
+line access log
+.It Pa /var/spool/lock/LCK..*
+lock file to avoid conflicts with
+.Xr uucp 1 Pq Pa ports/net/freebsd-uucp
+.El
+.Sh EXAMPLES
+Connect to the first USB serial port at the speed of 115200 baud:
+.Bd -literal -offset indent
+cu -s 115200 -l /dev/cuaU0
+.Ed
+.Sh SEE ALSO
+.Xr tip 1
+.Sh HISTORY
+The
+.Nm
+command appeared 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/cu.c b/usr.bin/tip/tip/cu.c
new file mode 100644
index 000000000000..6811432d19c3
--- /dev/null
+++ b/usr.bin/tip/tip/cu.c
@@ -0,0 +1,202 @@
+/* $OpenBSD: cu.c,v 1.19 2006/05/25 08:41:52 jmc Exp $ */
+/* $NetBSD: cu.c,v 1.5 1997/02/11 09:24:05 mrg Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#include "tip.h"
+
+static void cuusage(void);
+
+/*
+ * Botch the interface to look like cu's
+ */
+void
+cumain(int argc, char *argv[])
+{
+ int ch, i, parity;
+ long l;
+ char *cp;
+ static char sbuf[12];
+
+ if (argc < 2)
+ cuusage();
+ CU = DV = NOSTR;
+ BR = DEFBR;
+ parity = 0; /* none */
+
+ /*
+ * We want to accept -# as a speed. It's easiest to look through
+ * the arguments, replace -# with -s#, and let getopt() handle it.
+ */
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-' &&
+ argv[i][1] >= '0' && argv[i][1] <= '9') {
+ asprintf(&cp, "-s%s", argv[i] + 1);
+ if (cp == NULL) {
+ fprintf(stderr,
+ "%s: cannot convert -# to -s#\n",
+ __progname);
+ exit(3);
+ }
+ argv[i] = cp;
+ }
+ }
+
+ while ((ch = getopt(argc, argv, "a:l:s:htoe")) != -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) {
+ 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':
+ if (parity != 0)
+ parity = 0; /* -e -o */
+ else
+ parity = 1; /* odd */
+ break;
+ case 'e':
+ if (parity != 0)
+ parity = 0; /* -o -e */
+ else
+ parity = -1; /* even */
+ 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);
+ signal(SIGCHLD, SIG_DFL);
+
+ /*
+ * 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();
+ switch (parity) {
+ case -1:
+ setparity("even");
+ break;
+ case 1:
+ setparity("odd");
+ break;
+ default:
+ setparity("none");
+ break;
+ }
+ setboolean(value(VERBOSE), FALSE);
+ if (HW && ttysetup(BR)) {
+ fprintf(stderr, "%s: unsupported speed %ld\n",
+ __progname, BR);
+ daemon_uid();
+ (void)uu_unlock(uucplock);
+ exit(3);
+ }
+ if (con()) {
+ printf("Connect failed\n");
+ daemon_uid();
+ (void)uu_unlock(uucplock);
+ exit(1);
+ }
+ if (!HW && ttysetup(BR)) {
+ fprintf(stderr, "%s: unsupported speed %ld\n",
+ __progname, BR);
+ daemon_uid();
+ (void)uu_unlock(uucplock);
+ exit(3);
+ }
+}
+
+static void
+cuusage(void)
+{
+ fprintf(stderr, "usage: cu [-ehot] [-a acu] [-l line] "
+ "[-s speed | -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..f4795091cb88
--- /dev/null
+++ b/usr.bin/tip/tip/hunt.c
@@ -0,0 +1,101 @@
+/* $OpenBSD: hunt.c,v 1.13 2006/03/17 19:39:46 deraadt Exp $ */
+/* $NetBSD: hunt.c,v 1.6 1997/04/20 00:02:10 mellon Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#include "tip.h"
+
+static jmp_buf deadline;
+static int deadfl;
+
+static void dead(int);
+
+/*ARGSUSED*/
+static void
+dead(int signo)
+{
+ deadfl = 1;
+ longjmp(deadline, 1);
+}
+
+long
+hunt(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..5a3dc6e25ddc
--- /dev/null
+++ b/usr.bin/tip/tip/log.c
@@ -0,0 +1,84 @@
+/* $OpenBSD: log.c,v 1.8 2006/03/16 19:32:46 deraadt Exp $ */
+/* $NetBSD: log.c,v 1.4 1994/12/24 17:56:28 cgd Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#include "tip.h"
+
+#ifdef ACULOG
+static FILE *flog = NULL;
+
+/*
+ * Log file maintenance routines
+ */
+void
+logent(char *group, char *num, char *acu, char *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(void)
+{
+ 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..c15482811c67
--- /dev/null
+++ b/usr.bin/tip/tip/partab.c
@@ -0,0 +1,55 @@
+/* $OpenBSD: partab.c,v 1.5 2003/06/03 02:56:18 millert Exp $ */
+/* $NetBSD: partab.c,v 1.4 1996/12/29 10:38:21 cgd Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+/*
+ * 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..6bed255589de
--- /dev/null
+++ b/usr.bin/tip/tip/pathnames.h
@@ -0,0 +1,40 @@
+/* $OpenBSD: pathnames.h,v 1.3 2003/06/03 02:56:18 millert Exp $ */
+/* $NetBSD: pathnames.h,v 1.3 1994/12/08 09:30:59 jtc Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#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/phones b/usr.bin/tip/tip/phones
new file mode 100644
index 000000000000..597b0002ec82
--- /dev/null
+++ b/usr.bin/tip/tip/phones
@@ -0,0 +1,5 @@
+# phones -- remote host phone number data base
+# see tip(1), phones(5)
+# examples:
+#system1 9=2225551212
+#system2 9995551212
diff --git a/usr.bin/tip/tip/remote b/usr.bin/tip/tip/remote
new file mode 100644
index 000000000000..3f3f3b701bb6
--- /dev/null
+++ b/usr.bin/tip/tip/remote
@@ -0,0 +1,72 @@
+# remote -- remote host description file
+# see tip(1), remote(5)
+#
+# at ACU type
+# br bit rate (defaults to 9600)
+# cu call unit (default is dv)
+# du make a call flag (dial up)
+# dv device to use for the tty
+# el EOL marks (default is NULL)
+# fs frame size (default is BUFSIZ) -- used in buffering writes on
+# receive operations
+# ie input EOF marks (default is NULL)
+# oe output EOF string (default is NULL)
+# pa The parity type to use: even, odd, none, zero, one (default even)
+# pn phone numbers (@ =>'s search phones file; possibly taken from
+# PHONES environment variable)
+# tc to continue a capability
+
+# Example systems
+unixshell|Unix Access:\
+ :pn=\@:tc=unix57600:
+dosbbs|DOS-based BBS:\
+ :pn=\@:tc=dos57600:
+
+# UNIX system definitions
+unix57600|57600 Baud dial-out to a UNIX system:\
+ :el=^U^C^R^O^D^S^Q:ie=%$:oe=^D:tc=dial57600:
+unix33600|33600 Baud dial-out to a UNIX system:\
+ :el=^U^C^R^O^D^S^Q:ie=%$:oe=^D:tc=dial33600:
+
+# DOS system definitions
+dos57600|57600 Baud dial-out to a DOS system:\
+ :el=^U^C^R^O^D^S^Q:ie=%$:oe=^Z:pa=none:tc=dial57600:
+
+# 33.6k and 56k modems run the com port at 115200 bps to allow for the
+# compression performed in the modem. Note that some serial hardware
+# does not support speeds above 38400 bps and that speeds above that have
+# never been formally standardized. Modern architectures with 16550 or
+# better UARTs typically have no issues with the higher speeds.
+dial57600|57600 Baud Hayes attributes:\
+ br#115200:tc=dial:
+dial33600|33600 Baud Hayes attributes:\
+ br#115200:tc=dial:
+# 14.4k and 28.8k modems ran the port at 4x. Some rare 19.2 baud modems
+# did too, but those aren't included in this example.
+dial28800|28800 Baud Hayes attributes:\
+ br#115200:tc=dial:
+dial14400|14400 Baud Hayes attributes:\
+ br#57600:tc=dial:
+dial|Generic dialing parameters:\
+ :dv=/dev/cuau0:cu=/dev/cuau0:at=hayes:du:pa=none:
+
+# Hardwired line
+cuau0c|cua0c:dv=/dev/cuau0:br#9600:pa=none:
+
+# Finger friendly shortcuts
+uart0|com1:dv=/dev/cuau0:br#9600:pa=none:
+uart1|com2:dv=/dev/cuau1:br#9600:pa=none:
+uart2|com3:dv=/dev/cuau2:br#9600:pa=none:
+uart3|com4:dv=/dev/cuau3:br#9600:pa=none:
+uart4|com5:dv=/dev/cuau4:br#9600:pa=none:
+uart5|com6:dv=/dev/cuau5:br#9600:pa=none:
+uart6|com7:dv=/dev/cuau6:br#9600:pa=none:
+uart7|com8:dv=/dev/cuau7:br#9600:pa=none:
+ucom1:dv=/dev/cuaU0:br#9600:pa=none:
+ucom2:dv=/dev/cuaU1:br#9600:pa=none:
+ucom3:dv=/dev/cuaU2:br#9600:pa=none:
+ucom4:dv=/dev/cuaU3:br#9600:pa=none:
+ucom5:dv=/dev/cuaU4:br#9600:pa=none:
+ucom6:dv=/dev/cuaU5:br#9600:pa=none:
+ucom7:dv=/dev/cuaU6:br#9600:pa=none:
+ucom8:dv=/dev/cuaU7:br#9600:pa=none:
diff --git a/usr.bin/tip/tip/remote.c b/usr.bin/tip/tip/remote.c
new file mode 100644
index 000000000000..00ce25f52b5c
--- /dev/null
+++ b/usr.bin/tip/tip/remote.c
@@ -0,0 +1,228 @@
+/* $OpenBSD: remote.c,v 1.16 2006/06/06 23:24:52 deraadt Exp $ */
+/* $NetBSD: remote.c,v 1.5 1997/04/20 00:02:45 mellon Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#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(char *);
+
+static void
+getremcap(char *host)
+{
+ char **p, ***q, *bp, *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 != NULL) ||
+ (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 (!LD && (cgetnum(bp, "ld", &LD) == -1))
+ LD = TTYDISC;
+ 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 (cgetflag("hf"))
+ setboolean(value(HARDWAREFLOW), 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(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..136ba8d28389
--- /dev/null
+++ b/usr.bin/tip/tip/tip.1
@@ -0,0 +1,605 @@
+.\" $OpenBSD: tip.1,v 1.37 2006/06/07 06:35:59 mbalmer 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. 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.
+.\"
+.Dd April 28, 2018
+.Dt TIP 1
+.Os
+.Sh NAME
+.Nm tip
+.Nd connect to a remote system
+.Sh SYNOPSIS
+.Nm
+.Op Fl nv
+.Op Fl Ar speed
+.Op Ar system-name
+.Sh DESCRIPTION
+The
+.Nm
+utility
+establishes 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.
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl n
+No escape (disable tilde).
+.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
+.Dq Li tip
+with
+.Ar speed
+appended.
+For example,
+.Nm Fl 1200
+will set
+.Ar system-name
+to
+.Dq Li 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 -width indent
+.It Ic ~^D No or Ic ~.
+Drop the connection and exit.
+Only the connection is dropped \(en the login session is not terminated.
+.It Ic ~c Op Ar name
+Change directory to
+.Ar name
+(no argument implies change to home directory).
+.It Ic ~!
+Escape to a shell (exiting the shell will return to
+.Nm ) .
+.It Ic ~>
+Copy file from local to remote.
+The
+.Nm
+utility
+prompts for the name of a local file to transmit.
+.It Ic ~<
+Copy file from remote to local.
+The
+.Nm
+utility
+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.
+This command causes the remote
+.Ux
+system to run the following command string,
+sending it the
+.Ar from
+file:
+.Pp
+.Dl "stty -echo; cat > 'to'; stty echo"
+.Pp
+If the
+.Ar to
+file is not specified, the
+.Ar 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
+.Ic ~p
+command, the
+.Ar to
+file defaults to the
+.Ar from
+file name if it is not specified.
+The remote host executes the following command string
+to send the file to
+.Nm :
+.Pp
+.Dl "cat 'from'; echo '' | tr '\e012' '\e01'"
+.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
+.Tn XMODEM .
+The child program will be run with the following arrangement of
+file descriptors:
+.Bd -literal -offset indent
+0 <-> remote tty in
+1 <-> remote tty out
+2 <-> local tty stderr
+.Ed
+.It Ic ~#
+Send a
+.Dv BREAK
+to the remote system.
+For systems which do not support the necessary
+.Fn ioctl
+call, the break is simulated by a sequence of line speed changes and
+.Dv DEL
+characters.
+.It Ic ~s
+Set a variable (see the discussion below).
+.It Ic ~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 ,
+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 as follows:
+.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
+.Va br
+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.\&
+.Dq Li "tip -300 mds" .
+.Pp
+When
+.Nm
+establishes a connection, it sends out the connection message
+specified in the
+.Va cm
+capability of the system description being used.
+.Pp
+When
+.Nm
+prompts for an argument, for example 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 the user to the remote machine.
+.Pp
+The
+.Nm
+utility
+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 Pq Pa ports/net/freebsd-uucp .
+.Pp
+During file transfers
+.Nm
+provides a running count of the number of lines transferred.
+When using the
+.Ic ~>
+and
+.Ic ~<
+commands, the
+.Va eofread
+and
+.Va 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 hardwareflow or tandem mode for flow control.
+If the remote system does not support hardwareflow or tandem mode,
+.Va echocheck
+may be set to indicate that
+.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.
+The
+.Nm
+utility
+supports a variety of auto-call units and modems with the
+.Va 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
+.Nm
+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
+The
+.Nm
+utility
+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
+.Ic ~s
+escape.
+The syntax for variables is patterned after
+.Xr vi 1
+and
+.Xr Mail 1 .
+Supplying
+.Dq Li 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 Li 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
+.Ic ~s
+prefix) in the initialization file
+.Pa ~/.tiprc ;
+the
+.Fl v
+option additionally 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 indent
+.It Va baudrate
+.Pq Vt num
+The baud rate at which the connection was established;
+abbreviated
+.Va ba .
+.It Va beautify
+.Pq Vt bool
+Discard unprintable characters when a session is being
+scripted; abbreviated
+.Va be .
+.It Va dialtimeout
+.Pq Vt num
+When dialing a phone number, the time (in seconds) to wait for a
+connection to be established; abbreviated
+.Va dial .
+.It Va echocheck
+.Pq Vt bool
+Synchronize with the remote host during file transfer by
+waiting for the echo of the last character transmitted; default is
+.Cm off .
+.It Va eofread
+.Pq Vt str
+The set of characters which signify an end-of-transmission
+during a
+.Ic ~<
+file transfer command; abbreviated
+.Va eofr .
+.It Va eofwrite
+.Pq Vt str
+The string sent to indicate end-of-transmission during a
+.Ic ~>
+file transfer command; abbreviated
+.Va eofw .
+.It Va eol
+.Pq Vt str
+The set of characters which indicate an end-of-line.
+The
+.Nm
+utility
+will recognize escape characters only after an end-of-line.
+.It Va escape
+.Pq Vt char
+The command prefix (escape) character; abbreviated
+.Va es ;
+default value is
+.Ql ~ .
+.It Va exceptions
+.Pq Vt str
+The set of characters which should not be discarded due to the
+beautification switch; abbreviated
+.Va ex ;
+default value is
+.Dq Li \et\en\ef\eb .
+.It Va force
+.Pq Vt char
+The character used to force literal data transmission;
+abbreviated
+.Va fo ;
+default value is
+.Ql ^P .
+.It Va framesize
+.Pq Vt num
+The amount of data (in bytes) to buffer between file system
+writes when receiving files; abbreviated
+.Va fr .
+.It Va hardwareflow
+.Pq Vt bool
+Whether hardware flow control (CRTSCTS) is enabled for the
+connection; abbreviated
+.Va hf ;
+default value is
+.Cm off .
+.It Va host
+.Pq Vt str
+The name of the host to which you are connected; abbreviated
+.Va ho .
+.It Va linedisc
+.Pq Vt num
+The line discipline to use; abbreviated
+.Va ld .
+.It Va prompt
+.Pq Vt char
+The character which indicates an end-of-line on the remote
+host; abbreviated
+.Va 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 Va raise
+.Pq Vt bool
+Upper case mapping mode; abbreviated
+.Va ra ;
+default value is
+.Cm off .
+When this mode is enabled, all lowercase letters will be mapped to
+uppercase by
+.Nm
+for transmission to the remote machine.
+.It Va raisechar
+.Pq Vt char
+The input character used to toggle uppercase mapping mode;
+abbreviated
+.Va rc ;
+not set by default.
+.It Va record
+.Pq Vt str
+The name of the file in which a session script is recorded;
+abbreviated
+.Va rec ;
+default value is
+.Pa tip.record .
+.It Va script
+.Pq Vt bool
+Session scripting mode; abbreviated
+.Va sc ;
+default is
+.Cm off .
+When
+.Va script
+is
+.Cm true ,
+.Nm
+will record everything transmitted by the remote machine in the script
+record file specified in
+.Va record .
+If the
+.Va beautify
+switch is on, only printable
+.Tn ASCII
+characters will be included in the script file (those characters
+between 040 and 0177).
+The variable
+.Va exceptions
+is used to indicate characters which are an exception to the normal
+beautification rules.
+.It Va tabexpand
+.Pq Vt bool
+Expand tabs to spaces during file transfers; abbreviated
+.Va tab ;
+default value is
+.Cm false .
+Each tab is expanded to 8 spaces.
+.It Va tandem
+.Pq Vt bool
+Use XON/XOFF flow control to throttle data from the remote host;
+abbreviated
+.Va ta .
+The default value is
+.Cm true
+unless the
+.Va nt
+capability has been specified in
+.Pa /etc/remote ,
+in which case the default value is
+.Cm false .
+.It Va verbose
+.Pq Vt bool
+Verbose mode; abbreviated
+.Va verb ;
+default is
+.Cm 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 indent
+.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 PHONES
+A path to a
+.Xr phones 5
+database.
+.It Ev REMOTE
+A system description, or an absolute path to a
+.Xr remote 5
+system description database.
+.It Ev SHELL
+The name of the shell to use for the
+.Ic ~!
+command; default value is
+.Dq Li /bin/sh .
+.El
+.Sh FILES
+.Bl -tag -width ".Pa /var/spool/lock/LCK..*" -compact
+.It Pa ~/.tiprc
+initialization file
+.It Pa tip.record
+record file
+.It Pa /etc/phones
+default
+.Xr phones 5
+file
+.It Pa /etc/remote
+global
+.Xr remote 5
+database
+.It Pa /var/log/aculog
+line access log
+.It Pa /var/spool/lock/LCK..*
+lock file to avoid conflicts with
+.Xr uucp 1 Pq Pa ports/net/freebsd-uucp
+.El
+.Sh EXAMPLES
+Connect to the first USB serial port at the speed of 115200 baud:
+.Bd -literal -offset indent
+tip ucom1 -115200
+.Ed
+.Sh SEE ALSO
+.Xr cu 1 ,
+.Xr phones 5 ,
+.Xr remote 5
+.Sh HISTORY
+The
+.Nm
+command appeared 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..9315bffddc84
--- /dev/null
+++ b/usr.bin/tip/tip/tip.c
@@ -0,0 +1,624 @@
+/* $OpenBSD: tip.c,v 1.30 2006/08/18 03:06:18 jason Exp $ */
+/* $NetBSD: tip.c,v 1.13 1997/04/20 00:03:05 mellon Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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 - UNIX link to other systems
+ * tip [-v] [-speed] system-name
+ * or
+ * cu phone-number [-s speed] [-l line] [-a acu]
+ */
+#define EXTERN
+#include "tip.h"
+#include "pathnames.h"
+
+int disc = TTYDISC; /* tip normally runs this way */
+char PNbuf[256]; /* This limits the size of a number */
+
+static void intprompt(int);
+static void tipin(void);
+static int escape(void);
+
+int
+main(int argc, char *argv[])
+{
+ char *sys = NOSTR, sbuf[12], *p;
+ int i;
+
+ /* XXX preserve previous braindamaged behavior */
+ setboolean(value(DC), TRUE);
+
+ 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] != '-')
+ sys = 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 (sys == NOSTR)
+ goto notnumber;
+ if (isalpha(*sys))
+ 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(sys) > sizeof PNbuf - 1) {
+ fprintf(stderr, "%s: phone number too long (max = %d bytes)\n",
+ __progname, (int)sizeof(PNbuf) - 1);
+ exit(1);
+ }
+ strlcpy(PNbuf, sys, sizeof PNbuf - 1);
+ for (p = sys; *p; p++)
+ *p = '\0';
+ PN = PNbuf;
+ (void)snprintf(sbuf, sizeof(sbuf), "tip%ld", BR);
+ sys = sbuf;
+
+notnumber:
+ (void)signal(SIGINT, cleanup);
+ (void)signal(SIGQUIT, cleanup);
+ (void)signal(SIGHUP, cleanup);
+ (void)signal(SIGTERM, cleanup);
+ (void)signal(SIGCHLD, SIG_DFL);
+
+ if ((i = hunt(sys)) == 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 */
+
+ /*
+ * 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(number(value(BAUDRATE)))) {
+ fprintf(stderr, "%s: bad baud rate %ld\n", __progname,
+ number(value(BAUDRATE)));
+ daemon_uid();
+ (void)uu_unlock(uucplock);
+ exit(3);
+ }
+ if ((p = con())) {
+ printf("\07%s\n[EOT]\n", p);
+ daemon_uid();
+ (void)uu_unlock(uucplock);
+ exit(1);
+ }
+ if (!HW && ttysetup(number(value(BAUDRATE)))) {
+ fprintf(stderr, "%s: bad baud rate %ld\n", __progname,
+ number(value(BAUDRATE)));
+ daemon_uid();
+ (void)uu_unlock(uucplock);
+ exit(3);
+ }
+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(0);
+ }
+ i = fcntl(FD, F_SETFL, i & ~O_NONBLOCK);
+ if (i == -1) {
+ perror("fcntl");
+ cleanup(0);
+ }
+
+ tcgetattr(0, &defterm);
+ gotdefterm = 1;
+ 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);
+
+ if (value(LINEDISC) != TTYDISC) {
+ int ld = (int)(intptr_t)value(LINEDISC);
+ ioctl(FD, TIOCSETD, &ld);
+ }
+
+ /*
+ * 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");
+ tipin_pid = getpid();
+ if ((tipout_pid = fork()))
+ tipin();
+ else
+ tipout();
+ exit(0);
+}
+
+void
+cleanup(int signo)
+{
+ daemon_uid();
+ (void)uu_unlock(uucplock);
+ if (odisc)
+ ioctl(0, TIOCSETD, &odisc);
+ unraw();
+ if (signo && tipout_pid) {
+ kill(tipout_pid, signo);
+ wait(NULL);
+ }
+ 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(void)
+{
+ if (uidswapped == 0) {
+ seteuid(uid);
+ uidswapped = 1;
+ }
+}
+
+void
+daemon_uid(void)
+{
+
+ if (uidswapped) {
+ seteuid(euid);
+ uidswapped = 0;
+ }
+}
+
+void
+shell_uid(void)
+{
+ setegid(gid);
+ seteuid(uid);
+}
+
+/*
+ * put the controlling keyboard into raw mode
+ */
+void
+raw(void)
+{
+ tcsetattr(0, TCSADRAIN, &term);
+}
+
+
+/*
+ * return keyboard to normal mode
+ */
+void
+unraw(void)
+{
+ if (gotdefterm)
+ tcsetattr(0, TCSADRAIN, &defterm);
+}
+
+/*
+ * give up exclusive tty access
+ */
+void
+unexcl()
+{
+ ioctl(FD, TIOCNXCL, 0);
+}
+
+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(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
+ */
+/*ARGSUSED*/
+static void
+intprompt(int signo)
+{
+ (void)signal(SIGINT, SIG_IGN);
+ stoprompt = 1;
+ printf("\r\n");
+ longjmp(promptbuf, 1);
+}
+
+/*
+ * ****TIPIN TIPIN****
+ */
+static void
+tipin(void)
+{
+ int bol = 1;
+ int gch;
+ char ch;
+
+ /*
+ * 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();
+ if (gch == EOF)
+ return;
+ gch = gch & STRIP_PAR;
+ if ((gch == character(value(ESCAPE))) && bol) {
+ if (!noesc) {
+ gch = escape();
+ if (gch == EOF)
+ return;
+ if (gch == 0)
+ continue;
+ }
+ } else if (!cumode && gch == character(value(RAISECHAR))) {
+ setboolean(value(RAISE), !boolean(value(RAISE)));
+ continue;
+ } else if (gch == '\r') {
+ bol = 1;
+ ch = gch;
+ parwrite(FD, &ch, 1);
+ if (boolean(value(HALFDUPLEX)))
+ printf("\r\n");
+ continue;
+ } else if (!cumode && gch == character(value(FORCE))) {
+ gch = getchar();
+ if (gch == EOF)
+ return;
+ gch = gch & STRIP_PAR;
+ }
+ bol = any(gch, value(EOL));
+ if (boolean(value(RAISE)) && islower(gch))
+ gch = toupper(gch);
+ ch = gch;
+ parwrite(FD, &ch, 1);
+ if (boolean(value(HALFDUPLEX)))
+ printf("%c", ch);
+ }
+}
+
+extern esctable_t etable[];
+
+/*
+ * Escape handler --
+ * called on recognition of ``escapec'' at the beginning of a line
+ */
+static int
+escape(void)
+{
+ int gch;
+ esctable_t *p;
+ char c = character(value(ESCAPE));
+
+ gch = getchar();
+ if (gch == EOF)
+ return (EOF);
+ gch = gch & 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
+any(int cc, char *p)
+{
+ char c = cc;
+ while (p && *p)
+ if (*p++ == c)
+ return (1);
+ return (0);
+}
+
+size_t
+size(char *s)
+{
+ size_t i = 0;
+
+ while (s && *s++)
+ i++;
+ return (i);
+}
+
+char *
+interp(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(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(int 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
+ */
+int
+ttysetup(int speed)
+{
+ struct termios cntrl;
+
+ if (tcgetattr(FD, &cntrl))
+ return (-1);
+ cfsetspeed(&cntrl, speed);
+ cntrl.c_cflag &= ~(CSIZE|PARENB);
+ cntrl.c_cflag |= CS8;
+ if (boolean(value(DC)))
+ cntrl.c_cflag |= CLOCAL;
+ if (boolean(value(HARDWAREFLOW)))
+ cntrl.c_cflag |= CRTSCTS;
+ 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;
+ return (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(int fd, char *buf, size_t n)
+{
+ size_t 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 || errno == ENXIO)
+ tipabort("Lost carrier.");
+ /* this is questionable */
+ perror("write");
+ }
+}
+
+/*
+ * Build a parity table with appropriate high-order bit.
+ */
+void
+setparity(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..7e65fcb832c5
--- /dev/null
+++ b/usr.bin/tip/tip/tip.h
@@ -0,0 +1,355 @@
+/* $OpenBSD: tip.h,v 1.27 2006/08/18 03:06:18 jason Exp $ */
+/* $NetBSD: tip.h,v 1.7 1997/04/20 00:02:46 mellon Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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 - 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>
+
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+
+/*
+ * Remote host attributes
+ */
+EXTERN char *DV; /* UNIX device(s) to open */
+EXTERN char *EL; /* chars marking an EOL */
+EXTERN char *CM; /* initial connection message */
+EXTERN char *IE; /* EOT to expect on input */
+EXTERN char *OE; /* EOT to send to complete FT */
+EXTERN char *CU; /* call unit if making a phone call */
+EXTERN char *AT; /* acu type */
+EXTERN char *PN; /* phone number(s) */
+EXTERN char *DI; /* disconnect string */
+EXTERN char *PA; /* parity to be generated */
+
+EXTERN char *PH; /* phone number file */
+EXTERN char *RM; /* remote file name */
+EXTERN char *HO; /* host name */
+
+EXTERN long BR; /* line speed for conversation */
+EXTERN long FS; /* frame size for transfers */
+
+EXTERN short DU; /* this host is dialed up */
+EXTERN short HW; /* this device is hardwired, see hunt.c */
+EXTERN char *ES; /* escape character */
+EXTERN char *EX; /* exceptions */
+EXTERN char *FO; /* force (literal next) char*/
+EXTERN char *RC; /* raise character */
+EXTERN char *RE; /* script record file */
+EXTERN char *PR; /* remote prompt */
+EXTERN long DL; /* line delay for file transfers to remote */
+EXTERN long CL; /* char delay for file transfers to remote */
+EXTERN long ET; /* echocheck timeout */
+EXTERN long LD; /* line disc */
+EXTERN short HD; /* this host is half duplex - do local echo */
+
+/*
+ * String value table
+ */
+typedef
+ struct {
+ char *v_name; /* whose name is it */
+ char v_type; /* for interpreting set's */
+ char v_access; /* protection of touchy ones */
+ char *v_abrev; /* possible abbreviation */
+ 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)(char *, char *);
+ void (*acu_disconnect)(void);
+ void (*acu_abort)(void);
+ }
+ 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 lvalue(v) (long)(intptr_t)vtable[v].v_value
+
+#define number(v) ((long)(intptr_t)(v))
+#define boolean(v) ((short)(intptr_t)(v))
+#define character(v) ((char)(intptr_t)(v))
+
+#define setnumber(v,n) do { (v) = (char *)(intptr_t)(n); } while (0)
+#define setboolean(v,n) do { (v) = (char *)(intptr_t)(n); } while (0)
+#define setcharacter(v,n) do { (v) = (char *)(intptr_t)(n); } while (0)
+
+/*
+ * Escape command table definitions --
+ * lookup in this table is performed when ``escapec'' is recognized
+ * at the beginning of a line (as defined by the eolmarks variable).
+*/
+
+typedef
+ struct {
+ char e_char; /* char to match on */
+ char e_flags; /* experimental, privileged */
+ char *e_help; /* help string */
+ void (*e_func)(int); /* command */
+ }
+ esctable_t;
+
+#define NORM 00 /* normal protection, execute anyone */
+#define EXP 01 /* experimental, mark it with a `*' on help */
+#define PRIV 02 /* privileged, 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 HARDWAREFLOW 33
+#define LINEDISC 34
+#define DC 35
+
+#define NOVAL ((value_t *)NULL)
+#define NOACU ((acu_t *)NULL)
+#define NOSTR ((char *)NULL)
+#define NOFILE ((FILE *)NULL)
+#define NOPWD ((struct passwd *)0)
+
+EXTERN struct termios term; /* current mode of terminal */
+EXTERN struct termios defterm; /* initial mode of terminal */
+EXTERN struct termios defchars; /* current mode with initial chars */
+EXTERN int gotdefterm;
+
+EXTERN FILE *fscript; /* FILE for scripting */
+
+EXTERN int fildes[2]; /* file transfer synchronization channel */
+EXTERN int repdes[2]; /* read process synchronization channel */
+EXTERN int FD; /* open file descriptor to remote host */
+EXTERN int AC; /* open file descriptor to dialer (v831 only) */
+EXTERN int vflag; /* print .tiprc initialization sequence */
+EXTERN int noesc; /* no `~' escape char */
+EXTERN int sfd; /* for ~< operation */
+EXTERN pid_t tipin_pid; /* pid of tipin */
+EXTERN pid_t tipout_pid; /* pid of tipout */
+EXTERN uid_t uid, euid; /* real and effective user id's */
+EXTERN gid_t gid, egid; /* real and effective group id's */
+EXTERN int stop; /* stop transfer session flag */
+EXTERN int quit; /* same; but on other end */
+EXTERN int intflag; /* recognized interrupt */
+EXTERN int stoprompt; /* for interrupting a prompt session */
+EXTERN int timedout; /* ~> transfer timedout */
+EXTERN int cumode; /* simulating the "cu" program */
+EXTERN int bits8; /* terminal is 8-bit mode */
+#define STRIP_PAR (bits8 ? 0377 : 0177)
+
+EXTERN char fname[PATH_MAX]; /* file name buffer for ~< */
+EXTERN char copyname[PATH_MAX]; /* file name buffer for ~> */
+EXTERN char ccc; /* synchronization character */
+EXTERN char *uucplock; /* name of lock file for uucp's */
+
+EXTERN int odisc; /* initial tty line discipline */
+extern int disc; /* current tty discpline */
+
+extern char *__progname; /* program name */
+
+char *con(void);
+char *ctrl(char);
+char *expand(char *);
+char *getremote(char *);
+char *interp(char *);
+int any(int, char *);
+int biz22w_dialer(char *, char *);
+int biz22f_dialer(char *, char *);
+int biz31w_dialer(char *, char *);
+int biz31f_dialer(char *, char *);
+int cour_dialer(char *, char *);
+int df02_dialer(char *, char *);
+int df03_dialer(char *, char *);
+int dn_dialer(char *, char *);
+int hay_dialer(char *, char *);
+int prompt(char *, char *, size_t);
+size_t size(char *);
+int t3000_dialer(char *, char *);
+int ttysetup(int);
+int uu_lock(char *);
+int uu_unlock(char *);
+int v3451_dialer(char *, char *);
+int v831_dialer(char *, char *);
+int ven_dialer(char *, char *);
+int vstring(char *, char *);
+long hunt(char *);
+void biz22_disconnect(void);
+void biz22_abort(void);
+void biz31_disconnect(void);
+void biz31_abort(void);
+void chdirectory(int);
+void cleanup(int);
+void consh(int);
+void cour_abort(void);
+void cour_disconnect(void);
+void cu_put(int);
+void cu_take(int);
+void cumain(int, char **);
+void daemon_uid(void);
+void df_abort(void);
+void df_disconnect(void);
+void disconnect(char *);
+void dn_abort(void);
+void dn_disconnect(void);
+void finish(int);
+void genbrk(int);
+void getfl(int);
+void hay_abort(void);
+void hay_disconnect(void);
+void help(int);
+void listvariables(int);
+void logent(char *, char *, char *, char *);
+void loginit(void);
+void parwrite(int, char *, size_t);
+void pipefile(int);
+void pipeout(int);
+void raw(void);
+void sendfile(int);
+void setparity(char *);
+void setscript(void);
+void shell(int);
+void shell_uid(void);
+void suspend(int);
+void t3000_disconnect(void);
+void t3000_abort(void);
+void timeout(int);
+void tipabort(char *);
+void tipout(void);
+void user_uid(void);
+void unexcl(void);
+void unraw(void);
+void v3451_abort(void);
+void v3451_disconnect(void);
+void v831_disconnect(void);
+void v831_abort(void);
+void variable(int);
+void ven_disconnect(void);
+void ven_abort(void);
+void vinit(void);
+void vlex(char *);
diff --git a/usr.bin/tip/tip/tipout.c b/usr.bin/tip/tip/tipout.c
new file mode 100644
index 000000000000..be0d5c7c48e2
--- /dev/null
+++ b/usr.bin/tip/tip/tipout.c
@@ -0,0 +1,180 @@
+/* $OpenBSD: tipout.c,v 1.18 2006/05/31 07:03:08 jason Exp $ */
+/* $NetBSD: tipout.c,v 1.5 1996/12/29 10:34:12 cgd Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#include "tip.h"
+
+/*
+ * tip
+ *
+ * lower fork of tip -- handles passive side
+ * reading from the remote host
+ */
+
+static jmp_buf sigbuf;
+
+static void intIOT(int);
+static void intEMT(int);
+static void intTERM(int);
+static void intSYS(int);
+
+/*
+ * TIPOUT wait state routine --
+ * sent by TIPIN when it wants to posses the remote host
+ */
+/*ARGSUSED*/
+static void
+intIOT(int signo)
+{
+ 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
+ */
+/*ARGSUSED*/
+static void
+intEMT(int signo)
+{
+ char c, line[256];
+ char *pline = line;
+ char reply;
+
+ read(fildes[0], &c, 1);
+ while (c != '\n' && (size_t)(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);
+}
+
+static void
+intTERM(int signo)
+{
+ if (boolean(value(SCRIPT)) && fscript != NULL)
+ fclose(fscript);
+ if (signo && tipin_pid)
+ kill(tipin_pid, signo);
+ exit(0);
+}
+
+/*ARGSUSED*/
+static void
+intSYS(int signo)
+{
+ setboolean(value(BEAUTIFY), !boolean(value(BEAUTIFY)));
+ longjmp(sigbuf, 1);
+}
+
+/*
+ * ****TIPOUT TIPOUT****
+ */
+void
+tipout(void)
+{
+ char buf[BUFSIZ];
+ char *cp;
+ ssize_t scnt;
+ size_t 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);
+ scnt = read(FD, buf, BUFSIZ);
+ if (scnt <= 0) {
+ /* lost carrier */
+ if (scnt == 0 ||
+ (scnt < 0 && (errno == EIO || errno == ENXIO))) {
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGTERM);
+ sigprocmask(SIG_BLOCK, &mask, NULL);
+ intTERM(SIGHUP);
+ /*NOTREACHED*/
+ }
+ continue;
+ }
+ cnt = scnt;
+ 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(STDOUT_FILENO, buf, cnt);
+ if (boolean(value(SCRIPT)) && fscript != NULL) {
+ if (!boolean(value(BEAUTIFY))) {
+ fwrite(buf, 1, cnt, fscript);
+ } else {
+ for (cp = buf; cp < buf + cnt; cp++)
+ if ((*cp >= ' ' && *cp <= '~') ||
+ any(*cp, value(EXCEPTIONS)))
+ putc(*cp, fscript);
+ }
+ for (cp = buf; cp < buf + cnt; cp++) {
+ if (!isgraph(*cp)) {
+ fflush(fscript);
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/usr.bin/tip/tip/uucplock.c b/usr.bin/tip/tip/uucplock.c
new file mode 100644
index 000000000000..e29cbc149274
--- /dev/null
+++ b/usr.bin/tip/tip/uucplock.c
@@ -0,0 +1,123 @@
+/* $OpenBSD: uucplock.c,v 1.11 2006/03/16 19:32:46 deraadt Exp $ */
+/* $NetBSD: uucplock.c,v 1.7 1997/02/11 09:24:08 mrg Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "tip.h"
+#include "pathnames.h"
+
+/*
+ * uucp style locking routines
+ * return: 0 - success
+ * -1 - failure
+ */
+
+int
+uu_lock(char *ttyname)
+{
+ int fd, len;
+ char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN];
+ char text_pid[81];
+ pid_t pid;
+
+ (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=%ld... overriding.\n",
+ ttyname, (long)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)snprintf(text_pid, sizeof text_pid, "%10ld\n", (long)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(char *ttyname)
+{
+ char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN];
+
+ (void)snprintf(tbuf, sizeof tbuf, _PATH_LOCKDIRNAME, ttyname);
+ unexcl();
+ 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..4fce98e31361
--- /dev/null
+++ b/usr.bin/tip/tip/value.c
@@ -0,0 +1,355 @@
+/* $OpenBSD: value.c,v 1.14 2006/03/17 22:02:58 moritz Exp $ */
+/* $NetBSD: value.c,v 1.6 1997/02/11 09:24:09 mrg Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#include "tip.h"
+
+#define MIDDLE 35
+
+static value_t *vlookup(char *);
+static void vassign(value_t *, char *);
+static void vtoken(char *);
+static void vprint(value_t *);
+static int vaccess(unsigned int, unsigned int);
+static char *vinterp(char *, int);
+
+static size_t col = 0;
+
+/*
+ * Variable manipulation
+ */
+void
+vinit(void)
+{
+ char file[FILENAME_MAX], *cp;
+ value_t *p;
+ FILE *fp;
+
+ 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) {
+ switch (p->v_type&TMASK) {
+ case STRING:
+ p->v_value = *(char **)p->v_value;
+ break;
+ case NUMBER:
+ setnumber(p->v_value, *(long *)p->v_value);
+ break;
+ case BOOL:
+ setboolean(p->v_value, *(short *)p->v_value);
+ break;
+ case CHAR:
+ setcharacter(p->v_value, *(char *)p->v_value);
+ break;
+ }
+ }
+ }
+ /*
+ * Read the .tiprc file in the HOME directory
+ * for sets
+ */
+ cp = value(HOME);
+ if (cp == NULL) {
+ (void)fprintf(stderr,
+ "$HOME not set. Skipping check for ~/.tiprc\n");
+ } else if (strlen(cp) + 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 ((fp = fopen(file, "r")) != NULL) {
+ char *tp;
+
+ while (fgets(file, sizeof(file)-1, fp) != NULL) {
+ if (vflag)
+ printf("set %s", file);
+ if ((tp = strrchr(file, '\n')))
+ *tp = '\0';
+ vlex(file);
+ }
+ fclose(fp);
+ }
+ }
+ /*
+ * To allow definition of exception prior to fork
+ */
+ vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC);
+}
+
+/*VARARGS1*/
+static void
+vassign(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;
+}
+
+void
+vlex(char *s)
+{
+ value_t *p;
+ char *cp;
+
+ if (equal(s, "all")) {
+ for (p = vtable; p->v_name; p++)
+ if (vaccess(p->v_access, READ))
+ vprint(p);
+ } else {
+ do {
+ if ((cp = vinterp(s, ' ')))
+ cp++;
+ vtoken(s);
+ s = cp;
+ } while (s);
+ }
+ if (col > 0) {
+ printf("\r\n");
+ col = 0;
+ }
+}
+
+static void
+vtoken(char *s)
+{
+ value_t *p;
+ char *cp;
+
+ if ((cp = strchr(s, '='))) {
+ *cp = '\0';
+ if ((p = vlookup(s))) {
+ cp++;
+ if (p->v_type&NUMBER)
+ vassign(p, (char *)(intptr_t)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(value_t *p)
+{
+ char *cp;
+
+ 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);
+ 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(unsigned int mode, unsigned int rw)
+{
+ if (mode & (rw<<PUBLIC))
+ return (1);
+ if (mode & (rw<<PRIVATE))
+ return (1);
+ return ((mode & (rw<<ROOT)) && getuid() == 0);
+}
+
+static value_t *
+vlookup(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);
+}
+
+static char *
+vinterp(char *s, int 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(char *s, char *v)
+{
+ value_t *p;
+
+ p = vlookup(s);
+ if (p == 0)
+ return (1);
+ if (p->v_type&NUMBER)
+ vassign(p, (char *)(intptr_t)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..332d6b871ff1
--- /dev/null
+++ b/usr.bin/tip/tip/vars.c
@@ -0,0 +1,116 @@
+/* $OpenBSD: vars.c,v 1.8 2006/08/18 03:06:18 jason Exp $ */
+/* $NetBSD: vars.c,v 1.3 1994/12/08 09:31:19 jtc Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * 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. 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.
+ */
+
+#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", NOSTR },
+ { "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 },
+ { "hardwareflow", BOOL, (READ|WRITE)<<PUBLIC,
+ "hf", (char *)FALSE },
+ { "linedisc", NUMBER|IREMOTE|INIT, (READ|WRITE)<<PUBLIC,
+ "ld", (char *)&LD },
+ { "direct", BOOL, (READ<<PUBLIC)|(WRITE<<ROOT),
+ "dc", (char *)FALSE },
+ { NOSTR, 0, 0,
+ NOSTR, NOSTR }
+};