netbsd man

This commit is contained in:
Ben Gras 2010-06-26 02:35:08 +00:00
parent 24cb4e60fc
commit a187743e75
8 changed files with 1771 additions and 1 deletions

View file

@ -16,7 +16,7 @@ SUBDIR= aal add_route adduser advent arp ash at autil awk \
hostaddr id ifconfig ifdef indent install \
intr ipcrm ipcs irdpd isoread join kill last leave \
less lex life loadkeys loadramdisk logger login look lp \
lpd ls lspci M m4 mail make MAKEDEV \
lpd ls lspci M m4 mail make MAKEDEV man \
mdb mdocml mesg mined mkdep mkdir mkdist mkfifo mkfs mknod \
mkproto modem mount mt netconf newroot nice nm nohup \
nonamed od packit packman passwd paste patch pax \

11
commands/man/Makefile Normal file
View file

@ -0,0 +1,11 @@
# $NetBSD: Makefile,v 1.10 2007/10/05 07:38:52 lukem Exp $
# @(#)Makefile 8.1 (Berkeley) 6/6/93
PROG= man
SRCS= man.c manconf.c
MAN= man.1 man.conf.5
DPADD+= ${LIBUTIL}
LDADD+= -lutil
.include <bsd.prog.mk>

233
commands/man/man.1 Normal file
View file

@ -0,0 +1,233 @@
.\" $NetBSD: man.1,v 1.20 2006/04/13 21:10:44 wiz Exp $
.\"
.\" Copyright (c) 1989, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)man.1 8.2 (Berkeley) 1/2/94
.\"
.Dd April 10, 2006
.Dt MAN 1
.Os
.Sh NAME
.Nm man
.Nd display the on-line manual pages
.Pq aka Dq Em man pages
.Sh SYNOPSIS
.Nm
.Oo Fl acw Ns \&| Ns Fl h Oc
.Op Fl C Ar file
.Op Fl M Ar path
.Op Fl m Ar path
.Op Fl S Ar srch
.Oo
.Op Fl s
.Ar section
.Oc
.Ar name Ar ...
.Nm
.Op Fl k
.Op Fl C Ar file
.Op Fl M Ar path
.Op Fl m Ar path
.Ar keyword Ar ...
.Sh DESCRIPTION
The
.Nm
utility displays the manual pages named on the command line.
Its options are as follows:
.Bl -tag -width indent
.It Fl a
Display all of the man pages for a specified
.Ar section
and
.Ar name
combination.
(Normally, only the first man page found is displayed.)
.It Fl C
Use the specified
.Ar file
instead of the default configuration file.
This permits users to configure their own man environment.
See
.Xr man.conf 5
for a description of the contents of this file.
.It Fl c
Copy the man page to the standard output instead of using
.Xr more 1
to paginate it.
This is done by default if the standard output is not a terminal device.
.It Fl h
Display only the
.Dq Tn SYNOPSIS
lines of the requested man pages.
For commands, this is typically the command line usage information.
For library functions, this usually contains the required include
files and function prototypes.
.It Fl k
Display the header lines for any man pages matching
.Ar keyword Ns Pq s ,
in the same manner as
.Xr apropos 1 .
.It Fl M
Override the list of standard directories which
.Nm
searches for man pages.
The supplied
.Ar path
must be a colon
.Pq Dq \&:
separated list of directories.
This search path may also be set using the environment variable
.Ev MANPATH .
The subdirectories to be searched, and their search order,
is specified by the
.Dq _subdir
line in the
.Nm
configuration file.
.It Fl m
Augment the list of standard directories which
.Nm
searches for man pages.
The supplied
.Ar path
must be a colon
.Pq Dq \&:
separated list of directories.
These directories will be searched before the standard directories or
the directories specified using the
.Fl M
option or the
.Ev MANPATH
environment variable.
The subdirectories to be searched, and their search order,
is specified by the
.Dq _subdir
line in the
.Nm
configuration file.
.It Fl s
Restrict the directories that
.Nm
will search to the specified section.
The
.Nm
configuration file (see
.Xr man.conf 5 )
specifies the possible
.Ar section
values that are currently available.
.It Fl S
Display only man pages that have the specified string in the directory
part of their filenames.
This allows the man page search process criteria to be
narrowed without having to change the MANPATH or
.Dq _default
variables.
.It Fl w
List the pathnames of the man pages which
.Nm
would display for the specified
.Ar section
and
.Ar name
combination.
.El
.Pp
If the
.Ql Fl s
option is not specified,
there is more than one argument,
the
.Ql Fl k
option is not used, and the first argument is a valid section, then that
argument will be used as if specified by the
.Ql Fl s
option.
.Sh ENVIRONMENT
.Bl -tag -width MANPATHX
.It Ev MACHINE
As some man pages are intended only for specific architectures,
.Nm
searches any subdirectories,
with the same name as the current architecture,
in every directory which it searches.
Machine specific areas are checked before general areas.
The current machine type may be overridden by setting the environment
variable
.Ev MACHINE
to the name of a specific architecture.
.It Ev MANPATH
The standard search path used by
.Nm
may be overridden by specifying a path in the
.Ev MANPATH
environment
variable.
The format of the path is a colon
.Pq Dq \&:
separated list of directories.
The subdirectories to be searched as well as their search order
is specified by the
.Dq _subdir
line in the
.Nm
configuration file.
.It Ev PAGER
The pagination command used for writing the output.
If the
.Ev PAGER
environment variable is null or not set, the standard pagination program
.Xr more 1
will be used.
.El
.Sh FILES
.Bl -hang -width /etc/man.conf -compact
.It Pa /etc/man.conf
default man configuration file.
.It Pa /usr/{share,X11R6,pkg,local}/man/whatis.db
standard whatis/apropos database search path,
set in
.Pa /etc/man.conf .
.El
.Sh SEE ALSO
.Xr apropos 1 ,
.Xr whatis 1 ,
.Xr whereis 1 ,
.Xr man.conf 5 ,
.Xr mdoc 7 ,
.Xr mdoc.samples 7
.Sh STANDARDS
.Nm
conforms to
.St -xcu5 .
.\"and is expected to conform to
.\".St -p1003.2-?? .
.Sh BUGS
The on-line man pages are, by necessity, forgiving toward stupid
display devices, causing a few man pages to be not as nicely formatted
as their typeset counterparts.

