aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277>2005-09-29 11:31:26 +0000
committervodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277>2005-09-29 11:31:26 +0000
commite263de99f6eabc608e9f79181c8e146d8a951503 (patch)
treed39b290031623e956a930a9ebb2acb755ce12483
parentf334a67fa8b7f2ae67198ed9a545374be503530f (diff)
downloadbusybox-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.c401
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
54extern void updwtmp(const char *filename, const struct utmp *ut); 53extern 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
136struct options { 135struct 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 */ 146static 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
158struct chardata { 161struct 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
168static struct chardata init_chardata = { 171static 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);
226static void do_prompt(struct options *op, struct termio *tp); 229static void do_prompt(struct options *op, struct termio *tp);
227static void next_speed(struct termio *tp, struct options *op); 230static void next_speed(struct termio *tp, struct options *op);
228static char *get_logname(struct options *op, struct chardata *cp, 231static char *get_logname(struct options *op, struct chardata *cp,
229 232 struct termio *tp);
230 struct termio *tp);
231static void termio_final(struct options *op, struct termio *tp, 233static void termio_final(struct options *op, struct termio *tp,
232 234 struct chardata *cp);
233 struct chardata *cp);
234static int caps_lock(const char *s); 235static int caps_lock(const char *s);
235static int bcode(char *s); 236static int bcode(const char *s);
236static void error(const char *fmt, ...) __attribute__ ((noreturn)); 237static 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
240static void update_utmp(char *line); 241static 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"
253FILE *dbf; 254FILE *dbf;
254#else 255#else
255#define debug(s) /* nothing */ 256#define debug(s) /* nothing */
256#endif 257#endif
257 258
258int getty_main(int argc, char **argv) 259int 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
388static void parse_args(int argc, char **argv, struct options *op) 389static 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 } */
557static void open_tty(char *tty, struct termio *tp, int local) 518static 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
660static void termio_init(struct termio *tp, int speed, struct options *op) 625static 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 */
760static void do_prompt(struct options *op, struct termio *tp) 724static 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 */
769static void next_speed(struct termio *tp, struct options *op) 733static 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 */
966static int bcode(char *s) 930static 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 */
986static void error(const char *fmt, ...) 946static 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}