1df930be7Sderaadt /*- 2df930be7Sderaadt * Copyright (c) 1980, 1993 3df930be7Sderaadt * The Regents of the University of California. All rights reserved. 4df930be7Sderaadt * 5df930be7Sderaadt * Redistribution and use in source and binary forms, with or without 6df930be7Sderaadt * modification, are permitted provided that the following conditions 7df930be7Sderaadt * are met: 8df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright 9df930be7Sderaadt * notice, this list of conditions and the following disclaimer. 10df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright 11df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the 12df930be7Sderaadt * documentation and/or other materials provided with the distribution. 13df930be7Sderaadt * 3. All advertising materials mentioning features or use of this software 14df930be7Sderaadt * must display the following acknowledgement: 15df930be7Sderaadt * This product includes software developed by the University of 16df930be7Sderaadt * California, Berkeley and its contributors. 17df930be7Sderaadt * 4. Neither the name of the University nor the names of its contributors 18df930be7Sderaadt * may be used to endorse or promote products derived from this software 19df930be7Sderaadt * without specific prior written permission. 20df930be7Sderaadt * 21df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31df930be7Sderaadt * SUCH DAMAGE. 32df930be7Sderaadt */ 33df930be7Sderaadt 34df930be7Sderaadt #ifndef lint 35df930be7Sderaadt static char copyright[] = 36df930be7Sderaadt "@(#) Copyright (c) 1980, 1993\n\ 37df930be7Sderaadt The Regents of the University of California. All rights reserved.\n"; 38df930be7Sderaadt #endif /* not lint */ 39df930be7Sderaadt 40df930be7Sderaadt #ifndef lint 41df930be7Sderaadt /*static char sccsid[] = "from: @(#)main.c 8.1 (Berkeley) 6/20/93";*/ 42*8f901b87Stholo static char rcsid[] = "$Id: main.c,v 1.6 1996/12/17 19:33:53 tholo Exp $"; 43df930be7Sderaadt #endif /* not lint */ 44df930be7Sderaadt 45df930be7Sderaadt #include <sys/param.h> 46df930be7Sderaadt #include <sys/stat.h> 47df930be7Sderaadt #include <termios.h> 48df930be7Sderaadt #include <sys/ioctl.h> 49df930be7Sderaadt #include <sys/resource.h> 50df930be7Sderaadt #include <sys/utsname.h> 51df930be7Sderaadt #include <errno.h> 52df930be7Sderaadt #include <signal.h> 53df930be7Sderaadt #include <fcntl.h> 54df930be7Sderaadt #include <time.h> 55df930be7Sderaadt #include <ctype.h> 56df930be7Sderaadt #include <fcntl.h> 57df930be7Sderaadt #include <setjmp.h> 58df930be7Sderaadt #include <signal.h> 59df930be7Sderaadt #include <stdlib.h> 60df930be7Sderaadt #include <string.h> 61df930be7Sderaadt #include <syslog.h> 62df930be7Sderaadt #include <time.h> 63df930be7Sderaadt #include <unistd.h> 640abcd724Sderaadt #include <util.h> 65df930be7Sderaadt 66df930be7Sderaadt #include "gettytab.h" 67df930be7Sderaadt #include "pathnames.h" 68df930be7Sderaadt #include "extern.h" 69df930be7Sderaadt 70df930be7Sderaadt /* 71df930be7Sderaadt * Set the amount of running time that getty should accumulate 72df930be7Sderaadt * before deciding that something is wrong and exit. 73df930be7Sderaadt */ 74df930be7Sderaadt #define GETTY_TIMEOUT 60 /* seconds */ 75df930be7Sderaadt 76cf0bd593Sderaadt /* defines for auto detection of incoming PPP calls (->PAP/CHAP) */ 77cf0bd593Sderaadt 78cf0bd593Sderaadt #define PPP_FRAME 0x7e /* PPP Framing character */ 79cf0bd593Sderaadt #define PPP_STATION 0xff /* "All Station" character */ 80cf0bd593Sderaadt #define PPP_ESCAPE 0x7d /* Escape Character */ 81cf0bd593Sderaadt #define PPP_CONTROL 0x03 /* PPP Control Field */ 82cf0bd593Sderaadt #define PPP_CONTROL_ESCAPED 0x23 /* PPP Control Field, escaped */ 83cf0bd593Sderaadt #define PPP_LCP_HI 0xc0 /* LCP protocol - high byte */ 84cf0bd593Sderaadt #define PPP_LCP_LOW 0x21 /* LCP protocol - low byte */ 85cf0bd593Sderaadt 86df930be7Sderaadt struct termios tmode, omode; 87df930be7Sderaadt 88df930be7Sderaadt int crmod, digit, lower, upper; 89df930be7Sderaadt 90df930be7Sderaadt char hostname[MAXHOSTNAMELEN]; 91df930be7Sderaadt struct utsname kerninfo; 92df930be7Sderaadt char name[16]; 93df930be7Sderaadt char dev[] = _PATH_DEV; 94df930be7Sderaadt char ttyn[32]; 95df930be7Sderaadt char *portselector(); 96df930be7Sderaadt char *ttyname(); 97df930be7Sderaadt 98df930be7Sderaadt #define OBUFSIZ 128 99df930be7Sderaadt #define TABBUFSIZ 512 100df930be7Sderaadt 101df930be7Sderaadt char defent[TABBUFSIZ]; 102df930be7Sderaadt char tabent[TABBUFSIZ]; 103df930be7Sderaadt 104df930be7Sderaadt char *env[128]; 105df930be7Sderaadt 106df930be7Sderaadt char partab[] = { 107df930be7Sderaadt 0001,0201,0201,0001,0201,0001,0001,0201, 108df930be7Sderaadt 0202,0004,0003,0205,0005,0206,0201,0001, 109df930be7Sderaadt 0201,0001,0001,0201,0001,0201,0201,0001, 110df930be7Sderaadt 0001,0201,0201,0001,0201,0001,0001,0201, 111df930be7Sderaadt 0200,0000,0000,0200,0000,0200,0200,0000, 112df930be7Sderaadt 0000,0200,0200,0000,0200,0000,0000,0200, 113df930be7Sderaadt 0000,0200,0200,0000,0200,0000,0000,0200, 114df930be7Sderaadt 0200,0000,0000,0200,0000,0200,0200,0000, 115df930be7Sderaadt 0200,0000,0000,0200,0000,0200,0200,0000, 116df930be7Sderaadt 0000,0200,0200,0000,0200,0000,0000,0200, 117df930be7Sderaadt 0000,0200,0200,0000,0200,0000,0000,0200, 118df930be7Sderaadt 0200,0000,0000,0200,0000,0200,0200,0000, 119df930be7Sderaadt 0000,0200,0200,0000,0200,0000,0000,0200, 120df930be7Sderaadt 0200,0000,0000,0200,0000,0200,0200,0000, 121df930be7Sderaadt 0200,0000,0000,0200,0000,0200,0200,0000, 122df930be7Sderaadt 0000,0200,0200,0000,0200,0000,0000,0201 123df930be7Sderaadt }; 124df930be7Sderaadt 125df930be7Sderaadt #define ERASE tmode.c_cc[VERASE] 126df930be7Sderaadt #define KILL tmode.c_cc[VKILL] 127df930be7Sderaadt #define EOT tmode.c_cc[VEOF] 128df930be7Sderaadt 129df930be7Sderaadt jmp_buf timeout; 130df930be7Sderaadt 131df930be7Sderaadt static void 132df930be7Sderaadt dingdong() 133df930be7Sderaadt { 134df930be7Sderaadt 135df930be7Sderaadt alarm(0); 136df930be7Sderaadt signal(SIGALRM, SIG_DFL); 137df930be7Sderaadt longjmp(timeout, 1); 138df930be7Sderaadt } 139df930be7Sderaadt 140df930be7Sderaadt jmp_buf intrupt; 141df930be7Sderaadt 142df930be7Sderaadt static void 143df930be7Sderaadt interrupt() 144df930be7Sderaadt { 145df930be7Sderaadt 146df930be7Sderaadt signal(SIGINT, interrupt); 147df930be7Sderaadt longjmp(intrupt, 1); 148df930be7Sderaadt } 149df930be7Sderaadt 150df930be7Sderaadt /* 151df930be7Sderaadt * Action to take when getty is running too long. 152df930be7Sderaadt */ 153df930be7Sderaadt void 154df930be7Sderaadt timeoverrun(signo) 155df930be7Sderaadt int signo; 156df930be7Sderaadt { 157df930be7Sderaadt 158df930be7Sderaadt syslog(LOG_ERR, "getty exiting due to excessive running time\n"); 159df930be7Sderaadt exit(1); 160df930be7Sderaadt } 161df930be7Sderaadt 162df930be7Sderaadt static int getname __P((void)); 163df930be7Sderaadt static void oflush __P((void)); 164df930be7Sderaadt static void prompt __P((void)); 165df930be7Sderaadt static void putchr __P((int)); 166df930be7Sderaadt static void putf __P((char *)); 167df930be7Sderaadt static void putpad __P((char *)); 168df930be7Sderaadt static void puts __P((char *)); 169df930be7Sderaadt 170df930be7Sderaadt int 171df930be7Sderaadt main(argc, argv) 172df930be7Sderaadt int argc; 173df930be7Sderaadt char *argv[]; 174df930be7Sderaadt { 175df930be7Sderaadt extern char **environ; 176df930be7Sderaadt char *tname; 177df930be7Sderaadt long allflags; 178df930be7Sderaadt int repcnt = 0, failopenlogged = 0; 179df930be7Sderaadt struct rlimit limit; 180cf0bd593Sderaadt int rval; 181df930be7Sderaadt 182df930be7Sderaadt signal(SIGINT, SIG_IGN); 183df930be7Sderaadt /* 184df930be7Sderaadt signal(SIGQUIT, SIG_DFL); 185df930be7Sderaadt */ 186df930be7Sderaadt openlog("getty", LOG_ODELAY|LOG_CONS|LOG_PID, LOG_AUTH); 187df930be7Sderaadt gethostname(hostname, sizeof(hostname)); 188df930be7Sderaadt if (hostname[0] == '\0') 189df930be7Sderaadt strcpy(hostname, "Amnesiac"); 190df930be7Sderaadt uname(&kerninfo); 191df930be7Sderaadt 192df930be7Sderaadt /* 193df930be7Sderaadt * Limit running time to deal with broken or dead lines. 194df930be7Sderaadt */ 195df930be7Sderaadt (void)signal(SIGXCPU, timeoverrun); 196df930be7Sderaadt limit.rlim_max = RLIM_INFINITY; 197df930be7Sderaadt limit.rlim_cur = GETTY_TIMEOUT; 198df930be7Sderaadt (void)setrlimit(RLIMIT_CPU, &limit); 199df930be7Sderaadt 200df930be7Sderaadt /* 201df930be7Sderaadt * The following is a work around for vhangup interactions 202df930be7Sderaadt * which cause great problems getting window systems started. 203df930be7Sderaadt * If the tty line is "-", we do the old style getty presuming 204df930be7Sderaadt * that the file descriptors are already set up for us. 205df930be7Sderaadt * J. Gettys - MIT Project Athena. 206df930be7Sderaadt */ 207df930be7Sderaadt if (argc <= 2 || strcmp(argv[2], "-") == 0) 208df930be7Sderaadt strcpy(ttyn, ttyname(0)); 209df930be7Sderaadt else { 210df930be7Sderaadt int i; 211df930be7Sderaadt 212df930be7Sderaadt strcpy(ttyn, dev); 213df930be7Sderaadt strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev)); 214df930be7Sderaadt if (strcmp(argv[0], "+") != 0) { 215df930be7Sderaadt chown(ttyn, 0, 0); 216df930be7Sderaadt chmod(ttyn, 0600); 217df930be7Sderaadt revoke(ttyn); 218df930be7Sderaadt /* 219df930be7Sderaadt * Delay the open so DTR stays down long enough to be detected. 220df930be7Sderaadt */ 221df930be7Sderaadt sleep(2); 222df930be7Sderaadt while ((i = open(ttyn, O_RDWR)) == -1) { 223df930be7Sderaadt if ((repcnt % 10 == 0) && 224df930be7Sderaadt (errno != ENXIO || !failopenlogged)) { 225df930be7Sderaadt syslog(LOG_ERR, "%s: %m", ttyn); 226df930be7Sderaadt closelog(); 227df930be7Sderaadt failopenlogged = 1; 228df930be7Sderaadt } 229df930be7Sderaadt repcnt++; 230df930be7Sderaadt sleep(60); 231df930be7Sderaadt } 232df930be7Sderaadt login_tty(i); 233df930be7Sderaadt } 234df930be7Sderaadt } 235df930be7Sderaadt 236df930be7Sderaadt /* Start with default tty settings */ 237df930be7Sderaadt if (tcgetattr(0, &tmode) < 0) { 238df930be7Sderaadt syslog(LOG_ERR, "%s: %m", ttyn); 239df930be7Sderaadt exit(1); 240df930be7Sderaadt } 241df930be7Sderaadt omode = tmode; 242df930be7Sderaadt 243df930be7Sderaadt gettable("default", defent); 244df930be7Sderaadt gendefaults(); 245df930be7Sderaadt tname = "default"; 246df930be7Sderaadt if (argc > 1) 247df930be7Sderaadt tname = argv[1]; 248df930be7Sderaadt for (;;) { 249df930be7Sderaadt int off; 250df930be7Sderaadt 251df930be7Sderaadt gettable(tname, tabent); 252df930be7Sderaadt if (OPset || EPset || APset) 253df930be7Sderaadt APset++, OPset++, EPset++; 254df930be7Sderaadt setdefaults(); 255df930be7Sderaadt off = 0; 256df930be7Sderaadt (void)tcflush(0, TCIOFLUSH); /* clear out the crap */ 257df930be7Sderaadt ioctl(0, FIONBIO, &off); /* turn off non-blocking mode */ 258df930be7Sderaadt ioctl(0, FIOASYNC, &off); /* ditto for async mode */ 259df930be7Sderaadt 260df930be7Sderaadt if (IS) 261df930be7Sderaadt cfsetispeed(&tmode, IS); 262df930be7Sderaadt else if (SP) 263df930be7Sderaadt cfsetispeed(&tmode, SP); 264df930be7Sderaadt if (OS) 265df930be7Sderaadt cfsetospeed(&tmode, OS); 266df930be7Sderaadt else if (SP) 267df930be7Sderaadt cfsetospeed(&tmode, SP); 268df930be7Sderaadt setflags(0); 269df930be7Sderaadt setchars(); 270df930be7Sderaadt if (tcsetattr(0, TCSANOW, &tmode) < 0) { 271df930be7Sderaadt syslog(LOG_ERR, "%s: %m", ttyn); 272df930be7Sderaadt exit(1); 273df930be7Sderaadt } 274df930be7Sderaadt if (AB) { 275df930be7Sderaadt extern char *autobaud(); 276df930be7Sderaadt 277df930be7Sderaadt tname = autobaud(); 278df930be7Sderaadt continue; 279df930be7Sderaadt } 280df930be7Sderaadt if (PS) { 281df930be7Sderaadt tname = portselector(); 282df930be7Sderaadt continue; 283df930be7Sderaadt } 284df930be7Sderaadt if (CL && *CL) 285df930be7Sderaadt putpad(CL); 286df930be7Sderaadt edithost(HE); 287df930be7Sderaadt if (IM && *IM) 288df930be7Sderaadt putf(IM); 289df930be7Sderaadt if (setjmp(timeout)) { 290df930be7Sderaadt tmode.c_ispeed = tmode.c_ospeed = 0; 291df930be7Sderaadt (void)tcsetattr(0, TCSANOW, &tmode); 292df930be7Sderaadt exit(1); 293df930be7Sderaadt } 294df930be7Sderaadt if (TO) { 295df930be7Sderaadt signal(SIGALRM, dingdong); 296df930be7Sderaadt alarm(TO); 297df930be7Sderaadt } 298cf0bd593Sderaadt if ((rval = getname()) == 2) { 299cf0bd593Sderaadt execle(PP, "ppplogin", ttyn, (char *) 0, env); 300cf0bd593Sderaadt syslog(LOG_ERR, "%s: %m", PP); 301cf0bd593Sderaadt exit(1); 302cf0bd593Sderaadt } else if (rval) { 303df930be7Sderaadt register int i; 304df930be7Sderaadt 305df930be7Sderaadt oflush(); 306df930be7Sderaadt alarm(0); 307df930be7Sderaadt signal(SIGALRM, SIG_DFL); 308df930be7Sderaadt if (name[0] == '-') { 309df930be7Sderaadt puts("user names may not start with '-'."); 310df930be7Sderaadt continue; 311df930be7Sderaadt } 312df930be7Sderaadt if (!(upper || lower || digit)) 313df930be7Sderaadt continue; 314df930be7Sderaadt setflags(2); 315df930be7Sderaadt if (crmod) { 316df930be7Sderaadt tmode.c_iflag |= ICRNL; 317df930be7Sderaadt tmode.c_oflag |= ONLCR; 318df930be7Sderaadt } 319*8f901b87Stholo if (upper || UC) { 320*8f901b87Stholo tmode.c_iflag |= IUCLC; 321*8f901b87Stholo tmode.c_oflag |= OLCUC; 322*8f901b87Stholo tmode.c_lflag |= XCASE; 323*8f901b87Stholo } 324*8f901b87Stholo if (lower || LC) { 325*8f901b87Stholo tmode.c_iflag &= ~IUCLC; 326*8f901b87Stholo tmode.c_oflag &= ~OLCUC; 327*8f901b87Stholo tmode.c_lflag &= ~XCASE; 328*8f901b87Stholo } 329df930be7Sderaadt if (tcsetattr(0, TCSANOW, &tmode) < 0) { 330df930be7Sderaadt syslog(LOG_ERR, "%s: %m", ttyn); 331df930be7Sderaadt exit(1); 332df930be7Sderaadt } 333df930be7Sderaadt signal(SIGINT, SIG_DFL); 334df930be7Sderaadt for (i = 0; environ[i] != (char *)0; i++) 335df930be7Sderaadt env[i] = environ[i]; 336df930be7Sderaadt makeenv(&env[i]); 337df930be7Sderaadt 338df930be7Sderaadt limit.rlim_max = RLIM_INFINITY; 339df930be7Sderaadt limit.rlim_cur = RLIM_INFINITY; 340df930be7Sderaadt (void)setrlimit(RLIMIT_CPU, &limit); 341a03733e1Sniklas execle(LO, "login", "-p", "--", name, (char *)0, env); 342df930be7Sderaadt syslog(LOG_ERR, "%s: %m", LO); 343df930be7Sderaadt exit(1); 344df930be7Sderaadt } 345df930be7Sderaadt alarm(0); 346df930be7Sderaadt signal(SIGALRM, SIG_DFL); 347df930be7Sderaadt signal(SIGINT, SIG_IGN); 348df930be7Sderaadt if (NX && *NX) 349df930be7Sderaadt tname = NX; 350df930be7Sderaadt } 351df930be7Sderaadt } 352df930be7Sderaadt 353df930be7Sderaadt static int 354df930be7Sderaadt getname() 355df930be7Sderaadt { 356df930be7Sderaadt register int c; 357df930be7Sderaadt register char *np; 358cf0bd593Sderaadt unsigned char cs; 359cf0bd593Sderaadt int ppp_state; 360cf0bd593Sderaadt int ppp_connection = 0; 361df930be7Sderaadt 362df930be7Sderaadt /* 363df930be7Sderaadt * Interrupt may happen if we use CBREAK mode 364df930be7Sderaadt */ 365df930be7Sderaadt if (setjmp(intrupt)) { 366df930be7Sderaadt signal(SIGINT, SIG_IGN); 367df930be7Sderaadt return (0); 368df930be7Sderaadt } 369df930be7Sderaadt signal(SIGINT, interrupt); 370df930be7Sderaadt setflags(1); 371df930be7Sderaadt prompt(); 372df930be7Sderaadt if (PF > 0) { 373df930be7Sderaadt oflush(); 374df930be7Sderaadt sleep(PF); 375df930be7Sderaadt PF = 0; 376df930be7Sderaadt } 377df930be7Sderaadt if (tcsetattr(0, TCSANOW, &tmode) < 0) { 378df930be7Sderaadt syslog(LOG_ERR, "%s: %m", ttyn); 379df930be7Sderaadt exit(1); 380df930be7Sderaadt } 381df930be7Sderaadt crmod = digit = lower = upper = 0; 382df930be7Sderaadt np = name; 383df930be7Sderaadt for (;;) { 384df930be7Sderaadt oflush(); 385df930be7Sderaadt if (read(STDIN_FILENO, &cs, 1) <= 0) 386df930be7Sderaadt exit(0); 387df930be7Sderaadt if ((c = cs&0177) == 0) 388df930be7Sderaadt return (0); 389cf0bd593Sderaadt 390cf0bd593Sderaadt /* 391cf0bd593Sderaadt * PPP detection state machine.. 392cf0bd593Sderaadt * Look for sequences: 393cf0bd593Sderaadt * PPP_FRAME, PPP_STATION, PPP_ESCAPE, PPP_CONTROL_ESCAPED or 394cf0bd593Sderaadt * PPP_FRAME, PPP_STATION, PPP_CONTROL (deviant from RFC) 395cf0bd593Sderaadt * See RFC1662. 396cf0bd593Sderaadt * Derived from code from Michael Hancock <michaelh@cet.co.jp> 397cf0bd593Sderaadt * and Erik 'PPP' Olson <eriko@wrq.com> 398cf0bd593Sderaadt */ 399cf0bd593Sderaadt if (PP && cs == PPP_FRAME) { 400cf0bd593Sderaadt ppp_state = 1; 401cf0bd593Sderaadt } else if (ppp_state == 1 && cs == PPP_STATION) { 402cf0bd593Sderaadt ppp_state = 2; 403cf0bd593Sderaadt } else if (ppp_state == 2 && cs == PPP_ESCAPE) { 404cf0bd593Sderaadt ppp_state = 3; 405cf0bd593Sderaadt } else if ((ppp_state == 2 && cs == PPP_CONTROL) || 406cf0bd593Sderaadt (ppp_state == 3 && cs == PPP_CONTROL_ESCAPED)) { 407cf0bd593Sderaadt ppp_state = 4; 408cf0bd593Sderaadt } else if (ppp_state == 4 && cs == PPP_LCP_HI) { 409cf0bd593Sderaadt ppp_state = 5; 410cf0bd593Sderaadt } else if (ppp_state == 5 && cs == PPP_LCP_LOW) { 411cf0bd593Sderaadt ppp_connection = 1; 412cf0bd593Sderaadt break; 413cf0bd593Sderaadt } else { 414cf0bd593Sderaadt ppp_state = 0; 415cf0bd593Sderaadt } 416cf0bd593Sderaadt 417df930be7Sderaadt if (c == EOT) 418df930be7Sderaadt exit(1); 419df930be7Sderaadt if (c == '\r' || c == '\n' || np >= &name[sizeof name]) { 420df930be7Sderaadt putf("\r\n"); 421df930be7Sderaadt break; 422df930be7Sderaadt } 423df930be7Sderaadt if (islower(c)) 424df930be7Sderaadt lower = 1; 425df930be7Sderaadt else if (isupper(c)) 426df930be7Sderaadt upper = 1; 427df930be7Sderaadt else if (c == ERASE || c == '#' || c == '\b') { 428df930be7Sderaadt if (np > name) { 429df930be7Sderaadt np--; 430df930be7Sderaadt if (cfgetospeed(&tmode) >= 1200) 431df930be7Sderaadt puts("\b \b"); 432df930be7Sderaadt else 433df930be7Sderaadt putchr(cs); 434df930be7Sderaadt } 435df930be7Sderaadt continue; 436df930be7Sderaadt } else if (c == KILL || c == '@') { 437df930be7Sderaadt putchr(cs); 438df930be7Sderaadt putchr('\r'); 439df930be7Sderaadt if (cfgetospeed(&tmode) < 1200) 440df930be7Sderaadt putchr('\n'); 441df930be7Sderaadt /* this is the way they do it down under ... */ 442df930be7Sderaadt else if (np > name) 443df930be7Sderaadt puts(" \r"); 444df930be7Sderaadt prompt(); 445df930be7Sderaadt np = name; 446df930be7Sderaadt continue; 447df930be7Sderaadt } else if (isdigit(c)) 448df930be7Sderaadt digit++; 449df930be7Sderaadt if (IG && (c <= ' ' || c > 0176)) 450df930be7Sderaadt continue; 451df930be7Sderaadt *np++ = c; 452df930be7Sderaadt putchr(cs); 453df930be7Sderaadt } 454df930be7Sderaadt signal(SIGINT, SIG_IGN); 455df930be7Sderaadt *np = 0; 456df930be7Sderaadt if (c == '\r') 457df930be7Sderaadt crmod = 1; 458df930be7Sderaadt if (upper && !lower && !LC || UC) 459df930be7Sderaadt for (np = name; *np; np++) 460df930be7Sderaadt if (isupper(*np)) 461df930be7Sderaadt *np = tolower(*np); 462cf0bd593Sderaadt return (1 + ppp_connection); 463df930be7Sderaadt } 464df930be7Sderaadt 465df930be7Sderaadt static void 466df930be7Sderaadt putpad(s) 467df930be7Sderaadt register char *s; 468df930be7Sderaadt { 469df930be7Sderaadt register pad = 0; 470df930be7Sderaadt speed_t ospeed = cfgetospeed(&tmode); 471df930be7Sderaadt 472df930be7Sderaadt if (isdigit(*s)) { 473df930be7Sderaadt while (isdigit(*s)) { 474df930be7Sderaadt pad *= 10; 475df930be7Sderaadt pad += *s++ - '0'; 476df930be7Sderaadt } 477df930be7Sderaadt pad *= 10; 478df930be7Sderaadt if (*s == '.' && isdigit(s[1])) { 479df930be7Sderaadt pad += s[1] - '0'; 480df930be7Sderaadt s += 2; 481df930be7Sderaadt } 482df930be7Sderaadt } 483df930be7Sderaadt 484df930be7Sderaadt puts(s); 485df930be7Sderaadt /* 486df930be7Sderaadt * If no delay needed, or output speed is 487df930be7Sderaadt * not comprehensible, then don't try to delay. 488df930be7Sderaadt */ 489df930be7Sderaadt if (pad == 0 || ospeed <= 0) 490df930be7Sderaadt return; 491df930be7Sderaadt 492df930be7Sderaadt /* 493df930be7Sderaadt * Round up by a half a character frame, and then do the delay. 494df930be7Sderaadt * Too bad there are no user program accessible programmed delays. 495df930be7Sderaadt * Transmitting pad characters slows many terminals down and also 496df930be7Sderaadt * loads the system. 497df930be7Sderaadt */ 498df930be7Sderaadt pad = (pad * ospeed + 50000) / 100000; 499df930be7Sderaadt while (pad--) 500df930be7Sderaadt putchr(*PC); 501df930be7Sderaadt } 502df930be7Sderaadt 503df930be7Sderaadt static void 504df930be7Sderaadt puts(s) 505df930be7Sderaadt register char *s; 506df930be7Sderaadt { 507df930be7Sderaadt while (*s) 508df930be7Sderaadt putchr(*s++); 509df930be7Sderaadt } 510df930be7Sderaadt 511df930be7Sderaadt char outbuf[OBUFSIZ]; 512df930be7Sderaadt int obufcnt = 0; 513df930be7Sderaadt 514df930be7Sderaadt static void 515df930be7Sderaadt putchr(cc) 516df930be7Sderaadt int cc; 517df930be7Sderaadt { 518df930be7Sderaadt char c; 519df930be7Sderaadt 520df930be7Sderaadt c = cc; 521df930be7Sderaadt if (!NP) { 522df930be7Sderaadt c |= partab[c&0177] & 0200; 523df930be7Sderaadt if (OP) 524df930be7Sderaadt c ^= 0200; 525df930be7Sderaadt } 526df930be7Sderaadt if (!UB) { 527df930be7Sderaadt outbuf[obufcnt++] = c; 528df930be7Sderaadt if (obufcnt >= OBUFSIZ) 529df930be7Sderaadt oflush(); 530df930be7Sderaadt } else 531df930be7Sderaadt write(STDOUT_FILENO, &c, 1); 532df930be7Sderaadt } 533df930be7Sderaadt 534df930be7Sderaadt static void 535df930be7Sderaadt oflush() 536df930be7Sderaadt { 537df930be7Sderaadt if (obufcnt) 538df930be7Sderaadt write(STDOUT_FILENO, outbuf, obufcnt); 539df930be7Sderaadt obufcnt = 0; 540df930be7Sderaadt } 541df930be7Sderaadt 542df930be7Sderaadt static void 543df930be7Sderaadt prompt() 544df930be7Sderaadt { 545df930be7Sderaadt 546df930be7Sderaadt putf(LM); 547df930be7Sderaadt if (CO) 548df930be7Sderaadt putchr('\n'); 549df930be7Sderaadt } 550df930be7Sderaadt 551df930be7Sderaadt static void 552df930be7Sderaadt putf(cp) 553df930be7Sderaadt register char *cp; 554df930be7Sderaadt { 555df930be7Sderaadt extern char editedhost[]; 556df930be7Sderaadt time_t t; 557df930be7Sderaadt char *slash, db[100]; 558df930be7Sderaadt 559df930be7Sderaadt while (*cp) { 560df930be7Sderaadt if (*cp != '%') { 561df930be7Sderaadt putchr(*cp++); 562df930be7Sderaadt continue; 563df930be7Sderaadt } 564df930be7Sderaadt switch (*++cp) { 565df930be7Sderaadt 566df930be7Sderaadt case 't': 567df930be7Sderaadt slash = strrchr(ttyn, '/'); 568df930be7Sderaadt if (slash == (char *) 0) 569df930be7Sderaadt puts(ttyn); 570df930be7Sderaadt else 571df930be7Sderaadt puts(&slash[1]); 572df930be7Sderaadt break; 573df930be7Sderaadt 574df930be7Sderaadt case 'h': 575df930be7Sderaadt puts(editedhost); 576df930be7Sderaadt break; 577df930be7Sderaadt 578df930be7Sderaadt case 'd': { 579df930be7Sderaadt static char fmt[] = "%l:% %p on %A, %d %B %Y"; 580df930be7Sderaadt 581df930be7Sderaadt fmt[4] = 'M'; /* I *hate* SCCS... */ 582df930be7Sderaadt (void)time(&t); 583df930be7Sderaadt (void)strftime(db, sizeof(db), fmt, localtime(&t)); 584df930be7Sderaadt puts(db); 585df930be7Sderaadt break; 586df930be7Sderaadt 587df930be7Sderaadt case 's': 588df930be7Sderaadt puts(kerninfo.sysname); 589df930be7Sderaadt break; 590df930be7Sderaadt 591df930be7Sderaadt case 'm': 592df930be7Sderaadt puts(kerninfo.machine); 593df930be7Sderaadt break; 594df930be7Sderaadt 595df930be7Sderaadt case 'r': 596df930be7Sderaadt puts(kerninfo.release); 597df930be7Sderaadt break; 598df930be7Sderaadt 599df930be7Sderaadt case 'v': 600df930be7Sderaadt puts(kerninfo.version); 601df930be7Sderaadt break; 602df930be7Sderaadt } 603df930be7Sderaadt 604df930be7Sderaadt case '%': 605df930be7Sderaadt putchr('%'); 606df930be7Sderaadt break; 607df930be7Sderaadt } 608df930be7Sderaadt cp++; 609df930be7Sderaadt } 610df930be7Sderaadt } 611