From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp-1.sys.kth.se (smtp-1.sys.kth.se [130.237.32.175]) by krisdoz.my.domain (8.14.3/8.14.3) with ESMTP id pALLf59w003408 for ; Mon, 21 Nov 2011 16:41:06 -0500 (EST) Received: from mailscan-1.sys.kth.se (mailscan-1.sys.kth.se [130.237.32.91]) by smtp-1.sys.kth.se (Postfix) with ESMTP id 52CC61558A9 for ; Mon, 21 Nov 2011 22:40:59 +0100 (CET) X-Virus-Scanned: by amavisd-new at kth.se Received: from smtp-1.sys.kth.se ([130.237.32.175]) by mailscan-1.sys.kth.se (mailscan-1.sys.kth.se [130.237.32.91]) (amavisd-new, port 10024) with LMTP id dfonU3T6aXLK for ; Mon, 21 Nov 2011 22:40:54 +0100 (CET) X-KTH-Auth: kristaps [83.250.3.9] X-KTH-mail-from: kristaps@bsd.lv X-KTH-rcpt-to: tech@mdocml.bsd.lv Received: from macky.local (c83-250-3-9.bredband.comhem.se [83.250.3.9]) by smtp-1.sys.kth.se (Postfix) with ESMTP id 8E85D1557D7 for ; Mon, 21 Nov 2011 22:40:51 +0100 (CET) Message-ID: <4ECAC55F.3040205@bsd.lv> Date: Mon, 21 Nov 2011 22:40:47 +0100 From: Kristaps Dzonsons User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:8.0) Gecko/20111105 Thunderbird/8.0 X-Mailinglist: mdocml-tech Reply-To: tech@mdocml.bsd.lv MIME-Version: 1.0 To: tech@mdocml.bsd.lv Subject: mandocdb/apropos using man.conf Content-Type: multipart/mixed; boundary="------------090502030004090905050706" This is a multi-part message in MIME format. --------------090502030004090905050706 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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 --------------090502030004090905050706 Content-Type: text/plain; name="patch.txt" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="patch.txt" ? 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 #include #include -#include #include #include #include #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 + * Copyright (c) 2011 Kristaps Dzonsons + * + * 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 +#include +#include +#include +#include +#include + +#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 + * Copyright (c) 2011 Kristaps Dzonsons + * + * 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*/ --------------090502030004090905050706-- -- To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv