|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 9533 (0x253d)
Types: TextFile
Names: »rman.c«
└─⟦87ddcff64⟧ Bits:30001253 CPHDIST85 Tape, 1985 Autumn Conference Copenhagen
└─⟦this⟧ »cph85dist/rman/client/rman.c«
/*
* Copyright (c) 1985 Jonathan C. Broome and The Regents of the
* University of California.
*
* This software may be freely redistributed without licensing
* provided that this copyright notice remains intact and no profit
* is gained through any redistribution.
*
* Please report any bug fixes or modifications to the author at:
*
* broome@ucb-vax.berkeley.edu
* or:
* ...!ucbvax!broome
*
* The author and the Regents assume no liability for any damages
* or loss of revenue caused directly or indirectly by the use of
* this software.
*/
#ifndef lint
static char *RCSid = "$Header: rman.c,v 1.18 85/08/27 15:19:13 broome Exp $";
#endif
/*
* $Log: rman.c,v $
* Revision 1.18 85/08/27 15:19:13 broome
* Added copyright/distribution comment.
*
* Revision 1.17 85/08/27 15:04:52 broome
*
*
* Revision 1.16 85/08/05 22:14:53 broome
* Changed method for checking if an arg is a section name --
* cleaner and more reliable now ...
*
* Also changed local page lookup routine to check for MANPATH
* environment variable - list of dirs to search for pages.
*
* Revision 1.15 85/08/04 18:41:20 broome
*
* Revision 1.14 85/08/03 02:36:22 broome
* Changed to use buffered i/o on temp file, removed error message on
* bad options - acts more like the old "man" this way.
*
* Revision 1.13 85/07/31 09:31:28 broome
* Added "cantconnect" routine so that when EXEC_ON_ERROR is defined, it
* will fork and execl /usr/ucb/man for each page it needs. This is
* obviously only useful for testing purposes!
*
* Revision 1.12 85/07/30 18:51:59 broome
* Changed to avoid opening host connection until needed. This way
* local man pages can be found without needing a remote host.
*
* Revision 1.11 85/07/16 11:10:45 broome
* Added "-m" option to force use of more, "-" option now disables more,
* in keeping with the way the old "man" is set up.
*
* Revision 1.10 85/07/13 16:05:57 broome
* Added fix for setuid version of man.
*
* Revision 1.9 85/07/13 15:57:33 broome
* Incorporated "pinging" of remote hosts - great speed improvement!
*
* Revision 1.8 85/07/06 16:55:05 broome
* Ok, *now* it's ready.. Or is it???
*
* Revision 1.7 85/07/04 19:58:21 broome
* Separated into more logical routines, more error checking,
* follows the rfc ideas more closely.
*
* Revision 1.6 85/07/03 18:01:55 broome
* Fixed the '-' option (to force use of "more"), unfortunately breaks
* being able to specify multiple options in one arg.
*
* Revision 1.5 85/07/03 17:33:30 broome
* Trying to keep lint happy...
*
* Revision 1.4 85/07/02 21:03:49 broome
* Getting ready for beta test distribution (Kurt's machines)...
* Still needs a lot of cleaning in the server, but it works.
*
* Revision 1.3 85/07/02 13:03:28 broome
* New version, supports the '-k' and '-f' options.
*
* Revision 1.2 85/06/28 12:34:56 broome
* Added check for output to a tty, cleaned up w.r.t. lint.
*
* Revision 1.1 85/06/25 11:22:09 broome
* Initial revision
*/
#include <sys/file.h>
#include <stdio.h>
#include <signal.h>
#define eq(a,b) (strcmp (a,b) == 0)
/*
* Known sections. This method makes it easier to update...
*/
static char *sections[] = {
"1", "2",
"3", "4",
"5", "6",
"7", "8",
"cad", "c",
"local", "l",
"new", "n",
"old", "o",
"public", "p",
};
#define NUMSEC (sizeof (sections) / sizeof (char *))
#define MAN 1
#define APROPOS 2
#define WHATIS 3
#define RAW 4
#define MORE "more" /* use execlp to find it ... */
int mode = MAN;
int use_more = 0;
int verbose = 0;
int connected = 0;
int interrupt();
int sigpipe();
char *prog;
char *pager;
char fname[256];
char *type = (char *) 0;
FILE *sock_rp;
FILE *sock_wp;
FILE *tfp;
main (argc, argv)
int argc;
char *argv[];
{
char *section;
char *rindex();
char *getenv();
char *r;
if (r = rindex (*argv, '/')) /* what were we invoked as?? */
prog = ++r;
else
prog = *argv;
/*
* Process the command line.
*/
if (eq (prog, "apropos"))
mode = APROPOS;
else if (eq (prog, "whatis"))
mode = WHATIS;
while (*++argv && **argv == '-') {
switch ((*argv)[1]) {
case 'a':
case 'f': mode = APROPOS; break;
case 'w':
case 'k': mode = WHATIS; break;
case 'r': mode = RAW; break;
case 't': if (argv[1])
type = *++argv, argc--;
else
usage ();
break;
case 'v': verbose = 1; break;
case 'm': use_more = 1; break; /* force use of more */
case '\0': use_more = -1; break; /* force *not* use of more */
}
argc--;
}
if (argc <= 1)
usage ();
setlinebuf (stderr);
signal (SIGHUP, interrupt);
signal (SIGINT, interrupt);
signal (SIGQUIT, interrupt);
signal (SIGTERM, interrupt);
signal (SIGPIPE, sigpipe);
if (mode == MAN && !use_more) /* if not forced more and using `man' */
use_more = isatty (1);
if (use_more == 1) { /* set up temp file */
umask (0); /* should we do this when setuid? */
sprintf (fname, "/tmp/rman.%05d", getpid ());
if ((tfp = fopen (fname, "w")) == NULL) {
fprintf (stderr, "%s: cannot create temp file: ", prog);
perror (fname);
exit (1);
}
#ifdef SETUID
if (!geteuid ()) /* running as root */
(void) chown (fname, getuid (), -1);
#endif
if ((pager = getenv ("MANPAGER")) == (char *) 0) /* use ucb/more ?? */
if ((pager = getenv("PAGER")) == (char *) 0)
pager = MORE;
}
while (*argv) {
if (is_section (*argv))
section = *argv++;
else
section = (char *) 0;
if (section && !*argv) {
fprintf (stderr, "But what do you want from section %s?\n", section);
break;
}
doit (*argv++, section);
}
if (use_more)
unlink (fname);
if (connected)
fprintf (sock_wp, "quit\r\n");
exit (0);
}
doit (name, sec)
char *name, *sec;
{
static char *cmd = (char *) 0;
if (mode == MAN || mode == RAW) /* check for local pages first */
if (dolocal (name, sec, mode == RAW)) /* found it locally */
return;
/*
* Not connected yet, so try to connect to a server.
*/
if (!connected) {
if (open_server () == -1) {
cantconnect (name, sec);
return;
} else
connected = 1;
}
if (cmd == (char *) 0)
switch (mode) {
case MAN: cmd = "cat"; break;
case APROPOS: cmd = "apropos"; break;
case WHATIS: cmd = "whatis"; break;
case RAW: cmd = "raw"; break;
}
fprintf (sock_wp, "%s %s %s\n", cmd, sec, name); /* ask for a page */
(void) fflush (sock_wp);
if (response ()) /* bad response */
return;
if (use_more == 1)
getmore ();
else
getcat ();
}
/*
* Check to see if `arg' is a valid section name,
* return 1 if true, else 0.
*/
is_section (arg)
char *arg;
{
char *suffixes = "1234567890lnopc";
char suff;
int i, len, arglen;
arglen = strlen (arg);
suff = arg[arglen-1];
/*
* valid:
* exact match - strncmp (a,b,len) == 0 && len == arglen
* match for len of a, arglen == len-1, suff in suffixes.
*/
for (i = 0; i < NUMSEC; i++) {
len = strlen (sections[i]);
if (strncmp (arg, sections[i], len))
continue;
if (len == arglen) /* exact match */
return (1);
if ((arglen - 1) == len && index (suffixes, suff)) /* subsec */
return (1);
}
return (0);
}
/*
* Print a verbose usage message and exit.
*/
usage ()
{
if (eq (prog, "man") || eq (prog, "rman")) {
fprintf (stderr, "Usage: man [-r] [-t type] [-v] [ section ] command ...\n");
fprintf (stderr, " or: man -k | -w [-m] keyword\n");
fprintf (stderr, " or: man -a | -f [-m] file\n");
} else
fprintf (stderr, "%s what?\n", prog);
exit (1);
}
/*
* Come here on keyboard interrupt.
*/
interrupt ()
{
if (use_more)
(void) unlink (fname);
exit (1);
}
/*
* And come here on sigpipe.
*/
sigpipe ()
{
fprintf (stderr, "%s: lost connection to remote host.\n", prog);
if (use_more)
(void) unlink (fname);
exit (1);
}
/*
* Try to act intelligently when we can't connect to a server.
*/
/*ARGSUSED*/
cantconnect (name, sec)
char *name;
char *sec;
{
#ifdef EXEC_ON_ERROR
int pid;
if (verbose)
fprintf (stderr, "%s: processing locally.\n", prog);
if ((pid = fork ()) == -1) {
perror ("fork");
return (1);
} else if (pid == 0) {
if (sec)
execl ("/usr/ucb/man", prog, sec, name);
else
execl ("/usr/ucb/man", prog, name);
perror ("execl");
_exit (1);
}
while (wait (0) != pid)
;
#else
fprintf (stderr, "%s: cannot connect to server.\n", prog);
exit (1);
#endif
}