tech@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mandocdb/apropos using man.conf
@ 2011-11-21 21:40 Kristaps Dzonsons
  2011-11-22 11:29 ` Kristaps Dzonsons
  0 siblings, 1 reply; 2+ messages in thread
From: Kristaps Dzonsons @ 2011-11-21 21:40 UTC (permalink / raw)
  To: tech

[-- Attachment #1: Type: text/plain, Size: 1694 bytes --]

Hi,

Enclosed is a patch, mostly containing schwarze@'s original man.conf 
work, that lets apropos(1) and mandocdb(8) (and man.cgi, but it's not in 
the patch) behave much better.  Specifically:

apropos(1) now does as it traditionally has:
   If [-M manpath] is used, it sets the base path.
   If $MANPATH is used, it sets the base path (overriding -M).
   If neither -M or $MANPATH, man.conf/manpath(1)** is used.
   If [-m manpath] is used, it augments the base paths.

mandocdb(8) changes:
   If [dirs...] is empty, use man.conf/manpath(1).

manpath.c (was man.conf.c) changes:
   De-dupe the path listings.
   Resolve paths using realpath.
   Use manpath(1)** if -DUSE_MANPATH is specified.

Food for thought: MANPATH.  Does anybody set this?  It makes sense that 
it would be used by PATH.  But it's never set [on OpenBSD, at least], so 
users can't nicely just say "MANPATH=$MANPATH:foo/bar".  These days 
man.conf does that.  Unfortunately, setting MANPATH wipes these out, so 
users have no easy way of having their own MANPATH additions.  I think 
the MANPATH behaviour should be changed to augment the directory path 
(i.e., -m) instead of replace it (-M).  Does this make any sense or am I 
just pissing in the wind?

**What's manpath(1), you're asking?  It's a utility common to man-db and 
the new/old-man package.  It provides similar functionality to scanning 
man.conf, but also scans local manpath configuration files.  FreeBSD 
link below.  I think it's way over-engineered, but as mentioned above, I 
think our method is a little confusing too.

http://www.freebsd.org/cgi/man.cgi?query=manpath&sektion=1&apropos=0&manpath=FreeBSD+8.2-RELEASE+and+Ports

Thoughts?

Kristaps

[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 14141 bytes --]

? apropos
? apropos.dSYM
? bar
? config.h
? config.log
? db.bak.c
? db.bak.h
? demandoc
? foo
? foo.1
? foo.1.html
? foo.1.pdf
? foo.1.ps
? man.cgi
? mandoc
? mandoc.core
? mandoc.db
? mandoc.index
? mandocdb
? mandocdb.dSYM
? patch.txt
? preconv
? test-getsubopt.dSYM
? test-mmap.dSYM
? test-strlcat.dSYM
? test-strlcpy.dSYM
? test-strptime.dSYM
Index: Makefile
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/Makefile,v
retrieving revision 1.379
diff -u -r1.379 Makefile
--- Makefile	20 Nov 2011 21:36:00 -0000	1.379
+++ Makefile	21 Nov 2011 21:24:53 -0000
@@ -102,6 +102,8 @@
 		   mandocdb.c \
 		   mandocdb.h \
 		   mandoc_char.7 \
+		   manpath.c \
+		   manpath.h \
 		   mdoc.h \
 		   mdoc.7 \
 		   mdoc.c \
@@ -272,20 +274,20 @@
 $(MANDOC_TERM_OBJS) $(MANDOC_TERM_LNS): term.h
 $(MANDOC_OBJS) $(MANDOC_LNS): main.h mandoc.h mdoc.h man.h config.h out.h
 
-MANDOCDB_OBJS	 = mandocdb.o
-MANDOCDB_LNS	 = mandocdb.ln
+MANDOCDB_OBJS	 = mandocdb.o manpath.o
+MANDOCDB_LNS	 = mandocdb.ln manpath.ln
 
-$(MANDOCDB_OBJS) $(MANDOCDB_LNS): mandocdb.h mandoc.h mdoc.h man.h config.h
+$(MANDOCDB_OBJS) $(MANDOCDB_LNS): mandocdb.h mandoc.h mdoc.h man.h config.h manpath.h
 
 PRECONV_OBJS	 = preconv.o
 PRECONV_LNS	 = preconv.ln
 
 $(PRECONV_OBJS) $(PRECONV_LNS): config.h
 
-APROPOS_OBJS	 = apropos.o apropos_db.o
-APROPOS_LNS	 = apropos.ln apropos_db.ln
+APROPOS_OBJS	 = apropos.o apropos_db.o manpath.o
+APROPOS_LNS	 = apropos.ln apropos_db.ln manpath.ln
 
-$(APROPOS_OBJS) $(APROPOS_LNS): config.h mandoc.h mandocdb.h apropos_db.h
+$(APROPOS_OBJS) $(APROPOS_LNS): config.h mandoc.h mandocdb.h apropos_db.h manpath.h
 
 CGI_OBJS	 = cgi.o apropos_db.o
 CGI_LNS	 	 = cgi.ln apropos_db.ln
Index: apropos.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/apropos.c,v
retrieving revision 1.17
diff -u -r1.17 apropos.c
--- apropos.c	20 Nov 2011 21:36:00 -0000	1.17
+++ apropos.c	21 Nov 2011 21:24:54 -0000
@@ -22,34 +22,16 @@
 #include <assert.h>
 #include <ctype.h>
 #include <getopt.h>
-#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "apropos_db.h"
 #include "mandoc.h"
-
-/*
- * FIXME: add support for manpath(1), which everybody but OpenBSD and
- * NetBSD seem to use.
- */
-#define MAN_CONF_FILE	"/etc/man.conf"
-#define MAN_CONF_KEY	"_whatdb"
-
-/*
- * List of paths to be searched for manual databases.
- */
-struct	manpaths {
-	int	  sz;
-	char	**paths;
-};
+#include "manpath.h"
 
 static	int	 cmp(const void *, const void *);
 static	void	 list(struct res *, size_t, void *);
-static	void	 manpath_add(struct manpaths *, const char *);
-static	void	 manpath_parse(struct manpaths *, char *);
-static	void	 manpath_parseconf(struct manpaths *);
 static	void	 usage(void);
 
 static	char	*progname;
@@ -57,7 +39,7 @@
 int
 main(int argc, char *argv[])
 {
-	int		 i, ch, rc;
+	int		 ch, rc;
 	struct manpaths	 paths;
 	size_t		 terms;
 	struct opts	 opts;
@@ -106,15 +88,7 @@
 		goto out;
 	}
 
-	if (NULL != getenv("MANPATH"))
-		defpaths = getenv("MANPATH");
-
-	if (NULL == defpaths)
-		manpath_parseconf(&paths);
-	else
-		manpath_parse(&paths, defpaths);
-
-	manpath_parse(&paths, auxpaths);
+	manpath_parse(&paths, defpaths, auxpaths);
 
 	if (NULL == (e = exprcomp(argc, argv, &terms))) {
 		fprintf(stderr, "%s: Bad expression\n", progname);
@@ -130,10 +104,7 @@
 				"manual database\n", progname);
 
 out:
-	for (i = 0; i < paths.sz; i++)
-		free(paths.paths[i]);
-
-	free(paths.paths);
+	manpath_free(&paths);
 	exprfree(e);
 
 	return(rc ? EXIT_SUCCESS : EXIT_FAILURE);
@@ -173,104 +144,4 @@
 			"[-S arch] "
 			"[-s section] "
 			"expression...\n", progname);
-}
-
-/*
- * Parse a FULL pathname from a colon-separated list of arrays.
- */
-static void
-manpath_parse(struct manpaths *dirs, char *path) 
-{
-	char	*dir;
-
-	if (NULL == path)
-		return;
-
-	for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":"))
-		manpath_add(dirs, dir);
-}
-
-/*
- * Add a directory to the array, ignoring bad directories.
- * Grow the array one-by-one for simplicity's sake.
- */
-static void
-manpath_add(struct manpaths *dirs, const char *dir) 
-{
-	char		 buf[PATH_MAX];
-	char		*cp;
-	int		 i;
-
-	if (NULL == (cp = realpath(dir, buf)))
-		return;
-
-	for (i = 0; i < dirs->sz; i++)
-		if (0 == strcmp(dirs->paths[i], dir))
-			return;
-
-	dirs->paths = mandoc_realloc
-		(dirs->paths, 
-		 ((size_t)dirs->sz + 1) * sizeof(char *));
-
-	dirs->paths[dirs->sz++] = mandoc_strdup(cp);
-}
-
-static void
-manpath_parseconf(struct manpaths *dirs) 
-{
-	FILE		*stream;
-#ifdef	USE_MANPATH
-	char		*buf;
-	size_t		 sz, bsz;
-
-	stream = popen("manpath", "r");
-	if (NULL == stream)
-		return;
-
-	buf = NULL;
-	bsz = 0;
-
-	do {
-		buf = mandoc_realloc(buf, bsz + 1024);
-		sz = fread(buf + (int)bsz, 1, 1024, stream);
-		bsz += sz;
-	} while (sz > 0);
-
-	assert(bsz && '\n' == buf[bsz - 1]);
-	buf[bsz - 1] = '\0';
-
-	manpath_parse(dirs, buf);
-	free(buf);
-	pclose(stream);
-#else
-	char		*p, *q;
-	size_t	 	 len, keysz;
-
-	keysz = strlen(MAN_CONF_KEY);
-	assert(keysz > 0);
-
-	if (NULL == (stream = fopen(MAN_CONF_FILE, "r")))
-		return;
-
-	while (NULL != (p = fgetln(stream, &len))) {
-		if (0 == len || '\n' == p[--len])
-			break;
-		p[len] = '\0';
-		while (isspace((unsigned char)*p))
-			p++;
-		if (strncmp(MAN_CONF_KEY, p, keysz))
-			continue;
-		p += keysz;
-		while (isspace(*p))
-			p++;
-		if ('\0' == *p)
-			continue;
-		if (NULL == (q = strrchr(p, '/')))
-			continue;
-		*q = '\0';
-		manpath_add(dirs, p);
-	}
-
-	fclose(stream);
-#endif
 }
Index: mandocdb.8
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandocdb.8,v
retrieving revision 1.5
diff -u -r1.5 mandocdb.8
--- mandocdb.8	9 Oct 2011 08:56:27 -0000	1.5
+++ mandocdb.8	21 Nov 2011 21:24:54 -0000
@@ -71,6 +71,12 @@
 creates databases in each
 .Ar dir
 using files rooted in that directory.
+If
+.Ar dir
+is not provided,
+.Nm
+uses the default paths stipulated by
+.Xr man 1 .
 .Pp
 If fatal parse errors are encountered while parsing, the offending file
 is printed to stderr, omitted from the index, and the parse continues
@@ -190,6 +196,7 @@
 The output databases are corrupt and should be removed .
 .El
 .Sh SEE ALSO
+.Xr man 1 ,
 .Xr mandoc 1 ,
 .Xr btree 3 ,
 .Xr recno 3
Index: mandocdb.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandocdb.c,v
retrieving revision 1.9
diff -u -r1.9 mandocdb.c
--- mandocdb.c	20 Nov 2011 12:39:08 -0000	1.9
+++ mandocdb.c	21 Nov 2011 21:24:59 -0000
@@ -39,6 +39,7 @@
 #include "mdoc.h"
 #include "mandoc.h"
 #include "mandocdb.h"
+#include "manpath.h"
 
 #define	MANDOC_BUFSZ	  BUFSIZ
 #define	MANDOC_SLOP	  1024
@@ -247,6 +248,7 @@
 main(int argc, char *argv[])
 {
 	struct mparse	*mp; /* parse sequence */
+	struct manpaths	 dirs;
 	enum op		 op; /* current operation */
 	const char	*dir;
 	char		 ibuf[MAXPATHLEN], /* index fname */
@@ -274,6 +276,8 @@
 	else
 		++progname;
 
+	memset(&dirs, 0, sizeof(struct manpaths));
+
 	verb = 0;
 	of = NULL;
 	db = idx = NULL;
@@ -370,19 +374,34 @@
 		goto out;
 	}
 
-	for (i = 0; i < argc; i++) {
+	/*
+	 * Configure the directories we're going to scan.
+	 * If we have command-line arguments, use them.
+	 * If not, we use man(1)'s method (see mandocdb.8).
+	 */
+
+	if (argc > 0) {
+		dirs.paths = mandoc_malloc(argc * sizeof(char *));
+		dirs.sz = argc;
+		for (i = 0; i < argc; i++)
+			dirs.paths[i] = mandoc_strdup(argv[i]);
+	} else
+		manpath_parseconf(&dirs);
+
+	for (i = 0; i < dirs.sz; i++) {
 		ibuf[0] = fbuf[0] = '\0';
 
-		strlcat(fbuf, argv[i], MAXPATHLEN);
+		strlcat(fbuf, dirs.paths[i], MAXPATHLEN);
 		strlcat(fbuf, "/", MAXPATHLEN);
 		sz1 = strlcat(fbuf, MANDOC_DB, MAXPATHLEN);
 
-		strlcat(ibuf, argv[i], MAXPATHLEN);
+		strlcat(ibuf, dirs.paths[i], MAXPATHLEN);
 		strlcat(ibuf, "/", MAXPATHLEN);
 		sz2 = strlcat(ibuf, MANDOC_IDX, MAXPATHLEN);
 
 		if (sz1 >= MAXPATHLEN || sz2 >= MAXPATHLEN) {
-			fprintf(stderr, "%s: Path too long\n", argv[i]);
+			fprintf(stderr, "%s: Path too long\n", 
+					dirs.paths[i]);
 			exit((int)MANDOCLEVEL_BADARG);
 		}
 
@@ -405,7 +424,7 @@
 		ofile_free(of);
 		of = NULL;
 
-		if ( ! ofile_dirbuild(argv[i], verb, &of)) 
+		if ( ! ofile_dirbuild(dirs.paths[i], verb, &of)) 
 			exit((int)MANDOCLEVEL_SYSERR);
 
 		if (NULL == of)
@@ -427,6 +446,7 @@
 	if (mp)
 		mparse_free(mp);
 
+	manpath_free(&dirs);
 	ofile_free(of);
 	free(buf.cp);
 	free(dbuf.cp);
Index: manpath.c
===================================================================
RCS file: manpath.c
diff -N manpath.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ manpath.c	21 Nov 2011 21:25:00 -0000
@@ -0,0 +1,167 @@
+/*	$Id: apropos.c,v 1.17 2011/11/20 21:36:00 kristaps Exp $ */
+/*
+ * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mandoc.h"
+#include "manpath.h"
+
+#define MAN_CONF_FILE	"/etc/man.conf"
+#define MAN_CONF_KEY	"_whatdb"
+
+static	void	 manpath_add(struct manpaths *, const char *);
+
+void
+manpath_parse(struct manpaths *dirs, char *defp, char *auxp) 
+{
+
+	if (NULL != getenv("MANPATH"))
+		defp = getenv("MANPATH");
+
+	if (NULL == defp)
+		manpath_parseconf(dirs);
+	else
+		manpath_parseline(dirs, defp);
+
+	manpath_parseline(dirs, auxp);
+}
+
+/*
+ * Parse a FULL pathname from a colon-separated list of arrays.
+ */
+void
+manpath_parseline(struct manpaths *dirs, char *path) 
+{
+	char	*dir;
+
+	if (NULL == path)
+		return;
+
+	for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":"))
+		manpath_add(dirs, dir);
+}
+
+/*
+ * Add a directory to the array, ignoring bad directories.
+ * Grow the array one-by-one for simplicity's sake.
+ */
+static void
+manpath_add(struct manpaths *dirs, const char *dir) 
+{
+	char		 buf[PATH_MAX];
+	char		*cp;
+	int		 i;
+
+	if (NULL == (cp = realpath(dir, buf)))
+		return;
+
+	for (i = 0; i < dirs->sz; i++)
+		if (0 == strcmp(dirs->paths[i], dir))
+			return;
+
+	dirs->paths = mandoc_realloc
+		(dirs->paths, 
+		 ((size_t)dirs->sz + 1) * sizeof(char *));
+
+	dirs->paths[dirs->sz++] = mandoc_strdup(cp);
+}
+
+void
+manpath_parseconf(struct manpaths *dirs)
+{
+	FILE		*stream;
+#ifdef	USE_MANPATH
+	char		*buf;
+	size_t		 sz, bsz;
+
+	/* Open manpath(1).  Ignore errors. */
+
+	stream = popen("manpath", "r");
+	if (NULL == stream)
+		return;
+
+	buf = NULL;
+	bsz = 0;
+
+	/* Read in as much output as we can. */
+
+	do {
+		buf = mandoc_realloc(buf, bsz + 1024);
+		sz = fread(buf + (int)bsz, 1, 1024, stream);
+		bsz += sz;
+	} while (sz > 0);
+
+	if ( ! ferror(stream) && feof(stream) &&
+			bsz && '\n' == buf[bsz - 1]) {
+		buf[bsz - 1] = '\0';
+		manpath_parseline(dirs, buf);
+	}
+
+	free(buf);
+	pclose(stream);
+#else
+	char		*p, *q;
+	size_t	 	 len, keysz;
+
+	keysz = strlen(MAN_CONF_KEY);
+	assert(keysz > 0);
+
+	if (NULL == (stream = fopen(MAN_CONF_FILE, "r")))
+		return;
+
+	while (NULL != (p = fgetln(stream, &len))) {
+		if (0 == len || '\n' == p[--len])
+			break;
+		p[len] = '\0';
+		while (isspace((unsigned char)*p))
+			p++;
+		if (strncmp(MAN_CONF_KEY, p, keysz))
+			continue;
+		p += keysz;
+		while (isspace(*p))
+			p++;
+		if ('\0' == *p)
+			continue;
+		if (NULL == (q = strrchr(p, '/')))
+			continue;
+		*q = '\0';
+		manpath_add(dirs, p);
+	}
+
+	fclose(stream);
+#endif
+}
+
+void
+manpath_free(struct manpaths *p)
+{
+	int		 i;
+
+	for (i = 0; i < p->sz; i++)
+		free(p->paths[i]);
+
+	free(p->paths);
+}
Index: manpath.h
===================================================================
RCS file: manpath.h
diff -N manpath.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ manpath.h	21 Nov 2011 21:25:00 -0000
@@ -0,0 +1,39 @@
+/*	$Id: apropos_db.h,v 1.6 2011/11/20 15:43:14 kristaps Exp $ */
+/*
+ * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef MANPATH_H
+#define MANPATH_H
+
+/*
+ * Unsorted list of unique, absolute paths to be searched for manual
+ * databases.
+ */
+struct	manpaths {
+	int	  sz;
+	char	**paths;
+};
+
+__BEGIN_DECLS
+
+void	 manpath_parse(struct manpaths *, char *, char *);
+void	 manpath_parseconf(struct manpaths *);
+void	 manpath_parseline(struct manpaths *, char *);
+void	 manpath_free(struct manpaths *);
+
+__END_DECLS
+
+#endif /*!MANPATH_H*/

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: mandocdb/apropos using man.conf
  2011-11-21 21:40 mandocdb/apropos using man.conf Kristaps Dzonsons
@ 2011-11-22 11:29 ` Kristaps Dzonsons
  0 siblings, 0 replies; 2+ messages in thread
From: Kristaps Dzonsons @ 2011-11-22 11:29 UTC (permalink / raw)
  To: tech

> manpath.c (was man.conf.c) changes:
> De-dupe the path listings.
> Resolve paths using realpath.
> Use manpath(1)** if -DUSE_MANPATH is specified.

If you've read this patch, you'll note my error:

         while (NULL != (p = fgetln(stream, &len))) {
                 if (0 == len || '\n' == p[--len])
                         break;

Where the second == should be !=.  This has been fixed.
--
 To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-11-22 11:29 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-21 21:40 mandocdb/apropos using man.conf Kristaps Dzonsons
2011-11-22 11:29 ` Kristaps Dzonsons

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).