906
commands/man/man.c Normal file
View file

@ -0,0 +1,906 @@
/* $NetBSD: man.c,v 1.37 2008/07/21 14:19:24 lukem Exp $ */
/*
* Copyright (c) 1987, 1993, 1994, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/utsname.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <glob.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <util.h>
#include "manconf.h"
#include "pathnames.h"
#ifndef MAN_DEBUG
#define MAN_DEBUG 0 /* debug path output */
#endif
/*
* manstate: structure collecting the current global state so we can
* easily identify it and pass it to helper functions in one arg.
*/
struct manstate {
/* command line flags */
int all; /* -a: show all matches rather than first */
int cat; /* -c: do not use a pager */
char *conffile; /* -C: use alternate config file */
int how; /* -h: show SYNOPSIS only */
char *manpath; /* -M: alternate MANPATH */
char *addpath; /* -m: add these dirs to front of manpath */
char *pathsearch; /* -S: path of man must contain this string */
char *sectionname; /* -s: limit search to a given man section */
int where; /* -w: just show paths of all matching files */
/* important tags from the config file */
TAG *defaultpath; /* _default: default MANPATH */
TAG *subdirs; /* _subdir: default subdir search list */
TAG *suffixlist; /* _suffix: for files that can be cat()'d */
TAG *buildlist; /* _build: for files that must be built */
/* tags for internal use */
TAG *intmp; /* _intmp: tmp files we must cleanup */
TAG *missinglist; /* _missing: pages we couldn't find */
TAG *mymanpath; /* _new_path: final version of MANPATH */
TAG *section; /* <sec>: tag for m.sectionname */
/* other misc stuff */
const char *pager; /* pager to use */
size_t pagerlen; /* length of the above */
};
/*
* prototypes
*/
int main(int, char **);
static void build_page(char *, char **, struct manstate *);
static void cat(char *);
static const char *check_pager(const char *);
static int cleanup(void);
static void how(char *);
static void jump(char **, char *, char *);
static int manual(char *, struct manstate *, glob_t *);
static void onsig(int);
static void usage(void);
/*
* main function
*/
int
main(int argc, char **argv)
{
static struct manstate m = { 0 }; /* init to zero */
int ch, abs_section, found;
const char *machine;
ENTRY *esubd, *epath;
char *p, **ap, *cmd, buf[MAXPATHLEN * 2];
size_t len;
glob_t pg;
/*
* parse command line...
*/
while ((ch = getopt(argc, argv, "-aC:cfhkM:m:P:s:S:w")) != -1)
switch (ch) {
case 'a':
m.all = 1;
break;
case 'C':
m.conffile = optarg;
break;
case 'c':
case '-': /* XXX: '-' is a deprecated version of '-c' */
m.cat = 1;
break;
case 'h':
m.how = 1;
break;
case 'm':
m.addpath = optarg;
break;
case 'M':
case 'P': /* -P for backward compatibility */
m.manpath = strdup(optarg);
break;
/*
* The -f and -k options are backward compatible,
* undocumented ways of calling whatis(1) and apropos(1).
*/
case 'f':
jump(argv, "-f", "whatis");
/* NOTREACHED */
case 'k':
jump(argv, "-k", "apropos");
/* NOTREACHED */
case 's':
if (m.sectionname != NULL)
usage();
m.sectionname = optarg;
break;
case 'S':
m.pathsearch = optarg;
break;
case 'w':
m.all = m.where = 1;
break;
case '?':
default:
usage();
}
argc -= optind;
argv += optind;
if (!argc)
usage();
/*
* read the configuration file and collect any other information
* we will need (machine type, pager, section [if specified
* without '-s'], and MANPATH through the environment).
*/
config(m.conffile); /* exits on error ... */
if ((machine = getenv("MACHINE")) == NULL) {
struct utsname utsname;
if (uname(&utsname) == -1) {
perror("uname");
exit(1);
}
machine = utsname.machine;
}
if (!m.cat && !m.how && !m.where) { /* if we need a pager ... */
if (!isatty(STDOUT_FILENO)) {
m.cat = 1;
} else {
if ((m.pager = getenv("PAGER")) != NULL &&
m.pager[0] != '\0')
m.pager = check_pager(m.pager);
else
m.pager = _PATH_PAGER;
m.pagerlen = strlen(m.pager);
}
}
/* do we need to set m.section to a non-null value? */
if (m.sectionname) {
m.section = gettag(m.sectionname, 0); /* -s must be a section */
if (m.section == NULL)
errx(1, "unknown section: %s", m.sectionname);
} else if (argc > 1) {
m.section = gettag(*argv, 0); /* might be a section? */
if (m.section) {
argv++;
argc--;
}
}
if (m.manpath == NULL)
m.manpath = getenv("MANPATH"); /* note: -M overrides getenv */
/*
* get default values from config file, plus create the tags we
* use for keeping internal state. make sure all our mallocs
* go through.
*/
/* from cfg file */
m.defaultpath = gettag("_default", 1);
m.subdirs = gettag("_subdir", 1);
m.suffixlist = gettag("_suffix", 1);
m.buildlist = gettag("_build", 1);
/* internal use */
m.mymanpath = gettag("_new_path", 1);
m.missinglist = gettag("_missing", 1);
m.intmp = gettag("_intmp", 1);
if (!m.defaultpath || !m.subdirs || !m.suffixlist || !m.buildlist ||
!m.mymanpath || !m.missinglist || !m.intmp)
errx(1, "malloc failed");
/*
* are we using a section whose elements are all absolute paths?
* (we only need to look at the first entry on the section list,
* as config() will ensure that any additional entries will match
* the first one.)
*/
abs_section = (m.section != NULL &&
!TAILQ_EMPTY(&m.section->entrylist) &&
*(TAILQ_FIRST(&m.section->entrylist)->s) == '/');
/*
* now that we have all the data we need, we must determine the
* manpath we are going to use to find the requested entries using
* the following steps...
*
* [1] if the user specified a section and that section's elements
* from the config file are all absolute paths, then we override
* defaultpath and -M/MANPATH with the section's absolute paths.
*/
if (abs_section) {
m.manpath = NULL; /* ignore -M/MANPATH */
m.defaultpath = m.section; /* overwrite _default path */
m.section = NULL; /* promoted to defaultpath */
}
/*
* [2] section can now only be non-null if the user asked for
* a section and that section's elements did not have
* absolute paths. in this case we use the section's
* elements to override _subdir from the config file.
*
* after this step, we are done processing "m.section"...
*/
if (m.section)
m.subdirs = m.section;
/*
* [3] we need to setup the path we want to use (m.mymanpath).
* if the user gave us a path (m.manpath) use it, otherwise
* go with the default. in either case we need to append
* the subdir and machine spec to each element of the path.
*
* for absolute section paths that come from the config file,
* we only append the subdir spec if the path ends in
* a '/' --- elements that do not end in '/' are assumed to
* not have subdirectories. this is mainly for backward compat,
* but it allows non-subdir configs like:
* sect3 /usr/share/man/{old/,}cat3
* doc /usr/{pkg,share}/doc/{sendmail/op,sendmail/intro}
*
* note that we try and be careful to not put double slashes
* in the path (e.g. we want /usr/share/man/man1, not
* /usr/share/man//man1) because "more" will put the filename
* we generate in its prompt and the double slashes look ugly.
*/
if (m.manpath) {
/* note: strtok is going to destroy m.manpath */
for (p = strtok(m.manpath, ":") ; p ; p = strtok(NULL, ":")) {
len = strlen(p);
if (len < 1)
continue;
TAILQ_FOREACH(esubd, &m.subdirs->entrylist, q) {
snprintf(buf, sizeof(buf), "%s%s%s{/%s,}",
p, (p[len-1] == '/') ? "" : "/",
esubd->s, machine);
if (addentry(m.mymanpath, buf, 0) < 0)
errx(1, "malloc failed");
}
}
} else {
TAILQ_FOREACH(epath, &m.defaultpath->entrylist, q) {
/* handle trailing "/" magic here ... */
if (abs_section &&
epath->s[epath->len - 1] != '/') {
(void)snprintf(buf, sizeof(buf),
"%s{/%s,}", epath->s, machine);
if (addentry(m.mymanpath, buf, 0) < 0)
errx(1, "malloc failed");
continue;
}
TAILQ_FOREACH(esubd, &m.subdirs->entrylist, q) {
snprintf(buf, sizeof(buf), "%s%s%s{/%s,}",
epath->s,
(epath->s[epath->len-1] == '/') ? ""
: "/",
esubd->s, machine);
if (addentry(m.mymanpath, buf, 0) < 0)
errx(1, "malloc failed");
}
}
}
/*
* [4] finally, prepend the "-m" m.addpath to mymanpath if it
* was specified. subdirs and machine are always applied to
* m.addpath.
*/
if (m.addpath) {
/* note: strtok is going to destroy m.addpath */
for (p = strtok(m.addpath, ":") ; p ; p = strtok(NULL, ":")) {
len = strlen(p);
if (len < 1)
continue;
TAILQ_FOREACH(esubd, &m.subdirs->entrylist, q) {
snprintf(buf, sizeof(buf), "%s%s%s{/%s,}",
p, (p[len-1] == '/') ? "" : "/",
esubd->s, machine);
/* add at front */
if (addentry(m.mymanpath, buf, 1) < 0)
errx(1, "malloc failed");
}
}
}
/*
* now m.mymanpath is complete!
*/
#if MAN_DEBUG
printf("mymanpath:\n");
TAILQ_FOREACH(epath, &m.mymanpath->entrylist, q) {
printf("\t%s\n", epath->s);
}
#endif
/*
* start searching for matching files and format them if necessary.
* setup an interrupt handler so that we can ensure that temporary
* files go away.
*/
(void)signal(SIGINT, onsig);
(void)signal(SIGHUP, onsig);
(void)signal(SIGPIPE, onsig);
memset(&pg, 0, sizeof(pg));
for (found = 0; *argv; ++argv)
if (manual(*argv, &m, &pg)) {
found = 1;
}
/* if nothing found, we're done. */
if (!found) {
(void)cleanup();
exit (1);
}
/*
* handle the simple display cases first (m.cat, m.how, m.where)
*/
if (m.cat) {
for (ap = pg.gl_pathv; *ap != NULL; ++ap) {
if (**ap == '\0')
continue;
cat(*ap);
}
exit (cleanup());
}
if (m.how) {
for (ap = pg.gl_pathv; *ap != NULL; ++ap) {
if (**ap == '\0')
continue;
how(*ap);
}
exit(cleanup());
}
if (m.where) {
for (ap = pg.gl_pathv; *ap != NULL; ++ap) {
if (**ap == '\0')
continue;
(void)printf("%s\n", *ap);
}
exit(cleanup());
}
/*
* normal case - we display things in a single command, so
* build a list of things to display. first compute total
* length of buffer we will need so we can malloc it.
*/
for (ap = pg.gl_pathv, len = m.pagerlen + 1; *ap != NULL; ++ap) {
if (**ap == '\0')
continue;
len += strlen(*ap) + 1;
}
if ((cmd = malloc(len)) == NULL) {
warn("malloc");
(void)cleanup();
exit(1);
}
/* now build the command string... */
p = cmd;
len = m.pagerlen;
memcpy(p, m.pager, len);
p += len;
*p++ = ' ';
for (ap = pg.gl_pathv; *ap != NULL; ++ap) {
if (**ap == '\0')
continue;
len = strlen(*ap);
memcpy(p, *ap, len);
p += len;
*p++ = ' ';
}
*--p = '\0';
/* Use system(3) in case someone's pager is "pager arg1 arg2". */
(void)system(cmd);
exit(cleanup());
}
/*
* manual --
* Search the manuals for the pages.
*/
static int
manual(char *page, struct manstate *mp, glob_t *pg)
{
ENTRY *suffix, *mdir;
int anyfound, error, found;
size_t cnt;
char *p, buf[MAXPATHLEN], *escpage, *eptr;
static const char escglob[] = "\\~?*{}[]";
anyfound = 0;
/*
* Fixup page which may contain glob(3) special characters, e.g.
* the famous "No man page for [" FAQ.
*/
if ((escpage = malloc((2 * strlen(page)) + 1)) == NULL) {
warn("malloc");
(void)cleanup();
exit(1);
}
p = page;
eptr = escpage;
while (*p) {
if (strchr(escglob, *p) != NULL) {
*eptr++ = '\\';
*eptr++ = *p++;
} else
*eptr++ = *p++;
}
*eptr = '\0';
/* For each man directory in mymanpath ... */
TAILQ_FOREACH(mdir, &mp->mymanpath->entrylist, q) {
/*
* use glob(3) to look in the filesystem for matching files.
* match any suffix here, as we will check that later.
*/
(void)snprintf(buf, sizeof(buf), "%s/%s.*", mdir->s, escpage);
if ((error = glob(buf,
GLOB_APPEND | GLOB_BRACE | GLOB_NOSORT, NULL, pg)) != 0) {
if (error == GLOB_NOMATCH)
continue;
else {
warn("globbing");
(void)cleanup();
exit(1);
}
}
if (pg->gl_matchc == 0)
continue;
/*
* start going through the matches glob(3) just found and
* use m.pathsearch (if present) to filter out pages we
* don't want. then verify the suffix is valid, and build
* the page if we have a _build suffix.
*/
for (cnt = pg->gl_pathc - pg->gl_matchc;
cnt < pg->gl_pathc; ++cnt) {
/* filter on directory path name */
if (mp->pathsearch) {
p = strstr(pg->gl_pathv[cnt], mp->pathsearch);
if (!p || strchr(p, '/') == NULL) {
pg->gl_pathv[cnt] = ""; /* zap! */
continue;
}
}
/*
* Try the _suffix key words first.
*
* XXX
* Older versions of man.conf didn't have the suffix
* key words, it was assumed that everything was a .0.
* We just test for .0 first, it's fast and probably
* going to hit.
*/
(void)snprintf(buf, sizeof(buf), "*/%s.0", escpage);
if (!fnmatch(buf, pg->gl_pathv[cnt], 0))
goto next;
found = 0;
TAILQ_FOREACH(suffix, &mp->suffixlist->entrylist, q) {
(void)snprintf(buf,
sizeof(buf), "*/%s%s", escpage,
suffix->s);
if (!fnmatch(buf, pg->gl_pathv[cnt], 0)) {
found = 1;
break;
}
}
if (found)
goto next;
/* Try the _build key words next. */
found = 0;
TAILQ_FOREACH(suffix, &mp->buildlist->entrylist, q) {
for (p = suffix->s;
*p != '\0' && !isspace((unsigned char)*p);
++p)
continue;
if (*p == '\0')
continue;
*p = '\0';
(void)snprintf(buf,
sizeof(buf), "*/%s%s", escpage,
suffix->s);
if (!fnmatch(buf, pg->gl_pathv[cnt], 0)) {
if (!mp->where)
build_page(p + 1,
&pg->gl_pathv[cnt], mp);
*p = ' ';
found = 1;
break;
}
*p = ' ';
}
if (found) {
next: anyfound = 1;
if (!mp->all) {
/* Delete any other matches. */
while (++cnt< pg->gl_pathc)
pg->gl_pathv[cnt] = "";
break;
}
continue;
}
/* It's not a man page, forget about it. */
pg->gl_pathv[cnt] = "";
}
if (anyfound && !mp->all)
break;
}
/* If not found, enter onto the missing list. */
if (!anyfound) {
if (addentry(mp->missinglist, page, 0) < 0) {
warn("malloc");
(void)cleanup();
exit(1);
}
}
free(escpage);
return (anyfound);
}
/*
* build_page --
* Build a man page for display.
*/
static void
build_page(char *fmt, char **pathp, struct manstate *mp)
{
static int warned;
int olddir, fd, n, tmpdirlen;
char *p, *b;
char buf[MAXPATHLEN], cmd[MAXPATHLEN], tpath[MAXPATHLEN];
const char *tmpdir;
/* Let the user know this may take awhile. */
if (!warned) {
warned = 1;
warnx("Formatting manual page...");
}
/*
* Historically man chdir'd to the root of the man tree.
* This was used in man pages that contained relative ".so"
* directives (including other man pages for command aliases etc.)
* It even went one step farther, by examining the first line
* of the man page and parsing the .so filename so it would
* make hard(?) links to the cat'ted man pages for space savings.
* (We don't do that here, but we could).
*/
/* copy and find the end */
for (b = buf, p = *pathp; (*b++ = *p++) != '\0';)
continue;
/*
* skip the last two path components, page name and man[n] ...
* (e.g. buf will be "/usr/share/man" and p will be "man1/man.1")
* we also save a pointer to our current directory so that we
* can fchdir() back to it. this allows relative MANDIR paths
* to work with multiple man pages... e.g. consider:
* cd /usr/share && man -M ./man cat ls
* when no "cat1" subdir files are present.
*/
olddir = -1;
for (--b, --p, n = 2; b != buf; b--, p--)
if (*b == '/')
if (--n == 0) {
*b = '\0';
olddir = open(".", O_RDONLY);
(void) chdir(buf);
p++;
break;
}
/* advance fmt pass the suffix spec to the printf format string */
for (; *fmt && isspace((unsigned char)*fmt); ++fmt)
continue;
/*
* Get a temporary file and build a version of the file
* to display. Replace the old file name with the new one.
*/
if ((tmpdir = getenv("TMPDIR")) == NULL)
tmpdir = _PATH_TMP;
tmpdirlen = strlen(tmpdir);
(void)snprintf(tpath, sizeof (tpath), "%s%s%s", tmpdir,
(tmpdirlen && tmpdir[tmpdirlen-1] == '/') ? "" : "/", TMPFILE);
if ((fd = mkstemp(tpath)) == -1) {
warn("%s", tpath);
(void)cleanup();
exit(1);
}
(void)snprintf(buf, sizeof(buf), "%s > %s", fmt, tpath);
(void)snprintf(cmd, sizeof(cmd), buf, p);
(void)system(cmd);
(void)close(fd);
if ((*pathp = strdup(tpath)) == NULL) {
warn("malloc");
(void)cleanup();
exit(1);
}
/* Link the built file into the remove-when-done list. */
if (addentry(mp->intmp, *pathp, 0) < 0) {
warn("malloc");
(void)cleanup();
exit(1);
}
/* restore old directory so relative manpaths still work */
if (olddir != -1) {
fchdir(olddir);
close(olddir);
}
}
/*
* how --
* display how information
*/
static void
how(char *fname)
{
FILE *fp;
int lcnt, print;
char *p, buf[256];
if (!(fp = fopen(fname, "r"))) {
warn("%s", fname);
(void)cleanup();
exit (1);
}
#define S1 "SYNOPSIS"
#define S2 "S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS"
#define D1 "DESCRIPTION"
#define D2 "D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN"
for (lcnt = print = 0; fgets(buf, sizeof(buf), fp);) {
if (!strncmp(buf, S1, sizeof(S1) - 1) ||
!strncmp(buf, S2, sizeof(S2) - 1)) {
print = 1;
continue;
} else if (!strncmp(buf, D1, sizeof(D1) - 1) ||
!strncmp(buf, D2, sizeof(D2) - 1)) {
if (fp)
(void)fclose(fp);
return;
}
if (!print)
continue;
if (*buf == '\n')
++lcnt;
else {
for(; lcnt; --lcnt)
(void)putchar('\n');
for (p = buf; isspace((unsigned char)*p); ++p)
continue;
(void)fputs(p, stdout);
}
}
(void)fclose(fp);
}
/*
* cat --
* cat out the file
*/
static void
cat(char *fname)
{
int fd, n;
char buf[2048];
if ((fd = open(fname, O_RDONLY, 0)) < 0) {
warn("%s", fname);
(void)cleanup();
exit(1);
}
while ((n = read(fd, buf, sizeof(buf))) > 0)
if (write(STDOUT_FILENO, buf, n) != n) {
warn("write");
(void)cleanup();
exit (1);
}
if (n == -1) {
warn("read");
(void)cleanup();
exit(1);
}
(void)close(fd);
}
/*
* check_pager --
* check the user supplied page information
*/
static const char *
check_pager(const char *name)
{
const char *p;
/*
* if the user uses "more", we make it "more -s"; watch out for
* PAGER = "mypager /usr/ucb/more"
*/
for (p = name; *p && !isspace((unsigned char)*p); ++p)
continue;
for (; p > name && *p != '/'; --p);
if (p != name)
++p;
/* make sure it's "more", not "morex" */
if (!strncmp(p, "more", 4) && (!p[4] || isspace((unsigned char)p[4]))){
char *newname;
if(!(newname = malloc(strlen(p) + 20))) {
errx(1, "malloc failed");
}
(void)sprintf(newname, "%s %s", p, "-s");
name = newname;
}
return (name);
}
/*
* jump --
* strip out flag argument and jump
*/
static void
jump(char **argv, char *flag, char *name)
{
char **arg;
argv[0] = name;
for (arg = argv + 1; *arg; ++arg)
if (!strcmp(*arg, flag))
break;
for (; *arg; ++arg)
arg[0] = arg[1];
execvp(name, argv);
(void)fprintf(stderr, "%s: Command not found.\n", name);
exit(1);
}
/*
* onsig --
* If signaled, delete the temporary files.
*/
static void
onsig(int signo)
{
(void)cleanup();
#if 0
(void)raise_default_signal(signo);
#endif
/* NOTREACHED */
exit (1);
}
/*
* cleanup --
* Clean up temporary files, show any error messages.
*/
static int
cleanup()
{
TAG *intmpp, *missp;
ENTRY *ep;
int rval;
rval = 0;
/*
* note that _missing and _intmp were created by main(), so
* gettag() cannot return NULL here.
*/
missp = gettag("_missing", 0); /* missing man pages */
intmpp = gettag("_intmp", 0); /* tmp files we need to unlink */
TAILQ_FOREACH(ep, &missp->entrylist, q) {
warnx("no entry for %s in the manual.", ep->s);
rval = 1;
}
TAILQ_FOREACH(ep, &intmpp->entrylist, q)
(void)unlink(ep->s);
return (rval);
}
/*
* usage --
* print usage message and die
*/
static void
usage()
{
(void)fprintf(stderr, "usage: %s [-acw|-h] [-C cfg] [-M path] "
"[-m path] [-S srch] [[-s] sect] name ...\n", getprogname());
(void)fprintf(stderr,
"usage: %s -k [-C cfg] [-M path] [-m path] keyword ...\n",
getprogname());
exit(1);
}

271
commands/man/man.conf.5 Normal file
View file

@ -0,0 +1,271 @@
.\" $NetBSD: man.conf.5,v 1.20 2007/02/10 19:27:39 reed Exp $
.\"
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)man.conf.5 8.5 (Berkeley) 1/2/94
.\"
.Dd April 10, 2006
.Dt MAN.CONF 5
.Os
.Sh NAME
.Nm man.conf
.Nd configuration file for manual pages
.Sh DESCRIPTION
The
.Nm
file contains the default configuration used by
.Xr man 1 ,
.Xr apropos 1 ,
.Xr whatis 1 ,
.Xr catman 8 ,
and
.Xr makewhatis 8
to find manual pages and information about manual pages (e.g. the
whatis database).
.Pp
Manual pages are located by searching an ordered set of directories
called the
.Dq man path
for a file that matches the name of the requested page.
Each directory in the search path usually has a set of subdirectories
in it (though this is not required).
When subdirectories are used, there are normally two subdirectories
for each section of the manual.
One subdirectory contains formatted copies of that section's manual
pages that can be directly displayed to a terminal, while the other
section subdirectory contains unformatted copies of the pages (see
.Xr nroff 1
and
.Xr mdoc 7 ) .
Formatted manual pages are normally named with a trailing
.Dq \.0
suffix.
.Pp
The
.Nm
file contains comment and configuration lines.
Comment lines start with the
.Dq #
character.
Blank lines are also treated as comment lines.
Configuration lines consist of a configuration keyword followed by a
configuration string.
There are two types of configuration keywords: control keywords and
section keywords.
Control keywords must start with the
.Dq _
character.
The following control keywords are currently defined:
.Bl -tag -width "_version"
.It _build
identifies the set of suffixes used for manual pages that must be
formatted for display and the command that should be used to format
them.
Manual file names, regardless of their format, are expected to end in a
.Dq \.*
pattern, i.e. a
.Dq \&\.
followed by some suffix.
The first field of a _build line contains a man page suffix specification.
The suffix specification may contain the normal shell globbing characters
(NOT including curly braces
.Pq Dq {} ) .
The rest of the _build line is a shell command line whose standard
output is a formatted manual page that can be directly displayed to
the user.
Any occurrences of the string
.Dq %s
in the shell command line will
be replaced by the name of the file which is being formatted.
.It _crunch
used by
.Xr catman 8
to determine how to crunch formatted pages
which originally were compressed man pages: The first field lists a suffix
which indicates what kind of compression were used to compress the man page.
The rest of the line must be a shell command line, used to compress the
formatted pages.
.It _default
contains the system-wide default man path used to search for man pages.
.It _subdir
contains the list (in search order) of section subdirectories which will
be searched in any man path directory named with a trailing slash
.Pq Dq /
character.
This list is also used, even if there is no trailing slash character,
when a path is specified to the
.Xr man 1
utility by the user, by the
.Ev MANPATH
environment variable, or by the
.Fl M
and
.Fl m
options.
.It _suffix
identifies the set of suffixes used for formatted man pages
(the
.Dq \.0
suffix is normally used here).
Formatted man pages can be directly displayed to the user.
Each suffix may contain the normal shell globbing characters (NOT
including curly braces
.Pq Dq {} ) .
.It _version
contains the version of the configuration file.
.It _whatdb
defines the full pathname (not just a directory path) for a database to
be used
by the
.Xr apropos 1
and
.Xr whatis 1
commands.
The pathname may contain the normal shell globbing characters,
including curly braces
.Pq Dq {} ;
to escape a shell globbing character,
precede it with a backslash
.Pq Dq \e .
.El
.Pp
Section configuration lines in
.Nm
consist of a section keyword naming the section and a configuration
string that defines the directory or subdirectory path that the section's
manual pages are located in.
The path may contain the normal shell globbing characters,
including curly braces
.Pq Dq {} ;
to escape a shell globbing character,
precede it with a backslash
.Pq Dq \e .
Section keywords must not start with the
.Dq _
character.
.Pp
A section path may contain either a list of absolute directories or
a list of or relative directories (but not both).
Relative directory paths are treated as a list of subdirectories that
are appended to the current man path directory being searched.
Section configuration lines with absolute directory paths (starting with
.Dq / )
completely replace the current man search path directory with their
content.
.Pp
Section configuration lines with absolute directory paths ending
with a trailing slash character are expected to contain subdirectories
of manual pages, (see the keyword
.Dq _subdir
above).
The
.Dq _subdir
subdirectory list is not applied to absolute section directories
if there is no trailing slash.
.Pp
In addition to the above rules, the
.Xr man 1
command also always checks in each directory that it searches for
a subdirectory with the same name as the current machine type.
If the machine-specific directory is found, it is also searched.
This allows the manual to contain machine-specific man pages.
Note that the machine subdirectory does not need to be specified
in the
.Nm
file.
.Pp
Multiple specifications for all types of
.Nm
configuration lines are
cumulative and the entries are used in the order listed in the file;
multiple entries may be listed per line, as well.
.Sh FILES
.Bl -tag -width /etc/man.conf -compact
.It Pa /etc/man.conf
Standard manual configuration file.
.El
.Sh EXAMPLES
Given the following
.Nm
file:
.Bd -literal -offset indent
_version BSD.2
_subdir cat[123]
_suffix .0
_build .[1-9] nroff -man %s
_build .tbl tbl %s | nroff -man
_default /usr/share/man/
sect3 /usr/share/man/{old/,}cat3
.Ed
.Pp
By default, the command
.Dq Li man mktemp
will search for
.Dq mktemp.\*[Lt]any_digit\*[Gt]
and
.Dq mktemp.tbl
in the directories
.Dq Pa /usr/share/man/cat1 ,
.Dq Pa /usr/share/man/cat2 ,
and
.Dq Pa /usr/share/man/cat3 .
If on a machine of type
.Dq vax ,
the subdirectory
.Dq vax
in each
directory would be searched as well, before the directory was
searched.
.Pp
If
.Dq mktemp.tbl
was found first, the command
.Dq Li tbl \*[Lt]manual page\*[Gt] | nroff -man
would be run to build a man page for display to the user.
.Pp
The command
.Dq Li man sect3 mktemp
would search the directories
.Dq Pa /usr/share/man/old/cat3
and
.Dq Pa /usr/share/man/cat3 ,
in that order, for
the mktemp manual page.
If a subdirectory with the same name as the current machine type
existed in any of them, it would be searched as well, before each
of them were searched.
.Sh SEE ALSO
.Xr apropos 1 ,
.Xr machine 1 ,
.Xr man 1 ,
.Xr whatis 1 ,
.Xr whereis 1 ,
.Xr fnmatch 3 ,
.Xr glob 3 ,
.Xr catman 8 ,
.Xr makewhatis 8

250
commands/man/manconf.c Normal file
View file

@ -0,0 +1,250 @@
/* $NetBSD: manconf.c,v 1.6 2008/03/08 15:48:27 christos Exp $ */
/*
* Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* manconf.c: provides interface for reading man.conf files
*
* note that this code is shared across all programs that read man.conf.
* (currently: apropos, catman, makewhatis, man, and whatis...)
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "manconf.h"
#include "pathnames.h"
TAILQ_HEAD(_head, _tag);
static struct _head head; /* 'head' -- top level data structure */
/*
* xstrdup: like strdup, but also returns length of string in lenp
*/
static char *
xstrdup(const char *str, size_t *lenp)
{
size_t len;
char *copy;
len = strlen(str) + 1;
copy = malloc(len);
if (!copy)
return NULL;
(void)memcpy(copy, str, len);
if (lenp)
*lenp = len - 1; /* subtract out the null */
return copy;
}
/*
* config --
*
* Read the configuration file and build a doubly linked
* list off of "head" that looks like:
*
* tag1 <-> entry <-> entry <-> entry
* |
* tag2 <-> entry <-> entry <-> entry
*
* note: will err/errx out on error (fopen or malloc failure)
*/
void
config(const char *fname)
{
TAG *tp;
FILE *cfp;
size_t len;
int lcnt;
char *p, *t, type;
if (fname == NULL)
fname = _PATH_MANCONF;
if ((cfp = fopen(fname, "r")) == NULL)
err(EXIT_FAILURE, "%s", fname);
TAILQ_INIT(&head);
for (lcnt = 1; (p = fgetln(cfp, &len)) != NULL; ++lcnt) {
if (len == 1) /* Skip empty lines. */
continue;
if (p[len - 1] != '\n') { /* Skip corrupted lines. */
warnx("%s: line %d corrupted", fname, lcnt);
continue;
}
p[len - 1] = '\0'; /* Terminate the line. */
/* Skip leading space. */
for (/*EMPTY*/; *p != '\0' && isspace((unsigned char)*p); ++p)
continue;
/* Skip empty/comment lines. */
if (*p == '\0' || *p == '#')
continue;
/* Find first token. */
for (t = p; *t && !isspace((unsigned char)*t); ++t)
continue;
if (*t == '\0') /* Need more than one token.*/
continue;
*t = '\0';
tp = gettag(p, 1);
if (!tp)
errx(EXIT_FAILURE, "gettag: malloc failed");
/*
* Attach new records. Check to see if it is a
* section record or not.
*/
if (*p == '_') { /* not a section record */
/*
* Special cases: _build and _crunch take the
* rest of the line as a single entry.
*/
if (!strcmp(p, "_build") || !strcmp(p, "_crunch")) {
/*
* The reason we're not just using
* strtok(3) for all of the parsing is
* so we don't get caught if a line
* has only a single token on it.
*/
while (*++t && isspace((unsigned char)*t));
if (addentry(tp, t, 0) == -1)
errx(EXIT_FAILURE,
"addentry: malloc failed");
} else {
for (++t; (p = strtok(t, " \t\n")) != NULL;
t = NULL) {
if (addentry(tp, p, 0) == -1)
errx(EXIT_FAILURE,
"addentry: malloc failed");
}
}
} else { /* section record */
/*
* section entries can either be all absolute
* paths or all relative paths, but not both.
*/
type = (TAILQ_FIRST(&tp->entrylist) != NULL) ?
*(TAILQ_FIRST(&tp->entrylist)->s) : 0;
for (++t; (p = strtok(t, " \t\n")) != NULL; t = NULL) {
/* ensure an assigned type */
if (type == 0)
type = *p;
/* check for illegal mix */
if (*p != type) {
warnx("section %s: %s: invalid entry, does not match previous types",
tp->s, p);
warnx("man.conf cannot mix absolute and relative paths in an entry");
continue;
}
if (addentry(tp, p, 0) == -1)
errx(EXIT_FAILURE,
"addentry: malloc failed");
}
}
}
(void)fclose(cfp);
}
/*
* gettag --
* if (!create) return tag for given name if it exists, or NULL otherwise
*
* if (create) return tag for given name if it exists, try and create
* a new tag if it does not exist. return NULL if unable to create new
* tag.
*/
TAG *
gettag(const char *name, int create)
{
TAG *tp;
TAILQ_FOREACH(tp, &head, q)
if (!strcmp(name, tp->s))
return tp;
if (!create)
return NULL;
/* try and add it in */
tp = malloc(sizeof(*tp));
if (tp)
tp->s = xstrdup(name, &tp->len);
if (!tp || !tp->s) {
if (tp)
free(tp);
return NULL;
}
TAILQ_INIT(&tp->entrylist);
TAILQ_INSERT_TAIL(&head, tp, q);
return tp;
}
/*
* addentry --
* add an entry to a list.
* returns -1 if malloc failed, otherwise 0.
*/
int
addentry(TAG *tp, const char *newent, int ishead)
{
ENTRY *ep;
ep = malloc(sizeof(*ep));
if (ep)
ep->s = xstrdup(newent, &ep->len);
if (!ep || !ep->s) {
if (ep)
free(ep);
return -1;
}
if (ishead)
TAILQ_INSERT_HEAD(&tp->entrylist, ep, q);
else
TAILQ_INSERT_TAIL(&tp->entrylist, ep, q);
return 0;
}

60
commands/man/manconf.h Normal file
View file

@ -0,0 +1,60 @@
/* $NetBSD: manconf.h,v 1.3 2006/04/10 14:39:06 chuck Exp $ */
/*-
* Copyright (c) 1993
* The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)config.h 8.4 (Berkeley) 12/18/93
*/
/*
* manconf.h: common data structures and APIs shared across all programs
* that access man.conf (currently: apropos, catman, makewhatis, man, and
* whatis).
*/
/* TAG: top-level structure (one per section/reserved word) */
typedef struct _tag {
TAILQ_ENTRY(_tag) q; /* Queue of tags */
TAILQ_HEAD(tqh, _entry) entrylist; /* Queue of entries */
char *s; /* Associated string */
size_t len; /* Length of 's' */
} TAG;
/* ENTRY: each TAG has one or more ENTRY strings linked off of it */
typedef struct _entry {
TAILQ_ENTRY(_entry) q; /* Queue of entries */
char *s; /* Associated string */
size_t len; /* Length of 's' */
} ENTRY;
int addentry(TAG *, const char *, int);
void config(const char *);
TAG *gettag(const char *, int);

39
commands/man/pathnames.h Normal file
View file

@ -0,0 +1,39 @@
/* $NetBSD: pathnames.h,v 1.5 2003/08/07 11:15:11 agc Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pathnames.h 8.3 (Berkeley) 1/2/94
*/
#include <minix/paths.h>
#define _PATH_MANCONF "/etc/man.conf"
#define _PATH_PAGER "/usr/bin/more -s"
#define _PATH_WHATIS "whatis.db"
#define TMPFILE "man.XXXXXX"