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); }
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); }
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); }
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); }
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); }
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); }
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); }