v21i092: An Automounter for NFS systems, Part04/13
Rich Salz
rsalz at uunet.uu.net
Wed Apr 11 05:45:52 AEST 1990
Submitted-by: Jan-Simon Pendry <jsp at doc.ic.ac.uk>
Posting-number: Volume 21, Issue 92
Archive-name: amd/part04
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 4 (of 13)."
# Contents: amq.x amq_xdr.c clock.c doc/amd.bib doc/nh.doc info_file.c
# mount_fs.c nfs_prot_svc.c restart.c sched.c
# Wrapped by rsalz at papaya.bbn.com on Tue Apr 10 15:12:02 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'amq.x' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'amq.x'\"
else
echo shar: Extracting \"'amq.x'\" \(4120 characters\)
sed "s/^X//" >'amq.x' <<'END_OF_FILE'
X/*
X * $Id: amq.x,v 5.1.1.1 90/01/11 17:02:14 jsp Exp Locker: jsp $
X *
X * Copyright (c) 1990 Jan-Simon Pendry
X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
X * Copyright (c) 1990 The Regents of the University of California.
X * All rights reserved.
X *
X * This code is derived from software contributed to Berkeley by
X * Jan-Simon Pendry at Imperial College, London.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by Imperial College of Science, Technology and Medicine, London, UK.
X * The names of the College and University may not be used to endorse
X * or promote products derived from this software without specific
X * prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X * %W% (Berkeley) %G%
X */
X
X/*
X * Protocol description used by the amq program
X */
X
Xconst AMQ_STRLEN = 1024; /* Maximum length of a pathname */
X
X/*
X * The type dirpath is the pathname of a directory
X */
Xtypedef string amq_string<AMQ_STRLEN>;
X
X/*
X * The type time_type should correspond to the system time_t
X */
Xtypedef long time_type;
X
X/*
X * A tree of what is mounted
X */
Xstruct amq_mount_tree {
X amq_string mt_mountinfo; /* Mounted filesystem */
X amq_string mt_directory; /* Virtual mount */
X amq_string mt_mountpoint; /* Mount point */
X amq_string mt_type; /* Filesystem type */
X time_type mt_mounttime; /* Mount time */
X u_short mt_mountuid; /* Mounter */
X int mt_getattr; /* Count of getattrs */
X int mt_lookup; /* Count of lookups */
X int mt_readdir; /* Count of readdirs */
X int mt_readlink; /* Count of readlinks */
X int mt_statfs; /* Count of statfss */
X amq_mount_tree *mt_next; /* Sibling mount tree */
X amq_mount_tree *mt_child; /* Child mount tree */
X};
Xtypedef amq_mount_tree *amq_mount_tree_p;
X
X/*
X * List of mounted filesystems
X */
Xstruct amq_mount_info {
X amq_string mi_type; /* Type of mount */
X amq_string mi_mountpt; /* Mount point */
X amq_string mi_mountinfo; /* Mount info */
X amq_string mi_fserver; /* Fileserver */
X int mi_error; /* Error code */
X int mi_refc; /* References */
X int mi_up; /* Filesystem available */
X};
Xtypedef amq_mount_info amq_mount_info_list<>;
X
X/*
X * A list of mount trees
X */
Xtypedef amq_mount_tree_p amq_mount_tree_list<>;
X
X/*
X * System wide stats
X */
Xstruct amq_mount_stats {
X int as_drops; /* Dropped requests */
X int as_stale; /* Stale NFS handles */
X int as_mok; /* Succesful mounts */
X int as_merr; /* Failed mounts */
X int as_uerr; /* Failed unmounts */
X};
X
Xenum amq_opt {
X AMOPT_DEBUG=0,
X AMOPT_LOGFILE=1,
X AMOPT_XLOG=2,
X AMOPT_FLUSHMAPC=3
X};
X
Xstruct amq_setopt {
X amq_opt as_opt; /* Option */
X amq_string as_str; /* String */
X};
X
Xprogram AMQ_PROGRAM {
X version AMQ_VERSION {
X /*
X * Does no work. It is made available in all RPC services
X * to allow server reponse testing and timing
X */
X void
X AMQPROC_NULL(void) = 0;
X
X /*
X * Returned the mount tree descending from
X * the given directory. The directory must
X * be a top-level mount point of the automounter.
X */
X amq_mount_tree_p
X AMQPROC_MNTTREE(amq_string) = 1;
X
X /*
X * Force a timeout unmount on the specified directory.
X */
X void
X AMQPROC_UMNT(amq_string) = 2;
X
X /*
X * Obtain system wide statistics from the automounter
X */
X amq_mount_stats
X AMQPROC_STATS(void) = 3;
X
X /*
X * Obtain full tree
X */
X amq_mount_tree_list
X AMQPROC_EXPORT(void) = 4;
X
X /*
X * Control debug options.
X * Return status:
X * -1: debug not available
X * 0: everything wonderful
X * >0: number of options not recognised
X */
X int
X AMQPROC_SETOPT(amq_setopt) = 5;
X
X /*
X * List of mounted filesystems
X */
X amq_mount_info_list
X AMQPROC_GETMNTFS(void) = 6;
X } = 1;
X} = 300019; /* Allocated by Sun, 89/8/29 */
END_OF_FILE
if test 4120 -ne `wc -c <'amq.x'`; then
echo shar: \"'amq.x'\" unpacked with wrong size!
fi
# end of 'amq.x'
fi
if test -f 'amq_xdr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'amq_xdr.c'\"
else
echo shar: Extracting \"'amq_xdr.c'\" \(4678 characters\)
sed "s/^X//" >'amq_xdr.c' <<'END_OF_FILE'
X/*
X * $Id: amq_xdr.c,v 5.1.1.1 90/01/11 17:04:23 jsp Exp Locker: jsp $
X *
X * Copyright (c) 1990 Jan-Simon Pendry
X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
X * Copyright (c) 1990 The Regents of the University of California.
X * All rights reserved.
X *
X * This code is derived from software contributed to Berkeley by
X * Jan-Simon Pendry at Imperial College, London.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by Imperial College of Science, Technology and Medicine, London, UK.
X * The names of the College and University may not be used to endorse
X * or promote products derived from this software without specific
X * prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X * %W% (Berkeley) %G%
X */
X
X#include "am.h"
X#include "amq.h"
X
X
Xbool_t
Xxdr_amq_string(xdrs, objp)
X XDR *xdrs;
X amq_string *objp;
X{
X if (!xdr_string(xdrs, objp, AMQ_STRLEN)) {
X return (FALSE);
X }
X return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_time_type(xdrs, objp)
X XDR *xdrs;
X time_type *objp;
X{
X if (!xdr_long(xdrs, objp)) {
X return (FALSE);
X }
X return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_amq_mount_tree(xdrs, objp)
X XDR *xdrs;
X amq_mount_tree *objp;
X{
X if (!xdr_amq_string(xdrs, &objp->mt_mountinfo)) {
X return (FALSE);
X }
X if (!xdr_amq_string(xdrs, &objp->mt_directory)) {
X return (FALSE);
X }
X if (!xdr_amq_string(xdrs, &objp->mt_mountpoint)) {
X return (FALSE);
X }
X if (!xdr_amq_string(xdrs, &objp->mt_type)) {
X return (FALSE);
X }
X if (!xdr_time_type(xdrs, &objp->mt_mounttime)) {
X return (FALSE);
X }
X if (!xdr_u_short(xdrs, &objp->mt_mountuid)) {
X return (FALSE);
X }
X if (!xdr_int(xdrs, &objp->mt_getattr)) {
X return (FALSE);
X }
X if (!xdr_int(xdrs, &objp->mt_lookup)) {
X return (FALSE);
X }
X if (!xdr_int(xdrs, &objp->mt_readdir)) {
X return (FALSE);
X }
X if (!xdr_int(xdrs, &objp->mt_readlink)) {
X return (FALSE);
X }
X if (!xdr_int(xdrs, &objp->mt_statfs)) {
X return (FALSE);
X }
X if (!xdr_pointer(xdrs, (char **)&objp->mt_next, sizeof(amq_mount_tree), xdr_amq_mount_tree)) {
X return (FALSE);
X }
X if (!xdr_pointer(xdrs, (char **)&objp->mt_child, sizeof(amq_mount_tree), xdr_amq_mount_tree)) {
X return (FALSE);
X }
X return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_amq_mount_tree_p(xdrs, objp)
X XDR *xdrs;
X amq_mount_tree_p *objp;
X{
X if (!xdr_pointer(xdrs, (char **)objp, sizeof(amq_mount_tree), xdr_amq_mount_tree)) {
X return (FALSE);
X }
X return (TRUE);
X}
X
X
X
Xbool_t
Xxdr_amq_mount_info(xdrs, objp)
X XDR *xdrs;
X amq_mount_info *objp;
X{
X if (!xdr_amq_string(xdrs, &objp->mi_type)) {
X return (FALSE);
X }
X if (!xdr_amq_string(xdrs, &objp->mi_mountpt)) {
X return (FALSE);
X }
X if (!xdr_amq_string(xdrs, &objp->mi_mountinfo)) {
X return (FALSE);
X }
X if (!xdr_amq_string(xdrs, &objp->mi_fserver)) {
X return (FALSE);
X }
X if (!xdr_int(xdrs, &objp->mi_error)) {
X return (FALSE);
X }
X if (!xdr_int(xdrs, &objp->mi_refc)) {
X return (FALSE);
X }
X if (!xdr_int(xdrs, &objp->mi_up)) {
X return (FALSE);
X }
X return (TRUE);
X}
X
X
X
Xbool_t
Xxdr_amq_mount_info_list(xdrs, objp)
X XDR *xdrs;
X amq_mount_info_list *objp;
X{
X if (!xdr_array(xdrs, (char **)&objp->amq_mount_info_list_val, (u_int *)&objp->amq_mount_info_list_len, ~0, sizeof(amq_mount_info), xdr_amq_mount_info)) {
X return (FALSE);
X }
X return (TRUE);
X}
X
X
X
Xbool_t
Xxdr_amq_mount_tree_list(xdrs, objp)
X XDR *xdrs;
X amq_mount_tree_list *objp;
X{
X if (!xdr_array(xdrs, (char **)&objp->amq_mount_tree_list_val, (u_int *)&objp->amq_mount_tree_list_len, ~0, sizeof(amq_mount_tree_p), xdr_amq_mount_tree_p)) {
X return (FALSE);
X }
X return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_amq_mount_stats(xdrs, objp)
X XDR *xdrs;
X amq_mount_stats *objp;
X{
X if (!xdr_int(xdrs, &objp->as_drops)) {
X return (FALSE);
X }
X if (!xdr_int(xdrs, &objp->as_stale)) {
X return (FALSE);
X }
X if (!xdr_int(xdrs, &objp->as_mok)) {
X return (FALSE);
X }
X if (!xdr_int(xdrs, &objp->as_merr)) {
X return (FALSE);
X }
X if (!xdr_int(xdrs, &objp->as_uerr)) {
X return (FALSE);
X }
X return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_amq_opt(xdrs, objp)
X XDR *xdrs;
X amq_opt *objp;
X{
X if (!xdr_enum(xdrs, (enum_t *)objp)) {
X return (FALSE);
X }
X return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_amq_setopt(xdrs, objp)
X XDR *xdrs;
X amq_setopt *objp;
X{
X if (!xdr_amq_opt(xdrs, &objp->as_opt)) {
X return (FALSE);
X }
X if (!xdr_amq_string(xdrs, &objp->as_str)) {
X return (FALSE);
X }
X return (TRUE);
X}
X
X
END_OF_FILE
if test 4678 -ne `wc -c <'amq_xdr.c'`; then
echo shar: \"'amq_xdr.c'\" unpacked with wrong size!
fi
# end of 'amq_xdr.c'
fi
if test -f 'clock.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'clock.c'\"
else
echo shar: Extracting \"'clock.c'\" \(4452 characters\)
sed "s/^X//" >'clock.c' <<'END_OF_FILE'
X/*
X * $Id: clock.c,v 5.1 89/11/17 18:19:50 jsp Exp Locker: jsp $
X *
X * Copyright (c) 1989 Jan-Simon Pendry
X * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
X * Copyright (c) 1989 The Regents of the University of California.
X * All rights reserved.
X *
X * This code is derived from software contributed to Berkeley by
X * Jan-Simon Pendry at Imperial College, London.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by Imperial College of Science, Technology and Medicine, London, UK.
X * The names of the College and University may not be used to endorse
X * or promote products derived from this software without specific
X * prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X * %W% (Berkeley) %G%
X */
X
X/*
X * Callouts.
X *
X * Modelled on kernel object of the same name.
X * See usual references.
X *
X * Use of a heap-based mechanism was rejected:
X * 1. more complext implementation needed.
X * 2. not obvious that a list is too slow for amd.
X */
X
X#include "am.h"
X
Xtypedef struct callout callout;
Xstruct callout {
X callout *c_next; /* List of callouts */
X void (*c_fn)(); /* Function to call */
X voidp c_closure; /* Closure to pass to call */
X time_t c_time; /* Time of call */
X int c_id; /* Unique identifier */
X};
X
Xstatic callout callouts; /* List of pending callouts */
Xstatic callout *free_callouts; /* Cache of free callouts */
Xstatic int nfree_callouts; /* Number on free list */
Xstatic int callout_id; /* Next free callout identifier */
Xtime_t next_softclock; /* Time of next call to softclock() */
X
X/*
X * Number of callout slots we keep on the free list
X */
X#define CALLOUT_FREE_SLOP 10
X
X/*
X * Assumption: valid id's are non-zero.
X */
X#define CID_ALLOC() (++callout_id)
X#define CID_UNDEF (0)
X
Xstatic callout *alloc_callout()
X{
X callout *cp = free_callouts;
X if (cp) {
X --nfree_callouts;
X free_callouts = free_callouts->c_next;
X return cp;
X }
X return ALLOC(callout);
X}
X
Xstatic void free_callout(cp)
Xcallout *cp;
X{
X if (nfree_callouts > CALLOUT_FREE_SLOP) {
X free((voidp) cp);
X } else {
X cp->c_next = free_callouts;
X free_callouts = cp;
X nfree_callouts++;
X }
X}
X
X/*
X * Schedule a callout.
X *
X * (*fn)(closure) will be called at clocktime() + secs
X */
Xint timeout(secs, fn, closure)
Xunsigned int secs;
Xvoid (*fn)();
Xvoidp closure;
X{
X callout *cp, *cp2;
X time_t t = clocktime() + secs;
X
X /*
X * Allocate and fill in a new callout structure
X */
X callout *cpnew = alloc_callout();
X cpnew->c_closure = closure;
X cpnew->c_fn = fn;
X cpnew->c_time = t;
X cpnew->c_id = CID_ALLOC();
X
X if (t < next_softclock)
X next_softclock = t;
X
X /*
X * Find the correct place in the list
X */
X for (cp = &callouts; cp2 = cp->c_next; cp = cp2)
X if (cp2->c_time >= t)
X break;
X
X /*
X * And link it in
X */
X cp->c_next = cpnew;
X cpnew->c_next = cp2;
X
X /*
X * Return callout identifier
X */
X return cpnew->c_id;
X}
X
X/*
X * De-schedule a callout
X */
Xvoid untimeout(id)
Xint id;
X{
X callout *cp, *cp2;
X for (cp = &callouts; cp2 = cp->c_next; cp = cp2) {
X if (cp2->c_id == id) {
X cp->c_next = cp2->c_next;
X free_callout(cp2);
X break;
X }
X }
X}
X
X/*
X * Clock handler
X */
Xint softclock()
X{
X time_t now;
X callout *cp;
X
X do {
X if (task_notify_todo)
X task_notify();
X
X now = clocktime();
X
X /*
X * While there are more callouts waiting...
X */
X while ((cp = callouts.c_next) && cp->c_time <= now) {
X /*
X * Extract first from list, save fn & closure and
X * unlink callout from list and free.
X * Finally call function.
X *
X * The free is done first because
X * it is quite common that the
X * function will call timeout()
X * and try to allocate a callout
X */
X void (*fn)() = cp->c_fn;
X voidp closure = cp->c_closure;
X
X callouts.c_next = cp->c_next;
X free_callout(cp);
X#ifdef DEBUG
X /*dlog("Calling %#x(%#x)", fn, closure);*/
X#endif
X (*fn)(closure);
X }
X
X } while (task_notify_todo);
X
X /*
X * Return number of seconds to next event,
X * or 0 if there is no event.
X */
X if (cp = callouts.c_next)
X return cp->c_time - now;
X return 0;
X}
END_OF_FILE
if test 4452 -ne `wc -c <'clock.c'`; then
echo shar: \"'clock.c'\" unpacked with wrong size!
fi
# end of 'clock.c'
fi
if test -f 'doc/amd.bib' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'doc/amd.bib'\"
else
echo shar: Extracting \"'doc/amd.bib'\" \(3898 characters\)
sed "s/^X//" >'doc/amd.bib' <<'END_OF_FILE'
X% $Id: amd.bib,v 5.1 89/11/17 18:24:37 jsp Exp Locker: jsp $
X%
X% Copyright (c) 1989 Jan-Simon Pendry
X% Copyright (c) 1989 Imperial College of Science, Technology & Medicine
X% Copyright (c) 1989 The Regents of the University of California.
X% All rights reserved.
X%
X% This code is derived from software contributed to Berkeley by
X% Jan-Simon Pendry at Imperial College, London.
X%
X% Redistribution and use in source and binary forms are permitted
X% provided that the above copyright notice and this paragraph are
X% duplicated in all such forms and that any documentation,
X% advertising materials, and other materials related to such
X% distribution and use acknowledge that the software was developed
X% by Imperial College of Science, Technology and Medicine, London, UK.
X% The names of the College and University may not be used to endorse
X% or promote products derived from this software without specific
X% prior written permission.
X% THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X% IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X%
X% %W% (Berkeley) %G%
X
X at inproceedings{usenix:automounter
X ,author = "Brent Callaghan and Tom Lyon"
X ,month = "January"
X ,year = "1989"
X ,title = "{The Automounter}"
X ,booktitle = "Usenix Conference Proceedings, {\rm San Diego, California}"
X ,organization = "Usenix Association"
X ,pages = "43-51"
X}
X
X at inproceedings{mit:hesiod
X ,author = "Stephen P. Dyer"
X ,title = "{The {\em Hesiod} Name Server}"
X ,booktitle = "Usenix Conference Proceedings, {\rm Dallas, Texas}"
X ,year = "1988"
X ,month = "February"
X ,organization = "Usenix Association"
X ,pages = "183--189"
X}
X
X at techreport{mit:rvd
X ,author = "M. Greenwald and J. V. Sciver"
X ,title = "{Remote Virtual Disk Protocol Specification}"
X ,year = "1986"
X ,institution = "Massachusetts Institute of Technology"
X ,address = "Cambridge, Massachusetts"
X}
X
X at inbook{bsd:ufs
X ,author = "Samuel J. Leffler and others"
X ,year = "1989"
X ,title = "The Design and Implementation of the 4.3BSD UNIX Operating System"
X ,chapter = "7"
X ,pages = "187--223"
X ,publisher = "Addison-Wesley"
X}
X
X at techreport{rfc:icmp
X ,author = "J. Postel"
X ,title = "{Internet Control Message Protocol}"
X ,year = "1981"
X ,month = "September"
X ,institution = "SRI Network Information Center"
X ,address = "Menlo Park, California"
X ,type = "RFC"
X ,number = "792"
X}
X
X at techreport{rfc:ip
X ,author = "J. Postel"
X ,title = "{Internet Protocol}"
X ,year = "1981"
X ,month = "September"
X ,institution = "SRI Network Information Center"
X ,address = "Menlo Park, California"
X ,type = "RFC"
X ,number = "791"
X}
X
X at incollection{sun:yp
X ,author = "{Sun Microsystems}"
X ,year = "1988"
X ,booktitle = "System \& Network Administration"
X ,title = "{The Sun YP Service}"
X ,month = "May"
X ,chapter = "14"
X ,pages = "349--371"
X ,edition = "First"
X ,publisher = "Sun Microsystems, Inc"
X ,address = "Mountain View, California"
X}
X
X at incollection{sun:automount
X ,author = "{Sun Microsystems}"
X ,year = "1988"
X ,booktitle = "SunOS Reference Manual"
X ,title = "Automount"
X ,month = "May"
X ,chapter = "8"
X ,pages = "1583--1585"
X ,edition = "First"
X ,publisher = "Sun Microsystems, Inc"
X ,address = "Mountain View, California"
X}
X
X at incollection{sun:rpc
X ,author = "{Sun Microsystems}"
X ,year = "1988"
X ,booktitle = "Network Programming"
X ,title = "{Remote Procedure Calls: Protocol Specification}"
X ,month = "May"
X ,chapter = "6"
X ,pages = "143--163"
X ,edition = "First"
X ,publisher = "Sun Microsystems, Inc"
X ,address = "Mountain View, California"
X}
X
X at incollection{sun:nfs
X ,author = "{Sun Microsystems}"
X ,year = "1988"
X ,booktitle = "Network Programming"
X ,title = "{Network File System: Version 2 Protocol Specification}"
X ,month = "May"
X ,chapter = "7"
X ,pages = "165--185"
X ,edition = "First"
X ,publisher = "Sun Microsystems, Inc"
X ,address = "Mountain View, California"
X}
END_OF_FILE
if test 3898 -ne `wc -c <'doc/amd.bib'`; then
echo shar: \"'doc/amd.bib'\" unpacked with wrong size!
fi
# end of 'doc/amd.bib'
fi
if test -f 'doc/nh.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'doc/nh.doc'\"
else
echo shar: Extracting \"'doc/nh.doc'\" \(4900 characters\)
sed "s/^X//" >'doc/nh.doc' <<'END_OF_FILE'
X% Change page size parameters for A4 paper on LaserWriter,
X% allowing for headers and footers. Define some new macros for headers
X% and footers too.
X%
X% MJW 7 Jan 1987
X%
X% USAGE
X%
X% To enable this use \pagestyle{footers}.
X% This also overrides automatically getting chapter titles in headers, but you
X% could restore this by using \leftmark and \rightmark
X% in your own headers and footers. These macros are set by \chaptermark (and
X% possibly other things too). In one-sided printing all pages are right ones.
X%
X% One-Sided Printing
X%
X% \setheader{your header}
X% \setfooter{your footer}
X% \setchapterhead{header on first page of a chapter}
X% \setchapterfoot{footer on first page of a chapter}
X%
X% Two-sided Printing
X%
X% \setbothheaders{the left one (even no. pages}{the right one (odd)}
X% \setbothfooters{the left one}{the right one}
X% \setchapterhead{header on first page of a chapter}
X% \setchapterfoot{footer on first page of a chapter}
X%
X% Examples
X%
X% To get a page number use \thepage. Use \hfil to get centring etc.
X% Example \setheader{A\hfil\thepage\hfil B}
X% produces A at the extreme left of the page, the number in the middle
X% and B at the extreme right.
X%
X% The following produces chapter title at top left, page number top right,
X% with a line across the page underneath them,
X% Project 1022(1041) bottom left, Task 19.1 bottom right.
X% Except on the first page of a chapter when the heading is empty, and
X% the footer is as before, but with the page number in the middle.
X% \pagestyle{footers}
X% \setheader{\vbox{\hbox to\hsize{\rightmark\hfil\thepage}\vskip 2pt\hrule}}
X% \setfooter{Project 1022(1041)\hfil Task 19.1}
X% \setchapterfoot{Project 1022(1041)\hfil\thepage \hfil Task 19.1}
X
X\oddsidemargin 16pt % MJW actually get 1/2 inch (=32pt) margin because
X % of printer offset. was 1pt
X\evensidemargin 16pt % was 1pt
X\marginparwidth 30pt % these gain 53pt width
X\topmargin 5pt % gains 26pt height (MJW was 16pt)
X\headheight 14pt % gains 11pt height (MJW was 1pt)
X\headsep 25pt % gains 24pt height (MJW was 1pt)
X%\footheight 12 pt % cannot be changed as number must fit
X\footskip 24pt % gains 6pt height
X\textheight % 528 + 26 + 11 + 24 + 6 + 55 for luck -16 +32 (heads: -10 -15)
X% 650pt
X% 666pt
X 641pt
X\textwidth % 360 + 53 + 47 for luck -15 +8
X 453pt
X%\pagestyle{myheadings}
X%\markboth{LEFT}{RIGHT}
X%left = even, right = odd for two-sided
X% everything is right for one-sided
X\def\evenheadline{}\def\oddheadline{}
X\def\evenfootline{}\def\oddfootline{}
X
X% Use these to set headers and footers for two-sided printing.
X\def\setbothheaders#1#2{\def\evenheadline{#1}\def\oddheadline{#2}}
X\def\setbothfooters#1#2{\def\evenfootline{#1}\def\oddfootline{#2}}
X
X% Use these for one-sided printing.
X\def\setheader#1{\def\oddheadline{#1}}\def\setfooter#1{\def\oddfootline{#1}}
X
X% To set footer on first page of a chapter
X\def\setchapterfoot#1{\def\chapterfoot{#1}}
X\def\setchapterhead#1{\def\chapterhead{#1}}
X
X% Initialise footers to the page number.
X\setbothfooters{\hfil\thepage\hfil}{\hfil\thepage\hfil}
X
X% Initialise chapter footer to page number, header empty.
X\setchapterfoot{\hfil\thepage \hfil}
X\setchapterhead{}
X
X% My version of \chapter
X\def\chapter{\clearpage % Starts new page.
X% \if at twoside \cleardoublepage
X% \else\clearpage\fi % Starts new page.
X \thispagestyle{chapterpage} % Page style of chapter page is 'chapterpage'
X \global\@topnum\z@ % Prevents figures from going at top of page.
X \@afterindentfalse % Suppresses indent in first paragraph. Change
X \secdef\@chapter\@schapter} % to \@afterindenttrue to have indent.
X
X% Style for first page of a chapter
X\def\ps at chapterpage{\let\@mkboth\markboth
X\def\@evenhead{\chapterhead}\def\@oddhead{\chapterhead}
X\def\@evenfoot{\chapterfoot}\def\@oddfoot{\chapterfoot}}
X
X% Style for headers AND footers.
X\if at twoside % If two-sided printing.
X\def\ps at footers{\let\@mkboth\markboth
X\def\@evenhead{\evenheadline}\def\@oddhead{\oddheadline}
X\def\@evenfoot{\evenfootline}\def\@oddfoot{\oddfootline}
X% Chapter stuff
X\def\chaptermark##1{\markboth{\uppercase{\ifnum \c at secnumdepth >\m at ne
X \@chapapp\ \thechapter. \ \fi ##1}}{}}
X\def\sectionmark##1{\markright{\uppercase{\ifnum \c at secnumdepth >\z@
X \thesection. \ \fi ##1}}}
X}
X\else % If one-sided printing.
X\def\ps at footers{\let\@mkboth\markboth
X\def\@evenhead{\evenheadline}\def\@oddhead{\oddheadline}
X\def\@evenfoot{\evenfootline}\def\@oddfoot{\oddfootline}
X% Chapter stuff
X\def\chaptermark##1{\markright{\uppercase{\ifnum \c at secnumdepth >\m at ne
X \@chapapp\ \thechapter. \ \fi ##1}}}
X}
X\fi
X
X% Debugging stuff.
X%\let\markbothorig\markboth
X%\def\markboth#1#2{\typeout{---Markboth: \#1=#1, \#2=#2\newline}
X% \markbothorig {#1} {#2}}
X%
X%\let\markrightorig\markright
X%\def\markright#1{\typeout{---Markright: \#1=#1\newline}
X% \markrightorig {#1}}
END_OF_FILE
if test 4900 -ne `wc -c <'doc/nh.doc'`; then
echo shar: \"'doc/nh.doc'\" unpacked with wrong size!
fi
# end of 'doc/nh.doc'
fi
if test -f 'info_file.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'info_file.c'\"
else
echo shar: Extracting \"'info_file.c'\" \(4399 characters\)
sed "s/^X//" >'info_file.c' <<'END_OF_FILE'
X/*
X * $Id: info_file.c,v 5.1.1.1 90/01/11 17:07:25 jsp Exp Locker: jsp $
X *
X * Copyright (c) 1990 Jan-Simon Pendry
X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
X * Copyright (c) 1990 The Regents of the University of California.
X * All rights reserved.
X *
X * This code is derived from software contributed to Berkeley by
X * Jan-Simon Pendry at Imperial College, London.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by Imperial College of Science, Technology and Medicine, London, UK.
X * The names of the College and University may not be used to endorse
X * or promote products derived from this software without specific
X * prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X * %W% (Berkeley) %G%
X */
X
X/*
X * Get info from file
X */
X
X#include "am.h"
X
X#ifdef HAS_FILE_MAPS
X#include <ctype.h>
X#include <sys/stat.h>
X
X#define MAX_LINE_LEN 2048
X
Xstatic int read_line(buf, size, fp)
Xchar *buf;
Xint size;
XFILE *fp;
X{
X int done = 0;
X
X do {
X while (fgets(buf, size, fp)) {
X int len = strlen(buf);
X done += len;
X if (len > 1 && buf[len-2] == '\\' &&
X buf[len-1] == '\n') {
X int ch;
X buf += len - 2;
X size -= len - 2;
X /*
X * Skip leading white space on next line
X */
X while ((ch = getc(fp)) != EOF &&
X isascii(ch) && isspace(ch))
X ;
X (void) ungetc(ch, fp);
X } else {
X return done;
X }
X }
X } while (size > 0 && !feof(fp));
X
X return done;
X}
X
X/*
X * Try to locate a key in a file
X */
Xstatic int search_or_reload_file(fp, map, key, val, m, fn)
XFILE *fp;
Xchar *map;
Xchar *key;
Xchar **val;
Xmnt_map *m;
Xvoid (*fn) P((mnt_map*, char*, char*));
X{
X char key_val[MAX_LINE_LEN];
X int chuck = 0;
X int line_no = 0;
X
X while (read_line(key_val, sizeof(key_val), fp)) {
X char *kp;
X char *cp;
X char *hash;
X int len = strlen(key_val);
X line_no++;
X
X /*
X * Make sure we got the whole line
X */
X if (key_val[len-1] != '\n') {
X plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map);
X chuck = 1;
X } else {
X key_val[len-1] = '\0';
X }
X
X /*
X * Strip comments
X */
X hash = strchr(key_val, '#');
X if (hash)
X *hash = '\0';
X
X /*
X * Find start of key
X */
X for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++)
X ;
X
X /*
X * Ignore blank lines
X */
X if (!*kp)
X goto again;
X
X /*
X * Find end of key
X */
X for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++)
X ;
X
X /*
X * Check whether key matches
X */
X if (*cp)
X *cp++ = '\0';
X
X if ((*key == *kp && strcmp(key, kp) == 0) || fn) {
X while (*cp && isascii(*cp) && isspace(*cp))
X cp++;
X if (*cp) {
X /*
X * Return a copy of the data
X */
X char *dc = strdup(cp);
X if (fn)
X (*fn)(m, kp, dc);
X else
X *val = dc;
X#ifdef DEBUG
X dlog("%s returns %s", key, dc);
X#endif
X if (!fn)
X return 0;
X } else {
X plog(XLOG_USER, "%s: line %d has no value field", map, line_no);
X }
X }
X
Xagain:
X /*
X * If the last read didn't get a whole line then
X * throw away the remainder before continuing...
X */
X if (chuck) {
X while (fgets(key_val, sizeof(key_val), fp) &&
X !strchr(key_val, '\n'))
X ;
X chuck = 0;
X }
X }
X
X return fn ? 0 : ENOENT;
X}
X
Xint file_init(map)
Xchar *map;
X{
X FILE *mapf = fopen(map, "r");
X if (mapf) {
X (void) fclose(mapf);
X return 0;
X }
X return errno;
X}
X
Xint file_reload(m, map, fn)
Xmnt_map *m;
Xchar *map;
Xvoid (*fn)();
X{
X FILE *mapf = fopen(map, "r");
X if (mapf) {
X int error = search_or_reload_file(mapf, map, 0, 0, m, fn);
X (void) fclose(mapf);
X return error;
X }
X
X return errno;
X}
X
Xint file_search(m, map, key, pval, tp)
Xmnt_map *m;
Xchar *map;
Xchar *key;
Xchar **pval;
Xtime_t *tp;
X{
X FILE *mapf = fopen(map, "r");
X if (mapf) {
X struct stat stb;
X int error;
X error = fstat(fileno(mapf), &stb);
X if (!error && *tp < stb.st_mtime) {
X *tp = stb.st_mtime;
X error = -1;
X } else {
X error = search_or_reload_file(mapf, map, key, pval, 0, 0);
X }
X (void) fclose(mapf);
X return error;
X }
X
X return errno;
X}
X#endif
END_OF_FILE
if test 4399 -ne `wc -c <'info_file.c'`; then
echo shar: \"'info_file.c'\" unpacked with wrong size!
fi
# end of 'info_file.c'
fi
if test -f 'mount_fs.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'mount_fs.c'\"
else
echo shar: Extracting \"'mount_fs.c'\" \(5414 characters\)
sed "s/^X//" >'mount_fs.c' <<'END_OF_FILE'
X/*
X * $Id: mount_fs.c,v 5.1.1.2 90/01/11 17:10:47 jsp Exp Locker: jsp $
X *
X * Copyright (c) 1990 Jan-Simon Pendry
X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
X * Copyright (c) 1990 The Regents of the University of California.
X * All rights reserved.
X *
X * This code is derived from software contributed to Berkeley by
X * Jan-Simon Pendry at Imperial College, London.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by Imperial College of Science, Technology and Medicine, London, UK.
X * The names of the College and University may not be used to endorse
X * or promote products derived from this software without specific
X * prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X * %W% (Berkeley) %G%
X */
X
X#include "am.h"
X#ifdef NFS_3
Xtypedef nfs_fh fhandle_t;
X#endif
X#include <sys/mount.h>
X
X/*
X * System Vr4 / SunOS 4.1 compatibility
X * - put dev= in the options list
X *
X * From: Brent Callaghan <brent at eng.sun.com>
X */
X#define MNTINFO_DEV "dev"
X#include <sys/stat.h>
X
Xint compute_mount_flags(mnt)
Xstruct mntent *mnt;
X{
X int flags;
X#ifdef NFS_4
X flags = M_NEWTYPE;
X#else
X flags = 0;
X#endif
X
X /*
X * Crack basic mount options
X */
X flags |= hasmntopt(mnt, "ro") ? M_RDONLY : 0;
X#ifdef M_CACHE
X flags |= hasmntopt(mnt, "nocache") ? M_NOCACHE : 0;
X#endif
X#ifdef M_GRPID
X flags |= hasmntopt(mnt, "grpid") ? M_GRPID : 0;
X#endif
X#ifdef M_MULTI
X flags |= hasmntopt(mnt, "multi") ? M_MULTI : 0;
X#endif
X#ifdef M_NODEV
X flags |= hasmntopt(mnt, "nodev") ? M_NODEV : 0;
X#endif
X#ifdef M_NOEXEC
X flags |= hasmntopt(mnt, "noexec") ? M_NOEXEC : 0;
X#endif
X#ifdef M_NOSUB
X flags |= hasmntopt(mnt, "nosub") ? M_NOSUB : 0;
X#endif
X#ifdef hpux
X/* HP-UX has an annoying feature of printing error msgs on /dev/console */
X#undef M_NOSUID
X#endif
X#ifdef M_NOSUID
X flags |= hasmntopt(mnt, "nosuid") ? M_NOSUID : 0;
X#endif
X#ifdef M_SYNC
X flags |= hasmntopt(mnt, "sync") ? M_SYNC : 0;
X#endif
X
X return flags;
X}
X
Xint mount_fs(mnt, flags, mnt_data, retry, type)
Xstruct mntent *mnt;
Xint flags;
Xcaddr_t mnt_data;
Xint retry;
XMTYPE_TYPE type;
X{
X int error = 0;
X int automount = 0;
X#ifdef MNTINFO_DEV
X struct stat stb;
X char *xopts = 0;
X#endif
X
X#ifdef DEBUG
X#ifdef NFS_4
X dlog("%s fstype %s (%s) flags %#x (%s)",
X mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);
X#else
X dlog("%s fstype %d (%s) flags %#x (%s)",
X mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);
X#endif /* NFS_4 */
X#endif /* DEBUG */
X
X /*
X * Fake some mount table entries for the automounter
X */
X if (STREQ(mnt->mnt_type, MNTTYPE_AUTO)) {
X automount = 1;
X mnt->mnt_fsname = pid_fsname;
X /*
X * Try it with the normal name
X */
X#ifdef notdef
X mnt->mnt_type = MNTTYPE_IGNORE;
X#endif
X mnt->mnt_type = MNTTYPE_NFS;
X /*
X * Background the mount, so that the stat of the
X * mountpoint is done in a background process.
X */
X if (background())
X return 0;
X }
X
Xagain:
X clock_valid = 0;
X error = MOUNT_TRAP(type, mnt, flags, mnt_data);
X if (error < 0)
X plog(XLOG_ERROR, "%s: mount: %m", mnt->mnt_dir);
X if (error < 0 && --retry > 0) {
X sleep(1);
X goto again;
X }
X if (error < 0) {
X if (automount)
X going_down(errno);
X return errno;
X }
X
X#ifdef UPDATE_MTAB
X#ifdef MNTINFO_DEV
X /*
X * Add the extra dev= field to the mount table.
X */
X if (stat(mnt->mnt_dir, &stb) == 0) {
X char *zopts = (char *) xmalloc(strlen(mnt->mnt_opts) + 32);
X xopts = mnt->mnt_opts;
X if (sizeof(stb.st_dev) == 2) {
X /* SunOS 4.1 */
X sprintf(zopts, "%s,%s=%04lx", xopts, MNTINFO_DEV,
X (u_long) stb.st_dev & 0xffff);
X } else {
X /* System Vr4 */
X sprintf(zopts, "%s,%s=%08lx", xopts, MNTINFO_DEV,
X (u_long) stb.st_dev);
X }
X mnt->mnt_opts = zopts;
X }
X#endif /* MNTINFO_DEV */
X
X#ifdef hpux
X /*
X * Yet another gratuitously incompatible change in HP-UX
X */
X mnt->mnt_time = clocktime();
X#endif
X write_mntent(mnt);
X#ifdef MNTINFO_DEV
X if (xopts) {
X free(mnt->mnt_opts);
X mnt->mnt_opts = xopts;
X }
X#endif
X#endif /* UPDATE_MTAB */
X
X /*
X * Needed this way since mnt may contain a pointer
X * to a local variable in this stack frame.
X */
X if (automount)
X going_down(0);
X return 0;
X}
X
X#ifdef NEED_MNTOPT_PARSER
X/*
X * Some systems don't provide these to the user,
X * but amd needs them, so...
X *
X * From: Piete Brooks <pb at cl.cam.ac.uk>
X */
X
X#include <ctype.h>
X
Xstatic char *nextmntopt(p)
Xchar **p;
X{
X char *cp = *p;
X char *rp;
X /*
X * Skip past white space
X */
X while (*cp && isspace(*cp))
X cp++;
X /*
X * Word starts here
X */
X rp = cp;
X /*
X * Scan to send of string or separator
X */
X while (*cp && *cp != ',')
X cp++;
X /*
X * If separator found the overwrite with nul char.
X */
X if (*cp) {
X *cp = '\0';
X cp++;
X }
X /*
X * Return value for next call
X */
X *p = cp;
X return rp;
X}
X
Xchar *hasmntopt(mnt, opt)
Xstruct mntent *mnt;
Xchar *opt;
X{
X char t[MNTMAXSTR];
X char *f;
X char *o = t;
X int l = strlen(opt);
X strcpy(t, mnt->mnt_opts);
X
X while (*(f = nextmntopt(&o)))
X if (strncmp(opt, f, l) == 0)
X return f - t + mnt->mnt_opts;
X
X return 0;
X}
X#endif /* NEED_MNTOPT_PARSER */
END_OF_FILE
if test 5414 -ne `wc -c <'mount_fs.c'`; then
echo shar: \"'mount_fs.c'\" unpacked with wrong size!
fi
# end of 'mount_fs.c'
fi
if test -f 'nfs_prot_svc.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'nfs_prot_svc.c'\"
else
echo shar: Extracting \"'nfs_prot_svc.c'\" \(4786 characters\)
sed "s/^X//" >'nfs_prot_svc.c' <<'END_OF_FILE'
X/*
X * $Id: nfs_prot_svc.c,v 5.1 89/11/17 18:21:23 jsp Exp Locker: jsp $
X *
X * Copyright (c) 1989 Jan-Simon Pendry
X * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
X * Copyright (c) 1989 The Regents of the University of California.
X * All rights reserved.
X *
X * This code is derived from software contributed to Berkeley by
X * Jan-Simon Pendry at Imperial College, London.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by Imperial College of Science, Technology and Medicine, London, UK.
X * The names of the College and University may not be used to endorse
X * or promote products derived from this software without specific
X * prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X * %W% (Berkeley) %G%
X */
X
X#include "am.h"
X
Xvoid nfs_program_2(rqstp, transp)
Xstruct svc_req *rqstp;
XSVCXPRT *transp;
X{
X union {
X nfs_fh nfsproc_getattr_2_arg;
X sattrargs nfsproc_setattr_2_arg;
X diropargs nfsproc_lookup_2_arg;
X nfs_fh nfsproc_readlink_2_arg;
X readargs nfsproc_read_2_arg;
X writeargs nfsproc_write_2_arg;
X createargs nfsproc_create_2_arg;
X diropargs nfsproc_remove_2_arg;
X renameargs nfsproc_rename_2_arg;
X linkargs nfsproc_link_2_arg;
X symlinkargs nfsproc_symlink_2_arg;
X createargs nfsproc_mkdir_2_arg;
X diropargs nfsproc_rmdir_2_arg;
X readdirargs nfsproc_readdir_2_arg;
X nfs_fh nfsproc_statfs_2_arg;
X } argument;
X char *result;
X bool_t (*xdr_argument)(), (*xdr_result)();
X char *(*local)();
X
X switch (rqstp->rq_proc) {
X case NFSPROC_NULL:
X xdr_argument = xdr_void;
X xdr_result = xdr_void;
X local = (char *(*)()) nfsproc_null_2;
X break;
X
X case NFSPROC_GETATTR:
X xdr_argument = xdr_nfs_fh;
X xdr_result = xdr_attrstat;
X local = (char *(*)()) nfsproc_getattr_2;
X break;
X
X case NFSPROC_SETATTR:
X xdr_argument = xdr_sattrargs;
X xdr_result = xdr_attrstat;
X local = (char *(*)()) nfsproc_setattr_2;
X break;
X
X case NFSPROC_ROOT:
X xdr_argument = xdr_void;
X xdr_result = xdr_void;
X local = (char *(*)()) nfsproc_root_2;
X break;
X
X case NFSPROC_LOOKUP:
X xdr_argument = xdr_diropargs;
X xdr_result = xdr_diropres;
X local = (char *(*)()) nfsproc_lookup_2;
X break;
X
X case NFSPROC_READLINK:
X xdr_argument = xdr_nfs_fh;
X xdr_result = xdr_readlinkres;
X local = (char *(*)()) nfsproc_readlink_2;
X break;
X
X case NFSPROC_READ:
X xdr_argument = xdr_readargs;
X xdr_result = xdr_readres;
X local = (char *(*)()) nfsproc_read_2;
X break;
X
X case NFSPROC_WRITECACHE:
X xdr_argument = xdr_void;
X xdr_result = xdr_void;
X local = (char *(*)()) nfsproc_writecache_2;
X break;
X
X case NFSPROC_WRITE:
X xdr_argument = xdr_writeargs;
X xdr_result = xdr_attrstat;
X local = (char *(*)()) nfsproc_write_2;
X break;
X
X case NFSPROC_CREATE:
X xdr_argument = xdr_createargs;
X xdr_result = xdr_diropres;
X local = (char *(*)()) nfsproc_create_2;
X break;
X
X case NFSPROC_REMOVE:
X xdr_argument = xdr_diropargs;
X xdr_result = xdr_nfsstat;
X local = (char *(*)()) nfsproc_remove_2;
X break;
X
X case NFSPROC_RENAME:
X xdr_argument = xdr_renameargs;
X xdr_result = xdr_nfsstat;
X local = (char *(*)()) nfsproc_rename_2;
X break;
X
X case NFSPROC_LINK:
X xdr_argument = xdr_linkargs;
X xdr_result = xdr_nfsstat;
X local = (char *(*)()) nfsproc_link_2;
X break;
X
X case NFSPROC_SYMLINK:
X xdr_argument = xdr_symlinkargs;
X xdr_result = xdr_nfsstat;
X local = (char *(*)()) nfsproc_symlink_2;
X break;
X
X case NFSPROC_MKDIR:
X xdr_argument = xdr_createargs;
X xdr_result = xdr_diropres;
X local = (char *(*)()) nfsproc_mkdir_2;
X break;
X
X case NFSPROC_RMDIR:
X xdr_argument = xdr_diropargs;
X xdr_result = xdr_nfsstat;
X local = (char *(*)()) nfsproc_rmdir_2;
X break;
X
X case NFSPROC_READDIR:
X xdr_argument = xdr_readdirargs;
X xdr_result = xdr_readdirres;
X local = (char *(*)()) nfsproc_readdir_2;
X break;
X
X case NFSPROC_STATFS:
X xdr_argument = xdr_nfs_fh;
X xdr_result = xdr_statfsres;
X local = (char *(*)()) nfsproc_statfs_2;
X break;
X
X default:
X svcerr_noproc(transp);
X return;
X }
X bzero((char *)&argument, sizeof(argument));
X if (!svc_getargs(transp, xdr_argument, &argument)) {
X svcerr_decode(transp);
X return;
X }
X result = (*local)(&argument, rqstp);
X if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
X svcerr_systemerr(transp);
X }
X if (!svc_freeargs(transp, xdr_argument, &argument)) {
X plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_1");
X going_down(1);
X }
X}
X
END_OF_FILE
if test 4786 -ne `wc -c <'nfs_prot_svc.c'`; then
echo shar: \"'nfs_prot_svc.c'\" unpacked with wrong size!
fi
# end of 'nfs_prot_svc.c'
fi
if test -f 'restart.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'restart.c'\"
else
echo shar: Extracting \"'restart.c'\" \(4527 characters\)
sed "s/^X//" >'restart.c' <<'END_OF_FILE'
X/*
X * $Id: restart.c,v 5.1.1.2 90/01/11 17:18:41 jsp Exp Locker: jsp $
X *
X * Copyright (c) 1990 Jan-Simon Pendry
X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
X * Copyright (c) 1990 The Regents of the University of California.
X * All rights reserved.
X *
X * This code is derived from software contributed to Berkeley by
X * Jan-Simon Pendry at Imperial College, London.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by Imperial College of Science, Technology and Medicine, London, UK.
X * The names of the College and University may not be used to endorse
X * or promote products derived from this software without specific
X * prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X * %W% (Berkeley) %G%
X */
X
X#include "am.h"
X
X/*
X * Handle an amd restart.
X *
X * Scan through the mount list finding all "interesting" mount points.
X * Next hack up partial data structures and add the mounted file
X * system to the list of known filesystems. This will leave a
X * dangling reference to that filesystems, so when the filesystem is
X * finally inherited, an extra "free" must be done on it.
X *
X * This module relies on internal details of other components. If
X * you change something else make *sure* restart() still works.
X */
Xvoid restart()
X{
X /*
X * Read the existing mount table
X */
X mntlist *ml, *mlp;
X
X /*
X * For each entry, find nfs, ufs or auto mounts
X * and create a partial am_node to represent it.
X */
X for (mlp = ml = read_mtab("restart"); mlp; mlp = mlp->mnext) {
X struct mntent *me = mlp->mnt;
X am_ops *fs_ops = 0;
X if (STREQ(me->mnt_type, MTAB_TYPE_UFS)) {
X /*
X * UFS entry
X */
X fs_ops = &ufs_ops;
X } else if (STREQ(me->mnt_type, MTAB_TYPE_NFS)) {
X /*
X * NFS entry, or possibly an Amd entry...
X */
X int au_pid;
X char *colon = strchr(me->mnt_fsname, ':');
X if (colon && sscanf(colon, ":(pid%d)", &au_pid) == 1) {
X plog(XLOG_WARNING, "%s is an existing automount point", me->mnt_dir);
X fs_ops = &sfs_ops;
X } else {
X fs_ops = &nfs_ops;
X }
X#ifdef MTAB_TYPE_MFS
X } else if (STREQ(me->mnt_type, MTAB_TYPE_MFS)) {
X /*
X * MFS entry. Fake with a symlink.
X */
X fs_ops = &sfs_ops;
X#endif
X } else {
X /*
X * Catch everything else with symlinks to
X * avoid recursive mounts. This is debatable...
X */
X fs_ops = &sfs_ops;
X }
X
X /*
X * If we found something to do
X */
X if (fs_ops) {
X mntfs *mf;
X am_opts mo;
X char *cp;
X cp = strchr(me->mnt_fsname, ':');
X /*
X * Partially fake up an opts structure
X */
X mo.opt_rhost = 0;
X mo.opt_rfs = 0;
X if (cp) {
X *cp = '\0';
X mo.opt_rhost = strdup(me->mnt_fsname);
X mo.opt_rfs = strdup(cp+1);
X *cp = ':';
X } else if (fs_ops->ffserver == find_nfs_srvr) {
X /*
X * Prototype 4.4 BSD used to end up here -
X * might as well keep the workaround for now
X */
X plog(XLOG_WARNING, "NFS server entry assumed to be %s:/", me->mnt_fsname);
X mo.opt_rhost = strdup(me->mnt_fsname);
X mo.opt_rfs = strdup("/");
X me->mnt_fsname = str3cat(me->mnt_fsname, mo.opt_rhost, ":", "/");
X }
X mo.opt_fs = me->mnt_dir;
X
X /*
X * Make a new mounted filesystem
X */
X mf = find_mntfs(fs_ops, &mo, me->mnt_dir,
X me->mnt_fsname, me->mnt_opts);
X if (mf->mf_refc == 1) {
X mf->mf_flags |= MFF_RESTART|MFF_MOUNTED;
X mf->mf_error = 0; /* Already mounted correctly */
X /*
X * If the restarted type is a link then
X * don't time out.
X */
X if (fs_ops == &sfs_ops)
X mf->mf_flags |= MFF_RSTKEEP;
X if (fs_ops->fs_init) {
X /*
X * Don't care whether this worked since
X * it is checked again when the fs is
X * inherited.
X */
X (void) (*fs_ops->fs_init)(mf);
X }
X
X plog(XLOG_INFO, "%s restarted fstype %s on %s",
X me->mnt_fsname, fs_ops->fs_type, me->mnt_dir);
X } else {
X /* Something strange happened - two mounts at the same place! */
X free_mntfs(mf);
X }
X /*
X * Clean up mo
X */
X if (mo.opt_rhost)
X free(mo.opt_rhost);
X if (mo.opt_rfs)
X free(mo.opt_rfs);
X }
X }
X
X /*
X * Free the mount list
X */
X free_mntlist(ml);
X}
END_OF_FILE
if test 4527 -ne `wc -c <'restart.c'`; then
echo shar: \"'restart.c'\" unpacked with wrong size!
fi
# end of 'restart.c'
fi
if test -f 'sched.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'sched.c'\"
else
echo shar: Extracting \"'sched.c'\" \(4945 characters\)
sed "s/^X//" >'sched.c' <<'END_OF_FILE'
X/*
X * $Id: sched.c,v 5.1.1.1 90/01/11 17:19:12 jsp Exp Locker: jsp $
X *
X * Copyright (c) 1990 Jan-Simon Pendry
X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
X * Copyright (c) 1990 The Regents of the University of California.
X * All rights reserved.
X *
X * This code is derived from software contributed to Berkeley by
X * Jan-Simon Pendry at Imperial College, London.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by Imperial College of Science, Technology and Medicine, London, UK.
X * The names of the College and University may not be used to endorse
X * or promote products derived from this software without specific
X * prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X * %W% (Berkeley) %G%
X */
X
X/*
X * Process scheduler
X */
X
X#include "am.h"
X#include <sys/signal.h>
X#include WAIT
X#include <setjmp.h>
Xextern jmp_buf select_intr;
Xextern int select_intr_valid;
X
Xtypedef struct pjob pjob;
Xstruct pjob {
X qelem hdr; /* Linked list */
X int pid; /* Process ID of job */
X cb_fun cb_fun; /* Callback function */
X voidp cb_closure; /* Closure for callback */
X union wait w; /* Status filled in by sigchld */
X voidp wchan; /* Wait channel */
X};
X
Xextern qelem proc_list_head;
Xqelem proc_list_head = { &proc_list_head, &proc_list_head };
Xextern qelem proc_wait_list;
Xqelem proc_wait_list = { &proc_wait_list, &proc_wait_list };
X
Xint task_notify_todo;
X
Xvoid ins_que(elem, pred)
Xqelem *elem, *pred;
X{
X qelem *p = pred->q_forw;
X elem->q_back = pred;
X elem->q_forw = p;
X pred->q_forw = elem;
X p->q_back = elem;
X}
X
Xvoid rem_que(elem)
Xqelem *elem;
X{
X qelem *p = elem->q_forw;
X qelem *p2 = elem->q_back;
X p2->q_forw = p;
X p->q_back = p2;
X}
X
Xstatic pjob *sched_job(cf, ca)
Xcb_fun cf;
Xvoidp ca;
X{
X pjob *p = ALLOC(pjob);
X
X p->cb_fun = cf;
X p->cb_closure = ca;
X
X /*
X * Now place on wait queue
X */
X ins_que(&p->hdr, &proc_wait_list);
X
X return p;
X}
X
Xvoid run_task(tf, ta, cf, ca)
Xtask_fun tf;
Xvoidp ta;
Xcb_fun cf;
Xvoidp ca;
X{
X pjob *p = sched_job(cf, ca);
X int mask;
X
X p->wchan = (voidp) p;
X
X mask = sigblock(sigmask(SIGCHLD));
X
X if (p->pid = background()) {
X sigsetmask(mask);
X return;
X }
X
X exit((*tf)(ta));
X /* firewall... */
X abort();
X}
X
X/*
X * Schedule a task to be run when woken up
X */
Xvoid sched_task(cf, ca, wchan)
Xcb_fun cf;
Xvoidp ca;
Xvoidp wchan;
X{
X /*
X * Allocate a new task
X */
X pjob *p = sched_job(cf, ca);
X#ifdef DEBUG
X /*dlog("sleep(%#x)", wchan);*/
X#endif
X p->wchan = wchan;
X p->pid = 0;
X bzero((voidp) &p->w, sizeof(p->w));
X}
X
Xstatic void wakeupjob(p)
Xpjob *p;
X{
X rem_que(&p->hdr);
X ins_que(&p->hdr, &proc_list_head);
X task_notify_todo++;
X}
X
Xvoid wakeup(wchan)
Xvoidp wchan;
X{
X pjob *p, *p2;
X
X if (!foreground)
X return;
X
X#ifdef DEBUG
X /*dlog("wakeup(%#x)", wchan);*/
X#endif
X /*
X * Can't user ITER() here because
X * wakeupjob() juggles the list.
X */
X for (p = FIRST(pjob, &proc_wait_list);
X p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list);
X p = p2) {
X if (p->wchan == wchan)
X wakeupjob(p);
X }
X}
X
Xvoid wakeup_task(rc, term, cl)
Xint rc;
Xint term;
Xvoidp cl;
X{
X wakeup(cl);
X}
X
X/*ARGSUSED*/
Xvoid sigchld(sig)
Xint sig;
X{
X union wait w;
X int pid;
X
X#ifdef SYS5_SIGNALS
X if ((pid = wait(&w)) > 0) {
X#else
X while ((pid = wait3(&w, WNOHANG, (union wait *) 0)) > 0) {
X#endif
X pjob *p, *p2;
X
X if (WIFSIGNALED(w))
X plog(XLOG_ERROR, "Process %d exited with signal %d",
X pid, w.w_termsig);
X#ifdef DEBUG
X else
X dlog("Process %d exited with status %d",
X pid, w.w_retcode);
X#endif
X
X for (p = FIRST(pjob, &proc_wait_list);
X p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list);
X p = p2) {
X if (p->pid == pid) {
X p->w = w;
X wakeupjob(p);
X break;
X }
X }
X
X#ifdef DEBUG
X if (p) ; else dlog("can't locate task block for pid %d", pid);
X#endif
X }
X
X#ifdef SYS5_SIGNALS
X signal(sig, sigchld);
X#endif
X if (select_intr_valid)
X longjmp(select_intr, sigchld);
X}
X
X/*
X * Run any pending tasks.
X * This must be called with SIGCHLD disabled
X */
Xvoid task_notify(P_void)
X{
X /*
X * Keep taking the first item off the list and processing it.
X *
X * Done this way because the the callback can, quite reasonably,
X * queue a new task, so no local reference into the list can be
X * held here.
X */
X while (FIRST(pjob, &proc_list_head) != HEAD(pjob, &proc_list_head)) {
X pjob *p = FIRST(pjob, &proc_list_head);
X rem_que(&p->hdr);
X /*
X * This job has completed
X */
X --task_notify_todo;
X
X /*
X * Do callback if it exists
X */
X if (p->cb_fun)
X (*p->cb_fun)(p->w.w_retcode,
X p->w.w_termsig, p->cb_closure);
X
X free(p);
X }
X}
END_OF_FILE
if test 4945 -ne `wc -c <'sched.c'`; then
echo shar: \"'sched.c'\" unpacked with wrong size!
fi
# end of 'sched.c'
fi
echo shar: End of archive 4 \(of 13\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 13 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
exit 0 # Just in case...
--
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.
More information about the Comp.sources.unix
mailing list