[comp.sources.unix] v21i091: An Automounter for NFS systems, Part03/13

rsalz@uunet.uu.net (Rich Salz) (04/11/90)

Submitted-by: Jan-Simon Pendry <jsp@doc.ic.ac.uk>
Posting-number: Volume 21, Issue 91
Archive-name: amd/part03

#! /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 3 (of 13)."
# Contents:  am_ops.c amq.h amq_clnt.c doc/nh.sty ifs_ops.c mount.x
#   mount_xdr.c os-bsd44.h os-u2_2.h os-u3_0.h pfs_ops.c
#   scripts/mk-home-maps srvr_afs.c ufs_ops.c
# Wrapped by rsalz@papaya.bbn.com on Tue Apr 10 15:12:00 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'am_ops.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'am_ops.c'\"
else
echo shar: Extracting \"'am_ops.c'\" \(3174 characters\)
sed "s/^X//" >'am_ops.c' <<'END_OF_FILE'
X/*
X * $Id: am_ops.c,v 5.1.1.1 89/11/28 17:39:32 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
Xstatic am_ops *vops[] = {
X#ifdef HAS_UFS
X	&ufs_ops,
X#endif
X#ifdef HAS_NFS
X	&nfs_ops,
X#endif
X#ifdef HAS_SFS
X	&sfs_ops,
X#endif
X#ifdef HAS_LOFS
X	&lofs_ops,
X#endif
X#ifdef HAS_PFS
X	&pfs_ops,
X#endif
X	&afs_ops,	/* These three should be last ... */
X	&dfs_ops,	/* ... */
X	&efs_ops,	/* ... in the order afs; dfs; efs */
X	0
X};
X
X#ifdef SUNOS4_COMPAT
X/*
X * Crack a SunOS4-style host:fs:sub-link line
X * Construct an amd-style line and call the
X * normal amd matcher.
X */
Xam_ops *sunos4_match(fo, key, g_key, path, keym, map)
Xam_opts *fo;
Xchar *key;
Xchar *g_key;
Xchar *path;
Xchar *keym;
Xchar *map;
X{
X	char *host = key;
X	char *fs = strchr(host, ':');
X	char *sublink = fs ? strchr(fs+1, ':') : 0;
X	char keybuf[MAXPATHLEN];
X
X	sprintf(keybuf, "type:=nfs;rhost:=%s;rfs:=%s;sublink:=%s;opts:=%s", host,
X		fs ? fs+1 : "",
X		sublink ? sublink+1  : "",
X		g_key);
X	return ops_match(fo, keybuf, "", path, keym, map);
X}
X#endif /* SUNOS4_COMPAT */
X
Xam_ops *ops_match(fo, key, g_key, path, keym, map)
Xam_opts *fo;
Xchar *key;
Xchar *g_key;
Xchar *path;
Xchar *keym;
Xchar *map;
X{
X	am_ops **vp;
X	am_ops *rop = 0;
X
X	/*
X	 * First crack the global opts and the local opts
X	 */
X	if (!eval_fs_opts(fo, key, g_key, path, keym, map)) {
X		rop = &efs_ops;
X	} else if (fo->opt_type == 0) {
X		plog(XLOG_USER, "No fs type specified (somewhere!)");
X		rop = &efs_ops;
X	} else {
X		/*
X		 * Next find the correct filesystem type
X		 */
X		for (vp = vops; rop = *vp; vp++)
X			if (strcmp(rop->fs_type, fo->opt_type) == 0)
X				break;
X
X		if (!rop) {
X			plog(XLOG_USER, "fs type \"%s\" not recognised", fo->opt_type);
X			rop = &efs_ops;
X		}
X	}
X
X	/*
X	 * Make sure we have a default mount option.
X	 * Otherwise skip past any leading '-'.
X	 */
X	if (fo->opt_opts == 0)
X		fo->opt_opts = "rw,defaults";
X	else if (*fo->opt_opts == '-')
X		fo->opt_opts++;
X
X	/*
X	 * Check the filesystem is happy
X	 */
X	if ((*rop->fs_match)(fo))
X		return rop;
X
X	/*
X	 * Return error file system
X	 */
X	(void) (*efs_ops.fs_match)(fo);
X	return &efs_ops;
X}
END_OF_FILE
if test 3174 -ne `wc -c <'am_ops.c'`; then
    echo shar: \"'am_ops.c'\" unpacked with wrong size!
