Ejemplo n.º 1
0
void
manpath_parse(struct manpaths *dirs, const char *file,
		char *defp, char *auxp)
{
	char		*insert;

	/* Always prepend -m. */
	manpath_parseline(dirs, auxp);

	/* If -M is given, it overrides everything else. */
	if (NULL != defp) {
		manpath_parseline(dirs, defp);
		return;
	}

	/* MANPATH and man.conf(5) cooperate. */
	defp = getenv("MANPATH");
	if (NULL == file)
		file = MAN_CONF_FILE;

	/* No MANPATH; use man.conf(5) only. */
	if (NULL == defp || '\0' == defp[0]) {
		manpath_manconf(dirs, file);
		return;
	}

	/* Prepend man.conf(5) to MANPATH. */
	if (':' == defp[0]) {
		manpath_manconf(dirs, file);
		manpath_parseline(dirs, defp);
		return;
	}

	/* Append man.conf(5) to MANPATH. */
	if (':' == defp[(int)strlen(defp) - 1]) {
		manpath_parseline(dirs, defp);
		manpath_manconf(dirs, file);
		return;
	}

	/* Insert man.conf(5) into MANPATH. */
	insert = strstr(defp, "::");
	if (NULL != insert) {
		*insert++ = '\0';
		manpath_parseline(dirs, defp);
		manpath_manconf(dirs, file);
		manpath_parseline(dirs, insert + 1);
		return;
	}

	/* MANPATH overrides man.conf(5) completely. */
	manpath_parseline(dirs, defp);
}
Ejemplo n.º 2
0
static void
pg_search(const struct req *req, char *path)
{
	size_t		  tt, ressz;
	struct manpaths	  ps;
	int		  i, sz, rc;
	const char	 *ep, *start;
	struct res	*res;
	char		**cp;
	struct opts	  opt;
	struct expr	 *expr;

	if (req->q.manroot < 0 || 0 == req->psz) {
		resp_search(NULL, 0, (void *)req);
		return;
	}

	memset(&opt, 0, sizeof(struct opts));

	ep 	 = req->q.expr;
	opt.arch = req->q.arch;
	opt.cat  = req->q.sec;
	rc 	 = -1;
	sz 	 = 0;
	cp	 = NULL;
	ressz	 = 0;
	res	 = NULL;

	/*
	 * Begin by chdir()ing into the root of the manpath.
	 * This way we can pick up the database files, which are
	 * relative to the manpath root.
	 */

	assert(req->q.manroot < (int)req->psz);
	if (-1 == (chdir(req->p[req->q.manroot].path))) {
		perror(req->p[req->q.manroot].path);
		resp_search(NULL, 0, (void *)req);
		return;
	}

	memset(&ps, 0, sizeof(struct manpaths));
	manpath_manconf(&ps, "etc/catman.conf");

	/*
	 * Poor man's tokenisation: just break apart by spaces.
	 * Yes, this is half-ass.  But it works for now.
	 */

	while (ep && isspace((unsigned char)*ep))
		ep++;

	while (ep && '\0' != *ep) {
		cp = mandoc_realloc(cp, (sz + 1) * sizeof(char *));
		start = ep;
		while ('\0' != *ep && ! isspace((unsigned char)*ep))
			ep++;
		cp[sz] = mandoc_malloc((ep - start) + 1);
		memcpy(cp[sz], start, ep - start);
		cp[sz++][ep - start] = '\0';
		while (isspace((unsigned char)*ep))
			ep++;
	}

	/*
	 * Pump down into apropos backend.
	 * The resp_search() function is called with the results.
	 */

	expr = req->q.legacy ? 
		termcomp(sz, cp, &tt) : exprcomp(sz, cp, &tt);

	if (NULL != expr)
		rc = apropos_search
			(ps.sz, ps.paths, &opt, expr, tt, 
			 (void *)req, &ressz, &res, resp_search);

	/* ...unless errors occured. */

	if (0 == rc)
		resp_baddb();
	else if (-1 == rc)
		resp_search(NULL, 0, NULL);

	for (i = 0; i < sz; i++)
		free(cp[i]);

	free(cp);
	resfree(res, ressz);
	exprfree(expr);
	manpath_free(&ps);
}
Ejemplo n.º 3
0
static void
pg_show(const struct req *req, char *path)
{
	struct manpaths	 ps;
	size_t		 sz;
	char		*sub;
	char		 file[PATH_MAX];
	const char	*cp;
	int		 rc, catm;
	unsigned int	 vol, rec, mr;
	DB		*idx;
	DBT		 key, val;

	idx = NULL;

	/* Parse out mroot, volume, and record from the path. */

	if (NULL == path || NULL == (sub = strchr(path, '/'))) {
		resp_error400();
		return;
	} 
	*sub++ = '\0';
	if ( ! atou(path, &mr)) {
		resp_error400();
		return;
	}
	path = sub;
	if (NULL == (sub = strchr(path, '/'))) {
		resp_error400();
		return;
	}
	*sub++ = '\0';
	if ( ! atou(path, &vol) || ! atou(sub, &rec)) {
		resp_error400();
		return;
	} else if (mr >= (unsigned int)req->psz) {
		resp_error400();
		return;
	}

	/*
	 * Begin by chdir()ing into the manroot.
	 * This way we can pick up the database files, which are
	 * relative to the manpath root.
	 */

	if (-1 == chdir(req->p[(int)mr].path)) {
		perror(req->p[(int)mr].path);
		resp_baddb();
		return;
	}

	memset(&ps, 0, sizeof(struct manpaths));
	manpath_manconf(&ps, "etc/catman.conf");

	if (vol >= (unsigned int)ps.sz) {
		resp_error400();
		goto out;
	}

	sz = strlcpy(file, ps.paths[vol], PATH_MAX);
	assert(sz < PATH_MAX);
	strlcat(file, "/", PATH_MAX);
	strlcat(file, MANDOC_IDX, PATH_MAX);

	/* Open the index recno(3) database. */

	idx = dbopen(file, O_RDONLY, 0, DB_RECNO, NULL);
	if (NULL == idx) {
		perror(file);
		resp_baddb();
		goto out;
	}

	key.data = &rec;
	key.size = 4;

	if (0 != (rc = (*idx->get)(idx, &key, &val, 0))) {
		rc < 0 ? resp_baddb() : resp_error400();
		goto out;
	} else if (0 == val.size) {
		resp_baddb();
		goto out;
	}

	cp = (char *)val.data;
	catm = 'c' == *cp++;

	if (NULL == memchr(cp, '\0', val.size - 1)) 
		resp_baddb();
	else {
 		file[(int)sz] = '\0';
 		strlcat(file, "/", PATH_MAX);
 		strlcat(file, cp, PATH_MAX);
		if (catm) 
			catman(req, file);
		else
			format(req, file);
	}
out:
	if (idx)
		(*idx->close)(idx);
	manpath_free(&ps);
}