1*caba86e5Sjmcneill /* $NetBSD: main.c,v 1.68 2021/10/12 23:40:38 jmcneill Exp $ */
23ff0b1a7Sthorpej
361f28255Scgd /*-
4fe822416Spk * Copyright (c) 1980, 1993
5fe822416Spk * The Regents of the University of California. All rights reserved.
661f28255Scgd *
761f28255Scgd * Redistribution and use in source and binary forms, with or without
861f28255Scgd * modification, are permitted provided that the following conditions
961f28255Scgd * are met:
1061f28255Scgd * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd * notice, this list of conditions and the following disclaimer.
1261f28255Scgd * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd * notice, this list of conditions and the following disclaimer in the
1461f28255Scgd * documentation and/or other materials provided with the distribution.
158e6ab883Sagc * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd * may be used to endorse or promote products derived from this software
1761f28255Scgd * without specific prior written permission.
1861f28255Scgd *
1961f28255Scgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd * SUCH DAMAGE.
3061f28255Scgd */
3161f28255Scgd
3264521eb3Smikel #include <sys/cdefs.h>
3364521eb3Smikel
3461f28255Scgd #ifndef lint
350c4ddb15Slukem __COPYRIGHT("@(#) Copyright (c) 1980, 1993\
360c4ddb15Slukem The Regents of the University of California. All rights reserved.");
3761f28255Scgd #endif /* not lint */
3861f28255Scgd
3961f28255Scgd #ifndef lint
403ff0b1a7Sthorpej #if 0
413ff0b1a7Sthorpej static char sccsid[] = "from: @(#)main.c 8.1 (Berkeley) 6/20/93";
423ff0b1a7Sthorpej #else
43*caba86e5Sjmcneill __RCSID("$NetBSD: main.c,v 1.68 2021/10/12 23:40:38 jmcneill Exp $");
443ff0b1a7Sthorpej #endif
4561f28255Scgd #endif /* not lint */
4661f28255Scgd
4761f28255Scgd #include <sys/param.h>
487243f6f6Spk #include <sys/ioctl.h>
49fe822416Spk #include <sys/resource.h>
507d85ef5cSchristos #include <sys/stat.h>
51cea87043Smycroft #include <sys/utsname.h>
52a6da6f65Smikel
536c41aa55Sdholland #include <ctype.h>
546c5f1488Scgd #include <errno.h>
5561f28255Scgd #include <fcntl.h>
566c41aa55Sdholland #include <limits.h>
57fd97c4a9Scjs #include <pwd.h>
5861f28255Scgd #include <setjmp.h>
59fe822416Spk #include <signal.h>
6092227bd1Schristos #include <stdio.h>
6161f28255Scgd #include <stdlib.h>
6261f28255Scgd #include <string.h>
63fe822416Spk #include <syslog.h>
6498eb8895Sroy #include <term.h>
6592227bd1Schristos #include <termios.h>
66fe822416Spk #include <time.h>
676c41aa55Sdholland #include <ttyent.h>
68fe822416Spk #include <unistd.h>
6901120f44Sjtc #include <util.h>
70fe822416Spk
7161f28255Scgd #include "gettytab.h"
7261f28255Scgd #include "pathnames.h"
73fe822416Spk #include "extern.h"
7461f28255Scgd
75c6a0145eSchristos extern char editedhost[];
76fd97c4a9Scjs
77fe822416Spk /*
78fe822416Spk * Set the amount of running time that getty should accumulate
79fe822416Spk * before deciding that something is wrong and exit.
80fe822416Spk */
81fe822416Spk #define GETTY_TIMEOUT 60 /* seconds */
82fe822416Spk
8313b21dc1Stsarna /* defines for auto detection of incoming PPP calls (->PAP/CHAP) */
8413b21dc1Stsarna
8513b21dc1Stsarna #define PPP_FRAME 0x7e /* PPP Framing character */
8613b21dc1Stsarna #define PPP_STATION 0xff /* "All Station" character */
8713b21dc1Stsarna #define PPP_ESCAPE 0x7d /* Escape Character */
8813b21dc1Stsarna #define PPP_CONTROL 0x03 /* PPP Control Field */
8913b21dc1Stsarna #define PPP_CONTROL_ESCAPED 0x23 /* PPP Control Field, escaped */
9013b21dc1Stsarna #define PPP_LCP_HI 0xc0 /* LCP protocol - high byte */
9113b21dc1Stsarna #define PPP_LCP_LOW 0x21 /* LCP protocol - low byte */
9213b21dc1Stsarna
93fe822416Spk struct termios tmode, omode;
9461f28255Scgd
956fc636d8Sdholland int crmod, digit_or_punc, lower, upper;
9661f28255Scgd
972beab49aSmrg char hostname[MAXHOSTNAMELEN + 1];
98cea87043Smycroft struct utsname kerninfo;
99d46a0af8Sdrochner char name[LOGIN_NAME_MAX];
10061f28255Scgd char dev[] = _PATH_DEV;
10161f28255Scgd char ttyn[32];
102fcfd8038Sriastradh uid_t ttyowner = 0;
103ac8e2453Ssommerfeld char *rawttyn;
10461f28255Scgd
10561f28255Scgd #define OBUFSIZ 128
10661f28255Scgd #define TABBUFSIZ 512
10761f28255Scgd
10861f28255Scgd char defent[TABBUFSIZ];
10961f28255Scgd char tabent[TABBUFSIZ];
11061f28255Scgd
11161f28255Scgd char *env[128];
11261f28255Scgd
11323431545Schristos const unsigned char partab[] = {
11461f28255Scgd 0001,0201,0201,0001,0201,0001,0001,0201,
11561f28255Scgd 0202,0004,0003,0205,0005,0206,0201,0001,
11661f28255Scgd 0201,0001,0001,0201,0001,0201,0201,0001,
11761f28255Scgd 0001,0201,0201,0001,0201,0001,0001,0201,
11861f28255Scgd 0200,0000,0000,0200,0000,0200,0200,0000,
11961f28255Scgd 0000,0200,0200,0000,0200,0000,0000,0200,
12061f28255Scgd 0000,0200,0200,0000,0200,0000,0000,0200,
12161f28255Scgd 0200,0000,0000,0200,0000,0200,0200,0000,
12261f28255Scgd 0200,0000,0000,0200,0000,0200,0200,0000,
12361f28255Scgd 0000,0200,0200,0000,0200,0000,0000,0200,
12461f28255Scgd 0000,0200,0200,0000,0200,0000,0000,0200,
12561f28255Scgd 0200,0000,0000,0200,0000,0200,0200,0000,
12661f28255Scgd 0000,0200,0200,0000,0200,0000,0000,0200,
12761f28255Scgd 0200,0000,0000,0200,0000,0200,0200,0000,
12861f28255Scgd 0200,0000,0000,0200,0000,0200,0200,0000,
12961f28255Scgd 0000,0200,0200,0000,0200,0000,0000,0201
13061f28255Scgd };
13161f28255Scgd
1327243f6f6Spk #define ERASE tmode.c_cc[VERASE]
1337243f6f6Spk #define KILL tmode.c_cc[VKILL]
1347243f6f6Spk #define EOT tmode.c_cc[VEOF]
13561f28255Scgd
1365648feb3Sthorpej static void clearscreen(void);
13764521eb3Smikel
13827c14eadSdholland sigjmp_buf timeout;
13961f28255Scgd
140fabae2a4Sjoerg __dead static void
14123431545Schristos /*ARGSUSED*/
dingdong(int signo)1425648feb3Sthorpej dingdong(int signo)
14361f28255Scgd {
14461f28255Scgd
14523431545Schristos (void)alarm(0);
14623431545Schristos (void)signal(SIGALRM, SIG_DFL);
14727c14eadSdholland siglongjmp(timeout, 1);
14861f28255Scgd }
14961f28255Scgd
15027c14eadSdholland sigjmp_buf intrupt;
15161f28255Scgd
152fabae2a4Sjoerg __dead static void
15323431545Schristos /*ARGSUSED*/
interrupt(int signo)1545648feb3Sthorpej interrupt(int signo)
15561f28255Scgd {
15661f28255Scgd
15723431545Schristos (void)signal(SIGINT, interrupt);
15827c14eadSdholland siglongjmp(intrupt, 1);
15961f28255Scgd }
16061f28255Scgd
161fe822416Spk /*
162fe822416Spk * Action to take when getty is running too long.
163fe822416Spk */
164fabae2a4Sjoerg __dead static void
16523431545Schristos /*ARGSUSED*/
timeoverrun(int signo)1665648feb3Sthorpej timeoverrun(int signo)
167fe822416Spk {
168fe822416Spk
16913b21dc1Stsarna syslog(LOG_ERR, "getty exiting due to excessive running time");
170fe822416Spk exit(1);
171fe822416Spk }
172fe822416Spk
1735648feb3Sthorpej static int getname(void);
1745648feb3Sthorpej static void oflush(void);
1755648feb3Sthorpej static void prompt(void);
176d56846afSroy static int putchr(int);
1775648feb3Sthorpej static void putf(const char *);
1785648feb3Sthorpej static void xputs(const char *);
179fe822416Spk
180d56846afSroy #define putpad(s) tputs(s, 1, putchr)
181d56846afSroy
182fe822416Spk int
main(int argc,char * argv[],char * envp[])18323431545Schristos main(int argc, char *argv[], char *envp[])
18461f28255Scgd {
18543c3c3f7Schristos int repcnt = 0, failopenlogged = 0;
18643c3c3f7Schristos volatile int first_time = 1;
187fe822416Spk struct rlimit limit;
18813b21dc1Stsarna int rval;
18900b8abd4Smartin /* this is used past the siglongjmp, so make sure it is not cached
19000b8abd4Smartin in registers that might become invalid. */
19100b8abd4Smartin const char * volatile tname = "default";
19261f28255Scgd
19323431545Schristos (void)signal(SIGINT, SIG_IGN);
19423e33516Slukem openlog("getty", LOG_PID, LOG_AUTH);
19523431545Schristos (void)gethostname(hostname, sizeof(hostname));
1962beab49aSmrg hostname[sizeof(hostname) - 1] = '\0';
19761f28255Scgd if (hostname[0] == '\0')
19823431545Schristos (void)strlcpy(hostname, "Amnesiac", sizeof(hostname));
19923431545Schristos (void)uname(&kerninfo);
200fe822416Spk
201fe822416Spk /*
202fe822416Spk * Limit running time to deal with broken or dead lines.
203fe822416Spk */
204fe822416Spk (void)signal(SIGXCPU, timeoverrun);
205fe822416Spk limit.rlim_max = RLIM_INFINITY;
206fe822416Spk limit.rlim_cur = GETTY_TIMEOUT;
207fe822416Spk (void)setrlimit(RLIMIT_CPU, &limit);
208fe822416Spk
20961f28255Scgd /*
21061f28255Scgd * The following is a work around for vhangup interactions
21161f28255Scgd * which cause great problems getting window systems started.
21261f28255Scgd * If the tty line is "-", we do the old style getty presuming
21361f28255Scgd * that the file descriptors are already set up for us.
21461f28255Scgd * J. Gettys - MIT Project Athena.
21561f28255Scgd */
21680eef670Stls if (argc <= 2 || strcmp(argv[2], "-") == 0) {
21723431545Schristos (void)strlcpy(ttyn, ttyname(0), sizeof(ttyn));
21880eef670Stls }
21961f28255Scgd else {
22061f28255Scgd int i;
22161f28255Scgd
222ac8e2453Ssommerfeld rawttyn = argv[2];
22323431545Schristos (void)strlcpy(ttyn, dev, sizeof(ttyn));
22423431545Schristos (void)strlcat(ttyn, argv[2], sizeof(ttyn));
22561f28255Scgd if (strcmp(argv[0], "+") != 0) {
22623431545Schristos (void)chown(ttyn, ttyowner, 0);
22723431545Schristos (void)chmod(ttyn, 0600);
22823431545Schristos (void)revoke(ttyn);
229d2ae1a2cSgwr if (ttyaction(ttyn, "getty", "root"))
23023431545Schristos syslog(LOG_WARNING, "%s: ttyaction failed",
23123431545Schristos ttyn);
23261f28255Scgd while ((i = open(ttyn, O_RDWR)) == -1) {
2336c5f1488Scgd if ((repcnt % 10 == 0) &&
2346c5f1488Scgd (errno != ENXIO || !failopenlogged)) {
23523e33516Slukem syslog(LOG_WARNING, "%s: %m", ttyn);
23661f28255Scgd closelog();
2376c5f1488Scgd failopenlogged = 1;
23861f28255Scgd }
23961f28255Scgd repcnt++;
24023431545Schristos (void)sleep(60);
24161f28255Scgd }
24223431545Schristos (void)login_tty(i);
24361f28255Scgd }
24461f28255Scgd }
24561f28255Scgd
2467243f6f6Spk /* Start with default tty settings */
2477243f6f6Spk if (tcgetattr(0, &tmode) < 0) {
2487243f6f6Spk syslog(LOG_ERR, "%s: %m", ttyn);
2497243f6f6Spk exit(1);
2507243f6f6Spk }
251fe822416Spk omode = tmode;
2527243f6f6Spk
25303fe423bScgd gettable("default", defent);
25461f28255Scgd gendefaults();
25561f28255Scgd if (argc > 1)
25661f28255Scgd tname = argv[1];
25761f28255Scgd for (;;) {
258fe822416Spk int off;
25961f28255Scgd
260a8ce8744Slukem rval = 0;
26103fe423bScgd gettable(tname, tabent);
26261f28255Scgd if (OPset || EPset || APset)
26361f28255Scgd APset++, OPset++, EPset++;
26461f28255Scgd setdefaults();
265fe822416Spk off = 0;
2666b619f18Spk (void)tcflush(0, TCIOFLUSH); /* clear out the crap */
26723431545Schristos (void)ioctl(0, FIONBIO, &off); /* turn off non-blocking mode */
26823431545Schristos (void)ioctl(0, FIOASYNC, &off); /* ditto for async mode */
2697243f6f6Spk
27061f28255Scgd if (IS)
27123431545Schristos (void)cfsetispeed(&tmode, (speed_t)IS);
27261f28255Scgd else if (SP)
27323431545Schristos (void)cfsetispeed(&tmode, (speed_t)SP);
27461f28255Scgd if (OS)
27523431545Schristos (void)cfsetospeed(&tmode, (speed_t)OS);
27661f28255Scgd else if (SP)
27723431545Schristos (void)cfsetospeed(&tmode, (speed_t)SP);
2787243f6f6Spk setflags(0);
27961f28255Scgd setchars();
2807243f6f6Spk if (tcsetattr(0, TCSANOW, &tmode) < 0) {
2817243f6f6Spk syslog(LOG_ERR, "%s: %m", ttyn);
2827243f6f6Spk exit(1);
2837243f6f6Spk }
28461f28255Scgd if (AB) {
28561f28255Scgd tname = autobaud();
28661f28255Scgd continue;
28761f28255Scgd }
28861f28255Scgd if (PS) {
28961f28255Scgd tname = portselector();
29061f28255Scgd continue;
29161f28255Scgd }
292ac8e2453Ssommerfeld if (CS)
293ac8e2453Ssommerfeld clearscreen();
29461f28255Scgd if (CL && *CL)
29561f28255Scgd putpad(CL);
29661f28255Scgd edithost(HE);
2972a1297dbSad
2982a1297dbSad /*
2992a1297dbSad * If this is the first time through this, and an
3002a1297dbSad * issue file has been given, then send it.
3012a1297dbSad */
3026aa5f514Sad if (first_time != 0 && IF != NULL) {
3032a1297dbSad char buf[_POSIX2_LINE_MAX];
30423431545Schristos FILE *fp;
3052a1297dbSad
30623431545Schristos if ((fp = fopen(IF, "r")) != NULL) {
30723431545Schristos while (fgets(buf, sizeof(buf) - 1, fp) != NULL)
3082a1297dbSad putf(buf);
30923431545Schristos (void)fclose(fp);
3102a1297dbSad }
3112a1297dbSad }
3122a1297dbSad first_time = 0;
3132a1297dbSad
31461f28255Scgd if (IM && *IM)
31561f28255Scgd putf(IM);
316ca59ae7cSkml oflush();
31727c14eadSdholland if (sigsetjmp(timeout, 1)) {
3187243f6f6Spk tmode.c_ispeed = tmode.c_ospeed = 0;
3197243f6f6Spk (void)tcsetattr(0, TCSANOW, &tmode);
32061f28255Scgd exit(1);
32161f28255Scgd }
32261f28255Scgd if (TO) {
32323431545Schristos (void)signal(SIGALRM, dingdong);
32423431545Schristos (void)alarm((unsigned int)TO);
32561f28255Scgd }
3262c1e4826Sthorpej if (NN) {
3272c1e4826Sthorpej name[0] = '\0';
3282c1e4826Sthorpej lower = 1;
3296fc636d8Sdholland upper = digit_or_punc = 0;
3302c1e4826Sthorpej } else if (AL) {
3312a1297dbSad const char *p = AL;
3322a1297dbSad char *q = name;
3332a1297dbSad
3342a1297dbSad while (*p && q < &name[sizeof name - 1]) {
33555d39107Sdsl if (isupper((unsigned char)*p))
3362a1297dbSad upper = 1;
33755d39107Sdsl else if (islower((unsigned char)*p))
3382a1297dbSad lower = 1;
33955d39107Sdsl else if (isdigit((unsigned char)*p))
3406fc636d8Sdholland digit_or_punc = 1;
3412a1297dbSad *q++ = *p++;
3422a1297dbSad }
3432a1297dbSad } else if ((rval = getname()) == 2) {
3447f94fc6dSchristos setflags(2);
34523431545Schristos (void)execle(PP, "ppplogin", ttyn, (char *) 0, env);
34613b21dc1Stsarna syslog(LOG_ERR, "%s: %m", PP);
34713b21dc1Stsarna exit(1);
3482a1297dbSad }
3492a1297dbSad
3502c1e4826Sthorpej if (rval || AL || NN) {
351d5088f6aSmrg int i;
35261f28255Scgd
35361f28255Scgd oflush();
35423431545Schristos (void)alarm(0);
35523431545Schristos (void)signal(SIGALRM, SIG_DFL);
35661f28255Scgd if (name[0] == '-') {
3578cbf1ce9Sthorpej xputs("user names may not start with '-'.");
35861f28255Scgd continue;
35961f28255Scgd }
3606fc636d8Sdholland if (!(upper || lower || digit_or_punc))
36161f28255Scgd continue;
3627243f6f6Spk setflags(2);
3637243f6f6Spk if (crmod) {
3647243f6f6Spk tmode.c_iflag |= ICRNL;
3657243f6f6Spk tmode.c_oflag |= ONLCR;
3667243f6f6Spk }
3677243f6f6Spk #if XXX
36861f28255Scgd if (upper || UC)
36961f28255Scgd tmode.sg_flags |= LCASE;
37061f28255Scgd if (lower || LC)
37161f28255Scgd tmode.sg_flags &= ~LCASE;
3727243f6f6Spk #endif
3737243f6f6Spk if (tcsetattr(0, TCSANOW, &tmode) < 0) {
3747243f6f6Spk syslog(LOG_ERR, "%s: %m", ttyn);
3757243f6f6Spk exit(1);
3767243f6f6Spk }
37723431545Schristos (void)signal(SIGINT, SIG_DFL);
37823431545Schristos for (i = 0; envp[i] != NULL; i++)
37923431545Schristos env[i] = envp[i];
38061f28255Scgd makeenv(&env[i]);
381fe822416Spk
382fe822416Spk limit.rlim_max = RLIM_INFINITY;
383fe822416Spk limit.rlim_cur = RLIM_INFINITY;
384fe822416Spk (void)setrlimit(RLIMIT_CPU, &limit);
3852c1e4826Sthorpej if (NN)
38623431545Schristos (void)execle(LO, "login", AL ? "-fp" : "-p",
3872c1e4826Sthorpej NULL, env);
3882c1e4826Sthorpej else
38923431545Schristos (void)execle(LO, "login", AL ? "-fp" : "-p",
3902c1e4826Sthorpej "--", name, NULL, env);
39161f28255Scgd syslog(LOG_ERR, "%s: %m", LO);
39261f28255Scgd exit(1);
39361f28255Scgd }
39423431545Schristos (void)alarm(0);
39523431545Schristos (void)signal(SIGALRM, SIG_DFL);
39623431545Schristos (void)signal(SIGINT, SIG_IGN);
39761f28255Scgd if (NX && *NX)
39861f28255Scgd tname = NX;
39961f28255Scgd }
40061f28255Scgd }
40161f28255Scgd
402fe822416Spk static int
getname(void)4035648feb3Sthorpej getname(void)
40461f28255Scgd {
405d5088f6aSmrg int c;
406d5088f6aSmrg char *np;
40713b21dc1Stsarna unsigned char cs;
40813b21dc1Stsarna int ppp_state, ppp_connection;
40961f28255Scgd
41061f28255Scgd /*
41161f28255Scgd * Interrupt may happen if we use CBREAK mode
41261f28255Scgd */
41327c14eadSdholland if (sigsetjmp(intrupt, 1)) {
41423431545Schristos (void)signal(SIGINT, SIG_IGN);
41561f28255Scgd return (0);
41661f28255Scgd }
41723431545Schristos (void)signal(SIGINT, interrupt);
4187243f6f6Spk setflags(1);
41961f28255Scgd prompt();
42061f28255Scgd if (PF > 0) {
42161f28255Scgd oflush();
42223431545Schristos (void)sleep((unsigned int)PF);
42361f28255Scgd PF = 0;
42461f28255Scgd }
4257243f6f6Spk if (tcsetattr(0, TCSANOW, &tmode) < 0) {
4267243f6f6Spk syslog(LOG_ERR, "%s: %m", ttyn);
4277243f6f6Spk exit(1);
4287243f6f6Spk }
4296fc636d8Sdholland crmod = digit_or_punc = lower = upper = 0;
43013b21dc1Stsarna ppp_state = ppp_connection = 0;
43161f28255Scgd np = name;
43261f28255Scgd for (;;) {
43361f28255Scgd oflush();
43461f28255Scgd if (read(STDIN_FILENO, &cs, 1) <= 0)
43561f28255Scgd exit(0);
43661f28255Scgd if ((c = cs&0177) == 0)
43761f28255Scgd return (0);
43813b21dc1Stsarna
43913b21dc1Stsarna /*
44013b21dc1Stsarna * PPP detection state machine..
44113b21dc1Stsarna * Look for sequences:
44213b21dc1Stsarna * PPP_FRAME, PPP_STATION, PPP_ESCAPE, PPP_CONTROL_ESCAPED or
44313b21dc1Stsarna * PPP_FRAME, PPP_STATION, PPP_CONTROL (deviant from RFC)
44413b21dc1Stsarna * See RFC1662.
44513b21dc1Stsarna * Derived from code from Michael Hancock <michaelh@cet.co.jp>
44613b21dc1Stsarna * and Erik 'PPP' Olson <eriko@wrq.com>
44713b21dc1Stsarna */
44813b21dc1Stsarna if (PP && cs == PPP_FRAME) {
44913b21dc1Stsarna ppp_state = 1;
45013b21dc1Stsarna } else if (ppp_state == 1 && cs == PPP_STATION) {
45113b21dc1Stsarna ppp_state = 2;
45213b21dc1Stsarna } else if (ppp_state == 2 && cs == PPP_ESCAPE) {
45313b21dc1Stsarna ppp_state = 3;
45413b21dc1Stsarna } else if ((ppp_state == 2 && cs == PPP_CONTROL) ||
45513b21dc1Stsarna (ppp_state == 3 && cs == PPP_CONTROL_ESCAPED)) {
45613b21dc1Stsarna ppp_state = 4;
45713b21dc1Stsarna } else if (ppp_state == 4 && cs == PPP_LCP_HI) {
45813b21dc1Stsarna ppp_state = 5;
45913b21dc1Stsarna } else if (ppp_state == 5 && cs == PPP_LCP_LOW) {
46013b21dc1Stsarna ppp_connection = 1;
46113b21dc1Stsarna break;
46213b21dc1Stsarna } else {
46313b21dc1Stsarna ppp_state = 0;
46413b21dc1Stsarna }
46513b21dc1Stsarna
46661f28255Scgd if (c == EOT)
46761f28255Scgd exit(1);
468d46a0af8Sdrochner if (c == '\r' || c == '\n' ||
469d46a0af8Sdrochner np >= &name[LOGIN_NAME_MAX - 1]) {
470d46a0af8Sdrochner *np = '\0';
47161f28255Scgd putf("\r\n");
47261f28255Scgd break;
47361f28255Scgd }
47461f28255Scgd if (islower(c))
47561f28255Scgd lower = 1;
47661f28255Scgd else if (isupper(c))
47761f28255Scgd upper = 1;
47861f28255Scgd else if (c == ERASE || c == '#' || c == '\b') {
47961f28255Scgd if (np > name) {
48061f28255Scgd np--;
4812f65aa5dSmycroft if (cfgetospeed(&tmode) >= 1200)
4828cbf1ce9Sthorpej xputs("\b \b");
48361f28255Scgd else
48461f28255Scgd putchr(cs);
48561f28255Scgd }
48661f28255Scgd continue;
48761f28255Scgd } else if (c == KILL || c == '@') {
48861f28255Scgd putchr(cs);
48961f28255Scgd putchr('\r');
4902f65aa5dSmycroft if (cfgetospeed(&tmode) < 1200)
49161f28255Scgd putchr('\n');
49261f28255Scgd /* this is the way they do it down under ... */
49361f28255Scgd else if (np > name)
4948cbf1ce9Sthorpej xputs(
4958cbf1ce9Sthorpej " \r");
49661f28255Scgd prompt();
49761f28255Scgd np = name;
49861f28255Scgd continue;
4996fc636d8Sdholland } else if (isdigit(c) || c == '_')
5006fc636d8Sdholland digit_or_punc = 1;
50161f28255Scgd if (IG && (c <= ' ' || c > 0176))
50261f28255Scgd continue;
50361f28255Scgd *np++ = c;
50461f28255Scgd putchr(cs);
5056b9ab756Schristos
5066b9ab756Schristos /*
5076b9ab756Schristos * An MS-Windows direct connect PPP "client" won't send its
5086b9ab756Schristos * first PPP packet until we respond to its "CLIENT" poll
5096b9ab756Schristos * with a CRLF sequence. We cater to yet another broken
5106b9ab756Schristos * implementation of a previously-standard protocol...
5116b9ab756Schristos */
5126b9ab756Schristos *np = '\0';
5136b9ab756Schristos if (strstr(name, "CLIENT"))
5146b9ab756Schristos putf("\r\n");
51561f28255Scgd }
51623431545Schristos (void)signal(SIGINT, SIG_IGN);
51761f28255Scgd *np = 0;
51861f28255Scgd if (c == '\r')
51961f28255Scgd crmod = 1;
52064521eb3Smikel if ((upper && !lower && !LC) || UC)
52161f28255Scgd for (np = name; *np; np++)
52255d39107Sdsl *np = tolower((unsigned char)*np);
52313b21dc1Stsarna return (1 + ppp_connection);
52461f28255Scgd }
52561f28255Scgd
526fe822416Spk static void
xputs(const char * s)5275648feb3Sthorpej xputs(const char *s)
52861f28255Scgd {
52961f28255Scgd while (*s)
53061f28255Scgd putchr(*s++);
53161f28255Scgd }
53261f28255Scgd
53361f28255Scgd char outbuf[OBUFSIZ];
53423431545Schristos size_t obufcnt = 0;
53561f28255Scgd
536d56846afSroy static int
putchr(int cc)5375648feb3Sthorpej putchr(int cc)
53861f28255Scgd {
53923431545Schristos unsigned char c;
54061f28255Scgd
54161f28255Scgd c = cc;
54261f28255Scgd if (!NP) {
54361f28255Scgd c |= partab[c&0177] & 0200;
54461f28255Scgd if (OP)
54561f28255Scgd c ^= 0200;
54661f28255Scgd }
54761f28255Scgd if (!UB) {
54861f28255Scgd outbuf[obufcnt++] = c;
54961f28255Scgd if (obufcnt >= OBUFSIZ)
55061f28255Scgd oflush();
551d56846afSroy return 1;
552d56846afSroy }
553d56846afSroy return write(STDOUT_FILENO, &c, 1);
55461f28255Scgd }
55561f28255Scgd
556fe822416Spk static void
oflush(void)5575648feb3Sthorpej oflush(void)
55861f28255Scgd {
55961f28255Scgd if (obufcnt)
56023431545Schristos (void)write(STDOUT_FILENO, outbuf, obufcnt);
56161f28255Scgd obufcnt = 0;
56261f28255Scgd }
56361f28255Scgd
564fe822416Spk static void
prompt(void)5655648feb3Sthorpej prompt(void)
56661f28255Scgd {
56761f28255Scgd
56861f28255Scgd putf(LM);
56961f28255Scgd if (CO)
57061f28255Scgd putchr('\n');
57161f28255Scgd }
57261f28255Scgd
573fe822416Spk static void
putf(const char * cp)5745648feb3Sthorpej putf(const char *cp)
57561f28255Scgd {
57661f28255Scgd time_t t;
57761f28255Scgd char *slash, db[100];
57861f28255Scgd
57961f28255Scgd while (*cp) {
58061f28255Scgd if (*cp != '%') {
58161f28255Scgd putchr(*cp++);
58261f28255Scgd continue;
58361f28255Scgd }
58461f28255Scgd switch (*++cp) {
58561f28255Scgd
58661f28255Scgd case 't':
58700e4cd7dSchristos if ((slash = strstr(ttyn, "/pts/")) == NULL)
588fe822416Spk slash = strrchr(ttyn, '/');
5894fdc2599Smjl if (slash == NULL)
5908cbf1ce9Sthorpej xputs(ttyn);
59161f28255Scgd else
5928cbf1ce9Sthorpej xputs(&slash[1]);
59361f28255Scgd break;
59461f28255Scgd
59561f28255Scgd case 'h':
5968cbf1ce9Sthorpej xputs(editedhost);
59761f28255Scgd break;
59861f28255Scgd
599d657c604Sbjh21 case 'd':
60061f28255Scgd (void)time(&t);
601d657c604Sbjh21 (void)strftime(db, sizeof(db),
602bf31e2abSmbalmer "%l:%M%p on %A, %d %B %Y", localtime(&t));
6038cbf1ce9Sthorpej xputs(db);
60461f28255Scgd break;
605cea87043Smycroft
606cea87043Smycroft case 's':
6078cbf1ce9Sthorpej xputs(kerninfo.sysname);
608cea87043Smycroft break;
609cea87043Smycroft
610cea87043Smycroft case 'm':
6118cbf1ce9Sthorpej xputs(kerninfo.machine);
612cea87043Smycroft break;
613cea87043Smycroft
614cea87043Smycroft case 'r':
6158cbf1ce9Sthorpej xputs(kerninfo.release);
616cea87043Smycroft break;
617cea87043Smycroft
618cea87043Smycroft case 'v':
6198cbf1ce9Sthorpej xputs(kerninfo.version);
620cea87043Smycroft break;
62161f28255Scgd
62261f28255Scgd case '%':
62361f28255Scgd putchr('%');
62461f28255Scgd break;
62561f28255Scgd }
626c10e6676Sbjh21 if (*cp)
62761f28255Scgd cp++;
62861f28255Scgd }
62961f28255Scgd }
630ac8e2453Ssommerfeld
631ac8e2453Ssommerfeld static void
clearscreen(void)6325648feb3Sthorpej clearscreen(void)
633ac8e2453Ssommerfeld {
634ac8e2453Ssommerfeld struct ttyent *typ;
63598eb8895Sroy int err;
636ac8e2453Ssommerfeld
637ac8e2453Ssommerfeld if (rawttyn == NULL)
638ac8e2453Ssommerfeld return;
639ac8e2453Ssommerfeld
640ac8e2453Ssommerfeld typ = getttynam(rawttyn);
641ac8e2453Ssommerfeld
642ac8e2453Ssommerfeld if ((typ == NULL) || (typ->ty_type == NULL) ||
643ac8e2453Ssommerfeld (typ->ty_type[0] == 0))
644ac8e2453Ssommerfeld return;
645ac8e2453Ssommerfeld
64698eb8895Sroy if (setupterm(typ->ty_type, 0, &err) == ERR)
647ac8e2453Ssommerfeld return;
648ac8e2453Ssommerfeld
64998eb8895Sroy if (clear_screen)
65098eb8895Sroy putpad(clear_screen);
651ac8e2453Ssommerfeld
65298eb8895Sroy del_curterm(cur_term);
65398eb8895Sroy cur_term = NULL;
654ac8e2453Ssommerfeld }
655