Logo Search packages:      
Sourcecode: man2html version File versions  Download package

gripes.c

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

#include "gripes.h"
#include "man.h"        /* for progname */

extern char *msg[];

static char *mantexts = "man";            /* e.g. /usr/lib/locale/%L/man.cat */

#ifdef NONLS

static char *
getmsg (int n) {
    char *s;

    if (0 < n && n <= MAXMSG)
      s = msg[n];
    else {
      fprintf (stderr, "man: internal error - cannot find message %d\n", n);
      exit (1);
    }
    return s;
}

#else /* NONLS */

#include <string.h>
#include <nl_types.h>
#include "../catopen/catopen.c"

nl_catd catfd = (nl_catd) -1;
int cat_is_open = 0;

static void
catinit (void) {
    if (!cat_is_open) {
#ifdef NL_CAT_LOCALE
      catfd = my_catopen(mantexts,NL_CAT_LOCALE);
#else
      catfd = my_catopen(mantexts,0);
#endif
      if (catfd == (nl_catd) -1) {
          /*
           * Only complain if LANG exists, and LANG != "en"
           * (or when debugging). Also accept en_ZA etc.
           * No messages for C locale.
           */
          char *s, *lg;
          s = getenv("NLSPATH");
          lg = getenv("LANG");
          if (!lg)
                lg = getenv("LC_MESSAGES");
          if (!lg)
                lg = getenv("LC_ALL");
          if (lg && strncmp(lg, "en", 2) && strcmp(lg, "C")) {
            fprintf(stderr,
              "Cannot open the message catalog \"%s\" for locale \"%s\"\n"
              "(NLSPATH=\"%s\")\n\n",
                  mantexts, lg, s ? s : "<none>");
          } else if (debug) {
            fprintf(stderr,
"Looked whether there exists a message catalog %s, but there is none\n"
"(and for English messages none is needed)\n\n",
                  mantexts);
            }
      }
    }
    cat_is_open = 1;
}

/*
 * This routine is unnecessary, but people ask for such things.
 *
 * Maybe man is suid or sgid to some user that owns the cat directories.
 * Maybe NLSPATH can be manipulated by the user - even though
 * modern glibc avoids using environment variables when the
 * program is suid or sgid.
 * So, maybe the string s that we are returning was user invented
 * and we have to avoid %n and the like.
 *
 * As a random hack, only allow %s,%d,%o, and only two %-signs.
 */
static int
is_suspect (char *s) {
      int ct = 0;

      while (*s) {
            if (*s++ == '%') {
                  ct++;
                  if (*s != 's' && *s != 'd' && *s != 'o')
                        return 1;
            }
      }
      return (ct > 2);
}

static char *
getmsg (int n) {
      char *s = "";

      catinit ();
      if (catfd != (nl_catd) -1) {
            s = catgets(catfd, 1, n, "");
            if (*s && is_suspect(s))
                  s = "";
      }
      if (*s == 0 && 0 < n && n <= MAXMSG)
            s = msg[n];
      if (*s == 0) {
            fprintf(stderr,
                  "man: internal error - cannot find message %d\n", n);
            exit (1);
        }
      return s;
}

#endif /* NONLS */

void
gripe (int n, ...) {
    va_list p;

    va_start(p, n);
    vfprintf (stderr, getmsg(n), p);
    va_end(p);
    fflush (stderr);
}

void
fatal (int n, ...) {
    va_list p;
    fprintf (stderr, "%s: ", progname);
    va_start(p, n);
    vfprintf (stderr, getmsg(n), p);
    va_end(p);
    exit (1);
}

Generated by  Doxygen 1.6.0   Back to index