fi
# end of 'am_ops.c'
fi
if test -f 'amq.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'amq.h'\"
else
echo shar: Extracting \"'amq.h'\" \(3382 characters\)
sed "s/^X//" >'amq.h' <<'END_OF_FILE'
X/*
X * $Id: amq.h,v 5.1.1.1 90/01/11 17:01:34 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#define AMQ_STRLEN 1024
X
Xtypedef char *amq_string;
Xbool_t xdr_amq_string();
X
X
Xtypedef long *time_type;
Xbool_t xdr_time_type();
X
X
Xstruct amq_mount_tree {
X	amq_string mt_mountinfo;
X	amq_string mt_directory;
X	amq_string mt_mountpoint;
X	amq_string mt_type;
X	time_type mt_mounttime;
X	u_short mt_mountuid;
X	int mt_getattr;
X	int mt_lookup;
X	int mt_readdir;
X	int mt_readlink;
X	int mt_statfs;
X	struct amq_mount_tree *mt_next;
X	struct amq_mount_tree *mt_child;
X};
Xtypedef struct amq_mount_tree amq_mount_tree;
Xbool_t xdr_amq_mount_tree();
X
X
Xtypedef amq_mount_tree *amq_mount_tree_p;
Xbool_t xdr_amq_mount_tree_p();
X
X
Xstruct amq_mount_info {
X	amq_string mi_type;
X	amq_string mi_mountpt;
X	amq_string mi_mountinfo;
X	amq_string mi_fserver;
X	int mi_error;
X	int mi_refc;
X	int mi_up;
X};
Xtypedef struct amq_mount_info amq_mount_info;
Xbool_t xdr_amq_mount_info();
X
X
Xtypedef struct {
X	u_int amq_mount_info_list_len;
X	amq_mount_info *amq_mount_info_list_val;
X} amq_mount_info_list;
Xbool_t xdr_amq_mount_info_list();
X
X
Xtypedef struct {
X	u_int amq_mount_tree_list_len;
X	amq_mount_tree_p *amq_mount_tree_list_val;
X} amq_mount_tree_list;
Xbool_t xdr_amq_mount_tree_list();
X
X
Xstruct amq_mount_stats {
X	int as_drops;
X	int as_stale;
X	int as_mok;
X	int as_merr;
X	int as_uerr;
X};
Xtypedef struct amq_mount_stats amq_mount_stats;
Xbool_t xdr_amq_mount_stats();
X
X
Xenum amq_opt {
X	AMOPT_DEBUG = 0,
X	AMOPT_LOGFILE = 1,
X	AMOPT_XLOG = 2,
X	AMOPT_FLUSHMAPC = 3
X};
Xtypedef enum amq_opt amq_opt;
Xbool_t xdr_amq_opt();
X
X
Xstruct amq_setopt {
X	amq_opt as_opt;
X	amq_string as_str;
X};
Xtypedef struct amq_setopt amq_setopt;
Xbool_t xdr_amq_setopt();
X
X
X#define AMQ_PROGRAM ((u_long)300019)
X#define AMQ_VERSION ((u_long)1)
X#define AMQPROC_NULL ((u_long)0)
Xextern voidp amqproc_null_1();
X#define AMQPROC_MNTTREE ((u_long)1)
Xextern amq_mount_tree_p *amqproc_mnttree_1();
X#define AMQPROC_UMNT ((u_long)2)
Xextern voidp amqproc_umnt_1();
X#define AMQPROC_STATS ((u_long)3)
Xextern amq_mount_stats *amqproc_stats_1();
X#define AMQPROC_EXPORT ((u_long)4)
Xextern amq_mount_tree_list *amqproc_export_1();
X#define AMQPROC_SETOPT ((u_long)5)
Xextern int *amqproc_setopt_1();
X#define AMQPROC_GETMNTFS ((u_long)6)
Xextern amq_mount_info_list *amqproc_getmntfs_1();
X
END_OF_FILE
if test 3382 -ne `wc -c <'amq.h'`; then
    echo shar: \"'amq.h'\" unpacked with wrong size!
fi
# end of 'amq.h'
fi
if test -f 'amq_clnt.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'amq_clnt.c'\"
else
echo shar: Extracting \"'amq_clnt.c'\" \(3319 characters\)
sed "s/^X//" >'amq_clnt.c' <<'END_OF_FILE'
X/*
X * $Id: amq_clnt.c,v 5.1.1.1 90/01/11 17:03:17 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/* Default timeout can be changed using clnt_control() */
Xstatic struct timeval TIMEOUT = { 25, 0 };
X
Xvoidp
Xamqproc_null_1(argp, clnt)
X	voidp argp;
X	CLIENT *clnt;
X{
X	static char res;
X
X	bzero((char *)&res, sizeof(res));
X	if (clnt_call(clnt, AMQPROC_NULL, xdr_void, argp, xdr_void, &res, TIMEOUT) != RPC_SUCCESS) {
X		return (NULL);
X	}
X	return ((voidp)&res);
X}
X
X
Xamq_mount_tree_p *
Xamqproc_mnttree_1(argp, clnt)
X	amq_string *argp;
X	CLIENT *clnt;
X{
X	static amq_mount_tree_p res;
X
X	bzero((char *)&res, sizeof(res));
X	if (clnt_call(clnt, AMQPROC_MNTTREE, xdr_amq_string, argp, xdr_amq_mount_tree_p, &res, TIMEOUT) != RPC_SUCCESS) {
X		return (NULL);
X	}
X	return (&res);
X}
X
X
Xvoidp
Xamqproc_umnt_1(argp, clnt)
X	amq_string *argp;
X	CLIENT *clnt;
X{
X	static char res;
X
X	bzero((char *)&res, sizeof(res));
X	if (clnt_call(clnt, AMQPROC_UMNT, xdr_amq_string, argp, xdr_void, &res, TIMEOUT) != RPC_SUCCESS) {
X		return (NULL);
X	}
X	return ((voidp)&res);
X}
X
X
Xamq_mount_stats *
Xamqproc_stats_1(argp, clnt)
X	voidp argp;
X	CLIENT *clnt;
X{
X	static amq_mount_stats res;
X
X	bzero((char *)&res, sizeof(res));
X	if (clnt_call(clnt, AMQPROC_STATS, xdr_void, argp, xdr_amq_mount_stats, &res, TIMEOUT) != RPC_SUCCESS) {
X		return (NULL);
X	}
X	return (&res);
X}
X
X
Xamq_mount_tree_list *
Xamqproc_export_1(argp, clnt)
X	voidp argp;
X	CLIENT *clnt;
X{
X	static amq_mount_tree_list res;
X
X	bzero((char *)&res, sizeof(res));
X	if (clnt_call(clnt, AMQPROC_EXPORT, xdr_void, argp, xdr_amq_mount_tree_list, &res, TIMEOUT) != RPC_SUCCESS) {
X		return (NULL);
X	}
X	return (&res);
X}
X
Xint *
Xamqproc_setopt_1(argp, clnt)
X	amq_setopt *argp;
X	CLIENT *clnt;
X{
X	static int res;
X
X	bzero((char *)&res, sizeof(res));
X	if (clnt_call(clnt, AMQPROC_SETOPT, xdr_amq_setopt, argp, xdr_int, &res, TIMEOUT) != RPC_SUCCESS) {
X		return (NULL);
X	}
X	return (&res);
X}
X
X
Xamq_mount_info_list *
Xamqproc_getmntfs_1(argp, clnt)
X	voidp argp;
X	CLIENT *clnt;
X{
X	static amq_mount_info_list res;
X
X	bzero((char *)&res, sizeof(res));
X	if (clnt_call(clnt, AMQPROC_GETMNTFS, xdr_void, argp, xdr_amq_mount_info_list, &res, TIMEOUT) != RPC_SUCCESS) {
X		return (NULL);
X	}
X	return (&res);
X}
X
END_OF_FILE
if test 3319 -ne `wc -c <'amq_clnt.c'`; then
    echo shar: \"'amq_clnt.c'\" unpacked with wrong size!
fi
# end of 'amq_clnt.c'
fi
if test -f 'doc/nh.sty' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/nh.sty'\"
else
echo shar: Extracting \"'doc/nh.sty'\" \(3460 characters\)
sed "s/^X//" >'doc/nh.sty' <<'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 9 Jan 1987
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% 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% Use these for one-sided printing.
X\def\setheader#1{\def\oddheadline{#1}}\def\setfooter#1{\def\oddfootline{#1}}
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% Initialise footers to the page number.
X\setbothfooters{\hfil\thepage\hfil}{\hfil\thepage\hfil}
X% Initialise chapter footer to page number, header empty.
X\setchapterfoot{\hfil\thepage \hfil}
X\setchapterhead{}
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% 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% 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\def\chaptermark##1{\markright{\sf {\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 3460 -ne `wc -c <'doc/nh.sty'`; then
    echo shar: \"'doc/nh.sty'\" unpacked with wrong size!
