[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libcaca] updated neercs patch (VT100 altcharset seems to work 100% now)



http://xent.com/~bsittler/neercs-2.diff

as before, but fixed a few typos that caused altcharset to turn off
after one character. now e.g. pstree -g 2 displays correctly, and so
does myman (even when built with plain old ncurses.)

-ben

On 7/22/08, Ben Wiley Sittler <bsittler@gmail.com> wrote:
> missed: Raina/Titan's sound track is myman-0.7.0/sfx/start.xm
>
> On Tue, Jul 22, 2008 at 2:01 PM, Ben Wiley Sittler <bsittler@gmail.com>
> wrote:
>> first, a patch against the current neercs:
>>
>> http://xent.com/~bsittler/neercs.diff
>>
>> changes:
>>
>> * Ctrl-A ? is equivalent to Ctrl-A h, as in screen
>>
>> * Ctrl-A a sends a literal Ctrl-A to the contained application, as in
>> screen
>>
>> * Absolute hack: now compiles and runs under Mac OS X; mytrace stuff
>> is not implemented there and PAM lives in a different spot than on
>> Linux
>>
>> * VT100-style alternate character set support (somewhat buggy still);
>> this is a subset of ISO-2022 charset switching support
>>
>> second, a quick patch to libcaca's Cocoa driver:
>>
>> http://xent.com/~bsittler/libcaca.diff
>>
>> changes:
>>
>> * removed reference to missing "common.h"
>>
>> and lastly, i'm happy to announce a new release of myman with libcaca
>> support, much faster builds, and more maze variations
>>
>> http://freshmeat.net/redir/myman/6880/url_tgz/myman-0.7.0.tar.gz
>>
>> $ wget http://freshmeat.net/redir/myman/6880/url_tgz/myman-0.7.0.tar.gz
>> $ tar -xzvf myman-0.7.0.tar.gz
>> $ cd myman-0.7.0
>> $ ./configure --with-libcaca
>> $ make
>>  [ this takes about 5 minutes on my computer ]
>> $ ./myman
>>  [ optional: add -h for advanced usage; sudo make install to share the fun
>> ]
>>
>> some of the changes:
>>
>> * when you build it for mac os x and use the cocoa driver for libcaca,
>> a custom icon shows up in the dock while it's running
>>
>> * there's a sound track by Raina/Titan that you can play in your
>> favorite tracker; see
>>
>> * code is slightly less atrocious than in previous versions
>>
>> * hacks such as
>>  $ env CACA_DRIVER=x11 CACA_FONT=nil2 ./myman -2 -v kpacman -z otto
>>
>> enjoy,
>> -ben
>>
>
Index: neercs/trunk/src/input.c
===================================================================
--- neercs/trunk/src/input.c	(revision 2579)
+++ neercs/trunk/src/input.c	(working copy)
@@ -128,6 +128,7 @@
         refresh = 1;
         break;
     case 'h':
+    case '?':
     case 0x08: //CACA_KEY_CTRL_H:
         screen_list->help = !screen_list->help;
         refresh = 1;
Index: neercs/trunk/src/mytrace.c
===================================================================
--- neercs/trunk/src/mytrace.c	(revision 2579)
+++ neercs/trunk/src/mytrace.c	(working copy)
@@ -33,6 +33,82 @@
 #include "neercs.h"
 #include "mytrace.h"
 
