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 | } |