]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - text-utils/ul.c
wipefs: add --lock and LOCK_BLOCK_DEVICE
[thirdparty/util-linux.git] / text-utils / ul.c
index ab0a6e77c0c46693aa3fa056aa2e52995837dc55..39b69a5972350a26b07d1bc53e801e5bd5aff729 100644 (file)
@@ -34,7 +34,7 @@
 /*
  * modified by Kars de Jong <jongk@cs.utwente.nl>
  *     to use terminfo instead of termcap.
- * 1999-02-22 Arkadiusz Mikiewicz <misiek@pld.ORG.PL>
+ * 1999-02-22 Arkadiusz Miśkiewicz <misiek@pld.ORG.PL>
  *     added Native Language Support
  * 1999-09-19 Bruno Haible <haible@clisp.cons.org>
  *     modified to work correctly in multi-byte locales
 #include <stdio.h>
 #include <unistd.h>            /* for getopt(), isatty() */
 #include <string.h>            /* for memset(), strcpy() */
-#include <term.h>              /* for setupterm() */
 #include <stdlib.h>            /* for getenv() */
 #include <limits.h>            /* for INT_MAX */
 #include <signal.h>            /* for signal() */
-#include <err.h>
 #include <errno.h>
-#include "nls.h"
+#include <getopt.h>
+
+#if defined(HAVE_NCURSESW_TERM_H)
+# include <ncursesw/term.h>
+#elif defined(HAVE_NCURSES_TERM_H)
+# include <ncurses/term.h>
+#elif defined(HAVE_TERM_H)
+# include <term.h>
+#endif
 
+#include "nls.h"
+#include "xalloc.h"
 #include "widechar.h"
+#include "c.h"
+#include "closestream.h"
 
 #ifdef HAVE_WIDECHAR
-static int put1wc(int c) /* Output an ASCII character as a wide character */
+/* Output an ASCII character as a wide character */
+static int put1wc(int c)
 {
-  if (putwchar(c) == WEOF)
-    return EOF;
-  else
-    return c;
+       if (putwchar(c) == WEOF)
+               return EOF;
+
+       return c;
 }
-#define putwp(s) tputs(s,1,put1wc)
+#define putwp(s) tputs(s, STDOUT_FILENO, put1wc)
 #else
 #define putwp(s) putp(s)
 #endif
 
-void filter(FILE *f);
-void flushln(void);
-void overstrike(void);
-void iattr(void);
-void initbuf(void);
-void fwd(void);
-void reverse(void);
-void initinfo(void);
-void outc(wint_t c, int width);
-void setmode(int newmode);
+static int handle_escape(FILE * f);
+static void filter(FILE *f);
+static void flushln(void);
+static void overstrike(void);
+static void iattr(void);
+static void initbuf(void);
+static void fwd(void);
+static void reverse(void);
+static void initinfo(void);
+static void outc(wint_t c, int width);
+static void xsetmode(int newmode);
 static void setcol(int newcol);
 static void needcol(int col);
 static void sig_handler(int signo);
+static void print_out(char *line);
 
 #define        IESC    '\033'
 #define        SO      '\016'
@@ -93,256 +106,295 @@ static void sig_handler(int signo);
 #define        SUBSC   004     /* Dim | Ul */
 #define        UNDERL  010     /* Ul */
 #define        BOLD    020     /* Bold */
-#define        INITBUF 512
-
-int    must_use_uc, must_overstrike;
-char   *CURS_UP, *CURS_RIGHT, *CURS_LEFT,
-       *ENTER_STANDOUT, *EXIT_STANDOUT, *ENTER_UNDERLINE, *EXIT_UNDERLINE,
-       *ENTER_DIM, *ENTER_BOLD, *ENTER_REVERSE, *UNDER_CHAR, *EXIT_ATTRIBUTES;
 
