www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/06/19/12:57:43

Xref: news-dnh.mv.net comp.os.msdos.djgpp:443
Path: news-dnh.mv.net!mv!news.sprintlink.net!cs.utexas.edu!convex!not-for-mail
From: rosenkra AT convex DOT com (William Rosenkranz)
Newsgroups: comp.os.msdos.djgpp
Subject: man(1) system (part01/01)
Date: 19 Jun 1995 00:11:31 -0500
Organization: Engineering, Convex Computer Corporation, Richardson, Tx USA
Lines: 2659
Nntp-Posting-Host: convex1.convex.com
Summary: unix man, apropos, whatis
Keywords: unix manual man whatis apropos
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Dj-Gateway: from newsgroup comp.os.msdos.djgpp

man (part01/01)

this is a man(1) system. it has been run successfully under both unix
and with gcc on the atari ST. untested under dos and djgpp, but it
should port trivially. someone had asked for this, and i had it
laying around. written circa 1991-1992.

i am also posting whatis(1) (in 2 parts) that goes along with this.

see the readme files for instructions.

-bill rosenkranz
rosenkra AT convex DOT com

-------------------------- cut here --------------------------
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by William Rosenkranz <rosenkra AT det_hp> on Mon Jun 19 00:31:44 1995
#
# This archive contains:
#	man	
#
# Error checking via sum(1) will be performed.

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

if sum -r </dev/null >/dev/null 2>&1
then
	sumopt='-r'
else
	sumopt=''
fi

echo mkdir - man
mkdir man

echo x - man/README
cat >man/README <<'@EOF'
man v3.0.2 92/10/11
-------------------

This is a man(1) program, to be used in conjunction with manpager (which
I concurrently posted). It is fairly robust, patterned after BSD unix man.
It requires ul(1) and cat(1), if the "-" and "-ul" options are used,
whatis(1) if the "-f" option is used, apropos(1) for the "-k" option, and
always needs either less (setenv PAGER c:\bin\less.ttp) or manpager
(setenv MANPAGER c:\bin\manpager.ttp). One of these is required, or you
can setenv PAGER to your own prefered pager. Personally, I think less
is superior over pg or more. And this version is really oriented toward
using manpager, for reading nroff v1.10p4 manpages (with font changes).

NOTE: the manpage posted here, "man.1", uses special escape sequences
for changing fonts, so it must be viewed with manpager to get the full
effect. You can also use less or emacs, in a pinch.

What is nice about this man, is that it can deal with files compressed
with compress(1), using the "-z" switch in manpager (less does not support
this directly) without resorting to something like "zcat file | less".
I tested man and manpager with the compress on atari.archive.umich.edu
(terminator) which is v4.3, 16-bit. For more on this, see manpager docs.

Incidently, when I say "man(1)", the "(1)" refers to the section of the
unix programmer's manual (more on this below). Section 1 is user commands.
It is just the way things are refered to in unix-land.

I was going to post apropos(1), whatis(1), and whatisin(1), but they need
more work before I do. No timeframe for this. Sorry.

Anyway, it is pretty simple to use. To set up a manpage directory, do this:

	1) mkdir c:\man (this is the root of the manpage tree, the default
	   in the program, too, but you can use anything you like).

	2) cd c:\man
	   mkdir man0 man1 man2 man3 man4 man5 man6 man7 man8
	   mkdir manl mano mann. You will place formatted manpages in this
	   tree (those already run through nroff). Normally, these would be
	   called "catpages" and placed in .\cat*. man does NOT invoke nroff!

	3) copy man.ttp to your bin directory and rehash your shell. man can
	   also be run from the desktop, but you need an environment if you
	   want to override the default man directory.

	4) setenv MANDIR c:\man (or whatever).

	5) setenv MANPAGER c:\bin\manpager.ttp.

	6) put some manpages in the c:\man\man* directories as follows (note
	   that file extensions ARE important and MUST correspond to the
	   last char of the subdirectory):

		subdir	filename	description

		man0	*.0		general information
		man1	*.1		commands
		man2	*.2?		system calls, my convention is
					*.2	normal unix system calls
					*.2g	gemdos
					*.2b	bios
					*.2x	xbios
		man3	*.3?		libraries, normal unix convention is
					*.3	general libc
					*.3s	stdio (fopen, etc)
					*.3m	math (sin, etc)
					*.3c	compatibility
					*.3x	others
		man4	*.4		devices, special files (for dev drivers
					on unix, i use it for things like
					sound.4, dma.4, etc)
		man5	*.5		file formats (e.g. arc.5, ar.5, tar.5)
		man6	*.6		games
		man7	*.7		misc
		man8	*.8		system administration (e.g. ramdisk.8)
		manl	*.l		local commands specific to your setup
		mano	*.o		old manpages (replaced with newer)
		mann	*.n		new manpages (for testing prior to
					install)

	   You can start with man's manpage (cp man.1 c:\man\man1).

	7) run man (man man) if you copied man.1 to c:\man\man1. You do not
	   specify the section in the file name. note that
	   if you have 2 manpages called "xyz" (i.e. xyz.1 and xyz.2), man
	   will ALWAYS find xyz.1 and never the other. if you want xyz.2,
	   you should specify the section as in "man 2 xyz".

	8) if you want to use the -k and -f options, you will have to build
	   a whatis(1) database, which is simply the NAME text from manpages,
	   one per single line. the whatis entry for man is:

	   man - read online documentation

	   "whatis" is a file which goes in c:\lib. a sample is included
	   here. Each time you add a manpage to the system, add the NAME line
	   to whatis in the format specified (see whatis file). my own file
	   has about 600 entries!

You don't have to stick with these (BSD) conventions, but it will make life
simpler. At any rate, the program requires the directory stucture and searches
there. See the manpage (or source) for the search order. Try to put only
unix commands in man1 (putting other commands like uniterm) in manl. I have
hundreds of files in man1, and it gets to be a pain after a while.

Note that it is not necessarily to have a manpage for 2 commands or functions
which share the same manpage. You can "source" a manpage from another by
placing a single line in the file with a line such as:

	.so man3\fclose.3s

This is the manpage for fflush(3S). It uses the manpage for fclose(3S).

Someday, I may post manpages for sections 2 (bios, xbios, gemdos) and possibly
section 3 (dlibs, gemlib, etc). Don't hold your breath, though :-).


Enjoy...


-Bill Rosenkranz
rosenkra AT convex DOT com


@EOF
set `sum $sumopt <man/README`; if test $1 -ne 8878
then
	echo ERROR: man/README checksum is $1 should be 8878
fi

chmod 644 man/README

echo x - man/README.all
cat >man/README.all <<'@EOF'
README (man, whatis, 95/06/18)
------------------------------

someone (stanb AT netcom DOT com) had asked for a man(1) command for reading
manpages. i am posting such a system which includes:

man - read online manpages
apropos - list relevant manpages on a given topic (same as "man -k word")
whatis - give 1-line description of a command (same as "man -f word")
whatisin - list information about what is in sections of the manual
mkwhatis - tool to help build whatis database

note that man does not have its own pager. man calls the pager and
gives it a filename. what man does is find the file (in known places)
and figures out what to run (pager, whatis, apropos, etc.). in this
regard it is really pretty simple minded. the hard part is getting,
organizing, formatting, and maintaining the manpages. for example, i
have hundreds of manpages on my systems. the typical unix system might
have over a thousand manpages.

these programs function more or less the same as the unix (BSD) commands
with some exceptions:

	- man does not invoke nroff. your manpages should be preformatted.
	- every unix flavor has its own way of doing man so some of the
	  switches on these commands may not correspond with all unix
	  (or posix) ways of dealing with this.
	- the whatis database itself is different than how unix does it.
	  but it is similar, and no two unix systems do it the same
	  anyway.

as it stands, these programs assumes the following directory structure:

	c:\usr\man		main location of manpages, whatis db, etc
	c:\usr\man\man[0-9lno]	dirs containing *unformatted* manpages)
	c:\usr\man\cat[0-9lno]	dirs containing *formatted* manpages)
	c:\usr\man\whatis._?_	whatis databases for each section (you
				have to build these based on your collection
				of manpages)
	c:\usr\man\whatisin.___	whatisin database

man will ONLY look in the cat* directories, and does not format the manpages.
you will need nroff for this (cawf, groff, etc). i also have an nroff
that i wrote years ago that is PD. or you can format the manpages on a unix
system and download them to your PC.

everything is configurable, both in the source and via the environment.
for example, the c:\usr\man path can be overridded with:

	- setting environment variable MANPATH
	- using the commandline switch "-M path" on each command
	- changing the executables with a binary editor (i have left
	  space in the source for such patches)
	- changing the source and recompiling

caveats:

	- i am providing this free, with no restrictions. it is 100% my
	  code (does not contain any unix code).
	- i will not help in any way to fix anything or add new features.
	  this system runs fine under both Unix and on my atari ST (with
	  gcc) so it should port easily, though i have not tried it under
	  DOS or with djgpp.
	- i will not reformat the source to correspond to someone's notion
	  of style. this is my prefered style, after 10 years of C coding
	  and 20 years of fortran coding. :-)
	- if you don't like it, either a) fix it yourself, or b) don't use
	  it. it is free, after all.

