home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume7
/
man.7300
/
man.c
next >
Wrap
C/C++ Source or Header
|
1989-07-21
|
8KB
|
276 lines
/***************************************************************************\
* File name: man.c *
* *
* Purpose: Provide a better user interface to read the manual *
* pages. *
* *
* Programmer: Gil Kloepfer, Jr. ICUS Software Systems *
* *
* Revision history: 8-Jun-89 0.1 Program created [Beta release] *
* 12-Jul-89 1.0 Program released
* *
* Restrictions: Requires Doug Gwyn's "dirent" subroutine package. *
* Optionally requires "compress" package, as well *
* as links to it called "zcat," and a text pager *
* such as "more." Having "nroff" is also a plus. *
* *
* Program has been tested on the UNIX-pc 3B1. It *
* should work on other systems, but this hasn't been *
* tested. *
* *
* Usage: Invoked from the shell or a script by: *
* $ man [section] command *
* *
* This manual page interface provides the following *
* features: *
* o You can "man" compressed manual pages *
* o You don't have to know if the manual *
* pages are unformatted (/usr/man/man?) *
* or formatted (/usr/man/cat?). *
* o You don't have to know what section *
* the manual page is in (and it tells you *
* which one) *
* o You get automatic paging when you *
* invoke man from a tty *
* *
* Compiled by: $ cc -v -O -o man man.c -ldirent -s *
* *
* Copyright/ (C) 1989 Gil Kloepfer, Jr., ICUS Software Systems *
* Disclaimer: All Rights Reserved *
* *
* Permission is granted to use, copy, or redistribute*
* this software provided that this header in its *
* entirety is kept in the source code, that all *
* copyright notices are left intact, and that it is *
* not distributed or used for monetary gain of any *
* kind without the express, written permission of *
* the copyright holder(s). Furthermore, if this *
* software is modified, all changes should be mailed *
* to icus!gil. *
* *
* The user of this program agrees and understands *
* that this software is distributed on an "as-is" *
* basis, and shall not use this program as the basis *
* for any claims, now or in the future, against *
* any individual, organization, or entity. *
\***************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#define PROCD "/usr/man/cat" /* dir prefix for preformatted pages */
#define NPROCD "/usr/man/man" /* dir prefix for nroff format pages */
#define MAXPATH 128 /* maximum size of path to man page */
/* undefine any of the following if your system doesn't have them */
#define TYPECOMP "/usr/bin/zcat" /* command to display a compressed file */
#define FORMAT "/usr/bin/nroff -man" /* command to format a manual page */
#define PAGER "/usr/bin/more" /* system command to page a file */
/* Don't play with these constants!! */
#define C_PROC 1
#define C_NPROC 2
main(argc,argv)
int argc;
char *argv[];
{
int argno, section, kind, lookup();
char command[20], pagename[MAXPATH];
/* Process the command line arguments */
switch(argc) {
case 2: /* just the command name */
strncpy(command,argv[1],20);
section=0;
break;
case 3: /* the section and command name */
sscanf(argv[1], "%d", §ion);
strncpy(command,argv[2],20);
break;
default: /* invalid .. display the usage statement */
fprintf(stderr,"usage: %s [section] command\n", argv[0]);
exit(1);
}
/*
* If the section is not specified explicitly, try to find
* the manual page in the first directory where it's encountered.
*/
if (section == 0) {
for (section=1; section<=8; section++)
if (lookup(command,section,pagename,&kind)) {
fprintf(stderr,"%s: assuming %s from section %d\n",
argv[0], command, section);
printpage(pagename,kind);
exit(0);
}
fprintf(stderr,"%s: cannot find %s in the manual\n",
argv[0], command);
exit(2);
}
/*
* If the user specified a section, then see if we can find it
* there .. if so, print the page
*/
if (lookup(command,section,pagename,&kind)) {
printpage(pagename,kind);
exit(0);
} else {
fprintf(stderr,"%s: cannot find %s in section %d\n",
argv[0], command, section);
exit(2);
}
}
/*
* Function lookup returns 0 on failure and 1 on success. It will look
* through the directories for section and try to find the manual page
* for command. If it finds it, the entire filename is returned as
* pagename. "kind" passes along whether the name was found in the
* processed or unprocessed directory phases
*/
int lookup(command,section,pagename,kind)
char *command, *pagename;
int section, *kind;
{
int passno, cmpman();
char fullpath[MAXPATH];
DIR *mdir;
struct dirent *dentry;
/*
* Look through the formatted directory first to see if we
* can get one that's formatted. The second pass gets
* the formatted directory. This looks kludgy, but it's
* pretty neat nevertheless.
*/
for (passno=1; passno<=2; passno++) {
switch(passno) {
case 1: /* check formatted directory */
sprintf(fullpath, "%s%d", PROCD, section);
*kind = C_PROC;
break;
case 2: /* check unformatted directory */
sprintf(fullpath, "%s%d", NPROCD, section);
*kind = C_NPROC;
break;
}
if ((mdir=opendir(fullpath)) != NULL)
while ((dentry=readdir(mdir)) != NULL)
if (cmpman(dentry->d_name,command) == 0) {
closedir(mdir);
sprintf(pagename, "%s/%s", fullpath,
dentry->d_name);
return(1);
}
closedir(mdir);
}
return(0);
}
/*
* Compare name with command and see if it matches before the period
* so we can crown it the matching manual page for command
*/
int cmpman(name,command)
char *name, *command;
{
while ((*name == *command) && *name != '\0' && *command != '\0') {
name++;
command++;
}
if (*name == '.' && *command == '\0') return(0); /* OK */
if (*command == *name) return(0); /* also OK */
return(1); /* all other cases fail */
}
/*
* Printpage prints a manual page. It formats the page depending on
* where it comes from, and invokes the system pager depending on
* whether output is to a tty or a file/pipe
*/
printpage(pageloc,form)
char *pageloc;
int form;
{
int compress, endstr, ttypage;
char cmdline[512];
/* See if we're dealing with a compressed file (.Z) */
endstr=strlen(pageloc);
if (pageloc[endstr-2]=='.' && pageloc[endstr-1]=='Z')
compress=1;
else
compress=0;
#ifndef TYPECOMP
if (compress) {
fprintf(stdout,"%s: compressed files not supported\n",
argv[0]);
exit(2);
}
#endif
/* If we're a tty, page this using whatever our pager is */
#ifdef PAGER
if (isatty(1))
ttypage=1;
else
ttypage=0;
#else
ttypage=0;
#endif
/*
* Setup command line. This is some really sick code, but
* how else are we to do it? I can think of only one way, but
* it's kind of wasteful of system resources...
*/
if (compress) {
if (form == C_NPROC)
sprintf(cmdline, "%s %s | %s", TYPECOMP, pageloc, FORMAT);
else
sprintf(cmdline, "%s %s", TYPECOMP, pageloc);
} else {
if (form == C_NPROC)
sprintf(cmdline, "%s %s", FORMAT, pageloc);
else
sprintf(cmdline, "/bin/cat %s", pageloc);
}
if (ttypage) {
strcat(cmdline," | ");
strcat(cmdline,PAGER);
}
/* Invoke command */
system(cmdline);
}