+#if defined(__APPLE__)
+
+struct mytrace* mytrace_attach(long int pid)
+{
+    errno = ENOSYS;
+    return NULL;
+}
+
+struct mytrace* mytrace_fork(struct mytrace *t)
+{
+    errno = ENOSYS;
+    return NULL;
+}
+
+int mytrace_detach(struct mytrace *t)
+{
+    errno = ENOSYS;
+    return -1;
+}
+
+long mytrace_getpid(struct mytrace *t)
+{
+    errno = ENOSYS;
+    return -1;
+}
+
+int mytrace_open(struct mytrace *t, char const *path, int mode)
+{
+    errno = ENOSYS;
+    return -1;
+}
+
+int mytrace_write(struct mytrace *t, int fd, char const *data, size_t len)
+{
+    errno = ENOSYS;
+    return -1;
+}
+
+int mytrace_close(struct mytrace *t, int fd)
+{
+    errno = ENOSYS;
+    return -1;
+}
+
+int mytrace_dup2(struct mytrace *t, int oldfd, int newfd)
+{
+    errno = ENOSYS;
+    return -1;
+}
+
+int mytrace_setpgid(struct mytrace *t, long pid, long pgid)
+{
+    errno = ENOSYS;
+    return -1;
+}
+
+int mytrace_setsid(struct mytrace *t)
+{
+    errno = ENOSYS;
+    return -1;
+}
+
+int mytrace_kill(struct mytrace *t, long pid, int sig)
+{
+    errno = ENOSYS;
+    return -1;
+}
+
+int mytrace_exit(struct mytrace *t, int status)
+{
+    errno = ENOSYS;
+    return -1;
+}
+
+#else
+
 #if defined USE_GRAB
 static int memcpy_from_target(struct mytrace *t,
                               char* dest, long src, size_t n);
@@ -602,3 +678,4 @@
 
 #endif /* USE_GRAB */
 
+#endif /* ! defined(__APPLE__) */
Index: neercs/trunk/src/term.c
===================================================================
--- neercs/trunk/src/term.c	(revision 2579)
+++ neercs/trunk/src/term.c	(working copy)
@@ -31,6 +31,59 @@
 
 #include "neercs.h"
 
+/* DEC ACS with common extensions */
+static uint32_t dec_acs(uint32_t uc)
+{
+    switch (uc)
+    {
+    case '+': return 0x2192; /* RIGHTWARDS ARROW */
+    case ',': return 0x2190; /* LEFTWARDS ARROW */
+    case '-': return 0x2191; /* UPWARDS ARROW */
+    case '.': return 0x2193; /* DOWNWARDS ARROW */
+    case '0': return 0x25AE; /* BLACK VERTICAL RECTANGLE */
+    case '_': return 0x25AE; /* BLACK VERTICAL RECTANGLE */
+    case '`': return 0x25C6; /* BLACK DIAMOND */
+    case 'a': return 0x2592; /* MEDIUM SHADE */
+    case 'b': return 0x2409; /* SYMBOL FOR HORIZONTAL TABULATION */
+    case 'c': return 0x240C; /* SYMBOL FOR FORM FEED */
+    case 'd': return 0x240D; /* SYMBOL FOR CARRIAGE RETURN */
+    case 'e': return 0x240A; /* SYMBOL FOR LINE FEED */
+    case 'f': return 0x00B0; /* DEGREE SIGN */
+    case 'g': return 0x00B1; /* PLUS-MINUS SIGN */
+    case 'h': return 0x2424; /* SYMBOL FOR NEWLINE */
+    case 'i': return 0x240B; /* SYMBOL FOR VERTICAL TABULATION */
+    case 'j': return 0x2518; /* BOX DRAWINGS LIGHT UP AND LEFT */
+    case 'k': return 0x2510; /* BOX DRAWINGS LIGHT DOWN AND LEFT */
+    case 'l': return 0x250C; /* BOX DRAWINGS LIGHT DOWN AND RIGHT */
+    case 'm': return 0x2514; /* BOX DRAWINGS LIGHT UP AND RIGHT */
+    case 'n': return 0x253C; /* BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
+    case 'o': return 0x23BA; /* HORIZONTAL SCAN LINE-1 */
+    case 'p': return 0x23BB; /* HORIZONTAL SCAN LINE-3 */
+    case 'q': return 0x2500; /* BOX DRAWINGS LIGHT HORIZONTAL */
+    case 'r': return 0x23BC; /* HORIZONTAL SCAN LINE-7 */
+    case 's': return 0x23BD; /* HORIZONTAL SCAN LINE-9 */
+    case 't': return 0x251C; /* BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+    case 'u': return 0x2524; /* BOX DRAWINGS LIGHT VERTICAL AND LEFT */
+    case 'v': return 0x2534; /* BOX DRAWINGS LIGHT UP AND HORIZONTAL */
+    case 'w': return 0x252C; /* BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
+    case 'x': return 0x2502; /* BOX DRAWINGS LIGHT VERTICAL */
+    case 'y': return 0x2264; /* LESS-THAN OR EQUAL TO */
+    case 'z': return 0x2265; /* GREATER-THAN OR EQUAL TO */
+    case '{': return 0x03C0; /* GREEK SMALL LETTER PI */
+    case '|': return 0x2260; /* NOT EQUAL TO */
+    case '}': return 0x00A3; /* POUND SIGN */
+    case '~': return 0x00B7; /* MIDDLE DOT */
+    default:
+        return uc;
+    }
+};
+
+static void reset_conv_state(struct screen *);
+
+#define LITERAL2CHAR(i0,i1) (((i0) << 8) | (i1))
+
+#define LITERAL3CHAR(i0,i1,i2) LITERAL2CHAR(LITERAL2CHAR(i0, i1), i2)
+
 static void ansi_parse_grcm(struct screen *,
                             unsigned int, unsigned int const *);
 