Install:

	- Unpack everything into separate directories (./man, ./whatis).
	- The files are all ascii (no binary files). there are no CF-LF
	  (just LF) so if you need CR-LF, you have to fix this yourself.
	- go to each dir (./man and ./whatis) and look at the makefile.
	  change (at least) the following for your particular setup:

		CC		how to invoke compiler
		LD		how to link .o files
		MANTOP		main location to place manpages (install)
		MANDIR		specific location for manpage source
		CATDIR		specific location for formatted manpages
		BINDIR		location to install executables (man,
				whatis, etc)
		DEFS		in man, you should specify what you have
				available (eg, if you have ul(1) and want
				the -ul switch to function, define HAS_UL).
				you probably want to define MSDOS, __GNUC__,
				and possibly undefine unix.

		in general, check all the macros in upper case in the
		makefile. note that i could have used sed in the makefile
		to patch names in the program, but i don't know how good
		make is on the PC.

	- man invokes the PAGER and other programs via the system(3) call.
	  on unix (and on my atari), system will search PATH for executables
	  so you don't need a full path. if this is not the case with djgpp,
	  then you will have to alter ./man/man.c to build a full path
	  for executing PAGER, cat, ul, whatis, apropos, etc.

	- type:

		make all		will build the executables
		make install		will install the execs and manpages
		make clobber		will clean up after the make all.

	  you may also consider doing "make dirs" before make install
	  when building man. this creates the directory structure.

	  you should do man before whatis.

	- if successful, you should be all set. i have provided formatted
	  manpages (man.1, whatis.1, whatis.5, apropos.1, whatisin.1) from
	  the manpage sources (man.man, whatis.man, whatis.ma5, etc). these
	  were piped through "ul -t dumb" to remove any bold/underline
	  escape sequences. so the formatted manpages are pure ascii. if
	  you have a PAGER that groks how to handle nroff bold, etc, then
	  you may want to reformat the manpages.

you should at a minimum build man. it will allow you to read manpages.
if you are up for it, the whatis capability might be desirable. whatis
contains a 1-line description of every manpage you have on your system.
for more information, see the file ./whatis/whatis.5 and whatis.1.

note: i have not included any manpages here other than those for these
programs themselves. don't ask me for a manpage on ls(1).



Environment:

these programs recognize several environment variables:

	MANPAGER	man	if set, this pager is used by man. on my
				atari, i have a special pager that resets
				fonts, based on what -T does in nroff on
				my system. this gives me bold, etc.
	PAGER		man	if MANPAGER is not set, this pager is used.
				the default is less.
	MANPATH		man,	location of the manpages, top level. the
			whatis	default is c:\usr\man. at the moment, MANPATH
			apropos	is a single path, not a list.
			whatisin

for more, grep the sources for "getenv" or read the manpages.

note that man will invoke other programs as follows (using system(3)):

	man file	PAGER
	man -k word	apropos
	man -f name	whatis

you can also invoke apropos and whatis by themselves, of course.

that's about all i have time for. have fun...

-bill rosenkranz
rosenkra AT convex DOT com

@EOF
set `sum $sumopt <man/README.all`; if test $1 -ne 9384
then
	echo ERROR: man/README.all checksum is $1 should be 9384
fi

chmod 644 man/README.all

echo x - man/manifest
cat >man/manifest <<'@EOF'
README.all	readme for man and whatis (top level)
README		readme for man
makefile	makefile for man
man.1		formatted manpage for man
man.c		man source
man.man		unformatted manpage for man (nroff -man format)
manifest	this file
@EOF
set `sum $sumopt <man/manifest`; if test $1 -ne 13953
then
	echo ERROR: man/manifest checksum is $1 should be 13953
fi

chmod 644 man/manifest

echo x - man/makefile
cat >man/makefile <<'@EOF'
# makefile for man
#
# date:    Sat Jan 19 04:08:46 1991
# version: 2.0
#
#

# set this to executable file extension, if necessary (eg, .exe for MSDOS,
# .ttp for atari)
#
EXE		=

SECT		= 1
TARGET		= man$(EXE)
MANPAGE		= man.$(SECT)
MANSRC		= man.man
HEADERS		=
SRCS		= $(HEADERS) man.c
OTHERS		= readme makefile $(MANSRC)
DISTFILES	= $(OTHERS) $(SRCS)
OBJS		= man.o


# set CC to the command needed to compile a file (to a .o file).
# set LD to the command needed to link .o files.
#
#CC		= gcc -v -z -Wall -Ic:/u/gcc/include
#LD		= gcc -v -z -Wall -Lc:/u/gcc/lib -nostdlib c:/u/gcc/lib/crt0.o
CC		= cc -Aa
LD		= cc -Aa


# defines based on what you have:
#	-DHAS_CAT	yes, i have cat$(EXE)
#	-DHAS_UL	yes, i have ul$(EXE)
#	-DHAS_WHATIS	yes, i have whatis$(EXE)
#	-DHAS_APROPOS	yes, i have apropos$(EXE)
#	-DLONG_SECT	use longer list for things like "local"
#	-DUSE_INDEX	if you need index/rindex instead of strchr/strrchr
#	-Datarist	for Atari ST
#	-DMSDOS		for PC
#	-Dunix		for unix systems (or unix-like)
#
DEFS		= -DHAS_CAT -DHAS_UL -DHAS_WHATIS -DHAS_APROPOS -DLONG_SECT


# set ARCH for things like -mshort.
# set OPT potentially to -O.
# set libs to list of libraries needed in link (eg, -lc).
#
ARCH		=
OPT		=
CFLAGS		= $(ARCH) $(OPT) $(DEFS) 
LDFLAGS		= $(ARCH)
LIBS		=

# set BINDIR to the place where you want the executable installed.
# set MANDIR to the place where man's manpage will be installed (the
# directory must exist; consider doing "make dirs" before "make install")
# include a trailing / (or \) for both BINDIR and MANDIR.
#
#SLASH		=\\
#BINDIR		= c:\usr\bin
#MANTOP		= c:\usr\man
#MANDIR		= $(MANTOP)$(SLASH)man$(SECT)
#CATDIR		= $(MANTOP)$(SLASH)cat$(SECT)
SLASH		=/
BINDIR		= /mnt/rosenkra/test/bin
MANTOP		= /mnt/rosenkra/test/man
MANDIR		= $(MANTOP)$(SLASH)man$(SECT)
CATDIR		= $(MANTOP)$(SLASH)cat$(SECT)

# install commands
#
INST_BIN	= cp -p
INST_MAN	= cp -p

RM		= rm -f


# directions...
#
directions:
		@echo type "make all" to built $(TARGET)
		@echo type "make dirs" to create $(MANDIR) directories
		@echo type "make install" to build/install $(TARGET)
		@echo type "make clean" to remove objects
		@echo type "make clobber" to remove objects and $(TARGET)
		@echo these should be done in this order


# main target...
#
all:		$(TARGET)

$(TARGET):	$(OBJS)
		$(LD) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS)



# manpage (use built-in .man.cat rule)...
#
manpage:	$(MANPAGE)

$(MANPAGE):	$(MANSRC)
		nroff -man $(MANSRC)|ul -t dumb|cat -s >$(MANPAGE)




# create directories
#
dirs:		install_dirs

install_dirs:
		mkdir $(MANTOP)
		mkdir $(MANTOP)$(SLASH)cat0 $(MANTOP)$(SLASH)man0
		mkdir $(MANTOP)$(SLASH)cat1 $(MANTOP)$(SLASH)man1
		mkdir $(MANTOP)$(SLASH)cat2 $(MANTOP)$(SLASH)man2
		mkdir $(MANTOP)$(SLASH)cat3 $(MANTOP)$(SLASH)man3
		mkdir $(MANTOP)$(SLASH)cat4 $(MANTOP)$(SLASH)man4
		mkdir $(MANTOP)$(SLASH)cat5 $(MANTOP)$(SLASH)man5
		mkdir $(MANTOP)$(SLASH)cat6 $(MANTOP)$(SLASH)man6
		mkdir $(MANTOP)$(SLASH)cat7 $(MANTOP)$(SLASH)man7
		mkdir $(MANTOP)$(SLASH)cat8 $(MANTOP)$(SLASH)man8
		mkdir $(MANTOP)$(SLASH)cat9 $(MANTOP)$(SLASH)man9
		touch install_dirs


# to install it...
#
install:	install_dirs install_bin install_man

install_bin:	$(TARGET)
		$(INST_BIN) $(TARGET) $(BINDIR)$(SLASH)$(TARGET)
		touch install_bin

install_man:	$(MANPAGE)
		$(INST_MAN) $(MANSRC) $(MANDIR)$(SLASH)$(MANPAGE)
		$(INST_MAN) $(MANPAGE) $(CATDIR)$(SLASH)$(MANPAGE)
		touch install_man



# others...
#
clean:
		$(RM) core $(OBJS) errs

clobber:	clean
		$(RM) $(TARGET)




# dependencies...
#
man.o:		man.c 

@EOF
set `sum $sumopt <man/makefile`; if test $1 -ne 56249
then
	echo ERROR: man/makefile checksum is $1 should be 56249
fi

chmod 644 man/makefile

