Virgin import of AMD (am-utils) v6.0a16
This commit is contained in:
commit
663d5a0f32
190
contrib/amd/AUTHORS
Normal file
190
contrib/amd/AUTHORS
Normal file
@ -0,0 +1,190 @@
|
||||
# -*- 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, in no
|
||||
particular order, 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.
|
||||
|
||||
September 12, 1997: lots of small prototype cleanups and fixes to numerous
|
||||
files.
|
||||
|
||||
January 27, 1998: support pid files in the amd.conf file. Provide base name
|
||||
for hesiod zone files. Always use /etc/amd.conf if exists.
|
||||
|
||||
* 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.
|
||||
|
||||
August 4, 1997: info_ldap.c fixes and adding two new amd.conf ldap
|
||||
variables: ldap_cache_seconds and ldap_cache_maxmem.
|
||||
|
||||
* 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.
|
||||
|
||||
September 9, 1997: initialize all fields of mntent_t structures to 0.
|
||||
|
||||
October 2, 1997: don't log an RPC timeout as an error but only as an info
|
||||
message.
|
||||
|
||||
December 19, 1997: detected an FMR (Free Memory Read) in amd/mntfs.c,
|
||||
uninit_mntfs().
|
||||
|
||||
* 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.
|
||||
|
||||
January 19, 1998: print correct -l option depending if system supports
|
||||
syslog and/or syslog facilities.
|
||||
|
||||
January 29, 1998: fix for 0.0.0.0 loopback on SunOS 3.X which defines
|
||||
IFF_ROUTE instead of IFF_LOOPBACK.
|
||||
|
||||
* 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.
|
||||
|
||||
* Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
|
||||
|
||||
July 23, 1997: Got lots of patches from the Debian Linux folks, who fixed
|
||||
several generic bugs, and one serious one for Linux. The latter involved
|
||||
using connected sockets for NFS mounts on kernels 1.3.10 and older. Roman's
|
||||
work is baed on amd-upl102, and work from Ian Murdock <imurdock@debian.org>
|
||||
and Dominik Kubla <dominik@debian.org>.
|
||||
|
||||
* Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
|
||||
|
||||
August 6, 1997: assorted fixes to support hesiod-1.3, solaris 2.4 (which I
|
||||
already fixed but did not release yet), and support for $LDFLAGS at
|
||||
configure/compile time.
|
||||
|
||||
February 24, 1998: lots of patches for ultrix 4.3 port.
|
||||
|
||||
February 28, 1998: lots of documentation fixes!
|
||||
|
||||
* Jason Thorpe <thorpej@nas.nasa.gov>
|
||||
|
||||
August 25, 1997: make amd work when talking to NIS+ servers in NIS
|
||||
compatibility mode. Fix originally came from Matthieu Herrb
|
||||
<matthieu@laas.fr>.
|
||||
|
||||
* Chris Metcalf <metcalf@catfish.lcs.mit.edu>
|
||||
|
||||
August 29, 1997: patch to make amd use FQHN for NFS/RPC authentication,
|
||||
useful esp. for cross-domain NFS mounts.
|
||||
September 2, 1997: if plock() succeeded, don't display errno string.
|
||||
|
||||
* Enami Tsugutomo <enami@cv.sony.co.jp>
|
||||
|
||||
September 4, 1997: don't ping remote servers with NFS V.3 always, but V.2,
|
||||
regardless of client's NFS version. (conf/transp/transp_sockets.c)
|
||||
|
||||
* Dan Riley <dsr@mail.lns.cornell.edu>
|
||||
|
||||
September 19, 1997: make sure that amd works with more secure portmappers
|
||||
that do not allow forwarding of RPC messages to other services.
|
||||
|
||||
* Wolfgang Rupprecht <wolfgang@wsrcc.com>
|
||||
|
||||
August 10, 1997: netbsd and other bsd systems have a mask flag for
|
||||
pcfs_args (msdos mount).
|
||||
|
||||
* Christos Zoulas <christos@deshaw.com>
|
||||
|
||||
September 25, 1997: fix to initialize uid/gid fields of pcfs_args_t on
|
||||
netbsd.
|
||||
|
||||
October 10, 1997: compile time cleanups of printf()s in hlfsd code. If nfs
|
||||
server is down or does not support a portmapper call, then mark it down as
|
||||
version 2, and try again later.
|
||||
|
||||
* Bill Paul <wpaul@ctr.columbia.edu>
|
||||
|
||||
November 5, 1997: NFS v.3 support for AIX 4.2.1, which does *not* include
|
||||
headers for this. Bill had to guess at the right structures, field names,
|
||||
sizes, alignment, etc.
|
||||
|
||||
* Stefan Vogel <vogel@physik-rzu.unizh.ch>
|
||||
|
||||
November 14, 1997: typo in the subscription instructions to amd-dev.
|
||||
|
||||
* Guntram Wolski <gwolsk@sei.com>
|
||||
|
||||
November 15, 1997: pointed out mismatching documentation for the -o option.
|
||||
|
||||
* Michael Hucka <hucka@eecs.umich.edu>
|
||||
|
||||
January 11, 1997: pointed out reversed definition of NFS mount options vers
|
||||
and proto.
|
||||
|
||||
* Albert Chin <china@pprd.abbott.com>
|
||||
|
||||
January 12, 1998: minor bug in output of amd -H.
|
||||
|
||||
* Thomas Richter <richter@chemie.fu-berlin.de>
|
||||
|
||||
January 13, 1998: use case insensitive comparisons for variables that need
|
||||
it (such as all hostname related ones, and more).
|
||||
|
||||
* Fred Korz <korz@smarts.com>
|
||||
|
||||
January 30, 1998: minor typo fixed to tftp example in am-utils.texi.
|
||||
|
||||
* Donald Buczek <buczek@MPIMG-Berlin-Dahlem.MPG.DE>
|
||||
|
||||
March 6, 1998: correctly inherit existing NFS V.3 mounts upon restart.
|
||||
|
||||
March 17, 1998: compare log file name and syslog string with correct length.
|
||||
|
||||
March 20, 1998: do not close stdout in case it gets reused elsewhere and to
|
||||
allow startup script to redirect it. Set a temporary secure umask(0022)
|
||||
before writing log file and restore it afterwards.
|
||||
|
||||
* Matthew Crosby <mcrosby@ms.com>
|
||||
April 20, 1998: allow arbitrary number of interfaces in wire listing.
|
||||
|
73
contrib/amd/BUGS
Normal file
73
contrib/amd/BUGS
Normal file
@ -0,0 +1,73 @@
|
||||
# -*- text -*-
|
||||
|
||||
LIST OF KNOWN BUGS IN AM-UTILS OR OPERATING SYSTEMS
|
||||
|
||||
|
||||
(1) mips-sgi-irix*
|
||||
|
||||
[1A] known to have flakey NFS V.3 and TCP. Amd tends to hang or spin
|
||||
infinitely after a few hours or days of use. Users must install recommended
|
||||
patches from vendor. Patches help, but not all the time. Otherwise avoid
|
||||
using NFS V.3 and TCP on these systems, by setting
|
||||
|
||||
/defaults opts:=vers=2,proto=udp
|
||||
|
||||
[1B] yp_all() leaks a file descriptor. Eventually amd runs out of file
|
||||
descriptors and hangs. Am-utils circumvents this by using its own version
|
||||
of yp_all which uses udp and iterats over NIS maps. The latter isn't as
|
||||
reliable as yp_all() which uses TCP, but it is better than hanging.
|
||||
|
||||
|
||||
(2) alpha-unknown-linux-gnu (RedHat Linux 4.2)
|
||||
|
||||
hasmntopt(mnt, opt) can goes into an infinite loop if opt is any substring
|
||||
of mnt->mnt_opts. Redhat 5.0 does not have this libc bug. Here is an
|
||||
example program:
|
||||
|
||||
#include <stdio.h>
|
||||
#include <mntent.h>
|
||||
main()
|
||||
{
|
||||
struct mntent mnt;
|
||||
char *cp;
|
||||
mnt.mnt_opts = "intr,rw,port=1023,timeo=8,foo=br,retrans=110,indirect,map=/usr/local/AMD/etc/amd.proj,boo";
|
||||
cp = hasmntopt(&mnt, "ro");
|
||||
printf("cp = %s\n", cp);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
(3) mips-dec-ultrix4.3
|
||||
|
||||
Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> reports
|
||||
|
||||
[3A] At least the gcc 2.7.0 fixincludes-mangled <sys/utsname.h> needs a
|
||||
forward declaration of struct utsname to avoid lots of gcc warnings:
|
||||
|
||||
RCS file: RCS/utsname.h,v
|
||||
retrieving revision 1.1
|
||||
diff -u -r1.1 utsname.h
|
||||
--- utsname.h 1995/06/19 13:07:01 1.1
|
||||
+++ utsname.h 1998/01/27 12:34:26
|
||||
@@ -59,6 +59,7 @@
|
||||
#ifdef KERNEL
|
||||
#include "../h/limits.h"
|
||||
#else /* user mode */
|
||||
+struct utsname;
|
||||
extern int uname _PARAMS((struct utsname *));
|
||||
#endif
|
||||
#define __SYS_NMLN 32
|
||||
|
||||
[3B] It autoconfigures and compiles cleanly, but currently hangs after a
|
||||
couple of hours without leaving any traces in the syslog output.
|
||||
|
||||
|
||||
(4) powerpc-ibm-aix4.2.1.0
|
||||
|
||||
[4A] "Randall S. Winchester" <rsw@Glue.umd.edu> reports that for amd to
|
||||
start, you need to kill and restart rpc.mountd and possibly also make sure
|
||||
that nfsd is running. Normally these are not required.
|
||||
|
||||
[4B] "Stefan Vogel" <vogel@physik.unizh.ch> reports that if your amq
|
||||
executable dump core unexpectedly, then it may be a bug in gcc 2.7.x.
|
||||
Upgrade to gcc 2.8.x or use IBM's xlC compiler.
|
37
contrib/amd/COPYING
Normal file
37
contrib/amd/COPYING
Normal file
@ -0,0 +1,37 @@
|
||||
Copyright (c) 1997-1998 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 acknowledgment:
|
||||
This product includes software developed by the University of
|
||||
California, Berkeley and its contributors, as well as the Trustees of
|
||||
Columbia University.
|
||||
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.
|
3039
contrib/amd/ChangeLog
Normal file
3039
contrib/amd/ChangeLog
Normal file
File diff suppressed because it is too large
Load Diff
113
contrib/amd/INSTALL
Normal file
113
contrib/amd/INSTALL
Normal file
@ -0,0 +1,113 @@
|
||||
# -*- text -*-
|
||||
am-utils 6.0 compatibility list
|
||||
|
||||
For each system, list if it autoconfigures, compiles, or runs. Fill in
|
||||
email id of person who confirms the fact. A missing entry means unverified.
|
||||
A 'no' means verified broken.
|
||||
|
||||
SYSTEM AUTOCONF COMPILE RUN SHLIB
|
||||
========================= ======== ========= ======= =====
|
||||
alpha-dec-osf2.1 ezk ezk ezk
|
||||
alpha-dec-osf4.0 ezk ezk dsr[3]
|
||||
alphaev5-unknown-linux-gnu ezk ezk finkel ezk
|
||||
hppa1.0-hp-hpux11.00 ezk ezk ezk
|
||||
hppa1.1-hp-hpux10.10 ezk ezk ezk -ezk (!rpcsvc.so)
|
||||
hppa1.1-hp-hpux10.20 ezk ezk ezk -ezk (!rpcsvc.so)
|
||||
hppa1.1-hp-hpux9.01 ezk[4] ezk[4] nrh/ezk
|
||||
hppa1.1-hp-hpux9.05 ezk[4] ezk[4] nrh/ezk
|
||||
hppa1.1-hp-hpux9.07 ezk[4] ezk[4] nrh/ezk
|
||||
i386-pc-bsdi2.1 ezk ezk ezk
|
||||
i386-pc-bsdi3.0 ezk ezk ezk
|
||||
i386-pc-bsdi3.1 ezk ezk ezk
|
||||
i386-pc-solaris2.5.1 ezk ezk ezk ezk
|
||||
i386-pc-solaris2.6 ezk ezk ezk ezk
|
||||
i386-unknown-freebsd2.1.0 ezk ezk ezk
|
||||
i386-unknown-freebsd2.2.1 ezk ezk ezk ezk
|
||||
i386-unknown-freebsd3.0 ezk ezk ezk ezk
|
||||
i386-unknown-netbsd1.2.1 ezk ezk ezk ezk
|
||||
i386-unknown-netbsd1.3 ezk ezk ezk ezk
|
||||
i386-unknown-netbsd1.3.1 ezk ezk ezk ezk
|
||||
i386-unknown-openbsd2.1 ezk ezk ezk ezk
|
||||
i486-ncr-sysv4.3.03 ezk ezk
|
||||
i486-pc-linux-gnulibc1 ezk ezk ezk ezk
|
||||
i586-pc-linux-gnulibc1 ezk ezk ezk ezk
|
||||
i686-pc-linux-gnu ezk ezk ezk ezk
|
||||
m68k-hp-hpux9.00 ezk[4] ezk[4] nrh/ezk
|
||||
m68k-next-nextstep3 ezk ezk ezk
|
||||
m68k-sun-sunos4.1.1 ezk ezk
|
||||
mips-dec-ultrix4.3 ro ro ro
|
||||
mips-sgi-irix5.2
|
||||
mips-sgi-irix5.3 ezk ezk ezk
|
||||
mips-sgi-irix6.2 ezk[1] ezk[1] ezk[1]
|
||||
mips-sgi-irix6.4 ezk ezk ezk ezk (!gcc)
|
||||
powerpc-ibm-aix4.1.5.0 ezk ezk wpaul
|
||||
powerpc-ibm-aix4.2.1.0 ezk ezk ezk
|
||||
rs6000-ibm-aix3.2 ezk ezk ezk
|
||||
rs6000-ibm-aix3.2.5 ezk ezk ezk
|
||||
rs6000-ibm-aix4.1.4.0 ezk ezk
|
||||
sparc-sun-solaris2.3 ezk ezk ezk
|
||||
sparc-sun-solaris2.4 ezk ezk ezk ezk
|
||||
sparc-sun-solaris2.5 ezk ezk ezk ezk
|
||||
sparc-sun-solaris2.5.1 ezk ezk ezk ezk
|
||||
sparc-sun-solaris2.6 ezk ezk[2] ezk ezk
|
||||
sparc-sun-sunos4.1.1 ezk ezk ezk ezk
|
||||
sparc-sun-sunos4.1.3 ezk ezk ezk ezk
|
||||
sparc-sun-sunos4.1.3C ezk ezk ezk ezk
|
||||
sparc-sun-sunos4.1.3_U1 ezk ezk ezk ezk
|
||||
sparc-sun-sunos4.1.4 ezk ezk ezk ezk
|
||||
sparc-unknown-linux-gnulibc1 ezk ezk ezk ezk
|
||||
sparc-unknown-netbsd1.2E ezk ezk ezk
|
||||
|
||||
EMAIL ID LEGEND:
|
||||
|
||||
bking: Bevis R W King <B.King@ee.surrey.ac.uk>
|
||||
dsr: Dan Riley <dsr@mail.lns.cornell.edu>
|
||||
ezk: Erez Zadok <ezk@cs.columbia.edu>
|
||||
nrh: Nick Hall <nrh@dcs.ed.ac.uk>
|
||||
stolke: Andreas Stolcke <stolcke@speech.sri.com>
|
||||
wpaul: Bill Paul <wpaul@ctr.columbia.edu>
|
||||
finkel: Raphael Finkel <raphael@cs.uky.edu>
|
||||
ro: Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
|
||||
|
||||
|
||||
FOOTNOTES:
|
||||
|
||||
[1] If compiling with cc on Irix 6, then use
|
||||
|
||||
CC="cc -32 -Wl,-woff,84" ./buildall
|
||||
|
||||
to build (good) "old style" 32 bit code and suppress stupid linker warnings
|
||||
about unused libraries.
|
||||
|
||||
Also, to get NFS V3 working, you need these two patches from SGI:
|
||||
|
||||
patch 1615: NFS over TCP
|
||||
patch 2041: NFS roll-up patch
|
||||
|
||||
and then add "-p tcp" to /etc/config/nfsd.options.
|
||||
|
||||
[2] If compiling on Solaris 2.6, you need to add -D_LARGEFILE64_SOURCE to
|
||||
CFLAGS to enable the 64bit file offset interface:
|
||||
|
||||
make CFLAGS="-O2 -g -D_LARGEFILE64_SOURCE"
|
||||
|
||||
If you're using the standard configure script, it will add this flag for you
|
||||
automatically.
|
||||
|
||||
[3] DU-4.0 may not use NFS (server-side) V3 by default. You may need to
|
||||
adjust /etc/init.d/nfs, and change the nfsd startup line from to
|
||||
|
||||
if /usr/sbin/nfsd $NUM_NFSD; then
|
||||
to
|
||||
if /usr/sbin/nfsd -t 8 -u 8 ; then
|
||||
|
||||
[4] HPUX 9.X has a bad /bin/sh that runs out of fixed memory allocations.
|
||||
If you use the configure script, you must run it as
|
||||
|
||||
/bin/ksh ./configure
|
||||
|
||||
Also, this system has a bad /bin/make that cannot handle VPATH well. You
|
||||
cannot use --srcdir or the buildall script with it. I suggest you install
|
||||
GNU make or configure locally with "/bin/ksh ./configure".
|
||||
|
||||
Erez.
|
43
contrib/amd/MIRRORS
Normal file
43
contrib/amd/MIRRORS
Normal file
@ -0,0 +1,43 @@
|
||||
# -*- text -*-
|
||||
|
||||
AM-UTILS-6.0 MIRRORS
|
||||
|
||||
Note: in case of any problems accessing the individual FTP sites, please
|
||||
contact their respective maintainers. If you wish to be added to the
|
||||
official mirror list, please send mail to amd-dev@cs.columbia.edu with the
|
||||
full URL, maintainer's email, and geographical location.
|
||||
|
||||
U.S.A:
|
||||
New York (Primary Site):
|
||||
ftp://shekel.mcl.cs.columbia.edu/pub/am-utils
|
||||
Maintainer: ezk@cs.columbia.edu
|
||||
Maryland:
|
||||
ftp://ftp.cs.umn.edu/pub/AMD
|
||||
Maintainer: dokas@cs.umn.edu
|
||||
Virginia (Newport News):
|
||||
* ftp://www.ferginc.com/pub/unix/am-utils
|
||||
Maintainer: Branson.Matheson@FergInc.com
|
||||
|
||||
Europe:
|
||||
Germany:
|
||||
ftp://ftp.fu-berlin.de/pub/unix/network/am-utils
|
||||
Maintainer: ftp-adm@ftp.fu-berlin.de
|
||||
Sweden:
|
||||
ftp://ftp.sunet.se/pub/unix/admin/am-utils
|
||||
Maintainer: archive@ftp.sunet.se
|
||||
Sweden:
|
||||
ftp://ftp.matematik.su.se/pub/mirrors/shekel.mcl.cs.columbia.edu/pub/am-utils
|
||||
Maintainer: lifj@matematik.su.se
|
||||
UK:
|
||||
ftp://sunsite.org.uk/packages/am-utils
|
||||
Maintainer: lmjm@icparc.ic.ac.uk
|
||||
|
||||
Asia:
|
||||
Japan:
|
||||
ftp://ftp.u-aizu.ac.jp/pub/net/amd/am-utils
|
||||
Maintainer: ftp-admin@u-aizu.ac.jp
|
||||
|
||||
Australia:
|
||||
Melbourne:
|
||||
ftp://ftp.sage-au.org.au/pub/network/filesystem/am-utils
|
||||
Maintainer: mirror@ftp.sage-au.org.au
|
628
contrib/amd/NEWS
Normal file
628
contrib/amd/NEWS
Normal file
@ -0,0 +1,628 @@
|
||||
*** Notes specific to am-utils version 6.0a16:
|
||||
|
||||
- new ports:
|
||||
hppa1.0-hp-hpux11.00 (works, not NFS V.3 due to missing headers)
|
||||
mips-dec-ultrix4.3 (working, unverified)
|
||||
|
||||
- new minor ports:
|
||||
i386-pc-bsdi3.1
|
||||
i386-unknown-netbsd1.3.1
|
||||
alpha-dec-osf2.1
|
||||
|
||||
- new options addopt:=ARG will "smartly" add and override options specified
|
||||
in opts:=
|
||||
|
||||
- new amd.conf options:
|
||||
pid_file: specifies the file to store the PID
|
||||
hesiod_base: specifies the base for the Hesiod service
|
||||
unmount_on_exit: if 'yes' will attempt to unmount all file systems
|
||||
when amd exits.
|
||||
|
||||
- amd.conf file is parsed after all other command line options. If no
|
||||
options specified at all, then use /etc/amd.conf by default.
|
||||
|
||||
- some variables' values are now compared case-insensitive as per specs,
|
||||
such as host names, domain names, and more.
|
||||
|
||||
- NIS service uses a new isup() function to detect if the service is up
|
||||
before using it. Used to ensure amd doesn't clear the existing maps before
|
||||
reloading them, unless the remote info service is working.
|
||||
|
||||
- new cdfs mount options: rrip, noversion, defperm, nodefperm (OSF)
|
||||
|
||||
- support efs/xfs separately on irix
|
||||
|
||||
- new -D info trace option to turn on info specific debugging, such as
|
||||
RES_DEBUG for hesiod services.
|
||||
|
||||
- document updates and fixes
|
||||
|
||||
- new file MIRRORS lists official mirror sites (also in am-utils home page)
|
||||
|
||||
- new file BUGS lists known amd/OS bugs
|
||||
|
||||
- source restructuring: rename all Amd file-systems' sources to amfs_ARG.c
|
||||
such that it matches the type:=ARG as well. Free names afs/dfs for Andrew
|
||||
F/S and Distributed F/S.
|
||||
|
||||
- checkpoint config.guess several times during the long configure, so that
|
||||
if it is aborted midway, the bulk of the features discovered will be re-read
|
||||
from the config.cache file.
|
||||
|
||||
- more systems support shared libraries (libtool 1.2)
|
||||
|
||||
- using automake 1.3 + more fixes
|
||||
|
||||
- bugs fixed:
|
||||
use dynamic buffer for list of interfaces, not fixed size
|
||||
output of amd -H duplicated if >2 interfaces
|
||||
-D mem for hlfsd not on by default (so it will daemonize)
|
||||
linux looks for ext2fs before ufs
|
||||
CDFS looks for 'isofs' mount type as well
|
||||
compile on Solaris 2.6 with /opt/SUNWspro/bin/cc
|
||||
various additional fixes which gcc 2.8.x reported
|
||||
print syslog help string based on what's supported
|
||||
correctly ignore loopback interface on SunOS 3.x
|
||||
don't use -lucb for strcasecmp
|
||||
hlfsd's dump file securely written in /usr/tmp/hlfsd.dump.XXXXXX
|
||||
inherit NFS V.3 mounts correctly
|
||||
write pid file securely
|
||||
|
||||
*** Notes specific to am-utils version 6.0a15:
|
||||
|
||||
- new ports:
|
||||
alpha-unknown-linux-gnu: works
|
||||
i386-unknown-netbsd1.3: fully working
|
||||
*-sun-sunos3: compiles, not tested
|
||||
|
||||
- updated ports:
|
||||
m68k-next-nextstep3: cleaner compile, works.
|
||||
|
||||
- new file system type nfsl (NFS Link). Uses nfs if file system is remote,
|
||||
and link if it is local (based on if $rhost equals the host name).
|
||||
|
||||
- support for Solaris cachefs. Requires setting fs, rfs, and a new variable
|
||||
cachedir. See documentation for explanation, examples, and caveats.
|
||||
|
||||
- support negated selector functions such as !exists(/foo/bar)
|
||||
|
||||
- wire, network, netnumber, in_network() selectors now match against all
|
||||
locally attached networks (by either name or number), not just the first two
|
||||
interfaces.
|
||||
|
||||
- new program pawd (and man page for it) --- Print Automounter Working
|
||||
Directory, to print the proper pathname of the cwd or any other pathname,
|
||||
adjusted for automounter paths, while avoiding mount points.
|
||||
|
||||
- two new switches to amq: -U will force using UDP only; -T will force using
|
||||
only TCP to communicate with amd. If neither (or both) are specified, amq
|
||||
will try TCP first, and if that failed, will try UDP.
|
||||
|
||||
- support syslog facilities, using "amd -l syslog:facility". Old behavior
|
||||
when using only -l syslog is to use the LOG_DAEMON facility.
|
||||
|
||||
- you may specify browsable_dirs=full, to get a listing of all entries
|
||||
(other than /default), including those with '*' wildcard and '/'
|
||||
characters.
|
||||
|
||||
- amd -D trace now also includes as much of struct nfs_args as can be
|
||||
displayed. Useful in figuring out what the kernel really gets during a
|
||||
mount(2), as opposed to what the /etc/mnttab file says. -D trace also
|
||||
traces the xdr_* functions.
|
||||
|
||||
- support for versions of shared libamu version. upped version from 0.0.0
|
||||
to 1.0.0. each am-utils release that will change the library will also
|
||||
update its version.
|
||||
|
||||
- amd/ops_TEMPLATE.c: a new template file for those brave enough to try and
|
||||
implement a new amd file system. Includes comments and other info useful
|
||||
for developers.
|
||||
|
||||
- if localconfig.h exists in the current directory during the run of
|
||||
configure, it is included in all am-utils sources. This allows courageous
|
||||
developers to make certain modifications during compilations, and especially
|
||||
turn off undesired features (not very recommended).
|
||||
|
||||
- documentation types and updates for all new features, ports, etc.
|
||||
|
||||
- bugs fixed:
|
||||
support NFS mount options grpid and maxgrps
|
||||
nextstep: set NFS success code to 0 (NFS_OK), not 1 (EPERM)
|
||||
bsdi2: set NFS success code to 0 (NFS_OK), not 1 (EPERM)
|
||||
set NFS V.3 mount table names to "nfs" if vers/proto exist
|
||||
use mkstemp() if possible (more secure)
|
||||
ctl-amd looks for amd.conf in ${prefix}/etc after /etc
|
||||
hpux: use "ignore" mount table type
|
||||
openbsd2.2: turn off "noconn" mount option, so only connected used
|
||||
fixed memory leak in hlfsd (don't setpwent after endpwent)
|
||||
all NFS3 systems should have proto/vers mount/amd options
|
||||
DEBUG_MEM compiles and prints something more useful
|
||||
uninit_mntfs(): free() mf_private *after* it is used
|
||||
browsable_readdir: fewer bytes sent back to kernel for each chunk
|
||||
mount_toplvl: don't free() an automatic variable!
|
||||
amd should chdir() to / before daemonzing (for core dumps etc)
|
||||
cdfs should be called 'cdfs' not whatever the mnttab type is
|
||||
amd -v: don't print "FS:" list twice when >=2 net interfaces
|
||||
|
||||
*** Notes specific to am-utils version 6.0a14:
|
||||
|
||||
- updated ports:
|
||||
powerpc-ibm-aix4.2.1.0: NFS V.3 works
|
||||
|
||||
- minor new ports:
|
||||
sparc-sun-sunos4.1.3C
|
||||
m68k-sun-sunos4.1.1 (sun3)
|
||||
mips-sgi-irix5.2
|
||||
|
||||
- new option to amd, -O ARG, will override the operating systems *name* with
|
||||
ARG. Corrected documentation for amd -o ARG --- it overrides the operating
|
||||
system *version* and not the name as the docs incorrectly stated.
|
||||
|
||||
- logging now behave more like syslog: will not print repeated strings, but
|
||||
rather a count such as "last message repeated N times". (N will not exceed
|
||||
100.)
|
||||
|
||||
- restructured the code which deals with the numerous possible fields and
|
||||
flags that are set in struct nfs_args. That code was moved to libamu as
|
||||
the functions compute_nfs_args() and compute_automounter_nfs_args().
|
||||
|
||||
- bugs fixed:
|
||||
mnttab name ufs/cdfs/pcfs/etc filesystems corrected
|
||||
use pmap_ping for amq (a must for secure portmappers, bsdi2/3)
|
||||
test for xfs (irix) as a disk-based filesystem
|
||||
set correct nfs_prot headers for Solaris 2.5
|
||||
removed stale code from lostaltmail.in
|
||||
lostaltmail will look for conf file in multiple locations
|
||||
assorted documentation corrections
|
||||
amq does not print "get_secure_amd_client" if run as root
|
||||
|
||||
*** Notes specific to am-utils version 6.0a13:
|
||||
|
||||
- new in_network(ARG) nomadic selector, true if ARG is the name (or number)
|
||||
of any of this host's network interfaces.
|
||||
|
||||
- removed variables primnetname, primnetnum, subsnetname, and subsnetnum.
|
||||
(Kept "wire" and its alias "network", and "netnumber".)
|
||||
|
||||
- include am-utils.dvi and am-utils.ps in distribution.
|
||||
|
||||
- hlfsd supports new option -P ARG, for reading password map off of file
|
||||
ARG. Allows you to use the hlfs redirector using paths other than user's
|
||||
home directories.
|
||||
|
||||
- use a replacement yp_all for some systems (irix) known to have a broken
|
||||
one which leaks a file descriptor each time called.
|
||||
|
||||
- if remote NFS server is down or does not support portmap, downgrade
|
||||
machine to NFS V.2 and retry again later.
|
||||
|
||||
- bugs:
|
||||
don't redefine yywrap on systems using a modified flex
|
||||
use correct "ignore" mnttab/mount option on hpux for df(1)
|
||||
use nfs_args' fsname field (hpux) to avoid syncer/mount(1) problems
|
||||
don't add ops_ufs.o twice to Makefile's $(OBJS)
|
||||
don't fail if autofs listener fails to initialize
|
||||
hlfsd should test if run as root after usage() and getopt
|
||||
|
||||
- minor code cleanups for netbsd
|
||||
|
||||
- html docs now in http://www.cs.columbia.edu/~ezk/am-utils/
|
||||
|
||||
- added README file in binaries ftp directory
|
||||
|
||||
*** Notes specific to am-utils version 6.0a12:
|
||||
|
||||
- minor or updated/broken ports fixed:
|
||||
hppa1.1-hp-hpux10.10: compiles, untested (probably works).
|
||||
hppa1.1-hp-hpux9.05: compiles, untested (probably works).
|
||||
hppa1.1-hp-hpux9.07: compiles, untested (probably works).
|
||||
m68k-hp-hpux9.00: compiles, untested (probably works).
|
||||
rs6000-ibm-aix4.1.4.0: compiles, untested.
|
||||
sparc-sun-solaris2.6: works w/ NFS V.3.
|
||||
sparc-sun-sunos4.1.4: compiles, untested (probably works).
|
||||
|
||||
- new ports:
|
||||
powerpc-ibm-aix4.2.1.0: compiles w/ NFS V.3, untested.
|
||||
|
||||
- wire-test also checks for combinations of NFS protocol/version from the
|
||||
client to a remote (or local) host.
|
||||
|
||||
- conf/mtab/mtab_file.c: use flock() to lock the file, and fcntl() if
|
||||
flock() is not available. (Used to prefer fcntl() over flock().)
|
||||
|
||||
- bug fixes:
|
||||
tli get_nfs_version() gets into an infinite loop
|
||||
tli get_nfs_version() should time out faster
|
||||
sockets get_nfs_version() should work w/ secure portmappers
|
||||
ESTALE returned for NFS mounts for SunOS 4.x fixed
|
||||
do not exceed HOSTNAMESZ for nfs_args.hostname (get ENAMETOOLONG)
|
||||
properly initialize some mntent_t fields (fsck, freq, mnt_time)
|
||||
properly initialize some pcfs_args fields (mask, uid, gid)
|
||||
properly initialize some cdfs_args fields (ssector)
|
||||
|
||||
*** Notes specific to am-utils version 6.0a11:
|
||||
|
||||
- bug fixes:
|
||||
amd could not NFS mount v.2 servers from v.3 clients
|
||||
hlfsd will only use first occurrence of home dir for same uid
|
||||
|
||||
*** Notes specific to am-utils version 6.0a10:
|
||||
|
||||
- MAJOR DOCUMENTATION UPDATE! (first time in 6 years)
|
||||
|
||||
- new ports:
|
||||
m68k-next-nextstep3: configures, compiles, not tested.
|
||||
|
||||
- preliminary autofs support. See README.autofs for details.
|
||||
|
||||
- new amd.conf [global] yes/no keywords:
|
||||
show_statfs_entries: shows number of entries for df(1)
|
||||
fully_qualified_hosts: use FQHN for NFS/RPC authentication
|
||||
|
||||
- detect down remote hosts faster
|
||||
|
||||
- log output of "amd -v" at startup
|
||||
|
||||
- removed $osver override for solaris: now it is 2.5.1, not 5.5.1
|
||||
|
||||
- buildall will use gmake first if available
|
||||
|
||||
- bugs fixed:
|
||||
amd core dumped when remote host was down
|
||||
allow up to 1024 entries back from readdir()
|
||||
amd.conf works even if only [global] option defined
|
||||
avoid using bad memcmp() implementations
|
||||
fixed meaning of plock [global] option (was reversed)
|
||||
hlfsd infinite loop unless compiled with --enable-debug
|
||||
NIS code works with NIS+ servers in NIS compatibility mode
|
||||
reset tag fields in amd.conf so they don't carry to other entries
|
||||
|
||||
*** Notes specific to am-utils version 6.0a9:
|
||||
|
||||
- new ports:
|
||||
sparc-sun-solaris2.4:
|
||||
configures/compiles, and runs (no NFS V3)
|
||||
i386-unknown-openbsd2.1:
|
||||
configures/compiles, runs (NFS V3)
|
||||
|
||||
- updated ports:
|
||||
i486-ncr-sysv4.3.03: configures/compiles, not tested
|
||||
|
||||
- Multiple amd support: new amd.conf [global] key "portmap_program" can be
|
||||
used to specify an alternate RPC program number for amd to un/register.
|
||||
Allowed numbers range from 300019 to 300029. A matching new option for amq:
|
||||
-P prognum, will use an alternate program number to contact.
|
||||
|
||||
- man pages:
|
||||
amd.conf.5 new
|
||||
mk-amd-map.8 new
|
||||
amd.8 updated
|
||||
amq.8 updated
|
||||
(other man pages required minor updates)
|
||||
|
||||
- shared libraries support expanded. Using GNU libtool-1.0. You can build
|
||||
a shared version of libamu, and link with it accordingly, by specifying
|
||||
--enable-shared to configure. Default is --enable-static --disable-shared,
|
||||
and you can mix and match. See "INSTALL" file for listing of systems on
|
||||
which shared libraries seem to build and work fine.
|
||||
|
||||
- new option: amq -p, will return the PID of the running amd (local or
|
||||
remote). Uses a new RPC message. Useful especially in "ctl-amd stop".
|
||||
|
||||
- new configure script options --enable-ldflags, for specifying -L flags.
|
||||
The older --enable-libs is to be used only for -l options.
|
||||
|
||||
- two new LDAP map options for amd.conf: ldap_cache_seconds and
|
||||
ldap_cache_maxmem.
|
||||
|
||||
- new script, am-eject from Debian linux's version of amd-upl102.
|
||||
|
||||
- additional passwd map support using var[0-3], from Debian folks.
|
||||
|
||||
- hesiod code cleanup. works for hesiod 1.3 as well as 3.0.
|
||||
|
||||
- removed defunct -h option from amd.
|
||||
|
||||
- started using automake-1.2. This fixed several bugs that caused some
|
||||
versions of yacc/lex and non-GNU make to fail.
|
||||
|
||||
- bug fixes:
|
||||
amd/hlfsd mounts should be hidden from df(1)
|
||||
use "noconn" option for nfs mounts (multi-homed hosts)
|
||||
don't use connected sockets on linux before 1.3.10 (from Debian)
|
||||
better checks for [gn]dbm
|
||||
forbid excessive retries after timeouts (from Debian)
|
||||
readdir(): don't skip over map entries with prefix, and include it
|
||||
more assorted linux fixes from Debian folks
|
||||
lofs mount on svr4 was broken
|
||||
find default value of $karch from uname() not $arch
|
||||
hlfsd failed to mount itself on some little-endians
|
||||
|
||||
|
||||
*** Notes specific to am-utils version 6.0a8:
|
||||
|
||||
- new ports:
|
||||
i386-unknown-netbsd1.2.1: configures/compiles (with NFS V.3), works,
|
||||
but some OS stability problems exist.
|
||||
|
||||
- updated ports:
|
||||
hppa1.1-hp-hpux9.01:
|
||||
now tested and working
|
||||
rs6000-ibm-aix3.2 and rs6000-ibm-aix3.2.5:
|
||||
now tested and working
|
||||
|
||||
- fixed browsable directories (readdir) code.
|
||||
|
||||
- better methods to find amd/hlfsd pid to kill in ctl-{amd,hlfsd}
|
||||
|
||||
- "ignore/auto" mount types fixed for irix, sunos, and others, so "df" does not
|
||||
show amd mounts by default (but GNU df -a does).
|
||||
|
||||
- each time amd is built, a new "build" version is incremented. See amd -v.
|
||||
|
||||
- man page for fsinfo added
|
||||
|
||||
- empty fillers for new file (bsd44) systems: nullfs, unionfs, umapfs.
|
||||
|
||||
- when amd is not running, or portmapper is down, make amq timeout faster (5
|
||||
sec) than system default, usually 4-5 minutes.
|
||||
|
||||
- bug fixes:
|
||||
hlfsd mount got "protocol not supported"
|
||||
first regular map in amd.conf didn't inherit global options
|
||||
make "bad" versions of lex still work with amd/conf_parse.l
|
||||
check for 'nodev' option, not 'nondev'
|
||||
typo in "ro" option, and fillers to ac{reg,dir}{min,max} and others
|
||||
amd.conf parsing done before switching default log/debug options
|
||||
allow doubly-quoted values in amd.conf
|
||||
hesiod-reload code cleanup
|
||||
|
||||
- assorted code cleanup
|
||||
|
||||
|
||||
*** Notes specific to am-utils version 6.0a7:
|
||||
|
||||
- new ports:
|
||||
i386-unknown-freebsd3.0:
|
||||
fully functional with NFS V.3
|
||||
sparc-sun-solaris2.3:
|
||||
fully functional (should work for 2.4)
|
||||
sparc-unknown-netbsd1.2E:
|
||||
configures/compiles (with NFS V.3), untested
|
||||
|
||||
- updated ports:
|
||||
i386-pc-bsdi3.0:
|
||||
NFS V.3 works
|
||||
look for hesiod in libc
|
||||
mips-sgi-irix5.3:
|
||||
fully functional with NFS V.3
|
||||
|
||||
- LDAP support! New [global] amd.conf options ldap_base and ldap_hostports.
|
||||
Also includes a new script amd2ldif to convert amd maps into plain text LDAP
|
||||
object files.
|
||||
|
||||
- the following amd.conf variables: browsable_dirs, map_options, map_type,
|
||||
mount_type, and search_path --- can now be specified in [global] as well as
|
||||
the map entry itself. That way you can declare them only once in [global],
|
||||
and override them as needed per map.
|
||||
|
||||
- option "cluster" added to [global] (HPUX clusters ala "amd -C").
|
||||
|
||||
- assorted info_hesiod map fixes and cleanup. removed HESIOD_RELOAD code.
|
||||
|
||||
- added netgrp(name) function to amd map syntax to see if current host is in
|
||||
the <name> netgroup.
|
||||
|
||||
- removed unused option "amd -m".
|
||||
|
||||
- filled in "tasks" file with todo items.
|
||||
|
||||
- filled "COPYING" file with legal stuff.
|
||||
|
||||
- cleanup: all global variables are now in one big structure (struct
|
||||
amu_global_options) that's easy to identify and enhance. Also migrated
|
||||
several flags that used be an integer each into one unsigned integer that's
|
||||
used as a bit-flag.
|
||||
|
||||
- big fixes:
|
||||
xdr_mountres3 should compile only if has NFS V3
|
||||
lex/yacc macros show full pathname (to tell if correct one runs)
|
||||
misc fixes/cleanup
|
||||
|
||||
|
||||
*** Notes specific to am-utils version 6.0a6:
|
||||
|
||||
- amd configuration file!
|
||||
|
||||
See scripts/amd.conf-sample for help and some explanation. This new conf
|
||||
file allows for the following new features:
|
||||
|
||||
default selectors can be turned on/off globally.
|
||||
browsable_dirs/readdir() support can be turned on per map.
|
||||
search paths for file type maps.
|
||||
can force the map type to file, nis, ndbm, etc. rather than default
|
||||
to looking at all of them.
|
||||
tag each map for "amd -T tag", useful for grouping maps.
|
||||
can override $os and others (so if you don't like "sunos5" default
|
||||
naming, set os=sos5 and it will work with your old maps).
|
||||
and more goodies...
|
||||
|
||||
- enable-default-selectors: No longer turned on by the configure script or
|
||||
optionally compiled. Code made dynamic and can be turned on or off from the
|
||||
amd.conf file. This code is off by default, and must be turned on by
|
||||
amd.conf's [global] section.
|
||||
|
||||
- new ports:
|
||||
mips-sgi-irix5.3: configure/compile, not tested
|
||||
i486-ncr-sysv4.3.03: configure/compile, not tested
|
||||
|
||||
- updated ports:
|
||||
alpha-dec-osf4.0: major code redone
|
||||
sparc-sun-sunos4.1.3: fixed and working
|
||||
mips-sgi-irix6.2: tested with gcc and "cc -32 -Wl,-woff,84"
|
||||
mips-sgi-irix6.4: tested with gcc and "cc -32 -Wl,-woff,84"
|
||||
|
||||
- better NFS3 port, including more support for proto= and vers=, and
|
||||
automatic determination of proto/vers combination.
|
||||
|
||||
- conf/nfs_prot/nfs_prot_*.h: all of the NFS protocol header files had to be
|
||||
redone, because of the osf4 port. OSF used very different names for these,
|
||||
and they conflicted with am-utils'. The only solution was to more or less
|
||||
conform to OSF4's naming, and change all the others.
|
||||
|
||||
- ctl-amd script:
|
||||
improved to look for amd.conf in $prefix/etc and /etc
|
||||
better methods for finding the pid of amd to kill
|
||||
|
||||
- autoconf support for LDAP. amd/info_ldap.c needs to be written.
|
||||
|
||||
- wire-test also reports the local IP address. Some systems have multiple,
|
||||
buggy version of get_myaddress(), esp. SunOS and Irix. Note that Solaris
|
||||
x86 has a buggy htonl().
|
||||
|
||||
- amd -H prints usage.
|
||||
|
||||
- bugs fixed:
|
||||
minor TLI problem in fwd_socket
|
||||
mount options properly comma delimited
|
||||
LIBS is set only to the right set of libraries to include
|
||||
selectors-on-default code ignored last selector ent in /defaults
|
||||
assorted code cleanups
|
||||
|
||||
|
||||
*** Notes specific to am-utils version 6.0a5:
|
||||
|
||||
- NFS Version 3 support!!!
|
||||
|
||||
Works on Solaris 2.5.1.
|
||||
Minimal testing done on Irix 6.
|
||||
Compiles cleanly on DU-4.0 but no tests performed.
|
||||
|
||||
Will fall back to V2 mounts when V3 is not available. Will also use TCP if
|
||||
possible, UDP otherwise.
|
||||
|
||||
- Ports to new platforms:
|
||||
|
||||
alpha-dec-osf4.0 (not tested)
|
||||
i386-pc-bsdi3.0 (tested and working)
|
||||
i386-unknown-freebsd2.2.1 (tested and working)
|
||||
sparc-unknown-linux-gnu (tested and working)
|
||||
|
||||
- New scripts added:
|
||||
|
||||
amd2sun: convert amd maps to Sun automount maps
|
||||
ctl-amd: script to start/stop/restart amd
|
||||
ctl-hlfsd: script to start/stop/restart hlfsd
|
||||
expn: expand mail alias (used by hlfsd)
|
||||
lostaltmail: redeliver "lost" mail redirected by hlfsd
|
||||
lostaltmail.conf-sample: sample conf file for lostaltmail
|
||||
wait4amd: run a command once amd is up on a host
|
||||
wait4amd2die: wait for an amd process to die before returning
|
||||
|
||||
- "amd -v" now includes more info and "amq -v" lists all of it.
|
||||
|
||||
- new parser for linux specific mount options.
|
||||
|
||||
- Main bugs fixed:
|
||||
|
||||
"new toplvl readdir" bug caused amd to dump core
|
||||
handler for SIGCHLD didn't check for all possible children
|
||||
hlfsd leaking file descriptors when home file system was full
|
||||
cdfs/pcfs mounts should not timeout by default
|
||||
hesiod domain names should be compared in case-insensitive manner
|
||||
several printfs in amq were missing \n
|
||||
|
||||
|
||||
*** Notes specific to am-utils version 6.0a4:
|
||||
|
||||
- amd services both TCP and UDP amq requests. This will help because of the
|
||||
limited UDP message size.
|
||||
|
||||
- "amq -M" code is disabled by default because it is insecure. It is
|
||||
rarely used. Users who wish to use it should run
|
||||
"configure --enable-amq-mount".
|
||||
|
||||
|
||||
*** Notes specific to am-utils version 6.0a3:
|
||||
|
||||
- New tested ports (configures, compiles, and runs):
|
||||
|
||||
i386-unknown-freebsd2.2
|
||||
|
||||
- New ports (configures and compiles correctly, not tested):
|
||||
|
||||
rs6000-ibm-aix3.2.5
|
||||
rs6000-ibm-aix4.1.5.0
|
||||
|
||||
- More am-utils programs ported to all existing platforms: hlfsd, fsinfo,
|
||||
mk-amd-map, and fixmount.
|
||||
|
||||
- Shared libraries: a new configure option --enable-shared will build a
|
||||
shared libamu.so, link applications with it, and use it. Reduces binary
|
||||
sizes by 20-30%. This is the first step towards loadable modules, as many
|
||||
changes had to be done to be able to compile and use PIC code. This is code
|
||||
that obviously needs to be generalized to be able to build shared libraries
|
||||
on many other platforms. It was only tested on Solaris 5.5.1.
|
||||
|
||||
- the file INSTALL contains the latest compatibility table of which
|
||||
platforms am-utils configures, compiles and runs on.
|
||||
|
||||
- Trimmed down the size of the configure script. Some tests that are not
|
||||
used anywhere were removed.
|
||||
|
||||
|
||||
*** Notes specific to am-utils version 6.0a2:
|
||||
|
||||
- New ports (configures and compiles correctly, not tested):
|
||||
|
||||
i386-pc-bsdi2.1
|
||||
hppa1.1-hp-hpux9.01
|
||||
hppa1.1-hp-hpux10.20
|
||||
|
||||
- new configure options:
|
||||
|
||||
--enable-cppflags[=ARG]
|
||||
configure/compile with ARG (-I) preprocessor flags
|
||||
--enable-libs[=ARG]
|
||||
configure/compile with ARG (-L/-l) library flags
|
||||
|
||||
- filesystem, mount table entries, and mount type tests can now look in
|
||||
/lib/modules and /proc/filesystems for statically/dyadically loadable kernel
|
||||
modules (linux)
|
||||
|
||||
- prefer vfat over msdos/pc/etc filesystem for PCFS.
|
||||
|
||||
- moved all fixed headers to include/am_defs. Left only #define/#undef
|
||||
entries in aux/acconfig.h.
|
||||
|
||||
- make more sense of systems that have full, partial, or no NFS protocol
|
||||
headers.
|
||||
|
||||
- minor fixes for NetBSD (untested platform).
|
||||
|
||||
- hesiod map fixed.
|
||||
|
||||
- buildall -D: new option to run even stricter developer options.
|
||||
|
||||
- lots of other bugs fixed (see ChangeLog).
|
||||
|
||||
|
||||
*** Notes specific to am-utils version 6.0a1:
|
||||
|
||||
I have it configure and build correctly for the following systems:
|
||||
|
||||
i386-pc-solaris2.5.1
|
||||
i386-unknown-freebsd2.1.0
|
||||
mips-sgi-irix6.2
|
||||
sparc-sun-solaris2.5.1
|
||||
sparc-sun-sunos4.1.3
|
||||
|
||||
Amq, wire-test, and "amd -v" work on all of the above. A real running amd
|
||||
was only tested and confirmed working on
|
||||
|
||||
i386-pc-solaris2.5.1
|
||||
sparc-sun-solaris2.5.1
|
||||
|
||||
Many things are still missing: options, features, etc. But for now, let's
|
||||
concentrate on getting the basic functionality working on the more popular
|
||||
systems.
|
105
contrib/amd/README
Normal file
105
contrib/amd/README
Normal file
@ -0,0 +1,105 @@
|
||||
# -*- text -*-
|
||||
|
||||
This is an alpha version of amd. "Buyers" beware!!!
|
||||
|
||||
See the file NEWS for news on this and previous releases.
|
||||
|
||||
*** General Notes to alpha testers:
|
||||
|
||||
[A] an an alpha testers, I expect you to be able to find certain things on
|
||||
your own (especially look at the sources to figure out how things work).
|
||||
|
||||
[B] if you intend to modify any files, first find out if the file you want
|
||||
to modify gets autogenerated from some other place. If so, modify it at the
|
||||
source.
|
||||
|
||||
You can adjust some of the configuration of am-utils after it has been
|
||||
auto-configured by putting whatever definitions you wish in a file called
|
||||
localconfig.h, located in the top build directory (the same one where
|
||||
config.h is created for you).
|
||||
|
||||
[C] there are several ways you can build am-utils:
|
||||
|
||||
(1) run the buildall script as follows:
|
||||
|
||||
./buildall
|
||||
|
||||
This would build all the applications inside a special directory relative to
|
||||
the root of the source tree, called A.<cpu-company-system>, where the <>
|
||||
part is filled in by GNU's config.guess script. This is the preferred
|
||||
method, for it will separate the build from the sources, and allow you to
|
||||
run buildall for multiple architectures concurrently.
|
||||
|
||||
You can run "buildall -h" to see what options it takes.
|
||||
|
||||
(2) run the configure script such as:
|
||||
|
||||
./configure
|
||||
|
||||
and then run
|
||||
|
||||
make
|
||||
|
||||
This would configure amd in the directory you've run the configure script
|
||||
in, and the built it there. Run "make install" to install all the necessary
|
||||
files.
|
||||
|
||||
Note that this is good for building only one version of amd on one
|
||||
architecture! Don't try this for multiple architectures. If you must, then
|
||||
after doing one such build, run "make distclean" and then reconfigure for
|
||||
another architecture.
|
||||
|
||||
(3) run the configure script for build in a different location. Let's say
|
||||
that /src/am-utils-6.0 is where you unpacked the sources. So you could
|
||||
|
||||
mkdir /src/build/sunos5
|
||||
cd /src/build/sunos5
|
||||
/src/am-utils-6.0/configure --srcdir=/src/am-utils-6.0
|
||||
make
|
||||
|
||||
This is a manual method that will let you build in any directory outside the
|
||||
am-utils source tree. It requires that your "make" program understand
|
||||
VPATH. This can be used multiple times to build am-utils concurrently in
|
||||
multiple (but different) directories. In fact, the buildall script
|
||||
described above.
|
||||
|
||||
(4) If you need to configure am-utils with extra libraries and/or headers,
|
||||
for example to add hesiod support, do so as follows:
|
||||
|
||||
configure --enable-libs="-lhesiod -lresolv" \
|
||||
--enable-ldflags="-L/usr/local/hesiod/lib" \
|
||||
--enable-cppflags="-I/usr/local/hesiod/include"
|
||||
|
||||
[D] If you modify any of the *.[chyl] sources in the directories amd, amq,
|
||||
hlfsd, lib, etc, all you need to do to get a new version of am-utils is run
|
||||
make.
|
||||
|
||||
If you modify any of the files in the aux/ or conf/ directories, then you
|
||||
must rebuild the configure script, Makefile.in files, aclocal.m4, etc. The
|
||||
best way to do so is to run
|
||||
|
||||
./aux/mkconf
|
||||
or
|
||||
./buildall -K
|
||||
|
||||
To be a developer and be able to run mkconf, you must have autoconf-2.12,
|
||||
GNU make-3.75 or later, and automake-1.2 (plus my fixes to it) installed on
|
||||
your system. You may find my version of automake-1.2 where you ftp'ed this
|
||||
version of am-utils. You may also need GNU libtool 1.0.
|
||||
|
||||
After you've remade the basic configuration files you must rerun the
|
||||
buildall script to rerun configure and then remake the binaries.
|
||||
|
||||
Modifying M4 macros may not be very intuitive to anyone that has not done so
|
||||
before. Let me know if you are having any problems with them. I fully
|
||||
expect, at least initially, to have to be the sole developers of the M4
|
||||
macros and let others concentrate on C sources.
|
||||
|
||||
[E] Report all bugs to amd-dev@majordomo.cs.columbia.edu. Avoid reporting
|
||||
to my personal email address. It is important to involve the whole list in
|
||||
bug fixes etc.
|
||||
|
||||
Good luck.
|
||||
|
||||
Erez Zadok,
|
||||
Maintainer, am-utils.
|
177
contrib/amd/TODO
Normal file
177
contrib/amd/TODO
Normal file
@ -0,0 +1,177 @@
|
||||
# -*- text -*-
|
||||
|
||||
Make a tasks file that people can pick jobs off of.
|
||||
|
||||
take a look at am_compat.h and fix everything there...
|
||||
|
||||
fix all $Id bla bla bla $ on every file.
|
||||
add my own copyright 1997 etc.
|
||||
|
||||
NOT NEEDED: convert DEBUG symbol to ENABLE_DEBUG
|
||||
NOT NEEDED: convert DEBUG_MEM symbol to ENABLE_DEBUG_MEM
|
||||
|
||||
Use these two somewhere:
|
||||
AC_DEFINE(AM_UTILS_NAME_PACKAGE, "am-utils")
|
||||
AC_DEFINE(AM_UTILS_VERSION, "6.0a1)
|
||||
|
||||
check all "dnl XXX: in configure.in
|
||||
|
||||
check for: INLINE, Const->const, P_void, VOIDP
|
||||
|
||||
rename DEBUG_MTAB to DEBUG_MNTTAB
|
||||
rename UPDATE_MTAB to MOUNT_TABLE_ON_FILE
|
||||
rename HAS_NIS_MAPS to HAVE_MAP_NIS
|
||||
rename HAS_TFS to HAVE_FS_TFS
|
||||
rename SIG_HNDL_TYP to RETSIGTYPE
|
||||
|
||||
remove HOST_EXEC #define from everywhere. add to am_ops.c a static flag
|
||||
initialized_vops, which if not true, should set the host_ops vector field to
|
||||
0 or host_umounted. This way let the feature be turned on if -h option to
|
||||
amd is given.
|
||||
|
||||
nuke all code that is ifdef'd SUNOS4_COMPAT
|
||||
|
||||
rename NEED_MNTOPT_PARSER to HAVE_HASMNTOPT and cleanup the code. also take
|
||||
the supplied code in amd/mount_fs.c and include it as the library function
|
||||
libamd/hasmntopt.c
|
||||
|
||||
TLI code needs to be fixed.
|
||||
|
||||
a way to include a site-specific configuration file IFF it exists from
|
||||
directory local/<${target}.h>
|
||||
|
||||
replace #include WAIT with nothing (HAVE_SYS_WAIT_H?)
|
||||
|
||||
replace SYS5_SIGNALS with HAVE_SYS_WAIT_H (which is on only if it sys/wait.h
|
||||
exists and is using the newer "int" for type, not "union wait". The macro
|
||||
AC_HEADER_SYS_WAIT turns on HAVE_SYS_WAIT_H iff wait*() functions are
|
||||
posix.1 compliant. Make sure you don't remove SYS5_SIGNALS ifdef's that are
|
||||
not related to wait*() syscalls.
|
||||
|
||||
add username, hostname, and date at which time amd was compiled.
|
||||
|
||||
No more need for MOUNT_HELPER_SOURCE.
|
||||
|
||||
any code which is included by NEED_UMOUNT_FS, should be on iff
|
||||
MOUNT_TABLE_ON_FILE is on.
|
||||
|
||||
replace NFS_FH_FIELD with references fo ".fh" in calls to
|
||||
NFS_FH_DREF(src, dst) macro
|
||||
|
||||
For *EVERY* M4 Macro with case/esac, check that the $host_os case entries
|
||||
are correct.
|
||||
|
||||
I'm not using amd's regexp code. Instead, use generic system code. If the
|
||||
system has posix style regexp functions, then change amd/map.c to use
|
||||
correct new prototype.
|
||||
|
||||
use HAVE_SVC_GETREQSET instead of RPC_4.
|
||||
|
||||
replace all "jsp" in *.[hc] $Id$ with ezk.
|
||||
|
||||
use MNTTAB_FILE_NAME instead of MOUNTED
|
||||
|
||||
use MOUNT_TABLE_ON_FILE instead of READ_MTAB_FROM_FILE
|
||||
|
||||
no more HAS_EMPTY_AUTOMOUNTS, which was used if a df(1) divide by zero bug
|
||||
was invoked. Instead, change nfs_statfs() code to always return non-zero
|
||||
values. Then nuke HAS_EMPTY_AUTOMOUNTS.
|
||||
|
||||
REGEXP: use whatever regular expressionlibrary you have on the system,
|
||||
including regexp.h if available, and using regcomp/regexec. Amd was written
|
||||
with BSD regexps in mind, not Sys V, so if I use any of those, I have to
|
||||
watch for correct usage. Otherwise, I can include the older include/re.h
|
||||
and amd/re.c. Replace HAS_REGEXP with HAVE_REGEXEC.
|
||||
|
||||
The regex code in amd/mapc.c has changed a lot. It probably has bugs. Must
|
||||
test and debug it!!!
|
||||
|
||||
# string name of filesystem in /etc/mnttab file
|
||||
Use MNTTAB_TYPE_FOO instead of MTAB_TYPE_FOO.
|
||||
# string name of mount option in /etc/mnttab file
|
||||
Use MNTTAB_OPT_FOO instead of MNTOPT_FOO.
|
||||
# string (or integer?) name of filesystem type in mount(2) syscall
|
||||
Use MOUNT_TYPE_FOO instead of MNTTYPE_FOO or MOUNT_FOO.
|
||||
# hex/number of FS mount option in nfs_args passed to mount(2) syscall
|
||||
Use MNT2_NFS_OPT_FOO instead NFSMNT_FOO.
|
||||
# hex/number of generic FS mount option directly passed to mount(2) syscall
|
||||
Use MNT2_GEN_OPT_FOO instead of MS_FOO or M_FOO.
|
||||
|
||||
|
||||
update AMD_COMPAT to 6.0 in include/am_utils.h
|
||||
|
||||
convert all mem* functions b* functions (memset to bzero, etc.) or vice
|
||||
verse.
|
||||
|
||||
put my name/copyright on every src file
|
||||
|
||||
change all struct mnttab/mntent to "mntent_t"
|
||||
|
||||
cleanup lib/resvport.c (TLI vs. Sockets). TLI code is #defin'ed
|
||||
HAVE_T_OPEN.
|
||||
[
|
||||
setting MTAB_LOCK_FILE (mtab_svr4.c) should be an amd run-time configuration
|
||||
option.
|
||||
|
||||
change all UMOUNT_FS macros to umount_fs() fxn calls.
|
||||
|
||||
remove getnetbyaddr() from lib/getnetbyaddr.c and then link w/ -lsocket
|
||||
|
||||
take care of various (hlfsd et al) scripts in Makefile.am files.
|
||||
|
||||
rename HOSTNAMESZ to MAXHOSTNAMELEN
|
||||
|
||||
turn on all the NEW_TOPLVL_READDIR code (for "ls" to work in an amd point)
|
||||
|
||||
change all NEW_DEFAULTS to ENABLE_DEFAULT_SELECTOTS (which is now on by
|
||||
default)
|
||||
|
||||
remove refereces to mnt_freq and mnt_passno in mntent_t since it's not in
|
||||
use any more.
|
||||
|
||||
remove all the (lint?) comments /*ARGSUSED */
|
||||
|
||||
change HAS_FOOFS to HAVE_AM_FS_FOO (for example HAS_NFSX -> HAVE_AM_FS_FOO),
|
||||
but change HAS_UNION_FS to HAVE_AM_FS_UNION.
|
||||
|
||||
some code uses #ifdef M_NEWTYPE to tell if mount(2)'s type field is "char *"
|
||||
or int. Use MTYPE_TYPE declaration instead (not ifdef macro!)
|
||||
|
||||
change DEBUG_MTAB to DEBUG_MNTTAB
|
||||
|
||||
deal with the changes in values of $os, $arch, and $osver!
|
||||
|
||||
replace SYS5_SIGNALS with REINSTATE_SIGNAL_HANDLER
|
||||
|
||||
figure out how to auto-conf HAS_HESIOD_RELOAD (amd/info_hesiod.c). For now
|
||||
I've used the macro HAVE_HS_ZONE_TRANSFER.
|
||||
|
||||
|
||||
|
||||
|
||||
******************************************************************************
|
||||
PERL SCRIPT TO FIX OLD AMD MAPS:
|
||||
- fix '=' to ':='
|
||||
- fix sos5 -> solaris2, etc.
|
||||
|
||||
******************************************************************************
|
||||
USE AS IS:
|
||||
|
||||
- SVC_IN_ARG_TYPE (change from SVC_IN_ARGS_TYPE, with an 'S')
|
||||
- NFS_FH_TYPE
|
||||
- MTYPE_TYPE
|
||||
- MOUNT_TYPE_* NO!!!
|
||||
|
||||
******************************************************************************
|
||||
NEW FEATURES:
|
||||
|
||||
- autofs
|
||||
- cachefs
|
||||
- dbm/gdbm/db file maps
|
||||
- add amd option -O (override) to override $os, $osver, $arch, $karch, etc.
|
||||
|
||||
******************************************************************************
|
||||
DONE:
|
||||
|
||||
HAS_TFS is gone and all of it's code too.
|
||||
major code cleanup, removed if 0 code and if notdef
|
441
contrib/amd/amd/am_ops.c
Normal file
441
contrib/amd/amd/am_ops.c
Normal file
@ -0,0 +1,441 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: am_ops.c,v 5.2.2.1 1992/02/09 15:08:17 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
|
||||
/*
|
||||
* The order of these entries matters, since lookups in this table are done
|
||||
* on a first-match basis. The entries below are a mixture of native
|
||||
* filesystems supported by the OS (HAVE_FS_FOO), and some meta-filesystems
|
||||
* supported by amd (HAVE_AM_FS_FOO). The order is set here in expected
|
||||
* match-hit such that more popular filesystems are listed first (nfs is the
|
||||
* most popular, followed by a symlink F/S)
|
||||
*/
|
||||
static am_ops *vops[] =
|
||||
{
|
||||
#ifdef HAVE_FS_NFS
|
||||
&nfs_ops, /* network F/S (version 2) */
|
||||
#endif /* HAVE_FS_NFS */
|
||||
#ifdef HAVE_AM_FS_LINK
|
||||
&amfs_link_ops, /* symlink F/S */
|
||||
#endif /* HAVE_AM_FS_LINK */
|
||||
|
||||
/*
|
||||
* Other amd-supported meta-filesystems.
|
||||
*/
|
||||
#ifdef HAVE_AM_FS_NFSX
|
||||
&amfs_nfsx_ops, /* multiple-nfs F/S */
|
||||
#endif /* HAVE_AM_FS_NFSX */
|
||||
#ifdef HAVE_AM_FS_NFSL
|
||||
&amfs_nfsl_ops, /* NFS with local link existence check */
|
||||
#endif /* HAVE_AM_FS_NFSL */
|
||||
#ifdef HAVE_AM_FS_HOST
|
||||
&amfs_host_ops, /* multiple exported nfs F/S */
|
||||
#endif /* HAVE_AM_FS_HOST */
|
||||
#ifdef HAVE_AM_FS_LINKX
|
||||
&amfs_linkx_ops, /* symlink F/S with link target verify */
|
||||
#endif /* HAVE_AM_FS_LINKX */
|
||||
#ifdef HAVE_AM_FS_PROGRAM
|
||||
&amfs_program_ops, /* program F/S */
|
||||
#endif /* HAVE_AM_FS_PROGRAM */
|
||||
#ifdef HAVE_AM_FS_UNION
|
||||
&amfs_union_ops, /* union F/S */
|
||||
#endif /* HAVE_AM_FS_UNION */
|
||||
#ifdef HAVE_AM_FS_INHERIT
|
||||
&amfs_inherit_ops, /* inheritance F/S */
|
||||
#endif /* HAVE_AM_FS_INHERIT */
|
||||
|
||||
/*
|
||||
* A few more native filesystems.
|
||||
*/
|
||||
#ifdef HAVE_FS_UFS
|
||||
&ufs_ops, /* Unix F/S */
|
||||
#endif /* HAVE_FS_UFS */
|
||||
#ifdef HAVE_FS_XFS
|
||||
&xfs_ops, /* Unix (irix) F/S */
|
||||
#endif /* HAVE_FS_XFS */
|
||||
#ifdef HAVE_FS_EFS
|
||||
&efs_ops, /* Unix (irix) F/S */
|
||||
#endif /* HAVE_FS_EFS */
|
||||
#ifdef HAVE_FS_LOFS
|
||||
&lofs_ops, /* loopback F/S */
|
||||
#endif /* HAVE_FS_LOFS */
|
||||
#ifdef HAVE_FS_CDFS
|
||||
&cdfs_ops, /* CDROM/HSFS/ISO9960 F/S */
|
||||
#endif /* HAVE_FS_CDFS */
|
||||
#ifdef HAVE_FS_PCFS
|
||||
&pcfs_ops, /* Floppy/MSDOS F/S */
|
||||
#endif /* HAVE_FS_PCFS */
|
||||
#ifdef HAVE_FS_CACHEFS
|
||||
&cachefs_ops, /* caching F/S */
|
||||
#endif /* HAVE_FS_CACHEFS */
|
||||
#ifdef HAVE_FS_NULLFS
|
||||
/* FILL IN */ /* null (loopback) F/S */
|
||||
#endif /* HAVE_FS_NULLFS */
|
||||
#ifdef HAVE_FS_UNIONFS
|
||||
/* FILL IN */ /* union (bsd44) F/S */
|
||||
#endif /* HAVE_FS_UNIONFS */
|
||||
#ifdef HAVE_FS_UMAPFS
|
||||
/* FILL IN */ /* uid/gid mapping F/S */
|
||||
#endif /* HAVE_FS_UMAPFS */
|
||||
|
||||
/*
|
||||
* These 5 should be last, in the order:
|
||||
* (1) amfs_auto
|
||||
* (2) amfs_direct
|
||||
* (3) amfs_toplvl
|
||||
* (4) autofs
|
||||
* (5) amfs_error
|
||||
*/
|
||||
#ifdef HAVE_AM_FS_AUTO
|
||||
&amfs_auto_ops, /* Automounter F/S */
|
||||
#endif /* HAVE_AM_FS_AUTO */
|
||||
#ifdef HAVE_AM_FS_DIRECT
|
||||
&amfs_direct_ops, /* direct-mount F/S */
|
||||
#endif /* HAVE_AM_FS_DIRECT */
|
||||
#ifdef HAVE_AM_FS_TOPLVL
|
||||
&amfs_toplvl_ops, /* top-level mount F/S */
|
||||
#endif /* HAVE_AM_FS_TOPLVL */
|
||||
#ifdef HAVE_FS_AUTOFS
|
||||
&autofs_ops, /* autofs mount F/S */
|
||||
#endif /* HAVE_FS_AUTOFS */
|
||||
#ifdef HAVE_AM_FS_ERROR
|
||||
&amfs_error_ops, /* error F/S */
|
||||
#endif /* HAVE_AM_FS_ERROR */
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
ops_showamfstypes(char *buf)
|
||||
{
|
||||
struct am_ops **ap;
|
||||
int l = 0;
|
||||
|
||||
buf[0] = '\0';
|
||||
for (ap = vops; *ap; ap++) {
|
||||
strcat(buf, (*ap)->fs_type);
|
||||
if (ap[1])
|
||||
strcat(buf, ", ");
|
||||
l += strlen((*ap)->fs_type) + 2;
|
||||
if (l > 60) {
|
||||
l = 0;
|
||||
strcat(buf, "\n ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ops_show1(char *buf, int *lp, const char *name)
|
||||
{
|
||||
strcat(buf, name);
|
||||
strcat(buf, ", ");
|
||||
*lp += strlen(name) + 2;
|
||||
if (*lp > 60) {
|
||||
strcat(buf, "\t\n");
|
||||
*lp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ops_showfstypes(char *buf)
|
||||
{
|
||||
int l = 0;
|
||||
|
||||
buf[0] = '\0';
|
||||
|
||||
#ifdef MNTTAB_TYPE_AUTOFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_AUTOFS);
|
||||
#endif /* MNTTAB_TYPE_AUTOFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_CACHEFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_CACHEFS);
|
||||
#endif /* MNTTAB_TYPE_CACHEFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_CDFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_CDFS);
|
||||
#endif /* MNTTAB_TYPE_CDFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_CFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_CFS);
|
||||
#endif /* MNTTAB_TYPE_CFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_LOFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_LOFS);
|
||||
#endif /* MNTTAB_TYPE_LOFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_EFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_EFS);
|
||||
#endif /* MNTTAB_TYPE_EFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_MFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_MFS);
|
||||
#endif /* MNTTAB_TYPE_MFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_NFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_NFS);
|
||||
#endif /* MNTTAB_TYPE_NFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_NFS3
|
||||
ops_show1(buf, &l, "nfs3"); /* always hard-code as nfs3 */
|
||||
#endif /* MNTTAB_TYPE_NFS3 */
|
||||
|
||||
#ifdef MNTTAB_TYPE_NULLFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_NULLFS);
|
||||
#endif /* MNTTAB_TYPE_NULLFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_PCFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_PCFS);
|
||||
#endif /* MNTTAB_TYPE_PCFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_TFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_TFS);
|
||||
#endif /* MNTTAB_TYPE_TFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_TMPFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_TMPFS);
|
||||
#endif /* MNTTAB_TYPE_TMPFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_UFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_UFS);
|
||||
#endif /* MNTTAB_TYPE_UFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_UMAPFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_UMAPFS);
|
||||
#endif /* MNTTAB_TYPE_UMAPFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_UNIONFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_UNIONFS);
|
||||
#endif /* MNTTAB_TYPE_UNIONFS */
|
||||
|
||||
#ifdef MNTTAB_TYPE_XFS
|
||||
ops_show1(buf, &l, MNTTAB_TYPE_XFS);
|
||||
#endif /* MNTTAB_TYPE_XFS */
|
||||
|
||||
/* terminate with a period, newline, and NULL */
|
||||
if (buf[strlen(buf)-1] == '\n')
|
||||
buf[strlen(buf) - 4] = '\0';
|
||||
else
|
||||
buf[strlen(buf) - 2] = '\0';
|
||||
strcat(buf, ".\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* return string option which is the reverse of opt.
|
||||
* nosuid -> suid
|
||||
* quota -> noquota
|
||||
* ro -> rw
|
||||
* etc.
|
||||
* may return pointer to static buffer or subpointer within opt.
|
||||
*/
|
||||
static char *
|
||||
reverse_option(const char *opt)
|
||||
{
|
||||
static char buf[80];
|
||||
|
||||
/* sanity check */
|
||||
if (!opt)
|
||||
return NULL;
|
||||
|
||||
/* check special cases */
|
||||
/* XXX: if this gets too long, rewrite the code more flexibly */
|
||||
if (STREQ(opt, "ro")) return "rw";
|
||||
if (STREQ(opt, "rw")) return "ro";
|
||||
if (STREQ(opt, "bg")) return "fg";
|
||||
if (STREQ(opt, "fg")) return "bg";
|
||||
if (STREQ(opt, "soft")) return "hard";
|
||||
if (STREQ(opt, "hard")) return "soft";
|
||||
|
||||
/* check if string starts with 'no' and chop it */
|
||||
if (NSTREQ(opt, "no", 2)) {
|
||||
strcpy(buf, &opt[2]);
|
||||
} else {
|
||||
/* finally return a string prepended with 'no' */
|
||||
strcpy(buf, "no");
|
||||
strcat(buf, opt);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* start with an empty string. for each opts1 option that is not
|
||||
* in opts2, add it to the string (make sure the reverse of it
|
||||
* isn't in either). finally add opts2. return new string.
|
||||
* Both opts1 and opts2 must not be null!
|
||||
* Caller must eventually free the string being returned.
|
||||
*/
|
||||
static char *
|
||||
merge_opts(char *opts1, char *opts2)
|
||||
{
|
||||
mntent_t mnt2; /* place holder for opts2 */
|
||||
char *newstr; /* new string to return (malloc'ed) */
|
||||
char *tmpstr; /* temp */
|
||||
char *eq; /* pointer to '=' within temp */
|
||||
char oneopt[80]; /* one option w/o value if any */
|
||||
char *revoneopt; /* reverse of oneopt */
|
||||
int len = strlen(opts1) + strlen(opts2) + 2; /* space for "," and NULL */
|
||||
char *s1 = strdup(opts1); /* copy of opts1 to munge */
|
||||
|
||||
/* initialization */
|
||||
mnt2.mnt_opts = opts2;
|
||||
newstr = xmalloc(len);
|
||||
newstr[0] = '\0';
|
||||
|
||||
for (tmpstr = strtok(s1, ",");
|
||||
tmpstr;
|
||||
tmpstr = strtok(NULL, ",")) {
|
||||
/* copy option to temp buffer */
|
||||
strncpy(oneopt, tmpstr, 80);
|
||||
oneopt[79] = '\0';
|
||||
/* if option has a value such as rsize=1024, chop the value part */
|
||||
if ((eq = strchr(oneopt, '=')))
|
||||
eq[1] = '\0';
|
||||
/* find reverse option of oneopt */
|
||||
revoneopt = reverse_option(oneopt);
|
||||
/* if option orits reverse exist in opts2, ignore it */
|
||||
if (hasmntopt(&mnt2, oneopt) || hasmntopt(&mnt2, revoneopt))
|
||||
continue;
|
||||
/* add option to returned string */
|
||||
if (newstr && newstr[0]) {
|
||||
strcat(newstr, ",");
|
||||
strcat(newstr, tmpstr);
|
||||
} else {
|
||||
strcpy(newstr, tmpstr);
|
||||
}
|
||||
}
|
||||
|
||||
/* finally, append opts2 itself */
|
||||
if (newstr && newstr[0]) {
|
||||
strcat(newstr, ",");
|
||||
strcat(newstr, opts2);
|
||||
} else {
|
||||
strcpy(newstr, opts2);
|
||||
}
|
||||
|
||||
XFREE(s1);
|
||||
return newstr;
|
||||
}
|
||||
|
||||
|
||||
am_ops *
|
||||
ops_match(am_opts *fo, char *key, char *g_key, char *path, char *keym, char *map)
|
||||
{
|
||||
am_ops **vp;
|
||||
am_ops *rop = 0;
|
||||
|
||||
/*
|
||||
* First crack the global opts and the local opts
|
||||
*/
|
||||
if (!eval_fs_opts(fo, key, g_key, path, keym, map)) {
|
||||
rop = &amfs_error_ops;
|
||||
} else if (fo->opt_type == 0) {
|
||||
plog(XLOG_USER, "No fs type specified (key = \"%s\", map = \"%s\")", keym, map);
|
||||
rop = &amfs_error_ops;
|
||||
} else {
|
||||
/*
|
||||
* Next find the correct filesystem type
|
||||
*/
|
||||
for (vp = vops; (rop = *vp); vp++)
|
||||
if (STREQ(rop->fs_type, fo->opt_type))
|
||||
break;
|
||||
if (!rop) {
|
||||
plog(XLOG_USER, "fs type \"%s\" not recognized", fo->opt_type);
|
||||
rop = &amfs_error_ops;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we have a default mount option.
|
||||
* Otherwise skip past any leading '-'.
|
||||
*/
|
||||
if (fo->opt_opts == 0)
|
||||
fo->opt_opts = strdup("rw,defaults");
|
||||
else if (*fo->opt_opts == '-') {
|
||||
/*
|
||||
* We cannot simply do fo->opt_opts++ here since the opts
|
||||
* module will try to free the pointer fo->opt_opts later.
|
||||
* So just reallocate the thing -- stolcke 11/11/94
|
||||
*/
|
||||
char *old = fo->opt_opts;
|
||||
fo->opt_opts = strdup(old + 1);
|
||||
XFREE(old);
|
||||
}
|
||||
|
||||
/*
|
||||
* If addopts option was used, then append it to the
|
||||
* current options.
|
||||
*/
|
||||
if (fo->opt_addopts) {
|
||||
char *mergedstr;
|
||||
mergedstr = merge_opts(fo->opt_opts, fo->opt_addopts);
|
||||
plog(XLOG_USER, "merge opts \"%s\" add \"%s\" => \"%s\"",
|
||||
fo->opt_opts, fo->opt_addopts, mergedstr);
|
||||
XFREE(fo->opt_opts);
|
||||
fo->opt_opts = mergedstr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the filesystem is happy
|
||||
*/
|
||||
if (fo->fs_mtab)
|
||||
XFREE(fo->fs_mtab);
|
||||
|
||||
if ((fo->fs_mtab = (*rop->fs_match) (fo)))
|
||||
return rop;
|
||||
|
||||
/*
|
||||
* Return error file system
|
||||
*/
|
||||
fo->fs_mtab = (*amfs_error_ops.fs_match) (fo);
|
||||
return &amfs_error_ops;
|
||||
}
|
352
contrib/amd/amd/amd.8
Normal file
352
contrib/amd/amd/amd.8
Normal file
@ -0,0 +1,352 @@
|
||||
.\"
|
||||
.\" Copyright (c) 1997-1998 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 acknowledgment:
|
||||
.\" 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.8,v 5.2.2.1 1992/02/09 15:11:11 jsp beta $
|
||||
.\"
|
||||
.TH AMD 8 "3 November 1989"
|
||||
.SH NAME
|
||||
amd \- automatically mount file systems
|
||||
.SH SYNOPSIS
|
||||
.B amd
|
||||
.B \-H
|
||||
.br
|
||||
.B amd
|
||||
[
|
||||
.BI \-F " conf_file"
|
||||
]
|
||||
.br
|
||||
.B amd
|
||||
[
|
||||
.B \-nprvHS
|
||||
] [
|
||||
.BI \-a " mount_point"
|
||||
] [
|
||||
.BI \-c " duration"
|
||||
] [
|
||||
.BI \-d " domain"
|
||||
] [
|
||||
.BI \-k " kernel-arch"
|
||||
] [
|
||||
.BI \-l " logfile"
|
||||
] [
|
||||
.BI \-o " op_sys_ver"
|
||||
] [
|
||||
.BI \-t " interval.interval"
|
||||
] [
|
||||
.BI \-w " interval"
|
||||
] [
|
||||
.BI \-x " log-option"
|
||||
] [
|
||||
.BI \-y " YP-domain"
|
||||
] [
|
||||
.BI \-C " cluster-name"
|
||||
] [
|
||||
.BI \-D " option"
|
||||
] [
|
||||
.BI \-F " conf_file"
|
||||
] [
|
||||
.BI \-O " op_sys_name"
|
||||
] [
|
||||
.BI \-T " tag"
|
||||
]
|
||||
[
|
||||
.I directory
|
||||
.I mapname
|
||||
.RI [ " \-map-options " ]
|
||||
] .\|.\|.
|
||||
.SH DESCRIPTION
|
||||
.B Amd
|
||||
is a daemon that automatically mounts filesystems
|
||||
whenever a file or directory
|
||||
within that filesystem is accessed.
|
||||
Filesystems are automatically unmounted when they
|
||||
appear to have become quiescent.
|
||||
.LP
|
||||
.B Amd
|
||||
operates by attaching itself as an
|
||||
.SM NFS
|
||||
server to each of the specified
|
||||
.IB directories .
|
||||
Lookups within the specified directories
|
||||
are handled by
|
||||
.BR amd ,
|
||||
which uses the map defined by
|
||||
.I mapname
|
||||
to determine how to resolve the lookup.
|
||||
Generally, this will be a host name, some filesystem information
|
||||
and some mount options for the given filesystem.
|
||||
.LP
|
||||
In the first form depicted above,
|
||||
.B amd
|
||||
will print a short help string. In the second form, if no options are
|
||||
specified, or the
|
||||
.B -F
|
||||
is used,
|
||||
.B amd
|
||||
will read configuration parameters from the file
|
||||
.I conf_file
|
||||
which defaults to
|
||||
.BR /etc/amd.conf .
|
||||
The last form is described below.
|
||||
.SH OPTIONS
|
||||
|
||||
.\"*******************************************************"
|
||||
|
||||
.TP
|
||||
.BI \-a " temporary-directory"
|
||||
Specify an alternative location for the real mount points.
|
||||
The default is
|
||||
.BR /a .
|
||||
|
||||
.TP
|
||||
.BI \-c " duration"
|
||||
Specify a
|
||||
.IR duration ,
|
||||
in seconds, that a looked up name remains
|
||||
cached when not in use. The default is 5 minutes.
|
||||
|
||||
.TP
|
||||
.BI \-d " domain"
|
||||
Specify the local domain name. If this option is not
|
||||
given the domain name is determined from the hostname.
|
||||
|
||||
.TP
|
||||
.BI \-k " kernel-arch"
|
||||
Specifies the kernel architecture. This is used solely
|
||||
to set the ${karch} selector.
|
||||
|
||||
.TP
|
||||
.BI \-l " logfile"
|
||||
Specify a logfile in which to record mount and unmount 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).
|
||||
The default syslog facility used is LOG_DAEMON. If you
|
||||
wish to change it, append its name to the log file name, delimited by a
|
||||
single colon. For example, if
|
||||
.I logfile
|
||||
is the string
|
||||
.B syslog:local7
|
||||
then
|
||||
.B Amd
|
||||
will log messages via
|
||||
.IR syslog (3)
|
||||
using the LOG_LOCAL7 facility (if it exists on the system).
|
||||
|
||||
.TP
|
||||
.B \-n
|
||||
Normalize hostnames.
|
||||
The name refereed to by ${rhost} is normalized relative to the
|
||||
host database before being used. The effect is to translate
|
||||
aliases into ``official'' names.
|
||||
|
||||
.TP
|
||||
.BI \-o " op_sys_ver"
|
||||
Override the compiled-in version number of the operating system. Useful
|
||||
when the built in version is not desired for backward compatibility reasons.
|
||||
For example, if the build in version is ``2.5.1'', you can override it to
|
||||
``5.5.1'', and use older maps that were written with the latter in mind.
|
||||
|
||||
.TP
|
||||
.B \-p
|
||||
Print PID.
|
||||
Outputs the process-id of
|
||||
.B amd
|
||||
to standard output where it can be saved into a file.
|
||||
|
||||
.TP
|
||||
.B \-r
|
||||
Restart existing mounts.
|
||||
.B Amd
|
||||
will scan the mount file table to determine which filesystems
|
||||
are currently mounted. Whenever one of these would have
|
||||
been auto-mounted,
|
||||
.B amd
|
||||
.I inherits
|
||||
it.
|
||||
|
||||
.TP
|
||||
.BI \-t " interval.interval"
|
||||
Specify the
|
||||
.IR interval ,
|
||||
in tenths of a second, between NFS/RPC/UDP retries.
|
||||
The default is 0.8 seconds.
|
||||
The second values alters the restransmit counter.
|
||||
Useful defaults are supplied if either or both
|
||||
values are missing.
|
||||
|
||||
.TP
|
||||
.B \-v
|
||||
Version. Displays version and configuration information on standard error.
|
||||
|
||||
.TP
|
||||
.BI \-w " interval"
|
||||
Specify an
|
||||
.IR interval ,
|
||||
in seconds, between attempts to dismount
|
||||
filesystems that have exceeded their cached times.
|
||||
The default is 2 minutes.
|
||||
|
||||
.TP
|
||||
.BI \-x " 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 \-y " domain"
|
||||
Specify an alternative NIS domain from which to fetch the NIS maps.
|
||||
The default is the system domain name. This option is ignored if NIS
|
||||
support is not available.
|
||||
|
||||
.TP
|
||||
.BI \-C " cluster-name"
|
||||
Specify an alternative HP-UX cluster name to use.
|
||||
|
||||
.TP
|
||||
.BI \-D " option"
|
||||
Select from a variety of debug options. Prefixing an
|
||||
option with the strings
|
||||
.B no
|
||||
reverses the effect of that option. Options are cumulative.
|
||||
The most useful option is
|
||||
.BR all .
|
||||
Since
|
||||
.I \-D
|
||||
is only used for debugging other options are not documented here:
|
||||
the current supported set of options is listed by the \-v option
|
||||
and a fuller description is available in the program source.
|
||||
|
||||
.TP
|
||||
.BI \-F " conf_file"
|
||||
Specify an amd configuration file to use. See
|
||||
.BR amd.conf (5)
|
||||
for description of this file's format. This configuration file is used to
|
||||
specify any options in lieu of typing many of them on the command line. The
|
||||
.I amd.conf
|
||||
file includes directives for every command line option amd has, and many
|
||||
more that are only available via the configuration file facility. The
|
||||
configuration file specified by this option is processed after all other
|
||||
options had been processed, regardless of the actual location of this option
|
||||
on the command line.
|
||||
|
||||
.TP
|
||||
.B \-H
|
||||
Print help and usage string.
|
||||
|
||||
.TP
|
||||
.BI \-O " op_sys_name"
|
||||
Override the compiled-in name of the operating system. Useful when the
|
||||
built in name is not desired for backward compatibility reasons. For
|
||||
example, if the build in name is ``sunos5'', you can override it to
|
||||
``sos5'', and use older maps which were written with the latter in mind.
|
||||
|
||||
.TP
|
||||
.B \-S
|
||||
Do not lock the running executable pages of amd into memory. To improve
|
||||
amd's performance, systems that support the
|
||||
.BR plock (3)
|
||||
call, could lock the amd process into memory. This way there is less chance
|
||||
the operating system will schedule, page out, and swap the amd process as
|
||||
needed. This tends improves amd's performance, at the cost of reserving the
|
||||
memory used by the amd process (making it unavailable for other processes).
|
||||
If this behavior is not desired, use the
|
||||
.B \-S
|
||||
option.
|
||||
|
||||
.TP
|
||||
.BI \-T " tag"
|
||||
Specify a tag to use with
|
||||
.BR amd.conf (5).
|
||||
All map entries tagged with
|
||||
.I tag
|
||||
will be processed. Map entries that are not tagged are always processed.
|
||||
Map entries that are tagged with a tag other than
|
||||
.I tag
|
||||
will not be processed.
|
||||
|
||||
.SH FILES
|
||||
.PD 0
|
||||
.TP 5
|
||||
.B /a
|
||||
directory under which filesystems are dynamically mounted
|
||||
.TP 5
|
||||
.B /etc/amd.conf
|
||||
default configuration file
|
||||
.PD
|
||||
.SH CAVEATS
|
||||
Some care may be required when creating a mount map.
|
||||
.LP
|
||||
Symbolic links on an NFS filesystem can be incredibly inefficient.
|
||||
In most implementations of NFS, their interpolations are not cached
|
||||
by the kernel and each time a symlink is encountered during a
|
||||
.I lookuppn
|
||||
translation it costs an RPC call to the NFS server.
|
||||
It would appear that a large improvement in real-time
|
||||
performance could be gained by adding a cache somewhere.
|
||||
Replacing symlinks with a suitable incarnation of the auto-mounter
|
||||
results in a large real-time speedup, but also causes a large
|
||||
number of process context switches.
|
||||
.LP
|
||||
A weird imagination is most useful to gain full advantage of all
|
||||
the features.
|
||||
.SH "SEE ALSO"
|
||||
.BR amd.conf (5),
|
||||
.BR amq (8),
|
||||
.BR domainname (1),
|
||||
.BR hostname (1),
|
||||
.BR automount (8),
|
||||
.BR mount (8),
|
||||
.BR umount (8),
|
||||
.BR mtab (5),
|
||||
.BR syslog (3).
|
||||
.LP
|
||||
.I "Amd \- The 4.4 BSD Automounter"
|
||||
.SH AUTHORS
|
||||
Jan-Simon Pendry <jsp@doc.ic.ac.uk>, Department of Computing, Imperial College, London, UK.
|
||||
.P
|
||||
Erez Zadok <ezk@cs.columbia.edu>, Department of Computer Science, Columbia
|
||||
University, New York, USA.
|
||||
.P
|
||||
Other authors and contributors to am-utils are listed in the
|
||||
.B AUTHORS
|
||||
file distributed with am-utils.
|
535
contrib/amd/amd/amd.c
Normal file
535
contrib/amd/amd/amd.c
Normal file
@ -0,0 +1,535 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: amd.c,v 5.2.2.1 1992/02/09 15:08:15 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Automounter
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
struct amu_global_options gopt; /* where global options are stored */
|
||||
|
||||
char pid_fsname[16 + MAXHOSTNAMELEN]; /* "kiska.southseas.nz:(pid%d)" */
|
||||
char *progname; /* "amd" */
|
||||
char *hostdomain = "unknown.domain";
|
||||
char hostname[MAXHOSTNAMELEN] = "localhost"; /* Hostname */
|
||||
char hostd[2 * MAXHOSTNAMELEN]; /* Host+domain */
|
||||
char *endian = ARCH_ENDIAN; /* Big or Little endian */
|
||||
char *cpu = HOST_CPU; /* CPU type */
|
||||
char *PrimNetName; /* name of primary network */
|
||||
char *PrimNetNum; /* number of primary network */
|
||||
|
||||
int foreground = 1; /* This is the top-level server */
|
||||
int immediate_abort; /* Should close-down unmounts be retried */
|
||||
int orig_umask;
|
||||
int select_intr_valid;
|
||||
|
||||
jmp_buf select_intr;
|
||||
pid_t mypid; /* Current process id */
|
||||
serv_state amd_state;
|
||||
struct amd_stats amd_stats; /* Server statistics */
|
||||
struct in_addr myipaddr; /* (An) IP address of this host */
|
||||
time_t do_mapc_reload = 0; /* mapc_reload() call required? */
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigset_t masked_sigs;
|
||||
#endif /* HAVE_SIGACTION */
|
||||
|
||||
|
||||
/*
|
||||
* Signal handler:
|
||||
* SIGINT - tells amd to do a full shutdown, including unmounting all
|
||||
* filesystem.
|
||||
* SIGTERM - tells amd to shutdown now. Just unmounts the automount nodes.
|
||||
*/
|
||||
static RETSIGTYPE
|
||||
sigterm(int sig)
|
||||
{
|
||||
#ifdef REINSTALL_SIGNAL_HANDLER
|
||||
signal(sig, sigterm);
|
||||
#endif /* REINSTALL_SIGNAL_HANDLER */
|
||||
|
||||
switch (sig) {
|
||||
case SIGINT:
|
||||
immediate_abort = 15;
|
||||
break;
|
||||
|
||||
case SIGTERM:
|
||||
immediate_abort = -1;
|
||||
/* fall through... */
|
||||
|
||||
default:
|
||||
plog(XLOG_WARNING, "WARNING: automounter going down on signal %d", sig);
|
||||
break;
|
||||
}
|
||||
if (select_intr_valid)
|
||||
longjmp(select_intr, sig);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Hook for cache reload.
|
||||
* When a SIGHUP arrives it schedules a call to mapc_reload
|
||||
*/
|
||||
static RETSIGTYPE
|
||||
sighup(int sig)
|
||||
{
|
||||
#ifdef REINSTALL_SIGNAL_HANDLER
|
||||
signal(sig, sighup);
|
||||
#endif /* REINSTALL_SIGNAL_HANDLER */
|
||||
|
||||
#ifdef DEBUG
|
||||
if (sig != SIGHUP)
|
||||
dlog("spurious call to sighup");
|
||||
#endif /* DEBUG */
|
||||
/*
|
||||
* Force a reload by zero'ing the timer
|
||||
*/
|
||||
if (amd_state == Run)
|
||||
do_mapc_reload = 0;
|
||||
}
|
||||
|
||||
|
||||
static RETSIGTYPE
|
||||
parent_exit(int sig)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
daemon_mode(void)
|
||||
{
|
||||
int bgpid;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction sa, osa;
|
||||
|
||||
sa.sa_handler = parent_exit;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sigaddset(&(sa.sa_mask), SIGQUIT);
|
||||
sigaction(SIGQUIT, &sa, &osa);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
signal(SIGQUIT, parent_exit);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
bgpid = background();
|
||||
|
||||
if (bgpid != 0) {
|
||||
/*
|
||||
* Now wait for the automount points to
|
||||
* complete.
|
||||
*/
|
||||
for (;;)
|
||||
pause();
|
||||
/* should never reache here */
|
||||
}
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigaction(SIGQUIT, &osa, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
signal(SIGQUIT, SIG_DFL);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
/*
|
||||
* Record our pid to make it easier to kill the correct amd.
|
||||
*/
|
||||
if (gopt.flags & CFM_PRINT_PID) {
|
||||
if (STREQ(gopt.pid_file, "/dev/stdout")) {
|
||||
printf("%ld\n", (long) mypid);
|
||||
fflush(stdout);
|
||||
/* do not fclose stdout */
|
||||
} else {
|
||||
FILE *f;
|
||||
mode_t prev_umask = umask(0022); /* set secure temporary umask */
|
||||
|
||||
f = fopen(gopt.pid_file, "w");
|
||||
if (f) {
|
||||
fprintf(f, "%ld\n", (long) mypid);
|
||||
(void) fclose(f);
|
||||
} else {
|
||||
fprintf(stderr, "cannot open %s (errno=%d)\n", gopt.pid_file, errno);
|
||||
}
|
||||
umask(prev_umask); /* restore umask */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pretend we are in the foreground again
|
||||
*/
|
||||
foreground = 1;
|
||||
|
||||
/*
|
||||
* Dissociate from the controlling terminal
|
||||
*/
|
||||
amu_release_controlling_tty();
|
||||
|
||||
return getppid();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize global options structure.
|
||||
*/
|
||||
static void
|
||||
init_global_options(void)
|
||||
{
|
||||
#if defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME)
|
||||
static struct utsname un;
|
||||
#endif /* defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME) */
|
||||
|
||||
memset(&gopt, 0, sizeof(struct amu_global_options));
|
||||
|
||||
/* name of current architecture */
|
||||
gopt.arch = HOST_ARCH;
|
||||
|
||||
/* automounter temp dir */
|
||||
gopt.auto_dir = "/a";
|
||||
|
||||
/* cluster name */
|
||||
gopt.cluster = NULL;
|
||||
|
||||
/*
|
||||
* kernel architecture: this you must get from uname() if possible.
|
||||
*/
|
||||
#if defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME)
|
||||
if (uname(&un) >= 0)
|
||||
gopt.karch = un.machine;
|
||||
else
|
||||
#endif /* defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME) */
|
||||
gopt.karch = HOST_ARCH;
|
||||
|
||||
/* amd log file */
|
||||
gopt.logfile = NULL;
|
||||
|
||||
/* operating system name */
|
||||
gopt.op_sys = HOST_OS_NAME;
|
||||
|
||||
/* OS version */
|
||||
gopt.op_sys_ver = HOST_OS_VERSION;
|
||||
|
||||
/* pid file */
|
||||
gopt.pid_file = "/dev/stdout";
|
||||
|
||||
/* local domain */
|
||||
gopt.sub_domain = NULL;
|
||||
|
||||
/* NFS retransmit counter */
|
||||
gopt.amfs_auto_retrans = -1;
|
||||
|
||||
/* NFS retry interval */
|
||||
gopt.amfs_auto_timeo = -1;
|
||||
|
||||
/* cache duration */
|
||||
gopt.am_timeo = AM_TTL;
|
||||
|
||||
/* dismount interval */
|
||||
gopt.am_timeo_w = AM_TTL_W;
|
||||
|
||||
/*
|
||||
* various CFM_* flags.
|
||||
* by default, only the "plock" option is on (if available).
|
||||
*/
|
||||
gopt.flags = CFM_PROCESS_LOCK;
|
||||
|
||||
#ifdef HAVE_MAP_HESIOD
|
||||
/* Hesiod rhs zone */
|
||||
gopt.hesiod_base = "automount";
|
||||
#endif /* HAVE_MAP_HESIOD */
|
||||
|
||||
#ifdef HAVE_MAP_LDAP
|
||||
/* LDAP base */
|
||||
gopt.ldap_base = NULL;
|
||||
|
||||
/* LDAP host ports */
|
||||
gopt.ldap_hostports = NULL;
|
||||
|
||||
/* LDAP cache */
|
||||
gopt.ldap_cache_seconds = 0;
|
||||
gopt.ldap_cache_maxmem = 131072;
|
||||
#endif /* HAVE_MAP_LDAP */
|
||||
|
||||
#ifdef HAVE_MAP_NIS
|
||||
/* YP domain name */
|
||||
gopt.nis_domain = NULL;
|
||||
#endif /* HAVE_MAP_NIS */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *domdot, *verstr;
|
||||
int ppid = 0;
|
||||
int error;
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction sa;
|
||||
#endif /* HAVE_SIGACTION */
|
||||
|
||||
/*
|
||||
* Make sure some built-in assumptions are true before we start
|
||||
*/
|
||||
assert(sizeof(nfscookie) >= sizeof(u_int));
|
||||
assert(sizeof(int) >= 4);
|
||||
|
||||
/*
|
||||
* Set processing status.
|
||||
*/
|
||||
amd_state = Start;
|
||||
|
||||
/*
|
||||
* Determine program name
|
||||
*/
|
||||
if (argv[0]) {
|
||||
progname = strrchr(argv[0], '/');
|
||||
if (progname && progname[1])
|
||||
progname++;
|
||||
else
|
||||
progname = argv[0];
|
||||
}
|
||||
if (!progname)
|
||||
progname = "amd";
|
||||
|
||||
/*
|
||||
* Initialise process id. This is kept
|
||||
* cached since it is used for generating
|
||||
* and using file handles.
|
||||
*/
|
||||
mypid = getpid();
|
||||
|
||||
/*
|
||||
* Get local machine name
|
||||
*/
|
||||
if (gethostname(hostname, sizeof(hostname)) < 0) {
|
||||
plog(XLOG_FATAL, "gethostname: %m");
|
||||
going_down(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check it makes sense
|
||||
*/
|
||||
if (!*hostname) {
|
||||
plog(XLOG_FATAL, "host name is not set");
|
||||
going_down(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize global options structure.
|
||||
*/
|
||||
init_global_options();
|
||||
|
||||
/*
|
||||
* Partially initialise hostd[]. This
|
||||
* is completed in get_args().
|
||||
*/
|
||||
if ((domdot = strchr(hostname, '.'))) {
|
||||
/*
|
||||
* Hostname already contains domainname.
|
||||
* Split out hostname and domainname
|
||||
* components
|
||||
*/
|
||||
*domdot++ = '\0';
|
||||
hostdomain = domdot;
|
||||
}
|
||||
strcpy(hostd, hostname);
|
||||
|
||||
/*
|
||||
* Trap interrupts for shutdowns.
|
||||
*/
|
||||
#ifdef HAVE_SIGACTION
|
||||
sa.sa_handler = sigterm;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sigaddset(&(sa.sa_mask), SIGINT);
|
||||
sigaddset(&(sa.sa_mask), SIGTERM);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
(void) signal(SIGINT, sigterm);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
/*
|
||||
* Trap Terminate so that we can shutdown gracefully (some chance)
|
||||
*/
|
||||
#ifdef HAVE_SIGACTION
|
||||
sa.sa_handler = sigterm;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sigaddset(&(sa.sa_mask), SIGTERM);
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
(void) signal(SIGTERM, sigterm);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
/*
|
||||
* Hangups tell us to reload the cache
|
||||
*/
|
||||
#ifdef HAVE_SIGACTION
|
||||
sa.sa_handler = sighup;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sigaddset(&(sa.sa_mask), SIGHUP);
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
(void) signal(SIGHUP, sighup);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
/*
|
||||
* Trap Death-of-a-child. These allow us to
|
||||
* pick up the exit status of backgrounded mounts.
|
||||
* See "sched.c".
|
||||
*/
|
||||
#ifdef HAVE_SIGACTION
|
||||
sa.sa_handler = sigchld;
|
||||
sa.sa_flags = 0;
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sigaddset(&(sa.sa_mask), SIGCHLD);
|
||||
sigaction(SIGCHLD, &sa, NULL);
|
||||
|
||||
/*
|
||||
* construct global "masked_sigs" used in nfs_start.c
|
||||
*/
|
||||
sigemptyset(&masked_sigs);
|
||||
sigaddset(&masked_sigs, SIGHUP);
|
||||
sigaddset(&masked_sigs, SIGCHLD);
|
||||
sigaddset(&masked_sigs, SIGTERM);
|
||||
sigaddset(&masked_sigs, SIGINT);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
(void) signal(SIGCHLD, sigchld);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
/*
|
||||
* Fix-up any umask problems. Most systems default
|
||||
* to 002 which is not too convenient for our purposes
|
||||
*/
|
||||
orig_umask = umask(0);
|
||||
|
||||
/*
|
||||
* Figure out primary network name
|
||||
*/
|
||||
getwire(&PrimNetName, &PrimNetNum);
|
||||
|
||||
/*
|
||||
* Determine command-line arguments
|
||||
*/
|
||||
get_args(argc, argv);
|
||||
|
||||
/*
|
||||
* Log version information.
|
||||
*/
|
||||
verstr = strtok(get_version_string(), "\n");
|
||||
plog(XLOG_INFO, "AM-UTILS VERSION INFORMATION:");
|
||||
while (verstr) {
|
||||
plog(XLOG_INFO, verstr);
|
||||
verstr = strtok(NULL, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Get our own IP address so that we
|
||||
* can mount the automounter.
|
||||
*/
|
||||
amu_get_myaddress(&myipaddr);
|
||||
plog(XLOG_INFO, "My ip addr is 0x%x", htonl(myipaddr.s_addr));
|
||||
|
||||
/* avoid hanging on other NFS servers if started elsewhere */
|
||||
if (chdir("/") < 0)
|
||||
plog(XLOG_INFO, "cannot chdir to /: %m");
|
||||
|
||||
/*
|
||||
* Now check we are root.
|
||||
*/
|
||||
if (geteuid() != 0) {
|
||||
plog(XLOG_FATAL, "Must be root to mount filesystems (euid = %d)", geteuid());
|
||||
going_down(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock process text and data segment in memory.
|
||||
*/
|
||||
#ifdef HAVE_PLOCK
|
||||
if (gopt.flags & CFM_PROCESS_LOCK) {
|
||||
if (plock(PROCLOCK) != 0) {
|
||||
plog(XLOG_WARNING, "Couldn't lock process text and data segment in memory: %m");
|
||||
} else {
|
||||
plog(XLOG_INFO, "Locked process text and data segment in memory");
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_PLOCK */
|
||||
|
||||
#ifdef HAVE_MAP_NIS
|
||||
/*
|
||||
* If the domain was specified then bind it here
|
||||
* to circumvent any default bindings that may
|
||||
* be done in the C library.
|
||||
*/
|
||||
if (gopt.nis_domain && yp_bind(gopt.nis_domain)) {
|
||||
plog(XLOG_FATAL, "Can't bind to NIS domain \"%s\"", gopt.nis_domain);
|
||||
going_down(1);
|
||||
}
|
||||
#endif /* HAVE_MAP_NIS */
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_DAEMON)
|
||||
#endif /* DEBUG */
|
||||
ppid = daemon_mode();
|
||||
|
||||
sprintf(pid_fsname, "%s:(pid%ld)", hostname, (long) mypid);
|
||||
|
||||
do_mapc_reload = clocktime() + ONE_HOUR;
|
||||
|
||||
/*
|
||||
* Register automounter with system.
|
||||
*/
|
||||
error = mount_automounter(ppid);
|
||||
if (error && ppid)
|
||||
kill(SIGALRM, ppid);
|
||||
going_down(error);
|
||||
|
||||
abort();
|
||||
return 1; /* should never get here */
|
||||
}
|
303
contrib/amd/amd/amd.h
Normal file
303
contrib/amd/amd/amd.h
Normal file
@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 1996/01/13 23:23:39 ezk Exp ezk $
|
||||
*
|
||||
*/
|
||||
|
||||
#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_PROCESS_LOCK 0x0010
|
||||
#define CFM_PRINT_PID 0x0020
|
||||
#define CFM_RESTART_EXISTING_MOUNTS 0x0040
|
||||
#define CFM_SHOW_STATFS_ENTRIES 0x0080
|
||||
#define CFM_FULLY_QUALIFIED_HOSTS 0x0100
|
||||
#define CFM_BROWSABLE_DIRS_FULL 0x0200 /* allow '/' in readdir() */
|
||||
#define CFM_UNMOUNT_ON_EXIT 0x0400 /* when amd finishing */
|
||||
|
||||
/* 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 */
|
||||
|
||||
/* interval between forced retries of a mount */
|
||||
#define RETRY_INTERVAL 2
|
||||
|
||||
#define ereturn(x) { *error_return = x; return 0; }
|
||||
|
||||
|
||||
/*
|
||||
* 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 isup_fn(mnt_map *, char *);
|
||||
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 *pid_file; /* PID file */
|
||||
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 amfs_auto_retrans; /* NFS retransmit counter */
|
||||
int amfs_auto_timeo; /* NFS retry interval */
|
||||
int am_timeo; /* cache duration */
|
||||
int am_timeo_w; /* dismount interval */
|
||||
int portmap_program; /* amd RPC program number */
|
||||
#ifdef HAVE_MAP_HESIOD
|
||||
char *hesiod_base; /* Hesiod rhs */
|
||||
#endif /* HAVE_MAP_HESIOD */
|
||||
#ifdef HAVE_MAP_LDAP
|
||||
char *ldap_base; /* LDAP base */
|
||||
char *ldap_hostports; /* LDAP host ports */
|
||||
long ldap_cache_seconds; /* LDAP internal cache - keep seconds */
|
||||
long ldap_cache_maxmem; /* LDAP internal cache - max memory (bytes) */
|
||||
#endif /* HAVE_MAP_LDAP */
|
||||
#ifdef HAVE_MAP_NIS
|
||||
char *nis_domain; /* YP domain name */
|
||||
#endif /* HAVE_MAP_NIS */
|
||||
};
|
||||
|
||||
/* if you add anything here, update conf.c:reset_cf_map() */
|
||||
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 */
|
||||
isup_fn *isup; /* Is service up or not? (1=up, 0=down) */
|
||||
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 */
|
||||
void *map_data; /* Map data black box */
|
||||
};
|
||||
|
||||
/*
|
||||
* Mounting a file system may take a significant period of time. The
|
||||
* problem is that if this is done in the main process thread then
|
||||
* the entire automounter could be blocked, possibly hanging lots of
|
||||
* processes on the system. Instead we use a continuation scheme to
|
||||
* allow mounts to be attempted in a sub-process. When the sub-process
|
||||
* exits we pick up the exit status (by convention a UN*X error number)
|
||||
* and continue in a notifier. The notifier gets handed a data structure
|
||||
* and can then determine whether the mount was successful or not. If
|
||||
* not, it updates the data structure and tries again until there are no
|
||||
* more ways to try the mount, or some other permanent error occurs.
|
||||
* In the mean time no RPC reply is sent, even after the mount is succesful.
|
||||
* We rely on the RPC retry mechanism to resend the lookup request which
|
||||
* can then be handled.
|
||||
*/
|
||||
struct continuation {
|
||||
char **ivec; /* Current mount info */
|
||||
am_node *mp; /* Node we are trying to mount */
|
||||
char *key; /* Map key */
|
||||
char *info; /* Info string */
|
||||
char **xivec; /* Saved strsplit vector */
|
||||
char *auto_opts; /* Automount options */
|
||||
am_opts fs_opts; /* Filesystem options */
|
||||
char *def_opts; /* Default automount options */
|
||||
int retry; /* Try again? */
|
||||
int tried; /* Have we tried any yet? */
|
||||
time_t start; /* Time we started this mount */
|
||||
int callout; /* Callout identifier */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* EXTERNALS:
|
||||
*/
|
||||
|
||||
/* Amq server 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_getpid_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);
|
||||
|
||||
/* other external definitions */
|
||||
extern am_nfs_fh *root_fh(char *dir);
|
||||
extern am_node * autofs_lookuppn(am_node *mp, char *fname, int *error_return, int op);
|
||||
extern am_node *find_ap(char *);
|
||||
extern am_node *find_ap2(char *, am_node *);
|
||||
extern bool_t xdr_amq_mount_info_qelem(XDR *xdrs, qelem *qhead);
|
||||
extern fserver *find_nfs_srvr(mntfs *mf);
|
||||
extern int auto_fmount(am_node *mp);
|
||||
extern int auto_fumount(am_node *mp);
|
||||
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 int try_mount(voidp mvp);
|
||||
extern int yyparse (void);
|
||||
extern nfsentry *make_entry_chain(am_node *mp, const nfsentry *current_chain, int fully_browsable);
|
||||
extern void amfs_auto_cont(int rc, int term, voidp closure);
|
||||
extern void amfs_auto_mkcacheref(mntfs *mf);
|
||||
extern void amfs_auto_retry(int rc, int term, voidp closure);
|
||||
extern void assign_error_mntfs(am_node *mp);
|
||||
extern void flush_srvr_nfs_cache(void);
|
||||
extern void free_continuation(struct continuation *cp);
|
||||
extern void mf_mounted(mntfs *mf);
|
||||
extern void quick_reply(am_node *mp, int error);
|
||||
extern void root_newmap(const char *, const char *, const char *, const cf_map_t *);
|
||||
|
||||
/* amd global variables */
|
||||
extern FILE *yyin;
|
||||
extern SVCXPRT *nfs_program_2_transp; /* For quick_reply() */
|
||||
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 jmp_buf select_intr;
|
||||
extern qelem mfhead;
|
||||
extern struct amu_global_options gopt; /* where global options are stored */
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
extern sigset_t masked_sigs;
|
||||
#endif /* HAVE_SIGACTION */
|
||||
|
||||
#if defined(HAVE_AM_FS_LINK) || defined(HAVE_AM_FS_LINKX)
|
||||
extern char *amfs_link_match(am_opts *fo);
|
||||
extern int amfs_link_fumount(mntfs *mf);
|
||||
#endif /* defined(HAVE_AM_FS_LINK) || defined(HAVE_AM_FS_LINKX) */
|
||||
|
||||
#ifdef HAVE_AM_FS_NFSL
|
||||
extern char *nfs_match(am_opts *fo);
|
||||
#endif /* HAVE_AM_FS_NFSL */
|
||||
|
||||
#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) */
|
||||
|
||||
#ifdef HAVE_FS_AUTOFS
|
||||
extern SVCXPRT *autofsxprt;
|
||||
extern u_short autofs_port;
|
||||
|
||||
extern int autofs_mount(am_node *mp);
|
||||
extern int autofs_umount(am_node *mp);
|
||||
extern int create_autofs_service(int *soAUTOFSp, u_short *autofs_portp, SVCXPRT **autofs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp));
|
||||
extern int svc_create_local_service(void (*dispatch) (), u_long prognum, u_long versnum, char *nettype, char *servname);
|
||||
extern void autofs_mounted(mntfs *mf);
|
||||
extern void autofs_program_1(struct svc_req *rqstp, SVCXPRT *transp);
|
||||
#endif /* HAVE_FS_AUTOFS */
|
||||
|
||||
/* Unix file system (irix) */
|
||||
#ifdef HAVE_FS_XFS
|
||||
extern am_ops xfs_ops; /* Un*x file system */
|
||||
#endif /* HAVE_FS_XFS */
|
||||
|
||||
/* Unix file system (irix) */
|
||||
#ifdef HAVE_FS_EFS
|
||||
extern am_ops efs_ops; /* Un*x file system */
|
||||
#endif /* HAVE_FS_EFS */
|
||||
|
||||
#endif /* not _AMD_H */
|
1595
contrib/amd/amd/amfs_auto.c
Normal file
1595
contrib/amd/amd/amfs_auto.c
Normal file
File diff suppressed because it is too large
Load Diff
106
contrib/amd/amd/amfs_direct.c
Normal file
106
contrib/amd/amd/amfs_direct.c
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: amfs_direct.c,v 1.1 1997-1998/06/30 19:22:30 ezk Exp ezk $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Direct file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/****************************************************************************
|
||||
*** FORWARD DEFINITIONS ***
|
||||
****************************************************************************/
|
||||
static am_node *amfs_direct_readlink(am_node *mp, int *error_return);
|
||||
|
||||
/****************************************************************************
|
||||
*** OPS STRUCTURES ***
|
||||
****************************************************************************/
|
||||
am_ops amfs_direct_ops =
|
||||
{
|
||||
"direct",
|
||||
amfs_auto_match,
|
||||
0, /* amfs_direct_init */
|
||||
amfs_toplvl_mount,
|
||||
0,
|
||||
amfs_toplvl_umount,
|
||||
0,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
amfs_direct_readlink,
|
||||
amfs_toplvl_mounted,
|
||||
0, /* amfs_auto_umounted */
|
||||
find_amfs_auto_srvr,
|
||||
FS_MKMNT | FS_NOTIMEOUT | FS_BACKGROUND | FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*** FUNCTIONS ***
|
||||
****************************************************************************/
|
||||
|
||||
static am_node *
|
||||
amfs_direct_readlink(am_node *mp, int *error_return)
|
||||
{
|
||||
am_node *xp;
|
||||
int rc = 0;
|
||||
|
||||
xp = next_nonerror_node(mp->am_child);
|
||||
if (!xp) {
|
||||
if (!mp->am_mnt->mf_private)
|
||||
amfs_auto_mkcacheref(mp->am_mnt); /* XXX */
|
||||
xp = amfs_auto_lookuppn(mp, mp->am_path + 1, &rc, VLOOK_CREATE);
|
||||
}
|
||||
if (xp) {
|
||||
new_ttl(xp); /* (7/12/89) from Rein Tollevik */
|
||||
return xp;
|
||||
}
|
||||
if (amd_state == Finishing)
|
||||
rc = ENOENT;
|
||||
*error_return = rc;
|
||||
return 0;
|
||||
}
|
150
contrib/amd/amd/amfs_error.c
Normal file
150
contrib/amd/amd/amfs_error.c
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: amfs_error.c,v 5.2.2.1 1992/02/09 15:08:21 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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>
|
||||
|
||||
static char * amfs_error_match(am_opts *fo);
|
||||
static int amfs_error_fmount(mntfs *mf);
|
||||
static int amfs_error_fumount(mntfs *mf);
|
||||
static void amfs_error_umounted(am_node *mp);
|
||||
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops amfs_error_ops =
|
||||
{
|
||||
"error",
|
||||
amfs_error_match,
|
||||
0, /* amfs_error_init */
|
||||
amfs_auto_fmount,
|
||||
amfs_error_fmount,
|
||||
amfs_auto_fumount,
|
||||
amfs_error_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* amfs_error_readlink */
|
||||
0, /* amfs_error_mounted */
|
||||
amfs_error_umounted,
|
||||
find_amfs_auto_srvr,
|
||||
FS_DISCARD
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* EFS file system always matches
|
||||
*/
|
||||
static char *
|
||||
amfs_error_match(am_opts *fo)
|
||||
{
|
||||
return strdup("(error-hook)");
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
amfs_error_fmount(mntfs *mf)
|
||||
{
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
amfs_error_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 *
|
||||
amfs_error_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
|
||||
amfs_error_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
|
||||
amfs_error_umounted(am_node *mp)
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
686
contrib/amd/amd/amfs_host.c
Normal file
686
contrib/amd/amd/amfs_host.c
Normal file
@ -0,0 +1,686 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: amfs_host.c,v 5.2.2.2 1992/05/31 16:36:08 jsp 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 *amfs_host_match(am_opts *fo);
|
||||
static int amfs_host_fmount(mntfs *mf);
|
||||
static int amfs_host_fumount(mntfs *mf);
|
||||
static int amfs_host_init(mntfs *mf);
|
||||
static void amfs_host_umounted(am_node *mp);
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops amfs_host_ops =
|
||||
{
|
||||
"host",
|
||||
amfs_host_match,
|
||||
amfs_host_init,
|
||||
amfs_auto_fmount,
|
||||
amfs_host_fmount,
|
||||
amfs_auto_fumount,
|
||||
amfs_host_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* amfs_host_readlink */
|
||||
0, /* amfs_host_mounted */
|
||||
amfs_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 *
|
||||
amfs_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
|
||||
amfs_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
|
||||
* amfs_auto 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. amfs_auto_cont() is already sleeping on this mntfs
|
||||
* so as soon as that wakeup happens amfs_auto_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("amfs_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
|
||||
amfs_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, mnttab_file_name);
|
||||
|
||||
#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, "amfs_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) {
|
||||
#ifdef HAVE_CLNT_SPCREATEERROR
|
||||
plog(XLOG_ERROR, "get_mount_client failed for %s: %s",
|
||||
host, clnt_spcreateerror(""));
|
||||
#else /* not HAVE_CLNT_SPCREATEERROR */
|
||||
plog(XLOG_ERROR, "get_mount_client failed for %s", host);
|
||||
#endif /* not HAVE_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, "amfs_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)
|
||||
XFREE(ep);
|
||||
if (fp)
|
||||
XFREE(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 (!NSTREQ(pref, dir, len))
|
||||
return FALSE;
|
||||
if (dir[len] == '/' || dir[len] == '\0')
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unmount a mount tree
|
||||
*/
|
||||
static int
|
||||
amfs_host_fumount(mntfs *mf)
|
||||
{
|
||||
mntlist *ml, *mprev;
|
||||
int xerror = 0;
|
||||
|
||||
/*
|
||||
* Read the mount list
|
||||
*/
|
||||
mntlist *mlist = read_mtab(mf->mf_mount, mnttab_file_name);
|
||||
|
||||
#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("amfs_host: unmounts %s", dir);
|
||||
#endif /* DEBUG */
|
||||
/*
|
||||
* Unmount "dir"
|
||||
*/
|
||||
error = UMOUNT_FS(dir, mnttab_file_name);
|
||||
/*
|
||||
* 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 = amfs_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
|
||||
amfs_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, "amfs_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) {
|
||||
#ifdef HAVE_CLNT_SPCREATEERROR
|
||||
plog(XLOG_ERROR, "get_mount_client failed for %s: %s",
|
||||
host, clnt_spcreateerror(""));
|
||||
#else /* not HAVE_CLNT_SPCREATEERROR */
|
||||
plog(XLOG_ERROR, "get_mount_client failed for %s", host);
|
||||
#endif /* not HAVE_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
contrib/amd/amd/amfs_inherit.c
Normal file
200
contrib/amd/amd/amfs_inherit.c
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: amfs_inherit.c,v 5.2.2.1 1992/02/09 15:08:26 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 *amfs_inherit_match(am_opts *fo);
|
||||
static int amfs_inherit_fmount(mntfs *mf);
|
||||
static int amfs_inherit_fumount(mntfs *mf);
|
||||
static int amfs_inherit_init(mntfs *mf);
|
||||
static int amfs_inherit_mount(am_node *mp);
|
||||
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops amfs_inherit_ops =
|
||||
{
|
||||
"inherit",
|
||||
amfs_inherit_match,
|
||||
amfs_inherit_init,
|
||||
amfs_inherit_mount,
|
||||
amfs_inherit_fmount,
|
||||
amfs_auto_fumount,
|
||||
amfs_inherit_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* amfs_inherit_readlink */
|
||||
0, /* amfs_inherit_mounted */
|
||||
0, /* amfs_inherit_umounted */
|
||||
find_amfs_auto_srvr,
|
||||
FS_DISCARD
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* This should never be called.
|
||||
*/
|
||||
static char *
|
||||
amfs_inherit_match(am_opts *fo)
|
||||
{
|
||||
plog(XLOG_FATAL, "amfs_inherit_match called!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
amfs_inherit_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 *
|
||||
amfs_inherit_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
|
||||
amfs_inherit_mount(am_node *mp)
|
||||
{
|
||||
mntfs *newmf = amfs_inherit_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
|
||||
amfs_inherit_fmount(mntfs *mf)
|
||||
{
|
||||
am_node *mp = find_mf(mf);
|
||||
|
||||
if (mp)
|
||||
return amfs_inherit_mount(mp);
|
||||
return amfs_inherit_inherit(mf) ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
amfs_inherit_fumount(mntfs *mf)
|
||||
{
|
||||
/*
|
||||
* Always succeed
|
||||
*/
|
||||
return 0;
|
||||
}
|
141
contrib/amd/amd/amfs_link.c
Normal file
141
contrib/amd/amd/amfs_link.c
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: amfs_link.c,v 5.2.2.1 1992/02/09 15:09:04 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Symbol-link file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
|
||||
/*
|
||||
* Ops structures
|
||||
*/
|
||||
am_ops amfs_link_ops =
|
||||
{
|
||||
"link",
|
||||
amfs_link_match,
|
||||
0, /* amfs_link_init */
|
||||
amfs_auto_fmount,
|
||||
amfs_link_fmount,
|
||||
amfs_auto_fumount,
|
||||
amfs_link_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* amfs_link_readlink */
|
||||
0, /* amfs_link_mounted */
|
||||
0, /* amfs_link_umounted */
|
||||
find_amfs_auto_srvr,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* SFS needs a link.
|
||||
*/
|
||||
char *
|
||||
amfs_link_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)
|
||||
XFREE(fo->opt_sublink);
|
||||
fo->opt_sublink = fullpath;
|
||||
fo->opt_fs = str3cat(fo->opt_fs, ".", fullpath, "");
|
||||
}
|
||||
|
||||
return strdup(fo->opt_fs);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
amfs_link_fmount(mntfs *mf)
|
||||
{
|
||||
/*
|
||||
* Wow - this is hard to implement! :-)
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
amfs_link_fumount(mntfs *mf)
|
||||
{
|
||||
return 0;
|
||||
}
|
104
contrib/amd/amd/amfs_linkx.c
Normal file
104
contrib/amd/amd/amfs_linkx.c
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: amfs_linkx.c,v 5.2.2.1 1992/02/09 15:09:04 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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>
|
||||
|
||||
/* forward declarations */
|
||||
static int amfs_linkx_mount(am_node *mp);
|
||||
|
||||
/*
|
||||
* linkx operations
|
||||
*/
|
||||
struct am_ops amfs_linkx_ops =
|
||||
{
|
||||
"linkx",
|
||||
amfs_link_match,
|
||||
0, /* amfs_linkx_init */
|
||||
amfs_linkx_mount,
|
||||
0,
|
||||
amfs_auto_fumount,
|
||||
amfs_link_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* amfs_linkx_readlink */
|
||||
0, /* amfs_linkx_mounted */
|
||||
0, /* amfs_linkx_umounted */
|
||||
find_amfs_auto_srvr,
|
||||
FS_MBACKGROUND
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
amfs_linkx_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;
|
||||
}
|
||||
|
237
contrib/amd/amd/amfs_nfsl.c
Normal file
237
contrib/amd/amd/amfs_nfsl.c
Normal file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: amfs_nfsl.c,v 5.2.2.3 1992/08/02 10:42:21 jsp Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* NFSL: Network file system with local existence check. If the local
|
||||
* path denoted by $rfs exists, it behaves as type:=link.
|
||||
*
|
||||
* Example:
|
||||
* pkg type:=nfsl;rhost:=jonny;rfs:=/n/johnny/src/pkg;fs:=${rfs}
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
|
||||
/* forward declarations */
|
||||
static char *amfs_nfsl_match(am_opts *fo);
|
||||
static int amfs_nfsl_init(mntfs *mf);
|
||||
static int amfs_nfsl_fmount(mntfs *mf);
|
||||
static int amfs_nfsl_fumount(mntfs *mf);
|
||||
static void amfs_nfsl_umounted(am_node *mp);
|
||||
static fserver *amfs_nfsl_ffserver(mntfs *mf);
|
||||
|
||||
/*
|
||||
* NFS-Link operations
|
||||
*/
|
||||
am_ops amfs_nfsl_ops =
|
||||
{
|
||||
"nfsl", /* name of file system */
|
||||
amfs_nfsl_match, /* match */
|
||||
amfs_nfsl_init, /* initialize */
|
||||
amfs_auto_fmount, /* mount vnode */
|
||||
amfs_nfsl_fmount, /* mount vfs */
|
||||
amfs_auto_fumount, /* unmount vnode */
|
||||
amfs_nfsl_fumount, /* unmount VFS */
|
||||
amfs_error_lookuppn, /* lookup path-name */
|
||||
amfs_error_readdir, /* read directory */
|
||||
0, /* read link */
|
||||
0, /* after-mount extra actions */
|
||||
amfs_nfsl_umounted, /* after-umount extra actions */
|
||||
amfs_nfsl_ffserver, /* find a file server */
|
||||
FS_MKMNT | FS_BACKGROUND | FS_AMQINFO /* flags */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Check that f/s has all needed fields.
|
||||
* Returns: matched string if found, NULL otherwise.
|
||||
*/
|
||||
static char *
|
||||
amfs_nfsl_match(am_opts *fo)
|
||||
{
|
||||
char *cp = fo->opt_fs;
|
||||
char *ho = fo->opt_rhost;
|
||||
struct stat stb;
|
||||
|
||||
if (!cp || !ho) {
|
||||
plog(XLOG_USER, "amfs_nfsl: nost $fs and $rhost must be specified");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this host is not the same as $rhost, or if link does not exist,
|
||||
* perform nfs_match(), same as for type:=nfs.
|
||||
* If link value exists (or same host), then perform amfs_link_match(),
|
||||
* same as for linkx.
|
||||
*/
|
||||
if (!STRCEQ(ho, hostname)) {
|
||||
plog(XLOG_INFO, "amfs_nfsl: \"%s\" is not local host, using type:=nfs", ho);
|
||||
return nfs_match(fo);
|
||||
} else if (lstat(cp, &stb) < 0) {
|
||||
plog(XLOG_INFO, "amfs_nfsl: \"%s\" does not exist, using type:=nfs", cp);
|
||||
return nfs_match(fo);
|
||||
} else {
|
||||
plog(XLOG_INFO, "amfs_nfsl: \"%s\" exists, using type:=link", cp);
|
||||
return amfs_link_match(fo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
* Returns: 0 if OK, non-zero (errno) if failed.
|
||||
*/
|
||||
static int
|
||||
amfs_nfsl_init(mntfs *mf)
|
||||
{
|
||||
/*
|
||||
* If a link, do nothing (same as type:=link).
|
||||
* If non-link, do nfs_init (same as type:=nfs).
|
||||
*/
|
||||
if (mf->mf_flags & MFF_NFSLINK) {
|
||||
return 0;
|
||||
} else {
|
||||
return nfs_init(mf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mount vfs.
|
||||
* Returns: 0 if OK, non-zero (errno) if failed.
|
||||
*/
|
||||
static int
|
||||
amfs_nfsl_fmount(mntfs *mf)
|
||||
{
|
||||
/*
|
||||
* If a link, do run amfs_link_fmount() (same as type:=link)
|
||||
* If non-link, do nfs_fmount (same as type:=nfs).
|
||||
*/
|
||||
if (mf->mf_flags & MFF_NFSLINK) {
|
||||
return amfs_link_fmount(mf);
|
||||
} else {
|
||||
return nfs_fmount(mf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unmount VFS.
|
||||
* Returns: 0 if OK, non-zero (errno) if failed.
|
||||
*/
|
||||
static int
|
||||
amfs_nfsl_fumount(mntfs *mf)
|
||||
{
|
||||
/*
|
||||
* If a link, do run amfs_link_fumount() (same as type:=link)
|
||||
* If non-link, do nfs_fumount (same as type:=nfs).
|
||||
*/
|
||||
if (mf->mf_flags & MFF_NFSLINK) {
|
||||
return amfs_link_fumount(mf);
|
||||
} else {
|
||||
return nfs_fumount(mf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Async unmount callback function.
|
||||
* After the base umount() succeeds, we may want to take extra actions,
|
||||
* such as informing remote mount daemons that we've unmounted them.
|
||||
* See amfs_auto_umounted(), host_umounted(), nfs_umounted().
|
||||
*/
|
||||
static void
|
||||
amfs_nfsl_umounted(am_node *mp)
|
||||
{
|
||||
mntfs *mf = mp->am_mnt;
|
||||
|
||||
/*
|
||||
* If a link, do nothing (same as type:=link)
|
||||
* If non-link, do nfs_fumount (same as type:=nfs).
|
||||
*/
|
||||
if (mf->mf_flags & MFF_NFSLINK) {
|
||||
return;
|
||||
} else {
|
||||
nfs_umounted(mp);
|
||||
/*
|
||||
* MUST remove mount point directories, because if they remain
|
||||
* behind, the next nfsl access will think they are a link
|
||||
* type file system, and not NFS! (when it performs link target
|
||||
* existence test)
|
||||
*/
|
||||
if (mf->mf_flags & MFF_MKMNT)
|
||||
rmdirs(mf->mf_mount);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find a file server.
|
||||
* Returns: fserver of found server, or NULL if not found.
|
||||
*/
|
||||
static fserver *
|
||||
amfs_nfsl_ffserver(mntfs *mf)
|
||||
{
|
||||
char *cp = mf->mf_fo->opt_fs;
|
||||
char *ho = mf->mf_fo->opt_rhost;
|
||||
struct stat stb;
|
||||
|
||||
/*
|
||||
* If this host is not the same as $rhost, or if link does not exist,
|
||||
* perform find_nfs_srvr(), same as for type:=nfs.
|
||||
* If link value exists (or same host), then perform
|
||||
* find_amfs_auto_srvr(), same as for linkx.
|
||||
*/
|
||||
if (!STREQ(ho, hostname) || lstat(cp, &stb) < 0) {
|
||||
return find_nfs_srvr(mf);
|
||||
} else {
|
||||
mf->mf_flags |= MFF_NFSLINK;
|
||||
return find_amfs_auto_srvr(mf);
|
||||
}
|
||||
}
|
532
contrib/amd/amd/amfs_nfsx.c
Normal file
532
contrib/amd/amd/amfs_nfsx.c
Normal file
@ -0,0 +1,532 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: amfs_linxx.c,v 5.2.2.3 1992/05/31 16:13:07 jsp 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 amfs_nfsx_mnt {
|
||||
mntfs *n_mnt;
|
||||
int n_error;
|
||||
} amfs_nfsx_mnt;
|
||||
|
||||
struct amfs_nfsx {
|
||||
int nx_c; /* Number of elements in nx_v */
|
||||
amfs_nfsx_mnt *nx_v; /* Underlying mounts */
|
||||
amfs_nfsx_mnt *nx_try;
|
||||
};
|
||||
|
||||
/* forward definitions */
|
||||
static char *amfs_nfsx_match(am_opts *fo);
|
||||
static int amfs_nfsx_fmount (mntfs *);
|
||||
static int amfs_nfsx_fmount(mntfs *mf);
|
||||
static int amfs_nfsx_fumount(mntfs *mf);
|
||||
static int amfs_nfsx_init(mntfs *mf);
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops amfs_nfsx_ops =
|
||||
{
|
||||
"nfsx",
|
||||
amfs_nfsx_match,
|
||||
amfs_nfsx_init,
|
||||
amfs_auto_fmount,
|
||||
amfs_nfsx_fmount,
|
||||
amfs_auto_fumount,
|
||||
amfs_nfsx_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* amfs_nfsx_readlink */
|
||||
0, /* amfs_nfsx_mounted */
|
||||
0, /* amfs_nfsx_umounted */
|
||||
find_nfs_srvr, /* XXX */
|
||||
/* FS_UBACKGROUND| */ FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
static char *
|
||||
amfs_nfsx_match(am_opts *fo)
|
||||
{
|
||||
char *xmtab;
|
||||
char *ptr;
|
||||
int len;
|
||||
|
||||
if (!fo->opt_rfs) {
|
||||
plog(XLOG_USER, "amfs_nfsx: no remote filesystem specified");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!fo->opt_rhost) {
|
||||
plog(XLOG_USER, "amfs_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
|
||||
amfs_nfsx_prfree(voidp vp)
|
||||
{
|
||||
struct amfs_nfsx *nx = (struct amfs_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);
|
||||
}
|
||||
|
||||
XFREE(nx->nx_v);
|
||||
XFREE(nx);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
amfs_nfsx_init(mntfs *mf)
|
||||
{
|
||||
/*
|
||||
* mf_info has the form:
|
||||
* host:/prefix/path,sub,sub,sub
|
||||
*/
|
||||
int i;
|
||||
int glob_error;
|
||||
struct amfs_nfsx *nx;
|
||||
int asked_for_wakeup = 0;
|
||||
|
||||
nx = (struct amfs_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 amfs_nfsx);
|
||||
mf->mf_private = (voidp) nx;
|
||||
mf->mf_prfree = amfs_nfsx_prfree;
|
||||
|
||||
nx->nx_c = i - 1; /* i-1 because we don't want the prefix */
|
||||
nx->nx_v = (amfs_nfsx_mnt *) xmalloc(nx->nx_c * sizeof(amfs_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("amfs_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)
|
||||
XFREE(rfs);
|
||||
if (mp)
|
||||
XFREE(mp);
|
||||
if (xinfo)
|
||||
XFREE(xinfo);
|
||||
}
|
||||
|
||||
XFREE(ivec);
|
||||
errexit:
|
||||
if (info)
|
||||
XFREE(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++) {
|
||||
amfs_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
|
||||
amfs_nfsx_cont(int rc, int term, voidp closure)
|
||||
{
|
||||
mntfs *mf = (mntfs *) closure;
|
||||
struct amfs_nfsx *nx = (struct amfs_nfsx *) mf->mf_private;
|
||||
amfs_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 (amfs_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 (amfs_nfsx_fmount(mf) >= 0) {
|
||||
wakeup((voidp) mf);
|
||||
mf->mf_flags &= ~MFF_MOUNTING;
|
||||
mf_mounted(mf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
try_amfs_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
|
||||
amfs_nfsx_remount(mntfs *mf, int fg)
|
||||
{
|
||||
struct amfs_nfsx *nx = (struct amfs_nfsx *) mf->mf_private;
|
||||
amfs_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_amfs_nfsx_mount, (voidp) m, amfs_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
|
||||
amfs_nfsx_fmount(mntfs *mf)
|
||||
{
|
||||
return amfs_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
|
||||
amfs_nfsx_fumount(mntfs *mf)
|
||||
{
|
||||
struct amfs_nfsx *nx = (struct amfs_nfsx *) mf->mf_private;
|
||||
amfs_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 = amfs_nfsx_remount(mf, TRUE);
|
||||
if (glob_error) {
|
||||
errno = glob_error; /* XXX */
|
||||
plog(XLOG_USER, "amfs_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;
|
||||
}
|
191
contrib/amd/amd/amfs_program.c
Normal file
191
contrib/amd/amd/amfs_program.c
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: amfs_program.c,v 5.2.2.1 1992/02/09 15:08:56 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 *amfs_program_match(am_opts *fo);
|
||||
static int amfs_program_fmount(mntfs *mf);
|
||||
static int amfs_program_fumount(mntfs *mf);
|
||||
static int amfs_program_init(mntfs *mf);
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops amfs_program_ops =
|
||||
{
|
||||
"program",
|
||||
amfs_program_match,
|
||||
amfs_program_init,
|
||||
amfs_auto_fmount,
|
||||
amfs_program_fmount,
|
||||
amfs_auto_fumount,
|
||||
amfs_program_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* amfs_program_readlink */
|
||||
0, /* amfs_program_mounted */
|
||||
0, /* amfs_program_umounted */
|
||||
find_amfs_auto_srvr,
|
||||
FS_BACKGROUND | FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Execute needs a mount and unmount command.
|
||||
*/
|
||||
static char *
|
||||
amfs_program_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
|
||||
amfs_program_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 (*)(voidp)) free;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
amfs_program_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
|
||||
*/
|
||||
XFREE(info);
|
||||
XFREE(xivec);
|
||||
|
||||
/*
|
||||
* Return error
|
||||
*/
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
amfs_program_fmount(mntfs *mf)
|
||||
{
|
||||
return amfs_program_exec(mf->mf_fo->opt_mount);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
amfs_program_fumount(mntfs *mf)
|
||||
{
|
||||
return amfs_program_exec((char *) mf->mf_private);
|
||||
}
|
99
contrib/amd/amd/amfs_root.c
Normal file
99
contrib/amd/amd/amfs_root.c
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: amfs_root.c,v 1.1 1997-1998/06/30 19:22:30 ezk Exp ezk $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Root file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/****************************************************************************
|
||||
*** FORWARD DEFINITIONS ***
|
||||
****************************************************************************/
|
||||
static int amfs_root_mount(am_node *mp);
|
||||
|
||||
/****************************************************************************
|
||||
*** OPS STRUCTURES ***
|
||||
****************************************************************************/
|
||||
am_ops amfs_root_ops =
|
||||
{
|
||||
"root",
|
||||
0, /* amfs_root_match */
|
||||
0, /* amfs_root_init */
|
||||
amfs_root_mount,
|
||||
0,
|
||||
amfs_auto_umount,
|
||||
0,
|
||||
amfs_auto_lookuppn,
|
||||
amfs_auto_readdir,
|
||||
0, /* amfs_root_readlink */
|
||||
0, /* amfs_root_mounted */
|
||||
0, /* amfs_root_umounted */
|
||||
find_amfs_auto_srvr,
|
||||
FS_NOTIMEOUT | FS_AMQINFO | FS_DIRECTORY
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*** FUNCTIONS ***
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Mount the root...
|
||||
*/
|
||||
static int
|
||||
amfs_root_mount(am_node *mp)
|
||||
{
|
||||
mntfs *mf = mp->am_mnt;
|
||||
|
||||
mf->mf_mount = strealloc(mf->mf_mount, pid_fsname);
|
||||
mf->mf_private = (voidp) mapc_find(mf->mf_info, "", NULL);
|
||||
mf->mf_prfree = mapc_free;
|
||||
|
||||
return 0;
|
||||
}
|
355
contrib/amd/amd/amfs_toplvl.c
Normal file
355
contrib/amd/amd/amfs_toplvl.c
Normal file
@ -0,0 +1,355 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: amfs_toplvl.c,v 1.1 1997-1998/06/30 19:22:30 ezk Exp ezk $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Top-level file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/****************************************************************************
|
||||
*** FORWARD DEFINITIONS ***
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*** OPS STRUCTURES ***
|
||||
****************************************************************************/
|
||||
am_ops amfs_toplvl_ops =
|
||||
{
|
||||
"toplvl",
|
||||
amfs_auto_match,
|
||||
0, /* amfs_auto_init */
|
||||
amfs_toplvl_mount,
|
||||
0,
|
||||
amfs_toplvl_umount,
|
||||
0,
|
||||
amfs_auto_lookuppn,
|
||||
amfs_auto_readdir, /* browsable version of readdir() */
|
||||
0, /* amfs_toplvl_readlink */
|
||||
amfs_toplvl_mounted,
|
||||
0, /* amfs_toplvl_umounted */
|
||||
find_amfs_auto_srvr,
|
||||
FS_MKMNT | FS_NOTIMEOUT | FS_BACKGROUND | FS_AMQINFO | FS_DIRECTORY
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*** FUNCTIONS ***
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Mount an automounter directory.
|
||||
* The automounter is connected into the system
|
||||
* as a user-level NFS server. mount_amfs_toplvl constructs
|
||||
* the necessary NFS parameters to be given to the
|
||||
* kernel so that it will talk back to us.
|
||||
*
|
||||
* NOTE: automounter mounts in themselves are using NFS Version 2.
|
||||
*/
|
||||
static int
|
||||
mount_amfs_toplvl(char *dir, char *opts)
|
||||
{
|
||||
char fs_hostname[MAXHOSTNAMELEN + MAXPATHLEN + 1];
|
||||
int retry, error, genflags;
|
||||
mntent_t mnt;
|
||||
nfs_args_t nfs_args;
|
||||
am_nfs_fh *fhp;
|
||||
am_nfs_handle_t anh;
|
||||
MTYPE_TYPE type = MOUNT_TYPE_NFS;
|
||||
#ifndef HAVE_TRANSPORT_TYPE_TLI
|
||||
u_short port;
|
||||
struct sockaddr_in sin;
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
memset((voidp) &mnt, 0, sizeof(mnt));
|
||||
mnt.mnt_dir = dir;
|
||||
mnt.mnt_fsname = pid_fsname;
|
||||
mnt.mnt_opts = opts;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
|
||||
if (retry <= 0)
|
||||
retry = 2; /* XXX */
|
||||
|
||||
/*
|
||||
* SET MOUNT ARGS
|
||||
*/
|
||||
/*
|
||||
* get fhandle of remote path for automount point
|
||||
*/
|
||||
fhp = root_fh(dir);
|
||||
if (!fhp) {
|
||||
plog(XLOG_FATAL, "Can't find root file handle for %s", dir);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
#ifndef HAVE_TRANSPORT_TYPE_TLI
|
||||
/*
|
||||
* Create sockaddr to point to the local machine. 127.0.0.1
|
||||
* is not used since that will not work in HP-UX clusters and
|
||||
* this is no more expensive.
|
||||
*/
|
||||
memset((voidp) &sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr = myipaddr;
|
||||
port = hasmntval(&mnt, MNTTAB_OPT_PORT);
|
||||
if (port) {
|
||||
sin.sin_port = htons(port);
|
||||
} else {
|
||||
plog(XLOG_ERROR, "no port number specified for %s", dir);
|
||||
return EINVAL;
|
||||
}
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
/*
|
||||
* Make a ``hostname'' string for the kernel
|
||||
*/
|
||||
sprintf(fs_hostname, "pid%ld@%s:%s",
|
||||
(long) (foreground ? mypid : getppid()),
|
||||
hostname,
|
||||
dir);
|
||||
/*
|
||||
* Most kernels have a name length restriction (64 bytes)...
|
||||
*/
|
||||
if (strlen(fs_hostname) >= MAXHOSTNAMELEN)
|
||||
strcpy(fs_hostname + MAXHOSTNAMELEN - 3, "..");
|
||||
#ifdef HOSTNAMESZ
|
||||
/*
|
||||
* ... and some of these restrictions are 32 bytes (HOSTNAMESZ)
|
||||
* If you need to get the definition for HOSTNAMESZ found, you may
|
||||
* add the proper header file to the conf/nfs_prot/nfs_prot_*.h file.
|
||||
*/
|
||||
if (strlen(fs_hostname) >= HOSTNAMESZ)
|
||||
strcpy(fs_hostname + HOSTNAMESZ - 3, "..");
|
||||
#endif /* HOSTNAMESZ */
|
||||
|
||||
/*
|
||||
* Finally we can compute the mount genflags set above.
|
||||
*/
|
||||
genflags = compute_mount_flags(&mnt);
|
||||
|
||||
/* setup the many fields and flags within nfs_args */
|
||||
memmove(&anh.v2.fhs_fh, fhp, sizeof(*fhp));
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
compute_nfs_args(&nfs_args,
|
||||
&mnt,
|
||||
genflags,
|
||||
nfsncp,
|
||||
NULL, /* remote host IP addr is set below */
|
||||
NFS_VERSION, /* version 2 */
|
||||
"udp",
|
||||
&anh,
|
||||
fs_hostname,
|
||||
pid_fsname);
|
||||
/*
|
||||
* IMPORTANT: set the correct IP address AFTERWARDS. It cannot
|
||||
* be done using the normal mechanism of compute_nfs_args(), because
|
||||
* that one will allocate a new address and use NFS_SA_DREF() to copy
|
||||
* parts to it, while assuming that the ip_addr passed is always
|
||||
* a "struct sockaddr_in". That assumption is incorrect on TLI systems,
|
||||
* because they define a special macro HOST_SELF which is DIFFERENT
|
||||
* than localhost (127.0.0.1)!
|
||||
*/
|
||||
nfs_args.addr = &nfsxprt->xp_ltaddr;
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
compute_nfs_args(&nfs_args,
|
||||
&mnt,
|
||||
genflags,
|
||||
&sin,
|
||||
NFS_VERSION, /* version 2 */
|
||||
"udp",
|
||||
&anh,
|
||||
fs_hostname,
|
||||
pid_fsname);
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
/*************************************************************************
|
||||
* NOTE: while compute_nfs_args() works ok for regular NFS mounts *
|
||||
* the toplvl one is not, and so some options must be corrected by hand *
|
||||
* more carefully, *after* compute_nfs_args() runs. *
|
||||
*************************************************************************/
|
||||
compute_automounter_nfs_args(&nfs_args, &mnt);
|
||||
|
||||
/* This is it! Here we try to mount amd on its mount points */
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
print_nfs_args(&nfs_args, 0);
|
||||
#endif /* DEBUG */
|
||||
error = mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type,
|
||||
0, NULL, mnttab_file_name);
|
||||
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
free_knetconfig(nfs_args.knconf);
|
||||
/*
|
||||
* local automounter mounts do not allocate a special address, so
|
||||
* no need to XFREE(nfs_args.addr) under TLI.
|
||||
*/
|
||||
#endif /* HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mount the top-level
|
||||
*/
|
||||
int
|
||||
amfs_toplvl_mount(am_node *mp)
|
||||
{
|
||||
mntfs *mf = mp->am_mnt;
|
||||
struct stat stb;
|
||||
char opts[256], preopts[256];
|
||||
int error;
|
||||
char *mnttype;
|
||||
|
||||
/*
|
||||
* Mounting the automounter.
|
||||
* Make sure the mount directory exists, construct
|
||||
* the mount options and call the mount_amfs_toplvl routine.
|
||||
*/
|
||||
|
||||
if (stat(mp->am_path, &stb) < 0) {
|
||||
return errno;
|
||||
} else if ((stb.st_mode & S_IFMT) != S_IFDIR) {
|
||||
plog(XLOG_WARNING, "%s is not a directory", mp->am_path);
|
||||
return ENOTDIR;
|
||||
}
|
||||
if (mf->mf_ops == &amfs_toplvl_ops)
|
||||
mnttype = "indirect";
|
||||
else if (mf->mf_ops == &amfs_direct_ops)
|
||||
mnttype = "direct";
|
||||
#ifdef HAVE_AM_FS_UNION
|
||||
else if (mf->mf_ops == &amfs_union_ops)
|
||||
mnttype = "union";
|
||||
#endif /* HAVE_AM_FS_UNION */
|
||||
else
|
||||
mnttype = "auto";
|
||||
|
||||
/*
|
||||
* Construct some mount options:
|
||||
*
|
||||
* Tack on magic map=<mapname> option in mtab to emulate
|
||||
* SunOS automounter behavior.
|
||||
*/
|
||||
preopts[0] = '\0';
|
||||
#ifdef MNTTAB_OPT_INTR
|
||||
strcat(preopts, MNTTAB_OPT_INTR);
|
||||
strcat(preopts, ",");
|
||||
#endif /* MNTTAB_OPT_INTR */
|
||||
#ifdef MNTTAB_OPT_IGNORE
|
||||
strcat(preopts, MNTTAB_OPT_IGNORE);
|
||||
strcat(preopts, ",");
|
||||
#endif /* MNTTAB_OPT_IGNORE */
|
||||
sprintf(opts, "%s%s,%s=%d,%s=%d,%s=%d,%s,map=%s",
|
||||
preopts,
|
||||
MNTTAB_OPT_RW,
|
||||
MNTTAB_OPT_PORT, nfs_port,
|
||||
MNTTAB_OPT_TIMEO, gopt.amfs_auto_timeo,
|
||||
MNTTAB_OPT_RETRANS, gopt.amfs_auto_retrans,
|
||||
mnttype, mf->mf_info);
|
||||
|
||||
/* now do the mount */
|
||||
error = mount_amfs_toplvl(mf->mf_mount, opts);
|
||||
if (error) {
|
||||
errno = error;
|
||||
plog(XLOG_FATAL, "mount_amfs_toplvl: %m");
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
amfs_toplvl_mounted(mntfs *mf)
|
||||
{
|
||||
amfs_auto_mkcacheref(mf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unmount a top-level automount node
|
||||
*/
|
||||
int
|
||||
amfs_toplvl_umount(am_node *mp)
|
||||
{
|
||||
int error;
|
||||
struct stat stb;
|
||||
|
||||
again:
|
||||
/*
|
||||
* The lstat is needed if this mount is type=direct.
|
||||
* When that happens, the kernel cache gets confused
|
||||
* between the underlying type (dir) and the mounted
|
||||
* type (link) and so needs to be re-synced before
|
||||
* the unmount. This is all because the unmount system
|
||||
* call follows links and so can't actually unmount
|
||||
* a link (stupid!). It was noted that doing an ls -ld
|
||||
* of the mount point to see why things were not working
|
||||
* actually fixed the problem - so simulate an ls -ld here.
|
||||
*/
|
||||
if (lstat(mp->am_path, &stb) < 0) {
|
||||
#ifdef DEBUG
|
||||
dlog("lstat(%s): %m", mp->am_path);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
error = UMOUNT_FS(mp->am_path, mnttab_file_name);
|
||||
if (error == EBUSY) {
|
||||
plog(XLOG_WARNING, "amfs_toplvl_unmount retrying %s in 1s", mp->am_path);
|
||||
sleep(1); /* XXX */
|
||||
goto again;
|
||||
}
|
||||
return error;
|
||||
}
|
124
contrib/amd/amd/amfs_union.c
Normal file
124
contrib/amd/amd/amfs_union.c
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: amfs_union.c,v 1.1 1997-1998/06/30 19:22:30 ezk Exp ezk $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Union automounter file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/****************************************************************************
|
||||
*** FORWARD DEFINITIONS ***
|
||||
****************************************************************************/
|
||||
static void amfs_union_mounted(mntfs *mf);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*** OPS STRUCTURES ***
|
||||
****************************************************************************/
|
||||
am_ops amfs_union_ops =
|
||||
{
|
||||
"union",
|
||||
amfs_auto_match,
|
||||
0, /* amfs_auto_init */
|
||||
amfs_toplvl_mount,
|
||||
0,
|
||||
amfs_toplvl_umount,
|
||||
0,
|
||||
amfs_auto_lookuppn,
|
||||
amfs_auto_readdir,
|
||||
0, /* amfs_toplvl_readlink */
|
||||
amfs_union_mounted,
|
||||
0, /* amfs_toplvl_umounted */
|
||||
find_amfs_auto_srvr,
|
||||
FS_MKMNT | FS_NOTIMEOUT | FS_BACKGROUND | FS_AMQINFO | FS_DIRECTORY
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Create a reference to a union'ed entry
|
||||
* XXX: this function may not be used anywhere...
|
||||
*/
|
||||
static int
|
||||
create_amfs_union_node(char *dir, voidp arg)
|
||||
{
|
||||
if (!STREQ(dir, "/defaults")) {
|
||||
int error = 0;
|
||||
(void) amfs_toplvl_ops.lookuppn(arg, dir, &error, VLOOK_CREATE);
|
||||
if (error > 0) {
|
||||
errno = error; /* XXX */
|
||||
plog(XLOG_ERROR, "Could not mount %s: %m", dir);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
amfs_union_mounted(mntfs *mf)
|
||||
{
|
||||
int i;
|
||||
|
||||
amfs_auto_mkcacheref(mf);
|
||||
|
||||
/*
|
||||
* Having made the union mount point,
|
||||
* populate all the entries...
|
||||
*/
|
||||
for (i = 0; i <= last_used_map; i++) {
|
||||
am_node *mp = exported_ap[i];
|
||||
if (mp && mp->am_mnt == mf) {
|
||||
/* return value from create_amfs_union_node is ignored by mapc_keyiter */
|
||||
(void) mapc_keyiter((mnt_map *) mp->am_mnt->mf_private,
|
||||
(void (*)(char *, voidp)) create_amfs_union_node,
|
||||
mp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
501
contrib/amd/amd/amq_subr.c
Normal file
501
contrib/amd/amd/amq_subr.c
Normal file
@ -0,0 +1,501 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_subr.c,v 5.2.2.1 1992/02/09 15:08:18 jsp beta $
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Auxilliary routines for amq tool
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* forward definitions */
|
||||
bool_t xdr_amq_mount_tree_node(XDR *xdrs, amq_mount_tree *objp);
|
||||
bool_t xdr_amq_mount_subtree(XDR *xdrs, amq_mount_tree *objp);
|
||||
|
||||
|
||||
voidp
|
||||
amqproc_null_1_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
static char res;
|
||||
|
||||
return (voidp) &res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a sub-tree of mounts
|
||||
*/
|
||||
amq_mount_tree_p *
|
||||
amqproc_mnttree_1_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
static am_node *mp;
|
||||
|
||||
mp = find_ap(*(char **) argp);
|
||||
return (amq_mount_tree_p *) ∓
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unmount a single node
|
||||
*/
|
||||
voidp
|
||||
amqproc_umnt_1_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
static char res;
|
||||
am_node *mp = find_ap(*(char **) argp);
|
||||
|
||||
if (mp)
|
||||
forcibly_timeout_mp(mp);
|
||||
|
||||
return (voidp) &res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return global statistics
|
||||
*/
|
||||
amq_mount_stats *
|
||||
amqproc_stats_1_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
return (amq_mount_stats *) &amd_stats;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the entire tree of mount nodes
|
||||
*/
|
||||
amq_mount_tree_list *
|
||||
amqproc_export_1_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
static amq_mount_tree_list aml;
|
||||
|
||||
aml.amq_mount_tree_list_val = (amq_mount_tree_p *) &exported_ap[0];
|
||||
aml.amq_mount_tree_list_len = 1; /* XXX */
|
||||
|
||||
return &aml;
|
||||
}
|
||||
|
||||
|
||||
int *
|
||||
amqproc_setopt_1_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
static int rc;
|
||||
amq_setopt *opt = (amq_setopt *) argp;
|
||||
|
||||
rc = 0;
|
||||
|
||||
switch (opt->as_opt) {
|
||||
|
||||
case AMOPT_DEBUG:
|
||||
#ifdef DEBUG
|
||||
if (debug_option(opt->as_str))
|
||||
#endif /* DEBUG */
|
||||
rc = EINVAL;
|
||||
break;
|
||||
|
||||
case AMOPT_LOGFILE:
|
||||
if (gopt.logfile && opt->as_str
|
||||
&& STREQ(gopt.logfile, opt->as_str)) {
|
||||
if (switch_to_logfile(opt->as_str))
|
||||
rc = EINVAL;
|
||||
} else {
|
||||
rc = EACCES;
|
||||
}
|
||||
break;
|
||||
|
||||
case AMOPT_XLOG:
|
||||
if (switch_option(opt->as_str))
|
||||
rc = EINVAL;
|
||||
break;
|
||||
|
||||
case AMOPT_FLUSHMAPC:
|
||||
if (amd_state == Run) {
|
||||
plog(XLOG_INFO, "amq says flush cache");
|
||||
do_mapc_reload = 0;
|
||||
flush_nfs_fhandle_cache((fserver *) 0);
|
||||
flush_srvr_nfs_cache();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return &rc;
|
||||
}
|
||||
|
||||
|
||||
amq_mount_info_list *
|
||||
amqproc_getmntfs_1_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
return (amq_mount_info_list *) &mfhead; /* XXX */
|
||||
}
|
||||
|
||||
#ifdef ENABLE_AMQ_MOUNT
|
||||
/*
|
||||
* This is code that is vulnerable to IP spoofing attacks. Unless you
|
||||
* absolutely need it, I suggest you do not enable it
|
||||
* (using configure --enable-amq-mount)
|
||||
*/
|
||||
static int
|
||||
ok_security(struct svc_req *rqstp)
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *) NULL;
|
||||
|
||||
if ((sin = amu_svc_getcaller(rqstp->rq_xprt)) == NULL) {
|
||||
plog(XLOG_ERROR, "amu_svc_getcaller returned NULL");
|
||||
return(0); /* assume security is therefore not OK */
|
||||
}
|
||||
|
||||
if (ntohs(sin->sin_port) >= 1024 ||
|
||||
!(sin->sin_addr.s_addr == htonl(0x7f000001) ||
|
||||
sin->sin_addr.s_addr == myipaddr.s_addr)) {
|
||||
char dq[20];
|
||||
plog(XLOG_INFO, "AMQ request from %s.%d DENIED",
|
||||
inet_dquad(dq, sin->sin_addr.s_addr),
|
||||
ntohs(sin->sin_port));
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
int *
|
||||
amqproc_mount_1_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
static int rc;
|
||||
char *s = *(amq_string *) argp;
|
||||
char *cp;
|
||||
|
||||
plog(XLOG_INFO, "amq requested mount of %s", s);
|
||||
/*
|
||||
* Minimalist security check.
|
||||
*/
|
||||
if (!ok_security(rqstp)) {
|
||||
rc = EACCES;
|
||||
return &rc;
|
||||
}
|
||||
/*
|
||||
* Find end of key
|
||||
*/
|
||||
for (cp = (char *) s; *cp && (!isascii(*cp) || !isspace(*cp)); cp++) ;
|
||||
|
||||
if (!*cp) {
|
||||
plog(XLOG_INFO, "amqproc_mount: Invalid arguments");
|
||||
rc = EINVAL;
|
||||
return &rc;
|
||||
}
|
||||
*cp++ = '\0';
|
||||
|
||||
/*
|
||||
* Find start of value
|
||||
*/
|
||||
while (*cp && isascii(*cp) && isspace(*cp))
|
||||
cp++;
|
||||
|
||||
root_newmap(s, cp, (char *) 0, NULL);
|
||||
rc = mount_auto_node(s, (voidp) root_node);
|
||||
if (rc < 0)
|
||||
return 0;
|
||||
return &rc;
|
||||
}
|
||||
|
||||
#else /* not ENABLE_AMQ_MOUNT */
|
||||
|
||||
int *
|
||||
amqproc_mount_1_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
static int rc;
|
||||
char *s = *(amq_string *) argp;
|
||||
|
||||
plog(XLOG_ERROR, "amq requested mount of %s, but code is disabled", s);
|
||||
|
||||
rc = EINVAL;
|
||||
return &rc;
|
||||
}
|
||||
#endif /* not ENABLE_AMQ_MOUNT */
|
||||
|
||||
|
||||
amq_string *
|
||||
amqproc_getvers_1_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
static amq_string res;
|
||||
|
||||
res = get_version_string();
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
/* get PID of remote amd */
|
||||
int *
|
||||
amqproc_getpid_1_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
static int res;
|
||||
|
||||
res = getpid();
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* XDR routines.
|
||||
*/
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_amq_setopt(XDR *xdrs, amq_setopt *objp)
|
||||
{
|
||||
if (!xdr_enum(xdrs, (enum_t *) & objp->as_opt)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_string(xdrs, &objp->as_str, AMQ_STRLEN)) {
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* More XDR routines - Should be used for OUTPUT ONLY.
|
||||
*/
|
||||
bool_t
|
||||
xdr_amq_mount_tree_node(XDR *xdrs, amq_mount_tree *objp)
|
||||
{
|
||||
am_node *mp = (am_node *) objp;
|
||||
|
||||
if (!xdr_amq_string(xdrs, &mp->am_mnt->mf_info)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_amq_string(xdrs, &mp->am_path)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_amq_string(xdrs, mp->am_link ? &mp->am_link : &mp->am_mnt->mf_mount)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_amq_string(xdrs, &mp->am_mnt->mf_ops->fs_type)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_long(xdrs, (long *) &mp->am_stats.s_mtime)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_u_short(xdrs, &mp->am_stats.s_uid)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_int(xdrs, &mp->am_stats.s_getattr)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_int(xdrs, &mp->am_stats.s_lookup)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_int(xdrs, &mp->am_stats.s_readdir)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_int(xdrs, &mp->am_stats.s_readlink)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_int(xdrs, &mp->am_stats.s_statfs)) {
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_amq_mount_subtree(XDR *xdrs, amq_mount_tree *objp)
|
||||
{
|
||||
am_node *mp = (am_node *) objp;
|
||||
|
||||
if (!xdr_amq_mount_tree_node(xdrs, objp)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_pointer(xdrs, (char **) &mp->am_osib, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_pointer(xdrs, (char **) &mp->am_child, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_amq_mount_tree(XDR *xdrs, amq_mount_tree *objp)
|
||||
{
|
||||
am_node *mp = (am_node *) objp;
|
||||
am_node *mnil = 0;
|
||||
|
||||
if (!xdr_amq_mount_tree_node(xdrs, objp)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_pointer(xdrs, (char **) &mnil, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_pointer(xdrs, (char **) &mp->am_child, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
|
||||
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_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_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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Compute length of list
|
||||
*/
|
||||
bool_t
|
||||
xdr_amq_mount_info_qelem(XDR *xdrs, qelem *qhead)
|
||||
{
|
||||
mntfs *mf;
|
||||
u_int len = 0;
|
||||
|
||||
for (mf = AM_LAST(mntfs, qhead); mf != HEAD(mntfs, qhead); mf = PREV(mntfs, mf)) {
|
||||
if (!(mf->mf_ops->fs_flags & FS_AMQINFO))
|
||||
continue;
|
||||
len++;
|
||||
}
|
||||
xdr_u_int(xdrs, &len);
|
||||
|
||||
/*
|
||||
* Send individual data items
|
||||
*/
|
||||
for (mf = AM_LAST(mntfs, qhead); mf != HEAD(mntfs, qhead); mf = PREV(mntfs, mf)) {
|
||||
int up;
|
||||
if (!(mf->mf_ops->fs_flags & FS_AMQINFO))
|
||||
continue;
|
||||
|
||||
if (!xdr_amq_string(xdrs, &mf->mf_ops->fs_type)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_amq_string(xdrs, &mf->mf_mount)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_amq_string(xdrs, &mf->mf_info)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_amq_string(xdrs, &mf->mf_server->fs_host)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_int(xdrs, &mf->mf_error)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (!xdr_int(xdrs, &mf->mf_refc)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (mf->mf_server->fs_flags & FSF_ERROR)
|
||||
up = 0;
|
||||
else
|
||||
switch (mf->mf_server->fs_flags & (FSF_DOWN | FSF_VALID)) {
|
||||
case FSF_DOWN | FSF_VALID:
|
||||
up = 0;
|
||||
break;
|
||||
case FSF_VALID:
|
||||
up = 1;
|
||||
break;
|
||||
default:
|
||||
up = -1;
|
||||
break;
|
||||
}
|
||||
if (!xdr_int(xdrs, &up)) {
|
||||
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));
|
||||
}
|
157
contrib/amd/amd/amq_svc.c
Normal file
157
contrib/amd/amd/amq_svc.c
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 5.2.2.1 1992/02/09 15:09:26 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* typedefs */
|
||||
typedef char *(*amqsvcproc_t)(voidp, struct svc_req *);
|
||||
|
||||
|
||||
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;
|
||||
xdrproc_t xdr_argument, xdr_result;
|
||||
amqsvcproc_t local;
|
||||
|
||||
switch (rqstp->rq_proc) {
|
||||
|
||||
case AMQPROC_NULL:
|
||||
xdr_argument = (xdrproc_t) xdr_void;
|
||||
xdr_result = (xdrproc_t) xdr_void;
|
||||
local = (amqsvcproc_t) amqproc_null_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_MNTTREE:
|
||||
xdr_argument = (xdrproc_t) xdr_amq_string;
|
||||
xdr_result = (xdrproc_t) xdr_amq_mount_tree_p;
|
||||
local = (amqsvcproc_t) amqproc_mnttree_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_UMNT:
|
||||
xdr_argument = (xdrproc_t) xdr_amq_string;
|
||||
xdr_result = (xdrproc_t) xdr_void;
|
||||
local = (amqsvcproc_t) amqproc_umnt_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_STATS:
|
||||
xdr_argument = (xdrproc_t) xdr_void;
|
||||
xdr_result = (xdrproc_t) xdr_amq_mount_stats;
|
||||
local = (amqsvcproc_t) amqproc_stats_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_EXPORT:
|
||||
xdr_argument = (xdrproc_t) xdr_void;
|
||||
xdr_result = (xdrproc_t) xdr_amq_mount_tree_list;
|
||||
local = (amqsvcproc_t) amqproc_export_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_SETOPT:
|
||||
xdr_argument = (xdrproc_t) xdr_amq_setopt;
|
||||
xdr_result = (xdrproc_t) xdr_int;
|
||||
local = (amqsvcproc_t) amqproc_setopt_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_GETMNTFS:
|
||||
xdr_argument = (xdrproc_t) xdr_void;
|
||||
xdr_result = (xdrproc_t) xdr_amq_mount_info_qelem;
|
||||
local = (amqsvcproc_t) amqproc_getmntfs_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_MOUNT:
|
||||
xdr_argument = (xdrproc_t) xdr_amq_string;
|
||||
xdr_result = (xdrproc_t) xdr_int;
|
||||
local = (amqsvcproc_t) amqproc_mount_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_GETVERS:
|
||||
xdr_argument = (xdrproc_t) xdr_void;
|
||||
xdr_result = (xdrproc_t) xdr_amq_string;
|
||||
local = (amqsvcproc_t) amqproc_getvers_1_svc;
|
||||
break;
|
||||
|
||||
case AMQPROC_GETPID:
|
||||
xdr_argument = (xdrproc_t) xdr_void;
|
||||
xdr_result = (xdrproc_t) xdr_int;
|
||||
local = (amqsvcproc_t) amqproc_getpid_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);
|
||||
}
|
||||
}
|
418
contrib/amd/amd/autil.c
Normal file
418
contrib/amd/amd/autil.c
Normal file
@ -0,0 +1,418 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 5.2.2.2 1992/03/07 17:52:06 jsp 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((int)*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((int)*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 == &amfs_direct_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 = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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;
|
||||
} else { /* parent process, has one more child */
|
||||
NumChild++;
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
background(void)
|
||||
{
|
||||
int pid = dofork();
|
||||
|
||||
if (pid == 0) {
|
||||
#ifdef DEBUG
|
||||
dlog("backgrounded");
|
||||
#endif /* DEBUG */
|
||||
foreground = 0;
|
||||
}
|
||||
return pid;
|
||||
}
|
247
contrib/amd/amd/clock.c
Normal file
247
contrib/amd/amd/clock.c
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: clock.c,v 5.2.2.1 1992/02/09 15:08:20 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Callouts.
|
||||
*
|
||||
* Modelled on kernel object of the same name.
|
||||
* See usual references.
|
||||
*
|
||||
* Use of a heap-based mechanism was rejected:
|
||||
* 1. more complex implementation needed.
|
||||
* 2. not obvious that a list is too slow for Amd.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
int timeout(u_int secs, void (*fn) (voidp), voidp closure);
|
||||
void reschedule_timeouts(time_t now, time_t then);
|
||||
|
||||
typedef struct callout callout;
|
||||
struct callout {
|
||||
callout *c_next; /* List of callouts */
|
||||
void (*c_fn) (voidp); /* Function to call */
|
||||
voidp c_closure; /* Closure to pass to call */
|
||||
time_t c_time; /* Time of call */
|
||||
int c_id; /* Unique identifier */
|
||||
};
|
||||
|
||||
static callout callouts; /* List of pending callouts */
|
||||
static callout *free_callouts; /* Cache of free callouts */
|
||||
static int nfree_callouts; /* Number on free list */
|
||||
static int callout_id; /* Next free callout identifier */
|
||||
|
||||
time_t next_softclock; /* Time of next call to softclock() */
|
||||
|
||||
|
||||
/*
|
||||
* Number of callout slots we keep on the free list
|
||||
*/
|
||||
#define CALLOUT_FREE_SLOP 10
|
||||
|
||||
/*
|
||||
* Global assumption: valid id's are non-zero.
|
||||
*/
|
||||
#define CID_ALLOC(struct ) (++callout_id)
|
||||
#define CID_UNDEF (0)
|
||||
|
||||
|
||||
static callout *
|
||||
alloc_callout(void)
|
||||
{
|
||||
callout *cp = free_callouts;
|
||||
|
||||
if (cp) {
|
||||
--nfree_callouts;
|
||||
free_callouts = free_callouts->c_next;
|
||||
return cp;
|
||||
}
|
||||
return ALLOC(struct callout);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
free_callout(callout *cp)
|
||||
{
|
||||
if (nfree_callouts > CALLOUT_FREE_SLOP) {
|
||||
XFREE(cp);
|
||||
} else {
|
||||
cp->c_next = free_callouts;
|
||||
free_callouts = cp;
|
||||
nfree_callouts++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Schedule a callout.
|
||||
*
|
||||
* (*fn)(closure) will be called at clocktime() + secs
|
||||
*/
|
||||
int
|
||||
timeout(u_int secs, void (*fn) (voidp), voidp closure)
|
||||
{
|
||||
callout *cp, *cp2;
|
||||
time_t t = clocktime() + secs;
|
||||
|
||||
/*
|
||||
* Allocate and fill in a new callout structure
|
||||
*/
|
||||
callout *cpnew = alloc_callout();
|
||||
cpnew->c_closure = closure;
|
||||
cpnew->c_fn = fn;
|
||||
cpnew->c_time = t;
|
||||
cpnew->c_id = CID_ALLOC(struct );
|
||||
|
||||
if (t < next_softclock)
|
||||
next_softclock = t;
|
||||
|
||||
/*
|
||||
* Find the correct place in the list
|
||||
*/
|
||||
for (cp = &callouts; (cp2 = cp->c_next); cp = cp2)
|
||||
if (cp2->c_time >= t)
|
||||
break;
|
||||
|
||||
/*
|
||||
* And link it in
|
||||
*/
|
||||
cp->c_next = cpnew;
|
||||
cpnew->c_next = cp2;
|
||||
|
||||
/*
|
||||
* Return callout identifier
|
||||
*/
|
||||
return cpnew->c_id;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* De-schedule a callout
|
||||
*/
|
||||
void
|
||||
untimeout(int id)
|
||||
{
|
||||
callout *cp, *cp2;
|
||||
for (cp = &callouts; (cp2 = cp->c_next); cp = cp2) {
|
||||
if (cp2->c_id == id) {
|
||||
cp->c_next = cp2->c_next;
|
||||
free_callout(cp2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reschedule after clock changed
|
||||
*/
|
||||
void
|
||||
reschedule_timeouts(time_t now, time_t then)
|
||||
{
|
||||
callout *cp;
|
||||
|
||||
for (cp = callouts.c_next; cp; cp = cp->c_next) {
|
||||
if (cp->c_time >= now && cp->c_time <= then) {
|
||||
plog(XLOG_WARNING, "job %d rescheduled to run immediately", cp->c_id);
|
||||
#ifdef DEBUG
|
||||
dlog("rescheduling job %d back %d seconds", cp->c_id, cp->c_time - now);
|
||||
#endif /* DEBUG */
|
||||
next_softclock = cp->c_time = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clock handler
|
||||
*/
|
||||
int
|
||||
softclock(void)
|
||||
{
|
||||
time_t now;
|
||||
callout *cp;
|
||||
|
||||
do {
|
||||
if (task_notify_todo)
|
||||
do_task_notify();
|
||||
|
||||
now = clocktime();
|
||||
|
||||
/*
|
||||
* While there are more callouts waiting...
|
||||
*/
|
||||
while ((cp = callouts.c_next) && cp->c_time <= now) {
|
||||
/*
|
||||
* Extract first from list, save fn & closure and
|
||||
* unlink callout from list and free.
|
||||
* Finally call function.
|
||||
*
|
||||
* The free is done first because
|
||||
* it is quite common that the
|
||||
* function will call timeout()
|
||||
* and try to allocate a callout
|
||||
*/
|
||||
void (*fn) (voidp) = cp->c_fn;
|
||||
voidp closure = cp->c_closure;
|
||||
|
||||
callouts.c_next = cp->c_next;
|
||||
free_callout(cp);
|
||||
(*fn) (closure);
|
||||
}
|
||||
|
||||
} while (task_notify_todo);
|
||||
|
||||
/*
|
||||
* Return number of seconds to next event,
|
||||
* or 0 if there is no event.
|
||||
*/
|
||||
if ((cp = callouts.c_next))
|
||||
return cp->c_time - now;
|
||||
return 0;
|
||||
}
|
939
contrib/amd/amd/conf.c
Normal file
939
contrib/amd/amd/conf.c
Normal file
@ -0,0 +1,939 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 5.2.2.1 1992/02/09 15:08:23 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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_fully_qualified_hosts(const char *val);
|
||||
static int gopt_hesiod_base(const char *val);
|
||||
static int gopt_karch(const char *val);
|
||||
static int gopt_ldap_base(const char *val);
|
||||
static int gopt_ldap_cache_maxmem(const char *val);
|
||||
static int gopt_ldap_cache_seconds(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_pid_file(const char *val);
|
||||
static int gopt_portmap_program(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 gopt_show_statfs_entries(const char *val);
|
||||
static int gopt_unmount_on_exit(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},
|
||||
{"fully_qualified_hosts", gopt_fully_qualified_hosts},
|
||||
{"hesiod_base", gopt_hesiod_base},
|
||||
{"karch", gopt_karch},
|
||||
{"ldap_base", gopt_ldap_base},
|
||||
{"ldap_cache_maxmem", gopt_ldap_cache_maxmem},
|
||||
{"ldap_cache_seconds", gopt_ldap_cache_seconds},
|
||||
{"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},
|
||||
{"pid_file", gopt_pid_file},
|
||||
{"portmap_program", gopt_portmap_program},
|
||||
{"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},
|
||||
{"show_statfs_entries", gopt_show_statfs_entries},
|
||||
{"unmount_on_exit", gopt_unmount_on_exit},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Reset a map.
|
||||
*/
|
||||
static void
|
||||
reset_cf_map(cf_map_t *cfm)
|
||||
{
|
||||
if (!cfm)
|
||||
return;
|
||||
|
||||
if (cfm->cfm_dir) {
|
||||
XFREE(cfm->cfm_dir);
|
||||
cfm->cfm_dir = NULL;
|
||||
}
|
||||
|
||||
if (cfm->cfm_name) {
|
||||
XFREE(cfm->cfm_name);
|
||||
cfm->cfm_name = NULL;
|
||||
}
|
||||
|
||||
if (cfm->cfm_tag) {
|
||||
XFREE(cfm->cfm_tag);
|
||||
cfm->cfm_tag = 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)
|
||||
XFREE(cfm->cfm_type);
|
||||
cfm->cfm_type = gopt.map_type;
|
||||
|
||||
/* initialize map_opts from [global] */
|
||||
if (cfm->cfm_opts && cfm->cfm_opts != gopt.map_options)
|
||||
XFREE(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)
|
||||
XFREE(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_BROWSABLE_DIRS_FULL |
|
||||
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, "full")) {
|
||||
gopt.flags |= CFM_BROWSABLE_DIRS_FULL;
|
||||
return 0;
|
||||
} else 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_fully_qualified_hosts(const char *val)
|
||||
{
|
||||
if (STREQ(val, "yes")) {
|
||||
gopt.flags |= CFM_FULLY_QUALIFIED_HOSTS;
|
||||
return 0;
|
||||
} else if (STREQ(val, "no")) {
|
||||
gopt.flags &= ~CFM_FULLY_QUALIFIED_HOSTS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "conf: unknown value to fully_qualified_hosts \"%s\"\n", val);
|
||||
return 1; /* unknown value */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_hesiod_base(const char *val)
|
||||
{
|
||||
#ifdef HAVE_MAP_HESIOD
|
||||
gopt.hesiod_base = strdup((char *)val);
|
||||
return 0;
|
||||
#else /* not HAVE_MAP_HESIOD */
|
||||
fprintf(stderr, "conf: hesiod_base option ignored. No Hesiod support available.\n");
|
||||
return 1;
|
||||
#endif /* not HAVE_MAP_HESIOD */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_karch(const char *val)
|
||||
{
|
||||
gopt.karch = strdup((char *)val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_pid_file(const char *val)
|
||||
{
|
||||
gopt.pid_file = 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_cache_seconds(const char *val)
|
||||
{
|
||||
#ifdef HAVE_MAP_LDAP
|
||||
char *end;
|
||||
|
||||
gopt.ldap_cache_seconds = strtol((char *)val, &end, 10);
|
||||
if (end == val) {
|
||||
fprintf(stderr, "conf: bad LDAP cache (seconds) option: %s\n",val);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
#else /* not HAVE_MAP_LDAP */
|
||||
fprintf(stderr, "conf: ldap_cache option ignored. No LDAP support available.\n");
|
||||
return 1;
|
||||
#endif /* not HAVE_MAP_LDAP */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_ldap_cache_maxmem(const char *val)
|
||||
{
|
||||
#ifdef HAVE_MAP_LDAP
|
||||
char *end;
|
||||
|
||||
gopt.ldap_cache_maxmem = strtol((char *)val, &end, 10);
|
||||
if (end == val) {
|
||||
fprintf(stderr, "conf: bad LDAP cache (maxmem) option: %s\n",val);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
#else /* not HAVE_MAP_LDAP */
|
||||
fprintf(stderr, "conf: ldap_cache 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")) {
|
||||
#ifdef HAVE_FS_AUTOFS
|
||||
gopt.flags |= CFM_MOUNT_TYPE_AUTOFS;
|
||||
return 0;
|
||||
#else /* not HAVE_FS_AUTOFS */
|
||||
fprintf(stderr, "conf: no autofs support available\n");
|
||||
return 1;
|
||||
#endif /* not HAVE_FS_AUTOFS */
|
||||
} 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_portmap_program(const char *val)
|
||||
{
|
||||
gopt.portmap_program = atoi(val);
|
||||
/*
|
||||
* allow alternate program numbers to be no more than 10 offset from
|
||||
* official amd program number (300019).
|
||||
*/
|
||||
if (gopt.portmap_program < AMQ_PROGRAM ||
|
||||
gopt.portmap_program > AMQ_PROGRAM + 10) {
|
||||
gopt.portmap_program = AMQ_PROGRAM;
|
||||
set_amd_program_number(gopt.portmap_program);
|
||||
fprintf(stderr, "conf: illegal amd program numver \"%s\"\n", val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
set_amd_program_number(gopt.portmap_program);
|
||||
return 0; /* all is OK */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_nfs_retransmit_counter(const char *val)
|
||||
{
|
||||
gopt.amfs_auto_retrans = atoi(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_nfs_retry_interval(const char *val)
|
||||
{
|
||||
gopt.amfs_auto_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_PROCESS_LOCK;
|
||||
return 0;
|
||||
} else if (STREQ(val, "no")) {
|
||||
gopt.flags &= ~CFM_PROCESS_LOCK;
|
||||
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 */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_show_statfs_entries(const char *val)
|
||||
{
|
||||
if (STREQ(val, "yes")) {
|
||||
gopt.flags |= CFM_SHOW_STATFS_ENTRIES;
|
||||
return 0;
|
||||
} else if (STREQ(val, "no")) {
|
||||
gopt.flags &= ~CFM_SHOW_STATFS_ENTRIES;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "conf: unknown value to show_statfs_entries \"%s\"\n", val);
|
||||
return 1; /* unknown value */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gopt_unmount_on_exit(const char *val)
|
||||
{
|
||||
if (STREQ(val, "yes")) {
|
||||
gopt.flags |= CFM_UNMOUNT_ON_EXIT;
|
||||
return 0;
|
||||
} else if (STREQ(val, "no")) {
|
||||
gopt.flags &= ~CFM_UNMOUNT_ON_EXIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "conf: unknown value to unmount_on_exit \"%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, "full")) {
|
||||
cfm->cfm_flags |= CFM_BROWSABLE_DIRS_FULL;
|
||||
return 0;
|
||||
} else 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")) {
|
||||
#ifdef HAVE_FS_AUTOFS
|
||||
cfm->cfm_flags |= CFM_MOUNT_TYPE_AUTOFS;
|
||||
return 0;
|
||||
#else /* not HAVE_FS_AUTOFS */
|
||||
fprintf(stderr, "conf: no autofs support available\n");
|
||||
return 1;
|
||||
#endif /* not HAVE_FS_AUTOFS */
|
||||
} 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 (if any)
|
||||
*/
|
||||
int
|
||||
process_last_regular_map(void)
|
||||
{
|
||||
/*
|
||||
* If the amd.conf file only has a [global] section (pretty useless
|
||||
* IMHO), do not try to process a map that does not exist.
|
||||
*/
|
||||
if (!cur_map.cfm_dir)
|
||||
return 0;
|
||||
return process_regular_map(&cur_map);
|
||||
}
|
159
contrib/amd/amd/conf_parse.y
Normal file
159
contrib/amd/amd/conf_parse.y
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 5.2.2.1 1992/02/09 15:09:35 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
%{
|
||||
#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 */
|
||||
}
|
186
contrib/amd/amd/conf_tok.l
Normal file
186
contrib/amd/amd/conf_tok.l
Normal file
@ -0,0 +1,186 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 5.2.2.1 1992/02/09 15:09:36 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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>
|
||||
/* and once again undefine this, just in case */
|
||||
#ifdef ECHO
|
||||
# undef ECHO
|
||||
#endif /* ECHO */
|
||||
|
||||
/*
|
||||
* 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
|
||||
# ifndef ECHO
|
||||
# define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
|
||||
# endif /* not ECHO */
|
||||
int yylineno = 0;
|
||||
#endif /* FLEX_SCANNER */
|
||||
|
||||
int yylex(void);
|
||||
/*
|
||||
* some systems such as DU-4.x have a different GNU flex in /usr/bin
|
||||
* which automatically generates yywrap macros and symbols. So I must
|
||||
* distinguish between them and when yywrap is actually needed.
|
||||
*/
|
||||
#ifndef yywrap
|
||||
int yywrap(void);
|
||||
#endif /* not yywrap */
|
||||
|
||||
#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((char *)yytext);
|
||||
amu_return(LEFT_BRACKET);
|
||||
}
|
||||
|
||||
\] {
|
||||
dprintf("%8d: Right bracket \"%s\"\n", yytext);
|
||||
yylval.strtype = strdup((char *)yytext);
|
||||
amu_return(RIGHT_BRACKET);
|
||||
}
|
||||
|
||||
= {
|
||||
dprintf("%8d: Equal \"%s\"\n", yytext);
|
||||
yylval.strtype = strdup((char *)yytext);
|
||||
amu_return(EQUAL);
|
||||
}
|
||||
|
||||
[ \t]* {
|
||||
dprintf("%8d: Whitespace \"%s\"\n", yytext);
|
||||
}
|
||||
"#"[^\n]*\n {
|
||||
/* a comment line includes the terminating \n */
|
||||
yylineno++;
|
||||
yytext[strlen((char *)yytext)-1] = '\0';
|
||||
dprintf("%8d: Comment \"%s\"\n", yytext);
|
||||
}
|
||||
|
||||
{NONWSCHAR}{NONWSCHAR}* {
|
||||
dprintf("%8d: Non-WS string \"%s\"\n", yytext);
|
||||
yylval.strtype = strdup((char *)yytext);
|
||||
amu_return(NONWS_STRING);
|
||||
}
|
||||
|
||||
\"{NONQUOTE}{NONQUOTE}*\" {
|
||||
dprintf("%8d: QUOTED-Non-WS-EQ string \"%s\"\n", yytext);
|
||||
/* must strip quotes */
|
||||
yytext[strlen((char *)yytext)-1] = '\0';
|
||||
yylval.strtype = strdup((char *)&yytext[1]);
|
||||
amu_return(QUOTED_NONWSEQ_STRING);
|
||||
}
|
||||
|
||||
{NONWSEQCHAR}{NONWSEQCHAR}* {
|
||||
dprintf("%8d: Non-WS-EQ string \"%s\"\n", yytext);
|
||||
yylval.strtype = strdup((char *)yytext);
|
||||
amu_return(NONWSEQ_STRING);
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
/*
|
||||
* some systems such as DU-4.x have a different GNU flex in /usr/bin
|
||||
* which automatically generates yywrap macros and symbols. So I must
|
||||
* distinguish between them and when yywrap is actually needed.
|
||||
*/
|
||||
#ifndef yywrap
|
||||
int yywrap(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif /* not yywrap */
|
389
contrib/amd/amd/get_args.c
Normal file
389
contrib/amd/amd/get_args.c
Normal file
@ -0,0 +1,389 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: get_args.c,v 5.2.2.1 1992/02/09 15:08:23 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Argument decode
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* include auto-generated version file */
|
||||
#include <build_version.h>
|
||||
|
||||
char *conf_file = "/etc/amd.conf"; /* default amd configuration file */
|
||||
char *conf_tag = NULL; /* default conf file tags to use */
|
||||
int usage = 0;
|
||||
int use_conf_file = 0; /* default don't use amd.conf file */
|
||||
char *mnttab_file_name = NULL; /* symbol must be available always */
|
||||
#ifdef DEBUG
|
||||
int debug_flags = D_AMQ /* Register AMQ */
|
||||
| D_DAEMON; /* Enter daemon mode */
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
/*
|
||||
* Return the version string (dynamic buffer)
|
||||
*/
|
||||
char *
|
||||
get_version_string(void)
|
||||
{
|
||||
static char *vers = NULL;
|
||||
char tmpbuf[1024];
|
||||
char *wire_buf;
|
||||
int wire_buf_len = 0;
|
||||
|
||||
/* first get dynamic string listing all known networks */
|
||||
wire_buf = print_wires();
|
||||
if (wire_buf)
|
||||
wire_buf_len = strlen(wire_buf);
|
||||
|
||||
vers = xmalloc(2048 + wire_buf_len);
|
||||
sprintf(vers, "%s\n%s\n%s\n%s\n",
|
||||
"Copyright (c) 1997-1998 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.");
|
||||
sprintf(tmpbuf, "%s version %s (build %d).\n",
|
||||
PACKAGE, VERSION, AMU_BUILD_VERSION);
|
||||
strcat(vers, tmpbuf);
|
||||
sprintf(tmpbuf, "Built by %s@%s on date %s.\n",
|
||||
USER_NAME, HOST_NAME, CONFIG_DATE);
|
||||
strcat(vers, tmpbuf);
|
||||
sprintf(tmpbuf, "cpu=%s (%s-endian), arch=%s, karch=%s.\n",
|
||||
cpu, endian, gopt.arch, gopt.karch);
|
||||
strcat(vers, tmpbuf);
|
||||
sprintf(tmpbuf, "full_os=%s, os=%s, osver=%s, vendor=%s.\n",
|
||||
HOST_OS, gopt.op_sys, gopt.op_sys_ver, HOST_VENDOR);
|
||||
strcat(vers, tmpbuf);
|
||||
|
||||
strcat(vers, "Map support for: ");
|
||||
mapc_showtypes(tmpbuf);
|
||||
strcat(vers, tmpbuf);
|
||||
strcat(vers, ".\nAMFS: ");
|
||||
ops_showamfstypes(tmpbuf);
|
||||
strcat(vers, tmpbuf);
|
||||
strcat(vers, ".\nFS: ");
|
||||
ops_showfstypes(tmpbuf);
|
||||
strcat(vers, tmpbuf);
|
||||
|
||||
/* append list of networks if available */
|
||||
if (wire_buf) {
|
||||
strcat(vers, wire_buf);
|
||||
XFREE(wire_buf);
|
||||
}
|
||||
|
||||
return vers;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
get_args(int argc, char *argv[])
|
||||
{
|
||||
int opt_ch;
|
||||
FILE *fp = stdin;
|
||||
|
||||
/* if no arguments were passed, try to use /etc/amd.conf file */
|
||||
if (argc <= 1)
|
||||
use_conf_file = 1;
|
||||
|
||||
while ((opt_ch = getopt(argc, argv, "nprvSa:c:d:k:l:o:t:w:x:y:C:D:F:T:O:H")) != EOF)
|
||||
switch (opt_ch) {
|
||||
|
||||
case 'a':
|
||||
if (*optarg != '/') {
|
||||
fprintf(stderr, "%s: -a option must begin with a '/'\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
gopt.auto_dir = optarg;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
gopt.am_timeo = atoi(optarg);
|
||||
if (gopt.am_timeo <= 0)
|
||||
gopt.am_timeo = AM_TTL;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
gopt.sub_domain = optarg;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
gopt.karch = optarg;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
gopt.logfile = optarg;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
gopt.flags |= CFM_NORMALIZE_HOSTNAMES;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
gopt.op_sys_ver = optarg;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
gopt.flags |= CFM_PRINT_PID;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
gopt.flags |= CFM_RESTART_EXISTING_MOUNTS;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
/* timeo.retrans */
|
||||
{
|
||||
char *dot = strchr(optarg, '.');
|
||||
if (dot)
|
||||
*dot = '\0';
|
||||
if (*optarg) {
|
||||
gopt.amfs_auto_timeo = atoi(optarg);
|
||||
}
|
||||
if (dot) {
|
||||
gopt.amfs_auto_retrans = atoi(dot + 1);
|
||||
*dot = '.';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
fputs(get_version_string(), stderr);
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
gopt.am_timeo_w = atoi(optarg);
|
||||
if (gopt.am_timeo_w <= 0)
|
||||
gopt.am_timeo_w = AM_TTL_W;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
usage += switch_option(optarg);
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
#ifdef HAVE_MAP_NIS
|
||||
gopt.nis_domain = optarg;
|
||||
#else /* not HAVE_MAP_NIS */
|
||||
plog(XLOG_USER, "-y: option ignored. No NIS support available.");
|
||||
#endif /* not HAVE_MAP_NIS */
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
gopt.cluster = optarg;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
#ifdef DEBUG
|
||||
usage += debug_option(optarg);
|
||||
#else /* not DEBUG */
|
||||
fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n", progname);
|
||||
#endif /* not DEBUG */
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
conf_file = optarg;
|
||||
use_conf_file = 1;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
goto show_usage;
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
gopt.op_sys = optarg;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
gopt.flags &= ~CFM_PROCESS_LOCK; /* turn process locking off */
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
conf_tag = optarg;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* amd.conf file: if not command-line arguments were used, or if -F was
|
||||
* specified, then use that amd.conf file. If the file cannot be opened,
|
||||
* abort amd. If it can be found, open it, parse it, and then close it.
|
||||
*/
|
||||
if (use_conf_file && conf_file) {
|
||||
fp = fopen(conf_file, "r");
|
||||
if (!fp) {
|
||||
char buf[128];
|
||||
sprintf(buf, "Amd configuration file (%s)", conf_file);
|
||||
perror(buf);
|
||||
exit(1);
|
||||
}
|
||||
yyin = fp;
|
||||
yyparse();
|
||||
fclose(fp);
|
||||
if (process_last_regular_map() != 0)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* make sure there are some default options defined */
|
||||
if (xlog_level_init == ~0) {
|
||||
switch_option("");
|
||||
}
|
||||
#ifdef DEBUG
|
||||
usage += switch_option("debug");
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* log information regarding amd.conf file */
|
||||
if (use_conf_file && conf_file)
|
||||
plog(XLOG_INFO, "using configuration file %s", conf_file);
|
||||
|
||||
#ifdef HAVE_MAP_LDAP
|
||||
/* ensure that if ldap_base is specified, that also ldap_hostports is */
|
||||
if (gopt.ldap_hostports && !gopt.ldap_base) {
|
||||
fprintf(stderr, "must specify both ldap_hostports and ldap_base\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* HAVE_MAP_LDAP */
|
||||
|
||||
if (usage)
|
||||
goto show_usage;
|
||||
|
||||
while (optind <= argc - 2) {
|
||||
char *dir = argv[optind++];
|
||||
char *map = argv[optind++];
|
||||
char *opts = "";
|
||||
if (argv[optind] && *argv[optind] == '-')
|
||||
opts = &argv[optind++][1];
|
||||
|
||||
root_newmap(dir, opts, map, NULL);
|
||||
}
|
||||
|
||||
if (optind == argc) {
|
||||
/*
|
||||
* Append domain name to hostname.
|
||||
* sub_domain overrides hostdomain
|
||||
* if given.
|
||||
*/
|
||||
if (gopt.sub_domain)
|
||||
hostdomain = gopt.sub_domain;
|
||||
if (*hostdomain == '.')
|
||||
hostdomain++;
|
||||
strcat(hostd, ".");
|
||||
strcat(hostd, hostdomain);
|
||||
|
||||
#ifdef MOUNT_TABLE_ON_FILE
|
||||
# ifdef DEBUG
|
||||
if (debug_flags & D_MTAB)
|
||||
mnttab_file_name = DEBUG_MNTTAB;
|
||||
else
|
||||
# endif /* DEBUG */
|
||||
mnttab_file_name = MNTTAB_FILE_NAME;
|
||||
#else /* not MOUNT_TABLE_ON_FILE */
|
||||
# ifdef DEBUG
|
||||
if (debug_flags & D_MTAB)
|
||||
dlog("-D mtab option ignored");
|
||||
# endif /* DEBUG */
|
||||
#endif /* not MOUNT_TABLE_ON_FILE */
|
||||
|
||||
if (switch_to_logfile(gopt.logfile) != 0)
|
||||
plog(XLOG_USER, "Cannot switch logfile");
|
||||
|
||||
/*
|
||||
* If the kernel architecture was not specified
|
||||
* then use the machine architecture.
|
||||
*/
|
||||
if (gopt.karch == 0)
|
||||
gopt.karch = gopt.arch;
|
||||
|
||||
if (gopt.cluster == 0)
|
||||
gopt.cluster = hostdomain;
|
||||
|
||||
if (gopt.amfs_auto_timeo <= 0)
|
||||
gopt.amfs_auto_timeo = AMFS_AUTO_TIMEO;
|
||||
if (gopt.amfs_auto_retrans <= 0)
|
||||
gopt.amfs_auto_retrans = AMFS_AUTO_RETRANS;
|
||||
if (gopt.amfs_auto_retrans <= 0)
|
||||
gopt.amfs_auto_retrans = 3; /* XXX */
|
||||
return;
|
||||
}
|
||||
|
||||
show_usage:
|
||||
fprintf(stderr,
|
||||
"Usage: %s [-nprvHS] [-a mount_point] [-c cache_time] [-d domain]\n\
|
||||
\t[-k kernel_arch] [-l logfile%s\n\
|
||||
\t[-t timeout.retrans] [-w wait_timeout] [-C cluster_name]\n\
|
||||
\t[-o op_sys_ver] [-O op_sys_name]\n\
|
||||
\t[-F conf_file] [-T conf_tag]", progname,
|
||||
#ifdef HAVE_SYSLOG
|
||||
# ifdef LOG_DAEMON
|
||||
"|\"syslog[:facility]\"]"
|
||||
# else /* not LOG_DAEMON */
|
||||
"|\"syslog\"]"
|
||||
# endif /* not LOG_DAEMON */
|
||||
#else /* not HAVE_SYSLOG */
|
||||
"]"
|
||||
#endif /* not HAVE_SYSLOG */
|
||||
);
|
||||
|
||||
#ifdef HAVE_MAP_NIS
|
||||
fputs(" [-y nis-domain]\n", stderr);
|
||||
#else /* not HAVE_MAP_NIS */
|
||||
fputc('\n', stderr);
|
||||
#endif /* HAVE_MAP_NIS */
|
||||
|
||||
show_opts('x', xlog_opt);
|
||||
#ifdef DEBUG
|
||||
show_opts('D', dbg_opt);
|
||||
#endif /* DEBUG */
|
||||
fprintf(stderr, "\t[directory mapname [-map_options]] ...\n");
|
||||
exit(1);
|
||||
}
|
265
contrib/amd/amd/info_file.c
Normal file
265
contrib/amd/amd/info_file.c
Normal file
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: info_file.c,v 5.2.2.1 1992/02/09 15:08:28 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get info from file
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
#define MAX_LINE_LEN 1500
|
||||
|
||||
/* forward declarations */
|
||||
int file_init(mnt_map *m, char *map, time_t *tp);
|
||||
int file_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *));
|
||||
int file_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
|
||||
int file_mtime(mnt_map *m, char *map, time_t *tp);
|
||||
|
||||
|
||||
static int
|
||||
read_line(char *buf, int size, FILE * fp)
|
||||
{
|
||||
int done = 0;
|
||||
|
||||
do {
|
||||
while (fgets(buf, size, fp)) {
|
||||
int len = strlen(buf);
|
||||
done += len;
|
||||
if (len > 1 && buf[len - 2] == '\\' &&
|
||||
buf[len - 1] == '\n') {
|
||||
int ch;
|
||||
buf += len - 2;
|
||||
size -= len - 2;
|
||||
*buf = '\n';
|
||||
buf[1] = '\0';
|
||||
/*
|
||||
* Skip leading white space on next line
|
||||
*/
|
||||
while ((ch = getc(fp)) != EOF &&
|
||||
isascii(ch) && isspace(ch)) ;
|
||||
(void) ungetc(ch, fp);
|
||||
} else {
|
||||
return done;
|
||||
}
|
||||
}
|
||||
} while (size > 0 && !feof(fp));
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Try to locate a key in a file
|
||||
*/
|
||||
static int
|
||||
search_or_reload_file(FILE * fp, char *map, char *key, char **val, mnt_map *m, void (*fn) (mnt_map *m, char *, char *))
|
||||
{
|
||||
char key_val[MAX_LINE_LEN];
|
||||
int chuck = 0;
|
||||
int line_no = 0;
|
||||
|
||||
while (read_line(key_val, sizeof(key_val), fp)) {
|
||||
char *kp;
|
||||
char *cp;
|
||||
char *hash;
|
||||
int len = strlen(key_val);
|
||||
line_no++;
|
||||
|
||||
/*
|
||||
* Make sure we got the whole line
|
||||
*/
|
||||
if (key_val[len - 1] != '\n') {
|
||||
plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map);
|
||||
chuck = 1;
|
||||
} else {
|
||||
key_val[len - 1] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Strip comments
|
||||
*/
|
||||
hash = strchr(key_val, '#');
|
||||
if (hash)
|
||||
*hash = '\0';
|
||||
|
||||
/*
|
||||
* Find start of key
|
||||
*/
|
||||
for (kp = key_val; *kp && isascii(*kp) && isspace((int)*kp); kp++) ;
|
||||
|
||||
/*
|
||||
* Ignore blank lines
|
||||
*/
|
||||
if (!*kp)
|
||||
goto again;
|
||||
|
||||
/*
|
||||
* Find end of key
|
||||
*/
|
||||
for (cp = kp; *cp && (!isascii(*cp) || !isspace((int)*cp)); cp++) ;
|
||||
|
||||
/*
|
||||
* Check whether key matches
|
||||
*/
|
||||
if (*cp)
|
||||
*cp++ = '\0';
|
||||
|
||||
if (fn || (*key == *kp && STREQ(key, kp))) {
|
||||
while (*cp && isascii(*cp) && isspace((int)*cp))
|
||||
cp++;
|
||||
if (*cp) {
|
||||
/*
|
||||
* Return a copy of the data
|
||||
*/
|
||||
char *dc = strdup(cp);
|
||||
if (fn) {
|
||||
(*fn) (m, strdup(kp), dc);
|
||||
} else {
|
||||
*val = dc;
|
||||
#ifdef DEBUG
|
||||
dlog("%s returns %s", key, dc);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
if (!fn)
|
||||
return 0;
|
||||
} else {
|
||||
plog(XLOG_USER, "%s: line %d has no value field", map, line_no);
|
||||
}
|
||||
}
|
||||
|
||||
again:
|
||||
/*
|
||||
* If the last read didn't get a whole line then
|
||||
* throw away the remainder before continuing...
|
||||
*/
|
||||
if (chuck) {
|
||||
while (fgets(key_val, sizeof(key_val), fp) &&
|
||||
!strchr(key_val, '\n')) ;
|
||||
chuck = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return fn ? 0 : ENOENT;
|
||||
}
|
||||
|
||||
|
||||
static FILE *
|
||||
file_open(char *map, time_t *tp)
|
||||
{
|
||||
FILE *mapf = fopen(map, "r");
|
||||
|
||||
if (mapf && tp) {
|
||||
struct stat stb;
|
||||
if (fstat(fileno(mapf), &stb) < 0)
|
||||
*tp = clocktime();
|
||||
else
|
||||
*tp = stb.st_mtime;
|
||||
}
|
||||
return mapf;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
file_init(mnt_map *m, char *map, time_t *tp)
|
||||
{
|
||||
FILE *mapf = file_open(map, tp);
|
||||
|
||||
if (mapf) {
|
||||
fclose(mapf);
|
||||
return 0;
|
||||
}
|
||||
return errno;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
file_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *))
|
||||
{
|
||||
FILE *mapf = file_open(map, (time_t *) 0);
|
||||
|
||||
if (mapf) {
|
||||
int error = search_or_reload_file(mapf, map, 0, 0, m, fn);
|
||||
(void) fclose(mapf);
|
||||
return error;
|
||||
}
|
||||
return errno;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
file_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
|
||||
{
|
||||
time_t t;
|
||||
FILE *mapf = file_open(map, &t);
|
||||
|
||||
if (mapf) {
|
||||
int error;
|
||||
if (*tp < t) {
|
||||
*tp = t;
|
||||
error = -1;
|
||||
} else {
|
||||
error = search_or_reload_file(mapf, map, key, pval, 0, 0);
|
||||
}
|
||||
(void) fclose(mapf);
|
||||
return error;
|
||||
}
|
||||
return errno;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
file_mtime(mnt_map *m, char *map, time_t *tp)
|
||||
{
|
||||
FILE *mapf = file_open(map, tp);
|
||||
|
||||
if (mapf) {
|
||||
(void) fclose(mapf);
|
||||
return 0;
|
||||
}
|
||||
return errno;
|
||||
}
|
163
contrib/amd/amd/info_hesiod.c
Normal file
163
contrib/amd/amd/info_hesiod.c
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: info_hesiod.c,v 1.1 1997-1998/07/11 08:34:52 danny Exp danny $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get info from Hesiod
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
#define HES_PREFIX "hesiod."
|
||||
#define HES_PREFLEN 7
|
||||
|
||||
#ifdef HAVE_HESIOD_INIT
|
||||
/* bsdi3 does not define this extern in any header file */
|
||||
extern char **hesiod_resolve(void *context, const char *name, const char *type);
|
||||
|
||||
static voidp hesiod_context;
|
||||
#endif /* HAVE_HESIOD_INIT */
|
||||
|
||||
/*
|
||||
* No easy way to probe the server - check the map name begins with "hesiod."
|
||||
* Note: this name includes 'amu_' so as to not conflict with libhesiod's
|
||||
* hesiod_init() function.
|
||||
*/
|
||||
int
|
||||
amu_hesiod_init(mnt_map *m, char *map, time_t *tp)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
dlog("amu_hesiod_init(%s)", map);
|
||||
#endif /* DEBUG */
|
||||
*tp = 0;
|
||||
|
||||
#ifdef HAVE_HESIOD_INIT
|
||||
if(!hesiod_context && hesiod_init(&hesiod_context) != 0)
|
||||
return ENOENT;
|
||||
#endif /* HAVE_HESIOD_INIT */
|
||||
|
||||
return NSTREQ(map, HES_PREFIX, HES_PREFLEN) ? 0 : ENOENT;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Do a Hesiod nameserver call.
|
||||
* Modify time is ignored by Hesiod - XXX
|
||||
*/
|
||||
int
|
||||
hesiod_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
|
||||
{
|
||||
char hes_key[MAXPATHLEN];
|
||||
char **rvec;
|
||||
#ifndef HAVE_HESIOD_INIT
|
||||
int error;
|
||||
#endif /* not HAVE_HESIOD_INIT */
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("hesiod_search(m=%x, map=%s, key=%s, pval=%x tp=%x)", m, map, key, pval, tp);
|
||||
#endif /* DEBUG */
|
||||
|
||||
sprintf(hes_key, "%s.%s", key, map + HES_PREFLEN);
|
||||
|
||||
/*
|
||||
* Call the resolver
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
dlog("Hesiod base is: %s\n", gopt.hesiod_base);
|
||||
dlog("hesiod_search: hes_resolve(%s, %s)", hes_key, gopt.hesiod_base);
|
||||
if (debug_flags & D_INFO)
|
||||
_res.options |= RES_DEBUG;
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifdef HAVE_HESIOD_INIT
|
||||
/* new style hesiod */
|
||||
rvec = hesiod_resolve(hesiod_context, hes_key, gopt.hesiod_base);
|
||||
#else /* not HAVE_HESIOD_INIT */
|
||||
rvec = hes_resolve(hes_key, gopt.hesiod_base);
|
||||
#endif /* not HAVE_HESIOD_INIT */
|
||||
|
||||
/*
|
||||
* If a reply was forthcoming then return
|
||||
* it (and free subsequent replies)
|
||||
*/
|
||||
if (rvec && *rvec) {
|
||||
*pval = *rvec;
|
||||
while (*++rvec)
|
||||
XFREE(*rvec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_HESIOD_INIT
|
||||
/* new style hesiod */
|
||||
return errno;
|
||||
#else /* not HAVE_HESIOD_INIT */
|
||||
/*
|
||||
* Otherwise reflect the hesiod error into a Un*x error
|
||||
*/
|
||||
# ifdef DEBUG
|
||||
dlog("hesiod_search: Error: %d", hes_error());
|
||||
# endif /* DEBUG */
|
||||
switch (hes_error()) {
|
||||
case HES_ER_NOTFOUND:
|
||||
error = ENOENT;
|
||||
break;
|
||||
case HES_ER_CONFIG:
|
||||
error = EIO;
|
||||
break;
|
||||
case HES_ER_NET:
|
||||
error = ETIMEDOUT;
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
# ifdef DEBUG
|
||||
dlog("hesiod_search: Returning: %d", error);
|
||||
# endif /* DEBUG */
|
||||
return error;
|
||||
#endif /* not HAVE_HESIOD_INIT */
|
||||
}
|
465
contrib/amd/amd/info_ldap.c
Normal file
465
contrib/amd/amd/info_ldap.c
Normal file
@ -0,0 +1,465 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: info_ldap.c,v 5.2.2.1 1992/02/09 15:08:29 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Get info from LDAP (Lightweight Directory Access Protocol)
|
||||
* LDAP Home Page: http://www.umich.edu/~rsug/ldap/
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
|
||||
/*
|
||||
* MACROS:
|
||||
*/
|
||||
#define AMD_LDAP_TYPE "ldap"
|
||||
/* Time to live for an LDAP cached in an mnt_map */
|
||||
#define AMD_LDAP_TTL 3600
|
||||
#define AMD_LDAP_RETRIES 5
|
||||
#define AMD_LDAP_HOST "ldap"
|
||||
#ifndef LDAP_PORT
|
||||
# define LDAP_PORT 389
|
||||
#endif /* LDAP_PORT */
|
||||
|
||||
/* How timestamps are searched */
|
||||
#define AMD_LDAP_TSFILTER "(&(objectClass=amdmapTimestamp)(amdmapName=%s))"
|
||||
/* How maps are searched */
|
||||
#define AMD_LDAP_FILTER "(&(objectClass=amdmap)(amdmapName=%s)(amdmapKey=%s))"
|
||||
/* How timestamps are stored */
|
||||
#define AMD_LDAP_TSATTR "amdmaptimestamp"
|
||||
/* How maps are stored */
|
||||
#define AMD_LDAP_ATTR "amdmapvalue"
|
||||
|
||||
/*
|
||||
* TYPEDEFS:
|
||||
*/
|
||||
typedef struct ald_ent ALD;
|
||||
typedef struct cr_ent CR;
|
||||
typedef struct he_ent HE;
|
||||
|
||||
/*
|
||||
* STRUCTURES:
|
||||
*/
|
||||
struct ald_ent {
|
||||
LDAP *ldap;
|
||||
HE *hostent;
|
||||
CR *credentials;
|
||||
time_t timestamp;
|
||||
};
|
||||
|
||||
struct cr_ent {
|
||||
char *who;
|
||||
char *pw;
|
||||
int method;
|
||||
};
|
||||
|
||||
struct he_ent {
|
||||
char *host;
|
||||
int port;
|
||||
struct he_ent *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* FORWARD DECLARATIONS:
|
||||
*/
|
||||
static int amu_ldap_rebind(ALD *a);
|
||||
static int get_ldap_timestamp(LDAP *ld, char *map, time_t *ts);
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTIONS:
|
||||
*/
|
||||
|
||||
static void
|
||||
he_free(HE *h)
|
||||
{
|
||||
XFREE(h->host);
|
||||
if (h->next != NULL)
|
||||
he_free(h->next);
|
||||
XFREE(h);
|
||||
}
|
||||
|
||||
|
||||
static HE *
|
||||
string2he(char *s)
|
||||
{
|
||||
char *c, *p;
|
||||
HE *new, *old = NULL;
|
||||
|
||||
if (s == NULL)
|
||||
return (NULL);
|
||||
for (p = s; p; p = strchr(p, ',')) {
|
||||
if (old != NULL) {
|
||||
new = (HE *) xmalloc(sizeof(HE));
|
||||
old->next = new;
|
||||
old = new;
|
||||
} else {
|
||||
old = (HE *) xmalloc(sizeof(HE));
|
||||
old->next = NULL;
|
||||
}
|
||||
c = strchr(p, ':');
|
||||
if (c) { /* Host and port */
|
||||
*c++ = '\0';
|
||||
old->host = strdup(p);
|
||||
old->port = atoi(c);
|
||||
} else
|
||||
old->host = strdup(p);
|
||||
|
||||
}
|
||||
return (old);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cr_free(CR *c)
|
||||
{
|
||||
XFREE(c->who);
|
||||
XFREE(c->pw);
|
||||
XFREE(c);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ald_free(ALD *a)
|
||||
{
|
||||
he_free(a->hostent);
|
||||
cr_free(a->credentials);
|
||||
if (a->ldap != NULL)
|
||||
ldap_unbind(a->ldap);
|
||||
XFREE(a);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
amu_ldap_init(mnt_map *m, char *map, time_t *ts)
|
||||
{
|
||||
ALD *aldh;
|
||||
CR *creds;
|
||||
|
||||
if (!STREQ(gopt.map_type, AMD_LDAP_TYPE)) {
|
||||
return (ENOENT);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else {
|
||||
dlog("Map %s is ldap\n", map);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
aldh = (ALD *) xmalloc(sizeof(ALD));
|
||||
creds = (CR *) xmalloc(sizeof(CR));
|
||||
|
||||
aldh->hostent = string2he(gopt.ldap_hostports);
|
||||
if (aldh->hostent == NULL) {
|
||||
plog(XLOG_USER, "Unable to parse hostport %s for ldap map %s",
|
||||
gopt.ldap_hostports, map);
|
||||
return (ENOENT);
|
||||
}
|
||||
creds->who = "";
|
||||
creds->pw = "";
|
||||
creds->method = LDAP_AUTH_SIMPLE;
|
||||
aldh->credentials = creds;
|
||||
aldh->timestamp = 0;
|
||||
#ifdef DEBUG
|
||||
dlog("Trying for %s:%d\n", aldh->hostent->host, aldh->hostent->port);
|
||||
#endif /* DEBUG */
|
||||
if (amu_ldap_rebind(aldh)) {
|
||||
ald_free(aldh);
|
||||
return (ENOENT);
|
||||
}
|
||||
m->map_data = (void *) aldh;
|
||||
#ifdef DEBUG
|
||||
dlog("Bound to %s:%d\n", aldh->hostent->host, aldh->hostent->port);
|
||||
#endif /* DEBUG */
|
||||
if (get_ldap_timestamp(aldh->ldap, map, ts))
|
||||
return (ENOENT);
|
||||
#ifdef DEBUG
|
||||
dlog("Got timestamp for map %s: %d\n", map, *ts);
|
||||
#endif /* DEBUG */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
amu_ldap_rebind(ALD *a)
|
||||
{
|
||||
LDAP *ld;
|
||||
HE *h;
|
||||
CR *c = a->credentials;
|
||||
time_t now = clocktime();
|
||||
|
||||
if (a->ldap != NULL) {
|
||||
if ((a->timestamp - now) > AMD_LDAP_TTL) {
|
||||
#ifdef DEBUG
|
||||
dlog("Reestablishing ldap connection\n");
|
||||
#endif /* DEBUG */
|
||||
ldap_unbind(a->ldap);
|
||||
a->timestamp = now;
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
|
||||
while (TRUE) {
|
||||
for (h = a->hostent; h != NULL; h = h->next) {
|
||||
if ((ld = ldap_open(h->host, h->port)) == NULL) {
|
||||
plog(XLOG_WARNING, "Unable to ldap_open to %s:%d\n", h->host, h->port);
|
||||
break;
|
||||
}
|
||||
if (ldap_bind_s(ld, c->who, c->pw, c->method) != LDAP_SUCCESS) {
|
||||
plog(XLOG_WARNING, "Unable to ldap_bind to %s:%d as %s\n",
|
||||
h->host, h->port, c->who);
|
||||
break;
|
||||
}
|
||||
if (gopt.ldap_cache_seconds > 0) {
|
||||
ldap_enable_cache(ld, gopt.ldap_cache_seconds, gopt.ldap_cache_maxmem);
|
||||
a->ldap = ld;
|
||||
a->timestamp = now;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
plog(XLOG_WARNING, "Exausted list of ldap servers, looping.\n");
|
||||
}
|
||||
|
||||
plog(XLOG_USER, "Unable to (re)bind to any ldap hosts\n");
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_ldap_timestamp(LDAP * ld, char *map, time_t *ts)
|
||||
{
|
||||
struct timeval tv;
|
||||
char **vals, *end;
|
||||
char filter[MAXPATHLEN];
|
||||
int i, err, nentries = 0;
|
||||
LDAPMessage *res, *entry;
|
||||
|
||||
tv.tv_sec = 3;
|
||||
tv.tv_usec = 0;
|
||||
sprintf(filter, AMD_LDAP_TSFILTER, map);
|
||||
#ifdef DEBUG
|
||||
dlog("Getting timestamp for map %s\n", map);
|
||||
dlog("Filter is: %s\n", filter);
|
||||
dlog("Base is: %s\n", gopt.ldap_base);
|
||||
#endif /* DEBUG */
|
||||
for (i = 0; i < AMD_LDAP_RETRIES; i++) {
|
||||
err = ldap_search_st(ld,
|
||||
gopt.ldap_base,
|
||||
LDAP_SCOPE_SUBTREE,
|
||||
filter,
|
||||
0,
|
||||
0,
|
||||
&tv,
|
||||
&res);
|
||||
if (err == LDAP_SUCCESS)
|
||||
break;
|
||||
dlog("Timestamp search timed out, trying again...\n");
|
||||
}
|
||||
|
||||
if (err != LDAP_SUCCESS) {
|
||||
*ts = 0;
|
||||
plog(XLOG_USER, "LDAP timestamp search failed: %s\n",
|
||||
ldap_err2string(ld->ld_errno));
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
nentries = ldap_count_entries(ld, res);
|
||||
if (nentries == 0) {
|
||||
plog(XLOG_USER, "No timestamp entry for map %s\n", map);
|
||||
*ts = 0;
|
||||
ldap_msgfree(res);
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
entry = ldap_first_entry(ld, res);
|
||||
vals = ldap_get_values(ld, entry, AMD_LDAP_TSATTR);
|
||||
if (ldap_count_values(vals) == 0) {
|
||||
plog(XLOG_USER, "Missing timestamp value for map %s\n", map);
|
||||
*ts = 0;
|
||||
ldap_value_free(vals);
|
||||
ldap_msgfree(res);
|
||||
ldap_msgfree(entry);
|
||||
return (ENOENT);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
dlog("TS value is:%s:\n", vals[0]);
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (vals[0]) {
|
||||
*ts = (time_t) strtol(vals[0], &end, 10);
|
||||
if (end == vals[0]) {
|
||||
plog(XLOG_USER, "Unable to decode ldap timestamp %s for map %s\n",
|
||||
vals[0], map);
|
||||
err = ENOENT;
|
||||
}
|
||||
if (!*ts > 0) {
|
||||
plog(XLOG_USER, "Nonpositive timestamp %d for map %s\n",
|
||||
*ts, map);
|
||||
err = ENOENT;
|
||||
}
|
||||
} else {
|
||||
plog(XLOG_USER, "Empty timestamp value for map %s\n", map);
|
||||
*ts = 0;
|
||||
err = ENOENT;
|
||||
}
|
||||
|
||||
ldap_value_free(vals);
|
||||
ldap_msgfree(res);
|
||||
ldap_msgfree(entry);
|
||||
#ifdef DEBUG
|
||||
dlog("The timestamp for %s is %d (err=%d)\n", map, *ts, err);
|
||||
#endif /* DEBUG */
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
amu_ldap_search(mnt_map *m, char *map, char *key, char **pval, time_t *ts)
|
||||
{
|
||||
char **vals, filter[MAXPATHLEN];
|
||||
struct timeval tv;
|
||||
int i, err, nvals = 0, nentries = 0;
|
||||
LDAPMessage *entry, *res;
|
||||
ALD *a = (ALD *) (m->map_data);
|
||||
|
||||
tv.tv_sec = 2;
|
||||
tv.tv_usec = 0;
|
||||
if (a == NULL) {
|
||||
plog(XLOG_USER, "LDAP panic: no map data\n");
|
||||
return (EIO);
|
||||
}
|
||||
if (amu_ldap_rebind(a)) /* Check that's the handle is still valid */
|
||||
return (ENOENT);
|
||||
|
||||
sprintf(filter, AMD_LDAP_FILTER, map, key);
|
||||
#ifdef DEBUG
|
||||
dlog("Search with filter: %s\n", filter);
|
||||
#endif /* DEBUG */
|
||||
for (i = 0; i < AMD_LDAP_RETRIES; i++) {
|
||||
err = ldap_search_st(a->ldap,
|
||||
gopt.ldap_base,
|
||||
LDAP_SCOPE_SUBTREE,
|
||||
filter,
|
||||
0,
|
||||
0,
|
||||
&tv,
|
||||
&res);
|
||||
if (err == LDAP_SUCCESS)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (err) {
|
||||
case LDAP_SUCCESS:
|
||||
break;
|
||||
case LDAP_NO_SUCH_OBJECT:
|
||||
#ifdef DEBUG
|
||||
dlog("No object\n");
|
||||
#endif /* DEBUG */
|
||||
ldap_msgfree(res);
|
||||
return (ENOENT);
|
||||
default:
|
||||
plog(XLOG_USER, "LDAP search failed: %s\n",
|
||||
ldap_err2string(a->ldap->ld_errno));
|
||||
ldap_msgfree(res);
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
nentries = ldap_count_entries(a->ldap, res);
|
||||
#ifdef DEBUG
|
||||
dlog("Search found %d entries\n", nentries);
|
||||
#endif /* DEBUG */
|
||||
if (nentries == 0) {
|
||||
ldap_msgfree(res);
|
||||
return (ENOENT);
|
||||
}
|
||||
entry = ldap_first_entry(a->ldap, res);
|
||||
vals = ldap_get_values(a->ldap, entry, AMD_LDAP_ATTR);
|
||||
nvals = ldap_count_values(vals);
|
||||
if (nvals == 0) {
|
||||
plog(XLOG_USER, "Missing value for %s in map %s\n", key, map);
|
||||
ldap_value_free(vals);
|
||||
ldap_msgfree(res);
|
||||
ldap_msgfree(entry);
|
||||
return (EIO);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
dlog("Map %s, %s => %s\n", map, key, vals[0]);
|
||||
#endif /* DEBUG */
|
||||
if (vals[0]) {
|
||||
*pval = strdup(vals[0]);
|
||||
err = 0;
|
||||
} else {
|
||||
plog(XLOG_USER, "Empty value for %s in map %s\n", key, map);
|
||||
err = ENOENT;
|
||||
}
|
||||
ldap_msgfree(res);
|
||||
ldap_msgfree(entry);
|
||||
ldap_value_free(vals);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
amu_ldap_mtime(mnt_map *m, char *map, time_t *ts)
|
||||
{
|
||||
ALD *aldh = (ALD *) (m->map_data);
|
||||
|
||||
if (aldh == NULL) {
|
||||
dlog("LDAP panic: unable to find map data\n");
|
||||
return (ENOENT);
|
||||
}
|
||||
if (amu_ldap_rebind(aldh)) {
|
||||
return (ENOENT);
|
||||
}
|
||||
if (get_ldap_timestamp(aldh->ldap, map, ts)) {
|
||||
return (ENOENT);
|
||||
}
|
||||
return (0);
|
||||
}
|
141
contrib/amd/amd/info_ndbm.c
Normal file
141
contrib/amd/amd/info_ndbm.c
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: info_ndbm.c,v 5.2.2.1 1992/02/09 15:08:31 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get info from NDBM map
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* forward declarations */
|
||||
int ndbm_init(mnt_map *m, char *map, time_t *tp);
|
||||
int ndbm_mtime(mnt_map *m, char *map, time_t *tp);
|
||||
int ndbm_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
|
||||
|
||||
|
||||
static int
|
||||
search_ndbm(DBM *db, char *key, char **val)
|
||||
{
|
||||
datum k, v;
|
||||
|
||||
k.dptr = key;
|
||||
k.dsize = strlen(key) + 1;
|
||||
v = dbm_fetch(db, k);
|
||||
if (v.dptr) {
|
||||
*val = strdup(v.dptr);
|
||||
return 0;
|
||||
}
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ndbm_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
|
||||
{
|
||||
DBM *db;
|
||||
|
||||
db = dbm_open(map, O_RDONLY, 0);
|
||||
if (db) {
|
||||
struct stat stb;
|
||||
int error;
|
||||
#ifdef DBM_SUFFIX
|
||||
char dbfilename[256];
|
||||
|
||||
strcpy(dbfilename, map);
|
||||
strcat(dbfilename, DBM_SUFFIX);
|
||||
error = stat(dbfilename, &stb);
|
||||
#else /* not DBM_SUFFIX */
|
||||
error = fstat(dbm_pagfno(db), &stb);
|
||||
#endif /* not DBM_SUFFIX */
|
||||
if (!error && *tp < stb.st_mtime) {
|
||||
*tp = stb.st_mtime;
|
||||
error = -1;
|
||||
} else {
|
||||
error = search_ndbm(db, key, pval);
|
||||
}
|
||||
(void) dbm_close(db);
|
||||
return error;
|
||||
}
|
||||
return errno;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ndbm_init(mnt_map *m, char *map, time_t *tp)
|
||||
{
|
||||
DBM *db;
|
||||
|
||||
db = dbm_open(map, O_RDONLY, 0);
|
||||
if (db) {
|
||||
struct stat stb;
|
||||
int error;
|
||||
#ifdef DBM_SUFFIX
|
||||
char dbfilename[256];
|
||||
|
||||
strcpy(dbfilename, map);
|
||||
strcat(dbfilename, DBM_SUFFIX);
|
||||
error = stat(dbfilename, &stb);
|
||||
#else /* not DBM_SUFFIX */
|
||||
error = fstat(dbm_pagfno(db), &stb);
|
||||
#endif /* not DBM_SUFFIX */
|
||||
if (error < 0)
|
||||
*tp = clocktime();
|
||||
else
|
||||
*tp = stb.st_mtime;
|
||||
dbm_close(db);
|
||||
return 0;
|
||||
}
|
||||
return errno;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ndbm_mtime(mnt_map *m, char *map, time_t *tp)
|
||||
{
|
||||
return ndbm_init(m,map, tp);
|
||||
}
|
401
contrib/amd/amd/info_nis.c
Normal file
401
contrib/amd/amd/info_nis.c
Normal file
@ -0,0 +1,401 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: info_nis.c,v 5.2.2.1 1992/02/09 15:08:32 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get info from NIS map
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/*
|
||||
* NIS+ servers in NIS compat mode don't have yp_order()
|
||||
*/
|
||||
static int has_yp_order = FALSE;
|
||||
|
||||
/* forward declarations */
|
||||
int nis_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *));
|
||||
int nis_search(mnt_map *m, char *map, char *key, char **val, time_t *tp);
|
||||
int nis_init(mnt_map *m, char *map, time_t *tp);
|
||||
int nis_mtime(mnt_map *m, char *map, time_t *tp);
|
||||
|
||||
/* typedefs */
|
||||
typedef void (*nis_callback_fxn_t)(mnt_map *, char *, char *);
|
||||
#ifndef DEFINED_YPALL_CALLBACK_FXN_T
|
||||
typedef int (*ypall_callback_fxn_t)();
|
||||
#endif /* DEFINED_YPALL_CALLBACK_FXN_T */
|
||||
|
||||
struct nis_callback_data {
|
||||
mnt_map *ncd_m;
|
||||
char *ncd_map;
|
||||
nis_callback_fxn_t ncd_fn;
|
||||
};
|
||||
|
||||
/* Map to the right version of yp_all */
|
||||
#ifdef HAVE_BAD_YP_ALL
|
||||
# define yp_all am_yp_all
|
||||
static int am_yp_all(char *indomain, char *inmap, struct ypall_callback *incallback);
|
||||
#endif /* HAVE_BAD_YP_ALL */
|
||||
|
||||
|
||||
/*
|
||||
* Figure out the nis domain name
|
||||
*/
|
||||
static int
|
||||
determine_nis_domain(void)
|
||||
{
|
||||
static int nis_not_running = 0;
|
||||
char default_domain[YPMAXDOMAIN];
|
||||
|
||||
if (nis_not_running)
|
||||
return ENOENT;
|
||||
|
||||
if (getdomainname(default_domain, sizeof(default_domain)) < 0) {
|
||||
nis_not_running = 1;
|
||||
plog(XLOG_ERROR, "getdomainname: %m");
|
||||
return EIO;
|
||||
}
|
||||
if (!*default_domain) {
|
||||
nis_not_running = 1;
|
||||
plog(XLOG_WARNING, "NIS domain name is not set. NIS ignored.");
|
||||
return ENOENT;
|
||||
}
|
||||
gopt.nis_domain = strdup(default_domain);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Callback from yp_all
|
||||
*/
|
||||
static int
|
||||
callback(int status, char *key, int kl, char *val, int vl, char *data)
|
||||
{
|
||||
struct nis_callback_data *ncdp = (struct nis_callback_data *) data;
|
||||
|
||||
if (status == YP_TRUE) {
|
||||
|
||||
/*
|
||||
* Add to list of maps
|
||||
*/
|
||||
char *kp = strnsave(key, kl);
|
||||
char *vp = strnsave(val, vl);
|
||||
(*ncdp->ncd_fn) (ncdp->ncd_m, kp, vp);
|
||||
|
||||
/*
|
||||
* We want more ...
|
||||
*/
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
* NOMORE means end of map - otherwise log error
|
||||
*/
|
||||
if (status != YP_NOMORE) {
|
||||
/*
|
||||
* Check what went wrong
|
||||
*/
|
||||
int e = ypprot_err(status);
|
||||
|
||||
#ifdef DEBUG
|
||||
plog(XLOG_ERROR, "yp enumeration of %s: %s, status=%d, e=%d",
|
||||
ncdp->ncd_map, yperr_string(e), status, e);
|
||||
#else /* not DEBUG */
|
||||
plog(XLOG_ERROR, "yp enumeration of %s: %s", ncdp->ncd_map, yperr_string(e));
|
||||
#endif /* not DEBUG */
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nis_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *))
|
||||
{
|
||||
int error;
|
||||
struct nis_callback_data data;
|
||||
struct ypall_callback cbinfo;
|
||||
|
||||
if (!gopt.nis_domain) {
|
||||
error = determine_nis_domain();
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
data.ncd_m = m;
|
||||
data.ncd_map = map;
|
||||
data.ncd_fn = fn;
|
||||
cbinfo.data = (voidp) &data;
|
||||
cbinfo.foreach = (ypall_callback_fxn_t) callback;
|
||||
|
||||
/*
|
||||
* If you are using NIS and your yp_all function is "broken", you have to
|
||||
* get it fixed. The bug in yp_all() is that it does not close a TCP
|
||||
* connection to ypserv, and this ypserv runs out of open file descriptors,
|
||||
* getting into an infinite loop, thus all YP clients eventually unbind
|
||||
* and hang too.
|
||||
*/
|
||||
error = yp_all(gopt.nis_domain, map, &cbinfo);
|
||||
|
||||
if (error)
|
||||
plog(XLOG_ERROR, "error grabbing nis map of %s: %s", map, yperr_string(ypprot_err(error)));
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check if NIS is up, so we can determine if to clear the map or not.
|
||||
* Test it by checking the yp order.
|
||||
* Returns: 0 if NIS is down, 1 if it is up.
|
||||
*/
|
||||
int
|
||||
nis_isup(mnt_map *m, char *map)
|
||||
{
|
||||
YP_ORDER_OUTORDER_TYPE order;
|
||||
int error;
|
||||
static int last_status = 1; /* assume up by default */
|
||||
|
||||
if (has_yp_order) {
|
||||
error = yp_order(gopt.nis_domain, map, &order);
|
||||
if (error != 0) {
|
||||
plog(XLOG_ERROR,
|
||||
"nis_isup: error getting the order of map of %s: %s",
|
||||
map, yperr_string(ypprot_err(error)));
|
||||
last_status = 0;
|
||||
return 0; /* NIS is down */
|
||||
}
|
||||
}
|
||||
if (last_status == 0) { /* if was down before */
|
||||
time_t dummy;
|
||||
plog(XLOG_INFO, "nis_isup: NIS came back up for map %s", map);
|
||||
/* XXX: do we really need to reinitialize nis? */
|
||||
error = nis_init(m, map, &dummy);
|
||||
if (!error)
|
||||
last_status = 1;
|
||||
}
|
||||
return 1; /* NIS is up */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Try to locate a key using NIS.
|
||||
*/
|
||||
int
|
||||
nis_search(mnt_map *m, char *map, char *key, char **val, time_t *tp)
|
||||
{
|
||||
int outlen;
|
||||
int res;
|
||||
YP_ORDER_OUTORDER_TYPE order;
|
||||
|
||||
/*
|
||||
* Make sure domain initialised
|
||||
*/
|
||||
if (!gopt.nis_domain) {
|
||||
int error = determine_nis_domain();
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
if (has_yp_order) {
|
||||
/*
|
||||
* Check if map has changed
|
||||
*/
|
||||
if (yp_order(gopt.nis_domain, map, &order))
|
||||
return EIO;
|
||||
if ((time_t) order > *tp) {
|
||||
*tp = (time_t) order;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* NIS+ server without yp_order
|
||||
* Check if timeout has expired to invalidate the cache
|
||||
*/
|
||||
order = time(NULL);
|
||||
if ((time_t)order - *tp > gopt.am_timeo) {
|
||||
*tp = (time_t)order;
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup key
|
||||
*/
|
||||
res = yp_match(gopt.nis_domain, map, key, strlen(key), val, &outlen);
|
||||
|
||||
/*
|
||||
* Do something interesting with the return code
|
||||
*/
|
||||
switch (res) {
|
||||
case 0:
|
||||
return 0;
|
||||
|
||||
case YPERR_KEY:
|
||||
return ENOENT;
|
||||
|
||||
default:
|
||||
plog(XLOG_ERROR, "%s: %s", map, yperr_string(res));
|
||||
return EIO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nis_init(mnt_map *m, char *map, time_t *tp)
|
||||
{
|
||||
YP_ORDER_OUTORDER_TYPE order;
|
||||
int yp_order_result;
|
||||
char *master;
|
||||
|
||||
if (!gopt.nis_domain) {
|
||||
int error = determine_nis_domain();
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* To see if the map exists, try to find
|
||||
* a master for it.
|
||||
*/
|
||||
yp_order_result = yp_order(gopt.nis_domain, map, &order);
|
||||
switch (yp_order_result) {
|
||||
case 0:
|
||||
has_yp_order = TRUE;
|
||||
*tp = (time_t) order;
|
||||
#ifdef DEBUG
|
||||
dlog("NIS master for %s@%s has order %d", map, gopt.nis_domain, order);
|
||||
#endif /* DEBUG */
|
||||
break;
|
||||
case YPERR_YPERR:
|
||||
/* NIS+ server found ! */
|
||||
has_yp_order = FALSE;
|
||||
/* try yp_master() instead */
|
||||
if (yp_master(gopt.nis_domain, map, &master)) {
|
||||
return ENOENT;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
dlog("NIS master for %s@%s is a NIS+ server", map, gopt.nis_domain);
|
||||
#endif /* DEBUG */
|
||||
/* Use fake timestamps */
|
||||
*tp = time(NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ENOENT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nis_mtime(mnt_map *m, char *map, time_t *tp)
|
||||
{
|
||||
return nis_init(m, map, tp);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_BAD_YP_ALL
|
||||
/*
|
||||
* If you are using NIS and your yp_all function is "broken", use an
|
||||
* alternate code which avoids a bug in yp_all(). The bug in yp_all() is
|
||||
* that it does not close a TCP connection to ypserv, and this ypserv runs
|
||||
* out of open filedescriptors, getting into an infinite loop, thus all YP
|
||||
* clients enevtually unbind and hang too.
|
||||
*
|
||||
* Systems known to be plagued with this bug:
|
||||
* earlier SunOS 4.x
|
||||
* all irix systems (at this time, up to 6.4 was checked)
|
||||
*
|
||||
* -Erez Zadok <ezk@cs.columbia.edu>
|
||||
* -James Tanis <jtt@cs.columbia.edu> */
|
||||
static int
|
||||
am_yp_all(char *indomain, char *inmap, struct ypall_callback *incallback)
|
||||
{
|
||||
int i, j;
|
||||
char *outkey, *outval;
|
||||
int outkeylen, outvallen;
|
||||
char *outkey_old;
|
||||
int outkeylen_old;
|
||||
|
||||
plog(XLOG_INFO, "NIS map %s reloading using am_yp_all", inmap);
|
||||
|
||||
i = yp_first(indomain, inmap, &outkey, &outkeylen, &outval, &outvallen);
|
||||
if (i) {
|
||||
plog(XLOG_ERROR, "yp_first() returned error: %s\n", yperr_string(i));
|
||||
}
|
||||
do {
|
||||
j = (incallback->foreach)(YP_TRUE,
|
||||
outkey,
|
||||
outkeylen,
|
||||
outval,
|
||||
outvallen,
|
||||
incallback->data);
|
||||
if (j != FALSE) /* terminate loop */
|
||||
break;
|
||||
outkey_old = outkey;
|
||||
outkeylen_old = outkeylen;
|
||||
i = yp_next(indomain,
|
||||
inmap,
|
||||
outkey_old,
|
||||
outkeylen_old,
|
||||
&outkey,
|
||||
&outkeylen,
|
||||
&outval,
|
||||
&outvallen);
|
||||
} while (!i);
|
||||
#ifdef DEBUG
|
||||
if (i) {
|
||||
dlog("yp_next() returned error: %s\n", yperr_string(i));
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
if (i == YPERR_NOMORE)
|
||||
return 0;
|
||||
return i;
|
||||
}
|
||||
#endif /* HAVE_BAD_YP_ALL */
|
321
contrib/amd/amd/info_nisplus.c
Normal file
321
contrib/amd/amd/info_nisplus.c
Normal file
@ -0,0 +1,321 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: info_nisplus.c,v 5.2.2.1 1992/02/09 15:08:32 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get info from NIS+ (version 3) map
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
#define NISPLUS_KEY "key="
|
||||
#define NISPLUS_ORGDIR ".org_dir"
|
||||
|
||||
struct nis_callback_data {
|
||||
mnt_map *ncd_m;
|
||||
char *ncd_map;
|
||||
void (*ncd_fn)();
|
||||
};
|
||||
|
||||
struct nisplus_search_callback_data {
|
||||
nis_name key;
|
||||
char *value;
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
nisplus_callback(const nis_name key, const nis_object *value, voidp opaquedata)
|
||||
{
|
||||
char *kp = strnsave(ENTRY_VAL(value, 0), ENTRY_LEN(value, 0));
|
||||
char *vp = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1));
|
||||
struct nis_callback_data *data = (struct nis_callback_data *) opaquedata;
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("NISplus callback for <%s,%s>", kp, vp);
|
||||
#endif /* DEBUG */
|
||||
|
||||
(*data->ncd_fn) (data->ncd_m, kp, vp);
|
||||
|
||||
/*
|
||||
* We want more ...
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nisplus_reload(mnt_map *m, char *map, void (*fn) ())
|
||||
{
|
||||
int error = 0;
|
||||
struct nis_callback_data data;
|
||||
nis_result *result;
|
||||
char *org; /* if map does not have ".org_dir" then append it */
|
||||
nis_name map_name;
|
||||
|
||||
org = strstr(map, NISPLUS_ORGDIR);
|
||||
if (org == NULL)
|
||||
org = NISPLUS_ORGDIR;
|
||||
else
|
||||
org = "";
|
||||
|
||||
/* make some room for the NIS map_name */
|
||||
map_name = xmalloc(strlen(map) + sizeof(NISPLUS_ORGDIR));
|
||||
if (map_name == NULL) {
|
||||
plog(XLOG_ERROR, "Unable to create map_name %s: %s",
|
||||
map, strerror(ENOMEM));
|
||||
return ENOMEM;
|
||||
}
|
||||
sprintf(map_name, "%s%s", map, org);
|
||||
|
||||
data.ncd_m = m;
|
||||
data.ncd_map = map_name;
|
||||
data.ncd_fn = fn;
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("NISplus reload for %s", map);
|
||||
#endif /* DEBUG */
|
||||
|
||||
result = nis_list(map_name,
|
||||
EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH,
|
||||
(int (*)()) nisplus_callback,
|
||||
&data);
|
||||
|
||||
/* free off the NIS map_name */
|
||||
XFREE(map_name);
|
||||
|
||||
if (result->status != NIS_SUCCESS && result->status != NIS_CBRESULTS)
|
||||
error = 1;
|
||||
|
||||
if (error)
|
||||
plog(XLOG_ERROR, "error grabbing nisplus map of %s: %s",
|
||||
map,
|
||||
nis_sperrno(result->status));
|
||||
|
||||
nis_freeresult(result);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
nisplus_search_callback(const nis_name key, const nis_object *value, voidp opaquedata)
|
||||
{
|
||||
struct nisplus_search_callback_data *data = (struct nisplus_search_callback_data *) opaquedata;
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("NISplus search callback for <%s>", ENTRY_VAL(value, 0));
|
||||
dlog("NISplus search callback value <%s>", ENTRY_VAL(value, 1));
|
||||
#endif /* DEBUG */
|
||||
|
||||
data->value = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Try to locate a key using NIS+.
|
||||
*/
|
||||
int
|
||||
nisplus_search(mnt_map *m, char *map, char *key, char **val, time_t *tp)
|
||||
{
|
||||
nis_result *result;
|
||||
int error = 0;
|
||||
struct nisplus_search_callback_data data;
|
||||
nis_name index;
|
||||
char *org; /* if map does not have ".org_dir" then append it */
|
||||
|
||||
org = strstr(map, NISPLUS_ORGDIR);
|
||||
if (org == NULL)
|
||||
org = NISPLUS_ORGDIR;
|
||||
else
|
||||
org = "";
|
||||
|
||||
/* make some room for the NIS index */
|
||||
index = xmalloc(sizeof('[') /* for opening selection criteria */
|
||||
+sizeof(NISPLUS_KEY)
|
||||
+ strlen(key)
|
||||
+ sizeof(']') /* for closing selection criteria */
|
||||
+sizeof(',') /* + 1 for , separator */
|
||||
+strlen(map)
|
||||
+ sizeof(NISPLUS_ORGDIR)
|
||||
);
|
||||
if (index == NULL) {
|
||||
plog(XLOG_ERROR,
|
||||
"Unable to create index %s: %s",
|
||||
map,
|
||||
strerror(ENOMEM));
|
||||
return ENOMEM;
|
||||
}
|
||||
sprintf(index, "[%s%s],%s%s", NISPLUS_KEY, key, map, org);
|
||||
|
||||
data.key = key;
|
||||
data.value = NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("NISplus search for %s", index);
|
||||
#endif /* DEBUG */
|
||||
|
||||
result = nis_list(index,
|
||||
EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH,
|
||||
(int (*)()) nisplus_search_callback,
|
||||
&data);
|
||||
|
||||
/* free off the NIS index */
|
||||
XFREE(index);
|
||||
|
||||
if (result == NULL) {
|
||||
plog(XLOG_ERROR, "%s: %s", map, strerror(ENOMEM));
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do something interesting with the return code
|
||||
*/
|
||||
switch (result->status) {
|
||||
case NIS_SUCCESS:
|
||||
case NIS_CBRESULTS:
|
||||
|
||||
if (data.value == NULL) {
|
||||
nis_object *value = result->objects.objects_val;
|
||||
#ifdef DEBUG
|
||||
dlog("NISplus search found <nothing>");
|
||||
dlog("NISplus search for %s: %s(%d)",
|
||||
map, nis_sperrno(result->status), result->status);
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (value != NULL)
|
||||
data.value = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1));
|
||||
}
|
||||
*val = data.value;
|
||||
|
||||
if (*val) {
|
||||
error = 0;
|
||||
#ifdef DEBUG
|
||||
dlog("NISplus search found %s", *val);
|
||||
#endif /* DEBUG */
|
||||
} else {
|
||||
error = ENOENT;
|
||||
#ifdef DEBUG
|
||||
dlog("NISplus search found nothing");
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
*tp = 0;
|
||||
break;
|
||||
|
||||
case NIS_NOSUCHNAME:
|
||||
#ifdef DEBUG
|
||||
dlog("NISplus search returned %d", result->status);
|
||||
#endif /* DEBUG */
|
||||
error = ENOENT;
|
||||
break;
|
||||
|
||||
default:
|
||||
plog(XLOG_ERROR, "%s: %s", map, nis_sperrno(result->status));
|
||||
error = EIO;
|
||||
break;
|
||||
}
|
||||
nis_freeresult(result);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nisplus_init(mnt_map *m, char *map, time_t *tp)
|
||||
{
|
||||
nis_result *result;
|
||||
char *org; /* if map does not have ".org_dir" then append it */
|
||||
nis_name map_name;
|
||||
int error = 0;
|
||||
|
||||
org = strstr(map, NISPLUS_ORGDIR);
|
||||
if (org == NULL)
|
||||
org = NISPLUS_ORGDIR;
|
||||
else
|
||||
org = "";
|
||||
|
||||
/* make some room for the NIS map_name */
|
||||
map_name = xmalloc(strlen(map) + sizeof(NISPLUS_ORGDIR));
|
||||
if (map_name == NULL) {
|
||||
plog(XLOG_ERROR,
|
||||
"Unable to create map_name %s: %s",
|
||||
map,
|
||||
strerror(ENOMEM));
|
||||
return ENOMEM;
|
||||
}
|
||||
sprintf(map_name, "%s%s", map, org);
|
||||
|
||||
result = nis_lookup(map_name, (EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH));
|
||||
|
||||
/* free off the NIS map_name */
|
||||
XFREE(map_name);
|
||||
|
||||
if (result == NULL) {
|
||||
plog(XLOG_ERROR, "NISplus init <%s>: %s", map, strerror(ENOMEM));
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if (result->status != NIS_SUCCESS) {
|
||||
#ifdef DEBUG
|
||||
dlog("NISplus init <%s>: %s (%d)",
|
||||
map, nis_sperrno(result->status), result->status);
|
||||
#endif /* DEBUG */
|
||||
|
||||
error = ENOENT;
|
||||
}
|
||||
|
||||
*tp = 0; /* no time */
|
||||
nis_freeresult(result);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nisplus_mtime(mnt_map *m, char *map, time_t *tp)
|
||||
{
|
||||
return nisplus_init(m,map, tp);
|
||||
}
|
195
contrib/amd/amd/info_passwd.c
Normal file
195
contrib/amd/amd/info_passwd.c
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: info_passwd.c,v 5.2.2.1 1992/02/09 15:08:33 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get info from password "file"
|
||||
*
|
||||
* This is experimental and probably doesn't do what you expect.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
#define PASSWD_MAP "/etc/passwd"
|
||||
|
||||
/* forward declarations */
|
||||
int passwd_init(mnt_map *m, char *map, time_t *tp);
|
||||
int passwd_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
|
||||
|
||||
|
||||
/*
|
||||
* Nothing to probe - check the map name is PASSWD_MAP.
|
||||
*/
|
||||
int
|
||||
passwd_init(mnt_map *m, char *map, time_t *tp)
|
||||
{
|
||||
*tp = 0;
|
||||
|
||||
/*
|
||||
* Recognize the old format "PASSWD_MAP"
|
||||
* Uses default return string
|
||||
* "type:=nfs;rfs:=/${var0}/${var1};rhost:=${var1};sublink:=${var2};fs:=${autodir}${var3}"
|
||||
*/
|
||||
if (STREQ(map, PASSWD_MAP))
|
||||
return 0;
|
||||
/*
|
||||
* Recognize the new format "PASSWD_MAP:pval-format"
|
||||
*/
|
||||
if (!NSTREQ(map, PASSWD_MAP, sizeof(PASSWD_MAP) - 1))
|
||||
return ENOENT;
|
||||
if (map[sizeof(PASSWD_MAP)-1] != ':')
|
||||
return ENOENT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Grab the entry via the getpwname routine
|
||||
* Modify time is ignored by passwd - XXX
|
||||
*/
|
||||
int
|
||||
passwd_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
|
||||
{
|
||||
char *dir = 0;
|
||||
struct passwd *pw;
|
||||
|
||||
if (STREQ(key, "/defaults")) {
|
||||
*pval = strdup("type:=nfs");
|
||||
return 0;
|
||||
}
|
||||
pw = getpwnam(key);
|
||||
|
||||
if (pw) {
|
||||
/*
|
||||
* We chop the home directory up as follows:
|
||||
* /anydir/dom1/dom2/dom3/user
|
||||
*
|
||||
* and return
|
||||
* rfs:=/anydir/dom3;rhost:=dom3.dom2.dom1;sublink:=user
|
||||
* and now have
|
||||
* var0:=pw-prefix:=anydir
|
||||
* var1:=pw-rhost:=dom3.dom2.dom1
|
||||
* var2:=pw-user:=user
|
||||
* var3:=pw-home:=/anydir/dom1/dom2/dom3/user
|
||||
*
|
||||
* This allows cross-domain entries in your passwd file.
|
||||
* ... but forget about security!
|
||||
*/
|
||||
char *user;
|
||||
char *p, *q;
|
||||
char val[MAXPATHLEN];
|
||||
char rhost[MAXHOSTNAMELEN];
|
||||
dir = strdup(pw->pw_dir);
|
||||
|
||||
/*
|
||||
* Find user name. If no / then Invalid...
|
||||
*/
|
||||
user = strrchr(dir, '/');
|
||||
if (!user)
|
||||
goto enoent;
|
||||
*user++ = '\0';
|
||||
|
||||
/*
|
||||
* Find start of host "path". If no / then Invalid...
|
||||
*/
|
||||
p = strchr(dir + 1, '/');
|
||||
if (!p)
|
||||
goto enoent;
|
||||
*p++ = '\0';
|
||||
|
||||
/*
|
||||
* At this point, p is dom1/dom2/dom3
|
||||
* Copy, backwards, into rhost replacing
|
||||
* / with .
|
||||
*/
|
||||
rhost[0] = '\0';
|
||||
do {
|
||||
q = strrchr(p, '/');
|
||||
if (q) {
|
||||
strcat(rhost, q + 1);
|
||||
strcat(rhost, ".");
|
||||
*q = '\0';
|
||||
} else {
|
||||
strcat(rhost, p);
|
||||
}
|
||||
} while (q);
|
||||
|
||||
/*
|
||||
* Sanity check
|
||||
*/
|
||||
if (*rhost == '\0' || *user == '\0' || *dir == '\0')
|
||||
goto enoent;
|
||||
|
||||
/*
|
||||
* Make up return string
|
||||
*/
|
||||
q = strchr(rhost, '.');
|
||||
if (q)
|
||||
*q = '\0';
|
||||
p = strchr(map, ':');
|
||||
if (p)
|
||||
p++;
|
||||
else
|
||||
p = "type:=nfs;rfs:=/${var0}/${var1};rhost:=${var1};sublink:=${var2};fs:=${autodir}${var3}";
|
||||
sprintf(val, "var0:=%s;var1:=%s;var2:=%s;var3:=%s;%s",
|
||||
dir+1, rhost, user, pw->pw_dir, p);
|
||||
#ifdef DEBUG
|
||||
dlog("passwd_search: map=%s key=%s -> %s", map, key, val);
|
||||
#endif /* DEBUG */
|
||||
if (q)
|
||||
*q = '.';
|
||||
*pval = strdup(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
enoent:
|
||||
if (dir)
|
||||
XFREE(dir);
|
||||
|
||||
return ENOENT;
|
||||
}
|
149
contrib/amd/amd/info_union.c
Normal file
149
contrib/amd/amd/info_union.c
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: info_union.c,v 5.2.2.1 1992/02/09 15:08:34 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get info from the system namespace
|
||||
*
|
||||
* NOTE: Cannot handle reads back through the automounter.
|
||||
* THIS WILL CAUSE A DEADLOCK!
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
#define UNION_PREFIX "union:"
|
||||
#define UNION_PREFLEN 6
|
||||
|
||||
/* forward declarations */
|
||||
int union_init(mnt_map *m, char *map, time_t *tp);
|
||||
int union_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
|
||||
int union_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *));
|
||||
|
||||
|
||||
/*
|
||||
* No way to probe - check the map name begins with "union:"
|
||||
*/
|
||||
int
|
||||
union_init(mnt_map *m, char *map, time_t *tp)
|
||||
{
|
||||
*tp = 0;
|
||||
return NSTREQ(map, UNION_PREFIX, UNION_PREFLEN) ? 0 : ENOENT;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
union_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
|
||||
{
|
||||
char *mapd = strdup(map + UNION_PREFLEN);
|
||||
char **v = strsplit(mapd, ':', '\"');
|
||||
char **p;
|
||||
|
||||
for (p = v; p[1]; p++) ;
|
||||
*pval = xmalloc(strlen(*p) + 5);
|
||||
sprintf(*pval, "fs:=%s", *p);
|
||||
XFREE(mapd);
|
||||
XFREE(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
union_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *))
|
||||
{
|
||||
char *mapd = strdup(map + UNION_PREFLEN);
|
||||
char **v = strsplit(mapd, ':', '\"');
|
||||
char **dir;
|
||||
|
||||
/*
|
||||
* Add fake /defaults entry
|
||||
*/
|
||||
(*fn) (m, strdup("/defaults"), strdup("type:=link;opts:=nounmount;sublink:=${key}"));
|
||||
|
||||
for (dir = v; *dir; dir++) {
|
||||
int dlen;
|
||||
struct dirent *dp;
|
||||
|
||||
DIR *dirp = opendir(*dir);
|
||||
if (!dirp) {
|
||||
plog(XLOG_USER, "Cannot read directory %s: %m", *dir);
|
||||
continue;
|
||||
}
|
||||
dlen = strlen(*dir);
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("Reading directory %s...", *dir);
|
||||
#endif /* DEBUG */
|
||||
while ((dp = readdir(dirp))) {
|
||||
char *val, *dpname = &dp->d_name[0];
|
||||
if (dpname[0] == '.' &&
|
||||
(dpname[1] == '\0' ||
|
||||
(dpname[1] == '.' && dpname[2] == '\0')))
|
||||
continue;
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("... gives %s", dp->d_name);
|
||||
#endif /* DEBUG */
|
||||
val = xmalloc(dlen + 5);
|
||||
sprintf(val, "fs:=%s", *dir);
|
||||
(*fn) (m, strdup(dp->d_name), val);
|
||||
}
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add wildcard entry
|
||||
*/
|
||||
{
|
||||
char *val = xmalloc(strlen(dir[-1]) + 5);
|
||||
|
||||
sprintf(val, "fs:=%s", dir[-1]);
|
||||
(*fn) (m, strdup("*"), val);
|
||||
}
|
||||
XFREE(mapd);
|
||||
XFREE(v);
|
||||
return 0;
|
||||
}
|
1112
contrib/amd/amd/map.c
Normal file
1112
contrib/amd/amd/map.c
Normal file
File diff suppressed because it is too large
Load Diff
1205
contrib/amd/amd/mapc.c
Normal file
1205
contrib/amd/amd/mapc.c
Normal file
File diff suppressed because it is too large
Load Diff
335
contrib/amd/amd/mntfs.c
Normal file
335
contrib/amd/amd/mntfs.c
Normal file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: mntfs.c,v 5.2.2.2 1992/08/02 10:42:21 jsp Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
qelem mfhead = {&mfhead, &mfhead};
|
||||
|
||||
int mntfs_allocated;
|
||||
|
||||
|
||||
mntfs *
|
||||
dup_mntfs(mntfs *mf)
|
||||
{
|
||||
if (mf->mf_refc == 0) {
|
||||
if (mf->mf_cid)
|
||||
untimeout(mf->mf_cid);
|
||||
mf->mf_cid = 0;
|
||||
}
|
||||
mf->mf_refc++;
|
||||
|
||||
return mf;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_mntfs(mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)
|
||||
{
|
||||
mf->mf_ops = ops;
|
||||
mf->mf_fo = mo;
|
||||
mf->mf_mount = strdup(mp);
|
||||
mf->mf_info = strdup(info);
|
||||
mf->mf_auto = strdup(auto_opts);
|
||||
mf->mf_mopts = strdup(mopts);
|
||||
mf->mf_remopts = strdup(remopts);
|
||||
mf->mf_refc = 1;
|
||||
mf->mf_flags = 0;
|
||||
mf->mf_error = -1;
|
||||
mf->mf_cid = 0;
|
||||
mf->mf_private = 0;
|
||||
mf->mf_prfree = 0;
|
||||
|
||||
if (ops->ffserver)
|
||||
mf->mf_server = (*ops->ffserver) (mf);
|
||||
else
|
||||
mf->mf_server = 0;
|
||||
}
|
||||
|
||||
|
||||
static mntfs *
|
||||
alloc_mntfs(am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)
|
||||
{
|
||||
mntfs *mf = ALLOC(struct mntfs);
|
||||
|
||||
init_mntfs(mf, ops, mo, mp, info, auto_opts, mopts, remopts);
|
||||
ins_que(&mf->mf_q, &mfhead);
|
||||
mntfs_allocated++;
|
||||
|
||||
return mf;
|
||||
}
|
||||
|
||||
|
||||
mntfs *
|
||||
find_mntfs(am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)
|
||||
{
|
||||
mntfs *mf;
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("Locating mntfs reference to %s", mp);
|
||||
#endif /* DEBUG */
|
||||
|
||||
ITER(mf, mntfs, &mfhead) {
|
||||
if (STREQ(mf->mf_mount, mp)) {
|
||||
/*
|
||||
* Handle cases where error ops are involved
|
||||
*/
|
||||
if (ops == &amfs_error_ops) {
|
||||
/*
|
||||
* If the existing ops are not amfs_error_ops
|
||||
* then continue...
|
||||
*/
|
||||
if (mf->mf_ops != &amfs_error_ops)
|
||||
continue;
|
||||
else
|
||||
return dup_mntfs(mf);
|
||||
} else { /* ops != &amfs_error_ops */
|
||||
/*
|
||||
* If the existing ops are amfs_error_ops
|
||||
* then continue...
|
||||
*/
|
||||
if (mf->mf_ops == &amfs_error_ops)
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mf->mf_flags & MFF_RESTART) && amd_state == Run) {
|
||||
/*
|
||||
* Restart a previously mounted filesystem.
|
||||
*/
|
||||
mntfs *mf2 = alloc_mntfs(&amfs_inherit_ops, mo, mp, info, auto_opts, mopts, remopts);
|
||||
#ifdef DEBUG
|
||||
dlog("Restarting filesystem %s", mf->mf_mount);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Remember who we are restarting
|
||||
*/
|
||||
mf2->mf_private = (voidp) dup_mntfs(mf);
|
||||
mf2->mf_prfree = free_mntfs;
|
||||
return mf2;
|
||||
}
|
||||
|
||||
mf->mf_fo = mo;
|
||||
if (!(mf->mf_flags & (MFF_MOUNTED | MFF_MOUNTING | MFF_UNMOUNTING))) {
|
||||
fserver *fs;
|
||||
mf->mf_flags &= ~MFF_ERROR;
|
||||
mf->mf_error = -1;
|
||||
mf->mf_auto = strealloc(mf->mf_auto, auto_opts);
|
||||
mf->mf_mopts = strealloc(mf->mf_mopts, mopts);
|
||||
mf->mf_remopts = strealloc(mf->mf_remopts, remopts);
|
||||
mf->mf_info = strealloc(mf->mf_info, info);
|
||||
|
||||
if (mf->mf_private && mf->mf_prfree) {
|
||||
(*mf->mf_prfree) (mf->mf_private);
|
||||
mf->mf_private = 0;
|
||||
}
|
||||
|
||||
fs = ops->ffserver ? (*ops->ffserver) (mf) : (fserver *) NULL;
|
||||
if (mf->mf_server)
|
||||
free_srvr(mf->mf_server);
|
||||
mf->mf_server = fs;
|
||||
}
|
||||
return dup_mntfs(mf);
|
||||
}
|
||||
}
|
||||
|
||||
return alloc_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts);
|
||||
}
|
||||
|
||||
|
||||
mntfs *
|
||||
new_mntfs(void)
|
||||
{
|
||||
return alloc_mntfs(&amfs_error_ops, (am_opts *) 0, "//nil//", ".", "", "", "");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
uninit_mntfs(mntfs *mf, int rmd)
|
||||
{
|
||||
if (mf->mf_auto)
|
||||
XFREE(mf->mf_auto);
|
||||
if (mf->mf_mopts)
|
||||
XFREE(mf->mf_mopts);
|
||||
if (mf->mf_remopts)
|
||||
XFREE(mf->mf_remopts);
|
||||
if (mf->mf_info)
|
||||
XFREE(mf->mf_info);
|
||||
if (mf->mf_private && mf->mf_prfree)
|
||||
(*mf->mf_prfree) (mf->mf_private);
|
||||
|
||||
/*
|
||||
* Clean up any directories that were made
|
||||
*/
|
||||
if (rmd && (mf->mf_flags & MFF_MKMNT))
|
||||
rmdirs(mf->mf_mount);
|
||||
/* free mf_mount _AFTER_ removing the directories */
|
||||
if (mf->mf_mount)
|
||||
XFREE(mf->mf_mount);
|
||||
|
||||
/*
|
||||
* Clean up the file server
|
||||
*/
|
||||
if (mf->mf_server)
|
||||
free_srvr(mf->mf_server);
|
||||
|
||||
/*
|
||||
* Don't do a callback on this mount
|
||||
*/
|
||||
if (mf->mf_cid) {
|
||||
untimeout(mf->mf_cid);
|
||||
mf->mf_cid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
discard_mntfs(voidp v)
|
||||
{
|
||||
mntfs *mf = v;
|
||||
|
||||
rem_que(&mf->mf_q);
|
||||
|
||||
/*
|
||||
* Free memory
|
||||
*/
|
||||
uninit_mntfs(mf, TRUE);
|
||||
XFREE(mf);
|
||||
|
||||
--mntfs_allocated;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
flush_mntfs(void)
|
||||
{
|
||||
mntfs *mf;
|
||||
|
||||
mf = AM_FIRST(mntfs, &mfhead);
|
||||
while (mf != HEAD(mntfs, &mfhead)) {
|
||||
mntfs *mf2 = mf;
|
||||
mf = NEXT(mntfs, mf);
|
||||
if (mf2->mf_refc == 0 && mf2->mf_cid)
|
||||
discard_mntfs(mf2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
free_mntfs(voidp v)
|
||||
{
|
||||
mntfs *mf = v;
|
||||
|
||||
if (--mf->mf_refc == 0) {
|
||||
if (mf->mf_flags & MFF_MOUNTED) {
|
||||
int quoted;
|
||||
mf->mf_flags &= ~MFF_MOUNTED;
|
||||
|
||||
/*
|
||||
* Record for posterity
|
||||
*/
|
||||
quoted = strchr(mf->mf_info, ' ') != 0; /* cheap */
|
||||
plog(XLOG_INFO, "%s%s%s %sed fstype %s from %s",
|
||||
quoted ? "\"" : "",
|
||||
mf->mf_info,
|
||||
quoted ? "\"" : "",
|
||||
mf->mf_error ? "discard" : "unmount",
|
||||
mf->mf_ops->fs_type, mf->mf_mount);
|
||||
}
|
||||
|
||||
if (mf->mf_ops->fs_flags & FS_DISCARD) {
|
||||
#ifdef DEBUG
|
||||
dlog("Immediately discarding mntfs for %s", mf->mf_mount);
|
||||
#endif /* DEBUG */
|
||||
discard_mntfs(mf);
|
||||
|
||||
} else {
|
||||
|
||||
#ifdef DEBUG
|
||||
if (mf->mf_flags & MFF_RESTART) {
|
||||
dlog("Discarding remount hook for %s", mf->mf_mount);
|
||||
} else {
|
||||
dlog("Discarding last mntfs reference to %s fstype %s",
|
||||
mf->mf_mount, mf->mf_ops->fs_type);
|
||||
}
|
||||
if (mf->mf_flags & (MFF_MOUNTED | MFF_MOUNTING | MFF_UNMOUNTING))
|
||||
dlog("mntfs reference for %s still active", mf->mf_mount);
|
||||
#endif /* DEBUG */
|
||||
mf->mf_cid = timeout(ALLOWED_MOUNT_TIME, discard_mntfs, (voidp) mf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mntfs *
|
||||
realloc_mntfs(mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)
|
||||
{
|
||||
mntfs *mf2;
|
||||
|
||||
if (mf->mf_refc == 1 && mf->mf_ops == &amfs_inherit_ops && STREQ(mf->mf_mount, mp)) {
|
||||
/*
|
||||
* If we are inheriting then just return
|
||||
* the same node...
|
||||
*/
|
||||
return mf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-use the existing mntfs if it is mounted.
|
||||
* This traps a race in nfsx.
|
||||
*/
|
||||
if (mf->mf_ops != &amfs_error_ops &&
|
||||
(mf->mf_flags & MFF_MOUNTED) &&
|
||||
!FSRV_ISDOWN(mf->mf_server)) {
|
||||
mf->mf_fo = mo;
|
||||
return mf;
|
||||
}
|
||||
|
||||
mf2 = find_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts);
|
||||
free_mntfs(mf);
|
||||
return mf2;
|
||||
}
|
250
contrib/amd/amd/nfs_prot_svc.c
Normal file
250
contrib/amd/amd/nfs_prot_svc.c
Normal file
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 5.2.2.1 1992/02/09 15:09:30 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* external definitions */
|
||||
extern voidp nfsproc_null_2_svc(voidp, 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 voidp nfsproc_root_2_svc(voidp, 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 voidp nfsproc_writecache_2_svc(voidp, 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 *);
|
||||
|
||||
/* global variables */
|
||||
SVCXPRT *nfs_program_2_transp;
|
||||
|
||||
/* typedefs */
|
||||
typedef char *(*nfssvcproc_t)(voidp, struct svc_req *);
|
||||
|
||||
|
||||
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;
|
||||
xdrproc_t xdr_argument, xdr_result;
|
||||
nfssvcproc_t local;
|
||||
|
||||
nfs_program_2_transp = NULL;
|
||||
|
||||
switch (rqstp->rq_proc) {
|
||||
|
||||
case NFSPROC_NULL:
|
||||
xdr_argument = (xdrproc_t) xdr_void;
|
||||
xdr_result = (xdrproc_t) xdr_void;
|
||||
local = (nfssvcproc_t) nfsproc_null_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_GETATTR:
|
||||
xdr_argument = (xdrproc_t) xdr_nfs_fh;
|
||||
xdr_result = (xdrproc_t) xdr_attrstat;
|
||||
local = (nfssvcproc_t) nfsproc_getattr_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_SETATTR:
|
||||
xdr_argument = (xdrproc_t) xdr_sattrargs;
|
||||
xdr_result = (xdrproc_t) xdr_attrstat;
|
||||
local = (nfssvcproc_t) nfsproc_setattr_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_ROOT:
|
||||
xdr_argument = (xdrproc_t) xdr_void;
|
||||
xdr_result = (xdrproc_t) xdr_void;
|
||||
local = (nfssvcproc_t) nfsproc_root_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_LOOKUP:
|
||||
xdr_argument = (xdrproc_t) xdr_diropargs;
|
||||
xdr_result = (xdrproc_t) xdr_diropres;
|
||||
local = (nfssvcproc_t) nfsproc_lookup_2_svc;
|
||||
/*
|
||||
* Cheap way to pass transp down to amfs_auto_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 = (xdrproc_t) xdr_nfs_fh;
|
||||
xdr_result = (xdrproc_t) xdr_readlinkres;
|
||||
local = (nfssvcproc_t) nfsproc_readlink_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_READ:
|
||||
xdr_argument = (xdrproc_t) xdr_readargs;
|
||||
xdr_result = (xdrproc_t) xdr_readres;
|
||||
local = (nfssvcproc_t) nfsproc_read_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_WRITECACHE:
|
||||
xdr_argument = (xdrproc_t) xdr_void;
|
||||
xdr_result = (xdrproc_t) xdr_void;
|
||||
local = (nfssvcproc_t) nfsproc_writecache_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_WRITE:
|
||||
xdr_argument = (xdrproc_t) xdr_writeargs;
|
||||
xdr_result = (xdrproc_t) xdr_attrstat;
|
||||
local = (nfssvcproc_t) nfsproc_write_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_CREATE:
|
||||
xdr_argument = (xdrproc_t) xdr_createargs;
|
||||
xdr_result = (xdrproc_t) xdr_diropres;
|
||||
local = (nfssvcproc_t) nfsproc_create_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_REMOVE:
|
||||
xdr_argument = (xdrproc_t) xdr_diropargs;
|
||||
xdr_result = (xdrproc_t) xdr_nfsstat;
|
||||
local = (nfssvcproc_t) nfsproc_remove_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_RENAME:
|
||||
xdr_argument = (xdrproc_t) xdr_renameargs;
|
||||
xdr_result = (xdrproc_t) xdr_nfsstat;
|
||||
local = (nfssvcproc_t) nfsproc_rename_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_LINK:
|
||||
xdr_argument = (xdrproc_t) xdr_linkargs;
|
||||
xdr_result = (xdrproc_t) xdr_nfsstat;
|
||||
local = (nfssvcproc_t) nfsproc_link_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_SYMLINK:
|
||||
xdr_argument = (xdrproc_t) xdr_symlinkargs;
|
||||
xdr_result = (xdrproc_t) xdr_nfsstat;
|
||||
local = (nfssvcproc_t) nfsproc_symlink_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_MKDIR:
|
||||
xdr_argument = (xdrproc_t) xdr_createargs;
|
||||
xdr_result = (xdrproc_t) xdr_diropres;
|
||||
local = (nfssvcproc_t) nfsproc_mkdir_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_RMDIR:
|
||||
xdr_argument = (xdrproc_t) xdr_diropargs;
|
||||
xdr_result = (xdrproc_t) xdr_nfsstat;
|
||||
local = (nfssvcproc_t) nfsproc_rmdir_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_READDIR:
|
||||
xdr_argument = (xdrproc_t) xdr_readdirargs;
|
||||
xdr_result = (xdrproc_t) xdr_readdirres;
|
||||
local = (nfssvcproc_t) nfsproc_readdir_2_svc;
|
||||
break;
|
||||
|
||||
case NFSPROC_STATFS:
|
||||
xdr_argument = (xdrproc_t) xdr_nfs_fh;
|
||||
xdr_result = (xdrproc_t) xdr_statfsres;
|
||||
local = (nfssvcproc_t) 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_2");
|
||||
going_down(1);
|
||||
}
|
||||
}
|
472
contrib/amd/amd/nfs_start.c
Normal file
472
contrib/amd/amd/nfs_start.c
Normal file
@ -0,0 +1,472 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: nfs_start.c,v 5.2.2.1 1992/02/09 15:08:51 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
#ifndef SELECT_MAXWAIT
|
||||
# define SELECT_MAXWAIT 16
|
||||
#endif /* not SELECT_MAXWAIT */
|
||||
|
||||
SVCXPRT *nfsxprt;
|
||||
u_short nfs_port;
|
||||
|
||||
#ifdef HAVE_FS_AUTOFS
|
||||
SVCXPRT *autofsxprt = NULL;
|
||||
u_short autofs_port = 0;
|
||||
#endif /* HAVE_FS_AUTOFS */
|
||||
|
||||
#ifndef HAVE_SIGACTION
|
||||
# define MASKED_SIGS (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGCHLD)|sigmask(SIGHUP))
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Check that we are not burning resources
|
||||
*/
|
||||
static void
|
||||
checkup(void)
|
||||
{
|
||||
|
||||
static int max_fd = 0;
|
||||
static char *max_mem = 0;
|
||||
|
||||
int next_fd = dup(0);
|
||||
caddr_t next_mem = sbrk(0);
|
||||
close(next_fd);
|
||||
|
||||
if (max_fd < next_fd) {
|
||||
dlog("%d new fds allocated; total is %d",
|
||||
next_fd - max_fd, next_fd);
|
||||
max_fd = next_fd;
|
||||
}
|
||||
if (max_mem < next_mem) {
|
||||
#ifdef HAVE_GETPAGESIZE
|
||||
dlog("%#x bytes of memory allocated; total is %#x (%ld pages)",
|
||||
next_mem - max_mem, next_mem,
|
||||
((long) next_mem + getpagesize() - 1) / getpagesize());
|
||||
#else /* not HAVE_GETPAGESIZE */
|
||||
dlog("%#x bytes of memory allocated; total is %#x",
|
||||
next_mem - max_mem, next_mem);
|
||||
#endif /* not HAVE_GETPAGESIZE */
|
||||
max_mem = next_mem;
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
static int
|
||||
#ifdef HAVE_SIGACTION
|
||||
do_select(sigset_t smask, int fds, fd_set *fdp, struct timeval *tvp)
|
||||
#else /* not HAVE_SIGACTION */
|
||||
do_select(int smask, int fds, fd_set *fdp, struct timeval *tvp)
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
{
|
||||
|
||||
int sig;
|
||||
int nsel;
|
||||
|
||||
if ((sig = setjmp(select_intr))) {
|
||||
select_intr_valid = 0;
|
||||
/* Got a signal */
|
||||
switch (sig) {
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
amd_state = Finishing;
|
||||
reschedule_timeout_mp();
|
||||
break;
|
||||
}
|
||||
nsel = -1;
|
||||
errno = EINTR;
|
||||
} else {
|
||||
select_intr_valid = 1;
|
||||
/*
|
||||
* Invalidate the current clock value
|
||||
*/
|
||||
clock_valid = 0;
|
||||
/*
|
||||
* Allow interrupts. If a signal
|
||||
* occurs, then it will cause a longjmp
|
||||
* up above.
|
||||
*/
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigprocmask(SIG_SETMASK, &smask, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
(void) sigsetmask(smask);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
/*
|
||||
* Wait for input
|
||||
*/
|
||||
nsel = select(fds, fdp, (fd_set *) 0, (fd_set *) 0,
|
||||
tvp->tv_sec ? tvp : (struct timeval *) 0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigprocmask(SIG_BLOCK, &masked_sigs, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
(void) sigblock(MASKED_SIGS);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
/*
|
||||
* Perhaps reload the cache?
|
||||
*/
|
||||
if (do_mapc_reload < clocktime()) {
|
||||
mapc_reload();
|
||||
do_mapc_reload = clocktime() + ONE_HOUR;
|
||||
}
|
||||
return nsel;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Determine whether anything is left in
|
||||
* the RPC input queue.
|
||||
*/
|
||||
static int
|
||||
rpc_pending_now(void)
|
||||
{
|
||||
struct timeval tvv;
|
||||
int nsel;
|
||||
#ifdef FD_SET
|
||||
fd_set readfds;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(fwd_sock, &readfds);
|
||||
#else /* not FD_SET */
|
||||
int readfds = (1 << fwd_sock);
|
||||
#endif /* not FD_SET */
|
||||
|
||||
tvv.tv_sec = tvv.tv_usec = 0;
|
||||
nsel = select(FD_SETSIZE, &readfds, (fd_set *) 0, (fd_set *) 0, &tvv);
|
||||
if (nsel < 1)
|
||||
return (0);
|
||||
#ifdef FD_SET
|
||||
if (FD_ISSET(fwd_sock, &readfds))
|
||||
return (1);
|
||||
#else /* not FD_SET */
|
||||
if (readfds & (1 << fwd_sock))
|
||||
return (1);
|
||||
#endif /* not FD_SET */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static serv_state
|
||||
run_rpc(void)
|
||||
{
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigset_t smask;
|
||||
sigprocmask(SIG_BLOCK, &masked_sigs, &smask);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
int smask = sigblock(MASKED_SIGS);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
next_softclock = clocktime();
|
||||
|
||||
amd_state = Run;
|
||||
|
||||
/*
|
||||
* Keep on trucking while we are in Run mode. This state
|
||||
* is switched to Quit after all the file systems have
|
||||
* been unmounted.
|
||||
*/
|
||||
while ((int) amd_state <= (int) Finishing) {
|
||||
struct timeval tvv;
|
||||
int nsel;
|
||||
time_t now;
|
||||
#ifdef HAVE_SVC_GETREQSET
|
||||
fd_set readfds;
|
||||
|
||||
memmove(&readfds, &svc_fdset, sizeof(svc_fdset));
|
||||
FD_SET(fwd_sock, &readfds);
|
||||
#else /* not HAVE_SVC_GETREQSET */
|
||||
# ifdef FD_SET
|
||||
fd_set readfds;
|
||||
FD_ZERO(&readfds);
|
||||
readfds.fds_bits[0] = svc_fds;
|
||||
FD_SET(fwd_sock, &readfds);
|
||||
# else /* not FD_SET */
|
||||
int readfds = svc_fds | (1 << fwd_sock);
|
||||
# endif /* not FD_SET */
|
||||
#endif /* not HAVE_SVC_GETREQSET */
|
||||
|
||||
#ifdef DEBUG
|
||||
checkup();
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* If the full timeout code is not called,
|
||||
* then recompute the time delta manually.
|
||||
*/
|
||||
now = clocktime();
|
||||
|
||||
if (next_softclock <= now) {
|
||||
if (amd_state == Finishing)
|
||||
umount_exported();
|
||||
tvv.tv_sec = softclock();
|
||||
} else {
|
||||
tvv.tv_sec = next_softclock - now;
|
||||
}
|
||||
tvv.tv_usec = 0;
|
||||
|
||||
if (amd_state == Finishing && last_used_map < 0) {
|
||||
flush_mntfs();
|
||||
amd_state = Quit;
|
||||
break;
|
||||
}
|
||||
if (tvv.tv_sec <= 0)
|
||||
tvv.tv_sec = SELECT_MAXWAIT;
|
||||
#ifdef DEBUG
|
||||
if (tvv.tv_sec) {
|
||||
dlog("Select waits for %ds", tvv.tv_sec);
|
||||
} else {
|
||||
dlog("Select waits for Godot");
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
nsel = do_select(smask, FD_SETSIZE, &readfds, &tvv);
|
||||
|
||||
switch (nsel) {
|
||||
case -1:
|
||||
if (errno == EINTR) {
|
||||
#ifdef DEBUG
|
||||
dlog("select interrupted");
|
||||
#endif /* DEBUG */
|
||||
continue;
|
||||
}
|
||||
perror("select");
|
||||
break;
|
||||
|
||||
case 0:
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* Read all pending NFS responses at once to avoid having responses.
|
||||
* queue up as a consequence of retransmissions.
|
||||
*/
|
||||
#ifdef FD_SET
|
||||
if (FD_ISSET(fwd_sock, &readfds)) {
|
||||
FD_CLR(fwd_sock, &readfds);
|
||||
#else /* not FD_SET */
|
||||
if (readfds & (1 << fwd_sock)) {
|
||||
readfds &= ~(1 << fwd_sock);
|
||||
#endif /* not FD_SET */
|
||||
--nsel;
|
||||
do {
|
||||
fwd_reply();
|
||||
} while (rpc_pending_now() > 0);
|
||||
}
|
||||
|
||||
if (nsel) {
|
||||
/*
|
||||
* Anything left must be a normal
|
||||
* RPC request.
|
||||
*/
|
||||
#ifdef HAVE_SVC_GETREQSET
|
||||
svc_getreqset(&readfds);
|
||||
#else /* not HAVE_SVC_GETREQSET */
|
||||
# ifdef FD_SET
|
||||
svc_getreq(readfds.fds_bits[0]);
|
||||
# else /* not FD_SET */
|
||||
svc_getreq(readfds);
|
||||
# endif /* not FD_SET */
|
||||
#endif /* not HAVE_SVC_GETREQSET */
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigprocmask(SIG_SETMASK, &smask, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
(void) sigsetmask(smask);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
if (amd_state == Quit)
|
||||
amd_state = Done;
|
||||
|
||||
return amd_state;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mount_automounter(int ppid)
|
||||
{
|
||||
/*
|
||||
* Old code replaced by rpc-trash patch.
|
||||
* Erez Zadok <ezk@cs.columbia.edu>
|
||||
int so = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
*/
|
||||
SVCXPRT *udp_amqp = NULL, *tcp_amqp = NULL;
|
||||
int nmount, ret;
|
||||
int soNFS;
|
||||
int udp_soAMQ, tcp_soAMQ;
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
struct netconfig *udp_amqncp, *tcp_amqncp;
|
||||
#endif /* HAVE_TRANSPORT_TYPE_TLI */
|
||||
#ifdef HAVE_FS_AUTOFS
|
||||
int soAUTOFS;
|
||||
#endif /* HAVE_FS_AUTOFS */
|
||||
|
||||
/*
|
||||
* Create the nfs service for amd
|
||||
*/
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = create_amq_service(&udp_soAMQ, &udp_amqp, &udp_amqncp, &tcp_soAMQ, &tcp_amqp, &tcp_amqncp);
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = create_amq_service(&udp_soAMQ, &udp_amqp, &tcp_soAMQ, &tcp_amqp);
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
#ifdef HAVE_FS_AUTOFS
|
||||
/*
|
||||
* Create the autofs service for amd.
|
||||
*/
|
||||
plog(XLOG_INFO, "creating autofs service listener");
|
||||
ret = create_autofs_service(&soAUTOFS, &autofs_port, &autofsxprt, autofs_program_1);
|
||||
/* if autofs service fails it is OK if using a test amd */
|
||||
if (ret != 0 && gopt.portmap_program == AMQ_PROGRAM)
|
||||
return ret;
|
||||
#endif /* HAVE_FS_AUTOFS */
|
||||
|
||||
/*
|
||||
* Start RPC forwarding
|
||||
*/
|
||||
if (fwd_init() != 0)
|
||||
return 3;
|
||||
|
||||
/*
|
||||
* Construct the root automount node
|
||||
*/
|
||||
make_root_node();
|
||||
|
||||
/*
|
||||
* Pick up the pieces from a previous run
|
||||
* This is likely to (indirectly) need the rpc_fwd package
|
||||
* so it *must* come after the call to fwd_init().
|
||||
*/
|
||||
if (gopt.flags & CFM_RESTART_EXISTING_MOUNTS)
|
||||
restart();
|
||||
|
||||
/*
|
||||
* Mount the top-level auto-mountpoints
|
||||
*/
|
||||
nmount = mount_exported();
|
||||
|
||||
/*
|
||||
* Now safe to tell parent that we are up and running
|
||||
*/
|
||||
if (ppid)
|
||||
kill(ppid, SIGQUIT);
|
||||
|
||||
if (nmount == 0) {
|
||||
plog(XLOG_FATAL, "No work to do - quitting");
|
||||
amd_state = Done;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_AMQ) {
|
||||
#endif /* DEBUG */
|
||||
/*
|
||||
* Complete registration of amq (first TCP service then UDP)
|
||||
*/
|
||||
unregister_amq();
|
||||
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
ret = svc_reg(tcp_amqp, get_amd_program_number(), AMQ_VERSION,
|
||||
amq_program_1, tcp_amqncp);
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
ret = svc_register(tcp_amqp, get_amd_program_number(), AMQ_VERSION,
|
||||
amq_program_1, IPPROTO_TCP);
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
if (ret != 1) {
|
||||
plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM=%d, AMQ_VERSION, tcp)", get_amd_program_number());
|
||||
return 3;
|
||||
}
|
||||
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
ret = svc_reg(udp_amqp, get_amd_program_number(), AMQ_VERSION,
|
||||
amq_program_1, udp_amqncp);
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
ret = svc_register(udp_amqp, get_amd_program_number(), AMQ_VERSION,
|
||||
amq_program_1, IPPROTO_UDP);
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
if (ret != 1) {
|
||||
plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM=%d, AMQ_VERSION, udp)", get_amd_program_number());
|
||||
return 4;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Start timeout_mp rolling
|
||||
*/
|
||||
reschedule_timeout_mp();
|
||||
|
||||
/*
|
||||
* Start the server
|
||||
*/
|
||||
if (run_rpc() != Done) {
|
||||
plog(XLOG_FATAL, "run_rpc failed");
|
||||
amd_state = Done;
|
||||
}
|
||||
return 0;
|
||||
}
|
610
contrib/amd/amd/nfs_subr.c
Normal file
610
contrib/amd/amd/nfs_subr.c
Normal file
@ -0,0 +1,610 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: nfs_subr.c,v 5.2.2.1 1992/02/09 15:08:53 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/*
|
||||
* Convert from UN*X to NFS error code.
|
||||
* Some systems like linux define their own (see
|
||||
* conf/mount/mount_linux.h).
|
||||
*/
|
||||
#ifndef nfs_error
|
||||
# define nfs_error(e) ((nfsstat)(e))
|
||||
#endif /* nfs_error */
|
||||
|
||||
/* forward declarations */
|
||||
static void count_map_entries(const am_node *mp, u_int *out_blocks, u_int *out_bfree, u_int *out_bavail);
|
||||
|
||||
|
||||
static char *
|
||||
do_readlink(am_node *mp, int *error_return, nfsattrstat **attrpp)
|
||||
{
|
||||
char *ln;
|
||||
|
||||
/*
|
||||
* If there is a readlink method, then use
|
||||
* that, otherwise if a link exists use
|
||||
* that, otherwise use the mount point.
|
||||
*/
|
||||
if (mp->am_mnt->mf_ops->readlink) {
|
||||
int retry = 0;
|
||||
mp = (*mp->am_mnt->mf_ops->readlink) (mp, &retry);
|
||||
if (mp == 0) {
|
||||
*error_return = retry;
|
||||
return 0;
|
||||
}
|
||||
/* reschedule_timeout_mp(); */
|
||||
}
|
||||
|
||||
if (mp->am_link) {
|
||||
ln = mp->am_link;
|
||||
} else {
|
||||
ln = mp->am_mnt->mf_mount;
|
||||
}
|
||||
if (attrpp)
|
||||
*attrpp = &mp->am_attr;
|
||||
|
||||
return ln;
|
||||
}
|
||||
|
||||
|
||||
voidp
|
||||
nfsproc_null_2_svc(voidp argp, struct svc_req *rqstp)
|
||||
{
|
||||
static char res;
|
||||
|
||||
return (voidp) &res;
|
||||
}
|
||||
|
||||
|
||||
nfsattrstat *
|
||||
nfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsattrstat res;
|
||||
am_node *mp;
|
||||
int retry;
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
plog(XLOG_DEBUG, "getattr:");
|
||||
#endif /* DEBUG */
|
||||
|
||||
mp = fh_to_mp2(argp, &retry);
|
||||
if (mp == 0) {
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
plog(XLOG_DEBUG, "\tretry=%d", retry);
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (retry < 0)
|
||||
return 0;
|
||||
res.ns_status = nfs_error(retry);
|
||||
} else {
|
||||
nfsattrstat *attrp = &mp->am_attr;
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
plog(XLOG_DEBUG, "\tstat(%s), size = %d", mp->am_path,
|
||||
attrp->ns_u.ns_attr_u.na_size);
|
||||
#endif /* DEBUG */
|
||||
|
||||
mp->am_stats.s_getattr++;
|
||||
return attrp;
|
||||
}
|
||||
|
||||
#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 (++res.ns_u.ns_attr_u.na_mtime.nt_useconds == 0)
|
||||
++res.ns_u.ns_attr_u.na_mtime.nt_seconds;
|
||||
#endif /* not MNT2_NFS_OPT_SYMTTL */
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsattrstat *
|
||||
nfsproc_setattr_2_svc(nfssattrargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsattrstat res;
|
||||
|
||||
if (!fh_to_mp(&argp->sag_fhandle))
|
||||
res.ns_status = nfs_error(ESTALE);
|
||||
else
|
||||
res.ns_status = nfs_error(EROFS);
|
||||
|
||||
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;
|
||||
am_node *mp;
|
||||
int retry;
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
plog(XLOG_DEBUG, "lookup:");
|
||||
#endif /* DEBUG */
|
||||
|
||||
mp = fh_to_mp2(&argp->da_fhandle, &retry);
|
||||
if (mp == 0) {
|
||||
if (retry < 0)
|
||||
return 0;
|
||||
res.dr_status = nfs_error(retry);
|
||||
} else {
|
||||
int error;
|
||||
am_node *ap;
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
plog(XLOG_DEBUG, "\tlookuppn(%s, %s)", mp->am_path, argp->da_name);
|
||||
#endif /* DEBUG */
|
||||
ap = (*mp->am_mnt->mf_ops->lookuppn) (mp, argp->da_name, &error, VLOOK_CREATE);
|
||||
if (ap == 0) {
|
||||
if (error < 0) {
|
||||
#ifdef DEBUG
|
||||
dlog("Not sending RPC reply");
|
||||
#endif /* DEBUG */
|
||||
amd_stats.d_drops++;
|
||||
return 0;
|
||||
}
|
||||
res.dr_status = nfs_error(error);
|
||||
} else {
|
||||
mp_to_fh(ap, &res.dr_u.dr_drok_u.drok_fhandle);
|
||||
res.dr_u.dr_drok_u.drok_attributes = ap->am_fattr;
|
||||
res.dr_status = NFS_OK;
|
||||
}
|
||||
mp->am_stats.s_lookup++;
|
||||
/* reschedule_timeout_mp(); */
|
||||
}
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
quick_reply(am_node *mp, int error)
|
||||
{
|
||||
SVCXPRT *transp = mp->am_transp;
|
||||
nfsdiropres res;
|
||||
xdrproc_t xdr_result = (xdrproc_t) xdr_diropres;
|
||||
|
||||
/*
|
||||
* If there's a transp structure then we can reply to the client's
|
||||
* nfs lookup request.
|
||||
*/
|
||||
if (transp) {
|
||||
if (error == 0) {
|
||||
/*
|
||||
* Construct a valid reply to a lookup request. Same
|
||||
* code as in nfsproc_lookup_2_svc() above.
|
||||
*/
|
||||
mp_to_fh(mp, &res.dr_u.dr_drok_u.drok_fhandle);
|
||||
res.dr_u.dr_drok_u.drok_attributes = mp->am_fattr;
|
||||
res.dr_status = NFS_OK;
|
||||
} else
|
||||
/*
|
||||
* Return the error that was passed to us.
|
||||
*/
|
||||
res.dr_status = nfs_error(error);
|
||||
|
||||
/*
|
||||
* Send off our reply
|
||||
*/
|
||||
if (!svc_sendreply(transp, (XDRPROC_T_TYPE) xdr_result, (SVC_IN_ARG_TYPE) & res))
|
||||
svcerr_systemerr(transp);
|
||||
|
||||
/*
|
||||
* Free up transp. It's only used for one reply.
|
||||
*/
|
||||
XFREE(transp);
|
||||
mp->am_transp = NULL;
|
||||
#ifdef DEBUG
|
||||
dlog("Quick reply sent for %s", mp->am_mnt->mf_mount);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nfsreadlinkres *
|
||||
nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsreadlinkres res;
|
||||
am_node *mp;
|
||||
int retry;
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
plog(XLOG_DEBUG, "readlink:");
|
||||
#endif /* DEBUG */
|
||||
|
||||
mp = fh_to_mp2(argp, &retry);
|
||||
if (mp == 0) {
|
||||
readlink_retry:
|
||||
if (retry < 0)
|
||||
return 0;
|
||||
res.rlr_status = nfs_error(retry);
|
||||
} else {
|
||||
char *ln = do_readlink(mp, &retry, (nfsattrstat **) 0);
|
||||
if (ln == 0)
|
||||
goto readlink_retry;
|
||||
res.rlr_status = NFS_OK;
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
if (ln)
|
||||
plog(XLOG_DEBUG, "\treadlink(%s) = %s", mp->am_path, ln);
|
||||
#endif /* DEBUG */
|
||||
res.rlr_u.rlr_data_u = ln;
|
||||
mp->am_stats.s_readlink++;
|
||||
}
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsreadres *
|
||||
nfsproc_read_2_svc(nfsreadargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsreadres res;
|
||||
|
||||
memset((char *) &res, 0, sizeof(res));
|
||||
res.rr_status = nfs_error(EACCES);
|
||||
|
||||
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;
|
||||
|
||||
if (!fh_to_mp(&argp->wra_fhandle))
|
||||
res.ns_status = nfs_error(ESTALE);
|
||||
else
|
||||
res.ns_status = nfs_error(EROFS);
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsdiropres *
|
||||
nfsproc_create_2_svc(nfscreateargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsdiropres res;
|
||||
|
||||
if (!fh_to_mp(&argp->ca_where.da_fhandle))
|
||||
res.dr_status = nfs_error(ESTALE);
|
||||
else
|
||||
res.dr_status = nfs_error(EROFS);
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
static nfsstat *
|
||||
unlink_or_rmdir(nfsdiropargs *argp, struct svc_req *rqstp, int unlinkp)
|
||||
{
|
||||
static nfsstat res;
|
||||
int retry;
|
||||
|
||||
am_node *mp = fh_to_mp3(&argp->da_fhandle, &retry, VLOOK_DELETE);
|
||||
if (mp == 0) {
|
||||
if (retry < 0)
|
||||
return 0;
|
||||
res = nfs_error(retry);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mp->am_fattr.na_type != NFDIR) {
|
||||
res = nfs_error(ENOTDIR);
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
plog(XLOG_DEBUG, "\tremove(%s, %s)", mp->am_path, argp->da_name);
|
||||
#endif /* DEBUG */
|
||||
|
||||
mp = (*mp->am_mnt->mf_ops->lookuppn) (mp, argp->da_name, &retry, VLOOK_DELETE);
|
||||
if (mp == 0) {
|
||||
/*
|
||||
* Ignore retries...
|
||||
*/
|
||||
if (retry < 0)
|
||||
retry = 0;
|
||||
/*
|
||||
* Usual NFS workaround...
|
||||
*/
|
||||
else if (retry == ENOENT)
|
||||
retry = 0;
|
||||
res = nfs_error(retry);
|
||||
} else {
|
||||
forcibly_timeout_mp(mp);
|
||||
res = NFS_OK;
|
||||
}
|
||||
|
||||
out:
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsstat *
|
||||
nfsproc_remove_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
return unlink_or_rmdir(argp, rqstp, TRUE);
|
||||
}
|
||||
|
||||
|
||||
nfsstat *
|
||||
nfsproc_rename_2_svc(nfsrenameargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsstat res;
|
||||
|
||||
if (!fh_to_mp(&argp->rna_from.da_fhandle) || !fh_to_mp(&argp->rna_to.da_fhandle))
|
||||
res = nfs_error(ESTALE);
|
||||
/*
|
||||
* If the kernel is doing clever things with referenced files
|
||||
* then let it pretend...
|
||||
*/
|
||||
else if (NSTREQ(argp->rna_to.da_name, ".nfs", 4))
|
||||
res = NFS_OK;
|
||||
/*
|
||||
* otherwise a failure
|
||||
*/
|
||||
else
|
||||
res = nfs_error(EROFS);
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsstat *
|
||||
nfsproc_link_2_svc(nfslinkargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsstat res;
|
||||
|
||||
if (!fh_to_mp(&argp->la_fhandle) || !fh_to_mp(&argp->la_to.da_fhandle))
|
||||
res = nfs_error(ESTALE);
|
||||
else
|
||||
res = nfs_error(EROFS);
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsstat *
|
||||
nfsproc_symlink_2_svc(nfssymlinkargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsstat res;
|
||||
|
||||
if (!fh_to_mp(&argp->sla_from.da_fhandle))
|
||||
res = nfs_error(ESTALE);
|
||||
else
|
||||
res = nfs_error(EROFS);
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsdiropres *
|
||||
nfsproc_mkdir_2_svc(nfscreateargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsdiropres res;
|
||||
|
||||
if (!fh_to_mp(&argp->ca_where.da_fhandle))
|
||||
res.dr_status = nfs_error(ESTALE);
|
||||
else
|
||||
res.dr_status = nfs_error(EROFS);
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsstat *
|
||||
nfsproc_rmdir_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
return unlink_or_rmdir(argp, rqstp, FALSE);
|
||||
}
|
||||
|
||||
|
||||
nfsreaddirres *
|
||||
nfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsreaddirres res;
|
||||
static nfsentry e_res[MAX_READDIR_ENTRIES];
|
||||
am_node *mp;
|
||||
int retry;
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
plog(XLOG_DEBUG, "readdir:");
|
||||
#endif /* DEBUG */
|
||||
|
||||
mp = fh_to_mp2(&argp->rda_fhandle, &retry);
|
||||
if (mp == 0) {
|
||||
if (retry < 0)
|
||||
return 0;
|
||||
res.rdr_status = nfs_error(retry);
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
plog(XLOG_DEBUG, "\treaddir(%s)", mp->am_path);
|
||||
#endif /* DEBUG */
|
||||
res.rdr_status = nfs_error((*mp->am_mnt->mf_ops->readdir)
|
||||
(mp, argp->rda_cookie,
|
||||
&res.rdr_u.rdr_reply_u, e_res, argp->rda_count));
|
||||
mp->am_stats.s_readdir++;
|
||||
}
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
nfsstatfsres *
|
||||
nfsproc_statfs_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
|
||||
{
|
||||
static nfsstatfsres res;
|
||||
am_node *mp;
|
||||
int retry;
|
||||
mntent_t mnt;
|
||||
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
plog(XLOG_DEBUG, "statfs:");
|
||||
#endif /* DEBUG */
|
||||
|
||||
mp = fh_to_mp2(argp, &retry);
|
||||
if (mp == 0) {
|
||||
if (retry < 0)
|
||||
return 0;
|
||||
res.sfr_status = nfs_error(retry);
|
||||
} else {
|
||||
nfsstatfsokres *fp;
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
plog(XLOG_DEBUG, "\tstat_fs(%s)", mp->am_path);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* just return faked up file system information
|
||||
*/
|
||||
fp = &res.sfr_u.sfr_reply_u;
|
||||
|
||||
fp->sfrok_tsize = 1024;
|
||||
fp->sfrok_bsize = 1024;
|
||||
|
||||
/* check if map is browsable and show_statfs_entries=yes */
|
||||
if ((gopt.flags & CFM_SHOW_STATFS_ENTRIES) &&
|
||||
mp->am_mnt && mp->am_mnt->mf_mopts) {
|
||||
mnt.mnt_opts = mp->am_mnt->mf_mopts;
|
||||
if (hasmntopt(&mnt, "browsable")) {
|
||||
count_map_entries(mp,
|
||||
&fp->sfrok_blocks,
|
||||
&fp->sfrok_bfree,
|
||||
&fp->sfrok_bavail);
|
||||
}
|
||||
} else {
|
||||
fp->sfrok_blocks = 0; /* set to 1 if you don't want empty automounts */
|
||||
fp->sfrok_bfree = 0;
|
||||
fp->sfrok_bavail = 0;
|
||||
}
|
||||
|
||||
res.sfr_status = NFS_OK;
|
||||
mp->am_stats.s_statfs++;
|
||||
}
|
||||
|
||||
return &res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* count how many total entries there are in a map, and how many
|
||||
* of them are in use.
|
||||
*/
|
||||
static void
|
||||
count_map_entries(const am_node *mp, u_int *out_blocks, u_int *out_bfree, u_int *out_bavail)
|
||||
{
|
||||
u_int blocks, bfree, bavail, i;
|
||||
mntfs *mf;
|
||||
mnt_map *mmp;
|
||||
kv *k;
|
||||
|
||||
blocks = bfree = bavail = 0;
|
||||
if (!mp)
|
||||
goto out;
|
||||
mf = mp->am_mnt;
|
||||
if (!mf)
|
||||
goto out;
|
||||
mmp = (mnt_map *) mf->mf_private;
|
||||
if (!mmp)
|
||||
goto out;
|
||||
|
||||
/* iterate over keys */
|
||||
for (i = 0; i < NKVHASH; i++) {
|
||||
for (k = mmp->kvhash[i]; k ; k = k->next) {
|
||||
if (!k->key)
|
||||
continue;
|
||||
blocks++;
|
||||
/*
|
||||
* XXX: Need to count how many are actively in use and recompute
|
||||
* bfree and bavail based on it.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
*out_blocks = blocks;
|
||||
*out_bfree = bfree;
|
||||
*out_bavail = bavail;
|
||||
}
|
293
contrib/amd/amd/ops_TEMPLATE.c
Normal file
293
contrib/amd/amd/ops_TEMPLATE.c
Normal file
@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_TEMPLATE.c,v 5.2.2.3 1992/08/02 10:42:21 jsp Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* An empty template for an amd pseudo filesystem "foofs".
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: if this is an Amd file system, prepend "amfs_" to all foofs symbols
|
||||
* and renamed the file name to amfs_foofs.c. If it is a native file system
|
||||
* (such as pcfs, isofs, or ffs), then you can keep the names as is, and
|
||||
* just rename the file to ops_foofs.c.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* forward declarations */
|
||||
static char * foofs_match(am_opts *fo);
|
||||
static int foofs_init(mntfs *mf);
|
||||
static int foofs_mount(am_node *mp);
|
||||
static int foofs_fmount(mntfs *mf);
|
||||
static int foofs_umount(am_node *mp);
|
||||
static int foofs_fumount(mntfs *mf);
|
||||
static am_node * foofs_lookuppn(am_node *mp, char *fname, int *error_return, int op);
|
||||
static int foofs_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, int count);
|
||||
static am_node * foofs_readlink(am_node *mp, int *error_return);
|
||||
static void foofs_mounted(mntfs *mf);
|
||||
static void foofs_umounted(am_node *mp);
|
||||
fserver * foofs_ffserver(mntfs *mf);
|
||||
|
||||
|
||||
/*
|
||||
* Foofs operations.
|
||||
* Define only those you need, others set to 0 (NULL)
|
||||
*/
|
||||
am_ops foofs_ops =
|
||||
{
|
||||
"foofs", /* name of file system */
|
||||
foofs_match, /* match */
|
||||
foofs_init, /* initialize */
|
||||
foofs_mount, /* mount vnode */
|
||||
foofs_fmount, /* mount vfs */
|
||||
foofs_umount, /* unmount vnode */
|
||||
foofs_fumount, /* unmount VFS */
|
||||
foofs_lookuppn, /* lookup path-name */
|
||||
foofs_readdir, /* read directory */
|
||||
foofs_readlink, /* read link */
|
||||
foofs_mounted, /* after-mount extra actions */
|
||||
foofs_umounted, /* after-umount extra actions */
|
||||
foofs_ffserver, /* find a file server */
|
||||
FS_MKMNT | FS_BACKGROUND | FS_AMQINFO /* flags */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Check that f/s has all needed fields.
|
||||
* Returns: matched string if found, NULL otherwise.
|
||||
*/
|
||||
static char *
|
||||
foofs_match(am_opts *fo)
|
||||
{
|
||||
char *cp = "fill this with a way to find the match";
|
||||
|
||||
plog(XLOG_INFO, "entering foofs_match...");
|
||||
|
||||
if (cp)
|
||||
return cp; /* OK */
|
||||
|
||||
return NULL; /* not OK */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
* Returns: 0 if OK, non-zero (errno) if failed.
|
||||
*/
|
||||
static int
|
||||
foofs_init(mntfs *mf)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
plog(XLOG_INFO, "entering foofs_init...");
|
||||
|
||||
error = EPERM; /* XXX: fixme */
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mount vnode.
|
||||
* Returns: 0 if OK, non-zero (errno) if failed.
|
||||
*/
|
||||
static int
|
||||
foofs_mount(am_node *mp)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
plog(XLOG_INFO, "entering foofs_mount...");
|
||||
|
||||
error = EPERM; /* XXX: fixme */
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mount vfs.
|
||||
* Returns: 0 if OK, non-zero (errno) if failed.
|
||||
*/
|
||||
static int
|
||||
foofs_fmount(mntfs *mf)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
plog(XLOG_INFO, "entering foofs_fmount...");
|
||||
|
||||
error = EPERM; /* XXX: fixme */
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unmount vnode.
|
||||
* Returns: 0 if OK, non-zero (errno) if failed.
|
||||
*/
|
||||
static int
|
||||
foofs_umount(am_node *mp)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
plog(XLOG_INFO, "entering foofs_umount...");
|
||||
|
||||
error = EPERM; /* XXX: fixme */
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unmount VFS.
|
||||
* Returns: 0 if OK, non-zero (errno) if failed.
|
||||
*/
|
||||
static int
|
||||
foofs_fumount(mntfs *mf)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
plog(XLOG_INFO, "entering foofs_fumount...");
|
||||
|
||||
error = EPERM; /* XXX: fixme */
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Lookup path-name.
|
||||
* Returns: the am_node that was found, or NULL if failed.
|
||||
* If failed, also fills in errno in error_return.
|
||||
*/
|
||||
static am_node *
|
||||
foofs_lookuppn(am_node *mp, char *fname, int *error_return, int op)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
plog(XLOG_INFO, "entering foofs_lookuppn...");
|
||||
|
||||
error = EPERM; /* XXX: fixme */
|
||||
|
||||
*error_return = error;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read directory.
|
||||
* Returns: 0 if OK, non-zero (errno) if failed.
|
||||
* If OK, fills in ep with chain of directory entries.
|
||||
*/
|
||||
static int
|
||||
foofs_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, int count)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
plog(XLOG_INFO, "entering foofs_readdir...");
|
||||
|
||||
error = EPERM; /* XXX: fixme */
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read link.
|
||||
* Returns: am_node found, or NULL if not found.
|
||||
* If failed, fills in errno in error_return.
|
||||
*/
|
||||
static am_node *
|
||||
foofs_readlink(am_node *mp, int *error_return)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
plog(XLOG_INFO, "entering foofs_readlink...");
|
||||
|
||||
error = EPERM; /* XXX: fixme */
|
||||
|
||||
*error_return = error;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Async mount callback function.
|
||||
* After the base mount went OK, sometimes
|
||||
* there are additional actions that are needed. See union_mounted() and
|
||||
* toplvl_mounted().
|
||||
*/
|
||||
static void
|
||||
foofs_mounted(mntfs *mf)
|
||||
{
|
||||
plog(XLOG_INFO, "entering foofs_mounted...");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Async unmount callback function.
|
||||
* After the base umount() succeeds, we may want to take extra actions,
|
||||
* such as informing remote mount daemons that we've unmounted them.
|
||||
* See amfs_auto_umounted(), host_umounted(), nfs_umounted().
|
||||
*/
|
||||
static void
|
||||
foofs_umounted(am_node *mp)
|
||||
{
|
||||
plog(XLOG_INFO, "entering foofs_umounted...");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find a file server.
|
||||
* Returns: fserver of found server, or NULL if not found.
|
||||
*/
|
||||
fserver *
|
||||
foofs_ffserver(mntfs *mf)
|
||||
{
|
||||
plog(XLOG_INFO, "entering foofs_ffserver...");
|
||||
|
||||
return NULL;
|
||||
}
|
1275
contrib/amd/amd/ops_autofs.c
Normal file
1275
contrib/amd/amd/ops_autofs.c
Normal file
File diff suppressed because it is too large
Load Diff
247
contrib/amd/amd/ops_cachefs.c
Normal file
247
contrib/amd/amd/ops_cachefs.c
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_cachefs.c,v 5.2.2.3 1992/08/02 10:42:21 jsp Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Caching filesystem (Solaris 2.x)
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* forward declarations */
|
||||
static char *cachefs_match(am_opts *fo);
|
||||
static int cachefs_init(mntfs *mf);
|
||||
static int cachefs_fmount(mntfs *mf);
|
||||
static int cachefs_fumount(mntfs *mf);
|
||||
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops cachefs_ops =
|
||||
{
|
||||
"cachefs",
|
||||
cachefs_match,
|
||||
cachefs_init,
|
||||
amfs_auto_fmount,
|
||||
cachefs_fmount,
|
||||
amfs_auto_fumount,
|
||||
cachefs_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* cachefs_readlink */
|
||||
0, /* post-mount actions */
|
||||
0, /* post-umount actions */
|
||||
find_amfs_auto_srvr,
|
||||
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Check that f/s has all needed fields.
|
||||
* Returns: matched string if found, NULL otherwise.
|
||||
*/
|
||||
static char *
|
||||
cachefs_match(am_opts *fo)
|
||||
{
|
||||
/* sanity check */
|
||||
if (!fo->opt_rfs || !fo->opt_fs || !fo->opt_cachedir) {
|
||||
plog(XLOG_USER, "cachefs: must specify cachedir, rfs, and fs");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("CACHEFS: using cache directory \"%s\"", fo->opt_cachedir);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* determine magic cookie to put in mtab */
|
||||
return strdup(fo->opt_cachedir);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
* Returns: 0 if OK, non-zero (errno) if failed.
|
||||
*/
|
||||
static int
|
||||
cachefs_init(mntfs *mf)
|
||||
{
|
||||
/*
|
||||
* Save cache directory name
|
||||
*/
|
||||
if (mf->mf_refc == 1) {
|
||||
mf->mf_private = (voidp) strdup(mf->mf_fo->opt_cachedir);
|
||||
mf->mf_prfree = (void (*)(voidp)) free;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mntpt is the mount point ($fs) [XXX: was 'dir']
|
||||
* backdir is the mounted pathname ($rfs) [XXX: was 'fs_name']
|
||||
* cachedir is the cache directory ($cachedir)
|
||||
*/
|
||||
static int
|
||||
mount_cachefs(char *mntpt, char *backdir, char *cachedir, char *opts)
|
||||
{
|
||||
cachefs_args_t ca;
|
||||
mntent_t mnt;
|
||||
int flags;
|
||||
char *cp;
|
||||
MTYPE_TYPE type = MOUNT_TYPE_CACHEFS; /* F/S mount type */
|
||||
|
||||
memset((voidp) &ca, 0, sizeof(ca)); /* Paranoid */
|
||||
|
||||
/*
|
||||
* Fill in the mount structure
|
||||
*/
|
||||
memset((voidp) &mnt, 0, sizeof(mnt));
|
||||
mnt.mnt_dir = mntpt;
|
||||
mnt.mnt_fsname = backdir;
|
||||
mnt.mnt_type = MNTTAB_TYPE_CACHEFS;
|
||||
mnt.mnt_opts = opts;
|
||||
|
||||
flags = compute_mount_flags(&mnt);
|
||||
|
||||
/* Fill in cachefs mount arguments */
|
||||
|
||||
/*
|
||||
* XXX: Caveats
|
||||
* (1) cache directory is NOT checked for sanity beforehand, nor is it
|
||||
* purged. Maybe it should be purged first?
|
||||
* (2) cache directory is NOT locked. Should we?
|
||||
*/
|
||||
|
||||
/* mount flags */
|
||||
ca.cfs_options.opt_flags = CFS_WRITE_AROUND | CFS_ACCESS_BACKFS;
|
||||
/* cache population size */
|
||||
ca.cfs_options.opt_popsize = DEF_POP_SIZE; /* default: 64K */
|
||||
/* filegrp size */
|
||||
ca.cfs_options.opt_fgsize = DEF_FILEGRP_SIZE; /* default: 256 */
|
||||
|
||||
/* CFS ID for file system (must be unique) */
|
||||
ca.cfs_fsid = cachedir;
|
||||
|
||||
/* CFS fscdir name */
|
||||
memset(ca.cfs_cacheid, 0, sizeof(ca.cfs_cacheid));
|
||||
/* append cacheid and mountpoint */
|
||||
sprintf(ca.cfs_cacheid, "%s:%s", ca.cfs_fsid, mntpt);
|
||||
/* convert '/' to '_' (Solaris does that...) */
|
||||
cp = ca.cfs_cacheid;
|
||||
while ((cp = strpbrk(cp, "/")) != NULL)
|
||||
*cp = '_';
|
||||
|
||||
/* path for this cache dir */
|
||||
ca.cfs_cachedir = cachedir;
|
||||
|
||||
/* back filesystem dir */
|
||||
ca.cfs_backfs = backdir;
|
||||
|
||||
/* same as nfs values (XXX: need to handle these options) */
|
||||
ca.cfs_acregmin = 0;
|
||||
ca.cfs_acregmax = 0;
|
||||
ca.cfs_acdirmin = 0;
|
||||
ca.cfs_acdirmax = 0;
|
||||
|
||||
/*
|
||||
* Call generic mount routine
|
||||
*/
|
||||
return mount_fs(&mnt, flags, (caddr_t) &ca, 0, type, 0, NULL, mnttab_file_name);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cachefs_fmount(mntfs *mf)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = mount_cachefs(mf->mf_mount,
|
||||
mf->mf_fo->opt_rfs,
|
||||
mf->mf_fo->opt_cachedir,
|
||||
mf->mf_mopts);
|
||||
if (error) {
|
||||
errno = error;
|
||||
/* according to Solaris, if errno==ESRCH, "options to not match" */
|
||||
if (error == ESRCH)
|
||||
plog(XLOG_ERROR, "mount_cachefs: options to no match: %m");
|
||||
else
|
||||
plog(XLOG_ERROR, "mount_cachefs: %m");
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cachefs_fumount(mntfs *mf)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = UMOUNT_FS(mf->mf_mount, mnttab_file_name);
|
||||
|
||||
/*
|
||||
* In the case of cachefs, we must fsck the cache directory. Otherwise,
|
||||
* it will remain inconsistent, and the next cachefs mount will fail
|
||||
* with the error "no space left on device" (ENOSPC).
|
||||
*
|
||||
* XXX: this is hacky! use fork/exec/wait instead...
|
||||
*/
|
||||
if (!error) {
|
||||
char *cachedir = NULL;
|
||||
char cmd[128];
|
||||
|
||||
cachedir = (char *) mf->mf_private;
|
||||
plog(XLOG_INFO, "running fsck on cache directory \"%s\"", cachedir);
|
||||
sprintf(cmd, "fsck -F cachefs %s", cachedir);
|
||||
system(cmd);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
206
contrib/amd/amd/ops_cdfs.c
Normal file
206
contrib/amd/amd/ops_cdfs.c
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 5.2.2.1 1992/02/09 15:09:08 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* High Sierra (CD-ROM) file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* forward declarations */
|
||||
static char *cdfs_match(am_opts *fo);
|
||||
static int cdfs_fmount(mntfs *mf);
|
||||
static int cdfs_fumount(mntfs *mf);
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops cdfs_ops =
|
||||
{
|
||||
"cdfs",
|
||||
cdfs_match,
|
||||
0, /* cdfs_init */
|
||||
amfs_auto_fmount,
|
||||
cdfs_fmount,
|
||||
amfs_auto_fumount,
|
||||
cdfs_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* cdfs_readlink */
|
||||
0, /* cdfs_mounted */
|
||||
0, /* cdfs_umounted */
|
||||
find_amfs_auto_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 genflags, cdfs_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 */
|
||||
cdfs_flags = 0;
|
||||
|
||||
/*
|
||||
* Fill in the mount structure
|
||||
*/
|
||||
memset((voidp) &mnt, 0, sizeof(mnt));
|
||||
mnt.mnt_dir = dir;
|
||||
mnt.mnt_fsname = fs_name;
|
||||
mnt.mnt_type = MNTTAB_TYPE_CDFS;
|
||||
mnt.mnt_opts = opts;
|
||||
|
||||
#if defined(MNT2_CDFS_OPT_DEFPERM) && defined(MNTTAB_OPT_DEFPERM)
|
||||
if (hasmntopt(&mnt, MNTTAB_OPT_DEFPERM))
|
||||
# ifdef MNT2_CDFS_OPT_DEFPERM
|
||||
cdfs_flags |= MNT2_CDFS_OPT_DEFPERM;
|
||||
# else /* not MNT2_CDFS_OPT_DEFPERM */
|
||||
cdfs_flags &= ~MNT2_CDFS_OPT_NODEFPERM;
|
||||
# endif /* not MNT2_CDFS_OPT_DEFPERM */
|
||||
#endif /* defined(MNT2_CDFS_OPT_DEFPERM) && defined(MNTTAB_OPT_DEFPERM) */
|
||||
|
||||
#if defined(MNT2_CDFS_OPT_NODEFPERM) && defined(MNTTAB_OPT_NODEFPERM)
|
||||
if (hasmntopt(&mnt, MNTTAB_OPT_NODEFPERM))
|
||||
cdfs_flags |= MNT2_CDFS_OPT_NODEFPERM;
|
||||
#endif /* MNTTAB_OPT_NODEFPERM */
|
||||
|
||||
#if defined(MNT2_CDFS_OPT_NOVERSION) && defined(MNTTAB_OPT_NOVERSION)
|
||||
if (hasmntopt(&mnt, MNTTAB_OPT_NOVERSION))
|
||||
cdfs_flags |= MNT2_CDFS_OPT_NOVERSION;
|
||||
#endif /* defined(MNT2_CDFS_OPT_NOVERSION) && defined(MNTTAB_OPT_NOVERSION) */
|
||||
|
||||
#if defined(MNT2_CDFS_OPT_RRIP) && defined(MNTTAB_OPT_RRIP)
|
||||
if (hasmntopt(&mnt, MNTTAB_OPT_RRIP))
|
||||
cdfs_flags |= MNT2_CDFS_OPT_RRIP;
|
||||
#endif /* defined(MNT2_CDFS_OPT_RRIP) && defined(MNTTAB_OPT_RRIP) */
|
||||
|
||||
genflags = compute_mount_flags(&mnt);
|
||||
|
||||
#ifdef HAVE_FIELD_CDFS_ARGS_T_FLAGS
|
||||
cdfs_args.flags = cdfs_flags;
|
||||
#endif /* HAVE_FIELD_CDFS_ARGS_T_FLAGS */
|
||||
|
||||
#ifdef HAVE_FIELD_CDFS_ARGS_T_ISO_FLAGS
|
||||
cdfs_args.iso_flags = genflags | cdfs_flags;
|
||||
#endif /* HAVE_FIELD_CDFS_ARGS_T_ISO_FLAGS */
|
||||
|
||||
#ifdef HAVE_FIELD_CDFS_ARGS_T_ISO_PGTHRESH
|
||||
cdfs_args.iso_pgthresh = hasmntval(&mnt, MNTTAB_OPT_PGTHRESH);
|
||||
#endif /* HAVE_FIELD_CDFS_ARGS_T_ISO_PGTHRESH */
|
||||
|
||||
#ifdef HAVE_FIELD_CDFS_ARGS_T_FSPEC
|
||||
cdfs_args.fspec = fs_name;
|
||||
#endif /* HAVE_FIELD_CDFS_ARGS_T_FSPEC */
|
||||
|
||||
#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 */
|
||||
|
||||
#ifdef HAVE_FIELD_CDFS_ARGS_T_SSECTOR
|
||||
/* XXX: need to provide ssector mount option */
|
||||
cdfs_args.ssector = 0; /* use 1st session on disk */
|
||||
#endif /* HAVE_FIELD_CDFS_ARGS_T_SSECTOR */
|
||||
|
||||
/*
|
||||
* Call generic mount routine
|
||||
*/
|
||||
return mount_fs(&mnt, genflags, (caddr_t) &cdfs_args, 0, type, 0, NULL, mnttab_file_name);
|
||||
}
|
||||
|
||||
|
||||
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, mnttab_file_name);
|
||||
}
|
164
contrib/amd/amd/ops_efs.c
Normal file
164
contrib/amd/amd/ops_efs.c
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_efs.c,v 5.2.2.1 1992/02/09 15:09:08 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Irix UN*X file system: EFS (Extent File System)
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* forward declarations */
|
||||
static char *efs_match(am_opts *fo);
|
||||
static int efs_fmount(mntfs *mf);
|
||||
static int efs_fumount(mntfs *mf);
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops efs_ops =
|
||||
{
|
||||
"efs",
|
||||
efs_match,
|
||||
0, /* efs_init */
|
||||
amfs_auto_fmount,
|
||||
efs_fmount,
|
||||
amfs_auto_fumount,
|
||||
efs_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* efs_readlink */
|
||||
0, /* efs_mounted */
|
||||
0, /* efs_umounted */
|
||||
find_amfs_auto_srvr,
|
||||
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* EFS needs local filesystem and device.
|
||||
*/
|
||||
static char *
|
||||
efs_match(am_opts *fo)
|
||||
{
|
||||
|
||||
if (!fo->opt_dev) {
|
||||
plog(XLOG_USER, "efs: no device specified");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("EFS: 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_efs(char *dir, char *fs_name, char *opts)
|
||||
{
|
||||
efs_args_t efs_args;
|
||||
mntent_t mnt;
|
||||
int flags;
|
||||
|
||||
/*
|
||||
* Figure out the name of the file system type.
|
||||
*/
|
||||
MTYPE_TYPE type = MOUNT_TYPE_EFS;
|
||||
|
||||
memset((voidp) &efs_args, 0, sizeof(efs_args)); /* Paranoid */
|
||||
|
||||
/*
|
||||
* Fill in the mount structure
|
||||
*/
|
||||
memset((voidp) &mnt, 0, sizeof(mnt));
|
||||
mnt.mnt_dir = dir;
|
||||
mnt.mnt_fsname = fs_name;
|
||||
mnt.mnt_type = MNTTAB_TYPE_EFS;
|
||||
mnt.mnt_opts = opts;
|
||||
|
||||
flags = compute_mount_flags(&mnt);
|
||||
|
||||
#ifdef HAVE_FIELD_EFS_ARGS_T_FLAGS
|
||||
efs_args.flags = 0; /* XXX: fix this to correct flags */
|
||||
#endif /* HAVE_FIELD_EFS_ARGS_T_FLAGS */
|
||||
#ifdef HAVE_FIELD_EFS_ARGS_T_FSPEC
|
||||
efs_args.fspec = fs_name;
|
||||
#endif /* HAVE_FIELD_EFS_ARGS_T_FSPEC */
|
||||
|
||||
/*
|
||||
* Call generic mount routine
|
||||
*/
|
||||
return mount_fs(&mnt, flags, (caddr_t) &efs_args, 0, type, 0, NULL, mnttab_file_name);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
efs_fmount(mntfs *mf)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = mount_efs(mf->mf_mount, mf->mf_info, mf->mf_mopts);
|
||||
if (error) {
|
||||
errno = error;
|
||||
plog(XLOG_ERROR, "mount_efs: %m");
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
efs_fumount(mntfs *mf)
|
||||
{
|
||||
return UMOUNT_FS(mf->mf_mount, mnttab_file_name);
|
||||
}
|
154
contrib/amd/amd/ops_lofs.c
Normal file
154
contrib/amd/amd/ops_lofs.c
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_lofs.c,v 5.2.2.1 1992/02/09 15:09:08 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Loopback file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* forward definitions */
|
||||
static char * lofs_match(am_opts *fo);
|
||||
static int lofs_fmount(mntfs *mf);
|
||||
static int lofs_fumount(mntfs *mf);
|
||||
static int mount_lofs(char *dir, char *fs_name, char *opts);
|
||||
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops lofs_ops =
|
||||
{
|
||||
"lofs",
|
||||
lofs_match,
|
||||
0, /* lofs_init */
|
||||
amfs_auto_fmount,
|
||||
lofs_fmount,
|
||||
amfs_auto_fumount,
|
||||
lofs_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* lofs_readlink */
|
||||
0, /* lofs_mounted */
|
||||
0, /* lofs_umounted */
|
||||
find_amfs_auto_srvr,
|
||||
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* LOFS needs remote filesystem.
|
||||
*/
|
||||
static char *
|
||||
lofs_match(am_opts *fo)
|
||||
{
|
||||
if (!fo->opt_rfs) {
|
||||
plog(XLOG_USER, "lofs: no source filesystem specified");
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
dlog("LOFS: mounting fs \"%s\" on \"%s\"",
|
||||
fo->opt_rfs, fo->opt_fs);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Determine magic cookie to put in mtab
|
||||
*/
|
||||
return strdup(fo->opt_rfs);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
mount_lofs(char *dir, char *fs_name, char *opts)
|
||||
{
|
||||
mntent_t mnt;
|
||||
int flags;
|
||||
|
||||
/*
|
||||
* Figure out the name of the file system type.
|
||||
*/
|
||||
MTYPE_TYPE type = MOUNT_TYPE_LOFS;
|
||||
|
||||
/*
|
||||
* Fill in the mount structure
|
||||
*/
|
||||
memset((voidp) &mnt, 0, sizeof(mnt));
|
||||
mnt.mnt_dir = dir;
|
||||
mnt.mnt_fsname = fs_name;
|
||||
mnt.mnt_type = MNTTAB_TYPE_LOFS;
|
||||
mnt.mnt_opts = opts;
|
||||
|
||||
flags = compute_mount_flags(&mnt);
|
||||
|
||||
/*
|
||||
* Call generic mount routine
|
||||
*/
|
||||
return mount_fs(&mnt, flags, NULL, 0, type, 0, NULL, mnttab_file_name);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
lofs_fmount(mntfs *mf)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = mount_lofs(mf->mf_mount, mf->mf_info, mf->mf_mopts);
|
||||
if (error) {
|
||||
errno = error;
|
||||
plog(XLOG_ERROR, "mount_lofs: %m");
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
lofs_fumount(mntfs *mf)
|
||||
{
|
||||
return UMOUNT_FS(mf->mf_mount, mnttab_file_name);
|
||||
}
|
55
contrib/amd/amd/ops_mfs.c
Normal file
55
contrib/amd/amd/ops_mfs.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 5.2.2.3 1992/08/02 10:42:21 jsp 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... :-) */
|
799
contrib/amd/amd/ops_nfs.c
Normal file
799
contrib/amd/amd/ops_nfs.c
Normal file
@ -0,0 +1,799 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_nfs.c,v 5.2.2.3 1992/08/02 10:42:21 jsp Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Network file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/*
|
||||
* Convert from nfsstat to UN*X error code
|
||||
*/
|
||||
#define unx_error(e) ((int)(e))
|
||||
|
||||
/*
|
||||
* FH_TTL is the time a file handle will remain in the cache since
|
||||
* last being used. If the file handle becomes invalid, then it
|
||||
* will be flushed anyway.
|
||||
*/
|
||||
#define FH_TTL (5 * 60) /* five minutes */
|
||||
#define FH_TTL_ERROR (30) /* 30 seconds */
|
||||
#define FHID_ALLOC(struct) (++fh_id)
|
||||
|
||||
/*
|
||||
* The NFS layer maintains a cache of file handles.
|
||||
* This is *fundamental* to the implementation and
|
||||
* also allows quick remounting when a filesystem
|
||||
* is accessed soon after timing out.
|
||||
*
|
||||
* The NFS server layer knows to flush this cache
|
||||
* when a server goes down so avoiding stale handles.
|
||||
*
|
||||
* Each cache entry keeps a hard reference to
|
||||
* the corresponding server. This ensures that
|
||||
* the server keepalive information is maintained.
|
||||
*
|
||||
* The copy of the sockaddr_in here is taken so
|
||||
* that the port can be twiddled to talk to mountd
|
||||
* instead of portmap or the NFS server as used
|
||||
* elsewhere.
|
||||
* The port# is flushed if a server goes down.
|
||||
* The IP address is never flushed - we assume
|
||||
* that the address of a mounted machine never
|
||||
* changes. If it does, then you have other
|
||||
* problems...
|
||||
*/
|
||||
typedef struct fh_cache fh_cache;
|
||||
struct fh_cache {
|
||||
qelem fh_q; /* List header */
|
||||
voidp fh_wchan; /* Wait channel */
|
||||
int fh_error; /* Valid data? */
|
||||
int fh_id; /* Unique id */
|
||||
int fh_cid; /* Callout id */
|
||||
u_long fh_nfs_version; /* highest NFS version on host */
|
||||
am_nfs_handle_t fh_nfs_handle; /* Handle on filesystem */
|
||||
struct sockaddr_in fh_sin; /* Address of mountd */
|
||||
fserver *fh_fs; /* Server holding filesystem */
|
||||
char *fh_path; /* Filesystem on host */
|
||||
};
|
||||
|
||||
/* forward definitions */
|
||||
static int call_mountd(fh_cache *fp, u_long proc, fwd_fun f, voidp wchan);
|
||||
static int fh_id = 0;
|
||||
|
||||
/* globals */
|
||||
AUTH *nfs_auth;
|
||||
qelem fh_head = {&fh_head, &fh_head};
|
||||
|
||||
/*
|
||||
* Network file system operations
|
||||
*/
|
||||
am_ops nfs_ops =
|
||||
{
|
||||
"nfs",
|
||||
nfs_match,
|
||||
nfs_init,
|
||||
amfs_auto_fmount,
|
||||
nfs_fmount,
|
||||
amfs_auto_fumount,
|
||||
nfs_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* nfs_readlink */
|
||||
0, /* nfs_mounted */
|
||||
nfs_umounted,
|
||||
find_nfs_srvr,
|
||||
FS_MKMNT | FS_BACKGROUND | FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
static fh_cache *
|
||||
find_nfs_fhandle_cache(voidp idv, int done)
|
||||
{
|
||||
fh_cache *fp, *fp2 = 0;
|
||||
int id = (long) idv; /* for 64-bit archs */
|
||||
|
||||
ITER(fp, fh_cache, &fh_head) {
|
||||
if (fp->fh_id == id) {
|
||||
fp2 = fp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (fp2) {
|
||||
dlog("fh cache gives fp %#x, fs %s", fp2, fp2->fh_path);
|
||||
} else {
|
||||
dlog("fh cache search failed");
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (fp2 && !done) {
|
||||
fp2->fh_error = ETIMEDOUT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return fp2;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called when a filehandle appears
|
||||
*/
|
||||
static void
|
||||
got_nfs_fh(voidp pkt, int len, struct sockaddr_in * sa, struct sockaddr_in * ia, voidp idv, int done)
|
||||
{
|
||||
fh_cache *fp;
|
||||
|
||||
fp = find_nfs_fhandle_cache(idv, done);
|
||||
if (!fp)
|
||||
return;
|
||||
|
||||
/*
|
||||
* retrieve the correct RPC reply for the file handle, based on the
|
||||
* NFS protocol version.
|
||||
*/
|
||||
#ifdef HAVE_FS_NFS3
|
||||
if (fp->fh_nfs_version == NFS_VERSION3)
|
||||
fp->fh_error = pickup_rpc_reply(pkt, len, (voidp) &fp->fh_nfs_handle.v3,
|
||||
(XDRPROC_T_TYPE) xdr_mountres3);
|
||||
else
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
fp->fh_error = pickup_rpc_reply(pkt, len, (voidp) &fp->fh_nfs_handle.v2,
|
||||
(XDRPROC_T_TYPE) xdr_fhstatus);
|
||||
|
||||
if (!fp->fh_error) {
|
||||
#ifdef DEBUG
|
||||
dlog("got filehandle for %s:%s", fp->fh_fs->fs_host, fp->fh_path);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Wakeup anything sleeping on this filehandle
|
||||
*/
|
||||
if (fp->fh_wchan) {
|
||||
#ifdef DEBUG
|
||||
dlog("Calling wakeup on %#x", fp->fh_wchan);
|
||||
#endif /* DEBUG */
|
||||
wakeup(fp->fh_wchan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
flush_nfs_fhandle_cache(fserver *fs)
|
||||
{
|
||||
fh_cache *fp;
|
||||
|
||||
ITER(fp, fh_cache, &fh_head) {
|
||||
if (fp->fh_fs == fs || fs == 0) {
|
||||
fp->fh_sin.sin_port = (u_short) 0;
|
||||
fp->fh_error = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
discard_fh(voidp v)
|
||||
{
|
||||
fh_cache *fp = v;
|
||||
|
||||
rem_que(&fp->fh_q);
|
||||
if (fp->fh_fs) {
|
||||
#ifdef DEBUG
|
||||
dlog("Discarding filehandle for %s:%s", fp->fh_fs->fs_host, fp->fh_path);
|
||||
#endif /* DEBUG */
|
||||
free_srvr(fp->fh_fs);
|
||||
}
|
||||
if (fp->fh_path)
|
||||
XFREE(fp->fh_path);
|
||||
XFREE(fp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Determine the file handle for a node
|
||||
*/
|
||||
static int
|
||||
prime_nfs_fhandle_cache(char *path, fserver *fs, am_nfs_handle_t *fhbuf, voidp wchan)
|
||||
{
|
||||
fh_cache *fp, *fp_save = 0;
|
||||
int error;
|
||||
int reuse_id = FALSE;
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("Searching cache for %s:%s", fs->fs_host, path);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* First search the cache
|
||||
*/
|
||||
ITER(fp, fh_cache, &fh_head) {
|
||||
if (fs == fp->fh_fs && STREQ(path, fp->fh_path)) {
|
||||
switch (fp->fh_error) {
|
||||
case 0:
|
||||
plog(XLOG_INFO, "prime_nfs_fhandle_cache: NFS version %d", fp->fh_nfs_version);
|
||||
#ifdef HAVE_FS_NFS3
|
||||
if (fp->fh_nfs_version == NFS_VERSION3)
|
||||
error = fp->fh_error = unx_error(fp->fh_nfs_handle.v3.fhs_status);
|
||||
else
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
error = fp->fh_error = unx_error(fp->fh_nfs_handle.v2.fhs_status);
|
||||
if (error == 0) {
|
||||
if (fhbuf) {
|
||||
#ifdef HAVE_FS_NFS3
|
||||
if (fp->fh_nfs_version == NFS_VERSION3)
|
||||
memmove((voidp) &(fhbuf->v3), (voidp) &(fp->fh_nfs_handle.v3),
|
||||
sizeof(fp->fh_nfs_handle.v3));
|
||||
else
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
memmove((voidp) &(fhbuf->v2), (voidp) &(fp->fh_nfs_handle.v2),
|
||||
sizeof(fp->fh_nfs_handle.v2));
|
||||
}
|
||||
if (fp->fh_cid)
|
||||
untimeout(fp->fh_cid);
|
||||
fp->fh_cid = timeout(FH_TTL, discard_fh, (voidp) fp);
|
||||
} else if (error == EACCES) {
|
||||
/*
|
||||
* Now decode the file handle return code.
|
||||
*/
|
||||
plog(XLOG_INFO, "Filehandle denied for \"%s:%s\"",
|
||||
fs->fs_host, path);
|
||||
} else {
|
||||
errno = error; /* XXX */
|
||||
plog(XLOG_INFO, "Filehandle error for \"%s:%s\": %m",
|
||||
fs->fs_host, path);
|
||||
}
|
||||
|
||||
/*
|
||||
* The error was returned from the remote mount daemon.
|
||||
* Policy: this error will be cached for now...
|
||||
*/
|
||||
return error;
|
||||
|
||||
case -1:
|
||||
/*
|
||||
* Still thinking about it, but we can re-use.
|
||||
*/
|
||||
fp_save = fp;
|
||||
reuse_id = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* Return the error.
|
||||
* Policy: make sure we recompute if required again
|
||||
* in case this was caused by a network failure.
|
||||
* This can thrash mountd's though... If you find
|
||||
* your mountd going slowly then:
|
||||
* 1. Add a fork() loop to main.
|
||||
* 2. Remove the call to innetgr() and don't use
|
||||
* netgroups, especially if you don't use YP.
|
||||
*/
|
||||
error = fp->fh_error;
|
||||
fp->fh_error = -1;
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Not in cache
|
||||
*/
|
||||
if (fp_save) {
|
||||
fp = fp_save;
|
||||
/*
|
||||
* Re-use existing slot
|
||||
*/
|
||||
untimeout(fp->fh_cid);
|
||||
free_srvr(fp->fh_fs);
|
||||
XFREE(fp->fh_path);
|
||||
} else {
|
||||
fp = ALLOC(struct fh_cache);
|
||||
memset((voidp) fp, 0, sizeof(struct fh_cache));
|
||||
ins_que(&fp->fh_q, &fh_head);
|
||||
}
|
||||
if (!reuse_id)
|
||||
fp->fh_id = FHID_ALLOC(struct );
|
||||
fp->fh_wchan = wchan;
|
||||
fp->fh_error = -1;
|
||||
fp->fh_cid = timeout(FH_TTL, discard_fh, (voidp) fp);
|
||||
|
||||
/*
|
||||
* if fs->fs_ip is null, remote server is probably down.
|
||||
*/
|
||||
if (!fs->fs_ip) {
|
||||
/* Mark the fileserver down and invalid again */
|
||||
fs->fs_flags &= ~FSF_VALID;
|
||||
fs->fs_flags |= FSF_DOWN;
|
||||
error = AM_ERRNO_HOST_DOWN;
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the address has changed then don't try to re-use the
|
||||
* port information
|
||||
*/
|
||||
if (fp->fh_sin.sin_addr.s_addr != fs->fs_ip->sin_addr.s_addr) {
|
||||
fp->fh_sin = *fs->fs_ip;
|
||||
fp->fh_sin.sin_port = 0;
|
||||
fp->fh_nfs_version = fs->fs_version;
|
||||
}
|
||||
fp->fh_fs = dup_srvr(fs);
|
||||
fp->fh_path = strdup(path);
|
||||
|
||||
error = call_mountd(fp, MOUNTPROC_MNT, got_nfs_fh, wchan);
|
||||
if (error) {
|
||||
/*
|
||||
* Local error - cache for a short period
|
||||
* just to prevent thrashing.
|
||||
*/
|
||||
untimeout(fp->fh_cid);
|
||||
fp->fh_cid = timeout(error < 0 ? 2 * ALLOWED_MOUNT_TIME : FH_TTL_ERROR,
|
||||
discard_fh, (voidp) fp);
|
||||
fp->fh_error = error;
|
||||
} else {
|
||||
error = fp->fh_error;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
make_nfs_auth(void)
|
||||
{
|
||||
AUTH_CREATE_GIDLIST_TYPE group_wheel = 0;
|
||||
|
||||
/* Some NFS mounts (particularly cross-domain) require FQDNs to succeed */
|
||||
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
if (gopt.flags & CFM_FULLY_QUALIFIED_HOSTS) {
|
||||
plog(XLOG_INFO, "Using NFS auth for fqhn \"%s\"", hostd);
|
||||
nfs_auth = authsys_create(hostd, 0, 0, 1, &group_wheel);
|
||||
} else {
|
||||
nfs_auth = authsys_create_default();
|
||||
}
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
if (gopt.flags & CFM_FULLY_QUALIFIED_HOSTS) {
|
||||
plog(XLOG_INFO, "Using NFS auth for fqhn \"%s\"", hostd);
|
||||
nfs_auth = authunix_create(hostd, 0, 0, 1, &group_wheel);
|
||||
} else {
|
||||
nfs_auth = authunix_create_default();
|
||||
}
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
if (!nfs_auth)
|
||||
return ENOBUFS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
call_mountd(fh_cache *fp, u_long proc, fwd_fun f, voidp wchan)
|
||||
{
|
||||
struct rpc_msg mnt_msg;
|
||||
int len;
|
||||
char iobuf[8192];
|
||||
int error;
|
||||
u_long mnt_version;
|
||||
|
||||
if (!nfs_auth) {
|
||||
error = make_nfs_auth();
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
if (fp->fh_sin.sin_port == 0) {
|
||||
u_short port;
|
||||
error = nfs_srvr_port(fp->fh_fs, &port, wchan);
|
||||
if (error)
|
||||
return error;
|
||||
fp->fh_sin.sin_port = port;
|
||||
}
|
||||
|
||||
/* find the right version of the mount protocol */
|
||||
#ifdef HAVE_FS_NFS3
|
||||
if (fp->fh_nfs_version == NFS_VERSION3)
|
||||
mnt_version = MOUNTVERS3;
|
||||
else
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
mnt_version = MOUNTVERS;
|
||||
plog(XLOG_INFO, "call_mountd: NFS version %d, mount version %d",
|
||||
fp->fh_nfs_version, mnt_version);
|
||||
|
||||
rpc_msg_init(&mnt_msg, MOUNTPROG, mnt_version, MOUNTPROC_NULL);
|
||||
len = make_rpc_packet(iobuf,
|
||||
sizeof(iobuf),
|
||||
proc,
|
||||
&mnt_msg,
|
||||
(voidp) &fp->fh_path,
|
||||
(XDRPROC_T_TYPE) xdr_nfspath,
|
||||
nfs_auth);
|
||||
|
||||
if (len > 0) {
|
||||
error = fwd_packet(MK_RPC_XID(RPC_XID_MOUNTD, fp->fh_id),
|
||||
(voidp) iobuf,
|
||||
len,
|
||||
&fp->fh_sin,
|
||||
&fp->fh_sin,
|
||||
(voidp) ((long) fp->fh_id), /* for 64-bit archs */
|
||||
f);
|
||||
} else {
|
||||
error = -len;
|
||||
}
|
||||
|
||||
/*
|
||||
* It may be the case that we're sending to the wrong MOUNTD port. This
|
||||
* occurs if mountd is restarted on the server after the port has been
|
||||
* looked up and stored in the filehandle cache somewhere. The correct
|
||||
* solution, if we're going to cache port numbers is to catch the ICMP
|
||||
* port unreachable reply from the server and cause the portmap request
|
||||
* to be redone. The quick solution here is to invalidate the MOUNTD
|
||||
* port.
|
||||
*/
|
||||
fp->fh_sin.sin_port = 0;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* NFS needs the local filesystem, remote filesystem
|
||||
* remote hostname.
|
||||
* Local filesystem defaults to remote and vice-versa.
|
||||
*/
|
||||
char *
|
||||
nfs_match(am_opts *fo)
|
||||
{
|
||||
char *xmtab;
|
||||
|
||||
if (fo->opt_fs && !fo->opt_rfs)
|
||||
fo->opt_rfs = fo->opt_fs;
|
||||
if (!fo->opt_rfs) {
|
||||
plog(XLOG_USER, "nfs: no remote filesystem specified");
|
||||
return NULL;
|
||||
}
|
||||
if (!fo->opt_rhost) {
|
||||
plog(XLOG_USER, "nfs: no remote host specified");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine magic cookie to put in mtab
|
||||
*/
|
||||
xmtab = (char *) xmalloc(strlen(fo->opt_rhost) + strlen(fo->opt_rfs) + 2);
|
||||
sprintf(xmtab, "%s:%s", 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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize am structure for nfs
|
||||
*/
|
||||
int
|
||||
nfs_init(mntfs *mf)
|
||||
{
|
||||
int error;
|
||||
am_nfs_handle_t fhs;
|
||||
char *colon;
|
||||
|
||||
if (mf->mf_private)
|
||||
return 0;
|
||||
|
||||
colon = strchr(mf->mf_info, ':');
|
||||
if (colon == 0)
|
||||
return ENOENT;
|
||||
|
||||
error = prime_nfs_fhandle_cache(colon + 1, mf->mf_server, &fhs, (voidp) mf);
|
||||
if (!error) {
|
||||
mf->mf_private = (voidp) ALLOC(am_nfs_handle_t);
|
||||
mf->mf_prfree = (void (*)(voidp)) free;
|
||||
memmove(mf->mf_private, (voidp) &fhs, sizeof(fhs));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mount_nfs_fh(am_nfs_handle_t *fhp, char *dir, char *fs_name, char *opts, mntfs *mf)
|
||||
{
|
||||
MTYPE_TYPE type;
|
||||
char *colon;
|
||||
char *xopts;
|
||||
char host[MAXHOSTNAMELEN + MAXPATHLEN + 2];
|
||||
fserver *fs = mf->mf_server;
|
||||
u_long nfs_version = fs->fs_version;
|
||||
char *nfs_proto = fs->fs_proto; /* "tcp" or "udp" */
|
||||
int error;
|
||||
int genflags;
|
||||
int retry;
|
||||
mntent_t mnt;
|
||||
nfs_args_t nfs_args;
|
||||
|
||||
/*
|
||||
* Extract HOST name to give to kernel.
|
||||
* Some systems like osf1/aix3/bsd44 variants may need old code
|
||||
* for NFS_ARGS_NEEDS_PATH.
|
||||
*/
|
||||
if (!(colon = strchr(fs_name, ':')))
|
||||
return ENOENT;
|
||||
#ifdef MOUNT_TABLE_ON_FILE
|
||||
*colon = '\0';
|
||||
#endif /* MOUNT_TABLE_ON_FILE */
|
||||
strncpy(host, fs_name, sizeof(host));
|
||||
#ifdef MOUNT_TABLE_ON_FILE
|
||||
*colon = ':';
|
||||
#endif /* MOUNT_TABLE_ON_FILE */
|
||||
#ifdef MAXHOSTNAMELEN
|
||||
/* most kernels have a name length restriction */
|
||||
if (strlen(host) >= MAXHOSTNAMELEN)
|
||||
strcpy(host + MAXHOSTNAMELEN - 3, "..");
|
||||
#endif /* MAXHOSTNAMELEN */
|
||||
|
||||
if (mf->mf_remopts && *mf->mf_remopts && !islocalnet(fs->fs_ip->sin_addr.s_addr))
|
||||
xopts = strdup(mf->mf_remopts);
|
||||
else
|
||||
xopts = strdup(opts);
|
||||
|
||||
memset((voidp) &mnt, 0, sizeof(mnt));
|
||||
mnt.mnt_dir = dir;
|
||||
mnt.mnt_fsname = fs_name;
|
||||
mnt.mnt_opts = xopts;
|
||||
|
||||
/*
|
||||
* Set mount types accordingly
|
||||
*/
|
||||
#ifndef HAVE_FS_NFS3
|
||||
type = MOUNT_TYPE_NFS;
|
||||
mnt.mnt_type = MNTTAB_TYPE_NFS;
|
||||
#else /* HAVE_FS_NFS3 */
|
||||
if (nfs_version == NFS_VERSION3) {
|
||||
type = MOUNT_TYPE_NFS3;
|
||||
/*
|
||||
* Systems that include the mount table "vers" option generally do not
|
||||
* set the mnttab entry to "nfs3", but to "nfs" and then they set
|
||||
* "vers=3". Setting it to "nfs3" works, but it may break some things
|
||||
* like "df -t nfs" and the "quota" program (esp. on Solaris and Irix).
|
||||
* So on those systems, set it to "nfs".
|
||||
* Note: MNTTAB_OPT_VERS is always set for NFS3 (see am_compat.h).
|
||||
*/
|
||||
# if defined(MNTTAB_OPT_VERS) && defined(MOUNT_TABLE_ON_FILE)
|
||||
mnt.mnt_type = MNTTAB_TYPE_NFS;
|
||||
# else /* defined(MNTTAB_OPT_VERS) && defined(MOUNT_TABLE_ON_FILE) */
|
||||
mnt.mnt_type = MNTTAB_TYPE_NFS3;
|
||||
# endif /* defined(MNTTAB_OPT_VERS) && defined(MOUNT_TABLE_ON_FILE) */
|
||||
} else {
|
||||
type = MOUNT_TYPE_NFS;
|
||||
mnt.mnt_type = MNTTAB_TYPE_NFS;
|
||||
}
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
plog(XLOG_INFO, "mount_nfs_fh: NFS version %d", nfs_version);
|
||||
#if defined(HAVE_FS_NFS3) || defined(HAVE_TRANSPORT_TYPE_TLI)
|
||||
plog(XLOG_INFO, "mount_nfs_fh: using NFS transport %s", nfs_proto);
|
||||
#endif /* defined(HAVE_FS_NFS3) || defined(HAVE_TRANSPORT_TYPE_TLI) */
|
||||
|
||||
retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
|
||||
if (retry <= 0)
|
||||
retry = 1; /* XXX */
|
||||
|
||||
genflags = compute_mount_flags(&mnt);
|
||||
|
||||
/* setup the many fields and flags within nfs_args */
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
compute_nfs_args(&nfs_args,
|
||||
&mnt,
|
||||
genflags,
|
||||
NULL, /* struct netconfig *nfsncp */
|
||||
fs->fs_ip,
|
||||
nfs_version,
|
||||
nfs_proto,
|
||||
fhp,
|
||||
host,
|
||||
fs_name);
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
compute_nfs_args(&nfs_args,
|
||||
&mnt,
|
||||
genflags,
|
||||
fs->fs_ip,
|
||||
nfs_version,
|
||||
nfs_proto,
|
||||
fhp,
|
||||
host,
|
||||
fs_name);
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
/* finally call the mounting function */
|
||||
#ifdef DEBUG
|
||||
amuDebug(D_TRACE)
|
||||
print_nfs_args(&nfs_args, nfs_version);
|
||||
#endif /* DEBUG */
|
||||
error = mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type,
|
||||
nfs_version, nfs_proto, mnttab_file_name);
|
||||
XFREE(xopts);
|
||||
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
free_knetconfig(nfs_args.knconf);
|
||||
if (nfs_args.addr)
|
||||
XFREE(nfs_args.addr); /* allocated in compute_nfs_args() */
|
||||
#endif /* HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
mount_nfs(char *dir, char *fs_name, char *opts, mntfs *mf)
|
||||
{
|
||||
if (!mf->mf_private) {
|
||||
plog(XLOG_ERROR, "Missing filehandle for %s", fs_name);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return mount_nfs_fh((am_nfs_handle_t *) mf->mf_private, dir, fs_name, opts, mf);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nfs_fmount(mntfs *mf)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
error = mount_nfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, mf);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (error) {
|
||||
errno = error;
|
||||
dlog("mount_nfs: %m");
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nfs_fumount(mntfs *mf)
|
||||
{
|
||||
int error = UMOUNT_FS(mf->mf_mount, mnttab_file_name);
|
||||
|
||||
/*
|
||||
* Here is some code to unmount 'restarted' file systems.
|
||||
* The restarted file systems are marked as 'nfs', not
|
||||
* 'host', so we only have the map information for the
|
||||
* the top-level mount. The unmount will fail (EBUSY)
|
||||
* if there are anything else from the NFS server mounted
|
||||
* below the mount-point. This code checks to see if there
|
||||
* is anything mounted with the same prefix as the
|
||||
* file system to be unmounted ("/a/b/c" when unmounting "/a/b").
|
||||
* If there is, and it is a 'restarted' file system, we unmount
|
||||
* it.
|
||||
* Added by Mike Mitchell, mcm@unx.sas.com, 09/08/93
|
||||
*/
|
||||
if (error == EBUSY) {
|
||||
mntfs *new_mf;
|
||||
int len = strlen(mf->mf_mount);
|
||||
int didsome = 0;
|
||||
|
||||
ITER(new_mf, mntfs, &mfhead) {
|
||||
if (new_mf->mf_ops != mf->mf_ops ||
|
||||
new_mf->mf_refc > 1 ||
|
||||
mf == new_mf ||
|
||||
((new_mf->mf_flags & (MFF_MOUNTED | MFF_UNMOUNTING | MFF_RESTART)) == (MFF_MOUNTED | MFF_RESTART)))
|
||||
continue;
|
||||
|
||||
if (NSTREQ(mf->mf_mount, new_mf->mf_mount, len) &&
|
||||
new_mf->mf_mount[len] == '/') {
|
||||
UMOUNT_FS(new_mf->mf_mount, mnttab_file_name);
|
||||
didsome = 1;
|
||||
}
|
||||
}
|
||||
if (didsome)
|
||||
error = UMOUNT_FS(mf->mf_mount, mnttab_file_name);
|
||||
}
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nfs_umounted(am_node *mp)
|
||||
{
|
||||
/*
|
||||
* Don't bother to inform remote mountd that we are finished. Until a
|
||||
* full track of filehandles is maintained the mountd unmount callback
|
||||
* cannot be done correctly anyway...
|
||||
*/
|
||||
mntfs *mf = mp->am_mnt;
|
||||
fserver *fs;
|
||||
char *colon, *path;
|
||||
|
||||
if (mf->mf_error || mf->mf_refc > 1)
|
||||
return;
|
||||
|
||||
fs = mf->mf_server;
|
||||
|
||||
/*
|
||||
* Call the mount daemon on the server to announce that we are not using
|
||||
* the fs any more.
|
||||
*
|
||||
* This is *wrong*. The mountd should be called when the fhandle is
|
||||
* flushed from the cache, and a reference held to the cached entry while
|
||||
* the fs is mounted...
|
||||
*/
|
||||
colon = path = strchr(mf->mf_info, ':');
|
||||
if (fs && colon) {
|
||||
fh_cache f;
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("calling mountd for %s", mf->mf_info);
|
||||
#endif /* DEBUG */
|
||||
*path++ = '\0';
|
||||
f.fh_path = path;
|
||||
f.fh_sin = *fs->fs_ip;
|
||||
f.fh_sin.sin_port = (u_short) 0;
|
||||
f.fh_nfs_version = fs->fs_version;
|
||||
f.fh_fs = fs;
|
||||
f.fh_id = 0;
|
||||
f.fh_error = 0;
|
||||
prime_nfs_fhandle_cache(colon + 1, mf->mf_server, (am_nfs_handle_t *) 0, (voidp) mf);
|
||||
call_mountd(&f, MOUNTPROC_UMNT, (fwd_fun) 0, (voidp) 0);
|
||||
*colon = ':';
|
||||
}
|
||||
}
|
55
contrib/amd/amd/ops_nfs3.c
Normal file
55
contrib/amd/amd/ops_nfs3.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 5.2.2.3 1992/08/02 10:42:21 jsp 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... :-) */
|
55
contrib/amd/amd/ops_nullfs.c
Normal file
55
contrib/amd/amd/ops_nullfs.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_nullfs.c,v 5.2.2.3 1992/08/02 10:42:21 jsp Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The null filesystem in BSD-4.4 is similar to the loopback one.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* FEEL FREE TO INPLEMENT THIS... :-) */
|
179
contrib/amd/amd/ops_pcfs.c
Normal file
179
contrib/amd/amd/ops_pcfs.c
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 5.2.2.1 1992/02/09 15:09:08 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
amfs_auto_fmount,
|
||||
pcfs_fmount,
|
||||
amfs_auto_fumount,
|
||||
pcfs_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* pcfs_readlink */
|
||||
0, /* pcfs_mounted */
|
||||
0, /* pcfs_umounted */
|
||||
find_amfs_auto_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
|
||||
*/
|
||||
memset((voidp) &mnt, 0, sizeof(mnt));
|
||||
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_MASK
|
||||
pcfs_args.mask = 0777; /* this may be the msdos file modes */
|
||||
#endif /* HAVE_FIELD_PCFS_ARGS_T_MASK */
|
||||
|
||||
#ifdef HAVE_FIELD_PCFS_ARGS_T_UID
|
||||
pcfs_args.uid = 0; /* root */
|
||||
#endif /* HAVE_FIELD_PCFS_ARGS_T_UID */
|
||||
|
||||
#ifdef HAVE_FIELD_PCFS_ARGS_T_GID
|
||||
pcfs_args.gid = 0; /* wheel */
|
||||
#endif /* HAVE_FIELD_PCFS_ARGS_T_GID */
|
||||
|
||||
#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, mnttab_file_name);
|
||||
}
|
||||
|
||||
|
||||
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, mnttab_file_name);
|
||||
}
|
55
contrib/amd/amd/ops_tfs.c
Normal file
55
contrib/amd/amd/ops_tfs.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_tfs.c,v 5.2.2.3 1992/08/02 10:42:21 jsp Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Translucent file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* FEEL FREE TO INPLEMENT THIS... :-) */
|
55
contrib/amd/amd/ops_tmpfs.c
Normal file
55
contrib/amd/amd/ops_tmpfs.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_tmpfs.c,v 5.2.2.3 1992/08/02 10:42:21 jsp Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* TMPFS file system (combines RAM-fs and swap-fs)
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* FEEL FREE TO INPLEMENT THIS... :-) */
|
173
contrib/amd/amd/ops_ufs.c
Normal file
173
contrib/amd/amd/ops_ufs.c
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 5.2.2.1 1992/02/09 15:09:08 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* UN*X file system
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* forward declarations */
|
||||
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 */
|
||||
amfs_auto_fmount,
|
||||
ufs_fmount,
|
||||
amfs_auto_fumount,
|
||||
ufs_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* ufs_readlink */
|
||||
0, /* ufs_mounted */
|
||||
0, /* ufs_umounted */
|
||||
find_amfs_auto_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 genflags;
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
memset((voidp) &mnt, 0, sizeof(mnt));
|
||||
mnt.mnt_dir = dir;
|
||||
mnt.mnt_fsname = fs_name;
|
||||
mnt.mnt_type = MNTTAB_TYPE_UFS;
|
||||
mnt.mnt_opts = opts;
|
||||
|
||||
genflags = compute_mount_flags(&mnt);
|
||||
|
||||
#ifdef HAVE_FIELD_UFS_ARGS_T_FLAGS
|
||||
ufs_args.flags = genflags; /* XXX: is this correct? */
|
||||
#endif /* HAVE_FIELD_UFS_ARGS_T_FLAGS */
|
||||
|
||||
#ifdef HAVE_FIELD_UFS_ARGS_T_UFS_FLAGS
|
||||
ufs_args.ufs_flags = genflags; /* XXX: is this correct? */
|
||||
#endif /* HAVE_FIELD_UFS_ARGS_T_UFS_FLAGS */
|
||||
|
||||
#ifdef HAVE_FIELD_UFS_ARGS_T_FSPEC
|
||||
ufs_args.fspec = fs_name;
|
||||
#endif /* HAVE_FIELD_UFS_ARGS_T_FSPEC */
|
||||
|
||||
#ifdef HAVE_FIELD_UFS_ARGS_T_UFS_PGTHRESH
|
||||
ufs_args.ufs_pgthresh = hasmntval(&mnt, MNTTAB_OPT_PGTHRESH);
|
||||
#endif /* HAVE_FIELD_UFS_ARGS_T_UFS_PGTHRESH */
|
||||
|
||||
/*
|
||||
* Call generic mount routine
|
||||
*/
|
||||
return mount_fs(&mnt, genflags, (caddr_t) &ufs_args, 0, type, 0, NULL, mnttab_file_name);
|
||||
}
|
||||
|
||||
|
||||
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, mnttab_file_name);
|
||||
}
|
55
contrib/amd/amd/ops_umapfs.c
Normal file
55
contrib/amd/amd/ops_umapfs.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_umapfs.c,v 5.2.2.3 1992/08/02 10:42:21 jsp Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* uid/gid mapping filesystem.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* FEEL FREE TO INPLEMENT THIS... :-) */
|
55
contrib/amd/amd/ops_unionfs.c
Normal file
55
contrib/amd/amd/ops_unionfs.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_unionfs.c,v 5.2.2.3 1992/08/02 10:42:21 jsp Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Union filesystem (ala BSD-4.4)
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* FEEL FREE TO INPLEMENT THIS... :-) */
|
164
contrib/amd/amd/ops_xfs.c
Normal file
164
contrib/amd/amd/ops_xfs.c
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_xfs.c,v 5.2.2.1 1992/02/09 15:09:08 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Irix UN*X file system: XFS (Extended File System)
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* forward declarations */
|
||||
static char * xfs_match(am_opts *fo);
|
||||
static int xfs_fmount(mntfs *mf);
|
||||
static int xfs_fumount(mntfs *mf);
|
||||
|
||||
/*
|
||||
* Ops structure
|
||||
*/
|
||||
am_ops xfs_ops =
|
||||
{
|
||||
"xfs",
|
||||
xfs_match,
|
||||
0, /* xfs_init */
|
||||
amfs_auto_fmount,
|
||||
xfs_fmount,
|
||||
amfs_auto_fumount,
|
||||
xfs_fumount,
|
||||
amfs_error_lookuppn,
|
||||
amfs_error_readdir,
|
||||
0, /* xfs_readlink */
|
||||
0, /* xfs_mounted */
|
||||
0, /* xfs_umounted */
|
||||
find_amfs_auto_srvr,
|
||||
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* XFS needs local filesystem and device.
|
||||
*/
|
||||
static char *
|
||||
xfs_match(am_opts *fo)
|
||||
{
|
||||
|
||||
if (!fo->opt_dev) {
|
||||
plog(XLOG_USER, "xfs: no device specified");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("XFS: 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_xfs(char *dir, char *fs_name, char *opts)
|
||||
{
|
||||
xfs_args_t xfs_args;
|
||||
mntent_t mnt;
|
||||
int flags;
|
||||
|
||||
/*
|
||||
* Figure out the name of the file system type.
|
||||
*/
|
||||
MTYPE_TYPE type = MOUNT_TYPE_XFS;
|
||||
|
||||
memset((voidp) &xfs_args, 0, sizeof(xfs_args)); /* Paranoid */
|
||||
|
||||
/*
|
||||
* Fill in the mount structure
|
||||
*/
|
||||
memset((voidp) &mnt, 0, sizeof(mnt));
|
||||
mnt.mnt_dir = dir;
|
||||
mnt.mnt_fsname = fs_name;
|
||||
mnt.mnt_type = MNTTAB_TYPE_XFS;
|
||||
mnt.mnt_opts = opts;
|
||||
|
||||
flags = compute_mount_flags(&mnt);
|
||||
|
||||
#ifdef HAVE_FIELD_XFS_ARGS_T_FLAGS
|
||||
xfs_args.flags = 0; /* XXX: fix this to correct flags */
|
||||
#endif /* HAVE_FIELD_XFS_ARGS_T_FLAGS */
|
||||
#ifdef HAVE_FIELD_XFS_ARGS_T_FSPEC
|
||||
xfs_args.fspec = fs_name;
|
||||
#endif /* HAVE_FIELD_XFS_ARGS_T_FSPEC */
|
||||
|
||||
/*
|
||||
* Call generic mount routine
|
||||
*/
|
||||
return mount_fs(&mnt, flags, (caddr_t) &xfs_args, 0, type, 0, NULL, mnttab_file_name);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
xfs_fmount(mntfs *mf)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = mount_xfs(mf->mf_mount, mf->mf_info, mf->mf_mopts);
|
||||
if (error) {
|
||||
errno = error;
|
||||
plog(XLOG_ERROR, "mount_xfs: %m");
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
xfs_fumount(mntfs *mf)
|
||||
{
|
||||
return UMOUNT_FS(mf->mf_mount, mnttab_file_name);
|
||||
}
|
1304
contrib/amd/amd/opts.c
Normal file
1304
contrib/amd/amd/opts.c
Normal file
File diff suppressed because it is too large
Load Diff
208
contrib/amd/amd/restart.c
Normal file
208
contrib/amd/amd/restart.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: restart.c,v 5.2.2.2 1992/08/02 10:42:21 jsp Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
|
||||
/*
|
||||
* Handle an amd restart.
|
||||
*
|
||||
* Scan through the mount list finding all "interesting" mount points.
|
||||
* Next hack up partial data structures and add the mounted file
|
||||
* system to the list of known filesystems. This will leave a
|
||||
* dangling reference to that filesystems, so when the filesystem is
|
||||
* finally inherited, an extra "free" must be done on it.
|
||||
*
|
||||
* This module relies on internal details of other components. If
|
||||
* you change something else make *sure* restart() still works.
|
||||
*/
|
||||
void
|
||||
restart(void)
|
||||
{
|
||||
/*
|
||||
* Read the existing mount table
|
||||
*/
|
||||
mntlist *ml, *mlp;
|
||||
|
||||
/*
|
||||
* For each entry, find nfs, ufs or auto mounts
|
||||
* and create a partial am_node to represent it.
|
||||
*/
|
||||
for (mlp = ml = read_mtab("restart", mnttab_file_name);
|
||||
mlp;
|
||||
mlp = mlp->mnext) {
|
||||
mntent_t *me = mlp->mnt;
|
||||
am_ops *fs_ops = 0;
|
||||
if (STREQ(me->mnt_type, MNTTAB_TYPE_UFS)) {
|
||||
/*
|
||||
* UFS entry
|
||||
*/
|
||||
fs_ops = &ufs_ops;
|
||||
} else if (STREQ(me->mnt_type, MNTTAB_TYPE_NFS)) {
|
||||
/*
|
||||
* NFS entry, or possibly an Amd entry...
|
||||
* The mnt_fsname for daemon mount points is
|
||||
* host:(pidXXX)
|
||||
* or (seen on Solaris)
|
||||
* host:daemon(pidXXX)
|
||||
*/
|
||||
char *colon = strchr(me->mnt_fsname, ':');
|
||||
|
||||
if (colon && strstr(colon, "(pid")) {
|
||||
plog(XLOG_WARNING, "%s is an existing automount point", me->mnt_dir);
|
||||
fs_ops = &amfs_link_ops;
|
||||
} else {
|
||||
fs_ops = &nfs_ops;
|
||||
}
|
||||
#ifdef MNTTAB_TYPE_NFS3
|
||||
} else if (STREQ(me->mnt_type, MNTTAB_TYPE_NFS3)) {
|
||||
fs_ops = &nfs_ops;
|
||||
#endif /* MNTTAB_TYPE_NFS3 */
|
||||
#ifdef MNTTAB_TYPE_LOFS
|
||||
} else if (STREQ(me->mnt_type, MNTTAB_TYPE_LOFS)) {
|
||||
fs_ops = &lofs_ops;
|
||||
#endif /* MNTTAB_TYPE_LOFS */
|
||||
#ifdef MNTTAB_TYPE_CDFS
|
||||
} else if (STREQ(me->mnt_type, MNTTAB_TYPE_CDFS)) {
|
||||
fs_ops = &cdfs_ops;
|
||||
#endif /* MNTTAB_TYPE_CDFS */
|
||||
#ifdef MNTTAB_TYPE_PCFS
|
||||
} else if (STREQ(me->mnt_type, MNTTAB_TYPE_PCFS)) {
|
||||
fs_ops = &pcfs_ops;
|
||||
#endif /* MNTTAB_TYPE_PCFS */
|
||||
#ifdef MNTTAB_TYPE_MFS
|
||||
} else if (STREQ(me->mnt_type, MNTTAB_TYPE_MFS)) {
|
||||
/*
|
||||
* MFS entry. Fake with a symlink.
|
||||
*/
|
||||
fs_ops = &amfs_link_ops;
|
||||
#endif /* MNTTAB_TYPE_MFS */
|
||||
} else {
|
||||
/*
|
||||
* Catch everything else with symlinks to
|
||||
* avoid recursive mounts. This is debatable...
|
||||
*/
|
||||
fs_ops = &amfs_link_ops;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we found something to do
|
||||
*/
|
||||
if (fs_ops) {
|
||||
mntfs *mf;
|
||||
am_opts mo;
|
||||
char *cp;
|
||||
cp = strchr(me->mnt_fsname, ':');
|
||||
|
||||
/*
|
||||
* Partially fake up an opts structure
|
||||
*/
|
||||
mo.opt_rhost = 0;
|
||||
mo.opt_rfs = 0;
|
||||
if (cp) {
|
||||
*cp = '\0';
|
||||
mo.opt_rhost = strdup(me->mnt_fsname);
|
||||
mo.opt_rfs = strdup(cp + 1);
|
||||
*cp = ':';
|
||||
} else if (fs_ops->ffserver == find_nfs_srvr) {
|
||||
/*
|
||||
* Prototype 4.4 BSD used to end up here -
|
||||
* might as well keep the workaround for now
|
||||
*/
|
||||
plog(XLOG_WARNING, "NFS server entry assumed to be %s:/", me->mnt_fsname);
|
||||
mo.opt_rhost = strdup(me->mnt_fsname);
|
||||
mo.opt_rfs = strdup("/");
|
||||
me->mnt_fsname = str3cat(me->mnt_fsname, mo.opt_rhost, ":", "/");
|
||||
}
|
||||
mo.opt_fs = me->mnt_dir;
|
||||
mo.opt_opts = me->mnt_opts;
|
||||
|
||||
/*
|
||||
* Make a new mounted filesystem
|
||||
*/
|
||||
mf = find_mntfs(fs_ops, &mo, me->mnt_dir,
|
||||
me->mnt_fsname, "", me->mnt_opts, "");
|
||||
if (mf->mf_refc == 1) {
|
||||
mf->mf_flags |= MFF_RESTART | MFF_MOUNTED;
|
||||
mf->mf_error = 0; /* Already mounted correctly */
|
||||
mf->mf_fo = 0;
|
||||
/*
|
||||
* If the restarted type is a link then
|
||||
* don't time out.
|
||||
*/
|
||||
if (fs_ops == &amfs_link_ops || fs_ops == &ufs_ops)
|
||||
mf->mf_flags |= MFF_RSTKEEP;
|
||||
if (fs_ops->fs_init) {
|
||||
/*
|
||||
* Don't care whether this worked since
|
||||
* it is checked again when the fs is
|
||||
* inherited.
|
||||
*/
|
||||
(void) (*fs_ops->fs_init) (mf);
|
||||
}
|
||||
plog(XLOG_INFO, "%s restarted fstype %s on %s",
|
||||
me->mnt_fsname, fs_ops->fs_type, me->mnt_dir);
|
||||
} else {
|
||||
/* Something strange happened - two mounts at the same place! */
|
||||
free_mntfs(mf);
|
||||
}
|
||||
/*
|
||||
* Clean up mo
|
||||
*/
|
||||
if (mo.opt_rhost)
|
||||
XFREE(mo.opt_rhost);
|
||||
if (mo.opt_rfs)
|
||||
XFREE(mo.opt_rfs);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the mount list
|
||||
*/
|
||||
free_mntlist(ml);
|
||||
}
|
476
contrib/amd/amd/rpc_fwd.c
Normal file
476
contrib/amd/amd/rpc_fwd.c
Normal file
@ -0,0 +1,476 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: rpc_fwd.c,v 5.2.2.1 1992/02/09 15:09:01 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* RPC packet forwarding
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/*
|
||||
* Note that the ID field in the external packet is only
|
||||
* ever treated as a 32 bit opaque data object, so there
|
||||
* is no need to convert to and from network byte ordering.
|
||||
*/
|
||||
|
||||
#define XID_ALLOC(struct ) (xid++)
|
||||
#define MAX_PACKET_SIZE 8192 /* Maximum UDP packet size */
|
||||
|
||||
/*
|
||||
* Each pending reply has an rpc_forward structure
|
||||
* associated with it. These have a 15 second lifespan.
|
||||
* If a new structure is required, then an expired
|
||||
* one will be re-allocated if available, otherwise a fresh
|
||||
* one is allocated. Whenever a reply is received the
|
||||
* structure is discarded.
|
||||
*/
|
||||
typedef struct rpc_forward rpc_forward;
|
||||
struct rpc_forward {
|
||||
qelem rf_q; /* Linked list */
|
||||
time_t rf_ttl; /* Time to live */
|
||||
u_int rf_xid; /* Packet id */
|
||||
u_int rf_oldid; /* Original packet id */
|
||||
fwd_fun rf_fwd; /* Forwarding function */
|
||||
voidp rf_ptr;
|
||||
struct sockaddr_in rf_sin;
|
||||
};
|
||||
|
||||
/*
|
||||
* Head of list of pending replies
|
||||
*/
|
||||
qelem rpc_head = {&rpc_head, &rpc_head};
|
||||
int fwd_sock;
|
||||
static u_int xid;
|
||||
|
||||
|
||||
/*
|
||||
* Allocate a rely structure
|
||||
*/
|
||||
static rpc_forward *
|
||||
fwd_alloc(void)
|
||||
{
|
||||
time_t now = clocktime();
|
||||
rpc_forward *p = 0, *p2;
|
||||
|
||||
/*
|
||||
* First search for an existing expired one.
|
||||
*/
|
||||
ITER(p2, rpc_forward, &rpc_head) {
|
||||
if (p2->rf_ttl <= now) {
|
||||
p = p2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If one couldn't be found then allocate
|
||||
* a new structure and link it at the
|
||||
* head of the list.
|
||||
*/
|
||||
if (p) {
|
||||
/*
|
||||
* Call forwarding function to say that
|
||||
* this message was junked.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
dlog("Re-using packet forwarding slot - id %#x", p->rf_xid);
|
||||
#endif /* DEBUG */
|
||||
if (p->rf_fwd)
|
||||
(*p->rf_fwd) (0, 0, 0, &p->rf_sin, p->rf_ptr, FALSE);
|
||||
rem_que(&p->rf_q);
|
||||
} else {
|
||||
p = ALLOC(struct rpc_forward);
|
||||
}
|
||||
ins_que(&p->rf_q, &rpc_head);
|
||||
|
||||
/*
|
||||
* Set the time to live field
|
||||
* Timeout in 43 seconds
|
||||
*/
|
||||
p->rf_ttl = now + 43;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free an allocated reply structure.
|
||||
* First unlink it from the list, then
|
||||
* discard it.
|
||||
*/
|
||||
static void
|
||||
fwd_free(rpc_forward *p)
|
||||
{
|
||||
rem_que(&p->rf_q);
|
||||
XFREE(p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the RPC forwarder
|
||||
*/
|
||||
int
|
||||
fwd_init(void)
|
||||
{
|
||||
#ifdef FIONBIO
|
||||
int on = 1;
|
||||
#endif /* FIONBIO */
|
||||
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
/*
|
||||
* Create ping TLI socket (/dev/tcp and /dev/ticlts did not work)
|
||||
* (HPUX-11 does not like using O_NDELAY in flags)
|
||||
*/
|
||||
fwd_sock = t_open("/dev/udp", O_RDWR|O_NONBLOCK, 0);
|
||||
if (fwd_sock < 0) {
|
||||
plog(XLOG_ERROR, "unable to create RPC forwarding TLI socket: %s",
|
||||
t_errlist[t_errno]);
|
||||
return errno;
|
||||
}
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
/*
|
||||
* Create ping socket
|
||||
*/
|
||||
fwd_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fwd_sock < 0) {
|
||||
plog(XLOG_ERROR, "unable to create RPC forwarding socket: %m");
|
||||
return errno;
|
||||
}
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
/*
|
||||
* Some things we talk to require a priv port - so make one here
|
||||
*/
|
||||
if (bind_resv_port(fwd_sock, (u_short *) 0) < 0)
|
||||
plog(XLOG_ERROR, "can't bind privileged port");
|
||||
|
||||
if (fcntl(fwd_sock, F_SETFL, FNDELAY) < 0
|
||||
#ifdef FIONBIO
|
||||
&& ioctl(fwd_sock, FIONBIO, &on) < 0
|
||||
#endif /* FIONBIO */
|
||||
) {
|
||||
plog(XLOG_ERROR, "Can't set non-block on forwarding socket: %m");
|
||||
return errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Locate a packet in the forwarding list
|
||||
*/
|
||||
static rpc_forward *
|
||||
fwd_locate(u_int id)
|
||||
{
|
||||
rpc_forward *p;
|
||||
|
||||
ITER(p, rpc_forward, &rpc_head) {
|
||||
if (p->rf_xid == id)
|
||||
return p;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is called to forward a packet to another
|
||||
* RPC server. The message id is changed and noted
|
||||
* so that when a reply appears we can tie it up
|
||||
* correctly. Just matching the reply's source address
|
||||
* would not work because it might come from a
|
||||
* different address.
|
||||
*/
|
||||
int
|
||||
fwd_packet(int type_id, voidp pkt, int len, struct sockaddr_in *fwdto, struct sockaddr_in *replyto, voidp i, fwd_fun cb)
|
||||
{
|
||||
rpc_forward *p;
|
||||
u_int *pkt_int;
|
||||
int error;
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
struct t_unitdata ud;
|
||||
#endif /* HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
if ((int) amd_state >= (int) Finishing)
|
||||
return ENOENT;
|
||||
|
||||
/*
|
||||
* See if the type_id is fully specified.
|
||||
* If so, then discard any old entries
|
||||
* for this id.
|
||||
* Otherwise make sure the type_id is
|
||||
* fully qualified by allocating an id here.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
switch (type_id & RPC_XID_MASK) {
|
||||
case RPC_XID_PORTMAP:
|
||||
dlog("Sending PORTMAP request");
|
||||
break;
|
||||
case RPC_XID_MOUNTD:
|
||||
dlog("Sending MOUNTD request %#x", type_id);
|
||||
break;
|
||||
case RPC_XID_NFSPING:
|
||||
dlog("Sending NFS ping");
|
||||
break;
|
||||
default:
|
||||
dlog("UNKNOWN RPC XID");
|
||||
break;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (type_id & ~RPC_XID_MASK) {
|
||||
p = fwd_locate(type_id);
|
||||
if (p) {
|
||||
#ifdef DEBUG
|
||||
dlog("Discarding earlier rpc fwd handle");
|
||||
#endif /* DEBUG */
|
||||
fwd_free(p);
|
||||
}
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
dlog("Allocating a new xid...");
|
||||
#endif /* DEBUG */
|
||||
type_id = MK_RPC_XID(type_id, XID_ALLOC(struct ));
|
||||
}
|
||||
|
||||
p = fwd_alloc();
|
||||
if (!p)
|
||||
return ENOBUFS;
|
||||
|
||||
error = 0;
|
||||
|
||||
pkt_int = (u_int *) pkt;
|
||||
|
||||
/*
|
||||
* Get the original packet id
|
||||
*/
|
||||
p->rf_oldid = *pkt_int;
|
||||
|
||||
/*
|
||||
* Replace with newly allocated id
|
||||
*/
|
||||
p->rf_xid = *pkt_int = type_id;
|
||||
|
||||
/*
|
||||
* The sendto may fail if, for example, the route
|
||||
* to a remote host is lost because an intermediate
|
||||
* gateway has gone down. Important to fill in the
|
||||
* rest of "p" otherwise nasty things happen later...
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
{
|
||||
char dq[20];
|
||||
if (p && fwdto)
|
||||
dlog("Sending packet id %#x to %s.%d",
|
||||
p->rf_xid,
|
||||
inet_dquad(dq, fwdto->sin_addr.s_addr),
|
||||
ntohs(fwdto->sin_port));
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* if NULL, remote server probably down */
|
||||
if (!fwdto) {
|
||||
error = AM_ERRNO_HOST_DOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
ud.addr.buf = (char *) fwdto;
|
||||
if (fwdto) /* if NULL, set sizes to zero */
|
||||
ud.addr.maxlen = ud.addr.len = sizeof(struct sockaddr_in);
|
||||
else
|
||||
ud.addr.maxlen = ud.addr.len = 0;
|
||||
ud.opt.buf = (char *) NULL;
|
||||
ud.opt.maxlen = ud.opt.len = 0;
|
||||
ud.udata.buf = pkt;
|
||||
ud.udata.maxlen = ud.udata.len = len;
|
||||
if (t_sndudata(fwd_sock, &ud) < 0) {
|
||||
plog(XLOG_ERROR,"fwd_packet failed: t_errno=%d, errno=%d",t_errno,errno);
|
||||
error = errno;
|
||||
}
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
if (sendto(fwd_sock, (char *) pkt, len, 0,
|
||||
(struct sockaddr *) fwdto, sizeof(*fwdto)) < 0)
|
||||
error = errno;
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
/*
|
||||
* Save callback function and return address
|
||||
*/
|
||||
out:
|
||||
p->rf_fwd = cb;
|
||||
if (replyto)
|
||||
p->rf_sin = *replyto;
|
||||
else
|
||||
memset((voidp) &p->rf_sin, 0, sizeof(p->rf_sin));
|
||||
p->rf_ptr = i;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called when some data arrives on the forwarding socket
|
||||
*/
|
||||
void
|
||||
fwd_reply(void)
|
||||
{
|
||||
int len;
|
||||
u_int pkt[MAX_PACKET_SIZE / sizeof(u_int) + 1];
|
||||
u_int *pkt_int;
|
||||
int rc;
|
||||
rpc_forward *p;
|
||||
struct sockaddr_in src_addr;
|
||||
RECVFROM_FROMLEN_TYPE src_addr_len;
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
struct t_unitdata ud;
|
||||
int flags = 0;
|
||||
#endif /* HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
/*
|
||||
* Determine the length of the packet
|
||||
*/
|
||||
len = MAX_PACKET_SIZE;
|
||||
|
||||
/*
|
||||
* Read the packet and check for validity
|
||||
*/
|
||||
again:
|
||||
src_addr_len = sizeof(src_addr);
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
ud.addr.buf = (char *) &src_addr;
|
||||
ud.addr.maxlen = ud.addr.len = src_addr_len;
|
||||
ud.opt.buf = (char *) NULL;
|
||||
ud.opt.maxlen = ud.opt.len = 0;
|
||||
ud.udata.buf = (char *) pkt;
|
||||
ud.udata.maxlen = ud.udata.len = len;
|
||||
/* XXX: use flags accordingly such as if T_MORE set */
|
||||
rc = t_rcvudata(fwd_sock, &ud, &flags);
|
||||
if (rc == 0) /* success, reset rc to length */
|
||||
rc = ud.udata.len;
|
||||
else {
|
||||
plog(XLOG_ERROR,"fwd_reply failed: t_errno=%d, errno=%d, flags=%d",t_errno,errno, flags);
|
||||
}
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
rc = recvfrom(fwd_sock,
|
||||
(char *) pkt,
|
||||
len,
|
||||
0,
|
||||
(struct sockaddr *) &src_addr,
|
||||
&src_addr_len);
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
/*
|
||||
* XXX: in svr4, if the T_MORE bit of flags is set, what do
|
||||
* we then do? -Erez
|
||||
*/
|
||||
if (rc < 0 || src_addr_len != sizeof(src_addr) ||
|
||||
src_addr.sin_family != AF_INET) {
|
||||
if (rc < 0 && errno == EINTR)
|
||||
goto again;
|
||||
plog(XLOG_ERROR, "Error reading RPC reply: %m");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do no more work if finishing soon
|
||||
*/
|
||||
if ((int) amd_state >= (int) Finishing)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Find packet reference
|
||||
*/
|
||||
pkt_int = (u_int *) pkt;
|
||||
|
||||
#ifdef DEBUG
|
||||
switch (*pkt_int & RPC_XID_MASK) {
|
||||
case RPC_XID_PORTMAP:
|
||||
dlog("Receiving PORTMAP reply");
|
||||
break;
|
||||
case RPC_XID_MOUNTD:
|
||||
dlog("Receiving MOUNTD reply %#x", *pkt_int);
|
||||
break;
|
||||
case RPC_XID_NFSPING:
|
||||
dlog("Receiving NFS ping %#x", *pkt_int);
|
||||
break;
|
||||
default:
|
||||
dlog("UNKNOWN RPC XID");
|
||||
break;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
p = fwd_locate(*pkt_int);
|
||||
if (!p) {
|
||||
#ifdef DEBUG
|
||||
dlog("Can't forward reply id %#x", *pkt_int);
|
||||
#endif /* DEBUG */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (p->rf_fwd) {
|
||||
/*
|
||||
* Put the original message id back
|
||||
* into the packet.
|
||||
*/
|
||||
*pkt_int = p->rf_oldid;
|
||||
|
||||
/*
|
||||
* Call forwarding function
|
||||
*/
|
||||
(*p->rf_fwd) ((voidp) pkt, rc, &src_addr, &p->rf_sin, p->rf_ptr, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free forwarding info
|
||||
*/
|
||||
fwd_free(p);
|
||||
|
||||
out:;
|
||||
}
|
300
contrib/amd/amd/sched.c
Normal file
300
contrib/amd/amd/sched.c
Normal file
@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: sched.c,v 5.2.2.1 1992/02/09 15:09:02 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Process scheduler
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
|
||||
typedef struct pjob pjob;
|
||||
|
||||
struct pjob {
|
||||
qelem hdr; /* Linked list */
|
||||
int pid; /* Process ID of job */
|
||||
cb_fun cb_fun; /* Callback function */
|
||||
voidp cb_closure; /* Closure for callback */
|
||||
int w; /* everyone these days uses int, not a "union wait" */
|
||||
voidp wchan; /* Wait channel */
|
||||
};
|
||||
|
||||
/* globals */
|
||||
qelem proc_list_head = {&proc_list_head, &proc_list_head};
|
||||
qelem proc_wait_list = {&proc_wait_list, &proc_wait_list};
|
||||
int task_notify_todo;
|
||||
|
||||
|
||||
void
|
||||
ins_que(qelem *elem, qelem *pred)
|
||||
{
|
||||
qelem *p = pred->q_forw;
|
||||
|
||||
elem->q_back = pred;
|
||||
elem->q_forw = p;
|
||||
pred->q_forw = elem;
|
||||
p->q_back = elem;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rem_que(qelem *elem)
|
||||
{
|
||||
qelem *p = elem->q_forw;
|
||||
qelem *p2 = elem->q_back;
|
||||
|
||||
p2->q_forw = p;
|
||||
p->q_back = p2;
|
||||
}
|
||||
|
||||
|
||||
static pjob *
|
||||
sched_job(cb_fun cf, voidp ca)
|
||||
{
|
||||
pjob *p = ALLOC(struct pjob);
|
||||
|
||||
p->cb_fun = cf;
|
||||
p->cb_closure = ca;
|
||||
|
||||
/*
|
||||
* Now place on wait queue
|
||||
*/
|
||||
ins_que(&p->hdr, &proc_wait_list);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* tf: The task to execute (ta is its arguments)
|
||||
* cf: Continuation function (ca is its arguments)
|
||||
*/
|
||||
void
|
||||
run_task(task_fun tf, voidp ta, cb_fun cf, voidp ca)
|
||||
{
|
||||
pjob *p = sched_job(cf, ca);
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigset_t new, mask;
|
||||
#else /* not HAVE_SIGACTION */
|
||||
int mask;
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
p->wchan = (voidp) p;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigemptyset(&new); /* initialise signal set we wish to block */
|
||||
sigaddset(&new, SIGCHLD); /* only block on SIGCHLD */
|
||||
sigprocmask(SIG_BLOCK, &new, &mask);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
mask = sigblock(sigmask(SIGCHLD));
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
|
||||
if ((p->pid = background())) {
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigprocmask(SIG_SETMASK, &mask, NULL);
|
||||
#else /* not HAVE_SIGACTION */
|
||||
sigsetmask(mask);
|
||||
#endif /* not HAVE_SIGACTION */
|
||||
return;
|
||||
}
|
||||
|
||||
/* child code runs here, parent have returned to caller */
|
||||
|
||||
exit((*tf) (ta));
|
||||
/* firewall... */
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Schedule a task to be run when woken up
|
||||
*/
|
||||
void
|
||||
sched_task(cb_fun cf, voidp ca, voidp wchan)
|
||||
{
|
||||
/*
|
||||
* Allocate a new task
|
||||
*/
|
||||
pjob *p = sched_job(cf, ca);
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("SLEEP on %#x", wchan);
|
||||
#endif /* DEBUG */
|
||||
p->wchan = wchan;
|
||||
p->pid = 0;
|
||||
memset((voidp) &p->w, 0, sizeof(p->w));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wakeupjob(pjob *p)
|
||||
{
|
||||
rem_que(&p->hdr);
|
||||
ins_que(&p->hdr, &proc_list_head);
|
||||
task_notify_todo++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
wakeup(voidp wchan)
|
||||
{
|
||||
pjob *p, *p2;
|
||||
|
||||
if (!foreground)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Can't user ITER() here because
|
||||
* wakeupjob() juggles the list.
|
||||
*/
|
||||
for (p = AM_FIRST(pjob, &proc_wait_list);
|
||||
p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list);
|
||||
p = p2) {
|
||||
if (p->wchan == wchan) {
|
||||
wakeupjob(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
wakeup_task(int rc, int term, voidp cl)
|
||||
{
|
||||
wakeup(cl);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Run any pending tasks.
|
||||
* This must be called with SIGCHLD disabled
|
||||
*/
|
||||
void
|
||||
do_task_notify(void)
|
||||
{
|
||||
/*
|
||||
* Keep taking the first item off the list and processing it.
|
||||
*
|
||||
* Done this way because the the callback can, quite reasonably,
|
||||
* queue a new task, so no local reference into the list can be
|
||||
* held here.
|
||||
*/
|
||||
while (AM_FIRST(pjob, &proc_list_head) != HEAD(pjob, &proc_list_head)) {
|
||||
pjob *p = AM_FIRST(pjob, &proc_list_head);
|
||||
rem_que(&p->hdr);
|
||||
/*
|
||||
* This job has completed
|
||||
*/
|
||||
--task_notify_todo;
|
||||
|
||||
/*
|
||||
* Do callback if it exists
|
||||
*/
|
||||
if (p->cb_fun) {
|
||||
/* these two trigraphs will ensure compatibity with strict POSIX.1 */
|
||||
(*p->cb_fun) (WIFEXITED(p->w) ? WEXITSTATUS(p->w) : 0,
|
||||
WIFSIGNALED(p->w) ? WTERMSIG(p->w) : 0,
|
||||
p->cb_closure);
|
||||
}
|
||||
XFREE(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RETSIGTYPE
|
||||
sigchld(int sig)
|
||||
{
|
||||
int w; /* everyone these days uses int, not a "union wait" */
|
||||
int pid;
|
||||
|
||||
#ifdef HAVE_WAITPID
|
||||
while ((pid = waitpid((pid_t) -1, &w, WNOHANG)) > 0) {
|
||||
#else /* not HAVE_WAITPID */
|
||||
while ((pid = wait3( &w, WNOHANG, (struct rusage *) 0)) > 0) {
|
||||
#endif /* not HAVE_WAITPID */
|
||||
pjob *p, *p2;
|
||||
|
||||
if (WIFSIGNALED(w))
|
||||
plog(XLOG_ERROR, "Process %d exited with signal %d",
|
||||
pid, WTERMSIG(w));
|
||||
#ifdef DEBUG
|
||||
else
|
||||
dlog("Process %d exited with status %d",
|
||||
pid, WEXITSTATUS(w));
|
||||
#endif /* DEBUG */
|
||||
|
||||
for (p = AM_FIRST(pjob, &proc_wait_list);
|
||||
p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list);
|
||||
p = p2) {
|
||||
if (p->pid == pid) {
|
||||
p->w = w;
|
||||
wakeupjob(p);
|
||||
break;
|
||||
}
|
||||
} /* end of for loop */
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!p)
|
||||
dlog("can't locate task block for pid %d", pid);
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Must count down children inside the while loop, otherwise we won't
|
||||
* count them all, and NumChild (and later backoff) will be set
|
||||
* incorrectly. SH/RUNIT 940519.
|
||||
*/
|
||||
if (--NumChild < 0)
|
||||
NumChild = 0;
|
||||
} /* end of "while wait..." loop */
|
||||
|
||||
#ifdef REINSTALL_SIGNAL_HANDLER
|
||||
signal(sig, sigchld);
|
||||
#endif /* REINSTALL_SIGNAL_HANDLER */
|
||||
|
||||
if (select_intr_valid)
|
||||
longjmp(select_intr, sig);
|
||||
}
|
214
contrib/amd/amd/srvr_amfs_auto.c
Normal file
214
contrib/amd/amd/srvr_amfs_auto.c
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: srvr_amfs_auto.c,v 5.2.2.1 1992/02/09 15:09:05 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Automount FS server ("localhost") modeling
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/* globals */
|
||||
qelem amfs_auto_srvr_list = {&amfs_auto_srvr_list, &amfs_auto_srvr_list};
|
||||
|
||||
/* statics */
|
||||
static fserver *localhost;
|
||||
|
||||
|
||||
/*
|
||||
* Find an nfs server for the local host
|
||||
*/
|
||||
fserver *
|
||||
find_amfs_auto_srvr(mntfs *mf)
|
||||
{
|
||||
fserver *fs = localhost;
|
||||
|
||||
if (!fs) {
|
||||
fs = ALLOC(struct fserver);
|
||||
fs->fs_refc = 0;
|
||||
fs->fs_host = strdup("localhost");
|
||||
fs->fs_ip = 0;
|
||||
fs->fs_cid = 0;
|
||||
fs->fs_pinger = 0;
|
||||
fs->fs_flags = FSF_VALID;
|
||||
fs->fs_type = "local";
|
||||
fs->fs_private = 0;
|
||||
fs->fs_prfree = 0;
|
||||
|
||||
ins_que(&fs->fs_q, &amfs_auto_srvr_list);
|
||||
|
||||
srvrlog(fs, "starts up");
|
||||
|
||||
localhost = fs;
|
||||
}
|
||||
fs->fs_refc++;
|
||||
|
||||
return fs;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*** GENERIC ROUTINES FOLLOW
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Wakeup anything waiting for this server
|
||||
*/
|
||||
void
|
||||
wakeup_srvr(fserver *fs)
|
||||
{
|
||||
fs->fs_flags &= ~FSF_WANT;
|
||||
wakeup((voidp) fs);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called when final ttl of server has expired
|
||||
*/
|
||||
static void
|
||||
timeout_srvr(voidp v)
|
||||
{
|
||||
fserver *fs = v;
|
||||
|
||||
/*
|
||||
* If the reference count is still zero then
|
||||
* we are free to remove this node
|
||||
*/
|
||||
if (fs->fs_refc == 0) {
|
||||
#ifdef DEBUG
|
||||
dlog("Deleting file server %s", fs->fs_host);
|
||||
#endif /* DEBUG */
|
||||
if (fs->fs_flags & FSF_WANT)
|
||||
wakeup_srvr(fs);
|
||||
|
||||
/*
|
||||
* Remove from queue.
|
||||
*/
|
||||
rem_que(&fs->fs_q);
|
||||
/*
|
||||
* (Possibly) call the private free routine.
|
||||
*/
|
||||
if (fs->fs_private && fs->fs_prfree)
|
||||
(*fs->fs_prfree) (fs->fs_private);
|
||||
|
||||
/*
|
||||
* Free the net address
|
||||
*/
|
||||
if (fs->fs_ip)
|
||||
XFREE(fs->fs_ip);
|
||||
|
||||
/*
|
||||
* Free the host name.
|
||||
*/
|
||||
XFREE(fs->fs_host);
|
||||
|
||||
/*
|
||||
* Discard the fserver object.
|
||||
*/
|
||||
XFREE(fs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free a file server
|
||||
*/
|
||||
void
|
||||
free_srvr(fserver *fs)
|
||||
{
|
||||
if (--fs->fs_refc == 0) {
|
||||
/*
|
||||
* The reference count is now zero,
|
||||
* so arrange for this node to be
|
||||
* removed in AM_TTL seconds if no
|
||||
* other mntfs is referencing it.
|
||||
*/
|
||||
int ttl = (fs->fs_flags & (FSF_DOWN | FSF_ERROR)) ? 19 : AM_TTL;
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("Last hard reference to file server %s - will timeout in %ds", fs->fs_host, ttl);
|
||||
#endif /* DEBUG */
|
||||
if (fs->fs_cid) {
|
||||
untimeout(fs->fs_cid);
|
||||
/*
|
||||
* Turn off pinging - XXX
|
||||
*/
|
||||
fs->fs_flags &= ~FSF_PINGING;
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep structure lying around for a while
|
||||
*/
|
||||
fs->fs_cid = timeout(ttl, timeout_srvr, (voidp) fs);
|
||||
|
||||
/*
|
||||
* Mark the fileserver down and invalid again
|
||||
*/
|
||||
fs->fs_flags &= ~FSF_VALID;
|
||||
fs->fs_flags |= FSF_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Make a duplicate fserver reference
|
||||
*/
|
||||
fserver *
|
||||
dup_srvr(fserver *fs)
|
||||
{
|
||||
fs->fs_refc++;
|
||||
return fs;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Log state change
|
||||
*/
|
||||
void srvrlog(fserver *fs, char *state)
|
||||
{
|
||||
plog(XLOG_INFO, "file server %s type %s %s", fs->fs_host, fs->fs_type, state);
|
||||
}
|
851
contrib/amd/amd/srvr_nfs.c
Normal file
851
contrib/amd/amd/srvr_nfs.c
Normal file
@ -0,0 +1,851 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: srvr_nfs.c,v 5.2.2.1 1992/02/09 15:09:06 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* NFS server modeling
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amd.h>
|
||||
|
||||
/*
|
||||
* Number of pings allowed to fail before host is declared down
|
||||
* - three-fifths of the allowed mount time...
|
||||
*/
|
||||
#define MAX_ALLOWED_PINGS (3 + /* for luck ... */ 1)
|
||||
|
||||
/*
|
||||
* How often to ping when starting a new server
|
||||
*/
|
||||
#define FAST_NFS_PING 3
|
||||
|
||||
#if (FAST_NFS_PING * MAX_ALLOWED_PINGS) >= ALLOWED_MOUNT_TIME
|
||||
# error: sanity check failed in srvr_nfs.c
|
||||
/*
|
||||
* you cannot do things this way...
|
||||
* sufficient fast pings must be given the chance to fail
|
||||
* within the allowed mount time
|
||||
*/
|
||||
#endif /* (FAST_NFS_PING * MAX_ALLOWED_PINGS) >= ALLOWED_MOUNT_TIME */
|
||||
|
||||
#define NPXID_ALLOC(struct ) (++np_xid)
|
||||
|
||||
/* structures and typedefs */
|
||||
typedef struct nfs_private {
|
||||
u_short np_mountd; /* Mount daemon port number */
|
||||
char np_mountd_inval; /* Port *may* be invalid */
|
||||
int np_ping; /* Number of failed ping attempts */
|
||||
time_t np_ttl; /* Time when server is thought dead */
|
||||
int np_xid; /* RPC transaction id for pings */
|
||||
int np_error; /* Error during portmap request */
|
||||
} nfs_private;
|
||||
|
||||
/* globals */
|
||||
qelem nfs_srvr_list = {&nfs_srvr_list, &nfs_srvr_list};
|
||||
|
||||
/* statics */
|
||||
static int np_xid; /* For NFS pings */
|
||||
static int ping_len;
|
||||
static char ping_buf[sizeof(struct rpc_msg) + 32];
|
||||
|
||||
#if defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3)
|
||||
/* protocols we know about, in order of preference */
|
||||
static char *protocols[] = { "tcp", "udp", NULL };
|
||||
#endif /* defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) */
|
||||
|
||||
/* forward definitions */
|
||||
static void nfs_keepalive(voidp);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Flush any cached data
|
||||
*/
|
||||
void
|
||||
flush_srvr_nfs_cache(void)
|
||||
{
|
||||
fserver *fs = 0;
|
||||
|
||||
ITER(fs, fserver, &nfs_srvr_list) {
|
||||
nfs_private *np = (nfs_private *) fs->fs_private;
|
||||
if (np) {
|
||||
np->np_mountd_inval = TRUE;
|
||||
np->np_error = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Startup the NFS ping for a particular version.
|
||||
*/
|
||||
static void
|
||||
start_ping(u_long nfs_version)
|
||||
{
|
||||
XDR ping_xdr;
|
||||
struct rpc_msg ping_msg;
|
||||
|
||||
/*
|
||||
* Non nfs mounts like /afs/glue.umd.edu have ended up here.
|
||||
*/
|
||||
if (nfs_version == 0) {
|
||||
nfs_version = NFS_VERSION;
|
||||
plog(XLOG_WARNING, "start_ping: nfs_version = 0 fixed");
|
||||
}
|
||||
plog(XLOG_INFO, "start_ping: nfs_version: %d", nfs_version);
|
||||
|
||||
rpc_msg_init(&ping_msg, NFS_PROGRAM, nfs_version, NFSPROC_NULL);
|
||||
|
||||
/*
|
||||
* Create an XDR endpoint
|
||||
*/
|
||||
xdrmem_create(&ping_xdr, ping_buf, sizeof(ping_buf), XDR_ENCODE);
|
||||
|
||||
/*
|
||||
* Create the NFS ping message
|
||||
*/
|
||||
if (!xdr_callmsg(&ping_xdr, &ping_msg)) {
|
||||
plog(XLOG_ERROR, "Couldn't create ping RPC message");
|
||||
going_down(3);
|
||||
}
|
||||
/*
|
||||
* Find out how long it is
|
||||
*/
|
||||
ping_len = xdr_getpos(&ping_xdr);
|
||||
|
||||
/*
|
||||
* Destroy the XDR endpoint - we don't need it anymore
|
||||
*/
|
||||
xdr_destroy(&ping_xdr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called when a portmap reply arrives
|
||||
*/
|
||||
static void
|
||||
got_portmap(voidp pkt, int len, struct sockaddr_in * sa, struct sockaddr_in * ia, voidp idv, int done)
|
||||
{
|
||||
fserver *fs2 = (fserver *) idv;
|
||||
fserver *fs = 0;
|
||||
|
||||
/*
|
||||
* Find which fileserver we are talking about
|
||||
*/
|
||||
ITER(fs, fserver, &nfs_srvr_list)
|
||||
if (fs == fs2)
|
||||
break;
|
||||
|
||||
if (fs == fs2) {
|
||||
u_long port = 0; /* XXX - should be short but protocol is naff */
|
||||
int error = done ? pickup_rpc_reply(pkt, len, (voidp) &port, (XDRPROC_T_TYPE) xdr_u_long) : -1;
|
||||
nfs_private *np = (nfs_private *) fs->fs_private;
|
||||
|
||||
if (!error && port) {
|
||||
#ifdef DEBUG
|
||||
dlog("got port (%d) for mountd on %s", port, fs->fs_host);
|
||||
#endif /* DEBUG */
|
||||
/*
|
||||
* Grab the port number. Portmap sends back
|
||||
* an u_long in native ordering, so it
|
||||
* needs converting to a u_short in
|
||||
* network ordering.
|
||||
*/
|
||||
np->np_mountd = htons((u_short) port);
|
||||
np->np_mountd_inval = FALSE;
|
||||
np->np_error = 0;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
dlog("Error fetching port for mountd on %s", fs->fs_host);
|
||||
dlog("\t error=%d, port=%d", error, port);
|
||||
#endif /* DEBUG */
|
||||
/*
|
||||
* Almost certainly no mountd running on remote host
|
||||
*/
|
||||
np->np_error = error ? error : ETIMEDOUT;
|
||||
}
|
||||
|
||||
if (fs->fs_flags & FSF_WANT)
|
||||
wakeup_srvr(fs);
|
||||
} else if (done) {
|
||||
#ifdef DEBUG
|
||||
dlog("Got portmap for old port request");
|
||||
#endif /* DEBUG */
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
dlog("portmap request timed out");
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Obtain portmap information
|
||||
*/
|
||||
static int
|
||||
call_portmap(fserver *fs, AUTH * auth, u_long prog, u_long vers, u_long prot)
|
||||
{
|
||||
struct rpc_msg pmap_msg;
|
||||
int len;
|
||||
char iobuf[UDPMSGSIZE];
|
||||
int error;
|
||||
struct pmap pmap;
|
||||
|
||||
rpc_msg_init(&pmap_msg, PMAPPROG, PMAPVERS, PMAPPROC_NULL);
|
||||
pmap.pm_prog = prog;
|
||||
pmap.pm_vers = vers;
|
||||
pmap.pm_prot = prot;
|
||||
pmap.pm_port = 0;
|
||||
len = make_rpc_packet(iobuf,
|
||||
sizeof(iobuf),
|
||||
PMAPPROC_GETPORT,
|
||||
&pmap_msg,
|
||||
(voidp) &pmap,
|
||||
(XDRPROC_T_TYPE) xdr_pmap,
|
||||
auth);
|
||||
if (len > 0) {
|
||||
struct sockaddr_in sin;
|
||||
memset((voidp) &sin, 0, sizeof(sin));
|
||||
sin = *fs->fs_ip;
|
||||
sin.sin_port = htons(PMAPPORT);
|
||||
error = fwd_packet(RPC_XID_PORTMAP, (voidp) iobuf, len,
|
||||
&sin, &sin, (voidp) fs, got_portmap);
|
||||
} else {
|
||||
error = -len;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
recompute_portmap(fserver *fs)
|
||||
{
|
||||
int error;
|
||||
u_long mnt_version;
|
||||
|
||||
if (nfs_auth)
|
||||
error = 0;
|
||||
else
|
||||
error = make_nfs_auth();
|
||||
|
||||
if (error) {
|
||||
nfs_private *np = (nfs_private *) fs->fs_private;
|
||||
np->np_error = error;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fs->fs_version == 0)
|
||||
plog(XLOG_WARNING, "recompute_portmap: nfs_version = 0 fixed");
|
||||
|
||||
plog(XLOG_INFO, "recompute_portmap: NFS version %d", fs->fs_version);
|
||||
#ifdef HAVE_FS_NFS3
|
||||
if (fs->fs_version == NFS_VERSION3)
|
||||
mnt_version = MOUNTVERS3;
|
||||
else
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
mnt_version = MOUNTVERS;
|
||||
|
||||
plog(XLOG_INFO, "Using MOUNT version: %d", mnt_version);
|
||||
call_portmap(fs, nfs_auth, MOUNTPROG, mnt_version, (u_long) IPPROTO_UDP);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is called when we get a reply to an RPC ping.
|
||||
* The value of id was taken from the nfs_private
|
||||
* structure when the ping was transmitted.
|
||||
*/
|
||||
static void
|
||||
nfs_pinged(voidp pkt, int len, struct sockaddr_in * sp, struct sockaddr_in * tsp, voidp idv, int done)
|
||||
{
|
||||
int xid = (long) idv; /* for 64-bit archs */
|
||||
fserver *fs;
|
||||
#ifdef DEBUG
|
||||
int found_map = 0;
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (!done)
|
||||
return;
|
||||
|
||||
/*
|
||||
* For each node...
|
||||
*/
|
||||
ITER(fs, fserver, &nfs_srvr_list) {
|
||||
nfs_private *np = (nfs_private *) fs->fs_private;
|
||||
if (np->np_xid == xid && (fs->fs_flags & FSF_PINGING)) {
|
||||
/*
|
||||
* Reset the ping counter.
|
||||
* Update the keepalive timer.
|
||||
* Log what happened.
|
||||
*/
|
||||
if (fs->fs_flags & FSF_DOWN) {
|
||||
fs->fs_flags &= ~FSF_DOWN;
|
||||
if (fs->fs_flags & FSF_VALID) {
|
||||
srvrlog(fs, "is up");
|
||||
} else {
|
||||
if (np->np_ping > 1)
|
||||
srvrlog(fs, "ok");
|
||||
#ifdef DEBUG
|
||||
else
|
||||
srvrlog(fs, "starts up");
|
||||
#endif /* DEBUG */
|
||||
fs->fs_flags |= FSF_VALID;
|
||||
}
|
||||
|
||||
map_flush_srvr(fs);
|
||||
} else {
|
||||
if (fs->fs_flags & FSF_VALID) {
|
||||
#ifdef DEBUG
|
||||
dlog("file server %s type nfs is still up", fs->fs_host);
|
||||
#endif /* DEBUG */
|
||||
} else {
|
||||
if (np->np_ping > 1)
|
||||
srvrlog(fs, "ok");
|
||||
fs->fs_flags |= FSF_VALID;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjust ping interval
|
||||
*/
|
||||
untimeout(fs->fs_cid);
|
||||
fs->fs_cid = timeout(fs->fs_pinger, nfs_keepalive, (voidp) fs);
|
||||
|
||||
/*
|
||||
* Update ttl for this server
|
||||
*/
|
||||
np->np_ttl = clocktime() +
|
||||
(MAX_ALLOWED_PINGS - 1) * FAST_NFS_PING + fs->fs_pinger - 1;
|
||||
|
||||
/*
|
||||
* New RPC xid...
|
||||
*/
|
||||
np->np_xid = NPXID_ALLOC(struct );
|
||||
|
||||
/*
|
||||
* Failed pings is zero...
|
||||
*/
|
||||
np->np_ping = 0;
|
||||
|
||||
/*
|
||||
* Recompute portmap information if not known
|
||||
*/
|
||||
if (np->np_mountd_inval)
|
||||
recompute_portmap(fs);
|
||||
|
||||
#ifdef DEBUG
|
||||
found_map++;
|
||||
#endif /* DEBUG */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (found_map == 0)
|
||||
dlog("Spurious ping packet");
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called when no ping-reply received
|
||||
*/
|
||||
static void
|
||||
nfs_timed_out(voidp v)
|
||||
{
|
||||
fserver *fs = v;
|
||||
nfs_private *np = (nfs_private *) fs->fs_private;
|
||||
|
||||
/*
|
||||
* Another ping has failed
|
||||
*/
|
||||
np->np_ping++;
|
||||
|
||||
/*
|
||||
* Not known to be up any longer
|
||||
*/
|
||||
if (FSRV_ISUP(fs)) {
|
||||
fs->fs_flags &= ~FSF_VALID;
|
||||
if (np->np_ping > 1)
|
||||
srvrlog(fs, "not responding");
|
||||
}
|
||||
|
||||
/*
|
||||
* If ttl has expired then guess that it is dead
|
||||
*/
|
||||
if (np->np_ttl < clocktime()) {
|
||||
int oflags = fs->fs_flags;
|
||||
if ((fs->fs_flags & FSF_DOWN) == 0) {
|
||||
/*
|
||||
* Server was up, but is now down.
|
||||
*/
|
||||
srvrlog(fs, "is down");
|
||||
fs->fs_flags |= FSF_DOWN | FSF_VALID;
|
||||
/*
|
||||
* Since the server is down, the portmap
|
||||
* information may now be wrong, so it
|
||||
* must be flushed from the local cache
|
||||
*/
|
||||
flush_nfs_fhandle_cache(fs);
|
||||
np->np_error = -1;
|
||||
} else {
|
||||
/*
|
||||
* Known to be down
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
if ((fs->fs_flags & FSF_VALID) == 0)
|
||||
srvrlog(fs, "starts down");
|
||||
#endif /* DEBUG */
|
||||
fs->fs_flags |= FSF_VALID;
|
||||
}
|
||||
if (oflags != fs->fs_flags && (fs->fs_flags & FSF_WANT))
|
||||
wakeup_srvr(fs);
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
if (np->np_ping > 1)
|
||||
dlog("%d pings to %s failed - at most %d allowed", np->np_ping, fs->fs_host, MAX_ALLOWED_PINGS);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
/*
|
||||
* Run keepalive again
|
||||
*/
|
||||
nfs_keepalive(fs);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Keep track of whether a server is alive
|
||||
*/
|
||||
static void
|
||||
nfs_keepalive(voidp v)
|
||||
{
|
||||
fserver *fs = v;
|
||||
int error;
|
||||
nfs_private *np = (nfs_private *) fs->fs_private;
|
||||
int fstimeo = -1;
|
||||
|
||||
/*
|
||||
* Send an NFS ping to this node
|
||||
*/
|
||||
|
||||
if (ping_len == 0)
|
||||
start_ping(fs->fs_version);
|
||||
|
||||
/*
|
||||
* Queue the packet...
|
||||
*/
|
||||
error = fwd_packet(MK_RPC_XID(RPC_XID_NFSPING, np->np_xid),
|
||||
(voidp) ping_buf,
|
||||
ping_len,
|
||||
fs->fs_ip,
|
||||
(struct sockaddr_in *) 0,
|
||||
(voidp) ((long) np->np_xid), /* for 64-bit archs */
|
||||
nfs_pinged);
|
||||
|
||||
/*
|
||||
* See if a hard error occured
|
||||
*/
|
||||
switch (error) {
|
||||
case ENETDOWN:
|
||||
case ENETUNREACH:
|
||||
case EHOSTDOWN:
|
||||
case EHOSTUNREACH:
|
||||
np->np_ping = MAX_ALLOWED_PINGS; /* immediately down */
|
||||
np->np_ttl = (time_t) 0;
|
||||
/*
|
||||
* This causes an immediate call to nfs_timed_out
|
||||
* whenever the server was thought to be up.
|
||||
* See +++ below.
|
||||
*/
|
||||
fstimeo = 0;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
#ifdef DEBUG
|
||||
dlog("Sent NFS ping to %s", fs->fs_host);
|
||||
#endif /* DEBUG */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Back off the ping interval if we are not getting replies and
|
||||
* the remote system is know to be down.
|
||||
*/
|
||||
switch (fs->fs_flags & (FSF_DOWN | FSF_VALID)) {
|
||||
case FSF_VALID: /* Up */
|
||||
if (fstimeo < 0) /* +++ see above */
|
||||
fstimeo = FAST_NFS_PING;
|
||||
break;
|
||||
|
||||
case FSF_VALID | FSF_DOWN: /* Down */
|
||||
fstimeo = fs->fs_pinger;
|
||||
break;
|
||||
|
||||
default: /* Unknown */
|
||||
fstimeo = FAST_NFS_PING;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
dlog("NFS timeout in %d seconds", fstimeo);
|
||||
#endif /* DEBUG */
|
||||
|
||||
fs->fs_cid = timeout(fstimeo, nfs_timed_out, (voidp) fs);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nfs_srvr_port(fserver *fs, u_short * port, voidp wchan)
|
||||
{
|
||||
int error = -1;
|
||||
if ((fs->fs_flags & FSF_VALID) == FSF_VALID) {
|
||||
if ((fs->fs_flags & FSF_DOWN) == 0) {
|
||||
nfs_private *np = (nfs_private *) fs->fs_private;
|
||||
if (np->np_error == 0) {
|
||||
*port = np->np_mountd;
|
||||
error = 0;
|
||||
} else {
|
||||
error = np->np_error;
|
||||
}
|
||||
/*
|
||||
* Now go get the port mapping again in case it changed.
|
||||
* Note that it is used even if (np_mountd_inval)
|
||||
* is True. The flag is used simply as an
|
||||
* indication that the mountd may be invalid, not
|
||||
* that it is known to be invalid.
|
||||
*/
|
||||
if (np->np_mountd_inval)
|
||||
recompute_portmap(fs);
|
||||
else
|
||||
np->np_mountd_inval = TRUE;
|
||||
} else {
|
||||
error = EWOULDBLOCK;
|
||||
}
|
||||
}
|
||||
if (error < 0 && wchan && !(fs->fs_flags & FSF_WANT)) {
|
||||
/*
|
||||
* If a wait channel is supplied, and no
|
||||
* error has yet occured, then arrange
|
||||
* that a wakeup is done on the wait channel,
|
||||
* whenever a wakeup is done on this fs node.
|
||||
* Wakeup's are done on the fs node whenever
|
||||
* it changes state - thus causing control to
|
||||
* come back here and new, better things to happen.
|
||||
*/
|
||||
fs->fs_flags |= FSF_WANT;
|
||||
sched_task(wakeup_task, wchan, (voidp) fs);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
start_nfs_pings(fserver *fs, int pingval)
|
||||
{
|
||||
if (!(fs->fs_flags & FSF_PINGING)) {
|
||||
fs->fs_flags |= FSF_PINGING;
|
||||
if (fs->fs_cid)
|
||||
untimeout(fs->fs_cid);
|
||||
if (pingval < 0) {
|
||||
srvrlog(fs, "wired up");
|
||||
fs->fs_flags |= FSF_VALID;
|
||||
fs->fs_flags &= ~FSF_DOWN;
|
||||
} else {
|
||||
nfs_keepalive(fs);
|
||||
}
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
dlog("Already running pings to %s", fs->fs_host);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find an nfs server for a host.
|
||||
*/
|
||||
fserver *
|
||||
find_nfs_srvr(mntfs *mf)
|
||||
{
|
||||
char *host = mf->mf_fo->opt_rhost;
|
||||
char *nfs_proto = NULL;
|
||||
fserver *fs;
|
||||
int pingval;
|
||||
mntent_t mnt;
|
||||
nfs_private *np;
|
||||
struct hostent *hp = 0;
|
||||
struct sockaddr_in *ip;
|
||||
u_long nfs_version = 0; /* default is no version specified */
|
||||
#ifdef MNTTAB_OPT_PROTO
|
||||
char *rfsname = mf->mf_fo->opt_rfs;
|
||||
#endif /* MNTTAB_OPT_PROTO */
|
||||
|
||||
/*
|
||||
* Get ping interval from mount options.
|
||||
* Current only used to decide whether pings
|
||||
* are required or not. < 0 = no pings.
|
||||
*/
|
||||
mnt.mnt_opts = mf->mf_mopts;
|
||||
pingval = hasmntval(&mnt, "ping");
|
||||
|
||||
/*
|
||||
* Get the NFS version from the mount options. This is used
|
||||
* to decide the highest NFS version to try.
|
||||
*/
|
||||
#ifdef MNTTAB_OPT_VERS
|
||||
nfs_version = hasmntval(&mnt, MNTTAB_OPT_VERS);
|
||||
#endif /* MNTTAB_OPT_VERS */
|
||||
|
||||
#ifdef MNTTAB_OPT_PROTO
|
||||
{
|
||||
char *proto_opt = hasmntopt(&mnt, MNTTAB_OPT_PROTO);
|
||||
if (proto_opt) {
|
||||
char **p;
|
||||
|
||||
proto_opt += sizeof(MNTTAB_OPT_PROTO) - 1; /* skip the "proto" */
|
||||
|
||||
for (p = protocols; *p; p ++)
|
||||
if (proto_opt[0] == '=' &&
|
||||
NSTREQ(&proto_opt[1], *p, strlen(*p))) {
|
||||
nfs_proto = *p;
|
||||
break;
|
||||
}
|
||||
if (*p == NULL)
|
||||
plog(XLOG_WARNING, "ignoring unknown protocol option for %s:%s",
|
||||
host, rfsname);
|
||||
}
|
||||
}
|
||||
#endif /* MNTTAB_OPT_PROTO */
|
||||
|
||||
/*
|
||||
* lookup host address and canonical name
|
||||
*/
|
||||
hp = gethostbyname(host);
|
||||
|
||||
/*
|
||||
* New code from Bob Harris <harris@basil-rathbone.mit.edu>
|
||||
* Use canonical name to keep track of file server
|
||||
* information. This way aliases do not generate
|
||||
* multiple NFS pingers. (Except when we're normalizing
|
||||
* hosts.)
|
||||
*/
|
||||
if (hp && !(gopt.flags & CFM_NORMALIZE_HOSTNAMES))
|
||||
host = (char *) hp->h_name;
|
||||
|
||||
if (hp) {
|
||||
switch (hp->h_addrtype) {
|
||||
case AF_INET:
|
||||
ip = ALLOC(struct sockaddr_in);
|
||||
memset((voidp) ip, 0, sizeof(*ip));
|
||||
ip->sin_family = AF_INET;
|
||||
memmove((voidp) &ip->sin_addr, (voidp) hp->h_addr, sizeof(ip->sin_addr));
|
||||
|
||||
ip->sin_port = htons(NFS_PORT);
|
||||
break;
|
||||
|
||||
default:
|
||||
ip = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
plog(XLOG_USER, "Unknown host: %s", host);
|
||||
ip = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the NFS Version, and verify server is up. Probably no
|
||||
* longer need to start server down below.
|
||||
*/
|
||||
if (ip) {
|
||||
#ifdef HAVE_FS_NFS3
|
||||
/*
|
||||
* Find the best combination of NFS version and protocol.
|
||||
* When given a choice, use the highest available version,
|
||||
* and use TCP over UDP if available.
|
||||
*/
|
||||
if (nfs_proto)
|
||||
nfs_version = get_nfs_version(host, ip, nfs_version, nfs_proto);
|
||||
else {
|
||||
int best_nfs_version = 0;
|
||||
int proto_nfs_version;
|
||||
char **p;
|
||||
|
||||
for (p = protocols; *p; p ++) {
|
||||
proto_nfs_version = get_nfs_version(host, ip, nfs_version, *p);
|
||||
|
||||
if (proto_nfs_version > best_nfs_version) {
|
||||
best_nfs_version = proto_nfs_version;
|
||||
nfs_proto = *p;
|
||||
}
|
||||
}
|
||||
nfs_version = best_nfs_version;
|
||||
}
|
||||
|
||||
if (!nfs_version) {
|
||||
/*
|
||||
* If the NFS server is down or does not support the portmapper call
|
||||
* (such as certain Novell NFS servers) we mark it as version 2 and we
|
||||
* let the nfs code deal with the case that is down. If when the
|
||||
* server comes back up, it can support NFS V.3 and/or TCP, it will
|
||||
* use those.
|
||||
*/
|
||||
nfs_version = NFS_VERSION;
|
||||
nfs_proto = "udp";
|
||||
}
|
||||
#else /* not HAVE_FS_NFS3 */
|
||||
nfs_version = NFS_VERSION;
|
||||
#endif /* not HAVE_FS_NFS3 */
|
||||
}
|
||||
|
||||
if (!nfs_proto)
|
||||
nfs_proto = "udp";
|
||||
|
||||
plog(XLOG_INFO, "Using NFS version %d, protocol %s on host %s",
|
||||
nfs_version, nfs_proto, host);
|
||||
|
||||
/*
|
||||
* Try to find an existing fs server stucture for this host.
|
||||
* Note that differing versions or protocols have their own structures.
|
||||
* XXX: Need to fix the ping mechanism to actually use the NFS protocol
|
||||
* chosen here (right now it always uses datagram sockets).
|
||||
*/
|
||||
ITER(fs, fserver, &nfs_srvr_list) {
|
||||
if (STREQ(host, fs->fs_host) &&
|
||||
nfs_version == fs->fs_version &&
|
||||
STREQ(nfs_proto, fs->fs_proto)) {
|
||||
/*
|
||||
* following if statement from Mike Mitchell
|
||||
* <mcm@unx.sas.com>
|
||||
* Initialize the ping data if we aren't pinging
|
||||
* now. The np_ttl and np_ping fields are
|
||||
* especially important.
|
||||
*/
|
||||
if (!(fs->fs_flags & FSF_PINGING)) {
|
||||
np = (nfs_private *) fs->fs_private;
|
||||
np->np_mountd_inval = TRUE;
|
||||
np->np_xid = NPXID_ALLOC(struct );
|
||||
np->np_error = -1;
|
||||
np->np_ping = 0;
|
||||
/*
|
||||
* Initially the server will be deemed dead
|
||||
* after MAX_ALLOWED_PINGS of the fast variety
|
||||
* have failed.
|
||||
*/
|
||||
np->np_ttl = MAX_ALLOWED_PINGS * FAST_NFS_PING + clocktime() - 1;
|
||||
}
|
||||
/*
|
||||
* fill in the IP address -- this is only needed
|
||||
* if there is a chance an IP address will change
|
||||
* between mounts.
|
||||
* Mike Mitchell, mcm@unx.sas.com, 09/08/93
|
||||
*/
|
||||
if (hp && fs->fs_ip)
|
||||
memmove((voidp) &fs->fs_ip->sin_addr, (voidp) hp->h_addr, sizeof(fs->fs_ip->sin_addr));
|
||||
|
||||
start_nfs_pings(fs, pingval);
|
||||
fs->fs_refc++;
|
||||
if (ip)
|
||||
XFREE(ip);
|
||||
return fs;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get here if we can't find an entry
|
||||
*/
|
||||
|
||||
/*
|
||||
* Allocate a new server
|
||||
*/
|
||||
fs = ALLOC(struct fserver);
|
||||
fs->fs_refc = 1;
|
||||
fs->fs_host = strdup(hp ? hp->h_name : "unknown_hostname");
|
||||
if (gopt.flags & CFM_NORMALIZE_HOSTNAMES)
|
||||
host_normalize(&fs->fs_host);
|
||||
fs->fs_ip = ip;
|
||||
fs->fs_cid = 0;
|
||||
if (ip) {
|
||||
fs->fs_flags = FSF_DOWN; /* Starts off down */
|
||||
} else {
|
||||
fs->fs_flags = FSF_ERROR | FSF_VALID;
|
||||
mf->mf_flags |= MFF_ERROR;
|
||||
mf->mf_error = ENOENT;
|
||||
}
|
||||
fs->fs_version = nfs_version;
|
||||
fs->fs_proto = nfs_proto;
|
||||
fs->fs_type = MNTTAB_TYPE_NFS;
|
||||
fs->fs_pinger = AM_PINGER;
|
||||
np = ALLOC(struct nfs_private);
|
||||
memset((voidp) np, 0, sizeof(*np));
|
||||
np->np_mountd_inval = TRUE;
|
||||
np->np_xid = NPXID_ALLOC(struct );
|
||||
np->np_error = -1;
|
||||
|
||||
/*
|
||||
* Initially the server will be deemed dead after
|
||||
* MAX_ALLOWED_PINGS of the fast variety have failed.
|
||||
*/
|
||||
np->np_ttl = clocktime() + MAX_ALLOWED_PINGS * FAST_NFS_PING - 1;
|
||||
fs->fs_private = (voidp) np;
|
||||
fs->fs_prfree = (void (*)(voidp)) free;
|
||||
|
||||
if (!(fs->fs_flags & FSF_ERROR)) {
|
||||
/*
|
||||
* Start of keepalive timer
|
||||
*/
|
||||
start_nfs_pings(fs, pingval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add to list of servers
|
||||
*/
|
||||
ins_que(&fs->fs_q, &nfs_srvr_list);
|
||||
|
||||
return fs;
|
||||
}
|
214
contrib/amd/amq/amq.8
Normal file
214
contrib/amd/amq/amq.8
Normal file
@ -0,0 +1,214 @@
|
||||
.\"
|
||||
.\" Copyright (c) 1997-1998 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 acknowledgment:
|
||||
.\" 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.8,v 5.2.2.1 1992/02/09 15:11:15 jsp beta $
|
||||
.\"
|
||||
.TH AMQ 8 "25 April 1989"
|
||||
.SH NAME
|
||||
amq \- automounter query tool
|
||||
.SH SYNOPSIS
|
||||
.B amq
|
||||
[
|
||||
.BI \-fmpsuvTU
|
||||
] [
|
||||
.BI \-h " hostname"
|
||||
] [
|
||||
.BI \-l " log_file"
|
||||
] [
|
||||
.BI \-x " log_options"
|
||||
] [
|
||||
.BI \-D " debug_options"
|
||||
] [
|
||||
.BI \-M " mountmap entry"
|
||||
] [
|
||||
.BI \-P " program_number"
|
||||
] [
|
||||
.I directory
|
||||
] .\|.\|.
|
||||
.SH DESCRIPTION
|
||||
.B Amq
|
||||
provides a simple way of determining the current state of
|
||||
.B amd
|
||||
program.
|
||||
Communication is by
|
||||
.SM RPC.
|
||||
Three modes of operation are supported by the current protocol. By default
|
||||
a list of mount points and auto-mounted filesystems is output. An
|
||||
alternative host can be specified using the
|
||||
.I \-h
|
||||
option.
|
||||
.LP
|
||||
If
|
||||
.I directory
|
||||
names are given, as output by default, then per-filesystem
|
||||
information is displayed.
|
||||
.SH OPTIONS
|
||||
|
||||
.TP
|
||||
.B \-f
|
||||
Ask the automounter to flush the internal caches.
|
||||
|
||||
.TP
|
||||
.BI \-h " hostname"
|
||||
Specify an alternate host to query. By default the local host is used. In
|
||||
an
|
||||
.SM HP-UX
|
||||
cluster, the root server is queried by default, since that is the system on
|
||||
which the automounter is normally run.
|
||||
|
||||
.TP
|
||||
.BI \-l " log_file"
|
||||
Tell amd to use
|
||||
.I log_file
|
||||
as the log file name. For security reasons, this must be the same log file
|
||||
which amd used when started. This option is therefore only useful to
|
||||
refresh amd's open file handle on the log file, so that it can be rotated
|
||||
and compressed via daily cron jobs.
|
||||
|
||||
.TP
|
||||
.B \-m
|
||||
Ask the automounter to provide a list of mounted filesystems, including the
|
||||
number of references to each filesystem and any error which occurred while
|
||||
mounting.
|
||||
|
||||
.TP
|
||||
.B \-p
|
||||
Return the process ID of the remote or locally running amd. Useful when you
|
||||
need to send a signal to the local amd process, and would rather not have to
|
||||
search through the process table. This option is used in the
|
||||
.I ctl-amd
|
||||
script.
|
||||
|
||||
.TP
|
||||
.B \-s
|
||||
Ask the automounter to provide system-wide mount statistics.
|
||||
|
||||
.TP
|
||||
.B \-u
|
||||
Ask the automounter to unmount the filesystems named in
|
||||
.I directory
|
||||
instead of providing
|
||||
information about them. Unmounts are requested, not forced. They merely
|
||||
cause the mounted filesystem to timeout, which will be picked up by
|
||||
.BR amd 's
|
||||
main scheduler thus causing the normal timeout action to be taken.
|
||||
|
||||
.TP
|
||||
.B \-v
|
||||
Ask the automounter for its version information. This is a subset of the
|
||||
information output by
|
||||
.BR amd 's
|
||||
.I -v
|
||||
option.
|
||||
|
||||
.TP
|
||||
.BI \-x " log_options"
|
||||
Ask the automounter to use the logging options specified in
|
||||
.I log_options
|
||||
from now on.
|
||||
|
||||
.TP
|
||||
.BI \-D " log_options"
|
||||
Ask the automounter to use the debugging options specified in
|
||||
.I debug_options
|
||||
from now on.
|
||||
|
||||
.TP
|
||||
.BI \-M " map_ent"
|
||||
Pass a mount map entry to
|
||||
.B amd
|
||||
and wait for it to be evaluated, possible causing a mount. This option is
|
||||
highly insecure. By default, amd and amq do not support it. You have to
|
||||
configure am-utils with
|
||||
.I \-\-enable\-amq\-mount
|
||||
to enable this option.
|
||||
|
||||
.TP
|
||||
.BI \-P " program_number"
|
||||
Contact an alternate running amd that had registered itself on a different
|
||||
RPC
|
||||
.I program_number
|
||||
and apply all other operations to that instance of the automounter. This is
|
||||
useful when you run multiple copies of amd, and need to manage each
|
||||
one separately. If not specified, amq will use the default program number
|
||||
for amd, 300019. For security reasons, the only alternate program numbers
|
||||
amd can use range from 300019 to 300029, inclusive.
|
||||
|
||||
.TP
|
||||
.B \-T
|
||||
Contact
|
||||
.B amd
|
||||
using the TCP transport only. Normally
|
||||
.B amq
|
||||
will try TCP, and if that failed, will try UDP.
|
||||
|
||||
.TP
|
||||
.B \-U
|
||||
Contact
|
||||
.B amd
|
||||
using UDP (connectionless) transport only. Normally
|
||||
.B amq
|
||||
will try TCP, and if that failed, will try UDP.
|
||||
|
||||
.SH FILES
|
||||
.PD 0
|
||||
.TP 20
|
||||
.B amq.x
|
||||
.SM RPC
|
||||
protocol description.
|
||||
.SH CAVEATS
|
||||
.B Amq
|
||||
uses a Sun registered
|
||||
.SM RPC
|
||||
program number (300019 decimal) which may not
|
||||
be in the /etc/rpc database.
|
||||
.SH "SEE ALSO"
|
||||
.BR amd (8),
|
||||
.BR ctl-amd (8),
|
||||
.BR amd.conf (5).
|
||||
.SH AUTHORS
|
||||
Jan-Simon Pendry <jsp@doc.ic.ac.uk>, Department of Computing, Imperial College, London, UK.
|
||||
.P
|
||||
Erez Zadok <ezk@cs.columbia.edu>, Department of Computer Science, Columbia
|
||||
University, New York, USA.
|
||||
.P
|
||||
Other authors and contributors to am-utils are listed in the
|
||||
.B AUTHORS
|
||||
file distributed with am-utils.
|
938
contrib/amd/amq/amq.c
Normal file
938
contrib/amd/amq/amq.c
Normal file
@ -0,0 +1,938 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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.c,v 5.2.2.1 1992/02/09 15:09:16 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Automounter query tool
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] = "\
|
||||
@(#)Copyright (c) 1997-1998 Erez Zadok\n\
|
||||
@(#)Copyright (c) 1990 Jan-Simon Pendry\n\
|
||||
@(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\
|
||||
@(#)Copyright (c) 1990 The Regents of the University of California.\n\
|
||||
@(#)All rights reserved.\n";
|
||||
#if __GNUC__ < 2
|
||||
static char rcsid[] = "$Id: amq.c,v 6.0 1997-1998/01/01 15:09:16 ezk $";
|
||||
static char sccsid[] = "%W% (Berkeley) %G%";
|
||||
#endif /* __GNUC__ < 2 */
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amq.h>
|
||||
|
||||
/* locals */
|
||||
char *progname;
|
||||
static int flush_flag;
|
||||
static int minfo_flag;
|
||||
static int getpid_flag;
|
||||
static int unmount_flag;
|
||||
static int stats_flag;
|
||||
static int getvers_flag;
|
||||
static int amd_program_number = AMQ_PROGRAM;
|
||||
static int use_tcp_flag, use_udp_flag;
|
||||
static char *debug_opts;
|
||||
static char *amq_logfile;
|
||||
static char *mount_map;
|
||||
static char *xlog_optstr;
|
||||
static char localhost[] = "localhost";
|
||||
static char *def_server = localhost;
|
||||
|
||||
/* externals */
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
/* forward decalrations */
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
static CLIENT *get_secure_amd_client(char *host, struct timeval *tv, int *sock);
|
||||
static int amq_bind_resv_port(int td, u_short *pp);
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
static int privsock(int ty);
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
/* dummy variables */
|
||||
char hostname[MAXHOSTNAMELEN];
|
||||
int orig_umask, foreground, debug_flags;
|
||||
pid_t mypid;
|
||||
serv_state amd_state;
|
||||
|
||||
/* structures */
|
||||
enum show_opt {
|
||||
Full, Stats, Calc, Short, ShowDone
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* If (e) is Calc then just calculate the sizes
|
||||
* Otherwise display the mount node on stdout
|
||||
*/
|
||||
static void
|
||||
show_mti(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, int *twid)
|
||||
{
|
||||
switch (e) {
|
||||
case Calc:
|
||||
{
|
||||
int mw = strlen(mt->mt_mountinfo);
|
||||
int dw = strlen(mt->mt_directory);
|
||||
int tw = strlen(mt->mt_type);
|
||||
if (mw > *mwid)
|
||||
*mwid = mw;
|
||||
if (dw > *dwid)
|
||||
*dwid = dw;
|
||||
if (tw > *twid)
|
||||
*twid = tw;
|
||||
}
|
||||
break;
|
||||
|
||||
case Full:
|
||||
{
|
||||
struct tm *tp = localtime((time_t *) &mt->mt_mounttime);
|
||||
printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
|
||||
*dwid, *dwid,
|
||||
*mt->mt_directory ? mt->mt_directory : "/", /* XXX */
|
||||
*twid, *twid,
|
||||
mt->mt_type,
|
||||
*mwid, *mwid,
|
||||
mt->mt_mountinfo,
|
||||
mt->mt_mountpoint,
|
||||
|
||||
mt->mt_mountuid,
|
||||
mt->mt_getattr,
|
||||
mt->mt_lookup,
|
||||
mt->mt_readdir,
|
||||
mt->mt_readlink,
|
||||
mt->mt_statfs,
|
||||
|
||||
tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
|
||||
tp->tm_mon + 1, tp->tm_mday,
|
||||
tp->tm_hour, tp->tm_min, tp->tm_sec);
|
||||
}
|
||||
break;
|
||||
|
||||
case Stats:
|
||||
{
|
||||
struct tm *tp = localtime((time_t *) &mt->mt_mounttime);
|
||||
printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
|
||||
*dwid, *dwid,
|
||||
*mt->mt_directory ? mt->mt_directory : "/", /* XXX */
|
||||
|
||||
mt->mt_mountuid,
|
||||
mt->mt_getattr,
|
||||
mt->mt_lookup,
|
||||
mt->mt_readdir,
|
||||
mt->mt_readlink,
|
||||
mt->mt_statfs,
|
||||
|
||||
tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
|
||||
tp->tm_mon + 1, tp->tm_mday,
|
||||
tp->tm_hour, tp->tm_min, tp->tm_sec);
|
||||
}
|
||||
break;
|
||||
|
||||
case Short:
|
||||
{
|
||||
printf("%-*.*s %-*.*s %-*.*s %s\n",
|
||||
*dwid, *dwid,
|
||||
*mt->mt_directory ? mt->mt_directory : "/",
|
||||
*twid, *twid,
|
||||
mt->mt_type,
|
||||
*mwid, *mwid,
|
||||
mt->mt_mountinfo,
|
||||
mt->mt_mountpoint);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Display a mount tree.
|
||||
*/
|
||||
static void
|
||||
show_mt(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, int *pwid)
|
||||
{
|
||||
while (mt) {
|
||||
show_mti(mt, e, mwid, dwid, pwid);
|
||||
show_mt(mt->mt_next, e, mwid, dwid, pwid);
|
||||
mt = mt->mt_child;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_mi(amq_mount_info_list *ml, enum show_opt e, int *mwid, int *dwid, int *twid)
|
||||
{
|
||||
int i;
|
||||
|
||||
switch (e) {
|
||||
|
||||
case Calc:
|
||||
{
|
||||
for (i = 0; i < ml->amq_mount_info_list_len; i++) {
|
||||
amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
|
||||
int mw = strlen(mi->mi_mountinfo);
|
||||
int dw = strlen(mi->mi_mountpt);
|
||||
int tw = strlen(mi->mi_type);
|
||||
if (mw > *mwid)
|
||||
*mwid = mw;
|
||||
if (dw > *dwid)
|
||||
*dwid = dw;
|
||||
if (tw > *twid)
|
||||
*twid = tw;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Full:
|
||||
{
|
||||
for (i = 0; i < ml->amq_mount_info_list_len; i++) {
|
||||
amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
|
||||
printf("%-*.*s %-*.*s %-*.*s %-3d %s is %s",
|
||||
*mwid, *mwid, mi->mi_mountinfo,
|
||||
*dwid, *dwid, mi->mi_mountpt,
|
||||
*twid, *twid, mi->mi_type,
|
||||
mi->mi_refc, mi->mi_fserver,
|
||||
mi->mi_up > 0 ? "up" :
|
||||
mi->mi_up < 0 ? "starting" : "down");
|
||||
if (mi->mi_error > 0) {
|
||||
extern int sys_nerr;
|
||||
if (mi->mi_error < sys_nerr)
|
||||
printf(" (%s)", sys_errlist[mi->mi_error]);
|
||||
else
|
||||
printf(" (Error %d)", mi->mi_error);
|
||||
} else if (mi->mi_error < 0) {
|
||||
fputs(" (in progress)", stdout);
|
||||
}
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Display general mount statistics
|
||||
*/
|
||||
static void
|
||||
show_ms(amq_mount_stats *ms)
|
||||
{
|
||||
printf("\
|
||||
requests stale mount mount unmount\n\
|
||||
deferred fhandles ok failed failed\n\
|
||||
%-9d %-9d %-9d %-9d %-9d\n",
|
||||
ms->as_drops, ms->as_stale, ms->as_mok, ms->as_merr, ms->as_uerr);
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_CLUSTER_H) && defined(HAVE_CNODEID) && defined(HAVE_GETCCENT)
|
||||
static char *
|
||||
cluster_server(void)
|
||||
{
|
||||
struct cct_entry *cp;
|
||||
|
||||
if (cnodeid() == 0) {
|
||||
/*
|
||||
* Not clustered
|
||||
*/
|
||||
return def_server;
|
||||
}
|
||||
while (cp = getccent())
|
||||
if (cp->cnode_type == 'r')
|
||||
return cp->cnode_name;
|
||||
|
||||
return def_server;
|
||||
}
|
||||
#endif /* defined(HAVE_CLUSTER_H) && defined(HAVE_CNODEID) && defined(HAVE_GETCCENT) */
|
||||
|
||||
|
||||
/*
|
||||
* MAIN
|
||||
*/
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int opt_ch;
|
||||
int errs = 0;
|
||||
char *server;
|
||||
struct sockaddr_in server_addr;
|
||||
int s; /* to pass the Amd security check, we must use a priv port */
|
||||
CLIENT *clnt = NULL;
|
||||
struct hostent *hp;
|
||||
int nodefault = 0;
|
||||
struct timeval tv;
|
||||
#ifndef HAVE_TRANSPORT_TYPE_TLI
|
||||
enum clnt_stat cs;
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
|
||||
/*
|
||||
* Compute program name
|
||||
*/
|
||||
if (argv[0]) {
|
||||
progname = strrchr(argv[0], '/');
|
||||
if (progname && progname[1])
|
||||
progname++;
|
||||
else
|
||||
progname = argv[0];
|
||||
}
|
||||
if (!progname)
|
||||
progname = "amq";
|
||||
|
||||
/*
|
||||
* Parse arguments
|
||||
*/
|
||||
while ((opt_ch = getopt(argc, argv, "fh:l:msuvx:D:M:pP:TU")) != EOF)
|
||||
switch (opt_ch) {
|
||||
case 'f':
|
||||
flush_flag = 1;
|
||||
nodefault = 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
def_server = optarg;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
amq_logfile = optarg;
|
||||
nodefault = 1;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
minfo_flag = 1;
|
||||
nodefault = 1;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
getpid_flag = 1;
|
||||
nodefault = 1;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
stats_flag = 1;
|
||||
nodefault = 1;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
unmount_flag = 1;
|
||||
nodefault = 1;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
getvers_flag = 1;
|
||||
nodefault = 1;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
xlog_optstr = optarg;
|
||||
nodefault = 1;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
debug_opts = optarg;
|
||||
nodefault = 1;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
mount_map = optarg;
|
||||
nodefault = 1;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
amd_program_number = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
use_tcp_flag = 1;
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
use_udp_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
errs = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (optind == argc) {
|
||||
if (unmount_flag)
|
||||
errs = 1;
|
||||
}
|
||||
if (errs) {
|
||||
show_usage:
|
||||
fprintf(stderr, "\
|
||||
Usage: %s [-h host] [[-f] [-m] [-p] [-v] [-s]] | [[-u] directory ...]]\n\
|
||||
\t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts] [-M mapent]\n\
|
||||
\t[-P prognum] [-T] [-U]\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* set use_udp and use_tcp flags both to on if none are defined */
|
||||
if (!use_tcp_flag && !use_udp_flag)
|
||||
use_tcp_flag = use_udp_flag = 1;
|
||||
|
||||
#if defined(HAVE_CLUSTER_H) && defined(HAVE_CNODEID) && defined(HAVE_GETCCENT)
|
||||
/*
|
||||
* Figure out root server of cluster
|
||||
*/
|
||||
if (def_server == localhost)
|
||||
server = cluster_server();
|
||||
else
|
||||
#endif /* defined(HAVE_CLUSTER_H) && defined(HAVE_CNODEID) && defined(HAVE_GETCCENT) */
|
||||
server = def_server;
|
||||
|
||||
/*
|
||||
* Get address of server
|
||||
*/
|
||||
if ((hp = gethostbyname(server)) == 0 && !STREQ(server, localhost)) {
|
||||
fprintf(stderr, "%s: Can't get address of %s\n", progname, server);
|
||||
exit(1);
|
||||
}
|
||||
memset(&server_addr, 0, sizeof server_addr);
|
||||
server_addr.sin_family = AF_INET;
|
||||
if (hp) {
|
||||
memmove((voidp) &server_addr.sin_addr, (voidp) hp->h_addr,
|
||||
sizeof(server_addr.sin_addr));
|
||||
} else {
|
||||
/* fake "localhost" */
|
||||
server_addr.sin_addr.s_addr = htonl(0x7f000001);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create RPC endpoint
|
||||
*/
|
||||
tv.tv_sec = 5; /* 5 seconds for timeout or per retry */
|
||||
tv.tv_usec = 0;
|
||||
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
clnt = get_secure_amd_client(server, &tv, &s);
|
||||
if (!clnt && use_tcp_flag) /* try tcp first */
|
||||
clnt = clnt_create(server, amd_program_number, AMQ_VERSION, "tcp");
|
||||
if (!clnt && use_udp_flag) { /* try udp next */
|
||||
clnt = clnt_create(server, amd_program_number, AMQ_VERSION, "udp");
|
||||
/* if ok, set timeout (valid for connectionless transports only) */
|
||||
if (clnt)
|
||||
clnt_control(clnt, CLSET_RETRY_TIMEOUT, (char *) &tv);
|
||||
}
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
/* first check if remote portmapper is up */
|
||||
cs = pmap_ping(&server_addr);
|
||||
if (cs == RPC_TIMEDOUT) {
|
||||
fprintf(stderr, "%s: failed to contact portmapper on host \"%s\". %s\n",
|
||||
progname, server, clnt_sperrno(cs));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* portmapper exists: get remote amd info from it */
|
||||
if (!clnt && use_tcp_flag) { /* try tcp first */
|
||||
s = RPC_ANYSOCK;
|
||||
clnt = clnttcp_create(&server_addr, amd_program_number,
|
||||
AMQ_VERSION, &s, 0, 0);
|
||||
}
|
||||
if (!clnt && use_udp_flag) { /* try udp next */
|
||||
/* XXX: do we need to close(s) ? */
|
||||
s = privsock(SOCK_DGRAM);
|
||||
clnt = clntudp_create(&server_addr, amd_program_number,
|
||||
AMQ_VERSION, tv, &s);
|
||||
}
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
if (!clnt) {
|
||||
fprintf(stderr, "%s: ", progname);
|
||||
clnt_pcreateerror(server);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Control debugging
|
||||
*/
|
||||
if (debug_opts) {
|
||||
int *rc;
|
||||
amq_setopt opt;
|
||||
opt.as_opt = AMOPT_DEBUG;
|
||||
opt.as_str = debug_opts;
|
||||
rc = amqproc_setopt_1(&opt, clnt);
|
||||
if (rc && *rc < 0) {
|
||||
fprintf(stderr, "%s: daemon not compiled for debug\n", progname);
|
||||
errs = 1;
|
||||
} else if (!rc || *rc > 0) {
|
||||
fprintf(stderr, "%s: debug setting for \"%s\" failed\n", progname, debug_opts);
|
||||
errs = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Control logging
|
||||
*/
|
||||
if (xlog_optstr) {
|
||||
int *rc;
|
||||
amq_setopt opt;
|
||||
opt.as_opt = AMOPT_XLOG;
|
||||
opt.as_str = xlog_optstr;
|
||||
rc = amqproc_setopt_1(&opt, clnt);
|
||||
if (!rc || *rc) {
|
||||
fprintf(stderr, "%s: setting log level to \"%s\" failed\n", progname, xlog_optstr);
|
||||
errs = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Control log file
|
||||
*/
|
||||
if (amq_logfile) {
|
||||
int *rc;
|
||||
amq_setopt opt;
|
||||
opt.as_opt = AMOPT_LOGFILE;
|
||||
opt.as_str = amq_logfile;
|
||||
rc = amqproc_setopt_1(&opt, clnt);
|
||||
if (!rc || *rc) {
|
||||
fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", progname, amq_logfile);
|
||||
errs = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush map cache
|
||||
*/
|
||||
if (flush_flag) {
|
||||
int *rc;
|
||||
amq_setopt opt;
|
||||
opt.as_opt = AMOPT_FLUSHMAPC;
|
||||
opt.as_str = "";
|
||||
rc = amqproc_setopt_1(&opt, clnt);
|
||||
if (!rc || *rc) {
|
||||
fprintf(stderr, "%s: amd on %s cannot flush the map cache\n", progname, server);
|
||||
errs = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mount info
|
||||
*/
|
||||
if (minfo_flag) {
|
||||
int dummy;
|
||||
amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt);
|
||||
if (ml) {
|
||||
int mwid = 0, dwid = 0, twid = 0;
|
||||
show_mi(ml, Calc, &mwid, &dwid, &twid);
|
||||
mwid++;
|
||||
dwid++;
|
||||
twid++;
|
||||
show_mi(ml, Full, &mwid, &dwid, &twid);
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "%s: amd on %s cannot provide mount info\n", progname, server);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mount map
|
||||
*/
|
||||
if (mount_map) {
|
||||
int *rc;
|
||||
do {
|
||||
rc = amqproc_mount_1(&mount_map, clnt);
|
||||
} while (rc && *rc < 0);
|
||||
if (!rc || *rc > 0) {
|
||||
if (rc)
|
||||
errno = *rc;
|
||||
else
|
||||
errno = ETIMEDOUT;
|
||||
fprintf(stderr, "%s: could not start new ", progname);
|
||||
perror("autmount point");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get Version
|
||||
*/
|
||||
if (getvers_flag) {
|
||||
amq_string *spp = amqproc_getvers_1((voidp) 0, clnt);
|
||||
if (spp && *spp) {
|
||||
fputs(*spp, stdout);
|
||||
XFREE(*spp);
|
||||
} else {
|
||||
fprintf(stderr, "%s: failed to get version information\n", progname);
|
||||
errs = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get PID of amd
|
||||
*/
|
||||
if (getpid_flag) {
|
||||
int *ip = amqproc_getpid_1((voidp) 0, clnt);
|
||||
if (ip && *ip) {
|
||||
printf("%d\n", *ip);
|
||||
} else {
|
||||
fprintf(stderr, "%s: failed to get PID of amd\n", progname);
|
||||
errs = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply required operation to all remaining arguments
|
||||
*/
|
||||
if (optind < argc) {
|
||||
do {
|
||||
char *fs = argv[optind++];
|
||||
if (unmount_flag) {
|
||||
/*
|
||||
* Unmount request
|
||||
*/
|
||||
amqproc_umnt_1(&fs, clnt);
|
||||
} else {
|
||||
/*
|
||||
* Stats request
|
||||
*/
|
||||
amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt);
|
||||
if (mtp) {
|
||||
amq_mount_tree *mt = *mtp;
|
||||
if (mt) {
|
||||
int mwid = 0, dwid = 0, twid = 0;
|
||||
show_mt(mt, Calc, &mwid, &dwid, &twid);
|
||||
mwid++;
|
||||
dwid++, twid++;
|
||||
printf("%-*.*s Uid Getattr Lookup RdDir RdLnk Statfs Mounted@\n",
|
||||
dwid, dwid, "What");
|
||||
show_mt(mt, Stats, &mwid, &dwid, &twid);
|
||||
} else {
|
||||
fprintf(stderr, "%s: %s not automounted\n", progname, fs);
|
||||
}
|
||||
xdr_pri_free((XDRPROC_T_TYPE) xdr_amq_mount_tree_p, (caddr_t) mtp);
|
||||
} else {
|
||||
fprintf(stderr, "%s: ", progname);
|
||||
clnt_perror(clnt, server);
|
||||
errs = 1;
|
||||
}
|
||||
}
|
||||
} while (optind < argc);
|
||||
|
||||
} else if (unmount_flag) {
|
||||
goto show_usage;
|
||||
|
||||
} else if (stats_flag) {
|
||||
amq_mount_stats *ms = amqproc_stats_1((voidp) 0, clnt);
|
||||
if (ms) {
|
||||
show_ms(ms);
|
||||
} else {
|
||||
fprintf(stderr, "%s: ", progname);
|
||||
clnt_perror(clnt, server);
|
||||
errs = 1;
|
||||
}
|
||||
|
||||
} else if (!nodefault) {
|
||||
amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt);
|
||||
if (mlp) {
|
||||
enum show_opt e = Calc;
|
||||
int mwid = 0, dwid = 0, pwid = 0;
|
||||
while (e != ShowDone) {
|
||||
int i;
|
||||
for (i = 0; i < mlp->amq_mount_tree_list_len; i++) {
|
||||
show_mt(mlp->amq_mount_tree_list_val[i],
|
||||
e, &mwid, &dwid, &pwid);
|
||||
}
|
||||
mwid++;
|
||||
dwid++, pwid++;
|
||||
if (e == Calc)
|
||||
e = Short;
|
||||
else if (e == Short)
|
||||
e = ShowDone;
|
||||
}
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "%s: ", progname);
|
||||
clnt_perror(clnt, server);
|
||||
errs = 1;
|
||||
}
|
||||
}
|
||||
exit(errs);
|
||||
return errs; /* should never reache here */
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
|
||||
/*
|
||||
* How to bind to reserved ports.
|
||||
* TLI handle (socket) and port version.
|
||||
*/
|
||||
/* defined here so that it does not have to resolve it with libamu.a */
|
||||
static int
|
||||
amq_bind_resv_port(int td, u_short *pp)
|
||||
{
|
||||
int rc = -1, port;
|
||||
struct t_bind *treq, *tret;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
treq = (struct t_bind *) t_alloc(td, T_BIND, T_ADDR);
|
||||
if (!treq) {
|
||||
plog(XLOG_ERROR, "t_alloc 1");
|
||||
return -1;
|
||||
}
|
||||
tret = (struct t_bind *) t_alloc(td, T_BIND, T_ADDR);
|
||||
if (!tret) {
|
||||
t_free((char *) treq, T_BIND);
|
||||
plog(XLOG_ERROR, "t_alloc 2");
|
||||
return -1;
|
||||
}
|
||||
memset((char *) treq->addr.buf, 0, treq->addr.len);
|
||||
sin = (struct sockaddr_in *) treq->addr.buf;
|
||||
sin->sin_family = AF_INET;
|
||||
treq->qlen = 0;
|
||||
treq->addr.len = treq->addr.maxlen;
|
||||
errno = EADDRINUSE;
|
||||
port = IPPORT_RESERVED;
|
||||
|
||||
do {
|
||||
--port;
|
||||
sin->sin_port = htons(port);
|
||||
rc = t_bind(td, treq, tret);
|
||||
if (rc < 0) {
|
||||
} else {
|
||||
if (memcmp(treq->addr.buf, tret->addr.buf, tret->addr.len) == 0)
|
||||
break;
|
||||
else
|
||||
t_unbind(td);
|
||||
}
|
||||
} while ((rc < 0 || errno == EADDRINUSE) && (int) port > IPPORT_RESERVED / 2);
|
||||
|
||||
if (pp) {
|
||||
if (rc == 0)
|
||||
*pp = port;
|
||||
else
|
||||
plog(XLOG_ERROR, "could not t_bind to any reserved port");
|
||||
}
|
||||
t_free((char *) tret, T_BIND);
|
||||
t_free((char *) treq, T_BIND);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a secure rpc client attached to the amd daemon.
|
||||
*/
|
||||
static CLIENT *
|
||||
get_secure_amd_client(char *host, struct timeval *tv, int *sock)
|
||||
{
|
||||
CLIENT *client;
|
||||
struct netbuf nb;
|
||||
struct netconfig *nc, *pm_nc;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
|
||||
nb.maxlen = sizeof(sin);
|
||||
nb.buf = (char *) &sin;
|
||||
|
||||
/*
|
||||
* Ensure that remote portmapper is alive
|
||||
* (must use connectionless netconfig).
|
||||
*/
|
||||
if ((pm_nc = getnetconfigent(NC_UDP)) != NULL) {
|
||||
enum clnt_stat cs;
|
||||
|
||||
cs = rpcb_rmtcall(pm_nc,
|
||||
host,
|
||||
amd_program_number,
|
||||
AMQ_VERSION,
|
||||
AMQPROC_NULL,
|
||||
(XDRPROC_T_TYPE) xdr_void,
|
||||
NULL,
|
||||
(XDRPROC_T_TYPE) xdr_void,
|
||||
NULL,
|
||||
*tv,
|
||||
NULL);
|
||||
if (cs == RPC_TIMEDOUT) {
|
||||
fprintf(stderr, "%s: failed to contact portmapper on host \"%s\". %s\n",
|
||||
progname, host, clnt_sperrno(cs));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* First transport type to try: TCP
|
||||
*/
|
||||
if (use_tcp_flag) {
|
||||
/* Find amd address on TCP */
|
||||
nc = getnetconfigent(NC_TCP);
|
||||
if (!nc) {
|
||||
fprintf(stderr, "getnetconfig for tcp failed: %s\n", nc_sperror());
|
||||
goto tryudp;
|
||||
}
|
||||
|
||||
if (!rpcb_getaddr(amd_program_number, AMQ_VERSION, nc, &nb, host)) {
|
||||
/*
|
||||
* don't pring error messages here, since amd might legitimately
|
||||
* serve udp only
|
||||
*/
|
||||
goto tryudp;
|
||||
}
|
||||
/* Create priviledged TCP socket */
|
||||
*sock = t_open(nc->nc_device, O_RDWR, 0);
|
||||
|
||||
if (*sock < 0) {
|
||||
fprintf(stderr, "t_open %s: %m\n", nc->nc_device);
|
||||
goto tryudp;
|
||||
}
|
||||
if (amq_bind_resv_port(*sock, (u_short *) 0) < 0)
|
||||
goto tryudp;
|
||||
|
||||
client = clnt_vc_create(*sock, &nb, amd_program_number, AMQ_VERSION, 0, 0);
|
||||
if (!client) {
|
||||
fprintf(stderr, "clnt_vc_create failed");
|
||||
t_close(*sock);
|
||||
goto tryudp;
|
||||
}
|
||||
/* tcp succeeded */
|
||||
return client;
|
||||
}
|
||||
|
||||
tryudp:
|
||||
/*
|
||||
* TCP failed so try UDP
|
||||
*/
|
||||
if (use_udp_flag) {
|
||||
/* find amd address on UDP */
|
||||
nc = getnetconfigent(NC_UDP);
|
||||
if (!nc) {
|
||||
fprintf(stderr, "getnetconfig for udp failed: %s\n", nc_sperror());
|
||||
return NULL;
|
||||
}
|
||||
if (!rpcb_getaddr(amd_program_number, AMQ_VERSION, nc, &nb, host)) {
|
||||
fprintf(stderr, "%s\n",
|
||||
clnt_spcreateerror("couldn't get amd address on udp"));
|
||||
return NULL;
|
||||
}
|
||||
/* create priviledged UDP socket */
|
||||
*sock = t_open(nc->nc_device, O_RDWR, 0);
|
||||
|
||||
if (*sock < 0) {
|
||||
fprintf(stderr, "t_open %s: %m\n", nc->nc_device);
|
||||
return NULL; /* neither tcp not udp succeeded */
|
||||
}
|
||||
if (amq_bind_resv_port(*sock, (u_short *) 0) < 0)
|
||||
return NULL;
|
||||
|
||||
client = clnt_dg_create(*sock, &nb, amd_program_number, AMQ_VERSION, 0, 0);
|
||||
if (!client) {
|
||||
fprintf(stderr, "clnt_dg_create failed\n");
|
||||
t_close(*sock);
|
||||
return NULL; /* neither tcp not udp succeeded */
|
||||
}
|
||||
if (clnt_control(client, CLSET_RETRY_TIMEOUT, (char *) tv) == FALSE) {
|
||||
fprintf(stderr, "clnt_control CLSET_RETRY_TIMEOUT for udp failed\n");
|
||||
clnt_destroy(client);
|
||||
return NULL; /* neither tcp not udp succeeded */
|
||||
}
|
||||
/* udp succeeded */
|
||||
return client;
|
||||
}
|
||||
|
||||
/* should never get here */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
/*
|
||||
* inetresport creates a datagram socket and attempts to bind it to a
|
||||
* secure port.
|
||||
* returns: The bound socket, or -1 to indicate an error.
|
||||
*/
|
||||
static int
|
||||
inetresport(int ty)
|
||||
{
|
||||
int alport;
|
||||
struct sockaddr_in addr;
|
||||
int fd;
|
||||
|
||||
/* Use internet address family */
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
if ((fd = socket(AF_INET, ty, 0)) < 0)
|
||||
return -1;
|
||||
|
||||
for (alport = IPPORT_RESERVED - 1; alport > IPPORT_RESERVED / 2 + 1; alport--) {
|
||||
addr.sin_port = htons((u_short) alport);
|
||||
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) >= 0)
|
||||
return fd;
|
||||
if (errno != EADDRINUSE) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Privsock() calls inetresport() to attempt to bind a socket to a secure
|
||||
* port. If inetresport() fails, privsock returns a magic socket number which
|
||||
* indicates to RPC that it should make its own socket.
|
||||
* returns: A privileged socket # or RPC_ANYSOCK.
|
||||
*/
|
||||
static int
|
||||
privsock(int ty)
|
||||
{
|
||||
int sock = inetresport(ty);
|
||||
|
||||
if (sock < 0) {
|
||||
errno = 0;
|
||||
/* Couldn't get a secure port, let RPC make an insecure one */
|
||||
sock = RPC_ANYSOCK;
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
63
contrib/amd/amq/amq.h
Normal file
63
contrib/amd/amq/amq.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 1996/01/13 23:23:39 ezk Exp ezk $
|
||||
*
|
||||
*/
|
||||
|
||||
#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);
|
||||
extern int *amqproc_getpid_1(voidp argp, CLIENT *rqstp);
|
||||
|
||||
#endif /* not _AMQ_H */
|
208
contrib/amd/amq/amq_clnt.c
Normal file
208
contrib/amd/amq/amq_clnt.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_clnt.c,v 5.2.2.1 1992/02/09 15:09:24 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amq.h>
|
||||
|
||||
|
||||
static struct timeval TIMEOUT = {ALLOWED_MOUNT_TIME, 0};
|
||||
|
||||
|
||||
voidp
|
||||
amqproc_null_1(voidp argp, CLIENT *clnt)
|
||||
{
|
||||
static char res;
|
||||
|
||||
memset((char *) &res, 0, sizeof(res));
|
||||
if (clnt_call(clnt, AMQPROC_NULL,
|
||||
(XDRPROC_T_TYPE) xdr_void, argp,
|
||||
(XDRPROC_T_TYPE) xdr_void, &res, TIMEOUT)
|
||||
!= RPC_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
return ((voidp) &res);
|
||||
}
|
||||
|
||||
|
||||
amq_mount_tree_p *
|
||||
amqproc_mnttree_1(amq_string *argp, CLIENT *clnt)
|
||||
{
|
||||
static amq_mount_tree_p res;
|
||||
|
||||
memset((char *) &res, 0, sizeof(res));
|
||||
if (clnt_call(clnt, AMQPROC_MNTTREE,
|
||||
(XDRPROC_T_TYPE) xdr_amq_string, (SVC_IN_ARG_TYPE) argp,
|
||||
(XDRPROC_T_TYPE) xdr_amq_mount_tree_p, (SVC_IN_ARG_TYPE) & res,
|
||||
TIMEOUT) != RPC_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
return (&res);
|
||||
}
|
||||
|
||||
|
||||
voidp
|
||||
amqproc_umnt_1(amq_string *argp, CLIENT *clnt)
|
||||
{
|
||||
static char res;
|
||||
|
||||
memset((char *) &res, 0, sizeof(res));
|
||||
if (clnt_call(clnt, AMQPROC_UMNT,
|
||||
(XDRPROC_T_TYPE) xdr_amq_string, (SVC_IN_ARG_TYPE) argp,
|
||||
(XDRPROC_T_TYPE) xdr_void, &res,
|
||||
TIMEOUT) != RPC_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
return ((voidp) &res);
|
||||
}
|
||||
|
||||
|
||||
amq_mount_stats *
|
||||
amqproc_stats_1(voidp argp, CLIENT *clnt)
|
||||
{
|
||||
static amq_mount_stats res;
|
||||
|
||||
memset((char *) &res, 0, sizeof(res));
|
||||
if (clnt_call(clnt, AMQPROC_STATS,
|
||||
(XDRPROC_T_TYPE) xdr_void, argp,
|
||||
(XDRPROC_T_TYPE) xdr_amq_mount_stats,
|
||||
(SVC_IN_ARG_TYPE) & res,
|
||||
TIMEOUT) != RPC_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
return (&res);
|
||||
}
|
||||
|
||||
|
||||
amq_mount_tree_list *
|
||||
amqproc_export_1(voidp argp, CLIENT *clnt)
|
||||
{
|
||||
static amq_mount_tree_list res;
|
||||
|
||||
memset((char *) &res, 0, sizeof(res));
|
||||
if (clnt_call(clnt, AMQPROC_EXPORT,
|
||||
(XDRPROC_T_TYPE) xdr_void, argp,
|
||||
(XDRPROC_T_TYPE) xdr_amq_mount_tree_list,
|
||||
(SVC_IN_ARG_TYPE) & res, TIMEOUT) != RPC_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
return (&res);
|
||||
}
|
||||
|
||||
|
||||
int *
|
||||
amqproc_setopt_1(amq_setopt *argp, CLIENT *clnt)
|
||||
{
|
||||
static int res;
|
||||
|
||||
memset((char *) &res, 0, sizeof(res));
|
||||
if (clnt_call(clnt, AMQPROC_SETOPT, (XDRPROC_T_TYPE) xdr_amq_setopt,
|
||||
(SVC_IN_ARG_TYPE) argp, (XDRPROC_T_TYPE) xdr_int,
|
||||
(SVC_IN_ARG_TYPE) & res, TIMEOUT) != RPC_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
return (&res);
|
||||
}
|
||||
|
||||
|
||||
amq_mount_info_list *
|
||||
amqproc_getmntfs_1(voidp argp, CLIENT *clnt)
|
||||
{
|
||||
static amq_mount_info_list res;
|
||||
|
||||
memset((char *) &res, 0, sizeof(res));
|
||||
if (clnt_call(clnt, AMQPROC_GETMNTFS, (XDRPROC_T_TYPE) xdr_void, argp,
|
||||
(XDRPROC_T_TYPE) xdr_amq_mount_info_list,
|
||||
(SVC_IN_ARG_TYPE) & res, TIMEOUT) != RPC_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
return (&res);
|
||||
}
|
||||
|
||||
|
||||
int *
|
||||
amqproc_mount_1(voidp argp, CLIENT *clnt)
|
||||
{
|
||||
static int res;
|
||||
|
||||
memset((char *) &res, 0, sizeof(res));
|
||||
if (clnt_call(clnt, AMQPROC_MOUNT, (XDRPROC_T_TYPE) xdr_amq_string, argp,
|
||||
(XDRPROC_T_TYPE) xdr_int, (SVC_IN_ARG_TYPE) & res,
|
||||
TIMEOUT) != RPC_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
return (&res);
|
||||
}
|
||||
|
||||
|
||||
amq_string *
|
||||
amqproc_getvers_1(voidp argp, CLIENT *clnt)
|
||||
{
|
||||
static amq_string res;
|
||||
|
||||
memset((char *) &res, 0, sizeof(res));
|
||||
if (clnt_call(clnt, AMQPROC_GETVERS, (XDRPROC_T_TYPE) xdr_void, argp,
|
||||
(XDRPROC_T_TYPE) xdr_amq_string, (SVC_IN_ARG_TYPE) & res,
|
||||
TIMEOUT) != RPC_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
return (&res);
|
||||
}
|
||||
|
||||
|
||||
int *
|
||||
amqproc_getpid_1(voidp argp, CLIENT *clnt)
|
||||
{
|
||||
static int res;
|
||||
|
||||
memset((char *) &res, 0, sizeof(res));
|
||||
if (clnt_call(clnt, AMQPROC_GETPID, (XDRPROC_T_TYPE) xdr_void, argp,
|
||||
(XDRPROC_T_TYPE) xdr_int, (SVC_IN_ARG_TYPE) & res,
|
||||
TIMEOUT) != RPC_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
return (&res);
|
||||
}
|
259
contrib/amd/amq/amq_xdr.c
Normal file
259
contrib/amd/amq/amq_xdr.c
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 5.2.2.1 1992/02/09 15:09:23 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
#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));
|
||||
}
|
72
contrib/amd/amq/pawd.1
Normal file
72
contrib/amd/amq/pawd.1
Normal file
@ -0,0 +1,72 @@
|
||||
.\"
|
||||
.\" Copyright (c) 1997-1998 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 acknowledgment:
|
||||
.\" 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: pawd.1,v 5.2.2.1 1992/02/09 15:11:15 jsp beta $
|
||||
.\"
|
||||
.TH PAWD 1 "6 Jan 1998"
|
||||
.SH NAME
|
||||
pawd \- print automounter working directory
|
||||
.SH SYNOPSIS
|
||||
.B pawd
|
||||
[
|
||||
.I path ...
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.LP
|
||||
.B pawd
|
||||
is used to print the current working directory, adjusted to reflect proper
|
||||
paths that can be reused to go through the automounter for the shortest
|
||||
possible path. In particular, the path printed back does not include any
|
||||
of
|
||||
.BR Amd 's
|
||||
local mount points. Using them is unsafe, because
|
||||
.B Amd
|
||||
may unmount managed file systems from the mount points, and thus including
|
||||
them in paths may not always find the files within.
|
||||
.P
|
||||
Without any arguments,
|
||||
.B pawd
|
||||
will print the automounter adjusted current working directory. With any
|
||||
number of arguments, it will print the adjusted path of each one of the
|
||||
arguments.
|
||||
.SH "SEE ALSO"
|
||||
.BR amd (8),
|
||||
.BR amq (8),
|
||||
.BR pwd (1).
|
296
contrib/amd/amq/pawd.c
Normal file
296
contrib/amd/amq/pawd.c
Normal file
@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: pawd.c,v 5.2.2.1 1992/02/09 15:09:16 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* pawd is similar to pwd, except that it returns more "natural" versions of
|
||||
* pathnames for directories automounted with the amd automounter. If any
|
||||
* arguments are given, the "more natural" form of the given pathnames are
|
||||
* printed.
|
||||
*
|
||||
* Paul Anderson (paul@ed.lfcs)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amq.h>
|
||||
|
||||
/* dummy variables */
|
||||
char *progname;
|
||||
char hostname[MAXHOSTNAMELEN];
|
||||
int orig_umask, foreground, debug_flags;
|
||||
pid_t mypid;
|
||||
serv_state amd_state;
|
||||
|
||||
/* statics */
|
||||
static char *localhost="localhost";
|
||||
static char newdir[MAXPATHLEN];
|
||||
static char transform[MAXPATHLEN];
|
||||
|
||||
static int
|
||||
find_mt(amq_mount_tree *mt, char *dir)
|
||||
{
|
||||
while (mt) {
|
||||
if (STREQ(mt->mt_type, "link") || STREQ(mt->mt_type, "nfs")) {
|
||||
int len = strlen(mt->mt_mountpoint);
|
||||
if (NSTREQ(mt->mt_mountpoint, dir, len) &&
|
||||
((dir[len] == '\0') || (dir[len] == '/'))) {
|
||||
char tmp_buf[MAXPATHLEN];
|
||||
strcpy(tmp_buf, mt->mt_directory);
|
||||
strcat(tmp_buf, &dir[len]);
|
||||
strcpy(newdir, tmp_buf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (find_mt(mt->mt_next,dir))
|
||||
return 1;
|
||||
mt = mt->mt_child;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
find_mlp(amq_mount_tree_list *mlp, char *dir)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mlp->amq_mount_tree_list_len; i++) {
|
||||
if (find_mt(mlp->amq_mount_tree_list_val[i], dir))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_CNODEID
|
||||
static char *
|
||||
cluster_server(void)
|
||||
{
|
||||
# ifdef HAVE_EXTERN_GETCCENT
|
||||
struct cct_entry *cp;
|
||||
# endif /* HAVE_EXTERN_GETCCENT */
|
||||
|
||||
if (cnodeid() == 0)
|
||||
return localhost;
|
||||
|
||||
# ifdef HAVE_EXTERN_GETCCENT
|
||||
while ((cp = getccent()))
|
||||
if (cp->cnode_type == 'r')
|
||||
return cp->cnode_name;
|
||||
# endif /* HAVE_EXTERN_GETCCENT */
|
||||
|
||||
return localhost;
|
||||
}
|
||||
#endif /* HAVE_CNODEID */
|
||||
|
||||
|
||||
/* DISK_HOME_HACK added by gdmr */
|
||||
#ifdef DISK_HOME_HACK
|
||||
static char *
|
||||
hack_name(char *dir)
|
||||
{
|
||||
char partition[MAXPATHLEN];
|
||||
char username[MAXPATHLEN];
|
||||
char hesiod_lookup[MAXPATHLEN];
|
||||
char *to, *ch, *hes_name, *dot;
|
||||
char **hes;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "hack_name(%s)\n", dir);
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (dir[0] == '/' && dir[1] == 'a' && dir[2] == '/') {
|
||||
/* Could be /a/server/disk/home/partition/user... */
|
||||
ch = dir + 3;
|
||||
while (*ch && *ch != '/') ch++; /* Skip server */
|
||||
if (!NSTREQ(ch, "/disk/home/", 11))
|
||||
return NULL; /* Nope */
|
||||
/* Looking promising, next should be the partition name */
|
||||
ch += 11;
|
||||
to = partition;
|
||||
while (*ch && *ch != '/') *to++ = *ch++;
|
||||
to = '\0';
|
||||
if (!(*ch))
|
||||
return NULL; /* Off the end */
|
||||
/* Now the username */
|
||||
ch++;
|
||||
to = username;
|
||||
while (*ch && *ch != '/') *to++ = *ch++;
|
||||
to = '\0';
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "partition %s, username %s\n", partition, username);
|
||||
#endif /* DEBUG */
|
||||
|
||||
sprintf(hesiod_lookup, "%s.homes-remote", username);
|
||||
hes = hes_resolve(hesiod_lookup, "amd");
|
||||
if (!hes)
|
||||
return NULL;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "hesiod -> <%s>\n", *hes);
|
||||
#endif /* DEBUG */
|
||||
hes_name = strstr(*hes, "/homes/remote/");
|
||||
if (!hes_name) return NULL;
|
||||
hes_name += 14;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "hesiod -> <%s>\n", hes_name);
|
||||
#endif /* DEBUG */
|
||||
dot = hes_name;
|
||||
while (*dot && *dot != '.') dot++;
|
||||
*dot = '\0';
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "hesiod -> <%s>\n", hes_name);
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (strcmp(partition, hes_name)) return NULL;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "A match, munging....\n");
|
||||
#endif /* DEBUG */
|
||||
strcpy(transform, "/home/");
|
||||
strcat(transform, username);
|
||||
if (*ch) strcat(transform, ch);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Munged to <%s>\n", transform);
|
||||
#endif /* DEBUG */
|
||||
return transform;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif /* DISK_HOME_HACK */
|
||||
|
||||
|
||||
/*
|
||||
* The routine transform_dir(path) transforms pathnames of directories
|
||||
* mounted with the amd automounter to produce a more "natural" version.
|
||||
* The automount table is obtained from the local amd via the rpc interface
|
||||
* and reverse lookups are repeatedly performed on the directory name
|
||||
* substituting the name of the automount link for the value of the link
|
||||
* whenever it occurs as a prefix of the directory name.
|
||||
*/
|
||||
static char *
|
||||
transform_dir(char *dir)
|
||||
{
|
||||
#ifdef DISK_HOME_HACK
|
||||
char *ch;
|
||||
#endif /* DISK_HOME_HACK */
|
||||
char *server;
|
||||
struct sockaddr_in server_addr;
|
||||
int s = RPC_ANYSOCK;
|
||||
CLIENT *clnt;
|
||||
struct hostent *hp;
|
||||
amq_mount_tree_list *mlp;
|
||||
struct timeval tmo = {10, 0};
|
||||
|
||||
#ifdef DISK_HOME_HACK
|
||||
if (ch = hack_name(dir))
|
||||
return ch;
|
||||
#endif /* DISK_HOME_HACK */
|
||||
|
||||
#ifdef HAVE_CNODEID
|
||||
server = cluster_server();
|
||||
#else /* not HAVE_CNODEID */
|
||||
server = localhost;
|
||||
#endif /* not HAVE_CNODEID */
|
||||
|
||||
if ((hp = gethostbyname(server)) == 0)
|
||||
return dir;
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr = *(struct in_addr *) hp->h_addr;
|
||||
|
||||
clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, tmo, &s);
|
||||
if (clnt == 0)
|
||||
return dir;
|
||||
|
||||
strcpy(transform,dir);
|
||||
while ( (mlp = amqproc_export_1((voidp)0, clnt)) &&
|
||||
find_mlp(mlp,transform) ) {
|
||||
strcpy(transform,newdir);
|
||||
}
|
||||
return transform;
|
||||
}
|
||||
|
||||
|
||||
/* getawd() is a substitute for getwd() which transforms the path */
|
||||
static char *
|
||||
getawd(char *path)
|
||||
{
|
||||
#ifdef HAVE_GETCWD
|
||||
char *wd = getcwd(path, MAXPATHLEN+1);
|
||||
#else /* not HAVE_GETCWD */
|
||||
char *wd = getwd(path);
|
||||
#endif /* not HAVE_GETCWD */
|
||||
|
||||
if (wd == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
strcpy(path, transform_dir(wd));
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char tmp_buf[MAXPATHLEN], *wd;
|
||||
|
||||
if (argc == 1) {
|
||||
wd = getawd(tmp_buf);
|
||||
if (wd == NULL) {
|
||||
fprintf(stderr, "pawd: %s\n", tmp_buf);
|
||||
exit(1);
|
||||
} else {
|
||||
fprintf(stdout, "%s\n", wd);
|
||||
}
|
||||
} else {
|
||||
while (--argc) {
|
||||
wd = transform_dir(*++argv);
|
||||
fprintf(stdout, "%s\n", wd);
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
78
contrib/amd/conf/checkmount/checkmount_bsd44.c
Normal file
78
contrib/amd/conf/checkmount/checkmount_bsd44.c
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: checkmount_bsd44.c,v 5.2.2.2 1992/05/31 16:35:45 jsp 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);
|
||||
|
||||
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;
|
||||
}
|
2
contrib/amd/conf/fh_dref/fh_dref_freebsd22.h
Normal file
2
contrib/amd/conf/fh_dref/fh_dref_freebsd22.h
Normal file
@ -0,0 +1,2 @@
|
||||
/* $srcdir/conf/fh_dref/fh_dref_freebsd22.h */
|
||||
#define NFS_FH_DREF(dst, src) (dst) = (u_char *) (src)
|
2
contrib/amd/conf/hn_dref/hn_dref_default.h
Normal file
2
contrib/amd/conf/hn_dref/hn_dref_default.h
Normal file
@ -0,0 +1,2 @@
|
||||
/* $srcdir/conf/hn_dref/hn_dref_default.h */
|
||||
#define NFS_HN_DREF(dst, src) (dst) = (src)
|
68
contrib/amd/conf/mount/mount_freebsd3.c
Normal file
68
contrib/amd/conf/mount/mount_freebsd3.c
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_freebsd3.c,v 5.2.2.1 1992/02/09 15:10:08 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* FreeBSD 3.x (as of snapshot 3.0-980311-SNAP) Mount helper
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <amu.h>
|
||||
|
||||
/*
|
||||
* Map from conventional mount arguments
|
||||
* to FreeBSD 3.0 style arguments.
|
||||
*/
|
||||
int
|
||||
mount_freebsd3(MTYPE_TYPE type, const char *dir, int flags, voidp data)
|
||||
{
|
||||
char const *namelist[] = INITMOUNTNAMES;
|
||||
|
||||
return mount(namelist[type],
|
||||
dir,
|
||||
flags,
|
||||
data);
|
||||
}
|
145
contrib/amd/conf/mtab/mtab_bsd.c
Normal file
145
contrib/amd/conf/mtab/mtab_bsd.c
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: mtab_bsd.c,v 5.2.2.2 1992/11/12 23:29:14 jsp 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, const char *mnttabname)
|
||||
{
|
||||
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;
|
||||
}
|
146
contrib/amd/conf/nfs_prot/nfs_prot_freebsd2.h
Normal file
146
contrib/amd/conf/nfs_prot/nfs_prot_freebsd2.h
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: nfs_prot_freebsd2.h,v 1.1 1996/01/13 23:23:39 ezk Exp ezk $
|
||||
*
|
||||
*/
|
||||
|
||||
#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 */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
||||
/*
|
||||
* FreeBSD 2.2.x has NFS V3, but it does not define enough macros
|
||||
* in the headers to automatically detect it.
|
||||
* So fake it in the meant time.
|
||||
*/
|
||||
#if 0
|
||||
#define MOUNT_NFS3 MOUNT_NFS
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* not _AMU_NFS_PROT_H */
|
211
contrib/amd/conf/nfs_prot/nfs_prot_freebsd3.h
Normal file
211
contrib/amd/conf/nfs_prot/nfs_prot_freebsd3.h
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: nfs_prot_freebsd3.h,v 1.1 1996/01/13 23:23:39 ezk Exp ezk $
|
||||
*
|
||||
*/
|
||||
|
||||
#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 */
|
||||
#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;
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* FreeBSD 3.0 has NFS V3, but you need to regenrate the rpcsc header files
|
||||
* as follows:
|
||||
* cd /usr/local/rpcsvc
|
||||
* rpcgen -DWANT_NFS3 mount.x
|
||||
* rpcgen -DWANT_NFS3 nfs_prot.x
|
||||
* But that's not expected of everyone, plus there are additional things
|
||||
* needed 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 */
|
5
contrib/amd/conf/sa_dref/sa_dref_bsd44.h
Normal file
5
contrib/amd/conf/sa_dref/sa_dref_bsd44.h
Normal file
@ -0,0 +1,5 @@
|
||||
/* $srcdir/conf/sa_dref/sa_dref_bsd44.h */
|
||||
#define NFS_SA_DREF(dst, src) { \
|
||||
(dst)->addr = (struct sockaddr *) (src); \
|
||||
(dst)->addrlen = sizeof(*src); \
|
||||
}
|
399
contrib/amd/conf/transp/transp_sockets.c
Normal file
399
contrib/amd/conf/transp/transp_sockets.c
Normal file
@ -0,0 +1,399 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: transp_sockets.c,v 5.2.2.2 1992/07/18 18:57:03 jsp Exp jsp $
|
||||
*
|
||||
* 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 descriptor, 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 */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Ping the portmapper on a remote system by calling the nullproc
|
||||
*/
|
||||
enum clnt_stat
|
||||
pmap_ping(struct sockaddr_in *address)
|
||||
{
|
||||
CLIENT *client;
|
||||
enum clnt_stat clnt_stat = RPC_TIMEDOUT; /* assume failure */
|
||||
int socket = RPC_ANYSOCK;
|
||||
struct timeval timeout;
|
||||
|
||||
timeout.tv_sec = 3;
|
||||
timeout.tv_usec = 0;
|
||||
address->sin_port = htons(PMAPPORT);
|
||||
client = clntudp_create(address, PMAPPROG, PMAPVERS, timeout, &socket);
|
||||
if (client != (CLIENT *) NULL) {
|
||||
clnt_stat = clnt_call(client,
|
||||
PMAPPROC_NULL,
|
||||
(XDRPROC_T_TYPE) xdr_void,
|
||||
NULL,
|
||||
(XDRPROC_T_TYPE) xdr_void,
|
||||
NULL,
|
||||
timeout);
|
||||
clnt_destroy(client);
|
||||
}
|
||||
close(socket);
|
||||
address->sin_port = 0;
|
||||
|
||||
return clnt_stat;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 = 3; /* retry every 3 seconds, but also timeout */
|
||||
tv.tv_usec = 0;
|
||||
|
||||
/*
|
||||
* First check if remote portmapper is up (verify if remote host is up).
|
||||
*/
|
||||
clnt_stat = pmap_ping(sin);
|
||||
if (clnt_stat == RPC_TIMEDOUT) {
|
||||
plog(XLOG_ERROR, "get_nfs_version: failed to contact portmapper on host \"%s\": %s", host, clnt_sperrno(clnt_stat));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FS_NFS3
|
||||
try_again:
|
||||
#endif /* HAVE_FS_NFS3 */
|
||||
|
||||
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) {
|
||||
#ifdef HAVE_CLNT_SPCREATEERROR
|
||||
plog(XLOG_INFO, "get_nfs_version NFS(%d,%s) failed for %s :%s",
|
||||
nfs_version, proto, host, clnt_spcreateerror(""));
|
||||
#else /* not HAVE_CLNT_SPCREATEERROR */
|
||||
plog(XLOG_INFO, "get_nfs_version NFS(%d,%s) failed for %s",
|
||||
nfs_version, proto, host);
|
||||
#endif /* not HAVE_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_TYPE) xdr_void,
|
||||
0,
|
||||
(XDRPROC_T_TYPE) 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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* AUTOFS FUNCTIONS FOR SOCKETS:
|
||||
*/
|
||||
#ifdef HAVE_FS_AUTOFS
|
||||
/*
|
||||
* Create the nfs service for amd
|
||||
*/
|
||||
int
|
||||
create_autofs_service(int *soAUTOFSp, u_short *autofs_portp, SVCXPRT **autofs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp))
|
||||
{
|
||||
/* NOT IMPLEMENTED! */
|
||||
return -1;
|
||||
}
|
||||
#endif /* HAVE_FS_AUTOFS */
|
2
contrib/amd/conf/trap/trap_default.h
Normal file
2
contrib/amd/conf/trap/trap_default.h
Normal file
@ -0,0 +1,2 @@
|
||||
/* $srcdir/conf/trap/trap_default.h */
|
||||
#define MOUNT_TRAP(type, mnt, flags, mnt_data) mount(type, mnt->mnt_dir, flags, mnt_data)
|
3
contrib/amd/conf/trap/trap_freebsd3.h
Normal file
3
contrib/amd/conf/trap/trap_freebsd3.h
Normal file
@ -0,0 +1,3 @@
|
||||
/* $srcdir/conf/trap/trap_freebsd3.h */
|
||||
extern int mount_freebsd3(MTYPE_TYPE type, const char *dir, int flags, voidp data);
|
||||
#define MOUNT_TRAP(type, mnt, flags, mnt_data) mount_freebsd3(type, mnt->mnt_dir, flags, mnt_data)
|
89
contrib/amd/conf/umount/umount_bsd44.c
Normal file
89
contrib/amd/conf/umount/umount_bsd44.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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_bsd44.c,v 5.2.2.2 1993/01/27 07:32:45 jsp 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, const char *mnttabname)
|
||||
{
|
||||
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;
|
||||
}
|
7816
contrib/amd/doc/am-utils.texi
Normal file
7816
contrib/amd/doc/am-utils.texi
Normal file
File diff suppressed because it is too large
Load Diff
3
contrib/amd/doc/stamp-vti
Normal file
3
contrib/amd/doc/stamp-vti
Normal file
@ -0,0 +1,3 @@
|
||||
@set UPDATED 22 April 1998
|
||||
@set EDITION 6.0a16
|
||||
@set VERSION 6.0a16
|
4935
contrib/amd/doc/texinfo.tex
Normal file
4935
contrib/amd/doc/texinfo.tex
Normal file
File diff suppressed because it is too large
Load Diff
3
contrib/amd/doc/version.texi
Normal file
3
contrib/amd/doc/version.texi
Normal file
@ -0,0 +1,3 @@
|
||||
@set UPDATED 22 April 1998
|
||||
@set EDITION 6.0a16
|
||||
@set VERSION 6.0a16
|
159
contrib/amd/fixmount/fixmount.8
Normal file
159
contrib/amd/fixmount/fixmount.8
Normal file
@ -0,0 +1,159 @@
|
||||
.\"
|
||||
.\" Copyright (c) 1997-1998 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 acknowledgment:
|
||||
.\" 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.8,v 5.2.2.1 1992/02/09 15:11:15 jsp beta $
|
||||
.\"
|
||||
.TH FIXMOUNT 8L "26 Feb 1993"
|
||||
.SH NAME
|
||||
fixmount \- fix remote mount entries
|
||||
.SH SYNOPSIS
|
||||
.B 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
|
||||
.TP
|
||||
.B \-a \-d \-e
|
||||
These 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"
|
||||
.BR showmount (8),
|
||||
.BR mtab (5),
|
||||
.BR rmtab (5),
|
||||
.BR 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.
|
612
contrib/amd/fixmount/fixmount.c
Normal file
612
contrib/amd/fixmount/fixmount.c
Normal file
@ -0,0 +1,612 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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 5.2.2.2 1992/05/31 16:35:45 jsp 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
|
||||
|
||||
extern int fixmount_check_mount(char *host, struct in_addr hostaddr, char *path);
|
||||
|
||||
static char dir_path[NFS_MAXPATHLEN];
|
||||
static char localhost[] = "localhost";
|
||||
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;
|
||||
static CLIENT *clnt_create_timeout(char *, struct timeval *);
|
||||
|
||||
RETSIGTYPE create_timeout(int);
|
||||
int is_same_host(char *, char *, struct in_addr);
|
||||
int main(int, char *[]);
|
||||
int remove_all(CLIENT *, char *);
|
||||
int remove_mount(CLIENT *, char *, mountlist, int);
|
||||
void fix_rmtab(CLIENT *, char *, mountlist, int, int);
|
||||
void print_dump(mountlist);
|
||||
void usage(void);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
||||
#ifndef HAVE_TRANSPORT_TYPE_TLI
|
||||
/*
|
||||
* inetresport creates a datagram socket and attempts to bind it to a
|
||||
* secure port.
|
||||
* returns: The bound socket, or -1 to indicate an error.
|
||||
*/
|
||||
static int
|
||||
inetresport(int ty)
|
||||
{
|
||||
int alport;
|
||||
struct sockaddr_in addr;
|
||||
int fd;
|
||||
|
||||
/* Use internet address family */
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
if ((fd = socket(AF_INET, ty, 0)) < 0)
|
||||
return -1;
|
||||
|
||||
for (alport = IPPORT_RESERVED - 1; alport > IPPORT_RESERVED / 2 + 1; alport--) {
|
||||
addr.sin_port = htons((u_short) alport);
|
||||
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) >= 0)
|
||||
return fd;
|
||||
if (errno != EADDRINUSE) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Privsock() calls inetresport() to attempt to bind a socket to a secure
|
||||
* port. If inetresport() fails, privsock returns a magic socket number which
|
||||
* indicates to RPC that it should make its own socket.
|
||||
* returns: A privileged socket # or RPC_ANYSOCK.
|
||||
*/
|
||||
static int
|
||||
privsock(int ty)
|
||||
{
|
||||
int sock = inetresport(ty);
|
||||
|
||||
if (sock < 0) {
|
||||
errno = 0;
|
||||
/* Couldn't get a secure port, let RPC make an insecure one */
|
||||
sock = RPC_ANYSOCK;
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
|
||||
static CLIENT *
|
||||
clnt_create_timeout(char *host, struct timeval *tvp)
|
||||
{
|
||||
CLIENT *clnt;
|
||||
struct sockaddr_in host_addr;
|
||||
struct hostent *hp;
|
||||
#ifndef HAVE_TRANSPORT_TYPE_TLI
|
||||
int s;
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
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(tvp->tv_sec * 1000000 + tvp->tv_usec, 0);
|
||||
|
||||
/*
|
||||
* Get address of host
|
||||
*/
|
||||
if ((hp = gethostbyname(host)) == 0 && !STREQ(host, localhost)) {
|
||||
fprintf(stderr, "can't get address of %s\n", host);
|
||||
return NULL;
|
||||
}
|
||||
memset(&host_addr, 0, sizeof host_addr);
|
||||
host_addr.sin_family = AF_INET;
|
||||
if (hp) {
|
||||
memmove((voidp) &host_addr.sin_addr, (voidp) hp->h_addr,
|
||||
sizeof(host_addr.sin_addr));
|
||||
} else {
|
||||
/* fake "localhost" */
|
||||
host_addr.sin_addr.s_addr = htonl(0x7f000001);
|
||||
}
|
||||
|
||||
#ifdef HAVE_TRANSPORT_TYPE_TLI
|
||||
/* try TCP first (in case return data is large), then UDP */
|
||||
clnt = clnt_create(host, MOUNTPROG, MOUNTVERS, "tcp");
|
||||
if (!clnt)
|
||||
clnt = clnt_create(host, MOUNTPROG, MOUNTVERS, "udp");
|
||||
#else /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
s = RPC_ANYSOCK;
|
||||
clnt = clnttcp_create(&host_addr, MOUNTPROG, MOUNTVERS, &s, 0, 0);
|
||||
if (!clnt) {
|
||||
/* XXX: do we need to close(s) ? */
|
||||
s = privsock(SOCK_DGRAM);
|
||||
clnt = clntudp_create(&host_addr, MOUNTPROG, MOUNTVERS, *tvp, &s);
|
||||
}
|
||||
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
|
||||
|
||||
if (!clnt) {
|
||||
ualarm(0, 0);
|
||||
if (!quiet) {
|
||||
clnt_pcreateerror(host);
|
||||
fflush(stderr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ualarm(0, 0);
|
||||
return clnt;
|
||||
}
|
670
contrib/amd/fsinfo/fsi_analyze.c
Normal file
670
contrib/amd/fsinfo/fsi_analyze.c
Normal file
@ -0,0 +1,670 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: fsi_analyze.c,v 5.2.2.1 1992/02/09 15:09:41 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Analyze filesystem declarations
|
||||
*
|
||||
* Note: most of this is magic!
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <fsi_data.h>
|
||||
#include <fsinfo.h>
|
||||
|
||||
char *disk_fs_strings[] =
|
||||
{
|
||||
"fstype", "opts", "dumpset", "passno", "freq", "mount", "log", 0,
|
||||
};
|
||||
|
||||
char *mount_strings[] =
|
||||
{
|
||||
"volname", "exportfs", 0,
|
||||
};
|
||||
|
||||
char *fsmount_strings[] =
|
||||
{
|
||||
"as", "volname", "fstype", "opts", "from", 0,
|
||||
};
|
||||
|
||||
char *host_strings[] =
|
||||
{
|
||||
"host", "netif", "config", "arch", "cluster", "os", 0,
|
||||
};
|
||||
|
||||
char *ether_if_strings[] =
|
||||
{
|
||||
"inaddr", "netmask", "hwaddr", 0,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
void
|
||||
domain_strip(char *otherdom, char *localdom)
|
||||
{
|
||||
char *p1, *p2;
|
||||
|
||||
if ((p1 = strchr(otherdom, '.')) &&
|
||||
(p2 = strchr(localdom, '.')) &&
|
||||
STREQ(p1 + 1, p2 + 1))
|
||||
*p1 = '\0';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Take a little-endian domain name and
|
||||
* transform into a big-endian Un*x pathname.
|
||||
* For example: kiska.doc.ic -> ic/doc/kiska
|
||||
*/
|
||||
static char *
|
||||
compute_hostpath(char *hn)
|
||||
{
|
||||
char *p = strdup(hn);
|
||||
char *d;
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
domain_strip(p, hostname);
|
||||
path[0] = '\0';
|
||||
|
||||
do {
|
||||
d = strrchr(p, '.');
|
||||
if (d) {
|
||||
*d = 0;
|
||||
strcat(path, d + 1);
|
||||
strcat(path, "/");
|
||||
} else {
|
||||
strcat(path, p);
|
||||
}
|
||||
} while (d);
|
||||
|
||||
log("hostpath of '%s' is '%s'", hn, path);
|
||||
|
||||
strcpy(p, path);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
static dict_ent *
|
||||
find_volname(char *nn)
|
||||
{
|
||||
dict_ent *de;
|
||||
char *p = strdup(nn);
|
||||
char *q;
|
||||
|
||||
do {
|
||||
log("Searching for volname %s", p);
|
||||
de = dict_locate(dict_of_volnames, p);
|
||||
q = strrchr(p, '/');
|
||||
if (q)
|
||||
*q = '\0';
|
||||
} while (!de && q);
|
||||
|
||||
XFREE(p);
|
||||
return de;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
show_required(ioloc *l, int mask, char *info, char *hostname, char *strings[])
|
||||
{
|
||||
int i;
|
||||
log("mask left for %s:%s is %#x", hostname, info, mask);
|
||||
|
||||
for (i = 0; strings[i]; i++)
|
||||
if (ISSET(mask, i))
|
||||
lerror(l, "%s:%s needs field \"%s\"", hostname, info, strings[i]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check and fill in "exportfs" details.
|
||||
* Make sure the m_exported field references
|
||||
* the most local node with an "exportfs" entry.
|
||||
*/
|
||||
static int
|
||||
check_exportfs(qelem *q, fsi_mount *e)
|
||||
{
|
||||
fsi_mount *mp;
|
||||
int errors = 0;
|
||||
|
||||
ITER(mp, fsi_mount, q) {
|
||||
if (ISSET(mp->m_mask, DM_EXPORTFS)) {
|
||||
if (e)
|
||||
lwarning(mp->m_ioloc, "%s has duplicate exportfs data", mp->m_name);
|
||||
mp->m_exported = mp;
|
||||
if (!ISSET(mp->m_mask, DM_VOLNAME))
|
||||
set_mount(mp, DM_VOLNAME, strdup(mp->m_name));
|
||||
} else {
|
||||
mp->m_exported = e;
|
||||
}
|
||||
|
||||
/*
|
||||
* Recursively descend the mount tree
|
||||
*/
|
||||
if (mp->m_mount)
|
||||
errors += check_exportfs(mp->m_mount, mp->m_exported);
|
||||
|
||||
/*
|
||||
* If a volume name has been specified, but this node and none
|
||||
* of its parents has been exported, report an error.
|
||||
*/
|
||||
if (ISSET(mp->m_mask, DM_VOLNAME) && !mp->m_exported) {
|
||||
lerror(mp->m_ioloc, "%s has a volname but no exportfs data", mp->m_name);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
analyze_dkmount_tree(qelem *q, fsi_mount *parent, disk_fs *dk)
|
||||
{
|
||||
fsi_mount *mp;
|
||||
int errors = 0;
|
||||
|
||||
ITER(mp, fsi_mount, q) {
|
||||
log("Mount %s:", mp->m_name);
|
||||
if (parent) {
|
||||
char n[MAXPATHLEN];
|
||||
sprintf(n, "%s/%s", parent->m_name, mp->m_name);
|
||||
if (*mp->m_name == '/')
|
||||
lerror(mp->m_ioloc, "sub-directory %s of %s starts with '/'", mp->m_name, parent->m_name);
|
||||
else if (STREQ(mp->m_name, "default"))
|
||||
lwarning(mp->m_ioloc, "sub-directory of %s is named \"default\"", parent->m_name);
|
||||
log("Changing name %s to %s", mp->m_name, n);
|
||||
XFREE(mp->m_name);
|
||||
mp->m_name = strdup(n);
|
||||
}
|
||||
|
||||
mp->m_name_len = strlen(mp->m_name);
|
||||
mp->m_parent = parent;
|
||||
mp->m_dk = dk;
|
||||
if (mp->m_mount)
|
||||
analyze_dkmount_tree(mp->m_mount, mp, dk);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The mount tree is a singleton list
|
||||
* containing the top-level mount
|
||||
* point for a disk.
|
||||
*/
|
||||
static int
|
||||
analyze_dkmounts(disk_fs *dk, qelem *q)
|
||||
{
|
||||
int errors = 0;
|
||||
fsi_mount *mp, *mp2 = 0;
|
||||
int i = 0;
|
||||
|
||||
/*
|
||||
* First scan the list of subdirs to make
|
||||
* sure there is only one - and remember it
|
||||
*/
|
||||
if (q) {
|
||||
ITER(mp, fsi_mount, q) {
|
||||
mp2 = mp;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check...
|
||||
*/
|
||||
if (i < 1) {
|
||||
lerror(dk->d_ioloc, "%s:%s has no mount point", dk->d_host->h_hostname, dk->d_dev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (i > 1) {
|
||||
lerror(dk->d_ioloc, "%s:%s has more than one mount point", dk->d_host->h_hostname, dk->d_dev);
|
||||
errors++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now see if a default mount point is required
|
||||
*/
|
||||
if (STREQ(mp2->m_name, "default")) {
|
||||
if (ISSET(mp2->m_mask, DM_VOLNAME)) {
|
||||
char nbuf[1024];
|
||||
compute_automount_point(nbuf, dk->d_host, mp2->m_volname);
|
||||
XFREE(mp2->m_name);
|
||||
mp2->m_name = strdup(nbuf);
|
||||
log("%s:%s has default mount on %s", dk->d_host->h_hostname, dk->d_dev, mp2->m_name);
|
||||
} else {
|
||||
lerror(dk->d_ioloc, "no volname given for %s:%s", dk->d_host->h_hostname, dk->d_dev);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the disk mount point
|
||||
*/
|
||||
if (!errors && mp2 && mp2->m_name)
|
||||
dk->d_mountpt = strdup(mp2->m_name);
|
||||
else
|
||||
dk->d_mountpt = strdup("error");
|
||||
|
||||
/*
|
||||
* Analyze the mount tree
|
||||
*/
|
||||
errors += analyze_dkmount_tree(q, 0, dk);
|
||||
|
||||
/*
|
||||
* Analyze the export tree
|
||||
*/
|
||||
errors += check_exportfs(q, 0);
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fixup_required_disk_info(disk_fs *dp)
|
||||
{
|
||||
/*
|
||||
* "fstype"
|
||||
*/
|
||||
if (ISSET(dp->d_mask, DF_FSTYPE)) {
|
||||
if (STREQ(dp->d_fstype, "swap")) {
|
||||
|
||||
/*
|
||||
* Fixup for a swap device
|
||||
*/
|
||||
if (!ISSET(dp->d_mask, DF_PASSNO)) {
|
||||
dp->d_passno = 0;
|
||||
BITSET(dp->d_mask, DF_PASSNO);
|
||||
} else if (dp->d_freq != 0) {
|
||||
lwarning(dp->d_ioloc,
|
||||
"Pass number for %s:%s is non-zero",
|
||||
dp->d_host->h_hostname, dp->d_dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* "freq"
|
||||
*/
|
||||
if (!ISSET(dp->d_mask, DF_FREQ)) {
|
||||
dp->d_freq = 0;
|
||||
BITSET(dp->d_mask, DF_FREQ);
|
||||
} else if (dp->d_freq != 0) {
|
||||
lwarning(dp->d_ioloc,
|
||||
"dump frequency for %s:%s is non-zero",
|
||||
dp->d_host->h_hostname, dp->d_dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* "opts"
|
||||
*/
|
||||
if (!ISSET(dp->d_mask, DF_OPTS))
|
||||
set_disk_fs(dp, DF_OPTS, strdup("swap"));
|
||||
|
||||
/*
|
||||
* "mount"
|
||||
*/
|
||||
if (!ISSET(dp->d_mask, DF_MOUNT)) {
|
||||
qelem *q = new_que();
|
||||
fsi_mount *m = new_mount();
|
||||
|
||||
m->m_name = strdup("swap");
|
||||
m->m_mount = new_que();
|
||||
ins_que(&m->m_q, q->q_back);
|
||||
dp->d_mount = q;
|
||||
BITSET(dp->d_mask, DF_MOUNT);
|
||||
} else {
|
||||
lerror(dp->d_ioloc, "%s: mount field specified for swap partition", dp->d_host->h_hostname);
|
||||
}
|
||||
} else if (STREQ(dp->d_fstype, "export")) {
|
||||
|
||||
/*
|
||||
* "passno"
|
||||
*/
|
||||
if (!ISSET(dp->d_mask, DF_PASSNO)) {
|
||||
dp->d_passno = 0;
|
||||
BITSET(dp->d_mask, DF_PASSNO);
|
||||
} else if (dp->d_passno != 0) {
|
||||
lwarning(dp->d_ioloc,
|
||||
"pass number for %s:%s is non-zero",
|
||||
dp->d_host->h_hostname, dp->d_dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* "freq"
|
||||
*/
|
||||
if (!ISSET(dp->d_mask, DF_FREQ)) {
|
||||
dp->d_freq = 0;
|
||||
BITSET(dp->d_mask, DF_FREQ);
|
||||
} else if (dp->d_freq != 0) {
|
||||
lwarning(dp->d_ioloc,
|
||||
"dump frequency for %s:%s is non-zero",
|
||||
dp->d_host->h_hostname, dp->d_dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* "opts"
|
||||
*/
|
||||
if (!ISSET(dp->d_mask, DF_OPTS))
|
||||
set_disk_fs(dp, DF_OPTS, strdup("rw,defaults"));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fixup_required_mount_info(fsmount *fp, dict_ent *de)
|
||||
{
|
||||
if (!ISSET(fp->f_mask, FM_FROM)) {
|
||||
if (de->de_count != 1) {
|
||||
lerror(fp->f_ioloc, "ambiguous mount: %s is a replicated filesystem", fp->f_volname);
|
||||
} else {
|
||||
dict_data *dd;
|
||||
fsi_mount *mp = 0;
|
||||
dd = AM_FIRST(dict_data, &de->de_q);
|
||||
mp = (fsi_mount *) dd->dd_data;
|
||||
if (!mp)
|
||||
abort();
|
||||
fp->f_ref = mp;
|
||||
set_fsmount(fp, FM_FROM, mp->m_dk->d_host->h_hostname);
|
||||
log("set: %s comes from %s", fp->f_volname, fp->f_from);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ISSET(fp->f_mask, FM_FSTYPE)) {
|
||||
set_fsmount(fp, FM_FSTYPE, strdup("nfs"));
|
||||
log("set: fstype is %s", fp->f_fstype);
|
||||
}
|
||||
|
||||
if (!ISSET(fp->f_mask, FM_OPTS)) {
|
||||
set_fsmount(fp, FM_OPTS, strdup("rw,nosuid,grpid,defaults"));
|
||||
log("set: opts are %s", fp->f_opts);
|
||||
}
|
||||
|
||||
if (!ISSET(fp->f_mask, FM_LOCALNAME)) {
|
||||
if (fp->f_ref) {
|
||||
set_fsmount(fp, FM_LOCALNAME, strdup(fp->f_volname));
|
||||
log("set: localname is %s", fp->f_localname);
|
||||
} else {
|
||||
lerror(fp->f_ioloc, "cannot determine localname since volname %s is not uniquely defined", fp->f_volname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* For each disk on a host
|
||||
* analyze the mount information
|
||||
* and fill in any derivable
|
||||
* details.
|
||||
*/
|
||||
static void
|
||||
analyze_drives(host *hp)
|
||||
{
|
||||
qelem *q = hp->h_disk_fs;
|
||||
disk_fs *dp;
|
||||
|
||||
ITER(dp, disk_fs, q) {
|
||||
int req;
|
||||
log("Disk %s:", dp->d_dev);
|
||||
dp->d_host = hp;
|
||||
fixup_required_disk_info(dp);
|
||||
req = ~dp->d_mask & DF_REQUIRED;
|
||||
if (req)
|
||||
show_required(dp->d_ioloc, req, dp->d_dev, hp->h_hostname, disk_fs_strings);
|
||||
analyze_dkmounts(dp, dp->d_mount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check that all static mounts make sense and
|
||||
* that the source volumes exist.
|
||||
*/
|
||||
static void
|
||||
analyze_mounts(host *hp)
|
||||
{
|
||||
qelem *q = hp->h_mount;
|
||||
fsmount *fp;
|
||||
int netbootp = 0;
|
||||
|
||||
ITER(fp, fsmount, q) {
|
||||
char *p;
|
||||
char *nn = strdup(fp->f_volname);
|
||||
int req;
|
||||
dict_ent *de = (dict_ent *) NULL;
|
||||
int found = 0;
|
||||
int matched = 0;
|
||||
|
||||
if (ISSET(fp->f_mask, FM_DIRECT)) {
|
||||
found = 1;
|
||||
matched = 1;
|
||||
} else
|
||||
do {
|
||||
p = 0;
|
||||
de = find_volname(nn);
|
||||
log("Mount: %s (trying %s)", fp->f_volname, nn);
|
||||
|
||||
if (de) {
|
||||
found = 1;
|
||||
|
||||
/*
|
||||
* Check that the from field is really exporting
|
||||
* the filesystem requested.
|
||||
* LBL: If fake mount, then don't care about
|
||||
* consistency check.
|
||||
*/
|
||||
if (ISSET(fp->f_mask, FM_FROM) && !ISSET(fp->f_mask, FM_DIRECT)) {
|
||||
dict_data *dd;
|
||||
fsi_mount *mp2 = 0;
|
||||
|
||||
ITER(dd, dict_data, &de->de_q) {
|
||||
fsi_mount *mp = (fsi_mount *) dd->dd_data;
|
||||
|
||||
if (STREQ(mp->m_dk->d_host->h_hostname, fp->f_from)) {
|
||||
mp2 = mp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mp2) {
|
||||
fp->f_ref = mp2;
|
||||
matched = 1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
matched = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
p = strrchr(nn, '/');
|
||||
if (p)
|
||||
*p = 0;
|
||||
} while (de && p);
|
||||
XFREE(nn);
|
||||
|
||||
if (!found) {
|
||||
lerror(fp->f_ioloc, "volname %s unknown", fp->f_volname);
|
||||
} else if (matched) {
|
||||
|
||||
fixup_required_mount_info(fp, de);
|
||||
req = ~fp->f_mask & FM_REQUIRED;
|
||||
if (req) {
|
||||
show_required(fp->f_ioloc, req, fp->f_volname, hp->h_hostname,
|
||||
fsmount_strings);
|
||||
} else if (STREQ(fp->f_localname, "/")) {
|
||||
hp->h_netroot = fp;
|
||||
netbootp |= FM_NETROOT;
|
||||
} else if (STREQ(fp->f_localname, "swap")) {
|
||||
hp->h_netswap = fp;
|
||||
netbootp |= FM_NETSWAP;
|
||||
}
|
||||
|
||||
} else {
|
||||
lerror(fp->f_ioloc, "volname %s not exported from %s", fp->f_volname,
|
||||
fp->f_from ? fp->f_from : "anywhere");
|
||||
}
|
||||
}
|
||||
|
||||
if (netbootp && (netbootp != FM_NETBOOT))
|
||||
lerror(hp->h_ioloc, "network booting requires both root and swap areas");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
analyze_hosts(qelem *q)
|
||||
{
|
||||
host *hp;
|
||||
|
||||
show_area_being_processed("analyze hosts", 5);
|
||||
|
||||
/*
|
||||
* Check all drives
|
||||
*/
|
||||
ITER(hp, host, q) {
|
||||
log("disks on host %s", hp->h_hostname);
|
||||
show_new("ana-host");
|
||||
hp->h_hostpath = compute_hostpath(hp->h_hostname);
|
||||
|
||||
if (hp->h_disk_fs)
|
||||
analyze_drives(hp);
|
||||
|
||||
}
|
||||
|
||||
show_area_being_processed("analyze mounts", 5);
|
||||
|
||||
/*
|
||||
* Check static mounts
|
||||
*/
|
||||
ITER(hp, host, q) {
|
||||
log("mounts on host %s", hp->h_hostname);
|
||||
show_new("ana-mount");
|
||||
if (hp->h_mount)
|
||||
analyze_mounts(hp);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check an automount request
|
||||
*/
|
||||
static void
|
||||
analyze_automount(automount *ap)
|
||||
{
|
||||
dict_ent *de = find_volname(ap->a_volname);
|
||||
|
||||
if (de) {
|
||||
ap->a_mounted = de;
|
||||
} else {
|
||||
if (STREQ(ap->a_volname, ap->a_name))
|
||||
lerror(ap->a_ioloc, "unknown volname %s automounted", ap->a_volname);
|
||||
else
|
||||
lerror(ap->a_ioloc, "unknown volname %s automounted on %s", ap->a_volname, ap->a_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
analyze_automount_tree(qelem *q, char *pref, int lvl)
|
||||
{
|
||||
automount *ap;
|
||||
|
||||
ITER(ap, automount, q) {
|
||||
char nname[1024];
|
||||
|
||||
if (lvl > 0 || ap->a_mount)
|
||||
if (ap->a_name[1] && strchr(ap->a_name + 1, '/'))
|
||||
lerror(ap->a_ioloc, "not allowed '/' in a directory name");
|
||||
sprintf(nname, "%s/%s", pref, ap->a_name);
|
||||
XFREE(ap->a_name);
|
||||
ap->a_name = strdup(nname[1] == '/' ? nname + 1 : nname);
|
||||
log("automount point %s:", ap->a_name);
|
||||
show_new("ana-automount");
|
||||
|
||||
if (ap->a_mount) {
|
||||
analyze_automount_tree(ap->a_mount, ap->a_name, lvl + 1);
|
||||
} else if (ap->a_hardwiredfs) {
|
||||
log("\thardwired from %s to %s", ap->a_volname, ap->a_hardwiredfs);
|
||||
} else if (ap->a_volname) {
|
||||
log("\tautomount from %s", ap->a_volname);
|
||||
analyze_automount(ap);
|
||||
} else if (ap->a_symlink) {
|
||||
log("\tsymlink to %s", ap->a_symlink);
|
||||
} else {
|
||||
ap->a_volname = strdup(ap->a_name);
|
||||
log("\timplicit automount from %s", ap->a_volname);
|
||||
analyze_automount(ap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
analyze_automounts(qelem *q)
|
||||
{
|
||||
auto_tree *tp;
|
||||
|
||||
show_area_being_processed("analyze automount", 5);
|
||||
|
||||
/*
|
||||
* q is a list of automounts
|
||||
*/
|
||||
ITER(tp, auto_tree, q)
|
||||
analyze_automount_tree(tp->t_mount, "", 0);
|
||||
}
|
236
contrib/amd/fsinfo/fsi_data.h
Normal file
236
contrib/amd/fsinfo/fsi_data.h
Normal file
@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: fsi_data.h,v 5.2.2.1 1992/02/09 15:09:53 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct auto_tree auto_tree;
|
||||
typedef struct automount automount;
|
||||
typedef struct dict dict;
|
||||
typedef struct dict_data dict_data;
|
||||
typedef struct dict_ent dict_ent;
|
||||
typedef struct disk_fs disk_fs;
|
||||
typedef struct ether_if ether_if;
|
||||
typedef struct fsmount fsmount;
|
||||
typedef struct host host;
|
||||
typedef struct ioloc ioloc;
|
||||
typedef struct fsi_mount fsi_mount;
|
||||
|
||||
|
||||
/*
|
||||
* Automount tree
|
||||
*/
|
||||
struct automount {
|
||||
qelem a_q;
|
||||
ioloc *a_ioloc;
|
||||
char *a_name; /* Automount key */
|
||||
char *a_volname; /* Equivalent volume to be referenced */
|
||||
char *a_symlink; /* Symlink representation */
|
||||
char *a_opts; /* opts for mounting */
|
||||
char *a_hardwiredfs; /* hack to bypass bogus fs definitions */
|
||||
qelem *a_mount; /* Tree representation */
|
||||
dict_ent *a_mounted;
|
||||
};
|
||||
|
||||
/*
|
||||
* List of automount trees
|
||||
*/
|
||||
struct auto_tree {
|
||||
qelem t_q;
|
||||
ioloc *t_ioloc;
|
||||
char *t_defaults;
|
||||
qelem *t_mount;
|
||||
};
|
||||
|
||||
/*
|
||||
* A host
|
||||
*/
|
||||
struct host {
|
||||
qelem q;
|
||||
int h_mask;
|
||||
ioloc *h_ioloc;
|
||||
fsmount *h_netroot, *h_netswap;
|
||||
#define HF_HOST 0
|
||||
char *h_hostname; /* The full name of the host */
|
||||
char *h_lochost; /* The name of the host with local domains *
|
||||
* * * stripped */
|
||||
char *h_hostpath; /* The filesystem path to the host (cf * * *
|
||||
* compute_hostpath) */
|
||||
#define HF_ETHER 1
|
||||
qelem *h_ether;
|
||||
#define HF_CONFIG 2
|
||||
qelem *h_config;
|
||||
#define HF_ARCH 3
|
||||
char *h_arch;
|
||||
#define HF_CLUSTER 4
|
||||
char *h_cluster;
|
||||
#define HF_OS 5
|
||||
char *h_os;
|
||||
qelem *h_disk_fs;
|
||||
qelem *h_mount;
|
||||
};
|
||||
|
||||
/*
|
||||
* An ethernet interface
|
||||
*/
|
||||
struct ether_if {
|
||||
qelem e_q;
|
||||
int e_mask;
|
||||
ioloc *e_ioloc;
|
||||
char *e_if;
|
||||
#define EF_INADDR 0
|
||||
struct in_addr e_inaddr;
|
||||
#define EF_NETMASK 1
|
||||
u_long e_netmask;
|
||||
#define EF_HWADDR 2
|
||||
char *e_hwaddr;
|
||||
};
|
||||
|
||||
/*
|
||||
* Disk filesystem structure.
|
||||
*
|
||||
* If the DF_* numbers are changed
|
||||
* disk_fs_strings in analyze.c will
|
||||
* need updating.
|
||||
*/
|
||||
struct disk_fs {
|
||||
qelem d_q;
|
||||
int d_mask;
|
||||
ioloc *d_ioloc;
|
||||
host *d_host;
|
||||
char *d_mountpt;
|
||||
char *d_dev;
|
||||
#define DF_FSTYPE 0
|
||||
char *d_fstype;
|
||||
#define DF_OPTS 1
|
||||
char *d_opts;
|
||||
#define DF_DUMPSET 2
|
||||
char *d_dumpset;
|
||||
#define DF_PASSNO 3
|
||||
int d_passno;
|
||||
#define DF_FREQ 4
|
||||
int d_freq;
|
||||
#define DF_MOUNT 5
|
||||
qelem *d_mount;
|
||||
#define DF_LOG 6
|
||||
char *d_log;
|
||||
};
|
||||
|
||||
#define DF_REQUIRED ((1<<DF_FSTYPE)|(1<<DF_OPTS)|(1<<DF_PASSNO)|(1<<DF_MOUNT))
|
||||
|
||||
/*
|
||||
* A mount tree
|
||||
*/
|
||||
struct fsi_mount {
|
||||
qelem m_q;
|
||||
ioloc *m_ioloc;
|
||||
int m_mask;
|
||||
#define DM_VOLNAME 0
|
||||
char *m_volname;
|
||||
#define DM_EXPORTFS 1
|
||||
char *m_exportfs;
|
||||
#define DM_SEL 2
|
||||
char *m_sel;
|
||||
char *m_name;
|
||||
int m_name_len;
|
||||
fsi_mount *m_parent;
|
||||
disk_fs *m_dk;
|
||||
fsi_mount *m_exported;
|
||||
qelem *m_mount;
|
||||
};
|
||||
|
||||
/*
|
||||
* Additional filesystem mounts
|
||||
*
|
||||
* If the FM_* numbers are changed
|
||||
* disk_fs_strings in analyze.c will
|
||||
* need updating.
|
||||
*/
|
||||
struct fsmount {
|
||||
qelem f_q;
|
||||
fsi_mount *f_ref;
|
||||
ioloc *f_ioloc;
|
||||
int f_mask;
|
||||
#define FM_LOCALNAME 0
|
||||
char *f_localname;
|
||||
#define FM_VOLNAME 1
|
||||
char *f_volname;
|
||||
#define FM_FSTYPE 2
|
||||
char *f_fstype;
|
||||
#define FM_OPTS 3
|
||||
char *f_opts;
|
||||
#define FM_FROM 4
|
||||
char *f_from;
|
||||
#define FM_DIRECT 5
|
||||
};
|
||||
|
||||
#define FM_REQUIRED ((1<<FM_VOLNAME)|(1<<FM_FSTYPE)|(1<<FM_OPTS)|(1<<FM_FROM)|(1<<FM_LOCALNAME))
|
||||
#define FM_NETROOT 0x01
|
||||
#define FM_NETSWAP 0x02
|
||||
#define FM_NETBOOT (FM_NETROOT|FM_NETSWAP)
|
||||
|
||||
#define DICTHASH 5
|
||||
struct dict_ent {
|
||||
dict_ent *de_next;
|
||||
char *de_key;
|
||||
int de_count;
|
||||
qelem de_q;
|
||||
};
|
||||
|
||||
/*
|
||||
* Dictionaries ...
|
||||
*/
|
||||
struct dict_data {
|
||||
qelem dd_q;
|
||||
char *dd_data;
|
||||
};
|
||||
|
||||
struct dict {
|
||||
dict_ent *de[DICTHASH];
|
||||
};
|
||||
|
||||
/*
|
||||
* Source text location for error reports
|
||||
*/
|
||||
struct ioloc {
|
||||
int i_line;
|
||||
char *i_file;
|
||||
};
|
138
contrib/amd/fsinfo/fsi_dict.c
Normal file
138
contrib/amd/fsinfo/fsi_dict.c
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: fsi_dict.c,v 5.2.2.1 1992/02/09 15:09:43 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Dictionary support
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <fsi_data.h>
|
||||
#include <fsinfo.h>
|
||||
|
||||
|
||||
static int
|
||||
dict_hash(char *k)
|
||||
{
|
||||
u_int h;
|
||||
|
||||
for (h = 0; *k; h += *k++) ;
|
||||
return h % DICTHASH;
|
||||
}
|
||||
|
||||
|
||||
dict *
|
||||
new_dict(void)
|
||||
{
|
||||
dict *dp = CALLOC(struct dict);
|
||||
|
||||
return dp;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dict_add_data(dict_ent *de, char *v)
|
||||
{
|
||||
dict_data *dd = CALLOC(struct dict_data);
|
||||
|
||||
dd->dd_data = v;
|
||||
ins_que(&dd->dd_q, de->de_q.q_back);
|
||||
de->de_count++;
|
||||
}
|
||||
|
||||
|
||||
static dict_ent *
|
||||
new_dict_ent(char *k)
|
||||
{
|
||||
dict_ent *de = CALLOC(struct dict_ent);
|
||||
|
||||
de->de_key = k;
|
||||
init_que(&de->de_q);
|
||||
return de;
|
||||
}
|
||||
|
||||
|
||||
dict_ent *
|
||||
dict_locate(dict *dp, char *k)
|
||||
{
|
||||
dict_ent *de = dp->de[dict_hash(k)];
|
||||
|
||||
while (de && !STREQ(de->de_key, k))
|
||||
de = de->de_next;
|
||||
return de;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dict_add(dict *dp, char *k, char *v)
|
||||
{
|
||||
dict_ent *de = dict_locate(dp, k);
|
||||
|
||||
if (!de) {
|
||||
dict_ent **dep = &dp->de[dict_hash(k)];
|
||||
de = new_dict_ent(k);
|
||||
de->de_next = *dep;
|
||||
*dep = de;
|
||||
}
|
||||
dict_add_data(de, v);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dict_iter(dict *dp, int (*fn) (qelem *))
|
||||
{
|
||||
int i;
|
||||
int errors = 0;
|
||||
|
||||
for (i = 0; i < DICTHASH; i++) {
|
||||
dict_ent *de = dp->de[i];
|
||||
while (de) {
|
||||
errors += (*fn) (&de->de_q);
|
||||
de = de->de_next;
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
419
contrib/amd/fsinfo/fsi_gram.y
Normal file
419
contrib/amd/fsinfo/fsi_gram.y
Normal file
@ -0,0 +1,419 @@
|
||||
/*
|
||||
* Copyright (c) 1997-1998 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: fsi_gram.y,v 5.2.2.1 1992/02/09 15:09:35 jsp beta $
|
||||
*
|
||||
*/
|
||||
|
||||
%{
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <am_defs.h>
|
||||
#include <fsi_data.h>
|
||||
#include <fsinfo.h>
|
||||
|
||||
extern qelem *list_of_hosts, *list_of_automounts;
|
||||
%}
|
||||
|
||||
%union {
|
||||
auto_tree *a;
|
||||
disk_fs *d;
|
||||
ether_if *e;
|
||||
host *h;
|
||||
qelem *q;
|
||||
char *s;
|
||||
fsi_mount *m;
|
||||
fsmount *f;
|
||||
}
|
||||
|
||||
%token tARCH
|
||||
%token tAS
|
||||
%token tAUTOMOUNT
|
||||
%token tCLUSTER
|
||||
%token tCONFIG
|
||||
%token tDUMPSET
|
||||
%token tEQ
|
||||
%token tNFSEQ
|
||||
%token tEXPORTFS
|
||||
%token tFREQ
|
||||
%token tFROM
|
||||
%token tFS
|
||||
%token tFSTYPE
|
||||
%token tHWADDR
|
||||
%token tINADDR
|
||||
%token tHOST
|
||||
%token tLOCALHOST
|
||||
%token tLOG
|
||||
%token tMOUNT
|
||||
%token tNETMASK
|
||||
%token tNETIF
|
||||
%token tVOLNAME
|
||||
%token tOPTS
|
||||
%token tOS
|
||||
%token tPASSNO
|
||||
%token tDIRECT
|
||||
%token tSEL
|
||||
%token <s> tSTR
|
||||
|
||||
%start list_of_hosts
|
||||
|
||||
%type <a> automount
|
||||
%type <q> automount_tree
|
||||
%type <e> ether_attr
|
||||
%type <m> dir_tree_info
|
||||
%type <d> filesystem fs_info_list
|
||||
%type <h> host host_attr host_attr_list
|
||||
%type <q> list_of_hosts list_of_filesystems list_of_mounts dir_tree
|
||||
%type <f> localinfo_list
|
||||
%type <s> opt_auto_opts
|
||||
|
||||
%%
|
||||
|
||||
list_of_hosts :
|
||||
/* empty */
|
||||
{ $$ = new_que(); }
|
||||
|
||||
| list_of_hosts host
|
||||
{ if ($2) ins_que((qelem *) $2, list_of_hosts->q_back);
|
||||
$$ = $1; }
|
||||
|
||||
| list_of_hosts automount
|
||||
{ if ($2) ins_que((qelem *) $2, list_of_automounts->q_back);
|
||||
$$ = $1; }
|
||||
;
|
||||
|
||||
/*
|
||||
* A new host:
|
||||
*
|
||||
* host foo.domain
|
||||
*/
|
||||
host :
|
||||
tHOST host_attr list_of_filesystems list_of_mounts
|
||||
{ $$ = $2; $$->h_disk_fs = $3; $$->h_mount = $4; }
|
||||
|
||||
| error tHOST host_attr list_of_filesystems list_of_mounts
|
||||
{ $$ = $3; $$->h_disk_fs = $4; $$->h_mount = $5; }
|
||||
|
||||
;
|
||||
|
||||
host_attr :
|
||||
tSTR
|
||||
{ $$ = new_host(); set_host($$, HF_HOST, $1); }
|
||||
|
||||
| '{' host_attr_list '}' tSTR
|
||||
{ $$ = $2; set_host($$, HF_HOST, $4); }
|
||||
|
||||
;
|
||||
|
||||
host_attr_list :
|
||||
/* empty */
|
||||
{ $$ = new_host(); }
|
||||
|
||||
| host_attr_list tNETIF tSTR '{' ether_attr '}'
|
||||
{ if ($5) {
|
||||
$5->e_if = $3;
|
||||
$$ = $1; set_host($$, HF_ETHER, (char *) $5); }
|
||||
}
|
||||
|
||||
| host_attr_list tCONFIG tSTR
|
||||
{ $$ = $1; set_host($$, HF_CONFIG, $3); }
|
||||
|
||||
| host_attr_list tARCH '=' tSTR
|
||||
{ $$ = $1; set_host($$, HF_ARCH, $4); }
|
||||
|
||||
| host_attr_list tOS '=' tSTR
|
||||
{ $$ = $1; set_host($$, HF_OS, $4); }
|
||||
|
||||
| host_attr_list tCLUSTER '=' tSTR
|
||||
{ $$ = $1; set_host($$, HF_CLUSTER, $4); }
|
||||
|
||||
| host_attr_list error '=' tSTR
|
||||
{ yyerror("unknown host attribute"); }
|
||||
;
|
||||
|
||||
ether_attr :
|
||||
/* empty */
|
||||
{ $$ = new_ether_if(); }
|
||||
|
||||
| ether_attr tINADDR '=' tSTR
|
||||
{ $$ = $1; set_ether_if($$, EF_INADDR, $4); }
|
||||
| ether_attr tNETMASK '=' tSTR
|
||||
{ $$ = $1; set_ether_if($$, EF_NETMASK, $4); }
|
||||
| ether_attr tHWADDR '=' tSTR
|
||||
{ $$ = $1; set_ether_if($$, EF_HWADDR, $4); }
|
||||
;
|
||||
|
||||
/*
|
||||
* A new automount tree:
|
||||
*
|
||||
* automount /mountpoint { ... }
|
||||
*/
|
||||
automount :
|
||||
tAUTOMOUNT opt_auto_opts automount_tree
|
||||
{ if ($3) {
|
||||
$$ = new_auto_tree($2, $3);
|
||||
} else {
|
||||
$$ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
| tAUTOMOUNT error
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
opt_auto_opts :
|
||||
/* empty */
|
||||
{ $$ = strdup(""); }
|
||||
|
||||
| tOPTS tSTR
|
||||
{ $$ = $2; }
|
||||
;
|
||||
|
||||
list_of_filesystems :
|
||||
/* empty */
|
||||
{ $$ = 0; }
|
||||
|
||||
| list_of_filesystems filesystem
|
||||
{ if ($2) {
|
||||
if ($1)
|
||||
$$ = $1;
|
||||
else
|
||||
$$ = new_que();
|
||||
ins_que(&$2->d_q, $$->q_back);
|
||||
} else {
|
||||
$$ = $1;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* A new filesystem:
|
||||
*
|
||||
* fs /dev/whatever { ... }
|
||||
*/
|
||||
filesystem :
|
||||
tFS tSTR '{' fs_info_list '}'
|
||||
{ $4->d_dev = $2; $$ = $4; }
|
||||
|
||||
| tFS error '}'
|
||||
{ $$ = (disk_fs *) 0; }
|
||||
;
|
||||
|
||||
/*
|
||||
* Per-filesystem information:
|
||||
*
|
||||
* fstype - the type of the filesystem (4.2, nfs, swap, export)
|
||||
* opts - the mount options ("rw,grpid")
|
||||
* passno - fsck pass number
|
||||
* freq - dump frequency
|
||||
* dumpset - tape set for filesystem dumps
|
||||
* mount - where to mount this filesystem
|
||||
* log - log device
|
||||
*/
|
||||
fs_info_list :
|
||||
/* empty */
|
||||
{ $$ = new_disk_fs(); }
|
||||
|
||||
| fs_info_list tFSTYPE '=' tSTR
|
||||
{ $$ = $1; set_disk_fs($$, DF_FSTYPE, $4); }
|
||||
|
||||
| fs_info_list tOPTS '=' tSTR
|
||||
{ $$ = $1; set_disk_fs($$, DF_OPTS, $4); }
|
||||
|
||||
| fs_info_list tPASSNO '=' tSTR
|
||||
{ $$ = $1; set_disk_fs($$, DF_PASSNO, $4); }
|
||||
|
||||
| fs_info_list tFREQ '=' tSTR
|
||||
{ $$ = $1; set_disk_fs($$, DF_FREQ, $4); }
|
||||
|
||||
| fs_info_list tMOUNT dir_tree
|
||||
{ $$ = $1; set_disk_fs($$, DF_MOUNT, (char *) $3); }
|
||||
|
||||
| fs_info_list tDUMPSET '=' tSTR
|
||||
{ $$ = $1; set_disk_fs($$, DF_DUMPSET, $4); }
|
||||
|
||||
| fs_info_list tLOG '=' tSTR
|
||||
{ $$ = $1; set_disk_fs($$, DF_LOG, $4); }
|
||||
|
||||
| fs_info_list error '=' tSTR
|
||||
{ yyerror("unknown filesystem attribute"); }
|
||||
;
|
||||
|
||||
/*
|
||||
* An automount tree:
|
||||
*
|
||||
* name = "volname" name is a reference to volname
|
||||
* name -> "string" name is a link to "string"
|
||||
* name nfsalias "string" name is a link to "string", string parsed as NFS
|
||||
* pathname.
|
||||
* name { ... } name is an automount tree
|
||||
*/
|
||||
automount_tree :
|
||||
/* empty */
|
||||
{ $$ = 0; }
|
||||
|
||||
| automount_tree tSTR opt_auto_opts '=' tSTR
|
||||
{ automount *a = new_automount($2);
|
||||
a->a_volname = $5;
|
||||
a->a_opts = $3;
|
||||
if ($1)
|
||||
$$ = $1;
|
||||
else
|
||||
$$ = new_que();
|
||||
ins_que(&a->a_q, $$->q_back);
|
||||
}
|
||||
| automount_tree tSTR opt_auto_opts tNFSEQ tSTR
|
||||
{ automount *a = new_automount($2);
|
||||
a->a_hardwiredfs = $5;
|
||||
a->a_opts = $3;
|
||||
if ($1)
|
||||
$$ = $1;
|
||||
else
|
||||
$$ = new_que();
|
||||
ins_que(&a->a_q, $$->q_back);
|
||||
}
|
||||
|
||||
| automount_tree tSTR tEQ tSTR
|
||||
{ automount *a = new_automount($2);
|
||||
a->a_symlink = $4;
|
||||
if ($1)
|
||||
$$ = $1;
|
||||
else
|
||||
$$ = new_que();
|
||||
ins_que(&a->a_q, $$->q_back);
|
||||
}
|
||||
|
||||
| automount_tree tSTR opt_auto_opts '{' automount_tree '}'
|
||||
{ automount *a = new_automount($2);
|
||||
a->a_mount = $5;
|
||||
a->a_opts = $3;
|
||||
if ($1)
|
||||
$$ = $1;
|
||||
else
|
||||
$$ = new_que();
|
||||
ins_que(&a->a_q, $$->q_back);
|
||||
}
|
||||
;
|
||||
|
||||
dir_tree :
|
||||
/* empty */
|
||||
{ $$ = 0; }
|
||||
|
||||
| dir_tree tSTR '{' dir_tree_info dir_tree '}'
|
||||
{ $4->m_mount = $5;
|
||||
$4->m_name = $2;
|
||||
if ($2[0] != '/' && $2[1] && strchr($2+1, '/'))
|
||||
yyerror("not allowed '/' in a directory name");
|
||||
if ($1)
|
||||
$$ = $1;
|
||||
else
|
||||
$$ = new_que();
|
||||
ins_que(&$4->m_q, $$->q_back);
|
||||
}
|
||||
;
|
||||
|
||||
dir_tree_info :
|
||||
/* empty */
|
||||
{ $$ = new_mount(); }
|
||||
|
||||
| dir_tree_info tEXPORTFS tSTR
|
||||
{ $$ = $1; set_mount($$, DM_EXPORTFS, $3); }
|
||||
|
||||
| dir_tree_info tVOLNAME tSTR
|
||||
{ $$ = $1; set_mount($$, DM_VOLNAME, $3); }
|
||||
|
||||
| dir_tree_info tSEL tSTR
|
||||
{ $$ = $1; set_mount($$, DM_SEL, $3); }
|
||||
|
||||
| dir_tree_info error '=' tSTR
|
||||
{ yyerror("unknown directory attribute"); }
|
||||
;
|
||||
|
||||
/*
|
||||
* Additional mounts on a host
|
||||
*
|
||||
* mount "volname" ...
|
||||
*/
|
||||
list_of_mounts :
|
||||
/* empty */
|
||||
{ $$ = 0; }
|
||||
|
||||
| list_of_mounts tMOUNT tSTR localinfo_list
|
||||
{ set_fsmount($4, FM_VOLNAME, $3);
|
||||
if ($1)
|
||||
$$ = $1;
|
||||
else
|
||||
$$ = new_que();
|
||||
ins_que(&$4->f_q, $$->q_back);
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* Mount info:
|
||||
*
|
||||
* from "hostname" - obtain the object from the named host
|
||||
* as "string" - where to mount, if different from the volname
|
||||
* opts "string" - mount options
|
||||
* fstype "type" - type of filesystem mount, if not nfs
|
||||
* direct - mount entry, no need to create ad-hoc hosts file
|
||||
*/
|
||||
localinfo_list :
|
||||
/* empty */
|
||||
{ $$ = new_fsmount(); }
|
||||
|
||||
| localinfo_list tDIRECT
|
||||
{ $$ = $1; set_fsmount($$, FM_DIRECT, ""); }
|
||||
|
||||
| localinfo_list tAS tSTR
|
||||
{ $$ = $1; set_fsmount($$, FM_LOCALNAME, $3); }
|
||||
|
||||
| localinfo_list tFROM tSTR
|
||||
{ $$ = $1; set_fsmount($$, FM_FROM, $3); }
|
||||
|
||||
| localinfo_list tFSTYPE tSTR
|
||||
{ $$ = $1; set_fsmount($$, FM_FSTYPE, $3); }
|
||||
|
||||
| localinfo_list tOPTS tSTR
|
||||
{ $$ = $1; set_fsmount($$, FM_OPTS, $3); }
|
||||
|
||||
| localinfo_list error '=' tSTR
|
||||
{ yyerror("unknown mount attribute"); }
|
||||
;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user