diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-01-22 03:06:40 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-01-22 03:06:40 +0100 |
commit | 2b57b6cd43211e2430c78caa0895f41376f29dc1 (patch) | |
tree | 4fd9633add21c5093976e14dd444814b517ec63c | |
parent | 3a0f690dcd06ff693a0b76d764739425600ec1f1 (diff) | |
download | busybox-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.c | 112 |
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. */ |
109 | struct chardata { | 116 | struct 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. */ |
127 | static const struct chardata init_chardata = { | 138 | static 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 | ||
156 | static const char opt_string[] ALIGN1 = "I:LH:f:hil:mt:wn"; | 173 | static 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 */ |
260 | static void termios_init(struct termios *tp, int speed) | 277 | static 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 | ||