aboutsummaryrefslogtreecommitdiffstats
path: root/system_cmds/getty.tproj
diff options
context:
space:
mode:
authorCameron Katri <me@cameronkatri.com>2021-05-09 14:20:58 -0400
committerCameron Katri <me@cameronkatri.com>2021-05-09 14:20:58 -0400
commit5fd83771641d15c418f747bd343ba6738d3875f7 (patch)
tree5abf0f78f680d9837dbd93d4d4c3933bb7509599 /system_cmds/getty.tproj
downloadapple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.gz
apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.zst
apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.zip
Import macOS userland
adv_cmds-176 basic_cmds-55 bootstrap_cmds-116.100.1 developer_cmds-66 diskdev_cmds-667.40.1 doc_cmds-53.60.1 file_cmds-321.40.3 mail_cmds-35 misc_cmds-34 network_cmds-606.40.1 patch_cmds-17 remote_cmds-63 shell_cmds-216.60.1 system_cmds-880.60.2 text_cmds-106
Diffstat (limited to 'system_cmds/getty.tproj')
-rw-r--r--system_cmds/getty.tproj/chat.c492
-rw-r--r--system_cmds/getty.tproj/com.apple.getty.internal.plist33
-rw-r--r--system_cmds/getty.tproj/com.apple.getty.plist24
-rw-r--r--system_cmds/getty.tproj/com.apple.serialdebugconsole.plist39
-rw-r--r--system_cmds/getty.tproj/extern.h60
-rw-r--r--system_cmds/getty.tproj/generate_plist.sh16
-rw-r--r--system_cmds/getty.tproj/getty.8128
-rw-r--r--system_cmds/getty.tproj/gettytab.5546
-rw-r--r--system_cmds/getty.tproj/gettytab.h177
-rw-r--r--system_cmds/getty.tproj/init.c156
-rw-r--r--system_cmds/getty.tproj/main.c858
-rw-r--r--system_cmds/getty.tproj/pathnames.h40
-rw-r--r--system_cmds/getty.tproj/subr.c710
-rw-r--r--system_cmds/getty.tproj/ttys.5168
14 files changed, 3447 insertions, 0 deletions
diff --git a/system_cmds/getty.tproj/chat.c b/system_cmds/getty.tproj/chat.c
new file mode 100644
index 0000000..d79aae7
--- /dev/null
+++ b/system_cmds/getty.tproj/chat.c
@@ -0,0 +1,492 @@
+/*-
+ * Copyright (c) 1997
+ * David L Nugent <davidn@blaze.net.au>.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * 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. This work was done expressly for inclusion into FreeBSD. Other use
+ * is permitted provided this notation is included.
+ * 4. Absolutely no warranty of function or purpose is made by the authors.
+ * 5. Modifications may be freely made to this file providing the above
+ * conditions are met.
+ *
+ * Modem chat module - send/expect style functions for getty
+ * For semi-intelligent modem handling.
+ */
+
+#include <sys/cdefs.h>
+
+#ifndef lint
+__unused static const char rcsid[] =
+ "$FreeBSD: src/libexec/getty/chat.c,v 1.11 2005/04/06 17:42:24 stefanf Exp $";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/utsname.h>
+
+#include <ctype.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include "gettytab.h"
+#include "extern.h"
+
+#define PAUSE_CH (unsigned char)'\xff' /* pause kludge */
+
+#define CHATDEBUG_RECEIVE 0x01
+#define CHATDEBUG_SEND 0x02
+#define CHATDEBUG_EXPECT 0x04
+#define CHATDEBUG_MISC 0x08
+
+#define CHATDEBUG_DEFAULT 0
+#define CHAT_DEFAULT_TIMEOUT 10
+
+
+static int chat_debug = CHATDEBUG_DEFAULT;
+static int chat_alarm = CHAT_DEFAULT_TIMEOUT; /* Default */
+
+static volatile int alarmed = 0;
+
+
+static void chat_alrm(int);
+static int chat_unalarm(void);
+static int getdigit(unsigned char **, int, int);
+static char **read_chat(char **);
+static char *cleanchr(char **, unsigned char);
+static char *cleanstr(const char *, int);
+static const char *result(int);
+static int chat_expect(const char *);
+static int chat_send(char const *);
+
+
+/*
+ * alarm signal handler
+ * handle timeouts in read/write
+ * change stdin to non-blocking mode to prevent
+ * possible hang in read().
+ */
+
+static void
+chat_alrm(int signo)
+{
+ int on = 1;
+
+ alarm(1);
+ alarmed = 1;
+ signal(SIGALRM, chat_alrm);
+ ioctl(STDIN_FILENO, FIONBIO, &on);
+}
+
+
+/*
+ * Turn back on blocking mode reset by chat_alrm()
+ */
+
+static int
+chat_unalarm(void)
+{
+ int off = 0;
+ return ioctl(STDIN_FILENO, FIONBIO, &off);
+}
+
+
+/*
+ * convert a string of a given base (octal/hex) to binary
+ */
+
+static int
+getdigit(unsigned char **ptr, int base, int max)
+{
+ int i, val = 0;
+ unsigned char * q;
+
+ static const char xdigits[] = "0123456789abcdef";
+
+ for (i = 0, q = *ptr; i++ < max; ++q) {
+ int sval;
+ const char * s = strchr(xdigits, tolower(*q));
+
+ if (s == NULL || (sval = s - xdigits) >= base)
+ break;
+ val = (val * base) + sval;
+ }
+ *ptr = q;
+ return val;
+}
+
+
+/*
+ * read_chat()
+ * Convert a whitespace delimtied string into an array
+ * of strings, being expect/send pairs
+ */
+
+static char **
+read_chat(char **chatstr)
+{
+ char *str = *chatstr;
+ char **res = NULL;
+
+ if (str != NULL) {
+ char *tmp = NULL;
+ int l;
+
+ if ((l=strlen(str)) > 0 && (tmp=malloc(l + 1)) != NULL &&
+ (res=malloc((l / 2 + 1) * sizeof(char *))) != NULL) {
+ static char ws[] = " \t";
+ char * p;
+
+ for (l = 0, p = strtok(strcpy(tmp, str), ws);
+ p != NULL;
+ p = strtok(NULL, ws))
+ {
+ unsigned char *q, *r;
+
+ /* Read escapes */
+ for (q = r = (unsigned char *)p; *r; ++q)
+ {
+ if (*q == '\\')
+ {
+ /* handle special escapes */
+ switch (*++q)
+ {
+ case 'a': /* bell */
+ *r++ = '\a';
+ break;
+ case 'r': /* cr */
+ *r++ = '\r';
+ break;
+ case 'n': /* nl */
+ *r++ = '\n';
+ break;
+ case 'f': /* ff */
+ *r++ = '\f';
+ break;
+ case 'b': /* bs */
+ *r++ = '\b';
+ break;
+ case 'e': /* esc */
+ *r++ = 27;
+ break;
+ case 't': /* tab */
+ *r++ = '\t';
+ break;
+ case 'p': /* pause */
+ *r++ = PAUSE_CH;
+ break;
+ case 's':
+ case 'S': /* space */
+ *r++ = ' ';
+ break;
+ case 'x': /* hexdigit */
+ ++q;
+ *r++ = getdigit(&q, 16, 2);
+ --q;
+ break;
+ case '0': /* octal */
+ ++q;
+ *r++ = getdigit(&q, 8, 3);
+ --q;
+ break;
+ default: /* literal */
+ *r++ = *q;
+ break;
+ case 0: /* not past eos */
+ --q;
+ break;
+ }
+ } else {
+ /* copy standard character */
+ *r++ = *q;
+ }
+ }
+
+ /* Remove surrounding quotes, if any
+ */
+ if (*p == '"' || *p == '\'') {
+ q = (unsigned char*)strrchr(p+1, *p);
+ if (q != NULL && *q == *p && q[1] == '\0') {
+ *q = '\0';
+ strcpy(p, p+1);
+ }
+ }
+
+ res[l++] = p;
+ }
+ res[l] = NULL;
+ *chatstr = tmp;
+ return res;
+ }
+ free(tmp);
+ }
+ return res;
+}
+
+
+/*
+ * clean a character for display (ctrl/meta character)
+ */
+
+static char *
+cleanchr(char **buf, unsigned char ch)
+{
+ int l;
+ static char tmpbuf[5];
+ char * tmp = buf ? *buf : tmpbuf;
+
+ if (ch & 0x80) {
+ strcpy(tmp, "M-");
+ l = 2;
+ ch &= 0x7f;
+ } else
+ l = 0;
+
+ if (ch < 32) {
+ tmp[l++] = '^';
+ tmp[l++] = ch + '@';
+ } else if (ch == 127) {
+ tmp[l++] = '^';
+ tmp[l++] = '?';
+ } else
+ tmp[l++] = ch;
+ tmp[l] = '\0';
+
+ if (buf)
+ *buf = tmp + l;
+ return tmp;
+}
+
+
+/*
+ * clean a string for display (ctrl/meta characters)
+ */
+
+static char *
+cleanstr(const char *s, int l)
+{
+ static char * tmp = NULL;
+ static int tmplen = 0;
+
+ if (tmplen < l * 4 + 1)
+ tmp = realloc(tmp, tmplen = l * 4 + 1);
+
+ if (tmp == NULL) {
+ tmplen = 0;
+ return (char *)"(mem alloc error)";
+ } else {
+ int i = 0;
+ char * p = tmp;
+
+ while (i < l)
+ cleanchr(&p, s[i++]);
+ *p = '\0';
+ }
+
+ return tmp;
+}
+
+
+/*
+ * return result as a pseudo-english word
+ */
+
+static const char *
+result(int r)
+{
+ static const char * results[] = {
+ "OK", "MEMERROR", "IOERROR", "TIMEOUT"
+ };
+ return results[r & 3];
+}
+
+
+/*
+ * chat_expect()
+ * scan input for an expected string
+ */
+
+static int
+chat_expect(const char *str)
+{
+ int len, r = 0;
+
+ if (chat_debug & CHATDEBUG_EXPECT)
+ syslog(LOG_DEBUG, "chat_expect '%s'", cleanstr(str, strlen(str)));
+
+ if ((len = strlen(str)) > 0) {
+ int i = 0;
+ char * got;
+
+ if ((got = malloc(len + 1)) == NULL)
+ r = 1;
+ else {
+
+ memset(got, 0, len+1);
+ alarm(chat_alarm);
+ alarmed = 0;
+
+ while (r == 0 && i < len) {
+ if (alarmed)
+ r = 3;
+ else {
+ unsigned char ch;
+
+ if (read(STDIN_FILENO, &ch, 1) == 1) {
+
+ if (chat_debug & CHATDEBUG_RECEIVE)
+ syslog(LOG_DEBUG, "chat_recv '%s' m=%d",
+ cleanchr(NULL, ch), i);
+
+ if (ch == str[i])
+ got[i++] = ch;
+ else if (i > 0) {
+ int j = 1;
+
+ /* See if we can resync on a
+ * partial match in our buffer
+ */
+ while (j < i && memcmp(got + j, str, i - j) != 0)
+ j++;
+ if (j < i)
+ memcpy(got, got + j, i - j);
+ i -= j;
+ }
+ } else
+ r = alarmed ? 3 : 2;
+ }
+ }
+ alarm(0);
+ chat_unalarm();
+ alarmed = 0;
+ free(got);
+ }
+ }
+
+ if (chat_debug & CHATDEBUG_EXPECT)
+ syslog(LOG_DEBUG, "chat_expect %s", result(r));
+
+ return r;
+}
+
+
+/*
+ * chat_send()
+ * send a chat string
+ */
+
+static int
+chat_send(char const *str)
+{
+ int r = 0;
+
+ if (chat_debug & CHATDEBUG_SEND)
+ syslog(LOG_DEBUG, "chat_send '%s'", cleanstr(str, strlen(str)));
+
+ if (*str) {
+ alarm(chat_alarm);
+ alarmed = 0;
+ while (r == 0 && *str)
+ {
+ unsigned char ch = (unsigned char)*str++;
+
+ if (alarmed)
+ r = 3;
+ else if (ch == PAUSE_CH)
+ usleep(500000); /* 1/2 second */
+ else {
+ usleep(10000); /* be kind to modem */
+ if (write(STDOUT_FILENO, &ch, 1) != 1)
+ r = alarmed ? 3 : 2;
+ }
+ }
+ alarm(0);
+ chat_unalarm();
+ alarmed = 0;
+ }
+
+ if (chat_debug & CHATDEBUG_SEND)
+ syslog(LOG_DEBUG, "chat_send %s", result(r));
+
+ return r;
+}
+
+
+/*
+ * getty_chat()
+ *
+ * Termination codes:
+ * -1 - no script supplied
+ * 0 - script terminated correctly
+ * 1 - invalid argument, expect string too large, etc.
+ * 2 - error on an I/O operation or fatal error condition
+ * 3 - timeout waiting for a simple string
+ *
+ * Parameters:
+ * char *scrstr - unparsed chat script
+ * timeout - seconds timeout
+ * debug - debug value (bitmask)
+ */
+
+int
+getty_chat(char *scrstr, int timeout, int debug)
+{
+ int r = -1;
+
+ chat_alarm = timeout ? timeout : CHAT_DEFAULT_TIMEOUT;
+ chat_debug = debug;
+
+ if (scrstr != NULL) {
+ char **script;
+
+ if (chat_debug & CHATDEBUG_MISC)
+ syslog(LOG_DEBUG, "getty_chat script='%s'", scrstr);
+
+ if ((script = read_chat(&scrstr)) != NULL) {
+ int i = r = 0;
+ int off = 0;
+ sig_t old_alarm;
+
+ /*
+ * We need to be in raw mode for all this
+ * Rely on caller...
+ */
+
+ old_alarm = signal(SIGALRM, chat_alrm);
+ chat_unalarm(); /* Force blocking mode at start */
+
+ /*
+ * This is the send/expect loop
+ */
+ while (r == 0 && script[i] != NULL)
+ if ((r = chat_expect(script[i++])) == 0 && script[i] != NULL)
+ r = chat_send(script[i++]);
+
+ signal(SIGALRM, old_alarm);
+ free(script);
+ free(scrstr);
+
+ /*
+ * Ensure stdin is in blocking mode
+ */
+ ioctl(STDIN_FILENO, FIONBIO, &off);
+ }
+
+ if (chat_debug & CHATDEBUG_MISC)
+ syslog(LOG_DEBUG, "getty_chat %s", result(r));
+
+ }
+ return r;
+}
diff --git a/system_cmds/getty.tproj/com.apple.getty.internal.plist b/system_cmds/getty.tproj/com.apple.getty.internal.plist
new file mode 100644
index 0000000..bbd8345
--- /dev/null
+++ b/system_cmds/getty.tproj/com.apple.getty.internal.plist
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>EnablePressuredExit</key>
+ <false/>
+ <key>EnableTransactions</key>
+ <false/>
+ <key>KeepAlive</key>
+ <true/>
+ <key>Label</key>
+ <string>com.apple.getty</string>
+ <key>POSIXSpawnType</key>
+ <string>Interactive</string>
+ <key>_LimitLoadFromVariant</key>
+ <string>IsBaseSystem</string>
+ <key>LimitLoadToHardware</key>
+ <dict>
+ <key>serialdebugmode</key>
+ <array>
+ <integer>1</integer>
+ </array>
+ </dict>
+ <key>ProgramArguments</key>
+ <array>
+ <string>/usr/libexec/getty</string>
+ <string>std.9600</string>
+ <string>console</string>
+ </array>
+ <key>SessionCreate</key>
+ <true/>
+</dict>
+</plist>
diff --git a/system_cmds/getty.tproj/com.apple.getty.plist b/system_cmds/getty.tproj/com.apple.getty.plist
new file mode 100644
index 0000000..45b748f
--- /dev/null
+++ b/system_cmds/getty.tproj/com.apple.getty.plist
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>EnablePressuredExit</key>
+ <false/>
+ <key>EnableTransactions</key>
+ <false/>
+ <key>KeepAlive</key>
+ <true/>
+ <key>Label</key>
+ <string>com.apple.getty</string>
+ <key>POSIXSpawnType</key>
+ <string>Interactive</string>
+ <key>ProgramArguments</key>
+ <array>
+ <string>/usr/libexec/getty</string>
+ <string>std.9600</string>
+ <string>console</string>
+ </array>
+ <key>SessionCreate</key>
+ <true/>
+</dict>
+</plist>
diff --git a/system_cmds/getty.tproj/com.apple.serialdebugconsole.plist b/system_cmds/getty.tproj/com.apple.serialdebugconsole.plist
new file mode 100644
index 0000000..9be51e9
--- /dev/null
+++ b/system_cmds/getty.tproj/com.apple.serialdebugconsole.plist
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>EnablePressuredExit</key>
+ <false/>
+ <key>EnableTransactions</key>
+ <false/>
+ <key>KeepAlive</key>
+ <true/>
+ <key>Label</key>
+ <string>com.apple.serialdebugconsole</string>
+ <key>POSIXSpawnType</key>
+ <string>Interactive</string>
+ <key>_LimitLoadToVariant</key>
+ <string>AllowsInternalSecurityPolicies</string>
+ <key>LimitLoadToHardware</key>
+ <dict>
+ <key>serialdebugmode</key>
+ <array>
+ <integer>2</integer>
+ </array>
+ </dict>
+ <key>ProgramArguments</key>
+ <array>
+ <string>/bin/sh</string>
+ <string>-i</string>
+ <string>-l</string>
+ </array>
+ <key>StandardInPath</key>
+ <string>/dev/console</string>
+ <key>StandardOutPath</key>
+ <string>/dev/console</string>
+ <key>StandardErrorPath</key>
+ <string>/dev/console</string>
+ <key>SessionCreate</key>
+ <true/>
+</dict>
+</plist>
diff --git a/system_cmds/getty.tproj/extern.h b/system_cmds/getty.tproj/extern.h
new file mode 100644
index 0000000..34bc85d
--- /dev/null
+++ b/system_cmds/getty.tproj/extern.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)extern.h 8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/libexec/getty/extern.h,v 1.9 2005/04/06 17:42:24 stefanf Exp $
+ */
+
+struct delayval;
+struct termios;
+
+extern char hostname[];
+extern int hopcount;
+extern struct termios tmode, omode;
+extern struct gettyflags gettyflags[];
+extern struct gettynums gettynums[];
+extern struct gettystrs gettystrs[];
+
+int adelay(int, struct delayval *);
+const char *autobaud(void);
+int delaybits(void);
+void edithost(const char *);
+void gendefaults(void);
+void gettable(const char *);
+void makeenv(char *[]);
+const char *portselector(void);
+void set_ttydefaults(int);
+void setchars(void);
+void setdefaults(void);
+void set_flags(int);
+int speed(int);
+int getty_chat(char *, int, int);
diff --git a/system_cmds/getty.tproj/generate_plist.sh b/system_cmds/getty.tproj/generate_plist.sh
new file mode 100644
index 0000000..ef42607
--- /dev/null
+++ b/system_cmds/getty.tproj/generate_plist.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+set -e
+set -x
+
+cp "${SCRIPT_INPUT_FILE_0}" "${SCRIPT_OUTPUT_FILE_0}"
+case "$PLATFORM_NAME" in
+iphone*|appletv*|watch*|bridge*)
+ ;;
+macosx)
+ /usr/libexec/PlistBuddy -c "Add :Disabled bool true" "${SCRIPT_OUTPUT_FILE_0}"
+ ;;
+*)
+ echo "Unsupported platform: $PLATFORM_NAME"
+ exit 1
+ ;;
+esac
diff --git a/system_cmds/getty.tproj/getty.8 b/system_cmds/getty.tproj/getty.8
new file mode 100644
index 0000000..159b14a
--- /dev/null
+++ b/system_cmds/getty.tproj/getty.8
@@ -0,0 +1,128 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)getty.8 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD: src/libexec/getty/getty.8,v 1.16 2005/01/18 09:29:39 ru Exp $
+.\" "
+.Dd June 4, 1993
+.Dt GETTY 8
+.Os
+.Sh NAME
+.Nm getty
+.Nd set terminal mode
+.Sh SYNOPSIS
+.Nm
+.Oo
+.Ar type
+.Op Ar tty
+.Oc
+.Sh DESCRIPTION
+The
+.Nm
+utility is called by
+.Xr launchd 8
+to open and initialize the tty line, read a login name, and invoke
+.Xr login 1 .
+.Pp
+The argument
+.Ar tty
+is the special device file in
+.Pa /dev
+to open for the terminal (for example, ``ttyh0'').
+If there is no argument or the argument is
+.Sq Fl ,
+the tty line is assumed to be open as file descriptor 0.
+.Pp
+The
+.Ar type
+argument can be used to make
+.Nm
+treat the terminal line specially.
+This argument is used as an index into the
+.Xr gettytab 5
+database, to determine the characteristics of the line.
+If there is no argument, or there is no such table, the
+.Em default
+table is used.
+If there is no
+.Pa /etc/gettytab
+a set of system defaults is used.
+If indicated by the table located,
+.Nm
+will clear the terminal screen,
+print a banner heading,
+and prompt for a login name.
+Usually either the banner or the login prompt will include
+the system hostname.
+.Pp
+Most of the default actions of
+.Nm
+can be circumvented, or modified, by a suitable
+.Pa gettytab
+table.
+.Pp
+The
+.Nm
+utility can be set to timeout after some interval,
+which will cause dial up lines to hang up
+if the login name is not entered reasonably quickly.
+.Sh FILES
+.Bl -tag -width /etc/gettytab -compact
+.It Pa /etc/gettytab
+.It Pa /etc/ttys
+.El
+.Sh DIAGNOSTICS
+.Bl -diag
+.It "ttyxx: No such device or address."
+.It "ttyxx: No such file or address."
+.Pp
+A terminal which is turned
+on in the
+.Pa ttys
+file cannot be opened, likely because the requisite
+lines are either not configured into the system, the associated device
+was not attached during boot-time system configuration,
+or the special file in
+.Pa /dev
+does not exist.
+.El
+.Sh SEE ALSO
+.Xr login 1 ,
+.Xr ioctl 2 ,
+.Xr tty 4 ,
+.Xr gettytab 5 ,
+.Xr ttys 5 ,
+.Xr launchd 8
+.Sh HISTORY
+A
+.Nm
+utility appeared in
+.At v6 .
diff --git a/system_cmds/getty.tproj/gettytab.5 b/system_cmds/getty.tproj/gettytab.5
new file mode 100644
index 0000000..c2efc88
--- /dev/null
+++ b/system_cmds/getty.tproj/gettytab.5
@@ -0,0 +1,546 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)gettytab.5 8.4 (Berkeley) 4/19/94
+.\" $FreeBSD: src/libexec/getty/gettytab.5,v 1.41 2005/01/18 09:29:39 ru Exp $
+.\" "
+.Dd April 19, 1994
+.Dt GETTYTAB 5
+.Os
+.Sh NAME
+.Nm gettytab
+.Nd terminal configuration data base
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+The
+.Nm
+file
+is a simplified version of the
+.Xr termcap 5
+data base
+used to describe terminal lines.
+The initial terminal login process
+.Xr getty 8
+accesses the
+.Nm
+file each time it starts, allowing simpler
+reconfiguration of terminal characteristics.
+Each entry in the data base
+is used to describe one class of terminals.
+.Pp
+There is a default terminal class,
+.Va default ,
+that is used to set global defaults for all other classes.
+(That is, the
+.Va default
+entry is read, then the entry for the class required
+is used to override particular settings.)
+.Sh CAPABILITIES
+Refer to
+.Xr termcap 5
+for a description of the file layout.
+The
+.Va default
+column below lists defaults obtained if there is
+no entry in the table obtained, nor one in the special
+.Va default
+table.
+.Bl -column Name Type /usr/bin/login
+.It Sy "Name Type Default Description
+.It "ac str unused expect-send chat script for modem answer"
+.It "al str unused user to auto-login instead of prompting"
+.It "ap bool false terminal uses any parity"
+.It "bk str 0377 alternate end of line character (input break)"
+.It "c0 num unused tty control flags to write messages"
+.It "c1 num unused tty control flags to read login name"
+.It "c2 num unused tty control flags to leave terminal as"
+.It "ce bool false use crt erase algorithm"
+.It "ck bool false use crt kill algorithm"
+.It "cl str" Ta Dv NULL Ta
+.No "screen clear sequence"
+.It "co bool false console - add"
+.Ql \en
+after login prompt
+.It "ct num 10 chat timeout for"
+.Va \&ac
+and
+.Va \&ic
+scripts
+.It "dc num 0 chat debug bitmask"
+.It "de num 0 delay secs and flush input before writing first prompt"
+.It "df str %+ the" Xr strftime 3 "format used for \&%d in the banner message"
+.It "ds str" Ta So Li ^Y Sc Ta
+.No "delayed suspend character"
+.It "dx bool false set"
+.Dv DECCTLQ
+.It "ec bool false leave echo"
+.Em OFF
+.It "ep bool false terminal uses even parity"
+.It "er str" Ta So Li ^? Sc Ta
+.No "erase character"
+.It "et str" Ta So Li ^D Sc Ta
+.No "end of text"
+.Pq Dv EOF
+character
+.It "ev str" Ta Dv NULL Ta
+.No "initial environment"
+.It "f0 num unused tty mode flags to write messages"
+.It "f1 num unused tty mode flags to read login name"
+.It "f2 num unused tty mode flags to leave terminal as"
+.It "fl str" Ta So Li ^O Sc Ta
+.No "output flush character"
+.It "hc bool false do"
+.Em NOT
+hangup line on last close
+.It "he str" Ta Dv NULL Ta
+.No "hostname editing string"
+.It "hn str hostname hostname"
+.It "ht bool false terminal has real tabs"
+.It "hw bool false do cts/rts hardware flow control"
+.It "i0 num unused tty input flags to write messages"
+.It "i1 num unused tty input flags to read login name"
+.It "i2 num unused tty input flags to leave terminal as"
+.It "ic str unused expect-send chat script for modem initialization"
+.It "if str unused display named file before prompt, like /etc/issue"
+.It "ig bool false ignore garbage characters in login name"
+.It "im str" Ta Dv NULL Ta
+.No "initial (banner) message"
+.It "in str" Ta So Li ^C Sc Ta
+.No "interrupt character"
+.It "is num unused input speed"
+.It "kl str" Ta So Li ^U Sc Ta
+.No "kill character"
+.It "l0 num unused tty local flags to write messages"
+.It "l1 num unused tty local flags to read login name"
+.It "l2 num unused tty local flags to leave terminal as"
+.It "lm str login: login prompt"
+.It "ln str" Ta So Li ^V Sc Ta
+.No "``literal next'' character"
+.It "lo str" Ta Pa /usr/bin/login Ta
+.No "program to exec when name obtained"
+.It "mb bool false do flow control based on carrier"
+.It "nc bool false terminal does not supply carrier (set clocal)"
+.It "nl bool false terminal has (or might have) a newline character"
+.It "np bool false terminal uses no parity (i.e. 8-bit characters)"
+.It "nx str default next table (for auto speed selection)"
+.It "o0 num unused tty output flags to write messages"
+.It "o1 num unused tty output flags to read login name"
+.It "o2 num unused tty output flags to leave terminal as"
+.It "op bool false terminal uses odd parity"
+.It "os num unused output speed"
+.It "pc str" Ta So Li \e0 Sc Ta
+.No "pad character"
+.It "pe bool false use printer (hard copy) erase algorithm"
+.It "pf num 0 delay"
+between first prompt and following flush (seconds)
+.It "pl bool false start PPP login program unconditionally if"
+.Va \&pp
+is specified
+.It "pp str unused PPP login program"
+.It "ps bool false line connected to a"
+.Tn MICOM
+port selector
+.It "qu str" Ta So Li \&^\e Sc Ta
+.No "quit character"
+.It "rp str" Ta So Li ^R Sc Ta
+.No "line retype character"
+.It "rt num unused ring timeout when using"
+.Va \&ac
+.It "rw bool false do"
+.Em NOT
+use raw for input, use cbreak
+.It "sp num unused line speed (input and output)"
+.It "su str" Ta So Li ^Z Sc Ta
+.No "suspend character"
+.It "tc str none table continuation"
+.It "to num 0 timeout (seconds)"
+.It "tt str" Ta Dv NULL Ta
+.No "terminal type (for environment)"
+.It "ub bool false do unbuffered output (of prompts etc)"
+.It "we str" Ta So Li ^W Sc Ta
+.No "word erase character"
+.It "xc bool false do
+.Em NOT
+echo control chars as
+.Ql ^X
+.It "xf str" Ta So Li ^S Sc Ta Dv XOFF
+(stop output) character
+.It "xn str" Ta So Li ^Q Sc Ta Dv XON
+(start output) character
+.It "Lo str C the locale name used for \&%d in the banner message"
+.El
+.Pp
+The following capabilities are no longer supported by
+.Xr getty 8 :
+.Bl -column Name Type /usr/bin/login
+.It "bd num 0 backspace delay"
+.It "cb bool false use crt backspace mode"
+.It "cd num 0 carriage-return delay"
+.It "fd num 0 form-feed (vertical motion) delay"
+.It "lc bool false terminal has lower case"
+.It "nd num 0 newline (line-feed) delay"
+.It "uc bool false terminal is known upper case only"
+.El
+.Pp
+If no line speed is specified, speed will not be altered
+from that which prevails when getty is entered.
+Specifying an input or output speed will override
+line speed for stated direction only.
+.Pp
+Terminal modes to be used for the output of the message,
+for input of the login name,
+and to leave the terminal set as upon completion,
+are derived from the boolean flags specified.
+If the derivation should prove inadequate,
+any (or all) of these three may be overridden
+with one of the
+.Va \&c0 ,
+.Va \&c1 ,
+.Va \&c2 ,
+.Va \&i0 ,
+.Va \&i1 ,
+.Va \&i2 ,
+.Va \&l0 ,
+.Va \&l1 ,
+.Va \&l2 ,
+.Va \&o0 ,
+.Va \&o1 ,
+or
+.Va \&o2
+numeric specifications, which can be used to specify
+(usually in octal, with a leading '0')
+the exact values of the flags.
+These flags correspond to the termios
+.Va c_cflag ,
+.Va c_iflag ,
+.Va c_lflag ,
+and
+.Va c_oflag
+fields, respectively.
+Each of these sets must be completely specified to be effective.
+.Pp
+The
+.Va \&f0 ,
+.Va \&f1 ,
+and
+.Va \&f2
+are excepted for backwards compatibility with a previous incarnation of
+the TTY sub-system.
+In these flags the bottom 16 bits of the (32 bits)
+value contain the sgttyb
+.Va sg_flags
+field, while the top 16 bits represent the local mode word.
+.Pp
+Should
+.Xr getty 8
+receive a null character
+(presumed to indicate a line break)
+it will restart using the table indicated by the
+.Va \&nx
+entry.
+If there is none, it will re-use its original table.
+.Pp
+Delays are specified in milliseconds, the nearest possible
+delay available in the tty driver will be used.
+Should greater certainty be desired, delays
+with values 0, 1, 2, and 3 are interpreted as
+choosing that particular delay algorithm from the driver.
+.Pp
+The
+.Va \&cl
+screen clear string may be preceded by a (decimal) number
+of milliseconds of delay required (a la termcap).
+This delay is simulated by repeated use of the pad character
+.Va \&pc .
+.Pp
+The initial message, login message, and initial file;
+.Va \&im ,
+.Va \&lm
+and
+.Va \&if
+may include any of the following character sequences, which expand to
+information about the environment in which
+.Xr getty 8
+is running.
+.Pp
+.Bl -tag -offset indent -width \&%xxxxxxxxxxxxxx
+.It \&%d
+The current date and time formatted according to the
+.Va \&Lo
+and
+.Va \&df
+strings.
+.It \&%h
+The hostname of the machine, which is normally obtained from the
+system using
+.Xr gethostname 3 ,
+but may also be overridden by the
+.Va \&hn
+table entry.
+In either case it may be edited with the
+.Va \&he
+string.
+A '@' in the
+.Va \&he
+string causes one character from the real hostname to
+be copied to the final hostname.
+A '#' in the
+.Va \&he
+string causes the next character of the real hostname
+to be skipped.
+Each character that
+is neither '@' nor '#' is copied into the final hostname.
+Surplus '@' and '#' characters are ignored.
+.It \&%t
+The tty name.
+.It "\&%m, \&%r, \&%s, \&%v"
+The type of machine, release of the operating system, name of the
+operating system, and version of the kernel, respectively, as
+returned by
+.Xr uname 3 .
+.It \&%%
+A
+.Dq %
+character.
+.El
+.Pp
+When getty execs the login process, given
+in the
+.Va \&lo
+string (usually
+.Dq Pa /usr/bin/login ) ,
+it will have set
+the environment to include the terminal type, as indicated
+by the
+.Va \&tt
+string (if it exists).
+The
+.Va \&ev
+string, can be used to enter additional data into
+the environment.
+It is a list of comma separated strings, each of which
+will presumably be of the form
+.Li name=value .
+.Pp
+If a non-zero timeout is specified, with
+.Va \&to ,
+then getty will exit within the indicated
+number of seconds, either having
+received a login name and passed control
+to
+.Xr login 1 ,
+or having received an alarm signal, and exited.
+This may be useful to hangup dial in lines.
+.Pp
+Output from
+.Xr getty 8
+is even parity unless
+.Va \&op
+or
+.Va \&np
+is specified.
+The
+.Va \&op
+string
+may be specified with
+.Va \&ap
+to allow any parity on input, but generate odd parity output.
+Note: this only applies while getty is being run,
+terminal driver limitations prevent a more complete
+implementation.
+The
+.Xr getty 8
+utility does not check parity of input characters in
+.Dv RAW
+mode.
+.Pp
+If a
+.Va \&pp
+string is specified and a PPP link bring-up sequence is recognized,
+getty will invoke the program referenced by the
+.Va \&pp
+option.
+This can be used to handle incoming PPP calls.
+If the
+.Va \&pl
+option is true as well,
+.Xr getty 8
+will skip the user name prompt and the PPP detection phase, and will
+invoke the program specified by
+.Va \&pp
+instantly.
+.Pp
+.Nm Getty
+provides some basic intelligent modem handling by providing a chat
+script feature available via two capabilities:
+.Pp
+.Bl -tag -offset indent -width \&xxxxxxxx -compact
+.It ic
+Chat script to initialize modem.
+.It ac
+Chat script to answer a call.
+.El
+.Pp
+A chat script is a set of expect/send string pairs.
+When a chat string starts,
+.Nm getty
+will wait for the first string, and if it finds it, will send the
+second, and so on.
+Strings specified are separated by one or more tabs or spaces.
+Strings may contain standard ASCII characters and special 'escapes',
+which consist of a backslash character followed by one or more
+characters which are interpreted as follows:
+.Pp
+.Bl -tag -offset indent -width \&xxxxxxxx -compact
+.It \ea
+bell character.
+.It \eb
+backspace.
+.It \en
+newline.
+.It \ee
+escape.
+.It \ef
+formfeed.
+.It \ep
+half-second pause.
+.It \er
+carriage return.
+.It \eS , \es
+space character.
+.It \et
+tab.
+.It \exNN
+hexadecimal byte value.
+.It \e0NNN
+octal byte value.
+.El
+.Pp
+Note that the
+.Ql \ep
+sequence is only valid for send strings and causes a half-second
+pause between sending the previous and next characters.
+Hexadecimal values are, at most, 2 hex digits long, and octal
+values are a maximum of 3 octal digits.
+.Pp
+The
+.Va \&ic
+chat sequence is used to initialize a modem or similar device.
+A typical example of an init chat script for a modem with a
+hayes compatible command set might look like this:
+.Pp
+.Dl :ic="" ATE0Q0V1\er OK\er ATS0=0\er OK\er:
+.Pp
+This script waits for nothing (which always succeeds), sends
+a sequence to ensure that the modem is in the correct mode
+(suppress command echo, send responses in verbose mode),
+and then disables auto-answer.
+It waits for an "OK" response before it terminates.
+The init sequence is used to check modem responses to ensure that
+the modem is functioning correctly.
+If the init script fails to complete,
+.Nm getty
+considers this to be fatal, and results in an error logged via
+.Xr syslogd 8 ,
+and exiting.
+.Pp
+Similarly, an answer chat script is used to manually answer the
+phone in response to (usually) a "RING".
+When run with an answer script,
+.Nm getty
+opens the port in non-blocking mode, clears any extraneous input
+and waits for data on the port.
+As soon as any data is available, the answer chat script is
+started and scanned for a string, and responds according to
+the answer chat script.
+With a hayes compatible modem, this would normally look something
+like:
+.Pp
+.Dl :ac=RING\er ATA\er CONNECT:
+.Pp
+This causes the modem to answer the call via the "ATA" command,
+then scans input for a "CONNECT" string.
+If this is received before a
+.Va \&ct
+timeout, then a normal login sequence commences.
+.Pp
+The
+.Va \&ct
+capability specifies a timeout for all send and expect strings.
+This timeout is set individually for each expect wait and send
+string and must be at least as long as the time it takes for
+a connection to be established between a remote and local
+modem (usually around 10 seconds).
+.Pp
+In most situations, you will want to flush any additional
+input after the connection has been detected, and the
+.Va \&de
+capability may be used to do that, as well as delay for a
+short time after the connection has been established during
+which all of the connection data has been sent by the modem.
+.Sh SEE ALSO
+.Xr login 1 ,
+.Xr gethostname 3 ,
+.Xr uname 3 ,
+.Xr termcap 5 ,
+.Xr getty 8 ,
+.Xr telnetd 8
+.Sh HISTORY
+The
+.Nm
+file format appeared in
+.Bx 4.2 .
+.Sh BUGS
+The special characters (erase, kill, etc.) are reset to system defaults
+by
+.Xr login 1 .
+In
+.Em all
+cases, '#' or '^H' typed in a login name will be treated as
+an erase character, and '@' will be treated as a kill character.
+.Pp
+The delay stuff is a real crock.
+Apart form its general lack of flexibility, some
+of the delay algorithms are not implemented.
+The terminal driver should support sane delay settings.
+.Pp
+The
+.Va \&he
+capability is stupid.
+.Pp
+The
+.Xr termcap 5
+format is horrid, something more rational should
+have been chosen.
+.Pp
+This should be converted to use
+.Xr termios 4 .
diff --git a/system_cmds/getty.tproj/gettytab.h b/system_cmds/getty.tproj/gettytab.h
new file mode 100644
index 0000000..3addfe3
--- /dev/null
+++ b/system_cmds/getty.tproj/gettytab.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 1983, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)gettytab.h 8.2 (Berkeley) 3/30/94
+ * $FreeBSD: src/libexec/getty/gettytab.h,v 1.14 2003/06/10 18:30:41 yar Exp $
+ */
+
+/*
+ * Getty description definitions.
+ */
+struct gettystrs {
+ const char *field; /* name to lookup in gettytab */
+ char *defalt; /* value we find by looking in defaults */
+ char *value; /* value that we find there */
+};
+
+struct gettynums {
+ const char *field; /* name to lookup */
+ long defalt; /* number we find in defaults */
+ long value; /* number we find there */
+ int set; /* we actually got this one */
+};
+
+struct gettyflags {
+ const char *field; /* name to lookup */
+ char invrt; /* name existing in gettytab --> false */
+ char defalt; /* true/false in defaults */
+ char value; /* true/false flag */
+ char set; /* we found it */
+};
+
+/*
+ * String values.
+ */
+#define NX gettystrs[0].value
+#define CL gettystrs[1].value
+#define IM gettystrs[2].value
+#define LM gettystrs[3].value
+#define ER gettystrs[4].value
+#define KL gettystrs[5].value
+#define ET gettystrs[6].value
+#define PC gettystrs[7].value
+#define TT gettystrs[8].value
+#define EV gettystrs[9].value
+#define LO gettystrs[10].value
+#define HN gettystrs[11].value
+#define HE gettystrs[12].value
+#define IN gettystrs[13].value
+#define QU gettystrs[14].value
+#define XN gettystrs[15].value
+#define XF gettystrs[16].value
+#define BK gettystrs[17].value
+#define SU gettystrs[18].value
+#define DS gettystrs[19].value
+#define RP gettystrs[20].value
+#define FL gettystrs[21].value
+#define WE gettystrs[22].value
+#define LN gettystrs[23].value
+#define Lo gettystrs[24].value
+#define PP gettystrs[25].value
+#define IF gettystrs[26].value
+#define IC gettystrs[27].value
+#define AC gettystrs[28].value
+#define AL gettystrs[29].value
+#define DF gettystrs[30].value
+
+/*
+ * Numeric definitions.
+ */
+#define IS gettynums[0].value
+#define OS gettynums[1].value
+#define SP gettynums[2].value
+#define ND gettynums[3].value
+#define CD gettynums[4].value
+#define TD gettynums[5].value
+#define FD gettynums[6].value
+#define BD gettynums[7].value
+#define TO gettynums[8].value
+#define F0 gettynums[9].value
+#define F0set gettynums[9].set
+#define F1 gettynums[10].value
+#define F1set gettynums[10].set
+#define F2 gettynums[11].value
+#define F2set gettynums[11].set
+#define PF gettynums[12].value
+#define C0 gettynums[13].value
+#define C0set gettynums[13].set
+#define C1 gettynums[14].value
+#define C1set gettynums[14].set
+#define C2 gettynums[15].value
+#define C2set gettynums[15].set
+#define I0 gettynums[16].value
+#define I0set gettynums[16].set
+#define I1 gettynums[17].value
+#define I1set gettynums[17].set
+#define I2 gettynums[18].value
+#define I2set gettynums[18].set
+#define L0 gettynums[19].value
+#define L0set gettynums[19].set
+#define L1 gettynums[20].value
+#define L1set gettynums[20].set
+#define L2 gettynums[21].value
+#define L2set gettynums[21].set
+#define O0 gettynums[22].value
+#define O0set gettynums[22].set
+#define O1 gettynums[23].value
+#define O1set gettynums[23].set
+#define O2 gettynums[24].value
+#define O2set gettynums[24].set
+#define DE gettynums[25].value
+#define RTset gettynums[26].set
+#define RT gettynums[26].value
+#define CT gettynums[27].value
+#define DC gettynums[28].value
+
+/*
+ * Boolean values.
+ */
+#define HT gettyflags[0].value
+#define NL gettyflags[1].value
+#define EP gettyflags[2].value
+#define EPset gettyflags[2].set
+#define OP gettyflags[3].value
+#define OPset gettyflags[3].set
+#define AP gettyflags[4].value
+#define APset gettyflags[4].set
+#define EC gettyflags[5].value
+#define CO gettyflags[6].value
+#define CB gettyflags[7].value
+#define CK gettyflags[8].value
+#define CE gettyflags[9].value
+#define PE gettyflags[10].value
+#define RW gettyflags[11].value
+#define XC gettyflags[12].value
+#define LC gettyflags[13].value
+#define UC gettyflags[14].value
+#define IG gettyflags[15].value
+#define PS gettyflags[16].value
+#define HC gettyflags[17].value
+#define UB gettyflags[18].value
+#define AB gettyflags[19].value
+#define DX gettyflags[20].value
+#define NP gettyflags[21].value
+#define NPset gettyflags[21].set
+#define MB gettyflags[22].value
+#define HW gettyflags[23].value
+#define NC gettyflags[24].value
+#define PL gettyflags[25].value
diff --git a/system_cmds/getty.tproj/init.c b/system_cmds/getty.tproj/init.c
new file mode 100644
index 0000000..a0d69d2
--- /dev/null
+++ b/system_cmds/getty.tproj/init.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)from: init.c 8.1 (Berkeley) 6/4/93";
+#endif
+__unused static const char rcsid[] =
+ "$FreeBSD: src/libexec/getty/init.c,v 1.16 2005/04/06 17:42:24 stefanf Exp $";
+#endif /* not lint */
+
+/*
+ * Getty table initializations.
+ *
+ * Melbourne getty.
+ */
+#include <termios.h>
+#include "gettytab.h"
+#include "extern.h"
+#include "pathnames.h"
+
+static char loginmsg[] = "login: ";
+static char nullstr[] = "";
+static char loginprg[] = _PATH_LOGIN;
+static char datefmt[] = "%+";
+
+struct gettystrs gettystrs[] = {
+ { "nx" }, /* next table */
+ { "cl" }, /* screen clear characters */
+ { "im" }, /* initial message */
+ { "lm", loginmsg }, /* login message */
+ { "er", (char*)&omode.c_cc[VERASE] }, /* erase character */
+ { "kl", (char*)&omode.c_cc[VKILL] }, /* kill character */
+ { "et", (char*)&omode.c_cc[VEOF] }, /* eof chatacter (eot) */
+ { "pc", nullstr }, /* pad character */
+ { "tt" }, /* terminal type */
+ { "ev" }, /* enviroment */
+ { "lo", loginprg }, /* login program */
+ { "hn", hostname }, /* host name */
+ { "he" }, /* host name edit */
+ { "in", (char*)&omode.c_cc[VINTR] }, /* interrupt char */
+ { "qu", (char*)&omode.c_cc[VQUIT] }, /* quit char */
+ { "xn", (char*)&omode.c_cc[VSTART] }, /* XON (start) char */
+ { "xf", (char*)&omode.c_cc[VSTOP] }, /* XOFF (stop) char */
+ { "bk", (char*)&omode.c_cc[VEOL] }, /* brk char (alt \n) */
+ { "su", (char*)&omode.c_cc[VSUSP] }, /* suspend char */
+ { "ds", (char*)&omode.c_cc[VDSUSP] }, /* delayed suspend */
+ { "rp", (char*)&omode.c_cc[VREPRINT] },/* reprint char */
+ { "fl", (char*)&omode.c_cc[VDISCARD] },/* flush output */
+ { "we", (char*)&omode.c_cc[VWERASE] }, /* word erase */
+ { "ln", (char*)&omode.c_cc[VLNEXT] }, /* literal next */
+ { "Lo" }, /* locale for strftime() */
+ { "pp" }, /* ppp login program */
+ { "if" }, /* sysv-like 'issue' filename */
+ { "ic" }, /* modem init-chat */
+ { "ac" }, /* modem answer-chat */
+ { "al" }, /* user to auto-login */
+ { "df", datefmt}, /* format for strftime() */
+ { 0 }
+};
+
+struct gettynums gettynums[] = {
+ { "is" }, /* input speed */
+ { "os" }, /* output speed */
+ { "sp" }, /* both speeds */
+ { "nd" }, /* newline delay */
+ { "cd" }, /* carriage-return delay */
+ { "td" }, /* tab delay */
+ { "fd" }, /* form-feed delay */
+ { "bd" }, /* backspace delay */
+ { "to" }, /* timeout */
+ { "f0" }, /* output flags */
+ { "f1" }, /* input flags */
+ { "f2" }, /* user mode flags */
+ { "pf" }, /* delay before flush at 1st prompt */
+ { "c0" }, /* output c_flags */
+ { "c1" }, /* input c_flags */
+ { "c2" }, /* user mode c_flags */
+ { "i0" }, /* output i_flags */
+ { "i1" }, /* input i_flags */
+ { "i2" }, /* user mode i_flags */
+ { "l0" }, /* output l_flags */
+ { "l1" }, /* input l_flags */
+ { "l2" }, /* user mode l_flags */
+ { "o0" }, /* output o_flags */
+ { "o1" }, /* input o_flags */
+ { "o2" }, /* user mode o_flags */
+ { "de" }, /* delay before sending 1st prompt */
+ { "rt" }, /* reset timeout */
+ { "ct" }, /* chat script timeout */
+ { "dc" }, /* debug chat script value */
+ { 0 }
+};
+
+
+struct gettyflags gettyflags[] = {
+ { "ht", 0 }, /* has tabs */
+ { "nl", 1 }, /* has newline char */
+ { "ep", 0 }, /* even parity */
+ { "op", 0 }, /* odd parity */
+ { "ap", 0 }, /* any parity */
+ { "ec", 1 }, /* no echo */
+ { "co", 0 }, /* console special */
+ { "cb", 0 }, /* crt backspace */
+ { "ck", 0 }, /* crt kill */
+ { "ce", 0 }, /* crt erase */
+ { "pe", 0 }, /* printer erase */
+ { "rw", 1 }, /* don't use raw */
+ { "xc", 1 }, /* don't ^X ctl chars */
+ { "lc", 0 }, /* terminal las lower case */
+ { "uc", 0 }, /* terminal has no lower case */
+ { "ig", 0 }, /* ignore garbage */
+ { "ps", 0 }, /* do port selector speed select */
+ { "hc", 1 }, /* don't set hangup on close */
+ { "ub", 0 }, /* unbuffered output */
+ { "ab", 0 }, /* auto-baud detect with '\r' */
+ { "dx", 0 }, /* set decctlq */
+ { "np", 0 }, /* no parity at all (8bit chars) */
+ { "mb", 0 }, /* do MDMBUF flow control */
+ { "hw", 0 }, /* do CTSRTS flow control */
+ { "nc", 0 }, /* set clocal (no carrier) */
+ { "pl", 0 }, /* use PPP instead of login(1) */
+ { 0 }
+};
diff --git a/system_cmds/getty.tproj/main.c b/system_cmds/getty.tproj/main.c
new file mode 100644
index 0000000..ba501fb
--- /dev/null
+++ b/system_cmds/getty.tproj/main.c
@@ -0,0 +1,858 @@
+/*-
+ * Copyright (c) 1980, 1993
+ * The Regents of the University of California. All rights reserved.
+ * Portions copyright (c) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__unused static const char copyright[] =
+"@(#) Copyright (c) 1980, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)from: main.c 8.1 (Berkeley) 6/20/93";
+#endif
+__unused static const char rcsid[] =
+ "$FreeBSD: src/libexec/getty/main.c,v 1.47 2005/04/06 17:42:24 stefanf Exp $";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/ttydefaults.h>
+#include <sys/utsname.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#ifdef __APPLE__
+#include <util.h>
+#else
+#include <libutil.h>
+#endif
+#include <setjmp.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <termios.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
+#include "gettytab.h"
+#include "extern.h"
+#include "pathnames.h"
+
+/*
+ * Set the amount of running time that getty should accumulate
+ * before deciding that something is wrong and exit.
+ */
+#define GETTY_TIMEOUT 60 /* seconds */
+
+#undef CTRL
+#define CTRL(x) (x&037)
+
+/* defines for auto detection of incoming PPP calls (->PAP/CHAP) */
+
+#define PPP_FRAME 0x7e /* PPP Framing character */
+#define PPP_STATION 0xff /* "All Station" character */
+#define PPP_ESCAPE 0x7d /* Escape Character */
+#define PPP_CONTROL 0x03 /* PPP Control Field */
+#define PPP_CONTROL_ESCAPED 0x23 /* PPP Control Field, escaped */
+#define PPP_LCP_HI 0xc0 /* LCP protocol - high byte */
+#define PPP_LCP_LOW 0x21 /* LCP protocol - low byte */
+
+/* original mode; flags've been reset using values from <sys/ttydefaults.h> */
+struct termios omode;
+/* current mode */
+struct termios tmode;
+
+int crmod, digit, lower, upper;
+
+char hostname[MAXHOSTNAMELEN];
+char name[MAXLOGNAME*3];
+char dev[] = _PATH_DEV;
+char ttyn[32];
+
+#define OBUFSIZ 128
+#define TABBUFSIZ 512
+
+const char *tname;
+
+char *env[128];
+
+char partab[] = {
+ 0001,0201,0201,0001,0201,0001,0001,0201,
+ 0202,0004,0003,0205,0005,0206,0201,0001,
+ 0201,0001,0001,0201,0001,0201,0201,0001,
+ 0001,0201,0201,0001,0201,0001,0001,0201,
+ 0200,0000,0000,0200,0000,0200,0200,0000,
+ 0000,0200,0200,0000,0200,0000,0000,0200,
+ 0000,0200,0200,0000,0200,0000,0000,0200,
+ 0200,0000,0000,0200,0000,0200,0200,0000,
+ 0200,0000,0000,0200,0000,0200,0200,0000,
+ 0000,0200,0200,0000,0200,0000,0000,0200,
+ 0000,0200,0200,0000,0200,0000,0000,0200,
+ 0200,0000,0000,0200,0000,0200,0200,0000,
+ 0000,0200,0200,0000,0200,0000,0000,0200,
+ 0200,0000,0000,0200,0000,0200,0200,0000,
+ 0200,0000,0000,0200,0000,0200,0200,0000,
+ 0000,0200,0200,0000,0200,0000,0000,0201
+};
+
+#define ERASE tmode.c_cc[VERASE]
+#define KILL tmode.c_cc[VKILL]
+#define EOT tmode.c_cc[VEOF]
+
+#define puts Gputs
+
+static void defttymode(void);
+static void dingdong(int);
+static void dogettytab(void);
+static int getname(void);
+static void interrupt(int);
+static void oflush(void);
+static void prompt(void);
+static void putchr(int);
+static void putf(const char *);
+static void putpad(const char *);
+static void puts(const char *);
+static void timeoverrun(int);
+static char *getty_getline(int);
+static void setttymode(int);
+static int opentty(const char *, int);
+
+jmp_buf timeout;
+
+static void
+dingdong(int signo __unused)
+{
+ alarm(0);
+ longjmp(timeout, 1);
+}
+
+jmp_buf intrupt;
+
+static void
+interrupt(int signo __unused)
+{
+ longjmp(intrupt, 1);
+}
+
+/*
+ * Action to take when getty is running too long.
+ */
+static void
+timeoverrun(int signo __unused)
+{
+
+ syslog(LOG_ERR, "getty exiting due to excessive running time");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ extern char **environ;
+ int first_sleep = 1, first_time = 1;
+ struct rlimit limit;
+ int rval;
+#ifdef __APPLE__
+ int ttyopenmode = O_RDWR;
+#endif
+
+ signal(SIGINT, SIG_IGN);
+ signal(SIGQUIT, SIG_IGN);
+
+ openlog("getty", LOG_ODELAY|LOG_CONS|LOG_PID, LOG_AUTH);
+ gethostname(hostname, sizeof(hostname) - 1);
+ hostname[sizeof(hostname) - 1] = '\0';
+ if (hostname[0] == '\0')
+ strcpy(hostname, "Amnesiac");
+
+ /*
+ * Limit running time to deal with broken or dead lines.
+ */
+ (void)signal(SIGXCPU, timeoverrun);
+ limit.rlim_max = RLIM_INFINITY;
+ limit.rlim_cur = GETTY_TIMEOUT;
+ (void)setrlimit(RLIMIT_CPU, &limit);
+
+ gettable("default");
+ gendefaults();
+ tname = "default";
+ if (argc > 1)
+ tname = argv[1];
+
+ /*
+ * The following is a work around for vhangup interactions
+ * which cause great problems getting window systems started.
+ * If the tty line is "-", we do the old style getty presuming
+ * that the file descriptors are already set up for us.
+ * J. Gettys - MIT Project Athena.
+ */
+ if (argc <= 2 || strcmp(argv[2], "-") == 0)
+#ifdef __APPLE__
+ {
+ // <rdar://problem/5178373>
+ char* n = ttyname(STDIN_FILENO);
+ if (n) {
+ strlcpy(ttyn, n, sizeof(ttyn));
+ } else {
+ syslog(LOG_ERR, "ttyname %m");
+ exit(1);
+ }
+ }
+#else
+ strcpy(ttyn, ttyname(STDIN_FILENO));
+#endif
+ else {
+ strcpy(ttyn, dev);
+ strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev));
+ if (strcmp(argv[0], "+") != 0) {
+ chown(ttyn, 0, 0);
+ chmod(ttyn, 0600);
+ revoke(ttyn);
+
+ /*
+ * Do the first scan through gettytab.
+ * Terminal mode parameters will be wrong until
+ * defttymode() called, but they're irrelevant for
+ * the initial setup of the terminal device.
+ */
+ dogettytab();
+
+#if defined(__APPLE__) && !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
+ if (strncmp(ttyn, _PATH_CONSOLE, sizeof(ttyn)) == 0)
+ ttyopenmode |= O_POPUP;
+#endif
+ /*
+ * Init or answer modem sequence has been specified.
+ */
+ if (IC || AC) {
+#ifdef __APPLE__
+ if (!opentty(ttyn, ttyopenmode))
+#else
+ if (!opentty(ttyn, O_RDWR|O_NONBLOCK))
+#endif
+ exit(1);
+ defttymode();
+ setttymode(1);
+ }
+
+ if (IC) {
+ if (getty_chat(IC, CT, DC) > 0) {
+ syslog(LOG_ERR, "modem init problem on %s", ttyn);
+ (void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
+ exit(1);
+ }
+ }
+
+ if (AC) {
+ int i, rfds;
+ struct timeval to;
+
+ rfds = 1 << 0; /* FD_SET */
+ to.tv_sec = RT;
+ to.tv_usec = 0;
+ i = select(32, (fd_set*)&rfds, (fd_set*)NULL,
+ (fd_set*)NULL, RT ? &to : NULL);
+ if (i < 0) {
+ syslog(LOG_ERR, "select %s: %m", ttyn);
+ } else if (i == 0) {
+ syslog(LOG_NOTICE, "recycle tty %s", ttyn);
+ (void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
+ exit(0); /* recycle for init */
+ }
+ i = getty_chat(AC, CT, DC);
+ if (i > 0) {
+ syslog(LOG_ERR, "modem answer problem on %s", ttyn);
+ (void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
+ exit(1);
+ }
+ } else { /* maybe blocking open */
+#ifdef __APPLE__
+ if (!opentty(ttyn, ttyopenmode | (NC ? O_NONBLOCK : 0 )))
+#else
+ if (!opentty(ttyn, O_RDWR | (NC ? O_NONBLOCK : 0 )))
+#endif
+ exit(1);
+ }
+ }
+ }
+
+ defttymode();
+ for (;;) {
+
+ /*
+ * if a delay was specified then sleep for that
+ * number of seconds before writing the initial prompt
+ */
+ if (first_sleep && DE) {
+ sleep(DE);
+ /* remove any noise */
+ (void)tcflush(STDIN_FILENO, TCIOFLUSH);
+ }
+ first_sleep = 0;
+
+ setttymode(0);
+ if (AB) {
+ tname = autobaud();
+ dogettytab();
+ continue;
+ }
+ if (PS) {
+ tname = portselector();
+ dogettytab();
+ continue;
+ }
+ if (CL && *CL)
+ putpad(CL);
+ edithost(HE);
+
+ /* if this is the first time through this, and an
+ issue file has been given, then send it */
+ if (first_time && IF) {
+ int fd;
+
+ if ((fd = open(IF, O_RDONLY)) != -1) {
+ char * cp;
+
+ while ((cp = getty_getline(fd)) != NULL) {
+ putf(cp);
+ }
+ close(fd);
+ }
+ }
+ first_time = 0;
+
+ if (IM && *IM && !(PL && PP))
+ putf(IM);
+ if (setjmp(timeout)) {
+ cfsetispeed(&tmode, B0);
+ cfsetospeed(&tmode, B0);
+ (void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
+ exit(1);
+ }
+ if (TO) {
+ signal(SIGALRM, dingdong);
+ alarm(TO);
+ }
+
+ rval = 0;
+ if (AL) {
+ const char *p = AL;
+ char *q = name;
+
+ while (*p && q < &name[sizeof name - 1]) {
+ if (isupper(*p))
+ upper = 1;
+ else if (islower(*p))
+ lower = 1;
+ else if (isdigit(*p))
+ digit = 1;
+ *q++ = *p++;
+ }
+ } else if (!(PL && PP))
+ rval = getname();
+ if (rval == 2 || (PL && PP)) {
+ oflush();
+ alarm(0);
+ limit.rlim_max = RLIM_INFINITY;
+ limit.rlim_cur = RLIM_INFINITY;
+ (void)setrlimit(RLIMIT_CPU, &limit);
+ execle(PP, "ppplogin", ttyn, (char *) 0, env);
+ syslog(LOG_ERR, "%s: %m", PP);
+ exit(1);
+ } else if (rval || AL) {
+ int i;
+
+ oflush();
+ alarm(0);
+ signal(SIGALRM, SIG_DFL);
+ if (name[0] == '\0')
+ continue;
+ if (name[0] == '-') {
+ puts("user names may not start with '-'.");
+ continue;
+ }
+ if (!(upper || lower || digit)) {
+ if (AL) {
+ syslog(LOG_ERR,
+ "invalid auto-login name: %s", AL);
+ exit(1);
+ } else
+ continue;
+ }
+ set_flags(2);
+ if (crmod) {
+ tmode.c_iflag |= ICRNL;
+ tmode.c_oflag |= ONLCR;
+ }
+#if REALLY_OLD_TTYS
+ if (upper || UC)
+ tmode.sg_flags |= LCASE;
+ if (lower || LC)
+ tmode.sg_flags &= ~LCASE;
+#endif
+ if (tcsetattr(STDIN_FILENO, TCSANOW, &tmode) < 0) {
+ syslog(LOG_ERR, "tcsetattr %s: %m", ttyn);
+ exit(1);
+ }
+ signal(SIGINT, SIG_DFL);
+ for (i = 0; environ[i] != (char *)0; i++)
+ env[i] = environ[i];
+ makeenv(&env[i]);
+
+ limit.rlim_max = RLIM_INFINITY;
+ limit.rlim_cur = RLIM_INFINITY;
+ (void)setrlimit(RLIMIT_CPU, &limit);
+#ifdef __APPLE__
+ // <rdar://problem/3205179>
+ execle(LO, "login", AL ? "-fp1" : "-p1", name,
+#else
+ execle(LO, "login", AL ? "-fp" : "-p", name,
+#endif
+ (char *) 0, env);
+ syslog(LOG_ERR, "%s: %m", LO);
+ exit(1);
+ }
+ alarm(0);
+ signal(SIGALRM, SIG_DFL);
+ signal(SIGINT, SIG_IGN);
+ if (NX && *NX) {
+ tname = NX;
+ dogettytab();
+ }
+ }
+}
+
+static int
+opentty(const char *tty, int flags)
+{
+ int i;
+ int failopenlogged = 0;
+
+ while ((i = open(tty, flags)) == -1)
+ {
+ if (!failopenlogged) {
+ syslog(LOG_ERR, "open %s: %m", tty);
+ failopenlogged = 1;
+ }
+ sleep(60);
+ }
+ if (login_tty(i) < 0) {
+#ifndef __APPLE__
+ if (daemon(0,0) < 0) {
+ syslog(LOG_ERR,"daemon: %m");
+ close(i);
+ return 0;
+ }
+#endif
+ if (login_tty(i) < 0) {
+ syslog(LOG_ERR, "login_tty %s: %m", tty);
+ close(i);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void
+defttymode(void)
+{
+
+ /* Start with default tty settings. */
+ if (tcgetattr(STDIN_FILENO, &tmode) < 0) {
+ syslog(LOG_ERR, "tcgetattr %s: %m", ttyn);
+ exit(1);
+ }
+ omode = tmode; /* fill c_cc for dogettytab() */
+ dogettytab();
+ /*
+ * Don't rely on the driver too much, and initialize crucial
+ * things according to <sys/ttydefaults.h>. Avoid clobbering
+ * the c_cc[] settings however, the console drivers might wish
+ * to leave their idea of the preferred VERASE key value
+ * there.
+ */
+ tmode.c_iflag = TTYDEF_IFLAG;
+ tmode.c_oflag = TTYDEF_OFLAG;
+ tmode.c_lflag = TTYDEF_LFLAG;
+ tmode.c_cflag = TTYDEF_CFLAG;
+ if (NC)
+ tmode.c_cflag |= CLOCAL;
+ omode = tmode;
+}
+
+static void
+setttymode(int raw)
+{
+ int off = 0;
+
+ (void)tcflush(STDIN_FILENO, TCIOFLUSH); /* clear out the crap */
+ ioctl(STDIN_FILENO, FIONBIO, &off); /* turn off non-blocking mode */
+ ioctl(STDIN_FILENO, FIOASYNC, &off); /* ditto for async mode */
+
+ if (IS)
+ cfsetispeed(&tmode, speed(IS));
+ else if (SP)
+ cfsetispeed(&tmode, speed(SP));
+ if (OS)
+ cfsetospeed(&tmode, speed(OS));
+ else if (SP)
+ cfsetospeed(&tmode, speed(SP));
+ set_flags(0);
+ setchars();
+ if (raw)
+ cfmakeraw(&tmode);
+ if (tcsetattr(STDIN_FILENO, TCSANOW, &tmode) < 0) {
+ syslog(LOG_ERR, "tcsetattr %s: %m", ttyn);
+ exit(1);
+ }
+}
+
+
+static int
+getname(void)
+{
+ int c;
+ char *np;
+ unsigned char cs;
+ int ppp_state = 0;
+ int ppp_connection = 0;
+
+ /*
+ * Interrupt may happen if we use CBREAK mode
+ */
+ if (setjmp(intrupt)) {
+ signal(SIGINT, SIG_IGN);
+ return (0);
+ }
+ signal(SIGINT, interrupt);
+ set_flags(1);
+ prompt();
+ oflush();
+ if (PF > 0) {
+ sleep(PF);
+ PF = 0;
+ }
+ if (tcsetattr(STDIN_FILENO, TCSANOW, &tmode) < 0) {
+ syslog(LOG_ERR, "%s: %m", ttyn);
+ exit(1);
+ }
+ crmod = digit = lower = upper = 0;
+ np = name;
+ for (;;) {
+ oflush();
+ if (read(STDIN_FILENO, &cs, 1) <= 0)
+ exit(0);
+ if ((c = cs&0177) == 0)
+ return (0);
+
+ /* PPP detection state machine..
+ Look for sequences:
+ PPP_FRAME, PPP_STATION, PPP_ESCAPE, PPP_CONTROL_ESCAPED or
+ PPP_FRAME, PPP_STATION, PPP_CONTROL (deviant from RFC)
+ See RFC1662.
+ Derived from code from Michael Hancock, <michaelh@cet.co.jp>
+ and Erik 'PPP' Olson, <eriko@wrq.com>
+ */
+
+ if (PP && (cs == PPP_FRAME)) {
+ ppp_state = 1;
+ } else if (ppp_state == 1 && cs == PPP_STATION) {
+ ppp_state = 2;
+ } else if (ppp_state == 2 && cs == PPP_ESCAPE) {
+ ppp_state = 3;
+ } else if ((ppp_state == 2 && cs == PPP_CONTROL)
+ || (ppp_state == 3 && cs == PPP_CONTROL_ESCAPED)) {
+ ppp_state = 4;
+ } else if (ppp_state == 4 && cs == PPP_LCP_HI) {
+ ppp_state = 5;
+ } else if (ppp_state == 5 && cs == PPP_LCP_LOW) {
+ ppp_connection = 1;
+ break;
+ } else {
+ ppp_state = 0;
+ }
+
+ if (c == EOT || c == CTRL('d'))
+ exit(0);
+ if (c == '\r' || c == '\n' || np >= &name[sizeof name-1]) {
+ putf("\r\n");
+ break;
+ }
+ if (islower(c))
+ lower = 1;
+ else if (isupper(c))
+ upper = 1;
+ else if (c == ERASE || c == '\b' || c == 0177) {
+ if (np > name) {
+ np--;
+ if (cfgetospeed(&tmode) >= 1200)
+ puts("\b \b");
+ else
+ putchr(cs);
+ }
+ continue;
+ } else if (c == KILL || c == CTRL('u')) {
+ putchr('\r');
+ if (cfgetospeed(&tmode) < 1200)
+ putchr('\n');
+ /* this is the way they do it down under ... */
+ else if (np > name)
+ puts(" \r");
+ prompt();
+ digit = lower = upper = 0;
+ np = name;
+ continue;
+ } else if (isdigit(c))
+ digit = 1;
+ if (IG && (c <= ' ' || c > 0176))
+ continue;
+ *np++ = c;
+ putchr(cs);
+ }
+ signal(SIGINT, SIG_IGN);
+ *np = 0;
+ if (c == '\r')
+ crmod = 1;
+ if ((upper && !lower && !LC) || UC)
+ for (np = name; *np; np++)
+ if (isupper(*np))
+ *np = tolower(*np);
+ return (1 + ppp_connection);
+}
+
+static void
+putpad(const char *s)
+{
+ int pad = 0;
+ speed_t ospeed = cfgetospeed(&tmode);
+
+ if (isdigit(*s)) {
+ while (isdigit(*s)) {
+ pad *= 10;
+ pad += *s++ - '0';
+ }
+ pad *= 10;
+ if (*s == '.' && isdigit(s[1])) {
+ pad += s[1] - '0';
+ s += 2;
+ }
+ }
+
+ puts(s);
+ /*
+ * If no delay needed, or output speed is
+ * not comprehensible, then don't try to delay.
+ */
+ if (pad == 0 || ospeed <= 0)
+ return;
+
+ /*
+ * Round up by a half a character frame, and then do the delay.
+ * Too bad there are no user program accessible programmed delays.
+ * Transmitting pad characters slows many terminals down and also
+ * loads the system.
+ */
+ pad = (pad * ospeed + 50000) / 100000;
+ while (pad--)
+ putchr(*PC);
+}
+
+static void
+puts(const char *s)
+{
+ while (*s)
+ putchr(*s++);
+}
+
+char outbuf[OBUFSIZ];
+int obufcnt = 0;
+
+static void
+putchr(int cc)
+{
+ char c;
+
+ c = cc;
+ if (!NP) {
+ c |= partab[c&0177] & 0200;
+ if (OP)
+ c ^= 0200;
+ }
+ if (!UB) {
+ outbuf[obufcnt++] = c;
+ if (obufcnt >= OBUFSIZ)
+ oflush();
+ } else
+ write(STDOUT_FILENO, &c, 1);
+}
+
+static void
+oflush(void)
+{
+ if (obufcnt)
+ write(STDOUT_FILENO, outbuf, obufcnt);
+ obufcnt = 0;
+}
+
+static void
+prompt(void)
+{
+
+ putf(LM);
+ if (CO)
+ putchr('\n');
+}
+
+
+static char *
+getty_getline(int fd)
+{
+ int i = 0;
+ static char linebuf[512];
+
+ /*
+ * This is certainly slow, but it avoids having to include
+ * stdio.h unnecessarily. Issue files should be small anyway.
+ */
+ while (i < (sizeof linebuf - 3) && read(fd, linebuf+i, 1)==1) {
+ if (linebuf[i] == '\n') {
+ /* Don't rely on newline mode, assume raw */
+ linebuf[i++] = '\r';
+ linebuf[i++] = '\n';
+ linebuf[i] = '\0';
+ return linebuf;
+ }
+ ++i;
+ }
+ linebuf[i] = '\0';
+ return i ? linebuf : 0;
+}
+
+static void
+putf(const char *cp)
+{
+ extern char editedhost[];
+ time_t t;
+ char *slash, db[100];
+
+ static struct utsname kerninfo;
+
+ if (!*kerninfo.sysname)
+ uname(&kerninfo);
+
+ while (*cp) {
+ if (*cp != '%') {
+ putchr(*cp++);
+ continue;
+ }
+ switch (*++cp) {
+
+ case 't':
+ slash = strrchr(ttyn, '/');
+ if (slash == (char *) 0)
+ puts(ttyn);
+ else
+ puts(&slash[1]);
+ break;
+
+ case 'h':
+ puts(editedhost);
+ break;
+
+ case 'd': {
+ t = (time_t)0;
+ (void)time(&t);
+ if (Lo)
+ (void)setlocale(LC_TIME, Lo);
+ (void)strftime(db, sizeof(db), DF, localtime(&t));
+ puts(db);
+ break;
+
+ case 's':
+ puts(kerninfo.sysname);
+ break;
+
+ case 'm':
+ puts(kerninfo.machine);
+ break;
+
+ case 'r':
+ puts(kerninfo.release);
+ break;
+
+ case 'v':
+ puts(kerninfo.version);
+ break;
+ }
+
+ case '%':
+ putchr('%');
+ break;
+ }
+ cp++;
+ }
+}
+
+/*
+ * Read a gettytab database entry and perform necessary quirks.
+ */
+static void
+dogettytab()
+{
+ /* Read the database entry. */
+ gettable(tname);
+
+ /*
+ * Avoid inheriting the parity values from the default entry
+ * if any of them is set in the current entry.
+ * Mixing different parity settings is unreasonable.
+ */
+ if (OPset || EPset || APset || NPset)
+ OPset = EPset = APset = NPset = 1;
+
+ /* Fill in default values for unset capabilities. */
+ setdefaults();
+}
diff --git a/system_cmds/getty.tproj/pathnames.h b/system_cmds/getty.tproj/pathnames.h
new file mode 100644
index 0000000..2c64fd1
--- /dev/null
+++ b/system_cmds/getty.tproj/pathnames.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)pathnames.h 8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/libexec/getty/pathnames.h,v 1.7 1999/08/28 00:09:36 peter Exp $
+ */
+
+#include <paths.h>
+
+#define _PATH_GETTYTAB "/etc/gettytab"
+#define _PATH_LOGIN "/usr/bin/login"
diff --git a/system_cmds/getty.tproj/subr.c b/system_cmds/getty.tproj/subr.c
new file mode 100644
index 0000000..2bff200
--- /dev/null
+++ b/system_cmds/getty.tproj/subr.c
@@ -0,0 +1,710 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)from: subr.c 8.1 (Berkeley) 6/4/93";
+#endif
+__unused static const char rcsid[] =
+ "$FreeBSD: src/libexec/getty/subr.c,v 1.19 2004/06/25 10:11:28 phk Exp $";
+#endif /* not lint */
+
+/*
+ * Melbourne getty.
+ */
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <syslog.h>
+
+#include "gettytab.h"
+#include "pathnames.h"
+#include "extern.h"
+
+/*
+ * Get a table entry.
+ */
+void
+gettable(const char *name)
+{
+ char *buf = NULL;
+ struct gettystrs *sp;
+ struct gettynums *np;
+ struct gettyflags *fp;
+ long n;
+ int l;
+ char *p;
+ char *msg = NULL;
+ const char *dba[2];
+
+ static int firsttime = 1;
+
+ dba[0] = _PATH_GETTYTAB;
+ dba[1] = 0;
+
+ if (firsttime) {
+ /*
+ * we need to strdup() anything in the strings array
+ * initially in order to simplify things later
+ */
+ for (sp = gettystrs; sp->field; sp++)
+ if (sp->value != NULL) {
+ /* handle these ones more carefully */
+ if (sp >= &gettystrs[4] && sp <= &gettystrs[6])
+ l = 2;
+ else
+ l = (int)strlen(sp->value) + 1;
+ if ((p = malloc(l)) != NULL) {
+ strncpy(p, sp->value, l);
+ p[l-1] = '\0';
+ }
+ /*
+ * replace, even if NULL, else we'll
+ * have problems with free()ing static mem
+ */
+ sp->value = p;
+ }
+ firsttime = 0;
+ }
+
+ switch (cgetent(&buf, (char **)dba, (char *)name)) {
+ case 1:
+ msg = "%s: couldn't resolve 'tc=' in gettytab '%s'";
+ case 0:
+ break;
+ case -1:
+ msg = "%s: unknown gettytab entry '%s'";
+ break;
+ case -2:
+ msg = "%s: retrieving gettytab entry '%s': %m";
+ break;
+ case -3:
+ msg = "%s: recursive 'tc=' reference gettytab entry '%s'";
+ break;
+ default:
+ msg = "%s: unexpected cgetent() error for entry '%s'";
+ break;
+ }
+
+ if (msg != NULL) {
+ syslog(LOG_ERR, msg, "getty", name);
+ return;
+ }
+
+ for (sp = gettystrs; sp->field; sp++) {
+ if ((l = cgetstr(buf, (char*)sp->field, &p)) >= 0) {
+ if (sp->value) {
+ /* prefer existing value */
+ if (strcmp(p, sp->value) != 0)
+ free(sp->value);
+ else {
+ free(p);
+ p = sp->value;
+ }
+ }
+ sp->value = p;
+ } else if (l == -1) {
+ free(sp->value);
+ sp->value = NULL;
+ }
+ }
+
+ for (np = gettynums; np->field; np++) {
+ if (cgetnum(buf, (char*)np->field, &n) == -1)
+ np->set = 0;
+ else {
+ np->set = 1;
+ np->value = n;
+ }
+ }
+
+ for (fp = gettyflags; fp->field; fp++) {
+ if (cgetcap(buf, (char *)fp->field, ':') == NULL)
+ fp->set = 0;
+ else {
+ fp->set = 1;
+ fp->value = 1 ^ fp->invrt;
+ }
+ }
+
+#ifdef DEBUG
+ printf("name=\"%s\", buf=\"%s\"\r\n", name, buf);
+ for (sp = gettystrs; sp->field; sp++)
+ printf("cgetstr: %s=%s\r\n", sp->field, sp->value);
+ for (np = gettynums; np->field; np++)
+ printf("cgetnum: %s=%d\r\n", np->field, np->value);
+ for (fp = gettyflags; fp->field; fp++)
+ printf("cgetflags: %s='%c' set='%c'\r\n", fp->field,
+ fp->value + '0', fp->set + '0');
+#endif /* DEBUG */
+
+ free(buf);
+}
+
+void
+gendefaults(void)
+{
+ struct gettystrs *sp;
+ struct gettynums *np;
+ struct gettyflags *fp;
+
+ for (sp = gettystrs; sp->field; sp++)
+ if (sp->value)
+ sp->defalt = strdup(sp->value);
+ for (np = gettynums; np->field; np++)
+ if (np->set)
+ np->defalt = np->value;
+ for (fp = gettyflags; fp->field; fp++)
+ if (fp->set)
+ fp->defalt = fp->value;
+ else
+ fp->defalt = fp->invrt;
+}
+
+void
+setdefaults(void)
+{
+ struct gettystrs *sp;
+ struct gettynums *np;
+ struct gettyflags *fp;
+
+ for (sp = gettystrs; sp->field; sp++)
+ if (!sp->value)
+ sp->value = !sp->defalt ? sp->defalt
+ : strdup(sp->defalt);
+ for (np = gettynums; np->field; np++)
+ if (!np->set)
+ np->value = np->defalt;
+ for (fp = gettyflags; fp->field; fp++)
+ if (!fp->set)
+ fp->value = fp->defalt;
+}
+
+static char **
+charnames[] = {
+ &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
+ &SU, &DS, &RP, &FL, &WE, &LN, 0
+};
+
+static char *
+charvars[] = {
+ (char*)&tmode.c_cc[VERASE],
+ (char*)&tmode.c_cc[VKILL],
+ (char*)&tmode.c_cc[VINTR],
+ (char*)&tmode.c_cc[VQUIT],
+ (char*)&tmode.c_cc[VSTART],
+ (char*)&tmode.c_cc[VSTOP],
+ (char*)&tmode.c_cc[VEOF],
+ (char*)&tmode.c_cc[VEOL],
+ (char*)&tmode.c_cc[VSUSP],
+ (char*)&tmode.c_cc[VDSUSP],
+ (char*)&tmode.c_cc[VREPRINT],
+ (char*)&tmode.c_cc[VDISCARD],
+ (char*)&tmode.c_cc[VWERASE],
+ (char*)&tmode.c_cc[VLNEXT],
+ 0
+};
+
+void
+setchars(void)
+{
+ int i;
+ const char *p;
+
+ for (i = 0; charnames[i]; i++) {
+ p = *charnames[i];
+ if (p && *p)
+ *charvars[i] = *p;
+ else
+ *charvars[i] = _POSIX_VDISABLE;
+ }
+}
+
+/* Macros to clear/set/test flags. */
+#define SET(t, f) (t) |= (f)
+#define CLR(t, f) (t) &= ~(f)
+#define ISSET(t, f) ((t) & (f))
+
+void
+set_flags(int n)
+{
+ tcflag_t iflag, oflag, cflag, lflag;
+
+
+ switch (n) {
+ case 0:
+ if (C0set && I0set && L0set && O0set) {
+ tmode.c_cflag = C0;
+ tmode.c_iflag = I0;
+ tmode.c_lflag = L0;
+ tmode.c_oflag = O0;
+ return;
+ }
+ break;
+ case 1:
+ if (C1set && I1set && L1set && O1set) {
+ tmode.c_cflag = C1;
+ tmode.c_iflag = I1;
+ tmode.c_lflag = L1;
+ tmode.c_oflag = O1;
+ return;
+ }
+ break;
+ default:
+ if (C2set && I2set && L2set && O2set) {
+ tmode.c_cflag = C2;
+ tmode.c_iflag = I2;
+ tmode.c_lflag = L2;
+ tmode.c_oflag = O2;
+ return;
+ }
+ break;
+ }
+
+ iflag = omode.c_iflag;
+ oflag = omode.c_oflag;
+ cflag = omode.c_cflag;
+ lflag = omode.c_lflag;
+
+ if (NP) {
+ CLR(cflag, CSIZE|PARENB);
+ SET(cflag, CS8);
+ CLR(iflag, ISTRIP|INPCK|IGNPAR);
+ } else if (AP || EP || OP) {
+ CLR(cflag, CSIZE);
+ SET(cflag, CS7|PARENB);
+ SET(iflag, ISTRIP);
+ if (OP && !EP) {
+ SET(iflag, INPCK|IGNPAR);
+ SET(cflag, PARODD);
+ if (AP)
+ CLR(iflag, INPCK);
+ } else if (EP && !OP) {
+ SET(iflag, INPCK|IGNPAR);
+ CLR(cflag, PARODD);
+ if (AP)
+ CLR(iflag, INPCK);
+ } else if (AP || (EP && OP)) {
+ CLR(iflag, INPCK|IGNPAR);
+ CLR(cflag, PARODD);
+ }
+ } /* else, leave as is */
+
+#if 0
+ if (UC)
+ f |= LCASE;
+#endif
+
+ if (HC)
+ SET(cflag, HUPCL);
+ else
+ CLR(cflag, HUPCL);
+
+ if (MB)
+ SET(cflag, MDMBUF);
+ else
+ CLR(cflag, MDMBUF);
+
+ if (HW)
+ SET(cflag, CRTSCTS);
+ else
+ CLR(cflag, CRTSCTS);
+
+ if (NL) {
+ SET(iflag, ICRNL);
+ SET(oflag, ONLCR|OPOST);
+ } else {
+ CLR(iflag, ICRNL);
+ CLR(oflag, ONLCR);
+ }
+
+ if (!HT)
+ SET(oflag, OXTABS|OPOST);
+ else
+ CLR(oflag, OXTABS);
+
+#ifdef XXX_DELAY
+ SET(f, delaybits());
+#endif
+
+ if (n == 1) { /* read mode flags */
+ if (RW) {
+ iflag = 0;
+ CLR(oflag, OPOST);
+ CLR(cflag, CSIZE|PARENB);
+ SET(cflag, CS8);
+ lflag = 0;
+ } else {
+ CLR(lflag, ICANON);
+ }
+ goto out;
+ }
+
+ if (n == 0)
+ goto out;
+
+#if 0
+ if (CB)
+ SET(f, CRTBS);
+#endif
+
+ if (CE)
+ SET(lflag, ECHOE);
+ else
+ CLR(lflag, ECHOE);
+
+ if (CK)
+ SET(lflag, ECHOKE);
+ else
+ CLR(lflag, ECHOKE);
+
+ if (PE)
+ SET(lflag, ECHOPRT);
+ else
+ CLR(lflag, ECHOPRT);
+
+ if (EC)
+ SET(lflag, ECHO);
+ else
+ CLR(lflag, ECHO);
+
+ if (XC)
+ SET(lflag, ECHOCTL);
+ else
+ CLR(lflag, ECHOCTL);
+
+ if (DX)
+ SET(lflag, IXANY);
+ else
+ CLR(lflag, IXANY);
+
+out:
+ tmode.c_iflag = iflag;
+ tmode.c_oflag = oflag;
+ tmode.c_cflag = cflag;
+ tmode.c_lflag = lflag;
+}
+
+
+#ifdef XXX_DELAY
+struct delayval {
+ unsigned delay; /* delay in ms */
+ int bits;
+};
+
+/*
+ * below are random guesses, I can't be bothered checking
+ */
+
+struct delayval crdelay[] = {
+ { 1, CR1 },
+ { 2, CR2 },
+ { 3, CR3 },
+ { 83, CR1 },
+ { 166, CR2 },
+ { 0, CR3 },
+};
+
+struct delayval nldelay[] = {
+ { 1, NL1 }, /* special, calculated */
+ { 2, NL2 },
+ { 3, NL3 },
+ { 100, NL2 },
+ { 0, NL3 },
+};
+
+struct delayval bsdelay[] = {
+ { 1, BS1 },
+ { 0, 0 },
+};
+
+struct delayval ffdelay[] = {
+ { 1, FF1 },
+ { 1750, FF1 },
+ { 0, FF1 },
+};
+
+struct delayval tbdelay[] = {
+ { 1, TAB1 },
+ { 2, TAB2 },
+ { 3, XTABS }, /* this is expand tabs */
+ { 100, TAB1 },
+ { 0, TAB2 },
+};
+
+int
+delaybits(void)
+{
+ int f;
+
+ f = adelay(CD, crdelay);
+ f |= adelay(ND, nldelay);
+ f |= adelay(FD, ffdelay);
+ f |= adelay(TD, tbdelay);
+ f |= adelay(BD, bsdelay);
+ return (f);
+}
+
+int
+adelay(int ms, struct delayval *dp)
+{
+ if (ms == 0)
+ return (0);
+ while (dp->delay && ms > dp->delay)
+ dp++;
+ return (dp->bits);
+}
+#endif
+
+char editedhost[MAXHOSTNAMELEN];
+
+void
+edithost(const char *pat)
+{
+ const char *host = HN;
+ char *res = editedhost;
+
+ if (!pat)
+ pat = "";
+ while (*pat) {
+ switch (*pat) {
+
+ case '#':
+ if (*host)
+ host++;
+ break;
+
+ case '@':
+ if (*host)
+ *res++ = *host++;
+ break;
+
+ default:
+ *res++ = *pat;
+ break;
+
+ }
+ if (res == &editedhost[sizeof editedhost - 1]) {
+ *res = '\0';
+ return;
+ }
+ pat++;
+ }
+ if (*host)
+ strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
+ else
+ *res = '\0';
+ editedhost[sizeof editedhost - 1] = '\0';
+}
+
+static struct speedtab {
+ int speed;
+ int uxname;
+} speedtab[] = {
+ { 50, B50 },
+ { 75, B75 },
+ { 110, B110 },
+ { 134, B134 },
+ { 150, B150 },
+ { 200, B200 },
+ { 300, B300 },
+ { 600, B600 },
+ { 1200, B1200 },
+ { 1800, B1800 },
+ { 2400, B2400 },
+ { 4800, B4800 },
+ { 9600, B9600 },
+ { 19200, EXTA },
+ { 19, EXTA }, /* for people who say 19.2K */
+ { 38400, EXTB },
+ { 38, EXTB },
+ { 7200, EXTB }, /* alternative */
+ { 57600, B57600 },
+ { 115200, B115200 },
+ { 230400, B230400 },
+ { 0 }
+};
+
+int
+speed(int val)
+{
+ struct speedtab *sp;
+
+ if (val <= B230400)
+ return (val);
+
+ for (sp = speedtab; sp->speed; sp++)
+ if (sp->speed == val)
+ return (sp->uxname);
+
+ return (B300); /* default in impossible cases */
+}
+
+void
+makeenv(char *env[])
+{
+ static char termbuf[128] = "TERM=";
+ char *p, *q;
+ char **ep;
+
+ ep = env;
+ if (TT && *TT) {
+ strlcat(termbuf, TT, sizeof(termbuf));
+ *ep++ = termbuf;
+ }
+ if ((p = EV)) {
+ q = p;
+ while ((q = strchr(q, ','))) {
+ *q++ = '\0';
+ *ep++ = p;
+ p = q;
+ }
+ if (*p)
+ *ep++ = p;
+ }
+ *ep = (char *)0;
+}
+
+/*
+ * This speed select mechanism is written for the Develcon DATASWITCH.
+ * The Develcon sends a string of the form "B{speed}\n" at a predefined
+ * baud rate. This string indicates the user's actual speed.
+ * The routine below returns the terminal type mapped from derived speed.
+ */
+struct portselect {
+ const char *ps_baud;
+ const char *ps_type;
+} portspeeds[] = {
+ { "B110", "std.110" },
+ { "B134", "std.134" },
+ { "B150", "std.150" },
+ { "B300", "std.300" },
+ { "B600", "std.600" },
+ { "B1200", "std.1200" },
+ { "B2400", "std.2400" },
+ { "B4800", "std.4800" },
+ { "B9600", "std.9600" },
+ { "B19200", "std.19200" },
+ { 0 }
+};
+
+const char *
+portselector(void)
+{
+ char c, baud[20];
+ const char *type = "default";
+ struct portselect *ps;
+ int len;
+
+ alarm(5*60);
+ for (len = 0; len < sizeof (baud) - 1; len++) {
+ if (read(STDIN_FILENO, &c, 1) <= 0)
+ break;
+ c &= 0177;
+ if (c == '\n' || c == '\r')
+ break;
+ if (c == 'B')
+ len = 0; /* in case of leading garbage */
+ baud[len] = c;
+ }
+ baud[len] = '\0';
+ for (ps = portspeeds; ps->ps_baud; ps++)
+ if (strcmp(ps->ps_baud, baud) == 0) {
+ type = ps->ps_type;
+ break;
+ }
+ sleep(2); /* wait for connection to complete */
+ return (type);
+}
+
+/*
+ * This auto-baud speed select mechanism is written for the Micom 600
+ * portselector. Selection is done by looking at how the character '\r'
+ * is garbled at the different speeds.
+ */
+const char *
+autobaud(void)
+{
+ int rfds;
+ struct timeval timeout;
+ char c;
+ const char *type = "9600-baud";
+
+ (void)tcflush(0, TCIOFLUSH);
+ rfds = 1 << 0;
+ timeout.tv_sec = 5;
+ timeout.tv_usec = 0;
+ if (select(32, (fd_set *)&rfds, (fd_set *)NULL,
+ (fd_set *)NULL, &timeout) <= 0)
+ return (type);
+ if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char))
+ return (type);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 20;
+ (void) select(32, (fd_set *)NULL, (fd_set *)NULL,
+ (fd_set *)NULL, &timeout);
+ (void)tcflush(0, TCIOFLUSH);
+ switch (c & 0377) {
+
+ case 0200: /* 300-baud */
+ type = "300-baud";
+ break;
+
+ case 0346: /* 1200-baud */
+ type = "1200-baud";
+ break;
+
+ case 015: /* 2400-baud */
+ case 0215:
+ type = "2400-baud";
+ break;
+
+ default: /* 4800-baud */
+ type = "4800-baud";
+ break;
+
+ case 0377: /* 9600-baud */
+ type = "9600-baud";
+ break;
+ }
+ return (type);
+}
diff --git a/system_cmds/getty.tproj/ttys.5 b/system_cmds/getty.tproj/ttys.5
new file mode 100644
index 0000000..9a0a77c
--- /dev/null
+++ b/system_cmds/getty.tproj/ttys.5
@@ -0,0 +1,168 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)ttys.5 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD: src/libexec/getty/ttys.5,v 1.18 2005/06/14 08:40:10 ru Exp $
+.\" "
+.Dd May 27, 2005
+.Dt TTYS 5
+.Os
+.Sh NAME
+.Nm ttys
+.Nd terminal initialization information
+.Sh DESCRIPTION
+The file
+.Nm
+contains information that is used by various routines to initialize
+and control the use of terminal special files.
+This information is read with the
+.Xr getttyent 3
+library routines.
+There is one line in the
+.Nm
+file per special device file.
+Fields are separated by tabs and/or spaces.
+Fields comprised of more than one word should be enclosed in double
+quotes (``"'').
+Blank lines and comments may appear anywhere in the file; comments
+are delimited by hash marks (``#'') and new lines.
+Any unspecified fields will default to null.
+.Pp
+The first field is normally the
+name of the terminal special file as it is found in
+.Pa /dev .
+However, it can be any arbitrary string
+when the associated command is not related to a tty.
+.Pp
+The second field of the file is the command to execute for the line,
+usually
+.Xr getty 8 ,
+which initializes and opens the line, setting the speed, waiting for
+a user name and executing the
+.Xr login 1
+program.
+It can be, however, any desired command, for example
+the start up for a window system terminal emulator or some other
+daemon process, and can contain multiple words if quoted.
+.Pp
+The third field is the type of terminal usually connected to that
+tty line, normally the one found in the
+.Xr termcap 5
+data base file.
+The environment variable
+.Ev TERM
+is initialized with the value by
+either
+.Xr getty 8
+or
+.Xr login 1 .
+.Pp
+The remaining fields set flags in the
+.Fa ty_status
+entry (see
+.Xr getttyent 3 ) ,
+specify a window system process that
+.Xr launchd 8
+will maintain for the terminal line.
+.Pp
+As flag values, the strings ``on'' and ``off'' specify that
+.Xr launchd 8
+should (should not) execute the command given in the second field,
+while ``secure'' (if ``on'' is also specified) allows users with a
+uid of 0 to login on
+this line.
+The flags ``local'', ``rtscts'', ``mdmbuf'', and ``softcar''
+modify the default behaviour of the terminal line, and their actions
+are driver dependent.
+The ``local'' flag causes the driver to
+treat the line as if it locally connected.
+The ``rtscts'' flag
+instructs the driver to use RTS/CTS hardware flow control, if
+possible.
+The ``mdmbuf'' flag instructs the driver to use
+DTR/DCD flow control, if possible.
+The ``softcar'' flag causes the driver to ignore
+hardware carrier on the line.
+These flag fields should not be quoted.
+.Pp
+The string ``window='' may be followed by a quoted command
+string which
+.Xr launchd 8
+will execute
+.Em before
+starting the command specified by the second field.
+.Sh FILES
+.Bl -tag -width /etc/ttys -compact
+.It Pa /etc/ttys
+.El
+.Sh NUMERIC SEQUENCES
+Numeric sequences of terminals can be represented in a more compact format.
+A matching pair of square bracket may enclose two numbers (the start and
+stop values), separated by a hyphen.
+The numbers are assumed to be decimal, unless prefixed with ``0x'', in which
+case they are interpreted as hexadecimal.
+The number of characters (not including any ``0x'') in the starting value gives
+the minimum width; sequence values are zero padded up to this width.
+Thus ``tty[00-07]'' represents the eight terminals ``tty00'' through ``tty07''.
+.Sh EXAMPLES
+.Bd -literal
+# root login on console at 1200 baud
+console "/usr/libexec/getty std.1200" vt100 on secure
+# dialup at 1200 baud, no root logins
+ttyd0 "/usr/libexec/getty d1200" dialup on # 555-1234
+# Mike's terminal: hp2621
+ttyh0 "/usr/libexec/getty std.9600" hp2621-nl on # 457 Evans
+# John's terminal: vt100
+ttyh1 "/usr/libexec/getty std.9600" vt100 on # 459 Evans
+# terminal emulate/window system
+ttyv0 "/usr/X11/bin/xterm -display :0" xterm on window="/usr/X11/bin/X :0"
+# the sequence of eight terminals tty00 through tty07
+tty[00-07] "/usr/libexec/getty std.9600" vt100 on
+# Network pseudo ttys -- don't enable getty
+ttyp0 none network
+ttyp1 none network off
+# All sixteen of a pseudo tty sequence
+ttyq[0x0-0xf] none network
+.Ed
+.Sh SEE ALSO
+.Xr login 1 ,
+.Xr getttyent 3 ,
+.Xr ttyslot 3 ,
+.Xr gettytab 5 ,
+.Xr termcap 5 ,
+.Xr getty 8 ,
+.Xr launchd 8
+.\" .Xr ttyflags 8
+.Sh HISTORY
+A
+.Nm
+file appeared in
+.At v6 .