aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-01-22 03:06:40 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2011-01-22 03:06:40 +0100
commit2b57b6cd43211e2430c78caa0895f41376f29dc1 (patch)
tree4fd9633add21c5093976e14dd444814b517ec63c
parent3a0f690dcd06ff693a0b76d764739425600ec1f1 (diff)
downloadbusybox-w32-2b57b6cd43211e2430c78caa0895f41376f29dc1.tar.gz
busybox-w32-2b57b6cd43211e2430c78caa0895f41376f29dc1.tar.bz2
busybox-w32-2b57b6cd43211e2430c78caa0895f41376f29dc1.zip
getty: comment out parity detection code; improve usage text
function old new delta packed_usage 28155 28191 +36 static.erase 12 - -12 getty_main 1847 1621 -226 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/1 up/down: 36/-238) Total: -202 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--loginutils/getty.c112
1 files changed, 72 insertions, 40 deletions
diff --git a/loginutils/getty.c b/loginutils/getty.c
index 0f5e333a7..94c9147ab 100644
--- a/loginutils/getty.c
+++ b/loginutils/getty.c
@@ -58,9 +58,16 @@ static FILE *dbf;
58 * and for line editing at the same time. 58 * and for line editing at the same time.
59 */ 59 */
60 60
61/* I doubt there are systems which still need this */ 61/* I doubt there are systems which still... */
62/* ...have only uppercase: */
62#undef HANDLE_ALLCAPS 63#undef HANDLE_ALLCAPS
64/* ...use # and @ for backspace and line erase: */
63#undef ANCIENT_BS_KILL_CHARS 65#undef ANCIENT_BS_KILL_CHARS
66/* It actually makes sense (tries to guess parity by looking at 7th bit)
67 * but it's broken, and interferes with non-ASCII login names
68 * (yes, I did receive complains from real users):
69 */
70#undef BROKEN_PARITY_DETECTION_CODE
64 71
65#undef _PATH_LOGIN 72#undef _PATH_LOGIN
66#define _PATH_LOGIN "/bin/login" 73#define _PATH_LOGIN "/bin/login"
@@ -108,8 +115,11 @@ struct options {
108/* Storage for things detected while the login name was read. */ 115/* Storage for things detected while the login name was read. */
109struct chardata { 116struct chardata {
110 unsigned char erase; /* erase character */ 117 unsigned char erase; /* erase character */
118#ifdef ANCIENT_BS_KILL_CHARS
111 unsigned char kill; /* kill character */ 119 unsigned char kill; /* kill character */
120#endif
112 unsigned char eol; /* end-of-line character */ 121 unsigned char eol; /* end-of-line character */
122#ifdef BROKEN_PARITY_DETECTION_CODE
113 unsigned char parity; /* what parity did we see */ 123 unsigned char parity; /* what parity did we see */
114 /* (parity & 1): saw odd parity char with 7th bit set */ 124 /* (parity & 1): saw odd parity char with 7th bit set */
115 /* (parity & 2): saw even parity char with 7th bit set */ 125 /* (parity & 2): saw even parity char with 7th bit set */
@@ -117,7 +127,8 @@ struct chardata {
117 /* parity == 1: probably 7-bit, odd parity? */ 127 /* parity == 1: probably 7-bit, odd parity? */
118 /* parity == 2: probably 7-bit, even parity? */ 128 /* parity == 2: probably 7-bit, even parity? */
119 /* parity == 3: definitely 8 bit, no parity! */ 129 /* parity == 3: definitely 8 bit, no parity! */
120 /* Hmm... with any value of "parity" 8 bit, no parity is possible */ 130 /* Hmm... with any value of parity "8 bit, no parity" is possible */
131#endif
121#ifdef HANDLE_ALLCAPS 132#ifdef HANDLE_ALLCAPS
122 unsigned char capslock; /* upper case without lower case */ 133 unsigned char capslock; /* upper case without lower case */
123#endif 134#endif
@@ -126,9 +137,13 @@ struct chardata {
126/* Initial values for the above. */ 137/* Initial values for the above. */
127static const struct chardata init_chardata = { 138static const struct chardata init_chardata = {
128 DEF_ERASE, /* default erase character */ 139 DEF_ERASE, /* default erase character */
140#ifdef ANCIENT_BS_KILL_CHARS
129 DEF_KILL, /* default kill character */ 141 DEF_KILL, /* default kill character */
142#endif
130 13, /* default eol char */ 143 13, /* default eol char */
144#ifdef BROKEN_PARITY_DETECTION_CODE
131 0, /* space parity */ 145 0, /* space parity */
146#endif
132#ifdef HANDLE_ALLCAPS 147#ifdef HANDLE_ALLCAPS
133 0, /* no capslock */ 148 0, /* no capslock */
134#endif 149#endif
@@ -137,21 +152,23 @@ static const struct chardata init_chardata = {
137#define line_buf bb_common_bufsiz1 152#define line_buf bb_common_bufsiz1
138 153
139//usage:#define getty_trivial_usage 154//usage:#define getty_trivial_usage
140//usage: "[OPTIONS] BAUD_RATE TTY [TERMTYPE]" 155//usage: "[OPTIONS] BAUD_RATE[,BAUD_RATE]... TTY [TERMTYPE]"
141//usage:#define getty_full_usage "\n\n" 156//usage:#define getty_full_usage "\n\n"
142//usage: "Open a tty, prompt for a login name, then invoke /bin/login\n" 157//usage: "Open a tty, prompt for a login name, then invoke /bin/login\n"
143//usage: "\nOptions:" 158//usage: "\nOptions:"
144//usage: "\n -h Enable hardware (RTS/CTS) flow control" 159//usage: "\n -h Enable hardware (RTS/CTS) flow control"
145//usage: "\n -i Don't display /etc/issue" 160//usage: "\n -i Don't display /etc/issue"
146//usage: "\n -L Local line, don't do carrier detect" 161//usage: "\n -L Local line, set CLOCAL on it"
147//usage: "\n -m Get baud rate from modem's CONNECT status message" 162//usage: "\n -m Get baud rate from modem's CONNECT status message"
148//usage: "\n -w Wait for a CR or LF before sending /etc/issue" 163//usage: "\n -w Wait for CR or LF before sending /etc/issue"
149//usage: "\n -n Don't prompt the user for a login name" 164//usage: "\n -n Don't prompt for a login name"
150//usage: "\n -f ISSUE_FILE Display ISSUE_FILE instead of /etc/issue" 165//usage: "\n -f ISSUE_FILE Display ISSUE_FILE instead of /etc/issue"
151//usage: "\n -l LOGIN Invoke LOGIN instead of /bin/login" 166//usage: "\n -l LOGIN Invoke LOGIN instead of /bin/login"
152//usage: "\n -t SEC Terminate after SEC if no username is read" 167//usage: "\n -t SEC Terminate after SEC if no username is read"
153//usage: "\n -I INITSTR Send INITSTR before anything else" 168//usage: "\n -I INITSTR Send INITSTR before anything else"
154//usage: "\n -H HOST Log HOST into the utmp file as the hostname" 169//usage: "\n -H HOST Log HOST into the utmp file as the hostname"
170//usage: "\n"
171//usage: "\nBAUD_RATE of 0 leaves it unchanged"
155 172
156static const char opt_string[] ALIGN1 = "I:LH:f:hil:mt:wn"; 173static const char opt_string[] ALIGN1 = "I:LH:f:hil:mt:wn";
157#define F_INITSTRING (1 << 0) /* -I */ 174#define F_INITSTRING (1 << 0) /* -I */
@@ -259,29 +276,27 @@ static void open_tty(const char *tty)
259/* termios_init - initialize termios settings */ 276/* termios_init - initialize termios settings */
260static void termios_init(struct termios *tp, int speed) 277static void termios_init(struct termios *tp, int speed)
261{ 278{
262 speed_t ispeed, ospeed; 279 /* Flush input and output queues, important for modems! */
280 /* TODO: sleep(1)? Users report lost chars, and I hesitate
281 * to use tcdrain here instead of tcflush */
282 tcflush(0, TCIOFLUSH);
283
284 /* Set speed if it wasn't specified as "0" on command line. */
285 if (speed != B0) {
286 cfsetispeed(tp, speed);
287 cfsetospeed(tp, speed);
288 }
263 /* 289 /*
264 * Initial termios settings: 8-bit characters, raw-mode, blocking i/o. 290 * Initial termios settings: 8-bit characters, raw-mode, blocking i/o.
265 * Special characters are set after we have read the login name; all 291 * Special characters are set after we have read the login name; all
266 * reads will be done in raw mode anyway. Errors will be dealt with 292 * reads will be done in raw mode anyway. Errors will be dealt with
267 * later on. 293 * later on.
268 */ 294 */
269 /* flush input and output queues, important for modems! */
270 tcflush(0, TCIOFLUSH);
271 ispeed = ospeed = speed;
272 if (speed == B0) {
273 /* Speed was specified as "0" on command line.
274 * Just leave it unchanged */
275 ispeed = cfgetispeed(tp);
276 ospeed = cfgetospeed(tp);
277 }
278 tp->c_cflag = CS8 | HUPCL | CREAD; 295 tp->c_cflag = CS8 | HUPCL | CREAD;
279 if (option_mask32 & F_LOCAL) 296 if (option_mask32 & F_LOCAL)
280 tp->c_cflag |= CLOCAL; 297 tp->c_cflag |= CLOCAL;
281 cfsetispeed(tp, ispeed); 298 tp->c_iflag = 0;
282 cfsetospeed(tp, ospeed); 299 tp->c_lflag = 0;
283
284 tp->c_iflag = tp->c_lflag = 0;
285 tp->c_oflag = OPOST | ONLCR; 300 tp->c_oflag = OPOST | ONLCR;
286 tp->c_cc[VMIN] = 1; 301 tp->c_cc[VMIN] = 1;
287 tp->c_cc[VTIME] = 0; 302 tp->c_cc[VTIME] = 0;
@@ -388,14 +403,14 @@ static char *get_logname(char *logname, unsigned size_logname,
388 char *bp; 403 char *bp;
389 char c; /* input character, full eight bits */ 404 char c; /* input character, full eight bits */
390 char ascval; /* low 7 bits of input character */ 405 char ascval; /* low 7 bits of input character */
391 int bits; /* # of "1" bits per character */ 406#ifdef BROKEN_PARITY_DETECTION_CODE
392 int mask; /* mask with 1 bit up */
393 static const char erase[][3] = {/* backspace-space-backspace */ 407 static const char erase[][3] = {/* backspace-space-backspace */
394 "\010\040\010", /* space parity */ 408 "\010\040\010", /* space parity */
395 "\010\040\010", /* odd parity */ 409 "\010\040\010", /* odd parity */
396 "\210\240\210", /* even parity */ 410 "\210\240\210", /* even parity */
397 "\010\040\010", /* 8 bit no parity */ 411 "\010\040\010", /* 8 bit no parity */
398 }; 412 };
413#endif
399 414
400 /* NB: *cp is pre-initialized with init_chardata */ 415 /* NB: *cp is pre-initialized with init_chardata */
401 416
@@ -406,14 +421,13 @@ static char *get_logname(char *logname, unsigned size_logname,
406 /* Prompt for and read a login name. */ 421 /* Prompt for and read a login name. */
407 logname[0] = '\0'; 422 logname[0] = '\0';
408 while (!logname[0]) { 423 while (!logname[0]) {
409 /* Write issue file and prompt, with "parity" bit == 0. */ 424 /* Write issue file and prompt. */
410 do_prompt(op); 425 do_prompt(op);
411 426
412 /* Read name, watch for break, parity, erase, kill, end-of-line. */ 427 /* Read name, watch for break, parity, erase, kill, end-of-line. */
413 bp = logname; 428 bp = logname;
414 cp->eol = '\0'; 429 cp->eol = '\0';
415 while (cp->eol == '\0') { 430 while (1) {
416
417 /* Do not report trivial EINTR/EIO errors. */ 431 /* Do not report trivial EINTR/EIO errors. */
418 errno = EINTR; /* make read of 0 bytes be silent too */ 432 errno = EINTR; /* make read of 0 bytes be silent too */
419 if (read(STDIN_FILENO, &c, 1) < 1) { 433 if (read(STDIN_FILENO, &c, 1) < 1) {
@@ -427,10 +441,11 @@ static char *get_logname(char *logname, unsigned size_logname,
427 if (c == '\0' && op->numspeed > 1) 441 if (c == '\0' && op->numspeed > 1)
428 return NULL; 442 return NULL;
429 443
444#ifdef BROKEN_PARITY_DETECTION_CODE
430 /* Do parity bit handling. */ 445 /* Do parity bit handling. */
431 if (!(option_mask32 & F_LOCAL) && (c & 0x80)) { /* "parity" bit on? */ 446 if (!(option_mask32 & F_LOCAL) && (c & 0x80)) { /* "parity" bit on? */
432 bits = 1; 447 int bits = 1;
433 mask = 1; 448 int mask = 1;
434 while (mask & 0x7f) { 449 while (mask & 0x7f) {
435 if (mask & c) 450 if (mask & c)
436 bits++; /* count "1" bits */ 451 bits++; /* count "1" bits */
@@ -439,15 +454,18 @@ static char *get_logname(char *logname, unsigned size_logname,
439 /* ... |= 2 - even, 1 - odd */ 454 /* ... |= 2 - even, 1 - odd */
440 cp->parity |= 2 - (bits & 1); 455 cp->parity |= 2 - (bits & 1);
441 } 456 }
457 ascval = c & 0x7f;
458#else
459 ascval = c;
460#endif
442 461
443 /* Do erase, kill and end-of-line processing. */ 462 /* Do erase, kill and end-of-line processing. */
444 ascval = c & 0x7f;
445 switch (ascval) { 463 switch (ascval) {
446 case CR: 464 case CR:
447 case NL: 465 case NL:
448 *bp = '\0'; /* terminate logname */ 466 *bp = '\0'; /* terminate logname */
449 cp->eol = ascval; /* set end-of-line char */ 467 cp->eol = ascval; /* set end-of-line char */
450 break; 468 goto got_logname;
451 case BS: 469 case BS:
452 case DEL: 470 case DEL:
453#ifdef ANCIENT_BS_KILL_CHARS 471#ifdef ANCIENT_BS_KILL_CHARS
@@ -455,17 +473,25 @@ static char *get_logname(char *logname, unsigned size_logname,
455#endif 473#endif
456 cp->erase = ascval; /* set erase character */ 474 cp->erase = ascval; /* set erase character */
457 if (bp > logname) { 475 if (bp > logname) {
476#ifdef BROKEN_PARITY_DETECTION_CODE
458 full_write(STDOUT_FILENO, erase[cp->parity], 3); 477 full_write(STDOUT_FILENO, erase[cp->parity], 3);
478#else
479 full_write(STDOUT_FILENO, "\010 \010", 3);
480#endif
459 bp--; 481 bp--;
460 } 482 }
461 break; 483 break;
462 case CTL('U'): 484 case CTL('U'):
463#ifdef ANCIENT_BS_KILL_CHARS 485#ifdef ANCIENT_BS_KILL_CHARS
464 case '@': 486 case '@':
465#endif
466 cp->kill = ascval; /* set kill character */ 487 cp->kill = ascval; /* set kill character */
488#endif
467 while (bp > logname) { 489 while (bp > logname) {
490#ifdef BROKEN_PARITY_DETECTION_CODE
468 full_write(STDOUT_FILENO, erase[cp->parity], 3); 491 full_write(STDOUT_FILENO, erase[cp->parity], 3);
492#else
493 full_write(STDOUT_FILENO, "\010 \010", 3);
494#endif
469 bp--; 495 bp--;
470 } 496 }
471 break; 497 break;
@@ -474,19 +500,18 @@ static char *get_logname(char *logname, unsigned size_logname,
474 default: 500 default:
475 if (ascval < ' ') { 501 if (ascval < ' ') {
476 /* ignore garbage characters */ 502 /* ignore garbage characters */
477 } else if ((int)(bp - logname) >= size_logname - 1) { 503 } else if ((int)(bp - logname) < size_logname - 1) {
478 bb_error_msg_and_die("input overrun");
479 } else {
480 full_write(STDOUT_FILENO, &c, 1); /* echo the character */ 504 full_write(STDOUT_FILENO, &c, 1); /* echo the character */
481 *bp++ = ascval; /* and store it */ 505 *bp++ = ascval; /* and store it */
482 } 506 }
483 break; 507 break;
484 } 508 }
485 } 509 } /* end of get char loop */
486 } 510 got_logname: ;
487 /* Handle names with upper case and no lower case. */ 511 } /* while logname is empty */
488 512
489#ifdef HANDLE_ALLCAPS 513#ifdef HANDLE_ALLCAPS
514 /* Handle names with upper case and no lower case. */
490 cp->capslock = all_is_upcase(logname); 515 cp->capslock = all_is_upcase(logname);
491 if (cp->capslock) { 516 if (cp->capslock) {
492 for (bp = logname; *bp; bp++) 517 for (bp = logname; *bp; bp++)
@@ -520,8 +545,13 @@ static void termios_final(struct termios *tp, struct chardata *cp)
520 tp->c_oflag |= ONLCR; /* map NL in output to CR-NL */ 545 tp->c_oflag |= ONLCR; /* map NL in output to CR-NL */
521 } 546 }
522 tp->c_cc[VERASE] = cp->erase; /* set erase character */ 547 tp->c_cc[VERASE] = cp->erase; /* set erase character */
548#ifdef ANCIENT_BS_KILL_CHARS
523 tp->c_cc[VKILL] = cp->kill; /* set kill character */ 549 tp->c_cc[VKILL] = cp->kill; /* set kill character */
550#else
551 tp->c_cc[VKILL] = DEF_KILL; /* set kill character */
552#endif
524 553
554#ifdef BROKEN_PARITY_DETECTION_CODE
525 /* Account for the presence or absence of parity bits in input. */ 555 /* Account for the presence or absence of parity bits in input. */
526 switch (cp->parity) { 556 switch (cp->parity) {
527 case 0: /* space (always 0) parity */ 557 case 0: /* space (always 0) parity */
@@ -542,17 +572,19 @@ static void termios_final(struct termios *tp, struct chardata *cp)
542// Entire parity detection madness here just begs for deletion... 572// Entire parity detection madness here just begs for deletion...
543 break; 573 break;
544 } 574 }
575#endif
545 576
546 /* Account for upper case without lower case. */
547#ifdef HANDLE_ALLCAPS 577#ifdef HANDLE_ALLCAPS
578 /* Account for upper case without lower case. */
548 if (cp->capslock) { 579 if (cp->capslock) {
549 tp->c_iflag |= IUCLC; 580 tp->c_iflag |= IUCLC;
550 tp->c_lflag |= XCASE; 581 tp->c_lflag |= XCASE;
551 tp->c_oflag |= OLCUC; 582 tp->c_oflag |= OLCUC;
552 } 583 }
553#endif 584#endif
554 /* Optionally enable hardware flow control */ 585
555#ifdef CRTSCTS 586#ifdef CRTSCTS
587 /* Optionally enable hardware flow control */
556 if (option_mask32 & F_RTSCTS) 588 if (option_mask32 & F_RTSCTS)
557 tp->c_cflag |= CRTSCTS; 589 tp->c_cflag |= CRTSCTS;
558#endif 590#endif
@@ -685,7 +717,7 @@ int getty_main(int argc UNUSED_PARAM, char **argv)
685 717
686 logname = NULL; 718 logname = NULL;
687 if (!(option_mask32 & F_NOPROMPT)) { 719 if (!(option_mask32 & F_NOPROMPT)) {
688 /* NB:termios_init already set line speed 720 /* NB: termios_init already set line speed
689 * to options.speeds[0] */ 721 * to options.speeds[0] */
690 int baud_index = 0; 722 int baud_index = 0;
691 723