home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
OS2
/
MAN11A.ZIP
/
src
/
man.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-05
|
29KB
|
1,424 lines
/*
* man.c
*
* Copyright (c) 1990, 1991, John W. Eaton.
*
* You may distribute under the terms of the GNU General Public
* License as specified in the file COPYING that comes with the man
* distribution.
*
* John W. Eaton
* jwe@che.utexas.edu
* Department of Chemical Engineering
* The University of Texas at Austin
* Austin, Texas 78712
*/
#define MAN_MAIN
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#ifndef _MSC_VER
#include <sys/file.h>
#endif
#include <signal.h>
#include "config.h"
#include "gripes.h"
#include "version.h"
#ifndef POSIX
#include <unistd.h>
#else
#ifndef R_OK
#define R_OK 4
#endif
#endif
#ifdef SECURE_MAN_UID
extern uid_t getuid ();
extern int setuid ();
#endif
#ifdef STDC_HEADERS
#include <stdlib.h>
#else
extern char *malloc ();
extern char *getenv ();
extern void free ();
extern int system ();
extern int strcmp ();
extern int strncmp ();
extern int exit ();
extern int fflush ();
extern int printf ();
extern int fprintf ();
extern FILE *fopen ();
extern int fclose ();
extern char *sprintf ();
#endif
extern char *strdup ();
extern char **glob_vector ();
extern char **glob_filename ();
extern int access ();
extern int unlink ();
extern int system ();
extern int chmod ();
extern int is_newer ();
extern int is_directory ();
extern int do_system_command ();
char *prognam;
static char *pager;
static char *manp;
static char *manpathlist[MAXDIRS];
static char *section;
static char *colon_sep_section_list;
static char **section_list;
static char *roff_directive;
static int apropos;
static int whatis;
static int findall;
static int print_where;
static char nroff_cmd[] = NROFF;
static char *nroff = nroff_cmd;
#ifdef ALT_SYSTEMS
static int alt_system;
static char *alt_system_name;
#endif
static int troff = 0;
int debug;
#ifdef HAS_TROFF
#ifdef ALT_SYSTEMS
static char args[] = "M:P:S:adfhkm:p:tw?";
#else
#ifdef OS2
static char args[] = "M:N:P:S:adfhkp:tw?";
#else
static char args[] = "M:P:S:adfhkp:tw?";
#endif
#endif
#else
#ifdef ALT_SYSTEMS
static char args[] = "M:P:S:adfhkm:p:w?";
#else
static char args[] = "M:P:S:adfhkp:w?";
#endif
#endif
int
main (argc, argv)
int argc;
char **argv;
{
int status = 0;
char *nextarg;
char *tmp;
extern int optind;
extern char *mkprogname ();
char *is_section ();
char **get_section_list ();
void man_getopt ();
void do_apropos ();
void do_whatis ();
int man ();
prognam = mkprogname (argv[0]);
man_getopt (argc, argv);
if (optind == argc)
gripe_no_name ((char *)NULL);
section_list = get_section_list ();
if (optind == argc - 1)
{
tmp = is_section (argv[optind]);
if (tmp != NULL)
gripe_no_name (tmp);
}
while (optind < argc)
{
nextarg = argv[optind++];
/*
* See if this argument is a valid section name. If not,
* is_section returns NULL.
*/
tmp = is_section (nextarg);
if (tmp != NULL)
{
section = tmp;
if (debug)
fprintf (stderr, "\nsection: %s\n", section);
continue;
}
if (apropos)
do_apropos (nextarg);
else if (whatis)
do_whatis (nextarg);
else
{
status = man (nextarg);
if (status == 0)
gripe_not_found (nextarg, section);
}
}
return status;
}
void
usage ()
{
static char usage_string[1024] = "%s, version %s\n\n";
#ifdef HAS_TROFF
#ifdef ALT_SYSTEMS
static char s1[] =
"usage: %s [-adfhktw] [section] [-M path] [-P pager] [-S list]\n\
[-m system] [-p string] name ...\n\n";
#else
#ifdef OS2
static char s1[] =
"usage: %s [-adfhktw] [section] [-M path] [-N nroff] [-P pager] [-S list]\n\
[-p string] name ...\n\n";
#else
static char s1[] =
"usage: %s [-adfhktw] [section] [-M path] [-P pager] [-S list]\n\
[-p string] name ...\n\n";
#endif
#endif
#else
#ifdef ALT_SYSTEMS
static char s1[] =
"usage: %s [-adfhkw] [section] [-M path] [-P pager] [-S list]\n\
[-m system] [-p string] name ...\n\n";
#else
static char s1[] =
"usage: %s [-adfhkw] [section] [-M path] [-P pager] [-S list]\n\
[-p string] name ...\n\n";
#endif
#endif
static char s2[] = " a : find all matching entries\n\
d : print gobs of debugging information\n\
f : same as whatis(1)\n\
h : print this help message\n\
k : same as apropos(1)\n";
strcat (usage_string, s1);
strcat (usage_string, s2);
#ifdef HAS_TROFF
strcat(usage_string, " t : use troff to format pages for printing\n");
#endif
strcat(usage_string,
" w : print location of man page(s) that would be displayed\n\n");
fprintf (stderr, usage_string, prognam, version, prognam);
fprintf(stderr,
" M path : set search path for manual pages to `path'\n");
#ifdef OS2
fprintf(stderr,
" N nroff : set nroff command (%s)\n", nroff);
#endif
fprintf(stderr, "\
P pager : use program `pager' to display pages\n\
S list : colon separated section list\n");
#ifdef ALT_SYSTEMS
fprintf(stderr,
" m system : search for alternate system's man pages\n";
#endif
fprintf(stderr, "\
p string : string tells which preprocessors to run\n\
e - [n]eqn(1) p - pic(1) t - tbl(1)\n\
g - grap(1) r - refer(1) v - vgrind(1)\n");
exit(1);
}
char **
add_dir_to_mpath_list (mp, p)
char **mp;
char *p;
{
int status;
status = is_directory (p);
if (status < 0)
{
fprintf (stderr, "Warning: couldn't stat file %s!\n", p);
}
else if (status == 0)
{
fprintf (stderr, "Warning: %s isn't a directory!\n", p);
}
else if (status == 1)
{
if (debug)
fprintf (stderr, "adding %s to manpathlist\n", p);
*mp++ = strdup (p);
}
return mp;
}
/*
* Get options from the command line and user environment.
*/
void
man_getopt (argc, argv)
register int argc;
register char **argv;
{
register int c;
register char *p;
register char *end;
register char **mp;
extern char *optarg;
extern int getopt ();
extern void downcase ();
extern char *manpath ();
#ifdef OS2
if (NULL == (nroff = getenv("NROFF")))
nroff = (_osmode == DOS_MODE || _osmajor < 20) ? NROFF16 : nroff_cmd;
#endif
while ((c = getopt (argc, argv, args)) != EOF)
{
switch (c)
{
case 'M':
manp = strdup (optarg);
break;
#ifdef OS2
case 'N':
nroff = optarg;
break;
#endif
case 'P':
pager = strdup (optarg);
break;
case 'S':
colon_sep_section_list = strdup (optarg);
break;
case 'a':
findall++;
break;
case 'd':
debug++;
break;
case 'f':
if (troff)
gripe_incompatible ("-f and -t");
if (apropos)
gripe_incompatible ("-f and -k");
if (print_where)
gripe_incompatible ("-f and -w");
whatis++;
break;
case 'k':
if (troff)
gripe_incompatible ("-k and -t");
if (whatis)
gripe_incompatible ("-k and -f");
if (print_where)
gripe_incompatible ("-k and -w");
apropos++;
break;
#ifdef ALT_SYSTEMS
case 'm':
alt_system++;
alt_system_name = strdup (optarg);
break;
#endif
case 'p':
roff_directive = strdup (optarg);
break;
#ifdef HAS_TROFF
case 't':
if (apropos)
gripe_incompatible ("-t and -k");
if (whatis)
gripe_incompatible ("-t and -f");
if (print_where)
gripe_incompatible ("-t and -w");
troff++;
break;
#endif
case 'w':
if (apropos)
gripe_incompatible ("-w and -k");
if (whatis)
gripe_incompatible ("-w and -f");
if (troff)
gripe_incompatible ("-w and -t");
print_where++;
break;
case 'h':
case '?':
default:
usage();
break;
}
}
if (pager == NULL || *pager == '\0')
if ((pager = getenv ("PAGER")) == NULL)
pager = strdup (PAGER);
if (debug)
fprintf (stderr, "\nusing %s as pager\n", pager);
if (manp == NULL)
{
if ((manp = manpath (0)) == NULL)
gripe_manpath ();
if (debug)
fprintf (stderr,
"\nsearch path for pages determined by manpath is\n%s\n\n",
manp);
}
#ifdef ALT_SYSTEMS
if (alt_system_name == NULL || *alt_system_name == '\0')
if ((alt_system_name = getenv ("SYSTEM")) != NULL)
alt_system_name = strdup (alt_system_name);
if (alt_system_name != NULL && *alt_system_name != '\0')
downcase (alt_system_name);
#endif
/*
* Expand the manpath into a list for easier handling.
*/
#ifdef OS2
for (p = manp; p = strchr(p, '\\'); )
*p = '/';
#endif
mp = manpathlist;
for (p = manp; ; p = end+1)
{
if ((end = strchr (p, PATHSEP)) != NULL)
*end = '\0';
#ifdef ALT_SYSTEMS
if (alt_system)
{
char buf[BUFSIZ];
if (debug)
fprintf (stderr, "Alternate system `%s' specified\n",
alt_system_name);
strcpy (buf, p);
strcat (buf, "/");
strcat (buf, alt_system_name);
mp = add_dir_to_mpath_list (mp, buf);
}
else
{
mp = add_dir_to_mpath_list (mp, p);
}
#else
mp = add_dir_to_mpath_list (mp, p);
#endif
if (end == NULL)
break;
*end = PATHSEP;
}
*mp = NULL;
}
/*
* Check to see if the argument is a valid section number. If the
* first character of name is a numeral, or the name matches one of
* the sections listed in section_list, we'll assume that it's a section.
* The list of sections in config.h simply allows us to specify oddly
* named directories like .../man3f. Yuk.
*/
char *
is_section (name)
register char *name;
{
register char **vs;
for (vs = section_list; *vs != NULL; vs++)
if ((strcmp (*vs, name) == 0) || (isdigit (name[0])))
return strdup (name);
return NULL;
}
/*
* Handle the apropos option. Cheat by using another program.
*/
void
do_apropos (name)
register char *name;
{
register int len;
register char *command;
len = strlen (APROPOS) + strlen (name) + 2;
if ((command = (char *) malloc(len)) == NULL)
gripe_alloc (len, "command");
sprintf (command, "%s %s", APROPOS, name);
(void) do_system_command (command);
free (command);
}
/*
* Handle the whatis option. Cheat by using another program.
*/
void
do_whatis (name)
register char *name;
{
register int len;
register char *command;
len = strlen (WHATIS) + strlen (name) + 2;
if ((command = (char *) malloc(len)) == NULL)
gripe_alloc (len, "command");
sprintf (command, "%s %s", WHATIS, name);
(void) do_system_command (command);
free (command);
}
/*
* Change a name of the form ...man/man1/name.1 to ...man/cat1/name.1
* or a name of the form ...man/cat1/name.1 to ...man/man1/name.1
*/
char *
convert_name (name, to_cat)
register char *name;
register int to_cat;
{
register char *to_name;
register char *t1;
register char *t2 = NULL;
#ifdef DO_COMPRESS
if (to_cat)
{
int len = strlen (name) + strlen(COMPRESS_EXT) + 1;
to_name = (char *) malloc (len);
if (to_name == NULL)
gripe_alloc (len, "to_name");
strcpy (to_name, name);
strcat (to_name, COMPRESS_EXT);
}
else
to_name = strdup (name);
#else
to_name = strdup (name);
#endif
t1 = strrchr (to_name, '/');
if (t1 != NULL)
{
*t1 = '\0';
t2 = strrchr (to_name, '/');
*t1 = '/';
}
if (t2 == NULL)
gripe_converting_name (name, to_cat);
if (to_cat)
{
*(++t2) = 'c';
*(t2+2) = 't';
}
else
{
*(++t2) = 'm';
*(t2+2) = 'n';
}
if (debug)
fprintf (stderr, "to_name in convert_name () is: %s\n", to_name);
return to_name;
}
/*
* Try to find the man page corresponding to the given name. The
* reason we do this with globbing is because some systems have man
* page directories named man3 which contain files with names like
* XtPopup.3Xt. Rather than requiring that this program know about
* all those possible names, we simply try to match things like
* .../man[sect]/name[sect]*. This is *much* easier.
*
* Note that globbing is only done when the section is unspecified.
*/
char **
glob_for_file (path, section, name, cat)
register char *path;
register char *section;
register char *name;
register int cat;
{
char pathname[BUFSIZ];
char **gf;
if (cat)
sprintf (pathname, "%s/cat%s/%s.%s*", path, section, name, section);
else
sprintf (pathname, "%s/man%s/%s.%s*", path, section, name, section);
if (debug)
fprintf (stderr, "globbing %s\n", pathname);
gf = glob_filename (pathname);
if ((gf == (char **) -1 || *gf == NULL) && isdigit (*section))
{
if (cat)
sprintf (pathname, "%s/cat%s/%s.%c*", path, section, name, *section);
else
sprintf (pathname, "%s/man%s/%s.%c*", path, section, name, *section);
gf = glob_filename (pathname);
}
return gf;
}
/*
* Return an un-globbed name in the same form as if we were doing
* globbing.
*/
char **
make_name (path, section, name, cat)
register char *path;
register char *section;
register char *name;
register int cat;
{
register int i = 0;
static char *names[3];
char buf[BUFSIZ];
if (cat)
sprintf (buf, "%s/cat%s/%s.%s", path, section, name, section);
else
sprintf (buf, "%s/man%s/%s.%s", path, section, name, section);
if (access (buf, R_OK) == 0)
names[i++] = strdup (buf);
/*
* If we're given a section that looks like `3f', we may want to try
* file names like .../man3/foo.3f as well. This seems a bit
* kludgey to me, but what the hey...
*/
if (section[1] != '\0')
{
if (cat)
sprintf (buf, "%s/cat%c/%s.%s", path, section[0], name, section);
else
sprintf (buf, "%s/man%c/%s.%s", path, section[0], name, section);
if (access (buf, R_OK) == 0)
names[i++] = strdup (buf);
}
names[i] = NULL;
return &names[0];
}
#ifdef DO_UNCOMPRESS
char *
get_expander (file)
char *file;
{
char *expander = NULL;
int len = strlen (file);
int i;
UNCOMPRESS *u = uncompress;
while (u->ext) {
if (0 < (i = len - strlen(u->ext)))
if (!strcmp(file + i, u->ext)) {
expander = u->prog;
break;
}
u++;
}
return expander;
}
#endif
/*
* Simply display the preformatted page.
*/
int
display_cat_file (file)
register char *file;
{
register int found;
char command[BUFSIZ];
found = 0;
if (access (file, R_OK) == 0)
{
#ifdef DO_UNCOMPRESS
char *expander = get_expander (file);
if (expander != NULL)
sprintf (command, "%s %s | %s", expander, file, pager);
else
sprintf (command, "%s %s", pager, file);
#else
sprintf (command, "%s %s", pager, file);
#endif
found = do_system_command (command);
}
return found;
}
/*
* Try to find the ultimate source file. If the first line of the
* current file is not of the form
*
* .so man3/printf.3s
*
* the input file name is returned.
*/
char *
ultimate_source (name, path)
char *name;
char *path;
{
FILE *fp;
char buf[BUFSIZ];
char ult[BUFSIZ];
char *beg;
char *end;
strcpy (ult, name);
strcpy (buf, name);
next:
if ((fp = fopen (ult, "r")) == NULL)
return buf;
if (fgets (buf, BUFSIZ, fp) == NULL)
return ult;
if (strlen (buf) < 5)
return ult;
beg = buf;
if (*beg++ == '.' && *beg++ == 's' && *beg++ == 'o')
{
while ((*beg == ' ' || *beg == '\t') && *beg != '\0')
beg++;
end = beg;
while (*end != ' ' && *end != '\t' && *end != '\n' && *end != '\0')
end++;
*end = '\0';
strcpy (ult, path);
strcat (ult, "/");
strcat (ult, beg);
strcpy (buf, ult);
goto next;
}
if (debug)
fprintf (stderr, "found ultimate source file %s\n", ult);
return ult;
}
void
add_directive (first, d, file, buf)
int *first;
char *d;
char *file;
char *buf;
{
if (strcmp (d, "") != 0)
{
if (*first)
{
*first = 0;
strcpy (buf, d);
strcat (buf, " ");
strcat (buf, file);
}
else
{
strcat (buf, " | ");
strcat (buf, d);
}
}
}
int
parse_roff_directive (cp, file, buf)
char *cp;
char *file;
char *buf;
{
char c;
int first = 1;
int tbl_found = 0;
while ((c = *cp++) != '\0')
{
switch (c)
{
case 'e':
if (debug)
fprintf (stderr, "found eqn(1) directive\n");
if (troff)
add_directive (&first, EQN, file, buf);
else
add_directive (&first, NEQN, file, buf);
break;
case 'g':
if (debug)
fprintf (stderr, "found grap(1) directive\n");
add_directive (&first, GRAP, file, buf);
break;
case 'p':
if (debug)
fprintf (stderr, "found pic(1) directive\n");
add_directive (&first, PIC, file, buf);
break;
case 't':
if (debug)
fprintf (stderr, "found tbl(1) directive\n");
tbl_found++;
add_directive (&first, TBL, file, buf);
break;
case 'v':
if (debug)
fprintf (stderr, "found vgrind(1) directive\n");
add_directive (&first, VGRIND, file, buf);
break;
case 'r':
if (debug)
fprintf (stderr, "found refer(1) directive\n");
add_directive (&first, REFER, file, buf);
break;
case ' ':
case '\t':
case '\n':
goto done;
default:
return -1;
}
}
done:
if (first)
return 1;
#ifdef HAS_TROFF
if (troff)
{
strcat (buf, " | ");
strcat (buf, TROFF);
}
else
#endif
{
strcat (buf, " | ");
strcat (buf, nroff);
}
if (tbl_found && !troff && strcmp (COL, "") != 0)
{
strcat (buf, " | ");
strcat (buf, COL);
}
return 0;
}
char *
make_roff_command (file)
char *file;
{
FILE *fp;
char line [BUFSIZ];
static char buf [BUFSIZ];
int status;
char *cp;
if (roff_directive != NULL)
{
if (debug)
fprintf (stderr, "parsing directive from command line\n");
status = parse_roff_directive (roff_directive, file, buf);
if (status == 0)
return buf;
if (status == -1)
gripe_roff_command_from_command_line (file);
}
if ((fp = fopen (file, "r")) != NULL)
{
cp = &line[0];
fgets (line, 100, fp);
if (*cp++ == '\'' && *cp++ == '\\' && *cp++ == '"' && *cp++ == ' ')
{
if (debug)
fprintf (stderr, "parsing directive from file\n");
status = parse_roff_directive (cp, file, buf);
fclose (fp);
if (status == 0)
return buf;
if (status == -1)
gripe_roff_command_from_file (file);
}
}
else
{
/*
* Is there really any point in continuing to look for
* preprocessor options if we can't even read the man page source?
*/
gripe_reading_man_file (file);
return NULL;
}
if ((cp = getenv ("MANROFFSEQ")) != NULL)
{
if (debug)
fprintf (stderr, "parsing directive from environment\n");
status = parse_roff_directive (cp, file, buf);
if (status == 0)
return buf;
if (status == -1)
gripe_roff_command_from_env ();
}
if (debug)
fprintf (stderr, "using default preprocessor sequence\n");
#ifdef HAS_TROFF
if (troff)
{
if (strcmp (TBL, "") != 0)
{
strcpy (buf, TBL);
strcat (buf, " ");
strcat (buf, file);
strcat (buf, " | ");
strcat (buf, TROFF);
}
else
{
strcpy (buf, TROFF);
strcat (buf, " ");
strcat (buf, file);
}
}
else
#endif
{
if (nroff == nroff_cmd && strcmp (TBL, "") != 0)
{
strcpy (buf, TBL);
strcat (buf, " ");
strcat (buf, file);
strcat (buf, " | ");
strcat (buf, nroff);
}
else
{
strcpy (buf, nroff);
strcat (buf, " ");
strcat (buf, file);
}
if (strcmp (COL, "") != 0)
{
strcat (buf, " | ");
strcat (buf, COL);
}
}
return buf;
}
char *
path_fixup(s)
char *s;
{
#if defined(OS2)
char *p = s;
if (s)
while (p = strchr(p, '/')) *p = '\\';
#endif
return s;
}
char *
chdir_fmt(path)
char *path;
{
static char buf[MAXPATHLEN+9];
#ifdef OS2
/*
sprintf(buf, "cd %s & ", path);
path_fixup(buf+3);
*/
*buf = '\0';
#else
sprintf(buf, "cd %s ; ", path);
#endif
return(buf);
}
/*
* Try to format the man page and create a new formatted file. Return
* 1 for success and 0 for failure.
*/
int
make_cat_file (path, man_file, cat_file)
register char *path;
register char *man_file;
register char *cat_file;
{
int status;
int mode;
FILE *fp;
char *roff_command;
char command[BUFSIZ];
if ((fp = fopen (cat_file, "w")) != NULL)
{
fclose (fp);
unlink (cat_file);
roff_command = make_roff_command (man_file, 0);
if (roff_command == NULL)
return 0;
else
#ifdef DO_COMPRESS
sprintf (command, "(%s%s | %s > %s)", chdir_fmt(path),
roff_command, COMPRESSOR, cat_file);
#else
sprintf (command, "(%s%s > %s)", chdir_fmt(path),
roff_command, cat_file);
#endif
/*
* Don't let the user interrupt the system () call and screw up
* the formmatted man page if we're not done yet.
*/
signal (SIGINT, SIG_IGN);
fprintf (stderr, "Formatting page, please wait...\n");
status = do_system_command (command);
if (status == 1)
{
mode = CATMODE;
chmod (cat_file, mode);
if (debug)
fprintf (stderr, "mode of %s is now %o\n", cat_file, mode);
}
signal (SIGINT, SIG_DFL);
return 1;
}
else
{
if (debug)
fprintf (stderr, "Couldn't open %s for writing.\n", cat_file);
return 0;
}
}
/*
* Try to format the man page source and save it, then display it. If
* that's not possible, try to format the man page source and display
* it directly.
*
* Note that we've already been handed the name of the ultimate source
* file at this point.
*/
int
format_and_display (path, man_file, cat_file)
register char *path;
register char *man_file;
register char *cat_file;
{
int status;
register int found;
char *roff_command;
char command[BUFSIZ];
found = 0;
if (access (man_file, R_OK) != 0)
return 0;
if (troff)
{
roff_command = make_roff_command (man_file, 1);
if (roff_command == NULL)
return 0;
else
sprintf (command, "(%s%s)", chdir_fmt(path), roff_command);
found = do_system_command (command);
}
else
{
status = is_newer (man_file, cat_file);
if (debug)
fprintf (stderr, "status from is_newer() = %d\n");
if (status == 1 || status == -2)
{
/*
* Cat file is out of date. Try to format and save it.
*/
if (print_where)
{
printf ("%s\n", man_file);
found++;
}
else
{
found = make_cat_file (path, man_file, cat_file);
#ifdef SECURE_MAN_UID
if (!found)
{
/*
* Try again as real user. Note that for private
* man pages, we won't even get this far unless the
* effective user can read the real user's man page
* source. Also, if we are trying to find all the
* man pages, this will probably make it impossible
* to make cat files in the system directories if
* the real user's man directories are searched
* first, because there's no way to undo this (is
* there?). Yikes, am I missing something obvious?
*/
setuid (getuid ());
found = make_cat_file (path, man_file, cat_file);
}
#endif
if (found)
{
/*
* Creating the cat file worked. Now just display it.
*/
(void) display_cat_file (cat_file);
}
else
{
/*
* Couldn't create cat file. Just format it and
* display it through the pager.
*/
roff_command = make_roff_command (man_file, 0);
if (roff_command == NULL)
return 0;
else
sprintf (command, "(%s%s | %s)", chdir_fmt(path),
roff_command, pager);
found = do_system_command (command);
}
}
}
else if (access (cat_file, R_OK) == 0)
{
/*
* Formatting not necessary. Cat file is newer than source
* file, or source file is not present but cat file is.
*/
if (print_where)
{
printf ("%s (source: %s)\n", cat_file, man_file);
found++;
}
else
{
found = display_cat_file (cat_file);
}
}
}
return found;
}
/*
* See if the preformatted man page or the source exists in the given
* section.
*/
int
try_section (path, section, name, glob)
register char *path;
register char *section;
register char *name;
register int glob;
{
register int found = 0;
register int to_cat;
register int cat;
register char **names;
register char **np;
if (debug)
{
if (glob)
fprintf (stderr, "trying section %s with globbing\n", section);
else
fprintf (stderr, "trying section %s without globbing\n", section);
}
#ifndef NROFF_MISSING
/*
* Look for man page source files.
*/
cat = 0;
if (glob)
names = glob_for_file (path, section, name, cat);
else
names = make_name (path, section, name, cat);
if (names == (char **) -1 || *names == NULL)
/*
* No files match. See if there's a preformatted page around that
* we can display.
*/
#endif /* NROFF_MISSING */
{
if (!troff)
{
cat = 1;
if (glob)
names = glob_for_file (path, section, name, cat);
else
names = make_name (path, section, name, cat);
if (names != (char **) -1 && *names != NULL)
{
for (np = names; *np != NULL; np++)
{
if (print_where)
{
printf ("%s\n", *np);
found++;
}
else
{
found += display_cat_file (path_fixup(*np));
}
}
}
}
}
#ifndef NROFF_MISSING
else
{
for (np = names; *np != NULL; np++)
{
register char *cat_file = NULL;
register char *man_file;
man_file = ultimate_source (*np, path);
if (!troff)
{
to_cat = 1;
cat_file = convert_name (man_file, to_cat);
if (debug)
fprintf (stderr, "will try to write %s if needed\n", cat_file);
}
found += format_and_display (path, man_file, path_fixup(cat_file));
}
}
#endif /* NROFF_MISSING */
return found;
}
/*
* Search for manual pages.
*
* If preformatted manual pages are supported, look for the formatted
* file first, then the man page source file. If they both exist and
* the man page source file is newer, or only the source file exists,
* try to reformat it and write the results in the cat directory. If
* it is not possible to write the cat file, simply format and display
* the man file.
*
* If preformatted pages are not supported, or the troff option is
* being used, only look for the man page source file.
*
*/
int
man (name)
char *name;
{
register int found;
register int glob;
register char **mp;
register char **sp;
found = 0;
fflush (stdout);
if (section != NULL)
{
for (mp = manpathlist; *mp != NULL; mp++)
{
if (debug)
fprintf (stderr, "\nsearching in %s\n", *mp);
glob = 0;
found += try_section (*mp, section, name, glob);
if (found && !findall) /* i.e. only do this section... */
return found;
}
}
else
{
for (sp = section_list; *sp != NULL; sp++)
{
for (mp = manpathlist; *mp != NULL; mp++)
{
if (debug)
fprintf (stderr, "\nsearching in %s\n", *mp);
glob = 1;
found += try_section (*mp, *sp, name, glob);
if (found && !findall) /* i.e. only do this section... */
return found;
}
}
}
return found;
}
char **
get_section_list ()
{
int i;
char *p;
char *end;
static char *tmp_section_list[100];
if (colon_sep_section_list == NULL)
{
if ((p = getenv ("MANSECT")) == NULL)
{
return std_sections;
}
else
{
colon_sep_section_list = strdup (p);
}
}
i = 0;
for (p = colon_sep_section_list; ; p = end+1)
{
if ((end = strchr (p, ':')) != NULL)
*end = '\0';
tmp_section_list[i++] = strdup (p);
if (end == NULL)
break;
}
tmp_section_list [i] = NULL;
return tmp_section_list;
}