@@ -57,6 +110,8 @@
 
         ansi_parse_grcm(sc, 1, &dummy);
 
+        reset_conv_state(sc);
+
         sc->init = 1;
     }
 
@@ -94,18 +149,173 @@
                 x--;
         }
 
+        else if(buffer[i] == '\x0e')
+        {
+            /* Shift Out (Ctrl-N) -> Switch to
+             * Alternate Character Set: invokes
+             * the G1 character set. */
+            sc->conv_state.glr[0] = 1;
+        }
+
+        else if(buffer[i] == '\x0f')
+        {
+            /* Shift In (Ctrl-O) -> Switch to
+             * Standard Character Set: invokes
+             * the G0 character set. */
+            sc->conv_state.glr[0] = 0;
+        }
+
         /* If there are not enough characters to parse the escape sequence,
          * wait until the next try. We require 3. */
         else if(buffer[i] == '\x1b' && i + 2 >= size)
             break;
 
-        /* XXX: What the fuck is this shit? */
-        else if(buffer[i] == '\x1b' && buffer[i + 1] == '('
-                 && buffer[i + 2] == 'B')
+        /* Single Shift Select of G2 Character Set (SS2: 0x8e):
+         * affects next character only */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == 'N')
         {
+            sc->conv_state.ss = 2;
+            skip += 1;
+        }
+
+        /* Single Shift Select of G3 Character Set (SS2: 0x8f):
+         * affects next character only */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == 'O')
+        {
+            sc->conv_state.ss = 3;
+            skip += 1;
+        }
+
+        /* LOCKING-SHIFT TWO (LS2), ISO 2022, ECMA-48 (1986), ISO 6429 : 1988 */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == 'n')
+        {
+            sc->conv_state.glr[0] = 2;
+            skip += 1;
+        }
+
+        /* LOCKING-SHIFT THREE (LS3) ISO 2022, ECMA-48 (1986), ISO 6429 : 1988 */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == 'o')
+        {
+            sc->conv_state.glr[0] = 3;
+            skip += 1;
+        }
+
+        /* RESET TO INITIAL STATE (RIS), ECMA-48 (1986), ISO 6429 : 1988 */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == 'c')
+        {
+            sc->dfg = CUCUL_DEFAULT;
+            sc->dbg = CUCUL_DEFAULT;
+
+            cucul_set_color_ansi(sc->cv, sc->dfg, sc->dbg);
+            sc->clearattr = cucul_get_attr(sc->cv, -1, -1);
+            ansi_parse_grcm(sc, 1, &dummy);
+
+            reset_conv_state(sc);
+            skip += 1;
+        }
+
+        /* Coding Method Delimiter (CMD), ECMA-48 (1991), ISO/IEC 6429:1992 (ISO IR 189) */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == 'd')
+        {
+            reset_conv_state(sc);
+            skip += 1;
+        }
+
+        /* GZDM4, G0-Designators, multi, 94^n chars [grandfathered short form from ISO 2022:1986] */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == '$' && (buffer[i + 2] >= '@') && (buffer[i + 2] <= 'C'))
+        {
+            sc->conv_state.gn[0] = LITERAL2CHAR('$', buffer[i + 2]);
             skip += 2;
         }
 