fi
# end of 'doc/nh.sty'
fi
if test -f 'ifs_ops.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ifs_ops.c'\"
else
echo shar: Extracting \"'ifs_ops.c'\" \(3361 characters\)
sed "s/^X//" >'ifs_ops.c' <<'END_OF_FILE'
X/*
X * $Id: ifs_ops.c,v 5.1.1.1 89/11/28 17:46: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
X#include "am.h"
X
X#ifdef HAS_IFS
X
X/*
X * Inheritance file system.
X * This implements a filesystem restart.
X *
X * This is a *gross* hack - it knows far too
X * much about the way other parts of the
X * sytem work.  See restart.c too.
X */
Xstatic char not_a_filesystem[] = "Attempting to inherit not-a-filesystem";
X/*
X * This should never be called.
X */
Xstatic int ifs_match()
X{
X	plog(XLOG_FATAL, "ifs_match called!");
X	return FALSE;
X}
X
Xstatic int ifs_init(mf)
Xmntfs *mf;
X{
X	mntfs *mf_link = (mntfs *) mf->mf_private;
X	if (mf_link == 0) {
X		plog(XLOG_FATAL, not_a_filesystem);
X		return EINVAL;
X	}
X	/*
X	 * Fill in attribute fields
X	 */
X	mf_link->mf_fattr.type = NFLNK;
X	mf_link->mf_fattr.mode = NFSMODE_LNK | 0777;
X	mf_link->mf_fattr.nlink = 1;
X	mf_link->mf_fattr.size = MAXPATHLEN / 4;
X	if (mf_link->mf_ops->fs_init)
X		return (*mf_link->mf_ops->fs_init)(mf_link);
X	return 0;
X}
X
X/*ARGSUSED*/
Xstatic int ifs_mount(mp)
Xam_node *mp;
X{
X	mntfs *mf = mp->am_mnt;
X
X	/*
X	 * Take the linked mount point and
X	 * propogate.
X	 */
X	mntfs *mf_link = (mntfs *) mf->mf_private;
X	if (mf_link == 0) {
X		plog(XLOG_FATAL, not_a_filesystem);
X		return EINVAL;	/*XXX*/
X	}
X
X	mf_link->mf_fo = mf->mf_fo;
X	mf_link->mf_fattr.fileid = mf->mf_fattr.fileid;
X
X	/*
X	 * Discard the old map.
X	 * Don't call am_unmounted since this
X	 * node was never really mounted in the
X	 * first place.
X	 */
X	mf->mf_private = 0;
X	free_mntfs(mf);
X	/*
X	 * Free the dangling reference
X	 * to the mount link.
X	 */
X	free_mntfs(mf_link);
X	/*
X	 * Get a hold of the other entry
X	 */
X	mp->am_mnt = mf = mf_link;
X	mf->mf_flags &= ~MFF_RESTART;
X
X	/* Say what happened */
X	plog(XLOG_INFO, "restarting %s on %s", mf->mf_info, mf->mf_mount);
X
X	/*
X	 * XXX - must do the am_mounted call here
X	 */
X	if (mf->mf_ops->fs_flags & FS_MBACKGROUND)
X		am_mounted(mp);
X
X	new_ttl(mp);
X
X	return 0;
X}
X
X/*ARGSUSED*/
Xstatic int ifs_umount(mp)
Xam_node *mp;
X{
X	/*
X	 * Always succeed
X	 */
X	return 0;
X}
X
X/*
X * Ops structure
X */
Xam_ops ifs_ops = {
X	"inherit",
X	ifs_match,
X	ifs_init,
X	ifs_mount,
X	ifs_umount,
X	efs_lookuppn,
X	efs_readdir,
X	0, /* ifs_readlink */
X	0, /* ifs_mounted */
X	0, /* ifs_umounted */
X	find_afs_srvr,
X	FS_DISCARD,
X	&afs_srvr_list
X};
X
X#endif
END_OF_FILE
if test 3361 -ne `wc -c <'ifs_ops.c'`; then
    echo shar: \"'ifs_ops.c'\" unpacked with wrong size!
fi
# end of 'ifs_ops.c'
fi
if test -f 'mount.x' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mount.x'\"
else
echo shar: Extracting \"'mount.x'\" \(3121 characters\)
sed "s/^X//" >'mount.x' <<'END_OF_FILE'
X/* $Id: mount.x,v 5.1 89/11/17 18:20:52 jsp Exp Locker: jsp $ */
X/* From: mount.x 1.4 88/02/08 Copyr 1987 Sun Micro */
X
X/*
X * Protocol description for the mount program
X */
X
X
Xconst MNTPATHLEN = 1024;	/* maximum bytes in a pathname argument */
Xconst MNTNAMLEN = 255;		/* maximum bytes in a name argument */
Xconst FHSIZE = 32;		/* size in bytes of a file handle */
X
X/*
X * The fhandle is the file handle that the server passes to the client.
X * All file operations are done using the file handles to refer to a file
X * or a directory. The file handle can contain whatever information the
X * server needs to distinguish an individual file.
X */
Xtypedef opaque fhandle[FHSIZE];	
X
X/*
X * If a status of zero is returned, the call completed successfully, and 
X * a file handle for the directory follows. A non-zero status indicates
X * some sort of error. The status corresponds with UNIX error numbers.
X */
Xunion fhstatus switch (unsigned fhs_status) {
Xcase 0:
X	fhandle fhs_fhandle;
Xdefault:
X	void;
X};
X
X/*
X * The type dirpath is the pathname of a directory
X */
Xtypedef string dirpath<MNTPATHLEN>;
X
X/*
X * The type name is used for arbitrary names (hostnames, groupnames)
X */
Xtypedef string name<MNTNAMLEN>;
X
X/*
X * A list of who has what mounted
X */
Xtypedef struct mountbody *mountlist;
Xstruct mountbody {
X	name ml_hostname;
X	dirpath ml_directory;
X	mountlist ml_next;
X};
X
X/*
X * A list of netgroups
X */
Xtypedef struct groupnode *groups;
Xstruct groupnode {
X	name gr_name;
X	groups gr_next;
X};
X
X/*
X * A list of what is exported and to whom
X */
Xtypedef struct exportnode *exports;
Xstruct exportnode {
X	dirpath ex_dir;
X	groups ex_groups;
X	exports ex_next;
X};
X
Xprogram MOUNTPROG {
X	/*
X	 * Version one of the mount protocol communicates with version two
X	 * of the NFS protocol. The only connecting point is the fhandle 
X	 * structure, which is the same for both protocols.
X	 */
X	version MOUNTVERS {
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		MOUNTPROC_NULL(void) = 0;
X
X		/*	
X		 * If fhs_status is 0, then fhs_fhandle contains the
X	 	 * file handle for the directory. This file handle may
X		 * be used in the NFS protocol. This procedure also adds
X		 * a new entry to the mount list for this client mounting
X		 * the directory.
X		 * Unix authentication required.
X		 */
X		fhstatus 
X		MOUNTPROC_MNT(dirpath) = 1;
X
X		/*
X		 * Returns the list of remotely mounted filesystems. The 
X		 * mountlist contains one entry for each hostname and 
X		 * directory pair.
X		 */
X		mountlist
X		MOUNTPROC_DUMP(void) = 2;
X
X		/*
X		 * Removes the mount list entry for the directory
X		 * Unix authentication required.
X		 */
X		void
X		MOUNTPROC_UMNT(dirpath) = 3;
X
X		/*
X		 * Removes all of the mount list entries for this client
X		 * Unix authentication required.
X		 */
X		void
X		MOUNTPROC_UMNTALL(void) = 4;
X
X		/*
X		 * Returns a list of all the exported filesystems, and which
X		 * machines are allowed to import it.
X		 */
X		exports
X		MOUNTPROC_EXPORT(void)  = 5;
X	
X		/*
X		 * Identical to MOUNTPROC_EXPORT above
X		 */
X		exports
X		MOUNTPROC_EXPORTALL(void) = 6;
X	} = 1;
X} = 100005;
END_OF_FILE
if test 3121 -ne `wc -c <'mount.x'`; then
    echo shar: \"'mount.x'\" unpacked with wrong size!
