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
18 static const char rcsid[] =
26 #include <sys/param.h>
27 #include <sys/utsname.h>
56 extern char *malloc ();
57 extern char *getenv ();
61 extern int strncmp ();
65 extern int fprintf ();
66 extern FILE *fopen ();
68 extern char *sprintf ();
71 extern char **glob_filename ();
72 extern int is_newer ();
73 extern int is_directory ();
74 extern int is_file ();
75 extern int do_system_command ();
79 static char *machine_arch;
82 static char *manpathlist[MAXDIRS];
83 static char *shortsec;
85 static char *colon_sep_section_list;
86 static char **section_list;
87 static char *roff_directive;
91 static int print_where;
92 static char *ultimate_source ();
95 static char *locale, *locale_opts, *locale_nroff, *locale_codeset;
96 static char locale_terr[3], locale_lang[3];
97 static char *man_locale;
98 static int use_man_locale;
99 static int use_original;
104 static struct ltable ltable[] = {
105 {"KOI8-R", "koi8-r"},
106 {"ISO8859-1", "latin1"},
107 {"ISO8859-15", "latin1"},
113 static int troff = 0;
119 static char args[] = "M:P:S:adfhkm:op:tw?";
121 static char args[] = "M:P:S:adfhkm:p:tw?";
125 static char args[] = "M:P:S:adfhkm:op:w?";
127 static char args[] = "M:P:S:adfhkm:p:w?";
144 extern char *mkprogname ();
146 char **get_section_list ();
152 prognam = mkprogname (argv[0]);
157 (void) setlocale(LC_ALL, "");
159 man_getopt (argc, argv);
162 gripe_no_name ((char *)NULL);
164 section_list = get_section_list ();
166 if (optind == argc - 1)
168 tmp = is_section (argv[optind], manp);
180 while (optind < argc)
182 nextarg = argv[optind++];
185 * See if this argument is a valid section name. If not,
186 * is_section returns NULL.
188 tmp = is_section (nextarg, manp);
195 fprintf (stderr, "\nsection: %s\n", shortsec);
201 do_apropos (nextarg);
202 status = (status ? 0 : 1); /* reverts status, see below */
206 status = (status ? 0 : 1); /* reverts status, see below */
208 else if (strchr (nextarg, '/') != NULL && is_file (nextarg) == 1)
210 format_and_display (NULL, ultimate_source(nextarg, dirname(nextarg)),
215 status = man (nextarg);
218 gripe_not_found (nextarg, longsec);
221 return (status==0); /* status==1 --> exit(0),
222 status==0 --> exit(1) */
228 static char usage_string[1024] = "%s, version %s\n\n";
233 "usage: %s [-adfhkotw] [section] [-M path] [-P pager] [-S list]\n\
234 [-m machine] [-p string] name ...\n\n";
237 "usage: %s [-adfhktw] [section] [-M path] [-P pager] [-S list]\n\
238 [-m machine] [-p string] name ...\n\n";
243 "usage: %s [-adfhkow] [section] [-M path] [-P pager] [-S list]\n\
244 [-m machine] [-p string] name ...\n\n";
247 "usage: %s [-adfhkw] [section] [-M path] [-P pager] [-S list]\n\
248 [-m machine] [-p string] name ...\n\n";
252 static char s2[] = " a : find all matching entries\n\
253 d : print gobs of debugging information\n\
254 f : same as whatis(1)\n\
255 h : print this help message\n\
256 k : same as apropos(1)\n";
259 static char s3[] = " o : use original, non-localized manpages\n";
263 static char s4[] = " t : use troff to format pages for printing\n";
266 static char s5[] = " w : print location of man page(s) that would be displayed\n\n\
267 M path : set search path for manual pages to `path'\n\
268 P pager : use program `pager' to display pages\n\
269 S list : colon separated section list\n\
270 m machine : search for alternate architecture man pages\n";
272 static char s6[] = " p string : string tells which preprocessors to run\n\
273 e - [n]eqn(1) p - pic(1) t - tbl(1)\n\
274 g - grap(1) r - refer(1) v - vgrind(1)\n";
276 strcat (usage_string, s1);
277 strcat (usage_string, s2);
279 strcat (usage_string, s3);
283 strcat (usage_string, s4);
286 strcat (usage_string, s5);
288 strcat (usage_string, s6);
290 fprintf (stderr, usage_string, prognam, version, prognam);
295 add_dir_to_mpath_list (mp, p)
301 status = is_directory (p);
303 if (status < 0 && debug)
305 fprintf (stderr, "Warning: couldn't stat file %s!\n", p);
307 else if (status == 0 && debug)
309 fprintf (stderr, "Warning: %s isn't a directory!\n", p);
311 else if (status == 1)
314 fprintf (stderr, "adding %s to manpathlist\n", p);
322 * Get options from the command line and user environment.
325 man_getopt (argc, argv)
327 register char **argv;
333 extern void downcase ();
334 extern char *manpath ();
336 while ((c = getopt (argc, argv, args)) != -1)
341 manp = strdup (optarg);
344 pager = strdup (optarg);
345 if (setenv("PAGER", pager, 1) != 0)
346 (void)fprintf(stderr, "setenv PAGER=%s\n", pager);
349 colon_sep_section_list = strdup (optarg);
359 gripe_incompatible ("-f and -t");
361 gripe_incompatible ("-f and -k");
363 gripe_incompatible ("-f and -w");
368 gripe_incompatible ("-k and -t");
370 gripe_incompatible ("-k and -f");
372 gripe_incompatible ("-k and -w");
376 machine_arch = optarg;
377 if ((machine = strchr(optarg, ':')) != NULL)
388 roff_directive = strdup (optarg);
393 gripe_incompatible ("-t and -k");
395 gripe_incompatible ("-t and -f");
397 gripe_incompatible ("-t and -w");
403 gripe_incompatible ("-w and -k");
405 gripe_incompatible ("-w and -f");
407 gripe_incompatible ("-w and -t");
419 /* "" intentionally used to catch error */
420 if ((locale = setlocale(LC_CTYPE, "")) != NULL)
421 locale_codeset = nl_langinfo(CODESET);
422 if (!use_original && locale != NULL && *locale_codeset != '\0' &&
423 strcmp(locale_codeset, "US-ASCII") != 0
425 char *tmp, *short_locale;
426 struct ltable *pltable;
431 if ((short_locale = strdup(locale)) == NULL) {
432 perror ("ctype locale strdup");
435 if ((tmp = strchr(short_locale, '.')) != NULL)
438 if (strlen(short_locale) == 2)
439 strcpy(locale_lang, short_locale);
440 else if ((tmp = strchr(short_locale, '_')) == NULL ||
441 tmp != short_locale + 2 ||
445 perror ("ctype locale format");
448 strncpy(locale_terr, short_locale + 3, 2);
449 locale_terr[2] = '\0';
450 strncpy(locale_lang, short_locale, 2);
451 locale_lang[2] = '\0';
456 if (locale != NULL) {
457 for (pltable = ltable; pltable->lcode != NULL; pltable++) {
458 if (strcmp(pltable->lcode, locale_codeset) == 0) {
459 locale_nroff = pltable->nroff;
463 asprintf(&man_locale, "%s.%s", locale_lang, locale_codeset);
466 if (locale == NULL) {
468 perror ("ctype locale");
471 if (*locale_codeset == '\0') {
473 perror ("ctype codeset");
477 #endif /* __FreeBSD__ */
479 if (pager == NULL || *pager == '\0')
480 if ((pager = getenv ("PAGER")) == NULL || *pager == '\0')
481 pager = strdup (PAGER);
484 fprintf (stderr, "\nusing %s as pager\n", pager);
486 if (machine_arch == NULL && (machine_arch = getenv ("MACHINE_ARCH")) == NULL)
487 machine_arch = MACHINE_ARCH;
489 if (machine == NULL && (machine = getenv ("MACHINE")) == NULL)
491 static struct utsname utsname;
493 if (uname(&utsname) == -1)
498 machine = utsname.machine;
502 fprintf (stderr, "\nusing %s:%s architecture\n", machine_arch, machine);
506 if ((manp = manpath (0)) == NULL)
511 "\nsearch path for pages determined by manpath is\n%s\n\n",
516 * Expand the manpath into a list for easier handling.
519 for (p = manp; ; p = end+1)
521 if (mp == manpathlist + MAXDIRS - 1) {
522 fprintf (stderr, "Warning: too many directories in manpath, truncated!\n");
525 if ((end = strchr (p, ':')) != NULL)
528 mp = add_dir_to_mpath_list (mp, p);
538 * Check to see if the argument is a valid section number. If the
539 * first character of name is a numeral, or the name matches one of
540 * the sections listed in section_list, we'll assume that it's a section.
541 * The list of sections in config.h simply allows us to specify oddly
542 * named directories like .../man3f. Yuk.
545 is_section (name, path)
550 char *temp, *end, *loc;
554 for (vs = section_list; *vs != NULL; vs++)
555 if ((strcmp (*vs, name) == 0)
556 || (isdigit ((unsigned char)name[0]) && strlen(name) == 1))
557 return (longsec = strdup(name));
560 if (isdigit ((unsigned char)name[0]))
562 while (*plist != NULL)
564 asprintf (&temp, "%s/man%c/*", *plist, name[0]);
568 vs = glob_filename (temp);
569 if (vs == (char **) -1)
574 for ( ; *vs != NULL; vs++)
576 end = strrchr (*vs, '/');
577 if ((loc = strstr (end, name)) != NULL && loc - end > 2
579 && (*(loc+strlen(name)) == '\0' || *(loc+strlen(name)) == '.'))
588 asprintf (&temp, "%c", name[0]);
589 longsec = strdup (name);
598 * Handle the apropos option. Cheat by using another program.
605 register char *command;
607 len = strlen (APROPOS) + strlen (name) + 4;
609 if ((command = (char *) malloc(len)) == NULL)
610 gripe_alloc (len, "command");
612 sprintf (command, "%s \"%s\"", APROPOS, name);
614 (void) do_system_command (command);
620 * Handle the whatis option. Cheat by using another program.
627 register char *command;
629 len = strlen (WHATIS) + strlen (name) + 4;
631 if ((command = (char *) malloc(len)) == NULL)
632 gripe_alloc (len, "command");
634 sprintf (command, "%s \"%s\"", WHATIS, name);
636 (void) do_system_command (command);
642 * Change a name of the form ...man/man1/name.1 to ...man/cat1/name.1
643 * or a name of the form ...man/cat1/name.1 to ...man/man1/name.1
646 convert_name (name, to_cat)
650 register char *to_name;
652 register char *t2 = NULL;
657 int olen = strlen(name);
658 int cextlen = strlen(COMPRESS_EXT);
659 int len = olen + cextlen;
661 to_name = malloc (len+1);
663 gripe_alloc (len+1, "to_name");
664 strcpy (to_name, name);
666 /* Avoid tacking it on twice */
667 if (olen >= 1 && strcmp(name + olen, COMPRESS_EXT) != 0)
668 strcat (to_name, COMPRESS_EXT);
671 to_name = strdup (name);
673 to_name = strdup (name);
676 t1 = strrchr (to_name, '/');
680 t2 = strrchr (to_name, '/');
683 /* Skip architecture part (if present). */
684 if (t2 != NULL && (t1 - t2 < 5 || *(t2 + 1) != 'm' || *(t2 + 3) != 'n'))
688 t2 = strrchr (to_name, '/');
694 gripe_converting_name (name, to_cat);
708 fprintf (stderr, "to_name in convert_name () is: %s\n", to_name);
714 * Try to find the man page corresponding to the given name. The
715 * reason we do this with globbing is because some systems have man
716 * page directories named man3 which contain files with names like
717 * XtPopup.3Xt. Rather than requiring that this program know about
718 * all those possible names, we simply try to match things like
719 * .../man[sect]/name[sect]*. This is *much* easier.
721 * Note that globbing is only done when the section is unspecified.
724 glob_for_file (path, section, longsec, name, cat)
731 char pathname[FILENAME_MAX];
738 snprintf (pathname, sizeof(pathname), "%s/cat%s/%s.%s*", path, section,
741 snprintf (pathname, sizeof(pathname), "%s/man%s/%s.%s*", path, section,
745 fprintf (stderr, "globbing %s\n", pathname);
747 gf = glob_filename (pathname);
749 if ((gf == (char **) -1 || *gf == NULL) && isdigit ((unsigned char)*section)
750 && strlen (longsec) == 1)
753 snprintf (pathname, sizeof(pathname), "%s/cat%s/%s.%c*", path, section, name, *section);
755 snprintf (pathname, sizeof(pathname), "%s/man%s/%s.%c*", path, section, name, *section);
757 gf = glob_filename (pathname);
759 if ((gf == (char **) -1 || *gf == NULL) && isdigit ((unsigned char)*section)
760 && strlen (longsec) == 1)
763 snprintf (pathname, sizeof(pathname), "%s/cat%s/%s.0*", path, section, name);
765 snprintf (pathname, sizeof(pathname), "%s/man%s/%s.0*", path, section, name);
767 fprintf (stderr, "globbing %s\n", pathname);
768 gf = glob_filename (pathname);
774 * Return an un-globbed name in the same form as if we were doing
778 make_name (path, section, longsec, name, cat)
786 static char *names[3];
787 char buf[FILENAME_MAX];
790 snprintf (buf, sizeof(buf), "%s/cat%s/%s.%s", path, section, name, longsec);
792 snprintf (buf, sizeof(buf), "%s/man%s/%s.%s", path, section, name, longsec);
794 if (access (buf, R_OK) == 0)
795 names[i++] = strdup (buf);
798 * If we're given a section that looks like `3f', we may want to try
799 * file names like .../man3/foo.3f as well. This seems a bit
800 * kludgey to me, but what the hey...
802 if (section[1] != '\0')
805 snprintf (buf, sizeof(buf), "%s/cat%c/%s.%s", path, section[0], name, section);
807 snprintf (buf, sizeof(buf), "%s/man%c/%s.%s", path, section[0], name, section);
809 if (access (buf, R_OK) == 0)
810 names[i++] = strdup (buf);
822 char *end = file + (strlen (file) - 1);
824 while (end > file && end[-1] != '.')
837 if (*end == 'Z' || !strcmp(end, "gz") || !strcmp(end, "bz2"))
844 * Simply display the preformatted page.
847 display_cat_file (file)
851 char command[FILENAME_MAX];
855 if (access (file, R_OK) == 0)
857 char *expander = get_expander (file);
859 if (expander != NULL)
860 snprintf (command, sizeof(command), "%s %s | %s", expander, file, pager);
862 snprintf (command, sizeof(command), "%s %s", pager, file);
864 found = do_system_command (command);
870 * Try to find the ultimate source file. If the first line of the
871 * current file is not of the form
875 * the input file name is returned.
878 ultimate_source (name, path)
882 static char buf[BUFSIZ];
883 static char ult[FILENAME_MAX];
889 strncpy (ult, name, sizeof(ult)-1);
890 ult[sizeof(ult)-1] = '\0';
891 strncpy (buf, name, sizeof(buf)-1);
892 ult[sizeof(buf)-1] = '\0';
897 if ((fp = gzopen (ult, "r")) == NULL)
899 /* check for the compressed version too */
900 strlcat(ult, ".gz", FILENAME_MAX);
901 if ((fp = gzopen (ult, "r")) == NULL)
902 return ult; /* we munged it, but it doesn't exist anyway */
905 if ((fp = fopen (ult, "r")) == NULL)
910 end = gzgets (fp, buf, BUFSIZ);
913 end = fgets (buf, BUFSIZ, fp);
917 if (!end || strlen (buf) < 5)
921 if (*beg++ == '.' && *beg++ == 's' && *beg++ == 'o')
923 while ((*beg == ' ' || *beg == '\t') && *beg != '\0')
927 while (*end != ' ' && *end != '\t' && *end != '\n' && *end != '\0')
932 snprintf(ult, sizeof(ult), "%s/%s", path, beg);
933 snprintf(buf, sizeof(buf), "%s", ult);
939 fprintf (stderr, "found ultimate source file %s\n", ult);
945 add_directive (first, d, file, buf, bufsize)
952 if (strcmp (d, "") != 0)
957 snprintf(buf, bufsize, "%s %s", d, file);
961 strncat (buf, " | ", bufsize-strlen(buf)-1);
962 strncat (buf, d, bufsize-strlen(buf)-1);
968 parse_roff_directive (cp, file, buf, bufsize)
977 int preproc_found = 0;
980 if ((exp = get_expander(file)) != NULL)
981 add_directive (&first, exp, file, buf, bufsize);
983 while ((c = *cp++) != '\0')
990 fprintf (stderr, "found eqn(1) directive\n");
994 add_directive (&first, EQN, file, buf, bufsize);
997 char lbuf[FILENAME_MAX];
999 snprintf(lbuf, sizeof(lbuf), "%s -T%s", NEQN,
1000 locale_opts == NULL ? "ascii" : locale_opts);
1001 add_directive (&first, lbuf, file, buf, bufsize);
1003 add_directive (&first, NEQN, file, buf, bufsize);
1012 fprintf (stderr, "found grap(1) directive\n");
1015 add_directive (&first, GRAP, file, buf, bufsize);
1022 fprintf (stderr, "found pic(1) directive\n");
1025 add_directive (&first, PIC, file, buf, bufsize);
1032 fprintf (stderr, "found tbl(1) directive\n");
1036 add_directive (&first, TBL, file, buf, bufsize);
1042 fprintf (stderr, "found vgrind(1) directive\n");
1044 add_directive (&first, VGRIND, file, buf, bufsize);
1050 fprintf (stderr, "found refer(1) directive\n");
1052 add_directive (&first, REFER, file, buf, bufsize);
1071 add_directive (&first, TROFF, file, buf, bufsize);
1076 char lbuf[FILENAME_MAX];
1078 snprintf(lbuf, sizeof(lbuf), "%s -T%s%s%s", NROFF,
1079 locale_opts == NULL ? "ascii" : locale_opts,
1080 use_man_locale ? " -dlocale=" : "",
1081 use_man_locale ? man_locale : "");
1082 add_directive (&first, lbuf, file, buf, bufsize);
1084 add_directive (&first, NROFF " -Tascii", file, buf, bufsize);
1087 if (use_col && !troff)
1088 add_directive (&first, COL, file, buf, bufsize);
1097 make_roff_command (file)
1106 static char buf [BUFSIZ];
1110 if (roff_directive != NULL)
1113 fprintf (stderr, "parsing directive from command line\n");
1115 status = parse_roff_directive (roff_directive, file, buf, sizeof(buf));
1121 gripe_roff_command_from_command_line (file);
1125 if ((fp = gzopen (file, "r")) != NULL)
1127 if ((fp = fopen (file, "r")) != NULL)
1132 gzgets (fp, line, BUFSIZ);
1135 fgets (line, BUFSIZ, fp);
1138 if (*cp++ == '\'' && *cp++ == '\\' && *cp++ == '"' && *cp++ == ' ')
1141 fprintf (stderr, "parsing directive from file\n");
1143 status = parse_roff_directive (cp, file, buf, sizeof(buf));
1149 gripe_roff_command_from_file (file);
1155 * Is there really any point in continuing to look for
1156 * preprocessor options if we can't even read the man page source?
1158 gripe_reading_man_file (file);
1162 if ((cp = getenv ("MANROFFSEQ")) != NULL)
1165 fprintf (stderr, "parsing directive from environment\n");
1167 status = parse_roff_directive (cp, file, buf, sizeof(buf));
1173 gripe_roff_command_from_env ();
1177 fprintf (stderr, "using default preprocessor sequence\n");
1179 status = parse_roff_directive ("t", file, buf, sizeof(buf));
1182 else /* can't happen */
1186 sig_t ohup, oint, oquit, oterm;
1187 static char temp[FILENAME_MAX];
1198 ohup = signal(SIGHUP, cleantmp);
1199 oint = signal(SIGINT, cleantmp);
1200 oquit = signal(SIGQUIT, cleantmp);
1201 oterm = signal(SIGTERM, cleantmp);
1207 signal(SIGHUP, ohup);
1208 signal(SIGINT, oint);
1209 signal(SIGQUIT, oquit);
1210 signal(SIGTERM, oterm);
1214 * Try to format the man page and create a new formatted file. Return
1215 * 1 for success and 0 for failure.
1218 make_cat_file (path, man_file, cat_file, manid)
1219 register char *path;
1220 register char *man_file;
1221 register char *cat_file;
1225 #if defined(HAVE_LIBZ) && defined(DO_COMPRESS)
1231 char command[FILENAME_MAX];
1233 roff_command = make_roff_command (man_file);
1234 if (roff_command == NULL)
1237 snprintf(temp, sizeof(temp), "%s.tmpXXXXXX", cat_file);
1238 if ((f = mkstemp(temp)) >= 0 &&
1239 #if defined(HAVE_LIBZ) && defined(DO_COMPRESS)
1240 (fp = gzdopen(f, "w")) != NULL)
1242 (fp = fdopen(f, "w")) != NULL)
1247 if (fchmod (f, CATMODE) < 0) {
1254 fprintf (stderr, "mode of %s is now %o\n", temp, CATMODE);
1256 snprintf (command, sizeof(command), "(cd %s ; %s)", path,
1259 fprintf (stderr, "Formatting page, please wait...");
1263 fprintf (stderr, "\ntrying command: %s\n", command);
1270 if ((pp = popen(command, "r")) == NULL) {
1272 fprintf(stderr, "Failed.\n");
1281 #if defined(HAVE_LIBZ) && defined(DO_COMPRESS)
1294 while ((s = getc(pp)) != EOF) {
1295 #if defined(HAVE_LIBZ) && defined(DO_COMPRESS)
1303 if (!f || ((s = pclose(pp)) == -1)) {
1305 fprintf(stderr, "Failed.\n");
1311 #if defined(HAVE_LIBZ) && defined(DO_COMPRESS)
1320 fprintf(stderr, "Failed.\n");
1321 gripe_system_command(s);
1324 #if defined(HAVE_LIBZ) && defined(DO_COMPRESS)
1335 else if (rename(temp, cat_file) == -1) {
1338 "\nHmm! Can't seem to rename %s to %s, check permissions on man dir!\n",
1344 #if defined(HAVE_LIBZ) && defined(DO_COMPRESS)
1353 #if defined(HAVE_LIBZ) && defined(DO_COMPRESS)
1361 fprintf(stderr, "Failed.\n");
1368 fprintf(stderr, "No output, debug mode.\n");
1372 fprintf(stderr, "Done.\n");
1385 fprintf (stderr, "Couldn't open %s for writing.\n", temp);
1398 * Try to format the man page source and save it, then display it. If
1399 * that's not possible, try to format the man page source and display
1402 * Note that we've already been handed the name of the ultimate source
1403 * file at this point.
1406 format_and_display (path, man_file, cat_file)
1407 register char *path;
1408 register char *man_file;
1409 register char *cat_file;
1414 char command[FILENAME_MAX];
1418 if (access (man_file, R_OK) != 0)
1421 if (troff || path == NULL)
1423 roff_command = make_roff_command (man_file);
1424 if (roff_command == NULL)
1427 snprintf (command, sizeof(command), "(cd %s ; %s)", path, roff_command);
1429 snprintf (command, sizeof(command), "%s | %s", roff_command, pager);
1431 found = do_system_command (command);
1435 status = is_newer (man_file, cat_file);
1437 fprintf (stderr, "status from is_newer() = %d\n", status);
1439 if (status == 1 || status == -2)
1442 * Cat file is out of date. Try to format and save it.
1446 printf ("%s\n", man_file);
1454 found = make_cat_file (path, man_file, cat_file, 1);
1459 /* Try again as real user - see note below.
1461 effective group (user) ID == real group (user) ID
1462 except for the call above, I believe the problems
1463 of reading private man pages is avoided. */
1464 found = make_cat_file (path, man_file, cat_file, 0);
1467 found = make_cat_file (path, man_file, cat_file, 0);
1472 * Creating the cat file worked. Now just display it.
1474 (void) display_cat_file (cat_file);
1479 * Couldn't create cat file. Just format it and
1480 * display it through the pager.
1482 roff_command = make_roff_command (man_file);
1483 if (roff_command == NULL)
1486 snprintf (command, sizeof(command), "(cd %s ; %s | %s)", path,
1487 roff_command, pager);
1489 found = do_system_command (command);
1493 else if (access (cat_file, R_OK) == 0)
1496 * Formatting not necessary. Cat file is newer than source
1497 * file, or source file is not present but cat file is.
1501 printf ("%s (source: %s)\n", cat_file, man_file);
1506 found = display_cat_file (cat_file);
1514 * See if the preformatted man page or the source exists in the given
1518 try_section (path, section, longsec, name, glob)
1525 register int found = 0;
1526 register int to_cat;
1528 register char **names;
1530 static int arch_search;
1531 char buf[FILENAME_MAX];
1535 snprintf(buf, sizeof(buf), "%s/man%s/%s", path, section, machine);
1536 if (is_directory (buf) == 1)
1538 snprintf(buf, sizeof(buf), "%s/%s", machine, name);
1540 found = try_section (path, section, longsec, buf, glob);
1542 if (found && !findall) /* only do this architecture... */
1545 if (strcmp(machine_arch, machine) != 0)
1547 snprintf(buf, sizeof(buf), "%s/man%s/%s", path, section, machine_arch);
1548 if (is_directory (buf) == 1)
1550 snprintf(buf, sizeof(buf), "%s/%s", machine_arch, name);
1552 found = try_section (path, section, longsec, buf, glob);
1554 if (found && !findall) /* only do this architecture... */
1563 fprintf (stderr, "trying section %s with globbing\n", section);
1565 fprintf (stderr, "trying section %s without globbing\n", section);
1568 #ifndef NROFF_MISSING
1570 * Look for man page source files.
1574 names = glob_for_file (path, section, longsec, name, cat);
1576 names = make_name (path, section, longsec, name, cat);
1578 if (names == (char **) -1 || *names == NULL)
1580 * No files match. See if there's a preformatted page around that
1583 #endif /* NROFF_MISSING */
1589 names = glob_for_file (path, section, longsec, name, cat);
1591 names = make_name (path, section, longsec, name, cat);
1593 if (names != (char **) -1 && *names != NULL)
1595 for (np = names; *np != NULL; np++)
1599 printf ("%s\n", *np);
1604 found += display_cat_file (*np);
1610 #ifndef NROFF_MISSING
1613 for (np = names; *np != NULL; np++)
1615 register char *cat_file = NULL;
1616 register char *man_file;
1618 man_file = ultimate_source (*np, path);
1624 cat_file = convert_name (man_file, to_cat);
1627 fprintf (stderr, "will try to write %s if needed\n", cat_file);
1630 found += format_and_display (path, man_file, cat_file);
1633 #endif /* NROFF_MISSING */
1638 * Search for manual pages.
1640 * If preformatted manual pages are supported, look for the formatted
1641 * file first, then the man page source file. If they both exist and
1642 * the man page source file is newer, or only the source file exists,
1643 * try to reformat it and write the results in the cat directory. If
1644 * it is not possible to write the cat file, simply format and display
1647 * If preformatted pages are not supported, or the troff option is
1648 * being used, only look for the man page source file.
1661 char buf[FILENAME_MAX];
1667 if (shortsec != NULL)
1669 for (mp = manpathlist; *mp != NULL; mp++)
1672 fprintf (stderr, "\nsearching in %s\n", *mp);
1678 if (locale != NULL) {
1679 locale_opts = locale_nroff;
1681 if (*locale_lang != '\0' && *locale_terr != '\0') {
1682 snprintf(buf, sizeof(buf), "%s/%s_%s.%s", *mp,
1683 locale_lang, locale_terr, locale_codeset);
1684 if (is_directory (buf) == 1)
1685 l_found = try_section (buf, shortsec, longsec, name, glob);
1688 if (*locale_lang != '\0') {
1689 snprintf(buf, sizeof(buf), "%s/%s.%s", *mp,
1690 locale_lang, locale_codeset);
1691 if (is_directory (buf) == 1)
1692 l_found = try_section (buf, shortsec, longsec, name, glob);
1695 if (!l_found && strcmp(locale_lang, "en") != 0) {
1696 snprintf(buf, sizeof(buf), "%s/en.%s", *mp,
1698 if (is_directory (buf) == 1)
1699 l_found = try_section (buf, shortsec, longsec, name, glob);
1707 found += try_section (*mp, shortsec, longsec, name, glob);
1713 if (found && !findall) /* i.e. only do this section... */
1719 for (sp = section_list; *sp != NULL; sp++)
1721 for (mp = manpathlist; *mp != NULL; mp++)
1724 fprintf (stderr, "\nsearching in %s\n", *mp);
1730 if (locale != NULL) {
1731 locale_opts = locale_nroff;
1733 if (*locale_lang != '\0' && *locale_terr != '\0') {
1734 snprintf(buf, sizeof(buf), "%s/%s_%s.%s", *mp,
1735 locale_lang, locale_terr, locale_codeset);
1736 if (is_directory (buf) == 1)
1737 l_found = try_section (buf, *sp, longsec, name, glob);
1740 if (*locale_lang != '\0') {
1741 snprintf(buf, sizeof(buf), "%s/%s.%s", *mp,
1742 locale_lang, locale_codeset);
1743 if (is_directory (buf) == 1)
1744 l_found = try_section (buf, *sp, longsec, name, glob);
1747 if (!l_found && strcmp(locale_lang, "en") != 0) {
1748 snprintf(buf, sizeof(buf), "%s/en.%s", *mp,
1750 if (is_directory (buf) == 1)
1751 l_found = try_section (buf, *sp, longsec, name, glob);
1759 found += try_section (*mp, *sp, longsec, name, glob);
1765 if (found && !findall) /* i.e. only do this section... */
1779 #define TMP_SECTION_LIST_SIZE 100
1780 static char *tmp_section_list[TMP_SECTION_LIST_SIZE];
1782 if (colon_sep_section_list == NULL)
1784 if ((p = getenv ("MANSECT")) == NULL)
1786 return std_sections;
1790 colon_sep_section_list = strdup (p);
1795 for (p = colon_sep_section_list; i < TMP_SECTION_LIST_SIZE ; p = end+1)
1797 if ((end = strchr (p, ':')) != NULL)
1800 tmp_section_list[i++] = strdup (p);
1806 tmp_section_list [i] = NULL;
1807 return tmp_section_list;