4 * Copyright (c) 1990, 1991, John W. Eaton.
6 * You may distribute under the terms of the GNU General Public
7 * License as specified in the file COPYING that comes with the man
12 * Department of Chemical Engineering
13 * The University of Texas at Austin
23 #include <sys/types.h>
32 extern int fprintf ();
34 extern int strncmp ();
35 extern char *memcpy ();
36 extern char *getenv();
37 extern char *malloc();
42 extern char *strdup ();
43 extern int is_directory ();
52 extern char *strcpy ();
62 * Examine user's PATH and print a reasonable MANPATH.
73 extern char *mkprogname ();
79 prognam = mkprogname (argv[0]);
81 while ((c = getopt (argc, argv, "dhLq?")) != -1)
102 mp = manpath (quiet);
104 fprintf (stdout, "%s\n", mp);
113 fprintf (stderr, "usage: %s [-dLq]\n", prognam);
119 * If the environment variable MANPATH is set, return it.
120 * If the environment variable PATH is set and has a nonzero length,
121 * try to determine the corresponding manpath, otherwise, return the
124 * The manpath.config file is used to map system wide /bin directories
125 * to top level man page directories.
127 * For directories which are in the user's path but not in the
128 * manpath.config file, see if there is a subdirectory `man' or `MAN'.
129 * If so, add that directory to the path. Example: user has
130 * $HOME/bin in his path and the directory $HOME/bin/man exists -- the
131 * directory $HOME/bin/man will be added to the manpath.
133 * Also search for a `man' directory next to the directory on the path.
134 * Example: $HOME/bin will look for $HOME/man
141 register char *manpathlist;
145 char *get_manpath ();
148 gripe_reading_mp_config (config_file);
153 if ((manpathlist = getenv ("MANLOCALES")) != NULL)
159 fprintf (stderr, "(Warning: MANLOCALES environment variable set)\n");
160 return strdup (manpathlist);
162 return (man_locales ? man_locales : "");
166 if ((manpathlist = getenv ("MANPATH")) != NULL)
172 fprintf (stderr, "(Warning: MANPATH environment variable set)\n");
173 return strdup (manpathlist);
175 else if ((path = getenv ("PATH")) == NULL)
177 * Things aren't going to work well, but hey...
181 fprintf (stderr, "Warning: path not set\n");
182 return def_path (perrs);
186 if ((len = strlen (path)) == 0)
188 * Things aren't going to work well here either...
192 fprintf (stderr, "Warning: path set but has zero length\n");
193 return def_path (perrs);
195 return get_manpath (perrs, path);
200 * Get the list of bin directories and the corresponding man
201 * directories from the manpath.config file.
215 if ((config = fopen (config_file, "r")) == NULL)
216 gripe_getting_mp_config (config_file);
218 while ((bp = fgets (buf, BUFSIZ, config)) != NULL)
220 while (*bp && (*bp == ' ' || *bp == '\t'))
223 if (*bp == '#' || *bp == '\n')
226 if (!strncmp ("MANDATORY_MANPATH", bp, 17) ||
227 !strncmp ("OPTIONAL_MANPATH", bp, 16))
229 if ((p = strchr (bp, ' ')) == NULL &&
230 (p = strchr (bp, '\t')) == NULL) {
235 dlp->type = *bp == 'M'? MANPATH_MANDATORY: MANPATH_OPTIONAL;
239 while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
243 while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
244 dlp->mandir[i++] = *bp++;
245 dlp->mandir[i] = '\0';
248 fprintf (stderr, "found %s man directory %s\n",
249 dlp->type == MANPATH_MANDATORY? "mandatory": "optional",
252 else if (!strncmp ("MANPATH_MAP", bp, 11))
254 if ((p = strchr (bp, ' ')) == NULL &&
255 (p = strchr (bp, '\t')) == NULL) {
262 dlp->type = MANPATH_MAP;
264 while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
268 while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
269 dlp->bin[i++] = *bp++;
272 while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
276 while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
277 dlp->mandir[i++] = *bp++;
278 dlp->mandir[i] = '\0';
281 fprintf (stderr, "found manpath map %s --> %s\n",
282 dlp->bin, dlp->mandir);
284 else if (!strncmp ("MANLOCALES", bp, 10))
286 if ((p = strchr (bp, ' ')) == NULL &&
287 (p = strchr (bp, '\t')) == NULL) {
294 while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
297 for (p = bp; *p && *p != '\n'; p++)
301 } while (p >= bp && (*p == ' ' || *p == '\t'));
304 if (man_locales != NULL)
307 if ((man_locales = strdup (bp)) == NULL) {
314 fprintf (stderr, "found man locales: %s\n", bp);
318 gripe_reading_mp_config (config_file);
325 dlp->mandir[0] = '\0';
326 dlp->type = MANPATH_NONE;
332 * Construct the default manpath. This picks up mandatory
333 * and optional (if they exist) manpaths only.
340 register char *manpathlist, *p;
341 register DIRLIST *dlp;
345 while (dlp->type != MANPATH_NONE) {
346 if (dlp->type == MANPATH_MANDATORY || dlp->type == MANPATH_OPTIONAL)
347 len += strlen (dlp->mandir) + 1;
351 manpathlist = (char *) malloc (len);
352 if (manpathlist == NULL)
353 gripe_alloc (len, "manpathlist");
359 while (dlp->type != MANPATH_NONE) {
360 if (dlp->type == MANPATH_MANDATORY || dlp->type == MANPATH_OPTIONAL) {
362 char *path = dlp->mandir;
364 status = is_directory(path);
366 if (status < 0 && perrs && dlp->type == MANPATH_MANDATORY)
368 fprintf (stderr, "Warning: couldn't stat file %s!\n", path);
370 else if (status == 0 && perrs)
372 fprintf (stderr, "Warning: %s isn't a directory!\n", path);
374 else if (status == 1)
377 memcpy (p, path, len);
391 * For each directory in the user's path, see if it is one of the
392 * directories listed in the manpath.config file. If so, and it is
393 * not already in the manpath, add it. If the directory is not listed
394 * in the manpath.config file, see if there is a subdirectory `man' or
395 * `MAN'. If so, and it is not already in the manpath, add it.
396 * Example: user has $HOME/bin in his path and the directory
397 * $HOME/bin/man exists -- the directory $HOME/bin/man will be added
401 get_manpath (perrs, path)
406 register char *tmppath;
411 register char *manpathlist;
412 register DIRLIST *dlp;
413 void add_dir_to_list ();
414 char *has_subdirs ();
416 tmppath = strdup (path);
418 for (p = tmppath; ; p = end+1)
420 if ((end = strchr(p, ':')) != NULL)
424 fprintf (stderr, "\npath directory %s ", p);
429 fprintf (stderr, "is not an absolute pathname\n");
431 goto found; /* skip. */
435 * The directory we're working on is in the config file.
436 * If we haven't added it to the list yet, do.
438 for (dlp = list; dlp->mandir[0] != '\0'; dlp++)
439 if (dlp->bin[0] != '\0' && !strcmp (p, dlp->bin))
442 fprintf (stderr, "is in the config file\n");
444 add_dir_to_list (tmplist, dlp->mandir, perrs);
449 * The directory we're working on isn't in the config file. See
450 * if it has man or MAN subdirectories. If so, and it hasn't
451 * been added to the list, do.
454 fprintf (stderr, "is not in the config file\n");
460 fprintf (stderr, "but it does have a man or MAN subdirectory\n");
462 add_dir_to_list (tmplist, t, perrs);
468 fprintf (stderr, "and doesn't have man or MAN subdirectories\n");
478 fprintf (stderr, "\nadding mandatory man directories\n\n");
481 while (dlp->type != MANPATH_NONE) {
482 if (dlp->type == MANPATH_MANDATORY || dlp->type == MANPATH_OPTIONAL)
483 add_dir_to_list (tmplist, dlp->mandir,
484 dlp->type == MANPATH_MANDATORY? perrs: 0);
492 len += strlen (*lp) + 1;
499 manpathlist = (char *) malloc (len);
500 if (manpathlist == NULL)
501 gripe_alloc (len, "manpathlist");
510 memcpy (p, *lp, len);
522 * Add a directory to the manpath list if it isn't already there.
525 add_dir_to_list (lp, dir, perrs)
530 extern char *strdup ();
535 if (!strcmp (*lp, dir))
538 fprintf (stderr, "%s is already in the manpath\n", dir);
544 * Not found -- add it.
546 status = is_directory(dir);
548 if (status < 0 && perrs)
550 fprintf (stderr, "Warning: couldn't stat file %s!\n", dir);
552 else if (status == 0 && perrs)
554 fprintf (stderr, "Warning: %s isn't a directory!\n", dir);
556 else if (status == 1)
559 fprintf (stderr, "adding %s to manpath\n", dir);
566 * Check to see if the current directory has man or MAN
578 t = (char *) malloc ((unsigned) len + 5);
580 gripe_alloc (len+5, "p\n");
583 strcpy (t + len, "/man");
585 if (is_directory (t) == 1)
588 strcpy (t + len, "/MAN");
590 if (is_directory (t) == 1)
593 /* If the path ends in `bin' then replace with `man' and see if that works. */
594 if (len > 3 && strncmp(t+len-4, "/bin", 4) == 0) {
595 strcpy(t+len-4, "/man");
597 if (is_directory(t) == 1)