Ejemplo n.º 1
0
int
main(int argc, char *argv[])
{
	struct mparse	*mp;
	struct mchars	*mchars;
	int		 ch, fd, i, list;
	extern int	 optind;

	if (argc < 1)
		progname = "demandoc";
	else if ((progname = strrchr(argv[0], '/')) == NULL)
		progname = argv[0];
	else
		++progname;

	mp = NULL;
	list = 0;

	while (-1 != (ch = getopt(argc, argv, "ikm:pw")))
		switch (ch) {
		case ('i'):
			/* FALLTHROUGH */
		case ('k'):
			/* FALLTHROUGH */
		case ('m'):
			/* FALLTHROUGH */
		case ('p'):
			break;
		case ('w'):
			list = 1;
			break;
		default:
			usage();
			return((int)MANDOCLEVEL_BADARG);
		}

	argc -= optind;
	argv += optind;

	mchars = mchars_alloc();
	mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, mchars, NULL);
	assert(mp);

	if (argc < 1)
		pmandoc(mp, STDIN_FILENO, "<stdin>", list);

	for (i = 0; i < argc; i++) {
		mparse_reset(mp);
		if (mparse_open(mp, &fd, argv[i]) != MANDOCLEVEL_OK) {
			perror(argv[i]);
			continue;
		}
		pmandoc(mp, fd, argv[i], list);
	}

	mparse_free(mp);
	mchars_free(mchars);
	return((int)MANDOCLEVEL_OK);
}
Ejemplo n.º 2
0
Archivo: cgi.c Proyecto: 2asoft/freebsd
static void
format(const struct req *req, const char *file)
{
	struct manoutput conf;
	struct mparse	*mp;
	struct roff_man	*man;
	void		*vp;
	int		 fd;
	int		 usepath;

	if (-1 == (fd = open(file, O_RDONLY, 0))) {
		puts("<P>You specified an invalid manual file.</P>");
		return;
	}

	mchars_alloc();
	mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, req->q.manpath);
	mparse_readfd(mp, fd, file);
	close(fd);

	memset(&conf, 0, sizeof(conf));
	conf.fragment = 1;
	usepath = strcmp(req->q.manpath, req->p[0]);
	mandoc_asprintf(&conf.man, "%s?query=%%N&sec=%%S%s%s%s%s",
	    scriptname,
	    req->q.arch	? "&arch="       : "",
	    req->q.arch	? req->q.arch    : "",
	    usepath	? "&manpath="    : "",
	    usepath	? req->q.manpath : "");

	mparse_result(mp, &man, NULL);
	if (man == NULL) {
		fprintf(stderr, "fatal mandoc error: %s/%s\n",
		    req->q.manpath, file);
		pg_error_internal();
		mparse_free(mp);
		mchars_free();
		return;
	}

	vp = html_alloc(&conf);

	if (man->macroset == MACROSET_MDOC) {
		mdoc_validate(man);
		html_mdoc(vp, man);
	} else {
		man_validate(man);
		html_man(vp, man);
	}

	html_free(vp);
	mparse_free(mp);
	mchars_free();
	free(conf.man);
}
Ejemplo n.º 3
0
static void
format(const struct req *req, const char *file)
{
	struct mparse	*mp;
	int		 fd;
	struct mdoc	*mdoc;
	struct man	*man;
	void		*vp;
	enum mandoclevel rc;
	char		 opts[PATH_MAX + 128];

	if (-1 == (fd = open(file, O_RDONLY, 0))) {
		resp_baddb();
		return;
	}

	mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL, NULL);
	rc = mparse_readfd(mp, fd, file);
	close(fd);

	if (rc >= MANDOCLEVEL_FATAL) {
		resp_baddb();
		return;
	}

	snprintf(opts, sizeof(opts), "fragment,"
			"man=%s/search.html?sec=%%S&expr=Nm~^%%N$,"
			/*"includes=/cgi-bin/man.cgi/usr/include/%%I"*/,
			progname);

	mparse_result(mp, &mdoc, &man);
	if (NULL == man && NULL == mdoc) {
		resp_baddb();
		mparse_free(mp);
		return;
	}

	resp_begin_html(200, NULL);
	resp_searchform(req);

	vp = html_alloc(opts);

	if (NULL != mdoc)
		html_mdoc(vp, mdoc);
	else
		html_man(vp, man);

	puts("</BODY>\n"
	     "</HTML>");

	html_free(vp);
	mparse_free(mp);
}
Ejemplo n.º 4
0
int
main(int argc, char *argv[])
{
	struct mparse	*mp;
	int		 ch, i, list;
	extern int	 optind;

	progname = strrchr(argv[0], '/');
	if (progname == NULL)
		progname = argv[0];
	else
		++progname;

	mp = NULL;
	list = 0;

	while (-1 != (ch = getopt(argc, argv, "ikm:pw")))
		switch (ch) {
		case ('i'):
			/* FALLTHROUGH */
		case ('k'):
			/* FALLTHROUGH */
		case ('m'):
			/* FALLTHROUGH */
		case ('p'):
			break;
		case ('w'):
			list = 1;
			break;
		default:
			usage();
			return((int)MANDOCLEVEL_BADARG);
		}

	argc -= optind;
	argv += optind;

	mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_FATAL, NULL, NULL);
	assert(mp);

	if (0 == argc)
		pmandoc(mp, STDIN_FILENO, "<stdin>", list);

	for (i = 0; i < argc; i++) {
		mparse_reset(mp);
		pmandoc(mp, -1, argv[i], list);
	}

	mparse_free(mp);
	return((int)MANDOCLEVEL_OK);
}
Ejemplo n.º 5
0
int
main(int argc, char *argv[])
{
	struct mparse	*mp; /* parse sequence */
	struct manpaths	 dirs;
	struct mdb	 mdb;
	struct recs	 recs;
	enum op		 op; /* current operation */
	const char	*dir;
	int		 ch, i, flags;
	char		 dirbuf[MAXPATHLEN];
	DB		*hash; /* temporary keyword hashtable */
	BTREEINFO	 info; /* btree configuration */
	size_t		 sz1, sz2;
	struct buf	 buf, /* keyword buffer */
			 dbuf; /* description buffer */
	struct of	*of; /* list of files for processing */
	extern int	 optind;
	extern char	*optarg;

	progname = strrchr(argv[0], '/');
	if (progname == NULL)
		progname = argv[0];
	else
		++progname;

	memset(&dirs, 0, sizeof(struct manpaths));
	memset(&mdb, 0, sizeof(struct mdb));
	memset(&recs, 0, sizeof(struct recs));

	of = NULL;
	mp = NULL;
	hash = NULL;
	op = OP_DEFAULT;
	dir = NULL;

	while (-1 != (ch = getopt(argc, argv, "aC:d:tu:vW")))
		switch (ch) {
		case ('a'):
			use_all = 1;
			break;
		case ('C'):
			if (op) {
				fprintf(stderr,
				    "-C: conflicting options\n");
				goto usage;
			}
			dir = optarg;
			op = OP_CONFFILE;
			break;
		case ('d'):
			if (op) {
				fprintf(stderr,
				    "-d: conflicting options\n");
				goto usage;
			}
			dir = optarg;
			op = OP_UPDATE;
			break;
		case ('t'):
			dup2(STDOUT_FILENO, STDERR_FILENO);
			if (op) {
				fprintf(stderr,
				    "-t: conflicting options\n");
				goto usage;
			}
			op = OP_TEST;
			use_all = 1;
			warnings = 1;
			break;
		case ('u'):
			if (op) {
				fprintf(stderr,
				    "-u: conflicting options\n");
				goto usage;
			}
			dir = optarg;
			op = OP_DELETE;
			break;
		case ('v'):
			verb++;
			break;
		case ('W'):
			warnings = 1;
			break;
		default:
			goto usage;
		}

	argc -= optind;
	argv += optind;

	if (OP_CONFFILE == op && argc > 0) {
		fprintf(stderr, "-C: too many arguments\n");
		goto usage;
	}

	memset(&info, 0, sizeof(BTREEINFO));
	info.lorder = 4321;
	info.flags = R_DUP;

	mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL);

	memset(&buf, 0, sizeof(struct buf));
	memset(&dbuf, 0, sizeof(struct buf));

	buf.size = dbuf.size = MANDOC_BUFSZ;

	buf.cp = mandoc_malloc(buf.size);
	dbuf.cp = mandoc_malloc(dbuf.size);

	if (OP_TEST == op) {
		ofile_argbuild(argc, argv, &of, ".");
		if (NULL == of)
			goto out;
		index_merge(of, mp, &dbuf, &buf, 
				hash, &mdb, &recs, ".");
		goto out;
	}

	if (OP_UPDATE == op || OP_DELETE == op) {
		strlcat(mdb.dbn, dir, MAXPATHLEN);
		strlcat(mdb.dbn, "/", MAXPATHLEN);
		sz1 = strlcat(mdb.dbn, MANDOC_DB, MAXPATHLEN);

		strlcat(mdb.idxn, dir, MAXPATHLEN);
		strlcat(mdb.idxn, "/", MAXPATHLEN);
		sz2 = strlcat(mdb.idxn, MANDOC_IDX, MAXPATHLEN);

		if (sz1 >= MAXPATHLEN || sz2 >= MAXPATHLEN) {
			fprintf(stderr, "%s: path too long\n", dir);
			exit((int)MANDOCLEVEL_BADARG);
		}

		flags = O_CREAT | O_RDWR;
		mdb.db = dbopen(mdb.dbn, flags, 0644, DB_BTREE, &info);
		mdb.idx = dbopen(mdb.idxn, flags, 0644, DB_RECNO, NULL);

		if (NULL == mdb.db) {
			perror(mdb.dbn);
			exit((int)MANDOCLEVEL_SYSERR);
		} else if (NULL == mdb.idx) {
			perror(mdb.idxn);
			exit((int)MANDOCLEVEL_SYSERR);
		}

		ofile_argbuild(argc, argv, &of, dir);

		if (NULL == of)
			goto out;

		index_prune(of, &mdb, &recs, dir);

		/*
		 * Go to the root of the respective manual tree.
		 * This must work or no manuals may be found (they're
		 * indexed relative to the root).
		 */

		if (OP_UPDATE == op) {
			if (-1 == chdir(dir)) {
				perror(dir);
				exit((int)MANDOCLEVEL_SYSERR);
			}
			index_merge(of, mp, &dbuf, &buf, hash,
					&mdb, &recs, dir);
		}

		goto out;
	}

	/*
	 * 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_calloc(argc, sizeof(char *));
		dirs.sz = argc;
		for (i = 0; i < argc; i++) 
			dirs.paths[i] = mandoc_strdup(argv[i]);
	} else
		manpath_parse(&dirs, dir, NULL, NULL);

	for (i = 0; i < dirs.sz; i++) {
		/*
		 * Go to the root of the respective manual tree.
		 * This must work or no manuals may be found:
		 * They are indexed relative to the root.
		 */

		if (-1 == chdir(dirs.paths[i])) {
			perror(dirs.paths[i]);
			exit((int)MANDOCLEVEL_SYSERR);
		}

		strlcpy(mdb.dbn, MANDOC_DB, MAXPATHLEN);
		strlcpy(mdb.idxn, MANDOC_IDX, MAXPATHLEN);

		flags = O_CREAT | O_TRUNC | O_RDWR;
		mdb.db = dbopen(mdb.dbn, flags, 0644, DB_BTREE, &info);
		mdb.idx = dbopen(mdb.idxn, flags, 0644, DB_RECNO, NULL);

		if (NULL == mdb.db) {
			perror(mdb.dbn);
			exit((int)MANDOCLEVEL_SYSERR);
		} else if (NULL == mdb.idx) {
			perror(mdb.idxn);
			exit((int)MANDOCLEVEL_SYSERR);
		}

		/*
		 * Search for manuals and fill the new database.
		 */

		strlcpy(dirbuf, dirs.paths[i], MAXPATHLEN);
	       	ofile_dirbuild(".", "", "", 0, &of, dirbuf);

		if (NULL != of) {
			index_merge(of, mp, &dbuf, &buf, hash,
			     &mdb, &recs, dirs.paths[i]);
			ofile_free(of);
			of = NULL;
		}

		(*mdb.db->close)(mdb.db);
		(*mdb.idx->close)(mdb.idx);
		mdb.db = NULL;
		mdb.idx = NULL;
	}

