diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-01-24 14:35:09 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-01-24 14:35:09 +0100 |
| commit | faaf8cb3faf413485f2ea1bb3656ac40cb48b785 (patch) | |
| tree | 165225d4a3f3f0273ec8c0259973f357c9df0754 /loginutils | |
| parent | 6596380f52cd48b8b44443bb5677ec8caf538761 (diff) | |
| download | busybox-w32-faaf8cb3faf413485f2ea1bb3656ac40cb48b785.tar.gz busybox-w32-faaf8cb3faf413485f2ea1bb3656ac40cb48b785.tar.bz2 busybox-w32-faaf8cb3faf413485f2ea1bb3656ac40cb48b785.zip | |
getty: more simplifications; explain how we treat parity now
function old new delta
getty_main 1471 1434 -37
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'loginutils')
| -rw-r--r-- | loginutils/getty.c | 188 |
1 files changed, 93 insertions, 95 deletions
diff --git a/loginutils/getty.c b/loginutils/getty.c index bf66f2287..402e1c097 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c | |||
| @@ -1,15 +1,23 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
| 2 | /* Based on agetty - another getty program for Linux. By W. Z. Venema 1989 | 2 | /* |
| 3 | * Based on agetty - another getty program for Linux. By W. Z. Venema 1989 | ||
| 3 | * Ported to Linux by Peter Orbaek <poe@daimi.aau.dk> | 4 | * Ported to Linux by Peter Orbaek <poe@daimi.aau.dk> |
| 4 | * This program is freely distributable. | 5 | * This program is freely distributable. |
| 5 | * | 6 | * |
| 6 | * option added by Eric Rasmussen <ear@usfirst.org> - 12/28/95 | 7 | * option added by Eric Rasmussen <ear@usfirst.org> - 12/28/95 |
| 7 | * | 8 | * |
| 8 | * 1999-02-22 Arkadiusz Mickiewicz <misiek@misiek.eu.org> | 9 | * 1999-02-22 Arkadiusz Mickiewicz <misiek@misiek.eu.org> |
| 9 | * - added Native Language Support | 10 | * - Added Native Language Support |
| 10 | * | 11 | * |
| 11 | * 1999-05-05 Thorsten Kranzkowski <dl8bcu@gmx.net> | 12 | * 1999-05-05 Thorsten Kranzkowski <dl8bcu@gmx.net> |
| 12 | * - enable hardware flow control before displaying /etc/issue | 13 | * - Enabled hardware flow control before displaying /etc/issue |
| 14 | * | ||
| 15 | * 2011-01 Venys Vlasenko | ||
| 16 | * - Removed parity detection code. It can't work reliably: | ||
| 17 | * if all chars received have bit 7 cleared and odd (or even) parity, | ||
| 18 | * it is impossible to determine whether other side is 8-bit,no-parity | ||
| 19 | * or 7-bit,odd(even)-parity. It also interferes with non-ASCII usernames. | ||
| 20 | * - From now on, we assume that parity is correctly set. | ||
| 13 | * | 21 | * |
| 14 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 22 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
| 15 | */ | 23 | */ |
| @@ -23,13 +31,7 @@ | |||
| 23 | # define IUCLC 0 | 31 | # define IUCLC 0 |
| 24 | #endif | 32 | #endif |
| 25 | 33 | ||
| 26 | /* | 34 | #ifndef LOGIN_PROCESS |
| 27 | * Some heuristics to find out what environment we are in: if it is not | ||
| 28 | * System V, assume it is SunOS 4. | ||
| 29 | */ | ||
| 30 | #ifdef LOGIN_PROCESS /* defined in System V utmp.h */ | ||
| 31 | # include <sys/utsname.h> | ||
| 32 | #else /* if !sysV style, wtmp/utmp code is off */ | ||
| 33 | # undef ENABLE_FEATURE_UTMP | 35 | # undef ENABLE_FEATURE_UTMP |
| 34 | # undef ENABLE_FEATURE_WTMP | 36 | # undef ENABLE_FEATURE_WTMP |
| 35 | # define ENABLE_FEATURE_UTMP 0 | 37 | # define ENABLE_FEATURE_UTMP 0 |
| @@ -37,7 +39,7 @@ | |||
| 37 | #endif | 39 | #endif |
| 38 | 40 | ||
| 39 | 41 | ||
| 40 | /* The following is used for understandable diagnostics. */ | 42 | /* The following is used for understandable diagnostics */ |
| 41 | #ifdef DEBUGGING | 43 | #ifdef DEBUGGING |
| 42 | static FILE *dbf; | 44 | static FILE *dbf; |
| 43 | # define DEBUGTERM "/dev/ttyp0" | 45 | # define DEBUGTERM "/dev/ttyp0" |
| @@ -64,14 +66,14 @@ static FILE *dbf; | |||
| 64 | */ | 66 | */ |
| 65 | #define ISSUE "/etc/issue" | 67 | #define ISSUE "/etc/issue" |
| 66 | 68 | ||
| 67 | /* Some shorthands for control characters. */ | 69 | /* Some shorthands for control characters */ |
| 68 | #define CTL(x) ((x) ^ 0100) /* Assumes ASCII dialect */ | 70 | #define CTL(x) ((x) ^ 0100) /* Assumes ASCII dialect */ |
| 69 | #define CR CTL('M') /* carriage return */ | 71 | #define CR CTL('M') /* carriage return */ |
| 70 | #define NL CTL('J') /* line feed */ | 72 | #define NL CTL('J') /* line feed */ |
| 71 | #define BS CTL('H') /* back space */ | 73 | #define BS CTL('H') /* back space */ |
| 72 | #define DEL CTL('?') /* delete */ | 74 | #define DEL CTL('?') /* delete */ |
| 73 | 75 | ||
| 74 | /* Defaults for line-editing etc. characters; you may want to change this. */ | 76 | /* Defaults for line-editing etc. characters; you may want to change this */ |
| 75 | #define DEF_ERASE DEL /* default erase character */ | 77 | #define DEF_ERASE DEL /* default erase character */ |
| 76 | #define DEF_INTR CTL('C') /* default interrupt character */ | 78 | #define DEF_INTR CTL('C') /* default interrupt character */ |
| 77 | #define DEF_QUIT CTL('\\') /* default quit char */ | 79 | #define DEF_QUIT CTL('\\') /* default quit char */ |
| @@ -81,23 +83,22 @@ static FILE *dbf; | |||
| 81 | #define DEF_SWITCH 0 /* default switch char */ | 83 | #define DEF_SWITCH 0 /* default switch char */ |
| 82 | 84 | ||
| 83 | /* | 85 | /* |
| 84 | * When multiple baud rates are specified on the command line, the first one | 86 | * When multiple baud rates are specified on the command line, |
| 85 | * we will try is the first one specified. | 87 | * the first one we will try is the first one specified. |
| 86 | */ | 88 | */ |
| 87 | #define MAX_SPEED 10 /* max. nr. of baud rates */ | 89 | #define MAX_SPEED 10 /* max. nr. of baud rates */ |
| 88 | 90 | ||
| 89 | struct globals { | 91 | struct globals { |
| 90 | unsigned timeout; /* time-out period */ | 92 | unsigned timeout; /* time-out period */ |
| 91 | const char *login; /* login program */ | 93 | const char *login; /* login program */ |
| 94 | const char *fakehost; | ||
| 92 | const char *tty; /* name of tty */ | 95 | const char *tty; /* name of tty */ |
| 93 | const char *initstring; /* modem init string */ | 96 | const char *initstring; /* modem init string */ |
| 94 | const char *issue; /* alternative issue file */ | 97 | const char *issue; /* alternative issue file */ |
| 95 | int numspeed; /* number of baud rates to try */ | 98 | int numspeed; /* number of baud rates to try */ |
| 96 | int speeds[MAX_SPEED]; /* baud rates to be tried */ | 99 | int speeds[MAX_SPEED]; /* baud rates to be tried */ |
| 100 | unsigned char eol; /* end-of-line char seen (CR or NL) */ | ||
| 97 | struct termios termios; /* terminal mode bits */ | 101 | struct termios termios; /* terminal mode bits */ |
| 98 | /* Storage for things detected while the login name was read. */ | ||
| 99 | unsigned char erase; /* erase character */ | ||
| 100 | unsigned char eol; /* end-of-line character */ | ||
| 101 | char line_buf[128]; | 102 | char line_buf[128]; |
| 102 | }; | 103 | }; |
| 103 | 104 | ||
| @@ -168,14 +169,14 @@ static void parse_speeds(char *arg) | |||
| 168 | } | 169 | } |
| 169 | 170 | ||
| 170 | /* parse command-line arguments */ | 171 | /* parse command-line arguments */ |
| 171 | static void parse_args(char **argv, char **fakehost_p) | 172 | static void parse_args(char **argv) |
| 172 | { | 173 | { |
| 173 | char *ts; | 174 | char *ts; |
| 174 | int flags; | 175 | int flags; |
| 175 | 176 | ||
| 176 | opt_complementary = "-2:t+"; /* at least 2 args; -t N */ | 177 | opt_complementary = "-2:t+"; /* at least 2 args; -t N */ |
| 177 | flags = getopt32(argv, opt_string, | 178 | flags = getopt32(argv, opt_string, |
| 178 | &G.initstring, fakehost_p, &G.issue, | 179 | &G.initstring, &G.fakehost, &G.issue, |
| 179 | &G.login, &G.timeout | 180 | &G.login, &G.timeout |
| 180 | ); | 181 | ); |
| 181 | if (flags & F_INITSTRING) { | 182 | if (flags & F_INITSTRING) { |
| @@ -206,17 +207,17 @@ static void parse_args(char **argv, char **fakehost_p) | |||
| 206 | /* set up tty as standard input, output, error */ | 207 | /* set up tty as standard input, output, error */ |
| 207 | static void open_tty(void) | 208 | static void open_tty(void) |
| 208 | { | 209 | { |
| 209 | /* Set up new standard input, unless we are given an already opened port. */ | 210 | /* Set up new standard input, unless we are given an already opened port */ |
| 210 | if (NOT_LONE_DASH(G.tty)) { | 211 | if (NOT_LONE_DASH(G.tty)) { |
| 211 | if (G.tty[0] != '/') | 212 | if (G.tty[0] != '/') |
| 212 | G.tty = xasprintf("/dev/%s", G.tty); /* will leak it */ | 213 | G.tty = xasprintf("/dev/%s", G.tty); /* will leak it */ |
| 213 | 214 | ||
| 214 | /* Open the tty as standard input. */ | 215 | /* Open the tty as standard input */ |
| 215 | debug("open(2)\n"); | 216 | debug("open(2)\n"); |
| 216 | close(0); | 217 | close(0); |
| 217 | xopen(G.tty, O_RDWR | O_NONBLOCK); /* uses fd 0 */ | 218 | xopen(G.tty, O_RDWR | O_NONBLOCK); /* uses fd 0 */ |
| 218 | 219 | ||
| 219 | /* Set proper protections and ownership. */ | 220 | /* Set proper protections and ownership */ |
| 220 | fchown(0, 0, 0); /* 0:0 */ | 221 | fchown(0, 0, 0); /* 0:0 */ |
| 221 | fchmod(0, 0620); /* crw--w---- */ | 222 | fchmod(0, 0620); /* crw--w---- */ |
| 222 | } else { | 223 | } else { |
| @@ -229,7 +230,13 @@ static void open_tty(void) | |||
| 229 | } | 230 | } |
| 230 | } | 231 | } |
| 231 | 232 | ||
| 232 | /* initialize termios settings */ | 233 | /* We manipulate termios this way: |
| 234 | * - first, we read existing termios settings | ||
| 235 | * - termios_init modifies some parts and sets it | ||
| 236 | * - auto_baud and/or BREAK processing can set different speed and set termios | ||
| 237 | * - termios_final again modifies some parts and sets termios before | ||
| 238 | * execing login | ||
| 239 | */ | ||
| 233 | static void termios_init(int speed) | 240 | static void termios_init(int speed) |
| 234 | { | 241 | { |
| 235 | /* Flush input and output queues, important for modems! | 242 | /* Flush input and output queues, important for modems! |
| @@ -240,7 +247,7 @@ static void termios_init(int speed) | |||
| 240 | usleep(100*1000); /* 0.1 sec */ | 247 | usleep(100*1000); /* 0.1 sec */ |
| 241 | tcflush(STDIN_FILENO, TCIOFLUSH); | 248 | tcflush(STDIN_FILENO, TCIOFLUSH); |
| 242 | 249 | ||
| 243 | /* Set speed if it wasn't specified as "0" on command line. */ | 250 | /* Set speed if it wasn't specified as "0" on command line */ |
| 244 | if (speed != B0) | 251 | if (speed != B0) |
| 245 | cfsetspeed(&G.termios, speed); | 252 | cfsetspeed(&G.termios, speed); |
| 246 | 253 | ||
| @@ -271,13 +278,44 @@ static void termios_init(int speed) | |||
| 271 | debug("term_io 2\n"); | 278 | debug("term_io 2\n"); |
| 272 | } | 279 | } |
| 273 | 280 | ||
| 281 | static void termios_final(void) | ||
| 282 | { | ||
| 283 | /* General terminal-independent stuff */ | ||
| 284 | G.termios.c_iflag |= IXON | IXOFF; /* 2-way flow control */ | ||
| 285 | G.termios.c_lflag |= ICANON | ISIG | ECHO | ECHOE | ECHOK | ECHOKE; | ||
| 286 | /* no longer in lflag: | ECHOCTL | ECHOPRT */ | ||
| 287 | G.termios.c_oflag |= OPOST; | ||
| 288 | /* G.termios.c_cflag = 0; */ | ||
| 289 | G.termios.c_cc[VINTR] = DEF_INTR; | ||
| 290 | G.termios.c_cc[VQUIT] = DEF_QUIT; | ||
| 291 | G.termios.c_cc[VEOF] = DEF_EOF; | ||
| 292 | G.termios.c_cc[VEOL] = DEF_EOL; | ||
| 293 | #ifdef VSWTC | ||
| 294 | G.termios.c_cc[VSWTC] = DEF_SWITCH; | ||
| 295 | #endif | ||
| 296 | |||
| 297 | /* Account for special characters seen in input */ | ||
| 298 | if (G.eol == CR) { | ||
| 299 | G.termios.c_iflag |= ICRNL; /* map CR in input to NL */ | ||
| 300 | /* already done by termios_init */ | ||
| 301 | /* G.termios.c_oflag |= ONLCR; map NL in output to CR-NL */ | ||
| 302 | } | ||
| 303 | G.termios.c_cc[VKILL] = DEF_KILL; | ||
| 304 | |||
| 305 | #ifdef CRTSCTS | ||
| 306 | /* Optionally enable hardware flow control */ | ||
| 307 | if (option_mask32 & F_RTSCTS) | ||
| 308 | G.termios.c_cflag |= CRTSCTS; | ||
| 309 | #endif | ||
| 310 | |||
| 311 | /* Finally, make the new settings effective */ | ||
| 312 | if (tcsetattr_stdin_TCSANOW(&G.termios) < 0) | ||
| 313 | bb_perror_msg_and_die("tcsetattr"); | ||
| 314 | } | ||
| 315 | |||
| 274 | /* extract baud rate from modem status message */ | 316 | /* extract baud rate from modem status message */ |
| 275 | static void auto_baud(void) | 317 | static void auto_baud(void) |
| 276 | { | 318 | { |
| 277 | int speed; | ||
| 278 | int vmin; | ||
| 279 | unsigned iflag; | ||
| 280 | char *bp; | ||
| 281 | int nread; | 319 | int nread; |
| 282 | 320 | ||
| 283 | /* | 321 | /* |
| @@ -296,12 +334,9 @@ static void auto_baud(void) | |||
| 296 | */ | 334 | */ |
| 297 | 335 | ||
| 298 | /* | 336 | /* |
| 299 | * Use 7-bit characters, don't block if input queue is empty. Errors will | 337 | * Don't block if input queue is empty. |
| 300 | * be dealt with later on. | 338 | * Errors will be dealt with later on. |
| 301 | */ | 339 | */ |
| 302 | iflag = G.termios.c_iflag; | ||
| 303 | G.termios.c_iflag |= ISTRIP; /* enable 8th-bit stripping */ | ||
| 304 | vmin = G.termios.c_cc[VMIN]; | ||
| 305 | G.termios.c_cc[VMIN] = 0; /* don't block if queue empty */ | 340 | G.termios.c_cc[VMIN] = 0; /* don't block if queue empty */ |
| 306 | tcsetattr_stdin_TCSANOW(&G.termios); | 341 | tcsetattr_stdin_TCSANOW(&G.termios); |
| 307 | 342 | ||
| @@ -312,6 +347,8 @@ static void auto_baud(void) | |||
| 312 | sleep(1); | 347 | sleep(1); |
| 313 | nread = safe_read(STDIN_FILENO, G.line_buf, sizeof(G.line_buf) - 1); | 348 | nread = safe_read(STDIN_FILENO, G.line_buf, sizeof(G.line_buf) - 1); |
| 314 | if (nread > 0) { | 349 | if (nread > 0) { |
| 350 | int speed; | ||
| 351 | char *bp; | ||
| 315 | G.line_buf[nread] = '\0'; | 352 | G.line_buf[nread] = '\0'; |
| 316 | for (bp = G.line_buf; bp < G.line_buf + nread; bp++) { | 353 | for (bp = G.line_buf; bp < G.line_buf + nread; bp++) { |
| 317 | if (isdigit(*bp)) { | 354 | if (isdigit(*bp)) { |
| @@ -323,38 +360,38 @@ static void auto_baud(void) | |||
| 323 | } | 360 | } |
| 324 | } | 361 | } |
| 325 | 362 | ||
| 326 | /* Restore terminal settings. Errors will be dealt with later on. */ | 363 | /* Restore terminal settings. Errors will be dealt with later on */ |
| 327 | G.termios.c_iflag = iflag; | 364 | G.termios.c_cc[VMIN] = 1; /* restore to value set by termios_init */ |
| 328 | G.termios.c_cc[VMIN] = vmin; | ||
| 329 | tcsetattr_stdin_TCSANOW(&G.termios); | 365 | tcsetattr_stdin_TCSANOW(&G.termios); |
| 330 | } | 366 | } |
| 331 | 367 | ||
| 332 | /* get user name, establish parity, speed, erase, kill, eol; | 368 | /* get user name, establish parity, speed, erase, kill, eol; |
| 333 | * return NULL on BREAK, logname on success */ | 369 | * return NULL on BREAK, logname on success |
| 370 | */ | ||
| 334 | static char *get_logname(void) | 371 | static char *get_logname(void) |
| 335 | { | 372 | { |
| 336 | char *bp; | 373 | char *bp; |
| 337 | char c; | 374 | char c; |
| 338 | 375 | ||
| 339 | /* Flush pending input (esp. after parsing or switching the baud rate). */ | 376 | /* Flush pending input (esp. after parsing or switching the baud rate) */ |
| 340 | usleep(100*1000); /* 0.1 sec */ | 377 | usleep(100*1000); /* 0.1 sec */ |
| 341 | tcflush(STDIN_FILENO, TCIOFLUSH); | 378 | tcflush(STDIN_FILENO, TCIOFLUSH); |
| 342 | 379 | ||
| 343 | /* Prompt for and read a login name. */ | 380 | /* Prompt for and read a login name */ |
| 344 | G.line_buf[0] = '\0'; | 381 | G.line_buf[0] = '\0'; |
| 345 | while (!G.line_buf[0]) { | 382 | while (!G.line_buf[0]) { |
| 346 | /* Write issue file and prompt. */ | 383 | /* Write issue file and prompt */ |
| 347 | #ifdef ISSUE | 384 | #ifdef ISSUE |
| 348 | if (!(option_mask32 & F_NOISSUE)) | 385 | if (!(option_mask32 & F_NOISSUE)) |
| 349 | print_login_issue(G.issue, G.tty); | 386 | print_login_issue(G.issue, G.tty); |
| 350 | #endif | 387 | #endif |
| 351 | print_login_prompt(); | 388 | print_login_prompt(); |
| 352 | 389 | ||
| 353 | /* Read name, watch for break, parity, erase, kill, end-of-line. */ | 390 | /* Read name, watch for break, parity, erase, kill, end-of-line */ |
| 354 | bp = G.line_buf; | 391 | bp = G.line_buf; |
| 355 | G.eol = '\0'; | 392 | G.eol = '\0'; |
| 356 | while (1) { | 393 | while (1) { |
| 357 | /* Do not report trivial EINTR/EIO errors. */ | 394 | /* Do not report trivial EINTR/EIO errors */ |
| 358 | errno = EINTR; /* make read of 0 bytes be silent too */ | 395 | errno = EINTR; /* make read of 0 bytes be silent too */ |
| 359 | if (read(STDIN_FILENO, &c, 1) < 1) { | 396 | if (read(STDIN_FILENO, &c, 1) < 1) { |
| 360 | if (errno == EINTR || errno == EIO) | 397 | if (errno == EINTR || errno == EIO) |
| @@ -367,7 +404,7 @@ static char *get_logname(void) | |||
| 367 | if (c == '\0' && G.numspeed > 1) | 404 | if (c == '\0' && G.numspeed > 1) |
| 368 | return NULL; | 405 | return NULL; |
| 369 | 406 | ||
| 370 | /* Do erase, kill and end-of-line processing. */ | 407 | /* Do erase, kill and end-of-line processing */ |
| 371 | switch (c) { | 408 | switch (c) { |
| 372 | case CR: | 409 | case CR: |
| 373 | case NL: | 410 | case NL: |
| @@ -376,7 +413,7 @@ static char *get_logname(void) | |||
| 376 | goto got_logname; | 413 | goto got_logname; |
| 377 | case BS: | 414 | case BS: |
| 378 | case DEL: | 415 | case DEL: |
| 379 | G.erase = c; | 416 | G.termios.c_cc[VERASE] = c; |
| 380 | if (bp > G.line_buf) { | 417 | if (bp > G.line_buf) { |
| 381 | full_write(STDOUT_FILENO, "\010 \010", 3); | 418 | full_write(STDOUT_FILENO, "\010 \010", 3); |
| 382 | bp--; | 419 | bp--; |
| @@ -407,61 +444,22 @@ static char *get_logname(void) | |||
| 407 | return G.line_buf; | 444 | return G.line_buf; |
| 408 | } | 445 | } |
| 409 | 446 | ||
| 410 | /* set the final tty mode bits */ | ||
| 411 | static void termios_final(void) | ||
| 412 | { | ||
| 413 | /* General terminal-independent stuff. */ | ||
| 414 | G.termios.c_iflag |= IXON | IXOFF; /* 2-way flow control */ | ||
| 415 | G.termios.c_lflag |= ICANON | ISIG | ECHO | ECHOE | ECHOK | ECHOKE; | ||
| 416 | /* no longer in lflag: | ECHOCTL | ECHOPRT */ | ||
| 417 | G.termios.c_oflag |= OPOST; | ||
| 418 | /* G.termios.c_cflag = 0; */ | ||
| 419 | G.termios.c_cc[VINTR] = DEF_INTR; /* default interrupt */ | ||
| 420 | G.termios.c_cc[VQUIT] = DEF_QUIT; /* default quit */ | ||
| 421 | G.termios.c_cc[VEOF] = DEF_EOF; /* default EOF character */ | ||
| 422 | G.termios.c_cc[VEOL] = DEF_EOL; | ||
| 423 | #ifdef VSWTC | ||
| 424 | G.termios.c_cc[VSWTC] = DEF_SWITCH; /* default switch character */ | ||
| 425 | #endif | ||
| 426 | |||
| 427 | /* Account for special characters seen in input. */ | ||
| 428 | if (G.eol == CR) { | ||
| 429 | G.termios.c_iflag |= ICRNL; /* map CR in input to NL */ | ||
| 430 | G.termios.c_oflag |= ONLCR; /* map NL in output to CR-NL */ | ||
| 431 | } | ||
| 432 | G.termios.c_cc[VERASE] = G.erase; /* set erase character */ | ||
| 433 | G.termios.c_cc[VKILL] = DEF_KILL; /* set kill character */ | ||
| 434 | |||
| 435 | #ifdef CRTSCTS | ||
| 436 | /* Optionally enable hardware flow control */ | ||
| 437 | if (option_mask32 & F_RTSCTS) | ||
| 438 | G.termios.c_cflag |= CRTSCTS; | ||
| 439 | #endif | ||
| 440 | |||
| 441 | /* Finally, make the new settings effective */ | ||
| 442 | if (tcsetattr_stdin_TCSANOW(&G.termios) < 0) | ||
| 443 | bb_perror_msg_and_die("tcsetattr"); | ||
| 444 | } | ||
| 445 | |||
| 446 | int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 447 | int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 447 | int getty_main(int argc UNUSED_PARAM, char **argv) | 448 | int getty_main(int argc UNUSED_PARAM, char **argv) |
| 448 | { | 449 | { |
| 449 | int n; | 450 | int n; |
| 450 | pid_t pid; | 451 | pid_t pid; |
| 451 | char *fakehost = NULL; /* Fake hostname for ut_host */ | ||
| 452 | char *logname; | 452 | char *logname; |
| 453 | 453 | ||
| 454 | INIT_G(); | 454 | INIT_G(); |
| 455 | G.login = _PATH_LOGIN; /* default login program */ | 455 | G.login = _PATH_LOGIN; /* default login program */ |
| 456 | G.initstring = ""; /* modem init string */ | ||
| 457 | #ifdef ISSUE | 456 | #ifdef ISSUE |
| 458 | G.issue = ISSUE; /* default issue file */ | 457 | G.issue = ISSUE; /* default issue file */ |
| 459 | #endif | 458 | #endif |
| 460 | G.erase = DEF_ERASE; | ||
| 461 | G.eol = CR; | 459 | G.eol = CR; |
| 462 | 460 | ||
| 463 | /* Parse command-line arguments. */ | 461 | /* Parse command-line arguments */ |
| 464 | parse_args(argv, &fakehost); | 462 | parse_args(argv); |
| 465 | 463 | ||
| 466 | logmode = LOGMODE_NONE; | 464 | logmode = LOGMODE_NONE; |
| 467 | 465 | ||
| @@ -524,9 +522,9 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
| 524 | #endif | 522 | #endif |
| 525 | 523 | ||
| 526 | /* Update the utmp file. This tty is ours now! */ | 524 | /* Update the utmp file. This tty is ours now! */ |
| 527 | update_utmp(pid, LOGIN_PROCESS, G.tty, "LOGIN", fakehost); | 525 | update_utmp(pid, LOGIN_PROCESS, G.tty, "LOGIN", G.fakehost); |
| 528 | 526 | ||
| 529 | /* Initialize the termios settings (raw mode, eight-bit, blocking i/o). */ | 527 | /* Initialize the termios settings (raw mode, eight-bit, blocking i/o) */ |
| 530 | debug("calling termios_init\n"); | 528 | debug("calling termios_init\n"); |
| 531 | termios_init(G.speeds[0]); | 529 | termios_init(G.speeds[0]); |
| 532 | 530 | ||
| @@ -563,30 +561,30 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
| 563 | int baud_index = 0; | 561 | int baud_index = 0; |
| 564 | 562 | ||
| 565 | while (1) { | 563 | while (1) { |
| 566 | /* Read the login name. */ | 564 | /* Read the login name */ |
| 567 | debug("reading login name\n"); | 565 | debug("reading login name\n"); |
| 568 | logname = get_logname(); | 566 | logname = get_logname(); |
| 569 | if (logname) | 567 | if (logname) |
| 570 | break; | 568 | break; |
| 571 | /* We are here only if G.numspeed > 1. */ | 569 | /* We are here only if G.numspeed > 1 */ |
| 572 | baud_index = (baud_index + 1) % G.numspeed; | 570 | baud_index = (baud_index + 1) % G.numspeed; |
| 573 | cfsetspeed(&G.termios, G.speeds[baud_index]); | 571 | cfsetspeed(&G.termios, G.speeds[baud_index]); |
| 574 | tcsetattr_stdin_TCSANOW(&G.termios); | 572 | tcsetattr_stdin_TCSANOW(&G.termios); |
| 575 | } | 573 | } |
| 576 | } | 574 | } |
| 577 | 575 | ||
| 578 | /* Disable timer. */ | 576 | /* Disable timer */ |
| 579 | alarm(0); | 577 | alarm(0); |
| 580 | 578 | ||
| 581 | /* Finalize the termios settings. */ | 579 | /* Finalize the termios settings */ |
| 582 | termios_final(); | 580 | termios_final(); |
| 583 | 581 | ||
| 584 | /* Now the newline character should be properly written. */ | 582 | /* Now the newline character should be properly written */ |
| 585 | full_write(STDOUT_FILENO, "\n", 1); | 583 | full_write(STDOUT_FILENO, "\n", 1); |
| 586 | 584 | ||
| 587 | /* Let the login program take care of password validation. */ | 585 | /* Let the login program take care of password validation */ |
| 588 | /* We use PATH because we trust that root doesn't set "bad" PATH, | 586 | /* We use PATH because we trust that root doesn't set "bad" PATH, |
| 589 | * and getty is not suid-root applet. */ | 587 | * and getty is not suid-root applet */ |
| 590 | /* With -n, logname == NULL, and login will ask for username instead */ | 588 | /* With -n, logname == NULL, and login will ask for username instead */ |
| 591 | BB_EXECLP(G.login, G.login, "--", logname, NULL); | 589 | BB_EXECLP(G.login, G.login, "--", logname, NULL); |
| 592 | bb_error_msg_and_die("can't execute '%s'", G.login); | 590 | bb_error_msg_and_die("can't execute '%s'", G.login); |