echo x - man/man.1
cat >man/man.1 <<'@EOF'

 MAN(1)                                                               MAN(1)

 NAME
      man - read online documentation

 SYNOPSIS
      man [- [-ul]] [-s sect[subs]] [-M path] [-m path] [-e] [sect[subs]]
      name...
      man -f file...
      man -k keyword...

 DESCRIPTION
      The man command finds and displays information in the online
      documentation set.  When the standard output is a terminal, man pipes
      its output through less(1) or the name of the command specified with
      the MANPAGER or PAGER environment variables.

 OPTIONS
      The following command line options are recognized:

      -    Pipes the output through cat(1) rather than less(1) or PAGER.

      - -ul
           Use ul(1) rather than cat(1).

      -M path
           Specifies a directory tree in which to search.  By default, man
           searches in c:\usr\man under MSDOS or on the Atari ST or /usr/man
           under Unix, or the directory specified by the MANPATH environment
           variable, the standard location for online documentation.  The
           MANPATH variable should have a single path name at the present
           time (eventually, it will support a colon-separated list of
           locations).  This option assumes path is the root of a normal
           directory structure.  For compatibility with some Unix man
           systems, you can use -P as well as -M.

      -m path
           Specifies a directory in which to search.  This option does not
           use a directory tree.  Files are searched only in the directory
           specified by path.  This option is useful for debugging new
           manpages.  For example, assuming you are working on a manpage
           named mycmd.1, you can do this:

                man -m . 1 mycmd

      -e   Find every manpage concerning the given name regardless of
           section.  It is expected that a normal exit from the pager will
           result in an exit status of 0 (in which case the search is
           continued in other sections).  An abnormal exit should result in
           a nonzero exit status and the search is then terminated.

      -s sect[subsect]
           Specifies a section and subsection similar to the 4.2 BSD UNIX

                                    - 1 -          Formatted:  June 18, 1995

 MAN(1)                                                               MAN(1)

           Programmer's Manual (as explained below) in which to search.  If
           no section is specified, man searches through all of the
           sections.  Example:  man -s 3s fopen.

      sect As an alternative to -s, you can specify the section (and
           optional subsection) as the first argument.  Example:  man 3s
           fopen.

      name Searches for documentation files associated with the specified
           name.

      -f name
           Displays a one line synopsis of each online documentation file
           whose names match the specified word (equivalent to the whatis(1)
           command).  For example, man -f chmod will give entries for both
           chmod(1) and chmod(2).  Note that man invokes whatis(1) in this
           case, so it should be found in the path (see ENVIRONMENT).

      -k keyword
           Displays a one line synopsis of each online documentation file
           whose name or description contains the specified keyword
           (equivalent to the apropos(1) command).  Note that man invokes
           apropos(1) in this case, so it should be found in the path (see
           ENVIRONMENT).

 ENVIRONMENT
      The following environment variables are recognized:

      MANSECT
           This can be used to alter the search order and to customize
           subsections.  The default is equivalent to:

           setenv MANSECT 108234576,tcgesla,,s,mgbxl,msvcxgl,dkvscm,,,

           This means the major sections (man1, etc.) are searched in the
           order man1, man0, man8, etc.  For each section, you can also
           provide a list of subsections which must correspond in the
           remaining list.  In this case man1 subsections are t,c,g,e,s,l,
           and a; there are no subsections for man0; etc.  The first entry
           (the section list) must consist of numbers from 0 to 9 only.
           Numbers can be skipped.

           The default search order is oriented toward users.  To speed up
           the search, a casual programmer might perfer:

                325481760,gsmcvxl,mgbxl,,dkvscm,s,tcgesla,,,

           while a Unix programmer might prefer:

                235481760,mgbxl,csmxvlg,,dkvscm,s,tcgesla,,,

                                    - 2 -          Formatted:  June 18, 1995

 MAN(1)                                                               MAN(1)

      MANPATH,MANDIR
           Location of main manual direcotry, where subdirectories are to be
           found.  Man uses (in order of priority) the path specified with
           -M, the MANPATH specified, or the built-in default (c:\usr\man or
           /usr/man).

      MANPAGER
           Name of prefered pager.  Use this pager if you have compressed
           manpages (see manpager(1)).  Man will use first MANPAGER, if
           found, then PAGER, if found.  If neither are found, it uses
           c:\usr\bin\less.

      PAGER
           Name of secondary pager to replace less(1).  Use this if you do
           not have manpages generated with font changes (see nroff(1)).
           Either MANPAGER or PAGER should be defined.  The search order is
           MANPAGER then PAGER.

      Note that BINDIR and TMPDIR are not currently used.

 SECTION NAMES
      By convention, the "sections" of the manual are (see whatisin(1) as
      well):

      Sect Section Name   Description
      ---- -------------  --------------------------------------
      0    General        overview of features and documentation
      1    Commands  user commands
      2    System Calls   low-level system library calls (C)
      3    Library Calls  standard user calls (C)
      4    Special Files  special system files and hardware
      5    File formats   things like arc(1) file formats
      6    Games          games manual
      7    Miscellaneous  miscellaneous information
      8    Administration system administration commands

      In addition, this man recognizes the following section names:

      local          files specific to local system
      new       files added since current software release
      old       files from previous software release
      gnu       GNU files (gcc typically)
      paper          misc formal papers
      doc       misc documentation

      The search order, if no section is specified, is:

      108234576

      In addition to sections, there are a number of subsections possible,
      though these files do not reside in a special directory.  The

                                    - 3 -          Formatted:  June 18, 1995

 MAN(1)                                                               MAN(1)

      subsection name is simply appended to the file name.  Example:
      fopen.3s resides in $MANPATH\man3, the section is 3 (libraries) and
      the subsection is s, stdio.  Here is the subsection search order for
      subsections in each section (the square brackets mean a choice of each
      character contained in them, in that order):

      man1\*.1[tcgesla]   util & text,com,graphics,edit,shell,lang
                     archival
      man0\*.0
      man8\*.8[s]         util & system
      man2\*.2[mgbxl]          system & mint,gemdos,bios,xbios,lineA
      man3\*.3[msvcxgl]   C lib & math,stdio,sysV,compat,extra
                     gem(aes/vdi),local
      man4\*.4[dkvscm]    general & disk,keyboard,video,sound,chips
                     memory
      man5\*.5
      man7\*.7
      man6\*.6

 NOTES
      To save disk space, you can "source" other files by including the
      nroff(1) directive .so in a file as the first line.  In this case, the
      first line should start with .so followed by at least one space, then
      the file to use instead of the actual manpage.  For example, the
      manpage for feof.3s (in $MANPATH\man3) contains the single line:

           .so man3\ferror.3s

      which will cause man to display the contents of ferror.3s instead.
      Note the relative path (relative to MANPATH, by default c:\usr\man).
      In this way, numerous manpages can refer to a single (larger) file.
      Do not compress files with source lines as man only checks for this
      line if it finds a file which is not compressed.  Note that you should
      only compress files for viewing with a pager that supports reading
      compressed files (e.g., manpager(1)) and must set the MANPAGER
      environment variable as well.

      You can also specify just a file name for sourcing (without relative
      path):

           .so ferror.3s

      and man will use the relative path of the file containing this line.

 FILES
      c:\usr\man          root of standard manual page directory tree
      c:\usr\man\man*\*   manual entries
      c:\usr\man\whatis   table of contents and keyword database

 SEE ALSO
      apropos(1), cat(1), less(1), manpager(1), nroff(1), what(1),

                                    - 4 -          Formatted:  June 18, 1995

 MAN(1)                                                               MAN(1)

      whatis(1), whatisin(1), whereis(1), man(7)

 AUTHOR
      Bill Rosenkranz
      rosenkra AT convex DOT com

 VERSION
      man v3.0.2 92/10/11 rosenkra

                                    - 5 -          Formatted:  June 18, 1995

@EOF
set `sum $sumopt <man/man.1`; if test $1 -ne 25753
then
	echo ERROR: man/man.1 checksum is $1 should be 25753
fi

chmod 644 man/man.1

echo x - man/man.c
cat >man/man.c <<'@EOF'
static char *rcsid  = "$Id: man.c,v 1.4 1992/10/12 09:59:02 rosenkra Exp $";
static char *version = "man v3.0.2 92/10/11 rosenkra AT convex DOT com";
static char *myname  = "man";

/*
 *	man - read on-line documentation
 *
 *	This version uses "manpager" or "less" for paging. It does NOT
 *	call nroff (ie, manpages must be preformatted -- see SUBDIRBASE
 *	macro below).
 *
 *	search order (based on my manpage nomenclature):
 *
 *		man1/*.1[tcgesla]	cmds	util & text,com,graphics,
 *						edit,shell,lang, archival
 *		man0/*.0		gen
 *		man8/*.8[s]		admin	util & system
 *		man2/*.2[b]		syslib	system & bios
 *		man3/*.3[msvcxl]	libs	C lib & math,stdio,sysV,
 *						compat,extra,local
 *		man4/*.4[dkvscm]	h/w	gen & disk,keyboard,video,
 *						sound,chips,memory
 *		man5/*.5		files
 *		man7/*.7		misc
 *		man6/*.6		games
 *
 *	these are seached only if given sections "local", "new", "old":
 *
 *		manl/*.l		local
 *		mann/*.n		new
 *		mano/*.o		old
 */

/*
 * $Log: man.c,v $
 * Revision 1.4  1992/10/12  09:59:02  rosenkra
 * basically same as last version (which was premature). fix a couple
 * of bugs.
 *
 * Revision 1.3  1992/10/11  16:21:24  rosenkra
 * this is v3.0.2. it adds a -P alias for -M, ability to source files
 * with either .so manx/file.x or .so file.x; also added was MANSECT
 * env var. help (usage) was beefed up. all reading of env now done in
 * env_inquiry().
 *
 * Revision 1.2  1992/07/27  10:03:38  rosenkra
 * added ability to review all manpages of given name regardless
 * of section (-e). also do env checks before arg parsing.
 *
 * Revision 1.1  1992/07/27  02:03:58  rosenkra
 * Initial revision
 *
 */



#ifdef __hpux
/* HPUX for some reason needs this with <sys/stat.h> */
#define _INCLUDE_POSIX_SOURCE 1
#define unix 1
#endif

#include <stdio.h>
#include <ctype.h>
#if defined(unix) || defined(__unix)
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#elif defined(__GNUC__) && defined(MSDOS)
#include <types.h>
#include <stat.h>
#include <stdlib.h>
#include <unistd.h>
#else
#include <sys\types.h>
#include <sys\stat.h>
extern char    *index ();
extern char    *getenv ();
#endif
#ifdef USE_INDEX
#include <strings.h>
#define strchr index
#define strrchr rindex
#endif


/*
 *	deal with MSDOS
 */
#if defined(unix) || defined(__unix)
#define SLASH_CHR	'/'
#define SLASH_STR	"/"
#else
#define SLASH_CHR	'\\'
#define SLASH_STR	"\\"
#endif



