+ if (NULL == (f = fopen(file, "r"))) {
+ puts("<P>You specified an invalid manual file.</P>");
+ return;
+ }
+
+ puts("<DIV CLASS=\"catman\">\n"
+ "<PRE>");
+
+ while (NULL != (p = fgetln(f, &len))) {
+ bold = italic = 0;
+ for (i = 0; i < (int)len - 1; i++) {
+ /*
+ * This means that the catpage is out of state.
+ * Ignore it and keep going (although the
+ * catpage is bogus).
+ */
+
+ if ('\b' == p[i] || '\n' == p[i])
+ continue;
+
+ /*
+ * Print a regular character.
+ * Close out any bold/italic scopes.
+ * If we're in back-space mode, make sure we'll
+ * have something to enter when we backspace.
+ */
+
+ if ('\b' != p[i + 1]) {
+ if (italic)
+ printf("</I>");
+ if (bold)
+ printf("</B>");
+ italic = bold = 0;
+ html_putchar(p[i]);
+ continue;
+ } else if (i + 2 >= (int)len)
+ continue;
+
+ /* Italic mode. */
+
+ if ('_' == p[i]) {
+ if (bold)
+ printf("</B>");
+ if ( ! italic)
+ printf("<I>");
+ bold = 0;
+ italic = 1;
+ i += 2;
+ html_putchar(p[i]);
+ continue;
+ }
+
+ /*
+ * Handle funny behaviour troff-isms.
+ * These grok'd from the original man2html.c.
+ */
+
+ if (('+' == p[i] && 'o' == p[i + 2]) ||
+ ('o' == p[i] && '+' == p[i + 2]) ||
+ ('|' == p[i] && '=' == p[i + 2]) ||
+ ('=' == p[i] && '|' == p[i + 2]) ||
+ ('*' == p[i] && '=' == p[i + 2]) ||
+ ('=' == p[i] && '*' == p[i + 2]) ||
+ ('*' == p[i] && '|' == p[i + 2]) ||
+ ('|' == p[i] && '*' == p[i + 2])) {
+ if (italic)
+ printf("</I>");
+ if (bold)
+ printf("</B>");
+ italic = bold = 0;
+ putchar('*');
+ i += 2;
+ continue;
+ } else if (('|' == p[i] && '-' == p[i + 2]) ||
+ ('-' == p[i] && '|' == p[i + 1]) ||
+ ('+' == p[i] && '-' == p[i + 1]) ||
+ ('-' == p[i] && '+' == p[i + 1]) ||
+ ('+' == p[i] && '|' == p[i + 1]) ||
+ ('|' == p[i] && '+' == p[i + 1])) {
+ if (italic)
+ printf("</I>");
+ if (bold)
+ printf("</B>");
+ italic = bold = 0;
+ putchar('+');
+ i += 2;
+ continue;
+ }
+
+ /* Bold mode. */
+
+ if (italic)
+ printf("</I>");
+ if ( ! bold)
+ printf("<B>");
+ bold = 1;
+ italic = 0;
+ i += 2;
+ html_putchar(p[i]);
+ }
+
+ /*
+ * Clean up the last character.
+ * We can get to a newline; don't print that.
+ */
+
+ if (italic)
+ printf("</I>");
+ if (bold)
+ printf("</B>");
+
+ if (i == (int)len - 1 && '\n' != p[i])
+ html_putchar(p[i]);
+
+ putchar('\n');
+ }
+
+ puts("</PRE>\n"
+ "</DIV>");
+
+ fclose(f);
+}
+
+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))) {
+ puts("<P>You specified an invalid manual file.</P>");
+ return;
+ }
+
+ mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_FATAL, NULL,
+ 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;
+ }
+
+ snprintf(opts, sizeof(opts),
+ "fragment,man=%s?query=%%N&sec=%%S",
+ scriptname);
+
+ 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);
+ return;
+ }
+
+ vp = html_alloc(opts);
+
+ if (NULL != mdoc)
+ html_mdoc(vp, mdoc);
+ else
+ html_man(vp, man);