allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (07/22/89)
Posting-number: Volume 7, Issue 91 Submitted-by: gil@limbic.UUCP (Gil Kloepfer Jr.) Archive-name: man.7300 [Note that this has also been posted to unix-pc.sources] [[Crossposting between unmoderated and moderated groups is discouraged in general. ++bsa]] Here is a utility that I hacked for my UNIX-pc without a decent man(1) utility. I've heard that some others are also missing this utility, or have a braindamaged one. I'm passing it along to comp.sources.misc in case others have a use for it. I've only tested it on my UNIX-pc, but it should work with little or no changes on most unices (plural of unix?). Note that to link the program, you'll need Doug Gwyn's dirent package, previously posted to the net. All other information is in the README file, packaged with the shar. ======== | Gil Kloepfer, Jr. | ICUS Software Systems/Bowne Management Systems (depending on where I am) | ...icus!limbic!gil or gil@icus.islp.ny.us #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: README man.c # Wrapped by gil@limbic on Wed Jul 12 13:21:43 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f README -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"README\" else echo shar: Extracting \"README\" \(2273 characters\) sed "s/^X//" >README <<'END_OF_README' XREADME file for man v1.0 -- Last updated 7/12/89 X XThe following is my interpretation of the UNIX "man" command. Although Xit isn't very robust, it does handle some very useful cases which occur Xwhen trying to get stored manual pages, such as: X X[from the source] X X o You can "man" compressed manual pages X o You don't have to know if the manual X pages are unformatted (/usr/man/man?) X or formatted (/usr/man/cat?). X o You don't have to know what section X the manual page is in (and it tells you X which one) X o You get automatic paging when you X invoke man from a tty X X XI didn't bother with a makefile since there is only one source file Xhere. It compiles by: X X $ cc -O -o man man.c -ldirent -s X XUse whatever other favorite options you like. Install it in /usr/local/bin Xor /usr/lbin (whichever you use on your system). It does not require any Xs-bits to be set. X XIMPORTANT NOTE: As noted above, this requires that Doug Gwyn's "dirent" Xsubroutine library be installed. I didn't include it with this distribution! XIf you require it, drop me a note. If I get enough notes, I'll repost the Xsource. X XCONFIGURATION HINTS: In the source there are 3 "#define"s which define Xthe pager, compressed file "cat" program, and the name of your nroff Xprogram. These should be defined however you like them, or undefined if Xyou don't have them. There are two "#define"s which define where the Xmanual pages are located -- in /usr/man/man? and /usr/man/cat? . Set Xthese to the way your system is configured. X XOne more bit of background-- as you might notice from some of the code, Xthis program was a bit of a hack. I was tired of not having "man" work Xthis way, so I hacked this up quickly. There were several individuals Xinterested in the program, so I decided to post it. In any event, if Xyou think it needs more functionality or should be modified to do a Xparticular thing differently, don't complain to me about it. Make the Xchange and send me the diffs so I can get some patches on the net and Xeveryone can benefit! X XAlso note that the code has only been tested and used on my UNIX-pc, but Xit seems that it should run under almost any Unix environment. X XHope this is of use to lots of you. X X XGil Kloepfer, Jr. ICUS Software Systems X...!icus!limbic!gil END_OF_README if test 2273 -ne `wc -c <README`; then echo shar: \"README\" unpacked with wrong size! fi # end of overwriting check fi if test -f man.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"man.c\" else echo shar: Extracting \"man.c\" \(7578 characters\) sed "s/^X//" >man.c <<'END_OF_man.c' X/***************************************************************************\ X * File name: man.c * X * * X * Purpose: Provide a better user interface to read the manual * X * pages. * X * * X * Programmer: Gil Kloepfer, Jr. ICUS Software Systems * X * * X * Revision history: 8-Jun-89 0.1 Program created [Beta release] * X * 12-Jul-89 1.0 Program released X * * X * Restrictions: Requires Doug Gwyn's "dirent" subroutine package. * X * Optionally requires "compress" package, as well * X * as links to it called "zcat," and a text pager * X * such as "more." Having "nroff" is also a plus. * X * * X * Program has been tested on the UNIX-pc 3B1. It * X * should work on other systems, but this hasn't been * X * tested. * X * * X * Usage: Invoked from the shell or a script by: * X * $ man [section] command * X * * X * This manual page interface provides the following * X * features: * X * o You can "man" compressed manual pages * X * o You don't have to know if the manual * X * pages are unformatted (/usr/man/man?) * X * or formatted (/usr/man/cat?). * X * o You don't have to know what section * X * the manual page is in (and it tells you * X * which one) * X * o You get automatic paging when you * X * invoke man from a tty * X * * X * Compiled by: $ cc -v -O -o man man.c -ldirent -s * X * * X * Copyright/ (C) 1989 Gil Kloepfer, Jr., ICUS Software Systems * X * Disclaimer: All Rights Reserved * X * * X * Permission is granted to use, copy, or redistribute* X * this software provided that this header in its * X * entirety is kept in the source code, that all * X * copyright notices are left intact, and that it is * X * not distributed or used for monetary gain of any * X * kind without the express, written permission of * X * the copyright holder(s). Furthermore, if this * X * software is modified, all changes should be mailed * X * to icus!gil. * X * * X * The user of this program agrees and understands * X * that this software is distributed on an "as-is" * X * basis, and shall not use this program as the basis * X * for any claims, now or in the future, against * X * any individual, organization, or entity. * X\***************************************************************************/ X X#include <stdio.h> X#include <sys/types.h> X#include <dirent.h> X#include <sys/stat.h> X X#define PROCD "/usr/man/cat" /* dir prefix for preformatted pages */ X#define NPROCD "/usr/man/man" /* dir prefix for nroff format pages */ X#define MAXPATH 128 /* maximum size of path to man page */ X X/* undefine any of the following if your system doesn't have them */ X X#define TYPECOMP "/usr/bin/zcat" /* command to display a compressed file */ X#define FORMAT "/usr/bin/nroff -man" /* command to format a manual page */ X#define PAGER "/usr/bin/more" /* system command to page a file */ X X/* Don't play with these constants!! */ X#define C_PROC 1 X#define C_NPROC 2 X X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ X int argno, section, kind, lookup(); X char command[20], pagename[MAXPATH]; X X /* Process the command line arguments */ X X switch(argc) { X case 2: /* just the command name */ X strncpy(command,argv[1],20); X section=0; X break; X X case 3: /* the section and command name */ X sscanf(argv[1], "%d", §ion); X strncpy(command,argv[2],20); X break; X X default: /* invalid .. display the usage statement */ X fprintf(stderr,"usage: %s [section] command\n", argv[0]); X exit(1); X } X X /* X * If the section is not specified explicitly, try to find X * the manual page in the first directory where it's encountered. X */ X X if (section == 0) { X for (section=1; section<=8; section++) X if (lookup(command,section,pagename,&kind)) { X fprintf(stderr,"%s: assuming %s from section %d\n", X argv[0], command, section); X printpage(pagename,kind); X exit(0); X } X fprintf(stderr,"%s: cannot find %s in the manual\n", X argv[0], command); X exit(2); X } X X /* X * If the user specified a section, then see if we can find it X * there .. if so, print the page X */ X X if (lookup(command,section,pagename,&kind)) { X printpage(pagename,kind); X exit(0); X } else { X fprintf(stderr,"%s: cannot find %s in section %d\n", X argv[0], command, section); X exit(2); X } X} X X X/* X * Function lookup returns 0 on failure and 1 on success. It will look X * through the directories for section and try to find the manual page X * for command. If it finds it, the entire filename is returned as X * pagename. "kind" passes along whether the name was found in the X * processed or unprocessed directory phases X */ X Xint lookup(command,section,pagename,kind) Xchar *command, *pagename; Xint section, *kind; X{ X int passno, cmpman(); X char fullpath[MAXPATH]; X DIR *mdir; X struct dirent *dentry; X X /* X * Look through the formatted directory first to see if we X * can get one that's formatted. The second pass gets X * the formatted directory. This looks kludgy, but it's X * pretty neat nevertheless. X */ X X for (passno=1; passno<=2; passno++) { X switch(passno) { X case 1: /* check formatted directory */ X sprintf(fullpath, "%s%d", PROCD, section); X *kind = C_PROC; X break; X X case 2: /* check unformatted directory */ X sprintf(fullpath, "%s%d", NPROCD, section); X *kind = C_NPROC; X break; X } X X if ((mdir=opendir(fullpath)) != NULL) X while ((dentry=readdir(mdir)) != NULL) X if (cmpman(dentry->d_name,command) == 0) { X closedir(mdir); X sprintf(pagename, "%s/%s", fullpath, X dentry->d_name); X return(1); X } X X closedir(mdir); X } X return(0); X} X X X/* X * Compare name with command and see if it matches before the period X * so we can crown it the matching manual page for command X */ X Xint cmpman(name,command) Xchar *name, *command; X{ X while ((*name == *command) && *name != '\0' && *command != '\0') { X name++; X command++; X } X X if (*name == '.' && *command == '\0') return(0); /* OK */ X if (*command == *name) return(0); /* also OK */ X X return(1); /* all other cases fail */ X} X X X/* X * Printpage prints a manual page. It formats the page depending on X * where it comes from, and invokes the system pager depending on X * whether output is to a tty or a file/pipe X */ X Xprintpage(pageloc,form) Xchar *pageloc; Xint form; X{ X int compress, endstr, ttypage; X char cmdline[512]; X X /* See if we're dealing with a compressed file (.Z) */ X X endstr=strlen(pageloc); X if (pageloc[endstr-2]=='.' && pageloc[endstr-1]=='Z') X compress=1; X else X compress=0; X X#ifndef TYPECOMP X if (compress) { X fprintf(stdout,"%s: compressed files not supported\n", X argv[0]); X exit(2); X } X#endif X X /* If we're a tty, page this using whatever our pager is */ X X#ifdef PAGER X if (isatty(1)) X ttypage=1; X else X ttypage=0; X#else X ttypage=0; X#endif X X /* X * Setup command line. This is some really sick code, but X * how else are we to do it? I can think of only one way, but X * it's kind of wasteful of system resources... X */ X X if (compress) { X if (form == C_NPROC) X sprintf(cmdline, "%s %s | %s", TYPECOMP, pageloc, FORMAT); X else X sprintf(cmdline, "%s %s", TYPECOMP, pageloc); X } else { X if (form == C_NPROC) X sprintf(cmdline, "%s %s", FORMAT, pageloc); X else X sprintf(cmdline, "/bin/cat %s", pageloc); X } X X if (ttypage) { X strcat(cmdline," | "); X strcat(cmdline,PAGER); X } X X /* Invoke command */ X X system(cmdline); X} END_OF_man.c if test 7578 -ne `wc -c <man.c`; then echo shar: \"man.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of shell archive. exit 0