diff options
author | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2006-06-16 16:37:07 +0000 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2006-06-16 16:37:07 +0000 |
commit | 6d82f94681618d50411bb7e4e30e40a0f0046d4c (patch) | |
tree | a80ec19f3b5f9338998ec904a06f4f369d33a186 | |
parent | d9a761d9c3ed1ec9143b2327a5212574d115e29f (diff) | |
download | busybox-w32-6d82f94681618d50411bb7e4e30e40a0f0046d4c.tar.gz busybox-w32-6d82f94681618d50411bb7e4e30e40a0f0046d4c.tar.bz2 busybox-w32-6d82f94681618d50411bb7e4e30e40a0f0046d4c.zip |
- do away with the fwd-decls of functions. Should not contain any code changes
AFAICT.
-rw-r--r-- | loginutils/getty.c | 527 |
1 files changed, 260 insertions, 267 deletions
diff --git a/loginutils/getty.c b/loginutils/getty.c index 43a82df66..11eb5a050 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c | |||
@@ -212,20 +212,6 @@ static struct Speedtab speedtab[] = { | |||
212 | }; | 212 | }; |
213 | #endif | 213 | #endif |
214 | 214 | ||
215 | static void parse_args(int argc, char **argv, struct options *op); | ||
216 | static void parse_speeds(struct options *op, char *arg); | ||
217 | static void open_tty(char *tty, struct termio *tp, int local); | ||
218 | static void termio_init(struct termio *tp, int speed, struct options *op); | ||
219 | static void auto_baud(struct termio *tp); | ||
220 | static void do_prompt(struct options *op, struct termio *tp); | ||
221 | static void next_speed(struct termio *tp, struct options *op); | ||
222 | static char *get_logname(struct options *op, struct chardata *cp, | ||
223 | struct termio *tp); | ||
224 | static void termio_final(struct options *op, struct termio *tp, | ||
225 | struct chardata *cp); | ||
226 | static int caps_lock(const char *s); | ||
227 | static int bcode(const char *s); | ||
228 | static void error(const char *fmt, ...) ATTRIBUTE_NORETURN; | ||
229 | 215 | ||
230 | #ifdef SYSV_STYLE | 216 | #ifdef SYSV_STYLE |
231 | #ifdef CONFIG_FEATURE_UTMP | 217 | #ifdef CONFIG_FEATURE_UTMP |
@@ -247,136 +233,84 @@ FILE *dbf; | |||
247 | #define debug(s) /* nothing */ | 233 | #define debug(s) /* nothing */ |
248 | #endif | 234 | #endif |
249 | 235 | ||
250 | int getty_main(int argc, char **argv) | ||
251 | { | ||
252 | char *logname = NULL; /* login name, given to /bin/login */ | ||
253 | struct chardata chardata; /* set by get_logname() */ | ||
254 | struct termio termio; /* terminal mode bits */ | ||
255 | static struct options options = { | ||
256 | 0, /* show /etc/issue (SYSV_STYLE) */ | ||
257 | 0, /* no timeout */ | ||
258 | _PATH_LOGIN, /* default login program */ | ||
259 | "tty1", /* default tty line */ | ||
260 | "", /* modem init string */ | ||
261 | #ifdef ISSUE | ||
262 | ISSUE, /* default issue file */ | ||
263 | #else | ||
264 | NULL, | ||
265 | #endif | ||
266 | 0, /* no baud rates known yet */ | ||
267 | }; | ||
268 | 236 | ||
269 | #ifdef DEBUGGING | 237 | /* |
270 | dbf = bb_xfopen(DEBUGTERM, "w"); | 238 | * output error messages |
239 | */ | ||
240 | static void error(const char *fmt, ...) ATTRIBUTE_NORETURN; | ||
241 | static void error(const char *fmt, ...) | ||
242 | { | ||
243 | va_list va_alist; | ||
244 | char buf[256]; | ||
271 | 245 | ||
272 | { | 246 | #ifdef CONFIG_SYSLOGD |
273 | int i; | 247 | va_start(va_alist, fmt); |
248 | vsnprintf(buf, sizeof(buf), fmt, va_alist); | ||
249 | openlog(bb_applet_name, 0, LOG_AUTH); | ||
250 | syslog(LOG_ERR, "%s", buf); | ||
251 | closelog(); | ||
252 | #else | ||
253 | int fd; | ||
254 | size_t l; | ||
274 | 255 | ||
275 | for (i = 1; i < argc; i++) { | 256 | snprintf(buf, sizeof(buf), "%s: ", bb_applet_name); |
276 | debug(argv[i]); | 257 | l = strlen(buf); |
277 | debug("\n"); | 258 | va_start(va_alist, fmt); |
278 | } | 259 | vsnprintf(buf + l, sizeof(buf) - l, fmt, va_alist); |
260 | l = strlen(buf); | ||
261 | /* truncate if need */ | ||
262 | if((l + 3) > sizeof(buf)) | ||
263 | l = sizeof(buf) - 3; | ||
264 | /* add \r\n always */ | ||
265 | buf[l++] = '\r'; | ||
266 | buf[l++] = '\n'; | ||
267 | buf[l] = 0; | ||
268 | if ((fd = open("/dev/console", 1)) >= 0) { | ||
269 | write(fd, buf, l); | ||
270 | close(fd); | ||
279 | } | 271 | } |
280 | #endif | 272 | #endif |
281 | 273 | ||
282 | /* Parse command-line arguments. */ | 274 | va_end(va_alist); |
283 | |||
284 | parse_args(argc, argv, &options); | ||
285 | |||
286 | #ifdef __linux__ | ||
287 | setsid(); | ||
288 | #endif | ||
289 | |||
290 | /* Update the utmp file. */ | ||
291 | |||
292 | |||
293 | #ifdef SYSV_STYLE | ||
294 | #ifdef CONFIG_FEATURE_UTMP | ||
295 | update_utmp(options.tty); | ||
296 | #endif | ||
297 | #endif | ||
298 | 275 | ||
299 | debug("calling open_tty\n"); | 276 | (void) sleep((unsigned) 10); /* be kind to init(8) */ |
300 | /* Open the tty as standard { input, output, error }. */ | 277 | exit(1); |
301 | open_tty(options.tty, &termio, options.flags & F_LOCAL); | 278 | } |
302 | 279 | ||
303 | #ifdef __linux__ | ||
304 | { | ||
305 | int iv; | ||
306 | 280 | ||
307 | iv = getpid(); | ||
308 | ioctl(0, TIOCSPGRP, &iv); | ||
309 | } | ||
310 | #endif | ||
311 | /* Initialize the termio settings (raw mode, eight-bit, blocking i/o). */ | ||
312 | debug("calling termio_init\n"); | ||
313 | termio_init(&termio, options.speeds[FIRST_SPEED], &options); | ||
314 | 281 | ||
315 | /* write the modem init string and DON'T flush the buffers */ | 282 | /* bcode - convert speed string to speed code; return 0 on failure */ |
316 | if (options.flags & F_INITSTRING) { | 283 | static int bcode(const char *s) |
317 | debug("writing init string\n"); | 284 | { |
318 | write(1, options.initstring, strlen(options.initstring)); | 285 | int r; |
286 | unsigned long value; | ||
287 | if (safe_strtoul((char *)s, &value)) { | ||
288 | return -1; | ||
319 | } | 289 | } |
320 | 290 | if ((r = bb_value_to_baud(value)) > 0) { | |
321 | if (!(options.flags & F_LOCAL)) { | 291 | return r; |
322 | /* go to blocking write mode unless -L is specified */ | ||
323 | fcntl(1, F_SETFL, fcntl(1, F_GETFL, 0) & ~O_NONBLOCK); | ||
324 | } | 292 | } |
293 | return 0; | ||
294 | } | ||
325 | 295 | ||
326 | /* Optionally detect the baud rate from the modem status message. */ | ||
327 | debug("before autobaud\n"); | ||
328 | if (options.flags & F_PARSE) | ||
329 | auto_baud(&termio); | ||
330 | |||
331 | /* Set the optional timer. */ | ||
332 | if (options.timeout) | ||
333 | (void) alarm((unsigned) options.timeout); | ||
334 | |||
335 | /* optionally wait for CR or LF before writing /etc/issue */ | ||
336 | if (options.flags & F_WAITCRLF) { | ||
337 | char ch; | ||
338 | 296 | ||
339 | debug("waiting for cr-lf\n"); | 297 | /* parse_speeds - parse alternate baud rates */ |
340 | while (read(0, &ch, 1) == 1) { | 298 | static void parse_speeds(struct options *op, char *arg) |
341 | ch &= 0x7f; /* strip "parity bit" */ | 299 | { |
342 | #ifdef DEBUGGING | 300 | char *cp; |
343 | fprintf(dbf, "read %c\n", ch); | ||
344 | #endif | ||
345 | if (ch == '\n' || ch == '\r') | ||
346 | break; | ||
347 | } | ||
348 | } | ||
349 | 301 | ||
350 | chardata = init_chardata; | 302 | debug("entered parse_speeds\n"); |
351 | if (!(options.flags & F_NOPROMPT)) { | 303 | for (cp = strtok(arg, ","); cp != 0; cp = strtok((char *) 0, ",")) { |
352 | /* Read the login name. */ | 304 | if ((op->speeds[op->numspeed++] = bcode(cp)) <= 0) |
353 | debug("reading login name\n"); | 305 | error("bad speed: %s", cp); |
354 | /* while ((logname = get_logname(&options, &chardata, &termio)) == 0) */ | 306 | if (op->numspeed > MAX_SPEED) |
355 | while ((logname = get_logname(&options, &chardata, &termio)) == | 307 | error("too many alternate speeds"); |
356 | NULL) next_speed(&termio, &options); | ||
357 | } | 308 | } |
358 | 309 | debug("exiting parsespeeds\n"); | |
359 | /* Disable timer. */ | ||
360 | |||
361 | if (options.timeout) | ||
362 | (void) alarm(0); | ||
363 | |||
364 | /* Finalize the termio settings. */ | ||
365 | |||
366 | termio_final(&options, &termio, &chardata); | ||
367 | |||
368 | /* Now the newline character should be properly written. */ | ||
369 | |||
370 | (void) write(1, "\n", 1); | ||
371 | |||
372 | /* Let the login program take care of password validation. */ | ||
373 | |||
374 | (void) execl(options.login, options.login, "--", logname, (char *) 0); | ||
375 | error("%s: can't exec %s: %m", options.tty, options.login); | ||
376 | } | 310 | } |
377 | 311 | ||
378 | /* parse-args - parse command-line arguments */ | ||
379 | 312 | ||
313 | /* parse-args - parse command-line arguments */ | ||
380 | static void parse_args(int argc, char **argv, struct options *op) | 314 | static void parse_args(int argc, char **argv, struct options *op) |
381 | { | 315 | { |
382 | char *ts; | 316 | char *ts; |
@@ -427,84 +361,6 @@ static void parse_args(int argc, char **argv, struct options *op) | |||
427 | debug("exiting parseargs\n"); | 361 | debug("exiting parseargs\n"); |
428 | } | 362 | } |
429 | 363 | ||
430 | /* parse_speeds - parse alternate baud rates */ | ||
431 | |||
432 | static void parse_speeds(struct options *op, char *arg) | ||
433 | { | ||
434 | char *cp; | ||
435 | |||
436 | debug("entered parse_speeds\n"); | ||
437 | for (cp = strtok(arg, ","); cp != 0; cp = strtok((char *) 0, ",")) { | ||
438 | if ((op->speeds[op->numspeed++] = bcode(cp)) <= 0) | ||
439 | error("bad speed: %s", cp); | ||
440 | if (op->numspeed > MAX_SPEED) | ||
441 | error("too many alternate speeds"); | ||
442 | } | ||
443 | debug("exiting parsespeeds\n"); | ||
444 | } | ||
445 | |||
446 | #ifdef SYSV_STYLE | ||
447 | #ifdef CONFIG_FEATURE_UTMP | ||
448 | |||
449 | /* update_utmp - update our utmp entry */ | ||
450 | static void update_utmp(char *line) | ||
451 | { | ||
452 | struct utmp ut; | ||
453 | struct utmp *utp; | ||
454 | time_t t; | ||
455 | int mypid = getpid(); | ||
456 | #if ! (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)) | ||
457 | struct flock lock; | ||
458 | #endif | ||
459 | |||
460 | /* | ||
461 | * The utmp file holds miscellaneous information about things started by | ||
462 | * /sbin/init and other system-related events. Our purpose is to update | ||
463 | * the utmp entry for the current process, in particular the process type | ||
464 | * and the tty line we are listening to. Return successfully only if the | ||
465 | * utmp file can be opened for update, and if we are able to find our | ||
466 | * entry in the utmp file. | ||
467 | */ | ||
468 | if (access(_PATH_UTMP, R_OK|W_OK) == -1) { | ||
469 | close(creat(_PATH_UTMP, 0664)); | ||
470 | } | ||
471 | utmpname(_PATH_UTMP); | ||
472 | setutent(); | ||
473 | while ((utp = getutent()) | ||
474 | && !(utp->ut_type == INIT_PROCESS && utp->ut_pid == mypid)) /* nothing */ | ||
475 | ; | ||
476 | |||
477 | if (utp) { | ||
478 | memcpy(&ut, utp, sizeof(ut)); | ||
479 | } else { | ||
480 | /* some inits don't initialize utmp... */ | ||
481 | memset(&ut, 0, sizeof(ut)); | ||
482 | strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id)); | ||
483 | } | ||
484 | /*endutent(); */ | ||
485 | |||
486 | strncpy(ut.ut_user, "LOGIN", sizeof(ut.ut_user)); | ||
487 | strncpy(ut.ut_line, line, sizeof(ut.ut_line)); | ||
488 | if (fakehost) | ||
489 | strncpy(ut.ut_host, fakehost, sizeof(ut.ut_host)); | ||
490 | time(&t); | ||
491 | ut.ut_time = t; | ||
492 | ut.ut_type = LOGIN_PROCESS; | ||
493 | ut.ut_pid = mypid; | ||
494 | |||
495 | pututline(&ut); | ||
496 | endutent(); | ||
497 | |||
498 | #ifdef CONFIG_FEATURE_WTMP | ||
499 | if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) | ||
500 | close(creat(bb_path_wtmp_file, 0664)); | ||
501 | updwtmp(bb_path_wtmp_file, &ut); | ||
502 | #endif | ||
503 | } | ||
504 | |||
505 | #endif /* CONFIG_FEATURE_UTMP */ | ||
506 | #endif /* SYSV_STYLE */ | ||
507 | |||
508 | /* open_tty - set up tty as standard { input, output, error } */ | 364 | /* open_tty - set up tty as standard { input, output, error } */ |
509 | static void open_tty(char *tty, struct termio *tp, int local) | 365 | static void open_tty(char *tty, struct termio *tp, int local) |
510 | { | 366 | { |
@@ -611,7 +467,6 @@ static void open_tty(char *tty, struct termio *tp, int local) | |||
611 | } | 467 | } |
612 | 468 | ||
613 | /* termio_init - initialize termio settings */ | 469 | /* termio_init - initialize termio settings */ |
614 | |||
615 | static void termio_init(struct termio *tp, int speed, struct options *op) | 470 | static void termio_init(struct termio *tp, int speed, struct options *op) |
616 | { | 471 | { |
617 | /* | 472 | /* |
@@ -710,6 +565,18 @@ static void auto_baud(struct termio *tp) | |||
710 | (void) ioctl(0, TCSETA, tp); | 565 | (void) ioctl(0, TCSETA, tp); |
711 | } | 566 | } |
712 | 567 | ||
568 | /* next_speed - select next baud rate */ | ||
569 | static void next_speed(struct termio *tp, struct options *op) | ||
570 | { | ||
571 | static int baud_index = FIRST_SPEED; /* current speed index */ | ||
572 | |||
573 | baud_index = (baud_index + 1) % op->numspeed; | ||
574 | tp->c_cflag &= ~CBAUD; | ||
575 | tp->c_cflag |= op->speeds[baud_index]; | ||
576 | (void) ioctl(0, TCSETA, tp); | ||
577 | } | ||
578 | |||
579 | |||
713 | /* do_prompt - show login prompt, optionally preceded by /etc/issue contents */ | 580 | /* do_prompt - show login prompt, optionally preceded by /etc/issue contents */ |
714 | static void do_prompt(struct options *op, struct termio *tp) | 581 | static void do_prompt(struct options *op, struct termio *tp) |
715 | { | 582 | { |
@@ -719,22 +586,26 @@ static void do_prompt(struct options *op, struct termio *tp) | |||
719 | print_login_prompt(); | 586 | print_login_prompt(); |
720 | } | 587 | } |
721 | 588 | ||
722 | /* next_speed - select next baud rate */ | 589 | /* caps_lock - string contains upper case without lower case */ |
723 | static void next_speed(struct termio *tp, struct options *op) | 590 | /* returns 1 if true, 0 if false */ |
591 | static int caps_lock(const char *s) | ||
724 | { | 592 | { |
725 | static int baud_index = FIRST_SPEED; /* current speed index */ | 593 | int capslock; |
726 | 594 | ||
727 | baud_index = (baud_index + 1) % op->numspeed; | 595 | for (capslock = 0; *s; s++) { |
728 | tp->c_cflag &= ~CBAUD; | 596 | if (islower(*s)) |
729 | tp->c_cflag |= op->speeds[baud_index]; | 597 | return (0); |
730 | (void) ioctl(0, TCSETA, tp); | 598 | if (capslock == 0) |
599 | capslock = isupper(*s); | ||
600 | } | ||
601 | return (capslock); | ||
731 | } | 602 | } |
732 | 603 | ||
604 | #define logname bb_common_bufsiz1 | ||
733 | /* get_logname - get user name, establish parity, speed, erase, kill, eol */ | 605 | /* get_logname - get user name, establish parity, speed, erase, kill, eol */ |
734 | /* return NULL on failure, logname on success */ | 606 | /* return NULL on failure, logname on success */ |
735 | static char *get_logname(struct options *op, struct chardata *cp, struct termio *tp) | 607 | static char *get_logname(struct options *op, struct chardata *cp, struct termio *tp) |
736 | { | 608 | { |
737 | #define logname bb_common_bufsiz1 | ||
738 | char *bp; | 609 | char *bp; |
739 | char c; /* input character, full eight bits */ | 610 | char c; /* input character, full eight bits */ |
740 | char ascval; /* low 7 bits of input character */ | 611 | char ascval; /* low 7 bits of input character */ |
@@ -901,73 +772,195 @@ static void termio_final(struct options *op, struct termio *tp, struct chardata | |||
901 | error("%s: ioctl: TCSETA: %m", op->tty); | 772 | error("%s: ioctl: TCSETA: %m", op->tty); |
902 | } | 773 | } |
903 | 774 | ||
904 | /* caps_lock - string contains upper case without lower case */ | 775 | |
905 | /* returns 1 if true, 0 if false */ | 776 | #ifdef SYSV_STYLE |
906 | static int caps_lock(const char *s) | 777 | #ifdef CONFIG_FEATURE_UTMP |
778 | /* update_utmp - update our utmp entry */ | ||
779 | static void update_utmp(char *line) | ||
907 | { | 780 | { |
908 | int capslock; | 781 | struct utmp ut; |
782 | struct utmp *utp; | ||
783 | time_t t; | ||
784 | int mypid = getpid(); | ||
785 | #if ! (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)) | ||
786 | struct flock lock; | ||
787 | #endif | ||
909 | 788 | ||
910 | for (capslock = 0; *s; s++) { | 789 | /* |
911 | if (islower(*s)) | 790 | * The utmp file holds miscellaneous information about things started by |
912 | return (0); | 791 | * /sbin/init and other system-related events. Our purpose is to update |
913 | if (capslock == 0) | 792 | * the utmp entry for the current process, in particular the process type |
914 | capslock = isupper(*s); | 793 | * and the tty line we are listening to. Return successfully only if the |
794 | * utmp file can be opened for update, and if we are able to find our | ||
795 | * entry in the utmp file. | ||
796 | */ | ||
797 | if (access(_PATH_UTMP, R_OK|W_OK) == -1) { | ||
798 | close(creat(_PATH_UTMP, 0664)); | ||
915 | } | 799 | } |
916 | return (capslock); | 800 | utmpname(_PATH_UTMP); |
917 | } | 801 | setutent(); |
802 | while ((utp = getutent()) | ||
803 | && !(utp->ut_type == INIT_PROCESS && utp->ut_pid == mypid)) /* nothing */ | ||
804 | ; | ||
918 | 805 | ||
919 | /* bcode - convert speed string to speed code; return 0 on failure */ | 806 | if (utp) { |
920 | static int bcode(const char *s) | 807 | memcpy(&ut, utp, sizeof(ut)); |
921 | { | 808 | } else { |
922 | int r; | 809 | /* some inits don't initialize utmp... */ |
923 | unsigned long value; | 810 | memset(&ut, 0, sizeof(ut)); |
924 | if (safe_strtoul((char *)s, &value)) { | 811 | strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id)); |
925 | return -1; | ||
926 | } | ||
927 | if ((r = bb_value_to_baud(value)) > 0) { | ||
928 | return r; | ||
929 | } | 812 | } |
930 | return 0; | 813 | /*endutent(); */ |
814 | |||
815 | strncpy(ut.ut_user, "LOGIN", sizeof(ut.ut_user)); | ||
816 | strncpy(ut.ut_line, line, sizeof(ut.ut_line)); | ||
817 | if (fakehost) | ||
818 | strncpy(ut.ut_host, fakehost, sizeof(ut.ut_host)); | ||
819 | time(&t); | ||
820 | ut.ut_time = t; | ||
821 | ut.ut_type = LOGIN_PROCESS; | ||
822 | ut.ut_pid = mypid; | ||
823 | |||
824 | pututline(&ut); | ||
825 | endutent(); | ||
826 | |||
827 | #ifdef CONFIG_FEATURE_WTMP | ||
828 | if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) | ||
829 | close(creat(bb_path_wtmp_file, 0664)); | ||
830 | updwtmp(bb_path_wtmp_file, &ut); | ||
831 | #endif | ||
931 | } | 832 | } |
932 | 833 | ||
933 | /* | 834 | #endif /* CONFIG_FEATURE_UTMP */ |
934 | * output error messages | 835 | #endif /* SYSV_STYLE */ |
935 | */ | ||
936 | static void error(const char *fmt, ...) | ||
937 | { | ||
938 | va_list va_alist; | ||
939 | char buf[256]; | ||
940 | 836 | ||
941 | #ifdef CONFIG_SYSLOGD | 837 | |
942 | va_start(va_alist, fmt); | 838 | #undef logname |
943 | vsnprintf(buf, sizeof(buf), fmt, va_alist); | 839 | int getty_main(int argc, char **argv) |
944 | openlog(bb_applet_name, 0, LOG_AUTH); | 840 | { |
945 | syslog(LOG_ERR, "%s", buf); | 841 | char *logname = NULL; /* login name, given to /bin/login */ |
946 | closelog(); | 842 | struct chardata chardata; /* set by get_logname() */ |
843 | struct termio termio; /* terminal mode bits */ | ||
844 | static struct options options = { | ||
845 | 0, /* show /etc/issue (SYSV_STYLE) */ | ||
846 | 0, /* no timeout */ | ||
847 | _PATH_LOGIN, /* default login program */ | ||
848 | "tty1", /* default tty line */ | ||
849 | "", /* modem init string */ | ||
850 | #ifdef ISSUE | ||
851 | ISSUE, /* default issue file */ | ||
947 | #else | 852 | #else |
948 | int fd; | 853 | NULL, |
949 | size_t l; | 854 | #endif |
855 | 0, /* no baud rates known yet */ | ||
856 | }; | ||
950 | 857 | ||
951 | snprintf(buf, sizeof(buf), "%s: ", bb_applet_name); | 858 | #ifdef DEBUGGING |
952 | l = strlen(buf); | 859 | dbf = bb_xfopen(DEBUGTERM, "w"); |
953 | va_start(va_alist, fmt); | 860 | |
954 | vsnprintf(buf + l, sizeof(buf) - l, fmt, va_alist); | 861 | { |
955 | l = strlen(buf); | 862 | int i; |
956 | /* truncate if need */ | 863 | |
957 | if((l + 3) > sizeof(buf)) | 864 | for (i = 1; i < argc; i++) { |
958 | l = sizeof(buf) - 3; | 865 | debug(argv[i]); |
959 | /* add \r\n always */ | 866 | debug("\n"); |
960 | buf[l++] = '\r'; | 867 | } |
961 | buf[l++] = '\n'; | ||
962 | buf[l] = 0; | ||
963 | if ((fd = open("/dev/console", 1)) >= 0) { | ||
964 | write(fd, buf, l); | ||
965 | close(fd); | ||
966 | } | 868 | } |
967 | #endif | 869 | #endif |
968 | 870 | ||
969 | va_end(va_alist); | 871 | /* Parse command-line arguments. */ |
970 | 872 | ||
971 | (void) sleep((unsigned) 10); /* be kind to init(8) */ | 873 | parse_args(argc, argv, &options); |
972 | exit(1); | 874 | |
875 | #ifdef __linux__ | ||
876 | setsid(); | ||
877 | #endif | ||
878 | |||
879 | /* Update the utmp file. */ | ||
880 | |||
881 | |||
882 | #ifdef SYSV_STYLE | ||
883 | #ifdef CONFIG_FEATURE_UTMP | ||
884 | update_utmp(options.tty); | ||
885 | #endif | ||
886 | #endif | ||
887 | |||
888 | debug("calling open_tty\n"); | ||
889 | /* Open the tty as standard { input, output, error }. */ | ||
890 | open_tty(options.tty, &termio, options.flags & F_LOCAL); | ||
891 | |||
892 | #ifdef __linux__ | ||
893 | { | ||
894 | int iv; | ||
895 | |||
896 | iv = getpid(); | ||
897 | ioctl(0, TIOCSPGRP, &iv); | ||
898 | } | ||
899 | #endif | ||
900 | /* Initialize the termio settings (raw mode, eight-bit, blocking i/o). */ | ||
901 | debug("calling termio_init\n"); | ||
902 | termio_init(&termio, options.speeds[FIRST_SPEED], &options); | ||
903 | |||
904 | /* write the modem init string and DON'T flush the buffers */ | ||
905 | if (options.flags & F_INITSTRING) { | ||
906 | debug("writing init string\n"); | ||
907 | write(1, options.initstring, strlen(options.initstring)); | ||
908 | } | ||
909 | |||
910 | if (!(options.flags & F_LOCAL)) { | ||
911 | /* go to blocking write mode unless -L is specified */ | ||
912 | fcntl(1, F_SETFL, fcntl(1, F_GETFL, 0) & ~O_NONBLOCK); | ||
913 | } | ||
914 | |||
915 | /* Optionally detect the baud rate from the modem status message. */ | ||
916 | debug("before autobaud\n"); | ||
917 | if (options.flags & F_PARSE) | ||
918 | auto_baud(&termio); | ||
919 | |||
920 | /* Set the optional timer. */ | ||
921 | if (options.timeout) | ||
922 | (void) alarm((unsigned) options.timeout); | ||
923 | |||
924 | /* optionally wait for CR or LF before writing /etc/issue */ | ||
925 | if (options.flags & F_WAITCRLF) { | ||
926 | char ch; | ||
927 | |||
928 | debug("waiting for cr-lf\n"); | ||
929 | while (read(0, &ch, 1) == 1) { | ||
930 | ch &= 0x7f; /* strip "parity bit" */ | ||
931 | #ifdef DEBUGGING | ||
932 | fprintf(dbf, "read %c\n", ch); | ||
933 | #endif | ||
934 | if (ch == '\n' || ch == '\r') | ||
935 | break; | ||
936 | } | ||
937 | } | ||
938 | |||
939 | chardata = init_chardata; | ||
940 | if (!(options.flags & F_NOPROMPT)) { | ||
941 | /* Read the login name. */ | ||
942 | debug("reading login name\n"); | ||
943 | /* while ((logname = get_logname(&options, &chardata, &termio)) == 0) */ | ||
944 | while ((logname = get_logname(&options, &chardata, &termio)) == | ||
945 | NULL) next_speed(&termio, &options); | ||
946 | } | ||
947 | |||
948 | /* Disable timer. */ | ||
949 | |||
950 | if (options.timeout) | ||
951 | (void) alarm(0); | ||
952 | |||
953 | /* Finalize the termio settings. */ | ||
954 | |||
955 | termio_final(&options, &termio, &chardata); | ||
956 | |||
957 | /* Now the newline character should be properly written. */ | ||
958 | |||
959 | (void) write(1, "\n", 1); | ||
960 | |||
961 | /* Let the login program take care of password validation. */ | ||
962 | |||
963 | (void) execl(options.login, options.login, "--", logname, (char *) 0); | ||
964 | error("%s: can't exec %s: %m", options.tty, options.login); | ||
973 | } | 965 | } |
966 | |||