+        /* GnDMx Gn-Designators, 9x^n chars; need one more char to distinguish these */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == '$' && (i + 3 >= size))
+            break;
+
+        /* GZD4 G0-Designator, 94 chars */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == '(')
+        {
+            sc->conv_state.gn[0] = buffer[i + 2];
+            skip += 2;
+        }
+
+        /* G1D4 G1-Designator, 94 chars */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == ')')
+        {
+            sc->conv_state.gn[1] = buffer[i + 2];
+            skip += 2;
+        }
+
+        /* G2D4 G2-Designator, 94 chars */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == '*')
+        {
+            sc->conv_state.gn[2] = buffer[i + 2];
+            skip += 2;
+        }
+
+        /* G3D4 G3-Designator, 94 chars */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == '+')
+        {
+            sc->conv_state.gn[3] = buffer[i + 2];
+            skip += 2;
+        }
+
+        /* G2D6 G2-Designator, 96 chars */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == '.')
+        {
+            sc->conv_state.gn[2] = LITERAL2CHAR('.', buffer[i + 2]);
+            skip += 2;
+        }
+
+        /* G3D6 G3-Designator, 96 chars */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == '/')
+        {
+            sc->conv_state.gn[3] = LITERAL2CHAR('.', buffer[i + 2]);
+            skip += 2;
+        }
+
+        /* GZDM4 G0-Designator, 94^n chars */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == '$' && buffer[i + 2] == '(')
+        {
+            sc->conv_state.gn[0] = LITERAL2CHAR('$', buffer[i + 3]);
+            skip += 3;
+        }
+
+        /* G1DM4 G1-Designator, 94^n chars */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == '$' && buffer[i + 2] == ')')
+        {
+            sc->conv_state.gn[1] = LITERAL2CHAR('$', buffer[i + 3]);
+            skip += 3;
+        }
+
+        /* G2DM4 G2-Designator, 94^n chars */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == '$' && buffer[i + 2] == '*')
+        {
+            sc->conv_state.gn[2] = LITERAL2CHAR('$', buffer[i + 3]);
+            skip += 3;
+        }
+
+        /* G3DM4 G3-Designator, 94^n chars */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == '$' && buffer[i + 2] == '+')
+        {
+            sc->conv_state.gn[3] = LITERAL2CHAR('$', buffer[i + 3]);
+            skip += 3;
+        }
+
+        /* G2DM6 G2-Designator, 96^n chars */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == '$' && buffer[i + 2] == '.')
+        {
+            sc->conv_state.gn[2] = LITERAL3CHAR('$', '.', buffer[i + 3]);
+            skip += 3;
+        }
+
+        /* G3DM6 G3-Designator, 96^n chars */
+        else if(buffer[i] == '\x1b' && buffer[i + 1] == '$' && buffer[i + 2] == '/')
+        {
+            sc->conv_state.gn[3] = LITERAL3CHAR('$', '.', buffer[i + 3]);
+            skip += 3;
+        }
+
         /* Interpret escape commands, as per Standard ECMA-48 "Control
          * Functions for Coded Character Sets", 5.4. Control sequences. */
         else if(buffer[i] == '\x1b' && buffer[i + 1] == '[')
@@ -365,6 +575,25 @@
                 ch = buffer[i];
                 bytes = 1;
             }
