rsalz@uunet.uu.net (Rich Salz) (04/11/90)
Submitted-by: Jan-Simon Pendry <jsp@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@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@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@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@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@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@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@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@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@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@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@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@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@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@twoside % If two-sided printing. X\def\ps@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@secnumdepth >\m@ne X \@chapapp\ \thechapter. \ \fi ##1}}{}} X\def\sectionmark##1{\markright{\uppercase{\ifnum \c@secnumdepth >\z@ X \thesection. \ \fi ##1}}} X} X\else % If one-sided printing. X\def\ps@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@secnumdepth >\m@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@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@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@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.