remote manual server/client source available - part 4 of 4
Jonathan C. Broome
broome at ucbvax.ARPA
Wed Aug 28 13:05:36 AEST 1985
[ this is the last part - cat them all together and feed to 'sh' ]
if (i = index (buf, '\t')) /* tabs separate name from info */
printf ("%d-%s\r\n", INFO_HELP, ++i);
found++;
}
if (found)
printf ("%d End of HELP info for \"%s\"\r\n", INFO_HELP, subj);
else
printf ("%d HELP topic \"%s\" unknown\r\n", ERR_NOHELP, subj);
fflush (stdout);
return (found != 0);
}
!Funky!Stuff!
if test 1708 -ne "`wc -c < 'help.c'`"
then
echo shar: error transmitting "'help.c'" '(should have been 1708 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'find.c'" '(3500 characters)'
if test -f 'find.c'
then
echo shar: will not over-write existing file "'find.c'"
else
cat << \!Funky!Stuff! > 'find.c'
#ifndef lint
static char RCSid[] = "$Header: find.c,v 1.4 85/08/27 15:16:36 broome Exp $";
#endif
/*
* $Log: find.c,v $
* Revision 1.4 85/08/27 15:16:36 broome
* Last cleanup before release.
*
* Revision 1.3 85/08/04 16:32:15 broome
* Increased efficiency by checking for directory existence before stat'ing
* each possible file name.
*
* Revision 1.2 85/07/06 16:56:18 broome
*
* Revision 1.1 85/07/05 18:19:13 broome
* Initial revision
*/
#include <sys/file.h>
#include "defs.h"
/*
* Take the name/section argument and try to
* find the corresponding files.
*/
struct where *
find (argc, argv)
int argc;
char *argv[];
{
static struct where wp;
SEC *sec;
DIR *dir;
int d;
bzero ((char *)&wp, sizeof (wp));
if (argc == 2) { /* section specified */
wp.section = strsave (argv[0]);
wp.name = strsave (argv[1]);
if (strlen (*argv) == 2) /* subsection kludge */
wp.subsec = (*argv)[1];
if (sec = find_section (*argv++)) {
for (d = 0; sec->dirs[d]; d++) /* check each dir pointed to */
if (checkpath (sec->dirs[d], *argv, &wp))
break;
}
} else {
wp.name = strsave (*argv);
/*
* Default action is to check all known
* directories and suffixes.
*/
for (dir = dirs; dir; dir = dir->next)
if (checkpath (dir, *argv, &wp))
break;
}
return (&wp);
}
/*
* Return a pointer to the section structure for the named section,
* Null pointer if not found.
*/
SEC *
find_section (name)
char *name;
{
register SEC *sec;
register int len = strlen (name);
for (sec = sections; sec; sec = sec->next) {
if (eq (name, sec->name))
return (sec);
if (len == 2 && strlen (sec->name) == 1) /* kludge for `man 3x foo' */
if (*name == *sec->name)
return (sec);
}
return ((SEC *) 0);
}
/*
* Given a filename and DIR pointer, see if a file exists whose name
* is the concatenation of the dir, name, and suffix.
*/
checkpath (dir, name, wp)
DIR *dir;
char *name;
struct where *wp;
{
char *suff;
int i;
if (wp->subsec) { /* forced subsection, don't search list */
char suf[10];
sprintf (suf, ".%s", wp->section);
return (docheck (dir, name, suf, wp));
}
if (access (dir->man, 0) == -1) { /* test for dir existence */
if (debug)
printf ("%s: No such directory.\n", dir->man);
return (0);
}
for (i = 0; suff = dir->suff[i]; i++) /* test each possible suffix */
if (docheck (dir, name, suff, wp))
return (1);
return (0);
}
/*
* Common code to check on one file.
*/
static
docheck (dir, name, suff, wp)
DIR *dir;
char *name;
char *suff;
struct where *wp;
{
char buf[256];
sprintf (buf, "%s/%s%s", dir->man, name, suff); /* full name of file */
if (debug) /* show file we are checking */
printf ("Checking %s\t", buf);
if (access (buf, R_OK) == -1) { /* doesn't exist */
if (debug)
printf ("not found.\n");
return (0);
}
if (debug)
printf ("found.\n");
wp->man = strsave (buf);
sprintf (buf, "%s/%s%s", dir->cat, name, suff); /* name of cat file */
wp->cat = strsave (buf);
wp->found = 1;
return (1);
}
!Funky!Stuff!
if test 3500 -ne "`wc -c < 'find.c'`"
then
echo shar: error transmitting "'find.c'" '(should have been 3500 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'mand.cf'" '(3633 characters)'
if test -f 'mand.cf'
then
echo shar: will not over-write existing file "'mand.cf'"
else
cat << \!Funky!Stuff! > 'mand.cf'
# Anatomy of a directory entry:
#
# 1 /usr/man/man1 /usr/man/cat1 .1,.1m,.1c .1g .1p .1r .1v
#
# "1" -- Section name to be used by users (ie. "man 1 ls")
# "/usr/man/man1" -- Directory to search for unformatted pages
# "/usr/man/cat1" -- Directory to look/place formatted pages in
# ".1,.1m,.1c" --- Suffixes to add to name, ie. "/usr/man/man1/ls.1"
#
# List all the sections by name, then the directories and suffixes
# continuation lines must begin with a *tab* character, suffixes
# may be separated by white space or commas, long lines may be continued
# by ending with a backslash character.
#
# If you want multiple names to apply to one directory or set of directories,
# you need to have multiple lines with (at least) the section name and the
# man directory. The configuration routine will assign both section names
# to each directory.
#
# Note that if you want to have several sections use the same man directory
# with *different* suffixes (ie /usr/man/man1 w/ ".1 .1c" and ".1 .1f"), then
# you need to use different *names* for the two directories --- like
# "/usr/man//man1" for one of them will do.
#
#name man dir cat dir suffixes
1 /usr/man/man1 /usr/man/cat1 .1,.1m,.1c .1g .1p .1r .1v
/usr/man/mann /usr/man/catn .n
/usr/man/manl /usr/man/catl .l
/usr/man/mano /usr/man/cato .o
n /usr/man/mann /usr/man/catn .n
new /usr/man/mann /usr/man/catn .n
l /usr/man/manl /usr/man/catl .l
local /usr/man/manl /usr/man/catl .l
6 /usr/man/man6 /usr/man/cat6 .6
8 /usr/man/man8 /usr/man/cat8 .8 .8v .8c
2 /usr/man/man2 /usr/man/cat2 .2 .2v
3 /usr/man/man3 /usr/man/cat3 .3 .3j .3x .3m .3s .3n .3v .3c .3f
4 /usr/man/man4 /usr/man/cat4 .4 .4p .4f .4v .4s .4n
5 /usr/man/man5 /usr/man/cat5 .5
7 /usr/man/man7 /usr/man/cat7 .7
p /usr/man/manp /usr/man/catp .p
public /usr/man/manp /usr/man/catp .p
o /usr/man/mano /usr/man/cato .o
old /usr/man/mano /usr/man/cato .o
# Switch type to "cad" - this will override all other sections
# when cpu type is "cad" --> Note that Cad users have no access
# to sections 2, 3, 5, old, or public (Can use this to save
# users from themselves!)
TYPE cad
1 /usr/man/man1 /usr/man/cat1 .1,.1m,.1c .1g .1p .1r .1v
/usr/man/mann /usr/man/catn .n
/usr/man/manl /usr/man/catl .l
/usr/man/mano /usr/man/cato .o
n /usr/man/mann /usr/man/catn .n
new /usr/man/mann /usr/man/catn .n
l /usr/man/manl /usr/man/catl .l
local /usr/man/manl /usr/man/catl .l
6 /usr/man/man6 /usr/man/cat6 .6
8 /usr/man/man8 /usr/man/cat8 .8 .8v .8c
c /a/guest/hprg/cad/man/man1 /a/guest/hprg/cad/man/cat1 .1
cad /a/guest/hprg/cad/man/man1 /a/guest/hprg/cad/man/cat1 .1
TYPE cs8 # these guys don't get to read too much!
1 /c/cs8/doc/man /c/cs8/doc/cat .1 .out
/usr/man/man1 /usr/man/cat1 .1 .1 .1c .1p .1r .1v
TYPE sun
1 /sun/man/man1 /sun/man/cat1 .1,.1m,.1c .1g .1p .1r .1v
/usr/man/man1 /usr/man/cat1 .1,.1m,.1c .1g .1p .1r .1v
/sun/man/mann /sun/man/catn .n
/usr/man/mann /usr/man/catn .n
/sun/man/manl /sun/man/catl .l
/usr/man/manl /usr/man/catl .l
/sun/man/mano /sun/man/cato .o
n /sun/man/mann /sun/man/catn .n
new /sun/man/mann /sun/man/catn .n
l /sun/man/manl /sun/man/catl .l
l /usr/man/manl /usr/man/catl .l
local /sun/man/manl /sun/man/catl .l
local /usr/man/manl /usr/man/catl .l
6 /sun/man/man6 /sun/man/cat6 .6
8 /sun/man/man8 /sun/man/cat8 .8 .8v .8c
2 /sun/man/man2 /sun/man/cat2 .2 .2v
3 /sun/man/man3 /sun/man/cat3 .3 .3j .3x .3m .3s .3n .3v .3c .3f
4 /sun/man/man4 /sun/man/cat4 .4 .4p .4f .4v .4s .4n
5 /sun/man/man5 /sun/man/cat5 .5
7 /sun/man/man7 /sun/man/cat7 .7
sun /sun/man/mans /sun/man/cats .s
!Funky!Stuff!
if test 3633 -ne "`wc -c < 'mand.cf'`"
then
echo shar: error transmitting "'mand.cf'" '(should have been 3633 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'parse.c'" '(2147 characters)'
if test -f 'parse.c'
then
echo shar: will not over-write existing file "'parse.c'"
else
cat << \!Funky!Stuff! > 'parse.c'
#ifndef lint
static char *RCSid = "$Header: parse.c,v 1.3 85/08/04 16:35:30 broome Exp $";
#endif
/*
* $Log: parse.c,v $
* Revision 1.3 85/08/04 16:35:30 broome
* Cleaned up a little, added comma as delimiter so that config file can
* be more freely formatted.
*
* Revision 1.2 85/07/06 16:56:04 broome
*
* Revision 1.1 85/06/25 11:23:41 broome
* Initial revision
*/
#define iswhite(c) (c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\0'||c==',')
/*
* Turn a line buffer into a pointer to a set
* of strings, just like ``argv[]'', and return argc.
*/
parse (buf, array)
char *buf;
char ***array;
{
char **argv;
char *s;
char word[132];
int argc = 0;
int i = 0, j;
argv = *array;
if (argv != (char **) 0) { /* have to free up space taken by old array */
do
free (argv[i]); /* free up each element */
while (argv[i++] != (char *) 0);
free (argv); /* and then free argv itslef */
}
/*
* Count and null-terminate each word.
*/
for (s = buf; *s; s++)
if (!iswhite (*s) && iswhite(*(s+1))) /* the end of each word */
argc++;
else if (iswhite (*s))
*s = '\0';
/*
* Now malloc up space for the strings plus the null at the end.
*/
if ((argv = (char **) malloc ((argc+1) * sizeof(char *))) == (char **) 0) {
perror ("parse: cannot malloc space for argv[]");
exit (1);
}
/*
* And copy the contents in.
*/
i = 0;
for (s = buf, j = 0; j < argc; s++) {
if (!iswhite (*s) && iswhite(*(s+1))) { /* the end of each word */
word[i++] = *s;
word[i] = '\0';
if ((argv[j] = (char *)malloc (i+1)) == (char *) 0) {
perror ("parse: cannot malloc mem for word");
exit (1);
}
strcpy (argv[j++], word);
i = 0;
} else if (!iswhite (*s))
word[i++] = *s;
}
argv[j] = (char *) 0; /* and a null at the end of it all */
*array = argv;
return (argc);
}
!Funky!Stuff!
if test 2147 -ne "`wc -c < 'parse.c'`"
then
echo shar: error transmitting "'parse.c'" '(should have been 2147 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'mand.hf'" '(2838 characters)'
if test -f 'mand.hf'
then
echo shar: will not over-write existing file "'mand.hf'"
else
cat << \!Funky!Stuff! > 'mand.hf'
@(#) mand.hf Last revised 26/08/85.
edit this file with tabstops set to 8.
mand Commands available in ``mand'' are:
mand
mand APROPOS CAT DEBUG FIND HELP
mand LIST PATH QUIT RAW SHOW
mand SECS STAT TYPE VER WHATIS
mand
mand For help with a specific command, use "HELP topic".
mand Send questions or bug reports to broome at ucb-vax.berkeley.edu
mand This is an experimental version.
apropos Usage: apropos topic
apropos Searches through the permuted index for lines containing the
apropos topic substring. Very verbose.
cat Usage: cat <section> page
cat This is the main command used - it searches for the named
cat page and retrieves it, formatting it if needed.
debug Usage: debug
debug Enables tracing of search and configuration routines.
debug Not especially interesting.
find Usage: find <section> name
find Searches for the named page, returns the location
find of the source (unformatted) page or error if not found.
fmt Usage: fmt <section> name
fmt Takes the unformatted page and formats it, sending the
fmt output directly to the connection socket.
fmt NOT YET IMPLEMENTED ....
help Usage: help <command>
help Shows the help page for the named command
list Usage: list
list Lists all known directories and sections in the order
list that they will be searched (ie. when the section is
list left unspecified in a CAT command.)
path Usage: path [section]
path Lists the named section by name, showing each corresponding
path directory and suffix list in the order searched. When given
path no arguments, shows the information for all sections.
quit Usage: quit
quit Prints a goodbye message and closes down the connection.
raw Usage: raw <section> page
raw Sends the raw (unformatted) page if found, ERR otherwise.
secs Usage: secs
secs Returns a list of all currently valid section names,
secs preceded by the number of sections to be sent.
secs Can be used by a client to verify section names.
secs (No pun intended!)
show Usage: show page [ page [ page ] ... ]
show Shows all the known files for topic `page' in
show the order that they are selected.
stat Usage: stat <section> page
stat Returns OK status if a formatted copy of the named
stat page is found (and is of non-zero length), ERR otherwise
type Usage: type <cpu_type>
type If given an argument, will cause ``mand'' to reconfigure
type itself for ``cpu_type'', elsee will show the currently
type selected cpu type. Used to allow mand to specially
type cater to any of several machine types, such as Suns and
type System V workstations with special man pages.
ver Usage: ver
ver Shows the date this daemon was last compiled and
ver the current version number.
whatis Usage: whatis topic
whatis Searches for a line in the permuted manual index
whatis corresponding to the named topic and returns it.
!Funky!Stuff!
if test 2838 -ne "`wc -c < 'mand.hf'`"
then
echo shar: error transmitting "'mand.hf'" '(should have been 2838 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'misc.c'" '(2712 characters)'
if test -f 'misc.c'
then
echo shar: will not over-write existing file "'misc.c'"
else
cat << \!Funky!Stuff! > 'misc.c'
#ifndef lint
static char *RCSid = "$Header: misc.c,v 1.6 85/08/27 15:17:00 broome Exp $";
#endif
/*
* $Log: misc.c,v $
* Revision 1.6 85/08/27 15:17:00 broome
* Last cleanup before release.
*
* Revision 1.5 85/08/04 16:56:04 broome
* Added new "any" routine.
*
* Revision 1.4 85/07/06 16:56:01 broome
*
* Revision 1.3 85/07/03 17:34:34 broome
*
* Revision 1.2 85/07/02 21:05:56 broome
*
* Revision 1.1 85/06/25 11:23:39 broome
* Initial revision
*/
#include <stdio.h>
#include "response.h"
#include "defs.h"
/*
* Search for and print the path name to the topic and
* section requested. Duplicates the action used by
* `cat()' and `raw()' without actually sending the file.
*/
dofind (argc, argv)
int argc;
char *argv[];
{
struct where *wp;
argv++, argc--;
wp = find (argc, argv);
if (wp->found)
printf ("%d %s\r\n", OK_STAT, wp->man);
else
notfound (wp);
}
/*
* Toggle debugging information.
*/
dbug ()
{
debug = !debug;
printf ("100 Debugging is now %s\n", debug ? "ON" : "OFF");
}
/*
* Show a list of all known directories.
*/
list ()
{
DIR *dir;
char *suff;
int s;
printf ("121-List of all known directories:\r\n");
for (dir = dirs; dir; dir = dir->next) {
printf ("120-Man: %s\n120-Cat: %s\r\n120-\tSuffixes: ",
dir->man, dir->cat);
for (s = 0; suff = dir->suff[s]; s++)
printf ("%s ", suff);
puts ("\r");
}
printf ("122 That's all.\r\n");
}
/*
* Report that the requested file was not found.
*/
notfound (wp)
struct where *wp;
{
printf ("%d No entry for %s in ", ERR_NOENT, wp->name);
if (wp->section)
printf ("section %s of ", wp->section);
printf ("the manual.\r\n");
}
/*
* Allocate enough memory for the given string, then copy it in.
*/
char *
strsave (str)
char *str;
{
char *s;
char *malloc();
s = malloc (strlen (str) + 1);
strcpy (s, str);
return (s);
}
/*
* Return 1 if ch is contained in str, else 0.
*/
any (ch, str)
register char ch;
register char *str;
{
while (*str)
if (ch == *str++)
return (1);
return (0);
}
/*
* Return the lower case version of a given character.
* Can't use a macro when arg is of the form `*foo++'.
*/
tolower (c)
register c;
{
if ('A' <= c && c <= 'Z')
return (c - 'A' + 'a');
return (c);
}
/*
* Case insensitive version of strcmp(), returns 0 if equal, 1 if not.
*/
streql (a, b)
register char *a, *b;
{
while (tolower (*a) == tolower (*b)) {
if (*a == '\0')
return (0);
a++;
b++;
}
return (1);
}
!Funky!Stuff!
if test 2712 -ne "`wc -c < 'misc.c'`"
then
echo shar: error transmitting "'misc.c'" '(should have been 2712 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'sections.c'" '(899 characters)'
if test -f 'sections.c'
then
echo shar: will not over-write existing file "'sections.c'"
else
cat << \!Funky!Stuff! > 'sections.c'
#ifndef lint
static char RCSid[] = "$Header: sections.c,v 1.1 85/08/04 16:37:18 broome Exp $";
#endif
/*
* $Log: sections.c,v $
* Revision 1.1 85/08/04 16:37:18 broome
* Initial revision
*
*/
#include "defs.h"
/*
* Show the list of all valid sections that the user can ask for.
* This can be used by a client program to download a list of *current*
* sections, instead of compiling them in. For this reason, we count
* the number of sections first, so that the client can allocate enough
* memory to save all the sections...
*/
dosections ()
{
SEC *sec;
int num = 0;
for (sec = sections; sec; sec = sec->next) /* count number of sections */
num++;
printf ("121-%d sections follow:\r\n", num);
for (sec = sections; sec; sec = sec->next)
printf ("120-%s\r\n", sec->name);
printf ("122 That's all.\r\n");
fflush (stdout);
}
!Funky!Stuff!
if test 899 -ne "`wc -c < 'sections.c'`"
then
echo shar: error transmitting "'sections.c'" '(should have been 899 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'format.c'" '(2230 characters)'
if test -f 'format.c'
then
echo shar: will not over-write existing file "'format.c'"
else
cat << \!Funky!Stuff! > 'format.c'
#ifndef lint
static char *RCSid = "$Header: format.c,v 1.6 85/08/27 15:16:41 broome Exp $";
#endif
/*
* $Log: format.c,v $
* Revision 1.6 85/08/27 15:16:41 broome
* Last cleanup before release.
*
* Revision 1.5 85/08/06 11:43:56 broome
* Added check for exit status,
* remove core if it dumped ...
*
* Revision 1.4 85/07/06 16:55:50 broome
*
* Revision 1.3 85/07/03 17:34:18 broome
*
* Revision 1.2 85/07/02 21:05:43 broome
*
* Revision 1.1 85/06/25 11:23:33 broome
* Initial revision
*/
#include <stdio.h>
#include <sys/file.h>
#include <sys/wait.h>
#include "response.h"
#define NROFF "/usr/bin/nroff"
/*
* Format the named file into catable form, placing the output into `dest'.
*/
format (src, dest)
char *src, *dest;
{
union wait status;
int pid, fd;
extern int errno;
/* tell them what's going on */
printf ("%d-formatting file %s ==> %s ....\r\n", INFO_FMT, src, dest);
(void) fflush (stdout);
if ((fd = creat (dest, 0644)) == -1) { /* can't create file */
printf ("%d Cannot create output file %s (%d)\r\n",
ERR_OUTPUT, dest, errno);
return (1);
}
switch (pid = fork()) {
case -1: return (1); /* can't fork */
case 0: if (fd != 1) { /* child */
dup2 (fd, 1);
close (fd);
}
execl (NROFF, "nroff", "-man", src, 0);
perror ("exec");
exit (1);
default: close (fd); /* parent */
while (wait (&status) != pid)
;
if (status.w_coredump) { /* shouldn't core dump */
(void) unlink ("core"); /* clean up */
printf ("%d Format encountered core dump!\r\n", ERR_CORE);
return (1);
}
if (status.w_retcode) { /* non-zero exit status */
printf ("%d Format returned non-zero exit code.\r\n",
ERR_EXIT);
return (2);
}
printf ("%d-done.\r\n", INFO_DONE);
return (0); /* all was ok */
}
}
!Funky!Stuff!
if test 2230 -ne "`wc -c < 'format.c'`"
then
echo shar: error transmitting "'format.c'" '(should have been 2230 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ping.c'" '(2592 characters)'
if test -f 'ping.c'
then
echo shar: will not over-write existing file "'ping.c'"
else
cat << \!Funky!Stuff! > 'ping.c'
#ifndef lint
static char RCSid[] = "$Header: ping.c,v 1.5 85/08/27 15:17:08 broome Exp $";
#endif
/*
* $Log: ping.c,v $
* Revision 1.5 85/08/27 15:17:08 broome
* Last cleanup before release.
*
* Revision 1.4 85/08/04 16:36:11 broome
* Added load cutoff, such that if 1 minute load is above this, we
* won't respond to pings from clients.
*
* Revision 1.3 85/07/24 10:39:03 broome
*
* Revision 1.2 85/07/18 12:05:20 broome
*
* Revision 1.1 85/07/16 11:10:26 broome
* Initial revision
*/
/*
* Routines to handle `ping' calls on a dgram socket.
*/
#include <syslog.h>
#include <nlist.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
struct nlist nl[] = {
{ "_avenrun" },
{ 0 },
};
int sock; /* the datagram socket descriptor */
int kmem; /* and memory file descriptor */
double cutoff = -1.0; /* don't respond if 1min load is above this */
/*
* Initialize everything ...
*/
open_ping (port)
int port;
{
struct sockaddr_in sin;
if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {
syslog (LOG_ERR, "cannot open ping (datagram) socket: %m");
return (-1);
}
bzero ((char *)&sin, sizeof (sin));
sin.sin_port = port; /* should probably do a `getservice' */
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
if (bind (sock, (char *)&sin, sizeof (sin)) < 0) {
syslog (LOG_ERR, "cannot bind ping socket: %m");
return (-1);
}
if ((kmem = open ("/dev/kmem", 0, 0)) < 0) {
syslog (LOG_ERR, "No kmem: %m");
return (-1);
}
nlist ("/vmunix", nl);
if (nl[0].n_type == 0) {
syslog (LOG_ERR, "No namelist: %m");
return (-1);
}
return (sock);
}
/*
* Routine to actually handle `ping' packets sent to the datagram socket.
* Finds the load average and sends it back to the sending socket.
*/
ping ()
{
struct sockaddr_in from;
double avenrun[3];
char buf[20];
/* grab the load average */
lseek (kmem, (long) nl[0].n_value, 0);
read (kmem, avenrun, sizeof (avenrun));
if (cutoff != -1.0 && avenrun[0] > cutoff) /* load's too high */
return;
/* don't want to see what they sent, just need their address */
if (recvfrom (sock, buf, 20, 0, &from, sizeof (from)) < 1)
return;
sprintf (buf,"%.2f %.2f %.2f\n", avenrun[0], avenrun[1], avenrun[2]);
/* and send it on over */
if (sendto (sock, buf, strlen (buf), 0, &from, sizeof (from)) < 0)
perror ("sendto");
}
!Funky!Stuff!
if test 2592 -ne "`wc -c < 'ping.c'`"
then
echo shar: error transmitting "'ping.c'" '(should have been 2592 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'showpath.c'" '(1162 characters)'
if test -f 'showpath.c'
then
echo shar: will not over-write existing file "'showpath.c'"
else
cat << \!Funky!Stuff! > 'showpath.c'
#ifndef lint
static char RCSid[] = "$Header: showpath.c,v 1.2 85/07/16 11:12:04 broome Exp $";
#endif
/*
* $Log: showpath.c,v $
* Revision 1.2 85/07/16 11:12:04 broome
* Revised output format, allows path for a given section to be shown.
*
*
*/
#include "defs.h"
/*
* Print out the entire search path used.
*/
path (argc, argv)
int argc;
char **argv;
{
SEC *sec;
DIR *dir;
char *suff;
int d, s;
if (argc == 2)
printf ("121-search path for section %s:\r\n", *++argv);
else
printf ("121-All sections searched (in order):\r\n");
for (sec = sections; sec; sec = sec->next) {
if (argc == 2 && strcmp (sec->name, *argv))
continue;
printf ("120-Section: %s\n", sec->name);
for (d = 0; dir = sec->dirs[d]; d++) {
printf ("120-\tMan dir: %s\r\n120-\tCat dir: %s\r\n",
dir->man, dir->cat);
printf ("120-\t\tSuffixes: ");
for (s = 0; suff = dir->suff[s]; s++)
printf ("%s ", suff);
puts ("\r");
}
}
printf ("122 That's all.\r\n");
(void) fflush (stdout);
}
!Funky!Stuff!
if test 1162 -ne "`wc -c < 'showpath.c'`"
then
echo shar: error transmitting "'showpath.c'" '(should have been 1162 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'raw.c'" '(767 characters)'
if test -f 'raw.c'
then
echo shar: will not over-write existing file "'raw.c'"
else
cat << \!Funky!Stuff! > 'raw.c'
#ifndef lint
static char RCSid[] = "$Header: raw.c,v 1.4 85/08/27 15:17:12 broome Exp $";
#endif
/*
* $Log: raw.c,v $
* Revision 1.4 85/08/27 15:17:12 broome
* Last cleanup before release.
*
* Revision 1.3 85/07/06 16:56:07 broome
*
* Revision 1.2 85/07/04 20:35:55 broome
* Got the rfc protocol right, added rcs keywords.
*/
#include "defs.h"
#include "response.h"
#include <stdio.h>
/*
* Find and send the raw (unformatted) man page.
*/
raw (argc, argv)
int argc;
char **argv;
{
struct where *wp;
/* find the file */
wp = find (--argc, ++argv);
if (wp->found) {
printf ("%d Raw file %s on the way.\r\n", OK_COMING, wp->man);
soelim (wp->man);
puts (".\r");
} else
notfound (wp);
}
!Funky!Stuff!
if test 767 -ne "`wc -c < 'raw.c'`"
then
echo shar: error transmitting "'raw.c'" '(should have been 767 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'show.c'" '(1014 characters)'
if test -f 'show.c'
then
echo shar: will not over-write existing file "'show.c'"
else
cat << \!Funky!Stuff! > 'show.c'
#ifndef lint
static char RCSid[] = "$Header: show.c,v 1.3 85/08/27 15:17:21 broome Exp $";
#endif
/*
* $Log: show.c,v $
* Revision 1.3 85/08/27 15:17:21 broome
* Last cleanup before release.
*
* Revision 1.2 85/07/24 10:39:09 broome
*
* Revision 1.1 85/07/06 16:56:28 broome
* Initial revision
*/
#include "defs.h"
#include <sys/file.h>
/*
* Find all occurrences of pages for the given name.
*/
/*ARGSUSED*/
show (argc, argv)
int argc;
char *argv[];
{
DIR *dir;
int s;
char buf[256];
while (*++argv) {
printf ("101-Searching for %s.\r\n", *argv);
for (dir = dirs; dir; dir = dir->next)
for (s = 0; dir->suff[s]; s++) {
sprintf (buf, "%s/%s%s", dir->man, *argv, dir->suff[s]);
if (access (buf, R_OK) == 0) {
printf ("100-%s\r\n", buf);
(void) fflush (stdout);
}
}
printf ("102 That's all for \"%s\"\r\n", *argv);
}
}
!Funky!Stuff!
if test 1014 -ne "`wc -c < 'show.c'`"
then
echo shar: error transmitting "'show.c'" '(should have been 1014 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'whatis.c'" '(2159 characters)'
if test -f 'whatis.c'
then
echo shar: will not over-write existing file "'whatis.c'"
else
cat << \!Funky!Stuff! > 'whatis.c'
#ifndef lint
static char RCSid[] = "$Header: whatis.c,v 1.4 85/07/24 10:39:13 broome Exp $";
#endif
/*
* $Log: whatis.c,v $
* Revision 1.4 85/07/24 10:39:13 broome
*
*
* Revision 1.3 85/07/06 16:56:13 broome
*
* Revision 1.2 85/07/03 17:34:41 broome
*/
#include "response.h"
#include <stdio.h>
#define LIST "/usr/lib/whatis"
#define DELIMS " \t\n\r,\"\'-()" /* word delimiters */
int key;
/*ARGSUSED*/
whatis (argc, argv)
int argc;
char **argv;
{
extern int debug;
register FILE *fp;
register char *b;
char buf[512];
char *nextword();
char word[80];
int found = 0;
argv++;
if ((fp = fopen (LIST, "r")) == NULL) {
printf ("%d cannot open %s\r\n", ERR_NOFILE, LIST);
(void) fflush (stdout);
return;
}
while (fgets (buf, 512, fp)) {
key = 0;
b = buf;
while (b = nextword (b, word)) {
if (debug)
printf ("|%s|", word);
if (strcmp (word, *argv) == 0) { /* word matches arg */
if (found == 0)
printf ("%d information for \"%s\" on the way.\r\n",
OK_COMING, *argv);
printf ("%s", buf);
found++;
break;
}
if (key == 1) /* went through all the keywords */
break;
}
}
if (!found)
printf ("%d %s: not found.\n", ERR_NOENT, *argv);
else
puts (".\r");
(void) fflush (stdout);
}
/*
* Get the next word from the line and put it into `word', return
* the advanced line pointer (NULL if at end of the line).
*/
char *nextword (buf, word)
char *buf, *word;
{
register char *i = word;
if (!buf || !*buf)
return ((char *) 0);
while (*buf && any (*buf, DELIMS) == 0) /* get this word */
*i++ = *buf++;
*i = '\0';
while (*buf && any (*buf, DELIMS)) { /* skip over to next word */
if (*buf == '(') /*)*/ /* at end of keyword list */
key = 1;
buf++;
}
return (buf);
}
!Funky!Stuff!
if test 2159 -ne "`wc -c < 'whatis.c'`"
then
echo shar: error transmitting "'whatis.c'" '(should have been 2159 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'so.c'" '(1003 characters)'
if test -f 'so.c'
then
echo shar: will not over-write existing file "'so.c'"
else
cat << \!Funky!Stuff! > 'so.c'
#ifndef lint
static char RCSid[] = "$Header: so.c,v 1.3 85/08/27 15:17:24 broome Exp $";
#endif
/*
* $Log: so.c,v $
* Revision 1.3 85/08/27 15:17:24 broome
* Last cleanup before release.
*
* Revision 1.2 85/07/06 16:56:09 broome
*
* Revision 1.1 85/07/03 13:07:22 broome
* Initial revision
*/
#include <stdio.h>
/*
* A nice simple form of "soelim" to replace `.so'
* directives with the named file inline.
*/
soelim (name)
char *name;
{
FILE *fp;
char line[1024];
char so[512];
if ((fp = fopen (name, "r")) == NULL) {
sprintf (line, "/usr/man/%s", name); /* kludge for old files */
if ((fp = fopen (line, "r")) == NULL) {
perror (name);
return;
}
}
while (fgets (line, 1024, fp)) {
if (strncmp (line, ".so", 3) == 0) { /* include directive */
sscanf (line, ".so%s", so);
soelim (so);
} else
fputs (line, stdout);
}
fclose (fp);
}
!Funky!Stuff!
if test 1003 -ne "`wc -c < 'so.c'`"
then
echo shar: error transmitting "'so.c'" '(should have been 1003 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'stat.c'" '(1001 characters)'
if test -f 'stat.c'
then
echo shar: will not over-write existing file "'stat.c'"
else
cat << \!Funky!Stuff! > 'stat.c'
#ifndef lint
static char *RCSid = "$Header: stat.c,v 1.2 85/08/27 15:17:30 broome Exp $";
#endif
/*
* $Log: stat.c,v $
* Revision 1.2 85/08/27 15:17:30 broome
* Last cleanup before release.
*
* Revision 1.1 85/08/03 18:36:20 broome
* Initial revision
*/
#include "defs.h"
#include "response.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
dostat (argc, argv)
int argc;
char *argv[];
{
struct stat statb;
struct where *wp;
long date;
argc--, argv++;
wp = find (argc, argv);
if (wp->found) {
stat (wp->man, &statb); /* stat the unformatted form */
date = statb.st_mtime;
if (stat (wp->cat, &statb) < 0 || statb.st_size == 0 ||
statb.st_mtime < date) /* have to create/update it */
printf ("%d-No formatted file found for %s.\r\n", ERR_STAT, wp->name);
else
printf ("%d-Have formatted page for %s.\r\n", OK_STAT, wp->name);
} else
notfound (wp);
}
!Funky!Stuff!
if test 1001 -ne "`wc -c < 'stat.c'`"
then
echo shar: error transmitting "'stat.c'" '(should have been 1001 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'type.c'" '(1752 characters)'
if test -f 'type.c'
then
echo shar: will not over-write existing file "'type.c'"
else
cat << \!Funky!Stuff! > 'type.c'
#include "defs.h"
#include "response.h"
static int t_index = 0; /* index of current type */
static int n_types = 0; /* number of types known */
/*
* Switch to an alternate type. Returns 0 if ok, 1 on error.
*/
switchtype (name)
char *name;
{
int i;
for (i = 0; i < n_types; i++)
if (eq (name, types[i].name)) {
t_index = i; /* save the index */
dirs = types[i].dir; /* and set the pointers */
sections = types[i].sec;
return (0);
}
return (1);
}
/*
* Interface to the "switchtype" command. If no args,
* prints current cpu type.
*/
dotype (argc, argv)
int argc;
char *argv[];
{
if (argc == 1) {
printf ("%d cpu type is \"%s\"\r\n", INFO_TYPE, types[t_index].name);
} else {
if (switchtype (argv[1]))
printf ("%d unknown cpu type \"%s\"\r\n", ERR_TYPE, argv[1]);
else
printf ("%d new cpu type is \"%s\"\r\n", OK_TYPE, argv[1]);
}
fflush (stdout);
}
/*
* Add another cpu type to the list. Used in config(),
* but uses static data here. Note that "name" is the
* name of the _next_ type, not this one just ending.
*/
addtype (name)
char *name;
{
static char *this_type = (char *) 0;
static int this_index = 0;
n_types++;
types[this_index].dir = dirs; /* save pointer to list */
dirs = (DIR *) 0; /* and set it to zero for next list */
types[this_index].sec = sections;
sections = (SEC *) 0;
types[this_index].name = this_type ? this_type : "generic"; /* save name */
this_index++;
this_type = name ? strsave (name) : (char *) 0; /* this is next name */
}
!Funky!Stuff!
if test 1752 -ne "`wc -c < 'type.c'`"
then
echo shar: error transmitting "'type.c'" '(should have been 1752 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'mand.8'" '(2928 characters)'
if test -f 'mand.8'
then
echo shar: will not over-write existing file "'mand.8'"
else
cat << \!Funky!Stuff! > 'mand.8'
.TH MAND 8 "August 3 1985"
.UC 4
.ad
.SH NAME
mand \- manual page server daemon
.SH SYNOPSIS
\fB/etc/mand\fP [ -p port ] [ -f config_file ] [ -l load ] [ -s ]
.SH DESCRIPTION
\fIMand\fP is a manual page server normally invoked at boot time from the
\fI/etc/rc\fP or \fI/etc/rc.local\fP file.
It is used in conjunction with \fIrman\fP to allow network access
to manual pages from remote machines, typically workstations or other
machines short on disk space.
.SH OPTIONS
The \fI\-p\fP option can be used to run \fImand\fP on a port other than the
one defined in \fI/etc/services\fP, typically used to offer a secondary
set of pages to alternate machine types.
.PP
The \fI\-f\fP option can be used to cause \fImand\fP to read a
different configuration file.
.PP
The \fI\-l\fP option can be used to specify a load cutoff limit, such
that if the load is exceeded \fImand\fP will not respond to `pings' from
clients, though it will still accept stream connections.
.PP
The \fI\-s\fP ("secure") switch is used to toggle the identity checking
routine. If the secure flag is set, the server will deny access
to any client not identified in the host file. (The default setting
for this flag is system dependent.)
.SH CONFIGURATION
.PP
The configuration file specifies the directories and suffixes that
\fImand\fP will search when looking for a set of pages, indicating
the section name (ie. "cad"), the directory containing the unformatted
manual pages, the directory for formatted pages, and a list of file
suffixes to search. \fIMand\fP uses this information
to construct filenames by concatenating the directory, the topic
name, and the extension; it will try each extension in the order listed.
Multiple directories can be given for each section by
indenting all but the first line with a space or tab character.
.PP
Alternate machine \fItypes\fP are accomodated in the
configuration file by preceding the list of sections
for that type with a line of the form
.nf
.br
.sp
type \fImachine_type\fP
.sp
.br
When a client connects, \fImand\fP will check the host file for
a line indicating the client's type and will reconfigure itself to
use the list of sections and directories specified for that type.
If a client wishes to override the assigned type, it may issue a
command of the form "type \fItype\fP" upon opening a connection.
.SH PROTOCOL
\fIMand\fP and \fIrman\fP use a protocol similar to that of most internet
servers (e.g. the smtp server \fIsendmail\fP), with English commands and
three-digit response codes.
.SH FUTURE ADDITIONS
\fIMand\fP should use some type of multi-keyed hashing scheme to speed up
searching.
.SH FILES
.nf
.ta \w'/usr/lib/mand.hosts 'u
/etc/services list of service port numbers
/usr/lib/mand.cf configuration file
/usr/lib/mand.hf help file
/usr/lib/mand.hosts host name/type file
.fi
.SH "SEE ALSO"
rman(1), sendmail(8)
.SH AUTHOR
Jonathan C. Broome (broome at ucb-vax.berkeley.edu)
!Funky!Stuff!
if test 2928 -ne "`wc -c < 'mand.8'`"
then
echo shar: error transmitting "'mand.8'" '(should have been 2928 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'getline.c'" '(986 characters)'
if test -f 'getline.c'
then
echo shar: will not over-write existing file "'getline.c'"
else
cat << \!Funky!Stuff! > 'getline.c'
#ifndef lint
static char RCSid[] = "$Header: getline.c,v 1.1 85/08/04 13:59:54 broome Exp $";
#endif
/*
* $Log: getline.c,v $
* Revision 1.1 85/08/04 13:59:54 broome
* Initial revision
*
*/
#include <stdio.h>
/*
* Read at most _maxlen_ characters into the buffer pointed to by line.
* Strips newlines, allows escaped newlines, turns tabs to spaces, and
* eats comments beginning with a `#' sign.
*/
getline (line, maxlen, fp)
char *line;
int maxlen;
FILE *fp;
{
register int ch, len = maxlen, comment = 0;
while (len && (ch = getc (fp)) != EOF) {
if (ch == '\n')
break;
if (ch == '#')
comment = 1;
if (comment)
continue;
if (ch == '\\')
if ((ch = getc (fp)) == '\n')
continue;
if (ch == '\t')
ch = ' ';
*line++ = ch;
len--;
}
if (ch == EOF) /* at EOF */
return (0);
*line = '\0';
return (1);
}
!Funky!Stuff!
if test 986 -ne "`wc -c < 'getline.c'`"
then
echo shar: error transmitting "'getline.c'" '(should have been 986 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'.version'" '(3 characters)'
if test -f '.version'
then
echo shar: will not over-write existing file "'.version'"
else
cat << \!Funky!Stuff! > '.version'
12
!Funky!Stuff!
if test 3 -ne "`wc -c < '.version'`"
then
echo shar: error transmitting "'.version'" '(should have been 3 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'newver.csh'" '(231 characters)'
if test -f 'newver.csh'
then
echo shar: will not over-write existing file "'newver.csh'"
else
cat << \!Funky!Stuff! > 'newver.csh'
#! /bin/csh -f
set date = `date`
if (-e .version) then
set version = ` awk '{ print $1 + 1 }' .version `
else
set version = 1
endif
echo $version >! .version
sed -e "s;DATE;$date;;" -e "s;VERSION;$version;;" ver.c >! version.c
!Funky!Stuff!
if test 231 -ne "`wc -c < 'newver.csh'`"
then
echo shar: error transmitting "'newver.csh'" '(should have been 231 characters)'
fi
chmod +x 'newver.csh'
fi # end of overwriting check
echo shar: extracting "'mand.hosts'" '(721 characters)'
if test -f 'mand.hosts'
then
echo shar: will not over-write existing file "'mand.hosts'"
else
cat << \!Funky!Stuff! > 'mand.hosts'
# Recognized host addresses and their machine type.
#
# For those of you wondering why on earth we use
# addresses in this file rather than names, the
# gethostbyaddr() call takes forever!!!
128.32.149.3 generic # ucbseymour
128.32.149.5 generic # ucbbuddy
128.32.137.1 generic # ucbcory
128.32.149.4 generic # ucbholden
128.32.137.2 pdp # ucbholden-il
128.32.4 generic # ucbarpa arpa
128.32.5 cad # ucbcad cad
128.32.6 generic # ucbernie ernie
128.32.9 generic # ucbesvax esvax
128.32.10 generic # ucbvax vax
128.32.12 generic # ucbcalder calder
128.32.24 ucf # ucbmiro miro
128.32.132.1 cad # ucbic ic
128.32.132.2 cad # ucbicw icw
128.32.132.3 cad # ucbcad-ec cad-ec
128.32.132.4 cad # ucbsim sim
!Funky!Stuff!
if test 721 -ne "`wc -c < 'mand.hosts'`"
then
echo shar: error transmitting "'mand.hosts'" '(should have been 721 characters)'
fi
fi # end of overwriting check
echo shar: done with directory "'daemon'"
cd ..
# End of shell archive
exit 0
More information about the Comp.sources.unix
mailing list