+
+            /* very incomplete ISO-2022 implementation tailored to DEC ACS */
+            if(sc->conv_state.cs == '@')
+            {
+                if (((ch > ' ') && (ch <= '~'))
+                    &&
+                    (sc->conv_state.gn[sc->conv_state.ss ? sc->conv_state.gn[sc->conv_state.ss] : sc->conv_state.glr[0]] == '0'))
+                {
+                    ch = dec_acs(ch);
+                }
+                else if (((ch > 0x80) && (ch < 0xff))
+                         &&
+                         (sc->conv_state.gn[sc->conv_state.glr[1]] == '0'))
+                {
+                    ch = dec_acs(ch + ' ' - 0x80);
+                }
+            }
+            sc->conv_state.ss = 0; /* no single-shift (GL) */
+
             wch = cucul_utf32_is_fullwidth(ch) ? 2 : 1;
             skip += bytes - 1;
         }
@@ -411,6 +640,23 @@
     return i;
 }
 
+/* Coding Method Delimiter (CMD), ECMA-48 (1991), ISO/IEC 6429:1992 (ISO IR 189) */
+
+static void reset_conv_state(struct screen *sc)
+{
+    sc->conv_state.cs = '@'; /* ISO-2022 coding system */
+    sc->conv_state.cn[0] = '@'; /* ISO 646 C0 control charset */
+    sc->conv_state.cn[1] = 'C'; /* ISO 6429-1983 C1 control charset */
+    sc->conv_state.glr[0] = 0; /* G0 in GL */
+    sc->conv_state.glr[1] = 2; /* G2 in GR */
+    sc->conv_state.gn[0] = 'B'; /* US-ASCII G0 charset */
+    sc->conv_state.gn[1] = '0'; /* DEC ACS G1 charset */
+    sc->conv_state.gn[2] = LITERAL2CHAR('.', 'A'); /* ISO 8859-1 G2 charset */
+    sc->conv_state.gn[3] = LITERAL2CHAR('.', 'A'); /* ISO 8859-1 G3 charset */
+    sc->conv_state.ss = 0; /* no single-shift (GL) */
+    sc->conv_state.ctrl8bit = 1;
+}
+
 /* XXX : ANSI loader helper */
 
 static void ansi_parse_grcm(struct screen *sc,
Index: neercs/trunk/src/neercs.h
===================================================================
--- neercs/trunk/src/neercs.h	(revision 2579)
+++ neercs/trunk/src/neercs.h	(working copy)
@@ -36,6 +36,79 @@
 };
 
 