fi
# end of 'mount.x'
fi
if test -f 'mount_xdr.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mount_xdr.c'\"
else
echo shar: Extracting \"'mount_xdr.c'\" \(3132 characters\)
sed "s/^X//" >'mount_xdr.c' <<'END_OF_FILE'
X/*
X * $Id: mount_xdr.c,v 5.1 89/11/17 18:21:00 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#include "mount.h"
X
X
Xbool_t
Xxdr_fhandle(xdrs, objp)
X	XDR *xdrs;
X	fhandle objp;
X{
X	if (!xdr_opaque(xdrs, objp, FHSIZE)) {
X		return (FALSE);
X	}
X	return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_fhstatus(xdrs, objp)
X	XDR *xdrs;
X	fhstatus *objp;
X{
X	if (!xdr_u_int(xdrs, &objp->fhs_status)) {
X		return (FALSE);
X	}
X	switch (objp->fhs_status) {
X	case 0:
X		if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle)) {
X			return (FALSE);
X		}
X		break;
X	}
X	return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_dirpath(xdrs, objp)
X	XDR *xdrs;
X	dirpath *objp;
X{
X	if (!xdr_string(xdrs, objp, MNTPATHLEN)) {
X		return (FALSE);
X	}
X	return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_name(xdrs, objp)
X	XDR *xdrs;
X	name *objp;
X{
X	if (!xdr_string(xdrs, objp, MNTNAMLEN)) {
X		return (FALSE);
X	}
X	return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_mountlist(xdrs, objp)
X	XDR *xdrs;
X	mountlist *objp;
X{
X	if (!xdr_name(xdrs, &objp->ml_hostname)) {
X		return (FALSE);
X	}
X	if (!xdr_dirpath(xdrs, &objp->ml_directory)) {
X		return (FALSE);
X	}
X	if (!xdr_pointer(xdrs, (char **)&objp->ml_next, sizeof(mountlist), xdr_mountlist)) {
X		return (FALSE);
X	}
X	return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_groups(xdrs, objp)
X	XDR *xdrs;
X	groups *objp;
X{
X	if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct groupnode), xdr_groupnode)) {
X		return (FALSE);
X	}
X	return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_groupnode(xdrs, objp)
X	XDR *xdrs;
X	groupnode *objp;
X{
X	if (!xdr_name(xdrs, &objp->gr_name)) {
X		return (FALSE);
X	}
X	if (!xdr_groups(xdrs, &objp->gr_next)) {
X		return (FALSE);
X	}
X	return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_exports(xdrs, objp)
X	XDR *xdrs;
X	exports *objp;
X{
X	if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct exportnode), xdr_exportnode)) {
X		return (FALSE);
X	}
X	return (TRUE);
X}
X
X
X
X
Xbool_t
Xxdr_exportnode(xdrs, objp)
X	XDR *xdrs;
X	exportnode *objp;
X{
X	if (!xdr_dirpath(xdrs, &objp->ex_dir)) {
X		return (FALSE);
X	}
X	if (!xdr_groups(xdrs, &objp->ex_groups)) {
X		return (FALSE);
X	}
X	if (!xdr_exports(xdrs, &objp->ex_next)) {
X		return (FALSE);
X	}
X	return (TRUE);
X}
X
X
END_OF_FILE
if test 3132 -ne `wc -c <'mount_xdr.c'`; then
    echo shar: \"'mount_xdr.c'\" unpacked with wrong size!
fi
# end of 'mount_xdr.c'
fi
if test -f 'os-bsd44.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'os-bsd44.h'\"
else
echo shar: Extracting \"'os-bsd44.h'\" \(3568 characters\)
sed "s/^X//" >'os-bsd44.h' <<'END_OF_FILE'
X/* $Id: os-bsd44.h,v 5.1.1.3 90/01/11 17:14:58 jsp Exp Locker: jsp $ */
X
X/*
X * 4.4 BSD definitions for Amd (automounter)
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 * Does the compiler grok void *
X */
X#define	VOIDP
X
X/*
X * Which version of the Sun RPC library we are using
X * This is the implementation release number, not
X * the protocol revision number.
X */
X#define	RPC_3
X
X/*
X * Which version of the NFS interface are we using.
X * This is the implementation release number, not
X * the protocol revision number.
X */
X#define	NFS_44
X
X/*
X * Does this OS have NDBM support?
X */
X#define OS_HAS_NDBM
X
X/*
X * The mount table is obtained from the kernel
X */
X#undef	UPDATE_MTAB
X
X/*
X * No mntent info on 4.4 BSD
X */
X#undef	MNTENT_HDR
X
X/*
X * Name of filesystem types
X */
X#define	MOUNT_TYPE_NFS	MOUNT_NFS
X#define	MOUNT_TYPE_UFS	MOUNT_UFS
X#undef MTAB_TYPE_UFS
X#define	MTAB_TYPE_UFS	"ufs"
X#define	MTAB_TYPE_MFS	"mfs"
X
X/*
X * How to unmount filesystems
X */
X#undef UNMOUNT_TRAP
X#undef	NEED_UMOUNT_FS
X#define	NEED_UMOUNT_BSD
X
X/*
X * Byte ordering
X */
X#ifndef BYTE_ORDER
X#include <machine/endian.h>
X#endif /* BYTE_ORDER */
X
X#undef ARCH_ENDIAN
X#if BYTE_ORDER == LITTLE_ENDIAN
X#define ARCH_ENDIAN "little"
X#else
X#if BYTE_ORDER == BIG_ENDIAN
X#define ARCH_ENDIAN "big"
X#else
XXXX - Probably no hope of running Amd on this machine!
X#endif /* BIG */
X#endif /* LITTLE */
X
X/*
X * Miscellaneous 4.4 BSD bits
X */
X#define MISC_RPC
X#define	NEED_MNTOPT_PARSER
X#define	SHORT_MOUNT_NAME
X
X#define	MNTMAXSTR       128
X
X#define	MNTTYPE_UFS	"ufs"		/* Un*x file system */
X#define	MNTTYPE_NFS	"nfs"		/* network file system */
X#define	MNTTYPE_MFS	"mfs"		/* memory file system */
X#define	MNTTYPE_IGNORE	"ignore"	/* No type specified, ignore this entry */
X
X#define	M_SYNC	M_SYNCHRONOUS
X
X#define	MNTOPT_SOFT	"soft"		/* soft mount */
X#define	MNTOPT_INTR	"intr"		/* interrupts allowed */
X
Xstruct mntent {
X	char	*mnt_fsname;	/* name of mounted file system */
X	char	*mnt_dir;	/* file system path prefix */
X	char	*mnt_type;	/* MNTTYPE_* */
X	char	*mnt_opts;	/* MNTOPT* */
X	int	mnt_freq;	/* dump frequency, in days */
X	int	mnt_passno;	/* pass number on parallel fsck */
X};
X
X/*
X * Type of a file handle
X */
X#undef NFS_FH_TYPE
X#define	NFS_FH_TYPE	nfsv2fh_t *
X
X/*
X * How to get a mount list
X */
X#undef	READ_MTAB_FROM_FILE
X#define	READ_MTAB_BSD_STYLE
X
X/*
X * The data for the mount syscall needs the path in addition to the
X * host name since that is the only source of information about the
X * mounted filesystem.
X */
X#define	NFS_ARGS_NEEDS_PATH
END_OF_FILE
if test 3568 -ne `wc -c <'os-bsd44.h'`; then
    echo shar: \"'os-bsd44.h'\" unpacked with wrong size!
