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
16 * $FreeBSD: src/gnu/usr.bin/man/manpath/manpath.c,v 1.11.2.2 2003/02/15 05:33:06 kris Exp $
17 * $DragonFly: src/gnu/usr.bin/man/manpath/manpath.c,v 1.5 2008/07/10 18:29:51 swildner Exp $
24 #include <sys/types.h>
33 extern int fprintf ();
35 extern int strncmp ();
36 extern char *memcpy ();
37 extern char *getenv();
38 extern char *malloc();
43 extern char *strdup ();
44 extern int is_directory ();
53 extern char *strcpy ();
63 * Examine user's PATH and print a reasonable MANPATH.
74 extern char *mkprogname ();
80 prognam = mkprogname (argv[0]);
82 while ((c = getopt (argc, argv, "dhLq?")) != -1)
103 mp = manpath (quiet);
105 fprintf (stdout, "%s\n", mp);
114 fprintf (stderr, "usage: %s [-dLq]\n", prognam);
120 * If the environment variable MANPATH is set, return it.
121 * If the environment variable PATH is set and has a nonzero length,
122 * try to determine the corresponding manpath, otherwise, return the
125 * The manpath.config file is used to map system wide /bin directories
126 * to top level man page directories.
128 * For directories which are in the user's path but not in the
129 * manpath.config file, see if there is a subdirectory `man' or `MAN'.
130 * If so, add that directory to the path. Example: user has
131 * $HOME/bin in his path and the directory $HOME/bin/man exists -- the
132 * directory $HOME/bin/man will be added to the manpath.
134 * Also search for a `man' directory next to the directory on the path.
135 * Example: $HOME/bin will look for $HOME/man
142 register char *manpathlist;
146 char *get_manpath ();
149 gripe_reading_mp_config (config_file);
154 if ((manpathlist = getenv ("MANLOCALES")) != NULL)
160 fprintf (stderr, "(Warning: MANLOCALES environment variable set)\n");
161 return strdup (manpathlist);
163 return (man_locales ? man_locales : "");
167 if ((manpathlist = getenv ("MANPATH")) != NULL)
173 fprintf (stderr, "(Warning: MANPATH environment variable set)\n");
174 return strdup (manpathlist);
176 else if ((path = getenv ("PATH")) == NULL)
178 * Things aren't going to work well, but hey...
182 fprintf (stderr, "Warning: path not set\n");
183 return def_path (perrs);
187 if ((len = strlen (path)) == 0)
189 * Things aren't going to work well here either...
193 fprintf (stderr, "Warning: path set but has zero length\n");
194 return def_path (perrs);
196 return get_manpath (perrs, path);
201 * Get the list of bin directories and the corresponding man
202 * directories from the manpath.config file.
216 if ((config = fopen (config_file, "r")) == NULL)
217 gripe_getting_mp_config (config_file);
219 while ((bp = fgets (buf, BUFSIZ, config)) != NULL)
221 while (*bp && (*bp == ' ' || *bp == '\t'))
224 if (*bp == '#' || *bp == '\n')
227 if (!strncmp ("MANDATORY_MANPATH", bp, 17) ||
228 !strncmp ("OPTIONAL_MANPATH", bp, 16))
230 if ((p = strchr (bp, ' ')) == NULL &&
231 (p = strchr (bp, '\t')) == NULL) {
236 dlp->type = *bp == 'M'? MANPATH_MANDATORY: MANPATH_OPTIONAL;
240 while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
244 while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
245 dlp->mandir[i++] = *bp++;
246 dlp->mandir[i] = '\0';
249 fprintf (stderr, "found %s man directory %s\n",
250 dlp->type == MANPATH_MANDATORY? "mandatory": "optional",
253 else if (!strncmp ("MANPATH_MAP", bp, 11))
255 if ((p = strchr (bp, ' ')) == NULL &&
256 (p = strchr (bp, '\t')) == NULL) {
263 dlp->type = MANPATH_MAP;
265 while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
269 while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
270 dlp->bin[i++] = *bp++;
273 while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
277 while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
278 dlp->mandir[i++] = *bp++;
279 dlp->mandir[i] = '\0';
282 fprintf (stderr, "found manpath map %s --> %s\n",
283 dlp->bin, dlp->mandir);
285 else if (!strncmp ("MANLOCALES", bp, 10))
287 if ((p = strchr (bp, ' ')) == NULL &&
288 (p = strchr (bp, '\t')) == NULL) {
295 while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
298 for (p = bp; *p && *p != '\n'; p++)
302 } while (p >= bp && (*p == ' ' || *p == '\t'));
305 if (man_locales != NULL)
308 if ((man_locales = strdup (bp)) == NULL) {
315 fprintf (stderr, "found man locales: %s\n", bp);
319 gripe_reading_mp_config (config_file);
326 dlp->mandir[0] = '\0';
327 dlp->type = MANPATH_NONE;
333 * Construct the default manpath. This picks up mandatory
334 * and optional (if they exist) manpaths only.
341 register char *manpathlist, *p;
342 register DIRLIST *dlp;
346 while (dlp->type != MANPATH_NONE) {
347 if (dlp->type == MANPATH_MANDATORY || dlp->type == MANPATH_OPTIONAL)
348 len += strlen (dlp->mandir) + 1;
352 manpathlist = (char *) malloc (len);
353 if (manpathlist == NULL)
354 gripe_alloc (len, "manpathlist");
360 while (dlp->type != MANPATH_NONE) {
361 if (dlp->type == MANPATH_MANDATORY || dlp->type == MANPATH_OPTIONAL) {
363 char *path = dlp->mandir;
365 status = is_directory(path);
367 if (status < 0 && perrs && dlp->type == MANPATH_MANDATORY)
369 fprintf (stderr, "Warning: couldn't stat file %s!\n", path);
371 else if (status == 0 && perrs)
373 fprintf (stderr, "Warning: %s isn't a directory!\n", path);
375 else if (status == 1)
378 memcpy (p, path, len);
392 * For each directory in the user's path, see if it is one of the
393 * directories listed in the manpath.config file. If so, and it is
394 * not already in the manpath, add it. If the directory is not listed
395 * in the manpath.config file, see if there is a subdirectory `man' or
396 * `MAN'. If so, and it is not already in the manpath, add it.
397 * Example: user has $HOME/bin in his path and the directory
398 * $HOME/bin/man exists -- the directory $HOME/bin/man will be added
402 get_manpath (perrs, path)
407 register char *tmppath;
412 register char *manpathlist;
413 register DIRLIST *dlp;
414 void add_dir_to_list ();
415 char *has_subdirs ();
418 tmppath = strdup (path);
420 for (p = tmppath; ; p = end+1)
422 if ((end = strchr(p, ':')) != NULL)
426 fprintf (stderr, "\npath directory %s ", p);
431 fprintf (stderr, "is not an absolute pathname\n");
433 goto found; /* skip. */
437 * The directory we're working on is in the config file.
438 * If we haven't added it to the list yet, do.
440 for (dlp = list; dlp->mandir[0] != '\0'; dlp++)
441 if (dlp->bin[0] != '\0' && !strcmp (p, dlp->bin))
444 fprintf (stderr, "is in the config file\n");
446 add_dir_to_list (tmplist, dlp->mandir, perrs);
456 * The directory we're working on isn't in the config file. See
457 * if it has man or MAN subdirectories. If so, and it hasn't
458 * been added to the list, do.
461 fprintf (stderr, "is not in the config file\n");
467 fprintf (stderr, "but it does have a man or MAN subdirectory\n");
469 add_dir_to_list (tmplist, t, perrs);
475 fprintf (stderr, "and doesn't have man or MAN subdirectories\n");
485 fprintf (stderr, "\nadding mandatory man directories\n\n");
488 while (dlp->type != MANPATH_NONE) {
489 if (dlp->type == MANPATH_MANDATORY || dlp->type == MANPATH_OPTIONAL)
490 add_dir_to_list (tmplist, dlp->mandir,
491 dlp->type == MANPATH_MANDATORY? perrs: 0);
499 len += strlen (*lp) + 1;
506 manpathlist = (char *) malloc (len);
507 if (manpathlist == NULL)
508 gripe_alloc (len, "manpathlist");
517 memcpy (p, *lp, len);
529 * Add a directory to the manpath list if it isn't already there.
532 add_dir_to_list (lp, dir, perrs)
537 extern char *strdup ();
542 if (!strcmp (*lp, dir))
545 fprintf (stderr, "%s is already in the manpath\n", dir);
551 * Not found -- add it.
553 status = is_directory(dir);
555 if (status < 0 && perrs)
557 fprintf (stderr, "Warning: couldn't stat file %s!\n", dir);
559 else if (status == 0 && perrs)
561 fprintf (stderr, "Warning: %s isn't a directory!\n", dir);
563 else if (status == 1)
566 fprintf (stderr, "adding %s to manpath\n", dir);
573 * Check to see if the current directory has man or MAN
585 t = (char *) malloc ((unsigned) len + 5);
587 gripe_alloc (len+5, "p\n");
590 strcpy (t + len, "/man");
592 if (is_directory (t) == 1)
595 strcpy (t + len, "/MAN");
597 if (is_directory (t) == 1)
600 /* If the path ends in `bin' then replace with `man' and see if that works. */
601 if (len > 3 && strncmp(t+len-4, "/bin", 4) == 0) {
602 strcpy(t+len-4, "/man");
604 if (is_directory(t) == 1)