diff options
| author | vodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2005-09-29 11:31:26 +0000 |
|---|---|---|
| committer | vodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2005-09-29 11:31:26 +0000 |
| commit | e263de99f6eabc608e9f79181c8e146d8a951503 (patch) | |
| tree | d39b290031623e956a930a9ebb2acb755ce12483 | |
| parent | f334a67fa8b7f2ae67198ed9a545374be503530f (diff) | |
| download | busybox-w32-e263de99f6eabc608e9f79181c8e146d8a951503.tar.gz busybox-w32-e263de99f6eabc608e9f79181c8e146d8a951503.tar.bz2 busybox-w32-e263de99f6eabc608e9f79181c8e146d8a951503.zip | |
getty must chdir(/). Use bb_getopt_ulflags. Indent. error() perfect
git-svn-id: svn://busybox.net/trunk/busybox@11690 69ca8d6d-28ef-0310-b511-8ec308f3f277
| -rw-r--r-- | loginutils/getty.c | 401 |
1 files changed, 180 insertions, 221 deletions
diff --git a/loginutils/getty.c b/loginutils/getty.c index 9bad008c6..db9a150e0 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c | |||
| @@ -38,7 +38,6 @@ | |||
| 38 | /* If USE_SYSLOG is undefined all diagnostics go directly to /dev/console. */ | 38 | /* If USE_SYSLOG is undefined all diagnostics go directly to /dev/console. */ |
| 39 | #ifdef CONFIG_SYSLOGD | 39 | #ifdef CONFIG_SYSLOGD |
| 40 | #include <sys/param.h> | 40 | #include <sys/param.h> |
| 41 | #define USE_SYSLOG | ||
| 42 | #include <syslog.h> | 41 | #include <syslog.h> |
| 43 | #endif | 42 | #endif |
| 44 | 43 | ||
| @@ -48,8 +47,8 @@ | |||
| 48 | * System V, assume it is SunOS 4. | 47 | * System V, assume it is SunOS 4. |
| 49 | */ | 48 | */ |
| 50 | 49 | ||
| 51 | #ifdef LOGIN_PROCESS /* defined in System V utmp.h */ | 50 | #ifdef LOGIN_PROCESS /* defined in System V utmp.h */ |
| 52 | #define SYSV_STYLE /* select System V style getty */ | 51 | #define SYSV_STYLE /* select System V style getty */ |
| 53 | #ifdef CONFIG_FEATURE_WTMP | 52 | #ifdef CONFIG_FEATURE_WTMP |
| 54 | extern void updwtmp(const char *filename, const struct utmp *ut); | 53 | extern void updwtmp(const char *filename, const struct utmp *ut); |
| 55 | #endif | 54 | #endif |
| @@ -63,7 +62,7 @@ extern void updwtmp(const char *filename, const struct utmp *ut); | |||
| 63 | * and for line editing at the same time. | 62 | * and for line editing at the same time. |
| 64 | */ | 63 | */ |
| 65 | 64 | ||
| 66 | #ifdef SYSV_STYLE | 65 | #ifdef SYSV_STYLE |
| 67 | #include <sys/utsname.h> | 66 | #include <sys/utsname.h> |
| 68 | #include <time.h> | 67 | #include <time.h> |
| 69 | #endif | 68 | #endif |
| @@ -72,25 +71,25 @@ extern void updwtmp(const char *filename, const struct utmp *ut); | |||
| 72 | * /etc/issue file. You will not want to spit out large "issue" files at the | 71 | * /etc/issue file. You will not want to spit out large "issue" files at the |
| 73 | * wrong baud rate. | 72 | * wrong baud rate. |
| 74 | */ | 73 | */ |
| 75 | #define ISSUE "/etc/issue" /* displayed before the login prompt */ | 74 | #define ISSUE "/etc/issue" /* displayed before the login prompt */ |
| 76 | 75 | ||
| 77 | /* Some shorthands for control characters. */ | 76 | /* Some shorthands for control characters. */ |
| 78 | 77 | ||
| 79 | #define CTL(x) (x ^ 0100) /* Assumes ASCII dialect */ | 78 | #define CTL(x) (x ^ 0100) /* Assumes ASCII dialect */ |
| 80 | #define CR CTL('M') /* carriage return */ | 79 | #define CR CTL('M') /* carriage return */ |
| 81 | #define NL CTL('J') /* line feed */ | 80 | #define NL CTL('J') /* line feed */ |
| 82 | #define BS CTL('H') /* back space */ | 81 | #define BS CTL('H') /* back space */ |
| 83 | #define DEL CTL('?') /* delete */ | 82 | #define DEL CTL('?') /* delete */ |
| 84 | 83 | ||
| 85 | /* Defaults for line-editing etc. characters; you may want to change this. */ | 84 | /* Defaults for line-editing etc. characters; you may want to change this. */ |
| 86 | 85 | ||
| 87 | #define DEF_ERASE DEL /* default erase character */ | 86 | #define DEF_ERASE DEL /* default erase character */ |
| 88 | #define DEF_INTR CTL('C') /* default interrupt character */ | 87 | #define DEF_INTR CTL('C') /* default interrupt character */ |
| 89 | #define DEF_QUIT CTL('\\') /* default quit char */ | 88 | #define DEF_QUIT CTL('\\') /* default quit char */ |
| 90 | #define DEF_KILL CTL('U') /* default kill char */ | 89 | #define DEF_KILL CTL('U') /* default kill char */ |
| 91 | #define DEF_EOF CTL('D') /* default EOF char */ | 90 | #define DEF_EOF CTL('D') /* default EOF char */ |
| 92 | #define DEF_EOL '\n' | 91 | #define DEF_EOL '\n' |
| 93 | #define DEF_SWITCH 0 /* default switch char */ | 92 | #define DEF_SWITCH 0 /* default switch char */ |
| 94 | 93 | ||
| 95 | /* | 94 | /* |
| 96 | * SunOS 4.1.1 termio is broken. We must use the termios stuff instead, | 95 | * SunOS 4.1.1 termio is broken. We must use the termios stuff instead, |
| @@ -103,14 +102,14 @@ extern void updwtmp(const char *filename, const struct utmp *ut); | |||
| 103 | /* linux 0.12 termio is broken too, if we use it c_cc[VERASE] isn't set | 102 | /* linux 0.12 termio is broken too, if we use it c_cc[VERASE] isn't set |
| 104 | properly, but all is well if we use termios?! */ | 103 | properly, but all is well if we use termios?! */ |
| 105 | 104 | ||
| 106 | #ifdef TCGETS | 105 | #ifdef TCGETS |
| 107 | #undef TCGETA | 106 | #undef TCGETA |
| 108 | #undef TCSETA | 107 | #undef TCSETA |
| 109 | #undef TCSETAW | 108 | #undef TCSETAW |
| 110 | #define termio termios | 109 | #define termio termios |
| 111 | #define TCGETA TCGETS | 110 | #define TCGETA TCGETS |
| 112 | #define TCSETA TCSETS | 111 | #define TCSETA TCSETS |
| 113 | #define TCSETAW TCSETSW | 112 | #define TCSETAW TCSETSW |
| 114 | #endif | 113 | #endif |
| 115 | 114 | ||
| 116 | /* | 115 | /* |
| @@ -119,7 +118,7 @@ extern void updwtmp(const char *filename, const struct utmp *ut); | |||
| 119 | * Release <3). | 118 | * Release <3). |
| 120 | */ | 119 | */ |
| 121 | #ifndef BUFSIZ | 120 | #ifndef BUFSIZ |
| 122 | #define BUFSIZ 1024 | 121 | #define BUFSIZ 1024 |
| 123 | #endif | 122 | #endif |
| 124 | 123 | ||
| 125 | /* | 124 | /* |
| @@ -127,50 +126,54 @@ extern void updwtmp(const char *filename, const struct utmp *ut); | |||
| 127 | * we will try is the first one specified. | 126 | * we will try is the first one specified. |
| 128 | */ | 127 | */ |
| 129 | 128 | ||
| 130 | #define FIRST_SPEED 0 | 129 | #define FIRST_SPEED 0 |
| 131 | 130 | ||
| 132 | /* Storage for command-line options. */ | 131 | /* Storage for command-line options. */ |
| 133 | 132 | ||
| 134 | #define MAX_SPEED 10 /* max. nr. of baud rates */ | 133 | #define MAX_SPEED 10 /* max. nr. of baud rates */ |
| 135 | 134 | ||
| 136 | struct options { | 135 | struct options { |
| 137 | int flags; /* toggle switches, see below */ | 136 | int flags; /* toggle switches, see below */ |
| 138 | int timeout; /* time-out period */ | 137 | int timeout; /* time-out period */ |
| 139 | char *login; /* login program */ | 138 | char *login; /* login program */ |
| 140 | char *tty; /* name of tty */ | 139 | char *tty; /* name of tty */ |
| 141 | char *initstring; /* modem init string */ | 140 | char *initstring; /* modem init string */ |
| 142 | char *issue; /* alternative issue file */ | 141 | char *issue; /* alternative issue file */ |
| 143 | int numspeed; /* number of baud rates to try */ | 142 | int numspeed; /* number of baud rates to try */ |
| 144 | int speeds[MAX_SPEED]; /* baud rates to be tried */ | 143 | int speeds[MAX_SPEED]; /* baud rates to be tried */ |
| 145 | }; | 144 | }; |
| 146 | 145 | ||
| 147 | #define F_PARSE (1<<0) /* process modem status messages */ | 146 | static const char opt_string[] = "I:LH:f:hil:mt:wn"; |
| 148 | #define F_ISSUE (1<<1) /* display /etc/issue */ | 147 | #define F_INITSTRING (1<<0) /* initstring is set */ |
| 149 | #define F_RTSCTS (1<<2) /* enable RTS/CTS flow control */ | 148 | #define F_LOCAL (1<<1) /* force local */ |
| 150 | #define F_LOCAL (1<<3) /* force local */ | 149 | #define F_FAKEHOST (1<<2) /* force fakehost */ |
| 151 | #define F_INITSTRING (1<<4) /* initstring is set */ | 150 | #define F_CUSTISSUE (1<<3) /* give alternative issue file */ |
| 152 | #define F_WAITCRLF (1<<5) /* wait for CR or LF */ | 151 | #define F_RTSCTS (1<<4) /* enable RTS/CTS flow control */ |
| 153 | #define F_CUSTISSUE (1<<6) /* give alternative issue file */ | 152 | #define F_ISSUE (1<<5) /* display /etc/issue */ |
| 154 | #define F_NOPROMPT (1<<7) /* don't ask for login name! */ | 153 | #define F_LOGIN (1<<6) /* non-default login program */ |
| 154 | #define F_PARSE (1<<7) /* process modem status messages */ | ||
| 155 | #define F_TIMEOUT (1<<8) /* time out */ | ||
| 156 | #define F_WAITCRLF (1<<9) /* wait for CR or LF */ | ||
| 157 | #define F_NOPROMPT (1<<10) /* don't ask for login name! */ | ||
| 155 | 158 | ||
| 156 | /* Storage for things detected while the login name was read. */ | 159 | /* Storage for things detected while the login name was read. */ |
| 157 | 160 | ||
| 158 | struct chardata { | 161 | struct chardata { |
| 159 | int erase; /* erase character */ | 162 | int erase; /* erase character */ |
| 160 | int kill; /* kill character */ | 163 | int kill; /* kill character */ |
| 161 | int eol; /* end-of-line character */ | 164 | int eol; /* end-of-line character */ |
| 162 | int parity; /* what parity did we see */ | 165 | int parity; /* what parity did we see */ |
| 163 | int capslock; /* upper case without lower case */ | 166 | int capslock; /* upper case without lower case */ |
| 164 | }; | 167 | }; |
| 165 | 168 | ||
| 166 | /* Initial values for the above. */ | 169 | /* Initial values for the above. */ |
| 167 | 170 | ||
| 168 | static struct chardata init_chardata = { | 171 | static struct chardata init_chardata = { |
| 169 | DEF_ERASE, /* default erase character */ | 172 | DEF_ERASE, /* default erase character */ |
| 170 | DEF_KILL, /* default kill character */ | 173 | DEF_KILL, /* default kill character */ |
| 171 | 13, /* default eol char */ | 174 | 13, /* default eol char */ |
| 172 | 0, /* space parity */ | 175 | 0, /* space parity */ |
| 173 | 0, /* no capslock */ | 176 | 0, /* no capslock */ |
| 174 | }; | 177 | }; |
| 175 | 178 | ||
| 176 | #if 0 | 179 | #if 0 |
| @@ -193,16 +196,16 @@ static struct Speedtab speedtab[] = { | |||
| 193 | {2400, B2400}, | 196 | {2400, B2400}, |
| 194 | {4800, B4800}, | 197 | {4800, B4800}, |
| 195 | {9600, B9600}, | 198 | {9600, B9600}, |
| 196 | #ifdef B19200 | 199 | #ifdef B19200 |
| 197 | {19200, B19200}, | 200 | {19200, B19200}, |
| 198 | #endif | 201 | #endif |
| 199 | #ifdef B38400 | 202 | #ifdef B38400 |
| 200 | {38400, B38400}, | 203 | {38400, B38400}, |
| 201 | #endif | 204 | #endif |
| 202 | #ifdef EXTA | 205 | #ifdef EXTA |
| 203 | {19200, EXTA}, | 206 | {19200, EXTA}, |
| 204 | #endif | 207 | #endif |
| 205 | #ifdef EXTB | 208 | #ifdef EXTB |
| 206 | {38400, EXTB}, | 209 | {38400, EXTB}, |
| 207 | #endif | 210 | #endif |
| 208 | #ifdef B57600 | 211 | #ifdef B57600 |
| @@ -226,16 +229,14 @@ static void auto_baud(struct termio *tp); | |||
| 226 | static void do_prompt(struct options *op, struct termio *tp); | 229 | static void do_prompt(struct options *op, struct termio *tp); |
| 227 | static void next_speed(struct termio *tp, struct options *op); | 230 | static void next_speed(struct termio *tp, struct options *op); |
| 228 | static char *get_logname(struct options *op, struct chardata *cp, | 231 | static char *get_logname(struct options *op, struct chardata *cp, |
| 229 | 232 | struct termio *tp); | |
| 230 | struct termio *tp); | ||
| 231 | static void termio_final(struct options *op, struct termio *tp, | 233 | static void termio_final(struct options *op, struct termio *tp, |
| 232 | 234 | struct chardata *cp); | |
| 233 | struct chardata *cp); | ||
| 234 | static int caps_lock(const char *s); | 235 | static int caps_lock(const char *s); |
| 235 | static int bcode(char *s); | 236 | static int bcode(const char *s); |
| 236 | static void error(const char *fmt, ...) __attribute__ ((noreturn)); | 237 | static void error(const char *fmt, ...) __attribute__ ((noreturn)); |
| 237 | 238 | ||
| 238 | #ifdef SYSV_STYLE | 239 | #ifdef SYSV_STYLE |
| 239 | #ifdef CONFIG_FEATURE_UTMP | 240 | #ifdef CONFIG_FEATURE_UTMP |
| 240 | static void update_utmp(char *line); | 241 | static void update_utmp(char *line); |
| 241 | #endif | 242 | #endif |
| @@ -252,26 +253,26 @@ static char *fakehost = NULL; | |||
| 252 | #define DEBUGTERM "/dev/ttyp0" | 253 | #define DEBUGTERM "/dev/ttyp0" |
| 253 | FILE *dbf; | 254 | FILE *dbf; |
| 254 | #else | 255 | #else |
| 255 | #define debug(s) /* nothing */ | 256 | #define debug(s) /* nothing */ |
| 256 | #endif | 257 | #endif |
| 257 | 258 | ||
| 258 | int getty_main(int argc, char **argv) | 259 | int getty_main(int argc, char **argv) |
| 259 | { | 260 | { |
| 260 | char *logname = NULL; /* login name, given to /bin/login */ | 261 | char *logname = NULL; /* login name, given to /bin/login */ |
| 261 | struct chardata chardata; /* set by get_logname() */ | 262 | struct chardata chardata; /* set by get_logname() */ |
| 262 | struct termio termio; /* terminal mode bits */ | 263 | struct termio termio; /* terminal mode bits */ |
| 263 | static struct options options = { | 264 | static struct options options = { |
| 264 | F_ISSUE, /* show /etc/issue (SYSV_STYLE) */ | 265 | 0, /* show /etc/issue (SYSV_STYLE) */ |
| 265 | 0, /* no timeout */ | 266 | 0, /* no timeout */ |
| 266 | _PATH_LOGIN, /* default login program */ | 267 | _PATH_LOGIN, /* default login program */ |
| 267 | "tty1", /* default tty line */ | 268 | "tty1", /* default tty line */ |
| 268 | "", /* modem init string */ | 269 | "", /* modem init string */ |
| 269 | #ifdef ISSUE | 270 | #ifdef ISSUE |
| 270 | ISSUE, /* default issue file */ | 271 | ISSUE, /* default issue file */ |
| 271 | #else | 272 | #else |
| 272 | NULL, | 273 | NULL, |
| 273 | #endif | 274 | #endif |
| 274 | 0, /* no baud rates known yet */ | 275 | 0, /* no baud rates known yet */ |
| 275 | }; | 276 | }; |
| 276 | 277 | ||
| 277 | #ifdef DEBUGGING | 278 | #ifdef DEBUGGING |
| @@ -298,7 +299,7 @@ int getty_main(int argc, char **argv) | |||
| 298 | /* Update the utmp file. */ | 299 | /* Update the utmp file. */ |
| 299 | 300 | ||
| 300 | 301 | ||
| 301 | #ifdef SYSV_STYLE | 302 | #ifdef SYSV_STYLE |
| 302 | #ifdef CONFIG_FEATURE_UTMP | 303 | #ifdef CONFIG_FEATURE_UTMP |
| 303 | update_utmp(options.tty); | 304 | update_utmp(options.tty); |
| 304 | #endif | 305 | #endif |
| @@ -346,7 +347,7 @@ int getty_main(int argc, char **argv) | |||
| 346 | 347 | ||
| 347 | debug("waiting for cr-lf\n"); | 348 | debug("waiting for cr-lf\n"); |
| 348 | while (read(0, &ch, 1) == 1) { | 349 | while (read(0, &ch, 1) == 1) { |
| 349 | ch &= 0x7f; /* strip "parity bit" */ | 350 | ch &= 0x7f; /* strip "parity bit" */ |
| 350 | #ifdef DEBUGGING | 351 | #ifdef DEBUGGING |
| 351 | fprintf(dbf, "read %c\n", ch); | 352 | fprintf(dbf, "read %c\n", ch); |
| 352 | #endif | 353 | #endif |
| @@ -387,85 +388,45 @@ int getty_main(int argc, char **argv) | |||
| 387 | 388 | ||
| 388 | static void parse_args(int argc, char **argv, struct options *op) | 389 | static void parse_args(int argc, char **argv, struct options *op) |
| 389 | { | 390 | { |
| 390 | extern char *optarg; /* getopt */ | 391 | char *ts; |
| 391 | extern int optind; /* getopt */ | 392 | |
| 392 | int c; | 393 | op->flags = bb_getopt_ulflags(argc, argv, opt_string, |
| 393 | 394 | &(op->initstring), &fakehost, &(op->issue), | |
| 394 | while (isascii(c = getopt(argc, argv, "I:LH:f:hil:mt:wn"))) { | 395 | &(op->login), &ts); |
| 395 | switch (c) { | 396 | if(op->flags & F_INITSTRING) { |
| 396 | case 'I': | 397 | const char *p = op->initstring; |
| 397 | if (!(op->initstring = strdup(optarg))) | 398 | char *q; |
| 398 | error(bb_msg_memory_exhausted); | 399 | |
| 399 | 400 | q = op->initstring = bb_xstrdup(op->initstring); | |
| 400 | { | 401 | /* copy optarg into op->initstring decoding \ddd |
| 401 | const char *p; | 402 | octal codes into chars */ |
| 402 | char *q; | 403 | while (*p) { |
| 403 | 404 | if (*p == '\\') { | |
| 404 | /* copy optarg into op->initstring decoding \ddd | 405 | p++; |
| 405 | octal codes into chars */ | 406 | *q++ = bb_process_escape_sequence(&p); |
| 406 | q = op->initstring; | 407 | } else { |
| 407 | p = optarg; | 408 | *q++ = *p++; |
| 408 | while (*p) { | ||
| 409 | if (*p == '\\') { | ||
| 410 | p++; | ||
| 411 | *q++ = bb_process_escape_sequence(&p); | ||
| 412 | } else { | ||
| 413 | *q++ = *p++; | ||
| 414 | } | ||
| 415 | } | ||
| 416 | *q = '\0'; | ||
| 417 | } | 409 | } |
| 418 | op->flags |= F_INITSTRING; | ||
| 419 | break; | ||
| 420 | |||
| 421 | case 'L': /* force local */ | ||
| 422 | op->flags |= F_LOCAL; | ||
| 423 | break; | ||
| 424 | case 'H': /* fake login host */ | ||
| 425 | fakehost = optarg; | ||
| 426 | break; | ||
| 427 | case 'f': /* custom issue file */ | ||
| 428 | op->flags |= F_CUSTISSUE; | ||
| 429 | op->issue = optarg; | ||
| 430 | break; | ||
| 431 | case 'h': /* enable h/w flow control */ | ||
| 432 | op->flags |= F_RTSCTS; | ||
| 433 | break; | ||
| 434 | case 'i': /* do not show /etc/issue */ | ||
| 435 | op->flags &= ~F_ISSUE; | ||
| 436 | break; | ||
| 437 | case 'l': | ||
| 438 | op->login = optarg; /* non-default login program */ | ||
| 439 | break; | ||
| 440 | case 'm': /* parse modem status message */ | ||
| 441 | op->flags |= F_PARSE; | ||
| 442 | break; | ||
| 443 | case 'n': | ||
| 444 | op->flags |= F_NOPROMPT; | ||
| 445 | break; | ||
| 446 | case 't': /* time out */ | ||
| 447 | if ((op->timeout = atoi(optarg)) <= 0) | ||
| 448 | error("bad timeout value: %s", optarg); | ||
| 449 | break; | ||
| 450 | case 'w': | ||
| 451 | op->flags |= F_WAITCRLF; | ||
| 452 | break; | ||
| 453 | default: | ||
| 454 | bb_show_usage(); | ||
| 455 | } | 410 | } |
| 411 | *q = '\0'; | ||
| 412 | } | ||
| 413 | op->flags ^= F_ISSUE; /* revert flag show /etc/issue */ | ||
| 414 | if(op->flags & F_TIMEOUT) { | ||
| 415 | if ((op->timeout = atoi(ts)) <= 0) | ||
| 416 | error("bad timeout value: %s", ts); | ||
| 456 | } | 417 | } |
| 457 | debug("after getopt loop\n"); | 418 | debug("after getopt loop\n"); |
| 458 | if (argc < optind + 2) /* check parameter count */ | 419 | if (argc < optind + 2) /* check parameter count */ |
| 459 | bb_show_usage(); | 420 | bb_show_usage(); |
| 460 | 421 | ||
| 461 | /* we loosen up a bit and accept both "baudrate tty" and "tty baudrate" */ | 422 | /* we loosen up a bit and accept both "baudrate tty" and "tty baudrate" */ |
| 462 | if ('0' <= argv[optind][0] && argv[optind][0] <= '9') { | 423 | if ('0' <= argv[optind][0] && argv[optind][0] <= '9') { |
| 463 | /* a number first, assume it's a speed (BSD style) */ | 424 | /* a number first, assume it's a speed (BSD style) */ |
| 464 | parse_speeds(op, argv[optind++]); /* baud rate(s) */ | 425 | parse_speeds(op, argv[optind++]); /* baud rate(s) */ |
| 465 | op->tty = argv[optind]; /* tty name */ | 426 | op->tty = argv[optind]; /* tty name */ |
| 466 | } else { | 427 | } else { |
| 467 | op->tty = argv[optind++]; /* tty name */ | 428 | op->tty = argv[optind++]; /* tty name */ |
| 468 | parse_speeds(op, argv[optind]); /* baud rate(s) */ | 429 | parse_speeds(op, argv[optind]); /* baud rate(s) */ |
| 469 | } | 430 | } |
| 470 | 431 | ||
| 471 | optind++; | 432 | optind++; |
| @@ -491,7 +452,7 @@ static void parse_speeds(struct options *op, char *arg) | |||
| 491 | debug("exiting parsespeeds\n"); | 452 | debug("exiting parsespeeds\n"); |
| 492 | } | 453 | } |
| 493 | 454 | ||
| 494 | #ifdef SYSV_STYLE | 455 | #ifdef SYSV_STYLE |
| 495 | #ifdef CONFIG_FEATURE_UTMP | 456 | #ifdef CONFIG_FEATURE_UTMP |
| 496 | 457 | ||
| 497 | /* update_utmp - update our utmp entry */ | 458 | /* update_utmp - update our utmp entry */ |
| @@ -519,7 +480,7 @@ static void update_utmp(char *line) | |||
| 519 | utmpname(_PATH_UTMP); | 480 | utmpname(_PATH_UTMP); |
| 520 | setutent(); | 481 | setutent(); |
| 521 | while ((utp = getutent()) | 482 | while ((utp = getutent()) |
| 522 | && !(utp->ut_type == INIT_PROCESS && utp->ut_pid == mypid)) /* nothing */ | 483 | && !(utp->ut_type == INIT_PROCESS && utp->ut_pid == mypid)) /* nothing */ |
| 523 | ; | 484 | ; |
| 524 | 485 | ||
| 525 | if (utp) { | 486 | if (utp) { |
| @@ -544,7 +505,7 @@ static void update_utmp(char *line) | |||
| 544 | endutent(); | 505 | endutent(); |
| 545 | 506 | ||
| 546 | #ifdef CONFIG_FEATURE_WTMP | 507 | #ifdef CONFIG_FEATURE_WTMP |
| 547 | if (access(_PATH_WTMP, R_OK|W_OK) == -1) | 508 | if (access(_PATH_WTMP, R_OK|W_OK) == -1) |
| 548 | close(creat(_PATH_WTMP, 0664)); | 509 | close(creat(_PATH_WTMP, 0664)); |
| 549 | updwtmp(_PATH_WTMP, &ut); | 510 | updwtmp(_PATH_WTMP, &ut); |
| 550 | #endif | 511 | #endif |
| @@ -556,6 +517,8 @@ static void update_utmp(char *line) | |||
| 556 | /* open_tty - set up tty as standard { input, output, error } */ | 517 | /* open_tty - set up tty as standard { input, output, error } */ |
| 557 | static void open_tty(char *tty, struct termio *tp, int local) | 518 | static void open_tty(char *tty, struct termio *tp, int local) |
| 558 | { | 519 | { |
| 520 | int chdir_to_root = 0; | ||
| 521 | |||
| 559 | /* Set up new standard input, unless we are given an already opened port. */ | 522 | /* Set up new standard input, unless we are given an already opened port. */ |
| 560 | 523 | ||
| 561 | if (strcmp(tty, "-")) { | 524 | if (strcmp(tty, "-")) { |
| @@ -566,6 +529,7 @@ static void open_tty(char *tty, struct termio *tp, int local) | |||
| 566 | 529 | ||
| 567 | if (chdir("/dev")) | 530 | if (chdir("/dev")) |
| 568 | error("/dev: chdir() failed: %m"); | 531 | error("/dev: chdir() failed: %m"); |
| 532 | chdir_to_root = 1; | ||
| 569 | if (stat(tty, &st) < 0) | 533 | if (stat(tty, &st) < 0) |
| 570 | error("/dev/%s: %m", tty); | 534 | error("/dev/%s: %m", tty); |
| 571 | if ((st.st_mode & S_IFMT) != S_IFCHR) | 535 | if ((st.st_mode & S_IFMT) != S_IFCHR) |
| @@ -594,7 +558,7 @@ static void open_tty(char *tty, struct termio *tp, int local) | |||
| 594 | debug("duping\n"); | 558 | debug("duping\n"); |
| 595 | if (dup2(STDIN_FILENO, STDOUT_FILENO) == -1 || | 559 | if (dup2(STDIN_FILENO, STDOUT_FILENO) == -1 || |
| 596 | dup2(STDIN_FILENO, STDERR_FILENO) == -1) | 560 | dup2(STDIN_FILENO, STDERR_FILENO) == -1) |
| 597 | error("%s: dup problem: %m", tty); /* we have a problem */ | 561 | error("%s: dup problem: %m", tty); /* we have a problem */ |
| 598 | 562 | ||
| 599 | /* | 563 | /* |
| 600 | * The following ioctl will fail if stdin is not a tty, but also when | 564 | * The following ioctl will fail if stdin is not a tty, but also when |
| @@ -649,17 +613,17 @@ static void open_tty(char *tty, struct termio *tp, int local) | |||
| 649 | } | 613 | } |
| 650 | } | 614 | } |
| 651 | #else | 615 | #else |
| 652 | (void) chown(tty, 0, 0); /* root, sys */ | 616 | (void) chown(tty, 0, 0); /* root, sys */ |
| 653 | (void) chmod(tty, 0622); /* crw--w--w- */ | 617 | (void) chmod(tty, 0622); /* crw--w--w- */ |
| 654 | errno = 0; /* ignore above errors */ | ||
| 655 | #endif | 618 | #endif |
| 619 | if(chdir_to_root && chdir("/")) | ||
| 620 | error("chdir to / failed: %m"); | ||
| 656 | } | 621 | } |
| 657 | 622 | ||
| 658 | /* termio_init - initialize termio settings */ | 623 | /* termio_init - initialize termio settings */ |
| 659 | 624 | ||
| 660 | static void termio_init(struct termio *tp, int speed, struct options *op) | 625 | static void termio_init(struct termio *tp, int speed, struct options *op) |
| 661 | { | 626 | { |
| 662 | |||
| 663 | /* | 627 | /* |
| 664 | * Initial termio settings: 8-bit characters, raw-mode, blocking i/o. | 628 | * Initial termio settings: 8-bit characters, raw-mode, blocking i/o. |
| 665 | * Special characters are set after we have read the login name; all | 629 | * Special characters are set after we have read the login name; all |
| @@ -682,7 +646,7 @@ static void termio_init(struct termio *tp, int speed, struct options *op) | |||
| 682 | 646 | ||
| 683 | /* Optionally enable hardware flow control */ | 647 | /* Optionally enable hardware flow control */ |
| 684 | 648 | ||
| 685 | #ifdef CRTSCTS | 649 | #ifdef CRTSCTS |
| 686 | if (op->flags & F_RTSCTS) | 650 | if (op->flags & F_RTSCTS) |
| 687 | tp->c_cflag |= CRTSCTS; | 651 | tp->c_cflag |= CRTSCTS; |
| 688 | #endif | 652 | #endif |
| @@ -726,9 +690,9 @@ static void auto_baud(struct termio *tp) | |||
| 726 | */ | 690 | */ |
| 727 | 691 | ||
| 728 | iflag = tp->c_iflag; | 692 | iflag = tp->c_iflag; |
| 729 | tp->c_iflag |= ISTRIP; /* enable 8th-bit stripping */ | 693 | tp->c_iflag |= ISTRIP; /* enable 8th-bit stripping */ |
| 730 | vmin = tp->c_cc[VMIN]; | 694 | vmin = tp->c_cc[VMIN]; |
| 731 | tp->c_cc[VMIN] = 0; /* don't block if queue empty */ | 695 | tp->c_cc[VMIN] = 0; /* don't block if queue empty */ |
| 732 | (void) ioctl(0, TCSETA, tp); | 696 | (void) ioctl(0, TCSETA, tp); |
| 733 | 697 | ||
| 734 | /* | 698 | /* |
| @@ -759,7 +723,7 @@ static void auto_baud(struct termio *tp) | |||
| 759 | /* do_prompt - show login prompt, optionally preceded by /etc/issue contents */ | 723 | /* do_prompt - show login prompt, optionally preceded by /etc/issue contents */ |
| 760 | static void do_prompt(struct options *op, struct termio *tp) | 724 | static void do_prompt(struct options *op, struct termio *tp) |
| 761 | { | 725 | { |
| 762 | #ifdef ISSUE /* optional: show /etc/issue */ | 726 | #ifdef ISSUE /* optional: show /etc/issue */ |
| 763 | print_login_issue(op->issue, op->tty); | 727 | print_login_issue(op->issue, op->tty); |
| 764 | #endif | 728 | #endif |
| 765 | print_login_prompt(); | 729 | print_login_prompt(); |
| @@ -768,7 +732,7 @@ static void do_prompt(struct options *op, struct termio *tp) | |||
| 768 | /* next_speed - select next baud rate */ | 732 | /* next_speed - select next baud rate */ |
| 769 | static void next_speed(struct termio *tp, struct options *op) | 733 | static void next_speed(struct termio *tp, struct options *op) |
| 770 | { | 734 | { |
| 771 | static int baud_index = FIRST_SPEED; /* current speed index */ | 735 | static int baud_index = FIRST_SPEED; /* current speed index */ |
| 772 | 736 | ||
| 773 | baud_index = (baud_index + 1) % op->numspeed; | 737 | baud_index = (baud_index + 1) % op->numspeed; |
| 774 | tp->c_cflag &= ~CBAUD; | 738 | tp->c_cflag &= ~CBAUD; |
| @@ -782,15 +746,15 @@ static char *get_logname(struct options *op, struct chardata *cp, struct termio | |||
| 782 | { | 746 | { |
| 783 | static char logname[BUFSIZ]; | 747 | static char logname[BUFSIZ]; |
| 784 | char *bp; | 748 | char *bp; |
| 785 | char c; /* input character, full eight bits */ | 749 | char c; /* input character, full eight bits */ |
| 786 | char ascval; /* low 7 bits of input character */ | 750 | char ascval; /* low 7 bits of input character */ |
| 787 | int bits; /* # of "1" bits per character */ | 751 | int bits; /* # of "1" bits per character */ |
| 788 | int mask; /* mask with 1 bit up */ | 752 | int mask; /* mask with 1 bit up */ |
| 789 | static char *erase[] = { /* backspace-space-backspace */ | 753 | static char *erase[] = { /* backspace-space-backspace */ |
| 790 | "\010\040\010", /* space parity */ | 754 | "\010\040\010", /* space parity */ |
| 791 | "\010\040\010", /* odd parity */ | 755 | "\010\040\010", /* odd parity */ |
| 792 | "\210\240\210", /* even parity */ | 756 | "\210\240\210", /* even parity */ |
| 793 | "\210\240\210", /* no parity */ | 757 | "\210\240\210", /* no parity */ |
| 794 | }; | 758 | }; |
| 795 | 759 | ||
| 796 | /* Initialize kill, erase, parity etc. (also after switching speeds). */ | 760 | /* Initialize kill, erase, parity etc. (also after switching speeds). */ |
| @@ -829,10 +793,10 @@ static char *get_logname(struct options *op, struct chardata *cp, struct termio | |||
| 829 | 793 | ||
| 830 | /* Do parity bit handling. */ | 794 | /* Do parity bit handling. */ |
| 831 | 795 | ||
| 832 | if (c != (ascval = (c & 0177))) { /* "parity" bit on ? */ | 796 | if (c != (ascval = (c & 0177))) { /* "parity" bit on ? */ |
| 833 | for (bits = 1, mask = 1; mask & 0177; mask <<= 1) | 797 | for (bits = 1, mask = 1; mask & 0177; mask <<= 1) |
| 834 | if (mask & ascval) | 798 | if (mask & ascval) |
| 835 | bits++; /* count "1" bits */ | 799 | bits++; /* count "1" bits */ |
| 836 | cp->parity |= ((bits & 1) ? 1 : 2); | 800 | cp->parity |= ((bits & 1) ? 1 : 2); |
| 837 | } | 801 | } |
| 838 | /* Do erase, kill and end-of-line processing. */ | 802 | /* Do erase, kill and end-of-line processing. */ |
| @@ -840,13 +804,13 @@ static char *get_logname(struct options *op, struct chardata *cp, struct termio | |||
| 840 | switch (ascval) { | 804 | switch (ascval) { |
| 841 | case CR: | 805 | case CR: |
| 842 | case NL: | 806 | case NL: |
| 843 | *bp = 0; /* terminate logname */ | 807 | *bp = 0; /* terminate logname */ |
| 844 | cp->eol = ascval; /* set end-of-line char */ | 808 | cp->eol = ascval; /* set end-of-line char */ |
| 845 | break; | 809 | break; |
| 846 | case BS: | 810 | case BS: |
| 847 | case DEL: | 811 | case DEL: |
| 848 | case '#': | 812 | case '#': |
| 849 | cp->erase = ascval; /* set erase character */ | 813 | cp->erase = ascval; /* set erase character */ |
| 850 | if (bp > logname) { | 814 | if (bp > logname) { |
| 851 | (void) write(1, erase[cp->parity], 3); | 815 | (void) write(1, erase[cp->parity], 3); |
| 852 | bp--; | 816 | bp--; |
| @@ -854,7 +818,7 @@ static char *get_logname(struct options *op, struct chardata *cp, struct termio | |||
| 854 | break; | 818 | break; |
| 855 | case CTL('U'): | 819 | case CTL('U'): |
| 856 | case '@': | 820 | case '@': |
| 857 | cp->kill = ascval; /* set kill character */ | 821 | cp->kill = ascval; /* set kill character */ |
| 858 | while (bp > logname) { | 822 | while (bp > logname) { |
| 859 | (void) write(1, erase[cp->parity], 3); | 823 | (void) write(1, erase[cp->parity], 3); |
| 860 | bp--; | 824 | bp--; |
| @@ -868,8 +832,8 @@ static char *get_logname(struct options *op, struct chardata *cp, struct termio | |||
| 868 | } else if (bp - logname >= sizeof(logname) - 1) { | 832 | } else if (bp - logname >= sizeof(logname) - 1) { |
| 869 | error("%s: input overrun", op->tty); | 833 | error("%s: input overrun", op->tty); |
| 870 | } else { | 834 | } else { |
| 871 | (void) write(1, &c, 1); /* echo the character */ | 835 | (void) write(1, &c, 1); /* echo the character */ |
| 872 | *bp++ = ascval; /* and store it */ | 836 | *bp++ = ascval; /* and store it */ |
| 873 | } | 837 | } |
| 874 | break; | 838 | break; |
| 875 | } | 839 | } |
| @@ -880,7 +844,7 @@ static char *get_logname(struct options *op, struct chardata *cp, struct termio | |||
| 880 | if ((cp->capslock = caps_lock(logname))) { | 844 | if ((cp->capslock = caps_lock(logname))) { |
| 881 | for (bp = logname; *bp; bp++) | 845 | for (bp = logname; *bp; bp++) |
| 882 | if (isupper(*bp)) | 846 | if (isupper(*bp)) |
| 883 | *bp = tolower(*bp); /* map name to lower case */ | 847 | *bp = tolower(*bp); /* map name to lower case */ |
| 884 | } | 848 | } |
| 885 | return (logname); | 849 | return (logname); |
| 886 | } | 850 | } |
| @@ -890,39 +854,39 @@ static void termio_final(struct options *op, struct termio *tp, struct chardata | |||
| 890 | { | 854 | { |
| 891 | /* General terminal-independent stuff. */ | 855 | /* General terminal-independent stuff. */ |
| 892 | 856 | ||
| 893 | tp->c_iflag |= IXON | IXOFF; /* 2-way flow control */ | 857 | tp->c_iflag |= IXON | IXOFF; /* 2-way flow control */ |
| 894 | tp->c_lflag |= ICANON | ISIG | ECHO | ECHOE | ECHOK | ECHOKE; | 858 | tp->c_lflag |= ICANON | ISIG | ECHO | ECHOE | ECHOK | ECHOKE; |
| 895 | /* no longer| ECHOCTL | ECHOPRT */ | 859 | /* no longer| ECHOCTL | ECHOPRT */ |
| 896 | tp->c_oflag |= OPOST; | 860 | tp->c_oflag |= OPOST; |
| 897 | /* tp->c_cflag = 0; */ | 861 | /* tp->c_cflag = 0; */ |
| 898 | tp->c_cc[VINTR] = DEF_INTR; /* default interrupt */ | 862 | tp->c_cc[VINTR] = DEF_INTR; /* default interrupt */ |
| 899 | tp->c_cc[VQUIT] = DEF_QUIT; /* default quit */ | 863 | tp->c_cc[VQUIT] = DEF_QUIT; /* default quit */ |
| 900 | tp->c_cc[VEOF] = DEF_EOF; /* default EOF character */ | 864 | tp->c_cc[VEOF] = DEF_EOF; /* default EOF character */ |
| 901 | tp->c_cc[VEOL] = DEF_EOL; | 865 | tp->c_cc[VEOL] = DEF_EOL; |
| 902 | tp->c_cc[VSWTC] = DEF_SWITCH; /* default switch character */ | 866 | tp->c_cc[VSWTC] = DEF_SWITCH; /* default switch character */ |
| 903 | 867 | ||
| 904 | /* Account for special characters seen in input. */ | 868 | /* Account for special characters seen in input. */ |
| 905 | 869 | ||
| 906 | if (cp->eol == CR) { | 870 | if (cp->eol == CR) { |
| 907 | tp->c_iflag |= ICRNL; /* map CR in input to NL */ | 871 | tp->c_iflag |= ICRNL; /* map CR in input to NL */ |
| 908 | tp->c_oflag |= ONLCR; /* map NL in output to CR-NL */ | 872 | tp->c_oflag |= ONLCR; /* map NL in output to CR-NL */ |
| 909 | } | 873 | } |
| 910 | tp->c_cc[VERASE] = cp->erase; /* set erase character */ | 874 | tp->c_cc[VERASE] = cp->erase; /* set erase character */ |
| 911 | tp->c_cc[VKILL] = cp->kill; /* set kill character */ | 875 | tp->c_cc[VKILL] = cp->kill; /* set kill character */ |
| 912 | 876 | ||
| 913 | /* Account for the presence or absence of parity bits in input. */ | 877 | /* Account for the presence or absence of parity bits in input. */ |
| 914 | 878 | ||
| 915 | switch (cp->parity) { | 879 | switch (cp->parity) { |
| 916 | case 0: /* space (always 0) parity */ | 880 | case 0: /* space (always 0) parity */ |
| 917 | break; | 881 | break; |
| 918 | case 1: /* odd parity */ | 882 | case 1: /* odd parity */ |
| 919 | tp->c_cflag |= PARODD; | 883 | tp->c_cflag |= PARODD; |
| 920 | /* FALLTHROUGH */ | 884 | /* FALLTHROUGH */ |
| 921 | case 2: /* even parity */ | 885 | case 2: /* even parity */ |
| 922 | tp->c_cflag |= PARENB; | 886 | tp->c_cflag |= PARENB; |
| 923 | tp->c_iflag |= INPCK | ISTRIP; | 887 | tp->c_iflag |= INPCK | ISTRIP; |
| 924 | /* FALLTHROUGH */ | 888 | /* FALLTHROUGH */ |
| 925 | case (1 | 2): /* no parity bit */ | 889 | case (1 | 2): /* no parity bit */ |
| 926 | tp->c_cflag &= ~CSIZE; | 890 | tp->c_cflag &= ~CSIZE; |
| 927 | tp->c_cflag |= CS7; | 891 | tp->c_cflag |= CS7; |
| 928 | break; | 892 | break; |
| @@ -936,7 +900,7 @@ static void termio_final(struct options *op, struct termio *tp, struct chardata | |||
| 936 | } | 900 | } |
| 937 | /* Optionally enable hardware flow control */ | 901 | /* Optionally enable hardware flow control */ |
| 938 | 902 | ||
| 939 | #ifdef CRTSCTS | 903 | #ifdef CRTSCTS |
| 940 | if (op->flags & F_RTSCTS) | 904 | if (op->flags & F_RTSCTS) |
| 941 | tp->c_cflag |= CRTSCTS; | 905 | tp->c_cflag |= CRTSCTS; |
| 942 | #endif | 906 | #endif |
| @@ -963,11 +927,11 @@ static int caps_lock(const char *s) | |||
| 963 | } | 927 | } |
| 964 | 928 | ||
| 965 | /* bcode - convert speed string to speed code; return 0 on failure */ | 929 | /* bcode - convert speed string to speed code; return 0 on failure */ |
| 966 | static int bcode(char *s) | 930 | static int bcode(const char *s) |
| 967 | { | 931 | { |
| 968 | int r; | 932 | int r; |
| 969 | unsigned long value; | 933 | unsigned long value; |
| 970 | if (safe_strtoul(s, &value)) { | 934 | if (safe_strtoul((char *)s, &value)) { |
| 971 | return -1; | 935 | return -1; |
| 972 | } | 936 | } |
| 973 | if ((r = bb_value_to_baud(value)) > 0) { | 937 | if ((r = bb_value_to_baud(value)) > 0) { |
| @@ -976,49 +940,44 @@ static int bcode(char *s) | |||
| 976 | return 0; | 940 | return 0; |
| 977 | } | 941 | } |
| 978 | 942 | ||
| 979 | /* error - report errors to console or syslog; only understands %s and %m */ | ||
| 980 | |||
| 981 | #define str2cpy(b,s1,s2) strcat(strcpy(b,s1),s2) | ||
| 982 | |||
| 983 | /* | 943 | /* |
| 984 | * output error messages | 944 | * output error messages |
| 985 | */ | 945 | */ |
| 986 | static void error(const char *fmt, ...) | 946 | static void error(const char *fmt, ...) |
| 987 | { | 947 | { |
| 988 | va_list va_alist; | 948 | va_list va_alist; |
| 989 | char buf[256], *bp; | 949 | char buf[256]; |
| 990 | |||
| 991 | #ifndef USE_SYSLOG | ||
| 992 | int fd; | ||
| 993 | #endif | ||
| 994 | |||
| 995 | #ifdef USE_SYSLOG | ||
| 996 | buf[0] = '\0'; | ||
| 997 | bp = buf; | ||
| 998 | #else | ||
| 999 | strncpy(buf, bb_applet_name, 256); | ||
| 1000 | strncat(buf, ": ", 256); | ||
| 1001 | buf[255] = 0; | ||
| 1002 | bp = buf + strlen(buf); | ||
| 1003 | #endif | ||
| 1004 | 950 | ||
| 951 | #ifdef CONFIG_SYSLOGD | ||
| 1005 | va_start(va_alist, fmt); | 952 | va_start(va_alist, fmt); |
| 1006 | vsnprintf(bp, 256 - strlen(buf), fmt, va_alist); | 953 | vsnprintf(buf, sizeof(buf), fmt, va_alist); |
| 1007 | buf[255] = 0; | ||
| 1008 | va_end(va_alist); | ||
| 1009 | |||
| 1010 | #ifdef USE_SYSLOG | ||
| 1011 | openlog(bb_applet_name, 0, LOG_AUTH); | 954 | openlog(bb_applet_name, 0, LOG_AUTH); |
| 1012 | syslog(LOG_ERR, "%s", buf); | 955 | syslog(LOG_ERR, "%s", buf); |
| 1013 | closelog(); | 956 | closelog(); |
| 1014 | #else | 957 | #else |
| 1015 | strncat(bp, "\r\n", 256 - strlen(buf)); | 958 | int fd; |
| 1016 | buf[255] = 0; | 959 | size_t l; |
| 960 | |||
| 961 | snprintf(buf, sizeof(buf), "%s: ", bb_applet_name); | ||
| 962 | l = strlen(buf); | ||
| 963 | va_start(va_alist, fmt); | ||
| 964 | vsnprintf(buf + l, sizeof(buf) - l, fmt, va_alist); | ||
| 965 | l = strlen(buf); | ||
| 966 | /* truncate if need */ | ||
| 967 | if((l + 3) > sizeof(buf)) | ||
| 968 | l = sizeof(buf) - 3; | ||
| 969 | /* add \r\n always */ | ||
| 970 | buf[l++] = '\r'; | ||
| 971 | buf[l++] = '\n'; | ||
| 972 | buf[l] = 0; | ||
| 1017 | if ((fd = open("/dev/console", 1)) >= 0) { | 973 | if ((fd = open("/dev/console", 1)) >= 0) { |
| 1018 | write(fd, buf, strlen(buf)); | 974 | write(fd, buf, l); |
| 1019 | close(fd); | 975 | close(fd); |
| 1020 | } | 976 | } |
| 1021 | #endif | 977 | #endif |
| 1022 | (void) sleep((unsigned) 10); /* be kind to init(8) */ | 978 | |
| 979 | va_end(va_alist); | ||
| 980 | |||
| 981 | (void) sleep((unsigned) 10); /* be kind to init(8) */ | ||
| 1023 | exit(1); | 982 | exit(1); |
| 1024 | } | 983 | } |