/*
 *	common (default) places. note the patch space...
 */
#if defined(atarist) || defined(MSDOS)
# define MANDIR		"c:\\usr\\man\0\0\0<------MANDIR_patch_space------->\0"
# define BINDIR		"c:\\usr\\bin\0\0\0<------BINDIR_patch_space------->\0"
# define TMPDIR		"c:\\tmp\0\0\0<---------TMPDIR_patch_space--------->\0"
#else
/* assume unix */
# define MANDIR		"/usr/man"
# define BINDIR		"/usr/bin"
# define TMPDIR		"/tmp"
#endif



/*
 *	default pager (we invoke this with system()):
 */
#if defined(unix) || defined(__unix)
# define MORE		"less"		/* could use -m -s also */
#elif defined(atarist)
# define MORE		"less.ttp\0\0\0<--------MORE_patch_space----------->\0"
#elif defined(MSDOS)
# define MORE		"less.exe\0\0\0<--------MORE_patch_space----------->\0"
#endif


/*
 *	other commands we may run
 */
#ifdef HAS_CAT
# if defined(unix) || defined(__unix)
#  define CAT		"cat -s"	/* for '-' opt, use "cat -s" */
# elif defined(atarist)
#  define CAT		"cat.ttp\0\0\0<---------CAT_patch_space------------>\0"
# elif defined(MSDOS)
#  define CAT		"cat.exe\0\0\0<---------CAT_patch_space------------>\0"
# else
#  undef HAS_CAT
# endif
#endif

#ifdef HAS_UL
# if defined(unix) || defined(__unix)
#  define UL		"ul -t dumb"	/* for '- -ul' opt (don't use pager) */
# elif defined(atarist)
#  define UL		"ul.ttp\0\0\0<----------UL_patch_space------------->\0"
# elif defined(MSDOS)
#  define UL		"ul.exe\0\0\0<----------UL_patch_space------------->\0"
# else
#  undef HAS_UL
# endif
#endif

#ifdef HAS_APROPOS
# if defined(unix) || defined(__unix)
#  define APROPOS	"apropos"
# elif defined(atarist)
#  define APROPOS	"apropos.ttp\0\0<--------APROPOS_patch_space------->\0"
# elif defined(MSDOS)
#  define APROPOS	"apropos.exe\0\0<--------APROPOS_patch_space------->\0"
# else
#  undef HAS_APROPOS
# endif
#endif

#ifdef HAS_WHATIS
# if defined(unix) || defined(__unix)
#  define WHATIS	"whatis"
# elif defined(atarist)
#  define WHATIS	"whatis.ttp\0\0<--------WHATIS_patch_space--------->\0"
# elif defined(MSDOS)
#  define WHATIS	"whatis.ttp\0\0<--------WHATIS_patch_space--------->\0"
# else
#  undef HAS_WHATIS
# endif
#endif


/*
 *	define sections and subsections. sections are dirs like "man1" and
 *	"cat1". subsections are used in names of manpages within the dir
 *	(eg, "foo.1t").
 */
#define	ALLSECT		"108234576"	/* order to look through sections */

#define SUBSEC0		""		/* subsec to try in each section */
#define	SUBSEC1		"tcgesla"
#define	SUBSEC2		"g"
#define	SUBSEC3		"msvcxl"
#define	SUBSEC4		"dkvscm"
#define SUBSEC5		""
#define SUBSEC6		""
#define SUBSEC7		""
#define	SUBSEC8		"s"
#define SUBSEC9		""

/*
 *	deal with compressed files
 */
#if defined(MSDOS)
#define ZSUFFIX		"Z"		/* for compressed files */
#else
#define ZSUFFIX		".Z"		/* for compressed files */
#endif
#define ZSWITCH		"-z"	/* for MANPAGER to read compressed file */


/*
 *	files come from MANPATH/cat*. normally, unix man will first
 *	check for preformatted manpages in /usr/man/cat* dirs. if they
 *	are not found, nroff is run on /usr/man/man* files. with this
 *	man, however, we are assuming that manpages have already been
 *	formatted. by convention, this means that the dirs to search
 *	should be named 'cat[1-8]' and not 'man[1-8]'. if you don't
 *	care about this, make SUBDIRBASE "man".
 */
#define SUBDIRBASE	"cat"



#ifdef dbg
# undef dbg
#endif
#define dbg(x)		if(debugging_G)printf x , fflush(stdout)


/*
 *	misc macros
 */
#ifdef lastchar
# undef lastchar
#endif
#ifdef plastchar
# undef plastchar
#endif
#define lastchar(s)	((s)[strlen(s)-1])	/* last char in a string */
#define plastchar(s)	&((s)[strlen(s)-1])	/* ptr to it */


#define PLEN		256		/* max path length */




/*
 *	globals:
 */
#ifdef HAS_UL
int		ul4cat_G  = 0;		/* use ul instead of cat */
#endif
int		every_G = 0;		/* every section */
int		debugging_G = 0;
int		hasmanpager_G = 0;	/* if pager is MANPAGER */
int		usermanpath_G = 0;	/* if -M */
int     	nopager_G  = 0;		/* if no pager of any kind */
int		pthpager_G = 0;		/* if pager has a full path */
int		envmansect_G = 0;	/* if MANSECT in env */
char	       *manpath_G = 0L;
char		mpbuf[PLEN];
char	       *binpath_G = 0L;
char		bpbuf[PLEN];
char	       *tmppath_G = 0L;
char		tpbuf[PLEN];
char	       *pager_G = 0L;
char		pgbuf[PLEN];
char		cmdbuf_G[512];
int     	section_G = 0;		/* section, ascii char */
int     	subsec_G = 0;		/* subsection, ascii char */


/*
 *	set up default search lists. these can be overridden with the env:
 *
 *	setenv MANSECT 108234576,tcgesla,,s,mgbxl,msvcxgl,dkvscm,,,
 */
char	       *allsect = ALLSECT;
char	       *subsec0 = SUBSEC0;
char	       *subsec1 = SUBSEC1;
char	       *subsec2 = SUBSEC2;
char	       *subsec3 = SUBSEC3;
char	       *subsec4 = SUBSEC4;
char	       *subsec5 = SUBSEC5;
char	       *subsec6 = SUBSEC6;
char	       *subsec7 = SUBSEC7;
char	       *subsec8 = SUBSEC8;
char	       *subsec9 = SUBSEC9;

#ifdef LONG_SECT
char	       *longsect[] = {"local", "new", "old", "gnu", "paper",
			      "doc", (char *) 0};
#endif



/*
 *	functions:
 */
int		set_section (char *);
int		find_manpage (char *);
int		do_it (char *, int);
char	       *so_line (char *);
void		env_inquiry (void);
void		usage (int);