fi
# end of 'os-bsd44.h'
fi
if test -f 'os-u2_2.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'os-u2_2.h'\"
else
echo shar: Extracting \"'os-u2_2.h'\" \(3606 characters\)
sed "s/^X//" >'os-u2_2.h' <<'END_OF_FILE'
X/* $Id: os-u2_2.h,v 5.1.1.1 90/01/11 17:16:29 jsp Exp Locker: jsp $ */
X
X/*
X * Ultrix 2.2 definitions for Amd (automounter)
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 * Does the compiler grok void *
X */
X#undef	VOIDP
X
X/*
X * Which version of the Sun RPC library we are using
X * This is the implementation release number, not
X * the protocol revision number.
X */
X#define	RPC_3
X
X/*
X * Which version of the NFS interface are we using.
X * This is the implementation release number, not
X * the protocol revision number.
X */
X#define	NFS_3
X
X/*
X * Byte ordering
X */
X#undef	ARCH_ENDIAN
X#if defined(vax)
X#define	ARCH_ENDIAN "little"
X#endif
X
X/*
X * The mount table is obtained from the kernel
X */
X#undef	UPDATE_MTAB
X
X/*
X * No mntent info on Ultrix
X  */
X#undef	MNTENT_HDR
X
X/*
X * No support for syslog()
X */
X#undef	HAS_SYSLOG
X
X/*
X * No support for ndbm
X */
X#undef	HAS_NDBM_MAPS
X
X/*
X * Name of filesystem types
X */
X#define	MOUNT_TYPE_NFS	GT_NFS
X#define	MOUNT_TYPE_UFS	GT_ULTRIX
X#undef	MTAB_TYPE_UFS
X#define	MTAB_TYPE_UFS	"ufs"
X
X/*
X * Name of mount & unmount system calls
X */
X#undef	MOUNT_TRAP
X#define	MOUNT_TRAP(type, mnt, flag, mnt_data) \
X	mount(mnt->mnt_fsname, mnt->mnt_dir, flag, type, mnt_data)
X#undef	UNMOUNT_TRAP
X#define	UNMOUNT_TRAP(mnt)	umount(mnt->mnt_passno)
X
X/*
X * Miscellaneous Ultrix bits
X */
X#define	M_RDONLY	M_RONLY
X
X#ifndef MNTMAXSTR
X#define	MNTMAXSTR       128
X#endif
X
X#define	MNTTYPE_UFS	"ufs"		/* Un*x file system */
X#define	MNTTYPE_NFS	"nfs"		/* network file system */
X#define	MNTTYPE_IGNORE	"ignore"	/* No type specified, ignore this entry */
X
X#define	MNTOPT_RO	"ro"		/* read only */
X#define	MNTOPT_RW	"rw"		/* read/write */
X#define	MNTOPT_QUOTA	"quota"		/* quotas */
X#define	MNTOPT_NOQUOTA	"noquota"	/* no quotas */
X#define	MNTOPT_HARD	"hard"		/* hard mount */
X#define	MNTOPT_SOFT	"soft"		/* soft mount */
X#define	MNTOPT_INTR	"intr"		/* interrupts allowed */
X
X#define	MNTOPT_NOSUID	"nosuid"	/* no set uid allowed */
X
Xstruct mntent {
X	char	*mnt_fsname;	/* name of mounted file system */
X	char	*mnt_dir;	/* file system path prefix */
X	char	*mnt_type;	/* MNTTYPE_* */
X	char	*mnt_opts;	/* MNTOPT* */
X	int	mnt_freq;	/* dump frequency, in days */
X	int	mnt_passno;	/* pass number on parallel fsck */
X};
X#define	MOUNTED		"/etc/mtab"
X
X#define	NFS_HDR	"u2_2-nfs.h"
X#define	UFS_HDR	"u2_2-nfs.h"
X
X#define	MISC_RPC
X
X#define	nfs_args	nfs_gfs_mount
X#define	ULTRIX_HACK	/* Should be handled better than this !! */
X#define	NEED_MNTOPT_PARSER
X
X/*
X * How to get a mount list
X */
X#undef	READ_MTAB_FROM_FILE
X#define	READ_MTAB_ULTRIX_STYLE
END_OF_FILE
if test 3606 -ne `wc -c <'os-u2_2.h'`; then
    echo shar: \"'os-u2_2.h'\" unpacked with wrong size!
