broome@ucbvax.ARPA (Jonathan C. Broome) (08/28/85)
[ cat this file onto the end of the previous part ] { struct stat st; long time; FILE *fp; extern int use_more; register int ch, pid; if (israw) strcpy (cat, man); else { stat (man, &st); time = st.st_mtime; if (stat (cat, &st) < 0 || st.st_mtime < time || st.st_size == 0) { fprintf (stderr, "Reformatting page. Wait ... "); (void) fflush (stderr); if (format (man, cat)) { fprintf (stderr, "aborted (sorry)\n"); return (0); } fprintf (stderr, "done.\n"); } } if (!use_more) { if ((fp = fopen (cat, "r")) == NULL) return (0); while ((ch = getc (fp)) != EOF) putchar (ch); fclose (fp); } else { if ((pid = fork()) == 0) { #ifdef SETUID setuid (getuid ()); #endif execlp (pager, pager, "-s", cat, 0); perror (pager); _exit (1); } else { while (wait (0) != pid) ; } } return (1); } /* * Format the man page, placing the output into `cat'. */ format (man, cat) char *man, *cat; { int fd, pid; union wait status; if ((fd = creat (cat, 0644)) < 0) /* cannot create output file */ return (1); if ((pid = fork()) == 0) { /* child */ dup2 (fd, 1); execl (NROFF, "nroff", "-man", man, 0); perror ("exec"); _exit (1); } else if (pid > 0) { while (wait (&status) != pid) ; if (status.w_coredump) { (void) unlink ("core"); return (1); } if (status.w_status != 0) return (1); return (0); } return (1); } /* * Get the MANPATH environment variable and turn it * into a set of strings in an array so we can use it. */ getpath (manpath) char *manpath[]; { char **ap; char *getenv(); char *env; if ((env = getenv ("MANPATH")) == (char *) 0) #ifdef LOCAL env = "/usr/man"; /* give them the default local path */ #else return (0); #endif ap = manpath; while (*env) { *ap = env; while (*env) { if (*env == ':') { *env++ = '\0'; break; } env++; } if (*ap < env) ap++; } *ap = (char *) 0; return (ap - manpath); } !Funky!Stuff! if test 6792 -ne "`wc -c < 'dolocal.c'`" then echo shar: error transmitting "'dolocal.c'" '(should have been 6792 characters)' fi fi # end of overwriting check echo shar: extracting "'response.c'" '(886 characters)' if test -f 'response.c' then echo shar: will not over-write existing file "'response.c'" else cat << \!Funky!Stuff! > 'response.c' #ifndef lint static char RCSid[] = "$Header: response.c,v 1.2 85/07/06 16:55:32 broome Exp $"; #endif /* * $Log: response.c,v $ * Revision 1.2 85/07/06 16:55:32 broome * * */ #include <stdio.h> response () { extern FILE *sock_rp; char line[128]; for ( ;; ) { fgets (line, 128, sock_rp); if (strncmp (line, "141", 3) == 0) /* don't want to print the \r\n */ fprintf (stderr, "Reformatting page. Wait ... "); else if (line[0] != '2') /* not a positive response */ fprintf (stderr, line+4); (void) fflush (stderr); /* we're line buffered, so have to flush */ if (line[3] == ' ') /* end of text */ if (line[0] == '2') /* good response */ return (0); else /* not so good */ return (1); } } !Funky!Stuff! if test 886 -ne "`wc -c < 'response.c'`" then echo shar: error transmitting "'response.c'" '(should have been 886 characters)' fi fi # end of overwriting check echo shar: extracting "'server.c'" '(3018 characters)' if test -f 'server.c' then echo shar: will not over-write existing file "'server.c'" else cat << \!Funky!Stuff! > 'server.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: server.c,v 1.9 85/08/27 15:20:00 broome Exp $"; #endif /* * $Log: server.c,v $ * Revision 1.9 85/08/27 15:20:00 broome * Added copyright/distribution comment. * * Revision 1.8 85/08/27 15:05:04 broome * * * Revision 1.7 85/08/09 16:10:37 broome * Added #ifdef'ed code to ask for alternate machine type, define TYPE to * compile it in, i.e. "-DTYPE=\"sun\"" to cc. * * Revision 1.6 85/08/03 02:38:04 broome * * Revision 1.5 85/07/31 09:32:43 broome * Changed to set errno to EHOSTDOWN when the connection times out, always * returns instead of exiting on errors... * * Revision 1.4 85/07/16 11:11:29 broome * Rewritten to use the routines to ping all possible servers. * * Revision 1.3 85/07/04 19:59:09 broome * * Revision 1.2 85/07/02 21:05:25 broome * * Revision 1.1 85/06/25 11:22:58 broome * Initial revision */ #include <stdio.h> #include <netdb.h> #ifndef PORT #define PORT 9535 #endif /* * Open a socket to the specified host. */ open_server () { extern FILE *sock_rp, *sock_wp; extern char *type; #ifdef SERVICES struct servent *serv; #endif char buf[132]; int sock, port; #ifdef SERVICES /* listed in /etc/services */ if ((serv = getservbyname ("man", "tcp")) == NULL) { fprintf (stderr, "Unknown service: man/tcp\n"); exit (1); } port = serv->s_port; #else SERVICES port = htons (PORT); #endif SERVICES if ((sock = get_host (port)) == -1) return (-1); /* ** Create a pair of buffered descriptors to the socket ** so that we can use stdio ``fprintf'' and the like. */ sock_wp = fdopen (sock, "w"); sock_rp = fdopen (sock, "r"); fgets (buf, 128, sock_rp); /* get the banner line */ if (strncmp (buf, "210", 3)) { /* bad response code */ close (sock); fprintf (stderr, "%s", buf+4); return (-1); } #ifdef TYPE fprintf (sock_wp, "type %s\r\n", TYPE); /* ask for alternate cpu type */ fgets (buf, 128, sock_rp); /* get (and trash) response */ #endif TYPE if (type) { /* they specified a machine type */ fprintf (sock_wp, "type %s\r\n", type); (void) fflush (sock_wp); fgets (buf, 128, sock_rp); if (strncmp (buf, "223", 3)) fprintf (stderr, "%s", buf+4); } return (sock); } !Funky!Stuff! if test 3018 -ne "`wc -c < 'server.c'`" then echo shar: error transmitting "'server.c'" '(should have been 3018 characters)' fi fi # end of overwriting check echo shar: extracting "'man.1'" '(6856 characters)' if test -f 'man.1' then echo shar: will not over-write existing file "'man.1'" else cat << \!Funky!Stuff! > 'man.1' .TH MAN 1 "3 August 1985" .UC 4 .SH NAME man \- find manual information by keywords; print out the manual .SH SYNOPSIS .br \fBman\fP [ \- ] [ \-r ] [ \-t type ] [ \fBsection\fP ] \fBtitle\fP ... .br \fBman\fP \-a | \-f [ \-m ] \fBfile\fP .br \fBman\fP \-k | \-w [ \-m ] \fBkeyword\fP .SH DESCRIPTION \fIMan\fP is a program which uses the local area network and a remote server process to retrieve information from the online programmer's manual. It can be asked for one line descriptions of commands specified by name, or for all commands whose description contains any of a set of keywords. It can also provide on-line access to the sections of the printed manual. .SH OPTIONS When given one of the \fI\-k\fP or \fI\-w\fP options and a set of keywords, \fIman\fP prints out a one line synopsis of each manual sections whose listing in the table of contents contains one of those keywords. This is identical in operation to the \fIwhatis\fP command. .PP When given one of the options \fI\-a\fP or \fI\-f\fP and a list of file names, \fIman\fR will attempt to locate manual sections appropriate to those files, printing out the table of contents lines for those sections. This is similar to the \fIapropos\fP command. .PP When none of \fI\-a\fP, \fI\-f\fP, \fI\-k\fP, or \fI\-w\fP is specified, \fIman\fP will search for and print the specified set of manual pages, reformatting pages if they are out of date. If a section specifier is given then \fIman\fP will look in the that section of the manual for the named \fItitles\fP. \fISection\fP may be either an Arabic section number (3 for instance), or a name, typically one of the words ``new'', ``local'', ``old'', or ``public''. The first letter, i.e. \fIn\fP, \fIl\fP, \fIo\fP, or \fIp\fP, respectively, can also be used. A section \fInumber\fP may followed by a single letter classifier to restrict the search to a single category within the section (for instance, 1g, indicating a graphics program in section 1). If \fIsection\fP is omitted, \fIman\fP searches all sections of the manual, giving preference to commands over subroutines in system libraries, and printing the first section it finds, if any. .PP The \fI\-t\fP option can be used to specify the machine \fItype\fP that should be used when searching for any machine-specific pages, overriding the actual type of the current host. .PP When using \fIman\fP to view the manual pages (the default mode) with standard output to a terminal, \fIman\fP will use \fImore\fP as an output pagination filter, with the \fI\-s\fP option to crush out multiple blank lines. The \fI\-m\fP flag can be used with the \fI\-a\fP, \fI\-f\fP, \fI\-k\fP, \fI\-w\fP, and \fI\-r\fP options to force the use of \fImore\fP when in one of these modes. Likewise, the \fI\-\fP option tells \fIman\fP to \fBnot\fP use \fImore\fP. The environment variables `MANPAGER' and `PAGER' can be used to name the paginator to use (instead of \fImore\fP). \fIMan\fP will duplicate the shell's method of searching for the command, so a full pathname need not be specified. Note that the specified paginator should understand (or at least ignore) the \fI\-s\fP option that is normally passed to \fImore\fP. .PP The \fI\-r\fP flag causes \fIman\fP to produce the raw (unformatted) set of pages to standard output, suitable for input to \fItroff\fP with the \fI\-man\fP macros; see \fItroff\fP (1). .SH SEARCH STRATEGY \fIMan\fP first searches the local man directory (typically /usr/man/manl) for a local version of the requested \fItitle\fP, then if the desired page has not been located, \fIman\fP will ask the remote server for the \fItitle\fP, initiating a network connection if one has not already been made. .br If the shell environment variable \fIMANPATH\fP is set, \fIman\fP will search each directory listed there (instead of the default) for the named \fItitle\fP, reformatting pages if needed. \fIMANPATH\fP should be a set of colon-separated directory names, like ``/usr/cad/man:~/man'', each of which is the root of a subtree of ``man?'' and ``cat?'' directories. Note that this variable completely overrides searching of the standard \fI/usr/man\fP directory, so you if you still want /usr/man to be searched, you must include it in your \fIMANPATH\fP. Remote searching will still occur if the local search is unsuccessful. .SH REMOTE OPERATION \fIMan\fP uses a remote manual page daemon (\fImand\fP) running on a strategically-placed server host, allowing an entire local network to share one copy of the manual pages. This is beneficial in several areas, primarily in the savings in disk space (up to 20 megabytes per host!), and the ease of updating pages without needing to distribute to numerous hosts. .PP The decision as to which server to connect to (assuming that several are available) is made by first `pinging' each known server host on a relatively inexpensive datagram socket, then waiting for responses indicating a host's load average and willingness to be a server. A stream socket connection is then made to the one with the lowest load. This simple protocol may need to be augmented in the future as the number of clients increases with the profusion of workstations, due to the possibility of one host being bombarded with many requests at the same time. Currently, the only protection that a host has against this is a load cutoff that may be set. Another possible addition is to send the name of the page desired when `pinging', so that a server may indicate whether it has the page in formatted form when responding. Unfortunately, no suitable method for doing this has been established without entailing considerable overhead. .PP The protocol used by the \fImand\fP is similar to that used by the smtp server (\fIsendmail\fP), using a set of requests and three-digit response codes. For further information, consult the manual entry for \fImand\fP(8). .SH FILES .nf .ta \w'/usr/man/man?/* 'u /usr/man standard manual area (on remote host) /usr/man/man?/* directories containing source for manuals /usr/man/cat?/* directories containing preformatted pages /usr/man/whatis keyword database /tmp/man.$$ temporary man file .fi .SH DIAGNOSTICS "cannot connect to server" - the network is down, the selected host went down, or the host is not running a server process. .br "lost connection to remote host" - the server died, or the host went down. .SH BUGS The manual is supposed to be reproducible either on the phototypesetter or on a typewriter. However, on a typewriter some information is necessarily lost. .br When using \fImore\fP, the percentage values at the bottom of the screen are usually off due to \fImore\fP being invoked while the file is still being transferred. .SH AUTHOR Jonathan C. Broome (broome@ucb-vax.berkeley.edu) .SH SEE\ ALSO apropos(1), more(1), whereis(1), catman(8), mand(8) !Funky!Stuff! if test 6856 -ne "`wc -c < 'man.1'`" then echo shar: error transmitting "'man.1'" '(should have been 6856 characters)' fi fi # end of overwriting check echo shar: extracting "'getmore.c'" '(2628 characters)' if test -f 'getmore.c' then echo shar: will not over-write existing file "'getmore.c'" else cat << \!Funky!Stuff! > 'getmore.c' #ifndef lint static char RCSid[] = "$Header: getmore.c,v 1.5 85/08/27 15:04:44 broome Exp $"; #endif /* * $Log: getmore.c,v $ * Revision 1.5 85/08/27 15:04:44 broome * Final cleanup before sending out. * * Revision 1.4 85/08/03 02:35:50 broome * Changed to use buffered i/o on the temp file - fewer system calls that way. * * Revision 1.3 85/07/13 16:07:14 broome * Fixed for installations where man is setuid to root. * * Revision 1.2 85/07/04 20:18:13 broome */ #include <stdio.h> #define eq(a,b) (strcmp (a, b) == 0) /* * Get the text from the socket into the temp file * and invoke ``more''. */ getmore () { extern char fname[]; /* name of temp file */ extern FILE *tfp; /* temp file pointer */ extern FILE *sock_rp; /* socket read pointer */ extern char *pager; /* name of output paginator */ char line[BUFSIZ]; /* input buffer */ int pid; /* pid of `more' subprocess */ int lines; /* number of lines fetched */ int more = 1; /* more lines left to fetch */ fseek (tfp, 0L, 0); /* rewind the temp file */ ftruncate (fileno (tfp), 0L); /* and zap the contents */ /* * We get the first 66 lines (one page) into the temp * file before forking and invoking more on the temp file. */ for (lines = 0; lines < 66; lines++) { /* get the first page or so */ fgets (line, BUFSIZ, sock_rp); if (eq (line, ".\r\n")) { /* end of the file */ more = 0; break; } (void) fputs (line, tfp); } (void) fflush (tfp); /* * We now have the first screenful, so start up more.. */ switch (pid = fork ()) { case -1: perror ("cannot fork"); return; case 0: #ifdef SETUID setuid (getuid ()); /* running as root? */ #endif execlp (pager, pager, "-s", fname, 0); perror (pager); return; default: if (more) /* still have more lines to fetch */ while (fgets (line, BUFSIZ, sock_rp)) { if (eq (line, ".\r\n")) break; (void) fputs (line, tfp); if (++lines % 5 == 0) /* flush every 5 lines */ (void) fflush (tfp); } while (wait (0) != pid) ; } } !Funky!Stuff! if test 2628 -ne "`wc -c < 'getmore.c'`" then echo shar: error transmitting "'getmore.c'" '(should have been 2628 characters)' fi fi # end of overwriting check echo shar: extracting "'rman.1'" '(6880 characters)' if test -f 'rman.1' then echo shar: will not over-write existing file "'rman.1'" else cat << \!Funky!Stuff! > 'rman.1' .TH RMAN 1 "3 August 1985" .UC 4 .SH NAME rman \- find manual information by keywords; print out the manual .SH SYNOPSIS .br \fBrman\fP [ \- ] [ \-r ] [ \-t type ] [ \fBsection\fP ] \fBtitle\fP ... .br \fBrman\fP \-a | \-f [ \-m ] \fBfile\fP .br \fBrman\fP \-k | \-w [ \-m ] \fBkeyword\fP .SH DESCRIPTION \fIRman\fP is a program which uses the local area network and a remote server process to retrieve information from the online programmer's manual. It can be asked for one line descriptions of commands specified by name, or for all commands whose description contains any of a set of keywords. It can also provide on-line access to the sections of the printed manual. .SH OPTIONS When given one of the \fI\-k\fP or \fI\-w\fP options and a set of keywords, \fIrman\fP prints out a one line synopsis of each manual sections whose listing in the table of contents contains one of those keywords. This is identical in operation to the \fIwhatis\fP command. .PP When given one of the options \fI\-a\fP or \fI\-f\fP and a list of file names, \fIrman\fR will attempt to locate manual sections appropriate to those files, printing out the table of contents lines for those sections. This is similar to the \fIapropos\fP command. .PP When none of \fI\-a\fP, \fI\-f\fP, \fI\-k\fP, or \fI\-w\fP is specified, \fIrman\fP will search for and print the specified set of manual pages, reformatting pages if they are out of date. If a section specifier is given then \fIrman\fP will look in the that section of the manual for the named \fItitles\fP. \fISection\fP may be either an Arabic section number (3 for instance), or a name, typically one of the words ``new'', ``local'', ``old'', or ``public''. The first letter, i.e. \fIn\fP, \fIl\fP, \fIo\fP, or \fIp\fP, respectively, can also be used. A section \fInumber\fP may be followed by a single letter classifier to restrict the search to a single category within the section (for instance, 1g, indicating a graphics program in section 1). If \fIsection\fP is omitted, \fIrman\fP searches all sections of the manual, giving preference to commands over subroutines in system libraries, and printing the first section it finds, if any. .PP The \fI\-t\fP option can be used to specify the machine \fItype\fP that should be used when searching for any machine-specific pages, overriding the actual type of the current host. .PP When using \fIrman\fP to view the manual pages (the default mode) with standard output to a terminal, \fIrman\fP will use \fImore\fP as an output pagination filter, with the \fI\-s\fP option to crush out multiple blank lines. The \fI\-m\fP flag can be used with the \fI\-a\fP, \fI\-f\fP, \fI\-k\fP, \fI\-w\fP, and \fI\-r\fP options to force the use of \fImore\fP when in one of these modes. Likewise, the \fI\-\fP option tells \fIrman\fP to \fBnot\fP use \fImore\fP. The environment variables `MANPAGER' and `PAGER' can be used to name the paginator to use (instead of \fImore\fP). \fIRman\fP will duplicate the shell's method of searching for the command, so a full pathname need not be specified. Note that the specified paginator should understand (or at least ignore) the \fI\-s\fP option that is normally passed to \fImore\fP. .PP The \fI\-r\fP flag causes \fIrman\fP to produce the raw (unformatted) set of pages to standard output, suitable for input to \fItroff\fP with the \fI\-man\fP macros; see \fItroff\fP (1). .SH SEARCH STRATEGY \fIRman\fP first searches the local man directory (typically /usr/man/manl) for a local version of the requested \fItitle\fP, then if the desired page has not been located, \fIrman\fP will ask the remote server for the \fItitle\fP, initiating a network connection if one has not already been made. .br If the shell environment variable \fIMANPATH\fP is set, \fIrman\fP will search each directory listed there (instead of the default) for the named \fItitle\fP, reformatting pages if needed. \fIMANPATH\fP should be a set of colon-separated directory names, like ``/usr/cad/man:~/man'', each of which is the root of a subtree of ``man?'' and ``cat?'' directories. Note that this variable completely overrides searching of the standard \fI/usr/man\fP directory, so you if you still want /usr/man to be searched, you must include it in your \fIMANPATH\fP. Remote searching will still occur if the local search is unsuccessful. .SH REMOTE OPERATION \fIRman\fP uses a remote manual page daemon (\fImand\fP) running on a strategically-placed server host, allowing an entire local network to share one copy of the manual pages. This is beneficial in several areas, primarily in the savings in disk space (up to 20 megabytes per host!), and the ease of updating pages without needing to distribute to numerous hosts. .PP The decision as to which server to connect to (assuming that several are available) is made by first `pinging' each known server host on a relatively inexpensive datagram socket, then waiting for responses indicating a host's load average and willingness to be a server. A stream socket connection is then made to the one with the lowest load. This simple protocol may need to be augmented in the future as the number of clients increases with the profusion of workstations, due to the possibility of one host being bombarded with many requests at the same time. Currently, the only protection that a host has against this is a load cutoff that may be set. Another possible addition is to send the name of the page desired when `pinging', so that a server may indicate whether it has the page in formatted form when responding. Unfortunately, no suitable method for doing this has been established without entailing considerable overhead. .PP The protocol used by the \fImand\fP is similar to that used by the smtp server (\fIsendmail\fP), using a set of requests and three-digit response codes. For further information, consult the manual entry for \fImand\fP(8). .SH FILES .nf .ta \w'/usr/man/man?/* 'u /usr/man standard manual area (on remote host) /usr/man/man?/* directories containing source for manuals /usr/man/cat?/* directories containing preformatted pages /usr/man/whatis keyword database /tmp/rman.$$ temporary man file .fi .SH DIAGNOSTICS "cannot connect to server" - the network is down, the selected host went down, or the host is not running a server process. .br "lost connection to remote host" - the server died, or the host went down. .SH BUGS The manual is supposed to be reproducible either on the phototypesetter or on a typewriter. However, on a typewriter some information is necessarily lost. .br When using \fImore\fP, the percentage values at the bottom of the screen are usually off due to \fImore\fP being invoked while the file is still being transferred. .SH AUTHOR Jonathan C. Broome (broome@ucb-vax.berkeley.edu) .SH SEE\ ALSO apropos(1), more(1), whereis(1), catman(8), mand(8) !Funky!Stuff! if test 6880 -ne "`wc -c < 'rman.1'`" then echo shar: error transmitting "'rman.1'" '(should have been 6880 characters)' fi fi # end of overwriting check echo shar: extracting "'man.hosts'" '(500 characters)' if test -f 'man.hosts' then echo shar: will not over-write existing file "'man.hosts'" else cat << \!Funky!Stuff! > 'man.hosts' # Hosts that should be running servers. # Group them in the order to call, # we always grab the first one with # the lowest load average anyway. # Groups are separated by a blank line. # The primary servers 128.32.149.3 ucbseymour seymour 128.32.149.5 ucbbuddy buddy # Secondary servers 128.32.149.2 ucbzooey zooey 128.32.149.6 ucbfranny franny # And so on .... 128.32.5 ucbcad cad 128.32.132.1 ucbic ic 128.32.132.4 ucbsim sim 128.32.137.1 ucbcory cory 128.32.137.2 ucbholden-il holden-il !Funky!Stuff! if test 500 -ne "`wc -c < 'man.hosts'`" then echo shar: error transmitting "'man.hosts'" '(should have been 500 characters)' fi fi # end of overwriting check echo shar: done with directory "'client'" cd .. if test ! -d 'daemon' then echo shar: creating directory "'daemon'" mkdir 'daemon' fi echo shar: entering directory "'daemon'" cd 'daemon' echo shar: extracting "'Makefile'" '(3821 characters)' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else cat << \!Funky!Stuff! > 'Makefile' # # Makefile for manual server daemon 21 August 1985 # # Server (daemon) sources. HDRS = cmd.h defs.h response.h SRCS = apropos.c cat.c cmd.c config.c find.c format.c getline.c help.c \ identify.c main.c misc.c parse.c ping.c raw.c sections.c \ show.c showpath.c so.c stat.c type.c ver.c whatis.c OBJS = apropos.o cat.o cmd.o config.c find.o format.o getline.o help.o \ identify.o main.o misc.o parse.o ping.o raw.o sections.o \ show.o showpath.o so.o stat.o type.o version.o whatis.o DEST = mand MAN = mand.8 LPR = lpr # a few notes: # define SERVICES if you have "man" in /etc/services # use MODE = 2711 if the man directories are unwritable, else use MODE = 755 # set OWNER to the user who owns the man pages, usually root, sometimes "man" # KMEM needs to be the name of the group which can read /dev/kmem (for load avg) CFLAGS = -DSERVICES -O LFLAGS = -hbxa MODE = 711 OWNER = root KMEM = kmem # The help files should be in this directory. LIB = /usr/lib HELPFILE = ${LIB}/${DEST}.hf HOSTFILE = ${LIB}/${DEST}.hosts CONFIG = ${LIB}/${DEST}.cf .DEFAULT: co $< ${DEST}: ${OBJS} /bin/rm -f ${DEST} cc ${CFLAGS} -o ${DEST} ${OBJS} install: ${DEST} man install -c -m ${MODE} -o ${OWNER} -g ${KMEM} mand /etc/mand install -c -m 644 -o ${OWNER} mand.cf ${CONFIG} install -c -m 644 -o ${OWNER} mand.hf ${HELPFILE} install -c -m 644 mand.8 /usr/man/man8 @echo Don't forget to put "man" in /etc/services new: paths ${DEST} # need to recompile the ones with paths in them ... paths: -rm -f main.o help.o identify.o main.o: main.c cc ${CFLAGS} -c -DCONFIG=\"${CONFIG}\" main.c help.o: help.c cc ${CFLAGS} -c -DHELPFILE=\"${HELPFILE}\" help.c identify.o: identify.c cc ${CFLAGS} -c -DHOSTFILE=\"${HOSTFILE}\" identify.c # Updates whenever any sources change version.o: $(SRCS) @csh -f newver.csh cc ${CFLAGS} -c version.c lint: ${DSRCS} lint ${LFLAGS} -DCONFIG=\"${CONFIG}\" -DHELPFILE=\"${HELPFILE}\" \ -DHOSTFILE=\"${HOSTFILE}\" ${SRCS} | egrep -v "pointer alignment" \ > lint.out shar: ${HDRS} ${SRCS} shar -v Makefile ${HDRS} ${SRCS} mand.cf mand.hf ${MAN} > mand.shar print: pr -f ${HDRS} ${SRCS} ${CONFIG} ${HELPFILE} | ${LPR} tags: ${SRCS} ${DSRCS} ctags -w ${SRCS} ${DSRCS} clean: rm -f *.o core depend: ${SRCS} mv Makefile makefile.old sed '/^# Dependencies follow/,$$d' makefile.old > Makefile @echo '# Dependencies follow' >> Makefile includes -so ${SRCS} >> Makefile @echo ' ' >> Makefile @echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile @echo '# see depend: above' >> Makefile # DO NOT DELETE THE FOLLOWING LINE # Dependencies follow ping.o: /usr/include/nlist.h ping.o: /usr/include/syslog.h main.o: /usr/include/signal.h main.o: /usr/include/sys/ttydev.h main.o: /usr/include/sys/ttychars.h main.o: /usr/include/sys/ioctl.h main.o: /usr/include/time.h main.o: /usr/include/sys/time.h identify.o: /usr/include/netdb.h ping.o main.o identify.o: /usr/include/netinet/in.h ping.o main.o identify.o: /usr/include/sys/socket.h main.o format.o: /usr/include/sys/wait.h show.o format.o find.o: /usr/include/sys/file.h cmd.o: ./cmd.h main.o cat.o: /usr/include/errno.h stat.o cat.o: /usr/include/sys/stat.h stat.o ping.o main.o identify.o cat.o: /usr/include/sys/types.h type.o stat.o showpath.o show.o sections.o raw.o misc.o identify.o find.o \ config.o cat.o: ./defs.h whatis.o ver.o type.o stat.o stat.o so.o showpath.o show.o sections.o raw.o \ raw.o misc.o misc.o main.o identify.o identify.o help.o getline.o format.o \ find.o config.o cmd.o cat.o cat.o apropos.o: /usr/include/stdio.h whatis.o type.o stat.o raw.o misc.o main.o help.o format.o cmd.o cat.o \ apropos.o: ./response.h # IF YOU PUT STUFF HERE IT WILL GO AWAY # see depend: above !Funky!Stuff! if test 3821 -ne "`wc -c < 'Makefile'`" then echo shar: error transmitting "'Makefile'" '(should have been 3821 characters)' fi fi # end of overwriting check echo shar: extracting "'config.c'" '(3908 characters)' if test -f 'config.c' then echo shar: will not over-write existing file "'config.c'" else cat << \!Funky!Stuff! > 'config.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: config.c,v 1.4 85/08/27 18:46:06 broome Exp $"; #endif /* * $Log: config.c,v $ * Revision 1.4 85/08/27 15:16:26 broome * Last cleanup before release. * * Revision 1.3 85/08/04 16:31:12 broome * Rewrote most of the code to make it much less obscure, also faster. * * Revision 1.2 85/07/06 16:56:24 broome * * Revision 1.1 85/07/05 18:19:16 broome * Initial revision */ #include "defs.h" /* * Read in the configuration file, parse into sections and suffixes. */ config (file) char *file; { FILE *fp; char line[512]; char **argv = (char **) 0; int d = 0; int s; int iscont; int suffs; /* number of suffixes given */ SEC *sec = (SEC *) 0; SEC *seclast = (SEC *) 0; DIR *dir, *dirlast = (DIR *) 0; DIR *dup, *isdup(); if ((fp = fopen (file, "r")) == (FILE *) 0) { fprintf (stderr, "cannot open config file "); perror (file); exit (1); } while (getline (line, 512, fp)) { iscont = (*line == ' '); /* continuation line begins with a space */ if ((suffs = parse (line, &argv)) == 0) continue; if (streql (argv[0], "type") == 0) { /* beginning of new cpu type */ addtype (argv[1]); /* save the pointers */ continue; } if (!iscont) { /* not a continuation line - need new section */ if (sec) sec->dirs[d] = (DIR *) 0; /* null-term last list of dirs */ d = 0; sec = (SEC *) malloc (sizeof (SEC)); /* malloc section */ if (sections == (SEC *) 0) /* and add to list */ sections = sec; /* first one? */ else seclast->next = sec; sec->next = (SEC *) 0; /* nothing after it */ seclast = sec; /* keep track of last one in list */ sec->name = strsave (*argv++); /* save this section name */ suffs--; } if (dup = isdup (*argv)) { /* this element already exists */ sec->dirs[d++] = dup; /* point section to existing dir */ continue; } dir = (DIR *) malloc (sizeof (DIR)); dir->man = strsave (*argv++); dir->cat = strsave (*argv++);