/*------------------------------*/
/*	main			*/
/*------------------------------*/
void main (int argc, char *argv[])
{
	int	retcode;
	char  **av;
	int	ac;



	/*
	 *   quick scan of args to find debug since we need it first.
	 *   note that argc and argv are not changed...
	 */
	ac = argc;
	av = argv;
	for (ac--, av++; ac > 0 && **av == '-'; ac--, av++)
	{
		if (*(*av+1) == 'd')
		{
			debugging_G = 1;
			break;
		}
	}




	/*
	 *   check environment (cmdline overrules things)
	 */
	env_inquiry ();



	/*
	 *  must have an arg
	 */
	argc--, argv++;
	if (argc < 1)
	{
		usage (1);
	}



	/*
	 *   parse cmdline. it overrides defaults and environment...
	 */
	while (argc > 0 && **argv == '-')
	{
		switch (*(*argv+1))
		{

		case 0:				/* use cat (just a "-") */
#ifdef HAS_CAT
			nopager_G++;
#else
			fprintf (stderr, "%s: cat and not supported\n");
			usage (1);
#endif
			break;


		case 'e':			/* every section */
			every_G++;
			break;


		case 'P':
		case 'M':			/* reset path (-M path) */
						/* this is manpath/man[1...] */
			argc--, argv++;
			manpath_G = *argv;
			break;


		case 'm':			/* reset path (-m path) */
						/* this is manpath alone */
						/* use "-m ." for cwd */
			argc--, argv++;
			manpath_G     = *argv;
			usermanpath_G = 1;
			break;


		case 'u':			/* use ul(1) for cat */
#ifdef HAS_UL
			ul4cat_G++;
#else
			fprintf (stderr, "%s: ul not supported\n");
			usage (1);
#endif
			break;


		case 's': 			/* specific section */
			switch (--argc)
			{
			case 0:			/* Nothing follows -s */
				fprintf (stderr,
					"%s: must specify a section with -s\n",
					myname);
				usage (1);

			case 1: 		/* Section, but no man page */
				fprintf (stderr,
				  "%s: must specify an item from section %s\n",
					myname, *argv);
				usage (1);

			default: 
				/*
				 *   if valid section, set_section sets
				 *   section_G
				 */
				if (set_section (*++argv) == 0)
				{
					fprintf (stderr,
						"%s: unknown section: %s\n",
						myname, *argv);
					usage (1);
				}
				break;
			}
			break;


		case 'f':			/* whatis */
		case 'w':
#ifdef HAS_WHATIS
#if defined(__GNUC__) || defined(unix) || defined(__unix)
			strcpy (cmdbuf_G, WHATIS);
#else
			strcpy (cmdbuf_G, binpath_G);
			if (lastchar (cmdbuf_G) != SLASH_CHR)
				strcat (cmdbuf_G, SLASH_STR);
			strcat (cmdbuf_G, WHATIS);
#endif /*__GNUC__*/
			argc--, argv++;
			while (argc)
			{
				strcat (cmdbuf_G, " ");
				strcat (cmdbuf_G, *argv);
				argc--, argv++;
			}
dbg(("whatis, system (%s)\n",cmdbuf_G));
			retcode = system (cmdbuf_G);

			exit (retcode);
#else /*!HAS_WHATIS*/
			fprintf (stderr, "%s: whatis not supported\n");
			usage (1);
#endif /*HAS_WHATIS*/
			break;
			

		case 'k':			/* apropos */
		case 'a':
#ifdef HAS_APROPOS
			strcpy (cmdbuf_G, APROPOS);
#if defined(__GNUC__) || defined(unix) || defined(__unix)
			strcpy (cmdbuf_G, APROPOS);
#else
			strcpy (cmdbuf_G, binpath_G);
			if (lastchar (cmdbuf_G) != SLASH_CHR)
				strcat (cmdbuf_G, SLASH_STR);
			strcat (cmdbuf_G, APROPOS);
#endif /*__GNUC__*/
			argc--, argv++;
			while (argc)
			{
				strcat (cmdbuf_G, " ");
				strcat (cmdbuf_G, *argv);
				argc--, argv++;
			}
dbg(("apropos, system (%s)\n",cmdbuf_G));
			retcode = system (cmdbuf_G);

			exit (retcode);
#else /*!HAS_APROPOS*/
			fprintf (stderr, "%s: apropos not supported\n");
			usage (1);
#endif /*HAS_APROPOS*/
			break;
			

		case 'h':			/* help */
			usage (0);
			break;


		case 'd':			/* turn on debugging */
			debugging_G = 1;
			break;


		case 'v':			/* version */
			printf ("%s\n", version);
			exit (0);
			break;

		case '-':
			switch (*(*argv+2))
			{
			case 'v':		/* --version */
				printf ("%s\n", version);
				exit (0);
				break;

			case 'h':		/* --help */
				usage (0);
				break;
			}
			break;


		}
		argc--, argv++;
	}




	/*
	 *   If there are multiple words, no -s seen above, and the first
	 *   word is a valid section name, read the subsequent man pages
 	 *   from that section. set_section will set section_G if *argv is a
 	 *   bona fide section.
 	 *
 	 *   this also should make sure arg is a digit and only <sect>[<sub>]
 	 *   but will fail on actual manpages named something like "1.1".
 	 *   hopefully these are non-existent.
	 */
	if ((argc > 1) && (section_G == 0)
	&& (set_section (*argv) || (isdigit(**argv) && (strlen(*argv) < 3))))
	{
		argc--;
		argv++;
	}



	/*
	 *   move to correct directory. no need to move if it is cwd...
	 */
	if (strcmp (manpath_G, ".") && (chdir (manpath_G) < 0))
	{
		fprintf (stderr, "%s: can't chdir to %s.\n",
			 myname, manpath_G);
		exit (1);
	}



	/*
	 *   check if stdout not a tty an no pager.
	 */
#if 0
	if (nopager_G == 0 && !isatty (1))
		nopager_G++;
#endif
dbg(("nopager_G = %d, isatty(1) = %d\n", nopager_G, (int) isatty(1)));



	/*
	 *   do it for all remaining tokens
	 */
	while (argc-- > 0)
	{
		retcode = find_manpage (*argv++);

		if (retcode)
		{
			fprintf (stderr, "%s: failed!!!\n", myname);
			exit (retcode);
		}
	}

	exit (0);
}




/*------------------------------*/
/*	set_section		*/
/*------------------------------*/
int set_section (char *cptr)
{

/*
 *	routine to set section_G and subsec_G from a given section name,
 *	returning the letter of the section used or a zero if an unfamiliar
 *	keyword is used.
 */

	int	sec;
	int	ret;
	int	i;

	if (strlen (cptr) > 2)
	{
		/*
		 *   section is 3 or more char
		 */
#ifdef LONG_SECT
		for (i = 0; longsect[i]; i++)
		{
			if (!strcmp (longsect[i], cptr))
				return (section_G = (int) (*longsect[i]));
		}
#else
		if (!strcmp (cptr, "local"))
			return ((int) (section_G = 'l'));
		if (!strcmp (cptr, "new"))
			return ((int) (section_G = 'n'));
		if (!strcmp (cptr, "old"))
			return ((int) (section_G = 'o'));
#endif

		/* 
		 *   If we reach here, none of the special names match,
		 *   and we'll return a zero (error) on the other side of
		 *   the else. 
		 */
		section_G = '\0';
		subsec_G  = '\0';
		ret       = 0;
	}
	else
	{
		/*
		 *   section is 2 or less char. subsec could be 0
		 */
		section_G = (int) cptr[0];
		subsec_G  = (int) cptr[1];
		ret       = section_G;


		/*
		 *   crude check for legality: section must be 0-8, subsect
		 *   must be a letter
		 */
		sec = section_G - '0';
/*!!!*/		if (sec < 0 || sec > 9)
			ret = 0;
		if (subsec_G)
		{
			if (!isalpha (subsec_G))
				ret = 0;
		}
	}

	/*
	 *   ret is 0 if invalid section, else section number
	 */
	return (ret);
}



struct stat     sbuf;


/*------------------------------*/
/*	find_manpage		*/
/*------------------------------*/
int find_manpage (char *name)
{

/*
 *	find the manpage file
 */

	char    	c_sectn;
	char    	work[PLEN];
	int     	stflag;
	int     	last;
	char		seclist[30];
	char		sublist[30];
	char	       *psec;
	char	       *psub;
	char	       *ps;
	char	       *cp;
	int		iscompressed = 0;
	int		found = 0;



	/*
	 *   set up template (we removed any trailing '/' already)
	 *
	 *   if usermanpath is set, we read from that dir and don't assume
	 *   any "normal" dir structure (-m option). otherwise we do normal
	 *   (or -M option).
	 */
	if (usermanpath_G)
		sprintf (work,  "%s%s%s.x", manpath_G, SLASH_STR, name);
	else
		sprintf (work,  "%s%s%sx%s%s.x",
			 manpath_G, SLASH_STR, SUBDIRBASE, SLASH_STR, name);



	/*
	 *   index of last char in template. this should be section.
	 *   work[last+1] is subsection, and work[last+2] will be ZSUFFIX
	 *   if compressed and we are using MANPAGER.
	 */
	last = strlen (work) - 1;
dbg(("template, work = |%s|, last = %d\n", work, last));



	/*
	 *   set up list of sections to search. either use section_G or
	 *   allsect
	 */
	if (section_G)
	{
		seclist[0] = (char) section_G;
		seclist[1] = '\0';
	}
	else
	{
		strcpy (seclist, allsect);
	}
	psec = seclist;
	if (subsec_G)
	{
		sublist[0] = (char) subsec_G;
		sublist[1] = '\0';
		psub = sublist;
	}
	else
		psub = (char *) NULL;
dbg(("psec = |%s|, psub = |%s|\n", psec, (psub ? psub : "NULL")));



	/*
	 *   find manx string in template. ps points to the '/'
	 */
	if (!usermanpath_G)
	{
		char tmpstringx[PLEN];
		tmpstringx[0] = SLASH_CHR;
		strcpy(&tmpstringx[1], SUBDIRBASE);
		for (ps = work; *ps; ps++)
		{
			if (!strncmp (ps, tmpstringx, 4)
			&& *(ps+5) == SLASH_CHR)
				break;
		}
	}



	/*
	 *   loop thru all sections. could be only specified section
	 */
	for (c_sectn = *psec; c_sectn; c_sectn = *++psec)
	{
		/*
		 *   fill in template: man_/xxx._\0\0 (no sub yet)
		 */
		if (!usermanpath_G)
			ps[4] = c_sectn;

		work[last]     = c_sectn;
		work[last + 1] = 0;
		work[last + 2] = 0;
		work[last + 3] = 0;


		/*
		 *   if a subsection was specified, skip past this...
		 */
		if (subsec_G)
			goto SEARCH;


		/*
		 *   does this file exist?
		 */
dbg(("try |%s|...\n", work));
		if ((stflag = stat (work, &sbuf)) >= 0)
		{
			/*
			 *   yes...exit this for loop
			 */
			if (every_G)
			{
				/*
				 *   PAGER should support ^C exit. it should
				 *   exit with status 1 in that case (and
				 *   do_it() would also return 1). it is not
				 *   an error, however, to exit this way but
				 *   we return (with 0) so next item will
				 *   be searched.
				 */
				found++;
				if (do_it (work, iscompressed))
					return (0);
				goto NEXT_LOOP;
			}
			else
				goto FOUND_ONE;
		}


		/*
		 *   no...try looking for compressed version
		 */
		if (hasmanpager_G)
		{
dbg(("not found, try compressed file...\n"));

#if 0
			work[last + 1] = ZSUFFIX;
			work[last + 2] = '\0';
			work[last + 3] = '\0';
#endif
			strcpy(&work[last+1], ZSUFFIX);
			
dbg(("try |%s|...\n", work));
			if ((stflag = stat (work, &sbuf)) >= 0)
			{
				/*
				 *   yes...
				 */
				iscompressed = 1;

				if (every_G)
				{
					found++;
					if (do_it (work, iscompressed))
						return (0);
					goto NEXT_LOOP;
				}
				else
					goto FOUND_ONE;
			}
			work[last + 1] = '\0';	/* reset! */

dbg(("not found...\n"));
		}


SEARCH: ;
		/*
		 *   still not found...look for subsections in manx
		 *
		 *   set up subsect string
		 */
		if (subsec_G)
			cp = psub;
		else
		{
			/*
			 *   take the default subsections for a section...
			 */
			switch (work[last])
			{
			case '0': 	cp = subsec0;		break;
			case '1': 	cp = subsec1;		break;
			case '2': 	cp = subsec2;		break;
			case '3': 	cp = subsec3;		break;
			case '4': 	cp = subsec4;		break;
			case '5': 	cp = subsec5;		break;
			case '6': 	cp = subsec6;		break;
			case '7': 	cp = subsec7;		break;
			case '8': 	cp = subsec8;		break;
			case '9': 	cp = subsec9;		break;
			default: 	cp = "";		break;
			}
		}
dbg(("not found, try subsect, cp = |%s|\n", cp));


		/*
		 *   cycle thru subsections
		 */
		while (*cp)
		{
			/*
			 *   do we find one now?
			 */
			work[last + 1] = *cp++;
			work[last + 2] = '\0';
dbg(("try |%s|...\n", work));
			if ((stflag = stat (work, &sbuf)) >= 0)
			{
				/*
				 *   yes...
				 */
				if (every_G)
				{
					found++;
					if (do_it (work, iscompressed))
						return (0);
					goto NEXT_LOOP;
				}
				else
					goto FOUND_ONE;
			}


			/*
			 *   still no...try compressed...
			 */
			if (hasmanpager_G)
			{
dbg(("not found, try compressed file...\n"));

#if 0
				work[last + 2] = ZSUFFIX;
				work[last + 3] = '\0';
#endif
				strcpy(&work[last+2], ZSUFFIX);
				
dbg(("try |%s|...\n", work));
				if ((stflag = stat (work, &sbuf)) >= 0)
				{
					/*
					 *   yes...
					 */
					iscompressed = 1;
					if (every_G)
					{
						found++;
						if (do_it (work, iscompressed))
							return (0);
						goto NEXT_LOOP;
					}
					else
						goto FOUND_ONE;
				}
				work[last + 2] = '\0';	/* reset! */

dbg(("not found...\n"));
			}
			/* we give up. try next subsection, if any... */
		}
		/* we give up. try next section, if any... */

NEXT_LOOP: ;
	}

	if (every_G)
	{
		if (found)
		    return (0);
		else
		    printf ("%s: no manual entry for %s. try man local %s\n",
				myname, name, name);
	}
	else
	{
		if (section_G == 0)
		printf ("%s: no manual entry for %s. try man local %s\n",
				myname, name, name);
		else
		printf ("%s: no entry for %s in section %c%c of the manual.\n",
				myname, name,
				(char) section_G,
				(subsec_G ? (char) subsec_G : ' '));
	}
	return (1);


FOUND_ONE: ;

dbg(("Found: %s(%x), iscompressed = %d\n",work,stflag,iscompressed));

	return ((int) do_it (work, iscompressed));
}




