Import of Erez Zadok's am-utils
This commit is contained in:
parent
5dbbebc601
commit
5feec48523
67
usr.sbin/amd/AUTHORS
Normal file
67
usr.sbin/amd/AUTHORS
Normal file
@ -0,0 +1,67 @@
|
||||
# -*- text -*-
|
||||
PRIMARY AUTHORS AND MAJOR CONTRIBUTORS TO AM_UTILS:
|
||||
|
||||
Original authors of amd were the Berkeley team and especially Jan-Simon
|
||||
Pendry. Since then many people have contributed patches.
|
||||
|
||||
This file lists the ones who contributed major code changes, and I thank
|
||||
them all. This is of course not to diminish the smaller contributes of the
|
||||
many others. Thank you all.
|
||||
|
||||
* Erez Zadok <ezk@cs.columbia.edu>
|
||||
|
||||
The most significant changes were made by Erez Zadok in terms of bug fixes,
|
||||
ports, and new features added. Erez Zadok is the current maintainer of
|
||||
am-utils, as of January 1997.
|
||||
|
||||
There is a mailing list dedicated to developers of am-utils. To subscribe
|
||||
to it, send mail to majordomo@majordomo.cs.columbia.edu, with the body of
|
||||
the message having the single line "subscribe amd-dev".
|
||||
|
||||
* Randall S. Winchester <rsw@glue.umd.edu>
|
||||
|
||||
May 7, 1997: contributed a special version of upl102 that included NFS V.3
|
||||
support. Some of the code was contributed by Christos Zoulas
|
||||
<christos@deshaw.com>. I (Erez) ported these changes to am-utils.
|
||||
|
||||
* Hannes Reinecke <hare@MathI.UNI-Heidelberg.DE>
|
||||
|
||||
Back in 1995, contributed code for linux. A new parser for file system
|
||||
specific options that only exist under linux.
|
||||
|
||||
* Leif Johansson <leifj@matematik.su.se>
|
||||
|
||||
June 22, 1997: minor patch to ensure that systems without an RE library work.
|
||||
|
||||
June 23, 1997: mount options should be properly comma limited.
|
||||
|
||||
July 10, 1997: info_ldap.c and prototype changes to all map _init and _mtime
|
||||
functions. Contributed scripts/amd2ldif.pl.
|
||||
|
||||
* Andreas Stolcke <stolcke@speech.sri.com>
|
||||
|
||||
June 22, 1997: patches to ensure that proto= and vers= options work
|
||||
properly in mount tables and can be overridden. Later on, more code
|
||||
contribued to optimize the best combination of proto/vers.
|
||||
|
||||
July 4, 1997: patches to get NFS V.3 working under irix5.
|
||||
|
||||
* Danny Braniss <danny@cs.huji.ac.il>
|
||||
|
||||
July, 6 1997: contributed patches to hesiod on bsdi3.
|
||||
|
||||
* Tom Schmidt <tschmidt@micron.com>
|
||||
|
||||
July 10, 1997: Recommdation to include libgdbm if libc has no dbm_open.
|
||||
Patches for netgrp(host) command. Mods to aux/config.guess to recognize
|
||||
sun3.
|
||||
|
||||
* Daniel S. Riley <dsr@mail.lns.cornell.edu>
|
||||
|
||||
July 11, 1997: fixes to DU-4.0 to support string POSIX.1 signals, and struct
|
||||
sockaddr with sa_len field.
|
||||
|
||||
July 13, 1997: Move amd.conf parsing to before switch_option() on log/debug
|
||||
options. Minor type wrt "ro" option in libamu/mount_fs.c. Added more
|
||||
fillers of mnttab options, for acdirmax, acdirmin, acregmax, acregmin, noac,
|
||||
grpid, nosuid, and actimo.
|
36
usr.sbin/amd/COPYING
Normal file
36
usr.sbin/amd/COPYING
Normal file
@ -0,0 +1,36 @@
|
||||
Copyright (c) 1997 Erez Zadok
|
||||
Copyright (c) 1989 Jan-Simon Pendry
|
||||
Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
Copyright (c) 1989 The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
This code is derived from software contributed to Berkeley by
|
||||
Jan-Simon Pendry at Imperial College, London.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the University of
|
||||
California, Berkeley and its contributors.
|
||||
4. Neither the name of the University nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
148
usr.sbin/amd/amd/amq_svc.c
Normal file
148
usr.sbin/amd/amd/amq_svc.c
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: amq_svc.c,v 1.1.1.1 1997/07/24 21:20:37 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
|
||||
void
|
||||
amq_program_1(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
{
|
||||
union {
|
||||
amq_string amqproc_mnttree_1_arg;
|
||||
amq_string amqproc_umnt_1_arg;
|
||||
amq_setopt amqproc_setopt_1_arg;
|
||||
amq_string amqproc_mount_1_arg;
|
||||
} argument;
|
||||
char *result;
|
||||
bool_t(*xdr_argument) (), (*xdr_result) ();
|
||||
char *(*local) ();
|
||||
|
||||
switch (rqstp->rq_proc) {
|
||||
|
||||
case AMQPROC_NULL:
|
||||
xdr_argument = xdr_void;
|
||||
xdr_result = xdr_void;
|
||||
local = (char *(*)()) amqproc_null_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_MNTTREE:
|
||||
xdr_argument = xdr_amq_string;
|
||||
xdr_result = xdr_amq_mount_tree_p;
|
||||
local = (char *(*)()) amqproc_mnttree_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_UMNT:
|
||||
xdr_argument = xdr_amq_string;
|
||||
xdr_result = xdr_void;
|
||||
local = (char *(*)()) amqproc_umnt_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_STATS:
|
||||
xdr_argument = xdr_void;
|
||||
xdr_result = xdr_amq_mount_stats;
|
||||
local = (char *(*)()) amqproc_stats_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_EXPORT:
|
||||
xdr_argument = xdr_void;
|
||||
xdr_result = xdr_amq_mount_tree_list;
|
||||
local = (char *(*)()) amqproc_export_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_SETOPT:
|
||||
xdr_argument = xdr_amq_setopt;
|
||||
xdr_result = xdr_int;
|
||||
local = (char *(*)()) amqproc_setopt_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_GETMNTFS:
|
||||
xdr_argument = xdr_void;
|
||||
xdr_result = xdr_amq_mount_info_qelem;
|
||||
local = (char *(*)()) amqproc_getmntfs_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_MOUNT:
|
||||
xdr_argument = xdr_amq_string;
|
||||
xdr_result = xdr_int;
|
||||
local = (char *(*)()) amqproc_mount_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_GETVERS:
|
||||
xdr_argument = xdr_void;
|
||||
xdr_result = xdr_amq_string;
|
||||
local = (char *(*)()) amqproc_getvers_1_svc;
|
||||
break;
|
||||
|
||||
default:
|
||||
svcerr_noproc(transp);
|
||||
return;
|
||||
}
|
||||
|
||||
memset((char *) &argument, 0, sizeof(argument));
|
||||
if (!svc_getargs(transp,
|
||||
(XDRPROC_T_TYPE) xdr_argument,
|
||||
(SVC_IN_ARG_TYPE) & argument)) {
|
||||
svcerr_decode(transp);
|
||||
return;
|
||||
}
|
||||
|
||||
result = (*local) (&argument, rqstp);
|
||||
|
||||
if (result != NULL && !svc_sendreply(transp,
|
||||
(XDRPROC_T_TYPE) xdr_result,
|
||||
result)) {
|
||||
svcerr_systemerr(transp);
|
||||
}
|
||||
|
||||
if (!svc_freeargs(transp,
|
||||
(XDRPROC_T_TYPE) xdr_argument,
|
||||
(SVC_IN_ARG_TYPE) & argument)) {
|
||||
plog(XLOG_FATAL, "unable to free rpc arguments in amqprog_1");
|
||||
going_down(1);
|
||||
}
|
||||
}
|
469
usr.sbin/amd/amd/autil.c
Normal file
469
usr.sbin/amd/amd/autil.c
Normal file
@ -0,0 +1,469 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: autil.c,v 1.1.1.1 1997/07/24 21:20:37 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* utilities specified to amd, taken out of the older amd/util.c.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
int NumChild = 0; /* number of children of primary amd */
|
||||
static char invalid_keys[] = "\"'!;@ \t\n";
|
||||
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
# define PARENT_USLEEP_TIME 100000 /* 0.1 seconds */
|
||||
#endif /* HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
|
||||
char *
|
||||
strealloc(char *p, char *s)
|
||||
{
|
||||
int len = strlen(s) + 1;
|
||||
|
||||
p = (char *) xrealloc((voidp) p, len);
|
||||
|
||||
strcpy(p, s);
|
||||
#ifdef DEBUG_MEM
|
||||
malloc_verify();
|
||||
#endif /* DEBUG_MEM */
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
char **
|
||||
strsplit(char *s, int ch, int qc)
|
||||
{
|
||||
char **ivec;
|
||||
int ic = 0;
|
||||
int done = 0;
|
||||
|
||||
ivec = (char **) xmalloc((ic + 1) * sizeof(char *));
|
||||
|
||||
while (!done) {
|
||||
char *v;
|
||||
|
||||
/*
|
||||
* skip to split char
|
||||
*/
|
||||
while (*s && (ch == ' ' ? (isascii(*s) && isspace(*s)) : *s == ch))
|
||||
*s++ = '\0';
|
||||
|
||||
/*
|
||||
* End of string?
|
||||
*/
|
||||
if (!*s)
|
||||
break;
|
||||
|
||||
/*
|
||||
* remember start of string
|
||||
*/
|
||||
v = s;
|
||||
|
||||
/*
|
||||
* skip to split char
|
||||
*/
|
||||
while (*s && !(ch == ' ' ? (isascii(*s) && isspace(*s)) : *s == ch)) {
|
||||
if (*s++ == qc) {
|
||||
/*
|
||||
* Skip past string.
|
||||
*/
|
||||
s++;
|
||||
while (*s && *s != qc)
|
||||
s++;
|
||||
if (*s == qc)
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!*s)
|
||||
done = 1;
|
||||
*s++ = '\0';
|
||||
|
||||
/*
|
||||
* save string in new ivec slot
|
||||
*/
|
||||
ivec[ic++] = v;
|
||||
ivec = (char **) xrealloc((voidp) ivec, (ic + 1) * sizeof(char *));
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_STR)
|
||||
plog(XLOG_DEBUG, "strsplit saved \"%s\"", v);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_STR)
|
||||
plog(XLOG_DEBUG, "strsplit saved a total of %d strings", ic);
|
||||
#endif /* DEBUG */
|
||||
|
||||
ivec[ic] = 0;
|
||||
|
||||
return ivec;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Strip off the trailing part of a domain
|
||||
* to produce a short-form domain relative
|
||||
* to the local host domain.
|
||||
* Note that this has no effect if the domain
|
||||
* names do not have the same number of
|
||||
* components. If that restriction proves
|
||||
* to be a problem then the loop needs recoding
|
||||
* to skip from right to left and do partial
|
||||
* matches along the way -- ie more expensive.
|
||||
*/
|
||||
static void
|
||||
domain_strip(char *otherdom, char *localdom)
|
||||
{
|
||||
char *p1, *p2;
|
||||
|
||||
if ((p1 = strchr(otherdom, '.')) &&
|
||||
(p2 = strchr(localdom, '.')) &&
|
||||
STREQ(p1 + 1, p2 + 1))
|
||||
*p1 = '\0';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Normalize a host name
|
||||
*/
|
||||
void
|
||||
host_normalize(char **chp)
|
||||
{
|
||||
/*
|
||||
* Normalize hosts is used to resolve host name aliases
|
||||
* and replace them with the standard-form name.
|
||||
* Invoked with "-n" command line option.
|
||||
*/
|
||||
if (gopt.flags & CFM_NORMALIZE_HOSTNAMES) {
|
||||
struct hostent *hp;
|
||||
clock_valid = 0;
|
||||
hp = gethostbyname(*chp);
|
||||
if (hp && hp->h_addrtype == AF_INET) {
|
||||
#ifdef DEBUG
|
||||
dlog("Hostname %s normalized to %s", *chp, hp->h_name);
|
||||
#endif /* DEBUG */
|
||||
*chp = strealloc(*chp, (char *) hp->h_name);
|
||||
}
|
||||
}
|
||||
domain_strip(*chp, hostd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Keys are not allowed to contain " ' ! or ; to avoid
|
||||
* problems with macro expansions.
|
||||
*/
|
||||
int
|
||||
valid_key(char *key)
|
||||
{
|
||||
while (*key)
|
||||
if (strchr(invalid_keys, *key++))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
forcibly_timeout_mp(am_node *mp)
|
||||
{
|
||||
mntfs *mf = mp->am_mnt;
|
||||
/*
|
||||
* Arrange to timeout this node
|
||||
*/
|
||||
if (mf && ((mp->am_flags & AMF_ROOT) ||
|
||||
(mf->mf_flags & (MFF_MOUNTING | MFF_UNMOUNTING)))) {
|
||||
if (!(mf->mf_flags & MFF_UNMOUNTING))
|
||||
plog(XLOG_WARNING, "ignoring timeout request for active node %s", mp->am_path);
|
||||
} else {
|
||||
plog(XLOG_INFO, "\"%s\" forcibly timed out", mp->am_path);
|
||||
mp->am_flags &= ~AMF_NOTIMEOUT;
|
||||
mp->am_ttl = clocktime();
|
||||
reschedule_timeout_mp();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mf_mounted(mntfs *mf)
|
||||
{
|
||||
int quoted;
|
||||
int wasmounted = mf->mf_flags & MFF_MOUNTED;
|
||||
|
||||
if (!wasmounted) {
|
||||
/*
|
||||
* If this is a freshly mounted
|
||||
* filesystem then update the
|
||||
* mntfs structure...
|
||||
*/
|
||||
mf->mf_flags |= MFF_MOUNTED;
|
||||
mf->mf_error = 0;
|
||||
|
||||
/*
|
||||
* Do mounted callback
|
||||
*/
|
||||
if (mf->mf_ops->mounted) {
|
||||
(*mf->mf_ops->mounted) (mf);
|
||||
}
|
||||
mf->mf_fo = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Log message
|
||||
*/
|
||||
quoted = strchr(mf->mf_info, ' ') != 0;
|
||||
plog(XLOG_INFO, "%s%s%s %s fstype %s on %s",
|
||||
quoted ? "\"" : "",
|
||||
mf->mf_info,
|
||||
quoted ? "\"" : "",
|
||||
wasmounted ? "referenced" : "mounted",
|
||||
mf->mf_ops->fs_type, mf->mf_mount);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
am_mounted(am_node *mp)
|
||||
{
|
||||
mntfs *mf = mp->am_mnt;
|
||||
|
||||
mf_mounted(mf);
|
||||
|
||||
/*
|
||||
* Patch up path for direct mounts
|
||||
*/
|
||||
if (mp->am_parent && mp->am_parent->am_mnt->mf_ops == &dfs_ops)
|
||||
mp->am_path = str3cat(mp->am_path, mp->am_parent->am_path, "/", ".");
|
||||
|
||||
/*
|
||||
* Check whether this mount should be cached permanently
|
||||
*/
|
||||
if (mf->mf_ops->fs_flags & FS_NOTIMEOUT) {
|
||||
mp->am_flags |= AMF_NOTIMEOUT;
|
||||
} else if (mf->mf_mount[1] == '\0' && mf->mf_mount[0] == '/') {
|
||||
mp->am_flags |= AMF_NOTIMEOUT;
|
||||
} else {
|
||||
mntent_t mnt;
|
||||
if (mf->mf_mopts) {
|
||||
mnt.mnt_opts = mf->mf_mopts;
|
||||
if (hasmntopt(&mnt, "nounmount"))
|
||||
mp->am_flags |= AMF_NOTIMEOUT;
|
||||
if ((mp->am_timeo = hasmntval(&mnt, "utimeout")) == 0)
|
||||
mp->am_timeo = gopt.am_timeo;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If this node is a symlink then
|
||||
* compute the length of the returned string.
|
||||
*/
|
||||
if (mp->am_fattr.na_type == NFLNK)
|
||||
mp->am_fattr.na_size = strlen(mp->am_link ? mp->am_link : mp->am_mnt->mf_mount);
|
||||
|
||||
/*
|
||||
* Record mount time
|
||||
*/
|
||||
mp->am_fattr.na_mtime.nt_seconds = mp->am_stats.s_mtime = clocktime();
|
||||
new_ttl(mp);
|
||||
|
||||
/*
|
||||
* Update mtime of parent node
|
||||
*/
|
||||
if (mp->am_parent && mp->am_parent->am_mnt)
|
||||
mp->am_parent->am_fattr.na_mtime.nt_seconds = mp->am_stats.s_mtime;
|
||||
|
||||
/*
|
||||
* Now, if we can, do a reply to our NFS client here
|
||||
* to speed things up.
|
||||
*/
|
||||
quick_reply(mp, 0);
|
||||
|
||||
/*
|
||||
* Update stats
|
||||
*/
|
||||
amd_stats.d_mok++;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mount_node(am_node *mp)
|
||||
{
|
||||
mntfs *mf = mp->am_mnt;
|
||||
int error;
|
||||
|
||||
mf->mf_flags |= MFF_MOUNTING;
|
||||
error = (*mf->mf_ops->mount_fs) (mp);
|
||||
mf = mp->am_mnt;
|
||||
if (error >= 0)
|
||||
mf->mf_flags &= ~MFF_MOUNTING;
|
||||
if (!error && !(mf->mf_ops->fs_flags & FS_MBACKGROUND)) {
|
||||
/* ...but see ifs_mount */
|
||||
am_mounted(mp);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
am_unmounted(am_node *mp)
|
||||
{
|
||||
mntfs *mf = mp->am_mnt;
|
||||
|
||||
if (!foreground) /* firewall - should never happen */
|
||||
return;
|
||||
|
||||
/*
|
||||
* Do unmounted callback
|
||||
*/
|
||||
if (mf->mf_ops->umounted)
|
||||
(*mf->mf_ops->umounted) (mp);
|
||||
|
||||
/*
|
||||
* Update mtime of parent node
|
||||
*/
|
||||
if (mp->am_parent && mp->am_parent->am_mnt)
|
||||
mp->am_parent->am_fattr.na_mtime.nt_seconds = clocktime();
|
||||
|
||||
free_map(mp);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
auto_fmount(am_node *mp)
|
||||
{
|
||||
mntfs *mf = mp->am_mnt;
|
||||
return (*mf->mf_ops->fmount_fs) (mf);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
auto_fumount(am_node *mp)
|
||||
{
|
||||
mntfs *mf = mp->am_mnt;
|
||||
return (*mf->mf_ops->fumount_fs) (mf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fork the automounter
|
||||
*
|
||||
* TODO: Need a better strategy for handling errors
|
||||
*/
|
||||
static int
|
||||
dofork(void)
|
||||
{
|
||||
int pid;
|
||||
|
||||
top:
|
||||
pid = fork();
|
||||
|
||||
if (pid < 0) { /* fork error, retry in 1 second */
|
||||
sleep(1);
|
||||
goto top;
|
||||
}
|
||||
if (pid == 0) { /* child process (foreground==false) */
|
||||
mypid = getpid();
|
||||
foreground = 0;
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI_off
|
||||
/*
|
||||
* The sleep() right here is a hacky solution to some race conditions on
|
||||
* some systems, esp. Solaris with TLI on fast CPUs. Without it, all
|
||||
* top-level mounts bombard the system very fast, and some of them,
|
||||
* possibly the non-blocking RPCs, get lost. It is not guaranteed who
|
||||
* and how many get lost; sometimes none, sometimes all but one. I've
|
||||
* seen things like that under older systems like Mach-3 Either way.
|
||||
* This hack seems to solve the problem. Note that the sleep() is
|
||||
* progressively greater as there are more children, so as to
|
||||
* "randomize" the order in which they will reply back to the parent amd
|
||||
* process. It helps in getting the replies delivered back in order.
|
||||
* These hopefully don't slow down amd by much overall. For the time
|
||||
* being, I'm going to make this code dependent on TLI, because I have
|
||||
* no evidence that it is needed on any other system. Anyone is welcome
|
||||
* to figure out the bug or race condition.
|
||||
*
|
||||
* It is also possible that if there are too many children sending out
|
||||
* their (unreliable) UDP datagrams over the fwd_sock, that some of them
|
||||
* simply get lost. Then there's always the possibility that this is a
|
||||
* kernel networking bug.
|
||||
*
|
||||
* -Erez Zadok <ezk@cs.columbia.edu>
|
||||
*/
|
||||
if (NumChild > 0) {
|
||||
plog(XLOG_INFO,"too many background children(%d). sleep %d mSec...",
|
||||
NumChild, PARENT_USLEEP_TIME*NumChild);
|
||||
usleep(PARENT_USLEEP_TIME*NumChild);
|
||||
}
|
||||
#endif /* HAVE_TRANSPORT_TYPE_TLI */
|
||||
} else { /* parent process, has one more child */
|
||||
NumChild++;
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI_off
|
||||
if (NumChild > 1) {
|
||||
plog(XLOG_INFO,"parent sleeps for %d mSec...",
|
||||
PARENT_USLEEP_TIME*NumChild);
|
||||
usleep(PARENT_USLEEP_TIME*NumChild);
|
||||
}
|
||||
#endif /* HAVE_TRANSPORT_TYPE_TLI */
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
background(void)
|
||||
{
|
||||
int pid = dofork();
|
||||
|
||||
if (pid == 0) {
|
||||
#ifdef DEBUG
|
||||
dlog("backgrounded");
|
||||
#endif /* DEBUG */
|
||||
foreground = 0;
|
||||
}
|
||||
return pid;
|
||||
}
|
3
usr.sbin/amd/amd/build_version.h
Normal file
3
usr.sbin/amd/amd/build_version.h
Normal file
@ -0,0 +1,3 @@
|
||||
/* do not edit this file by hand */
|
||||
/* auto-generated by update_build_version script */
|
||||
#define AMU_BUILD_VERSION 1
|
767
usr.sbin/amd/amd/conf.c
Normal file
767
usr.sbin/amd/amd/conf.c
Normal file
@ -0,0 +1,767 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: conf.c,v 1.1.1.1 1997/07/24 21:20:42 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Functions to handle the configuration file.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
|
||||
/*
|
||||
* MACROS:
|
||||
*/
|
||||
/* Turn on to show some info about maps being configured */
|
||||
/* #define DEBUG_CONF */
|
||||
|
||||
/*
|
||||
* TYPEDEFS:
|
||||
*/
|
||||
typedef int (*OptFuncPtr)(const char *);
|
||||
|
||||
/*
|
||||
* STRUCTURES:
|
||||
*/
|
||||
struct _func_map {
|
||||
char *name;
|
||||
OptFuncPtr func;
|
||||
};
|
||||
|
||||
/*
|
||||
* FORWARD DECLARATIONS:
|
||||
*/
|
||||
static int gopt_arch(const char *val);
|
||||
static int gopt_auto_dir(const char *val);
|
||||
static int gopt_browsable_dirs(const char *val);
|
||||
static int gopt_cache_duration(const char *val);
|
||||
static int gopt_cluster(const char *val);
|
||||
static int gopt_debug_options(const char *val);
|
||||
static int gopt_dismount_interval(const char *val);
|
||||
static int gopt_karch(const char *val);
|
||||
static int gopt_ldap_base(const char *val);
|
||||
static int gopt_ldap_hostports(const char *val);
|
||||
static int gopt_local_domain(const char *val);
|
||||
static int gopt_log_file(const char *val);
|
||||
static int gopt_log_options(const char *val);
|
||||
static int gopt_map_options(const char *val);
|
||||
static int gopt_map_type(const char *val);
|
||||
static int gopt_mount_type(const char *val);
|
||||
static int gopt_nfs_retransmit_counter(const char *val);
|
||||
static int gopt_nfs_retry_interval(const char *val);
|
||||
static int gopt_nis_domain(const char *val);
|
||||
static int gopt_normalize_hostnames(const char *val);
|
||||
static int gopt_os(const char *val);
|
||||
static int gopt_osver(const char *val);
|
||||
static int gopt_plock(const char *val);
|
||||
static int gopt_print_pid(const char *val);
|
||||
static int gopt_print_version(const char *val);
|
||||
static int gopt_restart_mounts(const char *val);
|
||||
static int gopt_search_path(const char *val);
|
||||
static int gopt_selectors_on_default(const char *val);
|
||||
static int process_global_option(const char *key, const char *val);
|
||||
static int process_regular_map(cf_map_t *cfm);
|
||||
static int process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm);
|
||||
static int ropt_browsable_dirs(const char *val, cf_map_t *cfm);
|
||||
static int ropt_map_name(const char *val, cf_map_t *cfm);
|
||||
static int ropt_map_options(const char *val, cf_map_t *cfm);
|
||||
static int ropt_map_type(const char *val, cf_map_t *cfm);
|
||||
static int ropt_mount_type(const char *val, cf_map_t *cfm);
|
||||
static int ropt_search_path(const char *val, cf_map_t *cfm);
|
||||
static int ropt_tag(const char *val, cf_map_t *cfm);
|
||||
static void reset_cf_map(cf_map_t *cfm);
|
||||
|
||||
|
||||
/*
|
||||
* STATIC VARIABLES:
|
||||
*/
|
||||
static cf_map_t cur_map;
|
||||
static struct _func_map glob_functable[] = {
|
||||
{"arch", gopt_arch},
|
||||
{"auto_dir", gopt_auto_dir},
|
||||
{"browsable_dirs", gopt_browsable_dirs},
|
||||
{"cache_duration", gopt_cache_duration},
|
||||
{"cluster", gopt_cluster},
|
||||
{"debug_options", gopt_debug_options},
|
||||
{"dismount_interval", gopt_dismount_interval},
|
||||
{"karch", gopt_karch},
|
||||
{"ldap_base", gopt_ldap_base},
|
||||
{"ldap_hostports", gopt_ldap_hostports},
|
||||
{"local_domain", gopt_local_domain},
|
||||
{"log_file", gopt_log_file},
|
||||
{"log_options", gopt_log_options},
|
||||
{"map_options", gopt_map_options},
|
||||
{"map_type", gopt_map_type},
|
||||
{"mount_type", gopt_mount_type},
|
||||
{"nfs_retransmit_counter", gopt_nfs_retransmit_counter},
|
||||
{"nfs_retry_interval", gopt_nfs_retry_interval},
|
||||
{"nis_domain", gopt_nis_domain},
|
||||
{"normalize_hostnames", gopt_normalize_hostnames},
|
||||
{"os", gopt_os},
|
||||
{"osver", gopt_osver},
|
||||
{"plock", gopt_plock},
|
||||
{"print_pid", gopt_print_pid},
|
||||
{"print_version", gopt_print_version},
|
||||
{"restart_mounts", gopt_restart_mounts},
|
||||
{"search_path", gopt_search_path},
|
||||
{"selectors_on_default", gopt_selectors_on_default},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Reset a map.
|
||||
*/
|
||||
static void
|
||||
reset_cf_map(cf_map_t *cfm)
|
||||
{
|
||||
if (!cfm)
|
||||
return;
|
||||
|
||||
if (cfm->cfm_dir) {
|
||||
free(cfm->cfm_dir);
|
||||
cfm->cfm_dir = NULL;
|
||||
}
|
||||
|
||||
if (cfm->cfm_name) {
|
||||
free(cfm->cfm_name);
|
||||
cfm->cfm_name = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* reset/initialize a regular map's flags and other variables from the
|
||||
* global ones, so that they are applied to all maps. Of course, each map
|
||||
* can then override the flags individually.
|
||||
*
|
||||
* NOTES:
|
||||
* (1): Will only work for maps that appear after [global].
|
||||
* (2): Also be careful not to free() a global option.
|
||||
* (3): I'm doing direct char* pointer comparison, and not strcmp(). This
|
||||
* is correct!
|
||||
*/
|
||||
|
||||
/* initialize map_type from [global] */
|
||||
if (cfm->cfm_type && cfm->cfm_type != gopt.map_type)
|
||||
free(cfm->cfm_type);
|
||||
cfm->cfm_type = gopt.map_type;
|
||||
|
||||
/* initialize map_opts from [global] */
|
||||
if (cfm->cfm_opts && cfm->cfm_opts != gopt.map_options)
|
||||
free(cfm->cfm_opts);
|
||||
cfm->cfm_opts = gopt.map_options;
|
||||
|
||||
/* initialize search_path from [global] */
|
||||
if (cfm->cfm_search_path && cfm->cfm_search_path != gopt.search_path)
|
||||
free(cfm->cfm_search_path);
|
||||
cfm->cfm_search_path = gopt.search_path;
|
||||
|
||||
/*
|
||||
* Initialize flags that are common both to [global] and a local map.
|
||||
*/
|
||||
cfm->cfm_flags = gopt.flags & (CFM_BROWSABLE_DIRS |
|
||||
CFM_MOUNT_TYPE_AUTOFS |
|
||||
CFM_ENABLE_DEFAULT_SELECTORS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process configuration file options.
|
||||
* Return 0 if OK, 1 otherwise.
|
||||
*/
|
||||
int
|
||||
set_conf_kv(const char *section, const char *key, const char *val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef DEBUG_CONF
|
||||
fprintf(stderr,"set_conf_kv: section=%s, key=%s, val=%s\n",
|
||||
section, key, val);
|
||||
#endif /* DEBUG_CONF */
|
||||
|
||||
/*
|
||||
* If global section, process them one at a time.
|
||||
*/
|
||||
if (STREQ(section, "global")) {
|
||||
/*
|
||||
* Check if a regular map was configured before "global",
|
||||
* and process it as needed.
|
||||
*/
|
||||
if (cur_map.cfm_dir) {
|
||||
fprintf(stderr,"processing regular map \"%s\" before global one.\n",
|
||||
section);
|
||||
ret = process_regular_map(&cur_map); /* will reset map */
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* process the global option first */
|
||||
ret = process_global_option(key, val);
|
||||
|
||||
/* reset default options for regular maps from just updated globals */
|
||||
if (ret == 0)
|
||||
reset_cf_map(&cur_map);
|
||||
|
||||
/* return status from the processing of the global option */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* otherwise save options and process a single map all at once.
|
||||
*/
|
||||
|
||||
/* check if we found a new map, so process one already collected */
|
||||
if (cur_map.cfm_dir && !STREQ(cur_map.cfm_dir, section)) {
|
||||
ret = process_regular_map(&cur_map); /* will reset map */
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* now process a single entry of a regular map */
|
||||
return process_regular_option(section, key, val, &cur_map);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process global section of configuration file options.
|
||||
* Return 0 upon success, 1 otherwise.
|
||||
*/
|
||||
static int
|
||||
process_global_option(const char *key, const char *val)
|
||||
{
|
||||
struct _func_map *gfp;
|
||||
|
||||
/* ensure that val is valid */
|
||||
if (!val || val[0] == '\0')
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* search for global function.
|
||||
*/
|
||||
for (gfp = glob_functable; gfp->name; gfp++)
|
||||
if (FSTREQ(gfp->name, key))
|
||||
return (gfp->func)(val);
|
||||
|
||||
fprintf(stderr, "conf: unknown global key: \"%s\"\n", key);
|
||||
return 1; /* failed to match any command */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_arch(const char *val)
|
||||
{
|
||||
gopt.arch = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_auto_dir(const char *val)
|
||||
{
|
||||
gopt.auto_dir = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_browsable_dirs(const char *val)
|
||||
{
|
||||
if (STREQ(val, "yes")) {
|
||||
gopt.flags |= CFM_BROWSABLE_DIRS;
|
||||
return 0;
|
||||
} else if (STREQ(val, "no")) {
|
||||
gopt.flags &= ~CFM_BROWSABLE_DIRS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
|
||||
return 1; /* unknown value */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_cache_duration(const char *val)
|
||||
{
|
||||
gopt.am_timeo = atoi(val);
|
||||
if (gopt.am_timeo <= 0)
|
||||
gopt.am_timeo = AM_TTL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_cluster(const char *val)
|
||||
{
|
||||
gopt.cluster = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_debug_options(const char *val)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
usage += debug_option(strdup((char *)val));
|
||||
return 0;
|
||||
#else /* not DEBUG */
|
||||
fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n",
|
||||
progname);
|
||||
return 1;
|
||||
#endif /* not DEBUG */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_dismount_interval(const char *val)
|
||||
{
|
||||
gopt.am_timeo_w = atoi(val);
|
||||
if (gopt.am_timeo_w <= 0)
|
||||
gopt.am_timeo_w = AM_TTL_W;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_karch(const char *val)
|
||||
{
|
||||
gopt.karch = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_local_domain(const char *val)
|
||||
{
|
||||
gopt.sub_domain = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_ldap_base(const char *val)
|
||||
{
|
||||
#ifdef HAVE_MAP_LDAP
|
||||
gopt.ldap_base = strdup((char *)val);
|
||||
return 0;
|
||||
#else /* not HAVE_MAP_LDAP */
|
||||
fprintf(stderr, "conf: ldap_base option ignored. No LDAP support available.\n");
|
||||
return 1;
|
||||
#endif /* not HAVE_MAP_LDAP */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_ldap_hostports(const char *val)
|
||||
{
|
||||
#ifdef HAVE_MAP_LDAP
|
||||
gopt.ldap_hostports = strdup((char *)val);
|
||||
return 0;
|
||||
#else /* not HAVE_MAP_LDAP */
|
||||
fprintf(stderr, "conf: ldap_hostports option ignored. No LDAP support available.\n");
|
||||
return 1;
|
||||
#endif /* not HAVE_MAP_LDAP */
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_log_file(const char *val)
|
||||
{
|
||||
gopt.logfile = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_log_options(const char *val)
|
||||
{
|
||||
usage += switch_option(strdup((char *)val));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_map_options(const char *val)
|
||||
{
|
||||
gopt.map_options = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_map_type(const char *val)
|
||||
{
|
||||
gopt.map_type = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_mount_type(const char *val)
|
||||
{
|
||||
if (STREQ(val, "autofs")) {
|
||||
gopt.flags |= CFM_MOUNT_TYPE_AUTOFS;
|
||||
return 0;
|
||||
} else if (STREQ(val, "nfs")) {
|
||||
gopt.flags &= ~CFM_MOUNT_TYPE_AUTOFS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
|
||||
return 1; /* unknown value */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_nfs_retransmit_counter(const char *val)
|
||||
{
|
||||
gopt.afs_retrans = atoi(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_nfs_retry_interval(const char *val)
|
||||
{
|
||||
gopt.afs_timeo = atoi(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_nis_domain(const char *val)
|
||||
{
|
||||
#ifdef HAVE_MAP_NIS
|
||||
gopt.nis_domain = strdup((char *)val);
|
||||
return 0;
|
||||
#else /* not HAVE_MAP_NIS */
|
||||
fprintf(stderr, "conf: nis_domain option ignored. No NIS support available.\n");
|
||||
return 1;
|
||||
#endif /* not HAVE_MAP_NIS */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_normalize_hostnames(const char *val)
|
||||
{
|
||||
if (STREQ(val, "yes")) {
|
||||
gopt.flags |= CFM_NORMALIZE_HOSTNAMES;
|
||||
return 0;
|
||||
} else if (STREQ(val, "no")) {
|
||||
gopt.flags &= ~CFM_NORMALIZE_HOSTNAMES;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "conf: unknown value to normalize_hostnames \"%s\"\n", val);
|
||||
return 1; /* unknown value */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_os(const char *val)
|
||||
{
|
||||
gopt.op_sys = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_osver(const char *val)
|
||||
{
|
||||
gopt.op_sys_ver = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_plock(const char *val)
|
||||
{
|
||||
if (STREQ(val, "yes")) {
|
||||
gopt.flags |= CFM_NOSWAP;
|
||||
return 0;
|
||||
} else if (STREQ(val, "no")) {
|
||||
gopt.flags &= ~CFM_NOSWAP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "conf: unknown value to plock \"%s\"\n", val);
|
||||
return 1; /* unknown value */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_print_pid(const char *val)
|
||||
{
|
||||
if (STREQ(val, "yes")) {
|
||||
gopt.flags |= CFM_PRINT_PID;
|
||||
return 0;
|
||||
} else if (STREQ(val, "no")) {
|
||||
gopt.flags &= ~CFM_PRINT_PID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "conf: unknown value to print_pid \"%s\"\n", val);
|
||||
return 1; /* unknown value */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_print_version(const char *val)
|
||||
{
|
||||
if (STREQ(val, "yes")) {
|
||||
fputs(get_version_string(), stderr);
|
||||
return 0;
|
||||
} else if (STREQ(val, "no")) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "conf: unknown value to print_version \"%s\"\n", val);
|
||||
return 1; /* unknown value */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_restart_mounts(const char *val)
|
||||
{
|
||||
if (STREQ(val, "yes")) {
|
||||
gopt.flags |= CFM_RESTART_EXISTING_MOUNTS;
|
||||
return 0;
|
||||
} else if (STREQ(val, "no")) {
|
||||
gopt.flags &= ~CFM_RESTART_EXISTING_MOUNTS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "conf: unknown value to restart_mounts \"%s\"\n", val);
|
||||
return 1; /* unknown value */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_search_path(const char *val)
|
||||
{
|
||||
gopt.search_path = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_selectors_on_default(const char *val)
|
||||
{
|
||||
if (STREQ(val, "yes")) {
|
||||
gopt.flags |= CFM_ENABLE_DEFAULT_SELECTORS;
|
||||
return 0;
|
||||
} else if (STREQ(val, "no")) {
|
||||
gopt.flags &= ~CFM_ENABLE_DEFAULT_SELECTORS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "conf: unknown value to enable_default_selectors \"%s\"\n", val);
|
||||
return 1; /* unknown value */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Collect one entry for a regular map
|
||||
*/
|
||||
static int
|
||||
process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm)
|
||||
{
|
||||
/* ensure that val is valid */
|
||||
if (!section || section[0] == '\0' ||
|
||||
!key || key[0] == '\0' ||
|
||||
!val || val[0] == '\0' ||
|
||||
!cfm) {
|
||||
fprintf(stderr, "conf: process_regular_option: null entries\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* check if initializing a new map */
|
||||
if (!cfm->cfm_dir)
|
||||
cfm->cfm_dir = strdup((char *)section);
|
||||
|
||||
/* check for each possible field */
|
||||
if (STREQ(key, "browsable_dirs"))
|
||||
return ropt_browsable_dirs(val, cfm);
|
||||
|
||||
if (STREQ(key, "map_name"))
|
||||
return ropt_map_name(val, cfm);
|
||||
|
||||
if (STREQ(key, "map_options"))
|
||||
return ropt_map_options(val, cfm);
|
||||
|
||||
if (STREQ(key, "map_type"))
|
||||
return ropt_map_type(val, cfm);
|
||||
|
||||
if (STREQ(key, "mount_type"))
|
||||
return ropt_mount_type(val, cfm);
|
||||
|
||||
if (STREQ(key, "search_path"))
|
||||
return ropt_search_path(val, cfm);
|
||||
|
||||
if (STREQ(key, "tag"))
|
||||
return ropt_tag(val, cfm);
|
||||
|
||||
fprintf(stderr, "conf: unknown regular key \"%s\" for section \"%s\"\n",
|
||||
key, section);
|
||||
return 1; /* failed to match any command */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ropt_browsable_dirs(const char *val, cf_map_t *cfm)
|
||||
{
|
||||
if (STREQ(val, "yes")) {
|
||||
cfm->cfm_flags |= CFM_BROWSABLE_DIRS;
|
||||
return 0;
|
||||
} else if (STREQ(val, "no")) {
|
||||
cfm->cfm_flags &= ~CFM_BROWSABLE_DIRS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
|
||||
return 1; /* unknown value */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ropt_map_name(const char *val, cf_map_t *cfm)
|
||||
{
|
||||
cfm->cfm_name = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ropt_map_options(const char *val, cf_map_t *cfm)
|
||||
{
|
||||
cfm->cfm_opts = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ropt_map_type(const char *val, cf_map_t *cfm)
|
||||
{
|
||||
cfm->cfm_type = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ropt_mount_type(const char *val, cf_map_t *cfm)
|
||||
{
|
||||
if (STREQ(val, "autofs")) {
|
||||
cfm->cfm_flags |= CFM_MOUNT_TYPE_AUTOFS;
|
||||
return 0;
|
||||
} else if (STREQ(val, "nfs")) {
|
||||
cfm->cfm_flags &= ~CFM_MOUNT_TYPE_AUTOFS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
|
||||
return 1; /* unknown value */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ropt_search_path(const char *val, cf_map_t *cfm)
|
||||
{
|
||||
cfm->cfm_search_path = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ropt_tag(const char *val, cf_map_t *cfm)
|
||||
{
|
||||
cfm->cfm_tag = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process one collected map.
|
||||
*/
|
||||
static int
|
||||
process_regular_map(cf_map_t *cfm)
|
||||
{
|
||||
|
||||
if (!cfm->cfm_name) {
|
||||
fprintf(stderr, "conf: map_name must be defined for map \"%s\"\n", cfm->cfm_dir);
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* If map has no tag defined, process the map.
|
||||
* If no conf_tag was set in amd -T, process all untagged entries.
|
||||
* If a tag is defined, then process it only if it matches the map tag.
|
||||
*/
|
||||
if (!cfm->cfm_tag ||
|
||||
(conf_tag && STREQ(cfm->cfm_tag, conf_tag))) {
|
||||
#ifdef DEBUG_CONF
|
||||
fprintf(stderr, "processing map %s (flags=0x%x)...\n",
|
||||
cfm->cfm_dir, cfm->cfm_flags);
|
||||
#endif /* DEBUG_CONF */
|
||||
root_newmap(cfm->cfm_dir,
|
||||
cfm->cfm_opts ? cfm->cfm_opts : "",
|
||||
cfm->cfm_name,
|
||||
cfm);
|
||||
} else {
|
||||
fprintf(stderr, "skipping map %s...\n", cfm->cfm_dir);
|
||||
}
|
||||
|
||||
reset_cf_map(cfm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process last map in conf file
|
||||
*/
|
||||
int
|
||||
process_last_regular_map(void)
|
||||
{
|
||||
return process_regular_map(&cur_map);
|
||||
}
|
159
usr.sbin/amd/amd/conf_parse.y
Normal file
159
usr.sbin/amd/amd/conf_parse.y
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1989 Jan-Simon Pendry
|
||||
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: conf_parse.y,v 1.1.1.1 1997/07/24 21:22:27 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
%{
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
extern char *yytext;
|
||||
extern int yylineno;
|
||||
extern int yylex(void);
|
||||
|
||||
static int yyerror(const char *s);
|
||||
static int retval;
|
||||
static char *header_section = NULL; /* start with no header section */
|
||||
|
||||
#define YYDEBUG 1
|
||||
|
||||
#define PARSE_DEBUG 0
|
||||
|
||||
#if PARSE_DEBUG
|
||||
# define dprintf(f,s) fprintf(stderr, (f), yylineno, (s))
|
||||
# define amu_return(v)
|
||||
#else
|
||||
# define dprintf(f,s)
|
||||
# define amu_return(v) return((v))
|
||||
#endif /* PARSE_DEBUG */
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
char *strtype;
|
||||
}
|
||||
|
||||
%token LEFT_BRACKET RIGHT_BRACKET EQUAL
|
||||
%token NEWLINE
|
||||
%token <strtype> NONWS_STRING
|
||||
%token <strtype> NONWSEQ_STRING
|
||||
%token <strtype> QUOTED_NONWSEQ_STRING
|
||||
|
||||
%start file
|
||||
%%
|
||||
|
||||
/****************************************************************************/
|
||||
file : { yydebug = PARSE_DEBUG; } newlines map_sections
|
||||
| { yydebug = PARSE_DEBUG; } map_sections
|
||||
;
|
||||
|
||||
newlines : NEWLINE
|
||||
| NEWLINE newlines
|
||||
;
|
||||
|
||||
map_sections : map_section
|
||||
| map_section map_sections
|
||||
;
|
||||
|
||||
map_section : sec_header kv_pairs
|
||||
;
|
||||
|
||||
sec_header : LEFT_BRACKET NONWS_STRING RIGHT_BRACKET NEWLINE
|
||||
{
|
||||
if (yydebug)
|
||||
fprintf(stderr, "sec_header1 = \"%s\"\n", $2);
|
||||
header_section = $2;
|
||||
}
|
||||
;
|
||||
|
||||
kv_pairs : kv_pair
|
||||
| kv_pair kv_pairs
|
||||
;
|
||||
|
||||
kv_pair : NONWS_STRING EQUAL NONWS_STRING NEWLINE
|
||||
{
|
||||
if (yydebug)
|
||||
fprintf(stderr,"parse1: key=\"%s\", val=\"%s\"\n", $1, $3);
|
||||
retval = set_conf_kv(header_section, $1, $3);
|
||||
if (retval != 0) {
|
||||
yyerror("syntax error");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
| NONWS_STRING EQUAL NONWSEQ_STRING NEWLINE
|
||||
{
|
||||
if (yydebug)
|
||||
fprintf(stderr,"parse2: key=\"%s\", val=\"%s\"\n", $1, $3);
|
||||
retval = set_conf_kv(header_section, $1, $3);
|
||||
if (retval != 0) {
|
||||
yyerror("syntax error");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
| NONWS_STRING EQUAL QUOTED_NONWSEQ_STRING NEWLINE
|
||||
{
|
||||
if (yydebug)
|
||||
fprintf(stderr,"parse3: key=\"%s\", val=\"%s\"\n", $1, $3);
|
||||
retval = set_conf_kv(header_section, $1, $3);
|
||||
if (retval != 0) {
|
||||
yyerror("syntax error");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
| NEWLINE
|
||||
;
|
||||
|
||||
/****************************************************************************/
|
||||
%%
|
||||
|
||||
static int
|
||||
yyerror(const char *s)
|
||||
{
|
||||
fprintf(stderr, "AMDCONF: %s on line %d (section %s)\n",
|
||||
s, yylineno,
|
||||
(header_section ? header_section : "null"));
|
||||
exit(1);
|
||||
return 1; /* to full compilers that insist on a return statement */
|
||||
}
|
165
usr.sbin/amd/amd/conf_tok.l
Normal file
165
usr.sbin/amd/amd/conf_tok.l
Normal file
@ -0,0 +1,165 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1989 Jan-Simon Pendry
|
||||
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: conf_tok.l,v 1.1.1.1 1997/07/24 21:22:27 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Lexical analyzer for AMD configuration parser.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
/*
|
||||
* Some systems include a definition for the macro ECHO in <sys/ioctl.h>,
|
||||
* and their (bad) version of lex defines it too at the very beginning of
|
||||
* the generated lex.yy.c file (before it can be easily undefined),
|
||||
* resulting in a conflict. So undefine it here before needed.
|
||||
* Luckily, it does not appear that this macro is actually used in the rest
|
||||
* of the generated lex.yy.c file.
|
||||
*/
|
||||
#ifdef ECHO
|
||||
# undef ECHO
|
||||
#endif /* ECHO */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
#include <conf_parse.h>
|
||||
|
||||
/*
|
||||
* There are some things that need to be defined only if useing GNU flex.
|
||||
* These must not be defined if using standard lex
|
||||
*/
|
||||
#ifdef FLEX_SCANNER
|
||||
int yylineno = 0;
|
||||
#endif /* FLEX_SCANNER */
|
||||
|
||||
int yylex(void);
|
||||
int yywrap(void);
|
||||
|
||||
#define TOK_DEBUG 0
|
||||
|
||||
#if TOK_DEBUG
|
||||
# define dprintf(f,s) fprintf(stderr, (f), yylineno, (s))
|
||||
# define amu_return(v)
|
||||
#else
|
||||
# define dprintf(f,s)
|
||||
# define amu_return(v) return((v))
|
||||
#endif /* TOK_DEBUG */
|
||||
|
||||
/* no need to use yyunput() or yywrap() */
|
||||
#define YY_NO_UNPUT
|
||||
#define YY_SKIP_YYWRAP
|
||||
|
||||
%}
|
||||
|
||||
DIGIT [0-9]
|
||||
ALPHA [A-Za-z]
|
||||
ALPHANUM [A-Za-z0-9]
|
||||
SYMBOL [A-Za-z0-9_-]
|
||||
PATH [A-Za-z0-9_-/]
|
||||
NONWSCHAR [^ \t\n\[\]=]
|
||||
NONWSEQCHAR [^ \t\n\[\]]
|
||||
NONNL [^\n]
|
||||
NONQUOTE [^\"]
|
||||
|
||||
%%
|
||||
|
||||
\n {
|
||||
yylineno++;
|
||||
amu_return(NEWLINE);
|
||||
}
|
||||
|
||||
\[ {
|
||||
dprintf("%8d: Left bracket \"%s\"\n", yytext);
|
||||
yylval.strtype = strdup(yytext);
|
||||
amu_return(LEFT_BRACKET);
|
||||
}
|
||||
|
||||
\] {
|
||||
dprintf("%8d: Right bracket \"%s\"\n", yytext);
|
||||
yylval.strtype = strdup(yytext);
|
||||
amu_return(RIGHT_BRACKET);
|
||||
}
|
||||
|
||||
= {
|
||||
dprintf("%8d: Equal \"%s\"\n", yytext);
|
||||
yylval.strtype = strdup(yytext);
|
||||
amu_return(EQUAL);
|
||||
}
|
||||
|
||||
[ \t]* {
|
||||
dprintf("%8d: Whitespace \"%s\"\n", yytext);
|
||||
}
|
||||
"#"[^\n]*\n {
|
||||
/* a comment line includes the terminating \n */
|
||||
yylineno++;
|
||||
yytext[strlen(yytext)-1] = '\0';
|
||||
dprintf("%8d: Comment \"%s\"\n", yytext);
|
||||
}
|
||||
|
||||
{NONWSCHAR}{NONWSCHAR}* {
|
||||
dprintf("%8d: Non-WS string \"%s\"\n", yytext);
|
||||
yylval.strtype = strdup(yytext);
|
||||
amu_return(NONWS_STRING);
|
||||
}
|
||||
|
||||
\"{NONQUOTE}{NONQUOTE}*\" {
|
||||
dprintf("%8d: QUOTED-Non-WS-EQ string \"%s\"\n", yytext);
|
||||
/* must strip quotes */
|
||||
yytext[strlen(yytext)-1] = '\0';
|
||||
yylval.strtype = strdup(&yytext[1]);
|
||||
amu_return(QUOTED_NONWSEQ_STRING);
|
||||
}
|
||||
|
||||
{NONWSEQCHAR}{NONWSEQCHAR}* {
|
||||
dprintf("%8d: Non-WS-EQ string \"%s\"\n", yytext);
|
||||
yylval.strtype = strdup(yytext);
|
||||
amu_return(NONWSEQ_STRING);
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
int yywrap(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
245
usr.sbin/amd/amd/nfs_prot_svc.c
Normal file
245
usr.sbin/amd/amd/nfs_prot_svc.c
Normal file
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1989 Jan-Simon Pendry
|
||||
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: nfs_prot_svc.c,v 1.1.1.1 1997/07/24 21:21:27 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
extern void * nfsproc_null_2_svc(void *, struct svc_req *);
|
||||
extern nfsattrstat * nfsproc_getattr_2_svc(am_nfs_fh *, struct svc_req *);
|
||||
extern nfsattrstat * nfsproc_setattr_2_svc(nfssattrargs *, struct svc_req *);
|
||||
extern void * nfsproc_root_2_svc(void *, struct svc_req *);
|
||||
extern nfsdiropres * nfsproc_lookup_2_svc(nfsdiropargs *, struct svc_req *);
|
||||
extern nfsreadlinkres * nfsproc_readlink_2_svc(am_nfs_fh *, struct svc_req *);
|
||||
extern nfsreadres * nfsproc_read_2_svc(nfsreadargs *, struct svc_req *);
|
||||
extern void * nfsproc_writecache_2_svc(void *, struct svc_req *);
|
||||
extern nfsattrstat * nfsproc_write_2_svc(nfswriteargs *, struct svc_req *);
|
||||
extern nfsdiropres * nfsproc_create_2_svc(nfscreateargs *, struct svc_req *);
|
||||
extern nfsstat * nfsproc_remove_2_svc(nfsdiropargs *, struct svc_req *);
|
||||
extern nfsstat * nfsproc_rename_2_svc(nfsrenameargs *, struct svc_req *);
|
||||
extern nfsstat * nfsproc_link_2_svc(nfslinkargs *, struct svc_req *);
|
||||
extern nfsstat * nfsproc_symlink_2_svc(nfssymlinkargs *, struct svc_req *);
|
||||
extern nfsdiropres * nfsproc_mkdir_2_svc(nfscreateargs *, struct svc_req *);
|
||||
extern nfsstat * nfsproc_rmdir_2_svc(nfsdiropargs *, struct svc_req *);
|
||||
extern nfsreaddirres * nfsproc_readdir_2_svc(nfsreaddirargs *, struct svc_req *);
|
||||
extern nfsstatfsres * nfsproc_statfs_2_svc(am_nfs_fh *, struct svc_req *);
|
||||
|
||||
SVCXPRT *nfs_program_2_transp;
|
||||
|
||||
|
||||
void
|
||||
nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
{
|
||||
union {
|
||||
am_nfs_fh nfsproc_getattr_2_arg;
|
||||
nfssattrargs nfsproc_setattr_2_arg;
|
||||
nfsdiropargs nfsproc_lookup_2_arg;
|
||||
am_nfs_fh nfsproc_readlink_2_arg;
|
||||
nfsreadargs nfsproc_read_2_arg;
|
||||
nfswriteargs nfsproc_write_2_arg;
|
||||
nfscreateargs nfsproc_create_2_arg;
|
||||
nfsdiropargs nfsproc_remove_2_arg;
|
||||
nfsrenameargs nfsproc_rename_2_arg;
|
||||
nfslinkargs nfsproc_link_2_arg;
|
||||
nfssymlinkargs nfsproc_symlink_2_arg;
|
||||
nfscreateargs nfsproc_mkdir_2_arg;
|
||||
nfsdiropargs fsproc_rmdir_2_arg;
|
||||
nfsreaddirargs nfsproc_readdir_2_arg;
|
||||
am_nfs_fh nfsproc_statfs_2_arg;
|
||||
} argument;
|
||||
char *result;
|
||||
bool_t(*xdr_argument) (), (*xdr_result) ();
|
||||
char *(*local) ();
|
||||
|
||||
nfs_program_2_transp = NULL;
|
||||
|
||||
switch (rqstp->rq_proc) {
|
||||
|
||||
case NFSPROC_NULL:
|
||||
xdr_argument = xdr_void;
|
||||
xdr_result = xdr_void;
|
||||
local = (char *(*)()) nfsproc_null_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_GETATTR:
|
||||
xdr_argument = xdr_nfs_fh;
|
||||
xdr_result = xdr_attrstat;
|
||||
local = (char *(*)()) nfsproc_getattr_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_SETATTR:
|
||||
xdr_argument = xdr_sattrargs;
|
||||
xdr_result = xdr_attrstat;
|
||||
local = (char *(*)()) nfsproc_setattr_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_ROOT:
|
||||
xdr_argument = xdr_void;
|
||||
xdr_result = xdr_void;
|
||||
local = (char *(*)()) nfsproc_root_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_LOOKUP:
|
||||
xdr_argument = xdr_diropargs;
|
||||
xdr_result = xdr_diropres;
|
||||
local = (char *(*)()) nfsproc_lookup_2_svc;
|
||||
/*
|
||||
* Cheap way to pass transp down to afs_lookuppn so it can
|
||||
* be stored in the am_node structure and later used for
|
||||
* quick_reply().
|
||||
*/
|
||||
nfs_program_2_transp = transp;
|
||||
break;
|
||||
|
||||
case NFSPROC_READLINK:
|
||||
xdr_argument = xdr_nfs_fh;
|
||||
xdr_result = xdr_readlinkres;
|
||||
local = (char *(*)()) nfsproc_readlink_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_READ:
|
||||
xdr_argument = xdr_readargs;
|
||||
xdr_result = xdr_readres;
|
||||
local = (char *(*)()) nfsproc_read_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_WRITECACHE:
|
||||
xdr_argument = xdr_void;
|
||||
xdr_result = xdr_void;
|
||||
local = (char *(*)()) nfsproc_writecache_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_WRITE:
|
||||
xdr_argument = xdr_writeargs;
|
||||
xdr_result = xdr_attrstat;
|
||||
local = (char *(*)()) nfsproc_write_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_CREATE:
|
||||
xdr_argument = xdr_createargs;
|
||||
xdr_result = xdr_diropres;
|
||||
local = (char *(*)()) nfsproc_create_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_REMOVE:
|
||||
xdr_argument = xdr_diropargs;
|
||||
xdr_result = xdr_nfsstat;
|
||||
local = (char *(*)()) nfsproc_remove_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_RENAME:
|
||||
xdr_argument = xdr_renameargs;
|
||||
xdr_result = xdr_nfsstat;
|
||||
local = (char *(*)()) nfsproc_rename_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_LINK:
|
||||
xdr_argument = xdr_linkargs;
|
||||
xdr_result = xdr_nfsstat;
|
||||
local = (char *(*)()) nfsproc_link_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_SYMLINK:
|
||||
xdr_argument = xdr_symlinkargs;
|
||||
xdr_result = xdr_nfsstat;
|
||||
local = (char *(*)()) nfsproc_symlink_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_MKDIR:
|
||||
xdr_argument = xdr_createargs;
|
||||
xdr_result = xdr_diropres;
|
||||
local = (char *(*)()) nfsproc_mkdir_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_RMDIR:
|
||||
xdr_argument = xdr_diropargs;
|
||||
xdr_result = xdr_nfsstat;
|
||||
local = (char *(*)()) nfsproc_rmdir_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_READDIR:
|
||||
xdr_argument = xdr_readdirargs;
|
||||
xdr_result = xdr_readdirres;
|
||||
local = (char *(*)()) nfsproc_readdir_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_STATFS:
|
||||
xdr_argument = xdr_nfs_fh;
|
||||
xdr_result = xdr_statfsres;
|
||||
local = (char *(*)()) nfsproc_statfs_2_svc;
|
||||
break;
|
||||
|
||||
default:
|
||||
svcerr_noproc(transp);
|
||||
return;
|
||||
}
|
||||
|
||||
memset((char *) &argument, 0, sizeof(argument));
|
||||
if (!svc_getargs(transp,
|
||||
(XDRPROC_T_TYPE) xdr_argument,
|
||||
(SVC_IN_ARG_TYPE) & argument)) {
|
||||
plog(XLOG_ERROR,
|
||||
"NFS xdr decode failed for %d %d %d",
|
||||
rqstp->rq_prog, rqstp->rq_vers, rqstp->rq_proc);
|
||||
svcerr_decode(transp);
|
||||
return;
|
||||
}
|
||||
result = (*local) (&argument, rqstp);
|
||||
|
||||
nfs_program_2_transp = NULL;
|
||||
|
||||
if (result != NULL && !svc_sendreply(transp,
|
||||
(XDRPROC_T_TYPE) xdr_result,
|
||||
result)) {
|
||||
svcerr_systemerr(transp);
|
||||
}
|
||||
if (!svc_freeargs(transp,
|
||||
(XDRPROC_T_TYPE) xdr_argument,
|
||||
(SVC_IN_ARG_TYPE) & argument)) {
|
||||
plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_1");
|
||||
going_down(1);
|
||||
}
|
||||
}
|
2127
usr.sbin/amd/amd/ops_afs.c
Normal file
2127
usr.sbin/amd/amd/ops_afs.c
Normal file
File diff suppressed because it is too large
Load Diff
166
usr.sbin/amd/amd/ops_cdfs.c
Normal file
166
usr.sbin/amd/amd/ops_cdfs.c
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: ops_cdfs.c,v 1.1.1.1 1997/07/24 21:21:42 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* High Sierra (CD-ROM) file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
static char *cdfs_match(am_opts *fo);
|
||||
static int cdfs_fmount(mntfs *mf);
|
||||
static int cdfs_fumount(mntfs *mf);
|
||||
|
||||
am_node *efs_lookuppn(am_node *mp, char *fname, int *error_return, int op);
|
||||
fserver *find_afs_srvr(mntfs *mf);
|
||||
int auto_fmount(am_node *mp);
|
||||
int auto_fumount(am_node *mp);
|
||||
int efs_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, int count);
|
||||
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops cdfs_ops =
|
||||
{
|
||||
MNTTAB_TYPE_CDFS,
|
||||
cdfs_match,
|
||||
0, /* cdfs_init */
|
||||
auto_fmount,
|
||||
cdfs_fmount,
|
||||
auto_fumount,
|
||||
cdfs_fumount,
|
||||
efs_lookuppn,
|
||||
efs_readdir,
|
||||
0, /* cdfs_readlink */
|
||||
0, /* cdfs_mounted */
|
||||
0, /* cdfs_umounted */
|
||||
find_afs_srvr,
|
||||
FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* CDFS needs remote filesystem.
|
||||
*/
|
||||
static char *
|
||||
cdfs_match(am_opts *fo)
|
||||
{
|
||||
if (!fo->opt_dev) {
|
||||
plog(XLOG_USER, "cdfs: no source device specified");
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
dlog("CDFS: mounting device \"%s\" on \"%s\"",
|
||||
fo->opt_dev, fo->opt_fs);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Determine magic cookie to put in mtab
|
||||
*/
|
||||
return strdup(fo->opt_dev);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
mount_cdfs(char *dir, char *fs_name, char *opts)
|
||||
{
|
||||
cdfs_args_t cdfs_args;
|
||||
mntent_t mnt;
|
||||
int flags;
|
||||
|
||||
/*
|
||||
* Figure out the name of the file system type.
|
||||
*/
|
||||
MTYPE_TYPE type = MOUNT_TYPE_CDFS;
|
||||
|
||||
memset((voidp) &cdfs_args, 0, sizeof(cdfs_args)); /* Paranoid */
|
||||
|
||||
/*
|
||||
* Fill in the mount structure
|
||||
*/
|
||||
mnt.mnt_dir = dir;
|
||||
mnt.mnt_fsname = fs_name;
|
||||
mnt.mnt_type = MNTTAB_TYPE_CDFS;
|
||||
mnt.mnt_opts = opts;
|
||||
|
||||
flags = compute_mount_flags(&mnt);
|
||||
|
||||
cdfs_args.fspec = fs_name;
|
||||
#ifdef HAVE_FIELD_CDFS_ARGS_T_NORRIP
|
||||
/* XXX: need to provide norrip mount opt */
|
||||
cdfs_args.norrip = 0; /* use Rock-Ridge Protocol extensions */
|
||||
#endif /* HAVE_FIELD_CDFS_ARGS_T_NORRIP */
|
||||
|
||||
/*
|
||||
* Call generic mount routine
|
||||
*/
|
||||
return mount_fs(&mnt, flags, (caddr_t) &cdfs_args, 0, type, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cdfs_fmount(mntfs *mf)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = mount_cdfs(mf->mf_mount, mf->mf_info, mf->mf_mopts);
|
||||
if (error) {
|
||||
errno = error;
|
||||
plog(XLOG_ERROR, "mount_cdfs: %m");
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cdfs_fumount(mntfs *mf)
|
||||
{
|
||||
return UMOUNT_FS(mf->mf_mount);
|
||||
}
|
152
usr.sbin/amd/amd/ops_efs.c
Normal file
152
usr.sbin/amd/amd/ops_efs.c
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1989 Jan-Simon Pendry
|
||||
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: ops_efs.c,v 1.1.1.1 1997/07/24 21:21:42 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Error file system.
|
||||
* This is used as a last resort catchall if
|
||||
* nothing else worked. EFS just returns lots
|
||||
* of error codes, except for unmount which
|
||||
* always works of course.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
am_node *efs_lookuppn(am_node *mp, char *fname, int *error_return, int op);
|
||||
int efs_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, int count);
|
||||
static char * efs_match(am_opts *fo);
|
||||
static int efs_fmount(mntfs *mf);
|
||||
static int efs_fumount(mntfs *mf);
|
||||
static void efs_umounted(am_node *mp);
|
||||
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops efs_ops =
|
||||
{
|
||||
"error",
|
||||
efs_match,
|
||||
0, /* efs_init */
|
||||
auto_fmount,
|
||||
efs_fmount,
|
||||
auto_fumount,
|
||||
efs_fumount,
|
||||
efs_lookuppn,
|
||||
efs_readdir,
|
||||
0, /* efs_readlink */
|
||||
0, /* efs_mounted */
|
||||
efs_umounted,
|
||||
find_afs_srvr,
|
||||
FS_DISCARD
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* EFS file system always matches
|
||||
*/
|
||||
static char *
|
||||
efs_match(am_opts *fo)
|
||||
{
|
||||
return strdup("(error-hook)");
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
efs_fmount(mntfs *mf)
|
||||
{
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
efs_fumount(mntfs *mf)
|
||||
{
|
||||
/*
|
||||
* Always succeed
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* EFS interface to RPC lookup() routine.
|
||||
* Should never get here in the automounter.
|
||||
* If we do then just give an error.
|
||||
*/
|
||||
am_node *
|
||||
efs_lookuppn(am_node *mp, char *fname, int *error_return, int op)
|
||||
{
|
||||
*error_return = ESTALE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* EFS interface to RPC readdir() routine.
|
||||
* Should never get here in the automounter.
|
||||
* If we do then just give an error.
|
||||
*/
|
||||
int
|
||||
efs_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, int count)
|
||||
{
|
||||
return ESTALE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* umounted() callback for EFS.
|
||||
*
|
||||
* This prevents core-dumps on callbacks to error file-systems from
|
||||
* nfsx_fumount.
|
||||
*/
|
||||
static void
|
||||
efs_umounted(am_node *mp)
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
678
usr.sbin/amd/amd/ops_host.c
Normal file
678
usr.sbin/amd/amd/ops_host.c
Normal file
@ -0,0 +1,678 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: ops_host.c,v 1.1.1.1 1997/07/24 21:21:43 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* NFS host file system.
|
||||
* Mounts all exported filesystems from a given host.
|
||||
* This has now degenerated into a mess but will not
|
||||
* be rewritten. Amd 6 will support the abstractions
|
||||
* needed to make this work correctly.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
static char *host_match(am_opts *fo);
|
||||
static int host_fmount(mntfs *mf);
|
||||
static int host_fumount(mntfs *mf);
|
||||
static int host_init(mntfs *mf);
|
||||
static void host_umounted(am_node *mp);
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops host_ops =
|
||||
{
|
||||
"host",
|
||||
host_match,
|
||||
host_init,
|
||||
auto_fmount,
|
||||
host_fmount,
|
||||
auto_fumount,
|
||||
host_fumount,
|
||||
efs_lookuppn,
|
||||
efs_readdir,
|
||||
0, /* host_readlink */
|
||||
0, /* host_mounted */
|
||||
host_umounted,
|
||||
find_nfs_srvr,
|
||||
FS_MKMNT | FS_BACKGROUND | FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Determine the mount point:
|
||||
*
|
||||
* The next change we put in to better handle PCs. This is a bit
|
||||
* disgusting, so you'd better sit down. We change the make_mntpt function
|
||||
* to look for exported file systems without a leading '/'. If they don't
|
||||
* have a leading '/', we add one. If the export is 'a:' through 'z:'
|
||||
* (without a leading slash), we change it to 'a%' (or b% or z%). This
|
||||
* allows the entire PC disk to be mounted.
|
||||
*/
|
||||
static void
|
||||
make_mntpt(char *mntpt, const exports ex, const mntfs *mf)
|
||||
{
|
||||
if (ex->ex_dir[0] == '/') {
|
||||
if (ex->ex_dir[1] == 0)
|
||||
strcpy(mntpt, (mf)->mf_mount);
|
||||
else
|
||||
sprintf(mntpt, "%s%s", mf->mf_mount, ex->ex_dir);
|
||||
} else if (ex->ex_dir[0] >= 'a' &&
|
||||
ex->ex_dir[0] <= 'z' &&
|
||||
ex->ex_dir[1] == ':' &&
|
||||
ex->ex_dir[2] == '/' &&
|
||||
ex->ex_dir[3] == 0)
|
||||
sprintf(mntpt, "%s/%c%%", mf->mf_mount, ex->ex_dir[0]);
|
||||
else
|
||||
sprintf(mntpt, "%s/%s", mf->mf_mount, ex->ex_dir);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Execute needs the same as NFS plus a helper command
|
||||
*/
|
||||
static char *
|
||||
host_match(am_opts *fo)
|
||||
{
|
||||
extern am_ops nfs_ops;
|
||||
|
||||
/*
|
||||
* Make sure rfs is specified to keep nfs_match happy...
|
||||
*/
|
||||
if (!fo->opt_rfs)
|
||||
fo->opt_rfs = "/";
|
||||
|
||||
return (*nfs_ops.fs_match) (fo);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
host_init(mntfs *mf)
|
||||
{
|
||||
fserver *fs;
|
||||
u_short port;
|
||||
|
||||
if (strchr(mf->mf_info, ':') == 0)
|
||||
return ENOENT;
|
||||
|
||||
/*
|
||||
* This is primarily to schedule a wakeup so that as soon
|
||||
* as our fileserver is ready, we can continue setting up
|
||||
* the host filesystem. If we don't do this, the standard
|
||||
* afs code will set up a fileserver structure, but it will
|
||||
* have to wait for another nfs request from the client to come
|
||||
* in before finishing. Our way is faster since we don't have
|
||||
* to wait for the client to resend its request (which could
|
||||
* take a second or two).
|
||||
*/
|
||||
/*
|
||||
* First, we find the fileserver for this mntfs and then call
|
||||
* nfs_srvr_port with our mntfs passed as the wait channel.
|
||||
* nfs_srvr_port will check some things and then schedule
|
||||
* it so that when the fileserver is ready, a wakeup is done
|
||||
* on this mntfs. afs_cont() is already sleeping on this mntfs
|
||||
* so as soon as that wakeup happens afs_cont() is called and
|
||||
* this mount is retried.
|
||||
*/
|
||||
if ((fs = mf->mf_server))
|
||||
/*
|
||||
* We don't really care if there's an error returned.
|
||||
* Since this is just to help speed things along, the
|
||||
* error will get handled properly elsewhere.
|
||||
*/
|
||||
(void) nfs_srvr_port(fs, &port, (voidp) mf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_mount(am_nfs_handle_t *fhp, char *dir, char *fs_name, char *opts, mntfs *mf)
|
||||
{
|
||||
struct stat stb;
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("host: mounting fs %s on %s\n", fs_name, dir);
|
||||
#endif /* DEBUG */
|
||||
|
||||
(void) mkdirs(dir, 0555);
|
||||
if (stat(dir, &stb) < 0 || (stb.st_mode & S_IFMT) != S_IFDIR) {
|
||||
plog(XLOG_ERROR, "No mount point for %s - skipping", dir);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
return mount_nfs_fh(fhp, dir, fs_name, opts, mf);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sortfun(const voidp x, const voidp y)
|
||||
{
|
||||
exports *a = (exports *) x;
|
||||
exports *b = (exports *) y;
|
||||
|
||||
return strcmp((*a)->ex_dir, (*b)->ex_dir);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get filehandle
|
||||
*/
|
||||
static int
|
||||
fetch_fhandle(CLIENT * client, char *dir, am_nfs_handle_t *fhp, u_long nfs_version)
|
||||
{
|
||||
struct timeval tv;
|
||||
enum clnt_stat clnt_stat;
|
||||
|
||||
/*
|
||||
* Pick a number, any number...
|
||||
*/
|
||||
tv.tv_sec = 20;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("Fetching fhandle for %s", dir);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Call the mount daemon on the remote host to
|
||||
* get the filehandle. Use NFS version specific call.
|
||||
*/
|
||||
|
||||
plog(XLOG_INFO, "fetch_fhandle: NFS version %d", nfs_version);
|
||||
#ifdef HAVE_FS_NFS3
|
||||
if (nfs_version == NFS_VERSION3) {
|
||||
memset((char *) &fhp->v3, 0, sizeof(fhp->v3));
|
||||
clnt_stat = clnt_call(client,
|
||||
MOUNTPROC_MNT,
|
||||
(XDRPROC_T_TYPE) xdr_dirpath,
|
||||
(SVC_IN_ARG_TYPE) &dir,
|
||||
(XDRPROC_T_TYPE) xdr_mountres3,
|
||||
(SVC_IN_ARG_TYPE) &fhp->v3,
|
||||
tv);
|
||||
if (clnt_stat != RPC_SUCCESS) {
|
||||
plog(XLOG_ERROR, "mountd rpc failed: %s", clnt_sperrno(clnt_stat));
|
||||
return EIO;
|
||||
}
|
||||
/* Check the status of the filehandle */
|
||||
if ((errno = fhp->v3.fhs_status)) {
|
||||
#ifdef DEBUG
|
||||
dlog("fhandle fetch for mount version 3 failed: %m");
|
||||
#endif /* DEBUG */
|
||||
return errno;
|
||||
}
|
||||
} else { /* not NFS_VERSION3 mount */
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
clnt_stat = clnt_call(client,
|
||||
MOUNTPROC_MNT,
|
||||
(XDRPROC_T_TYPE) xdr_dirpath,
|
||||
(SVC_IN_ARG_TYPE) &dir,
|
||||
(XDRPROC_T_TYPE) xdr_fhstatus,
|
||||
(SVC_IN_ARG_TYPE) &fhp->v2,
|
||||
tv);
|
||||
if (clnt_stat != RPC_SUCCESS) {
|
||||
char *msg = clnt_sperrno(clnt_stat);
|
||||
plog(XLOG_ERROR, "mountd rpc failed: %s", msg);
|
||||
return EIO;
|
||||
}
|
||||
/* Check status of filehandle */
|
||||
if (fhp->v2.fhs_status) {
|
||||
errno = fhp->v2.fhs_status;
|
||||
#ifdef DEBUG
|
||||
dlog("fhandle fetch for mount version 1 failed: %m");
|
||||
#endif /* DEBUG */
|
||||
return errno;
|
||||
}
|
||||
#ifdef HAVE_FS_NFS3
|
||||
} /* end of "if (nfs_version == NFS_VERSION3)" statement */
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
|
||||
/* all is well */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Scan mount table to see if something already mounted
|
||||
*/
|
||||
static int
|
||||
already_mounted(mntlist *mlist, char *dir)
|
||||
{
|
||||
mntlist *ml;
|
||||
|
||||
for (ml = mlist; ml; ml = ml->mnext)
|
||||
if (STREQ(ml->mnt->mnt_dir, dir))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mount the export tree from a host
|
||||
*/
|
||||
static int
|
||||
host_fmount(mntfs *mf)
|
||||
{
|
||||
struct timeval tv2;
|
||||
CLIENT *client;
|
||||
enum clnt_stat clnt_stat;
|
||||
int n_export;
|
||||
int j, k;
|
||||
exports exlist = 0, ex;
|
||||
exports *ep = 0;
|
||||
am_nfs_handle_t *fp = 0;
|
||||
char *host;
|
||||
int error = 0;
|
||||
struct sockaddr_in sin;
|
||||
int sock = RPC_ANYSOCK;
|
||||
int ok = FALSE;
|
||||
mntlist *mlist;
|
||||
char fs_name[MAXPATHLEN], *rfs_dir;
|
||||
char mntpt[MAXPATHLEN];
|
||||
struct timeval tv;
|
||||
u_long mnt_version;
|
||||
|
||||
/*
|
||||
* Read the mount list
|
||||
*/
|
||||
mlist = read_mtab(mf->mf_mount);
|
||||
|
||||
#ifdef MOUNT_TABLE_ON_FILE
|
||||
/*
|
||||
* Unlock the mount list
|
||||
*/
|
||||
unlock_mntlist();
|
||||
#endif /* MOUNT_TABLE_ON_FILE */
|
||||
|
||||
/*
|
||||
* Take a copy of the server hostname, address, and nfs version
|
||||
* to mount version conversion.
|
||||
*/
|
||||
host = mf->mf_server->fs_host;
|
||||
sin = *mf->mf_server->fs_ip;
|
||||
plog(XLOG_INFO, "host_fmount: NFS version %d", mf->mf_server->fs_version);
|
||||
#ifdef HAVE_FS_NFS3
|
||||
if (mf->mf_server->fs_version == NFS_VERSION3)
|
||||
mnt_version = MOUNTVERS3;
|
||||
else
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
mnt_version = MOUNTVERS;
|
||||
|
||||
/*
|
||||
* The original 10 second per try timeout is WAY too large, especially
|
||||
* if we're only waiting 10 or 20 seconds max for the response.
|
||||
* That would mean we'd try only once in 10 seconds, and we could
|
||||
* lose the transmitt or receive packet, and never try again.
|
||||
* A 2-second per try timeout here is much more reasonable.
|
||||
* 09/28/92 Mike Mitchell, mcm@unx.sas.com
|
||||
*/
|
||||
tv.tv_sec = 2;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
/*
|
||||
* Create a client attached to mountd
|
||||
*/
|
||||
client = get_mount_client(host, &sin, &tv, &sock, mnt_version);
|
||||
if (client == NULL) {
|
||||
plog(XLOG_ERROR, "get_mount_client failed for %s: %s",
|
||||
host, clnt_spcreateerror(""));
|
||||
error = EIO;
|
||||
goto out;
|
||||
}
|
||||
if (!nfs_auth) {
|
||||
error = make_nfs_auth();
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
client->cl_auth = nfs_auth;
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("Fetching export list from %s", host);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Fetch the export list
|
||||
*/
|
||||
tv2.tv_sec = 10;
|
||||
tv2.tv_usec = 0;
|
||||
clnt_stat = clnt_call(client,
|
||||
MOUNTPROC_EXPORT,
|
||||
(XDRPROC_T_TYPE) xdr_void,
|
||||
0,
|
||||
(XDRPROC_T_TYPE) xdr_exports,
|
||||
(SVC_IN_ARG_TYPE) & exlist,
|
||||
tv2);
|
||||
if (clnt_stat != RPC_SUCCESS) {
|
||||
char *msg = clnt_sperrno(clnt_stat);
|
||||
plog(XLOG_ERROR, "host_fmount rpc failed: %s", msg);
|
||||
/* clnt_perror(client, "rpc"); */
|
||||
error = EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out how many exports were returned
|
||||
*/
|
||||
for (n_export = 0, ex = exlist; ex; ex = ex->ex_next) {
|
||||
/* printf("export %s\n", ex->ex_dir); */
|
||||
n_export++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate an array of pointers into the list
|
||||
* so that they can be sorted. If the filesystem
|
||||
* is already mounted then ignore it.
|
||||
*/
|
||||
ep = (exports *) xmalloc(n_export * sizeof(exports));
|
||||
for (j = 0, ex = exlist; ex; ex = ex->ex_next) {
|
||||
make_mntpt(mntpt, ex, mf);
|
||||
if (!already_mounted(mlist, mntpt))
|
||||
ep[j++] = ex;
|
||||
}
|
||||
n_export = j;
|
||||
|
||||
/*
|
||||
* Sort into order.
|
||||
* This way the mounts are done in order down the tree,
|
||||
* instead of any random order returned by the mount
|
||||
* daemon (the protocol doesn't specify...).
|
||||
*/
|
||||
qsort(ep, n_export, sizeof(exports), sortfun);
|
||||
|
||||
/*
|
||||
* Allocate an array of filehandles
|
||||
*/
|
||||
fp = (am_nfs_handle_t *) xmalloc(n_export * sizeof(am_nfs_handle_t));
|
||||
|
||||
/*
|
||||
* Try to obtain filehandles for each directory.
|
||||
* If a fetch fails then just zero out the array
|
||||
* reference but discard the error.
|
||||
*/
|
||||
for (j = k = 0; j < n_export; j++) {
|
||||
/* Check and avoid a duplicated export entry */
|
||||
if (j > k && ep[k] && STREQ(ep[j]->ex_dir, ep[k]->ex_dir)) {
|
||||
#ifdef DEBUG
|
||||
dlog("avoiding dup fhandle requested for %s", ep[j]->ex_dir);
|
||||
#endif /* DEBUG */
|
||||
ep[j] = 0;
|
||||
} else {
|
||||
k = j;
|
||||
error = fetch_fhandle(client, ep[j]->ex_dir, &fp[j],
|
||||
mf->mf_server->fs_version);
|
||||
if (error)
|
||||
ep[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mount each filesystem for which we have a filehandle.
|
||||
* If any of the mounts succeed then mark "ok" and return
|
||||
* error code 0 at the end. If they all fail then return
|
||||
* the last error code.
|
||||
*/
|
||||
strncpy(fs_name, mf->mf_info, sizeof(fs_name));
|
||||
if ((rfs_dir = strchr(fs_name, ':')) == (char *) 0) {
|
||||
plog(XLOG_FATAL, "host_fmount: mf_info has no colon");
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
++rfs_dir;
|
||||
for (j = 0; j < n_export; j++) {
|
||||
ex = ep[j];
|
||||
if (ex) {
|
||||
strcpy(rfs_dir, ex->ex_dir);
|
||||
make_mntpt(mntpt, ex, mf);
|
||||
if (do_mount(&fp[j], mntpt, fs_name, mf->mf_mopts, mf) == 0)
|
||||
ok = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up and exit
|
||||
*/
|
||||
out:
|
||||
discard_mntlist(mlist);
|
||||
if (ep)
|
||||
free(ep);
|
||||
if (fp)
|
||||
free(fp);
|
||||
if (sock != RPC_ANYSOCK)
|
||||
(void) amu_close(sock);
|
||||
if (client)
|
||||
clnt_destroy(client);
|
||||
if (exlist)
|
||||
xdr_pri_free((XDRPROC_T_TYPE) xdr_exports, (caddr_t) &exlist);
|
||||
if (ok)
|
||||
return 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return true if pref is a directory prefix of dir.
|
||||
*
|
||||
* XXX TODO:
|
||||
* Does not work if pref is "/".
|
||||
*/
|
||||
static int
|
||||
directory_prefix(char *pref, char *dir)
|
||||
{
|
||||
int len = strlen(pref);
|
||||
|
||||
if (strncmp(pref, dir, len) != 0)
|
||||
return FALSE;
|
||||
if (dir[len] == '/' || dir[len] == '\0')
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unmount a mount tree
|
||||
*/
|
||||
static int
|
||||
host_fumount(mntfs *mf)
|
||||
{
|
||||
mntlist *ml, *mprev;
|
||||
int xerror = 0;
|
||||
|
||||
/*
|
||||
* Read the mount list
|
||||
*/
|
||||
mntlist *mlist = read_mtab(mf->mf_mount);
|
||||
|
||||
#ifdef MOUNT_TABLE_ON_FILE
|
||||
/*
|
||||
* Unlock the mount list
|
||||
*/
|
||||
unlock_mntlist();
|
||||
#endif /* MOUNT_TABLE_ON_FILE */
|
||||
|
||||
/*
|
||||
* Reverse list...
|
||||
*/
|
||||
ml = mlist;
|
||||
mprev = 0;
|
||||
while (ml) {
|
||||
mntlist *ml2 = ml->mnext;
|
||||
ml->mnext = mprev;
|
||||
mprev = ml;
|
||||
ml = ml2;
|
||||
}
|
||||
mlist = mprev;
|
||||
|
||||
/*
|
||||
* Unmount all filesystems...
|
||||
*/
|
||||
for (ml = mlist; ml && !xerror; ml = ml->mnext) {
|
||||
char *dir = ml->mnt->mnt_dir;
|
||||
if (directory_prefix(mf->mf_mount, dir)) {
|
||||
int error;
|
||||
#ifdef DEBUG
|
||||
dlog("host: unmounts %s", dir);
|
||||
#endif /* DEBUG */
|
||||
/*
|
||||
* Unmount "dir"
|
||||
*/
|
||||
error = UMOUNT_FS(dir);
|
||||
/*
|
||||
* Keep track of errors
|
||||
*/
|
||||
if (error) {
|
||||
if (!xerror)
|
||||
xerror = error;
|
||||
if (error != EBUSY) {
|
||||
errno = error;
|
||||
plog(XLOG_ERROR, "Tree unmount of %s failed: %m", ml->mnt->mnt_dir);
|
||||
}
|
||||
} else {
|
||||
(void) rmdirs(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Throw away mount list
|
||||
*/
|
||||
discard_mntlist(mlist);
|
||||
|
||||
/*
|
||||
* Try to remount, except when we are shutting down.
|
||||
*/
|
||||
if (xerror && amd_state != Finishing) {
|
||||
xerror = host_fmount(mf);
|
||||
if (!xerror) {
|
||||
/*
|
||||
* Don't log this - it's usually too verbose
|
||||
plog(XLOG_INFO, "Remounted host %s", mf->mf_info);
|
||||
*/
|
||||
xerror = EBUSY;
|
||||
}
|
||||
}
|
||||
return xerror;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tell mountd we're done.
|
||||
* This is not quite right, because we may still
|
||||
* have other filesystems mounted, but the existing
|
||||
* mountd protocol is badly broken anyway.
|
||||
*/
|
||||
static void
|
||||
host_umounted(am_node *mp)
|
||||
{
|
||||
mntfs *mf = mp->am_mnt;
|
||||
char *host;
|
||||
CLIENT *client;
|
||||
enum clnt_stat clnt_stat;
|
||||
struct sockaddr_in sin;
|
||||
int sock = RPC_ANYSOCK;
|
||||
struct timeval tv;
|
||||
u_long mnt_version;
|
||||
|
||||
if (mf->mf_error || mf->mf_refc > 1 || !mf->mf_server)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Take a copy of the server hostname, address, and NFS version
|
||||
* to mount version conversion.
|
||||
*/
|
||||
host = mf->mf_server->fs_host;
|
||||
sin = *mf->mf_server->fs_ip;
|
||||
plog(XLOG_INFO, "host_umounted: NFS version %d", mf->mf_server->fs_version);
|
||||
#ifdef HAVE_FS_NFS3
|
||||
if (mf->mf_server->fs_version == NFS_VERSION3)
|
||||
mnt_version = MOUNTVERS3;
|
||||
else
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
mnt_version = MOUNTVERS;
|
||||
|
||||
/*
|
||||
* Create a client attached to mountd
|
||||
*/
|
||||
tv.tv_sec = 10;
|
||||
tv.tv_usec = 0;
|
||||
client = get_mount_client(host, &sin, &tv, &sock, mnt_version);
|
||||
if (client == NULL) {
|
||||
plog(XLOG_ERROR, "get_mount_client failed for %s: %s",
|
||||
host, clnt_spcreateerror(""));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!nfs_auth) {
|
||||
if (make_nfs_auth())
|
||||
goto out;
|
||||
}
|
||||
client->cl_auth = nfs_auth;
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("Unmounting all from %s", host);
|
||||
#endif /* DEBUG */
|
||||
|
||||
clnt_stat = clnt_call(client,
|
||||
MOUNTPROC_UMNTALL,
|
||||
(XDRPROC_T_TYPE) xdr_void,
|
||||
0,
|
||||
(XDRPROC_T_TYPE) xdr_void,
|
||||
0,
|
||||
tv);
|
||||
if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_SYSTEMERROR) {
|
||||
/* RPC_SYSTEMERROR seems to be returned for no good reason ... */
|
||||
char *msg = clnt_sperrno(clnt_stat);
|
||||
plog(XLOG_ERROR, "unmount all from %s rpc failed: %s", host, msg, clnt_stat);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (sock != RPC_ANYSOCK)
|
||||
(void) amu_close(sock);
|
||||
if (client)
|
||||
clnt_destroy(client);
|
||||
}
|
200
usr.sbin/amd/amd/ops_ifs.c
Normal file
200
usr.sbin/amd/amd/ops_ifs.c
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1989 Jan-Simon Pendry
|
||||
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: ops_ifs.c,v 1.1.1.1 1997/07/24 21:21:43 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Inheritance file system.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/*
|
||||
* This implements a filesystem restart.
|
||||
*
|
||||
* This is a *gross* hack - it knows far too
|
||||
* much about the way other parts of the
|
||||
* system work. See restart.c too.
|
||||
*/
|
||||
|
||||
static char *ifs_match(am_opts *fo);
|
||||
static int ifs_fmount(mntfs *mf);
|
||||
static int ifs_fumount(mntfs *mf);
|
||||
static int ifs_init(mntfs *mf);
|
||||
static int ifs_mount(am_node *mp);
|
||||
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops ifs_ops =
|
||||
{
|
||||
"inherit",
|
||||
ifs_match,
|
||||
ifs_init,
|
||||
ifs_mount,
|
||||
ifs_fmount,
|
||||
auto_fumount,
|
||||
ifs_fumount,
|
||||
efs_lookuppn,
|
||||
efs_readdir,
|
||||
0, /* ifs_readlink */
|
||||
0, /* ifs_mounted */
|
||||
0, /* ifs_umounted */
|
||||
find_afs_srvr,
|
||||
FS_DISCARD
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* This should never be called.
|
||||
*/
|
||||
static char *
|
||||
ifs_match(am_opts *fo)
|
||||
{
|
||||
plog(XLOG_FATAL, "ifs_match called!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ifs_init(mntfs *mf)
|
||||
{
|
||||
mntfs *mf_link = (mntfs *) mf->mf_private;
|
||||
|
||||
if (mf_link == 0) {
|
||||
plog(XLOG_ERROR, "Remount collision on %s?", mf->mf_mount);
|
||||
plog(XLOG_FATAL, "Attempting to init not-a-filesystem");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (mf_link->mf_ops->fs_init)
|
||||
return (*mf_link->mf_ops->fs_init) (mf_link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Take the linked mount point and
|
||||
* propogate.
|
||||
*/
|
||||
static mntfs *
|
||||
ifs_inherit(mntfs *mf)
|
||||
{
|
||||
mntfs *mf_link = (mntfs *) mf->mf_private;
|
||||
|
||||
if (mf_link == 0) {
|
||||
plog(XLOG_FATAL, "Attempting to inherit not-a-filesystem");
|
||||
return 0; /* XXX */
|
||||
}
|
||||
mf_link->mf_fo = mf->mf_fo;
|
||||
|
||||
/*
|
||||
* Discard the old map.
|
||||
* Don't call am_unmounted since this
|
||||
* node was never really mounted in the
|
||||
* first place.
|
||||
*/
|
||||
mf->mf_private = 0;
|
||||
free_mntfs(mf);
|
||||
|
||||
/*
|
||||
* Free the dangling reference
|
||||
* to the mount link.
|
||||
*/
|
||||
free_mntfs(mf_link);
|
||||
|
||||
/*
|
||||
* Get a hold of the other entry
|
||||
*/
|
||||
mf_link->mf_flags &= ~MFF_RESTART;
|
||||
|
||||
/* Say what happened */
|
||||
plog(XLOG_INFO, "restarting %s on %s", mf_link->mf_info, mf_link->mf_mount);
|
||||
|
||||
return mf_link;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ifs_mount(am_node *mp)
|
||||
{
|
||||
mntfs *newmf = ifs_inherit(mp->am_mnt);
|
||||
|
||||
if (newmf) {
|
||||
mp->am_mnt = newmf;
|
||||
/*
|
||||
* XXX - must do the am_mounted call here
|
||||
*/
|
||||
if (newmf->mf_ops->fs_flags & FS_MBACKGROUND)
|
||||
am_mounted(mp);
|
||||
|
||||
new_ttl(mp);
|
||||
return 0;
|
||||
}
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ifs_fmount(mntfs *mf)
|
||||
{
|
||||
am_node *mp = find_mf(mf);
|
||||
|
||||
if (mp)
|
||||
return ifs_mount(mp);
|
||||
return ifs_inherit(mf) ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ifs_fumount(mntfs *mf)
|
||||
{
|
||||
/*
|
||||
* Always succeed
|
||||
*/
|
||||
return 0;
|
||||
}
|
55
usr.sbin/amd/amd/ops_mfs.c
Normal file
55
usr.sbin/amd/amd/ops_mfs.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: ops_mfs.c,v 1.1.1.1 1997/07/24 21:21:44 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory file system (RAM filesystem)
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* FEEL FREE TO INPLEMENT THIS... :-) */
|
1023
usr.sbin/amd/amd/ops_nfs.c
Normal file
1023
usr.sbin/amd/amd/ops_nfs.c
Normal file
File diff suppressed because it is too large
Load Diff
55
usr.sbin/amd/amd/ops_nfs3.c
Normal file
55
usr.sbin/amd/amd/ops_nfs3.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: ops_nfs3.c,v 1.1.1.1 1997/07/24 21:21:44 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Network file system version 3.0
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* FEEL FREE TO INPLEMENT THIS... :-) */
|
532
usr.sbin/amd/amd/ops_nfsx.c
Normal file
532
usr.sbin/amd/amd/ops_nfsx.c
Normal file
@ -0,0 +1,532 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: ops_nfsx.c,v 1.1.1.1 1997/07/24 21:21:45 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* NFS hierarchical mounts
|
||||
*
|
||||
* TODO: Re-implement.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/*
|
||||
* The rfs field contains a list of mounts to be done from
|
||||
* the remote host.
|
||||
*/
|
||||
typedef struct nfsx_mnt {
|
||||
mntfs *n_mnt;
|
||||
int n_error;
|
||||
} nfsx_mnt;
|
||||
|
||||
struct nfsx {
|
||||
int nx_c; /* Number of elements in nx_v */
|
||||
nfsx_mnt *nx_v; /* Underlying mounts */
|
||||
nfsx_mnt *nx_try;
|
||||
};
|
||||
|
||||
/* forward definitions */
|
||||
static char * nfsx_match(am_opts *fo);
|
||||
static int nfsx_fmount (mntfs *);
|
||||
static int nfsx_fmount(mntfs *mf);
|
||||
static int nfsx_fumount(mntfs *mf);
|
||||
static int nfsx_init(mntfs *mf);
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops nfsx_ops =
|
||||
{
|
||||
"nfsx",
|
||||
nfsx_match,
|
||||
nfsx_init,
|
||||
auto_fmount,
|
||||
nfsx_fmount,
|
||||
auto_fumount,
|
||||
nfsx_fumount,
|
||||
efs_lookuppn,
|
||||
efs_readdir,
|
||||
0, /* nfsx_readlink */
|
||||
0, /* nfsx_mounted */
|
||||
0, /* nfsx_umounted */
|
||||
find_nfs_srvr, /* XXX */
|
||||
/* FS_UBACKGROUND| */ FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
static char *
|
||||
nfsx_match(am_opts *fo)
|
||||
{
|
||||
char *xmtab;
|
||||
char *ptr;
|
||||
int len;
|
||||
|
||||
if (!fo->opt_rfs) {
|
||||
plog(XLOG_USER, "nfsx: no remote filesystem specified");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!fo->opt_rhost) {
|
||||
plog(XLOG_USER, "nfsx: no remote host specified");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* set default sublink */
|
||||
if (fo->opt_sublink == 0) {
|
||||
ptr = strchr(fo->opt_rfs, ',');
|
||||
if (ptr && ptr != (fo->opt_rfs + 1))
|
||||
fo->opt_sublink = strnsave(fo->opt_rfs + 1, ptr - fo->opt_rfs - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove trailing ",..." from ${fs}
|
||||
* After deslashifying, overwrite the end of ${fs} with "/"
|
||||
* to make sure it is unique.
|
||||
*/
|
||||
if ((ptr = strchr(fo->opt_fs, ',')))
|
||||
*ptr = '\0';
|
||||
deslashify(fo->opt_fs);
|
||||
|
||||
/*
|
||||
* Bump string length to allow trailing /
|
||||
*/
|
||||
len = strlen(fo->opt_fs);
|
||||
fo->opt_fs = xrealloc(fo->opt_fs, len + 1 + 1);
|
||||
ptr = fo->opt_fs + len;
|
||||
|
||||
/*
|
||||
* Make unique...
|
||||
*/
|
||||
*ptr++ = '/';
|
||||
*ptr = '\0';
|
||||
|
||||
/*
|
||||
* Determine magic cookie to put in mtab
|
||||
*/
|
||||
xmtab = str3cat((char *) 0, fo->opt_rhost, ":", fo->opt_rfs);
|
||||
#ifdef DEBUG
|
||||
dlog("NFS: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"",
|
||||
fo->opt_rhost, fo->opt_rfs, fo->opt_fs);
|
||||
#endif /* DEBUG */
|
||||
|
||||
return xmtab;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nfsx_prfree(voidp vp)
|
||||
{
|
||||
struct nfsx *nx = (struct nfsx *) vp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nx->nx_c; i++) {
|
||||
mntfs *m = nx->nx_v[i].n_mnt;
|
||||
if (m)
|
||||
free_mntfs(m);
|
||||
}
|
||||
|
||||
free((voidp) nx->nx_v);
|
||||
free((voidp) nx);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
nfsx_init(mntfs *mf)
|
||||
{
|
||||
/*
|
||||
* mf_info has the form:
|
||||
* host:/prefix/path,sub,sub,sub
|
||||
*/
|
||||
int i;
|
||||
int glob_error;
|
||||
struct nfsx *nx;
|
||||
int asked_for_wakeup = 0;
|
||||
|
||||
nx = (struct nfsx *) mf->mf_private;
|
||||
|
||||
if (nx == 0) {
|
||||
char **ivec;
|
||||
char *info = 0;
|
||||
char *host;
|
||||
char *pref;
|
||||
int error = 0;
|
||||
|
||||
info = strdup(mf->mf_info);
|
||||
host = strchr(info, ':');
|
||||
if (!host) {
|
||||
error = EINVAL;
|
||||
goto errexit;
|
||||
}
|
||||
pref = host +1;
|
||||
host = info;
|
||||
|
||||
/*
|
||||
* Split the prefix off from the suffices
|
||||
*/
|
||||
ivec = strsplit(pref, ',', '\'');
|
||||
|
||||
/*
|
||||
* Count array size
|
||||
*/
|
||||
for (i = 0; ivec[i]; i++) ;
|
||||
|
||||
nx = ALLOC(struct nfsx);
|
||||
mf->mf_private = (voidp) nx;
|
||||
mf->mf_prfree = nfsx_prfree;
|
||||
|
||||
nx->nx_c = i - 1; /* i-1 because we don't want the prefix */
|
||||
nx->nx_v = (nfsx_mnt *) xmalloc(nx->nx_c * sizeof(nfsx_mnt));
|
||||
{
|
||||
char *mp = 0;
|
||||
char *xinfo = 0;
|
||||
char *fs = mf->mf_fo->opt_fs;
|
||||
char *rfs = 0;
|
||||
for (i = 0; i < nx->nx_c; i++) {
|
||||
char *path = ivec[i + 1];
|
||||
rfs = str3cat(rfs, pref, "/", path);
|
||||
/*
|
||||
* Determine the mount point.
|
||||
* If this is the root, then don't remove
|
||||
* the trailing slash to avoid mntfs name clashes.
|
||||
*/
|
||||
mp = str3cat(mp, fs, "/", rfs);
|
||||
normalize_slash(mp);
|
||||
deslashify(mp);
|
||||
/*
|
||||
* Determine the mount info
|
||||
*/
|
||||
xinfo = str3cat(xinfo, host, *path == '/' ? "" : "/", path);
|
||||
normalize_slash(xinfo);
|
||||
if (pref[1] != '\0')
|
||||
deslashify(xinfo);
|
||||
#ifdef DEBUG
|
||||
dlog("nfsx: init mount for %s on %s", xinfo, mp);
|
||||
#endif /* DEBUG */
|
||||
nx->nx_v[i].n_error = -1;
|
||||
nx->nx_v[i].n_mnt = find_mntfs(&nfs_ops, mf->mf_fo, mp, xinfo, "", mf->mf_mopts, mf->mf_remopts);
|
||||
}
|
||||
if (rfs)
|
||||
free(rfs);
|
||||
if (mp)
|
||||
free(mp);
|
||||
if (xinfo)
|
||||
free(xinfo);
|
||||
}
|
||||
|
||||
free((voidp) ivec);
|
||||
errexit:
|
||||
if (info)
|
||||
free(info);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate through the mntfs's and call
|
||||
* the underlying init routine on each
|
||||
*/
|
||||
glob_error = 0;
|
||||
|
||||
for (i = 0; i < nx->nx_c; i++) {
|
||||
nfsx_mnt *n = &nx->nx_v[i];
|
||||
mntfs *m = n->n_mnt;
|
||||
int error = (*m->mf_ops->fs_init) (m);
|
||||
/*
|
||||
* if you just "return error" here, you will have made a failure
|
||||
* in any submounts to fail the whole group. There was old unused code
|
||||
* here before.
|
||||
*/
|
||||
if (error > 0)
|
||||
n->n_error = error;
|
||||
|
||||
else if (error < 0) {
|
||||
glob_error = -1;
|
||||
if (!asked_for_wakeup) {
|
||||
asked_for_wakeup = 1;
|
||||
sched_task(wakeup_task, (voidp) mf, (voidp) m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return glob_error;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nfsx_cont(int rc, int term, voidp closure)
|
||||
{
|
||||
mntfs *mf = (mntfs *) closure;
|
||||
struct nfsx *nx = (struct nfsx *) mf->mf_private;
|
||||
nfsx_mnt *n = nx->nx_try;
|
||||
|
||||
n->n_mnt->mf_flags &= ~(MFF_ERROR | MFF_MOUNTING);
|
||||
mf->mf_flags &= ~MFF_ERROR;
|
||||
|
||||
/*
|
||||
* Wakeup anything waiting for this mount
|
||||
*/
|
||||
wakeup((voidp) n->n_mnt);
|
||||
|
||||
if (rc || term) {
|
||||
if (term) {
|
||||
/*
|
||||
* Not sure what to do for an error code.
|
||||
*/
|
||||
plog(XLOG_ERROR, "mount for %s got signal %d", n->n_mnt->mf_mount, term);
|
||||
n->n_error = EIO;
|
||||
} else {
|
||||
/*
|
||||
* Check for exit status
|
||||
*/
|
||||
errno = rc; /* XXX */
|
||||
plog(XLOG_ERROR, "%s: mount (nfsx_cont): %m", n->n_mnt->mf_mount);
|
||||
n->n_error = rc;
|
||||
}
|
||||
free_mntfs(n->n_mnt);
|
||||
n->n_mnt = new_mntfs();
|
||||
n->n_mnt->mf_error = n->n_error;
|
||||
n->n_mnt->mf_flags |= MFF_ERROR;
|
||||
} else {
|
||||
/*
|
||||
* The mount worked.
|
||||
*/
|
||||
mf_mounted(n->n_mnt);
|
||||
n->n_error = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the remaining bits
|
||||
*/
|
||||
if (nfsx_fmount(mf) >= 0) {
|
||||
wakeup((voidp) mf);
|
||||
mf->mf_flags &= ~MFF_MOUNTING;
|
||||
mf_mounted(mf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
try_nfsx_mount(voidp mv)
|
||||
{
|
||||
mntfs *mf = (mntfs *) mv;
|
||||
int error;
|
||||
|
||||
mf->mf_flags |= MFF_MOUNTING;
|
||||
error = (*mf->mf_ops->fmount_fs) (mf);
|
||||
mf->mf_flags &= ~MFF_MOUNTING;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
nfsx_remount(mntfs *mf, int fg)
|
||||
{
|
||||
struct nfsx *nx = (struct nfsx *) mf->mf_private;
|
||||
nfsx_mnt *n;
|
||||
int glob_error = -1;
|
||||
|
||||
for (n = nx->nx_v; n < nx->nx_v + nx->nx_c; n++) {
|
||||
mntfs *m = n->n_mnt;
|
||||
if (n->n_error < 0) {
|
||||
if (!(m->mf_flags & MFF_MKMNT) && m->mf_ops->fs_flags & FS_MKMNT) {
|
||||
int error = mkdirs(m->mf_mount, 0555);
|
||||
if (!error)
|
||||
m->mf_flags |= MFF_MKMNT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate through the mntfs's and mount each filesystem
|
||||
* which is not yet mounted.
|
||||
*/
|
||||
for (n = nx->nx_v; n < nx->nx_v + nx->nx_c; n++) {
|
||||
mntfs *m = n->n_mnt;
|
||||
if (n->n_error < 0) {
|
||||
/*
|
||||
* Check fmount entry pt. exists
|
||||
* and then mount...
|
||||
*/
|
||||
if (!m->mf_ops->fmount_fs) {
|
||||
n->n_error = EINVAL;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
dlog("calling underlying fmount on %s", m->mf_mount);
|
||||
#endif /* DEBUG */
|
||||
if (!fg && foreground && (m->mf_ops->fs_flags & FS_MBACKGROUND)) {
|
||||
m->mf_flags |= MFF_MOUNTING; /* XXX */
|
||||
#ifdef DEBUG
|
||||
dlog("backgrounding mount of \"%s\"", m->mf_info);
|
||||
#endif /* DEBUG */
|
||||
nx->nx_try = n;
|
||||
run_task(try_nfsx_mount, (voidp) m, nfsx_cont, (voidp) mf);
|
||||
n->n_error = -1;
|
||||
return -1;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
dlog("foreground mount of \"%s\" ...", mf->mf_info);
|
||||
#endif /* DEBUG */
|
||||
n->n_error = (*m->mf_ops->fmount_fs) (m);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (n->n_error > 0) {
|
||||
errno = n->n_error; /* XXX */
|
||||
dlog("underlying fmount of %s failed: %m", m->mf_mount);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (n->n_error == 0) {
|
||||
glob_error = 0;
|
||||
} else if (glob_error < 0) {
|
||||
glob_error = n->n_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return glob_error < 0 ? 0 : glob_error;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
nfsx_fmount(mntfs *mf)
|
||||
{
|
||||
return nfsx_remount(mf, FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unmount an NFS hierarchy.
|
||||
* Note that this is called in the foreground
|
||||
* and so may hang under extremely rare conditions.
|
||||
*/
|
||||
static int
|
||||
nfsx_fumount(mntfs *mf)
|
||||
{
|
||||
struct nfsx *nx = (struct nfsx *) mf->mf_private;
|
||||
nfsx_mnt *n;
|
||||
int glob_error = 0;
|
||||
|
||||
/*
|
||||
* Iterate in reverse through the mntfs's and unmount each filesystem
|
||||
* which is mounted.
|
||||
*/
|
||||
for (n = nx->nx_v + nx->nx_c - 1; n >= nx->nx_v; --n) {
|
||||
mntfs *m = n->n_mnt;
|
||||
/*
|
||||
* If this node has not been messed with
|
||||
* and there has been no error so far
|
||||
* then try and unmount.
|
||||
* If an error had occured then zero
|
||||
* the error code so that the remount
|
||||
* only tries to unmount those nodes
|
||||
* which had been successfully unmounted.
|
||||
*/
|
||||
if (n->n_error == 0) {
|
||||
#ifdef DEBUG
|
||||
dlog("calling underlying fumount on %s", m->mf_mount);
|
||||
#endif /* DEBUG */
|
||||
n->n_error = (*m->mf_ops->fumount_fs) (m);
|
||||
if (n->n_error) {
|
||||
glob_error = n->n_error;
|
||||
n->n_error = 0;
|
||||
} else {
|
||||
/*
|
||||
* Make sure remount gets this node
|
||||
*/
|
||||
n->n_error = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If any unmounts failed then remount the
|
||||
* whole lot...
|
||||
*/
|
||||
if (glob_error) {
|
||||
glob_error = nfsx_remount(mf, TRUE);
|
||||
if (glob_error) {
|
||||
errno = glob_error; /* XXX */
|
||||
plog(XLOG_USER, "nfsx: remount of %s failed: %m", mf->mf_mount);
|
||||
}
|
||||
glob_error = EBUSY;
|
||||
} else {
|
||||
/*
|
||||
* Remove all the mount points
|
||||
*/
|
||||
for (n = nx->nx_v; n < nx->nx_v + nx->nx_c; n++) {
|
||||
mntfs *m = n->n_mnt;
|
||||
am_node am;
|
||||
|
||||
/*
|
||||
* XXX: all the umounted handler needs is a
|
||||
* mntfs pointer, so pass an am_node with the right
|
||||
* pointer in it.
|
||||
*/
|
||||
memset((voidp) &am, 0, sizeof(am));
|
||||
am.am_mnt = m;
|
||||
#ifdef DEBUG
|
||||
dlog("calling underlying umounted on %s", m->mf_mount);
|
||||
#endif /* DEBUG */
|
||||
(*m->mf_ops->umounted) (&am);
|
||||
|
||||
if (n->n_error < 0) {
|
||||
if (m->mf_ops->fs_flags & FS_MKMNT) {
|
||||
(void) rmdirs(m->mf_mount);
|
||||
m->mf_flags &= ~MFF_MKMNT;
|
||||
}
|
||||
}
|
||||
free_mntfs(m);
|
||||
n->n_mnt = 0;
|
||||
n->n_error = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return glob_error;
|
||||
}
|
166
usr.sbin/amd/amd/ops_pcfs.c
Normal file
166
usr.sbin/amd/amd/ops_pcfs.c
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: ops_pcfs.c,v 1.1.1.1 1997/07/24 21:21:45 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* PC (MS-DOS) file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* forward definitions */
|
||||
static char *pcfs_match(am_opts *fo);
|
||||
static int pcfs_fmount(mntfs *mf);
|
||||
static int pcfs_fumount(mntfs *mf);
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops pcfs_ops =
|
||||
{
|
||||
"pcfs",
|
||||
pcfs_match,
|
||||
0, /* pcfs_init */
|
||||
auto_fmount,
|
||||
pcfs_fmount,
|
||||
auto_fumount,
|
||||
pcfs_fumount,
|
||||
efs_lookuppn,
|
||||
efs_readdir,
|
||||
0, /* pcfs_readlink */
|
||||
0, /* pcfs_mounted */
|
||||
0, /* pcfs_umounted */
|
||||
find_afs_srvr,
|
||||
FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* PCFS needs remote filesystem.
|
||||
*/
|
||||
static char *
|
||||
pcfs_match(am_opts *fo)
|
||||
{
|
||||
if (!fo->opt_dev) {
|
||||
plog(XLOG_USER, "pcfs: no source device specified");
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
dlog("PCFS: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Determine magic cookie to put in mtab
|
||||
*/
|
||||
return strdup(fo->opt_dev);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
mount_pcfs(char *dir, char *fs_name, char *opts)
|
||||
{
|
||||
pcfs_args_t pcfs_args;
|
||||
mntent_t mnt;
|
||||
int flags;
|
||||
|
||||
/*
|
||||
* Figure out the name of the file system type.
|
||||
*/
|
||||
MTYPE_TYPE type = MOUNT_TYPE_PCFS;
|
||||
|
||||
memset((voidp) &pcfs_args, 0, sizeof(pcfs_args)); /* Paranoid */
|
||||
|
||||
/*
|
||||
* Fill in the mount structure
|
||||
*/
|
||||
mnt.mnt_dir = dir;
|
||||
mnt.mnt_fsname = fs_name;
|
||||
mnt.mnt_type = MNTTAB_TYPE_PCFS;
|
||||
mnt.mnt_opts = opts;
|
||||
|
||||
flags = compute_mount_flags(&mnt);
|
||||
|
||||
#ifdef HAVE_FIELD_PCFS_ARGS_T_FSPEC
|
||||
pcfs_args.fspec = fs_name;
|
||||
#endif /* HAVE_FIELD_PCFS_ARGS_T_FSPEC */
|
||||
|
||||
#ifdef HAVE_FIELD_PCFS_ARGS_T_SECONDSWEST
|
||||
pcfs_args.secondswest = 0; /* XXX: fill in correct values */
|
||||
#endif /* HAVE_FIELD_PCFS_ARGS_T_SECONDSWEST */
|
||||
#ifdef HAVE_FIELD_PCFS_ARGS_T_DSTTIME
|
||||
pcfs_args.dsttime = 0; /* XXX: fill in correct values */
|
||||
#endif /* HAVE_FIELD_PCFS_ARGS_T_DSTTIME */
|
||||
|
||||
/*
|
||||
* Call generic mount routine
|
||||
*/
|
||||
return mount_fs(&mnt, flags, (caddr_t) & pcfs_args, 0, type, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pcfs_fmount(mntfs *mf)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = mount_pcfs(mf->mf_mount, mf->mf_info, mf->mf_mopts);
|
||||
if (error) {
|
||||
errno = error;
|
||||
plog(XLOG_ERROR, "mount_pcfs: %m");
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pcfs_fumount(mntfs *mf)
|
||||
{
|
||||
return UMOUNT_FS(mf->mf_mount);
|
||||
}
|
191
usr.sbin/amd/amd/ops_pfs.c
Normal file
191
usr.sbin/amd/amd/ops_pfs.c
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1989 Jan-Simon Pendry
|
||||
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: ops_pfs.c,v 1.1.1.1 1997/07/24 21:21:46 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Program file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* forward definitions */
|
||||
static char *pfs_match(am_opts *fo);
|
||||
static int pfs_fmount(mntfs *mf);
|
||||
static int pfs_fumount(mntfs *mf);
|
||||
static int pfs_init(mntfs *mf);
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops pfs_ops =
|
||||
{
|
||||
"program",
|
||||
pfs_match,
|
||||
pfs_init,
|
||||
auto_fmount,
|
||||
pfs_fmount,
|
||||
auto_fumount,
|
||||
pfs_fumount,
|
||||
efs_lookuppn,
|
||||
efs_readdir,
|
||||
0, /* pfs_readlink */
|
||||
0, /* pfs_mounted */
|
||||
0, /* pfs_umounted */
|
||||
find_afs_srvr,
|
||||
FS_BACKGROUND | FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Execute needs a mount and unmount command.
|
||||
*/
|
||||
static char *
|
||||
pfs_match(am_opts *fo)
|
||||
{
|
||||
char *prog;
|
||||
|
||||
if (!fo->opt_mount || !fo->opt_unmount) {
|
||||
plog(XLOG_USER, "program: no mount/unmount specified");
|
||||
return 0;
|
||||
}
|
||||
prog = strchr(fo->opt_mount, ' ');
|
||||
|
||||
return strdup(prog ? prog + 1 : fo->opt_mount);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pfs_init(mntfs *mf)
|
||||
{
|
||||
/*
|
||||
* Save unmount command
|
||||
*/
|
||||
if (mf->mf_refc == 1) {
|
||||
mf->mf_private = (voidp) strdup(mf->mf_fo->opt_unmount);
|
||||
mf->mf_prfree = (void (*)()) free;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pfs_exec(char *info)
|
||||
{
|
||||
char **xivec;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Split copy of command info string
|
||||
*/
|
||||
info = strdup(info);
|
||||
if (info == 0)
|
||||
return ENOBUFS;
|
||||
xivec = strsplit(info, ' ', '\'');
|
||||
|
||||
/*
|
||||
* Put stdout to stderr
|
||||
*/
|
||||
(void) fclose(stdout);
|
||||
(void) dup(fileno(logfp));
|
||||
if (fileno(logfp) != fileno(stderr)) {
|
||||
(void) fclose(stderr);
|
||||
(void) dup(fileno(logfp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Try the exec
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_FULL) {
|
||||
char **cp = xivec;
|
||||
plog(XLOG_DEBUG, "executing (un)mount command...");
|
||||
while (*cp) {
|
||||
plog(XLOG_DEBUG, "arg[%d] = '%s'", cp - xivec, *cp);
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (xivec[0] == 0 || xivec[1] == 0) {
|
||||
errno = EINVAL;
|
||||
plog(XLOG_USER, "1st/2nd args missing to (un)mount program");
|
||||
} else {
|
||||
(void) execv(xivec[0], xivec + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save error number
|
||||
*/
|
||||
error = errno;
|
||||
plog(XLOG_ERROR, "exec failed: %m");
|
||||
|
||||
/*
|
||||
* Free allocate memory
|
||||
*/
|
||||
free((voidp) info);
|
||||
free((voidp) xivec);
|
||||
|
||||
/*
|
||||
* Return error
|
||||
*/
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pfs_fmount(mntfs *mf)
|
||||
{
|
||||
return pfs_exec(mf->mf_fo->opt_mount);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pfs_fumount(mntfs *mf)
|
||||
{
|
||||
return pfs_exec((char *) mf->mf_private);
|
||||
}
|
142
usr.sbin/amd/amd/ops_sfs.c
Normal file
142
usr.sbin/amd/amd/ops_sfs.c
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: ops_sfs.c,v 1.1.1.1 1997/07/24 21:21:46 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Symbol-link file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
static int sfs_fmount(mntfs *mf);
|
||||
|
||||
/*
|
||||
* Ops structures
|
||||
*/
|
||||
am_ops sfs_ops =
|
||||
{
|
||||
"link",
|
||||
sfs_match,
|
||||
0, /* sfs_init */
|
||||
auto_fmount,
|
||||
sfs_fmount,
|
||||
auto_fumount,
|
||||
sfs_fumount,
|
||||
efs_lookuppn,
|
||||
efs_readdir,
|
||||
0, /* sfs_readlink */
|
||||
0, /* sfs_mounted */
|
||||
0, /* sfs_umounted */
|
||||
find_afs_srvr,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* SFS needs a link.
|
||||
*/
|
||||
char *
|
||||
sfs_match(am_opts *fo)
|
||||
{
|
||||
|
||||
if (!fo->opt_fs) {
|
||||
plog(XLOG_USER, "link: no fs specified");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bug report (14/12/89) from Jay Plett <jay@princeton.edu>
|
||||
* If an automount point has the same name as an existing
|
||||
* link type mount Amd hits a race condition and either hangs
|
||||
* or causes a symlink loop.
|
||||
*
|
||||
* If fs begins with a '/' change the opt_fs & opt_sublink
|
||||
* fields so that the fs option doesn't end up pointing at
|
||||
* an existing symlink.
|
||||
*
|
||||
* If sublink is nil then set sublink to fs
|
||||
* else set sublink to fs / sublink
|
||||
*
|
||||
* Finally set fs to ".".
|
||||
*/
|
||||
if (*fo->opt_fs == '/') {
|
||||
char *fullpath;
|
||||
char *link = fo->opt_sublink;
|
||||
if (link) {
|
||||
if (*link == '/')
|
||||
fullpath = strdup(link);
|
||||
else
|
||||
fullpath = str3cat((char *) 0, fo->opt_fs, "/", link);
|
||||
} else {
|
||||
fullpath = strdup(fo->opt_fs);
|
||||
}
|
||||
|
||||
if (fo->opt_sublink)
|
||||
free(fo->opt_sublink);
|
||||
fo->opt_sublink = fullpath;
|
||||
fo->opt_fs = str3cat(fo->opt_fs, ".", fullpath, "");
|
||||
}
|
||||
|
||||
return strdup(fo->opt_fs);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sfs_fmount(mntfs *mf)
|
||||
{
|
||||
/*
|
||||
* Wow - this is hard to implement! :-)
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sfs_fumount(mntfs *mf)
|
||||
{
|
||||
return 0;
|
||||
}
|
100
usr.sbin/amd/amd/ops_sfsx.c
Normal file
100
usr.sbin/amd/amd/ops_sfsx.c
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: ops_sfsx.c,v 1.1.1.1 1997/07/24 21:21:47 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Symbol-link file system, with test that the target of the link exists.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
static int sfsx_mount(am_node *mp);
|
||||
|
||||
struct am_ops sfsx_ops =
|
||||
{
|
||||
"linkx",
|
||||
sfs_match,
|
||||
0, /* sfsx_init */
|
||||
sfsx_mount,
|
||||
0,
|
||||
auto_fumount,
|
||||
sfs_fumount,
|
||||
efs_lookuppn,
|
||||
efs_readdir,
|
||||
0, /* sfsx_readlink */
|
||||
0, /* sfsx_mounted */
|
||||
0, /* sfsx_umounted */
|
||||
find_afs_srvr,
|
||||
FS_MBACKGROUND
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
sfsx_mount(am_node *mp)
|
||||
{
|
||||
/*
|
||||
* Check for existence of target.
|
||||
*/
|
||||
struct stat stb;
|
||||
char *ln;
|
||||
|
||||
if (mp->am_link)
|
||||
ln = mp->am_link;
|
||||
else /* should never occur */
|
||||
ln = mp->am_mnt->mf_mount;
|
||||
|
||||
/*
|
||||
* Use lstat, not stat, since we don't
|
||||
* want to know if the ultimate target of
|
||||
* a symlink chain exists, just the first.
|
||||
*/
|
||||
if (lstat(ln, &stb) < 0)
|
||||
return errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
163
usr.sbin/amd/amd/ops_ufs.c
Normal file
163
usr.sbin/amd/amd/ops_ufs.c
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: ops_ufs.c,v 1.1.1.1 1997/07/24 21:21:47 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* UN*X file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
static char * ufs_match(am_opts *fo);
|
||||
static int ufs_fmount(mntfs *mf);
|
||||
static int ufs_fumount(mntfs *mf);
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops ufs_ops =
|
||||
{
|
||||
"ufs",
|
||||
ufs_match,
|
||||
0, /* ufs_init */
|
||||
auto_fmount,
|
||||
ufs_fmount,
|
||||
auto_fumount,
|
||||
ufs_fumount,
|
||||
efs_lookuppn,
|
||||
efs_readdir,
|
||||
0, /* ufs_readlink */
|
||||
0, /* ufs_mounted */
|
||||
0, /* ufs_umounted */
|
||||
find_afs_srvr,
|
||||
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* UFS needs local filesystem and device.
|
||||
*/
|
||||
static char *
|
||||
ufs_match(am_opts *fo)
|
||||
{
|
||||
|
||||
if (!fo->opt_dev) {
|
||||
plog(XLOG_USER, "ufs: no device specified");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("UFS: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Determine magic cookie to put in mtab
|
||||
*/
|
||||
return strdup(fo->opt_dev);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
mount_ufs(char *dir, char *fs_name, char *opts)
|
||||
{
|
||||
ufs_args_t ufs_args;
|
||||
mntent_t mnt;
|
||||
int flags;
|
||||
|
||||
/*
|
||||
* Figure out the name of the file system type.
|
||||
*/
|
||||
MTYPE_TYPE type = MOUNT_TYPE_UFS;
|
||||
|
||||
memset((voidp) &ufs_args, 0, sizeof(ufs_args)); /* Paranoid */
|
||||
|
||||
/*
|
||||
* Fill in the mount structure
|
||||
*/
|
||||
mnt.mnt_dir = dir;
|
||||
mnt.mnt_fsname = fs_name;
|
||||
mnt.mnt_type = MNTTAB_TYPE_UFS;
|
||||
mnt.mnt_opts = opts;
|
||||
|
||||
flags = compute_mount_flags(&mnt);
|
||||
|
||||
#ifdef HAVE_FIELD_UFS_ARGS_T_FLAGS
|
||||
ufs_args.flags = 0; /* XXX: fix this to correct flags */
|
||||
#endif /* HAVE_FIELD_UFS_ARGS_T_FLAGS */
|
||||
#ifdef HAVE_FIELD_UFS_ARGS_T_FSPEC
|
||||
ufs_args.fspec = fs_name;
|
||||
#endif /* HAVE_FIELD_UFS_ARGS_T_FSPEC */
|
||||
|
||||
/*
|
||||
* Call generic mount routine
|
||||
*/
|
||||
return mount_fs(&mnt, flags, (caddr_t) &ufs_args, 0, type, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ufs_fmount(mntfs *mf)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = mount_ufs(mf->mf_mount, mf->mf_info, mf->mf_mopts);
|
||||
if (error) {
|
||||
errno = error;
|
||||
plog(XLOG_ERROR, "mount_ufs: %m");
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ufs_fumount(mntfs *mf)
|
||||
{
|
||||
return UMOUNT_FS(mf->mf_mount);
|
||||
}
|
2180
usr.sbin/amd/amd2netbsd
Normal file
2180
usr.sbin/amd/amd2netbsd
Normal file
File diff suppressed because it is too large
Load Diff
62
usr.sbin/amd/amq/amq.h
Normal file
62
usr.sbin/amd/amq/amq.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: amq.h,v 1.1.1.1 1997/07/24 21:22:53 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AMQ_H
|
||||
#define _AMQ_H
|
||||
|
||||
/*
|
||||
* external definitions for building amq
|
||||
*/
|
||||
|
||||
extern voidp amqproc_null_1(voidp argp, CLIENT *rqstp);
|
||||
extern amq_mount_tree_p *amqproc_mnttree_1(amq_string *argp, CLIENT *rqstp);
|
||||
extern voidp amqproc_umnt_1(amq_string *argp, CLIENT *rqstp);
|
||||
extern amq_mount_stats *amqproc_stats_1(voidp argp, CLIENT *rqstp);
|
||||
extern amq_mount_tree_list *amqproc_export_1(voidp argp, CLIENT *rqstp);
|
||||
extern int *amqproc_setopt_1(amq_setopt *argp, CLIENT *rqstp);
|
||||
extern amq_mount_info_list *amqproc_getmntfs_1(voidp argp, CLIENT *rqstp);
|
||||
extern int *amqproc_mount_1(voidp argp, CLIENT *rqstp);
|
||||
extern amq_string *amqproc_getvers_1(voidp argp, CLIENT *rqstp);
|
||||
|
||||
#endif /* not _AMQ_H */
|
259
usr.sbin/amd/amq/amq_xdr.c
Normal file
259
usr.sbin/amd/amq/amq_xdr.c
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: amq_xdr.c,v 1.1.1.1 1997/07/24 21:22:53 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amq.h>
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_time_type(XDR *xdrs, time_type *objp)
|
||||
{
|
||||
if (!xdr_long(xdrs, (long *) objp)) {
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_amq_mount_tree(XDR *xdrs, amq_mount_tree *objp)
|
||||
{
|
||||
|
||||
if (!xdr_amq_string(xdrs, &objp->mt_mountinfo)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_amq_string(xdrs, &objp->mt_directory)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_amq_string(xdrs, &objp->mt_mountpoint)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_amq_string(xdrs, &objp->mt_type)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_time_type(xdrs, &objp->mt_mounttime)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_u_short(xdrs, &objp->mt_mountuid)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_int(xdrs, &objp->mt_getattr)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_int(xdrs, &objp->mt_lookup)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_int(xdrs, &objp->mt_readdir)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_int(xdrs, &objp->mt_readlink)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_int(xdrs, &objp->mt_statfs)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_pointer(xdrs, (char **) &objp->mt_next, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_tree)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_pointer(xdrs, (char **) &objp->mt_child, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_tree)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_amq_mount_tree_p(XDR *xdrs, amq_mount_tree_p *objp)
|
||||
{
|
||||
if (!xdr_pointer(xdrs, (char **) objp, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_tree)) {
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_amq_mount_info(XDR *xdrs, amq_mount_info *objp)
|
||||
{
|
||||
|
||||
if (!xdr_amq_string(xdrs, &objp->mi_type)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_amq_string(xdrs, &objp->mi_mountpt)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_amq_string(xdrs, &objp->mi_mountinfo)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_amq_string(xdrs, &objp->mi_fserver)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_int(xdrs, &objp->mi_error)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_int(xdrs, &objp->mi_refc)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_int(xdrs, &objp->mi_up)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_amq_mount_info_list(XDR *xdrs, amq_mount_info_list *objp)
|
||||
{
|
||||
if (!xdr_array(xdrs,
|
||||
(char **) &objp->amq_mount_info_list_val,
|
||||
(u_int *) &objp->amq_mount_info_list_len,
|
||||
~0,
|
||||
sizeof(amq_mount_info),
|
||||
(XDRPROC_T_TYPE) xdr_amq_mount_info)) {
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_amq_mount_tree_list(XDR *xdrs, amq_mount_tree_list *objp)
|
||||
{
|
||||
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),
|
||||
(XDRPROC_T_TYPE) xdr_amq_mount_tree_p)) {
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_amq_mount_stats(XDR *xdrs, amq_mount_stats *objp)
|
||||
{
|
||||
|
||||
if (!xdr_int(xdrs, &objp->as_drops)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_int(xdrs, &objp->as_stale)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_int(xdrs, &objp->as_mok)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_int(xdrs, &objp->as_merr)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_int(xdrs, &objp->as_uerr)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_amq_opt(XDR *xdrs, amq_opt *objp)
|
||||
{
|
||||
if (!xdr_enum(xdrs, (enum_t *) objp)) {
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_amq_setopt(XDR *xdrs, amq_setopt *objp)
|
||||
{
|
||||
|
||||
if (!xdr_amq_opt(xdrs, &objp->as_opt)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (!xdr_amq_string(xdrs, &objp->as_str)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_pri_free(XDRPROC_T_TYPE xdr_args, caddr_t args_ptr)
|
||||
{
|
||||
XDR xdr;
|
||||
|
||||
xdr.x_op = XDR_FREE;
|
||||
return ((*xdr_args) (&xdr, (caddr_t *) args_ptr));
|
||||
}
|
7
usr.sbin/amd/fixmount/Makefile
Normal file
7
usr.sbin/amd/fixmount/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# $NetBSD: Makefile,v 1.1.1.1 1997/07/24 21:24:12 christos Exp $
|
||||
|
||||
PROG= fixmount
|
||||
SRCS= check_mount.c fixmount.c
|
||||
MAN+= fixmount.8
|
||||
|
||||
.include <bsd.prog.mk>
|
78
usr.sbin/amd/fixmount/check_mount.c
Normal file
78
usr.sbin/amd/fixmount/check_mount.c
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: check_mount.c,v 1.1.1.1 1997/07/24 21:24:12 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
|
||||
extern int is_same_host(char *name1, char *name2, struct in_addr addr2);
|
||||
|
||||
|
||||
int
|
||||
fixmount_check_mount(char *host, struct in_addr hostaddr, char *path)
|
||||
{
|
||||
struct statfs *mntbufp, *mntp;
|
||||
int nloc, i;
|
||||
char *colon;
|
||||
|
||||
/* read mount table from kernel */
|
||||
nloc = getmntinfo(&mntbufp, MNT_NOWAIT);
|
||||
if (nloc <= 0) {
|
||||
perror("getmntinfo");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mntp = mntbufp;
|
||||
for (i=0; i<nloc; ++i) {
|
||||
if ((colon = strchr(mntp->f_mntfromname, ':'))) {
|
||||
*colon = '\0';
|
||||
if (STREQ(colon + 1, path) &&
|
||||
is_same_host(mntp->f_mntfromname, host, hostaddr))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
121
usr.sbin/amd/fixmount/fixmount.8
Normal file
121
usr.sbin/amd/fixmount/fixmount.8
Normal file
@ -0,0 +1,121 @@
|
||||
.\" $Id: fixmount.8,v 1.1.1.1 1997/07/24 21:24:12 christos Exp $
|
||||
.TH FIXMOUNT 8L "26 Feb 1993"
|
||||
.SH NAME
|
||||
fixmount \- fix remote mount entries
|
||||
.SH SYNOPSIS
|
||||
.B /usr/local/etc/fixmount
|
||||
[
|
||||
.B \-adervq
|
||||
]
|
||||
[
|
||||
.B \-h
|
||||
.I name
|
||||
]
|
||||
.I host
|
||||
\&...
|
||||
.SH DESCRIPTION
|
||||
.IX "fixmount command" "" "\fLfixmount\fP \(em fix remote mount entries"
|
||||
.LP
|
||||
.B fixmount
|
||||
is a variant of
|
||||
.BR showmount (8)
|
||||
that can delete bogus mount entries in remote
|
||||
.BR mountd (8C)
|
||||
daemons.
|
||||
The actions specified by the options are performed for each
|
||||
.I host
|
||||
in turn.
|
||||
.SH OPTIONS
|
||||
The
|
||||
.BR \-a ,
|
||||
.BR \-d ,
|
||||
and
|
||||
.B \-e
|
||||
options work as in
|
||||
.BR showmount (8)
|
||||
except that only entries pertaining to the local host are printed.
|
||||
.TP
|
||||
.B \-r
|
||||
Removes those remote mount entries on
|
||||
.I host
|
||||
that do not correspond to current mounts, i.e., which are left-over
|
||||
from a crash or are the result of improper mount protocol.
|
||||
The actuality of mounts is verified using the entries in
|
||||
.BR /etc/mtab .
|
||||
.TP
|
||||
.B \-v
|
||||
Verify remote mounts. Similar to
|
||||
.B \-r
|
||||
except that only a notification message is printed for each bogus entry
|
||||
found. The remote mount table is not changed.
|
||||
.TP
|
||||
.B \-A
|
||||
Issues a command to the remote mountd declaring that ALL of its filesystems
|
||||
have been unmounted. This should be used with caution, as it removes all
|
||||
remote mount entries pertaining to the local system, whether or not any
|
||||
filesystems are still mounted locally.
|
||||
.TP
|
||||
.B \-q
|
||||
Be quiet.
|
||||
Suppresses error messages due to timeouts and "Program not registered",
|
||||
i.e., due to remote hosts not supporting RPC or not running mountd.
|
||||
.TP
|
||||
.BI \-h \ name
|
||||
Pretend the local hostname is
|
||||
.IR name .
|
||||
This is useful after the local hostname has been changed and rmtab entries
|
||||
using the old name remain on a remote machine.
|
||||
Unfortunately, most mountd's won't be able to successfully handle removal
|
||||
of such entries, so this option is useful in combination with
|
||||
.B \-v
|
||||
only.
|
||||
.br
|
||||
This option also saves time as comparisons of remotely recorded and local
|
||||
hostnames by address are avoided.
|
||||
.SH FILES
|
||||
.PD 0
|
||||
.TP 20
|
||||
.B /etc/mtab
|
||||
List of current mounts.
|
||||
.TP
|
||||
.B /etc/rmtab
|
||||
Backup file for remote mount entries on NFS server.
|
||||
.PD
|
||||
.SH "SEE ALSO"
|
||||
showmount(8),
|
||||
mtab(5),
|
||||
rmtab(5),
|
||||
mountd(8C)
|
||||
.SH BUGS
|
||||
No attempt is made to verify the information in
|
||||
.B /etc/mtab
|
||||
itself.
|
||||
.PP
|
||||
Since swap file mounts are not recorded in
|
||||
.BR /etc/mtab ,
|
||||
a heuristic specific to SunOS is used to determine whether such a mount
|
||||
is actual (replacing the string "swap" with "root" and verifying the resulting
|
||||
path).
|
||||
.PP
|
||||
Symbolic links on the server will cause the path in the remote entry to differ
|
||||
from the one in
|
||||
.BR /etc/mtab .
|
||||
To catch those cases, a filesystem is also deemed mounted if its
|
||||
.I local
|
||||
mount point is identical to the remote entry.
|
||||
I.e., on a SunOS diskless client,
|
||||
.B server:/export/share/sunos.4.1.1
|
||||
is actually
|
||||
.BR /usr/share .
|
||||
Since the local mount point is
|
||||
.B /usr/share
|
||||
as well this will be handled correctly.
|
||||
.PP
|
||||
There is no way to clear a stale entry in a remote mountd after the
|
||||
local hostname (or whatever reverse name resolution returns for it)
|
||||
has been changed. To take care of these cases,
|
||||
the remote /etc/rmtab file has to be edited and mountd restarted.
|
||||
.PP
|
||||
The RPC timeouts for mountd calls can only be changed by recompiling.
|
||||
The defaults are 2 seconds for client handle creation and 5 seconds for
|
||||
RPC calls.
|
513
usr.sbin/amd/fixmount/fixmount.c
Normal file
513
usr.sbin/amd/fixmount/fixmount.c
Normal file
@ -0,0 +1,513 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: fixmount.c,v 1.1.1.1 1997/07/24 21:24:11 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
|
||||
#define CREATE_TIMEOUT 2 /* seconds */
|
||||
#define CALL_TIMEOUT 5 /* seconds */
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
# define INADDR_NONE 0xffffffff
|
||||
#endif /* not INADDR_NONE */
|
||||
|
||||
/* Constant defs */
|
||||
#define ALL 1
|
||||
#define DIRS 2
|
||||
|
||||
#define DODUMP 0x1
|
||||
#define DOEXPORTS 0x2
|
||||
#define DOREMOVE 0x4
|
||||
#define DOVERIFY 0x8
|
||||
#define DOREMALL 0x10
|
||||
|
||||
static CLIENT *clnt_create_timeout();
|
||||
static char dir_path[NFS_MAXPATHLEN];
|
||||
static char thishost[MAXHOSTNAMELEN] = "";
|
||||
static exports mntexports;
|
||||
static int quiet = 0;
|
||||
static int type = 0;
|
||||
static jmp_buf before_rpc;
|
||||
static mountlist mntdump;
|
||||
static struct in_addr thisaddr;
|
||||
|
||||
extern int fixmount_check_mount(char *host, struct in_addr hostaddr, char *path);
|
||||
|
||||
/* dummy variables */
|
||||
char *progname;
|
||||
char hostname[MAXHOSTNAMELEN];
|
||||
int orig_umask, foreground, debug_flags;
|
||||
pid_t mypid;
|
||||
serv_state amd_state;
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: fixmount [-adervAqf] [-h hostname] host ...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check hostname against other name and its IP address
|
||||
*/
|
||||
int
|
||||
is_same_host(char *name1, char *name2, struct in_addr addr2)
|
||||
{
|
||||
if (strcasecmp(name1, name2) == 0) {
|
||||
return 1;
|
||||
} else if (addr2.s_addr == INADDR_NONE) {
|
||||
return 0;
|
||||
} else {
|
||||
static char lasthost[MAXHOSTNAMELEN] = "";
|
||||
static struct in_addr addr1;
|
||||
struct hostent *he;
|
||||
|
||||
/*
|
||||
* To save nameserver lookups, and because this function
|
||||
* is typically called repeatedly on the same names,
|
||||
* cache the last lookup result and reuse it if possible.
|
||||
*/
|
||||
if (strcasecmp(name1, lasthost) == 0) {
|
||||
return (addr1.s_addr == addr2.s_addr);
|
||||
} else if (!(he = gethostbyname(name1))) {
|
||||
return 0;
|
||||
} else {
|
||||
strncpy(lasthost, name1, sizeof(lasthost) - 1);
|
||||
memcpy(&addr1, he->h_addr, sizeof(addr1));
|
||||
return (addr1.s_addr == addr2.s_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print the binary tree in inorder so that output is sorted.
|
||||
*/
|
||||
void
|
||||
print_dump(mountlist mp)
|
||||
{
|
||||
if (mp == NULL)
|
||||
return;
|
||||
if (is_same_host(mp->ml_hostname, thishost, thisaddr)) {
|
||||
switch (type) {
|
||||
case ALL:
|
||||
printf("%s:%s\n", mp->ml_hostname, mp->ml_directory);
|
||||
break;
|
||||
case DIRS:
|
||||
printf("%s\n", mp->ml_directory);
|
||||
break;
|
||||
default:
|
||||
printf("%s\n", mp->ml_hostname);
|
||||
break;
|
||||
};
|
||||
}
|
||||
if (mp->ml_next)
|
||||
print_dump(mp->ml_next);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* remove entry from remote rmtab
|
||||
*/
|
||||
int
|
||||
remove_mount(CLIENT *client, char *host, mountlist ml, int fixit)
|
||||
{
|
||||
enum clnt_stat estat;
|
||||
struct timeval tv;
|
||||
char *pathp = dir_path;
|
||||
|
||||
strncpy(dir_path, ml->ml_directory, sizeof(dir_path));
|
||||
|
||||
if (!fixit) {
|
||||
printf("%s: bogus mount %s:%s\n", host, ml->ml_hostname, ml->ml_directory);
|
||||
fflush(stdout);
|
||||
} else {
|
||||
printf("%s: removing %s:%s\n", host, ml->ml_hostname, ml->ml_directory);
|
||||
fflush(stdout);
|
||||
|
||||
tv.tv_sec = CALL_TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if ((estat = clnt_call(client,
|
||||
MOUNTPROC_UMNT,
|
||||
(XDRPROC_T_TYPE) xdr_dirpath,
|
||||
(char *) &pathp,
|
||||
(XDRPROC_T_TYPE) xdr_void,
|
||||
(char *) 0,
|
||||
tv)) != RPC_SUCCESS) {
|
||||
fprintf(stderr, "%s:%s MOUNTPROC_UMNT: ",
|
||||
host, ml->ml_directory);
|
||||
clnt_perrno(estat);
|
||||
fflush(stderr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fix mount list on remote host
|
||||
*/
|
||||
void
|
||||
fix_rmtab(CLIENT *client, char *host, mountlist mp, int fixit, int force)
|
||||
{
|
||||
mountlist p;
|
||||
struct hostent *he;
|
||||
struct in_addr hostaddr;
|
||||
|
||||
/*
|
||||
* Obtain remote address for comparisons
|
||||
*/
|
||||
if ((he = gethostbyname(host))) {
|
||||
memcpy(&hostaddr, he->h_addr, sizeof(hostaddr));
|
||||
} else {
|
||||
hostaddr.s_addr = INADDR_NONE;
|
||||
}
|
||||
|
||||
for (p = mp; p; p = p->ml_next) {
|
||||
if (is_same_host(p->ml_hostname, thishost, thisaddr)) {
|
||||
if (force || !fixmount_check_mount(host, hostaddr, p->ml_directory))
|
||||
remove_mount(client, host, p, fixit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* remove all entries from remote rmtab
|
||||
*/
|
||||
int
|
||||
remove_all(CLIENT *client, char *host)
|
||||
{
|
||||
enum clnt_stat estat;
|
||||
struct timeval tv;
|
||||
|
||||
printf("%s: removing ALL\n", host);
|
||||
fflush(stdout);
|
||||
|
||||
tv.tv_sec = CALL_TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if ((estat = clnt_call(client,
|
||||
MOUNTPROC_UMNTALL,
|
||||
(XDRPROC_T_TYPE) xdr_void,
|
||||
(char *) 0,
|
||||
(XDRPROC_T_TYPE) xdr_void,
|
||||
(char *) 0,
|
||||
tv)) != RPC_SUCCESS) {
|
||||
/*
|
||||
* RPC_SYSTEMERROR is returned even if all went well
|
||||
*/
|
||||
if (estat != RPC_SYSTEMERROR) {
|
||||
fprintf(stderr, "%s MOUNTPROC_UMNTALL: ", host);
|
||||
clnt_perrno(estat);
|
||||
fflush(stderr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This command queries the NFS mount daemon for it's mount list and/or
|
||||
* it's exports list and prints them out.
|
||||
* See "NFS: Network File System Protocol Specification, RFC1094, Appendix A"
|
||||
* for detailed information on the protocol.
|
||||
*/
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
AUTH *auth;
|
||||
CLIENT *client;
|
||||
char *host;
|
||||
enum clnt_stat estat;
|
||||
exports exp;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
groups grp;
|
||||
int ch;
|
||||
int force = 0;
|
||||
int morethanone;
|
||||
register int rpcs = 0;
|
||||
struct timeval tv;
|
||||
|
||||
while ((ch = getopt(argc, argv, "adervAqfh:")) != EOF)
|
||||
switch ((char) ch) {
|
||||
|
||||
case 'a':
|
||||
if (type == 0) {
|
||||
type = ALL;
|
||||
rpcs |= DODUMP;
|
||||
} else
|
||||
usage();
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (type == 0) {
|
||||
type = DIRS;
|
||||
rpcs |= DODUMP;
|
||||
} else
|
||||
usage();
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
rpcs |= DOEXPORTS;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
rpcs |= DOREMOVE;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
rpcs |= DOREMALL;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
rpcs |= DOVERIFY;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
force = 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
strncpy(thishost, optarg, sizeof(thishost));
|
||||
thishost[sizeof(thishost) - 1] = '\0';
|
||||
break;
|
||||
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
|
||||
if (optind == argc)
|
||||
usage();
|
||||
|
||||
if (rpcs == 0)
|
||||
rpcs = DODUMP;
|
||||
|
||||
if (!*thishost) {
|
||||
struct hostent *he;
|
||||
|
||||
if (gethostname(thishost, sizeof(thishost)) < 0) {
|
||||
perror("gethostname");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* We need the hostname as it appears to the other side's
|
||||
* mountd, so get our own hostname by reverse address
|
||||
* resolution.
|
||||
*/
|
||||
if (!(he = gethostbyname(thishost))) {
|
||||
fprintf(stderr, "gethostbyname failed on %s\n",
|
||||
thishost);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(&thisaddr, he->h_addr, sizeof(thisaddr));
|
||||
if (!(he = gethostbyaddr((char *) &thisaddr, sizeof(thisaddr),
|
||||
he->h_addrtype))) {
|
||||
fprintf(stderr, "gethostbyaddr failed on %s\n",
|
||||
inet_ntoa(thisaddr));
|
||||
exit(1);
|
||||
}
|
||||
strncpy(thishost, he->h_name, sizeof(thishost));
|
||||
thishost[sizeof(thishost) - 1] = '\0';
|
||||
} else {
|
||||
thisaddr.s_addr = INADDR_NONE;
|
||||
}
|
||||
|
||||
if (!(auth = authunix_create_default())) {
|
||||
fprintf(stderr, "couldn't create authentication handle\n");
|
||||
exit(1);
|
||||
}
|
||||
morethanone = (optind + 1 < argc);
|
||||
|
||||
for (; optind < argc; optind++) {
|
||||
|
||||
host = argv[optind];
|
||||
tv.tv_sec = CREATE_TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (!(client = clnt_create_timeout(host, &tv)))
|
||||
continue;
|
||||
|
||||
client->cl_auth = auth;
|
||||
tv.tv_sec = CALL_TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (rpcs & (DODUMP | DOREMOVE | DOVERIFY))
|
||||
if ((estat = clnt_call(client,
|
||||
MOUNTPROC_DUMP,
|
||||
(XDRPROC_T_TYPE) xdr_void,
|
||||
(char *) 0,
|
||||
(XDRPROC_T_TYPE) xdr_mountlist,
|
||||
(char *) &mntdump,
|
||||
tv)) != RPC_SUCCESS) {
|
||||
fprintf(stderr, "%s: MOUNTPROC_DUMP: ", host);
|
||||
clnt_perrno(estat);
|
||||
fflush(stderr);
|
||||
mntdump = NULL;
|
||||
goto next;
|
||||
}
|
||||
if (rpcs & DOEXPORTS)
|
||||
if ((estat = clnt_call(client,
|
||||
MOUNTPROC_EXPORT,
|
||||
(XDRPROC_T_TYPE) xdr_void,
|
||||
(char *) 0,
|
||||
(XDRPROC_T_TYPE) xdr_exports,
|
||||
(char *) &mntexports,
|
||||
tv)) != RPC_SUCCESS) {
|
||||
fprintf(stderr, "%s: MOUNTPROC_EXPORT: ", host);
|
||||
clnt_perrno(estat);
|
||||
fflush(stderr);
|
||||
mntexports = NULL;
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* Now just print out the results */
|
||||
if ((rpcs & (DODUMP | DOEXPORTS)) &&
|
||||
morethanone) {
|
||||
printf(">>> %s <<<\n", host);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
if (rpcs & DODUMP) {
|
||||
print_dump(mntdump);
|
||||
}
|
||||
|
||||
if (rpcs & DOEXPORTS) {
|
||||
exp = mntexports;
|
||||
while (exp) {
|
||||
printf("%-35s", exp->ex_dir);
|
||||
grp = exp->ex_groups;
|
||||
if (grp == NULL) {
|
||||
printf("Everyone\n");
|
||||
} else {
|
||||
while (grp) {
|
||||
printf("%s ", grp->gr_name);
|
||||
grp = grp->gr_next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
exp = exp->ex_next;
|
||||
}
|
||||
}
|
||||
|
||||
if (rpcs & DOVERIFY)
|
||||
fix_rmtab(client, host, mntdump, 0, force);
|
||||
|
||||
if (rpcs & DOREMOVE)
|
||||
fix_rmtab(client, host, mntdump, 1, force);
|
||||
|
||||
if (rpcs & DOREMALL)
|
||||
remove_all(client, host);
|
||||
|
||||
next:
|
||||
if (mntdump)
|
||||
(void) clnt_freeres(client,
|
||||
(XDRPROC_T_TYPE) xdr_mountlist,
|
||||
(char *) &mntdump);
|
||||
if (mntexports)
|
||||
(void) clnt_freeres(client,
|
||||
(XDRPROC_T_TYPE) xdr_exports,
|
||||
(char *) &mntexports);
|
||||
|
||||
clnt_destroy(client);
|
||||
}
|
||||
exit(0);
|
||||
return 0; /* should never reach here */
|
||||
}
|
||||
|
||||
|
||||
RETSIGTYPE
|
||||
create_timeout(int sig)
|
||||
{
|
||||
signal(SIGALRM, SIG_DFL);
|
||||
longjmp(before_rpc, 1);
|
||||
}
|
||||
|
||||
|
||||
static CLIENT *
|
||||
clnt_create_timeout(char *host, struct timeval *to)
|
||||
{
|
||||
CLIENT *client;
|
||||
|
||||
if (setjmp(before_rpc)) {
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "%s: ", host);
|
||||
clnt_perrno(RPC_TIMEDOUT);
|
||||
fprintf(stderr, "\n");
|
||||
fflush(stderr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
signal(SIGALRM, create_timeout);
|
||||
ualarm(to->tv_sec * 1000000 + to->tv_usec, 0);
|
||||
|
||||
/*
|
||||
* Try TCP first (in case return data is large), then UDP
|
||||
*/
|
||||
if (!(client = clnt_create(host, MOUNTPROG, MOUNTVERS, "tcp")) &&
|
||||
! (client = clnt_create(host, MOUNTPROG, MOUNTVERS, "udp"))) {
|
||||
ualarm(0, 0);
|
||||
if (!quiet) {
|
||||
clnt_pcreateerror(host);
|
||||
fflush(stderr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
ualarm(0, 0);
|
||||
return client;
|
||||
}
|
7
usr.sbin/amd/hlfsd/Makefile
Normal file
7
usr.sbin/amd/hlfsd/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# $NetBSD: Makefile,v 1.1.1.1 1997/07/24 21:22:43 christos Exp $
|
||||
|
||||
PROG= hlfsd
|
||||
SRCS= stubs.c nfs_prot_svc.c homedir.c hlfsd.c
|
||||
MAN+= hlfsd.8
|
||||
|
||||
.include <bsd.prog.mk>
|
287
usr.sbin/amd/hlfsd/hlfsd.8
Normal file
287
usr.sbin/amd/hlfsd/hlfsd.8
Normal file
@ -0,0 +1,287 @@
|
||||
.\"
|
||||
.\" Copyright (c) 1989 Jan-Simon Pendry
|
||||
.\" Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
.\" Copyright (c) 1989 The Regents of the University of California.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to Berkeley by
|
||||
.\" Jan-Simon Pendry at Imperial College, London.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $Id: hlfsd.8,v 1.1.1.1 1997/07/24 21:22:43 christos Exp $
|
||||
.\"
|
||||
.\" HLFSD was written at Columbia University Computer Science Department, by
|
||||
.\" Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@smarts.com>
|
||||
.\" It is distributed under the same terms and conditions as AMD.
|
||||
.\"
|
||||
.TH HLFSD 8 "14 September 1993"
|
||||
.SH NAME
|
||||
hlfsd \- home-link file system daemon
|
||||
.SH SYNOPSIS
|
||||
.B hlfsd
|
||||
[
|
||||
.B \-Cfhnpv
|
||||
] [
|
||||
.BI \-a " alt_dir"
|
||||
] [
|
||||
.BI \-c " cache-interval"
|
||||
] [
|
||||
.BI \-g " group"
|
||||
] [
|
||||
.BI \-i " reload-interval"
|
||||
] [
|
||||
.BI \-l " logfile"
|
||||
] [
|
||||
.BI \-o " mount-options"
|
||||
] [
|
||||
.BI \-x " log-options"
|
||||
] [
|
||||
.BI \-D " debug-options"
|
||||
]
|
||||
[
|
||||
.I linkname
|
||||
.RI [ " subdir " ]
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.B Hlfsd
|
||||
is a daemon which implements a filesystem containing a symbolic link to
|
||||
subdirectory within a user's home directory, depending on the user
|
||||
which accessed that link. It was primarily designed to redirect
|
||||
incoming mail to users' home directories, so that it can read from
|
||||
anywhere.
|
||||
.LP
|
||||
.B Hlfsd
|
||||
operates by mounting itself as an
|
||||
.SM NFS
|
||||
server for the directory containing
|
||||
.IR linkname ,
|
||||
which defaults to
|
||||
.BR /hlfs/home .
|
||||
Lookups within that directory are handled by
|
||||
.BR hlfsd ,
|
||||
which uses the password map to determine how to resolve the lookup.
|
||||
The directory will be created if it doesn't already exist. The symbolic link will be to the accessing user's home directory, with
|
||||
.I subdir
|
||||
appended to it. If not specified,
|
||||
.I subdir
|
||||
defaults to
|
||||
.BR .hlfsdir .
|
||||
This directory will also be created if it does not already exist.
|
||||
.LP
|
||||
A SIGTERM sent to
|
||||
.B hlfsd
|
||||
will cause it to shutdown. A SIGHUP will flush the internal
|
||||
caches, and reload the password map. It will also close and
|
||||
reopen the log file, to enable the original log file to be
|
||||
removed or rotated.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI \-a " alt_dir"
|
||||
Alternate directory. The name of the directory to which
|
||||
the symbolic link returned by
|
||||
.B hlfsd
|
||||
will point, if it cannot access the home directory of the user. This
|
||||
defaults to
|
||||
.BR /var/hlfs .
|
||||
This directory will be created if it doesn't exist. It is expected
|
||||
that either users will read these files, or the system administrators
|
||||
will run a script to resend this "lost mail" to its owner.
|
||||
.TP
|
||||
.BI \-C
|
||||
Force
|
||||
.B hlfsd
|
||||
to run on systems that cannot turn off the NFS attribute-cache. Use of
|
||||
this option on those systems is discouraged, as it may result in loss
|
||||
or misdelivery of mail. The option is ignored on systems that can turn
|
||||
off the attribute-cache.
|
||||
.TP
|
||||
.BI \-c " cache-interval"
|
||||
Caching interval.
|
||||
.B Hlfsd
|
||||
will cache the validity of home directories for this interval, in
|
||||
seconds. Entries which have been verified within the last
|
||||
.I cache-interval
|
||||
seconds will not be verified again, since the operation could
|
||||
be expensive, and the entries are most likely still valid.
|
||||
After the interval has expired,
|
||||
.B hlfsd
|
||||
will re-verify the validity of the user's home directory, and
|
||||
reset the cache time-counter. The default value for
|
||||
.I cache-interval
|
||||
is 300 seconds (5 minutes).
|
||||
.TP
|
||||
.B \-f
|
||||
Force fast startup. This option tells
|
||||
.B hlfsd
|
||||
to skip startup-time consistency checks such as existence of mount
|
||||
directory, alternate spool directory, symlink to be hidden under the
|
||||
mount directory, their permissions and validity.
|
||||
.TP
|
||||
.BI \-g " group"
|
||||
Set the special group HLFS_GID to
|
||||
.IR group .
|
||||
Programs such as
|
||||
.B from
|
||||
or
|
||||
.BR comsat ,
|
||||
which access the mailboxes of other users) must be setgid HLFS_GID to
|
||||
work properly. The default group is "hlfs". If no group is provided,
|
||||
and there is no group "hlfs", this feature is disabled.
|
||||
.TP
|
||||
.B \-h
|
||||
Help. Print a brief help message, and exit.
|
||||
.TP
|
||||
.BI \-i " reload-interval"
|
||||
Map-reloading interval. Each
|
||||
.I reload-interval
|
||||
seconds,
|
||||
.B hlfsd
|
||||
will reload the password map.
|
||||
.B Hlfsd
|
||||
needs the password map for the UIDs and home directory pathnames.
|
||||
.B Hlfsd
|
||||
schedules a SIGALRM to reload the password maps. A SIGHUP sent to
|
||||
.B hlfsd
|
||||
will force it to reload the maps immediately. The default
|
||||
value for
|
||||
.I reload-interval
|
||||
is 900 seconds (15 minutes.)
|
||||
.TP
|
||||
.BI \-l " logfile"
|
||||
Specify a log file to which
|
||||
.B hlfsd
|
||||
will record events. If
|
||||
.I logfile
|
||||
is the string
|
||||
.B syslog
|
||||
then the log messages will be sent to the system log daemon by
|
||||
.IR syslog (3),
|
||||
using the LOG_DAEMON facility.
|
||||
This is also the default.
|
||||
.TP
|
||||
.B \-n
|
||||
No verify.
|
||||
.B Hlfsd
|
||||
will not verify the validity of the symbolic link it will be
|
||||
returning, or that the user's home directory contains
|
||||
sufficient disk-space for spooling. This can speed up
|
||||
.B hlfsd
|
||||
at the cost of possibly returning symbolic links to home
|
||||
directories which are not currently accessible or are full.
|
||||
By default,
|
||||
.B hlfsd
|
||||
validates the symbolic-link in the background.
|
||||
The
|
||||
.B \-n
|
||||
option overrides the meaning of the
|
||||
.B \-c
|
||||
option, since no caching is necessary.
|
||||
.TP
|
||||
.BI \-o " mount-options"
|
||||
Mount options. Mount options which
|
||||
.B hlfsd
|
||||
will use to mount itself on top of
|
||||
.I dirname.
|
||||
By default,
|
||||
.IR mount-options
|
||||
is set to "ro", unless M_CACHE is defined, in which case it is
|
||||
set to "ro,nocache".
|
||||
.TP
|
||||
.B \-p
|
||||
Print PID.
|
||||
Outputs the process-id of
|
||||
.B hlfsd
|
||||
to standard output where it can be saved into a file.
|
||||
.TP
|
||||
.B \-v
|
||||
Version. Displays version information to standard error.
|
||||
.TP
|
||||
.BI \-x " log-options"
|
||||
Specify run-time logging options. The options are a comma separated
|
||||
list chosen from: fatal, error, user, warn, info, map, stats, all.
|
||||
.TP
|
||||
.BI \-D " log-options"
|
||||
Select from a variety of debugging options. Prefixing an
|
||||
option with the string
|
||||
.B no
|
||||
reverses the effect of that option. Options are cumulative.
|
||||
The most useful option is
|
||||
.BR all .
|
||||
Since this option is only used for debugging other options are not
|
||||
documented here. A fuller description is available in the program
|
||||
source. A SIGUSR1 sent to
|
||||
.B hlfsd
|
||||
will cause it to dump its internal password map to the file
|
||||
.BR /tmp/hlfsdump .
|
||||
.SH FILES
|
||||
.PD 0
|
||||
.TP 5
|
||||
.B /hlfs
|
||||
directory under which
|
||||
.B hlfsd
|
||||
mounts itself and manages the symbolic link
|
||||
.BR home .
|
||||
.TP 5
|
||||
.B .hlfsdir
|
||||
default sub-directory in the user's home directory, to which the
|
||||
.B home
|
||||
symbolic link returned by
|
||||
.B hlfsd
|
||||
points.
|
||||
.TP 5
|
||||
.B /var/hlfs
|
||||
directory to which
|
||||
.B home
|
||||
symbolic link returned by
|
||||
.B hlfsd
|
||||
points if it is unable to verify the that
|
||||
user's home directory is accessible.
|
||||
.SH "SEE ALSO"
|
||||
.BR amd (8),
|
||||
.BR automount (8),
|
||||
.BR cron(8),
|
||||
.BR getgrent (3),
|
||||
.BR getpwent (3),
|
||||
.BR mail(1),
|
||||
.BR mount (8),
|
||||
.BR mtab (5),
|
||||
.BR passwd (5),
|
||||
.BR sendmail (8),
|
||||
.BR umount (8).
|
||||
.LP
|
||||
.IR "HLFSD: Delivering Email to Your $HOME" ,
|
||||
in
|
||||
.IR "Proc. LISA-VII, The 7th Usenix System Administration Conference" ,
|
||||
November 1993.
|
||||
.SH AUTHORS
|
||||
Erez Zadok <ezk@cs.columbia.edu>, Computer Science Department,
|
||||
Columbia University, New York City, New York, USA, and
|
||||
Alexander Dupuy <dupuy@smarts.com>, System Management ARTS,
|
||||
White Plains, New York, USA.
|
999
usr.sbin/amd/hlfsd/hlfsd.c
Normal file
999
usr.sbin/amd/hlfsd/hlfsd.c
Normal file
@ -0,0 +1,999 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1989 Jan-Simon Pendry
|
||||
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: hlfsd.c,v 1.1.1.1 1997/07/24 21:22:40 christos Exp $
|
||||
*
|
||||
* HLFSD was written at Columbia University Computer Science Department, by
|
||||
* Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu>
|
||||
* It is being distributed under the same terms and conditions as amd does.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <hlfsd.h>
|
||||
|
||||
/*
|
||||
* STATIC VARIABLES:
|
||||
*/
|
||||
static RETSIGTYPE proceed(int);
|
||||
static RETSIGTYPE reaper(int);
|
||||
static RETSIGTYPE reload(int);
|
||||
static char *hlfs_group = DEFAULT_HLFS_GROUP;
|
||||
static char default_dir_name[] = DEFAULT_DIRNAME;
|
||||
static char *dir_name = default_dir_name;
|
||||
static int printpid = 0;
|
||||
static int stoplight = 0;
|
||||
static void hlfsd_init(P_void);
|
||||
static void usage(P_void);
|
||||
|
||||
static struct itimerval reloadinterval = {
|
||||
{DEFAULT_INTERVAL, 0},
|
||||
{DEFAULT_INTERVAL, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
* default mount options.
|
||||
*/
|
||||
static char default_mntopts[] = "ro,noac";
|
||||
|
||||
/*
|
||||
* GLOBALS:
|
||||
*/
|
||||
SVCXPRT *nfsxprt;
|
||||
char *alt_spooldir = ALT_SPOOLDIR;
|
||||
char *home_subdir = HOME_SUBDIR;
|
||||
char *logfile = DEFAULT_LOGFILE;
|
||||
char *progname;
|
||||
char *slinkname = 0;
|
||||
char hostname[MAXHOSTNAMELEN] = "localhost";
|
||||
int cache_interval = DEFAULT_CACHE_INTERVAL;
|
||||
int foreground = 1; /* This is the top-level server */
|
||||
int hlfs_gid = -3;
|
||||
int masterpid = 0;
|
||||
int noverify = 0;
|
||||
int orig_umask;
|
||||
int serverpid = 0;
|
||||
nfstime startup;
|
||||
pid_t mypid; /* Current process id */
|
||||
serv_state amd_state;
|
||||
u_short nfs_port;
|
||||
|
||||
#ifdef MOUNT_TABLE_ON_FILE
|
||||
char *mtab = MNTTAB_FILE_NAME;
|
||||
#endif /* MOUNT_TABLE_ON_FILE */
|
||||
|
||||
#ifdef DEBUG
|
||||
int debug_flags = 0;
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s [-Cfhnpv] [-a altdir] [-c cache-interval] [-g group]\n",
|
||||
progname);
|
||||
fprintf(stderr, "\t[-i interval] [-l logfile] [-o mntopts]\n");
|
||||
show_opts('x', xlog_opt);
|
||||
#ifdef DEBUG
|
||||
show_opts('D', dbg_opt);
|
||||
#endif /* DEBUG */
|
||||
fprintf(stderr, "\t[dir_name [subdir]]\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *dot;
|
||||
char *mntopts = (char *) NULL;
|
||||
char hostpid_fs[MAXHOSTNAMELEN + 1 + 16]; /* room for ":(pid###)" */
|
||||
char progpid_fs[PROGNAMESZ + 1 + 11]; /* room for ":pid" */
|
||||
char preopts[128];
|
||||
int forcecache = 0;
|
||||
int forcefast = 0;
|
||||
int mntflags = 0;
|
||||
int opt, ret;
|
||||
int opterrs = 0;
|
||||
int retry;
|
||||
int soNFS; /* NFS socket */
|
||||
mntent_t mnt;
|
||||
nfs_args_t mountargs;
|
||||
struct dirent *direntry;
|
||||
struct group *grp;
|
||||
struct stat stmodes;
|
||||
DIR *mountdir;
|
||||
MTYPE_TYPE type = MOUNT_TYPE_NFS;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction sa;
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
#ifndef HAVE_TRANSPORT_TYPE_TLI
|
||||
struct sockaddr_in localsocket;
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
|
||||
/* ensure that only root can run hlfsd */
|
||||
if (geteuid()) {
|
||||
fprintf(stderr, "hlfsd can only be run as root\n");
|
||||
exit(1);
|
||||
}
|
||||
setbuf(stdout, (char *) NULL);
|
||||
umask(0);
|
||||
|
||||
/* get program name and truncate so we don't overflow progpid_fs */
|
||||
|
||||
if ((progname = strrchr(argv[0], '/')) != NULL)
|
||||
progname++;
|
||||
else
|
||||
progname = argv[0];
|
||||
if ((int) strlen(progname) > PROGNAMESZ) /* truncate to reasonable size */
|
||||
progname[PROGNAMESZ] = '\0';
|
||||
|
||||
while ((opt = getopt(argc, argv, "a:c:CD:fg:hi:l:no:px:v")) != EOF)
|
||||
switch (opt) {
|
||||
|
||||
case 'a':
|
||||
if (!optarg || optarg[0] != '/') {
|
||||
printf("%s: invalid directory for -a: %s\n",
|
||||
progname, optarg);
|
||||
exit(3);
|
||||
}
|
||||
alt_spooldir = optarg;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if (!atoi(optarg)) {
|
||||
printf("%s: invalid interval for -c: %s\n",
|
||||
progname, optarg);
|
||||
exit(3);
|
||||
}
|
||||
cache_interval = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
forcecache++;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
forcefast++;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
hlfs_group = optarg;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if (!atoi(optarg)) {
|
||||
printf("%s: invalid interval for -i: %s\n",
|
||||
progname, optarg);
|
||||
exit(3);
|
||||
}
|
||||
reloadinterval.it_interval.tv_sec = atoi(optarg);
|
||||
reloadinterval.it_value.tv_sec = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
logfile = optarg;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
noverify++;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
mntopts = optarg;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
printpid++;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
fprintf(stderr, "%s\n", HLFSD_VERSION);
|
||||
exit(0);
|
||||
|
||||
case 'x':
|
||||
opterrs += switch_option(optarg);
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
#ifdef DEBUG
|
||||
opterrs += debug_option(optarg);
|
||||
#else /* not DEBUG */
|
||||
fprintf(stderr, "%s: not compiled with DEBUG -- sorry.\n", progname);
|
||||
#endif /* not DEBUG */
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
opterrs++;
|
||||
}
|
||||
|
||||
/* set some default debugging options */
|
||||
if (xlog_level_init == ~0)
|
||||
switch_option("");
|
||||
/* need my pid before any dlog/plog */
|
||||
mypid = getpid();
|
||||
#ifdef DEBUG
|
||||
switch_option("debug");
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Terminate if did not ask to forcecache (-C) and hlfsd would not be able
|
||||
* to set the minimum cache intervals.
|
||||
*/
|
||||
#if !defined(MNT2_NFS_OPT_ACREGMIN) || !defined(MNT2_NFS_OPT_ACDIRMIN)
|
||||
if (!forcecache) {
|
||||
fprintf(stderr, "%s: will not be able to turn off attribute caches.\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
#endif /* !defined(MNT2_NFS_OPT_ACREGMIN) || !defined(MNT2_NFS_OPT_ACDIRMIN) */
|
||||
|
||||
switch (argc - optind) {
|
||||
case 2:
|
||||
home_subdir = argv[optind + 1];
|
||||
case 1:
|
||||
dir_name = argv[optind];
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
opterrs++;
|
||||
}
|
||||
|
||||
if (opterrs)
|
||||
usage();
|
||||
|
||||
/* find gid for hlfs_group */
|
||||
if ((grp = getgrnam(hlfs_group)) == (struct group *) NULL) {
|
||||
fprintf(stderr, "%s: cannot get gid for group \"%s\".\n",
|
||||
progname, hlfs_group);
|
||||
} else {
|
||||
hlfs_gid = grp->gr_gid;
|
||||
}
|
||||
|
||||
/* get hostname for logging and open log before we reset umask */
|
||||
gethostname(hostname, MAXHOSTNAMELEN);
|
||||
if ((dot = strchr(hostname, '.')) != NULL)
|
||||
*dot = '\0';
|
||||
if (logfile)
|
||||
switch_to_logfile(logfile);
|
||||
orig_umask = umask(0);
|
||||
|
||||
#if defined(DEBUG) && !defined(MOUNT_TABLE_ON_FILE)
|
||||
if (debug_flags & D_MTAB)
|
||||
dlog("-D mtab option ignored");
|
||||
#endif /* defined(DEBUG) && !defined(MOUNT_TABLE_ON_FILE) */
|
||||
|
||||
/* avoid hanging on other NFS servers if started elsewhere */
|
||||
if (chdir("/") < 0)
|
||||
fatal("cannot chdir to /: %m");
|
||||
|
||||
if (geteuid() != 0)
|
||||
fatal("must be root to mount filesystems");
|
||||
|
||||
/*
|
||||
* dir_name must match "^(/.*)/([^/]+)$", and is split at last '/' with
|
||||
* slinkname = `basename $dir_name` - requires dir_name be writable
|
||||
*/
|
||||
|
||||
if (dir_name[0] != '/'
|
||||
|| ((slinkname = strrchr(dir_name, '/')), *slinkname++ = '\0',
|
||||
(dir_name[0] == '\0' || slinkname[0] == '\0'))) {
|
||||
if (slinkname)
|
||||
*--slinkname = '/';
|
||||
printf("%s: invalid mount directory/link %s\n",
|
||||
progname, dir_name);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
if (!forcefast) {
|
||||
/* make sure mount point exists and is at least mode 555 */
|
||||
if (stat(dir_name, &stmodes) < 0)
|
||||
if (errno != ENOENT || mkdirs(dir_name, 0555) < 0
|
||||
|| stat(dir_name, &stmodes) < 0)
|
||||
fatalerror(dir_name);
|
||||
|
||||
if ((stmodes.st_mode & 0555) != 0555) {
|
||||
fprintf(stderr, "%s: directory %s not read/executable\n",
|
||||
progname, dir_name);
|
||||
plog(XLOG_WARNING, "directory %s not read/executable",
|
||||
dir_name);
|
||||
}
|
||||
|
||||
/* warn if extraneous stuff will be hidden by mount */
|
||||
if ((mountdir = opendir(dir_name)) == NULL)
|
||||
fatalerror(dir_name);
|
||||
|
||||
while ((direntry = readdir(mountdir)) != NULL) {
|
||||
if (strncmp(".", direntry->d_name,
|
||||
NAMLEN(direntry)) &&
|
||||
strncmp("..", direntry->d_name,
|
||||
NAMLEN(direntry)) &&
|
||||
strncmp(slinkname, direntry->d_name,
|
||||
NAMLEN(direntry)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (direntry != NULL) {
|
||||
fprintf(stderr, "%s: %s/%s will be hidden by mount\n",
|
||||
progname, dir_name, direntry->d_name);
|
||||
plog(XLOG_WARNING, "%s/%s will be hidden by mount\n",
|
||||
dir_name, direntry->d_name);
|
||||
}
|
||||
closedir(mountdir);
|
||||
|
||||
/* make sure alternate spool dir exists */
|
||||
if ((errno = mkdirs(alt_spooldir, OPEN_SPOOLMODE))) {
|
||||
fprintf(stderr, "%s: cannot create alternate dir ",
|
||||
progname);
|
||||
perror(alt_spooldir);
|
||||
plog(XLOG_ERROR, "cannot create alternate dir %s: %m",
|
||||
alt_spooldir);
|
||||
}
|
||||
chmod(alt_spooldir, OPEN_SPOOLMODE);
|
||||
|
||||
/* create failsafe link to alternate spool directory */
|
||||
slinkname[-1] = '/'; /* unsplit dir_name to include link */
|
||||
if (lstat(dir_name, &stmodes) == 0 &&
|
||||
(stmodes.st_mode & S_IFMT) != S_IFLNK) {
|
||||
fprintf(stderr, "%s: failsafe %s not a symlink\n",
|
||||
progname, dir_name);
|
||||
plog(XLOG_WARNING, "failsafe %s not a symlink\n",
|
||||
dir_name);
|
||||
} else {
|
||||
unlink(dir_name);
|
||||
|
||||
if (symlink(alt_spooldir, dir_name) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: cannot create failsafe symlink %s -> ",
|
||||
progname, dir_name);
|
||||
perror(alt_spooldir);
|
||||
plog(XLOG_WARNING,
|
||||
"cannot create failsafe symlink %s -> %s: %m",
|
||||
dir_name, alt_spooldir);
|
||||
}
|
||||
}
|
||||
|
||||
slinkname[-1] = '\0'; /* resplit dir_name */
|
||||
} /* end of "if (!forcefast) {" */
|
||||
|
||||
/*
|
||||
* Register hlfsd as an nfs service with the portmapper.
|
||||
*/
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
if (ret != 0)
|
||||
fatal("cannot create NFS service");
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
sa.sa_handler = proceed;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sigaddset(&(sa.sa_mask), SIGUSR2);
|
||||
sigaction(SIGUSR2, &sa, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
signal(SIGUSR2, proceed);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
plog(XLOG_INFO, "Initializing hlfsd...");
|
||||
hlfsd_init(); /* start up child (forking) to run svc_run */
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
sa.sa_handler = reaper;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sigaddset(&(sa.sa_mask), SIGCHLD);
|
||||
sigaction(SIGCHLD, &sa, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
signal(SIGCHLD, reaper);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* In the parent, if -D nodaemon (or -D daemon) , we don't need to
|
||||
* set this signal handler.
|
||||
*/
|
||||
amuDebug(D_DAEMON) {
|
||||
#endif /* DEBUG */
|
||||
/* XXX: port to use pure svr4 signals */
|
||||
while (stoplight != SIGUSR2) {
|
||||
int s = -99;
|
||||
plog(XLOG_INFO, "parent waits for child to setup");
|
||||
s = sigpause(0); /* wait for child to set up */
|
||||
}
|
||||
#ifdef DEBUG
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* setup options to mount table (/etc/{mtab,mnttab}) entry
|
||||
*/
|
||||
sprintf(hostpid_fs, "%s:(pid%d)", hostname, masterpid);
|
||||
memset((char *) &mnt, 0, sizeof(mnt));
|
||||
mnt.mnt_dir = dir_name; /* i.e., "/mail" */
|
||||
mnt.mnt_fsname = hostpid_fs;
|
||||
if (mntopts) {
|
||||
mnt.mnt_opts = mntopts;
|
||||
} else {
|
||||
strcpy(preopts, default_mntopts);
|
||||
/*
|
||||
* Turn off all kinds of attribute and symlink caches as
|
||||
* much as possible. Also make sure that mount does not
|
||||
* show up to df.
|
||||
*/
|
||||
#ifdef MNTTAB_OPT_INTR
|
||||
strcat(preopts, ",");
|
||||
strcat(preopts, MNTTAB_OPT_INTR);
|
||||
#endif /* MNTTAB_OPT_INTR */
|
||||
#ifdef MNTTAB_OPT_IGNORE
|
||||
strcat(preopts, ",");
|
||||
strcat(preopts, MNTTAB_OPT_IGNORE);
|
||||
#endif /* MNTTAB_OPT_IGNORE */
|
||||
#ifdef MNT2_GEN_OPT_CACHE
|
||||
strcat(preopts, ",nocache");
|
||||
#endif /* MNT2_GEN_OPT_CACHE */
|
||||
#ifdef MNT2_NFS_OPT_SYMTTL
|
||||
strcat(preopts, ",symttl=0");
|
||||
#endif /* MNT2_NFS_OPT_SYMTTL */
|
||||
mnt.mnt_opts = preopts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that amd's top-level NFS mounts are hidden by default
|
||||
* from df.
|
||||
* If they don't appear to support the either the "ignore" mnttab
|
||||
* option entry, or the "auto" one, set the mount type to "nfs".
|
||||
*/
|
||||
mnt.mnt_type = HIDE_MOUNT_TYPE;
|
||||
|
||||
/*
|
||||
* Set the address field of the nfs_args structure.
|
||||
*/
|
||||
memset((char *) &mountargs, 0, sizeof(mountargs));
|
||||
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
mountargs.addr = &nfsxprt->xp_ltaddr;
|
||||
|
||||
/*
|
||||
* set up knconf field.
|
||||
* the allocated mountargs.knconf is not freed via free_knetconfig().
|
||||
*/
|
||||
if (get_knetconfig(&mountargs.knconf, nfsncp, NULL) < 0) {
|
||||
plog(XLOG_ERROR, "cannot fill knetconfig structure for mountargs");
|
||||
}
|
||||
|
||||
/*
|
||||
* set up syncaddr field
|
||||
*/
|
||||
mountargs.syncaddr = (struct netbuf *) NULL;
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
amu_get_myaddress(&localsocket.sin_addr);
|
||||
localsocket.sin_family = AF_INET;
|
||||
localsocket.sin_port = nfsxprt->xp_port;
|
||||
|
||||
NFS_SA_DREF(mountargs, &localsocket);
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
/*
|
||||
* Update filehandle field
|
||||
*/
|
||||
NFS_FH_DREF(mountargs.NFS_FH_FIELD, root_fhp);
|
||||
|
||||
#ifdef HAVE_FIELD_NFS_ARGS_T_FHSIZE
|
||||
mountargs.fhsize = FHSIZE;
|
||||
#endif /* HAVE_FIELD_NFS_ARGS_T_FHSIZE */
|
||||
|
||||
/*
|
||||
* Update hostname field.
|
||||
* Make some name prog:pid (i.e., hlfsd:174) for hostname
|
||||
*/
|
||||
sprintf(progpid_fs, "%s:%d", progname, masterpid);
|
||||
|
||||
/* Most kernels have a name length restriction. */
|
||||
if ((int) strlen(progpid_fs) >= (int) MAXHOSTNAMELEN)
|
||||
strcpy(progpid_fs + MAXHOSTNAMELEN - 3, "..");
|
||||
|
||||
NFS_HN_DREF(mountargs.hostname, progpid_fs);
|
||||
|
||||
/*
|
||||
* General mount options
|
||||
*/
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
mountargs.flags |= MNT2_NFS_OPT_KNCONF;
|
||||
#endif /* HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
#ifdef MNT2_NFS_OPT_FSNAME
|
||||
mountargs.fsname = hostpid_fs;
|
||||
mountargs.flags |= MNT2_NFS_OPT_FSNAME;
|
||||
#endif /* MNT2_NFS_OPT_FSNAME */
|
||||
|
||||
#ifdef MNT2_NFS_OPT_HOSTNAME
|
||||
mountargs.flags |= MNT2_NFS_OPT_HOSTNAME;
|
||||
#endif /* MNT2_NFS_OPT_HOSTNAME */
|
||||
|
||||
mountargs.timeo = hasmntval(&mnt, MNTTAB_OPT_TIMEO);
|
||||
#ifdef MNT2_NFS_OPT_TIMEO
|
||||
if (mountargs.timeo)
|
||||
mountargs.flags |= MNT2_NFS_OPT_TIMEO;
|
||||
#endif /* MNT2_NFS_OPT_TIMEO */
|
||||
|
||||
mountargs.retrans = hasmntval(&mnt, MNTTAB_OPT_RETRANS);
|
||||
#ifdef MNT2_NFS_OPT_RETRANS
|
||||
if (mountargs.retrans)
|
||||
mountargs.flags |= MNT2_NFS_OPT_RETRANS;
|
||||
#endif /* MNT2_NFS_OPT_RETRANS */
|
||||
|
||||
if (hasmntopt(&mnt, MNTTAB_OPT_SOFT) != NULL)
|
||||
mountargs.flags |= MNT2_NFS_OPT_SOFT;
|
||||
|
||||
#ifdef MNTTAB_OPT_INT
|
||||
if (hasmntopt(&mnt, MNTTAB_OPT_INTR) != NULL)
|
||||
mountargs.flags |= MNT2_NFS_OPT_INT;
|
||||
#endif /* MNTTAB_OPT_INT */
|
||||
|
||||
#ifdef MNT2_NFS_OPT_BIODS
|
||||
if (mountargs.biods = hasmntval(&mnt, MNTTAB_OPT_BIODS))
|
||||
mountargs.flags |= MNT2_NFS_OPT_BIODS;
|
||||
#endif /* MNT2_NFS_OPT_BIODS */
|
||||
|
||||
#ifdef MNT2_NFS_OPT_DUMBTIMR
|
||||
mountargs.flags |= MNT2_NFS_OPT_DUMBTIMR;
|
||||
#endif /* MNT2_NFS_OPT_DUMBTIMR */
|
||||
|
||||
#ifdef MNT2_NFS_OPT_NOAC
|
||||
mountargs.flags |= MNT2_NFS_OPT_NOAC;
|
||||
#endif /* MNT2_NFS_OPT_NOAC */
|
||||
|
||||
#ifdef MNT2_NFS_OPT_ACREGMIN
|
||||
mountargs.flags |= MNT2_NFS_OPT_ACREGMIN;
|
||||
mountargs.acregmin = SYMTTL_ATTR_CACHE_VALUE;
|
||||
#endif /* MNT2_NFS_OPT_ACREGMIN */
|
||||
#ifdef MNT2_NFS_OPT_ACREGMAX
|
||||
mountargs.flags |= MNT2_NFS_OPT_ACREGMAX;
|
||||
mountargs.acregmax = SYMTTL_ATTR_CACHE_VALUE;
|
||||
#endif /* MNT2_NFS_OPT_ACREGMAX */
|
||||
#ifdef MNT2_NFS_OPT_ACDIRMIN
|
||||
mountargs.flags |= MNT2_NFS_OPT_ACDIRMIN;
|
||||
mountargs.acdirmin = SYMTTL_ATTR_CACHE_VALUE;
|
||||
#endif /* MNT2_NFS_OPT_ACDIRMIN */
|
||||
#ifdef MNT2_NFS_OPT_ACDIRMAX
|
||||
mountargs.flags |= MNT2_NFS_OPT_ACDIRMAX;
|
||||
mountargs.acdirmax = SYMTTL_ATTR_CACHE_VALUE;
|
||||
#endif /* MNT2_NFS_OPT_ACDIRMAX */
|
||||
|
||||
#ifdef MNT2_NFS_OPT_SYMTTL
|
||||
mountargs.flags |= MNT2_NFS_OPT_SYMTTL;
|
||||
mountargs.symttl = 0;
|
||||
#endif /* MNT2_NFS_OPT_SYMTTL */
|
||||
|
||||
#if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX)
|
||||
if (hasmntopt(&mnt, MNTTAB_OPT_POSIX) != NULL) {
|
||||
mountargs.flags |= MNT2_NFS_OPT_POSIX;
|
||||
mountargs.pathconf = NULL;
|
||||
}
|
||||
#endif /* MNT2_NFS_OPT_POSIX && MNTTAB_OPT_POSIX */
|
||||
|
||||
mntflags = compute_mount_flags(&mnt);
|
||||
|
||||
#if defined(MNT2_GEN_OPT_OVERLAY) && defined(MNTTAB_OPT_OVERLAY)
|
||||
/*
|
||||
* Overlay this amd mount (presumably on another amd which died
|
||||
* before and left the machine hung). This will allow a new amd or
|
||||
* hlfsd to be remounted on top of another one.
|
||||
* -Erez Zadok <ezk@cs.columbia.edu>
|
||||
*/
|
||||
if (hasmntopt(&mnt, MNTTAB_OPT_OVERLAY) != NULL) {
|
||||
mntflags |= MNT2_GEN_OPT_OVERLAY;
|
||||
plog(XLOG_INFO, "using and overlay mount");
|
||||
}
|
||||
#endif /* defined(MNT2_GEN_OPT_OVERLAY) && defined(MNTTAB_OPT_OVERLAY) */
|
||||
|
||||
retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
|
||||
|
||||
/*
|
||||
* The following code could be cleverly ifdef-ed, but I duplicated the
|
||||
* mount_fs call three times for simplicity and readability.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* For some reason, this mount may have to be done in the background, if I am
|
||||
* using -D nodebug. I suspect that the actual act of mounting requires
|
||||
* calling to hlfsd itself to invoke one or more of its nfs calls, to stat
|
||||
* /mail. That means that even if you say -D nodaemon, at least the mount
|
||||
* of hlfsd itself on top of /mail will be done in the background.
|
||||
* The other alternative I have is to run svc_run, but set a special
|
||||
* signal handler to perform the mount in N seconds via some alarm.
|
||||
* -Erez Zadok.
|
||||
*/
|
||||
if (debug_flags & D_DAEMON) { /* asked for -D daemon */
|
||||
if (mount_fs(&mnt, mntflags, (caddr_t) & mountargs, retry, type, 0, NULL) < 0)
|
||||
fatal("nfsmount: %m");
|
||||
} else { /* asked for -D nodaemon */
|
||||
if (fork() == 0) { /* child runs mount */
|
||||
if (mount_fs(&mnt, mntflags, (caddr_t) & mountargs, retry, type, 0, NULL) < 0)
|
||||
fatal("nfsmount: %m");
|
||||
exit(0); /* all went well */
|
||||
}
|
||||
}
|
||||
#else /* not DEBUG */
|
||||
if (mount_fs(&mnt, mntflags, (caddr_t) & mountargs, retry, type, 0, NULL) < 0)
|
||||
fatal("nfsmount: %m");
|
||||
#endif /* not DEBUG */
|
||||
|
||||
if (printpid)
|
||||
printf("%d\n", masterpid);
|
||||
|
||||
plog(XLOG_INFO, "hlfsd ready to serve");
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* If asked not to fork a daemon (-D nodaemon), then hlfsd_init()
|
||||
* will not run svc_run. We must start svc_run here.
|
||||
*/
|
||||
dlog("starting no-daemon debugging svc_run");
|
||||
amuDebugNo(D_DAEMON)
|
||||
svc_run();
|
||||
#endif /* DEBUG */
|
||||
|
||||
cleanup(0); /* should never happen here */
|
||||
return (0); /* everything went fine? */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hlfsd_init(void)
|
||||
{
|
||||
int child = 0;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction sa;
|
||||
#endif /* HAVE_SIGACTION */
|
||||
|
||||
#ifndef HAVE_SETPGRP
|
||||
int tty;
|
||||
#endif /* not HAVE_SETPGRP */
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* If -D daemon then we must fork.
|
||||
*/
|
||||
amuDebug(D_DAEMON)
|
||||
#endif /* DEBUG */
|
||||
child = fork();
|
||||
|
||||
if (child < 0)
|
||||
fatal("fork: %m");
|
||||
|
||||
if (child != 0) { /* parent process - save child pid */
|
||||
masterpid = child;
|
||||
mypid = getpid(); /* for AMD routines */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* CHILD CODE:
|
||||
* initialize server
|
||||
*/
|
||||
plog(XLOG_INFO, "initializing home directory database");
|
||||
init_homedir();
|
||||
plog(XLOG_INFO, "home directory database initialized");
|
||||
|
||||
masterpid = serverpid = mypid = getpid();
|
||||
|
||||
/*
|
||||
* SIGALRM/SIGHUP: reload password database if timer expired
|
||||
* or user sent HUP signal.
|
||||
*/
|
||||
#ifdef HAVE_SIGACTION
|
||||
sa.sa_handler = reload;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sigaddset(&(sa.sa_mask), SIGALRM);
|
||||
sigaddset(&(sa.sa_mask), SIGHUP);
|
||||
sigaction(SIGALRM, &sa, NULL);
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
signal(SIGALRM, reload);
|
||||
signal(SIGHUP, reload);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
/*
|
||||
* SIGTERM: cleanup and exit.
|
||||
*/
|
||||
#ifdef HAVE_SIGACTION
|
||||
sa.sa_handler = cleanup;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sigaddset(&(sa.sa_mask), SIGTERM);
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
signal(SIGTERM, cleanup);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
/*
|
||||
* SIGCHLD: interlock sycronization and testing
|
||||
*/
|
||||
#ifdef HAVE_SIGACTION
|
||||
sa.sa_handler = interlock;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sigaddset(&(sa.sa_mask), SIGCHLD);
|
||||
sigaction(SIGCHLD, &sa, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
signal(SIGCHLD, interlock);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
/*
|
||||
* SIGUSR1: dump internal hlfsd maps/cache to file
|
||||
*/
|
||||
#ifdef HAVE_SIGACTION
|
||||
# if defined(DEBUG) || defined(DEBUG_PRINT)
|
||||
sa.sa_handler = plt_print;
|
||||
# else /* not defined(DEBUG) || defined(DEBUG_PRINT) */
|
||||
sa.sa_handler = SIG_IGN;
|
||||
# endif /* not defined(DEBUG) || defined(DEBUG_PRINT) */
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sigaddset(&(sa.sa_mask), SIGUSR1);
|
||||
sigaction(SIGUSR1, &sa, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
# if defined(DEBUG) || defined(DEBUG_PRINT)
|
||||
signal(SIGUSR1, plt_print);
|
||||
# else /* not defined(DEBUG) || defined(DEBUG_PRINT) */
|
||||
signal(SIGUSR1, SIG_IGN);
|
||||
# endif /* not defined(DEBUG) || defined(DEBUG_PRINT) */
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
if (setitimer(ITIMER_REAL, &reloadinterval, (struct itimerval *) 0) < 0)
|
||||
fatal("setitimer: %m");
|
||||
|
||||
gettimeofday((struct timeval *) &startup, (struct timezone *) 0);
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* If -D daemon, then start serving here in the child,
|
||||
* and the parent will exit. But if -D nodaemon, then
|
||||
* skip this code and make sure svc_run is entered elsewhere.
|
||||
*/
|
||||
amuDebug(D_DAEMON) {
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifdef HAVE_SETPGID
|
||||
setpgid(getpid(), getpid());
|
||||
#else /* not HAVE_SETPGID */
|
||||
# ifdef HAVE_SETPGRP
|
||||
setpgrp();
|
||||
# else /* not HAVE_SETPGRP */
|
||||
if ((tty = open("/dev/tty", O_RDWR)) < 0) {
|
||||
/* not an error if already no ctty */
|
||||
if (errno != ENXIO)
|
||||
plog(XLOG_WARNING,
|
||||
"Could not open controlling tty: %m");
|
||||
} else {
|
||||
if (ioctl(tty, TIOCNOTTY, 0) < 0 && errno != ENOTTY)
|
||||
plog(XLOG_WARNING,
|
||||
"Could not disassociate tty (TIOCNOTTY): %m");
|
||||
close(tty);
|
||||
}
|
||||
# endif /* not HAVE_SETPGRP */
|
||||
#endif /* not HAVE_SETPGID */
|
||||
|
||||
/*
|
||||
* signal parent we are ready. parent should
|
||||
* mount(2) and die.
|
||||
*/
|
||||
if (kill(getppid(), SIGUSR2) < 0)
|
||||
fatal("kill: %m");
|
||||
plog(XLOG_INFO, "starting svc_run");
|
||||
svc_run();
|
||||
cleanup(0); /* should never happen, just in case */
|
||||
#ifdef DEBUG
|
||||
} /* end of code that runs iff hlfsd daemonizes */
|
||||
#endif /* DEBUG */
|
||||
|
||||
}
|
||||
|
||||
|
||||
static RETSIGTYPE
|
||||
proceed(int signum)
|
||||
{
|
||||
stoplight = signum;
|
||||
}
|
||||
|
||||
|
||||
static RETSIGTYPE
|
||||
reload(int signum)
|
||||
{
|
||||
int child;
|
||||
int status;
|
||||
|
||||
if (getpid() != masterpid)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If received a SIGHUP, close and reopen the log file (so that it
|
||||
* can be rotated)
|
||||
*/
|
||||
if (signum == SIGHUP && logfile)
|
||||
switch_to_logfile(logfile);
|
||||
|
||||
if ((child = fork()) > 0) {
|
||||
serverpid = child;
|
||||
|
||||
init_homedir();
|
||||
|
||||
if (kill(child, SIGKILL) < 0) {
|
||||
plog(XLOG_ERROR, "kill child: %m");
|
||||
} else { /* wait for child to die before continue */
|
||||
if (wait(&status) != child) {
|
||||
/*
|
||||
* I took out this line because it generates
|
||||
* annoying output. It indicates a very
|
||||
* small bug in hlfsd which is totally
|
||||
* harmless. It causes hlfsd to work a bit
|
||||
* harder than it should. Nevertheless, I
|
||||
* intend on fixing it in a future release.
|
||||
* Erez Zadok <ezk@cs.columbia.edu>
|
||||
*/
|
||||
/* plog(XLOG_ERROR, "unknown child"); */
|
||||
}
|
||||
}
|
||||
|
||||
serverpid = masterpid;
|
||||
} else if (child < 0) {
|
||||
plog(XLOG_ERROR, "unable to fork: %m");
|
||||
} else /* let child handle requests while we reload */
|
||||
serverpid = getpid();
|
||||
}
|
||||
|
||||
|
||||
RETSIGTYPE
|
||||
cleanup(int signum)
|
||||
{
|
||||
struct stat stbuf;
|
||||
int umount_result;
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_DAEMON)
|
||||
#endif /* DEBUG */
|
||||
if (getpid() != masterpid)
|
||||
return;
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_DAEMON)
|
||||
#endif /* DEBUG */
|
||||
if (fork() != 0) {
|
||||
masterpid = 0;
|
||||
return;
|
||||
}
|
||||
mypid = getpid();
|
||||
|
||||
for (;;) {
|
||||
while ((umount_result = UMOUNT_FS(dir_name)) == EBUSY) {
|
||||
#ifdef DEBUG
|
||||
dlog("cleanup(): umount delaying for 10 seconds");
|
||||
#endif /* DEBUG */
|
||||
sleep(10);
|
||||
}
|
||||
if (stat(dir_name, &stbuf) == 0 && stbuf.st_ino == ROOTID) {
|
||||
plog(XLOG_ERROR, "unable to unmount %s", dir_name);
|
||||
plog(XLOG_ERROR, "suspending, unmount before terminating");
|
||||
kill(mypid, SIGSTOP);
|
||||
continue; /* retry unmount */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("cleanup(): killing processes and terminating");
|
||||
amuDebug(D_DAEMON)
|
||||
#endif /* DEBUG */
|
||||
kill(masterpid, SIGKILL);
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_DAEMON)
|
||||
#endif /* DEBUG */
|
||||
kill(serverpid, SIGKILL);
|
||||
|
||||
plog(XLOG_INFO, "hlfsd terminating with status 0\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
static RETSIGTYPE
|
||||
reaper(int signum)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (wait(&result) == masterpid) {
|
||||
exit(4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hlfsd_going_down(int rc)
|
||||
{
|
||||
int mypid = getpid();
|
||||
|
||||
if (mypid == masterpid)
|
||||
cleanup(0);
|
||||
else if (mypid == serverpid)
|
||||
kill(masterpid, SIGTERM);
|
||||
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
fatal(char *mess)
|
||||
{
|
||||
if (logfile && !STREQ(logfile, "stderr")) {
|
||||
char lessmess[128];
|
||||
int messlen;
|
||||
|
||||
messlen = strlen(mess);
|
||||
|
||||
if (!STREQ(&mess[messlen + 1 - sizeof(ERRM)], ERRM))
|
||||
fprintf(stderr, "%s: %s\n", progname, mess);
|
||||
else {
|
||||
strcpy(lessmess, mess);
|
||||
lessmess[messlen - 4] = '\0';
|
||||
|
||||
if (errno < sys_nerr)
|
||||
fprintf(stderr, "%s: %s: %s\n", progname,
|
||||
lessmess, sys_errlist[errno]);
|
||||
else
|
||||
fprintf(stderr, "%s: %s: Error %d\n",
|
||||
progname, lessmess, errno);
|
||||
}
|
||||
}
|
||||
plog(XLOG_FATAL, mess);
|
||||
|
||||
hlfsd_going_down(1);
|
||||
}
|
148
usr.sbin/amd/hlfsd/hlfsd.h
Normal file
148
usr.sbin/amd/hlfsd/hlfsd.h
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1989 Jan-Simon Pendry
|
||||
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: hlfsd.h,v 1.1.1.1 1997/07/24 21:22:42 christos Exp $
|
||||
*
|
||||
* HLFSD was written at Columbia University Computer Science Department, by
|
||||
* Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu>
|
||||
* It is being distributed under the same terms and conditions as amd does.
|
||||
*/
|
||||
|
||||
#ifndef _HLFSD_HLFS_H
|
||||
#define _HLFSD_HLFS_H
|
||||
|
||||
/*
|
||||
* MACROS AND CONSTANTS:
|
||||
*/
|
||||
|
||||
#define HLFSD_VERSION "hlfsd 1.1 (March 4, 1997)"
|
||||
#define PERS_SPOOLMODE 0755
|
||||
#define OPEN_SPOOLMODE 01777
|
||||
#define ROOTID -1 /* don't change this from being -1 */
|
||||
#define SLINKID -2 /* don't change this from being -2 */
|
||||
#define DOTSTRING "."
|
||||
|
||||
#define DOTCOOKIE 1
|
||||
#define DOTDOTCOOKIE 2
|
||||
#define SLINKCOOKIE 3
|
||||
|
||||
#define ALT_SPOOLDIR "/var/hlfs" /* symlink to use if others fail */
|
||||
#define HOME_SUBDIR ".hlfsdir" /* dirname in user's home dir */
|
||||
#define DEFAULT_DIRNAME "/hlfs/home"
|
||||
#define DEFAULT_INTERVAL 900 /* secs b/t re-reads of the password maps */
|
||||
#define DEFAULT_CACHE_INTERVAL 300 /* secs during which assume a link is up */
|
||||
#define DEFAULT_HLFS_GROUP "hlfs" /* Group name for special hlfs_gid */
|
||||
|
||||
#define PROGNAMESZ (MAXHOSTNAMELEN - 5)
|
||||
|
||||
#ifdef MNT2_NFS_OPT_SYMTTL
|
||||
# define SYMTTL_ATTR_CACHE_VALUE 0
|
||||
#else /* MNT2_NFS_OPT_SYMTTL */
|
||||
# define SYMTTL_ATTR_CACHE_VALUE 1
|
||||
#endif /* MNT2_NFS_OPT_SYMTTL */
|
||||
|
||||
#ifdef HAVE_SYSLOG
|
||||
# define DEFAULT_LOGFILE "syslog"
|
||||
#else /* not HAVE)_SYSLOG */
|
||||
# define DEFAULT_LOGFILE 0
|
||||
#endif /* not HAVE)_SYSLOG */
|
||||
|
||||
#define ERRM ": %m"
|
||||
#define fatalerror(str) \
|
||||
(fatal (strcat (strnsave ((str), strlen ((str)) + sizeof (ERRM) - 1), ERRM)))
|
||||
|
||||
/*
|
||||
* TYPDEFS:
|
||||
*/
|
||||
typedef struct uid2home_t uid2home_t;
|
||||
typedef struct username2uid_t username2uid_t;
|
||||
|
||||
|
||||
/*
|
||||
* STRUCTURES:
|
||||
*/
|
||||
struct uid2home_t {
|
||||
uid_t uid;
|
||||
pid_t child;
|
||||
char *home;
|
||||
char *uname;
|
||||
u_long last_access_time;
|
||||
int last_status; /* 0=used $HOME/.hlfsspool; !0=used alt dir */
|
||||
};
|
||||
|
||||
struct username2uid_t {
|
||||
char *username;
|
||||
uid_t uid;
|
||||
char *home;
|
||||
};
|
||||
|
||||
/*
|
||||
* EXTERNALS:
|
||||
*/
|
||||
extern RETSIGTYPE cleanup(int);
|
||||
extern RETSIGTYPE interlock(int);
|
||||
extern SVCXPRT *nfs_program_2_transp; /* For quick_reply() */
|
||||
extern SVCXPRT *nfsxprt;
|
||||
extern char *alt_spooldir;
|
||||
extern char *home_subdir;
|
||||
extern char *homedir(int);
|
||||
extern char *mailbox(int, char *);
|
||||
extern char *slinkname;
|
||||
extern char mboxfile[];
|
||||
extern int cache_interval;
|
||||
extern int hlfs_gid;
|
||||
extern int noverify;
|
||||
extern int serverpid;
|
||||
extern int sys_nerr;
|
||||
extern int untab_index(char *username);
|
||||
extern am_nfs_fh *root_fhp;
|
||||
extern am_nfs_fh root;
|
||||
extern nfstime startup;
|
||||
extern uid2home_t *plt_search(int);
|
||||
extern username2uid_t *untab; /* user name table */
|
||||
extern void fatal(char *);
|
||||
extern void init_homedir(void);
|
||||
|
||||
#if defined(DEBUG) || defined(DEBUG_PRINT)
|
||||
extern void plt_dump(uid2home_t *, pid_t);
|
||||
extern void plt_print(int);
|
||||
#endif /* defined(DEBUG) || defined(DEBUG_PRINT) */
|
||||
|
||||
#endif /* _HLFSD_HLFS_H */
|
655
usr.sbin/amd/hlfsd/homedir.c
Normal file
655
usr.sbin/amd/hlfsd/homedir.c
Normal file
@ -0,0 +1,655 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1989 Jan-Simon Pendry
|
||||
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: homedir.c,v 1.1.1.1 1997/07/24 21:22:41 christos Exp $
|
||||
*
|
||||
* HLFSD was written at Columbia University Computer Science Department, by
|
||||
* Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu>
|
||||
* It is being distributed under the same terms and conditions as amd does.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <hlfsd.h>
|
||||
|
||||
|
||||
/*
|
||||
* STATIC VARIABLES:
|
||||
*/
|
||||
static hlfsd_diskspace(char *);
|
||||
static hlfsd_stat(char *, struct stat *);
|
||||
static int cur_pwtab_num = 0, max_pwtab_num = 0;
|
||||
static int plt_reset(void);
|
||||
static uid2home_t *lastchild;
|
||||
static uid2home_t *pwtab;
|
||||
static void delay(uid2home_t *, int);
|
||||
static void plt_init(void);
|
||||
static void table_add(int, char *, char *);
|
||||
|
||||
/*
|
||||
* GLOBALS:
|
||||
*/
|
||||
username2uid_t *untab; /* user name table */
|
||||
char mboxfile[MAXPATHLEN];
|
||||
|
||||
|
||||
/*
|
||||
* read and hash the passwd file or NIS map
|
||||
*/
|
||||
void
|
||||
init_homedir(void)
|
||||
{
|
||||
plt_init();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the home directory pathname for the user with uid "userid".
|
||||
*/
|
||||
char *
|
||||
homedir(int userid)
|
||||
{
|
||||
static char linkval[MAXPATHLEN + 1];
|
||||
static struct timeval tp;
|
||||
uid2home_t *found;
|
||||
char *homename;
|
||||
struct stat homestat;
|
||||
|
||||
if ((int) userid == 0) { /* force superuser to use "/" as home */
|
||||
sprintf(linkval, "/%s", home_subdir);
|
||||
return linkval;
|
||||
}
|
||||
if ((found = plt_search(userid)) == (uid2home_t *) NULL) {
|
||||
return alt_spooldir; /* use alt spool for unknown uid */
|
||||
}
|
||||
homename = found->home;
|
||||
|
||||
if (homename[0] != '/' || homename[1] == '\0') {
|
||||
found->last_status = 1;
|
||||
return alt_spooldir; /* use alt spool for / or rel. home */
|
||||
}
|
||||
sprintf(linkval, "%s/%s", homename, home_subdir);
|
||||
|
||||
if (noverify) {
|
||||
found->last_status = 0;
|
||||
return linkval;
|
||||
}
|
||||
|
||||
/*
|
||||
* To optimize hlfsd, we don't actually check the validity of the
|
||||
* symlink if it has been in checked in the last N seconds. It is
|
||||
* very likely that the link, machine, and filesystem are still
|
||||
* valid, as long as N is small. But if N ls large, that may not be
|
||||
* true. That's why the default N is 5 minutes, but we allow the
|
||||
* user to override this value via a command line option. Note that
|
||||
* we do not update the last_access_time each time it is accessed,
|
||||
* but only once every N seconds.
|
||||
*/
|
||||
if (gettimeofday(&tp, (struct timezone *) NULL) < 0) {
|
||||
tp.tv_sec = 0;
|
||||
} else {
|
||||
if ((tp.tv_sec - found->last_access_time) < cache_interval) {
|
||||
if (found->last_status == 0) {
|
||||
return linkval;
|
||||
} else {
|
||||
return alt_spooldir;
|
||||
}
|
||||
} else {
|
||||
found->last_access_time = tp.tv_sec;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* only run this forking code if asked for -D fork
|
||||
* or if did not ask for -D nofork
|
||||
*/
|
||||
amuDebug(D_FORK) {
|
||||
#endif /* DEBUG */
|
||||
/* fork child to process request if none in progress */
|
||||
if (found->child && kill(found->child, 0))
|
||||
found->child = 0;
|
||||
|
||||
if (found->child)
|
||||
delay(found, 5); /* wait a bit if in progress */
|
||||
|
||||
if (found->child) { /* better safe than sorry - maybe */
|
||||
found->last_status = 1;
|
||||
return alt_spooldir;
|
||||
}
|
||||
if ((found->child = fork()) < 0) {
|
||||
found->last_status = 1;
|
||||
return alt_spooldir;
|
||||
}
|
||||
|
||||
if (found->child) {
|
||||
/* parent */
|
||||
#ifdef DEBUG
|
||||
if (lastchild)
|
||||
plog(XLOG_INFO, "cache spill uid = %d, pid = %d, home = %s",
|
||||
lastchild->uid, lastchild->child,
|
||||
lastchild->home);
|
||||
#endif /* DEBUG */
|
||||
lastchild = found;
|
||||
return (char *) NULL; /* return NULL to parent, so it can continue */
|
||||
}
|
||||
#ifdef DEBUG
|
||||
} /* end of Debug(D_FORK) */
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* CHILD: (or parent if -D nofork)
|
||||
*
|
||||
* Check and create dir if needed.
|
||||
* Check disk space and/or quotas too.
|
||||
*
|
||||
* We don't need to set the _last_status field of found after the fork
|
||||
* in the child, b/c that information would be later determined in
|
||||
* nfsproc_readlink_2() and the correct exit status would be returned
|
||||
* to the parent upon SIGCHLD in interlock().
|
||||
*
|
||||
*/
|
||||
if (seteuid(userid) < 0) {
|
||||
plog(XLOG_WARNING, "could not seteuid to %d", userid);
|
||||
return linkval;
|
||||
}
|
||||
if (hlfsd_stat(linkval, &homestat) < 0) {
|
||||
if (errno == ENOENT) { /* make the spool dir if possible */
|
||||
/* don't use recursive mkdirs here */
|
||||
if (mkdir(linkval, PERS_SPOOLMODE) < 0) {
|
||||
seteuid(0);
|
||||
plog(XLOG_WARNING, "can't make directory %s: %m", linkval);
|
||||
return alt_spooldir;
|
||||
}
|
||||
/* fall through to testing the disk space / quota */
|
||||
} else { /* the home dir itself must not exist then */
|
||||
seteuid(0);
|
||||
plog(XLOG_WARNING, "bad link to %s: %m", linkval);
|
||||
return alt_spooldir;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If gets here, then either the spool dir in the home dir exists,
|
||||
* or it was just created. In either case, we now need to
|
||||
* test if we can create a small file and write at least one
|
||||
* byte into it. This will test that we have both enough inodes
|
||||
* and disk blocks to spare, or they fall within the user's quotas too.
|
||||
* We are still seteuid to the user at this point.
|
||||
*/
|
||||
if (hlfsd_diskspace(linkval) < 0) {
|
||||
seteuid(0);
|
||||
plog(XLOG_WARNING, "no more space in %s: %m", linkval);
|
||||
return alt_spooldir;
|
||||
} else {
|
||||
seteuid(0);
|
||||
return linkval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
hlfsd_diskspace(char *path)
|
||||
{
|
||||
char buf[MAXPATHLEN];
|
||||
int fd, len;
|
||||
|
||||
sprintf(buf, "%s/._hlfstmp_%lu", path, getpid());
|
||||
if ((fd = open(buf, O_RDWR | O_CREAT, 0600)) < 0) {
|
||||
plog(XLOG_ERROR, "cannot open %s: %m", buf);
|
||||
return -1;
|
||||
}
|
||||
len = strlen(buf);
|
||||
if (write(fd, buf, len) < len) {
|
||||
plog(XLOG_ERROR, "cannot write \"%s\" (%d bytes) to %s : %m", buf, len, buf);
|
||||
close(fd);
|
||||
unlink(buf); /* cleanup just in case */
|
||||
return -1;
|
||||
}
|
||||
if (unlink(buf) < 0) {
|
||||
plog(XLOG_ERROR, "cannot unlink %s : %m", buf);
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
hlfsd_stat(char *path, struct stat *statp)
|
||||
{
|
||||
if (stat(path, statp) < 0)
|
||||
return -1;
|
||||
else if (!S_ISDIR(statp->st_mode)) {
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
delay(uid2home_t *found, int secs)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (found)
|
||||
dlog("delaying on child %d for %d seconds", found->child, secs);
|
||||
#endif /* DEBUG */
|
||||
|
||||
tv.tv_usec = 0;
|
||||
|
||||
do {
|
||||
tv.tv_sec = secs;
|
||||
if (select(0, 0, 0, 0, &tv) == 0)
|
||||
break;
|
||||
} while (--secs && found->child);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function is called when a child has terminated after
|
||||
* servicing an nfs request. We need to check the exit status and
|
||||
* update the last_status field of the requesting user.
|
||||
*/
|
||||
RETSIGTYPE
|
||||
interlock(int signum)
|
||||
{
|
||||
int child;
|
||||
uid2home_t *lostchild;
|
||||
#ifdef HAVE_SIGACTION
|
||||
int status;
|
||||
#else /* not HAVE_SIGACTION */
|
||||
union wait status;
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
#ifdef HAVE_WAITPID
|
||||
while ((child = waitpid((pid_t) -1, &status, WNOHANG)) > 0) {
|
||||
#else /* not HAVE_WAITPID */
|
||||
while ((child = wait3(&status, WNOHANG, (struct rusage *) 0)) > 0) {
|
||||
#endif /* not HAVE_WAITPID */
|
||||
|
||||
/* high chances this was the last child forked */
|
||||
if (lastchild && lastchild->child == child) {
|
||||
lastchild->child = 0;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
if (WIFEXITED(status))
|
||||
lastchild->last_status = WEXITSTATUS(status);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
if (status.w_retcode)
|
||||
lastchild->last_status = status.w_retcode;
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
lastchild = (uid2home_t *) NULL;
|
||||
} else {
|
||||
/* and if not, we have to search for it... */
|
||||
for (lostchild = pwtab; lostchild < &pwtab[cur_pwtab_num]; lostchild++) {
|
||||
if (lostchild->child == child) {
|
||||
#ifdef HAVE_SIGACTION
|
||||
if (WIFEXITED(status))
|
||||
lostchild->last_status = WEXITSTATUS(status);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
if (status.w_retcode)
|
||||
lostchild->last_status = status.w_retcode;
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
lostchild->child = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PASSWORD AND USERNAME LOOKUP TABLES FUNCTIONS
|
||||
*/
|
||||
|
||||
/*
|
||||
* get index of UserName table entry which matches username.
|
||||
* must not return uid_t because we want to return a negative number.
|
||||
*/
|
||||
int
|
||||
untab_index(char *username)
|
||||
{
|
||||
int max, min, mid, cmp;
|
||||
|
||||
max = cur_pwtab_num - 1;
|
||||
min = 0;
|
||||
|
||||
do {
|
||||
mid = (max + min) / 2;
|
||||
cmp = strcmp(untab[mid].username, username);
|
||||
if (cmp == 0) /* record found! */
|
||||
return mid;
|
||||
if (cmp > 0)
|
||||
max = mid;
|
||||
else
|
||||
min = mid;
|
||||
} while (max > min + 1);
|
||||
|
||||
if (STREQ(untab[max].username, username))
|
||||
return max;
|
||||
if (STREQ(untab[min].username, username))
|
||||
return min;
|
||||
|
||||
/* if gets here then record was not found */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Don't make this return a uid_t, because we need to return negative
|
||||
* numbers as well (error codes.)
|
||||
*/
|
||||
int
|
||||
uidof(char *username)
|
||||
{
|
||||
int idx;
|
||||
|
||||
if ((idx = untab_index(username)) < 0) /* not found */
|
||||
return -3; /* an invalid user id */
|
||||
return untab[idx].uid;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Don't make this return a uid_t, because we need to return negative
|
||||
* numbers as well (error codes.)
|
||||
*/
|
||||
char *
|
||||
homeof(char *username)
|
||||
{
|
||||
int idx;
|
||||
|
||||
if ((idx = untab_index(username)) < 0) /* not found */
|
||||
return (char *) NULL; /* an invalid user id */
|
||||
return untab[idx].home;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
mailbox(int uid, char *username)
|
||||
{
|
||||
char *home;
|
||||
|
||||
if (uid < 0)
|
||||
return (char *) NULL; /* not found */
|
||||
|
||||
if ((home = homeof(username)) == (char *) NULL)
|
||||
return (char *) NULL;
|
||||
if (STREQ(home, "/"))
|
||||
sprintf(mboxfile, "/%s/%s", home_subdir, username);
|
||||
else
|
||||
sprintf(mboxfile, "%s/%s/%s", home, home_subdir, username);
|
||||
return mboxfile;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
plt_compare_fxn(const voidp x, const voidp y)
|
||||
|
||||
{
|
||||
uid2home_t *i = (uid2home_t *) x;
|
||||
uid2home_t *j = (uid2home_t *) y;
|
||||
|
||||
return i->uid - j->uid;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
unt_compare_fxn(const voidp x, const voidp y)
|
||||
{
|
||||
username2uid_t *i = (username2uid_t *) x;
|
||||
username2uid_t *j = (username2uid_t *) y;
|
||||
|
||||
return strcmp(i->username, j->username);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
plt_init(void)
|
||||
{
|
||||
struct passwd *pent_p;
|
||||
|
||||
if (plt_reset() < 0) /* could not reset table. skip. */
|
||||
return;
|
||||
|
||||
plog(XLOG_INFO, "reading password map");
|
||||
|
||||
setpwent(); /* prepare to read passwd entries */
|
||||
while ((pent_p = getpwent()) != (struct passwd *) NULL) {
|
||||
table_add(pent_p->pw_uid, pent_p->pw_dir, pent_p->pw_name);
|
||||
}
|
||||
endpwent();
|
||||
|
||||
qsort((char *) pwtab, cur_pwtab_num, sizeof(uid2home_t),
|
||||
plt_compare_fxn);
|
||||
qsort((char *) untab, cur_pwtab_num, sizeof(username2uid_t),
|
||||
unt_compare_fxn);
|
||||
|
||||
plog(XLOG_INFO, "password map read and sorted");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is essentially so that we don't reset known good lookup tables when a
|
||||
* YP server goes down.
|
||||
*/
|
||||
static int
|
||||
plt_reset(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
setpwent();
|
||||
if (getpwent() == (struct passwd *) NULL) {
|
||||
endpwent();
|
||||
return -1; /* did not reset table */
|
||||
}
|
||||
endpwent();
|
||||
|
||||
lastchild = (uid2home_t *) NULL;
|
||||
|
||||
if (max_pwtab_num > 0) /* was used already. cleanup old table */
|
||||
for (i = 0; i < cur_pwtab_num; ++i) {
|
||||
if (pwtab[i].home)
|
||||
free(pwtab[i].home);
|
||||
pwtab[i].home = (char *) NULL;
|
||||
pwtab[i].uid = -3; /* not a valid uid (yet...) */
|
||||
pwtab[i].child = (pid_t) 0;
|
||||
pwtab[i].uname = (char *) NULL; /* only a ptr to untab[i].username */
|
||||
if (untab[i].username)
|
||||
free(untab[i].username);
|
||||
untab[i].username = (char *) NULL;
|
||||
untab[i].uid = -3; /* invalid uid */
|
||||
untab[i].home = (char *) NULL; /* only a ptr to pwtab[i].home */
|
||||
}
|
||||
cur_pwtab_num = 0; /* zero current size */
|
||||
|
||||
return 0; /* resetting ok */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* u: uid number
|
||||
* h: home directory
|
||||
* n: user ID name
|
||||
*/
|
||||
static void
|
||||
table_add(int u, char *h, char *n)
|
||||
{
|
||||
|
||||
if (max_pwtab_num <= 0) { /* was never initialized */
|
||||
max_pwtab_num = 1;
|
||||
pwtab = (uid2home_t *) xmalloc(max_pwtab_num *
|
||||
sizeof(uid2home_t));
|
||||
untab = (username2uid_t *) xmalloc(max_pwtab_num *
|
||||
sizeof(username2uid_t));
|
||||
}
|
||||
|
||||
/* check if need more space. */
|
||||
if (cur_pwtab_num + 1 > max_pwtab_num) {
|
||||
/* need more space in table */
|
||||
max_pwtab_num *= 2;
|
||||
pwtab = (uid2home_t *) xrealloc(pwtab,
|
||||
sizeof(uid2home_t) * max_pwtab_num);
|
||||
untab = (username2uid_t *) xrealloc(untab,
|
||||
sizeof(username2uid_t) *
|
||||
max_pwtab_num);
|
||||
}
|
||||
|
||||
/* add new password entry */
|
||||
pwtab[cur_pwtab_num].home = xmalloc((strlen(h) + 1) * sizeof(char));
|
||||
strcpy(pwtab[cur_pwtab_num].home, h);
|
||||
pwtab[cur_pwtab_num].child = 0;
|
||||
pwtab[cur_pwtab_num].last_access_time = 0;
|
||||
pwtab[cur_pwtab_num].last_status = 0; /* assume best: used homedir */
|
||||
pwtab[cur_pwtab_num].uid = u;
|
||||
|
||||
/* add new userhome entry */
|
||||
untab[cur_pwtab_num].username = xmalloc((strlen(n) + 1) * sizeof(char));
|
||||
strcpy(untab[cur_pwtab_num].username, n);
|
||||
|
||||
/* just a second pointer */
|
||||
pwtab[cur_pwtab_num].uname = untab[cur_pwtab_num].username;
|
||||
untab[cur_pwtab_num].uid = u;
|
||||
untab[cur_pwtab_num].home = pwtab[cur_pwtab_num].home; /* a ptr */
|
||||
++cur_pwtab_num; /* increment counter */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* return entry in lookup table
|
||||
*/
|
||||
uid2home_t *
|
||||
plt_search(int u)
|
||||
{
|
||||
int max, min, mid;
|
||||
|
||||
/*
|
||||
* empty table should not happen,
|
||||
* but I have a bug with signals to trace...
|
||||
*/
|
||||
if (pwtab == (uid2home_t *) NULL)
|
||||
return (uid2home_t *) NULL;
|
||||
|
||||
max = cur_pwtab_num - 1;
|
||||
min = 0;
|
||||
|
||||
do {
|
||||
mid = (max + min) / 2;
|
||||
if (pwtab[mid].uid == u) /* record found! */
|
||||
return &pwtab[mid];
|
||||
if (pwtab[mid].uid > u)
|
||||
max = mid;
|
||||
else
|
||||
min = mid;
|
||||
} while (max > min + 1);
|
||||
|
||||
if (pwtab[max].uid == u)
|
||||
return &pwtab[max];
|
||||
if (pwtab[min].uid == u)
|
||||
return &pwtab[min];
|
||||
|
||||
/* if gets here then record was not found */
|
||||
return (uid2home_t *) NULL;
|
||||
}
|
||||
|
||||
|
||||
#if defined(DEBUG) || defined(DEBUG_PRINT)
|
||||
void
|
||||
plt_print(int signum)
|
||||
{
|
||||
FILE *dumpfile;
|
||||
int i;
|
||||
|
||||
if ((dumpfile = fopen("/tmp/hlfsdump", "a")) != NULL) {
|
||||
fprintf(dumpfile, "\n\nNew plt_dump():\n");
|
||||
for (i = 0; i < cur_pwtab_num; ++i)
|
||||
fprintf(dumpfile,
|
||||
"%4d %5lu %10lu %1d %4lu \"%s\" uname=\"%s\"\n",
|
||||
i,
|
||||
pwtab[i].child,
|
||||
pwtab[i].last_access_time,
|
||||
pwtab[i].last_status,
|
||||
pwtab[i].uid,
|
||||
pwtab[i].home,
|
||||
pwtab[i].uname);
|
||||
fprintf(dumpfile, "\nUserName table by plt_print():\n");
|
||||
for (i = 0; i < cur_pwtab_num; ++i)
|
||||
fprintf(dumpfile, "%4d : \"%s\" %4lu \"%s\"\n", i,
|
||||
untab[i].username, untab[i].uid, untab[i].home);
|
||||
fclose(dumpfile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
plt_dump(uid2home_t *lastc, pid_t this)
|
||||
{
|
||||
FILE *dumpfile;
|
||||
int i;
|
||||
|
||||
if ((dumpfile = fopen("/var/tmp/hlfsdump", "a")) != NULL) {
|
||||
fprintf(dumpfile, "\n\nNEW PLT_DUMP -- ");
|
||||
fprintf(dumpfile, "lastchild->child=%d ",
|
||||
(int) (lastc ? lastc->child : -999));
|
||||
fprintf(dumpfile, ", child from wait3=%lu:\n", this);
|
||||
for (i = 0; i < cur_pwtab_num; ++i)
|
||||
fprintf(dumpfile, "%4d %5lu: %4lu \"%s\" uname=\"%s\"\n", i,
|
||||
pwtab[i].child, pwtab[i].uid, pwtab[i].home, pwtab[i].uname);
|
||||
fprintf(dumpfile, "\nUserName table by plt_dump():\n");
|
||||
for (i = 0; i < cur_pwtab_num; ++i)
|
||||
fprintf(dumpfile, "%4d : \"%s\" %4lu \"%s\"\n", i,
|
||||
untab[i].username, untab[i].uid, untab[i].home);
|
||||
fprintf(dumpfile, "ezk: ent=%d, uid=%lu, home=\"%s\"\n",
|
||||
untab_index("ezk"),
|
||||
untab[untab_index("ezk")].uid,
|
||||
pwtab[untab[untab_index("ezk")].uid].home);
|
||||
fprintf(dumpfile, "rezk: ent=%d, uid=%lu, home=\"%s\"\n",
|
||||
untab_index("rezk"),
|
||||
untab[untab_index("rezk")].uid,
|
||||
pwtab[untab[untab_index("rezk")].uid].home);
|
||||
fclose(dumpfile);
|
||||
}
|
||||
}
|
||||
#endif /* defined(DEBUG) || defined(DEBUG_PRINT) */
|
245
usr.sbin/amd/hlfsd/nfs_prot_svc.c
Normal file
245
usr.sbin/amd/hlfsd/nfs_prot_svc.c
Normal file
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1989 Jan-Simon Pendry
|
||||
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: nfs_prot_svc.c,v 1.1.1.1 1997/07/24 21:22:41 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <hlfsd.h>
|
||||
|
||||
extern void * nfsproc_null_2_svc(void *, struct svc_req *);
|
||||
extern nfsattrstat * nfsproc_getattr_2_svc(am_nfs_fh *, struct svc_req *);
|
||||
extern nfsattrstat * nfsproc_setattr_2_svc(nfssattrargs *, struct svc_req *);
|
||||
extern void * nfsproc_root_2_svc(void *, struct svc_req *);
|
||||
extern nfsdiropres * nfsproc_lookup_2_svc(nfsdiropargs *, struct svc_req *);
|
||||
extern nfsreadlinkres * nfsproc_readlink_2_svc(am_nfs_fh *, struct svc_req *);
|
||||
extern nfsreadres * nfsproc_read_2_svc(nfsreadargs *, struct svc_req *);
|
||||
extern void * nfsproc_writecache_2_svc(void *, struct svc_req *);
|
||||
extern nfsattrstat * nfsproc_write_2_svc(nfswriteargs *, struct svc_req *);
|
||||
extern nfsdiropres * nfsproc_create_2_svc(nfscreateargs *, struct svc_req *);
|
||||
extern nfsstat * nfsproc_remove_2_svc(nfsdiropargs *, struct svc_req *);
|
||||
extern nfsstat * nfsproc_rename_2_svc(nfsrenameargs *, struct svc_req *);
|
||||
extern nfsstat * nfsproc_link_2_svc(nfslinkargs *, struct svc_req *);
|
||||
extern nfsstat * nfsproc_symlink_2_svc(nfssymlinkargs *, struct svc_req *);
|
||||
extern nfsdiropres * nfsproc_mkdir_2_svc(nfscreateargs *, struct svc_req *);
|
||||
extern nfsstat * nfsproc_rmdir_2_svc(nfsdiropargs *, struct svc_req *);
|
||||
extern nfsreaddirres * nfsproc_readdir_2_svc(nfsreaddirargs *, struct svc_req *);
|
||||
extern nfsstatfsres * nfsproc_statfs_2_svc(am_nfs_fh *, struct svc_req *);
|
||||
|
||||
SVCXPRT *nfs_program_2_transp;
|
||||
|
||||
|
||||
void
|
||||
nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
|
||||
{
|
||||
union {
|
||||
am_nfs_fh nfsproc_getattr_2_arg;
|
||||
nfssattrargs nfsproc_setattr_2_arg;
|
||||
nfsdiropargs nfsproc_lookup_2_arg;
|
||||
am_nfs_fh nfsproc_readlink_2_arg;
|
||||
nfsreadargs nfsproc_read_2_arg;
|
||||
nfswriteargs nfsproc_write_2_arg;
|
||||
nfscreateargs nfsproc_create_2_arg;
|
||||
nfsdiropargs nfsproc_remove_2_arg;
|
||||
nfsrenameargs nfsproc_rename_2_arg;
|
||||
nfslinkargs nfsproc_link_2_arg;
|
||||
nfssymlinkargs nfsproc_symlink_2_arg;
|
||||
nfscreateargs nfsproc_mkdir_2_arg;
|
||||
nfsdiropargs nfsproc_rmdir_2_arg;
|
||||
nfsreaddirargs nfsproc_readdir_2_arg;
|
||||
am_nfs_fh nfsproc_statfs_2_arg;
|
||||
} argument;
|
||||
char *result;
|
||||
bool_t(*xdr_argument) (), (*xdr_result) ();
|
||||
char *(*local) ();
|
||||
|
||||
nfs_program_2_transp = NULL;
|
||||
|
||||
switch (rqstp->rq_proc) {
|
||||
|
||||
case NFSPROC_NULL:
|
||||
xdr_argument = xdr_void;
|
||||
xdr_result = xdr_void;
|
||||
local = (char *(*)()) nfsproc_null_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_GETATTR:
|
||||
xdr_argument = xdr_nfs_fh;
|
||||
xdr_result = xdr_attrstat;
|
||||
local = (char *(*)()) nfsproc_getattr_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_SETATTR:
|
||||
xdr_argument = xdr_sattrargs;
|
||||
xdr_result = xdr_attrstat;
|
||||
local = (char *(*)()) nfsproc_setattr_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_ROOT:
|
||||
xdr_argument = xdr_void;
|
||||
xdr_result = xdr_void;
|
||||
local = (char *(*)()) nfsproc_root_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_LOOKUP:
|
||||
xdr_argument = xdr_diropargs;
|
||||
xdr_result = xdr_diropres;
|
||||
local = (char *(*)()) nfsproc_lookup_2_svc;
|
||||
/*
|
||||
* Cheap way to pass transp down to afs_lookuppn so it can
|
||||
* be stored in the am_node structure and later used for
|
||||
* quick_reply().
|
||||
*/
|
||||
nfs_program_2_transp = transp;
|
||||
break;
|
||||
|
||||
case NFSPROC_READLINK:
|
||||
xdr_argument = xdr_nfs_fh;
|
||||
xdr_result = xdr_readlinkres;
|
||||
local = (char *(*)()) nfsproc_readlink_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_READ:
|
||||
xdr_argument = xdr_readargs;
|
||||
xdr_result = xdr_readres;
|
||||
local = (char *(*)()) nfsproc_read_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_WRITECACHE:
|
||||
xdr_argument = xdr_void;
|
||||
xdr_result = xdr_void;
|
||||
local = (char *(*)()) nfsproc_writecache_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_WRITE:
|
||||
xdr_argument = xdr_writeargs;
|
||||
xdr_result = xdr_attrstat;
|
||||
local = (char *(*)()) nfsproc_write_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_CREATE:
|
||||
xdr_argument = xdr_createargs;
|
||||
xdr_result = xdr_diropres;
|
||||
local = (char *(*)()) nfsproc_create_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_REMOVE:
|
||||
xdr_argument = xdr_diropargs;
|
||||
xdr_result = xdr_nfsstat;
|
||||
local = (char *(*)()) nfsproc_remove_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_RENAME:
|
||||
xdr_argument = xdr_renameargs;
|
||||
xdr_result = xdr_nfsstat;
|
||||
local = (char *(*)()) nfsproc_rename_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_LINK:
|
||||
xdr_argument = xdr_linkargs;
|
||||
xdr_result = xdr_nfsstat;
|
||||
local = (char *(*)()) nfsproc_link_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_SYMLINK:
|
||||
xdr_argument = xdr_symlinkargs;
|
||||
xdr_result = xdr_nfsstat;
|
||||
local = (char *(*)()) nfsproc_symlink_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_MKDIR:
|
||||
xdr_argument = xdr_createargs;
|
||||
xdr_result = xdr_diropres;
|
||||
local = (char *(*)()) nfsproc_mkdir_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_RMDIR:
|
||||
xdr_argument = xdr_diropargs;
|
||||
xdr_result = xdr_nfsstat;
|
||||
local = (char *(*)()) nfsproc_rmdir_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_READDIR:
|
||||
xdr_argument = xdr_readdirargs;
|
||||
xdr_result = xdr_readdirres;
|
||||
local = (char *(*)()) nfsproc_readdir_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_STATFS:
|
||||
xdr_argument = xdr_nfs_fh;
|
||||
xdr_result = xdr_statfsres;
|
||||
local = (char *(*)()) nfsproc_statfs_2_svc;
|
||||
break;
|
||||
|
||||
default:
|
||||
svcerr_noproc(transp);
|
||||
return;
|
||||
}
|
||||
|
||||
memset((char *) &argument, 0, sizeof(argument));
|
||||
if (!svc_getargs(transp,
|
||||
(XDRPROC_T_TYPE) xdr_argument,
|
||||
(SVC_IN_ARG_TYPE) & argument)) {
|
||||
plog(XLOG_ERROR,
|
||||
"NFS xdr decode failed for %d %d %d",
|
||||
rqstp->rq_prog, rqstp->rq_vers, rqstp->rq_proc);
|
||||
svcerr_decode(transp);
|
||||
return;
|
||||
}
|
||||
result = (*local) (&argument, rqstp);
|
||||
|
||||
nfs_program_2_transp = NULL;
|
||||
|
||||
if (result != NULL && !svc_sendreply(transp,
|
||||
(XDRPROC_T_TYPE) xdr_result,
|
||||
result)) {
|
||||
svcerr_systemerr(transp);
|
||||
}
|
||||
if (!svc_freeargs(transp,
|
||||
(XDRPROC_T_TYPE) xdr_argument,
|
||||
(SVC_IN_ARG_TYPE) & argument)) {
|
||||
plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_1");
|
||||
going_down(1);
|
||||
}
|
||||
}
|
506
usr.sbin/amd/hlfsd/stubs.c
Normal file
506
usr.sbin/amd/hlfsd/stubs.c
Normal file
@ -0,0 +1,506 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1989 Jan-Simon Pendry
|
||||
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: stubs.c,v 1.1.1.1 1997/07/24 21:22:42 christos Exp $
|
||||
*
|
||||
* HLFSD was written at Columbia University Computer Science Department, by
|
||||
* Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu>
|
||||
* It is being distributed under the same terms and conditions as amd does.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <hlfsd.h>
|
||||
|
||||
/*
|
||||
* STATIC VARIABLES:
|
||||
*/
|
||||
static nfsfattr rootfattr = {NFDIR, 0040555, 2, 0, 0, 512, 512, 0,
|
||||
1, 0, ROOTID};
|
||||
static nfsfattr slinkfattr = {NFLNK, 0120777, 1, 0, 0, NFS_MAXPATHLEN, 512, 0,
|
||||
(NFS_MAXPATHLEN + 1) / 512, 0, SLINKID};
|
||||
/* user name file attributes */
|
||||
static nfsfattr un_fattr = {NFLNK, 0120777, 1, 0, 0, NFS_MAXPATHLEN, 512, 0,
|
||||
(NFS_MAXPATHLEN + 1) / 512, 0, -3};
|
||||
static int getcreds(struct svc_req *, uid_t *, int *);
|
||||
static int started;
|
||||
static am_nfs_fh slink = {{SLINKID}};
|
||||
static am_nfs_fh un_fhandle = {{-3}};
|
||||
|
||||
/*
|
||||
* GLOBALS:
|
||||
*/
|
||||
am_nfs_fh root = {{ROOTID}};
|
||||
am_nfs_fh *root_fhp = &root;
|
||||
|
||||
|
||||
voidp
|
||||
nfsproc_null_2_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
static char res;
|
||||
|
||||
return (voidp) &res;
|
||||
}
|
||||
|
||||
|
||||
/* compare if two filehandles are equal */
|
||||
static int
|
||||
eq_fh(const am_nfs_fh *fh1, const am_nfs_fh *fh2)
|
||||
{
|
||||
return (!memcmp((char *) fh1, (char *) fh2, sizeof(am_nfs_fh)));
|
||||
}
|
||||
|
||||
|
||||
nfsattrstat *
|
||||
nfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsattrstat res;
|
||||
uid_t uid = -3;
|
||||
int gid = -3;
|
||||
|
||||
if (!started) {
|
||||
started++;
|
||||
rootfattr.na_ctime = startup;
|
||||
rootfattr.na_mtime = startup;
|
||||
slinkfattr.na_ctime = startup;
|
||||
slinkfattr.na_mtime = startup;
|
||||
un_fattr.na_ctime = startup;
|
||||
un_fattr.na_mtime = startup;
|
||||
}
|
||||
|
||||
if (eq_fh(argp, &root)) {
|
||||
res.ns_status = NFS_OK;
|
||||
res.ns_u.ns_attr_u = rootfattr;
|
||||
} else if (eq_fh(argp, &slink)) {
|
||||
|
||||
#ifndef MNT2_NFS_OPT_SYMTTL
|
||||
/*
|
||||
* This code is needed to defeat Solaris 2.4's (and newer) symlink
|
||||
* values cache. It forces the last-modifed time of the symlink to be
|
||||
* current. It is not needed if the O/S has an nfs flag to turn off the
|
||||
* symlink-cache at mount time (such as Irix 5.x and 6.x). -Erez.
|
||||
*/
|
||||
if (++slinkfattr.na_mtime.nt_useconds == 0)
|
||||
++slinkfattr.na_mtime.nt_seconds;
|
||||
#endif /* not MNT2_NFS_OPT_SYMTTL */
|
||||
|
||||
res.ns_status = NFS_OK;
|
||||
res.ns_u.ns_attr_u = slinkfattr;
|
||||
} else {
|
||||
|
||||
if (getcreds(rqstp, &uid, &gid) < 0) {
|
||||
res.ns_status = NFSERR_STALE;
|
||||
return &res;
|
||||
}
|
||||
if (gid != hlfs_gid) {
|
||||
res.ns_status = NFSERR_STALE;
|
||||
} else {
|
||||
memset((char *) &uid, 0, sizeof(int));
|
||||
uid = *(u_int *) argp->fh_data;
|
||||
if (plt_search(uid) != (uid2home_t *) NULL) {
|
||||
res.ns_status = NFS_OK;
|
||||
un_fattr.na_fileid = uid;
|
||||
res.ns_u.ns_attr_u = un_fattr;
|
||||
#ifdef DEBUG
|
||||
dlog("nfs_getattr: succesful search for uid=%d, gid=%d", uid, gid);
|
||||
#endif /* DEBUG */
|
||||
} else { /* not found */
|
||||
res.ns_status = NFSERR_STALE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsattrstat *
|
||||
nfsproc_setattr_2_svc(nfssattrargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsattrstat res = {NFSERR_ROFS};
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
voidp
|
||||
nfsproc_root_2_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
static char res;
|
||||
|
||||
return (voidp) &res;
|
||||
}
|
||||
|
||||
|
||||
nfsdiropres *
|
||||
nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsdiropres res;
|
||||
int idx;
|
||||
uid_t uid = -3;
|
||||
int gid = -3;
|
||||
|
||||
if (!started) {
|
||||
started++;
|
||||
rootfattr.na_ctime = startup;
|
||||
rootfattr.na_mtime = startup;
|
||||
slinkfattr.na_ctime = startup;
|
||||
slinkfattr.na_mtime = startup;
|
||||
un_fattr.na_ctime = startup;
|
||||
un_fattr.na_mtime = startup;
|
||||
}
|
||||
|
||||
if (eq_fh(&argp->da_fhandle, &slink)) {
|
||||
res.dr_status = NFSERR_NOTDIR;
|
||||
return &res;
|
||||
}
|
||||
|
||||
if (eq_fh(&argp->da_fhandle, &root)) {
|
||||
if (argp->da_name[0] == '.' &&
|
||||
(argp->da_name[1] == '\0' ||
|
||||
(argp->da_name[1] == '.' &&
|
||||
argp->da_name[2] == '\0'))) {
|
||||
res.dr_u.dr_drok_u.drok_fhandle = root;
|
||||
res.dr_u.dr_drok_u.drok_attributes = rootfattr;
|
||||
res.dr_status = NFS_OK;
|
||||
return &res;
|
||||
}
|
||||
|
||||
if (STREQ(argp->da_name, slinkname)) {
|
||||
res.dr_u.dr_drok_u.drok_fhandle = slink;
|
||||
res.dr_u.dr_drok_u.drok_attributes = slinkfattr;
|
||||
res.dr_status = NFS_OK;
|
||||
return &res;
|
||||
}
|
||||
|
||||
if (getcreds(rqstp, &uid, &gid) < 0 || gid != hlfs_gid) {
|
||||
res.dr_status = NFSERR_NOENT;
|
||||
return &res;
|
||||
}
|
||||
|
||||
/* if get's here, gid == hlfs_gid */
|
||||
if ((idx = untab_index(argp->da_name)) < 0) {
|
||||
res.dr_status = NFSERR_NOENT;
|
||||
return &res;
|
||||
} else { /* entry found and gid is permitted */
|
||||
un_fattr.na_fileid = untab[idx].uid;
|
||||
res.dr_u.dr_drok_u.drok_attributes = un_fattr;
|
||||
memset((char *) &un_fhandle, 0, sizeof(am_nfs_fh));
|
||||
*(u_int *) un_fhandle.fh_data = (u_int) untab[idx].uid;
|
||||
strncpy((char *) &un_fhandle.fh_data[sizeof(int)],
|
||||
untab[idx].username,
|
||||
sizeof(am_nfs_fh) - sizeof(int));
|
||||
res.dr_u.dr_drok_u.drok_fhandle = un_fhandle;
|
||||
res.dr_status = NFS_OK;
|
||||
#ifdef DEBUG
|
||||
dlog("nfs_lookup: succesful lookup for uid=%d, gid=%d: username=%s",
|
||||
uid, gid, untab[idx].username);
|
||||
#endif /* DEBUG */
|
||||
return &res;
|
||||
}
|
||||
} /* end of "if (eq_fh(argp->dir.data, root.data)) {" */
|
||||
|
||||
res.dr_status = NFSERR_STALE;
|
||||
return &res;
|
||||
}
|
||||
|
||||
static int
|
||||
getcreds(struct svc_req *rp, uid_t *u, int *g)
|
||||
{
|
||||
struct authunix_parms *aup = (struct authunix_parms *) NULL;
|
||||
#ifdef HAVE_RPC_AUTH_DES_H
|
||||
struct authdes_cred *adp;
|
||||
#endif /* HAVE_RPC_AUTH_DES_H */
|
||||
|
||||
switch (rp->rq_cred.oa_flavor) {
|
||||
|
||||
case AUTH_UNIX:
|
||||
aup = (struct authunix_parms *) rp->rq_clntcred;
|
||||
*u = aup->aup_uid;
|
||||
*g = aup->aup_gid;
|
||||
break;
|
||||
|
||||
#ifdef HAVE_RPC_AUTH_DES_H
|
||||
case AUTH_DES:
|
||||
adp = (struct authdes_cred *) rp->rq_clntcred;
|
||||
*g = -3; /* some unknown group id */
|
||||
if (sscanf(adp->adc_fullname.name, "unix.%lu@", u) == 1)
|
||||
break;
|
||||
/* fall through */
|
||||
#endif /* HAVE_RPC_AUTH_DES_H */
|
||||
|
||||
default:
|
||||
*u = *g = -3; /* just in case */
|
||||
svcerr_weakauth(nfsxprt);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0; /* everything is ok */
|
||||
}
|
||||
|
||||
|
||||
nfsreadlinkres *
|
||||
nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsreadlinkres res;
|
||||
uid_t userid = -3;
|
||||
int groupid = hlfs_gid + 1; /* anything not hlfs_gid */
|
||||
int retval = 0;
|
||||
char *path_val = (char *) NULL;
|
||||
char *username;
|
||||
|
||||
if (eq_fh(argp, &root)) {
|
||||
res.rlr_status = NFSERR_ISDIR;
|
||||
} else if (eq_fh(argp, &slink)) {
|
||||
if (getcreds(rqstp, &userid, &groupid) < 0)
|
||||
return (nfsreadlinkres *) NULL;
|
||||
|
||||
gettimeofday((struct timeval *) &slinkfattr.na_atime, (struct timezone *) 0);
|
||||
|
||||
res.rlr_status = NFS_OK;
|
||||
if (groupid == hlfs_gid) {
|
||||
res.rlr_u.rlr_data_u = DOTSTRING;
|
||||
} else if (!(res.rlr_u.rlr_data_u = path_val = homedir(userid))) {
|
||||
/*
|
||||
* parent process (fork in homedir()) continues
|
||||
* processing, by getting a NULL returned as a
|
||||
* "special". Child returns result.
|
||||
*/
|
||||
return (nfsreadlinkres *) NULL;
|
||||
}
|
||||
|
||||
} else { /* check if asked for user mailbox */
|
||||
|
||||
if (getcreds(rqstp, &userid, &groupid) < 0) {
|
||||
return (nfsreadlinkres *) NULL;
|
||||
}
|
||||
|
||||
if (groupid == hlfs_gid) {
|
||||
memset((char *) &userid, 0, sizeof(int));
|
||||
userid = *(u_int *) argp->fh_data;
|
||||
username = (char *) &argp->fh_data[sizeof(int)];
|
||||
if (!(res.rlr_u.rlr_data_u = mailbox(userid, username)))
|
||||
return (nfsreadlinkres *) NULL;
|
||||
} else {
|
||||
res.rlr_status = NFSERR_STALE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("nfs_readlink: mailbox for uid=%d, gid=%d is %s",
|
||||
userid, groupid, (char *) res.rlr_u.rlr_data_u);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* I don't think will pass this if -D nofork */
|
||||
if (serverpid == getpid())
|
||||
return &res;
|
||||
|
||||
if (!svc_sendreply(nfsxprt, (XDRPROC_T_TYPE) xdr_readlinkres, (SVC_IN_ARG_TYPE) &res))
|
||||
svcerr_systemerr(nfsxprt);
|
||||
|
||||
/*
|
||||
* Child exists here. We need to determine which
|
||||
* exist status to return. The exit status
|
||||
* is gathered using wait() and determines
|
||||
* if we returned $HOME/.hlfsspool or $ALTDIR. The parent
|
||||
* needs this info so it can update the lookup table.
|
||||
*/
|
||||
if (path_val && alt_spooldir && STREQ(path_val, alt_spooldir))
|
||||
retval = 1; /* could not get real home dir (or uid 0 user) */
|
||||
else
|
||||
retval = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* If asked for -D nofork, then must return the value,
|
||||
* NOT exit, or else the main hlfsd server exits.
|
||||
* Bug where is that status information being collected?
|
||||
*/
|
||||
amuDebugNo(D_FORK)
|
||||
return &res;
|
||||
#endif /* DEBUG */
|
||||
|
||||
exit(retval);
|
||||
}
|
||||
|
||||
|
||||
nfsreadres *
|
||||
nfsproc_read_2_svc(nfsreadargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsreadres res = {NFSERR_ACCES};
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
voidp
|
||||
nfsproc_writecache_2_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
static char res;
|
||||
|
||||
return (voidp) &res;
|
||||
}
|
||||
|
||||
|
||||
nfsattrstat *
|
||||
nfsproc_write_2_svc(nfswriteargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsattrstat res = {NFSERR_ROFS};
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsdiropres *
|
||||
nfsproc_create_2_svc(nfscreateargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsdiropres res = {NFSERR_ROFS};
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsstat *
|
||||
nfsproc_remove_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsstat res = {NFSERR_ROFS};
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsstat *
|
||||
nfsproc_rename_2_svc(nfsrenameargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsstat res = {NFSERR_ROFS};
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsstat *
|
||||
nfsproc_link_2_svc(nfslinkargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsstat res = {NFSERR_ROFS};
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsstat *
|
||||
nfsproc_symlink_2_svc(nfssymlinkargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsstat res = {NFSERR_ROFS};
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsdiropres *
|
||||
nfsproc_mkdir_2_svc(nfscreateargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsdiropres res = {NFSERR_ROFS};
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsstat *
|
||||
nfsproc_rmdir_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsstat res = {NFSERR_ROFS};
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsreaddirres *
|
||||
nfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsreaddirres res;
|
||||
static nfsentry slinkent = {SLINKID, 0, {SLINKCOOKIE}};
|
||||
static nfsentry dotdotent = {ROOTID, "..", {DOTDOTCOOKIE}, &slinkent};
|
||||
static nfsentry dotent = {ROOTID, ".", {DOTCOOKIE}, &dotdotent};
|
||||
|
||||
slinkent.ne_name = slinkname;
|
||||
|
||||
if (eq_fh(&argp->rda_fhandle, &slink)) {
|
||||
res.rdr_status = NFSERR_NOTDIR;
|
||||
} else if (eq_fh(&argp->rda_fhandle, &root)) {
|
||||
gettimeofday((struct timeval *) &rootfattr.na_atime, (struct timezone *) 0);
|
||||
|
||||
res.rdr_status = NFS_OK;
|
||||
switch (argp->rda_cookie[0]) {
|
||||
case 0:
|
||||
res.rdr_u.rdr_reply_u.dl_entries = &dotent;
|
||||
break;
|
||||
case DOTCOOKIE:
|
||||
res.rdr_u.rdr_reply_u.dl_entries = &dotdotent;
|
||||
break;
|
||||
case DOTDOTCOOKIE:
|
||||
res.rdr_u.rdr_reply_u.dl_entries = &slinkent;
|
||||
break;
|
||||
case SLINKCOOKIE:
|
||||
res.rdr_u.rdr_reply_u.dl_entries = (nfsentry *) 0;
|
||||
break;
|
||||
}
|
||||
res.rdr_u.rdr_reply_u.dl_eof = TRUE;
|
||||
} else {
|
||||
res.rdr_status = NFSERR_STALE;
|
||||
}
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsstatfsres *
|
||||
nfsproc_statfs_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsstatfsres res = {NFS_OK};
|
||||
|
||||
res.sfr_u.sfr_reply_u.sfrok_tsize = 1024;
|
||||
res.sfr_u.sfr_reply_u.sfrok_bsize = 1024;
|
||||
/* set to 1 if want non-empty automounts */
|
||||
res.sfr_u.sfr_reply_u.sfrok_blocks = 0;
|
||||
res.sfr_u.sfr_reply_u.sfrok_bfree = 0;
|
||||
res.sfr_u.sfr_reply_u.sfrok_bavail = 0;
|
||||
|
||||
return &res;
|
||||
}
|
194
usr.sbin/amd/include/am_compat.h
Normal file
194
usr.sbin/amd/include/am_compat.h
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* am_compat.h:
|
||||
*
|
||||
* This file contains compatibility functions and macros, all of which
|
||||
* should be auto-discovered, but for one reason or another (mostly
|
||||
* brain-damage on the part of system designers and header files) they cannot.
|
||||
*
|
||||
* Each compatibility macro/function must include instructions on how/when
|
||||
* it can be removed the am-utils code.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AM_COMPAT_H
|
||||
|
||||
/*
|
||||
* incomplete mount options definitions (sunos4, irix6, linux, etc.)
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Complete MNTTAB_OPT_* options based on MNT2_NFS_OPT_* mount options.
|
||||
*/
|
||||
#if defined(MNT2_NFS_OPT_ACDIRMAX) && !defined(MNTTAB_OPT_ACDIRMAX)
|
||||
# define MNTTAB_OPT_ACDIRMAX "acdirmax"
|
||||
#endif /* defined(MNT2_NFS_OPT_ACDIRMAX) && !defined(MNTTAB_OPT_ACDIRMAX) */
|
||||
|
||||
#if defined(MNT2_NFS_OPT_ACDIRMIN) && !defined(MNTTAB_OPT_ACDIRMIN)
|
||||
# define MNTTAB_OPT_ACDIRMIN "acdirmin"
|
||||
#endif /* defined(MNT2_NFS_OPT_ACDIRMIN) && !defined(MNTTAB_OPT_ACDIRMIN) */
|
||||
|
||||
#if defined(MNT2_NFS_OPT_ACREGMAX) && !defined(MNTTAB_OPT_ACREGMAX)
|
||||
# define MNTTAB_OPT_ACREGMAX "acregmax"
|
||||
#endif /* defined(MNT2_NFS_OPT_ACREGMAX) && !defined(MNTTAB_OPT_ACREGMAX) */
|
||||
|
||||
#if defined(MNT2_NFS_OPT_ACREGMIN) && !defined(MNTTAB_OPT_ACREGMIN)
|
||||
# define MNTTAB_OPT_ACREGMIN "acregmin"
|
||||
#endif /* defined(MNT2_NFS_OPT_ACREGMIN) && !defined(MNTTAB_OPT_ACREGMIN) */
|
||||
|
||||
#if !defined(MNTTAB_OPT_IGNORE)
|
||||
/* SunOS 4.1.x and others define "noauto" option, but not "auto" */
|
||||
# if defined(MNTTAB_OPT_NOAUTO) && !defined(MNTTAB_OPT_AUTO)
|
||||
# define MNTTAB_OPT_AUTO "auto"
|
||||
# endif /* defined(MNTTAB_OPT_NOAUTO) && !defined(MNTTAB_OPT_AUTO) */
|
||||
#endif /* !defined(MNTTAB_OPT_IGNORE) */
|
||||
|
||||
#if defined(MNT2_NFS_OPT_NOAC) && !defined(MNTTAB_OPT_NOAC)
|
||||
# define MNTTAB_OPT_NOAC "noac"
|
||||
#endif /* defined(MNT2_NFS_OPT_NOAC) && !defined(MNTTAB_OPT_NOAC) */
|
||||
|
||||
#if defined(MNT2_NFS_OPT_OVERLAY) && !defined(MNTTAB_OPT_OVERLAY)
|
||||
# define MNTTAB_OPT_OVERLAY "overlay"
|
||||
#endif /* defined(MNT2_NFS_OPT_OVERLAY) && !defined(MNTTAB_OPT_OVERLAY) */
|
||||
|
||||
#if defined(MNT2_NFS_OPT_RETRANS) && !defined(MNTTAB_OPT_RETRANS)
|
||||
# define MNTTAB_OPT_RETRANS "retrans"
|
||||
#endif /* defined(MNT2_NFS_OPT_RETRANS) && !defined(MNTTAB_OPT_RETRANS) */
|
||||
|
||||
#if defined(MNT2_NFS_OPT_RSIZE) && !defined(MNTTAB_OPT_RSIZE)
|
||||
# define MNTTAB_OPT_RSIZE "rsize"
|
||||
#endif /* defined(MNT2_NFS_OPT_RSIZE) && !defined(MNTTAB_OPT_RSIZE) */
|
||||
|
||||
#if defined(MNT2_NFS_OPT_SOFT) && !defined(MNTTAB_OPT_SOFT)
|
||||
# define MNTTAB_OPT_SOFT "soft"
|
||||
#endif /* defined(MNT2_NFS_OPT_SOFT) && !defined(MNTTAB_OPT_SOFT) */
|
||||
|
||||
#if defined(MNT2_NFS_OPT_TIMEO) && !defined(MNTTAB_OPT_TIMEO)
|
||||
# define MNTTAB_OPT_TIMEO "timeo"
|
||||
#endif /* defined(MNT2_NFS_OPT_TIMEO) && !defined(MNTTAB_OPT_TIMEO) */
|
||||
|
||||
#if defined(MNT2_NFS_OPT_WSIZE) && !defined(MNTTAB_OPT_WSIZE)
|
||||
# define MNTTAB_OPT_WSIZE "wsize"
|
||||
#endif /* defined(MNT2_NFS_OPT_WSIZE) && !defined(MNTTAB_OPT_WSIZE) */
|
||||
|
||||
|
||||
/*
|
||||
* Complete MNTTAB_OPT_* options based on MNT2_GEN_OPT_* mount options.
|
||||
*/
|
||||
#if defined(MNT2_GEN_OPT_GRPID) && !defined(MNTTAB_OPT_GRPID)
|
||||
# define MNTTAB_OPT_GRPID "grpid"
|
||||
#endif /* defined(MNT2_GEN_OPT_GRPID) && !defined(MNTTAB_OPT_GRPID) */
|
||||
|
||||
#if defined(MNT2_GEN_OPT_NOSUID) && !defined(MNTTAB_OPT_NOSUID)
|
||||
# define MNTTAB_OPT_NOSUID "nosuid"
|
||||
#endif /* defined(MNT2_GEN_OPT_NOSUID) && !defined(MNTTAB_OPT_NOSUID) */
|
||||
|
||||
|
||||
/*
|
||||
* Complete MNTTAB_OPT_* options and their inverse based on MNT2_GEN_OPT_*
|
||||
* options.
|
||||
*/
|
||||
#if defined(MNT2_GEN_OPT_NODEV) && !defined(MNTTAB_OPT_NODEV)
|
||||
# define MNTTAB_OPT_NODEV "nodev"
|
||||
/* this is missing under some versions of Linux */
|
||||
# ifndef MNTTAB_OPT_DEV
|
||||
# define MNTTAB_OPT_DEV "dev"
|
||||
# endif /* not MNTTAB_OPT_DEV */
|
||||
#endif /* defined(MNT2_GEN_OPT_NODEV) && !defined(MNTTAB_OPT_NODEV) */
|
||||
|
||||
#if defined(MNT2_GEN_OPT_NOEXEC) && !defined(MNTTAB_OPT_NOEXEC)
|
||||
# define MNTTAB_OPT_NOEXEC "noexec"
|
||||
/* this is missing under some versions of Linux */
|
||||
# ifndef MNTTAB_OPT_EXEC
|
||||
# define MNTTAB_OPT_EXEC "exec"
|
||||
# endif /* not MNTTAB_OPT_EXEC */
|
||||
#endif /* defined(MNT2_GEN_OPT_NOEXEC) && !defined(MNTTAB_OPT_NOEXEC) */
|
||||
|
||||
|
||||
/*
|
||||
* Add missing MNTTAB_OPT_* options.
|
||||
*/
|
||||
#ifndef MNTTAB_OPT_ACTIMEO
|
||||
# define MNTTAB_OPT_ACTIMEO "actimeo"
|
||||
#endif /* not MNTTAB_OPT_ACTIMEO */
|
||||
|
||||
#ifndef MNTTAB_OPT_INTR
|
||||
# define MNTTAB_OPT_INTR "intr"
|
||||
#endif /* not MNTTAB_OPT_INTR */
|
||||
|
||||
#ifndef MNTTAB_OPT_PORT
|
||||
# define MNTTAB_OPT_PORT "port"
|
||||
#endif /* not MNTTAB_OPT_PORT */
|
||||
|
||||
#ifndef MNTTAB_OPT_RETRANS
|
||||
# define MNTTAB_OPT_RETRANS "retrans"
|
||||
#endif /* not MNTTAB_OPT_RETRANS */
|
||||
|
||||
#ifndef MNTTAB_OPT_RETRY
|
||||
# define MNTTAB_OPT_RETRY "retry"
|
||||
#endif /* not MNTTAB_OPT_RETRY */
|
||||
|
||||
#ifndef MNTTAB_OPT_RO
|
||||
# define MNTTAB_OPT_RO "ro"
|
||||
#endif /* not MNTTAB_OPT_RO */
|
||||
|
||||
#ifndef MNTTAB_OPT_RSIZE
|
||||
# define MNTTAB_OPT_RSIZE "rsize"
|
||||
#endif /* not MNTTAB_OPT_RSIZE */
|
||||
|
||||
#ifndef MNTTAB_OPT_RW
|
||||
# define MNTTAB_OPT_RW "rw"
|
||||
#endif /* not MNTTAB_OPT_RW */
|
||||
|
||||
#ifndef MNTTAB_OPT_RO
|
||||
# define MNTTAB_OPT_RO "ro"
|
||||
#endif /* not MNTTAB_OPT_RO */
|
||||
|
||||
#ifndef MNTTAB_OPT_TIMEO
|
||||
# define MNTTAB_OPT_TIMEO "timeo"
|
||||
#endif /* not MNTTAB_OPT_TIMEO */
|
||||
|
||||
#ifndef MNTTAB_OPT_WSIZE
|
||||
# define MNTTAB_OPT_WSIZE "wsize"
|
||||
#endif /* not MNTTAB_OPT_WSIZE */
|
||||
|
||||
|
||||
/*
|
||||
* Incomplete filesystem definitions (sunos4, irix6)
|
||||
*/
|
||||
#if defined(HAVE_FS_CDFS) && defined(MOUNT_TYPE_CDFS) && !defined(MNTTYPE_CDFS)
|
||||
# define MNTTYPE_CDFS "hsfs"
|
||||
#endif /* defined(HAVE_FS_CDFS) && defined(MOUNT_TYPE_CDFS) && !defined(MNTTYPE_CDFS) */
|
||||
#ifndef cdfs_args_t
|
||||
|
||||
/*
|
||||
* Solaris has an HSFS filesystem, but does not define hsfs_args.
|
||||
* XXX: the definition here for solaris is wrong, since under solaris,
|
||||
* hsfs_args should be a single integer used as a bit-field for options.
|
||||
* so this code has to be fixed later. -Erez.
|
||||
*/
|
||||
struct hsfs_args {
|
||||
char *fspec; /* name of filesystem to mount */
|
||||
int norrip;
|
||||
};
|
||||
# define cdfs_args_t struct hsfs_args
|
||||
# define HAVE_FIELD_CDFS_ARGS_T_NORRIP
|
||||
#endif /* not cdfs_args_t */
|
||||
|
||||
/*
|
||||
* if does not define struct pc_args, assume integer bit-field (irix6)
|
||||
*/
|
||||
#if defined(HAVE_FS_PCFS) && !defined(pcfs_args_t)
|
||||
# define pcfs_args_t u_int
|
||||
#endif /* defined(HAVE_FS_PCFS) && !defined(pcfs_args_t) */
|
||||
|
||||
/*
|
||||
* if does not define struct ufs_args, assume integer bit-field (linux)
|
||||
*/
|
||||
#if defined(HAVE_FS_UFS) && !defined(ufs_args_t)
|
||||
# define ufs_args_t u_int
|
||||
#endif /* defined(HAVE_FS_UFS) && !defined(ufs_args_t) */
|
||||
|
||||
|
||||
#define _AM_COMPAT_H
|
||||
#endif /* not _AM_COMPAT_H */
|
1161
usr.sbin/amd/include/am_defs.h
Normal file
1161
usr.sbin/amd/include/am_defs.h
Normal file
File diff suppressed because it is too large
Load Diff
877
usr.sbin/amd/include/am_utils.h
Normal file
877
usr.sbin/amd/include/am_utils.h
Normal file
@ -0,0 +1,877 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: am_utils.h,v 1.1.1.1 1997/07/24 21:20:14 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Definitions that are specific to the am-utils package.
|
||||
*/
|
||||
|
||||
#ifndef _AM_UTILS_H
|
||||
#define _AM_UTILS_H
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*** MACROS ***/
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* General macros.
|
||||
*/
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif /* not FALSE */
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
#endif /* not TRUE */
|
||||
#ifndef MAX
|
||||
# define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif /* not MAX */
|
||||
#ifndef MIN
|
||||
# define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif /* not MIN */
|
||||
|
||||
#define ONE_HOUR (60 * 60) /* One hour in seconds */
|
||||
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
# ifdef HOSTNAMESZ
|
||||
# define MAXHOSTNAMELEN HOSTNAMESZ
|
||||
# else /* not HOSTNAMESZ */
|
||||
# define MAXHOSTNAMELEN 64
|
||||
# endif /* not HOSTNAMESZ */
|
||||
#endif /* not MAXHOSTNAMELEN */
|
||||
|
||||
/*
|
||||
* String comparison macros
|
||||
*/
|
||||
#define STREQ(s1, s2) (strcmp((s1), (s2)) == 0)
|
||||
#define STREQ(s1, s2) (strcmp((s1), (s2)) == 0)
|
||||
#define FSTREQ(s1, s2) ((*(s1) == *(s2)) && STREQ((s1),(s2)))
|
||||
|
||||
/*
|
||||
* Logging options/flags
|
||||
*/
|
||||
#define XLOG_FATAL 0x0001
|
||||
#define XLOG_ERROR 0x0002
|
||||
#define XLOG_USER 0x0004
|
||||
#define XLOG_WARNING 0x0008
|
||||
#define XLOG_INFO 0x0010
|
||||
#define XLOG_DEBUG 0x0020
|
||||
#define XLOG_MAP 0x0040
|
||||
#define XLOG_STATS 0x0080
|
||||
#define XLOG_DEFSTR "all,nomap,nostats" /* Default log options */
|
||||
#define XLOG_ALL (XLOG_FATAL|XLOG_ERROR|XLOG_USER|XLOG_WARNING|XLOG_INFO|XLOG_MAP|XLOG_STATS)
|
||||
|
||||
#define clocktime() (clock_valid ? clock_valid : time(&clock_valid))
|
||||
|
||||
#ifndef ROOT_MAP
|
||||
# define ROOT_MAP "\"root\""
|
||||
#endif /* not ROOT_MAP */
|
||||
|
||||
#define NO_SUBNET "notknown" /* default subnet name for no subnet */
|
||||
#define NEXP_AP (1022) /* gdmr: was 254 */
|
||||
#define NEXP_AP_MARGIN (128)
|
||||
#define MAX_READDIR_ENTRIES 16
|
||||
|
||||
/*
|
||||
* Linked list macros
|
||||
*/
|
||||
#define AM_FIRST(ty, q) ((ty *) ((q)->q_forw))
|
||||
#define AM_LAST(ty, q) ((ty *) ((q)->q_back))
|
||||
#define NEXT(ty, q) ((ty *) (((qelem *) q)->q_forw))
|
||||
#define PREV(ty, q) ((ty *) (((qelem *) q)->q_back))
|
||||
#define HEAD(ty, q) ((ty *) q)
|
||||
#define ITER(v, ty, q) \
|
||||
for ((v) = AM_FIRST(ty,(q)); (v) != HEAD(ty,(q)); (v) = NEXT(ty,(v)))
|
||||
|
||||
/* allocate anything of type ty */
|
||||
#define ALLOC(ty) ((ty *) xmalloc(sizeof(ty)))
|
||||
#define CALLOC(ty) ((ty *) xcalloc(1, sizeof(ty)))
|
||||
|
||||
/* converting am-filehandles to mount-points */
|
||||
#define fh_to_mp2(fhp, rp) fh_to_mp3(fhp, rp, VLOOK_CREATE)
|
||||
|
||||
/*
|
||||
* Systems which have the mount table in a file need to read it before
|
||||
* they can perform an unmount() system call.
|
||||
*/
|
||||
#define UMOUNT_FS(dir) umount_fs(dir)
|
||||
extern int umount_fs(char *fs_name); /* imported via $srcdir/conf/umount */
|
||||
|
||||
/*
|
||||
* macros for automounter vfs/vnode operations.
|
||||
*/
|
||||
#define VLOOK_CREATE 0x1
|
||||
#define VLOOK_DELETE 0x2
|
||||
#define FS_DIRECTORY 0x0001 /* This looks like a dir, not a link */
|
||||
#define FS_MBACKGROUND 0x0002 /* Should background this mount */
|
||||
#define FS_NOTIMEOUT 0x0004 /* Don't bother with timeouts */
|
||||
#define FS_MKMNT 0x0008 /* Need to make the mount point */
|
||||
#define FS_UBACKGROUND 0x0010 /* Unmount in background */
|
||||
#define FS_BACKGROUND (FS_MBACKGROUND|FS_UBACKGROUND)
|
||||
#define FS_DISCARD 0x0020 /* Discard immediately on last reference */
|
||||
#define FS_AMQINFO 0x0040 /* Amq is interested in this fs type */
|
||||
|
||||
/*
|
||||
* macros for struct fserver.
|
||||
*/
|
||||
#define FSF_VALID 0x0001 /* Valid information available */
|
||||
#define FSF_DOWN 0x0002 /* This fileserver is thought to be down */
|
||||
#define FSF_ERROR 0x0004 /* Permanent error has occured */
|
||||
#define FSF_WANT 0x0008 /* Want a wakeup call */
|
||||
#define FSF_PINGING 0x0010 /* Already doing pings */
|
||||
#define FSRV_ISDOWN(fs) (((fs)->fs_flags & (FSF_DOWN|FSF_VALID)) == (FSF_DOWN|FSF_VALID))
|
||||
#define FSRV_ISUP(fs) (((fs)->fs_flags & (FSF_DOWN|FSF_VALID)) == (FSF_VALID))
|
||||
|
||||
/*
|
||||
* macros for struct mntfs (list of mounted filesystems)
|
||||
*/
|
||||
#define MFF_MOUNTED 0x0001 /* Node is mounted */
|
||||
#define MFF_MOUNTING 0x0002 /* Mount is in progress */
|
||||
#define MFF_UNMOUNTING 0x0004 /* Unmount is in progress */
|
||||
#define MFF_RESTART 0x0008 /* Restarted node */
|
||||
#define MFF_MKMNT 0x0010 /* Delete this node's am_mount */
|
||||
#define MFF_ERROR 0x0020 /* This node failed to mount */
|
||||
#define MFF_LOGDOWN 0x0040 /* Logged that this mount is down */
|
||||
#define MFF_RSTKEEP 0x0080 /* Don't timeout this filesystem - restarted */
|
||||
#define MFF_WANTTIMO 0x0100 /* Need a timeout call when not busy */
|
||||
|
||||
/*
|
||||
* macros for struct am_node (map of auto-mount points).
|
||||
*/
|
||||
#define AMF_NOTIMEOUT 0x0001 /* This node never times out */
|
||||
#define AMF_ROOT 0x0002 /* This is a root node */
|
||||
|
||||
/*
|
||||
* The following values can be tuned...
|
||||
*/
|
||||
#define ALLOWED_MOUNT_TIME 40 /* 40s for a mount */
|
||||
#define AM_TTL (5 * 60) /* Default cache period */
|
||||
#define AM_TTL_W (2 * 60) /* Default unmount interval */
|
||||
#define AM_PINGER 30 /* NFS ping interval for live systems */
|
||||
#define AFS_TIMEO 8 /* Default afs timeout - .8s */
|
||||
|
||||
/*
|
||||
* default afs retrans - 1/10th seconds
|
||||
*/
|
||||
#define AFS_RETRANS ((ALLOWED_MOUNT_TIME*10+5*gopt.afs_timeo)/gopt.afs_timeo * 2)
|
||||
|
||||
/*
|
||||
* RPC-related macros.
|
||||
*/
|
||||
#define RPC_XID_PORTMAP 0
|
||||
#define RPC_XID_MOUNTD 1
|
||||
#define RPC_XID_NFSPING 2
|
||||
#define RPC_XID_MASK (0x0f) /* 16 id's for now */
|
||||
#define MK_RPC_XID(type_id, uniq) ((type_id) | ((uniq) << 4))
|
||||
|
||||
/*
|
||||
* What level of AMD are we backward compatible with?
|
||||
* This only applies to externally visible characteristics.
|
||||
* Rev.Minor.Branch.Patch (2 digits each)
|
||||
*/
|
||||
#define AMD_COMPAT 5000000 /* 5.0 */
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*** STRUCTURES AND TYPEDEFS ***/
|
||||
/**************************************************************************/
|
||||
|
||||
/* some typedefs must come first */
|
||||
typedef char *amq_string;
|
||||
typedef struct mntfs mntfs;
|
||||
typedef struct am_opts am_opts;
|
||||
typedef struct am_ops am_ops;
|
||||
typedef struct am_node am_node;
|
||||
typedef struct _qelem qelem;
|
||||
typedef struct mntlist mntlist;
|
||||
typedef struct fserver fserver;
|
||||
|
||||
/*
|
||||
* Linked list
|
||||
* (the name 'struct qelem' conflicts with linux's unistd.h)
|
||||
*/
|
||||
struct _qelem {
|
||||
qelem *q_forw;
|
||||
qelem *q_back;
|
||||
};
|
||||
|
||||
/*
|
||||
* Option tables
|
||||
*/
|
||||
struct opt_tab {
|
||||
char *opt;
|
||||
int flag;
|
||||
};
|
||||
|
||||
/*
|
||||
* Server states
|
||||
*/
|
||||
typedef enum {
|
||||
Start,
|
||||
Run,
|
||||
Finishing,
|
||||
Quit,
|
||||
Done
|
||||
} serv_state;
|
||||
|
||||
/*
|
||||
* Options
|
||||
*/
|
||||
struct am_opts {
|
||||
char *fs_glob; /* Smashed copy of global options */
|
||||
char *fs_local; /* Expanded copy of local options */
|
||||
char *fs_mtab; /* Mount table entry */
|
||||
/* Other options ... */
|
||||
char *opt_dev;
|
||||
char *opt_delay;
|
||||
char *opt_dir;
|
||||
char *opt_fs;
|
||||
char *opt_group;
|
||||
char *opt_mount;
|
||||
char *opt_opts;
|
||||
char *opt_remopts;
|
||||
char *opt_pref;
|
||||
char *opt_autopref;
|
||||
char *opt_cache;
|
||||
char *opt_rfs;
|
||||
char *opt_rhost;
|
||||
char *opt_sublink;
|
||||
char *opt_type;
|
||||
char *opt_unmount;
|
||||
char *opt_user;
|
||||
char *opt_maptype; /* map type: file, nis, hesiod, etc. */
|
||||
};
|
||||
|
||||
/*
|
||||
* List of mounted filesystems
|
||||
*/
|
||||
struct mntfs {
|
||||
qelem mf_q; /* List of mounted filesystems */
|
||||
am_ops *mf_ops; /* Operations on this mountpoint */
|
||||
am_opts *mf_fo; /* File opts */
|
||||
char *mf_mount; /* "/a/kiska/home/kiska" */
|
||||
char *mf_info; /* Mount info */
|
||||
char *mf_auto; /* Automount opts */
|
||||
char *mf_mopts; /* FS mount opts */
|
||||
char *mf_remopts; /* Remote FS mount opts */
|
||||
fserver *mf_server; /* File server */
|
||||
int mf_flags; /* Flags */
|
||||
int mf_error; /* Error code from background mount */
|
||||
int mf_refc; /* Number of references to this node */
|
||||
int mf_cid; /* Callout id */
|
||||
void (*mf_prfree) (); /* Free private space */
|
||||
voidp mf_private; /* Private - per-fs data */
|
||||
};
|
||||
|
||||
/*
|
||||
* File Handle
|
||||
*
|
||||
* This is interpreted by indexing the exported array
|
||||
* by fhh_id.
|
||||
*
|
||||
* The whole structure is mapped onto a standard fhandle_t
|
||||
* when transmitted.
|
||||
*/
|
||||
struct am_fh {
|
||||
int fhh_pid; /* process id */
|
||||
int fhh_id; /* map id */
|
||||
int fhh_gen; /* generation number */
|
||||
};
|
||||
|
||||
/*
|
||||
* Multi-protocol NFS file handle
|
||||
*/
|
||||
union am_nfs_handle {
|
||||
/* placeholder for V4 file handle */
|
||||
#ifdef HAVE_FS_NFS3
|
||||
struct mountres3 v3; /* NFS version 3 handle */
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
struct fhstatus v2; /* NFS version 2 handle */
|
||||
};
|
||||
typedef union am_nfs_handle am_nfs_handle_t;
|
||||
|
||||
/*
|
||||
* automounter vfs/vnode operations.
|
||||
*/
|
||||
typedef char *(*vfs_match) (am_opts *);
|
||||
typedef int (*vfs_init) (mntfs *);
|
||||
typedef int (*vmount_fs) (am_node *);
|
||||
typedef int (*vfmount_fs) (mntfs *);
|
||||
typedef int (*vumount_fs) (am_node *);
|
||||
typedef int (*vfumount_fs) (mntfs *);
|
||||
typedef am_node *(*vlookuppn) (am_node *, char *, int *, int);
|
||||
typedef int (*vreaddir) (am_node *, nfscookie, nfsdirlist *, nfsentry *, int);
|
||||
typedef am_node *(*vreadlink) (am_node *, int *);
|
||||
typedef void (*vmounted) (mntfs *);
|
||||
typedef void (*vumounted) (am_node *);
|
||||
typedef fserver *(*vffserver) (mntfs *);
|
||||
|
||||
struct am_ops {
|
||||
char *fs_type; /* type of filesystems "nfsx" */
|
||||
vfs_match fs_match; /* fxn: match */
|
||||
vfs_init fs_init; /* fxn: initialization */
|
||||
vmount_fs mount_fs; /* fxn: mount vnode */
|
||||
vfmount_fs fmount_fs; /* fxn: mount VFS */
|
||||
vumount_fs umount_fs; /* fxn: unmount vnode */
|
||||
vfumount_fs fumount_fs; /* fxn: unmount VFS */
|
||||
vlookuppn lookuppn; /* fxn: lookup path-name */
|
||||
vreaddir readdir; /* fxn: read directory */
|
||||
vreadlink readlink; /* fxn: read link */
|
||||
vmounted mounted; /* fxn: */
|
||||
vumounted umounted; /* fxn: */
|
||||
vffserver ffserver; /* fxn: find a file server */
|
||||
int fs_flags; /* filesystem flags FS_* */
|
||||
};
|
||||
|
||||
typedef int (*task_fun) (voidp);
|
||||
typedef void (*cb_fun) (int, int, voidp);
|
||||
typedef void (*fwd_fun) P((voidp, int, struct sockaddr_in *,
|
||||
struct sockaddr_in *, voidp, int));
|
||||
|
||||
/*
|
||||
* Am-utils' internal mount entry structure
|
||||
* XXX: one day, nuke this thing. -Erez.
|
||||
*/
|
||||
struct _am_utils_mntent_dontuse {
|
||||
char *mnt_fsname; /* name of mounted file system */
|
||||
char *mnt_dir; /* file system path prefix */
|
||||
char *mnt_type; /* MOUNT_TYPE_* */
|
||||
char *mnt_opts; /* MNTTAB_OPT* */
|
||||
int mnt_freq; /* dump frequency, in days */
|
||||
int mnt_passno; /* pass number on parallel fsck */
|
||||
#ifdef HAVE_FIELD_MNTENT_T_MNT_CNODE
|
||||
int mnt_cnode; /* cluster node */
|
||||
#endif /* HAVE_FIELD_MNTENT_T_MNT_CNODE */
|
||||
#ifdef HAVE_FIELD_MNTENT_T_MNT_RO
|
||||
int mnt_ro; /* read-only mount option */
|
||||
#endif /* HAVE_FIELD_MNTENT_T_MNT_RO */
|
||||
#ifdef HAVE_FIELD_MNTENT_T_MNT_TIME
|
||||
# ifdef HAVE_FIELD_MNTENT_T_TIME_STRING
|
||||
char *mnt_time; /* time filesystem was mounted */
|
||||
# else /* not HAVE_FIELD_MNTENT_T_TIME_STRING */
|
||||
long mnt_time; /* time filesystem was mounted */
|
||||
# endif /* not HAVE_FIELD_MNTENT_T_TIME_STRING */
|
||||
#endif /* HAVE_FIELD_MNTENT_T_MNT_TIME */
|
||||
};
|
||||
|
||||
/*
|
||||
* List of mount table entries
|
||||
*/
|
||||
struct mntlist {
|
||||
struct mntlist *mnext;
|
||||
mntent_t *mnt;
|
||||
};
|
||||
|
||||
/*
|
||||
* Mount map
|
||||
*/
|
||||
typedef struct mnt_map mnt_map;
|
||||
|
||||
/*
|
||||
* Per-mountpoint statistics
|
||||
*/
|
||||
struct am_stats {
|
||||
time_t s_mtime; /* Mount time */
|
||||
u_short s_uid; /* Uid of mounter */
|
||||
int s_getattr; /* Count of getattrs */
|
||||
int s_lookup; /* Count of lookups */
|
||||
int s_readdir; /* Count of readdirs */
|
||||
int s_readlink; /* Count of readlinks */
|
||||
int s_statfs; /* Count of statfs */
|
||||
};
|
||||
typedef struct am_stats am_stats;
|
||||
|
||||
/*
|
||||
* System statistics
|
||||
*/
|
||||
struct amd_stats {
|
||||
int d_drops; /* Dropped requests */
|
||||
int d_stale; /* Stale NFS handles */
|
||||
int d_mok; /* Succesful mounts */
|
||||
int d_merr; /* Failed mounts */
|
||||
int d_uerr; /* Failed unmounts */
|
||||
};
|
||||
extern struct amd_stats amd_stats;
|
||||
|
||||
/*
|
||||
* List of fileservers
|
||||
*/
|
||||
struct fserver {
|
||||
qelem fs_q; /* List of fileservers */
|
||||
int fs_refc; /* Number of references to this node */
|
||||
char *fs_host; /* Normalized hostname of server */
|
||||
struct sockaddr_in *fs_ip; /* Network address of server */
|
||||
int fs_cid; /* Callout id */
|
||||
int fs_pinger; /* Ping (keepalive) interval */
|
||||
int fs_flags; /* Flags */
|
||||
char *fs_type; /* File server type */
|
||||
u_long fs_version; /* NFS version of server (2, 3, etc.)*/
|
||||
char *fs_proto; /* NFS protocol of server (tcp, udp, etc.) */
|
||||
voidp fs_private; /* Private data */
|
||||
void (*fs_prfree) (); /* Free private data */
|
||||
};
|
||||
|
||||
/*
|
||||
* Map of auto-mount points.
|
||||
*/
|
||||
struct am_node {
|
||||
int am_mapno; /* Map number */
|
||||
mntfs *am_mnt; /* Mounted filesystem */
|
||||
char *am_name; /* "kiska" Name of this node */
|
||||
char *am_path; /* "/home/kiska" Path of this node's mount */
|
||||
/* point */
|
||||
char *am_link; /* "/a/kiska/home/kiska/this/that" Link to */
|
||||
/* sub-directory */
|
||||
am_node *am_parent; /* Parent of this node */
|
||||
am_node *am_ysib; /* Younger sibling of this node */
|
||||
am_node *am_osib; /* Older sibling of this node */
|
||||
am_node *am_child; /* First child of this node */
|
||||
nfsattrstat am_attr; /* File attributes */
|
||||
#define am_fattr am_attr.ns_u.ns_attr_u
|
||||
int am_flags; /* Boolean flags */
|
||||
int am_error; /* Specific mount error */
|
||||
time_t am_ttl; /* Time to live */
|
||||
int am_timeo_w; /* Wait interval */
|
||||
int am_timeo; /* Timeout interval */
|
||||
u_int am_gen; /* Generation number */
|
||||
char *am_pref; /* Mount info prefix */
|
||||
am_stats am_stats; /* Statistics gathering */
|
||||
SVCXPRT *am_transp; /* Info for quick reply */
|
||||
};
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*** EXTERNALS ***/
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* Useful constants
|
||||
*/
|
||||
extern char *mtab; /* Mount table */
|
||||
extern char *cpu; /* "CPU type" */
|
||||
extern char *endian; /* "big" */
|
||||
extern char *hostdomain; /* "southseas.nz" */
|
||||
extern char copyright[]; /* Copyright info */
|
||||
extern char hostd[]; /* "kiska.southseas.nz" */
|
||||
extern char pid_fsname[]; /* kiska.southseas.nz:(pid%d) */
|
||||
extern char version[]; /* Version info */
|
||||
|
||||
/*
|
||||
* Global variables.
|
||||
*/
|
||||
extern AUTH *nfs_auth; /* Dummy uthorisation for remote servers */
|
||||
extern FILE *logfp; /* Log file */
|
||||
extern am_node **exported_ap; /* List of nodes */
|
||||
extern am_node *root_node; /* Node for "root" */
|
||||
extern char *PrimNetName; /* Name of primary connected network */
|
||||
extern char *PrimNetNum; /* Name of primary connected network */
|
||||
extern char *SubsNetName; /* Name of subsidiary connected network */
|
||||
extern char *SubsNetNum; /* Name of subsidiary connected network */
|
||||
extern char *progname; /* "amd"|"mmd" */
|
||||
extern char hostname[]; /* "kiska" */
|
||||
extern int first_free_map; /* First free node */
|
||||
extern int foreground; /* Foreground process */
|
||||
extern int immediate_abort; /* Should close-down unmounts be retried */
|
||||
extern int last_used_map; /* Last map being used for mounts */
|
||||
extern int orig_umask; /* umask() on startup */
|
||||
extern int task_notify_todo; /* Task notifier needs running */
|
||||
extern int xlog_level; /* Logging level */
|
||||
extern int xlog_level_init;
|
||||
extern pid_t mypid; /* Current process id */
|
||||
extern serv_state amd_state; /* Should we go now */
|
||||
extern struct in_addr myipaddr; /* (An) IP address of this host */
|
||||
extern struct opt_tab xlog_opt[];
|
||||
extern time_t clock_valid; /* Clock needs recalculating */
|
||||
extern time_t do_mapc_reload; /* Flush & reload mount map cache */
|
||||
extern time_t next_softclock; /* Time to call softclock() */
|
||||
extern u_short nfs_port; /* Our NFS service port */
|
||||
|
||||
/*
|
||||
* Global routines
|
||||
*/
|
||||
extern CLIENT *get_mount_client(char *unused_host, struct sockaddr_in *sin, struct timeval *tv, int *sock, u_long mnt_version);
|
||||
extern RETSIGTYPE sigchld(int);
|
||||
extern SVCXPRT *nfsxprt;
|
||||
extern am_node *efs_lookuppn(am_node *, char *, int *, int);
|
||||
extern am_node *exported_ap_alloc(void);
|
||||
extern am_node *fh_to_mp(am_nfs_fh *);
|
||||
extern am_node *fh_to_mp3(am_nfs_fh *, int *, int);
|
||||
extern am_node *find_ap(char *);
|
||||
extern am_node *find_mf(mntfs *);
|
||||
extern am_node *next_map(int *);
|
||||
extern am_node *root_ap(char *, int);
|
||||
extern am_ops *ops_match(am_opts *, char *, char *, char *, char *, char *);
|
||||
extern bool_t xdr_amq_string(XDR *xdrs, amq_string *objp);
|
||||
extern bool_t xdr_dirpath(XDR *xdrs, dirpath *objp);
|
||||
extern char **strsplit(char *, int, int);
|
||||
extern char *expand_key(char *);
|
||||
extern char *get_version_string(void);
|
||||
extern char *inet_dquad(char *, u_long);
|
||||
extern char *str3cat(char *, char *, char *, char *);
|
||||
extern char *strealloc(char *, char *);
|
||||
extern char *strip_selectors(char *, char *);
|
||||
extern char *strnsave(const char *, int);
|
||||
extern fserver *dup_srvr(fserver *);
|
||||
extern int amu_close(int fd);
|
||||
extern int auto_fmount(am_node *mp);
|
||||
extern int auto_fumount(am_node *mp);
|
||||
extern int background(void);
|
||||
extern int bind_resv_port(int, u_short *);
|
||||
extern int cmdoption(char *, struct opt_tab *, int *);
|
||||
extern int compute_mount_flags(mntent_t *);
|
||||
extern int efs_readdir(am_node *, nfscookie, nfsdirlist *, nfsentry *, int);
|
||||
extern int eval_fs_opts(am_opts *, char *, char *, char *, char *, char *);
|
||||
extern int fwd_init(void);
|
||||
extern int fwd_packet(int, voidp, int, struct sockaddr_in *, struct sockaddr_in *, voidp, fwd_fun);
|
||||
extern int hasmntval(mntent_t *, char *);
|
||||
extern int islocalnet(u_long);
|
||||
extern int make_nfs_auth(void);
|
||||
extern int make_rpc_packet(char *, int, u_long, struct rpc_msg *, voidp, XDRPROC_T_TYPE, AUTH *);
|
||||
extern int mapc_keyiter(mnt_map *, void(*)(char *, voidp), voidp);
|
||||
extern int mapc_search(mnt_map *, char *, char **);
|
||||
extern int mkdirs(char *, int);
|
||||
extern int mount_auto_node(char *, voidp);
|
||||
extern int mount_automounter(int);
|
||||
extern int mount_exported(void);
|
||||
extern int mount_fs(mntent_t *, int, caddr_t, int, MTYPE_TYPE, u_long, const char *);
|
||||
extern int mount_node(am_node *);
|
||||
extern int nfs_srvr_port(fserver *, u_short *, voidp);
|
||||
extern int pickup_rpc_reply(voidp, int, voidp, XDRPROC_T_TYPE);
|
||||
extern int root_keyiter(void(*)(char *, voidp), voidp);
|
||||
extern int softclock(void);
|
||||
extern int switch_option(char *);
|
||||
extern int switch_to_logfile(char *);
|
||||
extern int timeout(u_int, void(*fn)(), voidp);
|
||||
extern int umount_fs(char *);
|
||||
extern int valid_key(char *);
|
||||
extern mnt_map *mapc_find(char *, char *, const char *);
|
||||
extern mntfs *dup_mntfs(mntfs *);
|
||||
extern mntfs *find_mntfs(am_ops *, am_opts *, char *, char *, char *, char *, char *);
|
||||
extern mntfs *new_mntfs(void);
|
||||
extern mntfs *realloc_mntfs(mntfs *, am_ops *, am_opts *, char *, char *, char *, char *, char *);
|
||||
extern mntlist *read_mtab(char *);
|
||||
extern struct sockaddr_in *amu_svc_getcaller(SVCXPRT *xprt);
|
||||
extern time_t time(time_t *);
|
||||
extern void am_mounted(am_node *);
|
||||
extern void am_unmounted(am_node *);
|
||||
extern void amq_program_1(struct svc_req *rqstp, SVCXPRT * transp);
|
||||
extern void amu_get_myaddress(struct in_addr *iap);
|
||||
extern void deslashify(char *);
|
||||
extern void discard_mntlist(mntlist *mp);
|
||||
extern void do_task_notify(void);
|
||||
extern void flush_mntfs(void);
|
||||
extern void flush_nfs_fhandle_cache(fserver *);
|
||||
extern void forcibly_timeout_mp(am_node *);
|
||||
extern void free_map(am_node *);
|
||||
extern void free_mntfs(mntfs *);
|
||||
extern void free_mntlist(mntlist *);
|
||||
extern void free_opts(am_opts *);
|
||||
extern void free_srvr(fserver *);
|
||||
extern void fwd_reply(void);
|
||||
extern void get_args(int, char *[]);
|
||||
extern void getwire(char **, char **, char **, char **);
|
||||
extern void going_down(int);
|
||||
extern void host_normalize(char **);
|
||||
extern void init_map(am_node *, char *);
|
||||
extern void ins_que(qelem *, qelem *);
|
||||
extern void insert_am(am_node *, am_node *);
|
||||
extern void make_root_node(void);
|
||||
extern void map_flush_srvr(fserver *);
|
||||
extern void mapc_add_kv(mnt_map *, char *, char *);
|
||||
extern void mapc_free(mnt_map *);
|
||||
extern void mapc_reload(void);
|
||||
extern void mapc_showtypes(char *buf);
|
||||
extern void mk_fattr(am_node *, nfsftype);
|
||||
extern void mnt_free(mntent_t *);
|
||||
extern void mp_to_fh(am_node *, am_nfs_fh *);
|
||||
extern void new_ttl(am_node *);
|
||||
extern void nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp);
|
||||
extern void normalize_slash(char *);
|
||||
extern void ops_showamfstypes(char *buf);
|
||||
extern void ops_showfstypes(char *outbuf);
|
||||
extern void plog(int, char *,...);
|
||||
extern void rem_que(qelem *);
|
||||
extern void reschedule_timeout_mp(void);
|
||||
extern void restart(void);
|
||||
extern void rmdirs(char *);
|
||||
extern void rpc_msg_init(struct rpc_msg *, u_long, u_long, u_long);
|
||||
extern void run_task(task_fun, voidp, cb_fun, voidp);
|
||||
extern void sched_task(cb_fun, voidp, voidp);
|
||||
extern void show_opts(int ch, struct opt_tab *);
|
||||
extern void show_rcs_info(const char *, char *);
|
||||
extern void srvrlog(fserver *, char *);
|
||||
extern void timeout_mp(void);
|
||||
extern void umount_exported(void);
|
||||
extern void unregister_amq(void);
|
||||
extern void untimeout(int);
|
||||
extern void wakeup(voidp);
|
||||
extern void wakeup_srvr(fserver *);
|
||||
extern void wakeup_task(int, int, voidp);
|
||||
extern void write_mntent(mntent_t *);
|
||||
extern voidp xmalloc(int);
|
||||
extern voidp xrealloc(voidp, int);
|
||||
extern u_long get_nfs_version(char *host, struct sockaddr_in *sin, u_long nfs_version, const char *proto);
|
||||
|
||||
|
||||
#ifdef MOUNT_TABLE_ON_FILE
|
||||
extern void rewrite_mtab(mntlist *);
|
||||
extern void unlock_mntlist(void);
|
||||
#endif /* MOUNT_TABLE_ON_FILE */
|
||||
|
||||
#if defined(HAVE_SYSLOG_H) || defined(HAVE_SYS_SYSLOG_H)
|
||||
extern int syslogging;
|
||||
#endif /* defined(HAVE_SYSLOG_H) || defined(HAVE_SYS_SYSLOG_H) */
|
||||
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
extern int create_amq_service(int *udp_soAMQp, SVCXPRT **udp_amqpp, struct netconfig **udp_amqncpp, int *tcp_soAMQp, SVCXPRT **tcp_amqpp, struct netconfig **tcp_amqncpp);
|
||||
extern int create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp));
|
||||
extern int get_knetconfig(struct knetconfig **kncpp, struct netconfig *in_ncp, char *nc_protoname);
|
||||
extern struct netconfig *nfsncp;
|
||||
extern void free_knetconfig(struct knetconfig *kncp);
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
extern int create_amq_service(int *udp_soAMQp, SVCXPRT **udp_amqpp, int *tcp_soAMQp, SVCXPRT **tcp_amqpp);
|
||||
extern int create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp));
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
#ifndef HAVE_FIELD_STRUCT_FHSTATUS_FHS_FH
|
||||
# define fhs_fh fhstatus_u.fhs_fhandle
|
||||
#endif /* not HAVE_FIELD_STRUCT_FHSTATUS_FHS_FH */
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*** Generic file-system types, implemented as part of the native O/S. ***/
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* Loopback File System
|
||||
* Many systems can't support this, and in any case most of the
|
||||
* functionality is available with Symlink FS.
|
||||
*/
|
||||
#ifdef HAVE_FS_LOFS
|
||||
extern am_ops lofs_ops;
|
||||
#endif /* HAVE_FS_LOFS */
|
||||
|
||||
/*
|
||||
* CD-ROM File System (CD-ROM)
|
||||
* (HSFS: High Sierra F/S on some machines)
|
||||
* Many systems can't support this, and in any case most of the
|
||||
* functionality is available with program FS.
|
||||
*/
|
||||
#ifdef HAVE_FS_CDFS
|
||||
extern am_ops cdfs_ops;
|
||||
#endif /* HAVE_FS_CDFS */
|
||||
|
||||
/*
|
||||
* PC File System (MS-DOS)
|
||||
* Many systems can't support this, and in any case most of the
|
||||
* functionality is available with program FS.
|
||||
*/
|
||||
#ifdef HAVE_FS_PCFS
|
||||
extern am_ops pcfs_ops;
|
||||
#endif /* HAVE_FS_PCFS */
|
||||
|
||||
/*
|
||||
* Network File System
|
||||
* Good, slow, NFS V.2.
|
||||
*/
|
||||
#ifdef HAVE_FS_NFS
|
||||
extern am_ops nfs_ops; /* NFS */
|
||||
extern qelem nfs_srvr_list;
|
||||
extern fserver *find_nfs_srvr (mntfs *);
|
||||
#endif /* HAVE_FS_NFS */
|
||||
|
||||
/*
|
||||
* Network File System: the new generation
|
||||
* NFS V.3
|
||||
*/
|
||||
#ifdef HAVE_FS_NFS3
|
||||
# ifndef NFS_VERSION3
|
||||
# define NFS_VERSION3 ((u_int) 3)
|
||||
# endif /* not NFS_VERSION3 */
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
|
||||
/*
|
||||
* Un*x File System
|
||||
* Normal local disk file system.
|
||||
*/
|
||||
#ifdef HAVE_FS_UFS
|
||||
extern am_ops ufs_ops; /* Un*x file system */
|
||||
#endif /* HAVE_FS_UFS */
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*** Automounter file-system types, implemented by amd. ***/
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* Automount File System
|
||||
*/
|
||||
#ifdef HAVE_AM_FS_AFS
|
||||
extern am_ops afs_ops; /* Automount file system (this!) */
|
||||
extern am_ops toplvl_ops; /* Top-level automount file system */
|
||||
extern am_ops root_ops; /* Root file system */
|
||||
extern qelem afs_srvr_list;
|
||||
extern fserver *find_afs_srvr (mntfs *);
|
||||
#endif /* HAVE_AM_FS_AFS */
|
||||
|
||||
/*
|
||||
* Direct Automount File System
|
||||
*/
|
||||
#ifdef HAVE_AM_FS_DFS
|
||||
extern am_ops dfs_ops; /* Direct Automount file system (this too) */
|
||||
#endif /* HAVE_AM_FS_DFS */
|
||||
|
||||
/*
|
||||
* Error File System
|
||||
*/
|
||||
#ifdef HAVE_AM_FS_EFS
|
||||
extern am_ops efs_ops; /* Error file system */
|
||||
#endif /* HAVE_AM_FS_EFS */
|
||||
|
||||
/*
|
||||
* Inheritance File System
|
||||
*/
|
||||
#ifdef HAVE_AM_FS_IFS
|
||||
extern am_ops ifs_ops; /* Inheritance file system */
|
||||
#endif /* HAVE_AM_FS_IFS */
|
||||
|
||||
/*
|
||||
* Multi-nfs mounts.
|
||||
*/
|
||||
#ifdef HAVE_AM_FS_NFSX
|
||||
extern am_ops nfsx_ops; /* NFS X */
|
||||
#endif /* HAVE_AM_FS_NFSX */
|
||||
|
||||
/*
|
||||
* NFS host - a whole tree.
|
||||
*/
|
||||
#ifdef HAVE_AM_FS_HOST
|
||||
extern am_ops host_ops; /* NFS host */
|
||||
#endif /* HAVE_AM_FS_HOST */
|
||||
|
||||
/*
|
||||
* Program File System
|
||||
* This is useful for things like RVD.
|
||||
*/
|
||||
#ifdef HAVE_AM_FS_PFS
|
||||
extern am_ops pfs_ops; /* PFS */
|
||||
#endif /* HAVE_AM_FS_PFS */
|
||||
|
||||
/*
|
||||
* Symbolic-link file system.
|
||||
* A "filesystem" which is just a symbol link.
|
||||
*/
|
||||
#ifdef HAVE_AM_FS_SFS
|
||||
extern am_ops sfs_ops; /* Symlink FS */
|
||||
#endif /* HAVE_AM_FS_SFS */
|
||||
|
||||
/*
|
||||
* Symbolic-link file syste, which also checks that the target of
|
||||
* the symlink exists.
|
||||
* A "filesystem" which is just a symbol link.
|
||||
*/
|
||||
#ifdef HAVE_AM_FS_SFSX
|
||||
extern am_ops sfsx_ops; /* Symlink FS with existence check */
|
||||
#endif /* HAVE_AM_FS_SFSX */
|
||||
|
||||
/*
|
||||
* Union file system
|
||||
*/
|
||||
#ifdef HAVE_AM_FS_UNION
|
||||
extern am_ops union_ops; /* Union FS */
|
||||
#endif /* HAVE_AM_FS_UNION */
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*** DEBUGGING ***/
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* DEBUGGING:
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
|
||||
# define D_ALL (~0)
|
||||
# define D_DAEMON 0x0001 /* Enter daemon mode */
|
||||
# define D_TRACE 0x0002 /* Do protocol trace */
|
||||
# define D_FULL 0x0004 /* Do full trace */
|
||||
# define D_MTAB 0x0008 /* Use local mtab */
|
||||
# define D_AMQ 0x0010 /* Register amq program */
|
||||
# define D_STR 0x0020 /* Debug string munging */
|
||||
# ifdef DEBUG_MEM
|
||||
# define D_MEM 0x0040 /* Trace memory allocations */
|
||||
# endif /* DEBUG_MEM */
|
||||
# define D_FORK 0x0080 /* Fork server */
|
||||
|
||||
/*
|
||||
* Normally, don't enter daemon mode, and don't register amq
|
||||
*/
|
||||
# ifdef DEBUG_MEM
|
||||
# define D_TEST (~(D_DAEMON|D_MEM|D_STR))
|
||||
# else /* not DEBUG_MEM */
|
||||
# define D_TEST (~(D_DAEMON|D_STR))
|
||||
# endif /* not DEBUG_MEM */
|
||||
|
||||
# define amuDebug(x) if (!(debug_flags & (x))) ; else
|
||||
# define dlog amuDebug(D_FULL) dplog
|
||||
# define amuDebugNo(x) if (debug_flags & (x)) ; else
|
||||
|
||||
/* debugging mount-table file to use */
|
||||
# ifndef DEBUG_MNTTAB
|
||||
# define DEBUG_MNTTAB "./mnttab"
|
||||
# endif /* not DEBUG_MNTTAB */
|
||||
# ifdef DEBUG_MEM
|
||||
# define free(x) xfree(__FILE__,__LINE__,x)
|
||||
# endif /* DEBUG_MEM */
|
||||
#endif /* DEBUG */
|
||||
|
||||
extern int debug_flags; /* Debug options */
|
||||
extern int debug_option (char *);
|
||||
extern struct opt_tab dbg_opt[];
|
||||
extern void dplog(char *fmt, ...);
|
||||
|
||||
/**************************************************************************/
|
||||
/*** MISC (stuff left to autoconfiscate) ***/
|
||||
/**************************************************************************/
|
||||
|
||||
#endif /* not _AM_UTILS_H */
|
222
usr.sbin/amd/include/amd.h
Normal file
222
usr.sbin/amd/include/amd.h
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: amd.h,v 1.1.1.1 1997/07/24 21:20:15 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AMD_H
|
||||
#define _AMD_H
|
||||
|
||||
|
||||
/*
|
||||
* MACROS:
|
||||
*/
|
||||
|
||||
/* options for amd.conf */
|
||||
#define CFM_BROWSABLE_DIRS 0x0001
|
||||
#define CFM_MOUNT_TYPE_AUTOFS 0x0002
|
||||
#define CFM_ENABLE_DEFAULT_SELECTORS 0x0004
|
||||
#define CFM_NORMALIZE_HOSTNAMES 0x0008
|
||||
#define CFM_NOSWAP 0x0010
|
||||
#define CFM_PRINT_PID 0x0020
|
||||
#define CFM_RESTART_EXISTING_MOUNTS 0x0040
|
||||
|
||||
|
||||
/* some systems (SunOS 4.x) neglect to define the mount null message */
|
||||
#ifndef MOUNTPROC_NULL
|
||||
# define MOUNTPROC_NULL ((u_long)(0))
|
||||
#endif /* not MOUNTPROC_NULL */
|
||||
|
||||
/* Hash table size */
|
||||
#define NKVHASH (1 << 2) /* Power of two */
|
||||
|
||||
|
||||
/*
|
||||
* TYPEDEFS:
|
||||
*/
|
||||
|
||||
typedef struct cf_map cf_map_t;
|
||||
typedef struct kv kv;
|
||||
/*
|
||||
* Cache map operations
|
||||
*/
|
||||
typedef void add_fn(mnt_map *, char *, char *);
|
||||
typedef int init_fn(mnt_map *, char *, time_t *);
|
||||
typedef int mtime_fn(mnt_map *, char *, time_t *);
|
||||
typedef int reload_fn(mnt_map *, char *, add_fn *);
|
||||
typedef int search_fn(mnt_map *, char *, char *, char **, time_t *);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* STRUCTURES:
|
||||
*/
|
||||
|
||||
/* global amd options that are manipulated by conf.c */
|
||||
struct amu_global_options {
|
||||
char *arch; /* name of current architecture */
|
||||
char *auto_dir; /* automounter temp dir */
|
||||
char *cluster; /* cluster name */
|
||||
char *karch; /* kernel architecture */
|
||||
char *logfile; /* amd log file */
|
||||
char *op_sys; /* operating system name */
|
||||
char *op_sys_ver; /* OS version */
|
||||
char *sub_domain; /* local domain */
|
||||
char *map_options; /* global map options */
|
||||
char *map_type; /* global map type */
|
||||
char *search_path; /* search path for maps */
|
||||
char *mount_type; /* mount type for map */
|
||||
u_int flags; /* various CFM_* flags */
|
||||
int afs_retrans; /* NFS retransmit counter */
|
||||
int afs_timeo; /* NFS retry interval */
|
||||
int am_timeo; /* cache duration */
|
||||
int am_timeo_w; /* dismount interval */
|
||||
#ifdef HAVE_MAP_LDAP
|
||||
char *ldap_base; /* LDAP base */
|
||||
char *ldap_hostports; /* LDAP host ports */
|
||||
#endif /* HAVE_MAP_LDAP */
|
||||
#ifdef HAVE_MAP_NIS
|
||||
char *nis_domain; /* YP domain name */
|
||||
#endif /* HAVE_MAP_NIS */
|
||||
};
|
||||
|
||||
struct cf_map {
|
||||
char *cfm_dir; /* /home, /u, /src */
|
||||
char *cfm_name; /* amd.home, /etc/amd.home ... */
|
||||
char *cfm_type; /* file, hesiod, ndbm, nis ... */
|
||||
char *cfm_opts; /* -cache:=all, etc. */
|
||||
char *cfm_search_path; /* /etc/local:/etc/amdmaps:/misc/yp */
|
||||
char *cfm_tag; /* optional map tag for amd -T */
|
||||
u_int cfm_flags; /* browsable_dirs? mount_type? */
|
||||
};
|
||||
|
||||
/*
|
||||
* Key-value pair
|
||||
*/
|
||||
struct kv {
|
||||
kv *next;
|
||||
char *key;
|
||||
#ifdef HAVE_REGEXEC
|
||||
regex_t re; /* store the regexp from regcomp() */
|
||||
#endif /* HAVE_REGEXEC */
|
||||
char *val;
|
||||
};
|
||||
|
||||
struct mnt_map {
|
||||
qelem hdr;
|
||||
int refc; /* Reference count */
|
||||
short flags; /* Allocation flags */
|
||||
short alloc; /* Allocation mode */
|
||||
time_t modify; /* Modify time of map */
|
||||
char *map_name; /* Name of this map */
|
||||
char *wildcard; /* Wildcard value */
|
||||
reload_fn *reload; /* Function to be used for reloads */
|
||||
search_fn *search; /* Function to be used for searching */
|
||||
mtime_fn *mtime; /* Modify time function */
|
||||
kv *kvhash[NKVHASH]; /* Cached data */
|
||||
/* options available via amd conf file */
|
||||
char *cf_map_type; /* file, hesiod, ndbm, nis, etc. */
|
||||
char *cf_search_path; /* /etc/local:/etc/amdmaps:/misc/yp */
|
||||
u_int cf_flags; /* browsable_dirs? mount_type? */
|
||||
void *map_data; /* Map data black box */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* EXTERNALS:
|
||||
*/
|
||||
|
||||
/* amd global functions */
|
||||
extern amq_mount_info_list *amqproc_getmntfs_1_svc(voidp argp, struct svc_req *rqstp);
|
||||
extern amq_mount_stats *amqproc_stats_1_svc(voidp argp, struct svc_req *rqstp);
|
||||
extern amq_mount_tree_list *amqproc_export_1_svc(voidp argp, struct svc_req *rqstp);
|
||||
extern amq_mount_tree_p *amqproc_mnttree_1_svc(voidp argp, struct svc_req *rqstp);
|
||||
extern amq_string *amqproc_getvers_1_svc(voidp argp, struct svc_req *rqstp);
|
||||
extern int *amqproc_mount_1_svc(voidp argp, struct svc_req *rqstp);
|
||||
extern int *amqproc_setopt_1_svc(voidp argp, struct svc_req *rqstp);
|
||||
extern voidp amqproc_null_1_svc(voidp argp, struct svc_req *rqstp);
|
||||
extern voidp amqproc_umnt_1_svc(voidp argp, struct svc_req *rqstp);
|
||||
|
||||
extern SVCXPRT *nfs_program_2_transp; /* For quick_reply() */
|
||||
extern am_nfs_fh *root_fh(char *dir);
|
||||
extern bool_t xdr_amq_mount_info_qelem(XDR *xdrs, qelem *qhead);
|
||||
extern fserver *find_nfs_srvr(mntfs *mf);
|
||||
extern int mount_nfs_fh(am_nfs_handle_t *fhp, char *dir, char *fs_name, char *opts, mntfs *mf);
|
||||
extern int process_last_regular_map(void);
|
||||
extern int set_conf_kv(const char *section, const char *k, const char *v);
|
||||
extern nfsentry *make_entry_chain(am_node *mp, const nfsentry *current_chain);
|
||||
extern void flush_srvr_nfs_cache(void);
|
||||
extern void mf_mounted(mntfs *mf);
|
||||
extern void quick_reply(am_node *mp, int error);
|
||||
|
||||
/* amd global variables */
|
||||
extern struct amu_global_options gopt; /* where global options are stored */
|
||||
extern FILE *yyin;
|
||||
extern am_ops cdfs_ops;
|
||||
extern am_ops lofs_ops;
|
||||
extern am_ops nfs_ops;
|
||||
extern am_ops pcfs_ops;
|
||||
extern am_ops ufs_ops;
|
||||
extern char *conf_tag;
|
||||
extern int NumChild;
|
||||
extern int fwd_sock;
|
||||
extern int select_intr_valid;
|
||||
extern int usage;
|
||||
extern int use_conf_file; /* use amd configuration file */
|
||||
extern int yyparse (void);
|
||||
extern jmp_buf select_intr;
|
||||
extern qelem mfhead;
|
||||
extern void root_newmap(const char *, const char *, const char *, const cf_map_t *);
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
extern sigset_t masked_sigs;
|
||||
#endif /* HAVE_SIGACTION */
|
||||
|
||||
#if defined(HAVE_AM_FS_SFS) || defined(HAVE_AM_FS_SFSX)
|
||||
extern char * sfs_match(am_opts *fo);
|
||||
extern int sfs_fumount(mntfs *mf);
|
||||
#endif /* defined(HAVE_AM_FS_SFS) || defined(HAVE_AM_FS_SFSX) */
|
||||
|
||||
#if defined(HAVE_FS_NFS3) && !defined(HAVE_XDR_MOUNTRES3)
|
||||
extern bool_t xdr_mountres3(XDR *xdrs, mountres3 *objp);
|
||||
#endif /* defined(HAVE_FS_NFS3) && !defined(HAVE_XDR_MOUNTRES3) */
|
||||
|
||||
#endif /* not _AMD_H */
|
156
usr.sbin/amd/include/amq_defs.h
Normal file
156
usr.sbin/amd/include/amq_defs.h
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: amq_defs.h,v 1.1.1.1 1997/07/24 21:20:15 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AMQ_DEFS_H
|
||||
#define _AMQ_DEFS_H
|
||||
|
||||
/*
|
||||
* MACROS
|
||||
*/
|
||||
#ifndef AMQ_SIZE
|
||||
# define AMQ_SIZE 16384
|
||||
#endif /* not AMQ_SIZE */
|
||||
#define AMQ_STRLEN 1024
|
||||
#define AMQ_PROGRAM ((u_long)300019)
|
||||
#define AMQ_VERSION ((u_long)1)
|
||||
#define AMQPROC_NULL ((u_long)0)
|
||||
#define AMQPROC_MNTTREE ((u_long)1)
|
||||
#define AMQPROC_UMNT ((u_long)2)
|
||||
#define AMQPROC_STATS ((u_long)3)
|
||||
#define AMQPROC_EXPORT ((u_long)4)
|
||||
#define AMQPROC_SETOPT ((u_long)5)
|
||||
#define AMQPROC_GETMNTFS ((u_long)6)
|
||||
#define AMQPROC_MOUNT ((u_long)7)
|
||||
#define AMQPROC_GETVERS ((u_long)8)
|
||||
|
||||
/*
|
||||
* TYPEDEFS
|
||||
*/
|
||||
typedef long *time_type;
|
||||
typedef struct amq_mount_info amq_mount_info;
|
||||
typedef struct amq_mount_stats amq_mount_stats;
|
||||
typedef struct amq_mount_tree amq_mount_tree;
|
||||
typedef struct amq_setopt amq_setopt;
|
||||
typedef amq_mount_tree *amq_mount_tree_p;
|
||||
|
||||
/*
|
||||
* STRUCTURES:
|
||||
*/
|
||||
struct amq_mount_tree {
|
||||
amq_string mt_mountinfo;
|
||||
amq_string mt_directory;
|
||||
amq_string mt_mountpoint;
|
||||
amq_string mt_type;
|
||||
time_type mt_mounttime;
|
||||
u_short mt_mountuid;
|
||||
int mt_getattr;
|
||||
int mt_lookup;
|
||||
int mt_readdir;
|
||||
int mt_readlink;
|
||||
int mt_statfs;
|
||||
struct amq_mount_tree *mt_next;
|
||||
struct amq_mount_tree *mt_child;
|
||||
};
|
||||
|
||||
struct amq_mount_info {
|
||||
amq_string mi_type;
|
||||
amq_string mi_mountpt;
|
||||
amq_string mi_mountinfo;
|
||||
amq_string mi_fserver;
|
||||
int mi_error;
|
||||
int mi_refc;
|
||||
int mi_up;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
u_int amq_mount_info_list_len;
|
||||
amq_mount_info *amq_mount_info_list_val;
|
||||
} amq_mount_info_list;
|
||||
|
||||
typedef struct {
|
||||
u_int amq_mount_tree_list_len;
|
||||
amq_mount_tree_p *amq_mount_tree_list_val;
|
||||
} amq_mount_tree_list;
|
||||
|
||||
struct amq_mount_stats {
|
||||
int as_drops;
|
||||
int as_stale;
|
||||
int as_mok;
|
||||
int as_merr;
|
||||
int as_uerr;
|
||||
};
|
||||
|
||||
enum amq_opt {
|
||||
AMOPT_DEBUG = 0,
|
||||
AMOPT_LOGFILE = 1,
|
||||
AMOPT_XLOG = 2,
|
||||
AMOPT_FLUSHMAPC = 3
|
||||
};
|
||||
typedef enum amq_opt amq_opt; /* enum typedefs should be after enum */
|
||||
|
||||
struct amq_setopt {
|
||||
amq_opt as_opt;
|
||||
amq_string as_str;
|
||||
};
|
||||
|
||||
/*
|
||||
* EXTERNALS:
|
||||
*
|
||||
* external definitions for amqproc_*_1() have been moved off to private
|
||||
* headers in lib/amu.h, amd/amd.h, etc. They have to be private since the
|
||||
* same named functions appear in different places with different prototypes
|
||||
* an functionality.
|
||||
*/
|
||||
extern bool_t xdr_amq_mount_info(XDR *xdrs, amq_mount_info *objp);
|
||||
extern bool_t xdr_amq_mount_info_list(XDR *xdrs, amq_mount_info_list *objp);
|
||||
extern bool_t xdr_amq_mount_stats(XDR *xdrs, amq_mount_stats *objp);
|
||||
extern bool_t xdr_amq_mount_tree(XDR *xdrs, amq_mount_tree *objp);
|
||||
extern bool_t xdr_amq_mount_tree_list(XDR *xdrs, amq_mount_tree_list *objp);
|
||||
extern bool_t xdr_amq_mount_tree_p(XDR *xdrs, amq_mount_tree_p *objp);
|
||||
extern bool_t xdr_amq_opt(XDR *xdrs, amq_opt *objp);
|
||||
extern bool_t xdr_amq_setopt(XDR *xdrs, amq_setopt *objp);
|
||||
extern bool_t xdr_pri_free(XDRPROC_T_TYPE xdr_args, caddr_t args_ptr);
|
||||
extern bool_t xdr_time_type(XDR *xdrs, time_type *objp);
|
||||
|
||||
#endif /* not _AMQ_DEFS_H */
|
211
usr.sbin/amd/include/amu_nfs_prot.h
Normal file
211
usr.sbin/amd/include/amu_nfs_prot.h
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: amu_nfs_prot.h,v 1.1.1.1 1997/07/24 21:20:15 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AMU_NFS_PROT_H
|
||||
#define _AMU_NFS_PROT_H
|
||||
|
||||
#ifdef HAVE_RPCSVC_NFS_PROT_H
|
||||
# include <rpcsvc/nfs_prot.h>
|
||||
#endif /* HAVE_RPCSVC_NFS_PROT_H */
|
||||
#ifdef HAVE_NFS_RPCV2_H
|
||||
# include <nfs/rpcv2.h>
|
||||
#endif /* HAVE_NFS_RPCV2_H */
|
||||
|
||||
#ifndef NFS_NPROCS
|
||||
# define NFS_NPROCS 26
|
||||
#endif /* not NFS_NPROCS */
|
||||
#ifdef HAVE_NFS_NFS_H
|
||||
# include <nfs/nfs.h>
|
||||
#endif /* HAVE_NFS_NFS_H */
|
||||
|
||||
|
||||
/*
|
||||
* MACROS:
|
||||
*/
|
||||
#define dr_drok_u diropres
|
||||
#define ca_where where
|
||||
#define da_fhandle dir
|
||||
#define da_name name
|
||||
#define dl_entries entries
|
||||
#define dl_eof eof
|
||||
#define dr_status status
|
||||
#define dr_u diropres_u
|
||||
#define drok_attributes attributes
|
||||
#define drok_fhandle file
|
||||
#define fh_data data
|
||||
#define la_fhandle from
|
||||
#define la_to to
|
||||
#define na_atime atime
|
||||
#define na_ctime ctime
|
||||
#define na_fileid fileid
|
||||
#define na_fsid fsid
|
||||
#define na_mode mode
|
||||
#define na_mtime mtime
|
||||
#define na_nlink nlink
|
||||
#define na_size size
|
||||
#define na_type type
|
||||
#define ne_cookie cookie
|
||||
#define ne_fileid fileid
|
||||
#define ne_name name
|
||||
#define ne_nextentry nextentry
|
||||
#define ns_attr_u attributes
|
||||
#define ns_status status
|
||||
#define ns_u attrstat_u
|
||||
#define nt_seconds seconds
|
||||
#define nt_useconds useconds
|
||||
#define rda_cookie cookie
|
||||
#define rda_count count
|
||||
#define rda_fhandle dir
|
||||
#define rdr_reply_u reply
|
||||
#define rdr_status status
|
||||
#define rdr_u readdirres_u
|
||||
#define rlr_data_u data
|
||||
#define rlr_status status
|
||||
#define rlr_u readlinkres_u
|
||||
#define rna_from from
|
||||
#define rna_to to
|
||||
#define rr_status status
|
||||
#define sag_fhandle file
|
||||
#define sfr_reply_u reply
|
||||
#define sfr_status status
|
||||
#define sfr_u statfsres_u
|
||||
#define sfrok_bavail bavail
|
||||
#define sfrok_bfree bfree
|
||||
#define sfrok_blocks blocks
|
||||
#define sfrok_bsize bsize
|
||||
#define sfrok_tsize tsize
|
||||
#define sla_from from
|
||||
#define wra_fhandle file
|
||||
|
||||
|
||||
/*
|
||||
* TYPEDEFS:
|
||||
*/
|
||||
typedef attrstat nfsattrstat;
|
||||
typedef createargs nfscreateargs;
|
||||
typedef dirlist nfsdirlist;
|
||||
typedef diropargs nfsdiropargs;
|
||||
typedef diropres nfsdiropres;
|
||||
typedef entry nfsentry;
|
||||
typedef fattr nfsfattr;
|
||||
typedef ftype nfsftype;
|
||||
typedef linkargs nfslinkargs;
|
||||
typedef readargs nfsreadargs;
|
||||
typedef readdirargs nfsreaddirargs;
|
||||
typedef readdirres nfsreaddirres;
|
||||
typedef readlinkres nfsreadlinkres;
|
||||
typedef readres nfsreadres;
|
||||
typedef renameargs nfsrenameargs;
|
||||
typedef sattrargs nfssattrargs;
|
||||
typedef statfsokres nfsstatfsokres;
|
||||
typedef statfsres nfsstatfsres;
|
||||
typedef symlinkargs nfssymlinkargs;
|
||||
typedef writeargs nfswriteargs;
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* NetBSD 1.2 has NFS V3, but it is undefined in the header files.
|
||||
* so I define everything that's neede for NFS V3 here.
|
||||
*/
|
||||
#ifdef NFSMNT_NFSV3
|
||||
|
||||
# define MOUNT_NFS3 MOUNT_NFS
|
||||
# define MNTOPT_NFS3 "nfs"
|
||||
|
||||
#define FHSIZE3 64 /* size in bytes of a file handle (v3) */
|
||||
#define NFS3_FHSIZE 64
|
||||
#define MOUNTVERS3 ((unsigned long)(3))
|
||||
#define NFS_V3 ((unsigned long)(3))
|
||||
|
||||
typedef struct {
|
||||
u_int fhandle3_len;
|
||||
char *fhandle3_val;
|
||||
} fhandle3;
|
||||
|
||||
enum mountstat3 {
|
||||
MNT3_OK = 0,
|
||||
MNT3ERR_PERM = 1,
|
||||
MNT3ERR_NOENT = 2,
|
||||
MNT3ERR_IO = 5,
|
||||
MNT3ERR_ACCES = 13,
|
||||
MNT3ERR_NOTDIR = 20,
|
||||
MNT3ERR_INVAL = 22,
|
||||
MNT3ERR_NAMETOOLONG = 63,
|
||||
MNT3ERR_NOTSUPP = 10004,
|
||||
MNT3ERR_SERVERFAULT = 10006
|
||||
};
|
||||
typedef enum mountstat3 mountstat3;
|
||||
|
||||
struct mountres3_ok {
|
||||
fhandle3 fhandle;
|
||||
struct {
|
||||
u_int auth_flavors_len;
|
||||
int *auth_flavors_val;
|
||||
} auth_flavors;
|
||||
};
|
||||
typedef struct mountres3_ok mountres3_ok;
|
||||
|
||||
struct mountres3 {
|
||||
mountstat3 fhs_status;
|
||||
union {
|
||||
mountres3_ok mountinfo;
|
||||
} mountres3_u;
|
||||
};
|
||||
typedef struct mountres3 mountres3;
|
||||
|
||||
struct nfs_fh3 {
|
||||
u_int fh3_length;
|
||||
union nfs_fh3_u {
|
||||
struct nfs_fh3_i {
|
||||
fhandle_t fh3_i;
|
||||
} nfs_fh3_i;
|
||||
char data[NFS3_FHSIZE];
|
||||
} fh3_u;
|
||||
};
|
||||
typedef struct nfs_fh3 nfs_fh3;
|
||||
|
||||
#endif /* NFSMNT_NFSV3 */
|
||||
|
||||
#endif /* not _AMU_NFS_PROT_H */
|
69
usr.sbin/amd/include/aux_conf.h
Normal file
69
usr.sbin/amd/include/aux_conf.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* aux_conf.h:
|
||||
* This file gets "filled in" for each architecture.
|
||||
* Generated automatically from aux_conf.h.in by configure.
|
||||
*/
|
||||
|
||||
#ifndef _AUX_CONF_H
|
||||
#define _AUX_CONF_H
|
||||
|
||||
/*
|
||||
* The next line is a literal inclusion of a file which includes a
|
||||
* definition for the MOUNT_TRAP macro for a particular architecture.
|
||||
* If it defines the wrong entry, check the AC_CHECK_MOUNT_TRAP m4 macro
|
||||
* in $srcdir/aux/macros.
|
||||
*/
|
||||
|
||||
/* $srcdir/conf/trap/trap_default.h */
|
||||
#define MOUNT_TRAP(type, mnt, flags, mnt_data) mount(type, mnt->mnt_dir, flags, mnt_data)
|
||||
/* End of included MOUNT_TRAP macro definition file */
|
||||
|
||||
/*
|
||||
* The next line is a literal replacement of a variable which defines the
|
||||
* the UNMOUNT_TRAP macro for a particular architecture.
|
||||
* If it defines the wrong entry, check the AC_CHECK_UNMOUNT_CALL m4 macro
|
||||
* in $srcdir/aclocal.m4. If the arguments are being defined wrong, check
|
||||
* the macro AC_CHECK_UNMOUNT_ARGS in $srcdir/aux/macros.
|
||||
*/
|
||||
#define UNMOUNT_TRAP(mnt) unmount(mnt->mnt_dir)
|
||||
/* End of replaced UNMOUNT_TRAP macro definition */
|
||||
|
||||
/*
|
||||
* The next line is a literal inclusion of a file which includes a
|
||||
* definition for the NFS_FH_DREF macro for a particular architecture.
|
||||
* If it defines the wrong entry, check the AC_CHECK_NFS_FH_DREF m4 macro
|
||||
* in $srcdir/aux/macros.
|
||||
*/
|
||||
|
||||
/* $srcdir/conf/fh_dref/fh_dref_freebsd22.h */
|
||||
#define NFS_FH_DREF(dst, src) (dst) = (u_char *) (src)
|
||||
/* End of included NFS_FH_DREF macro definition file */
|
||||
|
||||
/*
|
||||
* The next line is a literal inclusion of a file which includes a
|
||||
* definition for the NFS_SA_DREF macro for a particular architecture.
|
||||
* If it defines the wrong entry, check the AC_CHECK_NFS_SA_DREF m4 macro
|
||||
* in $srcdir/aux/macros.
|
||||
*/
|
||||
|
||||
/* $srcdir/conf/sa_dref/sa_dref_bsd44.h */
|
||||
#define NFS_SA_DREF(dst, src) { \
|
||||
(dst).addr = (struct sockaddr *) (src); \
|
||||
(dst).addrlen = sizeof(*src); \
|
||||
(dst).sotype = SOCK_DGRAM; \
|
||||
(dst).proto = 0; \
|
||||
}
|
||||
/* End of included NFS_SA_DREF macro definition file */
|
||||
|
||||
/*
|
||||
* The next line is a literal inclusion of a file which includes a
|
||||
* definition for the NFS_HN_DREF macro for a particular architecture.
|
||||
* If it defines the wrong entry, check the AC_CHECK_NFS_HN_DREF m4 macro
|
||||
* in $srcdir/aux/macros.
|
||||
*/
|
||||
|
||||
/* $srcdir/conf/hn_dref/hn_dref_default.h */
|
||||
#define NFS_HN_DREF(dst, src) (dst) = (src)
|
||||
/* End of included NFS_HN_DREF macro definition file */
|
||||
|
||||
#endif /* not _AUX_CONF_H */
|
14
usr.sbin/amd/libamu/Makefile
Normal file
14
usr.sbin/amd/libamu/Makefile
Normal file
@ -0,0 +1,14 @@
|
||||
# $NetBSD: Makefile,v 1.1.1.1 1997/07/24 21:20:11 christos Exp $
|
||||
|
||||
LIB= amu
|
||||
SRCS= mtabutil.c tranputil.c umount_fs.c xutil.c xdr_mountres3.c wire.c \
|
||||
util.c nfs_prot_xdr.c mtab.c mount_fs.c misc_rpc.c hasmntopt.c
|
||||
|
||||
config_local.h: mkconf
|
||||
@rm -f ${.TARGET}
|
||||
sh ${.ALLSRC} > ${.TARGET}
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
LDADD=
|
||||
DPADD=
|
||||
${OBJS}: config_local.h
|
78
usr.sbin/amd/libamu/amu.h
Normal file
78
usr.sbin/amd/libamu/amu.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: amu.h,v 1.1.1.1 1997/07/24 21:20:10 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AMU_H
|
||||
#define _AMU_H
|
||||
|
||||
/*
|
||||
* Decide what maximum level of NFS server to try and mount with.
|
||||
*/
|
||||
#ifdef HAVE_FS_NFS3
|
||||
# define NFS_VERS_MAX NFS_VERSION3
|
||||
#else /* not HAVE_FS_NFS3 */
|
||||
# define NFS_VERS_MAX NFS_VERSION
|
||||
#endif /* not HAVE_FS_NFS3 */
|
||||
|
||||
/* some systems like ncr2 do not define this in <rpcsvc/mount.h> */
|
||||
#ifndef MNTPATHLEN
|
||||
# define MNTPATHLEN 1024
|
||||
#endif /* not MNTPATHLEN */
|
||||
#ifndef MNTNAMLEN
|
||||
# define MNTNAMLEN 255
|
||||
#endif /* not MNTNAMLEN */
|
||||
|
||||
/*
|
||||
* external definitions for building libamu.a
|
||||
*/
|
||||
extern voidp amqproc_null_1(voidp argp, CLIENT *rqstp);
|
||||
extern amq_mount_tree_p *amqproc_mnttree_1(amq_string *argp, CLIENT *rqstp);
|
||||
extern voidp amqproc_umnt_1(amq_string *argp, CLIENT *rqstp);
|
||||
extern amq_mount_stats *amqproc_stats_1(voidp argp, CLIENT *rqstp);
|
||||
extern amq_mount_tree_list *amqproc_export_1(voidp argp, CLIENT *rqstp);
|
||||
extern int *amqproc_setopt_1(amq_setopt *argp, CLIENT *rqstp);
|
||||
extern amq_mount_info_list *amqproc_getmntfs_1(voidp argp, CLIENT *rqstp);
|
||||
extern int *amqproc_mount_1(voidp argp, CLIENT *rqstp);
|
||||
extern amq_string *amqproc_getvers_1(voidp argp, CLIENT *rqstp);
|
||||
|
||||
#endif /* not _AMU_H */
|
18
usr.sbin/amd/libamu/config_local.h
Normal file
18
usr.sbin/amd/libamu/config_local.h
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
/* Define user name */
|
||||
#define USER_NAME "christos"
|
||||
|
||||
/* Define configuration date */
|
||||
#define CONFIG_DATE "Thu Jul 24 12:25:26 EDT 1997"
|
||||
|
||||
/* Define name of host */
|
||||
#define HOST_NAME "borken.nyc.deshaw.com"
|
||||
|
||||
/* Define only version of host machine (eg. 2.5.1) */
|
||||
#define HOST_OS_VERSION "1.2G"
|
||||
|
||||
/* Define only name of host machine OS (eg. solaris2) */
|
||||
#define HOST_OS_NAME "netbsd1"
|
||||
|
||||
#define HOST_OS "netbsd1.2G"
|
||||
|
119
usr.sbin/amd/libamu/hasmntopt.c
Normal file
119
usr.sbin/amd/libamu/hasmntopt.c
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
n * modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: hasmntopt.c,v 1.1.1.1 1997/07/24 21:20:07 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
#ifndef MNTMAXSTR
|
||||
# define MNTMAXSTR 128
|
||||
#endif /* not MNTMAXSTR */
|
||||
|
||||
|
||||
/*
|
||||
* Some systems don't provide these to the user,
|
||||
* but amd needs them, so...
|
||||
*
|
||||
* From: Piete Brooks <pb@cl.cam.ac.uk>
|
||||
*/
|
||||
|
||||
static char *
|
||||
nextmntopt(char **p)
|
||||
{
|
||||
char *cp = *p;
|
||||
char *rp;
|
||||
|
||||
/*
|
||||
* Skip past white space
|
||||
*/
|
||||
while (*cp && isspace(*cp))
|
||||
cp++;
|
||||
|
||||
/*
|
||||
* Word starts here
|
||||
*/
|
||||
rp = cp;
|
||||
|
||||
/*
|
||||
* Scan to send of string or separator
|
||||
*/
|
||||
while (*cp && *cp != ',')
|
||||
cp++;
|
||||
|
||||
/*
|
||||
* If separator found the overwrite with nul char.
|
||||
*/
|
||||
if (*cp) {
|
||||
*cp = '\0';
|
||||
cp++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return value for next call
|
||||
*/
|
||||
*p = cp;
|
||||
return rp;
|
||||
}
|
||||
|
||||
/*
|
||||
* replacement for hasmntopt if the system does not have it.
|
||||
*/
|
||||
char *
|
||||
hasmntopt(mntent_t *mnt, char *opt)
|
||||
{
|
||||
char t[MNTMAXSTR];
|
||||
char *f;
|
||||
char *o = t;
|
||||
int l = strlen(opt);
|
||||
|
||||
strcpy(t, mnt->mnt_opts);
|
||||
|
||||
while (*(f = nextmntopt(&o)))
|
||||
if (strncmp(opt, f, l) == 0)
|
||||
return f - t + mnt->mnt_opts;
|
||||
|
||||
return 0;
|
||||
}
|
168
usr.sbin/amd/libamu/misc_rpc.c
Normal file
168
usr.sbin/amd/libamu/misc_rpc.c
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: misc_rpc.c,v 1.1.1.1 1997/07/24 21:20:07 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Additions to Sun RPC.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
/*
|
||||
* Some systems renamed _seterr_reply to __seterr_reply (with two
|
||||
* leading underscores)
|
||||
*/
|
||||
#if !defined(HAVE__SETERR_REPLY) && defined(HAVE___SETERR_REPLY)
|
||||
# define _seterr_reply __seterr_reply
|
||||
#endif /* !defined(HAVE__SETERR_REPLY) && defined(HAVE___SETERR_REPLY) */
|
||||
|
||||
|
||||
void
|
||||
rpc_msg_init(struct rpc_msg *mp, u_long prog, u_long vers, u_long proc)
|
||||
{
|
||||
/*
|
||||
* Initialise the message
|
||||
*/
|
||||
memset((voidp) mp, 0, sizeof(*mp));
|
||||
mp->rm_xid = 0;
|
||||
mp->rm_direction = CALL;
|
||||
mp->rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||
mp->rm_call.cb_prog = prog;
|
||||
mp->rm_call.cb_vers = vers;
|
||||
mp->rm_call.cb_proc = proc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Field reply to call to mountd
|
||||
*/
|
||||
int
|
||||
pickup_rpc_reply(voidp pkt, int len, voidp where, XDRPROC_T_TYPE where_xdr)
|
||||
{
|
||||
XDR reply_xdr;
|
||||
int ok;
|
||||
struct rpc_err err;
|
||||
struct rpc_msg reply_msg;
|
||||
int error = 0;
|
||||
|
||||
/* memset((voidp) &err, 0, sizeof(err)); */
|
||||
memset((voidp) &reply_msg, 0, sizeof(reply_msg));
|
||||
memset((voidp) &reply_xdr, 0, sizeof(reply_xdr));
|
||||
|
||||
reply_msg.acpted_rply.ar_results.where = (caddr_t) where;
|
||||
reply_msg.acpted_rply.ar_results.proc = where_xdr;
|
||||
|
||||
xdrmem_create(&reply_xdr, pkt, len, XDR_DECODE);
|
||||
|
||||
ok = xdr_replymsg(&reply_xdr, &reply_msg);
|
||||
if (!ok) {
|
||||
error = EIO;
|
||||
goto drop;
|
||||
}
|
||||
_seterr_reply(&reply_msg, &err);
|
||||
if (err.re_status != RPC_SUCCESS) {
|
||||
error = EIO;
|
||||
goto drop;
|
||||
}
|
||||
|
||||
drop:
|
||||
if (reply_msg.rm_reply.rp_stat == MSG_ACCEPTED &&
|
||||
reply_msg.acpted_rply.ar_verf.oa_base) {
|
||||
reply_xdr.x_op = XDR_FREE;
|
||||
(void) xdr_opaque_auth(&reply_xdr,
|
||||
&reply_msg.acpted_rply.ar_verf);
|
||||
}
|
||||
xdr_destroy(&reply_xdr);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
make_rpc_packet(char *buf, int buflen, u_long proc, struct rpc_msg *mp, voidp arg, XDRPROC_T_TYPE arg_xdr, AUTH *auth)
|
||||
{
|
||||
XDR msg_xdr;
|
||||
int len;
|
||||
|
||||
xdrmem_create(&msg_xdr, buf, buflen, XDR_ENCODE);
|
||||
|
||||
/*
|
||||
* Basic protocol header
|
||||
*/
|
||||
if (!xdr_callhdr(&msg_xdr, mp))
|
||||
return -EIO;
|
||||
|
||||
/*
|
||||
* Called procedure number
|
||||
*/
|
||||
if (!xdr_enum(&msg_xdr, (enum_t *) & proc))
|
||||
return -EIO;
|
||||
|
||||
/*
|
||||
* Authorization
|
||||
*/
|
||||
if (!AUTH_MARSHALL(auth, &msg_xdr))
|
||||
return -EIO;
|
||||
|
||||
/*
|
||||
* Arguments
|
||||
*/
|
||||
if (!(*arg_xdr) (&msg_xdr, arg))
|
||||
return -EIO;
|
||||
|
||||
/*
|
||||
* Determine length
|
||||
*/
|
||||
len = xdr_getpos(&msg_xdr);
|
||||
|
||||
/*
|
||||
* Throw away xdr
|
||||
*/
|
||||
xdr_destroy(&msg_xdr);
|
||||
|
||||
return len;
|
||||
}
|
24
usr.sbin/amd/libamu/mkconf
Normal file
24
usr.sbin/amd/libamu/mkconf
Normal file
@ -0,0 +1,24 @@
|
||||
# $NetBSD: mkconf,v 1.1.1.1 1997/07/24 21:20:12 christos Exp $
|
||||
# mkconf
|
||||
# Generate local configuration parameters for amd
|
||||
#
|
||||
cat << __EOF
|
||||
|
||||
/* Define user name */
|
||||
#define USER_NAME "`whoami`"
|
||||
|
||||
/* Define configuration date */
|
||||
#define CONFIG_DATE "`date`"
|
||||
|
||||
/* Define name of host */
|
||||
#define HOST_NAME "`hostname`"
|
||||
|
||||
/* Define only version of host machine (eg. 2.5.1) */
|
||||
#define HOST_OS_VERSION "`uname -r`"
|
||||
|
||||
/* Define only name of host machine OS (eg. solaris2) */
|
||||
#define HOST_OS_NAME "`uname -s | tr '[A-Z]' '[a-z]'``uname -r | cut -d. -f 1`"
|
||||
|
||||
#define HOST_OS "`uname -s | tr '[A-Z]' '[a-z]'``uname -r`"
|
||||
|
||||
__EOF
|
290
usr.sbin/amd/libamu/mount_fs.c
Normal file
290
usr.sbin/amd/libamu/mount_fs.c
Normal file
@ -0,0 +1,290 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: mount_fs.c,v 1.1.1.1 1997/07/24 21:20:08 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
|
||||
/* ensure that mount table options are delimited by a comma */
|
||||
#define append_opts(old, new) { \
|
||||
if (*(old) != '\0') strcat(old, ","); \
|
||||
strcat(old, new); }
|
||||
|
||||
/*
|
||||
* Standard mount flags
|
||||
*/
|
||||
struct opt_tab mnt_flags[] =
|
||||
{
|
||||
#if defined(MNT2_GEN_OPT_RDONLY) && defined(MNTTAB_OPT_RO)
|
||||
{MNTTAB_OPT_RO, MNT2_GEN_OPT_RDONLY},
|
||||
#endif /* defined(MNT2_GEN_OPT_RDONLY) && defined(MNTTAB_OPT_RO) */
|
||||
|
||||
#if defined(MNT2_GEN_OPT_NOCACHE) && defined(MNTTAB_OPT_NOCACHE)
|
||||
{MNTTAB_OPT_NOCACHE, MNT2_GEN_OPT_NOCACHE},
|
||||
#endif /* defined(MNT2_GEN_OPT_NOCACHE) && defined(MNTTAB_OPT_NOCACHE) */
|
||||
|
||||
#if defined(MNT2_GEN_OPT_GRPID) && defined(MNTTAB_OPT_GRPID)
|
||||
{MNTTAB_OPT_GRPID, MNT2_GEN_OPT_GRPID},
|
||||
#endif /* defined(MNT2_GEN_OPT_GRPID) && defined(MNTTAB_OPT_GRPID) */
|
||||
|
||||
#if defined(MNT2_GEN_OPT_MULTI) && defined(MNTTAB_OPT_MULTI)
|
||||
{MNTTAB_OPT_MULTI, MNT2_GEN_OPT_MULTI},
|
||||
#endif /* defined(MNT2_GEN_OPT_MULTI) && defined(MNTTAB_OPT_MULTI) */
|
||||
|
||||
#if defined(MNT2_GEN_OPT_NODEV) && defined(MNTTAB_OPT_NODEV)
|
||||
{MNTTAB_OPT_NODEV, MNT2_GEN_OPT_NODEV},
|
||||
#endif /* defined(MNT2_GEN_OPT_NODEV) && defined(MNTTAB_OPT_NODEV) */
|
||||
|
||||
#if defined(MNT2_GEN_OPT_NOEXEC) && defined(MNTTAB_OPT_NOEXEC)
|
||||
{MNTTAB_OPT_NOEXEC, MNT2_GEN_OPT_NOEXEC},
|
||||
#endif /* defined(MNT2_GEN_OPT_NOEXEC) && defined(MNTTAB_OPT_NOEXEC) */
|
||||
|
||||
#if defined(MNT2_GEN_OPT_NOSUB) && defined(MNTTAB_OPT_NOSUB)
|
||||
{MNTTAB_OPT_NOSUB, MNT2_GEN_OPT_NOSUB},
|
||||
#endif /* defined(MNT2_GEN_OPT_NOSUB) && defined(MNTTAB_OPT_NOSUB) */
|
||||
|
||||
#if defined(MNT2_GEN_OPT_NOSUID) && defined(MNTTAB_OPT_NOSUID)
|
||||
{MNTTAB_OPT_NOSUID, MNT2_GEN_OPT_NOSUID},
|
||||
#endif /* defined(MNT2_GEN_OPT_NOSUID) && defined(MNTTAB_OPT_NOSUID) */
|
||||
|
||||
#if defined(MNT2_GEN_OPT_SYNC) && defined(MNTTAB_OPT_SYNC)
|
||||
{MNTTAB_OPT_SYNC, MNT2_GEN_OPT_SYNC},
|
||||
#endif /* defined(MNT2_GEN_OPT_SYNC) && defined(MNTTAB_OPT_SYNC) */
|
||||
|
||||
#if defined(MNT2_GEN_OPT_OVERLAY) && defined(MNTTAB_OPT_OVERLAY)
|
||||
{MNTTAB_OPT_OVERLAY, MNT2_GEN_OPT_OVERLAY},
|
||||
#endif /* defined(MNT2_GEN_OPT_OVERLAY) && defined(MNTTAB_OPT_OVERLAY) */
|
||||
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
compute_mount_flags(mntent_t *mnt)
|
||||
{
|
||||
struct opt_tab *opt;
|
||||
int flags;
|
||||
|
||||
#ifdef MNT2_GEN_OPT_NEWTYPE
|
||||
flags = MNT2_GEN_OPT_NEWTYPE;
|
||||
#else /* not MNT2_GEN_OPT_NEWTYPE */
|
||||
/* Not all machines have MNT2_GEN_OPT_NEWTYPE (HP-UX 9.01) */
|
||||
flags = 0;
|
||||
#endif /* not MNT2_GEN_OPT_NEWTYPE */
|
||||
|
||||
/*
|
||||
* Crack basic mount options
|
||||
*/
|
||||
for (opt = mnt_flags; opt->opt; opt++)
|
||||
flags |= hasmntopt(mnt, opt->opt) ? opt->flag : 0;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, u_long nfs_version, const char *nfs_proto)
|
||||
{
|
||||
int error = 0;
|
||||
#if defined(MNTTAB_OPT_DEV) || defined(MNTTAB_OPT_FSID)
|
||||
struct stat stb;
|
||||
#endif /* defined(MNTTAB_OPT_DEV) || defined(MNTTAB_OPT_FSID) */
|
||||
#ifdef MOUNT_TABLE_ON_FILE
|
||||
char *zopts = NULL, *xopts = NULL;
|
||||
# if defined(MNTTAB_OPT_DEV) || defined(HAVE_FS_NFS3) || defined(MNTTAB_OPT_VERS) || defined(MNTTAB_OPT_PROTO)
|
||||
char optsbuf[48];
|
||||
# endif /* defined(MNTTAB_OPT_DEV) || defined(HAVE_FS_NFS3) || defined(MNTTAB_OPT_VERS) || defined(MNTTAB_OPT_PROTO) */
|
||||
#endif /* MOUNT_TABLE_ON_FILE */
|
||||
#ifdef DEBUG
|
||||
char buf[80]; /* buffer for sprintf */
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifdef DEBUG
|
||||
sprintf(buf, "%s%s%s",
|
||||
"%s fstype ", MTYPE_PRINTF_TYPE, " (%s) flags %#x (%s)");
|
||||
dlog(buf, mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);
|
||||
#endif /* DEBUG */
|
||||
|
||||
again:
|
||||
clock_valid = 0;
|
||||
|
||||
error = MOUNT_TRAP(type, mnt, flags, mnt_data);
|
||||
|
||||
if (error < 0) {
|
||||
plog(XLOG_ERROR, "%s: mount: %m", mnt->mnt_dir);
|
||||
/*
|
||||
* The following code handles conditions which shouldn't
|
||||
* occur. They are possible either because amd screws up
|
||||
* in preparing for the mount, or because some human
|
||||
* messed with the mount point. Both have been known to
|
||||
* happen. -- stolcke 2/22/95
|
||||
*/
|
||||
if (errno == ENOENT) {
|
||||
/*
|
||||
* Occasionally the mount point vanishes, probably
|
||||
* due to some race condition. Just recreate it
|
||||
* as necessary.
|
||||
*/
|
||||
errno = mkdirs(mnt->mnt_dir, 0555);
|
||||
if (errno != 0 && errno != EEXIST)
|
||||
plog(XLOG_ERROR, "%s: mkdirs: %m", mnt->mnt_dir);
|
||||
else {
|
||||
plog(XLOG_WARNING, "extra mkdirs required for %s",
|
||||
mnt->mnt_dir);
|
||||
error = MOUNT_TRAP(type, mnt, flags, mnt_data);
|
||||
}
|
||||
} else if (errno == EBUSY) {
|
||||
/*
|
||||
* Also, sometimes unmount isn't called, e.g., because
|
||||
* our mountlist is garbled. This leaves old mount
|
||||
* points around which need to be removed before we
|
||||
* can mount something new in their place.
|
||||
*/
|
||||
errno = umount_fs(mnt->mnt_dir);
|
||||
if (errno != 0)
|
||||
plog(XLOG_ERROR, "%s: umount: %m", mnt->mnt_dir);
|
||||
else {
|
||||
plog(XLOG_WARNING, "extra umount required for %s",
|
||||
mnt->mnt_dir);
|
||||
error = MOUNT_TRAP(type, mnt, flags, mnt_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error < 0 && --retry > 0) {
|
||||
sleep(1);
|
||||
goto again;
|
||||
}
|
||||
if (error < 0) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
#ifdef MOUNT_TABLE_ON_FILE
|
||||
/*
|
||||
* Allocate memory for options:
|
||||
* dev=..., vers={2,3}, proto={tcp,udp}
|
||||
*/
|
||||
zopts = (char *) xmalloc(strlen(mnt->mnt_opts) + 48);
|
||||
|
||||
/* copy standard options */
|
||||
xopts = mnt->mnt_opts;
|
||||
|
||||
strcpy(zopts, xopts);
|
||||
|
||||
# ifdef MNTTAB_OPT_DEV
|
||||
/* add the extra dev= field to the mount table */
|
||||
if (lstat(mnt->mnt_dir, &stb) == 0) {
|
||||
if (sizeof(stb.st_dev) == 2) /* e.g. SunOS 4.1 */
|
||||
sprintf(optsbuf, "%s=%04lx",
|
||||
MNTTAB_OPT_DEV, (u_long) stb.st_dev & 0xffff);
|
||||
else /* e.g. System Vr4 */
|
||||
sprintf(optsbuf, "%s=%08lx",
|
||||
MNTTAB_OPT_DEV, (u_long) stb.st_dev);
|
||||
append_opts(zopts, optsbuf);
|
||||
}
|
||||
# endif /* MNTTAB_OPT_DEV */
|
||||
|
||||
# if defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS)
|
||||
/*
|
||||
* add the extra vers={2,3} field to the mount table,
|
||||
* unless already specified by user
|
||||
*/
|
||||
if (nfs_version == NFS_VERSION3 &&
|
||||
hasmntval(mnt, MNTTAB_OPT_VERS) != NFS_VERSION3) {
|
||||
sprintf(optsbuf, "%s=%d", MNTTAB_OPT_VERS, NFS_VERSION3);
|
||||
append_opts(zopts, optsbuf);
|
||||
}
|
||||
# endif /* defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS) */
|
||||
|
||||
# ifdef MNTTAB_OPT_PROTO
|
||||
/*
|
||||
* add the extra proto={tcp,udp} field to the mount table,
|
||||
* unless already specified by user.
|
||||
*/
|
||||
if (nfs_proto && !hasmntopt(mnt, MNTTAB_OPT_PROTO)) {
|
||||
sprintf(optsbuf, "%s=%s", MNTTAB_OPT_PROTO, nfs_proto);
|
||||
append_opts(zopts, optsbuf);
|
||||
}
|
||||
# endif /* MNTTAB_OPT_PROTO */
|
||||
|
||||
/* finally, store the options into the mount table structure */
|
||||
mnt->mnt_opts = zopts;
|
||||
|
||||
/*
|
||||
* Additional fields in mntent_t
|
||||
* are fixed up here
|
||||
*/
|
||||
# ifdef HAVE_FIELD_MNTENT_T_CNODE
|
||||
mnt->mnt_cnode = 0;
|
||||
# endif /* HAVE_FIELD_MNTENT_T_CNODE */
|
||||
# ifdef HAVE_FIELD_MNTENT_T_RO
|
||||
mnt->mnt_ro = (hasmntopt(mnt, MNTTAB_OPT_RO) != NULL);
|
||||
# endif /* HAVE_FIELD_MNTENT_T_RO */
|
||||
# ifdef HAVE_FIELD_MNTENT_T_TIME
|
||||
# ifdef HAVE_FIELD_MNTENT_T_TIME_STRING
|
||||
{ /* allocate enough space for a long */
|
||||
char *str = (char *) xmalloc(13 * sizeof(char));
|
||||
sprintf(str, "%ld", time((time_t *) NULL));
|
||||
mnt->mnt_time = str;
|
||||
}
|
||||
# else /* not HAVE_FIELD_MNTENT_T_TIME_STRING */
|
||||
mnt->mnt_time = time((time_t *) NULL);
|
||||
# endif /* not HAVE_FIELD_MNTENT_T_TIME_STRING */
|
||||
# endif /* HAVE_FIELD_MNTENT_T_TIME */
|
||||
|
||||
write_mntent(mnt);
|
||||
|
||||
# ifdef MNTTAB_OPT_DEV
|
||||
if (xopts) {
|
||||
free(mnt->mnt_opts);
|
||||
mnt->mnt_opts = xopts;
|
||||
}
|
||||
# endif /* MNTTAB_OPT_DEV */
|
||||
#endif /* MOUNT_TABLE_ON_FILE */
|
||||
|
||||
return 0;
|
||||
}
|
121
usr.sbin/amd/libamu/mtab.c
Normal file
121
usr.sbin/amd/libamu/mtab.c
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1989 Jan-Simon Pendry
|
||||
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: mtab.c,v 1.1.1.1 1997/07/24 21:20:08 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
|
||||
/*
|
||||
* Firewall /etc/mtab entries
|
||||
*/
|
||||
void
|
||||
mnt_free(mntent_t *mp)
|
||||
{
|
||||
free(mp->mnt_fsname);
|
||||
free(mp->mnt_dir);
|
||||
free(mp->mnt_type);
|
||||
free(mp->mnt_opts);
|
||||
|
||||
#ifdef HAVE_FIELD_MNTENT_T_TIME
|
||||
# ifdef HAVE_FIELD_MNTENT_T_TIME_STRING
|
||||
free(mp->mnt_time);
|
||||
# endif /* HAVE_FIELD_MNTENT_T_TIME_STRING */
|
||||
#endif /* HAVE_FIELD_MNTENT_T_TIME */
|
||||
|
||||
free((voidp) mp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Discard memory allocated for mount list
|
||||
*/
|
||||
void
|
||||
discard_mntlist(mntlist *mp)
|
||||
{
|
||||
mntlist *mp2;
|
||||
|
||||
while ((mp2 = mp)) {
|
||||
mp = mp->mnext;
|
||||
if (mp2->mnt)
|
||||
mnt_free(mp2->mnt);
|
||||
free((voidp) mp2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Throw away a mount list
|
||||
*/
|
||||
void
|
||||
free_mntlist(mntlist *mp)
|
||||
{
|
||||
discard_mntlist(mp);
|
||||
#ifdef MOUNT_TABLE_ON_FILE
|
||||
unlock_mntlist();
|
||||
#endif /* MOUNT_TABLE_ON_FILE */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Utility routine which determines the value of a
|
||||
* numeric option in the mount options (such as port=%d).
|
||||
* Returns 0 if the option is not specified.
|
||||
*/
|
||||
int
|
||||
hasmntval(mntent_t *mnt, char *opt)
|
||||
{
|
||||
char *str = hasmntopt(mnt, opt);
|
||||
|
||||
if (str) {
|
||||
char *eq = strchr(str, '=');
|
||||
if (eq)
|
||||
return atoi(eq + 1);
|
||||
else
|
||||
plog(XLOG_USER, "bad numeric option \"%s\" in \"%s\"", opt, str);
|
||||
}
|
||||
return 0;
|
||||
}
|
145
usr.sbin/amd/libamu/mtabutil.c
Normal file
145
usr.sbin/amd/libamu/mtabutil.c
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: mtabutil.c,v 1.1.1.1 1997/07/24 21:20:11 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* BSD 4.4 systems don't write their mount tables on a file. Instead, they
|
||||
* use a (better) system where the kernel keeps this state, and you access
|
||||
* the mount tables via a known interface.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
|
||||
static mntent_t *
|
||||
mnt_dup(struct statfs *mp)
|
||||
{
|
||||
mntent_t *new_mp = ALLOC(mntent_t);
|
||||
char *ty;
|
||||
|
||||
new_mp->mnt_fsname = strdup(mp->f_mntfromname);
|
||||
new_mp->mnt_dir = strdup(mp->f_mntonname);
|
||||
|
||||
#ifdef HAVE_FIELD_STRUCT_STATFS_F_FSTYPENAME
|
||||
ty = mp->f_fstypename;
|
||||
#else /* not HAVE_FIELD_STRUCT_STATFS_F_FSTYPENAME */
|
||||
switch (mp->f_type) {
|
||||
|
||||
# if defined(MOUNT_UFS) && defined(MNTTAB_TYPE_UFS)
|
||||
case MOUNT_UFS:
|
||||
ty = MNTTAB_TYPE_UFS;
|
||||
break;
|
||||
# endif /* defined(MOUNT_UFS) && defined(MNTTAB_TYPE_UFS) */
|
||||
|
||||
# if defined(MOUNT_NFS) && defined(MNTTAB_TYPE_NFS)
|
||||
case MOUNT_NFS:
|
||||
ty = MNTTAB_TYPE_NFS;
|
||||
break;
|
||||
# endif /* defined(MOUNT_NFS) && defined(MNTTAB_TYPE_NFS) */
|
||||
|
||||
# if defined(MOUNT_MFS) && defined(MNTTAB_TYPE_MFS)
|
||||
case MOUNT_MFS:
|
||||
ty = MNTTAB_TYPE_MFS;
|
||||
break;
|
||||
# endif /* defined(MOUNT_MFS) && defined(MNTTAB_TYPE_MFS) */
|
||||
|
||||
default:
|
||||
ty = "unknown";
|
||||
|
||||
break;
|
||||
}
|
||||
#endif /* not HAVE_FIELD_STRUCT_STATFS_F_FSTYPENAME */
|
||||
|
||||
new_mp->mnt_type = strdup(ty);
|
||||
new_mp->mnt_opts = strdup("unset");
|
||||
new_mp->mnt_freq = 0;
|
||||
new_mp->mnt_passno = 0;
|
||||
|
||||
return new_mp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read a mount table into memory
|
||||
*/
|
||||
mntlist *
|
||||
read_mtab(char *fs)
|
||||
{
|
||||
mntlist **mpp, *mhp;
|
||||
struct statfs *mntbufp, *mntp;
|
||||
|
||||
int nloc = getmntinfo(&mntbufp, MNT_NOWAIT);
|
||||
|
||||
if (nloc == 0) {
|
||||
plog(XLOG_ERROR, "Can't read mount table");
|
||||
return 0;
|
||||
}
|
||||
mpp = &mhp;
|
||||
for (mntp = mntbufp; mntp < mntbufp + nloc; mntp++) {
|
||||
/*
|
||||
* Allocate a new slot
|
||||
*/
|
||||
*mpp = ALLOC(struct mntlist);
|
||||
|
||||
/*
|
||||
* Copy the data returned by getmntent
|
||||
*/
|
||||
(*mpp)->mnt = mnt_dup(mntp);
|
||||
|
||||
/*
|
||||
* Move to next pointer
|
||||
*/
|
||||
mpp = &(*mpp)->mnext;
|
||||
}
|
||||
|
||||
/*
|
||||
* Terminate the list
|
||||
*/
|
||||
*mpp = 0;
|
||||
|
||||
return mhp;
|
||||
}
|
59
usr.sbin/amd/libamu/nfs_prot_xdr.c
Normal file
59
usr.sbin/amd/libamu/nfs_prot_xdr.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1989 Jan-Simon Pendry
|
||||
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: nfs_prot_xdr.c,v 1.1.1.1 1997/07/24 21:20:08 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_amq_string(XDR *xdrs, amq_string *objp)
|
||||
{
|
||||
if (!xdr_string(xdrs, objp, AMQ_STRLEN)) {
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
2
usr.sbin/amd/libamu/shlib_version
Normal file
2
usr.sbin/amd/libamu/shlib_version
Normal file
@ -0,0 +1,2 @@
|
||||
major=0
|
||||
minor=0
|
329
usr.sbin/amd/libamu/tranputil.c
Normal file
329
usr.sbin/amd/libamu/tranputil.c
Normal file
@ -0,0 +1,329 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: tranputil.c,v 1.1.1.1 1997/07/24 21:20:10 christos Exp $
|
||||
*
|
||||
* Socket specific utilities.
|
||||
* -Erez Zadok <ezk@cs.columbia.edu>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
|
||||
/*
|
||||
* find the IP address that can be used to connect to the local host
|
||||
*/
|
||||
void
|
||||
amu_get_myaddress(struct in_addr *iap)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
|
||||
memset((char *) &sin, 0, sizeof(sin));
|
||||
get_myaddress(&sin);
|
||||
iap->s_addr = sin.sin_addr.s_addr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* How to bind to reserved ports.
|
||||
*/
|
||||
int
|
||||
bind_resv_port(int so, u_short *pp)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int rc;
|
||||
u_short port;
|
||||
|
||||
memset((voidp) &sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
|
||||
port = IPPORT_RESERVED;
|
||||
|
||||
do {
|
||||
--port;
|
||||
sin.sin_port = htons(port);
|
||||
rc = bind(so, (struct sockaddr *) &sin, sizeof(sin));
|
||||
} while (rc < 0 && (int) port > IPPORT_RESERVED / 2);
|
||||
|
||||
if (pp && rc == 0)
|
||||
*pp = port;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* close a descriptot, Sockets style
|
||||
*/
|
||||
int
|
||||
amu_close(int fd)
|
||||
{
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create an rpc client attached to the mount daemon.
|
||||
*/
|
||||
CLIENT *
|
||||
get_mount_client(char *unused_host, struct sockaddr_in *sin, struct timeval *tv, int *sock, u_long mnt_version)
|
||||
{
|
||||
CLIENT *client;
|
||||
|
||||
/*
|
||||
* First try a TCP socket
|
||||
*/
|
||||
if ((*sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) > 0) {
|
||||
/*
|
||||
* Bind to a privileged port
|
||||
*/
|
||||
if (bind_resv_port(*sock, (u_short *) 0) < 0)
|
||||
plog(XLOG_ERROR, "can't bind privileged port");
|
||||
|
||||
/*
|
||||
* Find mountd port to connect to.
|
||||
* Connect to mountd.
|
||||
* Create a tcp client.
|
||||
*/
|
||||
if ((sin->sin_port = htons(pmap_getport(sin, MOUNTPROG, mnt_version, IPPROTO_TCP))) != 0) {
|
||||
if (connect(*sock, (struct sockaddr *) sin, sizeof(*sin)) >= 0
|
||||
&& ((client = clnttcp_create(sin, MOUNTPROG, mnt_version, sock, 0, 0)) != NULL))
|
||||
return client;
|
||||
}
|
||||
/*
|
||||
* Failed so close socket
|
||||
*/
|
||||
(void) close(*sock);
|
||||
} /* tcp socket opened */
|
||||
/* TCP failed so try UDP */
|
||||
if ((*sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
plog(XLOG_ERROR, "Can't create socket to connect to mountd: %m");
|
||||
*sock = RPC_ANYSOCK;
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
* Bind to a privileged port
|
||||
*/
|
||||
if (bind_resv_port(*sock, (u_short *) 0) < 0)
|
||||
plog(XLOG_ERROR, "can't bind privileged port");
|
||||
|
||||
/*
|
||||
* Zero out the port - make sure we recompute
|
||||
*/
|
||||
sin->sin_port = 0;
|
||||
|
||||
/*
|
||||
* Make a UDP client
|
||||
*/
|
||||
if ((client = clntudp_create(sin, MOUNTPROG, mnt_version, *tv, sock)) == NULL) {
|
||||
(void) close(*sock);
|
||||
*sock = RPC_ANYSOCK;
|
||||
return NULL;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
dlog("get_mount_client: Using udp, port %d", sin->sin_port);
|
||||
#endif /* DEBUG */
|
||||
return client;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* find the address of the caller of an RPC procedure.
|
||||
*/
|
||||
struct sockaddr_in *
|
||||
amu_svc_getcaller(SVCXPRT *xprt)
|
||||
{
|
||||
return svc_getcaller(xprt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Bind NFS to a reserved port.
|
||||
*/
|
||||
static int
|
||||
bindnfs_port(int so, u_short *nfs_portp)
|
||||
{
|
||||
u_short port;
|
||||
int error = bind_resv_port(so, &port);
|
||||
|
||||
if (error == 0)
|
||||
*nfs_portp = port;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create the nfs service for amd
|
||||
*/
|
||||
int
|
||||
create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp))
|
||||
{
|
||||
|
||||
*soNFSp = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if (*soNFSp < 0 || bindnfs_port(*soNFSp, nfs_portp) < 0) {
|
||||
plog(XLOG_FATAL, "Can't create privileged nfs port");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((*nfs_xprtp = svcudp_create(*soNFSp)) == NULL) {
|
||||
plog(XLOG_FATAL, "cannot create rpc/udp service");
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (!svc_register(*nfs_xprtp, NFS_PROGRAM, NFS_VERSION, dispatch_fxn, 0)) {
|
||||
plog(XLOG_FATAL, "unable to register (NFS_PROGRAM, NFS_VERSION, 0)");
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 0; /* all is well */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create the amq service for amd (both TCP and UDP)
|
||||
*/
|
||||
int
|
||||
create_amq_service(int *udp_soAMQp, SVCXPRT **udp_amqpp, int *tcp_soAMQp, SVCXPRT **tcp_amqpp)
|
||||
{
|
||||
/* first create TCP service */
|
||||
if (tcp_soAMQp) {
|
||||
*tcp_soAMQp = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (*tcp_soAMQp < 0) {
|
||||
plog(XLOG_FATAL, "cannot create tcp socket for amq service: %m");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* now create RPC service handle for amq */
|
||||
if (tcp_amqpp &&
|
||||
(*tcp_amqpp = svctcp_create(*tcp_soAMQp, AMQ_SIZE, AMQ_SIZE)) == NULL) {
|
||||
plog(XLOG_FATAL, "cannot create tcp service for amq: soAMQp=%d", *tcp_soAMQp);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* next create UDP service */
|
||||
if (udp_soAMQp) {
|
||||
*udp_soAMQp = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (*udp_soAMQp < 0) {
|
||||
plog(XLOG_FATAL, "cannot create udp socket for amq service: %m");
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* now create RPC service handle for amq */
|
||||
if (udp_amqpp &&
|
||||
(*udp_amqpp = svcudp_bufcreate(*udp_soAMQp, AMQ_SIZE, AMQ_SIZE)) == NULL) {
|
||||
plog(XLOG_FATAL, "cannot create udp service for amq: soAMQp=%d", *udp_soAMQp);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
return 0; /* all is well */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find the best NFS version for a host and protocol.
|
||||
*/
|
||||
u_long
|
||||
get_nfs_version(char *host, struct sockaddr_in *sin, u_long nfs_version, const char *proto)
|
||||
{
|
||||
CLIENT *clnt;
|
||||
int again = 0;
|
||||
enum clnt_stat clnt_stat;
|
||||
struct timeval tv;
|
||||
int sock;
|
||||
|
||||
/*
|
||||
* If not set or set wrong, then try from NFS_VERS_MAX on down. If
|
||||
* set, then try from nfs_version on down.
|
||||
*/
|
||||
if (nfs_version <= 0 || nfs_version > NFS_VERS_MAX) {
|
||||
nfs_version = NFS_VERS_MAX;
|
||||
again = 1;
|
||||
}
|
||||
tv.tv_sec = 2;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
try_again:
|
||||
|
||||
sock = RPC_ANYSOCK;
|
||||
if (STREQ(proto, "tcp"))
|
||||
clnt = clnttcp_create(sin, NFS_PROGRAM, nfs_version, &sock, 0, 0);
|
||||
else if (STREQ(proto, "udp"))
|
||||
clnt = clntudp_create(sin, NFS_PROGRAM, nfs_version, tv, &sock);
|
||||
else
|
||||
clnt = NULL;
|
||||
|
||||
if (clnt == NULL) {
|
||||
plog(XLOG_INFO, "get_nfs_version NFS(%d,%s) failed for %s :%s",
|
||||
nfs_version, proto, host, clnt_spcreateerror(""));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try a couple times to verify the CLIENT handle. */
|
||||
tv.tv_sec = 6;
|
||||
clnt_stat = clnt_call(clnt, NFSPROC_NULL, (xdrproc_t) xdr_void, 0,
|
||||
(xdrproc_t) xdr_void, 0, tv);
|
||||
close(sock);
|
||||
clnt_destroy(clnt);
|
||||
if (clnt_stat != RPC_SUCCESS) {
|
||||
if (again) {
|
||||
#ifdef HAVE_FS_NFS3
|
||||
if (nfs_version == NFS_VERSION3) {
|
||||
plog(XLOG_INFO, "get_nfs_version trying a lower version");
|
||||
nfs_version = NFS_VERSION;
|
||||
again = 0;
|
||||
}
|
||||
goto try_again;
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
}
|
||||
plog(XLOG_INFO, "get_nfs_version NFS(%d,%s) failed for %s",
|
||||
nfs_version, proto, host);
|
||||
return 0;
|
||||
}
|
||||
|
||||
plog(XLOG_INFO, "get_nfs_version: returning (%d,%s) on host %s",
|
||||
nfs_version, proto, host);
|
||||
return nfs_version;
|
||||
}
|
89
usr.sbin/amd/libamu/umount_fs.c
Normal file
89
usr.sbin/amd/libamu/umount_fs.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: umount_fs.c,v 1.1.1.1 1997/07/24 21:20:10 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Unmounting filesystems under BSD 4.4.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
|
||||
int
|
||||
umount_fs(char *fs_name)
|
||||
{
|
||||
int error;
|
||||
|
||||
eintr:
|
||||
error = unmount(fs_name, 0);
|
||||
if (error < 0)
|
||||
error = errno;
|
||||
|
||||
switch (error) {
|
||||
case EINVAL:
|
||||
case ENOTBLK:
|
||||
case ENOENT:
|
||||
plog(XLOG_WARNING, "unmount: %s is not mounted", fs_name);
|
||||
error = 0; /* Not really an error */
|
||||
break;
|
||||
|
||||
case EINTR:
|
||||
#ifdef DEBUG
|
||||
/* not sure why this happens, but it does. ask kirk one day... */
|
||||
dlog("%s: unmount: %m", fs_name);
|
||||
#endif /* DEBUG */
|
||||
goto eintr;
|
||||
|
||||
#ifdef DEBUG
|
||||
default:
|
||||
dlog("%s: unmount: %m", fs_name);
|
||||
break;
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
176
usr.sbin/amd/libamu/util.c
Normal file
176
usr.sbin/amd/libamu/util.c
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: util.c,v 1.1.1.1 1997/07/24 21:20:08 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* General Utilitiles.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
|
||||
char *
|
||||
strnsave(const char *str, int len)
|
||||
{
|
||||
char *sp = (char *) xmalloc(len + 1);
|
||||
memmove(sp, str, len);
|
||||
sp[len] = 0;
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Concatenate three strings and store in buffer pointed to
|
||||
* by p, making p large enough to hold the strings
|
||||
*/
|
||||
char *
|
||||
str3cat(char *p, char *s1, char *s2, char *s3)
|
||||
{
|
||||
int l1 = strlen(s1);
|
||||
int l2 = strlen(s2);
|
||||
int l3 = strlen(s3);
|
||||
|
||||
p = (char *) xrealloc(p, l1 + l2 + l3 + 1);
|
||||
memmove(p, s1, l1);
|
||||
memmove(p + l1, s2, l2);
|
||||
memmove(p + l1 + l2, s3, l3 + 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Make all the directories in the path.
|
||||
*/
|
||||
int
|
||||
mkdirs(char *path, int mode)
|
||||
{
|
||||
/*
|
||||
* take a copy in case path is in readonly store
|
||||
*/
|
||||
char *p2 = strdup(path);
|
||||
char *sp = p2;
|
||||
struct stat stb;
|
||||
int error_so_far = 0;
|
||||
|
||||
/*
|
||||
* Skip through the string make the directories.
|
||||
* Mostly ignore errors - the result is tested at the end.
|
||||
*
|
||||
* This assumes we are root so that we can do mkdir in a
|
||||
* mode 555 directory...
|
||||
*/
|
||||
while ((sp = strchr(sp + 1, '/'))) {
|
||||
*sp = '\0';
|
||||
if (mkdir(p2, mode) < 0) {
|
||||
error_so_far = errno;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
dlog("mkdir(%s)", p2);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
*sp = '/';
|
||||
}
|
||||
|
||||
if (mkdir(p2, mode) < 0) {
|
||||
error_so_far = errno;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
dlog("mkdir(%s)", p2);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
free(p2);
|
||||
|
||||
return stat(path, &stb) == 0 &&
|
||||
(stb.st_mode & S_IFMT) == S_IFDIR ? 0 : error_so_far;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Remove as many directories in the path as possible.
|
||||
* Give up if the directory doesn't appear to have
|
||||
* been created by Amd (not mode dr-x) or an rmdir
|
||||
* fails for any reason.
|
||||
*/
|
||||
void
|
||||
rmdirs(char *dir)
|
||||
{
|
||||
char *xdp = strdup(dir);
|
||||
char *dp;
|
||||
|
||||
do {
|
||||
struct stat stb;
|
||||
/*
|
||||
* Try to find out whether this was
|
||||
* created by amd. Do this by checking
|
||||
* for owner write permission.
|
||||
*/
|
||||
if (stat(xdp, &stb) == 0 && (stb.st_mode & 0200) == 0) {
|
||||
if (rmdir(xdp) < 0) {
|
||||
if (errno != ENOTEMPTY &&
|
||||
errno != EBUSY &&
|
||||
errno != EEXIST &&
|
||||
errno != EINVAL)
|
||||
plog(XLOG_ERROR, "rmdir(%s): %m", xdp);
|
||||
break;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
dlog("rmdir(%s)", xdp);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
dp = strrchr(xdp, '/');
|
||||
if (dp)
|
||||
*dp = '\0';
|
||||
} while (dp && dp > xdp);
|
||||
|
||||
free(xdp);
|
||||
}
|
342
usr.sbin/amd/libamu/wire.c
Normal file
342
usr.sbin/amd/libamu/wire.c
Normal file
@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: wire.c,v 1.1.1.1 1997/07/24 21:20:09 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This function returns the subnet (address&netmask) for the primary network
|
||||
* interface. If the resulting address has an entry in the hosts file, the
|
||||
* corresponding name is retuned, otherwise the address is returned in
|
||||
* standard internet format.
|
||||
* As a side-effect, a list of local IP/net address is recorded for use
|
||||
* by the islocalnet() function.
|
||||
*
|
||||
* Derived from original by Paul Anderson (23/4/90)
|
||||
* Updates from Dirk Grunwald (11/11/91)
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
|
||||
/*
|
||||
* List of locally connected networks
|
||||
*/
|
||||
typedef struct addrlist addrlist;
|
||||
struct addrlist {
|
||||
addrlist *ip_next;
|
||||
u_long ip_addr;
|
||||
u_long ip_mask;
|
||||
};
|
||||
static addrlist *localnets = 0;
|
||||
|
||||
#if defined(IFF_LOCAL_LOOPBACK) && !defined(IFF_LOOPBACK)
|
||||
# define IFF_LOOPBACK IFF_LOCAL_LOOPBACK
|
||||
#endif /* defined(IFF_LOCAL_LOOPBACK) && !defined(IFF_LOOPBACK) */
|
||||
|
||||
#if defined(HAVE_FIELD_STRUCT_IFREQ_IFR_ADDR) && defined(HAVE_FIELD_STRUCT_SOCKADDR_SA_LEN)
|
||||
# define SIZE(ifr) (MAX((ifr)->ifr_addr.sa_len, sizeof((ifr)->ifr_addr)) + sizeof(ifr->ifr_name))
|
||||
#else /* not defined(HAVE_FIELD_STRUCT_IFREQ_IFR_ADDR) && defined(HAVE_FIELD_STRUCT_SOCKADDR_SA_LEN) */
|
||||
# define SIZE(ifr) sizeof(*ifr)
|
||||
#endif /* not defined(HAVE_FIELD_STRUCT_IFREQ_IFR_ADDR) && defined(HAVE_FIELD_STRUCT_SOCKADDR_SA_LEN) */
|
||||
|
||||
#define C(x) ((x) & 0xff)
|
||||
#define GFBUFLEN 1024
|
||||
#define clist (ifc.ifc_ifcu.ifcu_req)
|
||||
#define count (ifc.ifc_len/sizeof(struct ifreq))
|
||||
|
||||
|
||||
void
|
||||
getwire(char **name1, char **number1, char **name2, char **number2)
|
||||
{
|
||||
struct hostent *hp;
|
||||
struct netent *np;
|
||||
struct ifconf ifc;
|
||||
struct ifreq *ifr;
|
||||
caddr_t cp, cplim;
|
||||
u_long address, netmask, subnet;
|
||||
char buf[GFBUFLEN], *s;
|
||||
int fd = -1;
|
||||
u_long net;
|
||||
u_long mask;
|
||||
u_long subnetshift;
|
||||
char netNumberBuf[64];
|
||||
|
||||
#ifndef SIOCGIFFLAGS
|
||||
/* if cannot get interface flags, return nothing */
|
||||
*name1 = strdup("no_subnet_known");
|
||||
*number1 = "0.0.0.0";
|
||||
*name2 = 0;
|
||||
*number2 = 0;
|
||||
return;
|
||||
#endif /* not SIOCGIFFLAGS */
|
||||
|
||||
*name1 = 0;
|
||||
*number1 = 0;
|
||||
*name2 = 0;
|
||||
*number2 = 0;
|
||||
|
||||
/*
|
||||
* Get suitable socket
|
||||
*/
|
||||
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Fill in ifconf details
|
||||
*/
|
||||
memset(&buf[0], 0, GFBUFLEN);
|
||||
ifc.ifc_len = sizeof(buf);
|
||||
ifc.ifc_buf = buf;
|
||||
|
||||
/*
|
||||
* Get network interface configurations
|
||||
*/
|
||||
if (ioctl(fd, SIOCGIFCONF, (caddr_t) & ifc) < 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Upper bound on array
|
||||
*/
|
||||
cplim = buf + ifc.ifc_len;
|
||||
|
||||
/*
|
||||
* This is some magic to cope with both "traditional" and the
|
||||
* new 4.4BSD-style struct sockaddrs. The new structure has
|
||||
* variable length and a size field to support longer addresses.
|
||||
* AF_LINK is a new definition for 4.4BSD.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Scan the list looking for a suitable interface
|
||||
*/
|
||||
for (cp = buf; cp < cplim; cp += SIZE(ifr)) {
|
||||
addrlist *al;
|
||||
ifr = (struct ifreq *) cp;
|
||||
|
||||
if (ifr->ifr_addr.sa_family != AF_INET)
|
||||
continue;
|
||||
else
|
||||
address = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
|
||||
|
||||
/*
|
||||
* Get interface flags
|
||||
*/
|
||||
if (ioctl(fd, SIOCGIFFLAGS, (caddr_t) ifr) < 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If the interface is a loopback, or its not running
|
||||
* then ignore it.
|
||||
*/
|
||||
#ifdef IFF_LOOPBACK
|
||||
if ((ifr->ifr_flags & IFF_LOOPBACK) != 0)
|
||||
continue;
|
||||
#endif /* IFF_LOOPBACK */
|
||||
|
||||
/* if the interface is not UP or not RUNNING, skip it */
|
||||
if ((ifr->ifr_flags & IFF_RUNNING) == 0 ||
|
||||
(ifr->ifr_flags & IFF_UP) == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Get the netmask of this interface
|
||||
*/
|
||||
if (ioctl(fd, SIOCGIFNETMASK, (caddr_t) ifr) < 0)
|
||||
continue;
|
||||
|
||||
netmask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
|
||||
|
||||
/*
|
||||
* Add interface to local network list
|
||||
*/
|
||||
al = ALLOC(struct addrlist);
|
||||
al->ip_addr = address;
|
||||
al->ip_mask = netmask;
|
||||
al->ip_next = localnets;
|
||||
localnets = al;
|
||||
|
||||
/*
|
||||
* Figure out the subnet's network address
|
||||
*/
|
||||
subnet = address & netmask;
|
||||
|
||||
#ifdef IN_CLASSA
|
||||
subnet = htonl(subnet);
|
||||
|
||||
if (IN_CLASSA(subnet)) {
|
||||
mask = IN_CLASSA_NET;
|
||||
subnetshift = 8;
|
||||
} else if (IN_CLASSB(subnet)) {
|
||||
mask = IN_CLASSB_NET;
|
||||
subnetshift = 8;
|
||||
} else {
|
||||
mask = IN_CLASSC_NET;
|
||||
subnetshift = 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there are more bits than the standard mask
|
||||
* would suggest, subnets must be in use.
|
||||
* Guess at the subnet mask, assuming reasonable
|
||||
* width subnet fields.
|
||||
* XXX: Or-in at least 1 byte's worth of 1s to make
|
||||
* sure the top bits remain set.
|
||||
*/
|
||||
while (subnet & ~mask)
|
||||
mask = (mask >> subnetshift) | 0xff000000;
|
||||
|
||||
net = subnet & mask;
|
||||
while ((mask & 1) == 0)
|
||||
mask >>= 1, net >>= 1;
|
||||
|
||||
/*
|
||||
* Now get a usable name.
|
||||
* First use the network database,
|
||||
* then the host database,
|
||||
* and finally just make a dotted quad.
|
||||
*/
|
||||
np = getnetbyaddr(net, AF_INET);
|
||||
|
||||
/* the network address has been masked off */
|
||||
if ((subnet & 0xffffff) == 0) {
|
||||
sprintf(netNumberBuf, "%lu", C(subnet >> 24));
|
||||
} else if ((subnet & 0xffff) == 0) {
|
||||
sprintf(netNumberBuf, "%lu.%lu",
|
||||
C(subnet >> 24), C(subnet >> 16));
|
||||
} else if ((subnet & 0xff) == 0) {
|
||||
sprintf(netNumberBuf, "%lu.%lu.%lu",
|
||||
C(subnet >> 24), C(subnet >> 16),
|
||||
C(subnet >> 8));
|
||||
} else {
|
||||
sprintf(netNumberBuf, "%lu.%lu.%lu.%lu",
|
||||
C(subnet >> 24), C(subnet >> 16),
|
||||
C(subnet >> 8), C(subnet));
|
||||
}
|
||||
if (!*number1) {
|
||||
*number1 = strdup(netNumberBuf);
|
||||
} else if (!*number2) {
|
||||
*number2 = strdup(netNumberBuf);
|
||||
} else {
|
||||
plog(XLOG_INFO, "Another unused interface discovered: netnumber %s", netNumberBuf);
|
||||
}
|
||||
#else /* not IN_CLASSA */
|
||||
/* This is probably very wrong. */
|
||||
np = getnetbyaddr(subnet, AF_INET);
|
||||
#endif /* not IN_CLASSA */
|
||||
|
||||
if (np)
|
||||
s = np->n_name;
|
||||
else {
|
||||
subnet = address & netmask;
|
||||
hp = gethostbyaddr((char *) &subnet, 4, AF_INET);
|
||||
if (hp)
|
||||
s = (char *) hp->h_name;
|
||||
else
|
||||
s = inet_dquad(buf, subnet);
|
||||
}
|
||||
if (!*name1) {
|
||||
*name1 = strdup(s);
|
||||
} else if (!*name2) {
|
||||
*name2 = strdup(s);
|
||||
} else {
|
||||
plog(XLOG_INFO, "Another unused interface discovered: netname %s", s);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (fd >= 0)
|
||||
(void) close(fd);
|
||||
if (!*name1)
|
||||
*name1 = strdup(NO_SUBNET);
|
||||
if (!*number1)
|
||||
*number1 = "0.0.0.0";
|
||||
if (!*name2)
|
||||
*name2 = strdup(NO_SUBNET);
|
||||
if (!*number2)
|
||||
*number2 = "0.0.0.0";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Make a dotted quad from a 32bit IP address
|
||||
* addr is in network byte order.
|
||||
* sizeof(buf) needs to be at least 16.
|
||||
*/
|
||||
char *
|
||||
inet_dquad(char *buf, u_long addr)
|
||||
{
|
||||
addr = ntohl(addr);
|
||||
sprintf(buf, "%ld.%ld.%ld.%ld",
|
||||
((addr >> 24) & 0xff),
|
||||
((addr >> 16) & 0xff),
|
||||
((addr >> 8) & 0xff),
|
||||
((addr >> 0) & 0xff));
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Determine whether a network is on a local network
|
||||
* (addr) is in network byte order.
|
||||
*/
|
||||
int
|
||||
islocalnet(u_long addr)
|
||||
{
|
||||
addrlist *al;
|
||||
#ifdef DEBUG
|
||||
char buf[16];
|
||||
#endif /* DEBUG */
|
||||
|
||||
for (al = localnets; al; al = al->ip_next)
|
||||
if (((addr ^ al->ip_addr) & al->ip_mask) == 0)
|
||||
return TRUE;
|
||||
|
||||
#ifdef DEBUG
|
||||
plog(XLOG_INFO, "%s is on a remote network", inet_dquad(buf, addr));
|
||||
#endif /* DEBUG */
|
||||
|
||||
return FALSE;
|
||||
}
|
117
usr.sbin/amd/libamu/xdr_mountres3.c
Normal file
117
usr.sbin/amd/libamu/xdr_mountres3.c
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: xdr_mountres3.c,v 1.1.1.1 1997/07/24 21:20:09 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
/*
|
||||
* This ifdef is a hack: this whole file needs to be compiled
|
||||
* only if the system has NFS V3 and does not have the xdr_mountres3
|
||||
* function. Autoconf should pick this source file to compile only
|
||||
* if these two conditions apply.
|
||||
*/
|
||||
#ifdef HAVE_FS_NFS3
|
||||
bool_t
|
||||
xdr_fhandle3(XDR *xdrs, fhandle3 *objp)
|
||||
{
|
||||
long *buf;
|
||||
|
||||
if (!xdr_bytes(xdrs,
|
||||
(char **) &objp->fhandle3_val,
|
||||
(u_int *) &objp->fhandle3_len,
|
||||
FHSIZE3))
|
||||
return (FALSE);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_mountstat3(XDR *xdrs, mountstat3 *objp)
|
||||
{
|
||||
long *buf;
|
||||
|
||||
if (!xdr_enum(xdrs, (enum_t *)objp))
|
||||
return (FALSE);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp)
|
||||
{
|
||||
long *buf;
|
||||
|
||||
if (!xdr_fhandle3(xdrs, &objp->fhandle))
|
||||
return (FALSE);
|
||||
if (!xdr_array(xdrs,
|
||||
(char **)&objp->auth_flavors.auth_flavors_val,
|
||||
(u_int *) &objp->auth_flavors.auth_flavors_len,
|
||||
~0,
|
||||
sizeof (int),
|
||||
(xdrproc_t) xdr_int))
|
||||
return (FALSE);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_mountres3(XDR *xdrs, mountres3 *objp)
|
||||
{
|
||||
long *buf;
|
||||
|
||||
if (!xdr_mountstat3(xdrs, &objp->fhs_status))
|
||||
return (FALSE);
|
||||
switch (objp->fhs_status) {
|
||||
case 0: /* 0 == MNT_OK or MNT3_OK */
|
||||
if (!xdr_mountres3_ok(xdrs, &objp->mountres3_u.mountinfo))
|
||||
return (FALSE);
|
||||
break;
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
#endif /* HAVE_FS_NFS3 */
|
587
usr.sbin/amd/libamu/xutil.c
Normal file
587
usr.sbin/amd/libamu/xutil.c
Normal file
@ -0,0 +1,587 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Erez Zadok
|
||||
* Copyright (c) 1990 Jan-Simon Pendry
|
||||
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Jan-Simon Pendry at Imperial College, London.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* %W% (Berkeley) %G%
|
||||
*
|
||||
* $Id: xutil.c,v 1.1.1.1 1997/07/24 21:20:09 christos Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
FILE *logfp = stderr; /* Log errors to stderr initially */
|
||||
|
||||
#ifdef HAVE_SYSLOG
|
||||
int syslogging;
|
||||
#endif /* HAVE_SYSLOG */
|
||||
int xlog_level = XLOG_ALL & ~XLOG_MAP & ~XLOG_STATS;
|
||||
int xlog_level_init = ~0;
|
||||
|
||||
time_t clock_valid = 0;
|
||||
time_t xclock_valid = 0;
|
||||
|
||||
#ifdef DEBUG_MEM
|
||||
static int mem_bytes;
|
||||
static int orig_mem_bytes;
|
||||
#endif /* DEBUG_MEM */
|
||||
|
||||
/* forward definitions */
|
||||
static void real_plog(int lvl, char *fmt, va_list vargs);
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* List of debug options.
|
||||
*/
|
||||
struct opt_tab dbg_opt[] =
|
||||
{
|
||||
{"all", D_ALL}, /* All */
|
||||
{"amq", D_AMQ}, /* Register for AMQ program */
|
||||
{"daemon", D_DAEMON}, /* Enter daemon mode */
|
||||
{"fork", D_FORK}, /* Fork server (nofork = don't fork) */
|
||||
{"full", D_FULL}, /* Program trace */
|
||||
# ifdef DEBUG_MEM
|
||||
{"mem", D_MEM}, /* Trace memory allocations */
|
||||
# endif /* DEBUG_MEM */
|
||||
{"mtab", D_MTAB}, /* Use local mtab file */
|
||||
{"str", D_STR}, /* Debug string munging */
|
||||
{"test", D_TEST}, /* Full debug - but no daemon */
|
||||
{"trace", D_TRACE}, /* Protocol trace */
|
||||
{0, 0}
|
||||
};
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* List of log options
|
||||
*/
|
||||
struct opt_tab xlog_opt[] =
|
||||
{
|
||||
{"all", XLOG_ALL}, /* All messages */
|
||||
#ifdef DEBUG
|
||||
{"debug", XLOG_DEBUG}, /* Debug messages */
|
||||
#endif /* DEBUG */ /* DEBUG */
|
||||
{"error", XLOG_ERROR}, /* Non-fatal system errors */
|
||||
{"fatal", XLOG_FATAL}, /* Fatal errors */
|
||||
{"info", XLOG_INFO}, /* Information */
|
||||
{"map", XLOG_MAP}, /* Map errors */
|
||||
{"stats", XLOG_STATS}, /* Additional statistical information */
|
||||
{"user", XLOG_USER}, /* Non-fatal user errors */
|
||||
{"warn", XLOG_WARNING}, /* Warnings */
|
||||
{"warning", XLOG_WARNING}, /* Warnings */
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
||||
voidp
|
||||
xmalloc(int len)
|
||||
{
|
||||
voidp p;
|
||||
int retries = 600;
|
||||
|
||||
/*
|
||||
* Avoid malloc's which return NULL for malloc(0)
|
||||
*/
|
||||
if (len == 0)
|
||||
len = 1;
|
||||
|
||||
do {
|
||||
p = (voidp) malloc((unsigned) len);
|
||||
if (p) {
|
||||
#if defined(DEBUG) && defined(DEBUG_MEM)
|
||||
amuDebug(D_MEM) plog(XLOG_DEBUG, "Allocated size %d; block %#x", len, p);
|
||||
#endif /* defined(DEBUG) && defined(DEBUG_MEM) */
|
||||
return p;
|
||||
}
|
||||
if (retries > 0) {
|
||||
plog(XLOG_ERROR, "Retrying memory allocation");
|
||||
sleep(1);
|
||||
}
|
||||
} while (--retries);
|
||||
|
||||
plog(XLOG_FATAL, "Out of memory");
|
||||
going_down(1);
|
||||
|
||||
abort();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
voidp
|
||||
xrealloc(voidp ptr, int len)
|
||||
{
|
||||
#if defined(DEBUG) && defined(DEBUG_MEM)
|
||||
amuDebug(D_MEM) plog(XLOG_DEBUG, "Reallocated size %d; block %#x", len, ptr);
|
||||
#endif /* defined(DEBUG) && defined(DEBUG_MEM) */
|
||||
|
||||
if (len == 0)
|
||||
len = 1;
|
||||
|
||||
if (ptr)
|
||||
ptr = (voidp) realloc(ptr, (unsigned) len);
|
||||
else
|
||||
ptr = (voidp) xmalloc((unsigned) len);
|
||||
|
||||
if (!ptr) {
|
||||
plog(XLOG_FATAL, "Out of memory in realloc");
|
||||
going_down(1);
|
||||
abort();
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#if defined(DEBUG) && defined(DEBUG_MEM)
|
||||
void
|
||||
xfree(char *f, int l, voidp p)
|
||||
{
|
||||
amuDebug(D_MEM) plog(XLOG_DEBUG, "Free in %s:%d: block %#x", f, l, p);
|
||||
free(p);
|
||||
}
|
||||
#endif /* defined(DEBUG) && defined(DEBUG_MEM) */
|
||||
|
||||
|
||||
#ifdef DEBUG_MEM
|
||||
static void
|
||||
checkup_mem(P_void)
|
||||
{
|
||||
extern struct mallinfo __mallinfo;
|
||||
if (mem_bytes != __mallinfo.uordbytes) {
|
||||
if (orig_mem_bytes == 0)
|
||||
mem_bytes = orig_mem_bytes = __mallinfo.uordbytes;
|
||||
else {
|
||||
fprintf(logfp, "%s[%d]: ", progname, mypid);
|
||||
if (mem_bytes < __mallinfo.uordbytes) {
|
||||
fprintf(logfp, "ALLOC: %d bytes",
|
||||
__mallinfo.uordbytes - mem_bytes);
|
||||
} else {
|
||||
fprintf(logfp, "FREE: %d bytes",
|
||||
mem_bytes - __mallinfo.uordbytes);
|
||||
}
|
||||
mem_bytes = __mallinfo.uordbytes;
|
||||
fprintf(logfp, ", making %d missing\n",
|
||||
mem_bytes - orig_mem_bytes);
|
||||
}
|
||||
}
|
||||
malloc_verify();
|
||||
}
|
||||
#endif /* DEBUG_MEM */
|
||||
|
||||
|
||||
/*
|
||||
* Take a log format string and expand occurences of %m
|
||||
* with the current error code take from errno.
|
||||
*/
|
||||
static void
|
||||
expand_error(char *f, char *e)
|
||||
{
|
||||
extern int sys_nerr;
|
||||
char *p;
|
||||
int error = errno;
|
||||
|
||||
for (p = f; (*e = *p); e++, p++) {
|
||||
if (p[0] == '%' && p[1] == 'm') {
|
||||
const char *errstr;
|
||||
if (error < 0 || error >= sys_nerr)
|
||||
errstr = NULL;
|
||||
else
|
||||
errstr = sys_errlist[error];
|
||||
if (errstr)
|
||||
strcpy(e, errstr);
|
||||
else
|
||||
sprintf(e, "Error %d", error);
|
||||
e += strlen(e) - 1;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Output the time of day and hostname to the logfile
|
||||
*/
|
||||
static void
|
||||
show_time_host_and_name(int lvl)
|
||||
{
|
||||
static time_t last_t = 0;
|
||||
static char *last_ctime = 0;
|
||||
time_t t = clocktime();
|
||||
char *sev;
|
||||
|
||||
if (t != last_t) {
|
||||
last_ctime = ctime(&t);
|
||||
last_t = t;
|
||||
}
|
||||
switch (lvl) {
|
||||
case XLOG_FATAL:
|
||||
sev = "fatal:";
|
||||
break;
|
||||
case XLOG_ERROR:
|
||||
sev = "error:";
|
||||
break;
|
||||
case XLOG_USER:
|
||||
sev = "user: ";
|
||||
break;
|
||||
case XLOG_WARNING:
|
||||
sev = "warn: ";
|
||||
break;
|
||||
case XLOG_INFO:
|
||||
sev = "info: ";
|
||||
break;
|
||||
case XLOG_DEBUG:
|
||||
sev = "debug:";
|
||||
break;
|
||||
case XLOG_MAP:
|
||||
sev = "map: ";
|
||||
break;
|
||||
case XLOG_STATS:
|
||||
sev = "stats:";
|
||||
break;
|
||||
default:
|
||||
sev = "hmm: ";
|
||||
break;
|
||||
}
|
||||
fprintf(logfp, "%15.15s %s %s[%ld]/%s ",
|
||||
last_ctime + 4, hostname,
|
||||
progname,
|
||||
mypid,
|
||||
sev);
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Switch on/off debug options
|
||||
*/
|
||||
int
|
||||
debug_option(char *opt)
|
||||
{
|
||||
return cmdoption(opt, dbg_opt, &debug_flags);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dplog(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
real_plog(XLOG_DEBUG, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
void
|
||||
plog(int lvl, char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
real_plog(lvl, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
real_plog(int lvl, char *fmt, va_list vargs)
|
||||
{
|
||||
char msg[1024];
|
||||
char efmt[1024];
|
||||
char *ptr = msg;
|
||||
|
||||
if (!(xlog_level & lvl))
|
||||
return;
|
||||
|
||||
#ifdef DEBUG_MEM
|
||||
checkup_mem();
|
||||
#endif /* DEBUG_MEM */
|
||||
|
||||
expand_error(fmt, efmt);
|
||||
|
||||
vsprintf(ptr, efmt, vargs);
|
||||
|
||||
ptr += strlen(ptr);
|
||||
if (ptr[-1] == '\n')
|
||||
*--ptr = '\0';
|
||||
|
||||
#ifdef HAVE_SYSLOG
|
||||
if (syslogging) {
|
||||
switch (lvl) { /* from mike <mcooper@usc.edu> */
|
||||
case XLOG_FATAL:
|
||||
lvl = LOG_CRIT;
|
||||
break;
|
||||
case XLOG_ERROR:
|
||||
lvl = LOG_ERR;
|
||||
break;
|
||||
case XLOG_USER:
|
||||
lvl = LOG_WARNING;
|
||||
break;
|
||||
case XLOG_WARNING:
|
||||
lvl = LOG_WARNING;
|
||||
break;
|
||||
case XLOG_INFO:
|
||||
lvl = LOG_INFO;
|
||||
break;
|
||||
case XLOG_DEBUG:
|
||||
lvl = LOG_DEBUG;
|
||||
break;
|
||||
case XLOG_MAP:
|
||||
lvl = LOG_DEBUG;
|
||||
break;
|
||||
case XLOG_STATS:
|
||||
lvl = LOG_INFO;
|
||||
break;
|
||||
default:
|
||||
lvl = LOG_ERR;
|
||||
break;
|
||||
}
|
||||
syslog(lvl, "%s", msg);
|
||||
return;
|
||||
}
|
||||
#endif /* HAVE_SYSLOG */
|
||||
|
||||
*ptr++ = '\n';
|
||||
*ptr = '\0';
|
||||
|
||||
/*
|
||||
* Mimic syslog header
|
||||
*/
|
||||
show_time_host_and_name(lvl);
|
||||
fwrite(msg, ptr - msg, 1, logfp);
|
||||
fflush(logfp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Display current debug options
|
||||
*/
|
||||
void
|
||||
show_opts(int ch, struct opt_tab *opts)
|
||||
{
|
||||
int i;
|
||||
int s = '{';
|
||||
|
||||
fprintf(stderr, "\t[-%c {no}", ch);
|
||||
for (i = 0; opts[i].opt; i++) {
|
||||
fprintf(stderr, "%c%s", s, opts[i].opt);
|
||||
s = ',';
|
||||
}
|
||||
fputs("}]\n", stderr);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cmdoption(char *s, struct opt_tab *optb, int *flags)
|
||||
{
|
||||
char *p = s;
|
||||
int errs = 0;
|
||||
|
||||
while (p && *p) {
|
||||
int neg;
|
||||
char *opt;
|
||||
struct opt_tab *dp, *dpn = 0;
|
||||
|
||||
s = p;
|
||||
p = strchr(p, ',');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
|
||||
/* check for "no" prefix to options */
|
||||
if (s[0] == 'n' && s[1] == 'o') {
|
||||
opt = s + 2;
|
||||
neg = 1;
|
||||
} else {
|
||||
opt = s;
|
||||
neg = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan the array of debug options to find the
|
||||
* corresponding flag value. If it is found
|
||||
* then set (or clear) the flag (depending on
|
||||
* whether the option was prefixed with "no").
|
||||
*/
|
||||
for (dp = optb; dp->opt; dp++) {
|
||||
if (STREQ(opt, dp->opt))
|
||||
break;
|
||||
if (opt != s && !dpn && STREQ(s, dp->opt))
|
||||
dpn = dp;
|
||||
}
|
||||
|
||||
if (dp->opt || dpn) {
|
||||
if (!dp->opt) {
|
||||
dp = dpn;
|
||||
neg = !neg;
|
||||
}
|
||||
if (neg)
|
||||
*flags &= ~dp->flag;
|
||||
else
|
||||
*flags |= dp->flag;
|
||||
} else {
|
||||
/*
|
||||
* This will log to stderr when parsing the command line
|
||||
* since any -l option will not yet have taken effect.
|
||||
*/
|
||||
plog(XLOG_USER, "option \"%s\" not recognised", s);
|
||||
errs++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the comma back
|
||||
*/
|
||||
if (p)
|
||||
*p++ = ',';
|
||||
}
|
||||
|
||||
return errs;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Switch on/off logging options
|
||||
*/
|
||||
int
|
||||
switch_option(char *opt)
|
||||
{
|
||||
int xl = xlog_level;
|
||||
int rc = cmdoption(opt, xlog_opt, &xl);
|
||||
|
||||
if (rc) {
|
||||
rc = EINVAL;
|
||||
} else {
|
||||
/*
|
||||
* Keep track of initial log level, and
|
||||
* don't allow options to be turned off.
|
||||
*/
|
||||
if (xlog_level_init == ~0)
|
||||
xlog_level_init = xl;
|
||||
else
|
||||
xl |= xlog_level_init;
|
||||
xlog_level = xl;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Change current logfile
|
||||
*/
|
||||
int
|
||||
switch_to_logfile(char *logfile)
|
||||
{
|
||||
FILE *new_logfp = stderr;
|
||||
|
||||
if (logfile) {
|
||||
#ifdef HAVE_SYSLOG
|
||||
syslogging = 0;
|
||||
#endif /* HAVE_SYSLOG */
|
||||
|
||||
if (STREQ(logfile, "/dev/stderr"))
|
||||
new_logfp = stderr;
|
||||
else if (STREQ(logfile, "syslog")) {
|
||||
|
||||
#ifdef HAVE_SYSLOG
|
||||
syslogging = 1;
|
||||
new_logfp = stderr;
|
||||
openlog(progname, LOG_PID | LOG_CONS | LOG_NOWAIT ,LOG_DAEMON);
|
||||
#else /* not HAVE_SYSLOG */
|
||||
plog(XLOG_WARNING, "syslog option not supported, logging unchanged");
|
||||
#endif /* not HAVE_SYSLOG */
|
||||
|
||||
} else {
|
||||
(void) umask(orig_umask);
|
||||
new_logfp = fopen(logfile, "a");
|
||||
umask(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we couldn't open a new file, then continue using the old.
|
||||
*/
|
||||
if (!new_logfp && logfile) {
|
||||
plog(XLOG_USER, "%s: Can't open logfile: %m", logfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close the previous file
|
||||
*/
|
||||
if (logfp && logfp != stderr)
|
||||
(void) fclose(logfp);
|
||||
logfp = new_logfp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
unregister_amq(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_AMQ)
|
||||
#endif /* DEBUG */
|
||||
/*
|
||||
* If pmap_unset fails, then try out the TLI version.
|
||||
(void) rpcb_unset(AMQ_PROGRAM, AMQ_VERSION, (struct netconfig *) NULL);
|
||||
*/
|
||||
(void) pmap_unset(AMQ_PROGRAM, AMQ_VERSION);
|
||||
}
|
||||
|
||||
void
|
||||
going_down(int rc)
|
||||
{
|
||||
if (foreground) {
|
||||
if (amd_state != Start) {
|
||||
if (amd_state != Done)
|
||||
return;
|
||||
unregister_amq();
|
||||
}
|
||||
}
|
||||
if (foreground) {
|
||||
plog(XLOG_INFO, "Finishing with status %d", rc);
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
dlog("background process exiting with status %d", rc);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
exit(rc);
|
||||
}
|
Loading…
Reference in New Issue
Block a user