#include #include #include #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 #include #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") && strcmp(lg, "POSIX")) { fprintf(stderr, "Cannot open the message catalog \"%s\" for locale \"%s\"\n" "(NLSPATH=\"%s\")\n\n", mantexts, lg, s ? s : ""); } 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); }