/*------------------------------*/
/*	do_it			*/
/*------------------------------*/
int do_it (char *cp, int iscompressed)
{
	char	cmdpath[256];
	char    cmd[256];
	char   *so;




	/*
	 *   open the file, look for ".so file" as first line. use that file
	 *   instead. only one level of this nesting is possible (the
	 *   included file can't include, too). do this only if file not
	 *   compressed!
	 */
dbg(("enter do_it, cp = |%s|...\n", cp));
	if (!iscompressed)
	{
		so = so_line (cp);
		if (so)
		{
			cp = so;
dbg(("so_line found something, new cp = |%s|...\n",cp));
		}
	}


	/*
	 *   set up command path (for paging)
	 */
#if defined(__GNUC__) || defined(unix) || defined(__unix)
	cmdpath[0] = '\0';
#else
	strcpy (cmdpath, binpath_G);
	if (lastchar (cmdpath) != SLASH_CHR)
		strcat (cmdpath, SLASH_STR);
#endif
	if (!nopager_G)
	{
		/*
		 *   use pager. if compressed, add correct switch (note:
		 *   iscompressed set only if hasmanpager is true)
		 */
		if (iscompressed)
		{
			sprintf (cmd, "%s%s %s %s",
				(pthpager_G ? "" : cmdpath),
				pager_G,
				ZSWITCH,
				cp);
		}
		else
		{
			sprintf (cmd, "%s%s %s",
				(pthpager_G ? "" : cmdpath),
				pager_G,
				cp);
		}
	}
#ifdef HAS_UL
	else if (ul4cat_G)
	{
		/*
		 *   use ul rather than cat if no pager
		 */
		sprintf (cmd, "%s%s %s", cmdpath, UL, cp);
	}
#endif
#ifdef HAS_CAT
	else
	{
		/*
		 *   use cat if no pager
		 */
		sprintf (cmd, "%s%s %s", cmdpath, CAT, cp);
	}
#endif

	/*
	 *   invoke the pager (or cat or ul)
	 */
dbg(("system (%s)\n", cmd));

	return ((int) system (cmd));
}




/*------------------------------*/
/*	so_line			*/
/*------------------------------*/
char *so_line (char *fname)
{

/*
 *	read first line from found file, looking for ".so " followed by
 *	alternate sourced file. if found, returns ptr to the new name.
 *	otherwise, null.
 *
 *	the file name should include the path of the subsection, e.g.
 *	the file for degas.5 (in man5) contains:
 *
 *		.so man5/picture.5
 *
 *	the rest of the file (man5/degas.5) is ignored.
 *
 *	new: now can also handle
 *
 *		.so picture.5
 *
 *	fname comes in with man5/degas.5 so use the leading path.
 */

	static char	buf[256];
	char		tbuf[256];
	char	       *so;
	FILE	       *stream;
	char	       *ps;

	so = (char *) 0;

	if ((stream = fopen (fname, "r")) == (FILE *) 0)
	{
		printf ("%s: could not open %s to look for .so\n",
				myname, fname);
		return (so);
	}

	/*
	 *   grab first line, delete newline
	 */
	fgets (buf, 255, stream);
	fclose (stream);
	so = buf;
	while (*++so)
		;
	*--so = '\0';

	/*
	 *   is it .so?
	 */
	so = buf;
	if (!strncmp (so, ".so ", 4))
	{
		so += 4;
		while (*so == ' ' || *so == '\t')
			so++;
dbg(("so_line read |%s|\n", so));

		if ((ps = strrchr (so, '\\')) == (char *) 0
		&&  (ps = strrchr (so, '/')) == (char *) 0)
		{
			/*
			 *   the .so line does not contain manx/name.x so
			 *   use path from fname.
			 */
			strcpy (tbuf, so);
			strcpy (so, fname);
			if (ps = strrchr (so, SLASH_CHR))
			{
				ps++;
				strcpy (ps, tbuf);
			}
			else if (ps = strrchr (so, '/'))
			{
				ps++;
				strcpy (ps, tbuf);
			}
		}

dbg(("so_line returning |%s|\n", so));
		return (so);
	}
	else
	{
dbg(("so_line returning NULL\n"));

		return ((char *) 0);
	}
}



/*------------------------------*/
/*	env_inquiry		*/
/*------------------------------*/
void env_inquiry (void)
{

/*
 *	look up things in environment:
 *
 *		MANPAGER,PAGER
 *		TEMP,TMPDIR
 *		MANPATH,MANDIR
 *		BINDIR
 *		MANSECT
 *
 *	setenv MANSECT 108234576
 *	setenv MANSECT 108234576,tcgesla,,s,mgbxl,msvcxgl,dkvscm,,,
 */
	char	       *ps;
	char	       *pl;
	char	       *pd;
	static char	sectbuf[256];



	/*
	 *   alternate pager from environment. if env has variable MANPAGER
	 *   defined, use it as pager (this allows dealing with bold and
	 *   italics in manpage, for example). if not, look for PAGER. if
	 *   neither is set, use default as defined by macro MORE here.
	 */
	if (pager_G == (char *) NULL)
	{
		if ((ps = getenv ("MANPAGER")) != (char *) NULL)
		{
			strcpy (pgbuf, ps);
			pager_G       = pgbuf;
			hasmanpager_G = 1;
		}
		else if ((ps = getenv ("PAGER")) != (char *) NULL)
		{
			strcpy (pgbuf, ps);
			pager_G = pgbuf;
		}
		else
			pager_G = MORE;
	}
	if (pager_G && (strchr (pager_G, ':') || strchr (pager_G, SLASH_CHR)))
		pthpager_G = 1;
dbg(("pager_G = |%s|, pthpager_G = %d\n",(pager_G ? pager_G : "NULL"), pthpager_G));




	/*
	 *   place to put temp files, if needed (not needed yet...)
	 */
	if (tmppath_G == (char *) NULL)
	{
		if ((ps = getenv ("TEMP")) != (char *) NULL)
		{
			strcpy (tpbuf, ps);
			tmppath_G = tpbuf;
		}
		else if ((ps = getenv ("TMPDIR")) != (char *) NULL)
		{
			strcpy (tpbuf, ps);
			tmppath_G = tpbuf;
		}
		else
			tmppath_G = TMPDIR;
	}
	if (tmppath_G && lastchar (tmppath_G) == SLASH_CHR)/* rem trail '/' */
		lastchar (tmppath_G) = '\0';
dbg(("tmppath_G = |%s|\n", tmppath_G ? tmppath_G : "NULL"));




	/*
	 *   where man pages are (e.g. /usr/man)
	 */
	if (manpath_G == (char *) NULL)
	{
		if ((ps = getenv ("MANPATH")) != (char *) NULL)
		{
			strcpy (mpbuf, ps);
			manpath_G = mpbuf;
		}
		else if ((ps = getenv ("MANDIR")) != (char *) NULL)
		{
			strcpy (mpbuf, ps);
			manpath_G = mpbuf;
		}
		else
			manpath_G = MANDIR;
	}
	if (manpath_G && lastchar (manpath_G) == SLASH_CHR)/* rem trail '/' */
		lastchar (manpath_G) = '\0';
dbg(("manpath_G = |%s|\n", manpath_G ? manpath_G : "NULL"));




	/*
	 *   place to find pagers
	 */
	if (binpath_G == (char *) NULL)
	{
		if ((ps = getenv ("BINDIR")) != (char *) NULL)
		{
			strcpy (bpbuf, ps);
			binpath_G = bpbuf;
		}
		else
			binpath_G = BINDIR;
	}
	if (binpath_G && lastchar (binpath_G) == SLASH_CHR)/* rem trail '/' */
		lastchar (binpath_G) = '\0';
dbg(("binpath_G = |%s|\n", binpath_G ? binpath_G : "NULL"));



	/*
	 *   finally, deal with MANSECT. this should be last section
	 *   since this returns.
	 */
	if ((ps = getenv ("MANSECT")) != (char *) NULL)
	{
		strcpy (sectbuf, ps);
dbg(("MANSECT = |%s|\n", sectbuf));
		envmansect_G = 1;

		pl = ps = sectbuf;
		while (*ps && *ps != ',')	/* find first , */
			ps++;
		if (*ps == '\0')		/* if no more list, return */
			return;
		*ps++ = '\0';			/* terminate allsect */

		allsect = pl;
dbg(("allsect = |%s|\n", allsect));

		while (*pl)
		{
dbg(("for sect %c, ", (int) *pl));
			pd = ps;
			switch (*pl)
			{
			case '0':	subsec0 = ps;	goto find_comma;
			case '1':	subsec1 = ps;	goto find_comma;
			case '2':	subsec2 = ps;	goto find_comma;
			case '3':	subsec3 = ps;	goto find_comma;
			case '4':	subsec4 = ps;	goto find_comma;
			case '5':	subsec5 = ps;	goto find_comma;
			case '6':	subsec6 = ps;	goto find_comma;
			case '7':	subsec7 = ps;	goto find_comma;
			case '8':	subsec8 = ps;	goto find_comma;
			case '9':	subsec9 = ps;
find_comma: ;
				if (*ps == ',')
				{
					*ps++ = '\0';
					if (*ps == '\0')
					{
dbg(("subsec = empty\n"));
						return;
					}
dbg(("subsec = empty\n"));
					break;
				}
				while (*ps && *ps != ',')
					ps++;
				if (*ps == '\0')
				{
dbg(("subsec = empty\n"));
					return;
				}
				*ps++ = '\0';
dbg(("subsec = |%s|\n", pd));
				break;

			default:
				break;
			}
			pl++;
		}
	}
}


