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/man/man.c,v 1.37.2.10 2003/02/14 15:38:51 ru Exp $
23 #include <sys/param.h>
41 extern char **glob_filename (char *);
42 extern char *manpath (int);
44 char *is_section (char *);
45 char **get_section_list (void);
46 void man_getopt (int, char **);
47 void do_apropos (char *);
48 void do_whatis (char *);
51 char **add_dir_to_mpath_list (char **, char *);
52 char *convert_name (char *, int);
53 char **glob_for_file (char *, char *, char *, char *, int);
54 char **make_name (char *, char *, char *, char *, int);
55 const char *get_expander (char *);
56 int display_cat_file (char *);
57 char *ultimate_source (char *, char *);
58 void add_directive (int *, const char *, char *, char *, int);
59 int parse_roff_directive (const char *, char *, char *, int);
60 char *make_roff_command (char *);
63 void restore_sigs(void);
64 int make_cat_file (char *, char *, char *, int);
65 int format_and_display (char *, char *, char *);
66 int try_section (char *, char *, char *, char *, int);
70 static const char *machine;
72 static char *manpathlist[MAXDIRS];
73 static char *shortsec;
75 static char *colon_sep_section_list;
76 static char **section_list;
77 static char *roff_directive;
81 static int print_where;
83 static char *locale, *locale_codeset;
84 static const char *locale_nroff, *locale_opts;
85 static char locale_terr[3], locale_lang[3];
86 static char *man_locale;
87 static int use_man_locale;
88 static int use_original;
93 static struct ltable ltable[] = {
95 {"ISO8859-1", "latin1"},
96 {"ISO8859-15", "latin1"},
100 static int troff = 0;
104 static char args[] = "M:P:S:adfhkm:op:tw?";
112 main (int argc, char **argv)
118 prognam = mkprogname (argv[0]);
122 (void) setlocale(LC_ALL, "");
123 man_getopt (argc, argv);
126 gripe_no_name ((char *)NULL);
128 section_list = get_section_list ();
130 if (optind == argc - 1)
132 tmp = is_section (argv[optind]);
145 while (optind < argc)
147 nextarg = argv[optind++];
150 * See if this argument is a valid section name. If not,
151 * is_section returns NULL.
153 tmp = is_section (nextarg);
160 fprintf (stderr, "\nsection: %s\n", shortsec);
166 do_apropos (nextarg);
167 status = (status ? 0 : 1); /* reverts status, see below */
171 status = (status ? 0 : 1); /* reverts status, see below */
175 status = man (nextarg);
178 gripe_not_found (nextarg, longsec);
181 return (status==0); /* status==1 --> exit(0),
182 status==0 --> exit(1) */
188 static char usage_string[1024] = "%s, version %s\n\n";
191 "usage: %s [-adfhkotw] [section] [-M path] [-P pager] [-S list]\n\
192 [-m machine] [-p string] name ...\n\n";
194 static char s2[] = " a : find all matching entries\n\
195 d : print gobs of debugging information\n\
196 f : same as whatis(1)\n\
197 h : print this help message\n\
198 k : same as apropos(1)\n";
200 static char s3[] = " o : use original, non-localized manpages\n";
202 static char s4[] = " t : use troff to format pages for printing\n";
204 static char s5[] = " w : print location of man page(s) that would be displayed\n\n\
205 M path : set search path for manual pages to `path'\n\
206 P pager : use program `pager' to display pages\n\
207 S list : colon separated section list\n\
208 m machine : search for alternate architecture man pages\n";
210 static char s6[] = " p string : string tells which preprocessors to run\n\
211 e - [n]eqn(1) p - pic(1) t - tbl(1)\n\
212 g - grap(1) r - refer(1) v - vgrind(1)\n";
214 strcat (usage_string, s1);
215 strcat (usage_string, s2);
216 strcat (usage_string, s3);
218 strcat (usage_string, s4);
220 strcat (usage_string, s5);
222 strcat (usage_string, s6);
224 fprintf (stderr, usage_string, prognam, version, prognam);
229 add_dir_to_mpath_list (char **mp, char *p)
233 status = is_directory (p);
235 if (status < 0 && debug)
237 fprintf (stderr, "Warning: couldn't stat file %s!\n", p);
239 else if (status == 0 && debug)
241 fprintf (stderr, "Warning: %s isn't a directory!\n", p);
243 else if (status == 1)
246 fprintf (stderr, "adding %s to manpathlist\n", p);
254 * Get options from the command line and user environment.
257 man_getopt (int argc, char **argv)
264 while ((c = getopt (argc, argv, args)) != -1)
269 manp = strdup (optarg);
272 pager = strdup (optarg);
273 if (setenv("PAGER", pager, 1) != 0)
274 (void)fprintf(stderr, "setenv PAGER=%s\n", pager);
277 colon_sep_section_list = strdup (optarg);
287 gripe_incompatible ("-f and -t");
289 gripe_incompatible ("-f and -k");
291 gripe_incompatible ("-f and -w");
296 gripe_incompatible ("-k and -t");
298 gripe_incompatible ("-k and -f");
300 gripe_incompatible ("-k and -w");
310 roff_directive = strdup (optarg);
314 gripe_incompatible ("-t and -k");
316 gripe_incompatible ("-t and -f");
318 gripe_incompatible ("-t and -w");
323 gripe_incompatible ("-w and -k");
325 gripe_incompatible ("-w and -f");
327 gripe_incompatible ("-w and -t");
338 /* "" intentionally used to catch error */
339 if ((locale = setlocale(LC_CTYPE, "")) != NULL)
340 locale_codeset = nl_langinfo(CODESET);
341 if (!use_original && locale != NULL && *locale_codeset != '\0' &&
342 strcmp(locale_codeset, "US-ASCII") != 0
344 char *tmp, *short_locale;
345 struct ltable *pltable;
351 if ((short_locale = strdup(locale)) == NULL) {
352 perror ("ctype locale strdup");
355 if ((tmp = strchr(short_locale, '.')) != NULL)
358 locale_len = strlen(short_locale);
359 tmp = strchr(short_locale, '_');
360 if (locale_len == 5 && tmp == short_locale + 2) {
361 /* assume position 3 and 4 are not "_"; don't check */
362 strncpy(locale_terr, short_locale + 3, 2);
363 locale_terr[2] = '\0';
364 strncpy(locale_lang, short_locale, 2);
365 locale_lang[2] = '\0';
366 } else if (locale_len == 10 && tmp == short_locale + 2 &&
367 short_locale[7] == '_') {
368 /* assume positions 3-6 and 8-9 are not "_" */
369 strncpy(locale_terr, short_locale + 8, 2);
370 locale_terr[2] = '\0';
371 strncpy(locale_lang, short_locale, 2);
372 locale_lang[2] = '\0';
375 perror ("ctype locale format");
381 if (locale != NULL) {
382 for (pltable = ltable; pltable->lcode != NULL; pltable++) {
383 if (strcmp(pltable->lcode, locale_codeset) == 0) {
384 locale_nroff = pltable->nroff;
388 asprintf(&man_locale, "%s.%s", locale_lang, locale_codeset);
391 if (locale == NULL) {
393 perror ("ctype locale");
396 if (*locale_codeset == '\0') {
398 perror ("ctype codeset");
403 if (pager == NULL || *pager == '\0')
404 if ((pager = getenv ("PAGER")) == NULL || *pager == '\0')
405 pager = strdup (PAGER);
408 fprintf (stderr, "\nusing %s as pager\n", pager);
410 if (machine == NULL && (machine = getenv ("MACHINE")) == NULL)
414 fprintf (stderr, "\nusing %s architecture\n", machine);
418 if ((manp = manpath (0)) == NULL)
423 "\nsearch path for pages determined by manpath is\n%s\n\n",
428 * Expand the manpath into a list for easier handling.
431 for (p = manp; ; p = end+1)
433 if (mp == manpathlist + MAXDIRS - 1) {
434 fprintf (stderr, "Warning: too many directories in manpath, truncated!\n");
437 if ((end = strchr (p, ':')) != NULL)
440 mp = add_dir_to_mpath_list (mp, p);
450 * Check to see if the argument is a valid section number. If the
451 * first character of name is a numeral, or the name matches one of
452 * the sections listed in section_list, we'll assume that it's a section.
453 * The list of sections in config.h simply allows us to specify oddly
454 * named directories like .../man3f. Yuk.
457 is_section (char *name)
460 char *temp, *end, *loc;
464 for (vs = section_list; *vs != NULL; vs++)
465 if ((strcmp (*vs, name) == 0)
466 || (isdigit ((unsigned char)name[0]) && strlen(name) == 1))
467 return (longsec = strdup (name));
470 if (isdigit ((unsigned char)name[0]))
472 while (*plist != NULL)
474 asprintf(&temp, "%s/man%c/*", *plist, name[0]);
478 vs = glob_filename (temp);
479 if (vs == (char **)-1)
484 for ( ; *vs != NULL; vs++)
486 end = strrchr (*vs, '/');
487 if ((loc = strstr (end, name)) != NULL && loc - end > 2
489 && (*(loc+strlen(name)) == '\0' || *(loc+strlen(name)) == '.'))
498 asprintf(&temp, "%c", name[0]);
499 longsec = strdup (name);
508 * Handle the apropos option. Cheat by using another program.
511 do_apropos (char *name)
516 len = strlen (APROPOS) + strlen (name) + 4;
518 if ((command = (char *) malloc(len)) == NULL)
519 gripe_alloc (len, "command");
521 sprintf (command, "%s \"%s\"", APROPOS, name);
523 (void) do_system_command (command);
529 * Handle the whatis option. Cheat by using another program.
532 do_whatis (char *name)
537 len = strlen (WHATIS) + strlen (name) + 4;
539 if ((command = (char *) malloc(len)) == NULL)
540 gripe_alloc (len, "command");
542 sprintf (command, "%s \"%s\"", WHATIS, name);
544 (void) do_system_command (command);
550 * Change a name of the form ...man/man1/name.1 to ...man/cat1/name.1
551 * or a name of the form ...man/cat1/name.1 to ...man/man1/name.1
554 convert_name (char *name, int to_cat)
562 int olen = strlen(name);
563 int cextlen = strlen(COMPRESS_EXT);
564 int len = olen + cextlen;
566 to_name = malloc (len+1);
568 gripe_alloc (len+1, "to_name");
569 strcpy (to_name, name);
571 /* Avoid tacking it on twice */
572 if (olen >= 1 && strcmp(name + olen, COMPRESS_EXT) != 0)
573 strcat (to_name, COMPRESS_EXT);
576 to_name = strdup (name);
578 t1 = strrchr (to_name, '/');
582 t2 = strrchr (to_name, '/');
585 /* Skip architecture part (if present). */
586 if (t2 != NULL && (t1 - t2 < 5 || *(t2 + 1) != 'm' || *(t2 + 3) != 'n'))
590 t2 = strrchr (to_name, '/');
596 gripe_converting_name (name, to_cat);
610 fprintf (stderr, "to_name in convert_name () is: %s\n", to_name);
616 * Try to find the man page corresponding to the given name. The
617 * reason we do this with globbing is because some systems have man
618 * page directories named man3 which contain files with names like
619 * XtPopup.3Xt. Rather than requiring that this program know about
620 * all those possible names, we simply try to match things like
621 * .../man[sect]/name[sect]*. This is *much* easier.
623 * Note that globbing is only done when the section is unspecified.
626 glob_for_file (char *path, char *section, char *_longsec, char *name, int cat)
628 char pathname[FILENAME_MAX];
631 if (_longsec == NULL)
635 snprintf (pathname, sizeof(pathname), "%s/cat%s/%s.%s*", path, section,
638 snprintf (pathname, sizeof(pathname), "%s/man%s/%s.%s*", path, section,
642 fprintf (stderr, "globbing %s\n", pathname);
644 gf = glob_filename (pathname);
646 if ((gf == (char **) -1 || *gf == NULL) && isdigit ((unsigned char)*section)
647 && strlen (_longsec) == 1)
650 snprintf (pathname, sizeof(pathname), "%s/cat%s/%s.%c*", path, section, name, *section);
652 snprintf (pathname, sizeof(pathname), "%s/man%s/%s.%c*", path, section, name, *section);
654 gf = glob_filename (pathname);
656 if ((gf == (char **) -1 || *gf == NULL) && isdigit ((unsigned char)*section)
657 && strlen (_longsec) == 1)
660 snprintf (pathname, sizeof(pathname), "%s/cat%s/%s.0*", path, section, name);
662 snprintf (pathname, sizeof(pathname), "%s/man%s/%s.0*", path, section, name);
664 fprintf (stderr, "globbing %s\n", pathname);
665 gf = glob_filename (pathname);
671 * Return an un-globbed name in the same form as if we were doing
675 make_name (char *path, char *section, char *_longsec, char *name, int cat)
678 static char *names[3];
679 char buf[FILENAME_MAX];
682 snprintf (buf, sizeof(buf), "%s/cat%s/%s.%s", path, section, name, _longsec);
684 snprintf (buf, sizeof(buf), "%s/man%s/%s.%s", path, section, name, _longsec);
686 if (access (buf, R_OK) == 0)
687 names[i++] = strdup (buf);
690 * If we're given a section that looks like `3f', we may want to try
691 * file names like .../man3/foo.3f as well. This seems a bit
692 * kludgey to me, but what the hey...
694 if (section[1] != '\0')
697 snprintf (buf, sizeof(buf), "%s/cat%c/%s.%s", path, section[0], name, section);
699 snprintf (buf, sizeof(buf), "%s/man%c/%s.%s", path, section[0], name, section);
701 if (access (buf, R_OK) == 0)
702 names[i++] = strdup (buf);
711 get_expander (char *file)
713 char *end = file + (strlen (file) - 1);
715 while (end > file && end[-1] != '.')
728 if (*end == 'Z' || !strcmp(end, "gz"))
735 * Simply display the preformatted page.
738 display_cat_file (char *file)
741 char command[FILENAME_MAX];
745 if (access (file, R_OK) == 0)
747 const char *expander = get_expander (file);
749 if (expander != NULL)
750 snprintf (command, sizeof(command), "%s %s | %s", expander, file, pager);
752 snprintf (command, sizeof(command), "%s %s", pager, file);
754 found = do_system_command (command);
760 * Try to find the ultimate source file. If the first line of the
761 * current file is not of the form
765 * the input file name is returned.
768 ultimate_source (char *name, char *path)
770 static char buf[BUFSIZ];
771 static char ult[FILENAME_MAX];
777 strncpy (ult, name, sizeof(ult)-1);
778 ult[sizeof(ult)-1] = '\0';
779 strncpy (buf, name, sizeof(buf)-1);
780 ult[sizeof(buf)-1] = '\0';
784 if ((fp = fopen (ult, "r")) == NULL)
787 end = fgets (buf, BUFSIZ, fp);
790 if (!end || strlen (buf) < 5)
794 if (*beg++ == '.' && *beg++ == 's' && *beg++ == 'o')
796 while ((*beg == ' ' || *beg == '\t') && *beg != '\0')
800 while (*end != ' ' && *end != '\t' && *end != '\n' && *end != '\0')
805 snprintf(ult, sizeof(ult), "%s/%s", path, beg);
806 snprintf(buf, sizeof(buf), "%s", ult);
812 fprintf (stderr, "found ultimate source file %s\n", ult);
818 add_directive (int *first, const char *d, char *file, char *buf, int bufsize)
820 if (strcmp (d, "") != 0)
825 snprintf(buf, bufsize, "%s %s", d, file);
829 strncat (buf, " | ", bufsize-strlen(buf)-1);
830 strncat (buf, d, bufsize-strlen(buf)-1);
836 parse_roff_directive (const char *cp, char *file, char *buf, int bufsize)
841 int preproc_found = 0;
844 if ((exp = get_expander(file)) != NULL)
845 add_directive (&first, exp, file, buf, bufsize);
847 while ((c = *cp++) != '\0')
854 fprintf (stderr, "found eqn(1) directive\n");
858 add_directive (&first, EQN, file, buf, bufsize);
860 char lbuf[FILENAME_MAX];
862 snprintf(lbuf, sizeof(lbuf), "%s -T%s", NEQN,
863 locale_opts == NULL ? "ascii" : locale_opts);
864 add_directive (&first, lbuf, file, buf, bufsize);
872 fprintf (stderr, "found grap(1) directive\n");
875 add_directive (&first, GRAP, file, buf, bufsize);
882 fprintf (stderr, "found pic(1) directive\n");
885 add_directive (&first, PIC, file, buf, bufsize);
892 fprintf (stderr, "found tbl(1) directive\n");
896 add_directive (&first, TBL, file, buf, bufsize);
902 fprintf (stderr, "found vgrind(1) directive\n");
904 add_directive (&first, VGRIND, file, buf, bufsize);
910 fprintf (stderr, "found refer(1) directive\n");
912 add_directive (&first, REFER, file, buf, bufsize);
930 add_directive (&first, TROFF, file, buf, bufsize);
933 char lbuf[FILENAME_MAX];
935 snprintf(lbuf, sizeof(lbuf), "%s -T%s%s%s", NROFF,
936 locale_opts == NULL ? "ascii" : locale_opts,
937 use_man_locale ? " -dlocale=" : "",
938 use_man_locale ? man_locale : "");
939 add_directive (&first, lbuf, file, buf, bufsize);
941 if (use_col && !troff)
942 add_directive (&first, COL, file, buf, bufsize);
951 make_roff_command (char *file)
955 static char buf [BUFSIZ];
959 if (roff_directive != NULL)
962 fprintf (stderr, "parsing directive from command line\n");
964 status = parse_roff_directive (roff_directive, file, buf, sizeof(buf));
970 gripe_roff_command_from_command_line ();
973 if ((fp = gzopen (file, "r")) != NULL)
976 gzgets (fp, line, BUFSIZ);
978 if (*cp++ == '\'' && *cp++ == '\\' && *cp++ == '"' && *cp++ == ' ')
981 fprintf (stderr, "parsing directive from file\n");
983 status = parse_roff_directive (cp, file, buf, sizeof(buf));
989 gripe_roff_command_from_file (file);
995 * Is there really any point in continuing to look for
996 * preprocessor options if we can't even read the man page source?
998 gripe_reading_man_file (file);
1002 if ((cp = getenv ("MANROFFSEQ")) != NULL)
1005 fprintf (stderr, "parsing directive from environment\n");
1007 status = parse_roff_directive (cp, file, buf, sizeof(buf));
1013 gripe_roff_command_from_env ();
1017 fprintf (stderr, "using default preprocessor sequence\n");
1019 status = parse_roff_directive ("t", file, buf, sizeof(buf));
1022 else /* can't happen */
1026 sig_t ohup, oint, oquit, oterm;
1027 static char temp[FILENAME_MAX];
1030 cleantmp(int signo __unused)
1039 ohup = signal(SIGHUP, cleantmp);
1040 oint = signal(SIGINT, cleantmp);
1041 oquit = signal(SIGQUIT, cleantmp);
1042 oterm = signal(SIGTERM, cleantmp);
1048 signal(SIGHUP, ohup);
1049 signal(SIGINT, oint);
1050 signal(SIGQUIT, oquit);
1051 signal(SIGTERM, oterm);
1055 * Try to format the man page and create a new formatted file. Return
1056 * 1 for success and 0 for failure.
1059 make_cat_file (char *path, char *man_file, char *cat_file, int manid)
1064 char command[FILENAME_MAX];
1066 roff_command = make_roff_command (man_file);
1067 if (roff_command == NULL)
1070 snprintf(temp, sizeof(temp), "%s.tmpXXXXXX", cat_file);
1071 if ((f = mkstemp(temp)) >= 0 && (fp = fdopen(f, "w")) != NULL)
1075 if (fchmod (f, CATMODE) < 0) {
1082 fprintf (stderr, "mode of %s is now %o\n", temp, CATMODE);
1084 snprintf (command, sizeof(command), "(cd %s ; %s | %s)", path,
1085 roff_command, COMPRESSOR);
1086 fprintf (stderr, "Formatting page, please wait...");
1090 fprintf (stderr, "\ntrying command: %s\n", command);
1096 if ((pp = popen(command, "r")) == NULL) {
1098 fprintf(stderr, "Failed.\n");
1116 while ((s = getc(pp)) != EOF) {
1120 if (!f || ((s = pclose(pp)) == -1)) {
1122 fprintf(stderr, "Failed.\n");
1132 fprintf(stderr, "Failed.\n");
1133 gripe_system_command(s);
1143 else if (rename(temp, cat_file) == -1) {
1146 "\nHmm! Can't seem to rename %s to %s, check permissions on man dir!\n",
1161 fprintf(stderr, "Failed.\n");
1168 fprintf(stderr, "No output, debug mode.\n");
1172 fprintf(stderr, "Done.\n");
1185 fprintf (stderr, "Couldn't open %s for writing.\n", temp);
1198 * Try to format the man page source and save it, then display it. If
1199 * that's not possible, try to format the man page source and display
1202 * Note that we've already been handed the name of the ultimate source
1203 * file at this point.
1206 format_and_display (char *path, char *man_file, char *cat_file)
1211 char command[FILENAME_MAX];
1215 if (access (man_file, R_OK) != 0)
1220 roff_command = make_roff_command (man_file);
1221 if (roff_command == NULL)
1224 snprintf (command, sizeof(command), "(cd %s ; %s)", path, roff_command);
1226 found = do_system_command (command);
1230 if (cat_file == NULL)
1231 goto format_and_display;
1233 status = is_newer (man_file, cat_file);
1235 fprintf (stderr, "status from is_newer() = %d\n", status);
1237 if (status == 1 || status == -2)
1240 * Cat file is out of date. Try to format and save it.
1244 printf ("%s\n", man_file);
1252 found = make_cat_file (path, man_file, cat_file, 1);
1258 /* Try again as real user - see note below.
1260 effective group (user) ID == real group (user) ID
1261 except for the call above, I believe the problems
1262 of reading private man pages is avoided. */
1263 found = make_cat_file (path, man_file, cat_file, 0);
1268 * Creating the cat file worked. Now just display it.
1270 (void) display_cat_file (cat_file);
1275 * Couldn't create cat file. Just format it and
1276 * display it through the pager.
1279 roff_command = make_roff_command (man_file);
1280 if (roff_command == NULL)
1283 snprintf (command, sizeof(command), "(cd %s ; %s | %s)", path,
1284 roff_command, pager);
1286 found = do_system_command (command);
1290 else if (access (cat_file, R_OK) == 0)
1293 * Formatting not necessary. Cat file is newer than source
1294 * file, or source file is not present but cat file is.
1298 printf ("%s (source: %s)\n", cat_file, man_file);
1303 found = display_cat_file (cat_file);
1311 * See if the preformatted man page or the source exists in the given
1315 try_section (char *path, char *section, char *_longsec, char *name, int glob)
1322 static int arch_search;
1323 char buf[FILENAME_MAX];
1327 snprintf(buf, sizeof(buf), "%s/man%s/%s", path, section, machine);
1328 if (is_directory (buf) == 1)
1330 snprintf(buf, sizeof(buf), "%s/%s", machine, name);
1332 found = try_section (path, section, _longsec, buf, glob);
1334 if (found && !findall) /* only do this architecture... */
1342 fprintf (stderr, "trying section %s with globbing\n", section);
1344 fprintf (stderr, "trying section %s without globbing\n", section);
1347 #ifndef NROFF_MISSING
1349 * Look for man page source files.
1353 names = glob_for_file (path, section, _longsec, name, cat);
1355 names = make_name (path, section, _longsec, name, cat);
1357 if (names == (char **) -1 || *names == NULL)
1359 * No files match. See if there's a preformatted page around that
1362 #endif /* NROFF_MISSING */
1368 names = glob_for_file (path, section, _longsec, name, cat);
1370 names = make_name (path, section, _longsec, name, cat);
1372 if (names != (char **) -1 && *names != NULL)
1374 for (np = names; *np != NULL; np++)
1378 printf ("%s\n", *np);
1383 found += display_cat_file (*np);
1389 #ifndef NROFF_MISSING
1392 for (np = names; *np != NULL; np++)
1394 char *cat_file = NULL;
1397 man_file = ultimate_source (*np, path);
1403 cat_file = convert_name (man_file, to_cat);
1406 fprintf (stderr, "will try to write %s if needed\n", cat_file);
1409 found += format_and_display (path, man_file, cat_file);
1412 #endif /* NROFF_MISSING */
1417 * Search for manual pages.
1419 * If preformatted manual pages are supported, look for the formatted
1420 * file first, then the man page source file. If they both exist and
1421 * the man page source file is newer, or only the source file exists,
1422 * try to reformat it and write the results in the cat directory. If
1423 * it is not possible to write the cat file, simply format and display
1426 * If preformatted pages are not supported, or the troff option is
1427 * being used, only look for the man page source file.
1443 if (strchr(name, '/')) /* Treat name as file name if it's a path */
1448 fprintf(stderr, "Trying as file name\n");
1451 * We need to pass an absolute file name to format_and_display,
1452 * or it will run into problems later.
1454 realpath(name, buf);
1456 if (stat(buf, &st) == 0)
1457 found += format_and_display(dirname(buf), buf, NULL);
1459 else if (shortsec != NULL)
1461 for (mp = manpathlist; *mp != NULL; mp++)
1464 fprintf (stderr, "\nsearching in %s\n", *mp);
1469 if (locale != NULL) {
1470 locale_opts = locale_nroff;
1472 if (*locale_lang != '\0' && *locale_terr != '\0') {
1473 snprintf(buf, sizeof(buf), "%s/%s_%s.%s", *mp,
1474 locale_lang, locale_terr, locale_codeset);
1475 if (is_directory (buf) == 1)
1476 l_found = try_section (buf, shortsec, longsec, name, glob);
1479 if (*locale_lang != '\0') {
1480 snprintf(buf, sizeof(buf), "%s/%s.%s", *mp,
1481 locale_lang, locale_codeset);
1482 if (is_directory (buf) == 1)
1483 l_found = try_section (buf, shortsec, longsec, name, glob);
1486 if (!l_found && strcmp(locale_lang, "en") != 0) {
1487 snprintf(buf, sizeof(buf), "%s/en.%s", *mp,
1489 if (is_directory (buf) == 1)
1490 l_found = try_section (buf, shortsec, longsec, name, glob);
1497 found += try_section (*mp, shortsec, longsec, name, glob);
1501 if (found && !findall) /* i.e. only do this section... */
1507 for (sp = section_list; *sp != NULL; sp++)
1509 for (mp = manpathlist; *mp != NULL; mp++)
1512 fprintf (stderr, "\nsearching in %s\n", *mp);
1517 if (locale != NULL) {
1518 locale_opts = locale_nroff;
1520 if (*locale_lang != '\0' && *locale_terr != '\0') {
1521 snprintf(buf, sizeof(buf), "%s/%s_%s.%s", *mp,
1522 locale_lang, locale_terr, locale_codeset);
1523 if (is_directory (buf) == 1)
1524 l_found = try_section (buf, *sp, longsec, name, glob);
1527 if (*locale_lang != '\0') {
1528 snprintf(buf, sizeof(buf), "%s/%s.%s", *mp,
1529 locale_lang, locale_codeset);
1530 if (is_directory (buf) == 1)
1531 l_found = try_section (buf, *sp, longsec, name, glob);
1534 if (!l_found && strcmp(locale_lang, "en") != 0) {
1535 snprintf(buf, sizeof(buf), "%s/en.%s", *mp,
1537 if (is_directory (buf) == 1)
1538 l_found = try_section (buf, *sp, longsec, name, glob);
1545 found += try_section (*mp, *sp, longsec, name, glob);
1549 if (found && !findall) /* i.e. only do this section... */
1558 get_section_list (void)
1563 #define TMP_SECTION_LIST_SIZE 100
1564 static char *tmp_section_list[TMP_SECTION_LIST_SIZE];
1566 if (colon_sep_section_list == NULL)
1568 if ((p = getenv ("MANSECT")) == NULL)
1570 return __DECONST(char **, std_sections);
1574 colon_sep_section_list = strdup (p);
1579 for (p = colon_sep_section_list; i < TMP_SECTION_LIST_SIZE ; p = end+1)
1581 if ((end = strchr (p, ':')) != NULL)
1584 tmp_section_list[i++] = strdup (p);
1590 tmp_section_list [i] = NULL;
1591 return tmp_section_list;