On Friday 07 November 2008 01:39, Cathey, Jim wrote:
> The /etc/nologin logic of BB 10&11 seems a bit odd, and
> had problems echoing newlines in our system. Also,
> as I understand it, if nologin has contents those
> are all that's echoed, whereas if there but empty
> a system default message is supplied.
>
> $ diff -c loginutils/login.c~ loginutils/login.c
> *** loginutils/login.c~ 2008-10-15 11:01:16.000000000 -0700
> --- loginutils/login.c 2008-11-06 15:19:18.000000000 -0800
> ***************
> *** 117,123 ****
> static void die_if_nologin(void)
> {
> FILE *fp;
> ! int c;
>
> if (access("/etc/nologin", F_OK))
> return;
> --- 117,123 ----
> static void die_if_nologin(void)
> {
> FILE *fp;
> ! int c, ii = 0;
>
> if (access("/etc/nologin", F_OK))
> return;
> ***************
> *** 125,135 ****
> fp = fopen("/etc/nologin", "r");
> if (fp) {
> while ((c = getc(fp)) != EOF)
> ! bb_putchar((c=='\n') ? '\r' : c);
> fflush(stdout);
> fclose(fp);
> ! } else
> puts("\r\nSystem closed for routine maintenance\r");
> exit(EXIT_FAILURE);
> }
> #else
> --- 125,139 ----
> fp = fopen("/etc/nologin", "r");
> if (fp) {
> while ((c = getc(fp)) != EOF)
> ! ++ii,bb_putchar((c=='\n') ? (bb_putchar('\r'),c) :
> c);
(1) Linewrapep patch
(2) Do you hate poor souls who read your code or just try
to win code obfuscation contest?
> fflush(stdout);
> fclose(fp);
> ! }
> ! if (!ii) {
> puts("\r\nSystem closed for routine maintenance\r");
> + fflush(stdout);
> + }
> + tcdrain(fileno(stdout));
fflush() can be done once, after if() - smaller code.
fileno(stdout) is a known constant, it's STDOUT_FILENO.
Use it directly - smaller code.
> The above change makes for a recursive \r-adder on \n's, and counts
> emitted characters. The original code wouldn't emit any \n's that were
> in a standard unix text file, converting them to \r's instead, resulting
> in lines that overwrote themselves on display. I thought the purpose of
> this was to be able to deal with output paths that didn't have a tty
> device driver that could do CRNL mapping itself. In which case you
> need both, not a conversion.
>
> If any characters are emitted due to the nologin file contents, the
> default message is suppressed. (This was how I understood the original
> login [big] to work, and allows for supporting non-English
> installations.)
>
> We also had problems with the emitted file contents being truncated
> due to the exit(), and the race of the close and the write. The
> tcdrain()
> call fixed that. (I don't remember if it was telnet or console that
> exhibited this problem.)
Thanks.
Applying this patch:
diff -d -urpN busybox.8/loginutils/login.c busybox.9/loginutils/login.c
--- busybox.8/loginutils/login.c 2008-10-30 08:41:37.000000000 +0100
+++ busybox.9/loginutils/login.c 2008-11-07 02:07:13.000000000 +0100
@@ -118,18 +118,25 @@ static void die_if_nologin(void)
{
FILE *fp;
int c;
+ int empty = 1;
- if (access("/etc/nologin", F_OK))
+ fp = fopen_for_read("/etc/nologin");
+ if (!fp) /* assuming it does not exist */
return;
- fp = fopen_for_read("/etc/nologin");
- if (fp) {
- while ((c = getc(fp)) != EOF)
- bb_putchar((c=='\n') ? '\r' : c);
- fflush(stdout);
- fclose(fp);
- } else
+ while ((c = getc(fp)) != EOF) {
+ if (c == '\n')
+ bb_putchar('\r');
+ bb_putchar(c);
+ empty = 0;
+ }
+ if (empty)
puts("\r\nSystem closed for routine maintenance\r");
+
+ fclose(fp);
+ fflush(NULL);
+ /* Users say that they do need this prior exit: */
+ tcdrain(STDOUT_FILENO);
exit(EXIT_FAILURE);
}
#else
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox