NetBSD Problem Report #1904

From gnats  Sat Jan  6 15:36:20 1996
Received: from snarf.umiacs.umd.edu by pain.lcs.mit.edu (8.6.12/8.6.9) with ESMTP id PAA09414 for <gnats-bugs@gnats.netbsd.org>; Sat, 6 Jan 1996 15:31:36 -0500
Message-Id: <199601062031.PAA19882@snarf.umiacs.umd.edu>
Date: Sat, 6 Jan 1996 15:31:23 -0500
From: kashmir@umiacs.umd.edu
To: gnats-bugs@gnats.netbsd.org
Subject: changes to man programs
X-Send-Pr-Version: 3.95

>Number:         1904
>Category:       bin
>Synopsis:       changes to man programs
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          closed
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Jan 06 15:50:01 +0000 1996
>Closed-Date:    Sun May 29 22:37:10 +0000 2016
>Last-Modified:  Sun May 29 22:37:10 +0000 2016
>Originator:     Mike Grupenhoff
>Release:        19960106
>Organization:
nyuk nyuk
>Environment:
System: NetBSD snarf.umiacs.umd.edu 1.1A NetBSD 1.1A (SNARF) #7: Fri Dec 29 23:04:19 EST 1995 kashmir@snarf.umiacs.umd.edu:/usr/src/sys/arch/i386/compile/SNARF i386
>Description:

- apropos and whatis can't handle multiple whatis db's when they
  are specified in shell glob syntax.  For example, a line like:

  _whatdb         /usr/{share,local,afs,X11}/man/whatis.db

  in /etc/man.conf will not be handled properly.

- catman doesn't work with /etc/man.conf and linked manpages

- bsd.man.mk doesn't use the build rules listed in /etc/man.conf
  catman should be used in bsd.man.mk instead of nroff

>How-To-Repeat:
look at the source
>Fix:
4 patches are attached.

The first patch adds support to apropos for globbing _whatdb.

-----cut-here-----
Index: apropos.c
===================================================================
RCS file: /snarf/netbsd/master/src/usr.bin/apropos/apropos.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 apropos.c
--- apropos.c	1995/11/16 02:27:00	1.1.1.1
+++ apropos.c	1996/01/02 05:28:43
@@ -52,6 +52,7 @@

 #include <ctype.h>
 #include <err.h>
+#include <glob.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -77,6 +78,7 @@
 	TAG *tp;
 	int ch, rv;
 	char *conffile, **p, *p_augment, *p_path;
+	glob_t pg;

 	conffile = NULL;
 	p_augment = p_path = NULL;
@@ -117,8 +119,15 @@
 		config(conffile);
 		ep = (tp = getlist("_whatdb")) == NULL ?
 		    NULL : tp->list.tqh_first;
-		for (; ep != NULL; ep = ep->q.tqe_next)
-			apropos(argv, ep->s, 0);
+		for (; ep != NULL; ep = ep->q.tqe_next) {
+			if (glob(ep->s, GLOB_BRACE|GLOB_QUOTE, NULL, &pg) != 0)
+				err(1, "glob");
+			if (pg.gl_matchc == 0)
+				continue;
+			for (ch = 0; pg.gl_pathv[ch] != NULL; ch++)
+				apropos(argv, pg.gl_pathv[ch], 0);
+			globfree(&pg);
+		}
 	}

 	if (!foundman)
-----cut-here-----



The second patch adds glob support to whatis.

-----cut-here-----
Index: whatis.c
===================================================================
RCS file: /snarf/netbsd/master/src/usr.bin/whatis/whatis.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 whatis.c
--- whatis.c	1995/11/16 02:28:52	1.1.1.1
+++ whatis.c	1996/01/02 05:27:59
@@ -1,3 +1,5 @@
+/*	$NetBSD$	*/
+
 /*
  * Copyright (c) 1987, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -38,7 +40,11 @@
 #endif /* not lint */

 #ifndef lint
+#if 0
 static char sccsid[] = "@(#)whatis.c	8.5 (Berkeley) 11/26/93";
+#else
+static char rcsid[] = "$NetBSD$";
+#endif
 #endif /* not lint */

 #include <sys/param.h>
@@ -46,6 +52,7 @@

 #include <ctype.h>
 #include <err.h>
+#include <glob.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -71,6 +78,7 @@
 	TAG *tp;
 	int ch, rv;
 	char *beg, *conffile, **p, *p_augment, *p_path;
+	glob_t pg;

 	conffile = NULL;
 	p_augment = p_path = NULL;
@@ -112,8 +120,15 @@
 		config(conffile);
 		ep = (tp = getlist("_whatdb")) == NULL ?
 		   NULL : tp->list.tqh_first;
-		for (; ep != NULL; ep = ep->q.tqe_next)
-			whatis(argv, ep->s, 0);
+		for (; ep != NULL; ep = ep->q.tqe_next) {
+			if (glob(ep->s, GLOB_BRACE|GLOB_QUOTE, NULL, &pg) != 0)
+				err(1, "glob");
+			if (pg.gl_matchc == 0)
+				continue;
+			for (ch = 0; pg.gl_pathv[ch] != NULL; ch++)
+				whatis(argv, pg.gl_pathv[ch], 0);
+			globfree(&pg);
+		}
 	}

 	if (!foundman) {
-----cut-here-----



The third patch is for catman.  It does the following:

	-adds $NetBSD$ rcsids

	-adds support for parsing man.conf

	-adds support for handling hard and symlinked manpages (it hard
	 links the catpage together in both cases)

	-adds a second mode of operation:

		catman <manpage>

	 will format the manpage using the build rules in /etc/man.conf,
	 and dump it to stdout.  This can be used in bsd.man.mk to
	 format manpages instead of assuming everything works with
	 nroff -man.

After applying this patch, TODO and pathnames.h should be removed from the
catman directory.  Note that this patch also modifies pathnames.h in the man
src directory (it adds _PATH_MAKEWHATIS).


-----cut-here-----
Index: Makefile
===================================================================
RCS file: /snarf/netbsd/master/src/usr.sbin/catman/Makefile,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 Makefile
--- Makefile	1995/11/16 02:29:24	1.1.1.1
+++ Makefile	1996/01/02 02:45:05
@@ -1,7 +1,8 @@
-#	$Id: Makefile,v 1.1.1.1 1995/11/16 02:29:24 kashmir Exp $
+#	$NetBSD$

-BINDIR=		/usr/sbin
 PROG=		catman
+SRCS=		catman.c config.c
 MAN=		catman.8
+.PATH:		${.CURDIR}/../../usr.bin/man

 .include <bsd.prog.mk>
Index: catman.8
===================================================================
RCS file: /snarf/netbsd/master/src/usr.sbin/catman/catman.8,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 catman.8
--- catman.8	1995/11/16 02:29:24	1.1.1.1
+++ catman.8	1996/01/02 02:29:22
@@ -1,3 +1,4 @@
+.\"	$NetBSD$
 .\"
 .\" Copyright (c) 1993 Winning Strategies, Inc.
 .\" All rights reserved.
@@ -27,9 +28,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\"	$Id: catman.8,v 1.1.1.1 1995/11/16 02:29:24 kashmir Exp $
-.\"
-.Dd July 30, 1993
+.Dd January 1, 1995
 .Dt CATMAN 8
 .Os
 .Sh NAME
@@ -38,13 +37,20 @@
 .Sh SYNOPSIS
 .Nm catman
 .Op Fl knpsw
+.Op Fl C Ar file
 .Op Fl M Ar directory
 .Op Ar sections
+.Nm catman
+.Op Fl C Ar file
+.Ar manpage
 .Sh DESCRIPTION
 .Nm Catman 
 creates formatted versions of the on-line manual pages from their 
 .Xr nroff 1
 source.
+.Pp
+The first form of the command operates on the man directories specified in
+/etc/man.conf.
 Manual pages whose formatted versions are missing or out of date are 
 regenerated.
 If manual pages are regenerated, 
@@ -66,6 +72,9 @@
 .Nm catman
 will try to operate on all of the known manual sections.
 .Pp
+The second form of the command takes a filename on the command line and
+generates formatted output to stdout.
+.Pp
 The options are as follows:
 .Bl -tag -width indent
 .It Fl k
@@ -86,15 +95,32 @@
 Only create the 
 .Nm whatis 
 database.
+.It Fl C Ar file
+Use the specified
+.Ar file
+instead of the default configuration file.
 .It Fl M Ar directory
 Update manual pages in 
 .Ar directory.
 .El
+.Sh ENVIRONMENT
+.Bl -tag -width MANPATH
+.It Ev MANPATH
+The standard search path may be overridden by specifying a path in the
+.Ev MANPATH
+environment variable.
+.El
+.Sh FILES
+.Bl -tag
+.It Pa /etc/man.conf
+default man configuration file.
+.El
+.Bl -tag
+.It Pa whatis.db
+name of the whatis database.
+.El
 .Sh SEE ALSO
 .Xr apropos 1 ,
 .Xr man 1 ,
 .Xr whatis 1
-.Sh BUGS
-Currently knows nothing about 
-.Pa /etc/man.conf 
-and machine specific man pages.
+.Xr man.conf 5
Index: catman.c
===================================================================
RCS file: /snarf/netbsd/master/src/usr.sbin/catman/catman.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 catman.c
--- catman.c	1995/11/16 02:29:24	1.1.1.1
+++ catman.c	1996/01/06 19:49:46
@@ -1,4 +1,7 @@
+/*	$NetBSD$	*/
+
 /*
+ * Copyright (c) 1996 Michael E. Grupenhoff.  All rights reserved.
  * Copyright (c) 1993 Winning Strategies, Inc.
  * All rights reserved.
  *
@@ -29,23 +32,28 @@
  */

 #ifndef lint
-static char rcsid[] = "$Id: catman.c,v 1.1.1.1 1995/11/16 02:29:24 kashmir Exp $";
+static char rcsid[] = "$NetBSD$";
 #endif /* not lint */

 #include <sys/types.h>
+#include <sys/queue.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
+
+#include <ctype.h>
 #include <dirent.h>
 #include <err.h>
 #include <errno.h>
+#include <fnmatch.h>
+#include <glob.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <paths.h>

-#include "pathnames.h"
+#include "../../usr.bin/man/config.h"
+#include "../../usr.bin/man/pathnames.h"

 int f_nowhatis;
 int f_noaction;
@@ -53,23 +61,29 @@
 int f_ignerr;
 int f_noprint;

-int dowhatis;
-
-char *mp = _PATH_MAN;
-char *sp = _MAN_SECTIONS;
-
-void usage __P((void));
-void catman __P((const char *, char *));
-void makewhatis __P((const char *));
+int catman __P((const char *));
+int dirformat __P((char *, char *, char *));
 void dosystem __P((const char *));
+void lncatpages __P((char *, char *, char *, char *, char *));
+void makedefault __P((char *));
+void makesubdir __P((const char *));
+void makewhatis __P((const char *));
+void mformat __P((char *, char *));
+void usage __P((void));

 int
 main(argc, argv)
 	int argc;
 	char **argv;
 {
-	int c;
+	int c, needwhatis;
+	char *conffile, *mp;
+	glob_t pg;
+	ENTRY *ep;
+	TAG *tp;

+	mp = NULL;
+	conffile = _PATH_MANCONF;
 	while ((c = getopt(argc, argv, "knpswM:")) != EOF) {
 		switch (c) {
 		case 'k':
@@ -87,6 +101,9 @@
 		case 'w':
 			f_noformat = 1;
 			break;
+		case 'C':
+			conffile = optarg;
+			break;
 		case 'M':
 			mp = optarg;
 			break;
@@ -105,37 +122,167 @@

 	if (argc > 1)
 		usage();
-	if (argc == 1)
-		sp = *argv;

-	if (f_noformat == 0 || f_nowhatis == 0)
-		catman(mp, sp);
-	if (f_nowhatis == 0 && dowhatis)
-		makewhatis(mp);
+	config(conffile);
+
+	/*
+	 * Remaining argument could either be an nroff source file, in
+	 * which case we format it to stdout, or a list of man sections.
+	 */
+	if (argc == 1)
+		if (access(*argv, F_OK) == 0) {
+			mformat(*argv, NULL);
+			exit(0);
+		} else
+			makesubdir(*argv);
+
+	if (mp != NULL || (mp = getenv("MANPATH")) != NULL)
+		makedefault(mp);
+
+	if ((tp = getlist("_default")) == NULL)
+		errx(1, "No manpath in %s.\n", _PATH_MANCONF);
+	for (ep = tp->list.tqh_first; ep != NULL; ep = ep->q.tqe_next) {
+		memset(&pg, 0, sizeof(pg));
+		if (glob(ep->s, GLOB_BRACE | GLOB_QUOTE, NULL, &pg) != 0)
+			err(1, "glob");
+		if (pg.gl_matchc == 0)
+			continue;
+		for (c = 0; pg.gl_pathv[c] != NULL; c++) {
+			if (f_noformat == 0 || f_nowhatis == 0)
+				needwhatis = catman(pg.gl_pathv[c]);
+			if (f_noformat || (needwhatis && f_nowhatis == 0))
+				makewhatis(pg.gl_pathv[c]);
+		}
+		globfree(&pg);
+	}

 	exit(0);
 }

-
-void
-catman(path, section)
+int
+catman(path)
 	const char *path;
-	char *section;
 {
+	int rval;
 	char mandir[PATH_MAX];
 	char catdir[PATH_MAX];
-	char manpage[PATH_MAX];
-	char catpage[PATH_MAX];
+	char *catsuffix, *slash;
+	TAG *subdirp, *sufp;
+	ENTRY *ep;
+
+	if (chdir(path) != 0) {
+		warn(path);
+		return (0);
+	}
+
+	if (path[strlen(path) - 1] == '/')
+		slash = "";
+	else
+		slash = "/";
+
+	if ((sufp = getlist("_suffix")) == NULL)
+		catsuffix = ".0";
+	else
+		catsuffix = sufp->list.tqh_first->s;
+
+	if ((subdirp = getlist("_subdir")) == NULL)
+		errx(1, "No man subdirectories to scan!\n");
+
+	rval = 0;
+	for (ep = subdirp->list.tqh_first; ep != NULL; ep = ep->q.tqe_next) {
+		if (strncmp(ep->s, "man", strlen("man")) != 0)
+			continue;
+		sprintf(mandir, "%s%s%s", path, slash, ep->s);
+		sprintf(catdir, "%s%scat%c", path, slash, ep->s[3]);
+		rval |= dirformat(mandir, catdir, catsuffix);
+	}
+
+	return (rval);
+}
+
+void
+makewhatis(path)
+	const char *path;
+{
 	char sysbuf[1024];
-	struct stat manstat;
-	struct stat catstat;
-	struct dirent *dp;
-	DIR *dirp;
-	char *s, *tmp;
-	int sectlen, error;

-	for (s = section; *s; s += sectlen) {
-#ifdef notdef
+	sprintf(sysbuf, "%s %s", _PATH_MAKEWHATIS, path);
+	if (f_noprint == 0)
+		printf("%s\n", sysbuf);
+	if (f_noaction == 0)
+		dosystem(sysbuf);
+}
+
+void
+dosystem(cmd)
+	const char *cmd;
+{
+	int status;
+
+	if ((status = system(cmd)) == 0)
+		return;
+
+	if (status == -1)
+		err(1, "cannot execute action");
+	if (WIFSIGNALED(status))
+		errx(1, "child was signaled to quit. aborting");
+	if (WIFSTOPPED(status))
+		errx(1, "child was stopped. aborting");
+	if (f_ignerr == 0)
+		errx(1, "*** Exited %d", status);
+	warnx("*** Exited %d (continuing)", status);
+}
+
+/*
+ * Replace the current _default entry
+ */
+void
+makedefault(mp)
+	char *mp;
+{
+	ENTRY *ep;
+	TAG *defp;
+	char *p;
+
+	if ((defp = getlist("_default")) == NULL)
+		defp = addlist("_default");
+	while ((ep = defp->list.tqh_first) != NULL) {
+		free(ep->s);
+		TAILQ_REMOVE(&defp->list, ep, q);
+		free(ep);
+	}
+
+	for (p = strsep(&mp, ":"); p != NULL; p = strsep(&mp, ":")) {
+		if (*p == '\0')
+			continue;
+		if ((ep = malloc(sizeof(ENTRY))) == NULL ||
+		    (ep->s = strdup(p)) == NULL)
+			errx(1, "Out of memory");
+		TAILQ_INSERT_TAIL(&defp->list, ep, q);
+	}
+}
+
+/*
+ * Replace the current _subdir entry
+ */
+void
+makesubdir(subsec)
+	const char *subsec;
+{
+	ENTRY *ep;
+	TAG *subdirp;
+	const char *s, *tmp;
+	int sectlen;
+
+	if ((subdirp = getlist("_subdir")) == NULL)
+		subdirp = addlist("_subdir");
+	while ((ep = subdirp->list.tqh_first) != NULL) {
+		free(ep->s);
+		TAILQ_REMOVE(&subdirp->list, ep, q);
+		free(ep);
+	}
+
+	for (s = subsec, sectlen = 0; *s; s += sectlen) {
 		tmp = s;
 		sectlen = 0;
 		if (isdigit(*tmp)) {
@@ -146,123 +293,225 @@
 				tmp++;
 			}
 		}
-#else
-		sectlen = 1;
-#endif
 		if (sectlen == 0)
-			errx(1, "malformed section string");
+			errx(1, "malformed section string \"%s\"", subsec);

-		sprintf(mandir, "%s/%s%.*s", path, _PATH_MANPAGES, sectlen, s);
-		sprintf(catdir, "%s/%s%.*s", path, _PATH_CATPAGES, sectlen, s);
+		if ((ep = malloc(sizeof(ENTRY))) == NULL ||
+		    (ep->s = malloc(sectlen + strlen("man") + 1)) == NULL)
+			err(1, "Out of memory");
+		sprintf(ep->s, "man%.*s", sectlen, s);
+		TAILQ_INSERT_TAIL(&subdirp->list, ep, q);
+	}
+}

-		if ((dirp = opendir(mandir)) == 0) {
-			warn("can't open %s", mandir);
+void
+lncatpages(mandir, manpage, catdir, catpage, catsuffix)
+	char *mandir, *manpage, *catdir, *catpage, *catsuffix;
+{
+	DIR *dirp;
+	struct dirent *dp;
+	struct stat st, manstat;
+	char manfile[PATH_MAX];
+	char catfile[PATH_MAX];
+	char *tmp;
+
+	if (stat(manpage, &manstat) < 0) {
+		warn("can't stat %s", manpage);
+		return;
+	}
+	if ((dirp = opendir(mandir)) == NULL) {
+		warn(mandir);
+		return;
+	}
+	while ((dp = readdir(dirp)) != NULL) {
+		if (strcmp(dp->d_name, ".") == 0 ||
+		    strcmp(dp->d_name, "..") == 0)
+			continue;
+		sprintf(manfile, "%s/%s", mandir, dp->d_name);
+		if (strcmp(manfile, manpage) == 0)
+			continue;
+		if (stat(manfile, &st) < 0) {
+			warn("can't stat %s", manfile);
 			continue;
 		}
-
-		if (stat(catdir, &catstat) < 0) {
-			if (errno != ENOENT) {
-				warn("can't stat %s", catdir);
-				closedir(dirp);
+		if (st.st_ino == manstat.st_ino) {
+			sprintf(catfile, "%s/%s", catdir, dp->d_name);
+			if ((tmp = strrchr(catfile, '.')) == NULL)
 				continue;
-			}
+			strcpy(tmp, catsuffix);
+			unlink(catfile);
 			if (f_noprint == 0)
-				printf("mkdir %s\n", catdir);
-			if (f_noaction == 0 && mkdir(catdir, 0755) < 0) {
-				warn("can't create %s", catdir);
-				closedir(dirp);
-				return;
+				printf("ln %s %s\n", catpage, catfile);
+			if (f_noaction == 0 && link(catpage, catfile) < 0) {
+				warn("can't link %s to %s", catpage, catfile);
+				continue;
 			}
+		}
+	}
+	closedir(dirp);
+}

+/*
+ * Format all pages in mandir, placing the output in catdir.
+ */
+int
+dirformat(mandir, catdir, catsuffix)
+	char *mandir, *catdir, *catsuffix;
+{
+	int error, rval, symlink;
+	char manpage[PATH_MAX];
+	char catpage[PATH_MAX];
+	char *tmp, *mansuffix;
+	DIR *dirp;
+	struct dirent *dp;
+	struct stat manstat;
+	struct stat catstat;
+
+	if (chdir(mandir) || (dirp = opendir(".")) == NULL) {
+		if (errno != ENOENT)
+			warn(mandir);
+		return (0);
+	}
+	if (stat(catdir, &catstat) < 0) {
+		if (errno != ENOENT) {
+			warn("can't stat %s", catdir);
+			closedir(dirp);
+			return (0);
+		}
+		if (f_noprint == 0)
+			printf("mkdir %s\n", catdir);
+		if (f_noaction == 0 && mkdir(catdir, 0755) < 0) {
+			warn("can't create %s", catdir);
+			closedir(dirp);
+			return (0);
 		}

-		while ((dp = readdir(dirp)) != NULL) {
-			if (strcmp(dp->d_name, ".") == 0 ||
-			    strcmp(dp->d_name, "..") == 0)
-				continue;
+	}

-			sprintf(manpage, "%s/%s", mandir, dp->d_name);
-			sprintf(catpage, "%s/%s", catdir, dp->d_name);
-			if ((tmp = strrchr(catpage, '.')) != NULL)
-				strcpy(tmp, ".0");
-			else
-				continue;
+	rval = 0;
+	while ((dp = readdir(dirp)) != NULL) {
+		if (strcmp(dp->d_name, ".") == 0 ||
+		    strcmp(dp->d_name, "..") == 0)
+			continue;

+		sprintf(manpage, "%s/%s", mandir, dp->d_name);
+		sprintf(catpage, "%s/%s", catdir, dp->d_name);
+
+		if (lstat(manpage, &manstat) < 0) {
+			warn("can't stat %s", manpage);
+			continue;
+		}
+
+		symlink = 0;
+		if (S_ISLNK(manstat.st_mode)) {
+			symlink = 1;
 			if (stat(manpage, &manstat) < 0) {
 				warn("can't stat %s", manpage);
 				continue;
 			}
+		}

-			if (!S_ISREG(manstat.st_mode)) {
+		if (!S_ISREG(manstat.st_mode)) {
+			/*
+			 * Subdirectories within man directories contain
+			 * architecture specific pages.
+			 */
+			if (S_ISDIR(manstat.st_mode))
+				dirformat(manpage, catpage, catsuffix);
+			else
 				warnx("not a regular file %s", manpage);
-				continue;
-			}
-			if ((error = stat(catpage, &catstat)) &&
-			    errno != ENOENT) {
-				warn("can't stat %s", catpage);
-				continue;
-			}
-
-			if ((error && errno == ENOENT) || 
-			    manstat.st_mtime >= catstat.st_mtime) {
-				if (f_noformat)
-					dowhatis = 1;
-				else {
-					/*
-					 * manpage is out of date,
-					 * reformat
-					 */
-					sprintf(sysbuf, "nroff -mandoc %s > %s",
-					    manpage, catpage);
-					if (f_noprint == 0)
-						printf("%s\n", sysbuf);
-					if (f_noaction == 0)
-						dosystem(sysbuf);
-					dowhatis = 1;
-				}
-			}
+			continue;
 		}
-		closedir(dirp);
-	}
-}

-void
-makewhatis(path)
-	const char *path;
-{
-	char sysbuf[1024];
+		if ((mansuffix = strrchr(manpage, '.')) == NULL)
+			continue;
+		if ((tmp = strrchr(catpage, '.')) == NULL)
+			continue;
+		else
+			strcpy(tmp, catsuffix);

-	sprintf(sysbuf, "%s %s", _PATH_MAKEWHATIS, path);
-	if (f_noprint == 0)
-		printf("%s\n", sysbuf);
-	if (f_noaction == 0)
-		dosystem(sysbuf);
+		if ((error = stat(catpage, &catstat)) &&
+		    errno != ENOENT) {
+			warn("can't stat %s", catpage);
+			continue;
+		}
+
+		/*
+		 * If manpage is out of date, reformat
+		 */
+		if ((error && errno == ENOENT) || 
+		    (manstat.st_mtime >= catstat.st_mtime &&
+		    f_noformat == 0)) {
+			mformat(manpage, catpage);
+			/*
+			 * If manpages hardlinked together, duplicate
+			 * with catpages.
+			 */
+			if (manstat.st_nlink > 1 || symlink)
+				lncatpages(mandir, manpage, catdir, catpage,
+				    catsuffix);
+			rval = 1;
+		}
+	}
+	closedir(dirp);
+	return (rval);
 }

 void
-dosystem(cmd)
-	const char *cmd;
+mformat(manpage, catpage)
+	char *manpage, *catpage;
 {
-	int status;
-
-	if ((status = system(cmd)) == 0)
-		return;
+	int fnd;
+	char buf[1024], fmtbuf[1024], *p, *sufent, *mansuffix;
+	TAG *sufp;
+	ENTRY *e_sufp;
+
+	if ((mansuffix = strrchr(manpage, '.')) == NULL)
+		mansuffix = ".1";
+
+	if ((sufp = getlist("_build")) == NULL)
+		errx(1, "No _build keywords found in %s", _PATH_MANCONF);
+
+	for (fnd = 0, e_sufp = sufp->list.tqh_first; e_sufp != NULL;
+	    e_sufp = e_sufp->q.tqe_next) {
+		if ((sufent = strdup(e_sufp->s)) == NULL)
+			errx(1, "Out of memory");
+		for (p = sufent; *p != '\0' && !isspace(*p); p++);
+		if (*p == '\0') {
+			free(sufent);
+			continue;
+		}
+		*p = '\0';
+		if (fnmatch(sufent, mansuffix, 0) != 0) {
+			free(sufent);
+			continue;
+		}
+		fnd = 1;

-	if (status == -1)
-		err(1, "cannot execute action");
-	if (WIFSIGNALED(status))
-		errx(1, "child was signaled to quit. aborting");
-	if (WIFSTOPPED(status))
-		errx(1, "child was stopped. aborting");
-	if (f_ignerr == 0)
-		errx(1,"*** Exited %d");
-	warnx("*** Exited %d (continuing)");
+		for (++p; isspace(*p); p++);
+		/*
+		 * If catpage is NULL, then we send it to stdout
+		 */
+		if (catpage == NULL)
+			strncpy(fmtbuf, p, sizeof(fmtbuf));
+		else
+			snprintf(fmtbuf, sizeof(fmtbuf), "%s > %s", p, catpage);
+		snprintf(buf, sizeof(buf), fmtbuf, manpage);
+		if (f_noprint == 0 && catpage != NULL)
+			printf("%s\n", buf);
+		if (f_noaction == 0)
+			dosystem(buf);
+		free(sufent);
+	}
+	if (fnd == 0)
+		warnx("Don't know how to format %s", manpage);
 }

 void
 usage()
 {
 	(void)fprintf(stderr,
-	    "usage: catman [-knpsw] [-M manpath] [sections]\n");
+	    "usage: catman [-knpsw] [-C file] [-M manpath] [sections]\n"
+	    "       catman [-C file] manpage\n");
 	exit(1);
 }
Index: ../../usr.bin/man/config.c
===================================================================
RCS file: /snarf/netbsd/master/src/usr.bin/man/config.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 config.c
--- config.c	1995/11/16 02:27:52	1.1.1.1
+++ config.c	1996/01/02 02:43:53
@@ -119,12 +119,12 @@
 			while (*++t && isspace(*t));
 			if ((ep = malloc(sizeof(ENTRY))) == NULL ||
 			    (ep->s = strdup(t)) == NULL)
-				err(1, NULL);
+				err(1, "Out of memory");
 			TAILQ_INSERT_TAIL(&tp->list, ep, q);
 		} else for (++t; (p = strtok(t, " \t\n")) != NULL; t = NULL) {
 			if ((ep = malloc(sizeof(ENTRY))) == NULL ||
 			    (ep->s = strdup(p)) == NULL)
-				err(1, NULL);
+				err(1, "Out of memory");
 			TAILQ_INSERT_TAIL(&tp->list, ep, q);
 		}
 	}
@@ -144,7 +144,7 @@

 	if ((tp = calloc(1, sizeof(TAG))) == NULL ||
 	    (tp->s = strdup(name)) == NULL)
-		err(1, NULL);
+		err(1, "Out of memory");
 	TAILQ_INIT(&tp->list);
 	TAILQ_INSERT_TAIL(&head, tp, q);
 	return (tp);
Index: ../../usr.bin/man/pathnames.h
===================================================================
RCS file: /snarf/netbsd/master/src/usr.bin/man/pathnames.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 pathnames.h
--- pathnames.h	1995/11/16 02:27:53	1.1.1.1
+++ pathnames.h	1996/01/01 20:16:32
@@ -35,6 +35,7 @@
  *	@(#)pathnames.h	8.3 (Berkeley) 1/2/94
  */

+#define	_PATH_MAKEWHATIS	"/usr/libexec/makewhatis"
 #define	_PATH_MANCONF	"/etc/man.conf"
 #define	_PATH_PAGER	"/usr/bin/more -s"
 #define	_PATH_TMP	"/tmp/man.XXXXXX"
-----cut-here-----


This final patch changes bsd.man.mk to use catman instead of nroff.
-----cut-here-----
Index: bsd.man.mk
===================================================================
RCS file: /snarf/netbsd/master/src/share/mk/bsd.man.mk,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 bsd.man.mk
--- bsd.man.mk	1995/12/15 12:08:10	1.1.1.2
+++ bsd.man.mk	1996/01/02 01:37:48
@@ -15,8 +15,8 @@
 	.cat7 .cat8 .cat9

 .9.cat9 .8.cat8 .7.cat7 .6.cat6 .5.cat5 .4.cat4 .3.cat3 .2.cat2 .1.cat1:
-	@echo "nroff -mandoc ${.IMPSRC} > ${.TARGET}"
-	@nroff -mandoc ${.IMPSRC} > ${.TARGET} || ( rm -f ${.TARGET} ; false )
+	@echo "catman ${.IMPSRC} > ${.TARGET}"
+	@catman ${.IMPSRC} > ${.TARGET} || ( rm -f ${.TARGET} ; false )

 .if defined(MAN) && !empty(MAN)
 MANALL=	${MAN:S/.1$/.cat1/g:S/.2$/.cat2/g:S/.3$/.cat3/g:S/.4$/.cat4/g:S/.5$/.cat5/g:S/.6$/.cat6/g:S/.7$/.cat7/g:S/.8$/.cat8/g:S/.9$/.cat9/g}
-----cut-here-----

>Release-Note:
>Audit-Trail:

From: Mike Grupenhoff <kashmir@umiacs.umd.edu>
To: gnats-bugs@gnats.netbsd.org
Cc:  Subject: Re: bin/1904
Date: Mon, 8 Jan 1996 20:25:28 -0500 (EST)

 The patch to catman that I sent in bin/1904 was incomplete with respect to
 handling manpages with extentions with more then one period (foo.1.gz, etc). 
 I wasn't sure at the time about the proper way to handle this, since a
 manpage might have a period in its name. 

 The previous patch did a strrchr(manpage, '.') to get the extension, 
 which obviously breaks with compressed pages.  At the bottom of this mail 
 is a patch which does a better job of guessing what the extension really 
 is.  Of course, if someone could guarantee to me that a manpage name will 
 never contain a '.', this could all be done a lot cleaner.  alas..

 I apologize for not getting this right the first time, in the first patch.  I
 had a moment of clarity today while shoveling snow, and came up with this
 workaround.  If you have a better way of handling this, let me know. 

 mike

 This patch should be applied after applying the one in bin/1904.

 Index: catman.c
 ===================================================================
 RCS file: /snarf/netbsd/master/src/usr.sbin/catman/catman.c,v
 retrieving revision 1.2
 diff -u -r1.2 catman.c
 --- catman.c	1996/01/07 15:50:45	1.2
 +++ catman.c	1996/01/08 01:51:53
 @@ -62,13 +62,14 @@
  int f_noprint;

  int catman __P((const char *));
 -int dirformat __P((char *, char *, char *));
 +int dirformat __P((char *, char *));
  void dosystem __P((const char *));
 -void lncatpages __P((char *, char *, char *, char *, char *));
 +void lncatpages __P((char *, char *, char *, char *));
  void makedefault __P((char *));
  void makesubdir __P((const char *));
  void makewhatis __P((const char *));
 -void mformat __P((char *, char *));
 +int mformat __P((char *, struct stat *, char *));
 +void mkcatsuff __P((char *, char *));
  void usage __P((void));

  int
 @@ -131,7 +132,7 @@
  	 */
  	if (argc == 1)
  		if (access(*argv, F_OK) == 0) {
 -			mformat(*argv, NULL);
 +			mformat(*argv, NULL, NULL);
  			exit(0);
  		} else
  			makesubdir(*argv);
 @@ -166,8 +167,8 @@
  	int rval;
  	char mandir[PATH_MAX];
  	char catdir[PATH_MAX];
 -	char *catsuffix, *slash;
 -	TAG *subdirp, *sufp;
 +	char *slash;
 +	TAG *subdirp;
  	ENTRY *ep;

  	if (chdir(path) != 0) {
 @@ -180,11 +181,6 @@
  	else
  		slash = "/";

 -	if ((sufp = getlist("_suffix")) == NULL)
 -		catsuffix = ".0";
 -	else
 -		catsuffix = sufp->list.tqh_first->s;
 -
  	if ((subdirp = getlist("_subdir")) == NULL)
  		errx(1, "No man subdirectories to scan!\n");

 @@ -194,7 +190,7 @@
  			continue;
  		sprintf(mandir, "%s%s%s", path, slash, ep->s);
  		sprintf(catdir, "%s%scat%c", path, slash, ep->s[3]);
 -		rval |= dirformat(mandir, catdir, catsuffix);
 +		rval |= dirformat(mandir, catdir);
  	}

  	return (rval);
 @@ -305,15 +301,14 @@
  }

  void
 -lncatpages(mandir, manpage, catdir, catpage, catsuffix)
 -	char *mandir, *manpage, *catdir, *catpage, *catsuffix;
 +lncatpages(mandir, manpage, catdir, catpage)
 +	char *mandir, *manpage, *catdir, *catpage;
  {
  	DIR *dirp;
  	struct dirent *dp;
  	struct stat st, manstat;
  	char manfile[PATH_MAX];
  	char catfile[PATH_MAX];
 -	char *tmp;

  	if (stat(manpage, &manstat) < 0) {
  		warn("can't stat %s", manpage);
 @@ -336,9 +331,7 @@
  		}
  		if (st.st_ino == manstat.st_ino) {
  			sprintf(catfile, "%s/%s", catdir, dp->d_name);
 -			if ((tmp = strrchr(catfile, '.')) == NULL)
 -				continue;
 -			strcpy(tmp, catsuffix);
 +			mkcatsuff(manfile, catfile);
  			unlink(catfile);
  			if (f_noprint == 0)
  				printf("ln %s %s\n", catpage, catfile);
 @@ -355,24 +348,22 @@
   * Format all pages in mandir, placing the output in catdir.
   */
  int
 -dirformat(mandir, catdir, catsuffix)
 -	char *mandir, *catdir, *catsuffix;
 +dirformat(mandir, catdir)
 +	char *mandir, *catdir;
  {
 -	int error, rval, symlink;
 +	int rval, slink;
  	char manpage[PATH_MAX];
  	char catpage[PATH_MAX];
 -	char *tmp, *mansuffix;
  	DIR *dirp;
  	struct dirent *dp;
  	struct stat manstat;
 -	struct stat catstat;

  	if (chdir(mandir) || (dirp = opendir(".")) == NULL) {
  		if (errno != ENOENT)
  			warn(mandir);
  		return (0);
  	}
 -	if (stat(catdir, &catstat) < 0) {
 +	if (stat(catdir, &manstat) < 0) {
  		if (errno != ENOENT) {
  			warn("can't stat %s", catdir);
  			closedir(dirp);
 @@ -402,9 +393,9 @@
  			continue;
  		}

 -		symlink = 0;
 +		slink = 0;
  		if (S_ISLNK(manstat.st_mode)) {
 -			symlink = 1;
 +			slink = 1;
  			if (stat(manpage, &manstat) < 0) {
  				warn("can't stat %s", manpage);
  				continue;
 @@ -417,39 +408,19 @@
  			 * architecture specific pages.
  			 */
  			if (S_ISDIR(manstat.st_mode))
 -				dirformat(manpage, catpage, catsuffix);
 +				dirformat(manpage, catpage);
  			else
  				warnx("not a regular file %s", manpage);
  			continue;
  		}

 -		if ((mansuffix = strrchr(manpage, '.')) == NULL)
 -			continue;
 -		if ((tmp = strrchr(catpage, '.')) == NULL)
 -			continue;
 -		else
 -			strcpy(tmp, catsuffix);
 -
 -		if ((error = stat(catpage, &catstat)) &&
 -		    errno != ENOENT) {
 -			warn("can't stat %s", catpage);
 -			continue;
 -		}
 -
 -		/*
 -		 * If manpage is out of date, reformat
 -		 */
 -		if ((error && errno == ENOENT) || 
 -		    (manstat.st_mtime >= catstat.st_mtime &&
 -		    f_noformat == 0)) {
 -			mformat(manpage, catpage);
 +		if (mformat(manpage, &manstat, catpage)) {
  			/*
  			 * If manpages hardlinked together, duplicate
  			 * with catpages.
  			 */
 -			if (manstat.st_nlink > 1 || symlink)
 -				lncatpages(mandir, manpage, catdir, catpage,
 -				    catsuffix);
 +			if (manstat.st_nlink > 1 || slink)
 +				lncatpages(mandir, manpage, catdir, catpage);
  			rval = 1;
  		}
  	}
 @@ -457,12 +428,14 @@
  	return (rval);
  }

 -void
 -mformat(manpage, catpage)
 +int
 +mformat(manpage, manstat, catpage)
  	char *manpage, *catpage;
 +	struct stat *manstat;
  {
 -	int fnd;
 +	int error, fnd, rval;
  	char buf[1024], fmtbuf[1024], *p, *sufent, *mansuffix;
 +	struct stat catstat;
  	TAG *sufp;
  	ENTRY *e_sufp;

 @@ -472,7 +445,7 @@
  	if ((sufp = getlist("_build")) == NULL)
  		errx(1, "No _build keywords found in %s", _PATH_MANCONF);

 -	for (fnd = 0, e_sufp = sufp->list.tqh_first; e_sufp != NULL;
 +	for (rval = fnd = 0, e_sufp = sufp->list.tqh_first; e_sufp != NULL;
  	    e_sufp = e_sufp->q.tqe_next) {
  		if ((sufent = strdup(e_sufp->s)) == NULL)
  			errx(1, "Out of memory");
 @@ -482,7 +455,9 @@
  			continue;
  		}
  		*p = '\0';
 -		if (fnmatch(sufent, mansuffix, 0) != 0) {
 +
 +		snprintf(buf, sizeof(buf), "*%s", sufent);
 +		if (fnmatch(buf, manpage, 0) != 0) {
  			free(sufent);
  			continue;
  		}
 @@ -494,17 +469,70 @@
  		 */
  		if (catpage == NULL)
  			strncpy(fmtbuf, p, sizeof(fmtbuf));
 -		else
 -			snprintf(fmtbuf, sizeof(fmtbuf), "%s > %s", p, catpage);
 +		else {
 +			mkcatsuff(sufent, catpage);
 +			if ((error = stat(catpage, &catstat)) &&
 +			    errno != ENOENT) {
 +				warn("can't stat %s", catpage);
 +				continue;
 +			}
 +
 +			/*
 +			 * See if manpage is out of date.
 +			 */
 +			if ((error && errno == ENOENT) || 
 +			    (manstat->st_mtime >= catstat.st_mtime &&
 +			    f_noformat == 0))
 +				snprintf(fmtbuf, sizeof(fmtbuf), "%s > %s", p,
 +				    catpage);
 +			else {
 +				free(sufent);
 +				break;
 +			}
 +		}
  		snprintf(buf, sizeof(buf), fmtbuf, manpage);
  		if (f_noprint == 0 && catpage != NULL)
  			printf("%s\n", buf);
  		if (f_noaction == 0)
  			dosystem(buf);
  		free(sufent);
 +		rval = 1;
  	}
  	if (fnd == 0)
  		warnx("Don't know how to format %s", manpage);
 +	return (rval);
 +}
 +
 +/*
 + * Given a path to a manpage and a path to a catpage, change
 + * the catpage suffix to _suffix.
 + */
 +void
 +mkcatsuff(mansuffix, catpage)
 +	char *mansuffix, *catpage;
 +{
 +	int ndots;
 +	char *q;
 +	static char *catsuffix = NULL;
 +	TAG *sufp;
 +
 +	if (catsuffix == NULL)
 +		if ((sufp = getlist("_suffix")) == NULL)
 +			catsuffix = ".0";
 +		else
 +			catsuffix = sufp->list.tqh_first->s;
 +
 +	/*
 +	 * Hack:  We count the number of dots in the manpage suffix
 +	 * and jump back that many dots in the catpage.
 +	 */
 +	for (ndots = 0, q = mansuffix; *q; q++)
 +		if (*q == '.')
 +			ndots++;
 +	for (q = catpage + strlen(catpage); ndots; q--)
 +		if (*q == '.')
 +			ndots--;
 +	strcpy(q + 1, catsuffix);
  }

  void

Responsible-Changed-From-To: bin-bug-people->mikel
Responsible-Changed-By: mikel
Responsible-Changed-When: Sat Sep 27 23:06:15 1997
Responsible-Changed-Why:
I'm handling this one.

Responsible-Changed-From-To: mikel->bin-bug-people 
Responsible-Changed-By: fair 
Responsible-Changed-When: Thu Mar 22 12:29:11 PST 2001 
Responsible-Changed-Why:  
Mike Long's E-mail address now bounces, so he appears to have vanished. 
Back to the role account this PR goes, ready for some other intrepid 
developer to step up to the plate. 
From: Abhinav Upadhyay <er.abhinav.upadhyay@gmail.com>
To: NetBSD GNATS <gnats-bugs@netbsd.org>
Cc: 
Subject: Re: bin/1904
Date: Sat, 21 May 2016 15:17:33 +0530

 Is this still relevant?
 The first two issues regarding apropos and whatis are not valid anymore
 as we don't use whatis.db for them.

 Not quite sure about the 3rd and 4th points.

 -
 Abhinav

From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: bin/1904
Date: Sat, 28 May 2016 16:36:05 +0000

 On Sat, May 21, 2016 at 09:50:00AM +0000, Abhinav Upadhyay wrote:
  >  Is this still relevant?
  >  The first two issues regarding apropos and whatis are not valid anymore
  >  as we don't use whatis.db for them.
  >  
  >  Not quite sure about the 3rd and 4th points.

 The last point (the one about bsd.man.mk using catman) is wrong; or at
 least, not useful. The build rules in the default man.conf are supposed
 to be consistent with the build rules in the makefiles; using custom
 rules from an installed man.conf is not consistent with the principle
 of the build being self-contained, cross builds working reliably, etc.
 Also it's only relevant if one is generating cat pages at build time,
 which has not been the default for some years now.

 The other point "catman doesn't work with /etc/man.conf and linked
 manpages" ... not even sure what that means. However, I guess we might
 want some of the patches to catman(8) in here...

 -- 
 David A. Holland
 dholland@netbsd.org

From: Abhinav Upadhyay <er.abhinav.upadhyay@gmail.com>
To: NetBSD GNATS <gnats-bugs@netbsd.org>
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org, kashmir@umiacs.umd.edu
Subject: Re: bin/1904
Date: Sat, 28 May 2016 22:54:24 +0530

 On Sat, May 28, 2016 at 10:10 PM, David Holland
 <dholland-bugs@netbsd.org> wrote:
 > The following reply was made to PR bin/1904; it has been noted by GNATS.
 >
 > From: David Holland <dholland-bugs@netbsd.org>
 > To: gnats-bugs@NetBSD.org
 > Cc:
 > Subject: Re: bin/1904
 > Date: Sat, 28 May 2016 16:36:05 +0000
 >
 >  On Sat, May 21, 2016 at 09:50:00AM +0000, Abhinav Upadhyay wrote:
 >   >  Is this still relevant?
 >   >  The first two issues regarding apropos and whatis are not valid anymore
 >   >  as we don't use whatis.db for them.
 >   >
 >   >  Not quite sure about the 3rd and 4th points.
 >
 >  The last point (the one about bsd.man.mk using catman) is wrong; or at
 >  least, not useful. The build rules in the default man.conf are supposed
 >  to be consistent with the build rules in the makefiles; using custom
 >  rules from an installed man.conf is not consistent with the principle
 >  of the build being self-contained, cross builds working reliably, etc.
 >  Also it's only relevant if one is generating cat pages at build time,
 >  which has not been the default for some years now.

 I guess that settles the 4th point as not being useful (in present time).

 >  The other point "catman doesn't work with /etc/man.conf and linked
 >  manpages" ... not even sure what that means. However, I guess we might
 >  want some of the patches to catman(8) in here...

 As per the description of the 3rd patch, it means that catman doesn't
 parse and use the rules from /etc/man.conf and, it also doesn't handle
 the symlinked or hard linked man pages, the patch fixes those issues.

 I think those are useful fixes if we are going to maintain catman.
 -
 Abhinav

From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: bin/1904
Date: Sat, 28 May 2016 18:41:59 +0000

 On Sat, May 28, 2016 at 05:25:00PM +0000, Abhinav Upadhyay wrote:
  >  As per the description of the 3rd patch, it means that catman doesn't
  >  parse and use the rules from /etc/man.conf and, it also doesn't handle
  >  the symlinked or hard linked man pages, the patch fixes those issues.
  >  
  >  I think those are useful fixes if we are going to maintain catman.

 Maybe; ISTM that the way to deal with man.conf is that it should use
 man(1) to generate the cat pages. Except for that man(1) needs a way
 to be told "please print this page" and while I thought it had an
 option for that, it doesn't currently seem to.

 (Also, I'd thought there was an option to man(1) to run troff to generate
 postscript for printing, but this doesn't seem to exist either...)

 Am I remembering options from some old vendor Unix?

 -- 
 David A. Holland
 dholland@netbsd.org

From: Abhinav Upadhyay <er.abhinav.upadhyay@gmail.com>
To: NetBSD GNATS <gnats-bugs@netbsd.org>
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org, kashmir@umiacs.umd.edu
Subject: Re: bin/1904
Date: Mon, 30 May 2016 01:57:40 +0530

 On Sun, May 29, 2016 at 1:35 AM, David Holland <dholland-bugs@netbsd.org> wrote:
 > The following reply was made to PR bin/1904; it has been noted by GNATS.
 >
 > From: David Holland <dholland-bugs@netbsd.org>
 > To: gnats-bugs@NetBSD.org
 > Cc:
 > Subject: Re: bin/1904
 > Date: Sat, 28 May 2016 18:41:59 +0000
 >
 >  On Sat, May 28, 2016 at 05:25:00PM +0000, Abhinav Upadhyay wrote:
 >   >  As per the description of the 3rd patch, it means that catman doesn't
 >   >  parse and use the rules from /etc/man.conf and, it also doesn't handle
 >   >  the symlinked or hard linked man pages, the patch fixes those issues.
 >   >
 >   >  I think those are useful fixes if we are going to maintain catman.
 >
 >  Maybe; ISTM that the way to deal with man.conf is that it should use
 >  man(1) to generate the cat pages. Except for that man(1) needs a way
 >  to be told "please print this page" and while I thought it had an
 >  option for that, it doesn't currently seem to.

 We could do that, mandoc has -Tascii option (I assume that's
 equivalent to a cat page output, correct me if I'm wrong)

 >
 >  (Also, I'd thought there was an option to man(1) to run troff to generate
 >  postscript for printing, but this doesn't seem to exist either...)
 >
 >  Am I remembering options from some old vendor Unix?
 >
 mandoc has an option for this too, and could be added to man(1).

 As we are already using mandoc for formatting man pages, we could add
 these options to man(1) too?

 -
 Abhinav

From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: bin/1904
Date: Sun, 29 May 2016 22:31:20 +0000

 On Sun, May 29, 2016 at 08:30:00PM +0000, Abhinav Upadhyay wrote:
  >  >  Maybe; ISTM that the way to deal with man.conf is that it should use
  >  >  man(1) to generate the cat pages. Except for that man(1) needs a way
  >  >  to be told "please print this page" and while I thought it had an
  >  >  option for that, it doesn't currently seem to.
  >  
  >  We could do that, mandoc has -Tascii option (I assume that's
  >  equivalent to a cat page output, correct me if I'm wrong)

 It is. What I meant was something like "man -Q /some/path/foo.1" to
 print /some/path/foo.1 directly rather than search for a page by name.
 Like I said, I remember man having such an option but that must have
 been on some other platform long ago.

 Anyway, more careful inspection of catman shows that it's had man.conf
 support since 1999. The only thing left in this PR is the support for
 hardlinked man pages... the patch here doesn't even begin to apply
 because the 1999 changes were a big rewrite, and the logic in this
 patch for identifying hardlinks does O(n^2) directory reads, which is
 neither necessary nor desirable. So I don't think we should bother
 with the amount of work it'll take to merge it.

 If anyone wants to implement hardlink handling it seems fairly
 straightforward in the current catman code to add a structure to hold
 a (fsid, ino) -> name mapping, to add to it when handling a page whose
 linkcount > 1, and to check it when encountering a page whose
 linkcount > 1. It doesn't seem to me to be worth the trouble given
 that we don't even build cat pages by default and with mandoc there's
 really no reason to except on the slowest of slow machines.

 I've added a note in catman(8) about how to do this in case anyone
 sees fit to bother.

 In the meantime I see no reason to keep this PR open.

 -- 
 David A. Holland
 dholland@netbsd.org

State-Changed-From-To: open->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Sun, 29 May 2016 22:37:10 +0000
State-Changed-Why:
Everything in here has been overtaken by events, except for the logic for
handling hardlinks... which in turn would take substantial work to merge
and isn't really done right, and therefore doesn't seem worthwhile.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.