-struct CHAR    {
+static int     must_use_uc, must_overstrike;
+static char    *CURS_UP,
+               *CURS_RIGHT,
+               *CURS_LEFT,
+               *ENTER_STANDOUT,
+               *EXIT_STANDOUT,
+               *ENTER_UNDERLINE,
+               *EXIT_UNDERLINE,
+               *ENTER_DIM,
+               *ENTER_BOLD,
+               *ENTER_REVERSE,
+               *UNDER_CHAR,
+               *EXIT_ATTRIBUTES;
+
+struct CHAR {
        char    c_mode;
        wchar_t c_char;
        int     c_width;
-} ;
+};
+
+static struct  CHAR    *obuf;
+static int     obuflen;
+static int     col, maxcol;
+static int     mode;
+static int     halfpos;
+static int     upln;
+static int     iflag;
+
+static void __attribute__((__noreturn__)) usage(void)
+{
+       FILE *out = stdout;
+       fputs(USAGE_HEADER, out);
+       fprintf(out, _(" %s [options] [<file> ...]\n"), program_invocation_short_name);
+
+       fputs(USAGE_SEPARATOR, out);
+       fputs(_("Do underlining.\n"), out);
 
-struct CHAR    *obuf;
-int    obuflen;                /* Tracks number of elements in obuf. */
-int    col, maxcol;
-int    mode;
-int    halfpos;
-int    upln;
-int    iflag;
+       fputs(USAGE_OPTIONS, out);
+       fputs(_(" -t, -T, --terminal TERMINAL  override the TERM environment variable\n"), out);
+       fputs(_(" -i, --indicated              underlining is indicated via a separate line\n"), out);
+       fputs(USAGE_SEPARATOR, out);
+       printf(USAGE_HELP_OPTIONS(30));
 
-#define        PRINT(s)        if (s == NULL) /* void */; else putwp(s)
+       printf(USAGE_MAN_TAIL("ul(1)"));
+
+       exit(EXIT_SUCCESS);
+}
 
 int main(int argc, char **argv)
 {
-       int c, ret;
+       int c, ret, tflag = 0;
        char *termtype;
        FILE *f;
 
+       static const struct option longopts[] = {
+               { "terminal",   required_argument,      NULL, 't' },
+               { "indicated",  no_argument,            NULL, 'i' },
+               { "version",    no_argument,            NULL, 'V' },
+               { "help",       no_argument,            NULL, 'h' },
+               { NULL, 0, NULL, 0 }
+       };
+
        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
+       close_stdout_atexit();
 
        signal(SIGINT, sig_handler);
        signal(SIGTERM, sig_handler);
 
        termtype = getenv("TERM");
-       if (termtype == NULL || (argv[0][0] == 'c' && !isatty(1)))
-               termtype = "lpr";
-       while ((c = getopt(argc, argv, "it:T:")) != -1)
-               switch(c) {
+
+       while ((c = getopt_long(argc, argv, "it:T:Vh", longopts, NULL)) != -1)
+               switch (c) {
 
                case 't':
-               case 'T': /* for nroff compatibility */
-                               termtype = optarg;
+               case 'T':
+                       /* for nroff compatibility */
+                       termtype = optarg;
+                       tflag = 1;
                        break;
                case 'i':
                        iflag = 1;
                        break;
 
+               case 'V':
+                       print_version(EXIT_SUCCESS);
+               case 'h':
+                       usage();
                default:
-                       fprintf(stderr,
-                               _("Usage: %s [ -i ] [ -tTerm ] file...\n"),
-                               program_invocation_short_name);
-                       return EXIT_FAILURE;
+                       errtryhelp(EXIT_FAILURE);
                }
-       setupterm(termtype, 1, &ret);
-       switch(ret) {
+       setupterm(termtype, STDOUT_FILENO, &ret);
+       switch (ret) {
 
        case 1:
                break;
 
        default:
                warnx(_("trouble reading terminfo"));
-               /* fall through to ... */
+               /* fallthrough */
 
        case 0:
-               /* No such terminal type - assume dumb */
-               setupterm("dumb", 1, (int *)0);
+               if (tflag)
+                       warnx(_("terminal `%s' is not known, defaulting to `dumb'"),
+                               termtype);
+               setupterm("dumb", STDOUT_FILENO, (int *)0);
                break;
        }
        initinfo();
-       if (    (tigetflag("os") && ENTER_BOLD==NULL ) ||
-               (tigetflag("ul") && ENTER_UNDERLINE==NULL && UNDER_CHAR==NULL))
-                       must_overstrike = 1;
+       if ((tigetflag("os") && ENTER_BOLD==NULL ) ||
+           (tigetflag("ul") && ENTER_UNDERLINE==NULL && UNDER_CHAR==NULL))
+               must_overstrike = 1;
        initbuf();
        if (optind == argc)
                filter(stdin);
-       else for (; optind<argc; optind++) {
-               f = fopen(argv[optind],"r");
-               if (!f)
-                       err(EXIT_FAILURE, _("%s: open failed"), argv[optind]);
-               filter(f);
-       }
-       if (ferror(stdout) || fclose(stdout))
-               return EXIT_FAILURE;
-
+       else
+               for (; optind < argc; optind++) {
+                       f = fopen(argv[optind],"r");
+                       if (!f)
+                               err(EXIT_FAILURE, _("cannot open %s"),
+                                   argv[optind]);
+                       filter(f);
+                       fclose(f);
+               }
+       free(obuf);
        return EXIT_SUCCESS;
 }
 
-void filter(FILE *f)
+static int handle_escape(FILE * f)
 {
        wint_t c;
-       int i, w;
 
-       while ((c = getwc(f)) != WEOF) switch(c) {
-
-       case '\b':
-               setcol(col - 1);
-               continue;
-
-       case '\t':
-               setcol((col+8) & ~07);
-               continue;
-
-       case '\r':
-               setcol(0);
-               continue;
-
-       case SO:
-               mode |= ALTSET;
-               continue;
-
-       case SI:
-               mode &= ~ALTSET;
-               continue;
+       switch (c = getwc(f)) {
+       case HREV:
+               if (halfpos == 0) {
+                       mode |= SUPERSC;
+                       halfpos--;
+               } else if (halfpos > 0) {
+                       mode &= ~SUBSC;
+                       halfpos--;
+               } else {
+                       halfpos = 0;
+                       reverse();
+               }
+               return 0;
+       case HFWD:
+               if (halfpos == 0) {
+                       mode |= SUBSC;
+                       halfpos++;
+               } else if (halfpos < 0) {
+                       mode &= ~SUPERSC;
+                       halfpos++;
+               } else {
+                       halfpos = 0;
+                       fwd();
+               }
+               return 0;
+       case FREV:
+               reverse();
+               return 0;
+       default:
+               /* unknown escape */
+               ungetwc(c, f);
+               return 1;
+       }
+}
 
-       case IESC:
-               switch (c = getwc(f)) {
+static void filter(FILE *f)
+{
+       wint_t c;
+       int i, w;
 
-               case HREV:
-                       if (halfpos == 0) {
-                               mode |= SUPERSC;
-                               halfpos--;
-                       } else if (halfpos > 0) {
-                               mode &= ~SUBSC;
-                               halfpos--;
-                       } else {
-                               halfpos = 0;
-                               reverse();
+       while ((c = getwc(f)) != WEOF) {
+               switch (c) {
+               case '\b':
+                       setcol(col - 1);
+                       continue;
+               case '\t':
+                       setcol((col + 8) & ~07);
+                       continue;
+               case '\r':
+                       setcol(0);
+                       continue;
+               case SO:
+                       mode |= ALTSET;
+                       continue;
+               case SI:
+                       mode &= ~ALTSET;
+                       continue;
+               case IESC:
+                       if (handle_escape(f)) {
+                               c = getwc(f);
+                               errx(EXIT_FAILURE,
+                                    _("unknown escape sequence in input: %o, %o"), IESC, c);
                        }
                        continue;
-
-               case HFWD:
-                       if (halfpos == 0) {
-                               mode |= SUBSC;
-                               halfpos++;
-                       } else if (halfpos < 0) {
-                               mode &= ~SUPERSC;
-                               halfpos++;
-                       } else {
-                               halfpos = 0;
-                               fwd();
+               case '_':
+                       if (obuf[col].c_char || obuf[col].c_width < 0) {
+                               while (col > 0 && obuf[col].c_width < 0)
+                                       col--;
+                               w = obuf[col].c_width;
+                               for (i = 0; i < w; i++)
+                                       obuf[col++].c_mode |= UNDERL | mode;
+                               setcol(col);
+                               continue;
                        }
+                       obuf[col].c_char = '_';
+                       obuf[col].c_width = 1;
+                       /* fallthrough */
+               case ' ':
+                       setcol(col + 1);
                        continue;
-
-               case FREV:
-                       reverse();
+               case '\n':
+                       flushln();
                        continue;
-
-               default:
-                       errx(EXIT_FAILURE,
-                               _("unknown escape sequence in input: %o, %o"),
-                               IESC, c);
-                       break;
-               }
-               continue;
-
-       case '_':
-               if (obuf[col].c_char || obuf[col].c_width < 0) {
-                       while(col > 0 && obuf[col].c_width < 0)
-                               col--;
-                       w = obuf[col].c_width;
-                       for (i = 0; i < w; i++)
-                               obuf[col++].c_mode |= UNDERL | mode;
-                       setcol(col);
+               case '\f':
+                       flushln();
+                       putwchar('\f');
                        continue;
-               }
-               obuf[col].c_char = '_';
-               obuf[col].c_width = 1;
-               /* fall through */
-       case ' ':
-               setcol(col + 1);
-               continue;
-
-       case '\n':
-               flushln();
-               continue;
-
-       case '\f':
-               flushln();
-               putwchar('\f');
-               continue;
-
-       default:
-               if (!iswprint(c))       /* non printing */
+               default:
+                       if (!iswprint(c))
+                               /* non printable */
+                               continue;
+                       w = wcwidth(c);
+                       needcol(col + w);
+                       if (obuf[col].c_char == '\0') {
+                               obuf[col].c_char = c;
+                               for (i = 0; i < w; i++)
+                                       obuf[col + i].c_mode = mode;
+                               obuf[col].c_width = w;
+                               for (i = 1; i < w; i++)
+                                       obuf[col + i].c_width = -1;
+                       } else if (obuf[col].c_char == '_') {
+                               obuf[col].c_char = c;
+                               for (i = 0; i < w; i++)
+                                       obuf[col + i].c_mode |= UNDERL | mode;
+                               obuf[col].c_width = w;
+                               for (i = 1; i < w; i++)
+                                       obuf[col + i].c_width = -1;
+                       } else if ((wint_t) obuf[col].c_char == c) {
+                               for (i = 0; i < w; i++)
+                                       obuf[col + i].c_mode |= BOLD | mode;
+                       } else {
+                               w = obuf[col].c_width;
+                               for (i = 0; i < w; i++)
+                                       obuf[col + i].c_mode = mode;
+                       }
+                       setcol(col + w);
                        continue;
-               w = wcwidth(c);
-               needcol(col + w);
-               if (obuf[col].c_char == '\0') {
-                       obuf[col].c_char = c;
-                       for (i = 0; i < w; i++)
-                               obuf[col+i].c_mode = mode;
-                       obuf[col].c_width = w;
-                       for (i = 1; i < w; i++)
-                               obuf[col+i].c_width = -1;
-               } else if (obuf[col].c_char == '_') {
-                       obuf[col].c_char = c;
-                       for (i = 0; i < w; i++)
-                               obuf[col+i].c_mode |= UNDERL|mode;
-                       obuf[col].c_width = w;
-                       for (i = 1; i < w; i++)
-                               obuf[col+i].c_width = -1;
-               } else if (obuf[col].c_char == c) {
-                       for (i = 0; i < w; i++)
-                               obuf[col+i].c_mode |= BOLD|mode;
-               } else {
-                       w = obuf[col].c_width;
-                       for (i = 0; i < w; i++)
-                               obuf[col+i].c_mode = mode;
                }
-               setcol(col + w);
-               continue;
        }
        if (maxcol)
                flushln();
 }
 
-void flushln(void)
+static void flushln(void)
 {
        int lastmode;
        int i;
        int hadmodes = 0;
 
        lastmode = NORMAL;
-       for (i=0; i<maxcol; i++) {
+       for (i = 0; i < maxcol; i++) {
                if (obuf[i].c_mode != lastmode) {
                        hadmodes++;
-                       setmode(obuf[i].c_mode);
+                       xsetmode(obuf[i].c_mode);
                        lastmode = obuf[i].c_mode;
                }
                if (obuf[i].c_char == '\0') {
                        if (upln) {
-                               PRINT(CURS_RIGHT);
+                               print_out(CURS_RIGHT);
                        } else
                                outc(' ', 1);
                } else
                        outc(obuf[i].c_char, obuf[i].c_width);
                if (obuf[i].c_width > 1)
-                       i += obuf[i].c_width -1;
+                       i += obuf[i].c_width - 1;
        }
        if (lastmode != NORMAL) {
-               setmode(0);
+               xsetmode(0);
        }
        if (must_overstrike && hadmodes)
                overstrike();
        putwchar('\n');
        if (iflag && hadmodes)
                iattr();
-       (void)fflush(stdout);
+       fflush(stdout);
        if (upln)
                upln--;
        initbuf();
@@ -352,19 +404,15 @@ void flushln(void)
  * For terminals that can overstrike, overstrike underlines and bolds.
  * We don't do anything with halfline ups and downs, or Greek.
  */
-void overstrike(void)
+static void overstrike(void)
 {
        register int i;
-#ifdef __GNUC__
-       register wchar_t *lbuf = __builtin_alloca((maxcol+1)*sizeof(wchar_t));
-#else
-       wchar_t lbuf[256];
-#endif
+       register wchar_t *lbuf = xcalloc(maxcol + 1, sizeof(wchar_t));
        register wchar_t *cp = lbuf;
        int hadbold=0;
 
        /* Set up overstrike buffer */
-       for (i=0; i<maxcol; i++)
+       for (i = 0; i < maxcol; i++)
                switch (obuf[i].c_mode) {
                case NORMAL:
                default:
@@ -381,31 +429,27 @@ void overstrike(void)
                        break;
                }
        putwchar('\r');
-       for (*cp=' '; *cp==' '; cp--)
+       for (*cp = ' '; *cp == ' '; cp--)
                *cp = 0;
-       for (cp=lbuf; *cp; cp++)
-               putwchar(*cp);
+       fputws(lbuf, stdout);
        if (hadbold) {
                putwchar('\r');
-               for (cp=lbuf; *cp; cp++)
-                       putwchar(*cp=='_' ? ' ' : *cp);
+               for (cp = lbuf; *cp; cp++)
+                       putwchar(*cp == '_' ? ' ' : *cp);
                putwchar('\r');
-               for (cp=lbuf; *cp; cp++)
-                       putwchar(*cp=='_' ? ' ' : *cp);
+               for (cp = lbuf; *cp; cp++)
+                       putwchar(*cp == '_' ? ' ' : *cp);
        }
+       free(lbuf);
 }
 
-void iattr(void)
+static void iattr(void)
 {
        register int i;
-#ifdef __GNUC__
-       register char *lbuf = __builtin_alloca((maxcol+1)*sizeof(char));
-#else
-       char lbuf[256];
-#endif
-       register char *cp = lbuf;
+       register wchar_t *lbuf = xcalloc(maxcol + 1, sizeof(wchar_t));
+       register wchar_t *cp = lbuf;
 
-       for (i=0; i<maxcol; i++)
+       for (i = 0; i < maxcol; i++)
                switch (obuf[i].c_mode) {
                case NORMAL:    *cp++ = ' '; break;
                case ALTSET:    *cp++ = 'g'; break;
@@ -415,30 +459,29 @@ void iattr(void)
                case BOLD:      *cp++ = '!'; break;
                default:        *cp++ = 'X'; break;
                }
-       for (*cp=' '; *cp==' '; cp--)
+       for (*cp = ' '; *cp == ' '; cp--)
                *cp = 0;
-       for (cp=lbuf; *cp; cp++)
-               putwchar(*cp);
+       fputws(lbuf, stdout);
        putwchar('\n');
+       free(lbuf);
 }
 
-void initbuf(void)
+static void initbuf(void)
 {
-       if (obuf == NULL) {     /* First time. */
-               obuflen = INITBUF;
-               obuf = malloc(sizeof(struct CHAR) * obuflen);
-               if (obuf == NULL)
-                       err(EXIT_FAILURE, _("unable to allocate buffer"));
-       }
+       if (obuf == NULL) {
+               /* First time. */
+               obuflen = BUFSIZ;
+               obuf = xcalloc(obuflen, sizeof(struct CHAR));
+       } else
+               /* assumes NORMAL == 0 */
+               memset(obuf, 0, sizeof(struct CHAR) * maxcol);
 
-       /* assumes NORMAL == 0 */
-       memset(obuf, 0, sizeof(struct CHAR) * obuflen);
        setcol(0);
        maxcol = 0;
        mode &= ALTSET;
 }
 
-void fwd(void)
+static void fwd(void)
 {
        int oldcol, oldmax;
 
@@ -449,16 +492,16 @@ void fwd(void)
        maxcol = oldmax;
 }
 
-void reverse(void)
+static void reverse(void)
 {
        upln++;
        fwd();
-       PRINT(CURS_UP);
-       PRINT(CURS_UP);
+       print_out(CURS_UP);
+       print_out(CURS_UP);
        upln++;
 }
 
-void initinfo(void)
+static void initinfo(void)
 {
        CURS_UP =               tigetstr("cuu1");
        CURS_RIGHT =            tigetstr("cuf1");
@@ -492,7 +535,7 @@ void initinfo(void)
 
        /*
         * Note that we use REVERSE for the alternate character set,
-        * not the as/ae capabilities.  This is because we are modelling
+        * not the as/ae capabilities.  This is because we are modeling
         * the model 37 teletype (since that's what nroff outputs) and
         * the typical as/ae is more of a graphics set, not the greek
         * letters the 37 has.
@@ -504,72 +547,70 @@ void initinfo(void)
 
 static int curmode = 0;
 
-void
-outc(wint_t c, int width) {
+static void outc(wint_t c, int width) {
        int i;
 
        putwchar(c);
        if (must_use_uc && (curmode&UNDERL)) {
-               for (i=0; i<width; i++)
-                       PRINT(CURS_LEFT);
-               for (i=0; i<width; i++)
-                       PRINT(UNDER_CHAR);
+               for (i = 0; i < width; i++)
+                       print_out(CURS_LEFT);
+               for (i = 0; i < width; i++)
+                       print_out(UNDER_CHAR);
        }
 }
 
-void setmode(int newmode)
+static void xsetmode(int newmode)
 {
        if (!iflag) {
                if (curmode != NORMAL && newmode != NORMAL)
-                       setmode(NORMAL);
+                       xsetmode(NORMAL);
                switch (newmode) {
                case NORMAL:
-                       switch(curmode) {
+                       switch (curmode) {
                        case NORMAL:
                                break;
                        case UNDERL:
-                               PRINT(EXIT_UNDERLINE);
+                               print_out(EXIT_UNDERLINE);
                                break;
                        default:
                                /* This includes standout */
-                               PRINT(EXIT_ATTRIBUTES);
+                               print_out(EXIT_ATTRIBUTES);
                                break;
                        }
                        break;
                case ALTSET:
-                       PRINT(ENTER_REVERSE);
+                       print_out(ENTER_REVERSE);
                        break;
                case SUPERSC:
                        /*
                         * This only works on a few terminals.
                         * It should be fixed.
                         */
-                       PRINT(ENTER_UNDERLINE);
-                       PRINT(ENTER_DIM);
+                       print_out(ENTER_UNDERLINE);
+                       print_out(ENTER_DIM);
                        break;
                case SUBSC:
-                       PRINT(ENTER_DIM);
+                       print_out(ENTER_DIM);
                        break;
                case UNDERL:
-                       PRINT(ENTER_UNDERLINE);
+                       print_out(ENTER_UNDERLINE);
                        break;
                case BOLD:
-                       PRINT(ENTER_BOLD);
+                       print_out(ENTER_BOLD);
                        break;
                default:
                        /*
                         * We should have some provision here for multiple modes
                         * on at once.  This will have to come later.
                         */
-                       PRINT(ENTER_STANDOUT);
+                       print_out(ENTER_STANDOUT);
                        break;
                }
        }
        curmode = newmode;
 }
 
-static void
-setcol(int newcol) {
+static void setcol(int newcol) {
        col = newcol;
 
        if (col < 0)
@@ -578,30 +619,35 @@ setcol(int newcol) {
                needcol(col);
 }
 
-static void
-needcol(int col) {
-       maxcol = col;
+static void needcol(int acol) {
+       maxcol = acol;
 
        /* If col >= obuflen, expand obuf until obuflen > col. */
-       while (col >= obuflen) {
+       while (acol >= obuflen) {
                /* Paranoid check for obuflen == INT_MAX. */
                if (obuflen == INT_MAX)
                        errx(EXIT_FAILURE, _("Input line too long."));
 
                /* Similar paranoia: double only up to INT_MAX. */
-               obuflen = ((INT_MAX / 2) < obuflen)
-                       ? INT_MAX
-                       : obuflen * 2;
+               if (obuflen < (INT_MAX / 2))
+                       obuflen *= 2;
+               else
+                       obuflen = INT_MAX;
 
                /* Now we can try to expand obuf. */
-               obuf = realloc(obuf, sizeof(struct CHAR) * obuflen);
-               if (obuf == NULL)
-                       err(EXIT_FAILURE, _("growing buffer failed"));
+               obuf = xrealloc(obuf, sizeof(struct CHAR) * obuflen);
        }
 }
 
-static void sig_handler(int signo)
+static void sig_handler(int signo __attribute__ ((__unused__)))
 {
        _exit(EXIT_SUCCESS);
 }
 
+static void print_out(char *line)
+{
+       if (line == NULL)
+               return;
+
+       putwp(line);
+}