fi
# end of 'os-u2_2.h'
fi
if test -f 'os-u3_0.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'os-u3_0.h'\"
else
echo shar: Extracting \"'os-u3_0.h'\" \(3536 characters\)
sed "s/^X//" >'os-u3_0.h' <<'END_OF_FILE'
X/* $Id: os-u3_0.h,v 5.1 89/11/17 18:23:18 jsp Exp Locker: jsp $ */
X
X/*
X * Ultrix 3.0 definitions for Amd (automounter)
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 * Does the compiler grok void *
X */
X#undef	VOIDP
X
X/*
X * Which version of the Sun RPC library we are using
X * This is the implementation release number, not
X * the protocol revision number.
X */
X#define	RPC_3
X
X/*
X * Which version of the NFS interface are we using.
X * This is the implementation release number, not
X * the protocol revision number.
X */
X#define	NFS_3
X
X/*
X * Byte ordering
X */
X#undef ARCH_ENDIAN
X#if defined(vax) || defined(mips)
X#define	ARCH_ENDIAN "little"
X#endif
X
X/*
X * The mount table is obtained from the kernel
X */
X#undef	UPDATE_MTAB
X
X/*
X * No mntent info on Ultrix
X  */
X#undef	MNTENT_HDR
X
X/*
X * No support for syslog()
X */
X#undef	HAS_SYSLOG
X
X/*
X * Name of filesystem types
X */
X#define	MOUNT_TYPE_NFS	GT_NFS
X#define	MOUNT_TYPE_UFS	GT_ULTRIX
X#undef	MTAB_TYPE_UFS
X#define	MTAB_TYPE_UFS	"ufs"
X
X/*
X * Name of mount & unmount system calls
X */
X#undef	MOUNT_TRAP
X#define	MOUNT_TRAP(type, mnt, flag, mnt_data) \
X	mount(mnt->mnt_fsname, mnt->mnt_dir, flag, type, mnt_data)
X#undef	UNMOUNT_TRAP
X#define	UNMOUNT_TRAP(mnt)	umount(mnt->mnt_passno)
X
X/*
X * Miscellaneous Ultrix bits
X */
X#define	M_RDONLY	M_RONLY
X
X#define	MNTMAXSTR	128
X
X#define	MNTTYPE_UFS	"ufs"		/* Un*x file system */
X#define	MNTTYPE_NFS	"nfs"		/* network file system */
X#define	MNTTYPE_IGNORE	"ignore"	/* No type specified, ignore this entry */
X
X#define	MNTOPT_RO	"ro"		/* read only */
X#define	MNTOPT_RW	"rw"		/* read/write */
X#define	MNTOPT_QUOTA	"quota"		/* quotas */
X#define	MNTOPT_NOQUOTA	"noquota"	/* no quotas */
X#define	MNTOPT_HARD	"hard"		/* hard mount */
X#define	MNTOPT_SOFT	"soft"		/* soft mount */
X#define	MNTOPT_INTR	"intr"		/* interrupts allowed */
X
X#define	MNTOPT_NOSUID	"nosuid"	/* no set uid allowed */
X
Xstruct mntent {
X	char	*mnt_fsname;	/* name of mounted file system */
X	char	*mnt_dir;	/* file system path prefix */
X	char	*mnt_type;	/* MNTTYPE_* */
X	char	*mnt_opts;	/* MNTOPT* */
X	int	mnt_freq;	/* dump frequency, in days */
X	int	mnt_passno;	/* pass number on parallel fsck */
X};
X#define	MOUNTED		"/etc/mtab"
X
X#define	NFS_HDR	"u2_2-nfs.h"
X#define	UFS_HDR	"u2_2-nfs.h"
X
X#define	MISC_RPC
X
X#define	nfs_args	nfs_gfs_mount
X#define	ULTRIX_HACK	/* Should be handled better than this !! */
X#define	NEED_MNTOPT_PARSER
X
X/*
X * How to get a mount list
X */
X#undef	READ_MTAB_FROM_FILE
X#define	READ_MTAB_ULTRIX_STYLE
END_OF_FILE
if test 3536 -ne `wc -c <'os-u3_0.h'`; then
    echo shar: \"'os-u3_0.h'\" unpacked with wrong size!
fi
# end of 'os-u3_0.h'
fi
if test -f 'pfs_ops.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pfs_ops.c'\"
else
echo shar: Extracting \"'pfs_ops.c'\" \(3296 characters\)
sed "s/^X//" >'pfs_ops.c' <<'END_OF_FILE'
X/*
X * $Id: pfs_ops.c,v 5.1.1.1 90/01/11 17:17:20 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
X#ifdef HAS_PFS
X
X/*
X * Program file system
X */
X
X/*
X * Execute needs a mount and unmount command.
X */
Xstatic int pfs_match(fo)
Xam_opts *fo;
X{
X	char *prog;
X	if (!fo->opt_mount || !fo->opt_unmount) {
X		plog(XLOG_USER, "program: no mount/unmount specified");
X		return FALSE;
X	}
X	prog = strchr(fo->opt_mount, ' ');
X	if (fo->fs_mtab = strealloc(fo->fs_mtab, prog ? prog+1 : fo->opt_mount))
X		return TRUE;
X	return FALSE;
X}
X
Xstatic int pfs_init(mf)
Xmntfs *mf;
X{
X	/*
X	 * Save unmount command
X	 */
X	if (mf->mf_refc == 1) {
X		mf->mf_private = (voidp) strdup(mf->mf_fo->opt_unmount);
X		mf->mf_prfree = free;
X	}
X	return 0;
X}
X
Xstatic int pfs_exec(info)
Xchar *info;
X{
X	char **xivec;
X	int error;
X	/*
X	 * Split copy of command info string
X	 */
X	info = strdup(info);
X	if (info == 0)
X		return ENOBUFS;
X	xivec = strsplit(info, '\'');
X	/*
X	 * Put stdout to stderr
X	 */
X	(void) fclose(stdout);
X	(void) dup(fileno(logfp));
X	if (fileno(logfp) != fileno(stderr)) {
X		(void) fclose(stderr);
X		(void) dup(fileno(logfp));
X	}
X	/*
X	 * Try the exec
X	 */
X#ifdef DEBUG
X	Debug(D_FULL) {
X		char **cp = xivec;
X		plog(XLOG_DEBUG, "executing (un)mount command...");
X		while (*cp) {
X	  		plog(XLOG_DEBUG, "arg[%d] = '%s'", cp-xivec, *cp);
X			cp++;
X		}
X	}
X#endif
X	if (xivec[0] == 0 || xivec[1] == 0) {
X		errno = EINVAL;
X		plog(XLOG_USER, "1st/2nd args missing to (un)mount program");
X	} else {
X		(void) execv(xivec[0], xivec+1);
X	}
X	/*
X	 * Save error number
X	 */
X	error = errno;
X	plog(XLOG_ERROR, "exec failed: %m");
X
X	/*
X	 * Free allocate memory
X	 */
X	free(info);
X	free(xivec);
X	/*
X	 * Return error
X	 */
X	return error;
X}
X
X/*ARGSUSED*/
Xstatic int pfs_mount(mp)
Xam_node *mp;
X{
X	mntfs *mf = mp->am_mnt;
X
X	return pfs_exec(mf->mf_fo->opt_mount);
X}
X
Xstatic int pfs_umount(mp)
Xam_node *mp;
X{
X	mntfs *mf = mp->am_mnt;
X
X	return pfs_exec((char *) mf->mf_private);
X}
X
X/*
X * Ops structure
X */
Xam_ops pfs_ops = {
X	"program",
X	pfs_match,
X	pfs_init,
X	pfs_mount,
X	pfs_umount,
X	efs_lookuppn,
X	efs_readdir,
X	0, /* pfs_readlink */
X	0, /* pfs_mounted */
X	0, /* pfs_umounted */
X	find_afs_srvr,
X	FS_BACKGROUND|FS_AMQINFO,
X	&afs_srvr_list
X};
X
X#endif
END_OF_FILE
if test 3296 -ne `wc -c <'pfs_ops.c'`; then
    echo shar: \"'pfs_ops.c'\" unpacked with wrong size!
