main.c (9875) | main.c (15645) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 1980 The Regents of the University of California. 3 * All rights reserved. | 2 * Copyright (c) 1980, 1993 3 * The Regents of the University of California. All rights reserved. |
4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the --- 15 unchanged lines hidden (view full) --- 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint | 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the --- 15 unchanged lines hidden (view full) --- 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint |
35char copyright[] = 36"@(#) Copyright (c) 1980 The Regents of the University of California.\n\ 37 All rights reserved.\n"; | 35static char copyright[] = 36"@(#) Copyright (c) 1980, 1993\n\ 37 The Regents of the University of California. All rights reserved.\n"; |
38#endif /* not lint */ 39 40#ifndef lint | 38#endif /* not lint */ 39 40#ifndef lint |
41static char sccsid[] = "@(#)main.c 5.16 (Berkeley) 3/27/91"; | 41/*static char sccsid[] = "from: @(#)main.c 8.1 (Berkeley) 6/20/93";*/ 42static char rcsid[] = "$Id: main.c,v 1.1.1.2 1996/04/13 15:33:11 joerg Exp $"; |
42#endif /* not lint */ 43 | 43#endif /* not lint */ 44 |
44#define USE_OLD_TTY 45 | |
46#include <sys/param.h> 47#include <sys/stat.h> | 45#include <sys/param.h> 46#include <sys/stat.h> |
47#include <sys/ioctl.h> 48#include <sys/resource.h> 49#include <sys/ttydefaults.h> 50#include <sys/utsname.h> 51#include <errno.h> |
|
48#include <signal.h> 49#include <fcntl.h> | 52#include <signal.h> 53#include <fcntl.h> |
50#include <sgtty.h> | |
51#include <time.h> 52#include <ctype.h> | 54#include <time.h> 55#include <ctype.h> |
56#include <fcntl.h> 57#include <libutil.h> 58#include <locale.h> |
|
53#include <setjmp.h> | 59#include <setjmp.h> |
54#include <syslog.h> 55#include <unistd.h> 56#include <ctype.h> | 60#include <signal.h> |
57#include <stdlib.h> 58#include <string.h> | 61#include <stdlib.h> 62#include <string.h> |
63#include <syslog.h> 64#include <termios.h> 65#include <time.h> 66#include <unistd.h> 67 |
|
59#include "gettytab.h" 60#include "pathnames.h" | 68#include "gettytab.h" 69#include "pathnames.h" |
70#include "extern.h" |
|
61 | 71 |
62struct sgttyb tmode = { 63 0, 0, CERASE, CKILL, 0 64}; 65struct tchars tc = { 66 CINTR, CQUIT, CSTART, 67 CSTOP, CEOF, CBRK, 68}; 69struct ltchars ltc = { 70 CSUSP, CDSUSP, CRPRNT, 71 CFLUSH, CWERASE, CLNEXT 72}; | 72/* 73 * Set the amount of running time that getty should accumulate 74 * before deciding that something is wrong and exit. 75 */ 76#define GETTY_TIMEOUT 60 /* seconds */ |
73 | 77 |
78#undef CTRL 79#define CTRL(x) (x&037) 80 81struct termios tmode, omode; 82 |
|
74int crmod, digit, lower, upper; 75 76char hostname[MAXHOSTNAMELEN]; | 83int crmod, digit, lower, upper; 84 85char hostname[MAXHOSTNAMELEN]; |
86struct utsname kerninfo; |
|
77char name[16]; 78char dev[] = _PATH_DEV; 79char ttyn[32]; | 87char name[16]; 88char dev[] = _PATH_DEV; 89char ttyn[32]; |
80char *portselector(); 81char *ttyname(); | |
82 83#define OBUFSIZ 128 84#define TABBUFSIZ 512 85 86char defent[TABBUFSIZ]; | 90 91#define OBUFSIZ 128 92#define TABBUFSIZ 512 93 94char defent[TABBUFSIZ]; |
87char defstrs[TABBUFSIZ]; | |
88char tabent[TABBUFSIZ]; | 95char tabent[TABBUFSIZ]; |
89char tabstrs[TABBUFSIZ]; | |
90 91char *env[128]; 92 93char partab[] = { 94 0001,0201,0201,0001,0201,0001,0001,0201, 95 0202,0004,0003,0205,0005,0206,0201,0001, 96 0201,0001,0001,0201,0001,0201,0201,0001, 97 0001,0201,0201,0001,0201,0001,0001,0201, --- 6 unchanged lines hidden (view full) --- 104 0000,0200,0200,0000,0200,0000,0000,0200, 105 0200,0000,0000,0200,0000,0200,0200,0000, 106 0000,0200,0200,0000,0200,0000,0000,0200, 107 0200,0000,0000,0200,0000,0200,0200,0000, 108 0200,0000,0000,0200,0000,0200,0200,0000, 109 0000,0200,0200,0000,0200,0000,0000,0201 110}; 111 | 96 97char *env[128]; 98 99char partab[] = { 100 0001,0201,0201,0001,0201,0001,0001,0201, 101 0202,0004,0003,0205,0005,0206,0201,0001, 102 0201,0001,0001,0201,0001,0201,0201,0001, 103 0001,0201,0201,0001,0201,0001,0001,0201, --- 6 unchanged lines hidden (view full) --- 110 0000,0200,0200,0000,0200,0000,0000,0200, 111 0200,0000,0000,0200,0000,0200,0200,0000, 112 0000,0200,0200,0000,0200,0000,0000,0200, 113 0200,0000,0000,0200,0000,0200,0200,0000, 114 0200,0000,0000,0200,0000,0200,0200,0000, 115 0000,0200,0200,0000,0200,0000,0000,0201 116}; 117 |
112#define ERASE tmode.sg_erase 113#define KILL tmode.sg_kill 114#define EOT tc.t_eofc | 118#define ERASE tmode.c_cc[VERASE] 119#define KILL tmode.c_cc[VKILL] 120#define EOT tmode.c_cc[VEOF] |
115 116jmp_buf timeout; 117 | 121 122jmp_buf timeout; 123 |
124static void dingdong __P((int)); 125static int getname __P((void)); 126static void interrupt __P((int)); 127static void oflush __P((void)); 128static void prompt __P((void)); 129static void putchr __P((int)); 130static void putf __P((const char *)); 131static void putpad __P((const char *)); 132static void puts __P((const char *)); 133static void timeoverrun __P((int)); 134 135int main __P((int, char **)); 136 |
|
118static void | 137static void |
119dingdong() | 138dingdong(signo) 139 int signo; |
120{ | 140{ |
121 | |
122 alarm(0); | 141 alarm(0); |
123 signal(SIGALRM, SIG_DFL); | |
124 longjmp(timeout, 1); 125} 126 127jmp_buf intrupt; 128 129static void | 142 longjmp(timeout, 1); 143} 144 145jmp_buf intrupt; 146 147static void |
130interrupt() | 148interrupt(signo) 149 int signo; |
131{ | 150{ |
132 133 signal(SIGINT, interrupt); | |
134 longjmp(intrupt, 1); 135} 136 | 151 longjmp(intrupt, 1); 152} 153 |
154/* 155 * Action to take when getty is running too long. 156 */ 157static void 158timeoverrun(signo) 159 int signo; 160{ 161 162 syslog(LOG_ERR, "getty exiting due to excessive running time\n"); 163 exit(1); 164} 165 166int |
|
137main(argc, argv) 138 int argc; 139 char **argv; 140{ 141 extern char **environ; | 167main(argc, argv) 168 int argc; 169 char **argv; 170{ 171 extern char **environ; |
142 char *tname; 143 int repcnt = 0; | 172 const char *tname; 173 int repcnt = 0, failopenlogged = 0; 174 struct rlimit limit; |
144 145 signal(SIGINT, SIG_IGN); 146 signal(SIGQUIT, SIG_IGN); 147 | 175 176 signal(SIGINT, SIG_IGN); 177 signal(SIGQUIT, SIG_IGN); 178 |
148 openlog("getty", LOG_ODELAY|LOG_CONS, LOG_AUTH); | 179 openlog("getty", LOG_ODELAY|LOG_CONS|LOG_PID, LOG_AUTH); |
149 gethostname(hostname, sizeof(hostname)); 150 if (hostname[0] == '\0') 151 strcpy(hostname, "Amnesiac"); | 180 gethostname(hostname, sizeof(hostname)); 181 if (hostname[0] == '\0') 182 strcpy(hostname, "Amnesiac"); |
183 |
|
152 /* | 184 /* |
185 * Limit running time to deal with broken or dead lines. 186 */ 187 (void)signal(SIGXCPU, timeoverrun); 188 limit.rlim_max = RLIM_INFINITY; 189 limit.rlim_cur = GETTY_TIMEOUT; 190 (void)setrlimit(RLIMIT_CPU, &limit); 191 192 /* |
|
153 * The following is a work around for vhangup interactions 154 * which cause great problems getting window systems started. 155 * If the tty line is "-", we do the old style getty presuming 156 * that the file descriptors are already set up for us. 157 * J. Gettys - MIT Project Athena. 158 */ 159 if (argc <= 2 || strcmp(argv[2], "-") == 0) 160 strcpy(ttyn, ttyname(0)); 161 else { 162 int i; 163 164 strcpy(ttyn, dev); 165 strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev)); 166 if (strcmp(argv[0], "+") != 0) { 167 chown(ttyn, 0, 0); 168 chmod(ttyn, 0600); 169 revoke(ttyn); 170 while ((i = open(ttyn, O_RDWR)) == -1) { | 193 * The following is a work around for vhangup interactions 194 * which cause great problems getting window systems started. 195 * If the tty line is "-", we do the old style getty presuming 196 * that the file descriptors are already set up for us. 197 * J. Gettys - MIT Project Athena. 198 */ 199 if (argc <= 2 || strcmp(argv[2], "-") == 0) 200 strcpy(ttyn, ttyname(0)); 201 else { 202 int i; 203 204 strcpy(ttyn, dev); 205 strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev)); 206 if (strcmp(argv[0], "+") != 0) { 207 chown(ttyn, 0, 0); 208 chmod(ttyn, 0600); 209 revoke(ttyn); 210 while ((i = open(ttyn, O_RDWR)) == -1) { |
171 if (repcnt % 10 == 0) { | 211 if ((repcnt % 10 == 0) && 212 (errno != ENXIO || !failopenlogged)) { |
172 syslog(LOG_ERR, "%s: %m", ttyn); 173 closelog(); | 213 syslog(LOG_ERR, "%s: %m", ttyn); 214 closelog(); |
215 failopenlogged = 1; |
|
174 } 175 repcnt++; 176 sleep(60); 177 } 178 login_tty(i); 179 } 180 } 181 | 216 } 217 repcnt++; 218 sleep(60); 219 } 220 login_tty(i); 221 } 222 } 223 |
182 gettable("default", defent, defstrs); | 224 /* Start with default tty settings */ 225 if (tcgetattr(0, &tmode) < 0) { 226 syslog(LOG_ERR, "%s: %m", ttyn); 227 exit(1); 228 } 229 /* 230 * Don't rely on the driver too much, and initialize crucial 231 * things according to <sys/ttydefaults.h>. Avoid clobbering 232 * the c_cc[] settings however, the console drivers might wish 233 * to leave their idea of the preferred VERASE key value 234 * there. 235 */ 236 tmode.c_iflag = TTYDEF_IFLAG; 237 tmode.c_oflag = TTYDEF_OFLAG; 238 tmode.c_lflag = TTYDEF_LFLAG; 239 tmode.c_cflag = TTYDEF_CFLAG; 240 omode = tmode; 241 242 gettable("default", defent); |
183 gendefaults(); 184 tname = "default"; 185 if (argc > 1) 186 tname = argv[1]; 187 for (;;) { 188 int off = 0; | 243 gendefaults(); 244 tname = "default"; 245 if (argc > 1) 246 tname = argv[1]; 247 for (;;) { 248 int off = 0; |
189 int flushboth = 0; 190 struct sgttyb fake; | |
191 | 249 |
192 gettable(tname, tabent, tabstrs); | 250 gettable(tname, tabent); |
193 if (OPset || EPset || APset) 194 APset++, OPset++, EPset++; 195 setdefaults(); | 251 if (OPset || EPset || APset) 252 APset++, OPset++, EPset++; 253 setdefaults(); |
196 ioctl(0, TIOCFLUSH, &flushboth); /* clear out the crap */ | 254 off = 0; 255 (void)tcflush(0, TCIOFLUSH); /* clear out the crap */ |
197 ioctl(0, FIONBIO, &off); /* turn off non-blocking mode */ 198 ioctl(0, FIOASYNC, &off); /* ditto for async mode */ | 256 ioctl(0, FIONBIO, &off); /* turn off non-blocking mode */ 257 ioctl(0, FIOASYNC, &off); /* ditto for async mode */ |
199 ioctl(0, TIOCGETP, &fake); /* initialize kernel termios */ | 258 |
200 if (IS) | 259 if (IS) |
201 tmode.sg_ispeed = speed(IS); | 260 cfsetispeed(&tmode, speed(IS)); |
202 else if (SP) | 261 else if (SP) |
203 tmode.sg_ispeed = speed(SP); | 262 cfsetispeed(&tmode, speed(SP)); |
204 if (OS) | 263 if (OS) |
205 tmode.sg_ospeed = speed(OS); | 264 cfsetospeed(&tmode, speed(OS)); |
206 else if (SP) | 265 else if (SP) |
207 tmode.sg_ospeed = speed(SP); 208 set_tmode(0); | 266 cfsetospeed(&tmode, speed(SP)); 267 setflags(0); |
209 setchars(); | 268 setchars(); |
210 ioctl(0, TIOCSETC, &tc); 211 if (HC) 212 ioctl(0, TIOCHPCL, 0); | 269 if (tcsetattr(0, TCSANOW, &tmode) < 0) { 270 syslog(LOG_ERR, "%s: %m", ttyn); 271 exit(1); 272 } |
213 if (AB) { | 273 if (AB) { |
214 extern char *autobaud(); 215 | |
216 tname = autobaud(); 217 continue; 218 } 219 if (PS) { 220 tname = portselector(); 221 continue; 222 } 223 if (CL && *CL) 224 putpad(CL); 225 edithost(HE); 226 if (IM && *IM) 227 putf(IM); 228 if (setjmp(timeout)) { | 274 tname = autobaud(); 275 continue; 276 } 277 if (PS) { 278 tname = portselector(); 279 continue; 280 } 281 if (CL && *CL) 282 putpad(CL); 283 edithost(HE); 284 if (IM && *IM) 285 putf(IM); 286 if (setjmp(timeout)) { |
229 tmode.sg_ispeed = tmode.sg_ospeed = 0; 230 ioctl(0, TIOCSETP, &tmode); | 287 tmode.c_ispeed = tmode.c_ospeed = 0; 288 (void)tcsetattr(0, TCSANOW, &tmode); |
231 exit(1); 232 } 233 if (TO) { 234 signal(SIGALRM, dingdong); 235 alarm(TO); 236 } 237 if (getname()) { 238 register int i; 239 | 289 exit(1); 290 } 291 if (TO) { 292 signal(SIGALRM, dingdong); 293 alarm(TO); 294 } 295 if (getname()) { 296 register int i; 297 |
298 oflush(); |
|
240 alarm(0); 241 signal(SIGALRM, SIG_DFL); | 299 alarm(0); 300 signal(SIGALRM, SIG_DFL); |
242 oflush(); | |
243 if (name[0] == '-') { 244 puts("user names may not start with '-'."); 245 continue; 246 } 247 if (!(upper || lower || digit)) 248 continue; | 301 if (name[0] == '-') { 302 puts("user names may not start with '-'."); 303 continue; 304 } 305 if (!(upper || lower || digit)) 306 continue; |
249 set_tmode(2); 250 ioctl(0, TIOCSLTC, <c); | 307 setflags(2); 308 if (crmod) { 309 tmode.c_iflag |= ICRNL; 310 tmode.c_oflag |= ONLCR; 311 } 312#if REALLY_OLD_TTYS 313 if (upper || UC) 314 tmode.sg_flags |= LCASE; 315 if (lower || LC) 316 tmode.sg_flags &= ~LCASE; 317#endif 318 if (tcsetattr(0, TCSANOW, &tmode) < 0) { 319 syslog(LOG_ERR, "%s: %m", ttyn); 320 exit(1); 321 } 322 signal(SIGINT, SIG_DFL); |
251 for (i = 0; environ[i] != (char *)0; i++) 252 env[i] = environ[i]; 253 makeenv(&env[i]); 254 | 323 for (i = 0; environ[i] != (char *)0; i++) 324 env[i] = environ[i]; 325 makeenv(&env[i]); 326 |
327 limit.rlim_max = RLIM_INFINITY; 328 limit.rlim_cur = RLIM_INFINITY; 329 (void)setrlimit(RLIMIT_CPU, &limit); |
|
255 execle(LO, "login", "-p", name, (char *) 0, env); 256 syslog(LOG_ERR, "%s: %m", LO); 257 exit(1); 258 } | 330 execle(LO, "login", "-p", name, (char *) 0, env); 331 syslog(LOG_ERR, "%s: %m", LO); 332 exit(1); 333 } |
259 signal(SIGINT, SIG_IGN); | |
260 alarm(0); 261 signal(SIGALRM, SIG_DFL); | 334 alarm(0); 335 signal(SIGALRM, SIG_DFL); |
336 signal(SIGINT, SIG_IGN); |
|
262 if (NX && *NX) 263 tname = NX; 264 } 265} 266 | 337 if (NX && *NX) 338 tname = NX; 339 } 340} 341 |
342static int |
|
267getname() 268{ 269 register int c; 270 register char *np; 271 char cs; | 343getname() 344{ 345 register int c; 346 register char *np; 347 char cs; |
272 int flushin = 1 /*FREAD*/; | |
273 274 /* 275 * Interrupt may happen if we use CBREAK mode 276 */ 277 if (setjmp(intrupt)) { 278 signal(SIGINT, SIG_IGN); 279 return (0); 280 } 281 signal(SIGINT, interrupt); | 348 349 /* 350 * Interrupt may happen if we use CBREAK mode 351 */ 352 if (setjmp(intrupt)) { 353 signal(SIGINT, SIG_IGN); 354 return (0); 355 } 356 signal(SIGINT, interrupt); |
282 ioctl(0, TIOCFLUSH, &flushin); /* purge any input */ | 357 setflags(1); |
283 prompt(); 284 oflush(); 285 if (PF > 0) { 286 sleep(PF); 287 PF = 0; 288 } | 358 prompt(); 359 oflush(); 360 if (PF > 0) { 361 sleep(PF); 362 PF = 0; 363 } |
289 set_tmode(1); | 364 if (tcsetattr(0, TCSANOW, &tmode) < 0) { 365 syslog(LOG_ERR, "%s: %m", ttyn); 366 exit(1); 367 } |
290 crmod = digit = lower = upper = 0; 291 np = name; 292 for (;;) { 293 oflush(); 294 if (read(STDIN_FILENO, &cs, 1) <= 0) 295 exit(0); 296 if ((c = cs&0177) == 0) 297 return (0); | 368 crmod = digit = lower = upper = 0; 369 np = name; 370 for (;;) { 371 oflush(); 372 if (read(STDIN_FILENO, &cs, 1) <= 0) 373 exit(0); 374 if ((c = cs&0177) == 0) 375 return (0); |
298 if (c == EOT || c == 4 /*^D*/) | 376 if (c == EOT || c == CTRL('d')) |
299 exit(1); 300 if (c == '\r' || c == '\n' || np >= &name[sizeof name]) { 301 putf("\r\n"); 302 break; 303 } 304 if (islower(c)) 305 lower = 1; 306 else if (isupper(c)) 307 upper = 1; 308 else if (c == ERASE || c == '\b' || c == 0177) { 309 if (np > name) { 310 np--; | 377 exit(1); 378 if (c == '\r' || c == '\n' || np >= &name[sizeof name]) { 379 putf("\r\n"); 380 break; 381 } 382 if (islower(c)) 383 lower = 1; 384 else if (isupper(c)) 385 upper = 1; 386 else if (c == ERASE || c == '\b' || c == 0177) { 387 if (np > name) { 388 np--; |
311 if (tmode.sg_ospeed >= B1200) | 389 if (cfgetospeed(&tmode) >= 1200) |
312 puts("\b \b"); 313 else 314 putchr(cs); 315 } 316 continue; | 390 puts("\b \b"); 391 else 392 putchr(cs); 393 } 394 continue; |
317 } else if (c == KILL || c == 025 /*^U*/) { | 395 } else if (c == KILL || c == CTRL('u')) { |
318 putchr('\r'); | 396 putchr('\r'); |
319 if (tmode.sg_ospeed < B1200) | 397 if (cfgetospeed(&tmode) < 1200) |
320 putchr('\n'); 321 /* this is the way they do it down under ... */ 322 else if (np > name) 323 puts(" \r"); 324 prompt(); 325 np = name; 326 continue; 327 } else if (isdigit(c)) 328 digit++; 329 if (IG && (c <= ' ' || c > 0176)) 330 continue; 331 *np++ = c; 332 putchr(cs); 333 } 334 signal(SIGINT, SIG_IGN); 335 *np = 0; 336 if (c == '\r') 337 crmod = 1; | 398 putchr('\n'); 399 /* this is the way they do it down under ... */ 400 else if (np > name) 401 puts(" \r"); 402 prompt(); 403 np = name; 404 continue; 405 } else if (isdigit(c)) 406 digit++; 407 if (IG && (c <= ' ' || c > 0176)) 408 continue; 409 *np++ = c; 410 putchr(cs); 411 } 412 signal(SIGINT, SIG_IGN); 413 *np = 0; 414 if (c == '\r') 415 crmod = 1; |
338 if (upper && !lower && !LC || UC) | 416 if ((upper && !lower && !LC) || UC) |
339 for (np = name; *np; np++) 340 if (isupper(*np)) 341 *np = tolower(*np); 342 return (1); 343} 344 | 417 for (np = name; *np; np++) 418 if (isupper(*np)) 419 *np = tolower(*np); 420 return (1); 421} 422 |
345static 346short tmspc10[] = { 347 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15 348}; 349 | 423static void |
350putpad(s) | 424putpad(s) |
351 register char *s; | 425 register const char *s; |
352{ 353 register pad = 0; | 426{ 427 register pad = 0; |
354 register mspc10; | 428 speed_t ospeed = cfgetospeed(&tmode); |
355 356 if (isdigit(*s)) { 357 while (isdigit(*s)) { 358 pad *= 10; 359 pad += *s++ - '0'; 360 } 361 pad *= 10; 362 if (*s == '.' && isdigit(s[1])) { 363 pad += s[1] - '0'; 364 s += 2; 365 } 366 } 367 368 puts(s); 369 /* 370 * If no delay needed, or output speed is 371 * not comprehensible, then don't try to delay. 372 */ | 429 430 if (isdigit(*s)) { 431 while (isdigit(*s)) { 432 pad *= 10; 433 pad += *s++ - '0'; 434 } 435 pad *= 10; 436 if (*s == '.' && isdigit(s[1])) { 437 pad += s[1] - '0'; 438 s += 2; 439 } 440 } 441 442 puts(s); 443 /* 444 * If no delay needed, or output speed is 445 * not comprehensible, then don't try to delay. 446 */ |
373 if (pad == 0) | 447 if (pad == 0 || ospeed <= 0) |
374 return; | 448 return; |
375 if (tmode.sg_ospeed <= 0 || 376 tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0])) 377 return; | |
378 379 /* 380 * Round up by a half a character frame, and then do the delay. 381 * Too bad there are no user program accessible programmed delays. 382 * Transmitting pad characters slows many terminals down and also 383 * loads the system. 384 */ | 449 450 /* 451 * Round up by a half a character frame, and then do the delay. 452 * Too bad there are no user program accessible programmed delays. 453 * Transmitting pad characters slows many terminals down and also 454 * loads the system. 455 */ |
385 mspc10 = tmspc10[tmode.sg_ospeed]; 386 pad += mspc10 / 2; 387 for (pad /= mspc10; pad > 0; pad--) | 456 pad = (pad * ospeed + 50000) / 100000; 457 while (pad--) |
388 putchr(*PC); 389} 390 | 458 putchr(*PC); 459} 460 |
461static void |
|
391puts(s) | 462puts(s) |
392 register char *s; | 463 register const char *s; |
393{ 394 while (*s) 395 putchr(*s++); 396} 397 398char outbuf[OBUFSIZ]; 399int obufcnt = 0; 400 | 464{ 465 while (*s) 466 putchr(*s++); 467} 468 469char outbuf[OBUFSIZ]; 470int obufcnt = 0; 471 |
472static void |
|
401putchr(cc) | 473putchr(cc) |
474 int cc; |
|
402{ 403 char c; 404 405 c = cc; 406 if (!NP) { 407 c |= partab[c&0177] & 0200; 408 if (OP) 409 c ^= 0200; 410 } 411 if (!UB) { 412 outbuf[obufcnt++] = c; 413 if (obufcnt >= OBUFSIZ) 414 oflush(); 415 } else 416 write(STDOUT_FILENO, &c, 1); 417} 418 | 475{ 476 char c; 477 478 c = cc; 479 if (!NP) { 480 c |= partab[c&0177] & 0200; 481 if (OP) 482 c ^= 0200; 483 } 484 if (!UB) { 485 outbuf[obufcnt++] = c; 486 if (obufcnt >= OBUFSIZ) 487 oflush(); 488 } else 489 write(STDOUT_FILENO, &c, 1); 490} 491 |
492static void |
|
419oflush() 420{ 421 if (obufcnt) 422 write(STDOUT_FILENO, outbuf, obufcnt); 423 obufcnt = 0; 424} 425 | 493oflush() 494{ 495 if (obufcnt) 496 write(STDOUT_FILENO, outbuf, obufcnt); 497 obufcnt = 0; 498} 499 |
500static void |
|
426prompt() 427{ 428 429 putf(LM); 430 if (CO) 431 putchr('\n'); 432} 433 | 501prompt() 502{ 503 504 putf(LM); 505 if (CO) 506 putchr('\n'); 507} 508 |
509static void |
|
434putf(cp) | 510putf(cp) |
435 register char *cp; | 511 register const char *cp; |
436{ 437 extern char editedhost[]; 438 time_t t; 439 char *slash, db[100]; 440 441 while (*cp) { 442 if (*cp != '%') { 443 putchr(*cp++); 444 continue; 445 } 446 switch (*++cp) { 447 448 case 't': | 512{ 513 extern char editedhost[]; 514 time_t t; 515 char *slash, db[100]; 516 517 while (*cp) { 518 if (*cp != '%') { 519 putchr(*cp++); 520 continue; 521 } 522 switch (*++cp) { 523 524 case 't': |
449 slash = rindex(ttyn, '/'); | 525 slash = strrchr(ttyn, '/'); |
450 if (slash == (char *) 0) 451 puts(ttyn); 452 else 453 puts(&slash[1]); 454 break; 455 456 case 'h': 457 puts(editedhost); 458 break; 459 460 case 'd': { | 526 if (slash == (char *) 0) 527 puts(ttyn); 528 else 529 puts(&slash[1]); 530 break; 531 532 case 'h': 533 puts(editedhost); 534 break; 535 536 case 'd': { |
461 static char fmt[] = "%l:% %p on %A, %d %B %Y"; 462 463 fmt[4] = 'M'; /* I *hate* SCCS... */ | 537 t = (time_t)0; |
464 (void)time(&t); | 538 (void)time(&t); |
465 (void)strftime(db, sizeof(db), fmt, localtime(&t)); | 539 if (Lo) 540 (void)setlocale(LC_TIME, Lo); 541 (void)strftime(db, sizeof(db), "%+", localtime(&t)); |
466 puts(db); 467 break; | 542 puts(db); 543 break; |
544 545 case 's': 546 puts(kerninfo.sysname); 547 break; 548 549 case 'm': 550 puts(kerninfo.machine); 551 break; 552 553 case 'r': 554 puts(kerninfo.release); 555 break; 556 557 case 'v': 558 puts(kerninfo.version); 559 break; |
|
468 } 469 470 case '%': 471 putchr('%'); 472 break; 473 } 474 cp++; 475 } 476} | 560 } 561 562 case '%': 563 putchr('%'); 564 break; 565 } 566 cp++; 567 } 568} |
477 478/* 479 * The conversions from sgttyb to termios make LITOUT and PASS8 affect 480 * the parity. So every TIOCSETP ioctl has to be paired with a TIOCLSET 481 * ioctl (at least if LITOUT or PASS8 has changed, and PASS8 may vary 482 * with 'n'). 483 */ 484set_tmode(n) 485 int n; 486{ 487 long allflags; 488 489 allflags = setflags(n); 490 tmode.sg_flags = allflags & 0xffff; 491 allflags >>= 16; 492 if (n == 2) { 493 if (crmod || NL) 494 tmode.sg_flags |= CRMOD; 495 if (upper || UC) 496 tmode.sg_flags |= LCASE; 497 if (lower || LC) 498 tmode.sg_flags &= ~LCASE; 499 } 500 ioctl(0, TIOCSETP, &tmode); 501 ioctl(0, TIOCLSET, &allflags); 502} | |