aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2006-06-16 16:37:07 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2006-06-16 16:37:07 +0000
commit6d82f94681618d50411bb7e4e30e40a0f0046d4c (patch)
treea80ec19f3b5f9338998ec904a06f4f369d33a186
parentd9a761d9c3ed1ec9143b2327a5212574d115e29f (diff)
downloadbusybox-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.c527
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
215static void parse_args(int argc, char **argv, struct options *op);
216static void parse_speeds(struct options *op, char *arg);
217static void open_tty(char *tty, struct termio *tp, int local);
218static void termio_init(struct termio *tp, int speed, struct options *op);
219static void auto_baud(struct termio *tp);
220static void do_prompt(struct options *op, struct termio *tp);
221static void next_speed(struct termio *tp, struct options *op);
222static char *get_logname(struct options *op, struct chardata *cp,
223 struct termio *tp);
224static void termio_final(struct options *op, struct termio *tp,
225 struct chardata *cp);
226static int caps_lock(const char *s);
227static int bcode(const char *s);
228static 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
250int 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 */
240static void error(const char *fmt, ...) ATTRIBUTE_NORETURN;
241static 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) { 283static 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) { 298static 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 */
380static void parse_args(int argc, char **argv, struct options *op) 314static 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
432static 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 */
450static 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 } */
509static void open_tty(char *tty, struct termio *tp, int local) 365static 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
615static void termio_init(struct termio *tp, int speed, struct options *op) 470static 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 */
569static 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 */
714static void do_prompt(struct options *op, struct termio *tp) 581static 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 */
723static void next_speed(struct termio *tp, struct options *op) 590/* returns 1 if true, 0 if false */
591static 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 */
735static char *get_logname(struct options *op, struct chardata *cp, struct termio *tp) 607static 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
906static int caps_lock(const char *s) 777#ifdef CONFIG_FEATURE_UTMP
778/* update_utmp - update our utmp entry */
779static 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) {
920static 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 */
936static 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); 839int 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