*BSD News Article 10336


Return to BSD News archive

Received: by minnie.vk1xwt.ampr.org with NNTP
	id AA7779 ; Tue, 26 Jan 93 04:01:19 EST
Path: sserve!manuel.anu.edu.au!munnari.oz.au!goanna!escargot!minyos.xx.rmit.OZ.AU!s902113
From: s902113@minyos.xx.rmit.OZ.AU (Luke Mewburn)
Newsgroups: comp.unix.bsd
Subject: man(1) command enhancements (compression, etc)
Summary: man that handles compressed/gzipped files
Keywords: compress, manual, bugfix, nifty
Message-ID: <1ju3jmINNgeh@escargot.xx.rmit.OZ.AU>
Date: 24 Jan 93 12:55:18 GMT
Organization: RMIT Computer Centre
Lines: 1670
NNTP-Posting-Host: minyos.xx.rmit.oz.au

A while back Graham Toal <gtoal@gtoal.com> posted a hacked version
of man which handled compressed manual pages (actually, at the time
I was working on my own version, but his hack was better overall, 
cause his worked with -h/-c with compressed files and mine didn't).

Anyway, since I've now installed gzip 0.8.1 on my system, I decided
to hack the new man to handle gzipped files as well. In the process,
I rewrote a script I wrote for A/UX which compresses/gzippes all files
in the manual subtree, including those with links (and restores the
links).

After cleaning up the code a bit, and modifying stuff such as the
makewhatis.db generation grok .[zZ] manual pages, I've got it ready
for the general public.

One last minute thing: whilst testing the new command, I found that
it would hang if you gave it more than one different manual page to
look for - I don't know if this was a bug that crept in with Graham's
hack, or was always there (i'm inclined to believe the latter). The
bug has also been found/fixed.

Well, here's the shar file. It will make it's own subdir, and there
is an INSTALLATION file full of meaningless stuff that you'll only
read after you can't get it working :)

Luke.

PS: Don't forget that you need to install gzip :)

--
#!/bin/sh
# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	zman
#	zman/INSTALLATION
#	zman/README.zman
#	zman/update_widb
#	zman/fixman.OLD
#	zman/man
#	zman/man/tags
#	zman/man/pathnames.h
#	zman/man/man.conf.5
#	zman/man/man.c
#	zman/man/man.1
#	zman/man/config.c
#	zman/man/Makefile
#	zman/whatis
#	zman/whatis/makewhatis.sed
#	zman/whatis/Makefile
#	zman/fixman
#
echo c - zman
mkdir zman > /dev/null 2>&1
echo x - zman/INSTALLATION
sed 's/^X//' >zman/INSTALLATION << 'END-of-zman/INSTALLATION'
XInstallation of new man(1) command and associated files.
X--------------------------------------------------------
X
X    This distribution consists of the source and auxiliary support
Xfiles needed to allow the use of compress(1)ed or gzip(1)ped files.
X
X
X    The code has be derived the original 386BSD and NET/2 manual
Xcode, with changes by the following people:
X
X    Graham Toal <gtoal@gtoal.com>
X- Modifiied man.c to enable the use of compressed manual pages.
X
X    Luke Mewburn <zak@rmit.edu.au>
X- Modified Graham's man.c to also recognize gzipped files.
X- Fixed problem with insertion of '\0' into middle of path var,
X  resulting in man file1 file2 hanging.
X- Fixes to the Makefile which generates the whatis.db to also
X  check compressed/gzipped files
X- A totally original script (fixman) which will gzip all manual
X  pages, and restore any hard/symbolic links.
X
X
X    I (Luke) haven't obtained official permission to distribute
XGraham's changes yet, but I don't think he will mind :)
X
X
X    To install this new kit, you need extract this distribution
Xinto a clean subdirectory (which you've most likely already done if
Xyou are reading this :), then do the following:
X
X1.	Install gzip (0.8.1) or later on your system. A working copy
X	should be available on ref.tfs.com in /usr/packages.
X	The normal sources can be found on your local gnu archive site
X	(for Australia, try: archie.au:/gnu)
X
X	I advise that you rename the old zcat/compress/uncompress
X	to Ozcat/Ocompress/Ouncompress, and ln gzip to compress -
X	that way you use gzip for compress, and gtar -z will also
X	use gzip. (Note that gzip 0.8.1 and later have a patch for
X	gtar 1.11.1 which allows it to recognize -z as gzip and -Z
X	as compress)
X
X	If you do replace zcat with gzip's zcat, ensure that /usr/bin/zcat
X	is a link to the gzip version of zcat.
X
X
X2.	Install the files in the whatis/ subdir into
X	/usr/othersrc/share/man.
X
X
X3.	Install fixman somewhere (/usr/local/bin maybe?)
X
X
X4.	Compile man (in man/) and install it.
X
X
X5.	Goto /usr/share/man, and run fixman. Note, it may compress
X	the whatis.db, so uncompress it again.
X
X	Before you do this, it may be an idea to set the environment
X	variable GZIP to "-9" to get the optimal compression.
X	(Note: the environment variable support is a hack I've sent
X	to Jean-loup which may or may not be implemented in the version
X	of gzip you obtain - I can send you diffs to 0.8.1 if you
X	want them)
X
X
X6.	Goto /usr/othersrc/share/man and type ``make makedb''
X
X
X7.	Install update_widb somewhere. Use this to update whatis.db
X	for a subtree when new manuals have been added.
X
X
X    Now you should have a working manual system, as well as about
X1.5-2 more free MB on your system (which will increase if you go and 
Xrecompress all .Z files with gzip -9 :)
X
X
X    If there are any problems with this, please mail me and I'll
Xtry and resolve them for you.
X
X
XLuke Mewburn <zak@rmit.edu.au>, 930124.
X
XPS: if you don't wish to use gzip, there is a version of fixman called
Xfixman.OLD which should use compress instead - except I've not tested
Xit, so beware.
END-of-zman/INSTALLATION
echo x - zman/README.zman
sed 's/^X//' >zman/README.zman << 'END-of-zman/README.zman'
XThis is a *very* quick hack to man to allow you to compress all the
Xman pages with unix compress and still be able to read them.
X
XJust go to /usr/man and do   compress */*.0 */*/*.0
X
XThere will be a lot of linked man pages that compress refuses to touch.
XEither leave them as is (I did) or unlink them, compress one by hand,
Xand relink all the .Z versions.  (Pref '-s' so you can see in future
Xwhich files were linked to what)
X
XI hope I haven't broken it.  Seems to work on everything I've tried.
X
XI started from the net2 man only because that's the only one I could
Xfind unpacked anywhere - the bsd src distribution is too big for me
Xto unpack on my machine (hey - if I had space, I wouldn't be compressing
Xthe man pages, right?)  If the 386bsd man is changed in any way from
Xthe net2 man, you'll have to fold in the mods yourself.
X
XIn the places in the code where I've been dirty, I've put comments
Xtelling people what to change if they want to spend the time to do
Xthe job properly.
X
XThis was a two-hour hack for my own benefit; if anyone else finds it
Xuseful they're welcome to it.  I won't be supporting it after this.
XIdeally the .Z compression should be done transparently by the filing
Xsystem, which I think is how bsd4.4 will do it? - in which case this
Xhack will be redundant.
X
XGraham Toal <gtoal@gtoal.com>
XPS Create a directory /usr/local/src/man/man for this, and
Xln -s /usr/local/src/man/man/man /usr/bin/man to install it.
XBuild this with cc -o man man.c config.c
X[config.c is straight off the net2 tape - only man.c and pathnames.h were
Xhacked]
END-of-zman/README.zman
echo x - zman/update_widb
sed 's/^X//' >zman/update_widb << 'END-of-zman/update_widb'
Xif [ $# -ne 1 ]; then
X    echo "Usage: $0 dir"
X    echo "	updates the subtree dir in the whatis.db"
X    exit 0
Xfi
X
Xecho "Updating subdir $1 in the whatis.db"
Xfor file in `find $1 -type f -name '*.0' -print`; do \
X    sed -n -f /usr/share/man/makewhatis.sed $file; \
Xdone | col -b >> whatis.db
Xfor file in `find $1 -type f -name '*.0.[zZ]' -print`; do \
X    zcat $file | sed -n -f /usr/share/man/makewhatis.sed; \
Xdone | col -b >> whatis.db
Xsort -u -o whatis.db whatis.db
END-of-zman/update_widb
echo x - zman/fixman.OLD
sed 's/^X//' >zman/fixman.OLD << 'END-of-zman/fixman.OLD'
X#!/bin/sh
X#
X# File: fixman.OLD
X# By:   Luke Mewburn (zak@rmit.EDU.AU)
X# Date: 930117
X# Vers: 2.0.1o
X#
X#
X# Synopsis:
X#	converts a manual tree to compressed format.
X#
X# Usage:
X#	fixman
X#
X# 	This converts all compressed and normal files in the current subtree
X# (with links) to compressed files (with # correct links)
X#
X# Bugs:
X#  - slow
X#
X#  - NOT TESTED - you have been warned
X#    --- ------
X#
X
Xls -li `find . \( -type f -o -type l \)` | \
Xsort | \
Xawk '
X{
X    if (NF == 11)
X    {
X	if ($10 == "->")
X	{
X	    symlink_arr[ $9 ] = $11
X	    printf "echo adding %s, %s to arr\n", $9, $11
X	}
X	next
X    }
X    if (NF != 9 )
X	next
X    links=$3
X    orig=$9
X#    if (index(orig, ".Z") != 0)
X#    {
X#	printf "gunzip %s\n", orig
X#	sub("\.Z$", "", orig)
X#    }
X    if (index(orig, ".Z") == 0)
X    {
X	printf "cat %s | compress -c > %s.Z\n", orig, orig
X	printf "rm -f %s\n", orig
X	printf "echo %s compressed.\n", orig
X    }
X    if (links>1)
X    {
X	inode=$1
X	for (count=1; count <links ; count++)
X	{
X	    getline
X	    if ($1 != inode)
X		next
X	    nxtnam=$9
X	    if (index(nxtnam, ".Z") != 0)
X	    {
X#		printf "echo skipping %s\n", nxtnam
X		continue;
X	    }
X	    printf "rm %s\n", $9
X#	    sub("\.Z$", "", nxtnam)
X	    printf "if ( -e %s.Z ) then\n", orig
X	    printf "  ln %s.Z %s.Z\n", orig, nxtnam
X	    printf "  echo %s.Z linked to %s.Z.\n", orig, nxtnam
X	    print  "else"
X	    printf "  ln %s %s\n", orig, nxtnam
X	    printf "  echo %s linked to %s.\n", orig, nxtnam
X	    print  "endif"
X	}
X    }
X}
X
XEND {
X    printf "\necho re-fixing symbolic links:\n"
X    for ( elm in symlink_arr )
X    {
X	src = symlink_arr[ elm ]
X	printf "rm %s\n", elm
X	printf "if ( -e `dirname %s`/%s.Z ) then\n", elm, src
X	printf "  ln -s %s.Z %s.Z\n", src, elm
X	printf "  echo %s.Z symlinked to %s.Z.\n", elm, src
X	print  "else"
X	printf "  ln -s %s %s\n", src, elm
X	printf "  echo %s symlinked to %s.\n", elm, src
X	print  "endif"
X    }
X}
X' | csh -f
END-of-zman/fixman.OLD
echo c - zman/man
mkdir zman/man > /dev/null 2>&1
echo x - zman/man/tags
sed 's/^X//' >zman/man/tags << 'END-of-zman/man/tags'
END-of-zman/man/tags
echo x - zman/man/pathnames.h
sed 's/^X//' >zman/man/pathnames.h << 'END-of-zman/man/pathnames.h'
X/*
X * Copyright (c) 1989 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X *    must display the following acknowledgement:
X *	This product includes software developed by the University of
X *	California, Berkeley and its contributors.
X * 4. Neither the name of the University nor the names of its contributors
X *    may be used to endorse or promote products derived from this software
X *    without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X *
X *	@(#)pathnames.h	5.4 (Berkeley) 6/1/90
X */
X
X#define	_PATH_MANCONF	"/etc/man.conf"
X#define	_PATH_PAGER	"/usr/bin/more -s"
X#define	_PATH_WHATIS	"whatis.db"
X#define _PATH_ZCAT	"/usr/bin/zcat"
END-of-zman/man/pathnames.h
echo x - zman/man/man.conf.5
sed 's/^X//' >zman/man/man.conf.5 << 'END-of-zman/man/man.conf.5'
X.\" Copyright (c) 1989, 1991 The Regents of the University of California.
X.\" All rights reserved.
X.\"
X.\" Redistribution and use in source and binary forms, with or without
X.\" modification, are permitted provided that the following conditions
X.\" are met:
X.\" 1. Redistributions of source code must retain the above copyright
X.\"    notice, this list of conditions and the following disclaimer.
X.\" 2. Redistributions in binary form must reproduce the above copyright
X.\"    notice, this list of conditions and the following disclaimer in the
X.\"    documentation and/or other materials provided with the distribution.
X.\" 3. All advertising materials mentioning features or use of this software
X.\"    must display the following acknowledgement:
X.\"	This product includes software developed by the University of
X.\"	California, Berkeley and its contributors.
X.\" 4. Neither the name of the University nor the names of its contributors
X.\"    may be used to endorse or promote products derived from this software
X.\"    without specific prior written permission.
X.\"
X.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X.\" SUCH DAMAGE.
X.\"
X.\"     @(#)man.conf.5	5.6 (Berkeley) 5/10/91
X.\"
X.Dd May 10, 1991
X.Dt MAN.CONF 5
X.Sh NAME
X.Nm man.conf
X.Nd configuration file for
X.Xr man 1
X.Sh DESCRIPTION
XThe
X.Xr man 1 ,
X.Xr apropos 1 ,
Xand
X.Xr whatis 1
Xcommands
Xsearch for manual pages or their database files as specified by the
X.Nm man.conf
Xfile.
XManual pages are expected to be preformatted (see
X.Xr nroff 1 )
Xand named with a trailing ``.0''.
X.Pp
XThe
X.Nm man.conf
Xfile contains two types of lines.
X.Pp
XThe first type of line is a ``section'' line, which contains a
Xsection name followed by a directory path.
XLines in this format specify that manual pages for the section
Xmay be found in the directory.
X.Pp
XDirectories named with a trailing slash character (``/'') are expected
Xto contain subdirectories (see the keyword ``_subdir'' below) instead
Xof manual pages.
XThese subdirectories are searched instead of the directory.
X.Pp
XAll directories (either explicitly specified or named with a trailing
Xslash) may contain subdirectories.
XThe
X.Xr man 1
Xcommand
Xautomatically searches any subdirectory with the same name as the
Xcurrent machine type before the directory is searched.
XNo specification of these subdirectories is necessary in the
X.Nm man.conf
Xfile.
X.Pp
XSection names are unrestricted except for the reserved words specified
Xbelow; in general, however, it is best to avoid anything beginning with
Xan underscore (``_'') in order to avoid future incompatibilities.
X.Pp
XThe section named ``_default'' is the list of directories to be
Xsearched if no section is specified.
X.Pp
XThe second type of line is preceded with a ``keyword''.
XThe possible keywords and their meanings are as follows:
X.Pp
X.Bl -tag -width indent
X.It _subdir
XThe list (in search order) of subdirectories which will be searched in
Xany directory named with a trailing slash (``/'') character.  This
Xlist is also used when a path is specified by the
X.Ev MANPATH
Xenvironment 
Xvariable or the
X.Fl M
Xoption.
X.It _version
XThe version of the configuration file.
X.It _whatdb
XThe full pathname (not just a directory path) for a database to be used
Xby the
X.Xr apropos 1
Xand
X.Xr whatis 1
Xcommands.
X.El
X.Pp
XMultiple specifications for all types of lines (except for ``_version'')
Xare cumulative and the entries are used in the order listed in the file;
Xmultiple entries may be listed per line, as well.
X.Pp
XEmpty lines or lines whose first non-whitespace character is a hash
Xmark (``#'') are ignored.
X.Sh EXAMPLES
XGiven the following
X.Nm man.conf
Xfile:
X.Bd -literal -offset indent
X_version	BSD.1
X_subdir		cat1 cat2 cat3
X_default	/usr/share/man/
Xsect3		/usr/share/man/cat3
X.Ed
X.Pp
XThe default
X.Xr mktemp 3
Xmanual page should be stored in
X.Dq Pa /usr/share/man/cat3/mktemp.0 .
XAny
X.Tn VAX
Xarchitecture specific version of it should be stored in
X.Dq Pa cat3/vax/mktemp.0 .
X.Pp
XThe command
X.Dq Li man mktemp
Xwould search the subdirectories
X.Dq Pa cat1
X.Dq Pa cat2 ,
Xand
X.Dq Pa cat3 ,
Xin
X.Dq Pa /usr/share/man ,
Xin that order, for
X.Dq Pa mktemp.0''.
XIf a subdirectory with the same name as the current machine type
Xexisted in any of them, it would be searched as well.
X.Pp
XThe command
X.Dq Li man sect3 mktemp
Xwould only search
X.Dq Li /usr/share/man/cat3
Xand any possible per machine subdirectory.
X.Sh FILES
X.Bl -tag -width /etc/man.conf -compact
X.It Pa /etc/man.conf
XStandard manual directory search path.
X.El
X.Sh SEE ALSO
X.Xr apropos 1 ,
X.Xr machine 1 ,
X.Xr man 1 ,
X.Xr whatis 1 ,
X.Xr whereis 1
X.Sh HISTORY
XThe
X.Nm
Xfile format
X.Ud .
END-of-zman/man/man.conf.5
echo x - zman/man/man.c
sed 's/^X//' >zman/man/man.c << 'END-of-zman/man/man.c'
X/*
X * Copyright (c) 1987 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X *    must display the following acknowledgement:
X *	This product includes software developed by the University of
X *	California, Berkeley and its contributors.
X * 4. Neither the name of the University nor the names of its contributors
X *    may be used to endorse or promote products derived from this software
X *    without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X */
X
X/*
X * Modified by Graham Toal <gtoal@gtoal.com> to allow compressed
X * manual pages.
X *
X * Modified by Luke Mewburn <zak@rmit.edu.au>:
X *  - allow gzipped manual pages.
X *  - fixed trashing of path variable in manual();
X *  - removed a lot of mallocs/frees which were unnecessary
X */
X
X
X#ifndef lint
Xchar copyright[] =
X"@(#) Copyright (c) 1987 Regents of the University of California.\n\
X All rights reserved.\n";
X#endif /* not lint */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)man.c	5.25 (386bsd) 01/24/92";
X#endif /* not lint */
X
X#include <sys/param.h>
X#include <sys/file.h>
X#include <errno.h>
X#include <stdio.h>
X#include <ctype.h>
X#include <string.h>
X#include <stdlib.h>
X#include <unistd.h> /* For mktemp */
X#include "pathnames.h"
X
Xextern int errno;
X
Xint f_all, f_cat, f_how, f_where;
Xchar *command, *machine, *p_augment, *p_path, *pager, *progname;
Xextern char **arorder, *pathbuf;
X
Xtypedef struct strlist {
X	char *fname;
X	struct strlist *next;
X} STRLIST;
X
XSTRLIST *delete_list = NULL;
X
Xvoid *
Xqueue_delete(fname)
Xchar *fname;
X{
X	STRLIST *l;
X	l = malloc(sizeof(STRLIST));
X	if (l == NULL)
X		enomem();
X	l->fname = strdup(fname);
X	if (l->fname == NULL)
X		enomem();
X	l->next = delete_list; delete_list = l;
X}
X
Xvoid delete_temps(void)
X{
X	while (delete_list != NULL) {
X		remove(delete_list->fname);
X/*		free(delete_list->fname);  - why slow the exit down...*/
X		delete_list = delete_list->next;
X	}
X}
X
XFILE *
Xmanopen(fname)
Xchar *fname;
X{
X	FILE *fp;
X	int l = strlen(fname);
X	if ((l > 2) && (strcasecmp(fname+l-2, ".Z") == 0)) {
X	    /* Should really look up env var first and stick in a variable */
X		command = malloc(strlen(_PATH_ZCAT)+1+strlen(fname)+1);
X		if (command == NULL) enomem();
X		sprintf(command, "%s %s", _PATH_ZCAT, fname);
X/*
X * should really do a check_zcat() like check_pager() -
X * but why bother.  1) it had better be there if people
X * have gone around compressing man pages, and 2) the
X * popen() will fail cleanly enough to give some sort
X * of error message...  Another alternative is my ZFILE *
X * interface which allows a zfopen(filename, mode)
X * and does all the decompressin itself without popen(),
X * but again, since this is for 386bsd and we always
X * have popen(), why bother?    - Graham
X */
X		if ((fp = popen(command, "r")) == NULL) {
X			(void)fprintf(stderr, "man: %s: %s\n", fname, strerror(errno));
X			exit(1);
X		}
X	} else if ((fp = fopen(fname, "r")) == NULL) {
X		(void)fprintf(stderr, "man: %s: %s\n", fname, strerror(errno));
X		exit(1);
X	} else {
X	}
X	if (command != NULL) free(command); command = NULL;
X	return(fp);
X}
X
Xint
Xmain(argc, argv)
X	int argc;
X	register char **argv;
X{
X	extern char *optarg;
X	extern int optind;
X	int ch, res;
X	char *section[2], *check_pager(), *getpath(), **getorder(), *tmp;
X
X	atexit(delete_temps);
X	progname = "man";
X	while ((ch = getopt(argc, argv, "-acfhkM:m:P:w")) != EOF)
X		switch((char)ch) {
X		case 'a':
X			f_all = 1;
X			break;
X		case 'c':
X		case '-':		/* deprecated */
X			f_cat = 1;
X			break;
X		case 'h':
X			f_how = 1;
X			break;
X		case 'm':
X			p_augment = optarg;
X			break;
X		case 'M':
X		case 'P':		/* backward compatibility */
X			p_path = optarg;
X			break;
X		/*
X		 * "man -f" and "man -k" are backward compatible, undocumented
X		 * ways of calling whatis(1) and apropos(1).
X		 */
X		case 'f':
X			jump(argv, "-f", "whatis");
X			/* NOTREACHED */
X		case 'k':
X			jump(argv, "-k", "apropos");
X			/* NOTREACHED */
X		case 'w':
X			f_all = f_where = 1;
X			break;
X		case '?':
X		default:
X			usage();
X		}
X	argv += optind;
X
X	if (!*argv)
X		usage();
X
X	if (!f_cat && !f_how)
X		if (!isatty(1))
X			f_cat = 1;
X		else if (pager = getenv("PAGER"))
X			pager = check_pager(pager);
X		else
X			pager = _PATH_PAGER;
X
X	if (!(machine = getenv("MACHINE")))
X		machine = MACHINE;
X
X	/* see if checking in a specific section */
X	if (argc > 1 && getsection(*argv)) {
X		section[0] = *argv++;
X		section[1] = (char *)NULL;
X	} else {
X		section[0] = "_default";
X		section[1] = (char *)NULL;
X	}
X
X	arorder = getorder();
X	if (p_path || (p_path = getenv("MANPATH"))) {
X		char buf[MAXPATHLEN], **av;
X
X		tmp = strtok(p_path, ":"); 
X		while (tmp) {
X			(void)sprintf(buf, "%s/", tmp);
X			for (av = arorder; *av; ++av)
X                		cadd(buf, strlen(buf), *av);
X			tmp = strtok((char *)NULL, ":"); 
X		}
X		p_path = pathbuf;
X	} else if (!(p_path = getpath(section)) && !p_augment) {
X		(void)fprintf(stderr,
X			"man: no place to search for those manual pages.\n");
X		exit(1);
X	}
X
X	for (; *argv; ++argv) {
X		if (p_augment)
X			res = manual(p_augment, *argv);
X		res = manual(p_path, *argv);
X		if (res || f_where)
X			continue;
X		(void)fprintf(stderr,
X		    "man: no entry for %s in the manual.\n", *argv);
X		exit(1);
X	}
X
X	/* use system(3) in case someone's pager is "pager arg1 arg2" */
X	if (command)
X		(void)system(command);
X	exit(0);
X}
X
X/*
X * manual --
X *	given a path, a directory list and a file name, find a file
X *	that matches; check ${directory}/${dir}/{file name} and
X *	${directory}/${dir}/${machine}/${file name}.
X */
Xmanual(path, name)
X	char *path, *name;
X{
X	register int res;
X	register char *end;
X	char fname[MAXPATHLEN + 1], tpath[MAXPATHLEN+1];
X
X	for (res = 0;; path = end + 1) {
X		if (!*path)				/* foo: */
X			break;
X		if (end = index(path, ':')) {
X			if (end == path + 1)		/* foo::bar */
X				continue;
X			    /* stop path getting trashed  - Luke*/
X			res = end - path;
X			strncpy(tpath, path, res);
X			tpath[res] = '\0';
X		}
X		else
X			strcpy(tpath, path);
X		(void)sprintf(fname, "%s/%s.0", tpath, name);
X		if (access(fname, R_OK)) {
X		    strcat(fname, ".z");
X		    if (access(fname, R_OK)) {
X			fname[strlen(fname)-1] = 'Z';
X			if (access(fname, R_OK)) {
X			    (void)sprintf(fname, "%s/%s/%s.0", tpath, machine, name);
X			    if (access(fname, R_OK)) {
X				strcat(fname, ".z");
X				if (access(fname, R_OK)) {
X				    fname[strlen(fname)-1] = 'Z';
X				    if (access(fname, R_OK)) {
X					continue;
X				    }
X				}
X			    }
X			}
X		    }
X		}
X
X		if (f_where)
X			(void)printf("man: found in %s.\n", fname);
X		else if (f_cat)
X			cat(fname);
X		else if (f_how)
X			how(fname);
X		else
X			add(fname);
X		if (!f_all)
X			return(1);
X		res = 1;
X		if (!end)
X			break;
X		*end = ':';
X	}
X	return(res);
X}
X
X/*
X * how --
X *	display how information
X */
Xhow(fname)
X	char *fname;
X{
X	register FILE *fp;
X
X	register int lcnt, print;
X	register char *p;
X	char buf[BUFSIZ];
X
X	if (!(fp = manopen(fname))) {
X		(void)fprintf(stderr, "man: %s: %s\n", fname, strerror(errno));
X		exit(1);
X	}
X#define	S1	"SYNOPSIS"
X#define	S2	"S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS"
X#define	D1	"DESCRIPTION"
X#define	D2	"D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN"
X	for (lcnt = print = 0; fgets(buf, sizeof(buf), fp);) {
X		if (!strncmp(buf, S1, sizeof(S1) - 1) ||
X		    !strncmp(buf, S2, sizeof(S2) - 1)) {
X			print = 1;
X			continue;
X		} else if (!strncmp(buf, D1, sizeof(D1) - 1) ||
X		    !strncmp(buf, D2, sizeof(D2) - 1))
X			return;
X		if (!print)
X			continue;
X		if (*buf == '\n')
X			++lcnt;
X		else {
X			for(; lcnt; --lcnt)
X				(void)putchar('\n');
X			for (p = buf; isspace(*p); ++p);
X			(void)fputs(p, stdout);
X		}
X	}
X	(void)fclose(fp);
X}
X/*
X * cat --
X *	cat out the file
X */
Xcat(fname)
X	char *fname;
X{
X	register int n;
X	FILE *fp;
X	char buf[BUFSIZ];
X
X	fp = manopen(fname);
X	for (;;) {
X		n = fread(buf, 1, sizeof(buf), fp);
X		if (n <= 0) break;
X		if (fwrite(buf, 1, n, stdout) != n) {
X			(void)fprintf(stderr,
X			    "man: write: %s\n", strerror(errno));
X			exit(1);
X		}
X	}
X	(void)fclose(fp);
X}
X
X/*
X * add --
X *	add a file name to the list for future paging
X */
Xadd(fname)
X	char *fname;
X{
X	static u_int buflen;
X	static int len;
X	static char *cp;
X	int flen;
X
X	if (!command) {
X		if (!(command = malloc(buflen = 1024)))
X			enomem();
X		len = strlen(strcpy(command, pager));
X		cp = command + len;
X	}
X	/* If filename ends in .Z, decompress it and more the tmp file */
X	flen = strlen(fname);
X	if (strcasecmp(fname+flen-2, ".Z") == 0) {
X/*
X * These local arrays should be off the heap, but this
X * is one of those quick hack programs that works and
X * I can't be bothered.  Someone else do it if it's a
X * problem.  Sorry folks.  - Graham
X */
X		char temp[256];
X		char cmnd[256];
X		char rootname[256];
X		char *s;
X		s = fname+flen-2-1;
X		for (;;) {
X			if (s == fname) break;
X			if (*(s-1) == '/') break;
X			s -= 1;
X		}
X		strcpy(rootname, s);
X		rootname[strlen(rootname)-2] = '\0';
X		sprintf(temp, "/tmp/%s.XXXX", rootname);
X		(void)mktemp(temp);
X		    /* And queue temp file for deletion */
X		queue_delete(temp);
X		sprintf(cmnd, "%s %s > %s", _PATH_ZCAT, fname, temp);
X		system(cmnd);
X		strcpy(fname, temp);	/* in manual(), fname is an array */
X	}
X	flen = strlen(fname);
X	if (len + flen + 2 > buflen) {		/* +2 == space, EOS */
X		if (!(command = realloc(command, buflen += 1024)))
X			enomem();
X		cp = command + len;
X	}
X	*cp++ = ' ';
X	len += flen + 1;			/* +1 = space */
X	(void)strcpy(cp, fname);
X	cp += flen;
X}
X
X/*
X * check_pager --
X *	check the user supplied page information
X */
Xchar *
Xcheck_pager(name)
X	char *name;
X{
X	register char *p;
X	char *save;
X
X	/*
X	 * if the user uses "more", we make it "more -s"; watch out for
X	 * PAGER = "mypager /usr/ucb/more"
X	 */
X	for (p = name; *p && !isspace(*p); ++p);
X	for (; p > name && *p != '/'; --p);
X	if (p != name)
X		++p;
X
X	/* make sure it's "more", not "morex" */
X	if (!strncmp(p, "more", 4) && (!p[4] || isspace(p[4]))){
X		save = name;
X		/* allocate space to add the "-s" */
X		if (!(name =
X		    malloc((u_int)(strlen(save) + sizeof("-s") + 1))))
X			enomem();
X		(void)sprintf(name, "%s %s", save, "-s");
X	}
X	return(name);
X}
X
X/*
X * jump --
X *	strip out flag argument and jump
X */
Xjump(argv, flag, name)
X	char **argv, *name;
X	register char *flag;
X{
X	register char **arg;
X
X	argv[0] = name;
X	for (arg = argv + 1; *arg; ++arg)
X		if (!strcmp(*arg, flag))
X			break;
X	for (; *arg; ++arg)
X		arg[0] = arg[1];
X	execvp(name, argv);
X	(void)fprintf(stderr, "%s: Command not found.\n", name);
X	exit(1);
X}
X
X/*
X * usage --
X *	print usage message and die
X */
Xusage()
X{
X	(void)fprintf(stderr,
X	    "usage: man [-ac] [-M path] [-m path] [section] title ...\n");
X	exit(1);
X}
END-of-zman/man/man.c
echo x - zman/man/man.1
sed 's/^X//' >zman/man/man.1 << 'END-of-zman/man/man.1'
X.\" Copyright (c) 1989, 1990 The Regents of the University of California.
X.\" All rights reserved.
X.\"
X.\" Redistribution and use in source and binary forms, with or without
X.\" modification, are permitted provided that the following conditions
X.\" are met:
X.\" 1. Redistributions of source code must retain the above copyright
X.\"    notice, this list of conditions and the following disclaimer.
X.\" 2. Redistributions in binary form must reproduce the above copyright
X.\"    notice, this list of conditions and the following disclaimer in the
X.\"    documentation and/or other materials provided with the distribution.
X.\" 3. All advertising materials mentioning features or use of this software
X.\"    must display the following acknowledgement:
X.\"	This product includes software developed by the University of
X.\"	California, Berkeley and its contributors.
X.\" 4. Neither the name of the University nor the names of its contributors
X.\"    may be used to endorse or promote products derived from this software
X.\"    without specific prior written permission.
X.\"
X.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X.\" SUCH DAMAGE.
X.\"
X.\"     @(#)man.1	6.14 (Berkeley) 4/29/91
X.\"
X.Dd April 29, 1991
X.Dt MAN 1
X.Os BSD 4
X.Sh NAME
X.Nm man
X.Nd display the on-line manual pages
X.Sh SYNOPSIS
X.Nm man
X.Op Fl achw
X.Op Fl M Ar path
X.Op Fl m Ar path
X.Op Ar section
X.Ar name Ar ...
X.Sh DESCRIPTION
XThe
X.Nm man
Xutility
Xdisplays the
X.Bx
Xmanual pages entitled
X.Ar name .
X.Pp
XThe options are as follows:
X.Bl -tag -width indent
X.It Fl a
XDisplay all of the manual pages for a specified
X.Ar section
Xand
X.Ar name
Xcombination.
X(Normally, only the first manual page found is displayed.)
X.It Fl c
XCopy the manual page to the standard output instead of using
X.Xr more 1
Xto paginate it.
XThis is done by default if the standard output is not a terminal device.
X.It Fl h
XDisplay only the
X.Dq Tn SYNOPSIS
Xlines of the requested manual pages.
X.It Fl M
XOverride the list of standard directories which
X.Nm man
Xsearches for manual pages.
XThe supplied
X.Ar path
Xmust be a colon (``:'') separated list of directories.
XThis search path may also be set using the environment variable
X.Ev MANPATH .
XThe subdirectories to be searched as well as their search order
Xis specified by the ``_subdir'' line in the
X.Nm man
Xconfiguration file.
X.It Fl m
XAugment the list of standard directories which
X.Nm man
Xsearches for manual pages.
XThe supplied
X.Ar path
Xmust be a colon (``:'') separated list of directories.
XThese directories will be searched before the standard directories or
Xthe directories specified using the
X.Fl M
Xoption or the
X.Ev MANPATH
Xenvironment variable.
X.It Fl w
XList the pathnames of the manual pages which
X.Nm man
Xwould display for the specified
X.Ar section
Xand
X.Ar name
Xcombination.
X.El
X.Pp
XThe optional
X.Ar section
Xrestricts the directories that
X.Nm man
Xwill search.
XThe
X.Nm man
Xconfiguration file (see
X.Xr man_conf 5 )
Xspecifies the possible
X.Ar section
Xvalues that are currently available.
XIf only a single argument is specified or if the first argument is
Xnot a valid section,
X.Nm man
Xassumes that the argument is the name of a manual page to be displayed.
X.Sh ENVIRONMENT
X.Bl -tag -width MANPATHX
X.It Ev MACHINE
XAs some manual pages are intended only for use on certain architectures,
X.Nm man
Xsearches certain directories applicable to the current machine.
XMan's
Xdetermination of the current machine type may be overridden by setting
Xthe environment variable
X.Ev MACHINE
Xto the name of an architecture (see
X.Xr machine 1 ) .
XMachine specific areas are checked before general areas.
X.It Ev MANPATH
XThe standard search path used by
X.Nm man
Xmay be overridden by specifying a path in the
X.Ev MANPATH
Xenvironment
Xvariable.
XThe format of the path is a colon (``:'') separated list of directories.
XThe subdirectories to be searched as well as their search order
Xis specified by the ``_subdir'' line in the
X.Nm man
Xconfiguration file.
X.It Ev PAGER
XAny value of the environment variable
X.Ev PAGER
Xwill be used instead of the standard pagination program
X.Xr more 1 .
X.El
X.Sh FILES
X.Bl -tag -width /etc/man.conf -compact
X.It Pa /etc/man.conf
Xman configuration file (see
X.Xr man_conf 5 )
X.El
X.Sh SEE ALSO
X.Xr apropos 1 ,
X.Xr machine 1 ,
X.Xr whatis 1 ,
X.Xr whereis 1 ,
X.Xr man_conf 5
X.Sh BUGS
XThe on-line manual pages are, by necessity, forgiving toward stupid
Xdisplay devices, causing some manual pages to not be as good as their
Xtypeset counterparts.
X.Sh HISTORY
XA
X.Nm
Xcommand appeared in
X.At v6 .
XThe ability to display manual pages compressed with
X.Xr compress 1
Xwas added by Luke Mewburn (zak@rmit.edu.au), 930105.
END-of-zman/man/man.1
echo x - zman/man/config.c
sed 's/^X//' >zman/man/config.c << 'END-of-zman/man/config.c'
X/*
X * Copyright (c) 1989 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X *    must display the following acknowledgement:
X *	This product includes software developed by the University of
X *	California, Berkeley and its contributors.
X * 4. Neither the name of the University nor the names of its contributors
X *    may be used to endorse or promote products derived from this software
X *    without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X *
X * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
X * --------------------         -----   ----------------------
X * CURRENT PATCH LEVEL:         1       00008
X * --------------------         -----   ----------------------
X *
X * 03 Sep 92	James Dolter		Fixed 1K pathbuf bug
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)config.c	5.6 (Berkeley) 3/1/91";
X#endif /* not lint */
X
X#include <sys/param.h>
X#include <stdio.h>
X#include <errno.h>
X#include <string.h>
X#include <stdlib.h>
X#include <pwd.h>
X#include "pathnames.h"
X
X#define	MAXLINE		1024
X
Xextern char *progname;
Xchar *pathbuf, **arorder;
X
Xstatic FILE *cfp;
X
X/*
X * getpath --
X *	read in the configuration file, calling a function with the line
X *	from each matching section.
X */
Xchar *
Xgetpath(sects)
X	char **sects;
X{
X	register char **av, *p;
X	size_t len;
X	char line[MAXLINE];
X	static int openconfig();
X
X	openconfig();
X	while (fgets(line, sizeof(line), cfp)) {
X		if (!index(line, '\n')) {
X			(void)fprintf(stderr, "%s: config line too long.\n",
X			    progname);
X			exit(1);
X		}
X		p = strtok(line, " \t\n");
X		if (!p || *p == '#')
X			continue;
X		for (av = sects; *av; ++av)
X			if (!strcmp(p, *av))
X				break;
X		if (!*av)
X			continue;
X		while (p = strtok((char *)NULL, " \t\n")) {
X			len = strlen(p);
X			if (p[len - 1] == '/')
X				for (av = arorder; *av; ++av)
X                			cadd(p, len, *av);
X			else
X				cadd(p, len, (char *)NULL);
X		}
X	}
X	return(pathbuf);
X}
X
Xcadd(add1, len1, add2)
Xchar *add1, *add2;
Xregister size_t len1;
X{
X	static size_t buflen;
X	static char *bp, *endp;
X	register size_t len2;
X	register size_t	oldlen;				/* 03 Sep 92*/
X
X	len2 = add2 ? strlen(add2) : 0;
X	if (!bp || bp + len1 + len2 + 2 >= endp) {
X		oldlen = bp - pathbuf;			/* 03 Sep 92*/
X		if (!(pathbuf = realloc(pathbuf, buflen += 1024)))
X			enomem();
X		bp = pathbuf + oldlen;			/* 03 Sep 92*/
X		endp = pathbuf + buflen;
X	}
X	bcopy(add1, bp, len1);
X	bp += len1;
X	if (len2) {
X		bcopy(add2, bp, len2);
X		bp += len2;
X	}
X	*bp++ = ':';
X	*bp = '\0';
X}
X
Xstatic
Xopenconfig()
X{
X	if (cfp) {
X		rewind(cfp);
X		return;
X	}
X	if (!(cfp = fopen(_PATH_MANCONF, "r"))) {
X		(void)fprintf(stderr, "%s: no configuration file %s.\n",
X		    progname, _PATH_MANCONF);
X		exit(1);
X	}
X}
X
Xchar **
Xgetdb()
X{
X	register char *p;
X	int cnt, num;
X	char **ar, line[MAXLINE];
X
X	ar = NULL;
X	num = 0;
X	cnt = -1;
X	openconfig();
X	while (fgets(line, sizeof(line), cfp)) {
X		if (!index(line, '\n')) {
X			(void)fprintf(stderr, "%s: config line too long.\n",
X			    progname);
X			exit(1);
X		}
X		p = strtok(line, " \t\n");
X#define	WHATDB	"_whatdb"
X		if (!p || *p == '#' || strcmp(p, WHATDB))
X			continue;
X		while (p = strtok((char *)NULL, " \t\n")) {
X			if (cnt == num - 1 &&
X			    !(ar = realloc(ar, (num += 30) * sizeof(char **))))
X				enomem();
X			if (!(ar[++cnt] = strdup(p)))
X				enomem();
X		}
X	}
X	if (ar) {
X		if (cnt == num - 1 &&
X		    !(ar = realloc(ar, ++num * sizeof(char **))))
X			enomem();
X		ar[++cnt] = NULL;
X	}
X	return(ar);
X}
X
Xchar **
Xgetorder()
X{
X	register char *p;
X	int cnt, num;
X	char **ar, line[MAXLINE];
X
X	ar = NULL;
X	num = 0;
X	cnt = -1;
X	openconfig();
X	while (fgets(line, sizeof(line), cfp)) {
X		if (!index(line, '\n')) {
X			(void)fprintf(stderr, "%s: config line too long.\n",
X			    progname);
X			exit(1);
X		}
X		p = strtok(line, " \t\n");
X#define	SUBDIR	"_subdir"
X		if (!p || *p == '#' || strcmp(p, SUBDIR))
X			continue;
X		while (p = strtok((char *)NULL, " \t\n")) {
X			if (cnt == num - 1 &&
X			    !(ar = realloc(ar, (num += 30) * sizeof(char **))))
X				enomem();
X			if (!(ar[++cnt] = strdup(p)))
X				enomem();
X		}
X	}
X	if (ar) {
X		if (cnt == num - 1 &&
X		    !(ar = realloc(ar, ++num * sizeof(char **))))
X			enomem();
X		ar[++cnt] = NULL;
X	}
X	return(ar);
X}
X
Xgetsection(sect)
X	char *sect;
X{
X	register char *p;
X	char line[MAXLINE];
X
X	openconfig();
X	while (fgets(line, sizeof(line), cfp)) {
X		if (!index(line, '\n')) {
X			(void)fprintf(stderr, "%s: config line too long.\n",
X			    progname);
X			exit(1);
X		}
X		p = strtok(line, " \t\n");
X		if (!p || *p == '#')
X			continue;
X		if (!strcmp(p, sect))
X			return(1);
X	}
X	return(0);
X}
X
Xenomem()
X{
X	(void)fprintf(stderr, "%s: %s\n", progname, strerror(ENOMEM));
X	exit(1);
X}
END-of-zman/man/config.c
echo x - zman/man/Makefile
sed 's/^X//' >zman/man/Makefile << 'END-of-zman/man/Makefile'
X#	@(#)Makefile	5.12 (Berkeley) 9/30/90
X
XPROG=	man
XSRCS=	config.c man.c
XMAN1=	man.0
XMAN5=	man.conf.0
X
X#.include "../Makefile.inc"
X.include <bsd.prog.mk>
END-of-zman/man/Makefile
echo c - zman/whatis
mkdir zman/whatis > /dev/null 2>&1
echo x - zman/whatis/makewhatis.sed
sed 's/^X//' >zman/whatis/makewhatis.sed << 'END-of-zman/whatis/makewhatis.sed'
X#!/usr/bin/sed -
X#
X# This file is: /usr/othersrc/share/man/makewhatis.sed
X#
X# Copyright (c) 1988 The Regents of the University of California.
X# All rights reserved.
X#
X# Redistribution and use in source and binary forms, with or without
X# modification, are permitted provided that the following conditions
X# are met:
X# 1. Redistributions of source code must retain the above copyright
X#    notice, this list of conditions and the following disclaimer.
X# 2. Redistributions in binary form must reproduce the above copyright
X#    notice, this list of conditions and the following disclaimer in the
X#    documentation and/or other materials provided with the distribution.
X# 3. All advertising materials mentioning features or use of this software
X#    must display the following acknowledgement:
X#	This product includes software developed by the University of
X#	California, Berkeley and its contributors.
X# 4. Neither the name of the University nor the names of its contributors
X#    may be used to endorse or promote products derived from this software
X#    without specific prior written permission.
X#
X# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X# SUCH DAMAGE.
X#
X#	@(#)makewhatis.sed	5.5 (Berkeley) 4/17/91
X#
X
X/(\([a-zA-Z0-9]*\).*UNIX Programmer's Manual/ {
X	s;.*(\([a-zA-Z0-9]*\).*UNIX.*;\1;
X	h
X	d
X}
X
X/^NNAAMMEE/!d
X
X:name
X	s;.*;;
X	N
X	s;\n;;
X	# some twits underline the command name
X	s;_;;g
X	/^[^	 ]/b print
X	H
X	b name
X
X:print
X	x
X	s;\n;;g
X	/-/!d
X	s;\([a-z][A-z]\)-[	 ][	 ]*;\1;
X	s;\([a-zA-Z0-9,]\)[	 ][	 ]*;\1 ;g
X	s;[^a-zA-Z0-9]*\([a-zA-Z0-9]*\)[^a-zA-Z0-9]*\(.*\) - \(.*\);\2 (\1) - \3;
X	p
X	q
END-of-zman/whatis/makewhatis.sed
echo x - zman/whatis/Makefile
sed 's/^X//' >zman/whatis/Makefile << 'END-of-zman/whatis/Makefile'
X#
X# This file is: /usr/othersrc/share/man/Makefile
X#
X#	@(#)Makefile	5.9 (Berkeley) 7/1/91
X#
X# PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
X# --------------------         -----   ----------------------
X# CURRENT PATCH LEVEL:         1       00026
X# --------------------         -----   ----------------------
X#
X# 05 Aug 92	James Jegers		Fix whatis.db file format
X# 17 Jan 93     Luke Mewburn		Will look in .[zZ] files
X
XSUBDIR=	man1 man3 man4 man5 man7 man8
XMANDIRS=/usr/share/man /usr/local/man
X
Xafterinstall:
X	install -c -o ${BINOWN} -g ${BINGRP} -m 444 makewhatis.sed \
X	    ${DESTDIR}/usr/share/man/makewhatis.sed
X	install -c -o ${BINOWN} -g ${BINGRP} -m 444 man0/COPYRIGHT \
X	    ${DESTDIR}/usr/share/man/COPYRIGHT
X
Xmakedb:
X	rm -f whatis.db
X	for file in `find ${MANDIRS} -type f -name '*.0' -print`; do \
X		sed -n -f /usr/share/man/makewhatis.sed $$file; \
X	done | col -b >> whatis.db
X	for file in `find ${MANDIRS} -type f -name '*.0.[zZ]' -print`; do \
X		zcat $$file | sed -n -f /usr/share/man/makewhatis.sed; \
X	done | col -b >> whatis.db
X	sort -u -o whatis.db whatis.db
X	install -o ${BINOWN} -g ${BINGRP} -m 444 whatis.db \
X	    ${DESTDIR}/usr/share/man
X
X.include <bsd.subdir.mk>
END-of-zman/whatis/Makefile
echo x - zman/fixman
sed 's/^X//' >zman/fixman << 'END-of-zman/fixman'
X#!/bin/sh
X#
X# File: fixman
X# By:   Luke Mewburn (zak@rmit.EDU.AU)
X# Date: 930117
X# Vers: 2.0.2
X#
X#
X# Synopsis:
X#	converts a manual tree to gzipped format.
X#
X# Usage:
X#	fixman
X#
X# 	This converts all compressed and normal files in the current subtree
X# (with links) to gzip -9 files (with # correct links)
X#
X# Bugs:
X#  - slow
X#
X
Xls -li `find . \( -type f -o -type l \)` | \
Xsort | \
Xawk '
X{
X    if (NF == 11)
X    {
X	if ($10 == "->")
X	{
X	    symlink_arr[ $9 ] = $11
X	    printf "echo adding %s, %s to arr\n", $9, $11
X	}
X	next
X    }
X    if (NF != 9 )
X	next
X    links=$3
X    orig=$9
X    if (index(orig, ".Z") != 0)
X    {
X	printf "gunzip %s\n", orig
X	sub("\.Z$", "", orig)
X    }
X    if (index(orig, ".z") == 0)
X    {
X	printf "gzip -9 -f %s\n", orig
X	printf "echo %s zipped.\n", orig
X    }
X    if (links>1)
X    {
X	inode=$1
X	for (count=1; count <links ; count++)
X	{
X	    getline
X	    if ($1 != inode)
X		next
X	    nxtnam=$9
X	    if (index(nxtnam, ".z") != 0)
X	    {
X#		printf "echo skipping %s\n", nxtnam
X		continue;
X	    }
X	    printf "rm %s\n", $9
X	    sub("\.Z$", "", nxtnam)
X	    printf "if ( -e %s.z ) then\n", orig
X	    printf "  ln %s.z %s.z\n", orig, nxtnam
X	    printf "  echo %s.z linked to %s.z.\n", orig, nxtnam
X	    print  "else"
X	    printf "  ln %s %s\n", orig, nxtnam
X	    printf "  echo %s linked to %s.\n", orig, nxtnam
X	    print  "endif"
X	}
X    }
X}
X
XEND {
X    printf "\necho re-fixing symbolic links:\n"
X    for ( elm in symlink_arr )
X    {
X	src = symlink_arr[ elm ]
X	printf "rm %s\n", elm
X	printf "if ( -e `dirname %s`/%s.z ) then\n", elm, src
X	printf "  ln -s %s.z %s.z\n", src, elm
X	printf "  echo %s.z symlinked to %s.z.\n", elm, src
X	print  "else"
X	printf "  ln -s %s %s\n", src, elm
X	printf "  echo %s symlinked to %s.\n", elm, src
X	print  "endif"
X    }
X}
X' | csh -f
END-of-zman/fixman
exit

--
               Luke Mewburn [Zak]     zak@rmit.edu.au
   "Nobody dies on the Discworld, they just become dimensionally
    disadvantaged."         Terry Pratchett in alt.fan.pratchett