#define FP		fprintf

/*------------------------------*/
/*	usage			*/
/*------------------------------*/
void usage (int excode)
{
	char *ps;
	int i;

#if 0
FP (stderr, "Usage: %s [-s sec[sub]] [-M dir | -m dir] [- [-ul]] [-k key] [-f file] [sec[sub]] name\n", myname);
#endif


FP (stderr, "\nUsage: %s [options] [sec[sub]] name\n", myname);


FP (stderr, "Opts:  -s sec[sub]        section/subsect (e.g. 2g)\n");
FP (stderr, "       -M dir             specify search dir (for man tree)\n");
FP (stderr, "       -m dir             specify search dir (dir, no tree, eg man -m .)\n");
#ifdef HAS_CAT
FP (stderr, "       -                  use cat rather than more or less\n");
# ifdef HAS_UL
FP (stderr, "       - -ul              use ul rather than cat\n");
# endif
#endif
#ifdef HAS_APROPOS
FP (stderr, "       -k key             same as \"apropos keyword\"\n");
#endif
#ifdef HAS_WHATIS
FP (stderr, "       -f file            same as \"whatis file\"\n");
#endif


FP (stderr, "Args:  sec                section, alternate for -s\n");
FP (stderr, "       sub                subsection, alternate for -s\n");
FP (stderr, "       name               desired entry (command, etc)\n");


FP (stderr, "Search order:\n");
if (envmansect_G)
{
 for (ps = allsect; *ps; ps++)
 {
  switch (*ps)
  {
  case '0':
	FP (stderr, "       %s0%s*.0", SUBDIRBASE, SLASH_STR);
	if (*subsec0)
	 FP (stderr, "[%s]%s", subsec0, (strlen(subsec0) < 7) ? "\t  " : "  ");
	else
	 FP (stderr, "\t\t  ");
	FP (stderr, "general\n");
  	break;
  case '1':
	FP (stderr, "       %s1%s*.1", SUBDIRBASE, SLASH_STR);
	if (*subsec1)
	 FP (stderr, "[%s]%s", subsec1, (strlen(subsec1) < 7) ? "\t  " : "  ");
	else
	 FP (stderr, "\t\t  ");
	FP (stderr, "commands\n");
  	break;
  case '2':
	FP (stderr, "       %s2%s*.2", SUBDIRBASE, SLASH_STR);
	if (*subsec2)
	 FP (stderr, "[%s]%s", subsec2, (strlen(subsec2) < 7) ? "\t  " : "  ");
	else
	 FP (stderr, "\t\t  ");
	FP (stderr, "system calls\n");
  	break;
  case '3':
	FP (stderr, "       %s3%s*.3", SUBDIRBASE, SLASH_STR);
	if (*subsec3)
	 FP (stderr, "[%s]%s", subsec3, (strlen(subsec3) < 7) ? "\t  " : "  ");
	else
	 FP (stderr, "\t\t  ");
	FP (stderr, "library calls\n");
  	break;
  case '4':
	FP (stderr, "       %s4%s*.4", SUBDIRBASE, SLASH_STR);
	if (*subsec4)
	 FP (stderr, "[%s]%s", subsec4, (strlen(subsec4) < 7) ? "\t  " : "  ");
	else
	 FP (stderr, "\t\t  ");
	FP (stderr, "hardware\n");
  	break;
  case '5':
	FP (stderr, "       %s5%s*.5", SUBDIRBASE, SLASH_STR);
	if (*subsec5)
	 FP (stderr, "[%s]%s", subsec5, (strlen(subsec5) < 7) ? "\t  " : "  ");
	else
	 FP (stderr, "\t\t  ");
	FP (stderr, "special files\n");
  	break;
  case '6':
	FP (stderr, "       %s6%s*.6", SUBDIRBASE, SLASH_STR);
	if (*subsec6)
	 FP (stderr, "[%s]%s", subsec6, (strlen(subsec6) < 7) ? "\t  " : "  ");
	else
	 FP (stderr, "\t\t  ");
	FP (stderr, "games\n");
  	break;
  case '7':
	FP (stderr, "       %s7%s*.7", SUBDIRBASE, SLASH_STR);
	if (*subsec7)
	 FP (stderr, "[%s]%s", subsec7, (strlen(subsec7) < 7) ? "\t  " : "  ");
	else
	 FP (stderr, "\t\t  ");
	FP (stderr, "misc\n");
  	break;
  case '8':
	FP (stderr, "       %s8%s*.8", SUBDIRBASE, SLASH_STR);
	if (*subsec8)
	 FP (stderr, "[%s]%s", subsec8, (strlen(subsec8) < 7) ? "\t  " : "  ");
	else
	 FP (stderr, "\t\t  ");
	FP (stderr, "admin commands\n");
  	break;
  case '9':
	FP (stderr, "       %s9%s*.9", SUBDIRBASE, SLASH_STR);
	if (*subsec9)
	 FP (stderr, "[%s]%s", subsec9, (strlen(subsec9) < 7) ? "\t  " : "  ");
	else
	 FP (stderr, "\t\t  ");
	FP (stderr, "other\n");
  	break;
  }
 }
}
else
{
FP (stderr, "       %s1%s*.1[tcgesla] cmds (util & text,com,graph,edit,shell,lang,archive)\n", SUBDIRBASE, SLASH_STR);
FP (stderr, "       %s0%s*.0          general\n", SUBDIRBASE, SLASH_STR);
FP (stderr, "       %s8%s*.8[s]       admin (util & system)\n", SUBDIRBASE, SLASH_STR);
FP (stderr, "       %s2%s*.2[b]       syslib (unix & bios)\n", SUBDIRBASE,SLASH_STR);
FP (stderr, "       %s3%s*.3[msvcxl]  libs (C lib & math,stdio,sysV,compat,misc,local)\n", SUBDIRBASE, SLASH_STR);
FP (stderr, "       %s4%s*.4[dkvscm]  h/w (gen & disk,keyboard,video,sound,chips,memory)\n", SUBDIRBASE, SLASH_STR);
FP (stderr, "       %s5%s*.5          special files\n", SUBDIRBASE,SLASH_STR);
FP (stderr, "       %s7%s*.7          misc\n", SUBDIRBASE, SLASH_STR);
FP (stderr, "       %s6%s*.6          games\n", SUBDIRBASE, SLASH_STR);
}


#ifdef LONG_SECT
FP (stderr, "Other sections:          ");
for (i = 0; i < 10; i++)
{
 if (longsect[i] == (char *) NULL)
  break;
 FP (stderr, "%s", longsect[i]);
 if (longsect[i+1])
  FP (stderr, ",");
}
FP (stderr, "\n");
#else
FP (stderr, "Other sections:          local,new,old\n");
#endif


FP (stderr, "Environment:             MANPAGER,PAGER,MANPATH,MANSECT,BINDIR,TMPDIR\n");


exit (excode);
}


@EOF
set `sum $sumopt <man/man.c`; if test $1 -ne 9208
then
	echo ERROR: man/man.c checksum is $1 should be 9208
fi

chmod 644 man/man.c

