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

Reply via email to