summaryrefslogtreecommitdiffstats
path: root/man2html
diff options
context:
space:
mode:
Diffstat (limited to 'man2html')
-rw-r--r--man2html/Makefile70
-rw-r--r--man2html/Makefile.in66
-rw-r--r--man2html/README91
-rw-r--r--man2html/TODO43
-rw-r--r--man2html/abbrev.c62
-rw-r--r--man2html/cgibase.c143
-rw-r--r--man2html/defs.h41
-rw-r--r--man2html/glimpse_filters3
-rw-r--r--man2html/hman96
-rw-r--r--man2html/hman.169
-rwxr-xr-xman2html/hman.sh96
-rw-r--r--man2html/locales/en/hman.169
-rw-r--r--man2html/locales/en/man2html.1151
-rw-r--r--man2html/locales/fr/man2html.1165
-rw-r--r--man2html/locales/it/hman.171
-rw-r--r--man2html/locales/it/man2html.1153
-rw-r--r--man2html/man2html.1151
-rw-r--r--man2html/man2html.c3241
-rw-r--r--man2html/scripts/cgi-aux/man/man.aux75
-rw-r--r--man2html/scripts/cgi-aux/man/mansearch.aux49
-rw-r--r--man2html/scripts/cgi-aux/man/mansearchhelp.aux295
-rwxr-xr-xman2html/scripts/cgi-bin/man/man2html109
-rwxr-xr-xman2html/scripts/cgi-bin/man/mansearch192
-rwxr-xr-xman2html/scripts/cgi-bin/man/mansearchhelp32
-rwxr-xr-xman2html/scripts/cgi-bin/man/mansec183
-rwxr-xr-xman2html/scripts/cgi-bin/man/manwhatis208
-rw-r--r--man2html/strdefs.c176
27 files changed, 6100 insertions, 0 deletions
diff --git a/man2html/Makefile b/man2html/Makefile
new file mode 100644
index 0000000..ed1b981
--- /dev/null
+++ b/man2html/Makefile
@@ -0,0 +1,70 @@
+#
+# Generated automatically from Makefile.in by the
+# configure script.
+#
+CC = gcc -O
+CFLAGS += -Wall -Wstrict-prototypes -Wmissing-prototypes
+OBJECTS = man2html.o cgibase.o abbrev.o strdefs.o
+EXEEXT =
+bindir = $(DESTDIR)$(PREFIX)/usr/bin
+mandir = $(DESTDIR)$(PREFIX)/usr/share/man
+vardir = $(DESTDIR)$(PREFIX)/var
+httpdir = $(DESTDIR)$(PREFIX)/home/httpd
+cgiowner = nobody
+cgigroup = nobody
+
+all: man2html$(EXEEXT) hman
+
+man2html$(EXEEXT): $(OBJECTS)
+ $(CC) $(LDFLAGS) -o man2html$(EXEEXT) $(OBJECTS)
+
+# man2html: ../src/version.h
+
+# This installs the man2html utility
+install: man2html$(EXEEXT)
+ mkdir -p $(bindir)
+ install -m 755 man2html$(EXEEXT) $(bindir)
+ mkdir -p $(mandir)/man1
+ install -m 644 man2html.1 $(mandir)/man1/man2html.1
+
+install-scripts: install-man-scripts install-glimpse-stuff install-hman
+
+# These are the scripts that allow pointing a browser at
+# http://localhost/cgi-bin/man/man2html
+# to work.
+install-man-scripts:
+ mkdir -p $(httpdir)/cgi-bin/man
+ mkdir -p $(httpdir)/cgi-aux/man
+ install -m 755 scripts/cgi-bin/man/* $(httpdir)/cgi-bin/man
+ install -m 644 scripts/cgi-aux/man/* $(httpdir)/cgi-aux/man
+ install -d -o $(cgiowner) -g $(cgigroup) -m 775 $(vardir)/man2html
+# (aux was renamed to cgi-aux since aux causes problems under DOS)
+
+# If you have installed glimpse, and have compressed man pages,
+# then perhaps you also want these filters.
+install-glimpse-stuff:
+ install -m 644 glimpse_filters $(vardir)/man2html/.glimpse_filters
+
+# In order not to have to type a long command like
+# netscape http://localhost/cgi-bin/man/man2html?section+topic
+# or
+# lynx lynxcgi:/home/httpd/cgi-bin/man/man2html?section+topic
+# it is convenient to have some shell script as a wrapper.
+# The script hman can be aliased to man. It uses an environment
+# variable MANHTMLPAGER to find out which browser you use, and
+# you can set MANHTMLHOST if the pages are not on localhost.
+hman: hman.sh
+ rm -f hman
+ sed -e 's,%version%,man-1.6g,' hman.sh > hman
+
+install-hman: hman
+ install -m 555 hman $(bindir)/hman
+ install -m 644 hman.1 $(mandir)/man1/hman.1
+
+clean:
+ rm -f core hman man2html$(EXEEXT) $(OBJECTS) *~
+
+spotless: clean
+ rm -f Makefile
+
+$(OBJECTS): defs.h
diff --git a/man2html/Makefile.in b/man2html/Makefile.in
new file mode 100644
index 0000000..b41eaba
--- /dev/null
+++ b/man2html/Makefile.in
@@ -0,0 +1,66 @@
+CC = @CC@
+CFLAGS += -Wall -Wstrict-prototypes -Wmissing-prototypes
+OBJECTS = man2html.o cgibase.o abbrev.o strdefs.o
+EXEEXT = @EXEEXT@
+bindir = $(DESTDIR)$(PREFIX)/usr/bin
+mandir = $(DESTDIR)$(PREFIX)@mandir@
+vardir = $(DESTDIR)$(PREFIX)/var
+httpdir = $(DESTDIR)$(PREFIX)/home/httpd
+cgiowner = nobody
+cgigroup = nobody
+
+all: man2html$(EXEEXT) hman
+
+man2html$(EXEEXT): $(OBJECTS)
+ $(CC) $(LDFLAGS) -o man2html$(EXEEXT) $(OBJECTS)
+
+# man2html: ../src/version.h
+
+# This installs the man2html utility
+install: man2html$(EXEEXT)
+ mkdir -p $(bindir)
+ install -m 755 man2html$(EXEEXT) $(bindir)
+ mkdir -p $(mandir)/man1
+ install -m 644 man2html.1 $(mandir)/man1/man2html.@man1ext@
+
+install-scripts: install-man-scripts install-glimpse-stuff install-hman
+
+# These are the scripts that allow pointing a browser at
+# http://localhost/cgi-bin/man/man2html
+# to work.
+install-man-scripts:
+ mkdir -p $(httpdir)/cgi-bin/man
+ mkdir -p $(httpdir)/cgi-aux/man
+ install -m 755 scripts/cgi-bin/man/* $(httpdir)/cgi-bin/man
+ install -m 644 scripts/cgi-aux/man/* $(httpdir)/cgi-aux/man
+ install -d -o $(cgiowner) -g $(cgigroup) -m 775 $(vardir)/man2html
+# (aux was renamed to cgi-aux since aux causes problems under DOS)
+
+# If you have installed glimpse, and have compressed man pages,
+# then perhaps you also want these filters.
+install-glimpse-stuff:
+ install -m 644 glimpse_filters $(vardir)/man2html/.glimpse_filters
+
+# In order not to have to type a long command like
+# netscape http://localhost/cgi-bin/man/man2html?section+topic
+# or
+# lynx lynxcgi:/home/httpd/cgi-bin/man/man2html?section+topic
+# it is convenient to have some shell script as a wrapper.
+# The script hman can be aliased to man. It uses an environment
+# variable MANHTMLPAGER to find out which browser you use, and
+# you can set MANHTMLHOST if the pages are not on localhost.
+hman: hman.sh
+ rm -f hman
+ sed -e 's,%version%,@version@,' hman.sh > hman
+
+install-hman: hman
+ install -m 555 hman $(bindir)/hman
+ install -m 644 hman.1 $(mandir)/man1/hman.@man1ext@
+
+clean:
+ rm -f core hman man2html$(EXEEXT) $(OBJECTS) *~
+
+spotless: clean
+ rm -f Makefile
+
+$(OBJECTS): defs.h
diff --git a/man2html/README b/man2html/README
new file mode 100644
index 0000000..6dabd52
--- /dev/null
+++ b/man2html/README
@@ -0,0 +1,91 @@
+This directory contains the following.
+
+1. man2html
+
+This is a pure manroff -> html converter.
+No manpath search etc.
+
+Call: man2html [-l | -H host.domain:port] [filename]
+
+The contents of FILENAME (or STDIN, in case FILENAME is "-" or absent)
+are converted from man-style nroff to html, and printed on STDOUT.
+
+With "-l" URLs of the form "lynxcgi:/home/httpd/cgi-bin/..." are generated.
+With "-H host" we make URLs of the form "http://host/cgi-bin/...".
+The default is "http://localhost/cgi-bin/...".
+
+2. A collection of scripts
+
+This part is not installed by "make install" of the global Makefile.
+There are security considerations: it is very unlikely that these
+scripts (still in alpha) are secure, so for the time being they
+should only be used where security is not a major concern.
+
+If you are not afraid, or are not running a httpd, do
+"make install-scripts" in this directory.
+This does three things: install man stuff, install glimpse stuff,
+and install user interface stuff.
+
+2A. man stuff
+
+This first part (that can be done separately with "make install-man-scripts")
+puts various scripts under /home/httpd/cgi-bin and /home/httpd/cgi-aux
+in a subdirectory man.
+It will create a directory /var/man2html to hold the indices.
+(This directory should be writable by the cgi scripts;
+probably that means that the owner should be nobody.
+Choose a group and add all non-httpd users that should be
+able to write this directory to that group.)
+
+Structure of the collection of scripts:
+ man2html is the main script.
+ It uses man.aux when called without arguments.
+ It uses manwhatis when asked for an index of manpages+descriptions.
+ It uses mansec when asked for a compact index of manpages.
+ It uses mansearch when asked for a glimpse search.
+ In its turn mansearch uses mansearch.aux when called
+ without arguments. It uses mansearchhelp (which uses
+ mansearchhelp.aux) when asked for help.
+
+2B. glimpse stuff
+The second part (that can be done separately with
+"make install-glimpse-stuff") installs .glimpse_filters
+in /var/man2html, in order to tell glimpse what decompressors to use.
+
+2C. user interface stuff
+The third part (that can be done separately with "make install-hman")
+installs a user interface to these scripts in /usr/bin/hman.
+Now people can say
+ alias man=/usr/bin/hman
+and have a man that uses a html browser.
+The browser is chosen via environment variables - look at the script.
+
+3. Glimpse.
+
+For the glimpse part, I quote Michael Hamilton:
+----------------------------------------------------------------------
+To use the Glimpse full text searching, you will need to install
+glimpse in /usr/bin. Redhat rpm users can get glimpse from
+
+ ftp://ftp.redhat.com/pub/contrib/i386/glimpse-4.0-6.i386.rpm
+
+The glimpse home ftp site is cs.arizona.edu. N.B. glimpse is not
+freely redistributable for commercial use, I'd be very interested in a
+more liberal alternative. Having installed glimpse, you will need to
+build a glimpse index in /var/man2html. This doesn't take too long -
+about 3 minutes on my 486DX2/66 16MB machine. As root do:
+
+ /usr/bin/glimpseindex -z -H /var/man2html /usr/man/man* /usr/X11R6/man/man* \
+ /usr/local/man/man* /opt/man/man*
+ chmod ugo+r /var/man2html/.glimpse*
+
+The -z option causes glimpse to apply any filters (for decompression etc)
+specified in /var/man2html/.glimpse_filters.
+
+This could be set up as a cron job in /etc/crontab, e.g. (the following
+must be all on one line):
+
+ 21 04 * * 1 root /usr/bin/glimpseindex -z -H /var/man2html /usr/man/man*
+ /usr/X11R6/man/man* /usr/local/man/man* /opt/man/man* ;
+ chmod +r /var/man2html/.glimpse*
+--------------------------------------------------------------------------
diff --git a/man2html/TODO b/man2html/TODO
new file mode 100644
index 0000000..b0101ad
--- /dev/null
+++ b/man2html/TODO
@@ -0,0 +1,43 @@
+There are still many problems with man2html.
+Partly these are caused by the imprecise definition
+of the man file format. (And the many buggy man pages.)
+Partly by the incomplete implementation of the man/doc macro packages.
+Partly by the imperfect emulation of troff.
+Partly by the variation between various browsers in the
+accepted html.
+Partly just because man2html is buggy.
+
+Of course in reality a man2html converter must contain
+large parts of the troff source, so that it can be fed
+with the defining macro packages and always do the right thing.
+
+On a RedHat 5.0 system:
+- /usr/man/mann/DirDlg.n is not formatted correctly.
+ (It does not start with .TH)
+- <i>bug_readline</i>@<i>prep.ai.mit.edu</i> does not generate
+ a mailto: link. It should generate
+ <a href="mailto:bug_readline@prep.ai.mit.edu>
+ <i>bug_readline</i>@<i>prep.ai.mit.edu</i>
+ </a>
+ but this requires parsing of the surrounding html markup.
+ Easy, but not done yet.
+- Some manpages generate bad whatis information
+ [where the name in the whatis line is not the filename of the man page].
+ (E.g., tc589_cs.4, auto.master.5, pcmcia.5, proc.5 and autofs.8
+ generate whatis lines
+ 3c589_cs (4) - 3Com 3c589 Etherlink III device driver
+ /etc/auto.master (5) - Master Map for automounter
+ /etc/init.d/rc.d/autofs (8) - Control Script for automounter
+ /etc/pcmcia/config (5) - PCMCIA card configuration database
+ /proc (5) - process information pseudo-filesystem
+ )
+ As a consequence, the corresponding manwhatis links are bad.
+- Some manpages have bad .so information.
+ (E.g., TIFFScanlineSize.3t contains .so TIFFsize.3t
+ instead of .so man3/TIFFsize.3t .)
+ This also confuses whatis, and generates bad links.
+ (But right now these happen to work.)
+
+Of course, patches are welcome!
+
+
diff --git a/man2html/abbrev.c b/man2html/abbrev.c
new file mode 100644
index 0000000..fa7df06
--- /dev/null
+++ b/man2html/abbrev.c
@@ -0,0 +1,62 @@
+#include <string.h>
+#include "defs.h"
+/*
+ * lookup_abbrev() is used for TX macros - is that
+ * something SUN-specific?
+ */
+
+char *abbrev_list[] = {
+ "GSBG", "Getting Started ",
+ "SUBG", "Customizing SunOS",
+ "SHBG", "Basic Troubleshooting",
+ "SVBG", "SunView User's Guide",
+ "MMBG", "Mail and Messages",
+ "DMBG", "Doing More with SunOS",
+ "UNBG", "Using the Network",
+ "GDBG", "Games, Demos &amp; Other Pursuits",
+ "CHANGE", "SunOS 4.1 Release Manual",
+ "INSTALL", "Installing SunOS 4.1",
+ "ADMIN", "System and Network Administration",
+ "SECUR", "Security Features Guide",
+ "PROM", "PROM User's Manual",
+ "DIAG", "Sun System Diagnostics",
+ "SUNDIAG", "Sundiag User's Guide",
+ "MANPAGES", "SunOS Reference Manual",
+ "REFMAN", "SunOS Reference Manual",
+ "SSI", "Sun System Introduction",
+ "SSO", "System Services Overview",
+ "TEXT", "Editing Text Files",
+ "DOCS", "Formatting Documents",
+ "TROFF", "Using <B>nroff</B> and <B>troff</B>",
+ "INDEX", "Global Index",
+ "CPG", "C Programmer's Guide",
+ "CREF", "C Reference Manual",
+ "ASSY", "Assembly Language Reference",
+ "PUL", "Programming Utilities and Libraries",
+ "DEBUG", "Debugging Tools",
+ "NETP", "Network Programming",
+ "DRIVER", "Writing Device Drivers",
+ "STREAMS", "STREAMS Programming",
+ "SBDK", "SBus Developer's Kit",
+ "WDDS", "Writing Device Drivers for the SBus",
+ "FPOINT", "Floating-Point Programmer's Guide",
+ "SVPG", "SunView 1 Programmer's Guide",
+ "SVSPG", "SunView 1 System Programmer's Guide",
+ "PIXRCT", "Pixrect Reference Manual",
+ "CGI", "SunCGI Reference Manual",
+ "CORE", "SunCore Reference Manual",
+ "4ASSY", "Sun-4 Assembly Language Reference",
+ "SARCH", "<FONT SIZE=\"-1\">SPARC</FONT> Architecture Manual",
+ "KR", "The C Programming Language",
+ 0, 0 };
+
+char *lookup_abbrev (char *s)
+{
+ int i=0;
+
+ if (!s)
+ return "";
+ while (abbrev_list[i] && strcmp(s, abbrev_list[i]))
+ i = i+2;
+ return abbrev_list[i] ? abbrev_list[i+1] : s;
+}
diff --git a/man2html/cgibase.c b/man2html/cgibase.c
new file mode 100644
index 0000000..de31cdf
--- /dev/null
+++ b/man2html/cgibase.c
@@ -0,0 +1,143 @@
+/*
+ * Here are the routines of man2html that output a HREF string.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <ctype.h> /* tolower() */
+#include <string.h> /* strlen() */
+#include "defs.h"
+
+/*
+ * The default is to use cgibase. With relative html style
+ * we generate URLs of the form "../manX/page.html".
+ */
+static int relat_html_style = 0;
+
+/*
+ * Either the user is non-local (or local, but using httpd),
+ * in which case we use http:/cgi-bin, or the user is local
+ * and uses lynx, and we use lynxcgi:/home/httpd/cgi-bin.
+ */
+
+static char *man2htmlpath = "/cgi-bin/man/man2html"; /* default */
+static char *cgibase_format = "http://%s"; /* host.domain:port */
+static char *cgibase_ll_format = "lynxcgi:%s"; /* directory */
+static char *cgibase = "http://localhost"; /* default */
+
+/*
+ * Separator between URL and argument string.
+ *
+ * With http:<path to script>/a/b?c+d+e the script is called
+ * with PATH_INFO=/a/b and QUERY_STRING=c+d+e and args $1=c, $2=d, $3=e.
+ * With lynxcgi:<full path to script>?c+d+e no PATH_INFO is possible.
+ */
+static char sep = '?'; /* or '/' */
+
+void
+set_separator(char s) {
+ sep = s;
+}
+
+void
+set_lynxcgibase(char *s) {
+ int n = strlen(cgibase_ll_format) + strlen(s);
+ char *t = (char *) xmalloc(n);
+
+ sprintf(t, cgibase_ll_format, s);
+ cgibase = t;
+}
+
+void
+set_cgibase(char *s) {
+ int n = strlen(cgibase_format) + strlen(s);
+ char *t = (char *) xmalloc(n);
+
+ sprintf(t, cgibase_format, s);
+ cgibase = t;
+}
+
+void
+set_man2htmlpath(char *s) {
+ man2htmlpath = xstrdup(s);
+}
+
+void
+set_relative_html_links(void) {
+ relat_html_style = 1;
+}
+
+/* What shall we say in case of relat_html_style? */
+static char *signature = "<HR>\n"
+"This document was created by\n"
+"<A HREF=\"%s%s\">man2html</A>,\n"
+"using the manual pages.<BR>\n"
+"%s\n";
+
+#define TIMEFORMAT "%T GMT, %B %d, %Y"
+#define TIMEBUFSZ 500
+
+void print_sig()
+{
+ char timebuf[TIMEBUFSZ];
+ struct tm *timetm;
+ time_t clock;
+
+ timebuf[0] = 0;
+#ifdef TIMEFORMAT
+ sprintf(timebuf, "Time: ");
+ clock=time(NULL);
+ timetm=gmtime(&clock);
+ strftime(timebuf+6, TIMEBUFSZ-6, TIMEFORMAT, timetm);
+ timebuf[TIMEBUFSZ-1] = 0;
+#endif
+ printf(signature, cgibase, man2htmlpath, timebuf);
+}
+
+void
+include_file_html(char *g) {
+ printf("<A HREF=\"file:/usr/include/%s\">%s</A>&gt;", g,g);
+}
+
+void
+man_page_html(char *sec, char *h) {
+ if (relat_html_style) {
+ if (!h)
+ printf("<A HREF=\"../index.html\">"
+ "Return to Main Contents</A>");
+ else
+ printf("<A HREF=\"../man%s/%s.%s.html\">%s</A>",
+ sec, h, sec, h);
+ } else {
+ if (!h)
+ printf("<A HREF=\"%s%s\">Return to Main Contents</A>",
+ cgibase, man2htmlpath);
+ else if (!sec)
+ printf("<A HREF=\"%s%s%c%s\">%s</A>",
+ cgibase, man2htmlpath, sep, h, h);
+ else
+ printf("<A HREF=\"%s%s%c%s+%s\">%s</A>",
+ cgibase, man2htmlpath, sep, sec, h, h);
+ }
+}
+
+void
+ftp_html(char *f) {
+ printf("<A HREF=\"ftp://%s\">%s</A>", f, f);
+}
+
+void
+www_html(char *f) {
+ printf("<A HREF=\"http://%s\">%s</A>", f, f);
+}
+
+void
+mailto_html(char *g) {
+ printf("<A HREF=\"mailto:%s\">%s</A>", g, g);
+}
+
+void
+url_html(char *g) {
+ printf("<A HREF=\"%s\">%s</A>", g, g);
+}
diff --git a/man2html/defs.h b/man2html/defs.h
new file mode 100644
index 0000000..f3e75ef
--- /dev/null
+++ b/man2html/defs.h
@@ -0,0 +1,41 @@
+extern int nroff;
+extern int local_lynx;
+
+typedef struct STRDEF STRDEF;
+struct STRDEF {
+ int nr,slen;
+ char *st;
+ STRDEF *next;
+};
+
+typedef struct INTDEF INTDEF;
+struct INTDEF {
+ int nr;
+ int val;
+ int incr;
+ INTDEF *next;
+};
+
+extern STRDEF *chardef, *strdef, *defdef;
+extern INTDEF *intdef;
+
+#define V(A,B) ((A)*256+(B))
+
+#include <sys/types.h>
+extern void stdinit(void);
+extern void print_sig(void);
+extern char *lookup_abbrev(char *);
+extern void include_file_html(char *);
+extern void man_page_html(char*, char *);
+extern void ftp_html(char *);
+extern void www_html(char *);
+extern void mailto_html(char *);
+extern void url_html(char *);
+extern void set_separator(char);
+extern void set_lynxcgibase(char *);
+extern void set_cgibase(char *);
+extern void set_man2htmlpath(char *);
+extern void set_relative_html_links(void);
+extern void *xmalloc(size_t size);
+extern void *xrealloc(void *ptr, size_t size);
+extern char *xstrdup(const char *s);
diff --git a/man2html/glimpse_filters b/man2html/glimpse_filters
new file mode 100644
index 0000000..1814e5d
--- /dev/null
+++ b/man2html/glimpse_filters
@@ -0,0 +1,3 @@
+*.gz gzip -d -c
+*.Z gzip -d -c
+
diff --git a/man2html/hman b/man2html/hman
new file mode 100644
index 0000000..9426c0d
--- /dev/null
+++ b/man2html/hman
@@ -0,0 +1,96 @@
+#!/bin/sh
+#
+# hman - interface to the man2html scripts
+#
+# Michael Hamilton <michael@actrix.gen.nz>, Apr 1996
+# Andries Brouwer <aeb@cwi.nl>, Jan 1998.
+#
+# Usage examples:
+# hman - get start page
+# hman man2html - get man page for man2html
+# hman 7 locale - get section 7 man page for locale
+# hman 1 - section 1 index of names only
+# hman 3 index - section 3 index names+descriptions
+# hman -k editor - search all man pages for some string
+# hman -P arena ./twm.man - specify browser; specify man page
+#
+# hman from man-1.6g
+#
+
+if [ x"$1" = x"-v" -o x"$1" = x"-V" ]; then
+ echo "`basename $0` from man-1.6g"
+ exit 0
+fi
+
+# The user has to set MANHTMLPAGER (or he will get httpd-free lynx).
+# Pick your favorite browser: lynx, xmosaic, netscape, arena, amaya, grail, ...
+BROWSER=${MANHTMLPAGER-lynxcgi}
+#
+# If the man pages are on a remote host, specify it in MANHTMLHOST.
+HOST=${MANHTMLHOST-localhost}
+
+# Perhaps the browser was specified on the command line?
+if [ $# -gt 1 -a "$1" = "-P" ]; then
+ BROWSER="$2"
+ shift; shift
+fi
+
+# Perhaps the host was specified on the command line?
+if [ $# -gt 1 -a "$1" = "-H" ]; then
+ HOST="$2"
+ shift; shift
+fi
+
+# Interface to a live (already running) netscape browser.
+function nsfunc () {
+ if ( /bin/ps xc | grep -q 'netscape$' ) ; then
+ if [ -x netscape-remote ] ; then
+ exec netscape-remote -remote "openURL($1,new_window)"
+ else
+ exec netscape -remote "openURL($1,new_window)"
+ fi
+ else
+ netscape $1 &
+ fi
+}
+
+case $BROWSER in
+ lynxcgi)
+ BROWSER=lynx
+ CG="lynxcgi:/home/httpd/cgi-bin/man"
+ ;;
+ netscape)
+ BROWSER=nsfunc
+ CG="http://$HOST/cgi-bin/man"
+ ;;
+ *)
+ CG="http://$HOST/cgi-bin/man"
+ ;;
+esac
+
+ case $# in
+ 0) $BROWSER $CG/man2html ;;
+ 1) case "$1" in
+ 1|2|3|4|5|6|7|8|l|n)
+ $BROWSER "$CG/mansec?$CG+$1" ;;
+ /*)
+ $BROWSER "$CG/man2html?$1" ;;
+ */*)
+ $BROWSER "$CG/man2html?$PWD/$1" ;;
+ *)
+ $BROWSER "$CG/man2html?$1" ;;
+ esac ;;
+ 2) case "$1" in
+ -k)
+ $BROWSER "$CG/mansearch?$2" ;;
+ *)
+ if [ "$2" = index ]; then
+ $BROWSER "$CG/manwhatis?$CG+$1"
+ else
+ $BROWSER "$CG/man2html?$1+$2"
+ fi ;;
+ esac ;;
+ *) echo "bad number of args" ;;
+ esac
+
+exit 0
diff --git a/man2html/hman.1 b/man2html/hman.1
new file mode 100644
index 0000000..4676f55
--- /dev/null
+++ b/man2html/hman.1
@@ -0,0 +1,69 @@
+.\" Copyright (c) 1998 Andries Brouwer
+.\"
+.\" You may distribute under the terms of the GNU General Public
+.\" License as specified in the README file that comes with the man 1.0
+.\" distribution.
+.TH hman 1 "19 January 1998"
+.LO 1
+.SH NAME
+hman \- browse the on-line manual pages
+.SH SYNOPSIS
+.B hman
+[ -P \fIbrowser\fP ] [ -H \fIhost\fP ] [ \fIsection\fP ] \fIname\fP
+.br
+.B hman
+[ -P \fIbrowser\fP ] [ -H \fIhost\fP ] [ \fIsection\fP ] [ index ]
+.SH DESCRIPTION
+The
+.B hman
+script is an interface to man2html(1) that allows you to enter man page
+requests at the command line and view the output in your favourite
+browser.
+The behaviour reminds of that of
+.BR man (1)
+so that many people will be able to alias
+.B hman
+to
+.BR man .
+If the browser used is netscape, and an incarnation of netscape
+is running already,
+.B hman
+will pass the request to the existing browser.
+
+.SH OPTIONS
+.TP
+.B \-\^P " browser"
+Specify which browser (like lynx, xmosaic, arena, chimera,
+netscape, amaya, ...) to use.
+This option overrides the
+.B MANHTMLPAGER
+environment variable.
+The default is the non-httpd version of
+.BR lynx .
+.TP
+.B \-\^H " host"
+Specify from what host to get the man pages.
+This option overrides the
+.B MANHTMLHOST
+environment variable.
+The default is
+.BR localhost .
+
+.SH ENVIRONMENT
+.TP
+MANHTMLPAGER
+The default browser to use is selected using this environment variable.
+.TP
+MANHTMLHOST
+The default host to use is selected using this environment variable.
+
+.SH "SEE ALSO"
+.BR man (1),
+.BR man2html (1),
+.BR arena (1),
+.BR lynx (1),
+.BR netscape (1),
+.BR xmosaic (1),
+.BR glimpse (1)
+
+http://www.mcom.com/newsref/std/x-remote.html
diff --git a/man2html/hman.sh b/man2html/hman.sh
new file mode 100755
index 0000000..c484acc
--- /dev/null
+++ b/man2html/hman.sh
@@ -0,0 +1,96 @@
+#!/bin/sh
+#
+# hman - interface to the man2html scripts
+#
+# Michael Hamilton <michael@actrix.gen.nz>, Apr 1996
+# Andries Brouwer <aeb@cwi.nl>, Jan 1998.
+#
+# Usage examples:
+# hman - get start page
+# hman man2html - get man page for man2html
+# hman 7 locale - get section 7 man page for locale
+# hman 1 - section 1 index of names only
+# hman 3 index - section 3 index names+descriptions
+# hman -k editor - search all man pages for some string
+# hman -P arena ./twm.man - specify browser; specify man page
+#
+# hman from %version%
+#
+
+if [ x"$1" = x"-v" -o x"$1" = x"-V" ]; then
+ echo "`basename $0` from %version%"
+ exit 0
+fi
+
+# The user has to set MANHTMLPAGER (or he will get httpd-free lynx).
+# Pick your favorite browser: lynx, xmosaic, netscape, arena, amaya, grail, ...
+BROWSER=${MANHTMLPAGER-lynxcgi}
+#
+# If the man pages are on a remote host, specify it in MANHTMLHOST.
+HOST=${MANHTMLHOST-localhost}
+
+# Perhaps the browser was specified on the command line?
+if [ $# -gt 1 -a "$1" = "-P" ]; then
+ BROWSER="$2"
+ shift; shift
+fi
+
+# Perhaps the host was specified on the command line?
+if [ $# -gt 1 -a "$1" = "-H" ]; then
+ HOST="$2"
+ shift; shift
+fi
+
+# Interface to a live (already running) netscape browser.
+function nsfunc () {
+ if ( /bin/ps xc | grep -q 'netscape$' ) ; then
+ if [ -x netscape-remote ] ; then
+ exec netscape-remote -remote "openURL($1,new_window)"
+ else
+ exec netscape -remote "openURL($1,new_window)"
+ fi
+ else
+ netscape $1 &
+ fi
+}
+
+case $BROWSER in
+ lynxcgi)
+ BROWSER=lynx
+ CG="lynxcgi:/home/httpd/cgi-bin/man"
+ ;;
+ netscape)
+ BROWSER=nsfunc
+ CG="http://$HOST/cgi-bin/man"
+ ;;
+ *)
+ CG="http://$HOST/cgi-bin/man"
+ ;;
+esac
+
+ case $# in
+ 0) $BROWSER $CG/man2html ;;
+ 1) case "$1" in
+ 1|2|3|4|5|6|7|8|l|n)
+ $BROWSER "$CG/mansec?$CG+$1" ;;
+ /*)
+ $BROWSER "$CG/man2html?$1" ;;
+ */*)
+ $BROWSER "$CG/man2html?$PWD/$1" ;;
+ *)
+ $BROWSER "$CG/man2html?$1" ;;
+ esac ;;
+ 2) case "$1" in
+ -k)
+ $BROWSER "$CG/mansearch?$2" ;;
+ *)
+ if [ "$2" = index ]; then
+ $BROWSER "$CG/manwhatis?$CG+$1"
+ else
+ $BROWSER "$CG/man2html?$1+$2"
+ fi ;;
+ esac ;;
+ *) echo "bad number of args" ;;
+ esac
+
+exit 0
diff --git a/man2html/locales/en/hman.1 b/man2html/locales/en/hman.1
new file mode 100644
index 0000000..4676f55
--- /dev/null
+++ b/man2html/locales/en/hman.1
@@ -0,0 +1,69 @@
+.\" Copyright (c) 1998 Andries Brouwer
+.\"
+.\" You may distribute under the terms of the GNU General Public
+.\" License as specified in the README file that comes with the man 1.0
+.\" distribution.
+.TH hman 1 "19 January 1998"
+.LO 1
+.SH NAME
+hman \- browse the on-line manual pages
+.SH SYNOPSIS
+.B hman
+[ -P \fIbrowser\fP ] [ -H \fIhost\fP ] [ \fIsection\fP ] \fIname\fP
+.br
+.B hman
+[ -P \fIbrowser\fP ] [ -H \fIhost\fP ] [ \fIsection\fP ] [ index ]
+.SH DESCRIPTION
+The
+.B hman
+script is an interface to man2html(1) that allows you to enter man page
+requests at the command line and view the output in your favourite
+browser.
+The behaviour reminds of that of
+.BR man (1)
+so that many people will be able to alias
+.B hman
+to
+.BR man .
+If the browser used is netscape, and an incarnation of netscape
+is running already,
+.B hman
+will pass the request to the existing browser.
+
+.SH OPTIONS
+.TP
+.B \-\^P " browser"
+Specify which browser (like lynx, xmosaic, arena, chimera,
+netscape, amaya, ...) to use.
+This option overrides the
+.B MANHTMLPAGER
+environment variable.
+The default is the non-httpd version of
+.BR lynx .
+.TP
+.B \-\^H " host"
+Specify from what host to get the man pages.
+This option overrides the
+.B MANHTMLHOST
+environment variable.
+The default is
+.BR localhost .
+
+.SH ENVIRONMENT
+.TP
+MANHTMLPAGER
+The default browser to use is selected using this environment variable.
+.TP
+MANHTMLHOST
+The default host to use is selected using this environment variable.
+
+.SH "SEE ALSO"
+.BR man (1),
+.BR man2html (1),
+.BR arena (1),
+.BR lynx (1),
+.BR netscape (1),
+.BR xmosaic (1),
+.BR glimpse (1)
+
+http://www.mcom.com/newsref/std/x-remote.html
diff --git a/man2html/locales/en/man2html.1 b/man2html/locales/en/man2html.1
new file mode 100644
index 0000000..c1c25b3
--- /dev/null
+++ b/man2html/locales/en/man2html.1
@@ -0,0 +1,151 @@
+'\" t
+.\" Man page for man2html
+.\" aeb, 980101
+.\"
+.TH man2html 1 "1 January 1998"
+.LO 1
+.SH NAME
+man2html \- format a manual page in html
+.SH SYNOPSIS
+man2html [options] [file]
+.SH DESCRIPTION
+.B man2html
+converts a manual page as found in
+.I file
+(or stdin, in case no file argument, or the argument "-", is given)
+from man-style nroff into html, and prints the result on stdout.
+It does support tbl but does not know about eqn.
+The exit status is 0. If something goes wrong,
+an error page is printed on stdout.
+
+This can be used as a stand-alone utility, but is mainly intended
+as an auxiliary, to enable users to browse their man pages using
+a html browser like
+.BR lynx (1),
+.BR xmosaic (1)
+or
+.BR netscape (1).
+./" (See
+./" .BR man (1)
+./" for info on how to browse man pages via
+./" .BR man2html .
+./" Usually it would suffice to put "MANHTMLPAGER=/usr/bin/lynx"
+./" in the environment.)
+
+The main part of
+.B man2html
+is the troff-to-html engine written by Richard Verhoeven (rcb5@win.tue.nl).
+It adds hyperlinks for the following constructs:
+.LP
+.TS
+l l.
+foo(3x) "http://localhost/cgi-bin/man/man2html?3x+foo"
+method://string "method://string"
+www.host.name "http://www.host.name"
+ftp.host.name "ftp://ftp.host.name"
+name@host "mailto:name@host"
+<string.h> "file:/usr/include/string.h"
+.TE
+.LP
+(The first of these can be tuned by options - see below.)
+No lookup is done - the links generated need not exist.
+Also an index with internal hyperlinks to the various sections
+is generated, so that it is easier to find one's way
+in large man pages like
+.BR bash (1).
+
+.SH OPTIONS
+When reading from stdin, it is not always clear how to
+do .so expansion. The \-D option allows a script to define
+the working directory.
+.LP
+.TP
+.B \-\^D pathname
+Strip the last two parts from the pathname, and do a
+\fIchdir\fP(\fIdir\fP) before starting the conversion.
+.LP
+The \-E option allows the easy generation of error messages
+from a cgi script.
+.LP
+.TP
+.B \-\^E string
+Output an error page containing the given error message.
+.LP
+The general form of a hyperlink generated for a man page reference is
+.IP
+<method:cgipath><man2htmlpath><separator><manpage>
+.LP
+with a default as shown above. The parts of this hyperlink
+are set using the various options.
+.TP
+.B \-\^h
+Set method:cgipath to http://localhost. This is the default.
+.TP
+.BI \-\^H " host[.domain][:port]"
+Set method:cgipath to
+.RI http:// host.domain:port .
+.TP
+.B \-\^l
+Set method:cgipath to
+.RI lynxcgi: /home/httpd .
+.TP
+.BI \-\^L " dir"
+Set method:cgipath to
+.RI lynxcgi: dir .
+.TP
+.BI \-\^M " man2htmlpath"
+Set the man2htmlpath to use. The default is
+.IR /cgi-bin/man/man2html .
+.TP
+.B \-\^p
+Set separator to '/'.
+.TP
+.B \-\^q
+Set separator to '?'. This is the default.
+.TP
+.B \-\^r
+Use relative html paths, instead of cgi-bin paths.
+.LP
+On a machine without running
+.BR httpd ,
+one can use
+.B lynx
+to browse the man pages, using the lynxcgi method.
+When some http daemon is running, lynx, or any other browser,
+can be used to browse the man pages, using the http method.
+The option \-l (for `lynxcgi') selects the former behaviour.
+With it, the default cgipath is \fI/home/httpd\fP.
+
+In general, a cgi script can be called by
+.IP
+<path_to_script>/<more_path>?<query>
+.LP
+and the environment variables PATH_INFO and QUERY_STRING
+will be set to <more_path> and <query>, respectively.
+Since lynxcgi does not handle the PATH_INFO part, we generate
+hyperlinks with `?' as a separator by default.
+The option \-p (for `path') selects '/' as a separator, while
+the option \-q (for `query') selects '?' as a separator.
+
+The option \-H \fIhost\fP will specify the host to use
+(instead of \fIlocalhost\fP). A cgi script could use
+.IP
+man2html -H $SERVER_NAME
+.LP
+if the variable SERVER_NAME is set. This would allow your machine
+to act as a server and export man pages.
+
+.SH BUGS
+There are many heuristics. The output will not always be perfect.
+The lynxcgi method will not work if lynx was compiled without
+selecting support for it. There may be problems with security.
+
+.SH AUTHOR
+Richard Verhoeven was the original author of
+.BR "man2html" .
+Michael Hamilton and Andries Brouwer subsequently improved on it.
+Federico Lucifredi <flucifredi@acm.org> is the current maintainer.
+
+.SH "SEE ALSO"
+.BR lynx (1),
+.BR man (1)
diff --git a/man2html/locales/fr/man2html.1 b/man2html/locales/fr/man2html.1
new file mode 100644
index 0000000..1e99cd8
--- /dev/null
+++ b/man2html/locales/fr/man2html.1
@@ -0,0 +1,165 @@
+'\" t
+.\" Man page for man2html
+.\" aeb, 980101
+.\"
+.TH man2html 1 "1er janvier 1998" "Manuel Linux" "Commandes utilisateur"
+.LO 1
+.SH NOM
+man2html \- formate une page de manuel en html
+.SH SYNOPSIS
+man2html [options] [fichier]
+.SH DESCRIPTION
+.B man2html
+convertit une page de manuel telle que trouvée dans
+.I fichier
+(ou l'entrée standard stdin si aucun argument fichier n'est donné
+ou si l'argument «\ -\ » est donné) à partir du format nroff
+(celui des pages de manuels) vers un format html et affiche le résultat
+sur la sortie standard (stdout).
+.B man2html
+supporte
+.BR tbl (1)
+mais ne connaît rien à propos de
+.BR eqn (1).
+Le code de sortie est 0. Si quelque chose va mal, une page d'erreur
+est affichée sur la sortie standard stdout.
+
+Cette commande peut être utilisée seule mais a été principalement conçue pour
+être un auxiliaire afin que les utilisateurs puissent naviguer dans les pages
+de manuel avec un navigateur html comme
+.BR lynx (1),
+.BR xmosaic (1)
+ou
+.BR netscape (1).
+./" (See
+./" .BR man (1)
+./" for info on how to browse man pages via
+./" .BR man2html .
+./" Usually it would suffice to put "MANHTMLPAGER=/usr/bin/lynx"
+./" in the environment.)
+
+La plus grande partie de
+.B man2html
+est l'engin «\ troff-vers-html\ » écrit par Richard Verhoeven (rcb5@win.tue.nl).
+Il ajoute des hyperliens aux constructions suivantes\ :
+.LP
+.TS
+l l.
+foo(3x) "http://localhost/cgi-bin/man/man2html?3x+foo"
+method://string "method://string"
+www.host.name "http://www.host.name"
+ftp.host.name "ftp://ftp.host.name"
+name@host "mailto:name@host"
+<string.h> "file:/usr/include/string.h"
+.TE
+.LP
+(La première de celles\-ci peut être ajustée par des options - voir plus loin.)
+Aucune consultation n'est effectuée - les liens générés n'ont pas besoin
+d'exister. Un index avec des hyperliens internes vers les diverses
+sections est également créé rendant plus facile la navigation dans les grandes
+pages comme
+.BR bash (1).
+
+.SH OPTIONS
+Lorsqu'on lit à partir de stdin, il n'est pas toujours évident de savoir
+comment se fait l'expansion .so. L'option \-D permet à un script de définir
+le répertoire de travail.
+.LP
+.TP
+.B \-\^D chemin
+Retire les deux derniers éléments du chemin et effectue un changement
+de répertoire courant \fIchdir\fP(\fIdir\fP) avant de débuter la conversion.
+.LP
+L'option \-E option facilite la production de messages d'erreurs à partir
+de scripts cgi.
+.LP
+.TP
+.B \-\^E chaîne
+Produire en sortie une page d'erreur contenant le message d'erreur donné.
+.LP
+La forme générale d'un hyperlien généré pour référencer une page de manuel est
+.IP
+<method:cgipath><man2htmlpath><separator><manpage>
+.LP
+qui est d'ailleurs la forme par défaut. Les éléments de cet hyperlien sont
+positionnés en utilisant diverses options.
+.TP
+.B \-\^h
+Positionner method:cgipath à http://localhost.
+C'est le comportement par défaut.
+.TP
+.BI \-\^H " hôte[.domaine][:port]"
+Positionner method:cgipath à
+.RI http:// hôte.domaine:port .
+.TP
+.B \-\^l
+Positionner method:cgipath à
+.RI lynxcgi: /home/httpd .
+.TP
+.BI \-\^L " dir"
+Positionner method:cgipath à
+.RI lynxcgi: dir .
+.TP
+.BI \-\^M " man2htmlpath"
+Positionner le chemin vers man2html à utiliser. La valeur par défaut est
+.IR /cgi-bin/man/man2html .
+.TP
+.B \-\^p
+Positionner le séparateur à «\ /\ ».
+.TP
+.B \-\^q
+Positionner le séparateur à «\ ?\ ». C'est la valeur par défaut.
+.TP
+.B \-\^r
+Utiliser des chemins html relatifs plutôt que les chemins cgi-bin.
+.LP
+Sur une machine sur laquelle
+.BR httpd
+ne tourne pas, vous pouvez utiliser
+.B lynx
+pour naviguer dans les pages de manuel en utilisant la méthode lynxcgi.
+Lorsqu'un démon http est en service, vous pouvez utiliser lynx ou n'importe
+quel autre navigateur pour parcourir les pages de manuel en utilisant
+la méthode http.
+L'option \-l (pour «\ lynxcgi\ ») sélectionne ce fonctionnement.
+Avec elle, le chemin cgi par défaut est \fI/home/httpd\fP.
+
+En général, un script cgi peut être appelé de la façon suivante
+.IP
+<path_to_script>/<more_path>?<query>
+.LP
+et les variables d'environnement PATH_INFO et QUERY_STRING seront positionnées
+respectivement à <more_path> et <query>.
+Puisque lynxcgi ne gère pas l'élément PATH_INFO, nous allons générer des
+hyperliens avec «\ ?\ » comme séparateur par défaut.
+L'option \-p (pour «\ path\ ») sélectionne «\ /\ » comme séparateur, alors que
+l'option \-q (for «\ query\ ») sélectionne «\ ?\ ».
+
+L'option \-H \fIhost\fP spécifiera l'hôte à utiliser
+(à la place \fIlocalhost\fP). Un script cgi pourra utiliser
+.IP
+man2html -H $SERVER_NAME
+.LP
+si la variable SERVER_NAME est positionnée. Cela permettra à votre machine
+de fonctionner en tant que serveur et d'exporter les pages manuel.
+
+.SH BOGUES
+Il y a beaucoup d'heuristiques. La sortie produite ne sera pas toujours
+parfaite. La méthode lynxcgi ne fonctionnera pas si lynx a été compilé sans
+le support de celle-ci. Il peut y avoir des problèmes de sécurité.
+
+.SH "VOIR AUSSI"
+.BR lynx (1),
+.BR man (1)
+
+.SH TRADUCTION
+.PP
+Ce document est une traduction réalisée par Alain Portal
+<aportal AT univ-montp2 DOT fr> le 1er juin 2005 et mise à jour
+le 7 novembre 2005.
+.PP
+L'équipe de traduction a fait le maximum pour réaliser une adaptation
+française de qualité. La version anglaise la plus à jour de ce document est
+toujours consultable via la commande\ : «\ \fBLANG=en\ man\ 1\ man2html\fR\ ».
+N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute
+erreur dans cette page de manuel.
diff --git a/man2html/locales/it/hman.1 b/man2html/locales/it/hman.1
new file mode 100644
index 0000000..730de9c
--- /dev/null
+++ b/man2html/locales/it/hman.1
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1998 Andries Brouwer
+.\"
+.\" You may distribute under the terms of the GNU General Public
+.\" License as specified in the README file that comes with the man 1.0
+.\" distribution.
+.\" Traduzione da man-1.6d di Giulio Daprelà <giulio@pluto.it>
+.\" Revisione a cura di Vieri Giugni <v.giugni@gmail.com>
+.\" agosto 2006
+.\"
+.TH hman 1 "19 Gennaio 1998"
+.LO 1
+.SH NOME
+hman \- naviga le pagine di manuale on-line
+.SH SINTASSI
+.B hman
+[ -P \fIbrowser\fP ] [ -H \fIhost\fP ] [ \fIsection\fP ] \fIname\fP
+.br
+.B hman
+[ -P \fIbrowser\fP ] [ -H \fIhost\fP ] [ \fIsection\fP ] [ index ]
+.SH DESCRIZIONE
+Lo script
+.B hman
+è un'interfaccia per man2html(1), che permette di inserire richieste di man
+page dalla linea di comando e vedere l'output nel browser
+preferito.
+Il comportamento ricorda quello di
+.BR man (1)
+perciò molte persone potranno utilizzare un alias da
+.B hman
+a
+.BR man .
+Se il browser usato è netscape, e una copia di netscape
+è già in esecuzione,
+.B hman
+passerà la richiesta a quest'ultima
+
+.SH OPZIONI
+.TP
+.B \-\^P " browser"
+Specifica quale browser (lynx, xmosaic, arena, chimera,
+netscape, amaya, ...) usare.
+Questa opzione sovrascrive la variabile d'ambiente
+.B MANHTMLPAGER .
+Il valore predefinito è la versione non-httpd di
+.BR lynx .
+.TP
+.B \-\^H " host"
+Specifica da quale host prendere le man page.
+Questa opzione sovrascrive la variabile d'ambiente
+.B MANHTMLHOST .
+Il valore predefinito è
+.BR localhost .
+
+.SH AMBIENTE
+.TP
+MANHTMLPAGER
+Il browser predefinito in uso è selezionato da questa variabile d'ambiente.
+.TP
+MANHTMLHOST
+L'host predefinito in uso è selezionato da questa variabile d'ambiente.
+
+.SH "VEDERE ANCHE"
+.BR man (1),
+.BR man2html (1),
+.BR arena (1),
+.BR lynx (1),
+.BR netscape (1),
+.BR xmosaic (1),
+.BR glimpse (1)
+
+http://www.mcom.com/newsref/std/x-remote.html
diff --git a/man2html/locales/it/man2html.1 b/man2html/locales/it/man2html.1
new file mode 100644
index 0000000..45feef0
--- /dev/null
+++ b/man2html/locales/it/man2html.1
@@ -0,0 +1,153 @@
+'\" t
+.\" Man page for man2html
+.\" aeb, 980101
+.\"
+.\" Traduzione da man-1.6d di Giulio Daprelà <giulio@pluto.it>
+.\" Revisione a cura di Vieri Giugni <v.giugni@gmail.com>
+.\" giugno 2006
+.\"
+.TH man2html 1 "1 gennaio 1998"
+.LO 1
+.SH NOME
+man2html \- formatta una pagina di manuale in html
+.SH SINTASSI
+man2html [options] [file]
+.SH DESCRIZIONE
+.B man2html
+converte una pagina di manuale che si trova in
+.I file
+(o standard input (stdin); nel caso non venga fornito alcun file come
+argomento, o sia indicato "-", come argomento)
+dallo stile man nroff in html, e stampa il risultato in standard output (stdout).
+Supporta tbl, ma non conosce eqn.
+Lo stato di uscita è 0. Se qualcosa va male
+viene stampata su stdout una pagina di errore.
+
+Può essere usato come utilità stand-alone, ma è pensato principalmente
+come ausilio per permettere agli utenti di navigare le proprie man page
+usando un browser html come
+.BR lynx (1),
+.BR xmosaic (1)
+o
+.BR netscape (1).
+./" (See
+./" .BR man (1)
+./" for info on how to browse man pages via
+./" .BR man2html .
+./" Usually it would suffice to put "MANHTMLPAGER=/usr/bin/lynx"
+./" in the environment.)
+
+La parte principale di
+.B man2html
+è il motore da troff a html scritto da Richard Verhoeven (rcb5@win.tue.nl).
+Esso aggiunge dei collegamenti ipertestuali per i seguenti costrutti:
+.LP
+.TS
+l l.
+foo(3x) "http://localhost/cgi-bin/man/man2html?3x+foo"
+method://string "method://string"
+www.host.name "http://www.host.name"
+ftp.host.name "ftp://ftp.host.name"
+name@host "mailto:name@host"
+<string.h> "file:/usr/include/string.h"
+.TE
+.LP
+(Il primo di questi può essere controllato dalle opzioni - vedere sotto).
+Non viene fatto nessun controllo - i collegamenti generati non sono
+necessari o indispensabili.
+Inoltre viene generato un indice con collegamenti interni alle varie sezioni,
+in modo che sia più facile effettuare ricerche personalizzate in pagine di
+manuale grandi come
+.BR bash (1).
+
+.SH OPZIONI
+Quando si legge da stdin non è sempre chiaro come effettuare l'espansione
+.so . L'opzione \-D permette a uno script di definire la
+directory di lavoro.
+.LP
+.TP
+.B \-\^D pathname
+Estrae le ultime due parti dal percorso, ed esegue
+\fIchdir\fP(\fIdir\fP) prima di iniziare la conversione.
+.LP
+L'opzione \-E permette una facile generazione di messaggi di errore
+da uno script cgi.
+.LP
+.TP
+.B \-\^E string
+Genera una pagina di errore contenente il messaggio di errore che si è verificato.
+.LP
+La forma generale di un collegamento ipertestuale creato per una
+man page di riferimento è
+.IP
+<method:cgipath><man2htmlpath><separator><manpage>
+.LP
+con un valore predefinito come mostrato sopra. Le parti di questo collegamento
+ipertestuale sono impostate usando le varie opzioni.
+.TP
+.B \-\^h
+Set method:cgipath to http://localhost. Questo è il valore predefinito.
+.TP
+.BI \-\^H " host[.domain][:port]"
+Set method:cgipath to
+.RI http:// host.domain:port .
+.TP
+.B \-\^l
+Set method:cgipath to
+.RI lynxcgi: /home/httpd .
+.TP
+.BI \-\^L " dir"
+Set method:cgipath to
+.RI lynxcgi: dir .
+.TP
+.BI \-\^M " man2htmlpath"
+Imposta il man2htmlpath da usare. Il valore predefinito è
+.IR /cgi-bin/man/man2html .
+.TP
+.B \-\^p
+Imposta '/' come separatore.
+.TP
+.B \-\^q
+Imposta '?' come separatore. Questo è il valore predefinito.
+.TP
+.B \-\^r
+Usa percorsi html relativi, invece dei percorsi cgi-bin.
+.LP
+Su una macchina, senza eseguire
+.BR httpd ,
+si può usare
+.B lynx
+per navigare le man page, usando il metodo lynxcgi.
+Quando è attivo qualche demone http, lynx, o qualunque altro browser,
+può essere usato per navigare le man page, usando il metodo http.
+L'opzione \-l (per `lynxcgi') seleziona il comportamento precedente.
+Con esso, il valore predefinito di cgipath è \fI/home/httpd\fP.
+
+In generale, uno script cgi può essere chiamato da
+.IP
+<path_to_script>/<more_path>?<query>
+.LP
+e le variabili d'ambiente PATH_INFO e QUERY_STRING
+verranno impostate rispettivamente in <more_path> e <query>.
+Poiché lynxcgi non gestisce la parte PATH_INFO, vengono generati
+collegamenti ipertestualil con `?' come separatore predefinito.
+L'opzione \-p (per `path') seleziona '/' come separatore, mentre
+l'opzione \-q (per `query') seleziona '?' come separatore.
+
+L'opzione \-H \fIhost\fP specificherà l'host da usare
+(invece di \fIlocalhost\fP). Uno script cgi può usare
+.IP
+man2html -H $SERVER_NAME
+.LP
+se è impostata la variabile SERVER_NAME . Questo permetterà alla propria
+macchina di comportarsi come un server ed esportare man page.
+
+.SH BUG
+Ci sono molti fattori difficilmente prevedibili. L'output potrebbe non
+essere sempre perfetto. Il metodo lynxcgi non funzionerà se lynx è stato
+compilato senza selezionare il supporto per quest'ultimo. Ci potrebbero
+essere problemi di sicurezza.
+
+.SH "VEDERE ANCHE"
+.BR lynx (1),
+.BR man (1)
diff --git a/man2html/man2html.1 b/man2html/man2html.1
new file mode 100644
index 0000000..c1c25b3
--- /dev/null
+++ b/man2html/man2html.1
@@ -0,0 +1,151 @@
+'\" t
+.\" Man page for man2html
+.\" aeb, 980101
+.\"
+.TH man2html 1 "1 January 1998"
+.LO 1
+.SH NAME
+man2html \- format a manual page in html
+.SH SYNOPSIS
+man2html [options] [file]
+.SH DESCRIPTION
+.B man2html
+converts a manual page as found in
+.I file
+(or stdin, in case no file argument, or the argument "-", is given)
+from man-style nroff into html, and prints the result on stdout.
+It does support tbl but does not know about eqn.
+The exit status is 0. If something goes wrong,
+an error page is printed on stdout.
+
+This can be used as a stand-alone utility, but is mainly intended
+as an auxiliary, to enable users to browse their man pages using
+a html browser like
+.BR lynx (1),
+.BR xmosaic (1)
+or
+.BR netscape (1).
+./" (See
+./" .BR man (1)
+./" for info on how to browse man pages via
+./" .BR man2html .
+./" Usually it would suffice to put "MANHTMLPAGER=/usr/bin/lynx"
+./" in the environment.)
+
+The main part of
+.B man2html
+is the troff-to-html engine written by Richard Verhoeven (rcb5@win.tue.nl).
+It adds hyperlinks for the following constructs:
+.LP
+.TS
+l l.
+foo(3x) "http://localhost/cgi-bin/man/man2html?3x+foo"
+method://string "method://string"
+www.host.name "http://www.host.name"
+ftp.host.name "ftp://ftp.host.name"
+name@host "mailto:name@host"
+<string.h> "file:/usr/include/string.h"
+.TE
+.LP
+(The first of these can be tuned by options - see below.)
+No lookup is done - the links generated need not exist.
+Also an index with internal hyperlinks to the various sections
+is generated, so that it is easier to find one's way
+in large man pages like
+.BR bash (1).
+
+.SH OPTIONS
+When reading from stdin, it is not always clear how to
+do .so expansion. The \-D option allows a script to define
+the working directory.
+.LP
+.TP
+.B \-\^D pathname
+Strip the last two parts from the pathname, and do a
+\fIchdir\fP(\fIdir\fP) before starting the conversion.
+.LP
+The \-E option allows the easy generation of error messages
+from a cgi script.
+.LP
+.TP
+.B \-\^E string
+Output an error page containing the given error message.
+.LP
+The general form of a hyperlink generated for a man page reference is
+.IP
+<method:cgipath><man2htmlpath><separator><manpage>
+.LP
+with a default as shown above. The parts of this hyperlink
+are set using the various options.
+.TP
+.B \-\^h
+Set method:cgipath to http://localhost. This is the default.
+.TP
+.BI \-\^H " host[.domain][:port]"
+Set method:cgipath to
+.RI http:// host.domain:port .
+.TP
+.B \-\^l
+Set method:cgipath to
+.RI lynxcgi: /home/httpd .
+.TP
+.BI \-\^L " dir"
+Set method:cgipath to
+.RI lynxcgi: dir .
+.TP
+.BI \-\^M " man2htmlpath"
+Set the man2htmlpath to use. The default is
+.IR /cgi-bin/man/man2html .
+.TP
+.B \-\^p
+Set separator to '/'.
+.TP
+.B \-\^q
+Set separator to '?'. This is the default.
+.TP
+.B \-\^r
+Use relative html paths, instead of cgi-bin paths.
+.LP
+On a machine without running
+.BR httpd ,
+one can use
+.B lynx
+to browse the man pages, using the lynxcgi method.
+When some http daemon is running, lynx, or any other browser,
+can be used to browse the man pages, using the http method.
+The option \-l (for `lynxcgi') selects the former behaviour.
+With it, the default cgipath is \fI/home/httpd\fP.
+
+In general, a cgi script can be called by
+.IP
+<path_to_script>/<more_path>?<query>
+.LP
+and the environment variables PATH_INFO and QUERY_STRING
+will be set to <more_path> and <query>, respectively.
+Since lynxcgi does not handle the PATH_INFO part, we generate
+hyperlinks with `?' as a separator by default.
+The option \-p (for `path') selects '/' as a separator, while
+the option \-q (for `query') selects '?' as a separator.
+
+The option \-H \fIhost\fP will specify the host to use
+(instead of \fIlocalhost\fP). A cgi script could use
+.IP
+man2html -H $SERVER_NAME
+.LP
+if the variable SERVER_NAME is set. This would allow your machine
+to act as a server and export man pages.
+
+.SH BUGS
+There are many heuristics. The output will not always be perfect.
+The lynxcgi method will not work if lynx was compiled without
+selecting support for it. There may be problems with security.
+
+.SH AUTHOR
+Richard Verhoeven was the original author of
+.BR "man2html" .
+Michael Hamilton and Andries Brouwer subsequently improved on it.
+Federico Lucifredi <flucifredi@acm.org> is the current maintainer.
+
+.SH "SEE ALSO"
+.BR lynx (1),
+.BR man (1)
diff --git a/man2html/man2html.c b/man2html/man2html.c
new file mode 100644
index 0000000..b37eef6
--- /dev/null
+++ b/man2html/man2html.c
@@ -0,0 +1,3241 @@
+/*
+** This program was written by Richard Verhoeven (NL:5482ZX35)
+** at the Eindhoven University of Technology. Email: rcb5@win.tue.nl
+**
+** Permission is granted to distribute, modify and use this program
+** as long as this comment is not removed or changed.
+*/
+
+/* BSD mandoc stuff added by Michael Hamilton. */
+
+/* This program is rather buggy, but in spite of that it often works.
+ Improved things a little - April 1997 & January 1998 & Dec 2001 -
+ aeb@cwi.nl. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include "defs.h"
+#include "../src/version.h"
+
+/* BSD mandoc Bd/Ed example(?) blocks */
+#define BD_LITERAL 1
+#define BD_INDENT 2
+
+#define SIZE(a) (sizeof(a)/sizeof(*a))
+
+static char NEWLINE[2]="\n";
+static char idxlabel[6] = "ixAAA";
+
+#define INDEXFILE "/tmp/manindex.list"
+
+char *fname;
+char *directory;
+FILE *idxfile;
+
+char eqndelimopen=0, eqndelimclose=0;
+char escapesym='\\', nobreaksym='\'', controlsym='.', fieldsym=0, padsym=0;
+
+char *buffer=NULL;
+int buffpos=0, buffmax=0;
+int scaninbuff=0;
+int still_dd=0;
+int tabstops[20] = { 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96 };
+int maxtstop=12;
+int curpos=0;
+
+static char *scan_troff(char *c, int san, char **result);
+static char *scan_troff_mandoc(char *c, int san, char **result);
+
+static char **argument=NULL;
+
+static char charb[3];
+
+static char *
+expand_char(int nr)
+{
+ STRDEF *h;
+
+ if (!nr)
+ return NULL;
+
+ h = chardef;
+ if (h->nr != V('*','*')) {
+ printf("chardef corrupted\n");
+ exit(1);
+ }
+
+ for (h = chardef; h; h = h->next)
+ if (h->nr == nr) {
+ curpos += h->slen;
+ return h->st;
+ }
+ charb[0] = nr/256;
+ charb[1] = nr%256;
+ charb[2] = 0;
+ curpos += 2;
+ return charb;
+}
+
+static char *
+expand_string(int nr)
+{
+ STRDEF *h;
+
+ if (!nr)
+ return NULL;
+ for (h = strdef; h; h = h->next)
+ if (h->nr == nr) {
+ curpos += h->slen;
+ return h->st;
+ }
+ return NULL;
+}
+
+
+static char outbuffer[1024];
+static int obp=0;
+static int no_newline_output=0; /* boolean, set by \c */
+static int newline_for_fun=0;
+static int output_possible=0;
+static int out_length=0;
+
+static void
+add_links(char *c)
+{
+ /*
+ ** Add the links to the output.
+ ** At the moment the following are recognized:
+ **
+ ** name(*) -> ../man?/name.*
+ ** method://string -> method://string
+ ** www.host.name -> http://www.host.name
+ ** ftp.host.name -> ftp://ftp.host.name
+ ** name@host -> mailto:name@host
+ ** <name.h> -> file:/usr/include/name.h (guess)
+ **
+ ** Other possible links to add in the future:
+ **
+ ** /dir/dir/file -> file:/dir/dir/file
+ */
+ int i,j,nr;
+ char *f, *g, *h;
+ char *idtest[6]; /* url, mailto, www, ftp, manpage, include file */
+
+ out_length+=strlen(c);
+
+ nr=0;
+ idtest[0]=strstr(c+1,"://");
+ idtest[1]=strchr(c+1,'@');
+ idtest[2]=strstr(c,"www.");
+ idtest[3]=strstr(c,"ftp.");
+ idtest[4]=strchr(c+1,'(');
+ idtest[5]=strstr(c+1,".h&gt;");
+ for (i=0; i<6; i++) nr += (idtest[i]!=NULL);
+ while (nr) {
+ j=-1;
+ for (i=0; i<6; i++)
+ if (idtest[i] && (j<0 || idtest[i]<idtest[j])) j=i;
+ switch (j) {
+ case 5: /* <name.h> */
+ f=idtest[5];
+ h=f+2;
+ g=f;
+ while (g>c && g[-1]!=';') g--;
+ if (g!=c) {
+ char t;
+ t=*g;
+ *g=0;
+ printf("%s",c);
+ *g=t;*h=0;
+ include_file_html(g);
+ c=f+6;
+ } else {
+ f[5]=0;
+ printf("%s",c);
+ f[5]=';';
+ c=f+5;
+ }
+ break;
+ case 4: /* manpage? */
+ f=idtest[j];
+ /* find section - accept (1), (3F), (3Xt), (n), (l) */
+ g=strchr(f,')');
+ if (g && g-f<7 /* section has length at most 5, like 3Xlib */
+ /* preceded by name or html markup */
+ && (isalnum(f[-1]) || f[-1]=='>')
+ /* section is n or l or starts with a digit */
+ && strchr("123456789nl", f[1])
+ && (g-f == 2 || (g-f == 3 && isdigit(f[1]) && isalpha(f[2]))
+ || (f[2] == 'X' && isdigit(f[1])))
+ ) {
+ /* this might be a link */
+ h=f-1;
+ /* skip html markup */
+ while (h>c && *h=='>') {
+ while (h!=c && *h!='<') h--;
+ if (h!=c) h--;
+ }
+ if (isalnum(*h)) {
+ char t,te,tg,*e;
+ e=h+1;
+ while (h>c && (isalnum(h[-1]) || h[-1]=='_' ||
+ h[-1]=='-' || h[-1]=='.' || h[-1]==':'))
+ h--;
+ t=*h; *h=0;
+ printf("%s", c);
+ *h=t;
+ tg=*g; *g=0;
+ te=*e; *e=0;
+ man_page_html(f+1, h); /* section, page */
+ *e=te;
+ *g=tg;
+ c=e;
+ }
+ }
+ *f=0;
+ printf("%s", c);
+ *f='(';
+ idtest[4]=f-1;
+ c=f;
+ break; /* manpage */
+ case 3: /* ftp */
+ case 2: /* www */
+ g=f=idtest[j];
+ while (*g && (isalnum(*g) || *g=='_' || *g=='-' || *g=='+' ||
+ *g=='.')) g++;
+ if (g[-1]=='.') g--;
+ if (g-f>4) {
+ char t;
+ t=*f; *f=0;
+ printf("%s",c);
+ *f=t; t=*g;*g=0;
+ if (j==3)
+ ftp_html(f);
+ else
+ www_html(f);
+ *g=t;
+ c=g;
+ } else {
+ f[3]=0;
+ printf("%s",c);
+ c=f+3;
+ f[3]='.';
+ }
+ break;
+ case 1: /* mailto */
+ g=f=idtest[1];
+ while (g>c && (isalnum(g[-1]) || g[-1]=='_' || g[-1]=='-' ||
+ g[-1]=='+' || g[-1]=='.' || g[-1]=='%')) g--;
+ h=f+1;
+ while (*h && (isalnum(*h) || *h=='_' || *h=='-' || *h=='+' ||
+ *h=='.')) h++;
+ if (h[-1]=='.') h--;
+ if (h-f>4 && f-g>1) {
+ char t;
+ t=*g;
+ *g=0;
+ printf("%s",c);
+ *g=t;t=*h;*h=0;
+ mailto_html(g);
+ *h=t;
+ c=h;
+ } else {
+ *f=0;
+ printf("%s",c);
+ *f='@';
+ idtest[1]=c;
+ c=f;
+ }
+ break;
+ case 0: /* url */
+ g=f=idtest[0];
+ while (g>c && isalpha(g[-1]) && islower(g[-1])) g--;
+ h=f+3;
+ while (*h && !isspace(*h) && *h!='<' && *h!='>' && *h!='"' &&
+ *h!='&') h++;
+ if (f-g>2 && f-g<7 && h-f>3) {
+ char t;
+ t=*g;
+ *g=0;
+ printf("%s", c);
+ *g=t; t=*h; *h=0;
+ url_html(g);
+ *h=t;
+ c=h;
+ } else {
+ f[1]=0;
+ printf("%s", c);
+ f[1]='/';
+ c=f+1;
+ }
+ break;
+ default:
+ break;
+ }
+ nr=0;
+ if (idtest[0] && idtest[0]<c) idtest[0]=strstr(c+1,"://");
+ if (idtest[1] && idtest[1]<c) idtest[1]=strchr(c+1,'@');
+ if (idtest[2] && idtest[2]<c) idtest[2]=strstr(c,"www.");
+ if (idtest[3] && idtest[3]<c) idtest[3]=strstr(c,"ftp.");
+ if (idtest[4] && idtest[4]<c) idtest[4]=strchr(c+1,'(');
+ if (idtest[5] && idtest[5]<c) idtest[5]=strstr(c+1,".h&gt;");
+ for (i=0; i<6; i++) nr += (idtest[i]!=NULL);
+ }
+ printf("%s", c);
+}
+
+int current_font=0;
+int current_size=0;
+int fillout = 1;
+
+/*
+ * Kludge: remove \a - in the context
+ * .TH NAME 2 date "Version" "Title"
+ * we got output \aTitle\a.
+ */
+static void
+out_html(char *c) {
+ if (!c)
+ return;
+ if (no_newline_output) { /* remove \n if present */
+ int i=0;
+ while (c[i]) {
+ if (!no_newline_output)
+ c[i-1]=c[i];
+ if (c[i]=='\n')
+ no_newline_output=0;
+ i++;
+ }
+ if (!no_newline_output)
+ c[i-1]=0;
+ }
+ if (scaninbuff) {
+ while (*c) {
+ if (buffpos >= buffmax) {
+ buffer = xrealloc(buffer, buffmax*2);
+ buffmax = buffmax*2;
+ }
+ if (*c != '\a')
+ buffer[buffpos++] = *c;
+ c++;
+ }
+ } else if (output_possible) {
+ while (*c) {
+ if (*c != '\a')
+ outbuffer[obp++] = *c;
+ if (*c == '\n' || obp > 1000) {
+ outbuffer[obp] = 0;
+ add_links(outbuffer);
+ obp = 0;
+ }
+ c++;
+ }
+ }
+}
+
+/* --------------------------------------------------------------- */
+/* All references to dl_set and itemdepth are here. */
+/* --------------------------------------------------------------- */
+static int itemdepth=0;
+static int dl_set[30]= { 0 };
+#define noDL 0
+#define DL 1
+#define UL 2
+#define OL 3
+static char *dl_open[4] = { "", "<DL COMPACT>\n", "<UL>", "<OL>" };
+static char *dl_close[4] = { "", "</DL>\n", "</UL>", "</OL>" };
+
+static inline void
+dl_begin(void) {
+ if (itemdepth < SIZE(dl_set) && dl_set[itemdepth] == noDL) {
+ out_html(dl_open[DL]);
+ dl_set[itemdepth]=DL;
+ }
+ out_html("<DT>");
+}
+
+static inline void
+dl_end(void) {
+ if (itemdepth < SIZE(dl_set)) {
+ int type = dl_set[itemdepth];
+ if (type == DL) {
+ out_html(dl_close[type]);
+ dl_set[itemdepth]=noDL;
+ }
+ }
+}
+
+static inline void
+dl_newlevel(void) {
+ itemdepth++;
+ if (itemdepth < SIZE(dl_set))
+ dl_set[itemdepth]=noDL;
+ out_html("<DL COMPACT><DT><DD>");
+}
+
+static inline void
+dl_endlevel(void) {
+ if (itemdepth) {
+ dl_end();
+ out_html("</DL>\n");
+ itemdepth--;
+ }
+}
+
+static inline void
+dl_down(void) {
+ while (itemdepth)
+ dl_endlevel();
+ dl_end();
+}
+
+static inline int
+dl_type(int type) {
+ return (itemdepth < SIZE(dl_set) && dl_set[itemdepth] == type);
+}
+
+static inline void
+dl_newlevel_type(int type) {
+ itemdepth++;
+ if (itemdepth < SIZE(dl_set)) {
+ dl_set[itemdepth]=type;
+ out_html(dl_open[type]);
+ }
+}
+
+static inline void
+dl_endlevel_type(void) {
+ if (itemdepth) {
+ if (itemdepth < SIZE(dl_set))
+ out_html(dl_close[dl_set[itemdepth]]);
+ itemdepth--;
+ }
+}
+/* --------------------------------------------------------------- */
+/* This stuff is broken.
+It generates
+ <DT><B>TIOCLINUX, subcode=0<DD>
+ Dump the screen.
+ </B><I>argp</I> points to a
+from
+ .IP "\fBTIOCLINUX, subcode=0"
+ Dump the screen.
+ \fIargp\fP points to a
+Bug 1: incorrect nesting: </B> is needed before <DD>.
+Bug 2: incorrect font: after the .IP things are roman again.
+*/
+
+#define FO0 ""
+#define FC0 ""
+#define FO1 "<I>"
+#define FC1 "</I>"
+#define FO2 "<B>"
+#define FC2 "</B>"
+#define FO3 "<TT>"
+#define FC3 "</TT>"
+
+char *switchfont[16] = { "" , FC0 FO1, FC0 FO2, FC0 FO3,
+ FC1 FO0, "" , FC1 FO2, FC1 FO3,
+ FC2 FO0, FC2 FO1, "" , FC2 FO3,
+ FC3 FO0, FC3 FO1, FC3 FO2, "" };
+
+static char *
+change_to_font(int nr)
+{
+ int i;
+ switch (nr) {
+ case '0': nr++;
+ case '1': case '2': case '3': case '4':
+ nr = nr-'1'; break;
+ case V('C','W'): break;
+ case 'L': nr=3; break;
+ case 'B': nr=2; break;
+ case 'I': nr=1; break;
+ case 0: case 1: case 2: case 3:
+ break;
+ case 'P': case 'R':
+ default: nr=0; break;
+ }
+ i= current_font*4+nr%4;
+ current_font=nr%4;
+ return switchfont[i];
+}
+
+static char sizebuf[200];
+
+static char *
+change_to_size(int nr)
+{
+ int i;
+ switch (nr) {
+ case '0': case '1': case '2': case '3': case '4': case '5': case '6':
+ case '7': case '8': case '9': nr=nr-'0'; break;
+ case '\0': break;
+ default: nr=current_size+nr; if (nr>9) nr=9; if (nr< -9) nr=-9; break;
+ }
+ if (nr==current_size) return "";
+ i=current_font;
+ sizebuf[0]=0;
+ strcat(sizebuf, change_to_font(0));
+ if (current_size) strcat(sizebuf, "</FONT>");
+ current_size=nr;
+ if (nr) {
+ int l;
+ strcat(sizebuf, "<FONT SIZE=\"");
+ l=strlen(sizebuf);
+ if (nr>0) sizebuf[l++]='+'; else sizebuf[l++]='-',nr=-nr;
+ sizebuf[l++]=nr+'0';
+ sizebuf[l++]='"';
+ sizebuf[l++]='>';
+ sizebuf[l]=0;
+ }
+ strcat(sizebuf, change_to_font(i));
+ return sizebuf;
+}
+
+int asint=0;
+int intresult=0;
+
+#define SKIPEOL while (*c && *c++!='\n')
+
+static int skip_escape=0;
+static int single_escape=0;
+
+static char *
+scan_escape(char *c) {
+ char *h=NULL;
+ char b[5];
+ INTDEF *intd;
+ int exoutputp,exskipescape;
+ int i,j;
+
+ intresult=0;
+ switch (*c) {
+ case 'e': h="\\"; curpos++;break;
+ case '0':
+ case ' ': h="&nbsp;";curpos++; break;
+ case '|': h=""; break;
+ case '"': SKIPEOL; c--; h=""; break;
+ case '$':
+ if (argument) {
+ c++;
+ i=(*c -'1');
+ if (!(h=argument[i])) h="";
+ }
+ break;
+ case 'z':
+ c++;
+ if (*c=='\\') { c=scan_escape(c+1); c--;h=""; }
+ else {
+ b[0]=*c;
+ b[1]=0;
+ h="";
+ }
+ break;
+ case 'k': c++; if (*c=='(') c+=2;
+ case '^':
+ case '!':
+ case '%':
+ case 'a':
+ case 'd':
+ case 'r':
+ case 'u':
+ case '\n':
+ case '&': h=""; break;
+ case '(':
+ c++;
+ i= c[0]*256+c[1];
+ c++;
+ h = expand_char(i);
+ break;
+ case '*':
+ c++;
+ if (*c=='(') {
+ c++;
+ i= c[0]*256+c[1];
+ c++;
+ } else
+ i= *c *256+' ';
+ h = expand_string(i);
+ break;
+ case 'f':
+ c++;
+ if (*c=='\\') {
+ c++;
+ c=scan_escape(c);
+ c--;
+ i=intresult;
+ } else if (*c != '(')
+ i=*c;
+ else {
+ c++;
+ i=c[0]*256+c[1];
+ c++;
+ }
+ if (!skip_escape) h=change_to_font(i); else h="";
+ break;
+ case 's':
+ c++;
+ j=0;i=0;
+ if (*c=='-') {j= -1; c++;} else if (*c=='+') {j=1; c++;}
+ if (*c=='0') c++; else if (*c=='\\') {
+ c++;
+ c=scan_escape(c);
+ i=intresult; if (!j) j=1;
+ } else
+ while (isdigit(*c) && (!i || (!j && i<4))) i=i*10+(*c++)-'0';
+ if (!j) { j=1; if (i) i=i-10; }
+ if (!skip_escape) h=change_to_size(i*j); else h="";
+ c--;
+ break;
+ case 'n':
+ c++;
+ j=0;
+ switch (*c) {
+ case '+': j=1; c++; break;
+ case '-': j=-1; c++; break;
+ default: break;
+ }
+ if (*c=='(') {
+ c++;
+ i=V(c[0],c[1]);
+ c=c+1;
+ } else {
+ i=V(c[0],' ');
+ }
+ intd=intdef;
+ while (intd && intd->nr!=i) intd=intd->next;
+ if (intd) {
+ intd->val=intd->val+j*intd->incr;
+ intresult=intd->val;
+ } else {
+ switch (i) {
+ case V('.','s'): intresult=current_size; break;
+ case V('.','f'): intresult=current_font; break;
+ default: intresult=0; break;
+ }
+ }
+ h="";
+ break;
+ case 'w':
+ c++;
+ i=*c;
+ c++;
+ exoutputp=output_possible;
+ exskipescape=skip_escape;
+ output_possible=0;
+ skip_escape=1;
+ j=0;
+ while (*c!=i) {
+ j++;
+ if (*c==escapesym) c=scan_escape(c+1); else c++;
+ }
+ output_possible=exoutputp;
+ skip_escape=exskipescape;
+ intresult=j;
+ break;
+ case 'l': h="<HR>"; curpos=0;
+ case 'b':
+ case 'v':
+ case 'x':
+ case 'o':
+ case 'L':
+ case 'h':
+ c++;
+ i=*c;
+ c++;
+ exoutputp=output_possible;
+ exskipescape=skip_escape;
+ output_possible=0;
+ skip_escape=1;
+ while (*c != i)
+ if (*c==escapesym) c=scan_escape(c+1);
+ else c++;
+ output_possible=exoutputp;
+ skip_escape=exskipescape;
+ break;
+ case 'c': no_newline_output=1; break;
+ case '{': newline_for_fun++; h="";break;
+ case '}': if (newline_for_fun) newline_for_fun--; h="";break;
+ case 'p': h="<BR>\n";curpos=0; break;
+ case 't': h="\t";curpos=(curpos+8)&0xfff8; break;
+ case '<': h="&lt;";curpos++; break;
+ case '>': h="&gt;";curpos++; break;
+ case '\\': if (single_escape) { c--; break;}
+ default: b[0]=*c; b[1]=0; h=b; curpos++; break;
+ }
+ c++;
+ if (!skip_escape) out_html(h);
+ return c;
+}
+
+typedef struct TABLEITEM TABLEITEM;
+
+struct TABLEITEM {
+ char *contents;
+ int size,align,valign,colspan,rowspan,font,vleft,vright,space,width;
+ TABLEITEM *next;
+};
+
+static TABLEITEM emptyfield = {NULL,0,0,0,1,1,0,0,0,0,0,NULL};
+typedef struct TABLEROW TABLEROW;
+
+struct TABLEROW {
+ TABLEITEM *first;
+ TABLEROW *prev, *next;
+};
+
+static char *tableopt[]= { "center", "expand", "box", "allbox", "doublebox",
+ "tab", "linesize", "delim", NULL };
+static int tableoptl[] = { 6,6,3,6,9,3,8,5,0};
+
+
+static void clear_table(TABLEROW *table)
+{
+ TABLEROW *tr1,*tr2;
+ TABLEITEM *ti1,*ti2;
+
+ tr1=table;
+ while (tr1->prev) tr1=tr1->prev;
+ while (tr1) {
+ ti1=tr1->first;
+ while (ti1) {
+ ti2=ti1->next;
+ if (ti1->contents) free(ti1->contents);
+ free(ti1);
+ ti1=ti2;
+ }
+ tr2=tr1;
+ tr1=tr1->next;
+ free(tr2);
+ }
+}
+
+char *scan_expression(char *c, int *result);
+
+static char *scan_format(char *c, TABLEROW **result, int *maxcol)
+{
+ TABLEROW *layout, *currow;
+ TABLEITEM *curfield;
+ int i,j;
+ if (*result) {
+ clear_table(*result);
+ }
+ layout= currow=(TABLEROW*) xmalloc(sizeof(TABLEROW));
+ currow->next=currow->prev=NULL;
+ currow->first=curfield=(TABLEITEM*) xmalloc(sizeof(TABLEITEM));
+ *curfield=emptyfield;
+ while (*c && *c!='.') {
+ switch (*c) {
+ case 'C': case 'c': case 'N': case 'n':
+ case 'R': case 'r': case 'A': case 'a':
+ case 'L': case 'l': case 'S': case 's':
+ case '^': case '_':
+ if (curfield->align) {
+ curfield->next=(TABLEITEM*)xmalloc(sizeof(TABLEITEM));
+ curfield=curfield->next;
+ *curfield=emptyfield;
+ }
+ curfield->align=toupper(*c);
+ c++;
+ break;
+ case 'i': case 'I': case 'B': case 'b':
+ curfield->font = toupper(*c);
+ c++;
+ break;
+ case 'f': case 'F':
+ c++;
+ curfield->font = toupper(*c);
+ c++;
+ if (!isspace(*c)) c++;
+ break;
+ case 't': case 'T': curfield->valign='t'; c++; break;
+ case 'p': case 'P':
+ c++;
+ i=j=0;
+ if (*c=='+') { j=1; c++; }
+ if (*c=='-') { j=-1; c++; }
+ while (isdigit(*c)) i=i*10+(*c++)-'0';
+ if (j) curfield->size= i*j; else curfield->size=j-10;
+ break;
+ case 'v': case 'V':
+ case 'w': case 'W':
+// c=scan_expression(c+2,&curfield->width);
+ c++;
+ if (*c == '(') {
+ c=scan_expression(c+1,&curfield->width);
+ } else {
+ i=0;
+ while (isdigit(*c)) i=i*10+(*c++)-'0';
+ curfield->width=i;
+ }
+ break;
+ case '|':
+ if (curfield->align) curfield->vleft++;
+ else curfield->vright++;
+ c++;
+ break;
+ case 'e': case 'E':
+ c++;
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ i=0;
+ while (isdigit(*c)) i=i*10+(*c++)-'0';
+ curfield->space=i;
+ break;
+ case ',': case '\n':
+ currow->next=(TABLEROW*)xmalloc(sizeof(TABLEROW));
+ currow->next->prev=currow;
+ currow=currow->next;
+ currow->next=NULL;
+ curfield=currow->first=(TABLEITEM*)xmalloc(sizeof(TABLEITEM));
+ *curfield=emptyfield;
+ c++;
+ break;
+ default:
+ c++;
+ break;
+ }
+ }
+ if (*c=='.') while (*c++!='\n');
+ *maxcol=0;
+ currow=layout;
+ while (currow) {
+ curfield=layout->first;
+ i=0;
+ while (curfield) {
+ i++;
+ curfield=curfield->next;
+ }
+ if (i>*maxcol) *maxcol=i;
+ currow=currow->next;
+ }
+ *result=layout;
+ return c;
+}
+
+static TABLEROW *
+next_row(TABLEROW *tr)
+{
+ if (tr->next) {
+ tr=tr->next;
+ if (!tr->next) next_row(tr);
+ return tr;
+ } else {
+ TABLEITEM *ti, *ti2;
+ tr->next=(TABLEROW*)xmalloc(sizeof(TABLEROW));
+ tr->next->prev=tr;
+ ti=tr->first;
+ tr=tr->next;
+ tr->next=NULL;
+ if (ti) tr->first=ti2=(TABLEITEM*) xmalloc(sizeof(TABLEITEM));
+ else tr->first=ti2=NULL;
+ while (ti!=ti2) {
+ *ti2=*ti;
+ ti2->contents=NULL;
+ if ((ti=ti->next)) {
+ ti2->next=(TABLEITEM*) xmalloc(sizeof(TABLEITEM));
+ }
+ ti2=ti2->next;
+ }
+ return tr;
+ }
+}
+
+char itemreset[20]="\\fR\\s0";
+
+static char *
+scan_table(char *c) {
+ char *h;
+ char *g;
+ int center=0, expand=0, box=0, border=0, linesize=1;
+ int i,j,maxcol=0, finished=0;
+ int oldfont, oldsize,oldfillout;
+ char itemsep='\t';
+ TABLEROW *layout=NULL, *currow;
+ TABLEITEM *curfield;
+ while (*c++!='\n'); /* skip TS */
+ h=c;
+ if (*h=='.') return c-1;
+ oldfont=current_font;
+ oldsize=current_size;
+ oldfillout=fillout;
+ out_html(change_to_font(0));
+ out_html(change_to_size(0));
+ if (!fillout) {
+ fillout=1;
+ out_html("</PRE>");
+ }
+ while (*h && *h!='\n') h++;
+ if (h[-1]==';') {
+ /* scan table options */
+ while (c<h) {
+ while (isspace(*c)) c++;
+ for (i=0; tableopt[i] && strncmp(tableopt[i],c,tableoptl[i]);i++);
+ c=c+tableoptl[i];
+ switch (i) {
+ case 0: center=1; break;
+ case 1: expand=1; break;
+ case 2: box=1; break;
+ case 3: border=1; break;
+ case 4: box=2; break;
+ case 5: while (*c++!='('); itemsep=*c++; break;
+ case 6: while (*c++!='('); linesize=0;
+ while (isdigit(*c)) linesize=linesize*10+(*c++)-'0';
+ break;
+ case 7: while (*c!=')') c++;
+ default: break;
+ }
+ c++;
+ }
+ c=h+1;
+ }
+ /* scan layout */
+ c=scan_format(c,&layout, &maxcol);
+ currow=layout;
+ next_row(currow);
+ curfield=layout->first;
+ i=0;
+ while (!finished && *c) {
+ /* search item */
+ h=c;
+ if ((*c=='_' || *c=='=') && (c[1]==itemsep || c[1]=='\n')) {
+ if (c[-1]=='\n' && c[1]=='\n') {
+ if (currow->prev) {
+ currow->prev->next=(TABLEROW*) xmalloc(sizeof(TABLEROW));
+ currow->prev->next->next=currow;
+ currow->prev->next->prev=currow->prev;
+ currow->prev=currow->prev->next;
+ } else {
+ currow->prev=layout=(TABLEROW*) xmalloc(sizeof(TABLEROW));
+ currow->prev->prev=NULL;
+ currow->prev->next=currow;
+ }
+ curfield=currow->prev->first=
+ (TABLEITEM*) xmalloc(sizeof(TABLEITEM));
+ *curfield=emptyfield;
+ curfield->align=*c;
+ curfield->colspan=maxcol;
+ curfield=currow->first;
+ c=c+2;
+ } else {
+ if (curfield) {
+ curfield->align=*c;
+ do {
+ curfield=curfield->next;
+ } while (curfield && curfield->align=='S');
+ }
+ if (c[1]=='\n') {
+ currow=next_row(currow);
+ curfield=currow->first;
+ }
+ c=c+2;
+ }
+ } else if (*c=='T' && c[1]=='{') {
+ h=c+2;
+ c=strstr(h,"\nT}");
+ c++;
+ *c=0;
+ g=NULL;
+ scan_troff(h, 0, &g);
+ scan_troff(itemreset, 0, &g);
+ *c='T';
+ c+=3;
+ if (curfield) {
+ curfield->contents=g;
+ do {
+ curfield=curfield->next;
+ } while (curfield && curfield->align=='S');
+ } else
+ if (g) free(g);
+ if (c[-1]=='\n') {
+ currow=next_row(currow);
+ curfield=currow->first;
+ }
+ } else if (*c=='.' && c[1]=='T' && c[2]=='&' && c[-1]=='\n') {
+ TABLEROW *hr;
+ while (*c++!='\n');
+ hr=currow;
+ currow=currow->prev;
+ hr->prev=NULL;
+ c=scan_format(c,&hr, &i);
+ hr->prev=currow;
+ currow->next=hr;
+ currow=hr;
+ next_row(currow);
+ curfield=currow->first;
+ } else if (*c=='.' && c[1]=='T' && c[2]=='E' && c[-1]=='\n') {
+ finished=1;
+ while (*c++!='\n');
+ if (currow->prev)
+ currow->prev->next=NULL;
+ currow->prev=NULL;
+ clear_table(currow);
+ } else if (*c=='.' && c[-1]=='\n' && !isdigit(c[1])) {
+ /* skip troff request inside table (usually only .sp ) */
+ while (*c++!='\n');
+ } else {
+ h=c;
+ while (*c && (*c!=itemsep || c[-1]=='\\') &&
+ (*c!='\n' || c[-1]=='\\')) c++;
+ i=0;
+ if (*c==itemsep) {i=1; *c='\n'; }
+ if (h[0]=='\\' && h[2]=='\n' &&
+ (h[1]=='_' || h[1]=='^')) {
+ if (curfield) {
+ curfield->align=h[1];
+ do {
+ curfield=curfield->next;
+ } while (curfield && curfield->align=='S');
+ }
+ h=h+3;
+ } else {
+ g=NULL;
+ h=scan_troff(h,1,&g);
+ scan_troff(itemreset,0,&g);
+ if (curfield) {
+ curfield->contents=g;
+ do {
+ curfield=curfield->next;
+ } while (curfield && curfield->align=='S');
+ } else if (g) free(g);
+ }
+ if (i) *c=itemsep;
+ c=h;
+ if (c[-1]=='\n') {
+ currow=next_row(currow);
+ curfield=currow->first;
+ }
+ }
+ }
+ /* calculate colspan and rowspan */
+ currow=layout;
+ while (currow->next) currow=currow->next;
+ while (currow) {
+ TABLEITEM *ti, *ti1=NULL, *ti2=NULL;
+ ti=currow->first;
+ if (currow->prev) ti1=currow->prev->first;
+ while (ti) {
+ switch (ti->align) {
+ case 'S':
+ if (ti2) {
+ ti2->colspan++;
+ if (ti2->rowspan<ti->rowspan) ti2->rowspan=ti->rowspan;
+ }
+ break;
+ case '^':
+ if (ti1) ti1->rowspan++;
+ default:
+ if (!ti2) ti2=ti;
+ else {
+ do {
+ ti2=ti2->next;
+ } while (ti2 && curfield->align=='S');
+ }
+ break;
+ }
+ ti=ti->next;
+ if (ti1) ti1=ti1->next;
+ }
+ currow=currow->prev;
+ }
+ /* produce html output */
+ if (center) out_html("<CENTER>");
+ if (box==2) out_html("<TABLE BORDER><TR><TD>");
+ out_html("<TABLE");
+ if (box || border) {
+ out_html(" BORDER");
+ if (!border) out_html("><TR><TD><TABLE");
+ if (expand) out_html(" WIDTH=100%");
+ }
+ out_html(">\n");
+ currow=layout;
+ while (currow) {
+ j=0;
+ out_html("<TR VALIGN=top>");
+ curfield=currow->first;
+ while (curfield) {
+ if (curfield->align!='S' && curfield->align!='^') {
+ out_html("<TD");
+ switch (curfield->align) {
+ case 'N':
+ curfield->space+=4;
+ case 'R':
+ out_html(" ALIGN=right");
+ break;
+ case 'C':
+ out_html(" ALIGN=center");
+ default:
+ break;
+ }
+ if (!curfield->valign && curfield->rowspan>1)
+ out_html(" VALIGN=center");
+ if (curfield->colspan>1) {
+ char buf[5];
+ out_html(" COLSPAN=");
+ sprintf(buf, "%i", curfield->colspan);
+ out_html(buf);
+ }
+ if (curfield->rowspan>1) {
+ char buf[5];
+ out_html(" ROWSPAN=");
+ sprintf(buf, "%i", curfield->rowspan);
+ out_html(buf);
+ }
+ j=j+curfield->colspan;
+ out_html(">");
+ if (curfield->size) out_html(change_to_size(curfield->size));
+ if (curfield->font) out_html(change_to_font(curfield->font));
+ switch (curfield->align) {
+ case '=': out_html("<HR><HR>"); break;
+ case '_': out_html("<HR>"); break;
+ default:
+ if (curfield->contents) out_html(curfield->contents);
+ break;
+ }
+ if (curfield->space)
+ for (i=0; i<curfield->space;i++) out_html("&nbsp;");
+ if (curfield->font) out_html(change_to_font(0));
+ if (curfield->size) out_html(change_to_size(0));
+ if (j>=maxcol && curfield->align>'@' && curfield->align!='_')
+ out_html("<BR>");
+ out_html("</TD>");
+ }
+ curfield=curfield->next;
+ }
+ out_html("</TR>\n");
+ currow=currow->next;
+ }
+ if (box && !border) out_html("</TABLE>");
+ out_html("</TABLE>");
+ if (box==2) out_html("</TABLE>");
+ if (center) out_html("</CENTER>\n");
+ else out_html("\n");
+ if (!oldfillout) out_html("<PRE>");
+ fillout=oldfillout;
+ out_html(change_to_size(oldsize));
+ out_html(change_to_font(oldfont));
+ return c;
+}
+
+char *scan_expression(char *c, int *result) {
+ int value=0,value2,sign=1,opex=0;
+ char oper='c';
+
+ if (*c=='!') {
+ c=scan_expression(c+1, &value);
+ value= (!value);
+ } else if (*c=='n') {
+ c++;
+ value=nroff;
+ } else if (*c=='t') {
+ c++;
+ value=1-nroff;
+ } else if (*c=='\'' || *c=='"' || *c<' ' || (*c=='\\' && c[1]=='(')) {
+ /* ?string1?string2?
+ ** test if string1 equals string2.
+ */
+ char *st1=NULL, *st2=NULL, *h;
+ char *tcmp=NULL;
+ char sep;
+ sep=*c;
+ if (sep=='\\') {
+ tcmp=c;
+ c=c+3;
+ }
+ c++;
+ h=c;
+ while (*c!= sep && (!tcmp || strncmp(c,tcmp,4))) c++;
+ *c='\n';
+ scan_troff(h, 1, &st1);
+ *c=sep;
+ if (tcmp) c=c+3;
+ c++;
+ h=c;
+ while (*c!=sep && (!tcmp || strncmp(c,tcmp,4))) c++;
+ *c='\n';
+ scan_troff(h,1,&st2);
+ *c=sep;
+ if (!st1 && !st2) value=1;
+ else if (!st1 || !st2) value=0;
+ else value=(!strcmp(st1, st2));
+ if (st1) free(st1);
+ if (st2) free(st2);
+ if (tcmp) c=c+3;
+ c++;
+ } else {
+ while (*c && !isspace(*c) && *c!=')') {
+ opex=0;
+ switch (*c) {
+ case '(':
+ c=scan_expression(c+1, &value2);
+ value2=sign*value2;
+ opex=1;
+ break;
+ case '.':
+ case '0': case '1':
+ case '2': case '3':
+ case '4': case '5':
+ case '6': case '7':
+ case '8': case '9': {
+ int num=0,denum=1;
+ value2=0;
+ while (isdigit(*c)) value2=value2*10+((*c++)-'0');
+ if (*c=='.') {
+ c++;
+ while (isdigit(*c)) {
+ num=num*10+((*c++)-'0');
+ denum=denum*10;
+ }
+ }
+ if (isalpha(*c)) {
+ /* scale indicator */
+ switch (*c) {
+ case 'i': /* inch -> 10pt */
+ value2=value2*10+(num*10+denum/2)/denum;
+ num=0;
+ break;
+ default:
+ break;
+ }
+ c++;
+ }
+ value2=value2+(num+denum/2)/denum;
+ value2=sign*value2;
+ opex=1;
+ break;
+ }
+ case '\\':
+ c=scan_escape(c+1);
+ value2=intresult*sign;
+ if (isalpha(*c)) c++; /* scale indicator */
+ opex=1;
+ break;
+ case '-':
+ if (oper) { sign=-1; c++; break; }
+ case '>':
+ case '<':
+ case '+':
+ case '/':
+ case '*':
+ case '%':
+ case '&':
+ case '=':
+ case ':':
+ if (c[1]=='=') oper=(*c++) +16; else oper=*c;
+ c++;
+ break;
+ default: c++; break;
+ }
+ if (opex) {
+ sign=1;
+ switch (oper) {
+ case 'c': value=value2; break;
+ case '-': value=value-value2; break;
+ case '+': value=value+value2; break;
+ case '*': value=value*value2; break;
+ case '/': if (value2) value=value/value2; break;
+ case '%': if (value2) value=value%value2; break;
+ case '<': value=(value<value2); break;
+ case '>': value=(value>value2); break;
+ case '>'+16: value=(value>=value2); break;
+ case '<'+16: value=(value<=value2); break;
+ case '=': case '='+16: value=(value==value2); break;
+ case '&': value = (value && value2); break;
+ case ':': value = (value || value2); break;
+ default: fprintf(stderr,
+ "man2html: Unknown operator %c.\n", oper);
+ }
+ oper=0;
+ }
+ }
+ if (*c==')') c++;
+ }
+ *result=value;
+ return c;
+}
+
+static void
+trans_char(char *c, char s, char t) {
+ char *sl = c;
+ int slash = 0;
+
+ while (*sl && (*sl != '\n' || slash)) {
+ if (!slash) {
+ if (*sl == escapesym)
+ slash = 1;
+ else if (*sl == s)
+ *sl = t;
+ } else
+ slash = 0;
+ sl++;
+ }
+}
+
+/*
+ * Read STR until end-of-line (not preceded by \).
+ * Find whitespace separated words, and store starts in WORDS of lth MAXN.
+ * Return number of words in N.
+ * Replace each end-of-word by the character EOW (usually \n or 0).
+ * Return pointer to last char seen (either \n or 0).
+ *
+ * A part \"... is skipped.
+ * Quotes not preceded by \ are replaced by \a.
+ */
+static char *
+fill_words(char *str, char *words[], int maxn, int *n, char eow) {
+ char *s = str;
+ int backslash = 0;
+ int skipspace = 0; /* 1 if space is not end-of-word */
+
+ *n = 0;
+ words[*n] = s;
+ while (*s && (*s != '\n' || backslash)) {
+ if (!backslash) {
+ if (*s == '"') {
+ *s = '\a';
+ skipspace = !skipspace;
+ } else if (*s == escapesym) {
+ backslash = 1;
+ } else if ((*s == ' ' || *s == '\t') && !skipspace) {
+ *s = eow;
+ if (words[*n] != s && *n < maxn-1)
+ (*n)++;
+ words[*n] = s+1;
+ }
+ } else {
+ if (*s == '"') {
+ s--;
+ *s = eow;
+ if (words[*n] != s && *n < maxn-1)
+ (*n)++;
+ s++;
+ while (*s && *s != '\n') s++;
+ words[*n] = s;
+ s--;
+ }
+ backslash = 0;
+ }
+ s++;
+ }
+ if (s != words[*n])
+ (*n)++;
+ return s;
+}
+
+
+char *section_list[] = {
+ "1", "User Commands ",
+ "1C", "User Commands",
+ "1G", "User Commands",
+ "1S", "User Commands",
+ "1V", "User Commands ",
+ "2", "System Calls",
+ "2V", "System Calls",
+ "3", "C Library Functions",
+ "3C", "Compatibility Functions",
+ "3F", "Fortran Library Routines",
+ "3K", "Kernel VM Library Functions",
+ "3L", "Lightweight Processes Library",
+ "3M", "Mathematical Library",
+ "3N", "Network Functions",
+ "3R", "RPC Services Library",
+ "3S", "Standard I/O Functions",
+ "3V", "C Library Functions",
+ "3X", "Miscellaneous Library Functions",
+ "4", "Devices and Network Interfaces",
+ "4F", "Protocol Families",
+ "4I", "Devices and Network Interfaces",
+ "4M", "Devices and Network Interfaces",
+ "4N", "Devices and Network Interfaces",
+ "4P", "Protocols",
+ "4S", "Devices and Network Interfaces",
+ "4V", "Devices and Network Interfaces",
+ "5", "File Formats",
+ "5V", "File Formats",
+ "6", "Games and Demos",
+ "7", "Environments, Tables, and Troff Macros",
+ "7V", "Environments, Tables, and Troff Macros",
+ "8", "Maintenance Commands",
+ "8C", "Maintenance Commands",
+ "8S", "Maintenance Commands",
+ "8V", "Maintenance Commands",
+ "L", "Local Commands",
+/* for Solaris:
+ "1", "User Commands",
+ "1B", "SunOS/BSD Compatibility Package Commands",
+ "1b", "SunOS/BSD Compatibility Package Commands",
+ "1C", "Communication Commands ",
+ "1c", "Communication Commands",
+ "1F", "FMLI Commands ",
+ "1f", "FMLI Commands",
+ "1G", "Graphics and CAD Commands ",
+ "1g", "Graphics and CAD Commands ",
+ "1M", "Maintenance Commands",
+ "1m", "Maintenance Commands",
+ "1S", "SunOS Specific Commands",
+ "1s", "SunOS Specific Commands",
+ "2", "System Calls",
+ "3", "C Library Functions",
+ "3B", "SunOS/BSD Compatibility Library Functions",
+ "3b", "SunOS/BSD Compatibility Library Functions",
+ "3C", "C Library Functions",
+ "3c", "C Library Functions",
+ "3E", "C Library Functions",
+ "3e", "C Library Functions",
+ "3F", "Fortran Library Routines",
+ "3f", "Fortran Library Routines",
+ "3G", "C Library Functions",
+ "3g", "C Library Functions",
+ "3I", "Wide Character Functions",
+ "3i", "Wide Character Functions",
+ "3K", "Kernel VM Library Functions",
+ "3k", "Kernel VM Library Functions",
+ "3L", "Lightweight Processes Library",
+ "3l", "Lightweight Processes Library",
+ "3M", "Mathematical Library",
+ "3m", "Mathematical Library",
+ "3N", "Network Functions",
+ "3n", "Network Functions",
+ "3R", "Realtime Library",
+ "3r", "Realtime Library",
+ "3S", "Standard I/O Functions",
+ "3s", "Standard I/O Functions",
+ "3T", "Threads Library",
+ "3t", "Threads Library",
+ "3W", "C Library Functions",
+ "3w", "C Library Functions",
+ "3X", "Miscellaneous Library Functions",
+ "3x", "Miscellaneous Library Functions",
+ "4", "File Formats",
+ "4B", "SunOS/BSD Compatibility Package File Formats",
+ "4b", "SunOS/BSD Compatibility Package File Formats",
+ "5", "Headers, Tables, and Macros",
+ "6", "Games and Demos",
+ "7", "Special Files",
+ "7B", "SunOS/BSD Compatibility Special Files",
+ "7b", "SunOS/BSD Compatibility Special Files",
+ "8", "Maintenance Procedures",
+ "8C", "Maintenance Procedures",
+ "8c", "Maintenance Procedures",
+ "8S", "Maintenance Procedures",
+ "8s", "Maintenance Procedures",
+ "9", "DDI and DKI",
+ "9E", "DDI and DKI Driver Entry Points",
+ "9e", "DDI and DKI Driver Entry Points",
+ "9F", "DDI and DKI Kernel Functions",
+ "9f", "DDI and DKI Kernel Functions",
+ "9S", "DDI and DKI Data Structures",
+ "9s", "DDI and DKI Data Structures",
+ "L", "Local Commands",
+*/
+ NULL, "Misc. Reference Manual Pages",
+ NULL, NULL
+};
+
+static char *
+section_name(char *c)
+{
+ int i=0;
+
+ if (!c) return "";
+ while (section_list[i] && strcmp(c,section_list[i])) i=i+2;
+ if (section_list[i+1]) return section_list[i+1];
+ else return c;
+}
+
+int manidxlen = 0;
+char *manidx = NULL;
+int subs = 0;
+int mip = 0; /* current offset in manidx[] */
+char label[5]="lbAA";
+
+static void
+manidx_need(int m) {
+ if (mip + m >= manidxlen) {
+ manidxlen += 10000;
+ manidx = xrealloc(manidx, manidxlen);
+ }
+}
+
+static void
+add_to_index(int level, char *item)
+{
+ char *c = NULL;
+
+ label[3]++;
+ if (label[3]>'Z') {
+ label[3]='A';
+ label[2]++;
+ }
+
+ if (level != subs) {
+ manidx_need(6);
+ if (subs) {
+ strcpy(manidx+mip, "</DL>\n");
+ mip += 6;
+ } else {
+ strcpy(manidx+mip, "<DL>\n");
+ mip += 5;
+ }
+ }
+ subs = level;
+
+ scan_troff(item, 1, &c);
+ manidx_need(100 + strlen(c));
+ sprintf(manidx+mip, "<DT><A HREF=\"#%s\">%s</A><DD>\n", label, c);
+ if (c) free(c);
+ while (manidx[mip]) mip++;
+}
+
+static char *
+skip_till_newline(char *c)
+{
+ int lvl=0;
+
+ while (*c && (*c!='\n' || lvl>0)) {
+ if (*c=='\\') {
+ c++;
+ if (*c=='}') lvl--; else if (*c=='{') lvl++;
+ }
+ c++;
+ }
+ c++;
+ if (lvl<0 && newline_for_fun) {
+ newline_for_fun = newline_for_fun+lvl;
+ if (newline_for_fun<0) newline_for_fun=0;
+ }
+ return c;
+}
+
+int ifelseval=0;
+
+static char *
+scan_request(char *c) {
+ /* BSD Mandoc stuff - by Michael Hamilton */
+ static int mandoc_synopsis=0; /* True if we are in the synopsis section */
+ static int mandoc_command=0; /* True if this is mandoc page */
+ static int mandoc_bd_options; /* Only copes with non-nested Bd's */
+ static int inXo=0;
+
+ int i,j,mode = 0;
+ char *h;
+ char *wordlist[20];
+ int words;
+ char *sl;
+ STRDEF *owndef;
+
+ while (*c == ' ' || *c == '\t')
+ c++;
+ if (c[0] == '\n')
+ return c+1;
+ if (c[1] == '\n')
+ j = 1;
+ else
+ j = 2;
+ while (c[j] == ' ' || c[j] == '\t')
+ j++;
+ if (c[0] == escapesym) {
+ /* some pages use .\" .\$1 .\} */
+ /* .\$1 is too difficult/stupid */
+ if (c[1] == '$')
+ c = skip_till_newline(c);
+ else
+ c = scan_escape(c+1);
+ } else {
+ i=V(c[0],c[1]);
+ switch (i) {
+ case V('a','b'):
+ h=c+j;
+ while (*h && *h !='\n') h++;
+ *h=0;
+ if (scaninbuff && buffpos) {
+ buffer[buffpos]=0;
+ printf("%s\n", buffer);
+ }
+ fprintf(stderr, "%s\n", c+2); /* XXX */
+ exit(0);
+ break;
+ case V('d','i'):
+ {
+ STRDEF *de;
+ c=c+j;
+ i=V(c[0],c[1]);
+ if (*c == '\n') { c++;break; }
+ while (*c && *c!='\n') c++;
+ c++;
+ h=c;
+ while (*c && strncmp(c,".di",3)) while (*c && *c++!='\n');
+ *c=0;
+ de=strdef;
+ while (de && de->nr !=i) de=de->next;
+ if (!de) {
+ de=(STRDEF*) xmalloc(sizeof(STRDEF));
+ de->nr=i;
+ de->slen=0;
+ de->next=strdef;
+ de->st=NULL;
+ strdef=de;
+ } else {
+ if (de->st) free(de->st);
+ de->slen=0;
+ de->st=NULL;
+ }
+ scan_troff(h,0,&de->st);
+ *c='.';
+ while (*c && *c++!='\n');
+ break;
+ }
+ case V('d','s'):
+ mode=1;
+ case V('a','s'):
+ {
+ STRDEF *de;
+ int oldcurpos=curpos;
+ c=c+j;
+ while (*c == ' ') c++;
+ i=V(c[0],c[1]);
+ j=0;
+ while (c[j] && c[j]!='\n') j++;
+ if (j<3) { c=c+j; break; }
+ if (c[1] == ' ') c=c+1; else c=c+2;
+ while (isspace(*c)) c++;
+ if (*c == '"') c++;
+ de=strdef;
+ while (de && de->nr != i) de=de->next;
+ single_escape=1;
+ curpos=0;
+ if (!de) {
+ char *h;
+ de=(STRDEF*) xmalloc(sizeof(STRDEF));
+ de->nr=i;
+ de->slen=0;
+ de->next=strdef;
+ de->st=NULL;
+ strdef=de;
+ h=NULL;
+ c=scan_troff(c, 1, &h);
+ de->st=h;
+ de->slen=curpos;
+ } else {
+ if (mode) { /* .ds */
+ char *h=NULL;
+ c=scan_troff(c, 1, &h);
+ free(de->st); /* segfault XXX */
+ de->slen=curpos;
+ de->st=h;
+ } else { /* .as */
+ c=scan_troff(c,1,&de->st); /* XXX */
+ de->slen+=curpos;
+ }
+ }
+ single_escape=0;
+ curpos=oldcurpos;
+ }
+ break;
+ case V('b','r'):
+ if (still_dd) out_html("<DD>");
+ else out_html("<BR>\n");
+ curpos=0;
+ c=c+j;
+ if (c[0] == escapesym) { c=scan_escape(c+1); }
+ c=skip_till_newline(c);break;
+ case V('c','2'):
+ c=c+j;
+ if (*c!='\n') { nobreaksym=*c; }
+ else nobreaksym='\'';
+ c=skip_till_newline(c);
+ break;
+ case V('c','c'):
+ c=c+j;
+ if (*c!='\n') { controlsym=*c; }
+ else controlsym='.';
+ c=skip_till_newline(c);
+ break;
+ case V('c','e'):
+ c=c+j;
+ if (*c == '\n') { i=1; }
+ else {
+ i=0;
+ while ('0'<=*c && *c<='9') {
+ i=i*10+*c-'0';
+ c++;
+ }
+ }
+ c=skip_till_newline(c);
+ /* center next i lines */
+ if (i>0) {
+ out_html("<CENTER>\n");
+ while (i && *c) {
+ char *line=NULL;
+ c=scan_troff(c,1, &line);
+ if (line && strncmp(line, "<BR>", 4)) {
+ out_html(line);
+ out_html("<BR>\n");
+ i--;
+ }
+ }
+ out_html("</CENTER>\n");
+ curpos=0;
+ }
+ break;
+ case V('e','c'):
+ c=c+j;
+ if (*c!='\n') { escapesym=*c; }
+ else escapesym='\\';
+ break;
+ c=skip_till_newline(c);
+ case V('e','o'):
+ escapesym=0;
+ c=skip_till_newline(c);
+ break;
+ case V('e','x'):
+ exit(0);
+ break;
+ case V('f','c'):
+ c=c+j;
+ if (*c == '\n') {
+ fieldsym=padsym=0;
+ } else {
+ fieldsym=c[0];
+ padsym=c[1];
+ }
+ c=skip_till_newline(c);
+ break;
+ case V('f','i'):
+ if (!fillout) {
+ out_html(change_to_font(0));
+ out_html(change_to_size('0'));
+ out_html("</PRE>\n");
+ }
+ curpos=0;
+ fillout=1;
+ c=skip_till_newline(c);
+ break;
+ case V('f','t'):
+ c=c+j;
+ if (*c == '\n') {
+ out_html(change_to_font(0));
+ } else {
+ if (*c == escapesym) {
+ int fn;
+ c=scan_expression(c, &fn);
+ c--;
+ out_html(change_to_font(fn));
+ } else {
+ out_html(change_to_font(*c));
+ c++;
+ }
+ }
+ c=skip_till_newline(c);
+ break;
+ case V('e','l'):
+ /* .el anything : else part of if else */
+ if (ifelseval) {
+ c=c+j;
+ c[-1]='\n';
+ c=scan_troff(c,1,NULL);
+ } else
+ c=skip_till_newline(c+j);
+ break;
+ case V('i','e'):
+ /* .ie c anything : then part of if else */
+ case V('i','f'):
+ /* .if c anything
+ * .if !c anything
+ * .if N anything
+ * .if !N anything
+ * .if 'string1'string2' anything
+ * .if !'string1'string2' anything
+ */
+ c=c+j;
+ c=scan_expression(c, &i);
+ ifelseval=!i;
+ if (i) {
+ *c='\n';
+ c++;
+ c=scan_troff(c,1,NULL);
+ } else
+ c=skip_till_newline(c);
+ break;
+ case V('i','g'): /* .ig: ignore until .. */
+ {
+ char *endwith="..\n";
+ i=3;
+ c=c+j;
+ while (*c == ' ') c++;
+ if (*c == escapesym && c[1] == '"')
+ while (*c != '\n') c++;
+ if (*c!='\n') { /* .ig yy: ignore until .yy, then call .yy */
+ endwith=c-1;i=1;
+ c[-1]='.';
+ while (*c && *c!='\n') c++,i++;
+ }
+ c++;
+ while (*c && strncmp(c,endwith,i))
+ while (*c && *c++!='\n');
+ while (*c && *c++!='\n');
+ break;
+ }
+ case V('n','f'):
+ if (fillout) {
+ out_html(change_to_font(0));
+ out_html(change_to_size('0'));
+ out_html("<PRE>\n");
+ }
+ curpos=0;
+ fillout=0;
+ c=skip_till_newline(c);
+ break;
+ case V('p','s'):
+ c=c+j;
+ if (*c == '\n') {
+ out_html(change_to_size('0'));
+ } else {
+ j=0;i=0;
+ if (*c == '-') { j= -1;c++; } else if (*c == '+') { j=1;c++;}
+ c=scan_expression(c, &i);
+ if (!j) { j=1; if (i>5) i=i-10; }
+ out_html(change_to_size(i*j));
+ }
+ c=skip_till_newline(c);
+ break;
+ case V('s','p'):
+ c=c+j;
+ if (fillout) out_html("<P>"); else {
+ out_html(NEWLINE);
+ NEWLINE[0]='\n';
+ }
+ curpos=0;
+ c=skip_till_newline(c);
+ break;
+ case V('s','o'):
+ {
+ FILE *f;
+ struct stat stbuf;
+ int l; char *buf;
+ char *name = NULL;
+
+ curpos=0;
+ c += j; /* skip .so part and whitespace */
+ if (*c == '/') {
+ h = c;
+ } else { /* .so man3/cpow.3 -> ../man3/cpow.3 */
+ h = c-3;
+ h[0] = '.';
+ h[1] = '.';
+ h[2] = '/';
+ }
+ while (*c != '\n') c++;
+ while (c[-1] == ' ') c--;
+ while (*c != '\n') *c++ = 0;
+ *c = 0;
+ scan_troff(h,1, &name);
+ if (name[3] == '/') h=name+3; else h=name;
+ l = 0;
+ if (stat(h, &stbuf)!=-1) l=stbuf.st_size;
+ buf = (char*) xmalloc((l+4)*sizeof(char));
+#if NOCGI
+ if (!out_length) {
+ char *t,*s;
+ t=strrchr(fname, '/');
+ if (!t) t=fname;
+ fprintf(stderr, "ln -s %s.html %s.html\n", h, t);
+ s=strrchr(t, '.');if (!s) s=t;
+ printf("<HTML><HEAD><TITLE> Manpage of %s</TITLE>\n"
+ "</HEAD><BODY>\n"
+ "See the manpage for <A HREF=\"%s.html\">%s</A>.\n"
+ "</BODY></HTML>\n",
+ s, h, h);
+ } else
+#endif
+ {
+ /* this works alright, except for section 3 */
+ if (!l || !(f = fopen(h,"r"))) {
+ fprintf(stderr,
+ "man2html: unable to open or read file %s\n", h);
+ out_html("<BLOCKQUOTE>"
+ "man2html: unable to open or read file\n");
+ out_html(h);
+ out_html("</BLOCKQUOTE>\n");
+ } else {
+ i=fread(buf+1,1,l,f);
+ fclose(f);
+ buf[0]=buf[l]='\n';
+ buf[l+1]=buf[l+2]=0;
+ scan_troff(buf+1,0,NULL);
+ }
+ if (buf) free(buf);
+ }
+ *c++='\n';
+ break;
+ }
+ case V('t','a'):
+ c=c+j;
+ j=0;
+ while (*c!='\n') {
+ sl=scan_expression(c, &tabstops[j]);
+ if (*c == '-' || *c == '+') tabstops[j]+=tabstops[j-1];
+ c=sl;
+ while (*c == ' ' || *c == '\t') c++;
+ if (j+1 < SIZE(tabstops))
+ j++;
+ }
+ maxtstop=j;
+ curpos=0;
+ break;
+ case V('t','i'):
+#if 0
+ dl_down();
+#endif
+ out_html("<BR>\n");
+ c=c+j;
+ c=scan_expression(c, &j);
+ for (i=0; i<j; i++) out_html("&nbsp;");
+ curpos=j;
+ c=skip_till_newline(c);
+ break;
+ case V('t','m'):
+ c=c+j;
+ h=c;
+ while (*c!='\n') c++;
+ *c=0;
+ fprintf(stderr,"%s\n", h); /* XXX */
+ *c='\n';
+ break;
+ case V('B',' '):
+ case V('B','\n'):
+ case V('I',' '):
+ case V('I','\n'):
+ /* parse one line in a certain font */
+ out_html(change_to_font(*c));
+ trans_char(c, '"', '\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ c=scan_troff(c, 1, NULL);
+ out_html(change_to_font('R'));
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('O','P'): /* groff manpages use this construction */
+ /* .OP a b : [ <B>a</B> <I>b</I> ] */
+ mode=1;
+ c[0]='B'; c[1]='I';
+ out_html(change_to_font('R'));
+ out_html("[");
+ curpos++;
+ case V('B','R'):
+ case V('B','I'):
+ case V('I','B'):
+ case V('I','R'):
+ case V('R','B'):
+ case V('R','I'):
+ {
+ char font[2];
+ font[0] = c[0]; font[1] = c[1];
+ c = c+j;
+ if (*c == '\n') c++;
+ sl = fill_words(c, wordlist, SIZE(wordlist), &words, '\n');
+ c = sl+1;
+ /* .BR name (section)
+ ** indicates a link. It will be added in the output routine.
+ */
+ for (i=0; i<words; i++) {
+ if (mode) { out_html(" "); curpos++; }
+ wordlist[i][-1]=' ';
+ out_html(change_to_font(font[i&1]));
+ scan_troff(wordlist[i],1,NULL);
+ }
+ out_html(change_to_font('R'));
+ if (mode) { out_html(" ]"); curpos++;}
+ out_html(NEWLINE); if (!fillout) curpos=0; else curpos++;
+ }
+ break;
+ case V('D','T'):
+ maxtstop = SIZE(tabstops);
+ for (j=0; j<maxtstop; j++)
+ tabstops[j]=(j+1)*8;
+ c=skip_till_newline(c); break;
+ case V('I','P'):
+ sl = fill_words(c+j, wordlist, SIZE(wordlist), &words, '\n');
+ c = sl+1;
+ dl_begin();
+ if (words) {
+ scan_troff(wordlist[0], 1,NULL);
+ }
+ out_html("<DD>");
+ curpos = 0;
+ break;
+ case V('T','P'):
+ dl_begin();
+ c=skip_till_newline(c);
+ /* somewhere a definition ends with '.TP' */
+ if (!*c) still_dd=1; else {
+ c=scan_troff(c,1,NULL);
+ out_html("<DD>");
+ }
+ curpos=0;
+ break;
+ case V('I','X'):
+ /* general index */
+ sl = fill_words(c+j, wordlist, SIZE(wordlist), &words, '\n');
+ c = sl+1;
+ j = 4;
+ while (idxlabel[j] == 'Z') idxlabel[j--]='A';
+ idxlabel[j]++;
+#ifdef MAKEINDEX
+ if (idxfile) {
+ fprintf(idxfile, "%s@%s@", fname, idxlabel);
+ for (j=0; j<words; j++) {
+ h=NULL;
+ scan_troff(wordlist[j], 1, &h);
+ fprintf(idxfile, "_\b@%s", h);
+ free(h);
+ }
+ fprintf(idxfile,"\n");
+ }
+#endif
+ out_html("<A NAME=\"");
+ out_html(idxlabel);
+ /* this will not work in mosaic (due to a bug).
+ ** Adding '&nbsp;' between '>' and '<' solves it, but creates
+ ** some space. A normal space does not work.
+ */
+ out_html("\"></A>");
+ break;
+ case V('L','P'):
+ case V('P','P'):
+ dl_end();
+ if (fillout) out_html("<P>\n"); else {
+ out_html(NEWLINE);
+ NEWLINE[0]='\n';
+ }
+ curpos=0;
+ c=skip_till_newline(c);
+ break;
+ case V('H','P'):
+ dl_begin();
+ still_dd=1;
+ c=skip_till_newline(c);
+ curpos=0;
+ break;
+ case V('P','D'):
+ c=skip_till_newline(c);
+ break;
+ case V('R','s'): /* BSD mandoc */
+ case V('R','S'):
+ sl = fill_words(c+j, wordlist, SIZE(wordlist), &words, '\n');
+ j = 1;
+ if (words>0) scan_expression(wordlist[0], &j);
+ if (j>=0) {
+ dl_newlevel();
+ c=skip_till_newline(c);
+ curpos=0;
+ break;
+ }
+ case V('R','e'): /* BSD mandoc */
+ case V('R','E'):
+ dl_endlevel();
+ c=skip_till_newline(c);
+ curpos=0;
+ break;
+ case V('S','B'):
+ out_html(change_to_size(-1));
+ out_html(change_to_font('B'));
+ c=scan_troff(c+j, 1, NULL);
+ out_html(change_to_font('R'));
+ out_html(change_to_size('0'));
+ break;
+ case V('S','M'):
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html(change_to_size(-1));
+ trans_char(c,'"','\a');
+ c=scan_troff(c,1,NULL);
+ out_html(change_to_size('0'));
+ break;
+ case V('S','s'): /* BSD mandoc */
+ mandoc_command = 1;
+ case V('S','S'):
+ mode=1;
+ goto sh_below;
+ case V('S','h'): /* BSD mandoc */
+ mandoc_command = 1;
+ case V('S','H'):
+ sh_below:
+ c=c+j;
+ if (*c == '\n') c++;
+ dl_down();
+ out_html(change_to_font(0));
+ out_html(change_to_size(0));
+ if (!fillout) {
+ fillout=1;
+ out_html("</PRE>");
+ }
+ trans_char(c,'"', '\a');
+ add_to_index(mode, c);
+ out_html("<A NAME=\"");
+ out_html(label);
+ /* &nbsp; for mosaic users */
+ if (mode) out_html("\">&nbsp;</A>\n<H3>");
+ else out_html("\">&nbsp;</A>\n<H2>");
+ mandoc_synopsis = (strncmp(c, "SYNOPSIS", 8) == 0);
+ c = (mandoc_command ? scan_troff_mandoc : scan_troff)(c,1,NULL);
+ if (mode) out_html("</H3>\n");
+ else out_html("</H2>\n");
+ curpos=0;
+ break;
+ case V('T','S'):
+ c=scan_table(c);
+ break;
+ case V('D','t'): /* BSD mandoc */
+ mandoc_command = 1;
+ case V('T','H'):
+ if (!output_possible) {
+ sl = fill_words(c+j, wordlist, SIZE(wordlist), &words, 0);
+ *sl = 0;
+ if (words > 1) {
+ output_possible=1;
+ out_html("<HTML><HEAD><TITLE>Manpage of ");
+ out_html(wordlist[0]);
+ out_html("</TITLE>\n</HEAD><BODY>\n<H1>");
+ out_html(wordlist[0]);
+ out_html("</H1>\nSection: ");
+ if (words>4)
+ out_html(wordlist[4]);
+ else
+ out_html(section_name(wordlist[1]));
+ out_html(" (");
+ out_html(wordlist[1]);
+ if (words>2) {
+ out_html(")<BR>Updated: ");
+ scan_troff(wordlist[2], 1, NULL);
+ } else out_html(")");
+ out_html("<BR><A HREF=\"#index\">Index</A>\n");
+ man_page_html(0,0); /* Return to Main Contents */
+ *sl='\n';
+ out_html("<HR>\n");
+ if (mandoc_command) out_html("<BR>BSD mandoc<BR>");
+ }
+ c = sl+1;
+ } else
+ c = skip_till_newline(c);
+ curpos=0;
+ break;
+ case V('T','X'):
+ sl=fill_words(c+j, wordlist, SIZE(wordlist), &words, '\n');
+ *sl=0;
+ out_html(change_to_font('I'));
+ if (words>1) wordlist[1][-1]=0;
+ c=lookup_abbrev(wordlist[0]);
+ curpos+=strlen(c);
+ out_html(c);
+ out_html(change_to_font('R'));
+ if (words>1)
+ out_html(wordlist[1]);
+ *sl='\n';
+ c=sl+1;
+ break;
+ case V('r','m'):
+ /* .rm xx : Remove request, macro or string */
+ case V('r','n'):
+ /* .rn xx yy : Rename request, macro or string xx to yy */
+ {
+ STRDEF *de;
+ c=c+j;
+ i=V(c[0],c[1]);
+ c=c+2;
+ while (isspace(*c) && *c!='\n') c++;
+ j=V(c[0],c[1]);
+ while (*c && *c!='\n') c++;
+ c++;
+ de=strdef;
+ while (de && de->nr!=j) de=de->next;
+ if (de) {
+ if (de->st) free(de->st);
+ de->nr=0;
+ }
+ de=strdef;
+ while (de && de->nr!=i) de=de->next;
+ if (de) de->nr=j;
+ break;
+ }
+ case V('n','x'):
+ /* .nx filename : next file. */
+ case V('i','n'):
+ /* .in +-N : Indent */
+ c=skip_till_newline(c);
+ break;
+ case V('n','r'):
+ /* .nr R +-N M: define and set number register R by +-N;
+ ** auto-increment by M
+ */
+ {
+ INTDEF *intd;
+ c=c+j;
+ i=V(c[0],c[1]);
+ c=c+2;
+ intd=intdef;
+ while (intd && intd->nr!=i) intd=intd->next;
+ if (!intd) {
+ intd = (INTDEF*) xmalloc(sizeof(INTDEF));
+ intd->nr=i;
+ intd->val=0;
+ intd->incr=0;
+ intd->next=intdef;
+ intdef=intd;
+ }
+ while (*c == ' ' || *c == '\t') c++;
+ c=scan_expression(c,&intd->val);
+ if (*c!='\n') {
+ while (*c == ' ' || *c == '\t') c++;
+ c=scan_expression(c,&intd->incr);
+ }
+ c=skip_till_newline(c);
+ break;
+ }
+ case V('a','m'):
+ /* .am xx yy : append to a macro. */
+ /* define or handle as .ig yy */
+ mode=1;
+ case V('d','e'):
+ /* .de xx yy : define or redefine macro xx; end at .yy (..) */
+ /* define or handle as .ig yy */
+ {
+ STRDEF *de;
+ int olen=0;
+ c=c+j;
+ sl=fill_words(c, wordlist, SIZE(wordlist), &words, '\n');
+ i=V(c[0],c[1]);j=2;
+ if (words == 1) wordlist[1]=".."; else {
+ wordlist[1]--;
+ wordlist[1][0]='.';
+ j=3;
+ }
+ c=sl+1;
+ sl=c;
+ while (*c && strncmp(c,wordlist[1],j)) c=skip_till_newline(c);
+ de=defdef;
+ while (de && de->nr!= i) de=de->next;
+ if (mode && de) olen=strlen(de->st);
+ j=olen+c-sl;
+ h= (char*) xmalloc((j*2+4)*sizeof(char));
+ if (h) {
+ for (j=0; j<olen; j++)
+ h[j]=de->st[j];
+ if (!j || h[j-1]!='\n')
+ h[j++]='\n';
+ while (sl!=c) {
+ if (sl[0] == '\\' && sl[1] == '\\') {
+ h[j++]='\\'; sl++;
+ } else
+ h[j++]=*sl;
+ sl++;
+ }
+ h[j]=0;
+ if (de) {
+ if (de->st) free(de->st);
+ de->st=h;
+ } else {
+ de = (STRDEF*) xmalloc(sizeof(STRDEF));
+ de->nr=i;
+ de->next=defdef;
+ de->st=h;
+ defdef=de;
+ }
+ }
+ }
+ c=skip_till_newline(c);
+ break;
+
+ /* ----- BSD mandoc stuff below ----- */
+ case V('U','x'): /* BSD mandoc */
+ c=c+j;
+ out_html("UNIX");
+ c=skip_till_newline(c);
+ break;
+ case V('A','t'): /* BSD mandoc - called with arg V */
+ c=c+j;
+ out_html("AT&amp;T System");
+ break;
+ case V('B','l'): /* BSD mandoc */
+ {
+ char *nl, t=0 /* just for gcc */;
+ c=c+j;
+ nl = strchr(c,'\n');
+ if (nl) {
+ t = *nl;
+ *nl = 0;
+ }
+ if (strstr(c, "-bullet")) /* HTML Unnumbered List */
+ dl_newlevel_type(UL);
+ else if (strstr(c, "-enum")) /* HTML Ordered List */
+ dl_newlevel_type(OL);
+ else /* HTML Descriptive List */
+ dl_newlevel_type(DL);
+ if (nl)
+ *nl = t;
+ if (fillout) out_html("<P>\n"); else {
+ out_html(NEWLINE);
+ NEWLINE[0]='\n';
+ }
+ curpos=0;
+ c=skip_till_newline(c);
+ break;
+ }
+ case V('E','l'): /* BSD mandoc */
+ c=c+j;
+ dl_endlevel_type();
+ if (fillout) out_html("<P>\n"); else {
+ out_html(NEWLINE);
+ NEWLINE[0]='\n';
+ }
+ curpos=0;
+ c=skip_till_newline(c);
+ break;
+ case V('I','t'): /* BSD mandoc */
+ c=c+j;
+ if (dl_type(DL)) {
+ out_html("<DT>");
+ out_html(change_to_font('B'));
+ if (*c == '\n') {
+ /* Don't allow embedded comms after a newline */
+ c++;
+ c=scan_troff(c,1,NULL);
+ } else {
+ /* Do allow embedded comms on the same line. */
+ c=scan_troff_mandoc(c,1,NULL);
+ }
+ out_html(change_to_font('R'));
+ out_html(NEWLINE);
+ if (inXo)
+ still_dd = 1;
+ else
+ out_html("<DD>");
+ } else if (dl_type(UL) || dl_type(OL)) {
+ out_html("<LI>");
+ c=scan_troff_mandoc(c,1,NULL);
+ out_html(NEWLINE);
+ }
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('X','o'): /* BSD mandoc */
+ c=c+j;
+ inXo = 1;
+ break;
+ case V('X','c'): /* BSD mandoc - Xc closes an Xo */
+ c=c+j;
+ if (inXo) {
+ if (still_dd)
+ out_html("<DD>");
+ inXo = 0;
+ }
+ break;
+ case V('S','m'): /* BSD mandoc - called with arg on/off */
+ c=skip_till_newline(c);
+ break;
+ case V('B','k'): /* BSD mandoc */
+ case V('E','k'): /* BSD mandoc */
+ case V('D','d'): /* BSD mandoc */
+ case V('O','s'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('B','t'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ out_html(" is currently in beta test.");
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('B','x'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html("BSD ");
+ c=scan_troff_mandoc(c, 1, NULL);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('D','l'): /* BSD mandoc */
+ c=c+j;
+ out_html(NEWLINE);
+ out_html("<BLOCKQUOTE>");
+ out_html(change_to_font('L'));
+ if (*c == '\n') c++;
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(change_to_font('R'));
+ out_html("</BLOCKQUOTE>");
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('B','d'): /* BSD mandoc */
+ { /* Seems like a kind of example/literal mode */
+ char *nl, t=0 /* just for gcc */;
+ c=c+j;
+ nl = strchr(c,'\n');
+ if (nl) {
+ t = *nl;
+ *nl = 0;
+ }
+ out_html(NEWLINE);
+ mandoc_bd_options = 0; /* Remember options for terminating Bl */
+ if (strstr(c, "-offset indent")) {
+ mandoc_bd_options |= BD_INDENT;
+ out_html("<BLOCKQUOTE>\n");
+ }
+ if (strstr(c, "-literal") || strstr(c, "-unfilled")) {
+ if (fillout) {
+ mandoc_bd_options |= BD_LITERAL;
+ out_html(change_to_font(0));
+ out_html(change_to_size('0'));
+ out_html("<PRE>\n");
+ }
+ curpos=0;
+ fillout=0;
+ }
+ if (nl)
+ *nl = t;
+ c=skip_till_newline(c);
+ break;
+ }
+ case V('E','d'): /* BSD mandoc */
+ if (mandoc_bd_options & BD_LITERAL) {
+ if (!fillout) {
+ out_html(change_to_font(0));
+ out_html(change_to_size('0'));
+ out_html("</PRE>\n");
+ }
+ }
+ if (mandoc_bd_options & BD_INDENT)
+ out_html("</BLOCKQUOTE>\n");
+ curpos=0;
+ fillout=1;
+ c=skip_till_newline(c);
+ break;
+ case V('B','e'): /* BSD mandoc */
+ c=c+j;
+ if (fillout) out_html("<P>"); else {
+ out_html(NEWLINE);
+ NEWLINE[0]='\n';
+ }
+ curpos=0;
+ c=skip_till_newline(c);
+ break;
+ case V('X','r'): /* BSD mandoc */
+ {
+ /* Translate xyz 1 to xyz(1)
+ * Allow for multiple spaces. Allow the section to be missing.
+ */
+ char buff[100];
+ char *bufptr;
+ trans_char(c,'"','\a');
+ bufptr = buff;
+ c = c+j;
+ if (*c == '\n') c++; /* Skip spaces */
+ while (isspace(*c) && *c != '\n') c++;
+ while (isalnum(*c) && bufptr < buff + SIZE(buff)-4) {
+ /* Copy the xyz part */
+ *bufptr++ = *c++;
+ }
+ while (isspace(*c) && *c != '\n') c++; /* Skip spaces */
+ if (isdigit(*c)) { /* Convert the number if there is one */
+ *bufptr++ = '(';
+ while (isalnum(*c) && bufptr < buff + SIZE(buff)-3) {
+ *bufptr++ = *c++;
+ }
+ *bufptr++ = ')';
+ }
+ while (*c != '\n' && bufptr < buff + SIZE(buff)-2) {
+ /* Copy the remainder */
+ if (!isspace(*c)) {
+ *bufptr++ = *c;
+ }
+ c++;
+ }
+ *bufptr++ = '\n';
+ *bufptr = 0;
+ scan_troff_mandoc(buff, 1, NULL);
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ }
+ break;
+ case V('F','l'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ out_html("-");
+ if (*c!='\n') {
+ out_html(change_to_font('B'));
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(change_to_font('R'));
+ }
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('P','a'): /* BSD mandoc */
+ case V('P','f'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('P','p'): /* BSD mandoc */
+ if (fillout) out_html("<P>\n"); else {
+ out_html(NEWLINE);
+ NEWLINE[0]='\n';
+ }
+ curpos=0;
+ c=skip_till_newline(c);
+ break;
+ case V('D','q'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html("``");
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html("''");
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('O','p'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html(change_to_font('R'));
+ out_html("[");
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(change_to_font('R'));
+ out_html("]");
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('O','o'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html(change_to_font('R'));
+ out_html("[");
+ c=scan_troff_mandoc(c, 1, NULL);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('O','c'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(change_to_font('R'));
+ out_html("]");
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('P','q'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html("(");
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(")");
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('Q','l'): /* BSD mandoc */
+ { /* Single quote first word in the line */
+ char *sp;
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ sp = c;
+ do { /* Find first whitespace after the
+ * first word that isn't a mandoc macro
+ */
+ while (*sp && isspace(*sp)) sp++;
+ while (*sp && !isspace(*sp)) sp++;
+ } while (*sp && isupper(*(sp-2)) && islower(*(sp-1)));
+
+ /* Use a newline to mark the end of text to
+ * be quoted
+ */
+ if (*sp) *sp = '\n';
+ out_html("`"); /* Quote the text */
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html("'");
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ }
+ case V('S','q'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html("`");
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html("'");
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('A','r'): /* BSD mandoc */
+ /* parse one line in italics */
+ out_html(change_to_font('I'));
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') { /* An empty Ar means "file ..." */
+ out_html("file ...");
+ } else {
+ c=scan_troff_mandoc(c, 1, NULL);
+ }
+ out_html(change_to_font('R'));
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('A','d'): /* BSD mandoc */
+ case V('E','m'): /* BSD mandoc */
+ case V('V','a'): /* BSD mandoc */
+ /* parse one line in italics */
+ out_html(change_to_font('I'));
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(change_to_font('R'));
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('N','d'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html(" - ");
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('N','m'): /* BSD mandoc */
+ {
+ static char *mandoc_name = 0;
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (mandoc_synopsis) {
+ /*
+ * Break lines only in the Synopsis.
+ * The Synopsis section seems to be treated
+ * as a special case - Bummer!
+ */
+ static int count = 0; /* Don't break on the first Nm */
+ if (count) {
+ out_html("<BR>");
+ } else {
+ char *end, t=0 /* just for gcc */;
+ end = strchr(c, '\n');
+ if (end) {
+ t = *end;
+ *end = 0;
+ }
+ if (mandoc_name)
+ free(mandoc_name);
+ mandoc_name = xstrdup(c);
+ if (end)
+ *end = t;
+ }
+ count++;
+ }
+ out_html(change_to_font('B'));
+ while (*c == ' ' || *c == '\t') c++;
+ if (*c == '\n') {
+ /*
+ * If Nm has no argument, use one from an earlier
+ * Nm command that did have one. Hope there aren't
+ * too many commands that do this.
+ */
+ if (mandoc_name)
+ out_html(mandoc_name);
+ } else {
+ c=scan_troff_mandoc(c, 1, NULL);
+ }
+ out_html(change_to_font('R'));
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ }
+ case V('C','d'): /* BSD mandoc */
+ case V('C','m'): /* BSD mandoc */
+ case V('I','c'): /* BSD mandoc */
+ case V('M','s'): /* BSD mandoc */
+ case V('O','r'): /* BSD mandoc */
+ case V('S','y'): /* BSD mandoc */
+ /* parse one line in bold */
+ out_html(change_to_font('B'));
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(change_to_font('R'));
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('D','v'): /* BSD mandoc */
+ case V('E','v'): /* BSD mandoc */
+ case V('F','r'): /* BSD mandoc */
+ case V('L','i'): /* BSD mandoc */
+ case V('N','o'): /* BSD mandoc */
+ case V('N','s'): /* BSD mandoc */
+ case V('T','n'): /* BSD mandoc */
+ case V('n','N'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html(change_to_font('B'));
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(change_to_font('R'));
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('%','A'): /* BSD mandoc biblio stuff */
+ case V('%','D'):
+ case V('%','N'):
+ case V('%','O'):
+ case V('%','P'):
+ case V('%','Q'):
+ case V('%','V'):
+ c=c+j;
+ if (*c == '\n') c++;
+ c=scan_troff(c, 1, NULL); /* Don't allow embedded mandoc coms */
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('%','B'):
+ case V('%','J'):
+ case V('%','R'):
+ case V('%','T'):
+ c=c+j;
+ out_html(change_to_font('I'));
+ if (*c == '\n') c++;
+ c=scan_troff(c, 1, NULL); /* Don't allow embedded mandoc coms */
+ out_html(change_to_font('R'));
+ if (fillout) curpos++; else curpos=0;
+ break;
+ /* ----- end of BSD mandoc stuff ----- */
+
+ default:
+ /* search macro database of self-defined macros */
+ owndef = defdef;
+ while (owndef && owndef->nr!=i) owndef=owndef->next;
+ if (owndef) {
+ char **oldargument;
+ int deflen;
+ int onff;
+ sl=fill_words(c+j, wordlist, SIZE(wordlist), &words, '\n');
+ c=sl+1;
+ *sl=0;
+ for (i=1; i<words; i++)
+ wordlist[i][-1]=0;
+ for (i=0; i<words; i++) {
+ char *h=NULL;
+ if (mandoc_command)
+ scan_troff_mandoc(wordlist[i],1,&h);
+ else
+ scan_troff(wordlist[i],1,&h);
+ wordlist[i]=h;
+ }
+ for (i=words; i<SIZE(wordlist); i++)
+ wordlist[i]=NULL;
+ deflen = strlen(owndef->st);
+ owndef->st[deflen+1]='a';
+ for (i=0; (owndef->st[deflen+2+i] = owndef->st[i]); i++);
+ oldargument=argument;
+ argument=wordlist;
+ onff=newline_for_fun;
+ if (mandoc_command)
+ scan_troff_mandoc(owndef->st+deflen+2, 0, NULL);
+ else
+ scan_troff(owndef->st+deflen+2, 0, NULL);
+ newline_for_fun=onff;
+ argument=oldargument;
+ for (i=0; i<words; i++) if (wordlist[i]) free(wordlist[i]);
+ *sl='\n';
+ } else if (mandoc_command &&
+ ((isupper(*c) && islower(c[1]))
+ || (islower(*c) && isupper(c[1])))) {
+ /*
+ * Let through any BSD mandoc commands that haven't
+ * been dealt with.
+ * I don't want to miss anything out of the text.
+ */
+ char buf[4];
+ strncpy(buf,c,2);
+ buf[2] = ' ';
+ buf[3] = 0;
+ out_html(buf); /* Print the command (it might just be text). */
+ c=c+j;
+ trans_char(c,'"','\a');
+ if (*c == '\n') c++; /* really? */
+ out_html(change_to_font('R'));
+ c=scan_troff(c, 1, NULL);
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ } else
+ c=skip_till_newline(c);
+ break;
+ }
+ }
+ if (fillout) { out_html(NEWLINE); curpos++; }
+ NEWLINE[0]='\n';
+ return c;
+}
+
+static int contained_tab=0;
+static int mandoc_line=0;/* Signals whether to look for embedded mandoc cmds */
+
+static char *
+scan_troff(char *c, int san, char **result) { /* san : stop at newline */
+ char *h;
+ char intbuff[500];
+ int ibp=0;
+#define FLUSHIBP if (ibp) { intbuff[ibp]=0; out_html(intbuff); ibp=0; }
+ char *exbuffer;
+ int exbuffpos, exbuffmax, exscaninbuff, exnewline_for_fun;
+ int usenbsp = 0;
+
+ exbuffer = buffer;
+ exbuffpos = buffpos;
+ exbuffmax = buffmax;
+ exnewline_for_fun = newline_for_fun;
+ exscaninbuff = scaninbuff;
+ newline_for_fun = 0;
+ if (result) {
+ if (*result) {
+ buffer = *result;
+ buffpos = strlen(buffer);
+ buffmax = buffpos;
+ } else {
+ buffer = (char *) xmalloc(1000*sizeof(char));
+ buffpos = 0;
+ buffmax = 1000;
+ }
+ scaninbuff = 1;
+ }
+ h = c;
+ /* start scanning */
+ while (*h && (!san || newline_for_fun || *h != '\n')) {
+ if (*h == escapesym) {
+ h++;
+ FLUSHIBP;
+ h = scan_escape(h);
+ } else if (*h == controlsym && h[-1] == '\n') {
+ h++;
+ FLUSHIBP;
+ h = scan_request(h);
+ if (san && h[-1] == '\n') h--;
+ } else if (mandoc_line
+ && *(h) && isupper(*(h))
+ && *(h+1) && islower(*(h+1))
+ && *(h+2) && isspace(*(h+2))) {
+ /* BSD imbedded command eg ".It Fl Ar arg1 Fl Ar arg2" */
+ FLUSHIBP;
+ h = scan_request(h);
+ if (san && h[-1] == '\n') h--;
+ } else if (*h == nobreaksym && h[-1] == '\n') {
+ h++;
+ FLUSHIBP;
+ h = scan_request(h);
+ if (san && h[-1] == '\n') h--;
+ } else {
+ if (h[-1] == '\n' && still_dd && isalnum(*h)) {
+ /* sometimes a .HP request is not followed by a .br request */
+ FLUSHIBP;
+ out_html("<DD>");
+ curpos=0;
+ still_dd=0;
+ }
+ switch (*h) {
+ case '&':
+ intbuff[ibp++]='&';
+ intbuff[ibp++]='a';
+ intbuff[ibp++]='m';
+ intbuff[ibp++]='p';
+ intbuff[ibp++]=';';
+ curpos++;
+ break;
+ case '<':
+ intbuff[ibp++]='&';
+ intbuff[ibp++]='l';
+ intbuff[ibp++]='t';
+ intbuff[ibp++]=';';
+ curpos++;
+ break;
+ case '>':
+ intbuff[ibp++]='&';
+ intbuff[ibp++]='g';
+ intbuff[ibp++]='t';
+ intbuff[ibp++]=';';
+ curpos++;
+ break;
+ case '"':
+ intbuff[ibp++]='&';
+ intbuff[ibp++]='q';
+ intbuff[ibp++]='u';
+ intbuff[ibp++]='o';
+ intbuff[ibp++]='t';
+ intbuff[ibp++]=';';
+ curpos++;
+ break;
+ case '\n':
+ if (h[-1] == '\n' && fillout) {
+ intbuff[ibp++]='<';
+ intbuff[ibp++]='P';
+ intbuff[ibp++]='>';
+ }
+ if (contained_tab && fillout) {
+ intbuff[ibp++]='<';
+ intbuff[ibp++]='B';
+ intbuff[ibp++]='R';
+ intbuff[ibp++]='>';
+ }
+ contained_tab=0;
+ curpos=0;
+ usenbsp=0;
+ intbuff[ibp++]='\n';
+ break;
+ case '\t':
+ {
+ int curtab=0;
+ contained_tab=1;
+ FLUSHIBP;
+ /* like a typewriter, not like TeX */
+ tabstops[SIZE(tabstops)-1] = curpos+1;
+ while (curtab < maxtstop && tabstops[curtab] <= curpos)
+ curtab++;
+ if (curtab < maxtstop) {
+ if (!fillout) {
+ while (curpos<tabstops[curtab]) {
+ intbuff[ibp++]=' ';
+ if (ibp>480) { FLUSHIBP; }
+ curpos++;
+ }
+ } else {
+ out_html("<TT>");
+ while (curpos < tabstops[curtab]) {
+ out_html("&nbsp;");
+ curpos++;
+ }
+ out_html("</TT>");
+ }
+ }
+ }
+ break;
+ default:
+ if (*h == ' ' && (h[-1] == '\n' || usenbsp)) {
+ FLUSHIBP;
+ if (!usenbsp && fillout) {
+ out_html("<BR>");
+ curpos=0;
+ }
+ usenbsp=fillout;
+ if (usenbsp) out_html("&nbsp;"); else intbuff[ibp++]=' ';
+ } else if (*h > 31 && *h < 127) {
+ intbuff[ibp++]=*h;
+ } else if (((unsigned char)(*h)) > 127) {
+#ifdef NO_8BIT
+ intbuff[ibp++]='&';
+ intbuff[ibp++]='#';
+ intbuff[ibp++]='0'+((unsigned char)(*h))/100;
+ intbuff[ibp++]='0'+(((unsigned char)(*h))%100)/10;
+ intbuff[ibp++]='0'+((unsigned char)(*h))%10;
+ intbuff[ibp++]=';';
+#else
+ intbuff[ibp++]=*h;
+#endif
+ }
+ curpos++;
+ break;
+ }
+ if (ibp>480) FLUSHIBP;
+ h++;
+ }
+ }
+ FLUSHIBP;
+ if (buffer) buffer[buffpos]=0;
+ if (san && *h) h++;
+ newline_for_fun=exnewline_for_fun;
+ if (result) {
+ *result = buffer;
+ buffer=exbuffer;
+ buffpos=exbuffpos;
+ buffmax=exbuffmax;
+ scaninbuff=exscaninbuff;
+ }
+ return h;
+}
+
+static char *scan_troff_mandoc(char *c, int san, char **result) {
+ char *ret, *end = c;
+ int oldval = mandoc_line;
+ mandoc_line = 1;
+ while (*end && *end != '\n') {
+ end++;
+ }
+
+ if (end > c + 2
+ && ispunct(*(end - 1))
+ && isspace(*(end - 2)) && *(end - 2) != '\n') {
+ /*
+ * Don't format lonely punctuation. E.g. in "xyz ," format
+ * the xyz and then append the comma removing the space.
+ */
+ *(end - 2) = '\n';
+ ret = scan_troff(c, san, result);
+ *(end - 2) = *(end - 1);
+ *(end - 1) = ' ';
+ } else {
+ ret = scan_troff(c, san, result);
+ }
+ mandoc_line = oldval;
+ return ret;
+}
+
+STRDEF *foundpages=NULL;
+
+static void
+error_page(char *s, char *t, ...) {
+ va_list p;
+
+ printf("<HTML><HEAD><TITLE>%s</TITLE></HEAD>\n"
+ "<BODY>\n<H1>%s</H1>\n", s, s);
+ va_start(p, t);
+ vfprintf(stdout, t, p);
+ va_end(p);
+ printf("</BODY></HTML>\n");
+ exit(0);
+}
+
+char *
+xstrdup(const char *s) {
+ char *p = strdup(s);
+ if (p == NULL)
+ error_page("Out of memory",
+ "Sorry, out of memory, aborting...\n");
+ return p;
+}
+
+void *
+xmalloc(size_t size) {
+ void *p = malloc(size);
+ if (p == NULL)
+ error_page("Out of memory",
+ "Sorry, out of memory, aborting...\n");
+ return p;
+}
+
+void *
+xrealloc(void *ptr, size_t size) {
+ void *p = realloc(ptr,size);
+ if (p == NULL)
+ error_page("Out of memory",
+ "Sorry, out of memory, aborting...\n");
+ return p;
+}
+
+static void
+usage(void) {
+ error_page("man2html: bad invocation",
+ "Call: man2html [-l|-h host.domain:port] [-p|-q] [filename]\n"
+ "or: man2html -r [filename]\n");
+}
+
+static void
+goto_dir(char *path, char **dir, char **name) {
+ char *s, *t, *u;
+
+ s = xstrdup(path);
+ t = strrchr(s, '/');
+ if (t) {
+ *t = 0;
+ u = strrchr(s, '/');
+ *t = '/';
+ if (u) {
+ *u = 0;
+ if (chdir(s) == 0) {
+ if (dir)
+ *dir = s;
+ if (name)
+ *name = u+1;
+ }
+#if 0
+ else /* complain or not - this need not be fatal */
+ error_page("Error", "man2html: could not chdir to %s", s);
+#endif
+ }
+ }
+}
+
+/*
+ * Call: man2html [-l] [filename]
+ *
+ * The contents of FILENAME (or STDIN, in case FILENAME is "-" or absent)
+ * are converted from man-style nroff to html, and printed on STDOUT.
+ *
+ * Possible errors are reflected in the output. The return status is 0.
+ */
+int
+main(int argc, char **argv) {
+ FILE *f;
+ struct stat stbuf;
+ int l, c;
+ char *buf, *filename, *fnam = NULL;
+
+#ifdef __CYGWIN__
+ int opterr;
+
+ extern int optind;
+ extern char *optarg;
+#endif
+
+ printf("Content-type: text/html\n\n");
+
+ opterr = 0; /* no stderr error messages */
+ while ((c = getopt (argc, argv, "D:E:hH:lL:M:pqr?vVf")) != -1) {
+ switch(c) {
+ case 'D':
+ goto_dir(optarg, 0, 0); break;
+ case 'E':
+ error_page("Error", "%s", optarg); break;
+ case 'h':
+ set_cgibase("localhost"); break;
+ case 'H':
+ set_cgibase(optarg); break;
+ case 'l':
+ set_lynxcgibase("/home/httpd"); break;
+ case 'L':
+ set_lynxcgibase(optarg); break;
+ case 'M':
+ set_man2htmlpath(optarg); break;
+ case 'p':
+ set_separator('/'); break;
+ case 'q':
+ set_separator('?'); break;
+ case 'r':
+ set_relative_html_links(); break;
+ case 'v':
+ case 'V':
+ error_page("Version", "%s from man-%s", argv[0], version);
+ exit(0);
+ case '?':
+ default:
+ usage();
+ case 'f': /* It is rumoured that some other
+ incarnation of man2html uses this flag;
+ ignore when given for compatibility. */
+ /* case 'F': this will assign a format for man_page_html() */
+ break;
+ }
+ }
+
+ /* Find filename */
+ if (argc == optind+1)
+ fnam = argv[optind];
+ else if (argc != optind)
+ usage();
+
+ filename = fnam;
+ directory = 0;
+
+ /* Open input file */
+ if (!fnam || !strcmp(fnam, "-")) {
+ f = stdin;
+ fname = "(stdin)";
+ } else {
+ /* do a chdir() first, to get .so expansion right */
+ goto_dir(fnam, &directory, &fnam);
+
+ f = fopen(fnam, "r");
+ if (f == NULL)
+ error_page("File not found", "Could not open %s\n", filename);
+ fname = fnam;
+ }
+
+ /* Read entire file into buf[1..l] */
+#define XTRA 5
+ /* buf has 1 extra byte at the start, and XTRA extra bytes at the end */
+ if (f == stdin) {
+ int sz = 1024;
+ int ct = 1, tot = 0;
+ char *p = NULL;
+
+ clearerr(stdin);
+ while (ct > 0) {
+ tot += ct;
+ if (feof(stdin))
+ break;
+ sz = 2*sz+tot;
+ p = xrealloc(p, sz);
+ ct = fread(p+tot,1,sz-tot-XTRA,stdin);
+ }
+
+ buf = p;
+ l = tot-1;
+ } else {
+ int ct;
+
+ l = 0;
+ if (fstat(fileno(f), &stbuf) != -1)
+ l = stbuf.st_size;
+ buf = (char *) xmalloc((l+1+XTRA)*sizeof(char));
+ ct = fread(buf+1,1,l,f);
+ if (ct < l)
+ l = ct;
+ fclose(f);
+ }
+
+ buf[0] = '\n';
+ buf[l+1] = '\n';
+ buf[l+2] = buf[l+3] = 0;
+
+#ifdef MAKEINDEX
+ idxfile = fopen(INDEXFILE, "a");
+#endif
+ stdinit();
+
+ scan_troff(buf+1,0,NULL);
+ dl_down();
+ out_html(change_to_font(0));
+ out_html(change_to_size(0));
+ if (!fillout) {
+ fillout=1;
+ out_html("</PRE>");
+ }
+ out_html(NEWLINE);
+ if (output_possible) {
+ /* &nbsp; for mosaic users */
+ printf("<HR>\n<A NAME=\"index\">&nbsp;</A><H2>Index</H2>\n<DL>\n");
+ manidx[mip]=0;
+ printf("%s", manidx);
+ if (subs) printf("</DL>\n");
+ printf("</DL>\n");
+ print_sig();
+ printf("</BODY>\n</HTML>\n");
+ } else {
+ if (!filename)
+ filename = fname;
+ if (*filename == '/')
+ error_page("Invalid Manpage",
+ "The requested file %s is not a valid (unformatted) "
+ "man page.\nIf the file is a formatted manpage, "
+ "you could try to load the\n"
+ "<A HREF=\"file://localhost%s\">plain file</A>.\n",
+ filename, filename);
+ else
+ error_page("Invalid Manpage",
+ "The requested file %s is not a valid (unformatted) "
+ "man page.", filename);
+ }
+ if (idxfile)
+ fclose(idxfile);
+ if (buf)
+ free(buf);
+ return 0;
+}
diff --git a/man2html/scripts/cgi-aux/man/man.aux b/man2html/scripts/cgi-aux/man/man.aux
new file mode 100644
index 0000000..e381b01
--- /dev/null
+++ b/man2html/scripts/cgi-aux/man/man.aux
@@ -0,0 +1,75 @@
+Content-type: text/html
+
+<HTML>
+<HEAD>
+<TITLE>Manual Pages - Main Contents</TITLE>
+<!-- Note: this is not html, but requires preprocessing -->
+<!-- It is used by /home/httpd/cgi-bin/man/man2html -->
+</HEAD>
+<BODY>
+<H1>Manual Pages - Main Contents</H1>
+<HR>
+
+<H2>Name and Section lookup</H2>
+<ISINDEX>
+
+%lynx <i>Start a query</i> by typing an s.
+You can enter a program name, possibly preceded by the section,
+the directories to search (with -M) or a full name.
+For example:
+<UL>
+ <LI><TT>find</TT>
+ <LI><TT>1 find</TT>
+ <LI><TT>-M /usr/man:/usr/X11R6/man:/usr/lib/perl5/man find</TT>
+ <LI><TT>/local/gcc/man/man1/gperf.1</TT>
+</UL>
+
+<HR>
+
+<H2>Index of pages by name and description</H2>
+Sections:
+ <A HREF="%cg/manwhatis?%cg+1">1. User Commands</A>;
+ <A HREF="%cg/manwhatis?%cg+2">2. System Calls</A>;
+ <A HREF="%cg/manwhatis?%cg+3">3. Library Functions</A>;
+ <A HREF="%cg/manwhatis?%cg+4">4. Special Files</A>;
+ <A HREF="%cg/manwhatis?%cg+5">5. File Formats</A>;
+ <A HREF="%cg/manwhatis?%cg+6">6. Games</A>;
+ <A HREF="%cg/manwhatis?%cg+7">7. Miscellany</A>;
+ <A HREF="%cg/manwhatis?%cg+8">8. Administration and Privileged Commands</A>;
+ <A HREF="%cg/manwhatis?%cg+l">l. Postgresql Commands</A>;
+ <A HREF="%cg/manwhatis?%cg+n">n. Tcl Commands</A>.
+<P>
+<HR>
+<H2>Index of pages by name only</H2>
+ <A HREF="%cg/mansec?%cg+1">1. User Commands</A>;
+ <A HREF="%cg/mansec?%cg+2">2. System Calls</A>;
+ <A HREF="%cg/mansec?%cg+3">3. Library Functions</A>;
+ <A HREF="%cg/mansec?%cg+4">4. Special Files</A>;
+ <A HREF="%cg/mansec?%cg+5">5. File Formats</A>;
+ <A HREF="%cg/mansec?%cg+6">6. Games</A>;
+ <A HREF="%cg/mansec?%cg+7">7. Miscellany</A>;
+ <A HREF="%cg/mansec?%cg+8">8. Administration and Privileged Commands</A>;
+ <A HREF="%cg/mansec?%cg+l">l. Postgresql Commands</A>;
+ <A HREF="%cg/mansec?%cg+n">n. Tcl Commands</A>;
+ <A HREF="%cg/mansec?%cg+all">All Sections</A>.
+<P>
+<hr>
+
+<H2>Manual Pages full text search</H2>
+
+<A HREF="%cg/mansearch">
+Search the full text of the Manual Pages.
+</A>
+
+<P>
+<HR>
+
+The original man2html program and scripts are due to
+<A HREF="http://wsinwp01.win.tue.nl:1234/index.html">
+Richard Verhoeven</A> and
+<A HREF="mailto:michael@actrix.gen.nz">
+Michael Hamilton</A>.
+This version is from man-1.6g maintained by <A HREF="mailto:flucifredi@acm.org">
+Federico Lucifredi</A>.
+</body>
+</HTML>
diff --git a/man2html/scripts/cgi-aux/man/mansearch.aux b/man2html/scripts/cgi-aux/man/mansearch.aux
new file mode 100644
index 0000000..f1d19a2
--- /dev/null
+++ b/man2html/scripts/cgi-aux/man/mansearch.aux
@@ -0,0 +1,49 @@
+Content-type: text/html
+
+<HTML>
+<HEAD>
+<TITLE>Manual Pages - Text Search</TITLE>
+<!-- Changed by: Michael Hamilton, 6-Apr-1996 -->
+<!-- Note: this is not html, but requires preprocessing -->
+</HEAD>
+<BODY>
+<H1>Manual Pages - Text Search</H1>
+
+<A HREF="%cg/man2html">Return to Main Contents</A>
+<P>
+<ISINDEX>
+
+%lynx <i>Start a query</i> by typing an s.
+
+Examples:
+<UL>
+ <LI><TT>pwd;directory</TT> - Find both in the same man page.
+ <LI><TT>pwd,directory</TT> - Find either.
+ <LI><TT>pwd directory</TT> - Find the exact phrase.
+ <LI><TT>-F 1 pwd</TT> - Look in section 1 only.
+ <LI><TT>-B glipmse</TT> - Find the best match (allow for misspelling).
+ <LI><TT>-L 0:10 pwd</TT> - Only show the first 10 man pages matched.
+</UL>
+
+<HR>
+<P>
+The index uses the <I>Glimpse</I>
+(<A HREF="%cg/man2html?1+glimpse">glimpse(1)</A>)
+text indexing system. Many of the glimpse
+options, regular expressions, and wildcards are valid:
+see the <A HREF="%cg/mansearchhelp">help page</A> for a summary.
+<P>
+<HR>
+
+<P>
+Glimpse
+was developed by Udi Manber and Burra Gopal of the University of
+Arizona, and Sun Wu of the National Chung-Cheng University, Taiwan.
+You may contact the authors at <A HREF="mailto:glimpse@cs.arizona.edu">
+glimpse@cs.arizona.edu</A>
+<P>
+The Manual Page text search interface was created for Linux by
+<A HREF="mailto:michael@actrix.gen.nz">
+Michael Hamilton</A>.
+</BODY>
+</HTML>
diff --git a/man2html/scripts/cgi-aux/man/mansearchhelp.aux b/man2html/scripts/cgi-aux/man/mansearchhelp.aux
new file mode 100644
index 0000000..200b509
--- /dev/null
+++ b/man2html/scripts/cgi-aux/man/mansearchhelp.aux
@@ -0,0 +1,295 @@
+Content-type: text/html
+
+<HTML>
+<HEAD>
+<TITLE>Manual Pages - Search Help</TITLE>
+<!-- Changed by: Michael Hamilton, 6-Apr-1996 -->
+<!-- Note: this is not html, but requires preprocessing -->
+</HEAD>
+<BODY>
+<H1>Manual Pages - Search Help</H1>
+
+<A HREF="%cg/mansearch">Perform another search</A>
+<BR>
+<A HREF="%cg/man2html">Return to Main Contents</A>
+<P>
+<HR>
+<P>
+The full text index uses the <I>Glimpse</I> text indexing system.
+The
+<A HREF="%cg/man2html?1+glimpse">glimpse(1)</A>
+manual page documents glimpse in full. This summary documents those
+features of glimpse that are valid when searching through the manual pages.
+<P>
+<HR>
+
+<H2>Search Options</H2>
+
+The following search options must be at the start of the search string.
+
+<DL COMPACT>
+
+<DT><B>-</B> <I>#</I>
+<DD>
+<I>#</I> is an integer between 1 and 8
+specifying the maximum number of errors
+permitted in finding the approximate matches (the default is zero).
+Generally, each insertion, deletion, or substitution counts as one error.
+Since the index stores only lower case characters, errors of
+substituting upper case with lower case may be missed.
+
+<DT><B>-B</B>
+<DD>
+Best match mode. (Warning: -B sometimes misses matches. It is safer
+to specify the number of errors explicitly.)
+When -B is specified and no exact matches are found, glimpse
+will continue to search until the closest matches (i.e., the ones
+with minimum number of errors)
+are found.
+In general, -B may be slower than -#, but not by very much.
+Since the index stores only lower case characters, errors of
+substituting upper case with lower case may be missed.
+
+<DT><B>-L <I>x</I> | <I>x</I>:<I>y</I> | <I>x</I>:<I>y</I>:<I>z</I></B>
+<DD>
+A non-zero value of <I>x</I> limits the number of matches
+that will be shown.
+A non-zero value of <I>y</I> limits the number of man pages
+that will be shown.
+A non-zero valye of <I>z</I> will only show pages that have
+less that z matches.
+For example, -L 0:10 will output all matches for the first 10 files that
+contain a match.
+
+<DT><B>-F</B> <I>pattern</I>
+<DD>
+The -F option provides a pattern that restricts the search results to
+those filenames that match the pattern.
+or example, <I>-F 8</I> effectively restricts matches to section 8.
+
+<DT><B>-w</B>
+<DD>
+Search for the pattern as a word - i.e., surrounded by non-alphanumeric
+characters. For example,
+<I>-w -1 car</I> will match cars, but not characters and not
+car10.
+The non-alphanumeric <I>must</I>
+surround the match; they cannot be counted as errors.
+This option does not work with regular expressions.
+
+<DT><B>-W</B>
+<DD>
+The default for Boolean AND queries is that they cover one record
+(the default for a record is one line) at a time.
+For example, glimpse 'good;bad' will output all lines containing
+both 'good' and 'bad'.
+The -W option changes the scope of Booleans to be the whole file.
+Within a file glimpse will output all matches to any of the patterns.
+So, glimpse -W 'good;bad' will output all lines containing 'good'
+<I>or</I> 'bad', but only in files that contain both patterns.
+
+<DT><B>-k</B>
+<DD>
+No symbol in the pattern is treated as a meta character.
+For example, <I>-k a(b|c)*d</I> will find
+the occurrences of a(b|c)*d whereas <I>a(b|c)*d</I>
+will find substrings that match the regular expression 'a(b|c)*d'.
+(The only exception is ^ at the beginning of the pattern and $ at the
+end of the pattern, which are still interpreted in the usual way.
+Use \^ or \$ if you need them verbatim.)
+
+</DL>
+
+<P>
+<HR>
+
+<H2>Patterns</H2>
+
+<I>Glimpse</I>
+supports a large variety of patterns, including simple
+strings, strings with classes of characters, sets of strings,
+wild cards, and regular expressions (see <A HREF="#limitations">LIMITATIONS</A>).
+
+<DL COMPACT>
+<DT><B>Strings </B><DD>
+Strings are any sequence of characters, including the special symbols
+`^' for beginning of line and `$' for end of line.
+The following special characters (
+`<B>$</B>',
+
+`^<B>',</B>
+
+`<B>*</B>',
+
+`<B>[</B>'<B>,</B>
+
+`<B>^</B>',
+
+`<B>|</B>',
+
+`<B>(</B>',
+
+`<B>)</B>',
+
+`<B>!</B>',
+
+and
+`<B>\</B>'
+
+)
+as well as the following meta characters special to glimpse (and agrep):
+`<B>;</B>',
+
+`<B>,</B>',
+
+`<B>#</B>',
+
+`<B>&lt;</B>',
+
+`<B>&gt;</B>',
+
+`<B>-</B>',
+
+and
+`<B>.</B>',
+
+should be preceded by `\' if they are to be matched as regular
+characters. For example, \^abc\\ corresponds to the string ^abc\,
+whereas ^abc corresponds to the string abc at the beginning of a
+line.
+<DT><B>Classes of characters</B><DD>
+a list of characters inside [] (in order) corresponds to any character
+from the list. For example, [a-ho-z] is any character between a and h
+or between o and z. The symbol `^' inside [] complements the list.
+For example, [^i-n] denote any character in the character set except
+character 'i' to 'n'.
+The symbol `^' thus has two meanings, but this is consistent with
+egrep.
+The symbol `.' (don't care) stands for any symbol (except for the
+newline symbol).
+<DT><B>Boolean operations</B><DD>
+<B>Glimpse </B>
+
+supports an `AND' operation denoted by the symbol `;'
+an `OR' operation denoted by the symbol `,',
+or any combination.
+For example,
+<I>glimpse 'pizza;cheeseburger'</I> will output all lines containing
+both patterns.
+<I>glimpse -F 'gnu;\.c$' 'define;DEFAULT'</I>
+will output all lines containing both 'define' and 'DEFAULT'
+(anywhere in the line, not necessarily in order) in
+files whose name contains 'gnu' and ends with .c.
+<I>glimpse '{political,computer};science'</I> will match 'political science'
+or 'science of computers'.
+<DT><B>Wild cards</B><DD>
+The symbol '#' is used to denote a sequence
+of any number (including 0)
+of arbitrary characters (see <A HREF="#limitations">LIMITATIONS</A>).
+The symbol # is equivalent to .* in egrep.
+In fact, .* will work too, because it is a valid regular expression
+(see below), but unless this is part of an actual regular expression,
+# will work faster.
+(Currently glimpse is experiencing some problems with #.)
+<DT><B>Combination of exact and approximate matching</B><DD>
+Any pattern inside angle brackets &lt;&gt; must match the text exactly even
+if the match is with errors. For example, &lt;mathemat&gt;ics matches
+mathematical with one error (replacing the last s with an a), but
+mathe&lt;matics&gt; does not match mathematical no matter how many errors are
+allowed.
+(This option is buggy at the moment.)
+<DT><B>Regular expressions</B><DD>
+Since the index is word based, a regular expression must match
+words that appear in the index for glimpse to find it.
+Glimpse first strips the regular expression from all non-alphabetic
+characters, and searches the index for all remaining words.
+It then applies the regular expression matching algorithm to the
+files found in the index.
+For example, <I>glimpse</I> 'abc.*xyz' will search the index
+for all files that contain both 'abc' and 'xyz', and then
+search directly for 'abc.*xyz' in those files.
+(If you use glimpse -w 'abc.*xyz', then 'abcxyz' will not be found,
+because glimpse
+will think that abc and xyz need to be matches to whole words.)
+The syntax of regular expressions in <B>glimpse</B> is in general the same as
+that for <B>agrep</B>. The union operation `|', Kleene closure `*',
+and parentheses () are all supported.
+Currently '+' is not supported.
+Regular expressions are currently limited to approximately 30
+characters (generally excluding meta characters). Some options
+(-d, -w, -t, -x, -D, -I, -S) do not
+currently work with regular expressions.
+The maximal number of errors for regular expressions that use '*'
+or '|' is 4. (See <A HREF="#limitations">LIMITATIONS</A>.)
+
+</DL>
+
+<HR>
+
+<H2><A NAME="limitations">Limitations</A></H2>
+
+The index of glimpse is word based. A pattern that contains more than
+one word cannot be found in the index. The way glimpse overcomes this
+weakness is by splitting any multi-word pattern into its set of words
+and looking for all of them in the index.
+For example, <B>glimpse 'linear programming'</B> will first consult the index
+to find all files containing both <I>linear</I> and <I>programming</I>,
+and then apply agrep to find the combined pattern.
+This is usually an effective solution, but it can be slow for
+cases where both words are very common, but their combination is not.
+<P>
+
+As was mentioned in the section on PATTERNS above, some characters
+serve as meta characters for glimpse and need to be
+preceded by '\' to search for them. The most common
+examples are the characters '.' (which stands for a wild card),
+and '*' (the Kleene closure).
+So, &quot;glimpse ab.de&quot; will match abcde, but &quot;glimpse ab\.de&quot;
+will not, and &quot;glimpse ab*de&quot; will not match ab*de, but
+&quot;glimpse ab\*de&quot; will.
+The meta character - is translated automatically to a hyphen
+unless it appears between [] (in which case it denotes a range of
+characters).
+<P>
+
+The index of glimpse stores all patterns in lower case.
+When glimpse searches the index it first converts
+all patterns to lower case, finds the appropriate files,
+and then searches the actual files using the original
+patterns.
+So, for example, <I>glimpse ABCXYZ</I> will first find all
+files containing abcxyz in any combination of lower and upper
+cases, and then searches these files directly, so only the
+right cases will be found.
+One problem with this approach is discovering misspellings
+that are caused by wrong cases.
+For example, <I>glimpse -B abcXYZ</I> will first search the
+index for the best match to abcxyz (because the pattern is
+converted to lower case); it will find that there are matches
+with no errors, and will go to those files to search them
+directly, this time with the original upper cases.
+If the closest match is, say AbcXYZ, glimpse may miss it,
+because it doesn't expect an error.
+Another problem is speed. If you search for &quot;ATT&quot;, it will look
+at the index for &quot;att&quot;. Unless you use -w to match the whole word,
+glimpse may have to search all files containing, for example, &quot;Seattle&quot;
+which has &quot;att&quot; in it.
+<P>
+
+There is no size limit for simple patterns and simple patterns
+within Boolean expressions.
+More complicated patterns, such as regular expressions,
+are currently limited to approximately 30 characters.
+Lines are limited to 1024 characters.
+Records are limited to 48K, and may be truncated if they are larger
+than that.
+The limit of record length can be
+changed by modifying the parameter Max_record in agrep.h.
+<P>
+
+Glimpseindex does not index words of size &gt; 64.
+<A NAME="lbAQ">&nbsp;</A>
+
+<HR>
+</BODY>
+</HTML>
diff --git a/man2html/scripts/cgi-bin/man/man2html b/man2html/scripts/cgi-bin/man/man2html
new file mode 100755
index 0000000..7c515d1
--- /dev/null
+++ b/man2html/scripts/cgi-bin/man/man2html
@@ -0,0 +1,109 @@
+#!/bin/sh
+# man2html cgi script - uses /usr/bin/man2html to format man pages
+# auxiliary text files in /home/httpd/cgi-aux/man
+# aeb@cwi.nl - 980109
+
+MAN2HTML="/usr/bin/man2html"
+MANX="/home/httpd/cgi-aux/man/man.aux"
+
+# Do we need lynxcgi URLs? For the moment our criterion is
+# 1) HTTP_USER_AGENT=Lynx* and 2) HTTP_HOST is unset.
+AGENT="${HTTP_USER_AGENT-unknown}"
+
+case "$AGENT" in
+ Lynx*|lynx*)
+ HH="${HTTP_HOST-nohh}"
+ SED="s/%lynx //"
+ ;;
+ *)
+ HH=nolynx
+ SED="/%lynx/d"
+ ;;
+esac
+
+SERVER="${SERVER_NAME-localhost}"
+case "$HH" in
+ nohh)
+ LL="-l"
+ CG="lynxcgi:/home/httpd/cgi-bin/man"
+ ;;
+ *)
+ LL="-H$SERVER"
+ CG="http://$SERVER/cgi-bin/man"
+ ;;
+esac
+
+# Find the required page - expect to be called with "man2html [sec] page".
+# There may a prefixed "-M manpath" option.
+if [ $# -ge 2 -a x"$1" = x-M ]; then
+ MANPATH="$2"
+ export MANPATH
+ shift; shift
+ MP=" using the given MANPATH"
+else
+ MP=""
+fi
+
+# If no arguments given, show a start page.
+if [ $# = 0 ]; then
+ if [ -r $MANX ]; then
+ cat $MANX | sed "s#%cg#$CG#g; $SED"
+ else
+ "$MAN2HTML" -E "man2html: cannot open $MANX"
+ fi
+ exit 0
+fi
+
+if [ $# -gt 2 ]; then
+ "$MAN2HTML" -E "man2html: bad invocation: too many arguments"
+ exit 0
+fi
+
+# A single argument may be an explicitly give path name
+# Otherwise, ask man where to find it
+if [ $# = 1 ]; then
+ case "$1" in
+ /*)
+ PAGE="$1"
+ ;;
+ *)
+ PAGE=`man -w -c "$@" 2>/dev/null`
+ ;;
+ esac
+else
+ PAGE=`man -w -c "$@" 2>/dev/null`
+fi
+
+if [ x"$PAGE" = x ]; then
+ complaint="man2html: cannot find a page"
+ if [ $# = 1 ]; then
+ "$MAN2HTML" -E "$complaint for $1$MP"
+ else
+ "$MAN2HTML" -E "$complaint for $2 in section $1$MP"
+ fi
+ exit 0
+fi
+
+if [ -r "$PAGE" ]
+then
+ case "$PAGE" in
+ *.gz)
+ zcat "$PAGE" | "$MAN2HTML" "$LL" -D "$PAGE"
+ ;;
+ *.bz2)
+ bzcat "$PAGE" | "$MAN2HTML" "$LL" -D "$PAGE"
+ ;;
+ *)
+ "$MAN2HTML" "$LL" "$PAGE"
+ ;;
+ esac
+elif [ -r "$PAGE".gz ]
+then
+ zcat "$PAGE".gz | "$MAN2HTML" "$LL" -D "$PAGE"
+elif [ -r "$PAGE".bz2 ]
+then
+ bzcat "$PAGE".bz2 | "$MAN2HTML" "$LL" -D "$PAGE"
+else
+ "$MAN2HTML" -E "Strange... Cannot find (or read) $PAGE."
+fi
+exit 0
diff --git a/man2html/scripts/cgi-bin/man/mansearch b/man2html/scripts/cgi-bin/man/mansearch
new file mode 100755
index 0000000..2644db6
--- /dev/null
+++ b/man2html/scripts/cgi-bin/man/mansearch
@@ -0,0 +1,192 @@
+#!/bin/sh
+#
+# Interface to a glimpse search of the man pages.
+# Michael Hamilton <michael@actrix.gen.nz>
+# Small changes - aeb, 980109
+#
+
+# Do we need lynxcgi URLs? For the moment our criterion is
+# 1) HTTP_USER_AGENT=Lynx* and 2) HTTP_HOST is unset.
+AGENT="${HTTP_USER_AGENT-unknown}"
+
+case "$AGENT" in
+ Lynx*|lynx*)
+ HH="${HTTP_HOST-nohh}"
+ SED="s/%lynx //"
+ ;;
+ *)
+ HH=nolynx
+ SED="/%lynx/d"
+ ;;
+esac
+
+SERVER="${SERVER_NAME-localhost}"
+case "$HH" in
+ nohh)
+ CG="lynxcgi:/home/httpd/cgi-bin/man"
+ ;;
+ *)
+ CG="http://$SERVER/cgi-bin/man"
+ ;;
+esac
+QUOTE="'"
+export CG QUOTE SED
+
+exec awk '
+function removeopts(string) {
+ gsub(/^[ \t]/, "", string); # Remove leading spaces
+ gsub(/[ \t]$/, "", string); # Remove trailing spaces
+ gsub(/[ \t\\];/, ";", string); # Remove spaces before ;
+ gsub(/[ \t];/, ",", string); # Remove spaces before ,
+ while (match(string, /^-[FLBwk1-8]/)) {
+ if (match(string, /^-[FL]( |.)[^ \t]+[ \t]+/)) { # Option with arg
+ options = options " " substr(string, RSTART, RLENGTH);
+ string = substr(string, RSTART + RLENGTH);
+ }
+ else if (match(string, /^-[Bwk1-8][ \t]+/)) { # Option without arg
+ options = options " " substr(string, RSTART, RLENGTH);
+ string = substr(string, RSTART + RLENGTH);
+ }
+ else if (match(string, /^-[^ \t]/)) { # Remove it
+ string = substr(string, RSTART + RLENGTH);
+ }
+ }
+ return string;
+}
+
+BEGIN {
+
+ searchdocument = "/home/httpd/cgi-aux/man/mansearch.aux";
+ quote = ENVIRON["QUOTE"];
+ cgipath = ENVIRON["CG"];
+ sedcmd = ENVIRON["SED"];
+ truncate_at = 11; # Single page display match limit.
+
+ glimpse_cmd = "glimpse -z -H /var/man2html -y -W -i "
+
+ for (i = 1; i < ARGC; i++) {
+ string = string " " ARGV[i];
+ }
+ # Have to be careful to single quote this
+ # string later.
+ gsub(/[^a-zA-Z0-9-_+ \t\/@%:;,$*|]/, " ", string);
+
+ string = removeopts(string);
+
+ gsub(/[^a-zA-Z0-9-_+ \t\/@%:,]/, " ", options);
+
+ if (!string) {
+ if (system("test -r " searchdocument ) != 0) {
+ print "Content-type: text/html\n\n";
+ print "<head>";
+ print "<title>mansearch - file not found</title>";
+ print "</head>\n<body>";
+ print "Sorry - cannot read " searchdocument ".";
+ print "</body>";
+ exit;
+ }
+ system("sed " quote "s#%cg#" cgipath "#g;" sedcmd quote " " searchdocument );
+ exit;
+ }
+
+ print "Content-type: text/html";
+ print "";
+ print "<HTML>";
+ print "<HEAD>";
+ print "<TITLE>Manual Pages - Search Results: " string "</TITLE>";
+ print "</HEAD>";
+ print "<BODY>";
+
+ print "<H1>Manual Pages - Search Results</H1>";
+ print "<H2>Target text: " options " " string "</H2>";
+
+ print "<A HREF=\"" cgipath "/mansearch\">";
+ print "Perform another search";
+ print "</A><BR>";
+ print "<A HREF=\"" cgipath "/man2html\">";
+ print "Return to Main Contents";
+ print "</A>";
+
+ print "<HR>";
+
+ print "<DL>";
+ # Unless you like being hacked, the single
+ # forward quotes are most important.
+ cmd = glimpse_cmd " " options " " quote string quote " 2>/dev/null" ;
+
+ while ((cmd | getline matchline) > 0) {
+ if (split(matchline, part, ": ") == 1) {
+ continue;
+ }
+ else {
+ fullname = part[1];
+ }
+
+ if (fullname == "glimpse") {
+ print "<DT><B>"fullname"</B>:";
+ }
+ else if (fullname != last_fullname) {
+ mcount++;
+ tcount = 0;
+ last_fullname = fullname ;
+ last_text = "";
+
+ if (match(fullname, ".*/")) {
+ dirname = substr(fullname, 1, RLENGTH);
+ filename = substr(fullname, RLENGTH + 1);
+ if (dirname != last_dirname) {
+ last_dirname = dirname;
+ print "</DL>";
+ print "<H3>Location: " dirname "</H3>";
+ print "<DL>";
+ }
+ }
+ else {
+ filename = fullname;
+ }
+
+ if (match(filename, /\.[^.]+$/)) {
+ ref = substr(filename, 1, RSTART - 1) "+" substr(filename, RSTART + 1);
+ }
+ else {
+ ref = filename;
+ }
+ print "<DT> <a href=\"" cgipath "/man2html?" fullname "\">";
+ textname = filename;
+ sub(/\.(gz)|Z|z$/, "", textname);
+ sub(/\./, "(", textname);
+ textname = textname ")";
+ print textname;
+ print "</A>";
+ }
+
+ text = substr(matchline, length(fullname) + 2);
+ tcount++;
+ if (tcount < truncate_at) {
+ sub(/^ *.[^ ]+ /, "", text);
+ sub(/ +$/, "", text);
+ gsub(/\\f./, "", text);
+ gsub(/\\&/, "", text);
+ gsub(/\\/, "", text);
+ print "<DD>" text;
+ }
+ else if (tcount == truncate_at) {
+ print "<DD> <I>...additional matches not shown.</I>";
+ }
+ }
+
+ print "</DL>";
+ if (mcount == 0) {
+ print "No matches found.";
+ }
+ else if (mcount == 1) {
+ print "<HR>\n<P>1 match found."
+ }
+ else {
+ print "<HR>\n<P>" mcount " matches found."
+ }
+ print "</BODY>";
+ print "</HTML>";
+ exit;
+}' "$@"
+
diff --git a/man2html/scripts/cgi-bin/man/mansearchhelp b/man2html/scripts/cgi-bin/man/mansearchhelp
new file mode 100755
index 0000000..a96e796
--- /dev/null
+++ b/man2html/scripts/cgi-bin/man/mansearchhelp
@@ -0,0 +1,32 @@
+#!/bin/sh
+MAN2HTML=/usr/bin/man2html
+MANSH=/home/httpd/cgi-aux/man/mansearchhelp.aux
+
+# Do we need lynxcgi URLs? For the moment our criterion is
+# 1) HTTP_USER_AGENT=Lynx* and 2) HTTP_HOST is unset.
+AGENT="${HTTP_USER_AGENT-unknown}"
+case "$AGENT" in
+ Lynx*|lynx*)
+ HH="${HTTP_HOST-nohh}"
+ ;;
+ *)
+ HH=nolynx
+ ;;
+esac
+
+SERVER="${SERVER_NAME-localhost}"
+case "$HH" in
+ nohh)
+ CG="lynxcgi:/home/httpd/cgi-bin/man"
+ ;;
+ *)
+ CG="http://$SERVER/cgi-bin/man"
+ ;;
+esac
+
+if [ -r $MANSH ]; then
+ sed s#%cg#$CG#g $MANSH
+else
+ $MAN2HTML -E "man2html: cannot open $MANSH"
+fi
+exit 0
diff --git a/man2html/scripts/cgi-bin/man/mansec b/man2html/scripts/cgi-bin/man/mansec
new file mode 100755
index 0000000..24c189e
--- /dev/null
+++ b/man2html/scripts/cgi-bin/man/mansec
@@ -0,0 +1,183 @@
+#!/usr/bin/awk -f
+#
+# Generate an index into a manual section by using find.
+# Michael Hamilton <michael@actrix.gen.nz>
+# Small changes - aeb, 980109
+#
+BEGIN {
+
+ OFS="";
+
+ if (ARGC != 3) {
+ print "Content-type: text/html\n\n";
+ print "<head>";
+ print "<title>manwhatis - bad call</title>";
+ print "</head>\n<body>";
+ print "manwhatis: wrong number of arguments";
+ print "</body>";
+ exit;
+ }
+ cgipath = ARGV[1];
+ section = ARGV[2];
+
+ if (section !~ /^[1-8ln]$/ && section != "all") {
+ print "Content-type: text/html\n\n";
+ print "<head>";
+ print "<title>Manual - Illegal section</title>";
+ print "<body>";
+ print "Illegal section number '" section "'." ;
+ print "Must be one of 1,2,3,4,5,6,7,8,l,n or all";
+ print "</body>";
+ exit;
+ }
+
+ "echo $PPID" | getline pid;
+
+ if (cgipath ~ /lynxcgi/) {
+ cache_suffix = "l";
+ }
+ else {
+ cache_suffix = "h";
+ }
+
+ cache_dir = "/var/man2html";
+ cache_file = "manindex" cache_suffix "-" section ".html";
+ cache = cache_dir "/" cache_file;
+ cache_tmp = cache "_" pid;
+ buffer_tmp = cache "_items_" pid;
+
+ # Find out the man path
+ "man -w" | getline man_path
+ man_path = man_path ":";
+ gsub(":", " ", man_path);
+ # See if anything is out of date.
+ # Check all man[1-8] dir dates vs cache date
+ if (section == "all") {
+ if (system("test -f " cache) == 0) {
+ cmd = "find " man_path " -maxdepth 1 -name 'man[1-8]' -newer " cache;
+ cmd | getline need_update;
+ }
+ else {
+ need_update = 1;
+ }
+ }
+ else {
+ if (system("test -f " cache) == 0) {
+ cmd = "find " man_path " -maxdepth 1 -name man" section " -newer " cache;
+ cmd | getline need_update;
+ }
+ else {
+ need_update = 1;
+ }
+ }
+
+ if (need_update != "") {
+ if (system("test -w " cache_dir "/.") != 0) {
+ print "Content-type: text/html\n\n";
+ print "<head>";
+ print "<title>mansec - no cache</title>";
+ print "</head>\n<body>";
+ print "Sorry - cannot create index.";
+ print "No writable cache directory " cache_dir " exists.";
+ print "</body>";
+ exit;
+ }
+
+ sec_name[1] = "User Commands";
+ sec_name[2] = "System Calls";
+ sec_name[3] = "Library Functions";
+ sec_name[4] = "Special Files";
+ sec_name[5] = "File Formats";
+ sec_name[6] = "Games";
+ sec_name[7] = "Miscellany";
+ sec_name[8] = "Administration and Privileged Commands";
+ sec_name["all"] = "All available manual pages";
+ num_sections = 8;
+
+ # Print heading
+ print "Content-type: text/html\n\n" > cache_tmp;
+ print "<html>\n<head>" > cache_tmp;
+ print "<title>Manual Pages - Names: " section ". " sec_name[section] "</title>"> cache_tmp;
+ print "</head>\n<body>" > cache_tmp;
+ print "<h1>Manual Pages - Page Names</h1>" > cache_tmp;
+ print "<h2>Section " section ": " sec_name[section] "</h2>" > cache_tmp;
+
+ "hostname" | getline hostname;
+ "date" | getline date;
+ print hostname " (" date ")" > cache_tmp;
+
+ if (section != "all") {
+ sec_sub_dir = "/man" section;
+ }
+ else {
+ sec_sub_dir = "/man*";
+ }
+ gsub(" ", sec_sub_dir " ", man_path);
+
+ print "<p>Manual pages found under " man_path "." > cache_tmp;
+
+ # Find any man[1-8]/filenames
+ while ((("find " man_path " -follow -type f -printf '%f\n' | sort -f ") | getline manpage) > 0) {
+ # Check for new letter of alphabet
+ letter = tolower(substr(manpage,1,1));
+ if (letter != last_letter) {
+ last_letter = letter;
+ letter_index[++num_letters] = letter;
+ # Start a new alphabetic heading
+ print "<h2> <a name=\"", letter, "\">", toupper(letter), "</a></h2>" > buffer_tmp;
+ # Print out alphabetic quick index and other links
+ }
+ # Split page.n into "page" and "n" and generate an entry
+ sub(/[.]([zZ]|(gz))$/, "", manpage);
+ match(manpage, /[.][^.]+$/);
+ title = substr(manpage, 1, RSTART - 1);
+ if (section != "all") {
+ print "<a href=\"" cgipath "/man2html?", section, "+", title, "\">", title, "(", substr(manpage, RSTART + 1), ")</a>" > buffer_tmp;
+ }
+ else {
+ sec = substr(manpage, RSTART + 1)
+ print "<a href=\"" cgipath "/man2html?", sec, "+", title, "\">", title, "(", sec, ")</a>" > buffer_tmp;
+ }
+ }
+
+ close(buffer_tmp);
+
+ print "<p>" > cache_tmp;
+
+ # Print out alphabetic quick index and other links
+ for (i = 1; i <= num_letters; i++) {
+ print "<a href=\"#" letter_index[i] "\">" toupper(letter_index[i]) "</a>" > cache_tmp;
+ }
+
+ print "<p><hr>" > cache_tmp;
+ print "<a href=\"" cgipath "/man2html\">Return to Main Contents</a>" > cache_tmp;
+
+ print "<p>Other sections:" > cache_tmp;
+ for (i=1; i<=num_sections; i++) {
+ if (i != section) { # Dont print an entry for the section we are in
+ print "<a href=\"" cgipath "/mansec?" cgipath "+" i "\">" i ". " sec_name[i] "</a> " > cache_tmp;
+ }
+ }
+ print "<hr><p>" > cache_tmp;
+ # Print out the accumulated index entries
+ while ((getline < buffer_tmp) > 0) print > cache_tmp;
+ print "<hr><p>" > cache_tmp;
+ # Print out alphabetic quick index and other links
+ for (i = 1; i <= num_letters; i++) {
+ print "<a href=\"#" letter_index[i] "\">" toupper(letter_index[i]) "</a>" > cache_tmp;
+ }
+ print "<hr>" > cache_tmp;
+ print "<p><a href=\"" cgipath "/man2html\">Return to Main Contents</a>" > cache_tmp;
+ print "<p>Other sections:" > cache_tmp;
+ for (i=1; i<=num_sections; i++) {
+ if (i != section) { # Dont print an entry for the section we are in
+ print "<a href=\"" cgipath "/mansec?" cgipath "+" i "\">" i ". " sec_name[i] "</a> " > cache_tmp;
+ }
+ }
+ print "</body>\n</html>" > cache_tmp;
+ system("/bin/mv " cache_tmp " " cache);
+ system("/bin/rm -f " buffer_tmp);
+ }
+ system("/bin/cat " cache);
+ exit;
+}
diff --git a/man2html/scripts/cgi-bin/man/manwhatis b/man2html/scripts/cgi-bin/man/manwhatis
new file mode 100755
index 0000000..d14a516
--- /dev/null
+++ b/man2html/scripts/cgi-bin/man/manwhatis
@@ -0,0 +1,208 @@
+#!/usr/bin/awk -f
+#
+# Generate a whatis index into the manual pages by using find to
+# locate all the whatis files.
+# Michael Hamilton <michael@actrix.gen.nz>
+# Small changes - aeb, 980109
+#
+BEGIN {
+
+ OFS="";
+
+ if (ARGC != 3) {
+ print "Content-type: text/html\n\n";
+ print "<head>";
+ print "<title>manwhatis - bad call</title>";
+ print "</head>\n<body>";
+ print "manwhatis: wrong number of arguments";
+ print "</body>";
+ exit;
+ }
+ cgipath = ARGV[1];
+ section = ARGV[2];
+
+ if (section !~ /^[1-8ln]$/) {
+ print "Content-type: text/html\n\n";
+ print "<head>";
+ print "<title>Manual - Illegal section</title>";
+ print "</head>\n<body>";
+ print "Illegal section number '" section "'." ;
+ print "Must be one of 1,2,3,4,5,6,7,8,l,n";
+ print "</body>";
+ exit;
+ }
+
+ if (cgipath ~ /lynxcgi/) {
+ cache_suffix = "l";
+ }
+ else {
+ cache_suffix = "h";
+ }
+
+ cache_dir = "/var/man2html";
+ cache_file = "whatis" cache_suffix "-" section ".html";
+ cache = cache_dir "/" cache_file;
+
+
+ # Find out the man path
+ "man -w" | getline man_path
+ gsub(":", " ", man_path);
+ # See if anything is out of date.
+ if (system("test -f " cache) == 0) {
+ cmd = "find " man_path " -maxdepth 1 -name whatis -newer " cache;
+ cmd | getline need_update;
+ }
+ else {
+ need_update = 1;
+ }
+
+ if (need_update != "") {
+
+ if (system("test -w " cache_dir "/.") != 0) {
+ print "Content-type: text/html\n\n";
+ print "<head>";
+ print "<title>manwhatis - no cache</title>";
+ print "</head>\n<body>";
+ print "Sorry - cannot create index.";
+ print "No writable cache directory " cache_dir " exists.";
+ print "</body>";
+ exit;
+ }
+
+ "echo $PPID" | getline pid;
+
+ cache_tmp = cache "_" pid;
+ sort_tmp = cache_dir "/manwhatis_tmp_" pid ;
+ buffer_tmp = cache_dir "/manwhatis_tmp2_" pid;
+
+ sec_name[1] = "User Commands";
+ sec_name[2] = "System Calls";
+ sec_name[3] = "Library Functions";
+ sec_name[4] = "Special Files";
+ sec_name[5] = "File Formats";
+ sec_name[6] = "Games";
+ sec_name[7] = "Miscellany";
+ sec_name[8] = "Administration and Privileged Commands";
+ num_sections = 8;
+ # Print heading
+ print "Content-type: text/html\n\n" > cache_tmp;
+ print "<html>\n<head>" > cache_tmp;
+ print "<title>Manual Pages - Names and Descriptions: " section ". " sec_name[section] "</title>" > cache_tmp;
+
+ print "</head>\n<body>" > cache_tmp;
+ print "<h1>Manual Pages - Names and Descriptions</h1>" > cache_tmp;
+ print "<h1>Section " section ": " sec_name[section] "</h1>" > cache_tmp;
+ "hostname" | getline hostname;
+ "date" | getline date;
+ print hostname " (" date ")" > cache_tmp;
+ # Find out the man path
+ "man -w" | getline;
+ $1 = $1 ":";
+ gsub(":", " ", $1);
+
+ find_cmd = "find " man_path " -maxdepth 1 -name whatis -printf '%p '";
+ find_cmd | getline whatis_files;
+ close(find_cmd);
+
+ if (whatis_files == "") {
+ print "Content-type: text/html\n\n";
+ print "<head>";
+ print "<title>Manwhatis - Error updating index</title>";
+ print "</head>\n<body>";
+ print "Unable to find whatis files - Sorry."
+ print "</body>";
+ exit;
+ }
+ # Try to parse valid entries - those that contain ([0-9])
+ # Note that egrep is sometimes in /bin, sometimes in /usr/bin
+ extract_cmd = "egrep -h '\\(" section "[A-Za-z]*\\)' " whatis_files ;
+
+ print "<br>Manual pages referenced in " whatis_files "<p>" > cache_tmp;
+
+ # Note that sort sometimes lives in /bin and sometimes in /usr/bin
+ sort_cmd = "sort -f >> " sort_tmp;
+
+ while ( (extract_cmd | getline) > 0 ) {
+ if (bracket_pos = index($0, "(")) {
+ sec_full_num = substr($0, bracket_pos + 1, index($0, ")") - bracket_pos - 1);
+ names = substr($0, 1, bracket_pos - 2);
+ # Get rid of blanks and commas.
+ n = split(names, name_list, " *, *");
+ description = substr($0, bracket_pos + length(sec_full_num) + 2);
+ # Get rid of AT&T
+ gsub("&", "\&amp;", description);
+ # Generate a entry for each name
+ for (i = 1; i <= n; i++) {
+ print name_list[i] " " sec_full_num " " name_list[1] " / " description | sort_cmd;
+ }
+ }
+ }
+ close(extract_cmd);
+ close(sort_cmd);
+
+ while ((getline < sort_tmp) > 0) {
+
+ letter = tolower(substr($1,1,1));
+ if (letter != last_letter) {
+ if (last_letter) {
+ print "</dl><p>" > buffer_tmp;
+ }
+ last_letter = letter;
+ letter_index[++num_letters] = letter;
+ # Terminate list, start a new one
+
+ print "<h2> <a name=\"", letter, "\">", toupper(letter), "</a></h2>\n<dl>" > buffer_tmp ;
+ }
+ # Generate a <dt> for the name
+ if ($3 != last_file || $1 != last_name) { # Don't repeat the same entry link.
+ print "<dt><a href=\"" cgipath "/man2html?", $2, "+", $3, "\">", $1, "(", $2, ")", "</a>" > buffer_tmp;
+ last_file = $3;
+ last_name = $1;
+ }
+ print "<dd>", substr($0, match($0, "/") + 1) > buffer_tmp;
+ }
+ # Finish off last list
+
+ print "\n</dl><p>" > buffer_tmp;
+ close(buffer_tmp);
+
+ system("/bin/rm " sort_tmp);
+
+ # Print out alphabetic quick index and other links
+ for (i = 1; i <= num_letters; i++) {
+ print "<a href=\"#" letter_index[i] "\">" toupper(letter_index[i]) "</a>" > cache_tmp;
+ }
+ print "<hr>" > cache_tmp;
+ print "<a href=\"" cgipath "/man2html\">Return to Main Contents</a>" > cache_tmp;
+
+ print "<p>Other sections:" > cache_tmp;
+ for (i=1; i<=num_sections; i++) {
+ if (i != section) { # Dont print an entry for the section we are in
+ print "<a href=\"" cgipath "/manwhatis?" cgipath "+" i "\">" i ". " sec_name[i] "</a> " > cache_tmp;
+ }
+ }
+ print "<hr><p>" > cache_tmp;
+ # Print out the accumulated contents entries
+ while ((getline < buffer_tmp) > 0) print > cache_tmp;
+ print "<hr><p>" > cache_tmp;
+
+ for (i = 1; i <= num_letters; i++) {
+ print "<a href=\"#" letter_index[i] "\">" toupper(letter_index[i]) "</a>" > cache_tmp;
+ }
+ print "<hr>" > cache_tmp;
+ print "<p><a href=\"" cgipath "/man2html\">Return to Main Contents</a>" > cache_tmp;
+
+ print "<p>Other sections:" > cache_tmp;
+ for (i=1; i<=num_sections; i++) {
+ if (i != section) { # Dont print an entry for the section we are in
+ print "<a href=\"" cgipath "/manwhatis?" cgipath "+" i "\">" i ". " sec_name[i] "</a> " > cache_tmp;
+ }
+ }
+ print "</body>" > cache_tmp;
+ print "</html>" > cache_tmp;
+ system("/bin/mv " cache_tmp " " cache);
+ system("/bin/rm " buffer_tmp);
+ }
+ system("/bin/cat " cache);
+ exit;
+}
diff --git a/man2html/strdefs.c b/man2html/strdefs.c
new file mode 100644
index 0000000..8515b82
--- /dev/null
+++ b/man2html/strdefs.c
@@ -0,0 +1,176 @@
+#include "defs.h"
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+int nroff = 1;
+
+#define NROFF (-666)
+#define TROFF (-667)
+
+STRDEF *chardef, *strdef, *defdef;
+INTDEF *intdef;
+
+static INTDEF standardint[] = {
+ { V('n',' '), NROFF, 0, NULL },
+ { V('t',' '), TROFF, 0, NULL },
+ { V('o',' '), 1, 0, NULL },
+ { V('e',' '), 0, 0, NULL },
+ { V('.','l'), 70, 0, NULL },
+ { V('.','$'), 0, 0, NULL },
+ { V('.','A'), NROFF, 0, NULL },
+ { V('.','T'), TROFF, 0, NULL },
+ { V('.','V'), 1, 0, NULL }, /* the me package tests for this */
+ { 0, 0, 0, NULL } };
+
+static STRDEF standardstring[] = {
+ { V('R',' '), 1, "&#174;", NULL },
+ { V('l','q'), 2, "``", NULL },
+ { V('r','q'), 2, "''", NULL },
+ { 0, 0, NULL, NULL}
+};
+
+
+static STRDEF standardchar[] = {
+ { V('*','*'), 1, "*", NULL }, /* math star */
+ { V('*','A'), 1, "A", NULL },
+ { V('*','B'), 1, "B", NULL },
+ { V('*','C'), 2, "Xi", NULL },
+ { V('*','D'), 5, "Delta", NULL },
+ { V('*','E'), 1, "E", NULL },
+ { V('*','F'), 3, "Phi", NULL },
+ { V('*','G'), 5, "Gamma", NULL },
+ { V('*','H'), 5, "Theta", NULL },
+ { V('*','I'), 1, "I", NULL },
+ { V('*','K'), 1, "K", NULL },
+ { V('*','L'), 6, "Lambda", NULL },
+ { V('*','M'), 1, "M", NULL },
+ { V('*','N'), 1, "N", NULL },
+ { V('*','O'), 1, "O", NULL },
+ { V('*','P'), 2, "Pi", NULL },
+ { V('*','Q'), 3, "Psi", NULL },
+ { V('*','R'), 1, "P", NULL },
+ { V('*','S'), 5, "Sigma", NULL },
+ { V('*','T'), 1, "T", NULL },
+ { V('*','U'), 1, "Y", NULL },
+ { V('*','W'), 5, "Omega", NULL },
+ { V('*','X'), 1, "X", NULL },
+ { V('*','Y'), 1, "H", NULL },
+ { V('*','Z'), 1, "Z", NULL },
+ { V('*','a'), 5, "alpha", NULL },
+ { V('*','b'), 4, "beta", NULL },
+ { V('*','c'), 2, "xi", NULL },
+ { V('*','d'), 5, "delta", NULL },
+ { V('*','e'), 7, "epsilon", NULL },
+ { V('*','f'), 3, "phi", NULL },
+ { V('*','g'), 5, "gamma", NULL },
+ { V('*','h'), 5, "theta", NULL },
+ { V('*','i'), 4, "iota", NULL },
+ { V('*','k'), 5, "kappa", NULL },
+ { V('*','l'), 6, "lambda", NULL },
+ { V('*','m'), 1, "&#181;", NULL },
+ { V('*','n'), 2, "nu", NULL },
+ { V('*','o'), 1, "o", NULL },
+ { V('*','p'), 2, "pi", NULL },
+ { V('*','q'), 3, "psi", NULL },
+ { V('*','r'), 3, "rho", NULL },
+ { V('*','s'), 5, "sigma", NULL },
+ { V('*','t'), 3, "tau", NULL },
+ { V('*','u'), 7, "upsilon", NULL },
+ { V('*','w'), 5, "omega", NULL },
+ { V('*','x'), 3, "chi", NULL },
+ { V('*','y'), 3, "eta", NULL },
+ { V('*','z'), 4, "zeta", NULL },
+ { V('+','-'), 1, "&#177;", NULL },
+ { V('1','2'), 1, "&#189;", NULL },
+ { V('1','4'), 1, "&#188;", NULL },
+ { V('3','4'), 1, "&#190;", NULL },
+ { V('F','i'), 3, "ffi", NULL },
+ { V('F','l'), 3, "ffl", NULL },
+ { V('a','a'), 1, "&#180;", NULL },
+ { V('a','p'), 1, "~", NULL },
+ { V('b','r'), 1, "|", NULL },
+ { V('b','u'), 1, "*", NULL }, /* bullet */
+ { V('b','v'), 1, "|", NULL },
+ { V('c','i'), 1, "o", NULL }, /* circle */
+ { V('c','o'), 1, "&#169;", NULL },
+ { V('c','t'), 1, "&#162;", NULL },
+ { V('d','e'), 1, "&#176;", NULL },
+ { V('d','g'), 1, "+", NULL }, /* dagger */
+ { V('d','i'), 1, "&#247;", NULL },
+ { V('e','m'), 3, "---", NULL }, /* em dash */
+ { V('e','n'), 1, "-", NULL }, /* en dash */
+ { V('e','q'), 1, "=", NULL },
+ { V('e','s'), 1, "&#216;", NULL },
+ { V('f','f'), 2, "ff", NULL },
+ { V('f','i'), 2, "fi", NULL },
+ { V('f','l'), 2, "fl", NULL },
+ { V('f','m'), 1, "&#180;", NULL },
+ { V('g','a'), 1, "`", NULL },
+ { V('h','y'), 1, "-", NULL },
+ { V('l','c'), 2, "|&#175;", NULL },
+ { V('i','f'), 8, "Infinity", NULL }, /* infinity sign */
+ { V('i','s'), 8, "Integral", NULL }, /* integral sign */
+ { V('l','f'), 2, "|_", NULL },
+ { V('l','k'), 1, "<FONT SIZE=\"+2\">{</FONT>", NULL },
+ { V('m','i'), 1, "-", NULL },
+ { V('m','u'), 1, "&#215;", NULL },
+ { V('n','o'), 1, "&#172;", NULL },
+ { V('o','r'), 1, "|", NULL },
+ { V('p','d'), 1, "d", NULL }, /* partial derivative */
+ { V('p','l'), 1, "+", NULL },
+ { V('r','c'), 2, "&#175;|", NULL },
+ { V('r','f'), 2, "_|", NULL },
+ { V('r','g'), 1, "&#174;", NULL },
+ { V('r','k'), 1, "<FONT SIZE=\"+2\">}</FONT>", NULL },
+ { V('r','n'), 1, "&#175;", NULL },
+ { V('r','u'), 1, "_", NULL },
+ { V('s','c'), 1, "&#167;", NULL },
+ { V('s','l'), 1, "/", NULL },
+ { V('s','q'), 2, "[]", NULL },
+ { V('t','s'), 1, "s", NULL }, /* should be terminal sigma */
+ { V('u','l'), 1, "_", NULL },
+ { V('>','='), 1, "&gt;", NULL },
+ { V('<','='), 1, "&lt;", NULL },
+ { 0, 0, NULL, NULL }
+};
+
+void stdinit(void) {
+ STRDEF *stdf;
+ int i;
+
+ stdf = &standardchar[0];
+ i = 0;
+ while (stdf->nr) {
+ if (stdf->st) stdf->st = xstrdup(stdf->st);
+ stdf->next = &standardchar[i];
+ stdf = stdf->next;
+ i++;
+ }
+ chardef=&standardchar[0];
+
+ stdf=&standardstring[0];
+ i=0;
+ while (stdf->nr) {
+ /* waste a little memory, and make a copy, to avoid
+ the segfault when we free non-malloced memory */
+ if (stdf->st) stdf->st = xstrdup(stdf->st);
+ stdf->next = &standardstring[i];
+ stdf = stdf->next;
+ i++;
+ }
+ strdef=&standardstring[0];
+
+ intdef=&standardint[0];
+ i=0;
+ while (intdef->nr) {
+ if (intdef->nr == NROFF) intdef->nr = nroff; else
+ if (intdef->nr == TROFF) intdef->nr = !nroff;
+ intdef->next = &standardint[i];
+ intdef = intdef->next;
+ i++;
+ }
+ intdef = &standardint[0];
+ defdef = NULL;
+}