echo x - man/man.man
sed 's/^@//' >man/man.man <<'@EOF'
@.\" man v3.0.2 92/10/11 rosenkra
@.TH MAN 1
@.SH NAME
man \- read online documentation
@.SH SYNOPSIS
@.\" man [- [-ul]] [-s sect[subs]] [-M path] [-m path] [-e] [sect[subs]] name ...
@.B man
@.RB [ \-
@.RB [ \-ul ]]
@.RB [ \-s
@.IR sect [ subs ]]
@.RB [ \-M
@.IR path ]
@.RB [ \-m
@.IR path ]
@.RB [ \-e ]
@.RI [ sect [ subs ]]
@.IR name ...
@.br
@.\" man -f file
@.B man
@.B \-f
@.IR file ...
@.br
@.\" man -k keyword...
@.B man
@.B \-k
@.IR keyword ...
@.SH DESCRIPTION
The
@.B man
command finds and displays information in the online documentation set.
When the standard output is a terminal,
@.B man
pipes its output through
@.IR less (1)
or the name of the command specified with the MANPAGER or PAGER environment
variables.
@.SH OPTIONS
The following command line options are recognized:
@.IP \fB\-\fR
Pipes the output through
@.IR cat (1)
rather than
@.IR less (1)
or PAGER.
@.IP "\fB\- \-ul\fR"
Use
@.IR ul (1)
rather than
@.IR cat (1).
@.IP "\fB\-M\fR \fIpath\fR"
Specifies a directory tree in which to search.
By default,
@.B man
searches in c:\\usr\\man under MSDOS or on the Atari ST or
/usr/man under Unix,
or the directory specified by the
MANPATH environment variable, the standard location for online
documentation.
The MANPATH variable should have a single path name at the
present time (eventually, it will support a colon-separated
list of locations).
This option assumes
@.I path
is the root of a \*(lqnormal\*(rq directory structure.
For compatibility with some Unix man systems, you can use
@.B \-P
as well as
@.BR \-M .
@.IP "\fB\-m\fR \fIpath\fR"
Specifies a directory in which to search.
This option does not use a directory tree.
Files are searched only in the directory specified by
@.IR path .
This option is useful for debugging new manpages.
For example, assuming you are working on a manpage
named \*(lqmycmd.1\*(rq, you can do this:
@.sp
@.nf
	man -m . 1 mycmd
@.fi
@.IP \fB\-e\fR
Find every manpage concerning the given
@.I name
regardless of section.
It is expected that a \*(lqnormal\*(rq exit from the pager
will result in an exit status of 0 (in which case the search is continued
in other sections).
An \*(lqabnormal\*(rq exit should result in a nonzero exit status
and the search is then terminated.
@.IP "\fB\-s\fR \fIsect\fR[\fIsubsect\fR]"
Specifies a
@.I section
and
@.I subsection
similar to the 4.2 BSD UNIX Programmer's Manual (as explained below)
in which to search.
If no
@.I section
is specified,
@.B man
searches through all of the sections.
Example:  \*(lqman -s 3s fopen\*(rq.
@.IP \fIsect\fR
As an alternative to
@.BR \-s ,
you can specify the section (and optional subsection) as the first
argument.
Example:  \*(lqman 3s fopen\*(rq.
@.IP \fIname\fR
Searches for documentation files associated with the specified
@.IR name .
@.IP "\fB\-f\fR \fIname\fR"
Displays a one line synopsis of each online documentation file whose
names match the specified word (equivalent to the
@.IR whatis (1)
command).
For example, \*(lqman -f chmod\*(rq will give entries for both
@.IR chmod (1)
and
@.IR chmod (2).
Note that
@.B man
invokes
@.IR whatis (1)
in this case, so it should be found in the path (see ENVIRONMENT).
@.IP "\fB\-k\fR \fIkeyword\fR"
Displays a one line synopsis of each online documentation file whose name
or description contains the specified
@.I keyword
(equivalent to the
@.IR apropos (1)
command).
Note that
@.B man
invokes
@.IR apropos (1)
in this case, so it should be found in the path (see ENVIRONMENT).
@.SH ENVIRONMENT
The following environment variables are recognized:
@.IP MANSECT
This can be used to alter the search order and to customize subsections.
The default is equivalent to:
@.sp
@.nf
setenv MANSECT 108234576,tcgesla,,s,mgbxl,msvcxgl,dkvscm,,,
@.fi
@.sp
This means the major sections (man1, etc.) are searched in the order
man1, man0, man8, etc.
For each section, you can also provide a list of subsections which must
correspond in the remaining list.
In this case man1 subsections are t,c,g,e,s,l, and a;
there are no subsections for man0;
etc.
The first entry (the section list) must consist of numbers from 0 to 9
@.IR only .
Numbers can be skipped.
@.sp
The default search order is oriented toward users.
To speed up the search, a casual programmer might perfer:
@.sp
@.nf
	325481760,gsmcvxl,mgbxl,,dkvscm,s,tcgesla,,,
@.fi
@.sp
while a Unix programmer might prefer:
@.sp
@.nf
	235481760,mgbxl,csmxvlg,,dkvscm,s,tcgesla,,,
@.fi
@.IP MANPATH,MANDIR
Location of main manual direcotry, where subdirectories are to be found.
@.B Man
uses (in order of priority) the path specified with
@.BR \-M ,
the MANPATH specified, or the built-in default (c:\\usr\\man or /usr/man).
@.IP MANPAGER
Name of prefered pager.
Use this pager if you have compressed manpages (see
@.IR manpager (1)).
@.B Man
will use first MANPAGER, if found, then PAGER, if found.
If neither are found, it uses c:\\usr\\bin\\less.
@.IP PAGER
Name of secondary pager to replace
@.IR less (1).
Use this if you do not have manpages generated with font changes (see
@.IR nroff (1)).
Either MANPAGER or PAGER should be defined.
The search order is MANPAGER then PAGER.
@.\" .IP BINDIR
@.\" Alternate location to find all necessary executables.
@.\" The default is c:\\bin.
@.\" You need
@.\" .BR less (1),
@.\" .BR cat (1),
@.\" and
@.\" .BR ul (1)
@.\" at a minimum.
@.\" .IP TMPDIR
@.\" Place to put temporary files, if necessary.
@.\" Default is g:\\tmp.
@.\" Make it a ramdisk partition, if you have one.
@.\" So far this is not used.
@.PP
Note that BINDIR and TMPDIR are not currently used.
@.SH "SECTION NAMES"
By convention, the "sections" of the manual are (see
@.IR whatisin (1)
as well):
@.sp
@.nf
Sect	Section Name	Description
----	-------------	--------------------------------------
0	General		overview of features and documentation
1	Commands	user commands
2	System Calls	low-level system library calls (C)
3	Library Calls	standard user calls (C)
4	Special Files	special system files and hardware
5	File formats	things like arc(1) file formats
6	Games		games manual
7	Miscellaneous	miscellaneous information
8	Administration	system administration commands
@.fi
@.sp
In addition, this
@.B man
recognizes the following section names:
@.sp
@.nf
local		files specific to local system
new		files added since current software release
old		files from previous software release
gnu		GNU files (gcc typically)
paper		misc formal papers
doc		misc documentation
@.fi
@.PP
The search order, if no section is specified, is:
@.sp
@.nf
108234576
@.fi
@.PP
In addition to sections, there are a number of subsections possible,
though these files do not reside in a special directory.
The subsection name is simply appended to the file name.
Example:
\*(lqfopen.3s\*(rq resides in $MANPATH\\man3, the section is \*(lq3\*(rq
(libraries) and the subsection is \*(lqs\*(rq, stdio.
Here is the subsection search order for subsections in each section
(the square brackets mean a choice of each character contained in them,
in that order):
@.sp
@.nf
man1\\*.1[tcgesla]	util & text,com,graphics,edit,shell,lang
			archival
man0\\*.0
man8\\*.8[s]		util & system
man2\\*.2[mgbxl]		system & mint,gemdos,bios,xbios,lineA
man3\\*.3[msvcxgl]	C lib & math,stdio,sysV,compat,extra
			gem(aes/vdi),local
man4\\*.4[dkvscm]	general & disk,keyboard,video,sound,chips
			memory
man5\\*.5
man7\\*.7
man6\\*.6
@.fi
@.SH NOTES
To save disk space, you can "source" other files by including the
@.BR nroff (1)
directive \*(lq.so\*(rq in a file as the first line.
In this case, the first line should start with .so followed by at least
one space, then the file to use instead of the actual manpage.
For example, the manpage for feof.3s (in $MANPATH\\man3) contains the single
line:
@.sp
@.nf
	\&.so man3\\ferror.3s
@.fi
@.sp
which will cause
@.B man
to display the contents of \*(lqferror.3s\*(rq instead.
Note the relative path (relative to MANPATH, by default c:\\usr\\man).
In this way, numerous manpages can refer to a single (larger) file.
Do not compress files with source lines as
@.B man
only checks for this line if it finds a file which is not compressed.
Note that you should only compress files for viewing with a pager
that supports reading compressed files (e.g.,
@.BR manpager (1))
and must set the MANPAGER environment variable as well.
@.PP
You can also specify just a file name for sourcing (without relative path):
@.sp
@.nf
	\&.so ferror.3s
@.fi
@.sp
and
@.B man
will use the relative path of the file containing this line.
@.SH FILES
@.nf
c:\\usr\\man		root of standard manual page directory tree
c:\\usr\\man\\man*\\*	manual entries
c:\\usr\\man\\whatis	table of contents and keyword database
@.fi
@.SH "SEE ALSO"
apropos(1), cat(1), less(1), manpager(1), nroff(1), what(1), whatis(1), whatisin(1), whereis(1), man(7)
@.SH AUTHOR
Bill Rosenkranz
@.br
rosenkra AT convex DOT com
@.SH VERSION
man v3.0.2 92/10/11 rosenkra
@EOF
set `sum $sumopt <man/man.man`; if test $1 -ne 53179
then
	echo ERROR: man/man.man checksum is $1 should be 53179
fi

chmod 644 man/man.man

chmod 755 man

exit 0

-- 
Bill Rosenkranz            |UUCP: {uunet,texsun}!convex!rosenkra
Convex Computer Corp.      |ARPA: rosenkra AT convex DOT com

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019