1#include <stdio.h> 2#include <stdarg.h> 3#include <stdlib.h> 4 5#include "gripes.h" 6#include "man.h" /* for progname */ 7 8extern char *msg[]; 9 10static char *mantexts = "man"; /* e.g. /usr/lib/locale/%L/man.cat */ 11 12#ifdef NONLS 13 14static char * 15getmsg (int n) { 16 char *s; 17 18 if (0 < n && n <= MAXMSG) 19 s = msg[n]; 20 else { 21 fprintf (stderr, "man: internal error - cannot find message %d\n", n); 22 exit (1); 23 } 24 return s; 25} 26 27#else /* NONLS */ 28 29#include <string.h> 30#include <nl_types.h> 31#include "../catopen/catopen.c" 32 33nl_catd catfd = (nl_catd) -1; 34int cat_is_open = 0; 35 36static void 37catinit (void) { 38 if (!cat_is_open) { 39#ifdef NL_CAT_LOCALE 40 catfd = my_catopen(mantexts,NL_CAT_LOCALE); 41#else 42 catfd = my_catopen(mantexts,0); 43#endif 44 if (catfd == (nl_catd) -1) { 45 /* 46 * Only complain if LANG exists, and LANG != "en" 47 * (or when debugging). Also accept en_ZA etc. 48 * No messages for C locale. 49 */ 50 if (debug) { 51 fprintf(stderr, 52"Looked whether there exists a message catalog %s, but there is none\n" 53"(and for English messages none is needed)\n\n", 54 mantexts); 55 } 56 } 57 } 58 cat_is_open = 1; 59} 60 61/* 62 * This routine is unnecessary, but people ask for such things. 63 * 64 * Maybe man is suid or sgid to some user that owns the cat directories. 65 * Maybe NLSPATH can be manipulated by the user - even though 66 * modern glibc avoids using environment variables when the 67 * program is suid or sgid. 68 * So, maybe the string s that we are returning was user invented 69 * and we have to avoid %n and the like. 70 * 71 * As a random hack, only allow %s,%d,%o, and only two %-signs. 72 */ 73static int 74is_suspect (char *s) { 75 int ct = 0; 76 77 while (*s) { 78 if (*s++ == '%') { 79 ct++; 80 if (*s != 's' && *s != 'd' && *s != 'o') 81 return 1; 82 } 83 } 84 return (ct > 2); 85} 86 87static char * 88getmsg (int n) { 89 char *s = ""; 90 91 catinit (); 92 if (catfd != (nl_catd) -1) { 93 s = catgets(catfd, 1, n, ""); 94 if (*s && is_suspect(s)) 95 s = ""; 96 } 97 if (*s == 0 && 0 < n && n <= MAXMSG) 98 s = msg[n]; 99 if (*s == 0) { 100 fprintf(stderr, 101 "man: internal error - cannot find message %d\n", n); 102 exit (1); 103 } 104 return s; 105} 106 107#endif /* NONLS */ 108 109void 110gripe (int n, ...) { 111 va_list p; 112 113 va_start(p, n); 114 vfprintf (stderr, getmsg(n), p); 115 va_end(p); 116 fflush (stderr); 117} 118 119void 120fatal (int n, ...) { 121 va_list p; 122 fprintf (stderr, "%s: ", progname); 123 va_start(p, n); 124 vfprintf (stderr, getmsg(n), p); 125 va_end(p); 126 exit (1); 127} 128