1#include <stdio.h> 2#include <stdlib.h> 3#include <unistd.h> 4#include <string.h> 5 6#include "defs.h" 7#include "gripes.h" 8#include "man.h" 9#include "man-config.h" 10#include "man-getopt.h" 11#include "util.h" 12#include "version.h" 13 14int alt_system; 15char *alt_system_name; 16char *opt_manpath; 17int global_apropos = 0; 18 19static void 20print_version (void) { 21 gripe (VERSION, progname, version); 22} 23 24static void 25usage (void) { 26 print_version(); 27 gripe (USAGE1, progname); 28 29 gripe (USAGE2); /* only for alt_systems */ 30 31 gripe (USAGE3); 32 gripe (USAGE4); 33 gripe (USAGE5); /* maybe only if troff found? */ 34 gripe (USAGE6); 35 36 gripe (USAGE7); /* only for alt_systems */ 37 38 gripe (USAGE8); 39 exit(1); 40} 41 42static char short_opts[] = "B:C:H:xM:P:S:acdfFhkKm:p:s:tvVwW?Lq"; 43 44#ifndef NOGETOPT 45#undef _GNU_SOURCE 46#define _GNU_SOURCE 47#include <getopt.h> 48 49static const struct option long_opts[] = { 50 { "help", no_argument, NULL, 'h' }, 51 { "version", no_argument, NULL, 'v' }, 52 { "path", no_argument, NULL, 'w' }, 53 { "preformat", no_argument, NULL, 'F' }, 54 { NULL, 0, NULL, 0 } 55}; 56#endif 57 58/* 59 * Read options, return count. 60 */ 61static int 62get_options_from_argvec(int argc, char **argv, char **config_file, 63 char **manpath) { 64 char *s; 65 int c; 66 int optct = 0; 67 68#ifndef NOGETOPT 69 while ((c = getopt_long (argc, argv, short_opts, long_opts, NULL)) != -1){ 70#else 71 while ((c = getopt (argc, argv, short_opts)) != -1) { 72#endif 73 switch (c) { 74 case 'C': 75 no_privileges (); 76 if (config_file) 77 *config_file = my_strdup (optarg); 78 break; 79 case'F': 80 preformat = 1; 81 break; 82 case 'M': 83 if (manpath) 84 *manpath = my_strdup (optarg); 85 break; 86 case 'P': 87 pager = my_strdup (optarg); 88 break; 89 case 'B': 90 browser = my_strdup (optarg); 91 break; 92 case 'H': 93 htmlpager = my_strdup (optarg); 94 break; 95 case 'S': 96 colon_sep_section_list = my_strdup (optarg); 97 break; 98 case 's': 99 /* undocumented; compatibility with Sun */ 100 s = colon_sep_section_list = my_strdup (optarg); 101 while (*s) { 102 if (*s == ',') 103 *s = ':'; 104 s++; 105 } 106 break; 107 case 'a': 108 findall++; 109 break; 110 case 'c': 111 nocats++; 112 break; 113 case 'd': 114 debug++; 115 break; 116 case 'f': 117 if (do_troff) 118 fatal (INCOMPAT, "-f", "-t"); 119 if (apropos) 120 fatal (INCOMPAT, "-f", "-k"); 121 if (print_where) 122 fatal (INCOMPAT, "-f", "-w"); 123 whatis++; 124 break; 125 case 'k': 126 if (do_troff) 127 fatal (INCOMPAT, "-k", "-t"); 128 if (whatis) 129 fatal (INCOMPAT, "-k", "-f"); 130 if (print_where) 131 fatal (INCOMPAT, "-k", "-w"); 132 apropos++; 133 break; 134 case 'K': 135 global_apropos++; 136 break; 137 case 'm': 138 alt_system++; 139 alt_system_name = my_strdup (optarg); 140 break; 141 /* or: gripe (NO_ALTERNATE); exit(1); */ 142 case 'p': 143 roff_directive = my_strdup (optarg); 144 break; 145 case 't': 146 if (apropos) 147 fatal (INCOMPAT, "-t", "-k"); 148 if (whatis) 149 fatal (INCOMPAT, "-t", "-f"); 150 if (print_where) 151 fatal (INCOMPAT, "-t", "-w"); 152 do_troff++; 153 break; 154 case 'v': 155 case 'V': 156 print_version(); 157 exit(0); 158 case 'W': 159 one_per_line++; 160 /* fall through */ 161 case 'w': 162 if (apropos) 163 fatal (INCOMPAT, "-w", "-k"); 164 if (whatis) 165 fatal (INCOMPAT, "-w", "-f"); 166 if (do_troff) 167 fatal (INCOMPAT, "-w", "-t"); 168 print_where++; 169 break; 170 /* Silently ignore manpath -q and -L (3825529). */ 171 case 'L': 172 case 'q': 173 if (!strncmp(progname, "manpath", 7)) 174 break; 175 case 'h': 176 case '?': 177 default: 178 usage(); 179 break; 180 } 181 optct++; 182 } 183 184 return optct; 185} 186 187static void 188get_options_from_string(const char *s) { 189 char *s0, *ss; 190 int argct; 191 char **argvec; 192 int optindsv; 193 194 if (!s || *s == 0) 195 return; 196 197 /* In order to avoid having a list of options in two places, 198 massage the string so that it can be fed to getopt() */ 199 200 s0 = my_strdup(s); 201 202 /* count arguments */ 203 argct = 0; 204 ss = s0; 205 while (*ss) { 206 while (*ss == ' ') 207 ss++; 208 if (*ss) { 209 argct++; 210 while (*ss && *ss != ' ') 211 ss++; 212 } 213 } 214 215 /* allocate argvec */ 216 argvec = (char **) my_malloc((argct+2)*sizeof(char *)); 217 argct = 0; 218 argvec[argct++] = "dummy"; 219 ss = s0; 220 while (*ss) { 221 while (*ss == ' ') 222 *ss++ = 0; 223 if (*ss) { 224 argvec[argct++] = ss; 225 while (*ss && *ss != ' ') 226 ss++; 227 } 228 } 229 argvec[argct] = 0; 230 231 optindsv = optind; 232 optind = 1; 233 get_options_from_argvec(argct, argvec, NULL, NULL); 234 optind = optindsv; 235} 236 237static void 238mysetenv(const char *name, const char *value) { 239#if defined(__sgi__) || defined(__sun__) || defined(sun) 240 int len = strlen(value)+1+strlen(value)+1; 241 char *str = my_malloc(len); 242 sprintf(str, "%s=%s", name, value); 243 putenv(str); 244#else 245 setenv(name, value, 1); 246#endif 247} 248 249/* 250 * Get options from the command line and user environment. 251 * Also reads the configuration file. 252 */ 253 254void 255man_getopt (int argc, char **argv) { 256 char *config_file = NULL; 257 char *manp = NULL; 258 int optct = 0; 259 260 optct = get_options_from_argvec(argc, argv, &config_file, &manp); 261 262 read_config_file (config_file); 263 264 /* If no options were given and MANDEFOPTIONS is set, use that */ 265 if (optct == 0) { 266 const char *defopts = getval ("MANDEFOPTIONS"); 267 get_options_from_string(defopts); 268 } 269 270 /* In case an explicit -P option was given, put it in the 271 environment for possible use with -k or -K. 272 Ignore errors (out of memory?) */ 273 274 if (pager && (global_apropos || apropos || whatis)) 275 mysetenv("PAGER", pager); 276 277 if (pager == NULL || *pager == '\0') 278 if ((pager = getenv ("MANPAGER")) == NULL) 279 if ((pager = getenv ("PAGER")) == NULL) 280 pager = getval ("PAGER"); 281 282 if (debug) 283 gripe (PAGER_IS, pager); 284 285 /* Ditto for BROWSER and -B */ 286 if (browser && (global_apropos || apropos || whatis)) 287 mysetenv("BROWSER", browser); 288 289 if (browser == NULL || *browser == '\0') 290 if ((browser = getenv ("BROWSER")) == NULL) 291 browser = getval ("BROWSER"); 292 293 if (debug) 294 gripe (BROWSER_IS, browser); 295 296 /* Ditto for HTMLHTMLPAGER and -D */ 297 if (htmlpager && (global_apropos || apropos || whatis)) 298 mysetenv("HTMLPAGER", htmlpager); 299 300 if (htmlpager == NULL || *htmlpager == '\0') 301 if ((htmlpager = getenv ("HTMLPAGER")) == NULL) 302 htmlpager = getval ("HTMLPAGER"); 303 304 if (debug) 305 gripe (HTMLPAGER_IS, htmlpager); 306 307 if (do_compress && !*getval ("COMPRESS")) { 308 if (debug) 309 gripe (NO_COMPRESS); 310 do_compress = 0; 311 } 312 313 if (do_troff && !*getval ("TROFF")) { 314 gripe (NO_TROFF, configuration_file); 315 exit (1); 316 } 317 318 opt_manpath = manp; /* do not yet expand manpath - 319 maybe it is not needed */ 320 321 if (alt_system_name == NULL || *alt_system_name == '\0') 322 if ((alt_system_name = getenv ("SYSTEM")) != NULL) 323 alt_system_name = my_strdup (alt_system_name); 324 325} 326