+
+/* ISO-2022 Conversion State */
+struct iso2022_conv_state
+{
+    /* cs = coding system/coding method: */
+    /* (with standard return) */
+    /* '@' = ISO-2022, */
+    /* 'G' = UTF-8 without implementation level, */
+    /* '8' = UTF-8 (Linux console and imitators), */
+    /* and many others that are rarely used; */
+    /* (without standard return) */
+    /* '/G' = UTF-8 Level 1, */
+    /* '/H' = UTF-8 Level 2, */
+    /* '/I' = UTF-8 Level 3, */
+    /* and many others that are rarely used */
+    uint32_t cs;
+    /* ctrl8bit = allow 8-bit controls */
+    uint8_t ctrl8bit;
+    /* cn[0] = C0 control charset (0x00 ... 0x1f):
+     * '@' = ISO 646,
+     * '~' = empty,
+     * and many others that are rarely used */
+    /* cn[1] = C1 control charset (0x80 ... 0x9f):
+     * 'C' = ISO 6429-1983,
+     * '~' = empty,
+     * and many others that are rarely used */
+    uint32_t cn[2];
+    /* glr[0] = GL graphic charset (94-char. 0x21 ... 0x7e,
+     *                              94x94-char. 0x21/0x21 ... 0x7e/0x7e),
+     * and
+     * glr[1] = GR graphic charset (94-char. 0xa1 ... 0xfe,
+     *                              96-char. 0xa0 ... 0xff,
+     *                              94x94-char. 0xa1/0xa1 ... 0xfe/0xfe,
+     *                              96x96-char. 0xa0/0xa0 ... 0xff/0xff):
+     * 0 = G0, 1 = G1, 2 = G2, 3 = G3 */
+    uint8_t glr[2];
+    /* gn[i] = G0/G1/G2/G3 graphic charset state:
+     * (94-char. sets)
+     * '0' = DEC ACS (VT100 and imitators),
+     * 'B' = US-ASCII,
+     * and many others that are rarely used for e.g. various national ASCII variations;
+     * (96-char. sets)
+     * '.A' = ISO 8859-1 "Latin 1" GR,
+     * '.~' = empty 96-char. set,
+     * and many others that are rarely used for e.g. ISO 8859-n GR;
+     * (double-byte 94x94-charsets)
+     * '$@' = Japanese Character Set ("old JIS") (JIS C 6226:1978),
+     * '$A' = Chinese Character Set (GB 2312),
+     * '$B' = Japanese Character Set (JIS X0208/JIS C 6226:1983),
+     * '$C' = Korean Graphic Character Set (KSC 5601:1987),
+     * '$D' = Supplementary Japanese Graphic Character Set (JIS X0212),
+     * '$E' = CCITT Chinese Set (GB 2312 + GB 8565),
+     * '$G' = CNS 11643 plane 1,
+     * '$H' = CNS 11643 plane 2,
+     * '$I' = CNS 11643 plane 3,
+     * '$J' = CNS 11643 plane 4,
+     * '$K' = CNS 11643 plane 5,
+     * '$L' = CNS 11643 plane 6,
+     * '$M' = CNS 11643 plane 7,
+     * '$O' = JIS X 0213 plane 1,
+     * '$P' = JIS X 0213 plane 2,
+     * '$Q' = JIS X 0213-2004 Plane 1,
+     * and many others that are rarely used for e.g. traditional
+     * ideographic Vietnamese and BlissSymbolics;
+     * (double-byte 96x96-charsets)
+     * none standardized or in use on terminals AFAIK (Mule does use
+     * some internally)
+     */
+    uint32_t gn[4];
+    /* ss = single-shift state: 0 = GL, 2 = G2, 3 = G3 */
+    uint8_t ss;
+};
+
 struct screen
 {
     /* Graphics stuff */
@@ -46,6 +119,7 @@
     uint8_t dfg, dbg; /* Default fg/bg */
     uint8_t bold, blink, italics, negative, concealed, underline;
     uint8_t faint, strike, proportional; /* unsupported */
+    struct iso2022_conv_state conv_state; /* charset mess */
 
     /* Other stuff */
     int visible;                 /* Draw canvas and border flag */
@@ -62,7 +136,6 @@
 
     int orig_x, orig_y;          /* Used by recurrents */
     int orig_w, orig_h;          /* Used by recurrents */
-
 };
 
 struct screen_list
Index: neercs/trunk/src/main.c
===================================================================
--- neercs/trunk/src/main.c	(revision 2579)
+++ neercs/trunk/src/main.c	(working copy)
@@ -333,8 +333,9 @@
             unsigned int c = caca_get_event_key_ch(&ev);
             char *str = NULL;
             int size = 0;
-            /* CTRL-A has been pressed before, handle this as a command */
-            if(command)
+            /* CTRL-A has been pressed before, handle this as a
+             * command, except that CTRL-A a sends literal CTRL-A */
+            if(command && (c != 'a'))
             {
                 command = 0;
                 refresh |= handle_command_input(screen_list, c);
@@ -370,6 +371,11 @@
                             break;
                         }
                     default:
+                        /* CTRL-A a sends literal CTRL-A */
+                        if (command && (c == 'a'))
+                        {
+                            c = 0x01;
+                        }
                         /* Normal key, convert it if needed */
                         str = convert_input_ansi(&c, &size);
                         write(screen_list->screen[screen_list->pty]->fd, str, size);
Index: neercs/trunk/src/lock.c
===================================================================
--- neercs/trunk/src/lock.c	(revision 2579)
+++ neercs/trunk/src/lock.c	(working copy)
@@ -24,8 +24,13 @@
 #include <sys/types.h>
 
 #if defined USE_LOCK
+#if defined(__APPLE__)
+#   include <pam/pam_appl.h>
+#   include <pam/pam_misc.h>
+#else
 #   include <security/pam_appl.h>
 #   include <security/pam_misc.h>
+#endif
 #   include <pwd.h>
 #endif