out:
	if (mdb.db)
		(*mdb.db->close)(mdb.db);
	if (mdb.idx)
		(*mdb.idx->close)(mdb.idx);
	if (hash)
		(*hash->close)(hash);
	if (mp)
		mparse_free(mp);

	manpath_free(&dirs);
	ofile_free(of);
	free(buf.cp);
	free(dbuf.cp);
	free(recs.stack);

	return(MANDOCLEVEL_OK);

usage:
	fprintf(stderr,
		"usage: %s [-av] [-C file] | dir ... | -t file ...\n"
		"                        -d dir [file ...] | "
		"-u dir [file ...]\n",
		progname);

	return((int)MANDOCLEVEL_BADARG);
}
Ejemplo n.º 6
0
static void
format(const struct req *req, const char *file)
{
	struct mparse	*mp;
	struct mchars	*mchars;
	struct mdoc	*mdoc;
	struct man	*man;
	void		*vp;
	char		*opts;
	enum mandoclevel rc;
	int		 fd;
	int		 usepath;

	if (-1 == (fd = open(file, O_RDONLY, 0))) {
		puts("<P>You specified an invalid manual file.</P>");
		return;
	}

	mchars = mchars_alloc();
	mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_FATAL, NULL,
	    mchars, req->q.manpath);
	rc = mparse_readfd(mp, fd, file);
	close(fd);

	if (rc >= MANDOCLEVEL_FATAL) {
		fprintf(stderr, "fatal mandoc error: %s/%s\n",
		    req->q.manpath, file);
		pg_error_internal();
		return;
	}

	usepath = strcmp(req->q.manpath, req->p[0]);
	mandoc_asprintf(&opts,
	    "fragment,man=%s?query=%%N&sec=%%S%s%s%s%s",
	    scriptname,
	    req->q.arch	? "&arch="       : "",
	    req->q.arch	? req->q.arch    : "",
	    usepath	? "&manpath="    : "",
	    usepath	? req->q.manpath : "");

	mparse_result(mp, &mdoc, &man, NULL);
	if (NULL == man && NULL == mdoc) {
		fprintf(stderr, "fatal mandoc error: %s/%s\n",
		    req->q.manpath, file);
		pg_error_internal();
		mparse_free(mp);
		mchars_free(mchars);
		return;
	}

	vp = html_alloc(mchars, opts);

	if (NULL != mdoc)
		html_mdoc(vp, mdoc);
	else
		html_man(vp, man);

	html_free(vp);
	mparse_free(mp);
	mchars_free(mchars);
	free(opts);
}
Ejemplo n.º 7
0
int
main(int argc, char *argv[])
{
	struct mparse	*mp; /* parse sequence */
	struct mdoc	*mdoc; /* resulting mdoc */
	char		*fn;
	const char	*dir; /* result dir (default: cwd) */
	char		 ibuf[MAXPATHLEN], /* index fname */
			 ibbuf[MAXPATHLEN], /* index backup fname */
			 fbuf[MAXPATHLEN],  /* btree fname */
			 fbbuf[MAXPATHLEN]; /* btree backup fname */
	int		 c;
	DB		*index, /* index database */
			*db; /* keyword database */
	DBT		 rkey, rval, /* recno entries */
			 key, val; /* persistent keyword entries */
	size_t		 ksz; /* entry buffer size */
	char		 vbuf[8];
	BTREEINFO	 info; /* btree configuration */
	recno_t		 rec;
	extern int	 optind;
	extern char	*optarg;

	progname = strrchr(argv[0], '/');
	if (progname == NULL)
		progname = argv[0];
	else
		++progname;

	dir = "";

	while (-1 != (c = getopt(argc, argv, "d:")))
		switch (c) {
		case ('d'):
			dir = optarg;
			break;
		default:
			usage();
			return((int)MANDOCLEVEL_BADARG);
		}

	argc -= optind;
	argv += optind;

	/*
	 * Set up temporary file-names into which we're going to write
	 * all of our data (both for the index and database).  These
	 * will be securely renamed to the real file-names after we've
	 * written all of our data.
	 */

	ibuf[0] = ibuf[MAXPATHLEN - 2] =
		ibbuf[0] = ibbuf[MAXPATHLEN - 2] = 
		fbuf[0] = fbuf[MAXPATHLEN - 2] = 
		fbbuf[0] = fbbuf[MAXPATHLEN - 2] = '\0';

	strlcat(fbuf, dir, MAXPATHLEN);
	strlcat(fbuf, MANDOC_DB, MAXPATHLEN);

	strlcat(fbbuf, fbuf, MAXPATHLEN);
	strlcat(fbbuf, "~", MAXPATHLEN);

	strlcat(ibuf, dir, MAXPATHLEN);
	strlcat(ibuf, MANDOC_IDX, MAXPATHLEN);

	strlcat(ibbuf, ibuf, MAXPATHLEN);
	strlcat(ibbuf, "~", MAXPATHLEN);

	if ('\0' != fbuf[MAXPATHLEN - 2] ||
			'\0' != fbbuf[MAXPATHLEN - 2] ||
			'\0' != ibuf[MAXPATHLEN - 2] ||
			'\0' != ibbuf[MAXPATHLEN - 2]) {
		fprintf(stderr, "%s: Path too long\n", progname);
		exit((int)MANDOCLEVEL_SYSERR);
	}

	/*
	 * For the keyword database, open a BTREE database that allows
	 * duplicates.  For the index database, use a standard RECNO
	 * database type.
	 */

	memset(&info, 0, sizeof(BTREEINFO));
	info.flags = R_DUP;
	db = dbopen(fbbuf, MANDOC_FLAGS, 0644, DB_BTREE, &info);

	if (NULL == db) {
		perror(fbbuf);
		exit((int)MANDOCLEVEL_SYSERR);
	}

	index = dbopen(ibbuf, MANDOC_FLAGS, 0644, DB_RECNO, NULL);

	if (NULL == db) {
		perror(ibbuf);
		(*db->close)(db);
		exit((int)MANDOCLEVEL_SYSERR);
	}

	/*
	 * Try parsing the manuals given on the command line.  If we
	 * totally fail, then just keep on going.  Take resulting trees
	 * and push them down into the database code.
	 * Use the auto-parser and don't report any errors.
	 */

	mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL);

	memset(&key, 0, sizeof(DBT));
	memset(&val, 0, sizeof(DBT));
	memset(&rkey, 0, sizeof(DBT));
	memset(&rval, 0, sizeof(DBT));

	val.size = sizeof(vbuf);
	val.data = vbuf;
	rkey.size = sizeof(recno_t);

	rec = 1;
	ksz = 0;

	while (NULL != (fn = *argv++)) {
		mparse_reset(mp);

		if (mparse_readfd(mp, -1, fn) >= MANDOCLEVEL_FATAL) {
			fprintf(stderr, "%s: Parse failure\n", fn);
			continue;
		}

		mparse_result(mp, &mdoc, NULL);
		if (NULL == mdoc)
			continue;

		rkey.data = &rec;
		rval.data = fn;
		rval.size = strlen(fn) + 1;

		if (-1 == (*index->put)(index, &rkey, &rval, 0)) {
			perror(ibbuf);
			break;
		}

		memset(val.data, 0, sizeof(uint32_t));
		memcpy(val.data + 4, &rec, sizeof(uint32_t));

		pmdoc(db, fbbuf, &key, &ksz, &val, fn, mdoc);
		rec++;
	}

	(*db->close)(db);
	(*index->close)(index);

	mparse_free(mp);

	free(key.data);

	/* Atomically replace the file with our temporary one. */

	if (-1 == rename(fbbuf, fbuf))
		perror(fbuf);
	if (-1 == rename(ibbuf, ibuf))
		perror(fbuf);

	return((int)MANDOCLEVEL_OK);
}