|
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 }