fi
# end of 'pfs_ops.c'
fi
if test -f 'scripts/mk-home-maps' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'scripts/mk-home-maps'\"
else
echo shar: Extracting \"'scripts/mk-home-maps'\" \(3570 characters\)
sed "s/^X//" >'scripts/mk-home-maps' <<'END_OF_FILE'
X#!/bin/sh -
X#
X# $Id: mk-home-maps,v 5.1 89/11/17 18:24:18 jsp Exp Locker: jsp $
X#
X# Copyright (C) 1989 by Jan-Simon Pendry
X# All Rights Reserved.
X#
X# Take a list of user-name/directory pairs and a list of
X# block-device/mount-point pairs and construct the information
X# required for amd to automount the whole lot.
X#
X# The two mandatory arguments are the names of the files containing
X# the required information.
X# The output is placed in a file of the same name with .cf appended
X#
Xusage="Usage: $0 dirs part"
Xif [ $# -ne 2 ]; then
X	echo $usage 2>&1
X	exit 1
Xfi
Xautoroot=/a
Xufstype=ufs
Xopts=rw,grpid,nosuid
X
Xdirs="$1"
Xpart="$2"
Xsfx=".cf"
X(
Xcat $part | sed -e 's/#.*//' -e '/^$/d'
Xecho ""
Xcat $dirs | sed -e 's/#.*//' -e '/^$/d'
X) |
Xawk '
XBEGIN {
X	dirs = "'"$dirs"$sfx'"; part = "'"$part"$sfx'"; fstab = "'"$part"'.fstab"
X	seen_blank = -1
X	npart = 0
X	status = 0
X	print "# /home" > part
X	printf "/defaults \\\n\ttype=nfs;opts=%s\n", "'"$opts"'" >> part
X	print "# /homes" > dirs
X	printf "/defaults \\\n\ttype=nfs;opts=%s\n", "'"$opts"'" >> dirs
X	printf "" > fstab
X}
Xseen_blank < 0 {
X	if (NF == 0) {
X		seen_blank = NR
X		next
X	} else {
X		if (split($1, dev, ":") != 2) {
X			printf "line %d, $s is not host:/dev/disk\n", NR
X			status = 1
X		}
X#
X# Generate an /etc/fstab line
X# dev	/a/dom/host/whatever	type	opts	n n
X# or
X# dev	/a/host/whatever	type	opts	n n
X#
X		if (NF != 3)
X			fstype = "'"$ufstype"'"
X		else
X			fstype = $3
X
X		printf "#\n# Fstab entry for %s\n#\n", dev[1] >> fstab
X		printf "%s\t%s/%s%s\t%s\t%s\t0 1\n", dev[2], "'"$autoroot"'", dev[1], $2, fstype, "'"$opts"'" >> fstab
X
X		device[npart] = dev[2]
X		partition[npart] = $2
X		hostname[$2] = dev[1]
X		n = split($2, v, "/")
X#		printf "%d: dev = %s, part = %s, n = %d\n", npart, dev[2], $2, n
X		mc = ""
X		if (n < 3 || v[2] != "home") {
X			printf "line %d, %s is not of the form /home/machine/...", NR, $2
X			status = 1
X		} else {
X			mc = v[3]
X			for (p = 3; p < n; p++) {
X				if (automap[mc] == "") {
X					automap[mc] = mc;
X					printf "%s", mc >> part
X					if (length(mc) > 7) print " \\" >> part
X					printf "\ttype=auto;fs=${map};pref=%s/\n", mc >> part
X				}
X				mc = mc "/" v[p+1]
X			}
X			printf "%s", mc >> part
X			if (length(mc) > 7) print " \\" >> part
X			printf "\trfs=%s;rhost=%s\n", $2, dev[1] >> part
X			npart++
X		}
X	}
X}
X
Xseen_blank >= 0 {
X	user = $1
X	dir = $2
X	n = split(dir, v, "/")
X#	printf "n = %d, user = %s, dir = %s\n", n, user, dir
X	if (n < 4 || v[2] != "home") {
X		printf "Warning: %s (~%s) is not of the form /home/machine/...\n", dir, user
X		printf "%s", user >> dirs
X		if (length(user) > 7) print " \\" >> dirs
X		printf "\ttype=link;fs=%s\n", dir >> dirs
X	} else {
X		fs = ""
X		other = ""
X		path = "/home"
X		i = 3;
X		while (i < n) {
X			path = path "/" v[i];
X			for (p = 0; p < npart; p++) {
X#				printf "checking path %s against partition %s\n", path, partition[p]
X				if (partition[p] == path) {
X					fs = path
X					bdev = device[p]
X					machine = hostname[fs]
X#					printf "machine = %s\n", machine
X					break
X				}
X			}
X			i++
X			if (fs != "")
X				break
X		}
X		if (fs != "") {
X			rest = ""
X			while (i <= n) {
X				rest = rest v[i]
X#				printf "i = %d, n = %d, rest = %s\n", i, n, rest
X				if (i != n)
X					rest = rest "/"
X				i++
X			}
X
X#			printf "user=%s, filesys=%s, rest=%s, machine=%s\n", user, fs, rest, machine
X			printf "%s", user >> dirs
X			if (length(user) > 7) print " \\" >> dirs
X			printf "\trfs=%s;rhost=%s;sublink=%s\n", fs, machine, rest >> dirs
X		} else {
X			printf "ERROR: Cannot find a partition for %s (~%s)\n", dir, user
X			status = 1
X		}
X	}
X}
XEND {
X	exit(status)
X}
X' >&2
X
END_OF_FILE
if test 3570 -ne `wc -c <'scripts/mk-home-maps'`; then
    echo shar: \"'scripts/mk-home-maps'\" unpacked with wrong size!
fi
chmod +x 'scripts/mk-home-maps'
# end of 'scripts/mk-home-maps'
fi
if test -f 'srvr_afs.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'srvr_afs.c'\"
else
echo shar: Extracting \"'srvr_afs.c'\" \(3865 characters\)
sed "s/^X//" >'srvr_afs.c' <<'END_OF_FILE'
X/*
X * $Id: srvr_afs.c,v 5.1 89/11/17 18:22:16 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 * Automount FS server ("localhost") modeling
X */
X
X#include "am.h"
X
Xextern qelem afs_srvr_list;
Xqelem afs_srvr_list = { &afs_srvr_list, &afs_srvr_list };
X
Xstatic fserver *localhost;
X
X/*
X * Find an nfs server for the local host
X */
Xfserver *find_afs_srvr P((mntfs *));
Xfserver *find_afs_srvr(mf)
Xmntfs *mf;
X{
X	fserver *fs = localhost;
X
X	if (!fs) {
X		fs = ALLOC(fserver);
X		fs->fs_refc = 0;
X		fs->fs_host = strdup("localhost");
X		fs->fs_ip = 0;
X		fs->fs_cid = 0;
X		fs->fs_pinger = 0;
X		fs->fs_flags = FSF_VALID;
X		fs->fs_private = 0;
X		fs->fs_prfree = 0;
X
X		ins_que(&fs->fs_q, &afs_srvr_list);
X		localhost = fs;
X	}
X
X	fs->fs_refc++;
X
X	return fs;
X}
X
X/*------------------------------------------------------------------*/
X		/* Generic routines follow */
X
X/*
X * Wakeup anything waiting for this server
X */
Xvoid wakeup_srvr P((fserver *fs));
Xvoid wakeup_srvr(fs)
Xfserver *fs;
X{
X	fs->fs_flags &= ~FSF_WANT;
X	wakeup((voidp) fs);
X}
X
X/*
X * Called when final ttl of server has expired
X */
Xstatic void timeout_srvr P((fserver *fs));
Xstatic void timeout_srvr(fs)
Xfserver *fs;
X{
X	/*
X	 * If the reference count is still zero then
X	 * we are free to remove this node
X	 */
X	if (fs->fs_refc == 0) {
X#ifdef DEBUG
X		dlog("Deleting file server %s", fs->fs_host);
X#endif
X		if (fs->fs_flags & FSF_WANT)
X			wakeup_srvr(fs);
X
X		/*
X		 * Remove from queue.
X		 */
X		rem_que(&fs->fs_q);
X		/*
X		 * (Possibly) call the private free routine.
X		 */
X		if (fs->fs_private && fs->fs_prfree)
X			(*fs->fs_prfree)(fs->fs_private);
X
X		/*
X		 * Free the net address
X		 */
X		if (fs->fs_ip)
X			free((voidp) fs->fs_ip);
X
X		/*
X		 * Free the host name.
X		 */
X		free((voidp) fs->fs_host);
X
X		/*
X		 * Discard the fserver object.
X		 */
X		free((voidp) fs);
X	}
X}
X
X/*
X * Free a file server
X */
Xvoid free_srvr P((fserver *fs));
Xvoid free_srvr(fs)
Xfserver *fs;
X{
X	if (--fs->fs_refc == 0) {
X		/*
X		 * The reference count is now zero,
X		 * so arrange for this node to be
X		 * removed in AM_TTL seconds if no
X		 * other mntfs is referencing it.
X		 */
X		int ttl = (fs->fs_flags & (FSF_DOWN|FSF_ERROR)) ? 19 : AM_TTL;
X#ifdef DEBUG
X		dlog("Last hard reference to file server %s - will timeout in %ds", fs->fs_host, ttl);
X#endif
X		if (fs->fs_cid) {
X			untimeout(fs->fs_cid);
X			/*
X			 * Turn off pinging - XXX
X			 */
X			fs->fs_flags &= ~FSF_PINGING;
X		}
X		/*
X		 * Keep structure lying around for a while
X		 */
X		fs->fs_cid = timeout(ttl, timeout_srvr, (voidp) fs);
X		/*
X		 * Mark the fileserver down and invalid again
X		 */
X		fs->fs_flags &= ~FSF_VALID;
X		fs->fs_flags |= FSF_DOWN;
X	}
X}
X
X/*
X * Make a duplicate fserver reference
X */
Xfserver *dup_srvr P((fserver *fs));
Xfserver *dup_srvr(fs)
Xfserver *fs;
X{
X	fs->fs_refc++;
X	return fs;
X}
END_OF_FILE
if test 3865 -ne `wc -c <'srvr_afs.c'`; then
    echo shar: \"'srvr_afs.c'\" unpacked with wrong size!
fi
# end of 'srvr_afs.c'
fi
if test -f 'ufs_ops.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ufs_ops.c'\"
else
echo shar: Extracting \"'ufs_ops.c'\" \(3269 characters\)
sed "s/^X//" >'ufs_ops.c' <<'END_OF_FILE'
X/*
X * $Id: ufs_ops.c,v 5.1.1.2 90/01/11 17:22:09 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#ifdef HAS_UFS
X
X#include <sys/stat.h>
X#ifdef NFS_3
Xtypedef nfs_fh fhandle_t;
X#endif
X#include <sys/mount.h>
X
X#ifdef UFS_HDR
X#include UFS_HDR
X#endif
X
X/*
X * UN*X file system
X */
X
X/*
X * UFS needs local filesystem and device.
X */
Xstatic int ufs_match(fo)
Xam_opts *fo;
X{
X	if (!fo->opt_dev) {
X		plog(XLOG_USER, "ufs: no device specified");
X		return 0;
X	}
X	/*
X	 * Determine magic cookie to put in mtab
X	 */
X	fo->fs_mtab = strealloc(fo->fs_mtab, fo->opt_dev);
X#ifdef DEBUG
X	dlog("UFS: mounting device \"%s\" on \"%s\"",
X		fo->opt_dev, fo->opt_fs);
X#endif
X
X	return 1;
X}
X
Xstatic mount_ufs(dir, fs_name, opts)
Xchar *dir;
Xchar *fs_name;
Xchar *opts;
X{
X	struct ufs_args ufs_args;
X	struct mntent mnt;
X	int flags;
X
X	/*
X	 * Figure out the name of the file system type.
X	 */
X#ifdef M_NEWTYPE
X	char *type = MOUNT_TYPE_UFS;
X#else
X	int type = MOUNT_TYPE_UFS;
X#endif
X
X	bzero((voidp) &ufs_args, sizeof(ufs_args));	/* Paranoid */
X
X	/*
X	 * Fill in the mount structure
X	 */
X	mnt.mnt_dir = dir;
X	mnt.mnt_fsname = fs_name;
X	mnt.mnt_type = MTAB_TYPE_UFS;
X	mnt.mnt_opts = opts;
X	mnt.mnt_freq = 1;
X	mnt.mnt_passno = 2;
X
X	flags = compute_mount_flags(&mnt);
X
X#ifdef ULTRIX_HACK
X	ufs_args.ufs_flags = flags;
X	ufs_args.ufs_pgthresh = 64; /* 64K - XXX */
X	flags &= M_RDONLY;
X#else
X	ufs_args.fspec = fs_name;
X#endif
X
X	/*
X	 * Call generic mount routine
X	 */
X	return mount_fs(&mnt, flags, (caddr_t) &ufs_args, 0, type);
X}
X
X/*ARGSUSED*/
Xstatic int ufs_mount(mp)
Xam_node *mp;
X{
X	mntfs *mf = mp->am_mnt;
X
X	int error;
X
X	error = mount_ufs(mf->mf_mount, mf->mf_info, mf->mf_fo->opt_opts);
X	if (error) {
X		errno = error;
X		plog(XLOG_ERROR, "mount_ufs: %m");
X		return error;
X	}
X
X	return 0;
X}
X
Xstatic int ufs_umount(mp)
Xam_node *mp;
X{
X	mntfs *mf = mp->am_mnt;
X
X	return UMOUNT_FS(mf->mf_mount);
X}
X
X/*
X * Ops structure
X */
Xam_ops ufs_ops = {
X	"ufs",
X	ufs_match,
X	0, /* ufs_init */
X	ufs_mount,
X	ufs_umount,
X	efs_lookuppn,
X	efs_readdir,
X	0, /* ufs_readlink */
X	0, /* ufs_mounted */
X	0, /* ufs_umounted */
X	find_afs_srvr,
X	FS_MKMNT|FS_NOTIMEOUT|FS_UBACKGROUND|FS_AMQINFO,
X	&afs_srvr_list,
X};
X
X#endif /* HAS_UFS */
END_OF_FILE
if test 3269 -ne `wc -c <'ufs_ops.c'`; then
    echo shar: \"'ufs_ops.c'\" unpacked with wrong size!
fi
# end of 'ufs_ops.c'
fi
echo shar: End of archive 3 \(of 13\).
cp /dev/null ark3isdone
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.