From: mfaurot@phzzzt.uucp (Michael Faurot)
Newsgroups: comp.os.coherent
Subject: ZMAN v1.2 (source)
Date: 14 Oct 92 22:02:21 GMT
Reply-To: mfaurot@phzzzt.uucp (Michael Faurot)
Organization: A.T.W.W.

After waiting for a couple of weeks for suggestions in regards to posting
source here, I've only received one, and decided to go ahead and post. 
Anyone interested in flaming me for posting source: flames > /dev/null 2>&1

Here's an excerpt from ZMAN's README file:


What is it?
===========

	ZMAN is an argument compatible plug-in replacement for man. 
	Its primary feature is its ability to work with man pages in a
	compressed format.
	
	The idea for doing this comes from administering a Sequent
	Balance which stores all of its freetext (ie. nroff processed)
	man pages in this manner.  After drinking a few beers one afternoon
	I asked myself, "Why not do the same thing for Coherent?"


==================== Cut here and you'll break your monitor ===================

#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
#	Run the following text with /bin/sh to create:
#	  README
#	  MANIFEST
#	  Makefile
#	  man.h
#	  HISTORY
#	  TODO
#	  main.c
#	  show_help.c
#	  split_rec.c
#	  find_man.c
#	  show_man.c
#
echo "x - extracting README (Text)"
sed 's/^X//' << 'SHAR_EOF' > README &&
X                                  ZMAN v1.2
X                                  =========
X
X                            Michael Faurot H.A.L.
X                            =====================
X
XWhat is it?
X===========
X
X	ZMAN is an argument compatible plug-in replacement for man. 
X	Its primary feature is its ability to work with man pages in a
X	compressed format.
X	
X	The idea for doing this comes from administering a Sequent
X	Balance which stores all of its freetext (ie. nroff processed)
X	man pages in this manner.  After drinking a few beers one afternoon
X	I asked myself, "Why not do the same thing for Coherent?"
X	
XLame disclaimers to avoid blame . . . 
X=====================================
X
X	What would a freeware package be without this and because
X	I don't feel like getting screwed . . .
X	 
X	If you decide to use this program on your system you do
X	so at your own risk, and are solely responsible for any actions that
X	may result from its use or non-use.  You're free to copy this program,
X	give it away, barter it for sheep and livestock, or swap it for a
X	six-pack and a pizza.  However you're not free to re-sell, sell,
X	claim that it was your brain-child or make money from this.  Any copies
X	made should include the source in its entireity including this file and
X	notice.  Redistribution with pre-made binaries is fine, as long as the
X	source is also included.  If you need to charge a couple of bucks to
X	cover the cost of media or the hassle of copying this for
X	someone--that's okay.   I'm no lawyer, and didn't feel like digging up
X	a GNU public license, but just #include <gnu/license.h> :-)
X
XNotational convention
X=====================
X
X	Throughout this document I will be making reference to compression
X	programs in general and using the word *compress* with asterisks
X	to denote the program /bin/compress which comes with Coherent. 
X	When compress is seen alone without asterisks this is meant to
X	denote compression in a generic sense.
X	
XHow closely does it emulate the original man program?
X=====================================================
X
X	As stated previously, ZMAN is designed to be a plug-in replacment
X	for the stock man program and accepts the same arguments.  Thus
X	ZMAN supports the -w option to display the filenames of the man
X	pages and also recognizes a user's preferance for a specific pager
X	as defined in the PAGER environment variable.  It also defaults
X	to the same pager (subject to personal tuning) that man does should
X	the user not have a preferance.  In general ZMAN should have the
X	same look and feel that man does, except that it will save space
X	on your filesystem by allowing you to compress your manual pages.
X	Also, the same Lexicon entry for man which describes it's arguments
X	and options will describe ZMAN's as well.
X
X	New to v1.2, ZMAN is now able to work with files that are both
X	compressed and files that are deliberately left uncompressed.
X	Thus ZMAN can be installed and experimented with, without having
X	to first compress all your man pages.
X	
XWill it work with v3.X Coherent?
X================================
X
X	Yes, although your mileage may vary.  ZMAN is developed and tested
X	under Coherent v4.X with v3.X adaptations coming later after
X	users point them out.
X
X	If you're using this under v3.X and have had to make changes to
X	get it working please send me a note so that I can update my
X	sources.
X	
XWill it work with an OS other than Coherent?
X============================================
X
X	Probably not since Coherent has a somewhat unique layout for its
X	manpage directories and the way in which the man pages are located.
X	However if you want to either convert your system to use the Coherent
X	directory conventions and/or modify these sorces for your own
X	ends--go for it.  However, please do not ask me for help in porting
X	it! :-{  The only other thing I would ask is you mention where your
X	sources originated from (ie, me!).
X	
XWhat are the trade offs involved?
X=================================
X
X	If you're running a system that's tight on disk space you'll
X	benefit from being able to shrink the size of the man pages.
X	On the other hand, depending upon how loaded your machine is and
X	how fast, it may take a little longer for ZMAN to pop up a man page
X	on your screen.  On my 386/40 system, I haven't noticed too much
X	of a difference between how fast man and ZMAN display things, but
X	it does appear like ZMAN is a wee bit slower.
X
XWhat is required to convert my existing man pages over to being used by ZMAN?
X=============================================================================
X
X	Not much at all.  Just go to each directory under /usr/man and 
X	run the compression program of your choise on the various files
X	in each of the sub-directories. See the section "What's The
X	Installation Procedure?" for details.
X
XWill I have to make any changes to my existing man.index file?
X==============================================================
X
X	Nope.  ZMAN uses it just the way it is.  However please see the
X	section entitled "What about those uncompressed files?" for details
X	on how to make some optional modifications.
X
XHow does ZMAN handle filenames which are too big to have a suffix on them?
X==========================================================================
X
X	ZMAN is able to deal with this situation by looking at the
X	basename of the relative pathname in man.index.  If that basename
X	has too many characters to allow appending a suffix to it and still
X	remain a legal filename ZMAN makes the assumption that your compression
X	program was not able to compress it.  In this situation ZMAN will just
X	run a pager against it.
X	
X	For example, assuming you choose to use *compress* and zcat which
X	come with Coherent, *compress* will be unable to compress some of
X	the files in /usr/man/COHERENT such as "virtualconsole" and
X	"registervariab" because they both have more than 12 characters
X	in them.
X
XWhich compression programs will ZMAN work with?
X===============================================
X
X	ZMAN has been tested and developed primarily with the stock
X	compression programs that come with Coherent: *compress*,
X	uncompress & zcat.  In fact the *compress* scheme is the default
X	configuration.
X
X	ZMAN has also partially been tested with UnZip v4.1 by Samuel H.
X	Smith.  This is the same version available on MWCBBS.  When I say
X	"partially been tested" I've only tried UnZip with a few man
X	pages because I currently don't have a working copy of ZIP
X	for Coherent. :-}  But when using UnZip I merely set-up the 
X	macro CAT, in man.h, to be defined as "/usr/local/bin/unzip -p"
X	and CATEXT to be ".zip".  A couple of thoughts occur to me
X	should you decide to use ZIP as your compression scheme:
X
X	A)	Since ZIP uses a larger extension than *compress* there
X		will likely be more files left uncompressed because
X		the maximum file length will be reduced from 12 with
X		*compress* to 10 with ZIP.
X
X	B)	You might need to come up with a script file to have
X		ZIP compress all of your files properly, especially
X		since ZIP is not only capable of compression but
X		also of archiving numerious files into a single file
X		like tar.  Perhaps something like the following
X		untested script:
X		^^^^^^^^
X			cd /usr/man/COHERENT
X			for file in *
X			do
X				zip -m $file $file	
X			done
X
X		Note:  The reason the script would be needed is that
X		unlike *compress* which will compress each file individually
X		and create a seperate compressed version of that file
X		ZIP would probably try and put all of the files into a
X		SINGLE archive file!
X
X	In general I don't foresee many problems with using other
X	compression schemes.  The only pre-requisite for the compression
X	scheme is that it is capable of doing its decompression to
X	standard out so that it can be used in a pipeline like zcat.
X
XWhat's the installation procedure?
X==================================
X
X	Typical stuff, just follow this checklist:
X
X	1)	Take a look at Makefile, and see if any of the variables
X		at the top should be changed for your site.  If you're
X		using a stock installation of Coherent you probably won't
X		need to make any changes.
X
X	2)	Take a look at man.h and optionally edit the parameters
X		under the section "User Adjustable Macros".  There are
X		comments next to all of these parameters and should be fairly
X		self-explanatory.
X
X	3)	Run make.
X
X	4)	As root go to each directory under /usr/man
X		(eg /usr/man/COHERENT) and run your compression program
X		against all of the files.  For example if you're using
X		*compress* you might do the following:
X		
X		 	/bin/compress -v *
X		 	
X		NOTE:  There will be some files that cannot be compressed
X		because their filenames are already too large to allow a
X		suffix appended to them. This is OKAY, ZMAN will be able
X		to deal with these filenames not being compressed.  See
X		the section "What about those uncompressed files?" for more
X		information on options to deal with this.
X
X	6)	mv /bin/man to /bin/man.old
X
X	7)	cp zman to /bin/man.
X
X	8)	Adjust permissions to the new /bin/man as appropriate.
X
X
XWhat about a man page for ZMAN itself?
X======================================
X
X	ZMAN is designed to be a plug-in replacement for the original man
X	program, and as near as I've been able to determine it seems to
X	work just like the original.  Therefore in my mind this spares me
X	the aweful tedium of having to come up with a man page! :-)  However
X	if some net.citizen would care to write one for a future distribution
X	I will gladly include it and give you all the blame in the next
X	version's README! :-)
X	
XWhat about those uncompressed files?
X====================================
X
X	As mentioned in the section outlining the installation steps, when
X	you run your compression program against the existing man pages,
X	some of them won't compress because their filenames are too big.
X	My philosophy in designing this was to not require any major
X	modifications to the existing system, and an easy way to back this
X	thing out.  Thus it is unnecessary to make any changes to the file
X	man.index.  If however you want to squeeze out every bit of space,
X	you can do it by manually renaming those files that have too many
X	characters in them to something shorter and then updating man.index.
X	
X	NOTE: only use the basename of the file without the compression
X	program's suffix (eg, don't put .Z when using *compress*).
X	
X	For example if you want to change structureassig to structassig.
X	You would do the following if using *compress*:
X	
X		1)	become root if you're not already
X		
X		2)	cd to /usr/man/COHERENT
X		
X		3) 	mv structureassig to structassig
X		
X		4)	/bin/compress structassig
X		
X		5)	edit /usr/man/man.index and change the filename
X			reference from COHERENT/structureassig to
X			COHERENT/structassig.
X
X	One other thing to consider, before doing this, is the issue
X	of future Coherent updates.  I'm not sure if Mark Williams 
X	issues updates or deltas to their OS, but if they did and 
X	the updates were expecting to find specific files under
X	/usr/man/COHERENT that update program is not going to find
X	the file(s) you've renamed.  However, if all you've done is simply
X	run your compression program against all of the man pages and
X	left the ones it couldn't compress alone, all that you'll need
X	to do to make your man pages ready to accept the update is 
X	uncompress them again.
X
XWhat's the procedure when I want to add new man pages?
X======================================================
X
X	It's basically the same procedure as outlined in the Coherent Lexicon
X	but of course now you will also want to run your compression program
X	against the new pages after they have been installed in the appropriate
X	directory.  Should you forget to compress the man page(s) ZMAN will
X	be able to determine this for itself and will not attempt to run
X	a decompression program on the file(s).
X
X	Note:  When installing new software which has a makefile that will
X	also install its man pages as part of a "make install" procedure
X	you may wish to either update the makefile and add in the
X	compression step or just go to the directory under /usr/man where
X	the man page(s) were installed and manually compress those pages
X	yourself.
X	
XAre there any known bugs or limitations?
X========================================
X
X	Sure!  Whaddaya want for nothing? :-)  I can think of the
X	following:
X
X	1)	Currently ZMAN is designed to work with only one compression
X		scheme.  In other words, if you're going to compress your man
X		pages, they must ALL be compressed with the same program.
X		There is currently no provision for having some compressed
X		using *compress* some using zip and some using some other
X		system.  
X
X	2)	ZMAN deals with multiple arguments a little bit differently
X		than man does.  I think man will attempt to put all of the
X		files together into one pipeline  whereas ZMAN will call
X		zcat and your pager individually on each man page.
X
X	3)	Probably something else I haven't found yet, but you as
X		a good net.citizen will dutifully inform me of. :-)
X
X		
XHow do I uninstall this if I don't like it?
X===========================================
X
X	Assuming you haven't modified your man.index file, it is very easy
X	to revert back to the original man program and man pages.  Just
X	following these steps:
X
X	1)	Become root.
X
X	2)	Run your uncompress program in each of the directories
X	 	under /usr/man against all of the files (eg, "uncompress *").
X
X	3)	cd to /bin
X
X	4)	rm man
X
X	5)	mv man.old to man
X
XIs there a mailing list for ZMAN?
X=================================
X
X	Yes.  For updates or discussions concerning ZMAN address your
X	mail to zman@phzzzt.uucp.  I would encourage you to send me a mail
X	message if you intend on making use of ZMAN so I can add your address
X	to my mailing list.  Thus when bug fixes or updates come out you'll
X	be in the pipeline for receiving them.  To get your address on the
X	mailing list please send mail to one of the addresses listed at
X	the end of "Who's to blame for this thing?".  Please include the
X	address you would like me to use and where/how you got your copy
X	of ZMAN.
X
X	Note: If you've received ZMAN directly from me via e-mail I've
X	already included your address in the mailing list.  Please let me
X	know if you do not wish your name on this list and I will remove
X	it.
X	
XWho's to blame for this thing?
X==============================
X
X	Michael Faurot (pronounce four-oh).  Who by day is a self
X	proclaimed H.A.L. (Hacker At Large) and System Administrator
X	for the Federal Government and by night is still a H.A.L. but
X	happily sitting in his drawers and swilling beer while pounding
X	on his Coherent installation . . . :-)
X	
X	If this proves to be a useful addition to your Coherent installation
X	you don't have to send money, but an e-mail note to one of the
X	addresses located at the end of this file would be nice.  If
X	something needs fixing or improving I'd like to hear your constructive
X	criticism as well.  As always, flames > /dev/null 2>&1 !
X
X	Thanks to:
X	
X		agentv (agentv@phzzzt.uucp) for proof reading this document
X		and letting me debug my code out loud.  :-)
X		
X		Mike McAdams (mmcadams@speck.uucp) for finding the quirks
X		between make under v3.X and v4.X and for testing ZMAN's
X		initial release under v3.X.
X		
X	Domain: mfaurot@phzzzt.uucp
X	UUCP:   ...!mimsy!bogart!phzzzt!mfaurot
X	        ...!uunet!media!irscscm!bogart!phzzzt!mfaurot
X
X	phzzzt is home of the bi-labial fricative and HQ for A.T.W.W. where
X	our motto is "Never eat anything bigger than your head!"
SHAR_EOF
chmod 0644 README || echo "restore of README fails"
echo "x - extracting MANIFEST (Text)"
sed 's/^X//' << 'SHAR_EOF' > MANIFEST &&
Xzman v1.2 should include the following files
X============================================
X
XMANIFEST
XHISTORY
XTODO
XMakefile
XREADME
Xfind_man.c
Xmain.c
Xman.h
Xshow_help.c
Xshow_man.c
Xsplit_rec.c
SHAR_EOF
chmod 0644 MANIFEST || echo "restore of MANIFEST fails"
echo "x - extracting Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
X#
X#  makefile for zman
X#
X
XCFLAGS	= -O
X
XCC	= cc
X
XSHAR	= /usr/local/bin/shar -v
X
XSRC	= main.c show_help.c split_rec.c \
X	  find_man.c show_man.c
XOBJ	= main.o show_help.o split_rec.o \
X	  find_man.o show_man.o
X
XMISC	= README MANIFEST Makefile man.h HISTORY TODO
X
Xzman	: $(OBJ)
X	$(CC) $(CFLAGS) $(OBJ) -s -o zman 
X
Xmain.o		: main.c man.h
X	$(CC) $(CFLAGS) -c main.c
X	
Xshow_help.o	: show_help.c man.h
X	$(CC) $(CFLAGS) -c show_help.c
X	
Xshow_man.o	: show_man.c man.h
X	$(CC) $(CFLAGS) -c show_man.c
X	
Xfind_man.o	: find_man.c man.h
X	$(CC) $(CFLAGS) -c find_man.c
X	
Xsplit_rec.o	: split_rec.c man.h
X	$(CC) $(CFLAGS) -c split_rec.c
X
Xshar 	: $(SRC) $(MISC)
X	$(SHAR) $(MISC) $(SRC)  > zman.shar
SHAR_EOF
chmod 0644 Makefile || echo "restore of Makefile fails"
echo "x - extracting man.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > man.h &&
X/* --------------------------------[ Headers ]------------------------------ */
X
X#include <stdio.h>
X#include <errno.h>
X#include <string.h>
X#include <sys/fcntl.h>
X
X/* -----------------------[ User Adjustable Macros ]------------------------ */
X
X/*
X**  Maximum number of tokens (words) there should be in a search string.
X**  For instance, I've only seen at most two like "calling conventions"
X**  but if you wanted to be really verbose, you could up this from 3
X**  words to something else, although I wouldn't recommend getting too
X**  much beyond 5 or 6 as you might start blowing out some of the array
X**  boundaries.
X*/
X#define MAXTOK	3
X
X/*
X**  If the user has not defined their screen display program via the PAGER
X**  variable, then this will be the default pager used.
X*/
X#define	DEFAULT	"exec /bin/scat -1"
X
X/*
X**  Locacation of the index to the man pages.  Under normal circumstances
X**  I don't think this will change, but there's nothing stopping you
X**  from putting it someplace different . . .
X*/
X#define INDEX	"/usr/man/man.index"
X
X/*
X**  Location of the help file used by man when man is called with
X**  no arguments.  Again, this is the standard location but guess
X**  you could move it if you wanted to . . .
X*/
X#define HELP	"/usr/man/man.help"
X
X/*
X**  Location of the man page directories.  This is pretty standard,
X**  and shouldn't need to be changed.
X*/
X#define MANDIR	"/usr/man"
X
X/*
X**  Name of the program to use to decompress the man pages.  This
X**  should be a program that is capable of taking a filename 
X**  as it's first argument and then sending it's output to stdout.
X*/
X#define CAT	"/bin/zcat"
X
X/*
X**  What is the filename extension/suffix used by the decompression
X**  program defined in CAT. Be sure to include the "." (dot character).
X**  For example zcat uses ".Z".
X*/
X#define CATEXT	".Z"
X
X/*
X**  END OF USER ADJUSTABLE MACROS
X*/
X
X/* ---------------------------------[ Macros ]------------------------------ */
X
X#define	TRUE	1
X#define	FALSE	0
X
X#define	MAX	1024
X#define	HALF	512
X
X#define FOUND	 0
X#define NOTFOUND 1
X
X#define	MAXNAME	14
X
X/* ------------------------------[ Prototypes ]----------------------------- */
X
Xvoid	show_help ();
Xvoid	usage ();
Xint	find_man ();
Xvoid	show_man ();
Xint	split_rec ();
X
Xextern char *getenv();
X
X/* -------------------------------[ Globals ]------------------------------- */
X
Xextern	int sys_nerr;
Xextern	char *sys_errlist[];
SHAR_EOF
chmod 0644 man.h || echo "restore of man.h fails"
echo "x - extracting HISTORY (Text)"
sed 's/^X//' << 'SHAR_EOF' > HISTORY &&
Xv1.2 (10/11/92)
X===============
X
X	After contemplating my navel yesterday I realized there was a
X	fairly simply way to work around the problems with open()
X	automatically truncating anything you passed it down to 14
X	characters, which was causing problems with trying to make
X	a solid determination on wheter or not the file was actually
X	compressed or not.  Now what I'm doing is first looking at
X	the basename of the filename as it looks in man.index.  If
X	that basename has too many characters in it then it is safe
X	to assume that whatever the compression program du jour
X	is that it could not append its suffix.  In this scenario
X	we just simply call the pager to display the file.  If
X	the filename is less than the maximum number of characters
X	now we attempt to do an open() on the filename.  If we're
X	successful, then the file is not compressed.  If we're
X	not successful we hope to god this is an indication that the
X	file is compressed. :-)  
X
X	Some additions were also made to man.h to better handle 
X	using an alternative decompression program.  ZMAN will still
X	depend on the decompression program being capable of 
X	writing to standard out, but now we no longer make the
X	assumption that the compression program will be simply
X	appeneding a two character suffix such as ".Z"
X	
X
Xv1.1 (10/07/92)
X===============
X
X	Adjusted the Makefile to accomodate portability to Coherent v3.X.
X	Apparently it doesn't like curly braces around macros.  So changed
X	all of the curly braces to parens.  Also updated README with the
X	new information concerning using ZMAN with v3.X.  Thanks to
X	mmcadams@speck.uucp for testing this.
X	
Xv1.1 (9/30/92)
X==============
X
X	Fixed a logic bug in the handling of search topics.  Prior
X	to today, hadn't realized that it was perfectly legal for there
X	to be more than one search topic with the same name.
X	v1.0 logic assumed there would only be one unique search topic and
X	would only display the first topic.  For example there are two
X 	references to "stty" in man.index.  The first is for the system
X 	call stty() and the second for the command "stty".
X	
Xv1.0 (9/23/92)
X==============
X
X	Initial development, only used for a week or so.
SHAR_EOF
chmod 0644 HISTORY || echo "restore of HISTORY fails"
echo "x - extracting TODO (Text)"
sed 's/^X//' << 'SHAR_EOF' > TODO &&
X10/11/1992
X==========
X
X	In a future release I would like to include the capability to
X	use more than one compression scheme at a time.  This it might
X	be possible to have some files in /bin/compress format, some
X	in ZIP format and others in something else.
SHAR_EOF
chmod 0644 TODO || echo "restore of TODO fails"
echo "x - extracting main.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > main.c &&
X/* ------------------------------[ main() ]-------------------------------- */
X
X#include "man.h"
X
X/*
X**  09/30/92 M. Faurot
X**
X**  Removed the logic to call show_man () from here and added it to
X**  find_man () so that it could deal with when there is more than
X**  one occurance of the same search topic with in man.index (ie, stty).
X**
X**  Ultimate handling of -w option also moved from here to find_man().
X*/
X
Xmain (argc, argv)
X
X	int	argc;
X	char	**argv;
X{
X	char	chArg;			/* temp var which holds cmd args */
X
X	short	shShowFile = FALSE;	/* default to not showing filename */
X	
X	extern int optind;		/* external int for getopt () */
X	extern char *optarg;		/* external pointer for getopt () */
X
X	register int iCounter;		/* generic counting variable */
X	
X	/*
X	**  Command line validity checking.  If the user has called
X	**  the program with no args, then we display the file
X	**  defined in HELP to the user.
X	*/
X	
X	if (argc <= 1) {
X		show_help ();
X		exit (1);
X	}
X		
X	/*
X	** Process options.  Check for valid command line arguments.
X	*/
X  	while ((chArg = getopt (argc, argv, "w")) != EOF) {
X    		switch (chArg) {
X    		case 'w':
X    			shShowFile = TRUE;
X	    		break;
X    			
X    		default:
X    			fprintf (stderr,
X    			"\nusage: %s [-w] topic...topicN\n\n", argv[0]);
X    			exit (1);
X    			break;
X		}
X	}
X
X	/*
X	**  Each argument after the option "-w" is considered to
X	**  be a search topic in the manual.  This loop processes
X	**  all of these arguments and either simply displays the
X	**  pathname of the man page itself (option -w) or displays
X	**  the appropriate man page to the user.
X	*/
X	for (iCounter = optind; iCounter < argc; iCounter++) {
X	
X		if (find_man (argv[iCounter], shShowFile)) {
X			fprintf (stderr,
X		       		"%s: %s not found in manual.\n",
X		         	argv[0],
X		         	argv[iCounter]);
X		}
X	}
X	
X	exit (0);
X
X}  /* main () */
SHAR_EOF
chmod 0644 main.c || echo "restore of main.c fails"
echo "x - extracting show_help.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > show_help.c &&
X/* --------------------------[ show_help () ]------------------------------ */
X
X#include "man.h"
X
Xvoid	show_help ()
X{
X	char	achPager[128];		/* Holds the name of screen pager */
X	char	achCmdLine[512];	/* cmd line passed off to system () */
X	char	*pachPager;		/* pointer to achPager */
X	
X	/*
X	**  Attempt to locate a user's preferance for a particular pager
X	**  via the environment variable PAGER, otherwise use the default
X	**  defined in the macro DEFAULT
X	*/
X	if ((pachPager = getenv ("PAGER")) == NULL ) {
X		strcpy (achPager, DEFAULT);
X		pachPager = achPager;
X	}
X
X	/*
X	**  Build the command line to hand off to system()
X	*/
X	sprintf ( achCmdLine,
X		  "%s %s",
X                  pachPager,
X                  HELP );
X                  
X	system (achCmdLine);
X		
X}  /* show_help () */
SHAR_EOF
chmod 0644 show_help.c || echo "restore of show_help.c fails"
echo "x - extracting split_rec.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > split_rec.c &&
X/* ----------------------------[ split_rec () ]--------------------------- */
X
X/*
X** split_rec () returns a 0 upon successfully splitting up the fields
X** in the index record into seperate filename and search strings.  It
X** returns a 1 to indicate and difficulties.
X*/
X
X#include "man.h"
X
Xint	split_rec (pachRecord, pachFileName, pachSearch)
X	char	*pachRecord,
X		*pachFileName,
X		*pachSearch;
X{
X	char	*pachBegin;	/* pointer to beginning of token */
X	
X	register int iCounter;	/* generic counting variable */
X	
X	/*
X	**  Pull out the filename portion from the record.  If
X	**  it can't be found, then return a 1
X	*/
X	pachBegin = strtok (pachRecord, "\t ");
X	if (pachBegin == NULL) {
X		return (1);
X	} else {
X		strcpy (pachFileName, pachBegin);
X	}
X
X	/*
X	**  Pull out the search string portion of the record.
X	**
X	**  I believe I've elaborated a little on the way in which
X	**  this portion of the record is handled.  This handles the
X	**  possibility that there may be a tab a space or more than
X	**  one tab or space between the filename and the search
X	**  string(s).  It also handles the details of deciding
X	**  if the search string is more than one word, and then putting
X	**  those words together (albeit still with spaces) .
X        */	
X	pachBegin = strtok (NULL, "\t \n");
X	if (pachBegin == NULL) {
X		return (1);
X	}
X
X	/*
X	**  After finding the first (and in many cases only) part
X	**  of the search string, we now check to see if there
X	**  are any other words up to the maximum number defined in
X	**  MAXTOK.  
X	*/
X	for (iCounter = 1; iCounter < MAXTOK && pachBegin != NULL;
X	     iCounter++) {
X	
X		if (iCounter == 1) {
X			strcpy (pachSearch, pachBegin);
X		} else {
X			strcat (pachSearch, " ");
X			strcat (pachSearch, pachBegin);
X		}
X		
X		pachBegin = strtok (NULL, "\t \n");
X	}
X
X	/*
X	**  Everything went okay, so we let the calling function know
X	**  this was the situation.
X	*/
X	return (0);
X	
X}  /* split_rec () */
SHAR_EOF
chmod 0644 split_rec.c || echo "restore of split_rec.c fails"
echo "x - extracting find_man.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > find_man.c &&
X/* ----------------------------[ find_man () ]--------------------------- */
X
X/*
X**  This function returns a 0 (FOUND) if it finds a matching search token in
X**  the INDEX file, otherwise it returns 1 (NOTFOUND) to indicate failure.
X*/
X
X/*
X**  09/30/92 M. Faurot
X**
X**  Changed second argument to find_man() to be a short which should
X**  be set to either a 1 or 0 to indicate whether or not we're dealing
X**  with a -w (show filename) option.  Previously this argument was
X**  a pointer to array of characters that used to return the full
X**  pathname of the appropriate man page file.
X**
X**  Moved the logic to call show_man() to this function from main()
X**  so that we can properly handle multiple (different) man pages
X**  which have the same search topic (ie, stty).
X*/
X
X
X
X#include "man.h"
X
Xint	find_man (pachTopic, shShowFile)
X	char	*pachTopic;
X	short	shShowFile;
X{
X	FILE	*fIndex;		/* file pointer to INDEX */
X	
X	char	achIdxRecord[MAX],	/* entire record from INDEX */
X		achFileToken[HALF],	/* filename portion of record */
X		achSearchToken[HALF];	/* search string portion of record */
X
X	char	achPathName[HALF];	/* full pathname of man page */
X
X	int	iFoundPage = NOTFOUND;	/* flag for if found page or not */
X
X	/*
X	**  Open INDEX for reading . . .
X	*/
X	if ((fIndex = fopen (INDEX, "r")) == NULL) {
X		perror (INDEX);
X		return (NOTFOUND);
X	}
X
X	/*
X	**  Priming read of INDEX
X	*/
X	fgets (achIdxRecord, MAX, fIndex);
X
X	while (!feof (fIndex)) {
X
X		/*
X		**  break-up the record into seperate filename and
X		**  search string tokens.
X		**  
X		**  Note: split_rec() destroys achIdxRecord in the
X		**        process of pulling the seperate tokens
X		**        from it.
X		*/
X		if (split_rec (achIdxRecord, achFileToken, achSearchToken)) {
X			goto skip;
X		} 
X
X		/*
X		**  Compare what we've got in achSearchToken
X		**  and see how it compares with what the user
X		**  supplied as their topic in pachTopic. 
X		*/
X		if ((strcmp (achSearchToken, pachTopic)) != 0) {
X			goto skip;
X		} else {
X			iFoundPage = FOUND;		 
X			
X			sprintf (achPathName, "%s/%s",
X				 MANDIR, achFileToken);
X
X			if (shShowFile) {
X				/*
X				**  Display file (-w option)
X				*/
X				printf ("%s\n", achPathName);
X			} else {
X				/*
X				**  Display the man page to the user
X				*/
X				show_man (achPathName);
X			}
X		}
X
X		/*
X		**  Read another record . . .
X		*/
X	skip: 	fgets (achIdxRecord, MAX, fIndex);
X	}
X
X	/*
X	**  Close the INDEX file.
X	*/
X	fclose (fIndex);
X
X	/*
X	**  Return if we actually found anything useful or not.
X	*/
X	return (iFoundPage);
X
X}  /* find_man () */
SHAR_EOF
chmod 0644 find_man.c || echo "restore of find_man.c fails"
echo "x - extracting show_man.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > show_man.c &&
X/* --------------------------[ show_man () ]------------------------------ */
X
X#include "man.h"
X
X/*
X**  10/11/92
X**  ========
X**
X**  1)  Changed the behaviour, after detecting that there's no slash
X**      (ie, '/') in the pathname to just simply displaying the error
X**	message, sleeping for 2 seconds and then returning.  Previously
X**      it was doing an exit(1).  This would have caused problems
X**      with displaying further man pages.  No reason to stop the
X**      whole show just cause of one bad apple.  
X**
X**  2)	We now dynamically figure out what the maximum filename size
X**      is instead of assuming it will be 13 and the decompression
X**      program will be zcat which uses a .Z suffix.
X**
X**  3)  Determination of #2 is now based upon the macros CATEXT and
X**      MAXNAME.  CATEXT is a string which holds the name of the suffix
X**      used by the decompression program (eg. .Z).  MAXNAME is the
X**      maximum number of characters that can be in a filename (eg 14).
X**
X**  4)	ZMAN can now work in the scenario where you might not want
X**      to compress some (all?) of your man pages.
X*/
X
Xvoid	show_man (pachManPage)
X	char	*pachManPage;
X{
X	char	achPager[128];		/* screen pager to use */
X	char	achCmdLine[HALF];	/* cmd line used by system() */
X	char	achName[HALF];		/* copy of pachManPage */
X	
X	char	*pachPager;		/* pointer to achPager */
X	char	*pachBaseName;		/* basename portion of pachManPage */
X
X	short	shMaxSize;		/* max filename without extension */
X
X	int	fdManPage;		/* file descriptor for manpage */
X
X	/*
X	**  Here we figure out what is the maximum length a filename
X	**  can have before a compression program will abort compressing
X	**  it because it can't append it's suffix.  For example the
X	**  maximum size a filename can have using compress is 13
X	**  characters.
X	*/
X	shMaxSize = MAXNAME - (strlen (CATEXT)) + 1;
X	
X	/*
X	**  Attempt to locate a user specified screen pager via the
X	**  environment variable PAGER, otherwise use the one defined
X	**  in DEFAULT.
X	*/
X	if ((pachPager = getenv ("PAGER")) == NULL ) {
X		strcpy (achPager, DEFAULT);
X		pachPager = achPager;
X	}
X
X	/*
X	**  Because of the 14 character filename limitations to
X	**  Coherent there may be some man pages that cannot be
X	**  "simply" converted into compress format because the
X	**  filename is already 13 or 14 characters and thus
X	**  a .Z may not be appended to the end.
X	**
X	**  I initially thought to just attempt to open the filename
X	**  via an fopen() or open() call and if it failed with
X	**  .Z appended to it, I could use that to make the determination
X	**  of wheter the filename was too long to get converted
X	**  but couldn't get that to work as it appears that the
X	**  fopen() and open() calls were both automatically truncating
X	**  anything I passed to it down to 14 characters.  For
X	**  example if I tryed to do an fopen() on callingconvent.Z
X	**  I'd have problems.  Even though there can be no filename
X	**  like this under Coherent, because of the 14 character
X	**  naming limitation, the fopen() works successfully, because
X	**  the filename "callingconvent" actually exists.  callingconvent
X	**  didn't get compressed because compress couldn't appened
X	**  a .Z onto it's end . . .
X	**
X	**  Rather than work myself up too much about this, I instead
X	**  figured I'd just look at the basename of the file.  If
X	**  the basename of the file is greater than or equal to
X	**  13 then it couldn't have been compressed.  Note: basename
X	**  is the basename of the file as defined in INDEX and should
X	**  not have a .Z appened onto it!
X	*/
X
X	strcpy (achName, pachManPage);
X	
X	if ((pachBaseName = strrchr (achName, '/')) == NULL) {
X		fprintf (stderr,
X		"\nFilename %s not in proper format.\n\n", pachManPage);
X		sleep (2);
X		return;
X	} else {
X		*(pachBaseName)++;	
X	}
X		
X	/*
X	**  This file couldn't be compressed so just run the pager
X	**  on the file directly instead of having CAT pipeline
X	**  the information to it.
X	*/
X	if (strlen (pachBaseName) >= shMaxSize) {
X	  	sprintf ( achCmdLine,
X			  "%s %s",
X       		          pachPager,
X			  pachManPage);
X	        /*
X       		**  Finally what we've all been waiting for! :-)
X       		*/
X		system (achCmdLine);
X		return;
X	}
X	
X	/*
X	**  Now that we're past the problem with open() returning
X	**  bogus information because it was truncating the file
X	**  length, let's try and open this file with CATEXT.
X	**  If we're successful, then hasn't been compressed
X	**  and we'll just run the pager on the file directly.  If
X	**  we're not successful then we know it "should" be
X	**  compressed.
X	*/
X	if ((fdManPage = open (pachManPage, O_RDONLY)) == -1) {
X	  	sprintf ( achCmdLine,
X			  "%s %s | %s",
X			  CAT,
X			  pachManPage,
X       		          pachPager);
X  	} else {
X	  	sprintf ( achCmdLine,
X			  "%s %s",
X       		          pachPager,
X			  pachManPage);
X  	}
X
X  	close (fdManPage);
X                  
X        /*
X        **  Finally what we've all been waiting for! :-)
X        */
X	system (achCmdLine);
X		
X}  /* show_man () */
SHAR_EOF
chmod 0644 show_man.c || echo "restore of show_man.c fails"
exit 0
-- 
+--------------------+-------------------------------------------------------+
|   Michael Faurot   | Domain: mfaurot@phzzzt.UUCP		             |
|   ------- ------   | UUCP: uunet!media!irscscm!bogart!phzzzt!mfaurot       |
+--------------------+-------------------------------------------------------+
Newsgroups: comp.os.coherent