1/* 2 * man-config.c 3 * 4 * Read the man.conf file 5 * 6 * Input line types: 7 * MANBIN /usr/bin/man 8 * MANPATH /usr/X386/man [/var/catman/X386] 9 * MANPATH_MAP /usr/bin /usr/man 10 * FHS 11 * FSSTND 12 * NOAUTOPATH 13 * NROFF /usr/bin/groff -Tascii -mandoc 14 * BROWSER /usr/bin/lynx 15 * HTMLPAGER /usr/bin/lynx -dump 16 * .gz /usr/bin/gunzip -c 17 * # Comment 18 * 19 * Allow globbing in MANPATH elements. 20 * This is useful e.g. for having MANPATH /opt/ * /man 21 * (avoid comment within comment). 22 */ 23 24#include <stdio.h> 25#include <string.h> 26#include <stdlib.h> 27 28#include "defs.h" 29#include "glob.h" 30#include "man-config.h" 31#include "man.h" 32#include "paths.h" 33#include "gripes.h" 34#include "util.h" 35 36#define BUFSIZE 4096 37 38extern char *rindex (const char *, int); /* not always in <string.h> */ 39 40#define whitespace(x) ((x) == ' ' || (x) == '\t') 41 42/* directories listed in config file */ 43struct dirs cfdirlist; /* linked list, 1st entry unused */ 44 45static void 46addval (char *buf) { 47 int i, len; 48 char *bp; 49 50 for (i = 0; i < sizeof(paths)/sizeof(paths[0]); i++) { 51 len = strlen (paths[i].name); 52 bp = buf + len; 53 if(!strncmp (buf, paths[i].name, len) && (!*bp || whitespace(*bp))) { 54 while(whitespace(*bp)) 55 bp++; 56 paths[i].path = my_strdup(bp); 57 return; 58 } 59 } 60 gripe (UNRECOGNIZED_LINE, buf); 61} 62 63const char * 64getval (const char *cmd) { 65 int i; 66 67 for (i = 0; i < sizeof(paths)/sizeof(paths[0]); i++) 68 if (!strcmp (cmd, paths[i].name)) 69 return paths[i].path; /* never NULL */ 70 gripe (GETVAL_ERROR, cmd); 71 return ""; /* impossible */ 72} 73 74static void 75adddir (const char *bp, int mandatory) { 76 int i; 77 struct dirs *dlp; 78 79 while (whitespace(*bp)) 80 bp++; 81 if (*bp == 0) 82 gripe (PARSE_ERROR_IN_CONFIG); 83 84 dlp = &cfdirlist; 85 while (dlp->nxt) 86 dlp = dlp->nxt; 87 dlp->nxt = (struct dirs *) my_malloc (sizeof(struct dirs)); 88 dlp = dlp->nxt; 89 dlp->mandatory = mandatory; 90 dlp->nxt = 0; 91 92 if (!mandatory) { 93 i = 0; 94 while (*bp && !whitespace(*bp)) { 95 if (i < MAXPATHLEN - 1) 96 dlp->bindir[i++] = *bp; 97 bp++; 98 } 99 dlp->bindir[i] = 0; 100 101 while (whitespace(*bp)) 102 bp++; 103 } else { 104 dlp->bindir[0] = 0; 105 } 106 107 i = 0; 108 while (*bp && !whitespace(*bp)) { 109 if (i < MAXPATHLEN - 1) 110 dlp->mandir[i++] = *bp; 111 bp++; 112 } 113 dlp->mandir[i] = 0; 114 115 while (whitespace(*bp)) 116 bp++; 117 118 i = 0; 119 while (*bp && !whitespace(*bp)) { 120 if (i < MAXPATHLEN - 1) 121 dlp->catdir[i++] = *bp; 122 bp++; 123 } 124 dlp->catdir[i] = 0; 125 126 if (debug) { 127 if (dlp->mandatory) 128 gripe (FOUND_MANDIR, dlp->mandir); 129 else 130 gripe (FOUND_MAP, dlp->bindir, dlp->mandir); 131 if (dlp->catdir[0]) 132 gripe (FOUND_CATDIR, dlp->catdir); 133 } 134} 135 136static void 137addglobdir (const char *bp, int mandatory) { 138 const char *dir; 139 140 while (whitespace(*bp)) 141 bp++; 142 143 dir = bp; 144 if (index(dir, '*') || index(dir, '?') || index(dir, '[')) { 145 char **dp = glob_filename (dir); 146 147 if (dp && dp != (char **) -1) { 148 while (*dp) 149 adddir(*dp++, mandatory); 150 return; 151 } 152 } 153 adddir(dir, mandatory); 154} 155 156static struct xp { 157 char *extension; /* non-null, including initial . */ 158 char *expander; 159 struct xp *nxt; 160} uncompressors; /* linked list, 1st entry unused */ 161 162static void 163addext (char *bp) { 164 char *p, csv; 165 struct xp *xpp; 166 167 xpp = &uncompressors; 168 while (xpp->nxt) 169 xpp = xpp->nxt; 170 xpp->nxt = (struct xp *) my_malloc (sizeof(struct xp)); 171 xpp = xpp->nxt; 172 xpp->nxt = 0; 173 174 p = bp; 175 while(*p && !whitespace(*p)) 176 p++; 177 csv = *p; 178 *p = 0; 179 xpp->extension = my_strdup(bp); 180 181 *p = csv; 182 while(whitespace(*p)) 183 p++; 184 xpp->expander = my_strdup(p); 185} 186 187const char * 188get_expander (const char *file) { 189 struct xp *xp; 190 char *extp = NULL; 191 192 if (dohp) { 193 /* Some HP systems have both man1 and man1.Z */ 194 /* For man1.Z/file.1 let extp=".Z" */ 195 /* For .1 return NULL */ 196 int len = strlen (dohp); 197 char *dirname_end = rindex (file, '/'); 198 if (dirname_end && !strncmp (dirname_end-len, dohp, len)) 199 extp = dohp; 200 } else 201 extp = rindex (file, '.'); 202 if (extp != NULL) { 203 if (uncompressors.nxt) { 204 for (xp = uncompressors.nxt; xp; xp = xp->nxt) 205 if (!strcmp (extp, xp->extension)) 206 return (xp->expander); 207 } else if (!strcmp (extp, getval("COMPRESS_EXT"))) { 208 return getval("DECOMPRESS"); 209 } 210 } 211 return NULL; 212} 213 214const char *configuration_file = "[no configuration file]"; 215 216char *default_config_files[] = { 217 CONFIG_FILE, /* compiled-in default */ 218 "/etc/man.conf", "/etc/man.config", 219 "/usr/lib/man.conf", "/usr/lib/man.config", 220 "/usr/share/misc/man.conf", "/usr/share/misc/man.config" 221}; 222 223#define SIZE(x) (sizeof(x)/sizeof((x)[0])) 224 225void 226read_config_file (const char *cf) { 227 char *bp; 228 char *p; 229 char buf[BUFSIZE]; 230 FILE *config = NULL; 231 232 if (cf) { 233 /* User explicitly specified a config file */ 234 if ((config = fopen (cf, "r")) == NULL) { 235 perror (cf); 236 gripe (CONFIG_OPEN_ERROR, cf); 237 return; 238 } 239 } else { 240 /* Try some things - unfortunately we cannot lookup 241 the config file to use in the config file :-). */ 242 int i; 243 244 for(i=0; i < SIZE(default_config_files); i++) { 245 cf = default_config_files[i]; 246 if ((config = fopen (cf, "r")) != NULL) 247 break; 248 } 249 250 if (config == NULL) { 251 gripe (CONFIG_OPEN_ERROR, CONFIG_FILE); 252 return; 253 } 254 } 255 256 if (debug) 257 fprintf(stderr, "Reading config file %s\n", cf); 258 configuration_file = cf; 259 260 while ((bp = fgets (buf, BUFSIZE, config)) != NULL) { 261 while (whitespace(*bp)) 262 bp++; 263 264 for (p = bp; *p && *p != '#' && *p != '\n'; p++) ; 265 if (!*p) { 266 gripe (LINE_TOO_LONG); 267 gripe (BAD_CONFIG_FILE, cf); 268 return; 269 } 270 while (p > bp && whitespace(p[-1])) 271 p--; 272 *p = 0; 273 274 if (*bp == 0) 275 continue; 276 277 if (!strncmp ("MANPATH_MAP", bp, 11)) 278 adddir (bp+11, 0); 279 else if (!strncmp ("MANPATH", bp, 7)) 280 addglobdir (bp+7, 1); 281 else if(!strncmp ("MANDATORY_MANPATH", bp, 17))/* backwards compatible */ 282 adddir (bp+17, 1); 283 else if (!strncmp ("FHS", bp, 3)) 284 fhs = 1; 285 else if (!strncmp ("FSSTND", bp, 6)) 286 fsstnd = 1; 287 else if (!strncmp ("NOAUTOPATH", bp, 10)) 288 noautopath = 1; 289 else if (!strncmp ("NOCACHE", bp, 7)) 290 nocache = 1; 291 else if (*bp == '.') 292 addext (bp); 293 else 294 addval (bp); 295 } 296} 297 298