retire amd(8)

autofs was introduced with FreeBSD 10.1 and is the supported method for
automounting filesystems.  As of r296194 the amd man page claimed that it
is deprecated.  Remove it from base now; the sysutils/am-utils port is
still available if necessary.

Discussed with:	cy
Relnotes:	Yes
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Ed Maste 2020-03-09 20:46:43 +00:00
parent 9b7938dcf3
commit 13f7dbe822
230 changed files with 29 additions and 101999 deletions

View File

@ -2284,11 +2284,6 @@ _basic_bootstrap_tools+=sbin/sysctl bin/chflags
# mkfifo is used by sys/conf/newvers.sh
_basic_bootstrap_tools+=usr.bin/mkfifo
.if ${MK_AMD} != "no"
# unifdef is only used by usr.sbin/amd/libamu/Makefile
_basic_bootstrap_tools+=usr.bin/unifdef
.endif
.if ${MK_BOOT} != "no"
_basic_bootstrap_tools+=bin/dd
# xz/unxz is used by EFI

View File

@ -36,6 +36,28 @@
# xargs -n1 | sort | uniq -d;
# done
# 20200309: amd(8) retired
OLD_FILES+=etc/amd.map
OLD_FILES+=etc/newsyslog.conf.d/amd.conf
OLD_FILES+=etc/rc.d/amd
OLD_FILES+=usr/bin/pawd
OLD_FILES+=usr/sbin/amd
OLD_FILES+=usr/sbin/amq
OLD_FILES+=usr/sbin/fixmount
OLD_FILES+=usr/sbin/fsinfo
OLD_FILES+=usr/sbin/hlfsd
OLD_FILES+=usr/sbin/mk-amd-map
OLD_FILES+=usr/sbin/wire-test
OLD_FILES+=usr/share/examples/etc/amd.map
OLD_FILES+=usr/share/man/man1/pawd.1.gz
OLD_FILES+=usr/share/man/man5/amd.conf.5.gz
OLD_FILES+=usr/share/man/man8/amd.8.gz
OLD_FILES+=usr/share/man/man8/amq.8.gz
OLD_FILES+=usr/share/man/man8/fixmount.8.gz
OLD_FILES+=usr/share/man/man8/fsinfo.8.gz
OLD_FILES+=usr/share/man/man8/hlfsd.8.gz
OLD_FILES+=usr/share/man/man8/mk-amd-map.8.gz
OLD_FILES+=usr/share/man/man8/wire-test.8.gz
# 20200301: bktr removed
OLD_DIRS+=usr/include/dev/bktr
OLD_FILES+=usr/include/dev/bktr/ioctl_bktr.h

View File

@ -26,6 +26,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
20200309:
The amd(8) automount daemon has been removed from the source tree.
As of FreeBSD 10.1 autofs(5) is the preferred tool for automounting.
amd is still available in the sysutils/am-utils port.
20200301:
Removed brooktree driver (bktr.4) from the tree.

View File

@ -1,427 +0,0 @@
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 AT cs.sunysb.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.
* Ion Badulescu <ion AT cs.columbia.edu>
Co-maintainer of am-utils since late 1999: Linux and Solaris autofs support,
Linux NFSv3 support, major code reorganization, etc...
* Randall S. Winchester <rsw AT 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 AT 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.
August 8, 1998: add detection support for NFS V.3 for NetBSD 1.3F.
February 1, 1998: fixes for NetBSD to better detect its features.
September 4, 1999: assorted fixes for NetBSD 1.4+.
* Hannes Reinecke <hare AT 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 AT 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 AT 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 AT cs.huji.ac.il>
July, 6 1997: contributed patches to hesiod on bsdi3.
* Tom Schmidt <tschmidt AT 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.
May 30, 2000: correct logging types for addopts/mergeopts messages.
* Daniel S. Riley <dsr AT 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.
August 15, 1998: fix memory leak in processing of /defaults, and avoid
accessing uninitialized memory in osf1.
* Roman Hodek <Roman.Hodek AT 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 AT debian.org>
and Dominik Kubla <dominik AT debian.org>.
* Rainer Orth <ro AT 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!
January 8, 1999: texi fixes, and more Ultrix 4.3 fixes, among others.
January 11, 1999: hesiod_isup function. Fix format errors in dlog/plog.
Remove obsolete or unnecessary files/macros. Don't report disabled file
systems. More misc fixes.
February 3, 1998: don't start autofs listener unless autofs maps were in
use.
December 10, 1999: assorted fixed and lots of fixes to support in-kernel
mount tables in Solaris 8.
February 9, 2000: new debug options hrtime (hi-res timer) and xdrtrace. bug
fixes.
* Jason Thorpe <thorpej AT 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 AT laas.fr>.
* Chris Metcalf <metcalf AT 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 AT 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 AT 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 AT wsrcc.com>
August 10, 1997: netbsd and other bsd systems have a mask flag for
pcfs_args (msdos mount).
* Christos Zoulas <christos AT zoulas.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.
November 29, 2002: compile fixes for NetBSD, a couple of bug fixes (one
already fixed by maintainers)
April 12, 2003: support new "unmount" option, useful to timeout removable
local media mounts.
October 12, 2004: patch to support two new amd.conf options, domain_strip
and auto_attrcache. Patch to cleanup NFS attribute-cache flag computation.
Patch to fix an inconsistency in timeouts in the RPC code between socket and
TLI implementations. Patch to print version string (amd -v) after all
options had been initialized, so we can print domain, host, and hostd.
Linux patch to use umount2(2) if umount(2) fails.
* Bill Paul <wpaul AT 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.
January 15, 1999: small ldap bug fixes.
* Stefan Vogel <vogel AT physik-rzu.unizh.ch>
November 14, 1997: typo in the subscription instructions to amd-dev.
* Guntram Wolski <gwolsk AT sei.com>
November 15, 1997: pointed out mismatching documentation for the -o option.
* Michael Hucka <hucka AT eecs.umich.edu>
January 11, 1997: pointed out reversed definition of NFS mount options vers
and proto.
* Albert Chin <china AT pprd.abbott.com>
January 12, 1998: minor bug in output of amd -H.
June 23, 2005: assortment of small compile bugs on aix4, and solaris 5/6/7.
* Thomas Richter <richter AT chemie.fu-berlin.de>
January 13, 1998: use case insensitive comparisons for variables that need
it (such as all hostname related ones, and more).
July 20, 1998: don't leak memory in the private version of yp_all (when
vendor yp_all is bad).
* Fred Korz <korz AT smarts.com>
January 30, 1998: minor typo fixed to tftp example in am-utils.texi.
* Donald Buczek <buczek AT 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 AT ms.com>
April 20, 1998: allow arbitrary number of interfaces in wire listing.
* David O'Brien <obrien AT NUXI.com>
September 4, 1998: bug fix to avoid overrunning hostname buffer, and minor
amd.conf man page typo correction.
September 22, 1999: use more secure vsnprintf in real_plog().
* Danny Rathjens <dkr AT cs.fiu.edu>
October 29, 1998: swap arguments to kill(2) in amd.c.
* Mike Mitchell <mcm AT unx.sas.com>
November 3, 1998: amd/nfs_subr.c (nfsproc_lookup_2_svc): try to avoid a race
condition between unmounting and re-mounting an entry, by increasing the ttl
of a looked up entry before unmounting it.
* Douglas K. Rand" <rand AT aero.und.edu>
December 3, 1998: case insensitive host name match for nfsl.
* David Wolfskill <dhw AT whistle.com>
January 28, 1999: don't turn on/off noconn option if it was already in that
state.
* Jeffrey C Honig <jch AT BSDI.COM>
March 14, 1999: clean up more autogenerated files upon "make distclean".
March 15, 1999: avoid overly verbose NIS warning even on systems that don't
run NIS. On BSD systems, wire.c uses getifaddrs(), sysctl(), IRS routines,
and more fixes. Numerous IP packet security fixes.
March 16, 1999: documentation typos. new cdfs options. ufs structure
detection for bsdi4.
September 17, 1999: fixes to expn.
* Paul Balyoz <pbalyoz AT sedona.ch.intel.com>
March 26, 1999: ensure lostaltmail displays Y2K compliant dates.
* Jon Peatfield <J.S.Peatfield AT damtp.cam.ac.uk>
March 30, 1999: turn off incomplete NFS V.3 support in HPUX 10.20.
September 22, 1999: safe reloading of maps without first clearing old
copies, and using cached copies if map failed to reload.
* Peter Breitenlohner <peb AT mppmu.mpg.de>
July 24, 1999: patch for linux 2.2.x to work with older libc5 systems, and
nis_isup mis-logic fixes.
December 13, 2001: report typos in scripts/amd.conf.5.
* Dale Talcott <aeh AT quest.cc.purdue.edu>
July 26, 1999: added NFS3 support for AIX mounting.
* Christophe Kalt <Christophe-Kalt AT deshaw.com>
July 14, 1999: add netgrpd() syntax function which uses FQHN.
* Andrew J. Korty <ajk AT purdue.edu>
September 5, 1999: pawd works for type:=nfsl.
* Nick Williams <njw AT ms.com>
September 1, 1999: bug fix for incorrect symlinks when two locations are
requested simultaneously.
November 1, 1999: fixes to sync maps even if they are set to mapcache:=sync.
January 19, 2000: fix (and reduce the incidence of) stale file handles when
doing rapid mounts and umounts in succession.
June 5, 2000: better handling of potential race-conditions during rapid
u/mounts. Correctly update d_drops stats for amq -s.
* Johann Pfefferl <johann.pfefferl.jp AT germany.agfa.com>
November 16, 1999: fix to ldap code so repeated calls to string2he don't
corrupt the string passed.
* Amitha Perera <perera AT cs.rpi.edu>
December 9, 1999: detect all wire() interfaces correctly.
* Steven Danz <sdanz AT awc.kc.noaa.gov>
January 25, 2000: allow browsable auto maps.
* Wolfram Klaus <klaus AT physik.fu-berlin.de>.
November 21, 2000: recognize proplist mnttab flag.
* Thomas Klausner <tk AT giga.or.at>
November 21, 2000: lots of NetBSD fixes (many of which are generic).
April 18, 2003: patch to reference am-utils info pages in man page.
November 28, 2004: small fixes to typos in amd.conf(5) man page.
* Olaf Kirch <okir AT caldera.de>
February 1, 2001: important Linux NFS error number mapping fixed
* Ahmon Dancy <dancy AT franz.com>
February 9, 2001: Apple Rhapsody/Darwin/OS X port
* Sebastien Bahloul <sebastien.bahloul AT mangoosta.fr>
July 3, 2001: LDAP fixes and updates to support new APIs
March 27, 2002: LDAP bug and port to HPUX-11.
* Philippe Troin <phil AT fifi.org>
July 12, 2001: Proper handling of GNU getopt, support for optionally
disabling LDAP/Hesiod, fixes for the dev/nodev option on Linux. Texi
documentation fix.
November 28, 2001: Bug fix. Support "nolock" as an NFS option, not a
generic mount option.
July 17, 2003: pref:=null core dump fix. libgdbm portability. tcpd/librap
support. And a few other things for the 6.0 branch.
* Trond Myklebust <trond.myklebust AT fys.uio.no>
January 10, 2002: Proper initialization of the timeo parameter on Linux, TCP
_must_ have a timeout 2 orders of magnitude larger than UDP
* George Ross <gdmr AT dcs.ed.ac.uk>
April 29, 2002: Rework of old code, support for wildcards in LDAP queries,
and an FD leak fix. Amd -A support.
October 21, 2002: ldap_unbind fix for SIGPIPE, and support for LDAPv3
protocol version parameter (with Tim Colles <timc AT inf.ed.ac.uk>).
* Matthias Scheler <tron AT zhadum.de>
June 14, 2002: patch to use "xlatecookie" NFS mount option.
* Jun-ichiro itojun Hagino <itojun AT iijlab.net>.
June 11, 2002: minor fixes to support NetBSD 1.6A.
* Sean Fagan <sef AT apple.com>
March 14, 2003: detect and use the MNT2_GEN_OPT_AUTOMNTFS mount flag
on OS X / Darwin.
* Hendrik Scholz <hscholz AT raisdorf.net>
June 9, 2003: mk-amd-map should open temp db file using O_EXCL.
* Mark Davies <mark AT mcs.vuw.ac.nz>
July 14, 2003: define "xlatecookie" mnttab option if not defined (for
NetBSD). Support null hesiod entries if they start with a ".".
* Eric S. Raymond <esr AT thyrsus.com>
December 9, 2003: fix unbalanced [] typo in fsinfo man page.
* Martin Blapp <mb AT imp.ch>
July 6, 2004: recognize fields in pcfs_args_t in FreeBSD 5.
* Dan Nelson <dnelson AT allantgroup.com>
August 2, 2004: pawd to recognize "host" type mounts.
* Hauke Fath <hauke AT Espresso.Rhein-Neckar.DE>
August 3, 2004: pawd to recognize "linkx" type mounts.
* Michael van Elst <M.van.Elst AT science-computing.de>
September 1, 2004: bug fix to avoid race condition in calls to mntctl on
AIX.
* Jonathan Chen <jon+amd AT spock.org>
October 22, 2004: patch/fix to move mlock/mlockall/plock code after the
fork().
June 29, 2005: core dump going off end of exported_ap[] array.
September 29, 2005: patch/fix for pawd not to go into an infinite loop.
October 25, 2005: patch/fix for pawd to repeatedly resolve path.
* David Rage <rage AT ucl.ac.uk>
January 17, 2005: prevent Amd from logging 'Read-only filesystem' errors
when the mount point has an ancestor (i.e. '/') that is mounted read-only.
* Kevin Layer <layer AT franz.com>
January 28, 2005: basic instructions how to setup Amd on Mac OS-X.
* Dan Ottavio <dottavio AT ic.sunysb.edu>
March 2, 2005: new global amd.conf option debug_mtab_file, to set the debug
mtab file when using debug_options=mtab. Default has changed from "./mtab"
to "/tmp/mtab" to avoid security problem. Bug fixed to ensure that Amd
terminates properly even mtab file doesn't exist.
* Erik Kline <ekline at ekline dot com>
January 3, 2005: implementation of executable maps for Amd.
* Jim Zajkowski <jim.zajkowski AT gmail.com>
March 14, 2005: small patch to amd2ldif.
* Adam Morley <adam at gmi dot com>
January 27, 2005: synchronize what amd2ldif does vs. what the ldap.schema
expects.
* Graeme Wilford <G.Wilford AT surrey.ac.uk>
July 4, 2005: buffer overflow in pawd.

View File

@ -1,303 +0,0 @@
LIST OF KNOWN BUGS IN AM-UTILS OR OPERATING SYSTEMS
Note: report am-utils bugs via Bugzilla to https://bugzilla.am-utils.org/ or
by email to the am-utils mailing list (see www.am-utils.org).
(1) mips-sgi-irix*
[1A] known to have flaky 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 iterates over NIS maps. The latter isn't as
reliable as yp_all() which uses TCP, but it is better than hanging.
(I have some reports that older version of hpux-9, with older libc, also
leak file descriptors.)
[1C] SGI's MIPSpro C compiler on IRIX 6 has the unfortunate habit of
creating code specificially for the machine it runs on. The ABI and ISA
used depend very much on the OS version and compiler release used. This
means that the resulting amd binary won't run on machines different from
the build host, particularly older ones. Older versions of am-utils
enforced the O32 ABI when compiling with cc to work around this, but this
ABI is deprecated in favor of the N32 ABI now, so we use -n32 -mips3 to
ensure that the binaries run on every host capable of running IRIX 6 at
all. If this is not appropriate for you, configure with something like
CC='cc -64' instead to get the desired ABI and ISA.
(2) alpha-unknown-linux-gnu (RedHat Linux 4.2)
hasmntopt(mnt, opt) can go 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);
}
It is possible that sufficiently newer version of libc for RH4.2 fix this
problem.
(3) mips-dec-ultrix4.3
Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> reports
[3A] One needs the Kernel Config Files (UDTBIN430) subset installed to
compile am-utils, otherwise essential header files (net/if.h, net/route.h,
rpcsvc/mount.h, rpcsvc/yp_prot.h, rpcsvc/ypclnt.h, sys/proc.h) are
missing.
[3B] It's probably impossible to build am-utils with DEC C on Ultrix V4.3.
This compiler is pseudo-ANSI only. Maybe the new ANSI C compiler in V4.3A
and beyond will do. I successfully used gcc 2.8.1.
[3C] You need to build against a recent libhesiod (I used 3.0.2) and
libresolv/lib44bsd (I used BIND 4.9.5-P1). The resolver routines in
libc seem to cause random memory corruption. It is necessary to specify
LIBS=-l44bsd. lib44bsd is a helper library of libresolv used to supply
functions like strdup which are missing on the host system. This isn't
currently autoconfiscated.
[3D] You need to configure with CONFIG_SHELL=/bin/sh5 /bin/sh5 buildall;
/bin/sh cannot handle the shell functions used in buildall and is both
buggy and slow.
[3E] 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
(4) powerpc-ibm-aix4.2.1.0
[4A] "Randall S. Winchester" <rsw AT 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 AT 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.
[C] Do not link amd with libnsl. It is buggy and causes amd to core dump
in strlen inside strdup inside svc_register().
(5) *-linux-rh51 (RedHat Linux 5.1)
There's a UDP file descriptor leak in libnsl in RedHat Linux 5.1. This
library part of glibc2. Am-utils currently declares redhat 5.1 systems as
having a "broken yp_all" and using an internal, slower, leak-free version.
The leak is known to the glibc maintainers and a fix from them is due soon,
but it is not yet in the glibc-2.0.7-19 RPM.
(6) rs6000-ibm-aix4.1.x
A bug in libc results in an amq binary that doesn't work; amq -v dumps core
in xdr_string. There is no known fix (source code or vendor patch) at this
time. (Please let us know if you have a fix; see www.am-utils.org.)
(7) *-aix4.3.2.0
The plock() function will pre-reserve all of the memory up to the maximum
listed in the ulimit. If the ulimit is infinite, plock() will try to take
all of the system's memory, and fail with ENOMEM (Not Enough Space).
Normally ulimit may be set to a few gigs of max memory usage, but even that
is too much; Amd doesn't need more than a few megs of resident memory size
(depending on the particular usage, number of maps, etc.) Solution: lower
your ulimit before starting amd. This can be done inside the ctl-amd
script, but be careful not to limit it too low. Alternatively, don't use
plock on aix-4.3: set it to plock=no in amd.conf (which is the default if
you do nothing).
(8) *-linux (systems using glibc 2.1, such as RedHat-6.x)
There's a UDP file descriptor leak in the NIS routines in glibc, especially
those that do yp_bind. Until this is bug fixed, do not set nis_domain in
amd.conf, but let the system pick up the default domain name as set by your
system. That would avoid using the buggy yp_bind routines in libc.
(9) *-linux (SuSE systems using unfsd)
The user-level nfsd (2.2beta44) on older SuSE Linux systems (and possibly
others) dies with a SEGV when amd tries to contact it for access to a volume
that does not exist, or one for which there is no permission to mount.
(10) *-*-hpux11
If you're using NFSv3, you must install HP patches PHNE_20344 and
PHNE_20371. If you don't, and you try to use amd with NFSv3 over TCP, your
kernel will panic.
(11) *-linux* (any system using a 2.2.18+ kernel)
The Linux kernels don't support Amd's direct mounts very well, leading to
erratic behavior: shares that don't get remounted after the first timeout,
inability to restart Amd because its mount points cannot be unmounted, etc.
There are some kernel patches on the am-utils Web site, which solve these
problems. See http://www.am-utils.org/patches/.
Later 2.4.x kernels completely disallow the hack amd was using for direct
mounts, so another solution will have to be found.
Note: the above is for the old-style amd mount_type = nfs. The autofs mounts
don't support direct mounts at all (due to lack of kernel support).
(12) *-aix5.1.0.0 and *-hpux9*
/bin/sh is broken and fails to run the configure script properly. You need
to use /bin/ksh instead. The buildall script will do it for you; if for some
reason you need to run configure directly, run it using 'ksh configure'
instead of just 'configure'.
[12A] *-aix5.2.*
Apparently there is an NFS client side bug in vmount() which causes amd to
hang when it starts (and tries to NFS-mount itself). According to IBM
engineers, this has to do with partial support code for IPv6: the NFS kernel
code doesn't appear to recognize the sin_family of the amd vmount(),
although amd does the right thing. The bug doesn't appear to be in 5.1 or
4.3.3. A fix from IBM is available, APAR number IY41417.
A binary built on 4.3.3 will not work on 5.2, because the kernel ABIs have
changed.
[12C] *-aix*
It is important that you install bos.net.nfs.adt before configuring and
building am-utils. If you don't, you will get compile-time or
configure-time errors, especially when configure tries to find AIX's
definition of struct nfs_args.
(13) *-linux and *-darwin6.0
Certain linux kernels (2.4.18+ are fine, 2.4.10- are probably bad, those in
between have not been tested) have a bug which causes them to reconnect
broken NFS/TCP connections using unprivileged ports (greater than 1024),
unlike the initial connections which do originate from privileged
ports. This can upset quite a few NFS servers and causes accesses to the
mounted shares to fail with "Operation not permitted" (EPERM).
The darwin (MacOS X) kernel defaults to using unprivileged ports, but that
can be changed by setting the resvport mount flag (which amd sets by
default). Nonetheless, if a TCP connection breaks, under certain unclear
circumstances the kernel might "forget" about that flag and start using
unprivileged ports, causing the same EPERM error above.
(14) Solaris
The line "%option" in *.l files may cause Solaris /usr/ccs/bin/lex to abort
with the error "missing translation value." This is a bug in Solaris lex.
Moreover, both Solaris yacc and lex produce code that does not pass strict
compilation such as "gcc -Wall -Werror".
Use GNU Flex and Bison instead. You can download ready-made binaries from
www.sunfreeware.com. Note, however, that sometimes the binaries on
sunfreeware.com don't seem to work, often because they are built against an
older revision of Solaris or build tools. In that case, build a fresh
version of GNU flex and/or bison from the latest stable sources. See
http://www.gnu.org/software/flex/ and http://www.gnu.org/software/bison/.
(15) Solaris 8 + patch 10899[34]-xx (18 <= xx < 25) or patch 11260[56]-xx
With this patch, Sun updated the autofs kernel module and automountd
userspace daemon from version 3 to version 4. They also updated the
/usr/include/rpcsvc/autofs_prot.x file, but forgot to regenerate the
autofs_prot.h file. Thus, when amd is compiled, it uses the old header and
thinks it should use autofs version 3, when in fact the kernel now supports
(and expects) only version 4.
The workaround is to run 'rpcgen -C -h /usr/include/rpcsvc/autofs_prot.x >
/usr/include/rpcsvc/autofs_prot.h' and completely reconfigure and rebuild
am-utils (removing config.cache before running configure).
The problem is fixed in patch revisions 10899[34]-25 and up.
(16) Linux kernel 2.4+ and lofs mounts
Lofs mounts are not supported by the linux kernel, at all, but since 2.4.0
the kernel supports a similar type of mount called a bind mount. Its
semantics are closer to those of a hardlink than to those of lofs, and one
of the results is that bind mounts ignore any mount options paseed to them.
Amd uses bind mounts internally to emulate lofs mounts, which means that
lofs mounts on linux will effectively ignore their mount parameters and
inherit whatever options the original filesystem mounted upon had.
(17) autoconf 2.57
If you see configure warnings of the following kind:
configure: WARNING: sys/proc.h: present but cannot be compiled
configure: WARNING: sys/proc.h: check for missing prerequisite headers?
configure: WARNING: sys/proc.h: proceeding with the preprocessor's result
configure: WARNING: ## ------------------------------------ ##
configure: WARNING: ## Report this to bug-autoconf@gnu.org. ##
configure: WARNING: ## ------------------------------------ ##
please ignore them. They are not real errors, and neither
bug-autoconf@gnu.org nor the am-utils maintainers are interested in hearing
about them. Autoconf simply tries to do more than we need and attempts to
compile each header in isolation, which fails for many system headers.
That's ok, because we only need to know if a header file exists -- we know
how to use it properly ourselves.
While autoconf does offer a way to specify other files to be included with
the tested header, in order to avoid these warnings, using it would enlarge
the resulting configure script by an order of magnitude, and for no real
gain. Configure is big enough as it is, we don't need any more useless
baggage in it.
(18) NetBSD 2.0.2, FreeBSD 5.4, OpenBSD 3.7, and quite possibly most other
BSDs and other OSs (as of September 2005)
Some BSD kernels don't have a way to turn off the NFS attribute cache. They
don't have a 'noac' mount flag, and setting various cache timeout fields in
struct nfs_args doesn't turn off the attribute cache; instead, it sets the
attribute cache timeout to some internal hard-coded default (usually
anywhere from 5-30 seconds). If Amd cannot turn off the NFS attribute
cache, under heavy Amd usage, users could get ESTALE errors from automounted
symlinks, or find that those symlinks point to the wrong place. One
workaround which would minimize this effect is to set auto_attrcache=1 in
your amd.conf, but it doesn't eliminate the problem! The best solutions are
(1) to use Amd in Autofs mode, if it's supported in your OS, and (2) talk to
your OS vendor to support a true "noac" flag. See README.attrcache for more
details.
Erez & the am-utils team.

View File

@ -1,32 +0,0 @@
Copyright (c) 1997-2014 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. 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.

File diff suppressed because it is too large Load Diff

View File

@ -1,69 +0,0 @@
Am-utils Frequently Asked Questions
Note: we started this FAQ only on March 15, 2005; so it's not long or
comprehensive, yet. Amd is much older than that, and so there's a lot of
information that's already available in other forms. If this FAQ doesn't
answer your questions, see information in the following sources:
1. The Am-utils book: http://www.am-utils.org/docs/amd-book/
2. The Am-utils user manual, which is part of the distribution and is also
available from www.am-utils.org.
3. The www.am-utils.org Web site resources, especially the "am-utils" mailing
list (and its archives).
4. In the am-utils distribution (always use the latest ones), see all of the
various README files (README, README.autofs, README.ldap, README.osx, and
README.y2k). The "BUGS" file also lists useful information about bugs
and problems with specific OSs which affect Amd. All of these text files
are also available from www.am-utils.org.
5. Some FAQ questions (including newbie questions) are available here:
http://www.kernelcorp.com/resources_faqs.html
6. Some problems are known bugs but have not been fixed yet: this are
listed in bugzilla in https://bugzilla.am-utils.org/
If you have additions to this FAQ, please let us know at
the am-utils list (see www.am-utils.org).
Thank you,
The Am-utils development team.
<FAQ>
*** Linux Questions
Q1. When I use Amd with Autofs and I restart Amd, how come it cannot remount
the Autofs partitions?
A1. This is a limitation of the Linux Autofs kernel module (for both autofs
v2. and v3). The Linux Autofs does not allow restarting automounted
points. There's nothing Amd can do about this. In fact, the same
problem exists if you use the userland "automount" daemon instead of
Amd. Hopefully Autofs-v4 or the separate effort of Autofs-NG will
address this serious problem.
Note that Amd itself can restart autofs automounted points just fine on
OSs that support it, for example Solaris.
Q2. When I use Amd, I get this console message frequently: "mount version
older than kernel." Is it a problem?
A2. No, it's a harmless warning message that the Linux kernel prints for NFS
mounts. The intent was to alert administrators that the kernel has
supposedly a different version of the mount(2) code than a userland
program used. This happens if you compile Amd against kernel headers
that are different than the kernel you're running. If the message
really bothers you, then one way to "fix" the problem is to recompile
Amd against the same kernel headers as the running kernel.
Nevertheless, it is a relatively useless message because as far as we
know, the NFS v2 and v3 mount codes have been in perfect sync between
the userland and kernel sides, and were "standardized" for years
already. This warning message caused more unnecessary worry among
administrators than helping alert them to legitimate problems.
</FAQ>

View File

@ -1,268 +0,0 @@
$FreeBSD$
*LSM.am-utils
*Makefile.*
*README.autofs
*README.osx
*ac*.m4
*.old
*acconfig.h
*aux
*autom4te.cache*
*buildall
*config*
*depcomp
*install-sh
*lt*
*missing
*mkinstalldirs
*stamp-h.in
*amd/test1.sh
*amd/Makefile.*
*amq/Makefile.*
*commit
*cvs-server.txt
*conf/checkmount/checkmount_aix.c
*conf/checkmount/checkmount_default.c
*conf/checkmount/checkmount_osf.c
*conf/checkmount/checkmount_svr4.c
*conf/checkmount/checkmount_ultrix.c
*conf/fh_dref/fh_dref_aix3.h
*conf/fh_dref/fh_dref_aix42.h
*conf/fh_dref/fh_dref_bsd44.h
*conf/fh_dref/fh_dref_default.h
*conf/fh_dref/fh_dref_hpux.h
*conf/fh_dref/fh_dref_irix.h
*conf/fh_dref/fh_dref_isc3.h
*conf/fh_dref/fh_dref_linux.h
*conf/fh_dref/fh_dref_nextstep.h
*conf/fh_dref/fh_dref_osf2.h
*conf/fh_dref/fh_dref_osf4.h
*conf/fh_dref/fh_dref_sunos3.h
*conf/fh_dref/fh_dref_sunos4.h
*conf/fh_dref/fh_dref_svr4.h
*conf/hn_dref/hn_dref_default.h,
*conf/hn_dref/hn_dref_isc3.h
*conf/hn_dref/hn_dref_linux.h
*conf/mount/mount_aix.c
*conf/mount/mount_aix3.c
*conf/mount/mount_bsdi3.c
*conf/mount/mount_default.c
*conf/mount/mount_freebsd3.c
*conf/mount/mount_hpux.c
*conf/mount/mount_irix5.c
*conf/mount/mount_irix6.c
*conf/mount/mount_isc3.c
*conf/mount/mount_linux.c
*conf/mount/mount_mach3.c
*conf/mount/mount_stellix.c
*conf/mount/mount_svr4.c
*conf/mtab/mtab_aix.c
*conf/mtab/mtab_file.c
*conf/mtab/mtab_isc3.c
*conf/mtab/mtab_linux.c
*conf/mtab/mtab_mach3.c
*conf/mtab/mtab_osf.c
*conf/mtab/mtab_svr4.c
*conf/mtab/mtab_ultrix.c
*conf/nfs_prot/nfs_prot_aix3.h
*conf/nfs_prot/nfs_prot_aix4.h
*conf/nfs_prot/nfs_prot_aix4_2.h
*conf/nfs_prot/nfs_prot_aix4_3.h
*conf/nfs_prot/nfs_prot_aix5_1.h
*conf/nfs_prot/nfs_prot_aix5_2.h
*conf/nfs_prot/nfs_prot_bsdi2.h
*conf/nfs_prot/nfs_prot_bsdi3.h
*conf/nfs_prot/nfs_prot_darwin.h
*conf/nfs_prot/nfs_prot_default.h
*conf/nfs_prot/nfs_prot_hpux.h
*conf/nfs_prot/nfs_prot_hpux11.h
*conf/nfs_prot/nfs_prot_irix5.h
*conf/nfs_prot/nfs_prot_irix6.h
*conf/nfs_prot/nfs_prot_linux.h
*conf/nfs_prot/nfs_prot_ncr2.h
*conf/nfs_prot/nfs_prot_netbsd.h
*conf/nfs_prot/nfs_prot_netbsd1_3.h
*conf/nfs_prot/nfs_prot_netbsd1_4.h
*conf/nfs_prot/nfs_prot_nextstep.h
*conf/nfs_prot/nfs_prot_openbsd.h
*conf/nfs_prot/nfs_prot_osf2.h
*conf/nfs_prot/nfs_prot_osf4.h
*conf/nfs_prot/nfs_prot_osf5.h
*conf/nfs_prot/nfs_prot_osf5_1.h
*conf/nfs_prot/nfs_prot_sunos3.h
*conf/nfs_prot/nfs_prot_sunos4.h
*conf/nfs_prot/nfs_prot_sunos5_3.h
*conf/nfs_prot/nfs_prot_sunos5_4.h
*conf/nfs_prot/nfs_prot_sunos5_5.h
*conf/nfs_prot/nfs_prot_sunos5_6.h
*conf/nfs_prot/nfs_prot_sunos5_7.h
*conf/nfs_prot/nfs_prot_sunos5_8.h
*conf/nfs_prot/nfs_prot_svr4.h
*conf/nfs_prot/nfs_prot_ultrix.h
*conf/autofs/autofs_linux.h
*conf/autofs/autofs_linux.c
*conf/autofs/autofs_solaris_v1.h
*conf/autofs/autofs_solaris_v1.c
*conf/autofs/autofs_solaris_v2_v3.h
*conf/autofs/autofs_solaris_v2_v3.c
*conf/sa_dref/sa_dref_386bsd.h
*conf/sa_dref/sa_dref_aix3.h
*conf/sa_dref/sa_dref_aoi.h
*conf/sa_dref/sa_dref_default.h
*conf/sa_dref/sa_dref_isc3.h
*conf/sa_dref/sa_dref_linux.h
*conf/sa_dref/sa_dref_svr4.h
*conf/transp/transp_tli.c
*conf/trap/trap_aix3.h
*conf/trap/trap_aux.h
*conf/trap/trap_dgux.h
*conf/trap/trap_freebsd3.h
*conf/trap/trap_hcx.h
*conf/trap/trap_hpux.h
*conf/trap/trap_hpux11.h
*conf/trap/trap_irix.h
*conf/trap/trap_isc3.h
*conf/trap/trap_linux.h
*conf/trap/trap_mach3.h
*conf/trap/trap_news4.h
*conf/trap/trap_rtu6.h
*conf/trap/trap_stellix.h
*conf/trap/trap_svr4.h
*conf/trap/trap_ultrix.h
*conf/umount/umount_aix.c
*conf/umount/umount_default.c
*conf/umount/umount_linux.c
*conf/umount/umount_osf.c
*doc/Makefile.am
*doc/Makefile.in
*doc/am-utils.dvi
*doc/am-utils.info
*doc/am-utils.info-1
*doc/am-utils.info-2
*doc/am-utils.info-3
*doc/am-utils.info-4
*doc/am-utils.info-5
*doc/am-utils.info-6
*doc/am-utils.info-7
*doc/am-utils.ps
*doc/hlfsd.ps
*doc/mdate-sh
*fixmount/Makefile.*
*fsinfo/Makefile.*
*hlfsd/Makefile.*
*libamu/Makefile.*
*libamu/alloca.c
*libamu/clnt_sperrno.c
*libamu/memcmp.c
*libamu/strcasecmp.c
*libamu/strdup.c
*libamu/strstr.c
*libamu/strlcat.c
*libamu/strlcpy.c
*libamu/ualarm.c
*mk-amd-map/Makefile.*
*wire-test/Makefile.*
*m4/GNUmakefile
*m4/amdgrep*
*m4/amindent*
*m4/autopat*
*m4/chop-aclocal.pl*
*m4/copy-if-newbig*
*m4/mk-aclocal*
*m4/mkconf*
*m4/rmtspc*
*m4/update_build_version*
*m4/macros/HEADER
*m4/macros/TRAILER
*m4/macros/c_void_p.m4
*m4/macros/cache_check_dynamic.m4
*m4/macros/check_amu_fs.m4
*m4/macros/check_checkmount_style.m4
*m4/macros/check_extern.m4
*m4/macros/check_fhandle.m4
*m4/macros/check_field.m4
*m4/macros/check_fs_headers.m4
*m4/macros/check_fs_mntent.m4
*m4/macros/check_gnu_getopt.m4
*m4/macros/check_hide_mount_type.m4
*m4/macros/check_lib2.m4
*m4/macros/check_map_funcs.m4
*m4/macros/check_mnt2_cdfs_opt.m4
*m4/macros/check_mnt2_gen_opt.m4
*m4/macros/check_mnt2_nfs_opt.m4
*m4/macros/check_mnttab_file_name.m4
*m4/macros/check_mnttab_location.m4
*m4/macros/check_mnttab_opt.m4
*m4/macros/check_mnttab_style.m4
*m4/macros/check_mnttab_type.m4
*m4/macros/check_mount_style.m4
*m4/macros/check_mount_trap.m4
*m4/macros/check_mount_type.m4
*m4/macros/check_mtype_printf_type.m4
*m4/macros/check_mtype_type.m4
*m4/macros/check_network_transport_type.m4
*m4/macros/check_nfs_fh_dref.m4
*m4/macros/check_nfs_hn_dref.m4
*m4/macros/check_nfs_prot_headers.m4
*m4/macros/check_nfs_sa_dref.m4
*m4/macros/check_nfs_socket_connection.m4
*m4/macros/check_os_libs.m4
*m4/macros/check_restartable_signal_handler.m4
*m4/macros/check_umount_style.m4
*m4/macros/check_unmount_args.m4
*m4/macros/check_unmount_call.m4
*m4/macros/expand_cpp_hex.m4
*m4/macros/expand_cpp_int.m4
*m4/macros/expand_cpp_string.m4
*m4/macros/expand_run_string.m4
*m4/macros/extern_optarg.m4
*m4/macros/extern_sys_errlist.m4
*m4/macros/field_mntent_t_mnt_time_string.m4
*m4/macros/func_bad_memcmp.m4
*m4/macros/func_bad_yp_all.m4
*m4/macros/header_templates.m4
*m4/macros/host_macros.m4
*m4/macros/linux_headers.m4
*m4/macros/localconfig.m4
*m4/macros/mount_headers.m4
*m4/macros/name_package.m4
*m4/macros/name_version.m4
*m4/macros/opt_amu_cflags.m4
*m4/macros/opt_cppflags.m4
*m4/macros/opt_debug.m4
*m4/macros/opt_ldflags.m4
*m4/macros/opt_libs.m4
*m4/macros/os_cflags.m4
*m4/macros/os_cppflags.m4
*m4/macros/os_ldflags.m4
*m4/macros/package_bugreport.m4
*m4/macros/package_name.m4
*m4/macros/package_version.m4
*m4/macros/save_state.m4
*m4/macros/struct_field_nfs_fh.m4
*m4/macros/struct_mntent.m4
*m4/macros/struct_mnttab.m4
*m4/macros/struct_nfs_args.m4
*m4/macros/struct_nfs_fh.m4
*m4/macros/struct_nfs_fh3.m4
*m4/macros/struct_nfs_gfs_mount.m4
*m4/macros/try_compile_anyfs.m4
*m4/macros/try_compile_nfs.m4
*m4/macros/try_compile_rpc.m4
*m4/macros/type_auth_create_gidlist.m4
*m4/macros/type_cachefs_args.m4
*m4/macros/type_cdfs_args.m4
*m4/macros/type_efs_args.m4
*m4/macros/type_lofs_args.m4
*m4/macros/type_mfs_args.m4
*m4/macros/type_pcfs_args.m4
*m4/macros/type_recvfrom_fromlen.m4
*m4/macros/type_rfs_args.m4
*m4/macros/type_svc_in_arg.m4
*m4/macros/type_time_t.m4
*m4/macros/type_tmpfs_args.m4
*m4/macros/type_ufs_args.m4
*m4/macros/type_xdrproc_t.m4
*m4/macros/type_xfs_args.m4
*m4/macros/type_yp_order_outorder.m4
*m4/macros/with_addon.m4

View File

@ -1,103 +0,0 @@
# ex:ts=8
$FreeBSD$
AMD (am-utils) 6.1.5
originals can be found at: ftp://ftp.am-utils.org/pub/am-utils/
For the import of AMD many files were pruned by:
tar -X FREEBSD-Xlist -xf am-utils-6.1.5.tar.gz
and `find . -name '.cvsignore' -delete`
Then imported by:
cvs import -m 'Virgin import of AMD (am-utils) v6.1.5' \
src/contrib/amd COLUMBIA amd_6_1_5
After the import, a separate extraction of am-utils was GNU configured in
the "normal" way. The resulting config.h file should be compared with
src/usr.sbin/amd/include/config.h, and src/usr.sbin/amd/include/config.h
updated as needed.
To make local changes to amd, simply patch and commit to the main
branch (aka HEAD). Never make local changes on the vendor (COLUMBIA) branch.
Note, we don't trim anything in scripts/ as sysadmins may find the bits
as a useful reference.
All local changes should be submitted to "am-utils@am-utils.org" or
https://bugzilla.am-utils.org for inclusion in the next vendor release.
Local changes:
amd/amd.8
- corrected formatting of SEE ALSO
r1.17 Uniformly refer to a file system as "file system"
r1.16 Add the am-utils homepage to SEE ALSO
r1.15 s/BSD/.Bx/ where appropriate
r1.14 Avoid using parenthesis enclosure macros
r1.13 split punctuation characters + misc fixes
r1.12 mdoc(7)NG
r1.11 Catch a left over reference to "/a"
r1.10 Document change to the default mount dir.
r1.9 Mention "amd -H" in the synopsis
r1.8 Fix miscellaneous mdoc macro argument limit infringements
r1.7 Don't refer to non-existent automount(8)
r1.6 Fix errors in .Xr usage
r1.3 un-mandocafied, un4.4BSD'ed
r1.2 sort cross references
amd/amd.c
r1.7 use /.amd_mnt as default for -a
amq/amq.8
r1.9 Uniformly refer to a file system as "file system".
r1.8 s/BSD/.Bx/ where appropriate.
r1.6 mdoc(7)NG.
r1.5 Remove reference to non-existent manpage
r1.4 Fix typos
r1.3 un-mandocafied, un4.4BSD'ed
amq/pawd.1
r1.3 un-mandocafied, un4.4BSD'ed
r1.2 sorting of references
conf/nfs_prot/nfs_prot_freebsd3.h
r1.11 Userland part of nfs client/server split and cleanup
r1.6 restore the standard name nfs_fh3
r1.3 Fully use our own generated files for NFSv3
r1.2 rpcgen our own files for NFSv3 support
fixmount/fixmount.8
r1.8 Uniformly refer to a file system as "file system"
r1.6 split punctuation characters + misc fixes.
r1.5 mdoc(7)NG.
r1.4 ".Mn mountd" -> ".Nm mountd"
r1.3 un-mandocafied, un4.4BSD'ed
r1.2 More sorting of references.
fsinfo/fsinfo.8
r1.9 add section number to .Xr directive
r1.7 Uniformly refer to a file system as "file system"
r1.6 split punctuation characters + misc fixes
r1.5 mdoc(7)NG
r1.3 describe all of the command line options
r1.2 un-mandocafied, un4.4BSD'ed
hlfsd/hlfsd.8
- Fix a broken SEE ALSO section and some mdoc issues
mk-amd-map/mk-amd-map.8
r1.4 removed HISTORY info from the .Os call.
r1.2 un-mandocafied, un4.4BSD'ed
scripts/amd.conf.5
r1.15 Bring man page back in shape
r1.13 Uniformly refer to a file system as "file system"
r1.12 Avoid using parenthesis enclosure macros
r1.11 mdoc(7)NG
r1.10 Fix miscellaneous mdoc macro argument limit infringements
r1.8 Fix a bunch of broken cross-references
r1.7 Bad reference of uname(2) -> uname(3)
r1.6 Grammer fix and style nits.
r1.5 xfer typo
r1.4 un-mandocafied, un4.4BSD'ed
r1.3 More sorting of references.
wire-test/wire-test.8
r1.2 un-mandocafied, un4.4BSD'ed
mbr@FreeBSD.org
obrien@NUXI.com
05-November-1999

View File

@ -1,370 +0,0 @@
Installation Instructions
*************************
Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Basic Installation
==================
Briefly, the shell command `./configure && make && make install'
should configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
4. Type `make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
privileges.
5. Optionally, type `make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
7. Often, you can also type `make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide `make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, `make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.
The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
HP-UX `make' updates targets which have the same time stamps as
their prerequisites, which makes it generally unusable when shipped
generated files such as `configure' are involved. Use GNU `make'
instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf limitation. Until the limitation is lifted, you can use
this workaround:
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of all of the options to `configure', and exit.
`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

View File

@ -1,106 +0,0 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Erez Zadok">
<TITLE>Am-Utils 6.x Mirror Sites</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<CENTER>
<H1> Am-Utils 6.x Software Mirror Sites</H1></CENTER>
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
"am-utils-developers AT am-utils.org" with the
full URL, maintainer's email, and geographical location.
<P>
<H2>North America</H2>
<UL>
<LI> New York (Stony Brook, Primary Site)
<UL>
<LI> FTP: <A
HREF="ftp://ftp.am-utils.org/pub/am-utils">ftp.am-utils.org</A>.
Contact person in case of problems
"am-utils-developers AT am-utils.org".
</LI>
</UL>
<LI> Minnesota
<UL>
<LI> FTP: <A
HREF="ftp://ftp.cs.umn.edu/pub/am-utils">ftp.cs.umn.edu</A>.
Maintainer <A HREF="mailto:dokas AT cs.umn.edu">dokas AT cs.umn.edu</A>.
</LI>
</UL>
<LI> Florida (University of Florida)
<UL>
<LI> FTP: <A HREF="ftp://ftp.cise.ufl.edu/pub/mirrors/am-utils">ftp.cise.ufl.edu</A>.
Maintainer <A HREF="mailto:mirror AT cise.ufl.edu">mirror AT cise.ufl.edu</A>.
</LI>
</UL>
</UL>
<H2>Europe</H2>
<UL>
<LI> Germany
<UL>
<LI> FTP: <A HREF="ftp://ftp.fu-berlin.de/unix/network/am-utils">ftp.fu-berlin.de</A>.
Maintainer <A HREF="mailto:ftp-adm AT ftp.fu-berlin.de">ftp-adm AT ftp.fu-berlin.de</A>.
</LI>
<LI> FTP: <A HREF="ftp://ftp.tu-darmstadt.de/pub/networking/filesystems/am-utils/">ftp.tu-darmstadt.de</A>.
Maintainer <A HREF="mailto:networking AT ftp.tu-darmstadt.de">networking AT ftp.tu-darmstadt.de</A>.
</LI>
</UL>
<LI> Sweden
<UL>
<LI> FTP: <A HREF="ftp://ftp.sunet.se/pub/unix/admin/am-utils">ftp.sunet.se</A>.
Maintainer <A HREF="mailto:archive AT ftp.sunet.se">archive AT ftp.sunet.se</A>.
</LI>
</UL>
<LI> UK
<UL>
<LI> FTP: <A HREF="ftp://sunsite.org.uk/package/am-utils">sunsite.org.uk</A>.
Maintainer <A HREF="mailto:lmjm AT icparc.ic.ac.uk">lmjm AT icparc.ic.ac.uk</A>.
</LI>
</UL>
</UL>
<H2>Asia</H2>
<UL>
<LI> Japan
<UL>
<LI> FTP: <A HREF="ftp://ftp.u-aizu.ac.jp/pub/net/amd/am-utils">ftp.u-aizu.ac.jp</A>.
Maintainer <A HREF="mailto:ftp-admin AT u-aizu.ac.jp">ftp-admin AT u-aizu.ac.jp</A>.
</LI>
<LI> FTP: <A HREF="ftp://core.ring.gr.jp/pub/net/am-utils/">core.ring.gr.jp</A>.
Maintainer <A HREF="mailto:ftpadmin AT ring.gr.jp">ftpadmin AT ring.gr.jp</A>.
</LI>
<LI> FTP: <A HREF="ftp://ftp.ring.gr.jp/pub/net/am-utils/">ftp.ring.gr.jp</A>.
Maintainer <A HREF="mailto:ftpadmin AT ring.gr.jp">ftpadmin AT ring.gr.jp</A>.
</LI>
</UL>
</UL>
<HR>
<I> Last updated: 2006-11-27</I>
</BODY>
</HTML>
<!---
<LI> FTP: <A HREF="X">X</A>.
Maintainer <A HREF="mailto:X">X</A>.
-->

View File

@ -1,60 +0,0 @@
AM-UTILS-6.x 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 am-utils-developers AT am-utils.org
with the full URL, maintainer's email, and geographical location.
U.S.A:
New York (Stony Brook, Primary Site):
ftp://ftp.am-utils.org/pub/am-utils
Maintainer: ezk AT am-utils.org
Minnesota:
ftp://ftp.cs.umn.edu/pub/am-utils
Maintainer: dokas AT cs.umn.edu
#Avoid for now: empty directory
# Virginia (Newport News):
# ftp://ftp.ferginc.com/pub/unix/am-utils
# Maintainer: Branson.Matheson AT FergInc.com
#server gone? (Jan 5, 2004)
# Ohio (Kent State University):
# ftp://info.mcs.kent.edu/pub/am-utils
# Maintainer: root AT mcs.kent.edu
Florida (University of Florida)
ftp://ftp.cise.ufl.edu/pub/mirrors/am-utils
Maintainer: mirror AT cise.ufl.edu
Europe:
Germany:
ftp://ftp.fu-berlin.de/unix/network/am-utils
Maintainer: ftp-adm AT ftp.fu-berlin.de
Germany:
ftp://ftp.tu-darmstadt.de/pub/networking/filesystems/am-utils/
Maintainer: networking AT ftp.tu-darmstadt.de
Sweden:
ftp://ftp.sunet.se/pub/unix/admin/am-utils
Maintainer: archive AT ftp.sunet.se
# not responding (Jan 5, 2004)
# Sweden (Stockholm University, Math Depat):
# ftp://mirror.matematik.su.se/pub/am-utils
# Maintainer: leifj AT matematik.su.se
UK:
ftp://sunsite.org.uk/package/am-utils
Maintainer: lmjm AT icparc.ic.ac.uk
Asia:
Japan:
ftp://ftp.u-aizu.ac.jp/pub/net/amd/am-utils
Maintainer: ftp-admin AT u-aizu.ac.jp
Japan:
ftp://core.ring.gr.jp/pub/net/am-utils/
Maintainer: ftpadmin AT ring.gr.jp
Japan:
ftp://ftp.ring.gr.jp/pub/net/am-utils/
Maintainer: ftpadmin AT ring.gr.jp
# gone? (Jan 5, 2004)
# Australia:
# Melbourne:
# ftp://ftp.sage-au.org.au/pub/network/filesystem/am-utils
# Maintainer: mirror AT ftp.sage-au.org.au

File diff suppressed because it is too large Load Diff

View File

@ -1,104 +0,0 @@
This is the official version of am-utils.
See the file NEWS for news on this and previous releases.
*** General Notes to alpha/beta testers:
[A] as alpha/beta 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 does precisely that, using the A.* subdirectories.
(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 m4/ or conf/ directories, or any *.in
or *.am file, then you must rebuild the configure script, Makefile.in files,
aclocal.m4, etc. The best way to do so is to run
./bootstrap
or
./buildall -K
To be a developer and be able to run "bootstrap", you must have
autoconf-2.68, automake-1.11.1, and libtool 2.2.6b installed on your system (or
later versions thereof). You no longer need to get my special version of
automake. Contact me if you'd like to be a maintainer and get access to the
CVS server.
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 via Bugzilla or the am-utils list (see
www.am-utils.org). 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.

View File

@ -1,129 +0,0 @@
NFS Attribute Caching OS Problems and Amd
Last updated September 18, 2005
* Summary:
Some OSs don't seem to have a way to turn off the NFS attribute cache, which
breaks the Amd automounter so badly that it is not recommend using Amd on
such OS for heavy use, not until this is fixed.
* Details:
Amd is a user-level NFSv2 server that manages automounts of all other file
systems. The kernel contacts Amd via RPCs, and Amd in turn performs the
actual mounts, and then responds back to the kernel's RPCs. Every kernel
caches attributes of files, in a cache called the Directory Name Lookup
Cache (DNLC), or a Directory Cache (dcache).
Amd manages its namespace in the user level, but the kernel caches names
itself. So the two must coordinate to ensure that both namespaces are in
sync. If the kernel uses a cached entry from the DNLC, without consulting
Amd, users may see corruption of the automounter namespace (symlinks
pointing to the wrong places, ESTALE errors, and more). For example,
suppose Amd timed out an entry and removed the entry from Amd's namespace.
Amd has to tell the kernel to purge its corresponding DNLC entry too. The
way Amd often does that is by incrementing the last modification time
(mtime) of the parent directory. This is the most common method for kernels
to check if their DNLC entries are stale: if the parent directory mtime is
newer, the kernel will discard all cached entries for that directory, and
will re-issue lookup methods. Those lookups will result in
NFS_GETATTR/NFS_LOOKUP calls sent from the kernel down to Amd, and Amd can
then properly inform the kernel of the new state of automounted entries.
In order to ensure that Amd is "in charge" of its namespace without
interference from the kernel, Amd will try to turn off the NFS attribute
cache. It does so by using the NFSMNT_NOAC flag, if it exists, or by
setting various "cache timeout" fields in struct nfs_args to 0 (acregmin,
acregmax, acdirmin, or acdirmax).
We have released a major new version of am-utils, version 6.1, in June 2005.
Since then, a lot of people have experimented with Amd, in anticipation of
migrating from the very old am-utils 6.0 to the new 6.1. For a couple of
months since the release of 6.1, we have received reports of problems with
Amd, especially under heavy use. Users reported getting ESTALE errors from
time to time, or seeing automounted entries whose symlinks don't point to
where it should be. After much debugging, we traced it to a few places in
Amd where it wasn't updating the parent directory mtime as it should have;
in some places where Amd was indeed updating the mtime, it was using a
resolution of only 1 second, which was not fine enough under heavy load. We
fixed this problem and switched to using a microsecond resolution mtime.
After fixing this in Amd, we went on to verify that things work for other
OSs. When we got to test certain BSDs, we found out that they always cache
directory entries, and there is no way to turn it off completely.
Specifically, if we set the ac{reg,dir}{min,max} fields in struct nfs_args
all to zero, the kernel seems to cache the entries for a default number of
seconds (something like 5-30 seconds). On some OSs, setting these four
fields to 0 turns off the attribute cache, but not on some BSDs. We were
able to verify this using Amd and a script that exercises the interaction of
the kernel's attrcache and Amd. (If you're interested, the script can be
made available.)
We then experimented by setting the ac{reg,dir}{min,max} fields in struct
nfs_args all to 1, the smallest non-zero value we could. When we ran the
Amd exercising script, we found that the value of 1 reduced the race between
the DNLC and Amd, and the script took a little longer to run before it
detected an incoherency. That makes sense: the smaller the DNLC cache
interval is, the shorter the window of vulnerability is. (BTW, the man
pages on some OSs say that the ac{reg,dir}{min,max} fields use a 1 second
resolution, but experimentation indicated it was in 0.1 second units.)
Clearly, setting the ac{reg,dir}{min,max} fields to 0 is worse than setting
it to 1 on those OSs that don't have a way to turn off the attribute cache.
So the current workaround I've implemented in am-utils is to create a
configuration parameter called "broken_attrcache" which, if turned on, will
set these nfs_args fields to 1 instead of 0. I wish I didn't have to create
such ugly workaround features in Amd, but I've got no choice.
The near term solution is for every OS to support a true 'noac' flag, which
can be added fairly easily. This'd make Amd work reliably.
The long term solution is to implement Autofs support for all OSs and to
support it in Amd. Currently, Amd supports autofs on Solaris and Linux;
FreeBSD is next. Still, we found that even with autofs support, many
sysadmins still prefer to use the good 'ol non-autofs mode.
* Confirmed Status
This is the confirmed status of various OSs' vulnerability to this attribute
cache bug. We are slowly checking the status of other OSs. The status of
any OS not listed is unknown as of the date at the top of this file.
** Not Vulnerable (support a proper "noac" flag):
Sun Solaris 8 and 9 (10 probably works fine)
Linux: 2.6.11 kernel (2.4.latest probably works fine)
FreeBSD 5.4 and 6.0-SNAP001 (older versions probably work fine)
OpenBSD 3.7 (older versions probably work fine)
** Vulnerable (don't support a proper "noac" flag natively):
NetBSD 2.0.2 (older versions are also probably affected)
Note: NetBSD has promised to support a noac flag hopefully after 2.1.0 is
released (maybe in 3.0 or 2.2). In the mean time, you can apply one of
these two kernel patchs to support a 'noac' flag in NetBSD 2.x or 3.x:
ftp://ftp.netbsd.org/pub/NetBSD/misc/christos/2x.nfs.noac.diff
ftp://ftp.netbsd.org/pub/NetBSD/misc/christos/3x.nfs.noac.diff
After applying this patch and rebuilding your kernel, reboot with the new
kernel. Then copy the new nfs.h and nfsmount.h from /sys/nfs/ to
/usr/include/nfs/, and finally rebuild am-utils from scratch.
** Testing
When you build am-utils, a script named scripts/test-attrcache is built,
which can be used to test the NFS attribute cache behavior of the current
OS. You can run this script as root as follows:
# make install
# cd scripts
# sh test-attrcache
If you run this script on an OS whose status is known (and not listed
above), please report it to us via Bugzilla or the am-utils mailing list
(see www.am-utils.org), so we can record it in this file.
Sincerely,
Erez.

View File

@ -1,57 +0,0 @@
LDAP support for am-utils was originally done by Leif Johansson
<leifj AT it.su.se>. He no longer maintains it.
The current LDAP support for am-utils is for LDAPv2 only. Reportedly,
LDAPv3 mostly works. Volunteers and patches are welcome.
The IANA has assigned the following Private Enterprise Number to:
10180 Am-utils Organization Erez Zadok ezk AT am-utils.org
There are three files in this directory that relate to LDAP:
ldap.schema:
This is the most current schema.
ldap-id.txt:
This is an experimental schema for amd mount maps in LDAP. Since
LDAP isn't maintained now, this code may not match with either the
current ldap_info.c code or with Amd mount maps in general.
The schema is written in the form of an internet-draft but it has
not been published as such. We need volunteers who know and use
LDAP to clean it up and further its process of submission.
ldap-id.ms:
This is the NROFF source of the draft. To generate the text from
it, run "nroff -ms ldap-id.ms > ldap-id.txt"
Erez.
------- Forwarded Message
From: "IANA Private Enterprise Number" <iana-pen AT icann.org>
To: "Erez Zadok" <ezk AT cs.columbia.edu>
Subject: RE: Application for Enterprise-number (10180)
Date: Sun, 15 Jul 2001 14:43:45 -0700
Dear Erez,
The IANA has assigned the following Private Enterprise
Number to:
10180 Am-utils Organization Erez Zadok ezk AT am-utils.org
Please notify the IANA if there is a change in your contact
or company information.
Thank you,
Bill Huang
IANA - Private Enterprise Numbers
------- End of Forwarded Message

View File

@ -1,26 +0,0 @@
AM-UTILS YEAR-2000 COMPLIANCE
Most likely am-utils is y2k compliant.
I do not know for sure because I have not certified am-utils myself, nor do
I have the time for it. I do not think that amd will be affected by y2k at
all, because it does not do anything with dates other than print the date on
the log file, in whatever format is provided by your os/libc --- especially
the ctime(3) call.
However, on Friday, September 18th 1998, Matthew Crosby <mcrosby AT ms.com>
reported that they evaluated 6.0a16 and found it to be compliant.
On March 26, 1999, Paul Balyoz <pbalyoz AT sedona.ch.intel.com> submitted a
patch to lostaltmail which makes it print Y2K compliant dates. He used a
code scanner and manually "eyeballed" the code and could not find any more
problems. Paul's patch is included in am-utils-6.0.1s7 and newer versions.
Paul also said that other 2-digit years used in am-utils are "harmless."
NOTE: NONE OF THE PERSONS MENTIONED HERE, AUTHOR INCLUDED, ARE WILLING TO
CERTIFY AM-UTILS AS Y2K COMPLIANT. USE AT YOUR OWN RISK.
---
Erez Zadok.
Maintainer, am-utils package and am-utils list.
WWW: http://www.am-utils.org

View File

@ -1,484 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/am_ops.c
*
*/
#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_AMU_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_AMU_FS_LINK
&amfs_link_ops, /* symlink F/S */
#endif /* HAVE_AMU_FS_LINK */
/*
* Other amd-supported meta-filesystems.
*/
#ifdef HAVE_AMU_FS_NFSX
&amfs_nfsx_ops, /* multiple-nfs F/S */
#endif /* HAVE_AMU_FS_NFSX */
#ifdef HAVE_AMU_FS_NFSL
&amfs_nfsl_ops, /* NFS with local link existence check */
#endif /* HAVE_AMU_FS_NFSL */
#ifdef HAVE_AMU_FS_HOST
&amfs_host_ops, /* multiple exported nfs F/S */
#endif /* HAVE_AMU_FS_HOST */
#ifdef HAVE_AMU_FS_LINKX
&amfs_linkx_ops, /* symlink F/S with link target verify */
#endif /* HAVE_AMU_FS_LINKX */
#ifdef HAVE_AMU_FS_PROGRAM
&amfs_program_ops, /* program F/S */
#endif /* HAVE_AMU_FS_PROGRAM */
#ifdef HAVE_AMU_FS_UNION
&amfs_union_ops, /* union F/S */
#endif /* HAVE_AMU_FS_UNION */
/*
* 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_EXT
&ext2_ops, /* Unix (linux) F/S */
&ext3_ops, /* Unix (linux) F/S */
&ext4_ops, /* Unix (linux) F/S */
#endif /* HAVE_FS_EXT */
#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_TMPFS
&tmpfs_ops, /* /tmp (in memory) F/S */
#endif /* HAVE_FS_TMPFS */
#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 */
#ifdef HAVE_FS_UDF
&udf_ops, /* UDF F/S */
#endif /* HAVE_FS_UDF */
#ifdef HAVE_FS_LUSTRE
&lustre_ops, /* Lustre */
#endif /* HAVE_FS_LUSTRE */
/*
* These 4 should be last, in the order:
* (1) amfs_auto
* (2) amfs_direct
* (3) amfs_toplvl
* (4) amfs_error
*/
#ifdef HAVE_AMU_FS_AUTO
&amfs_auto_ops, /* Automounter F/S */
#endif /* HAVE_AMU_FS_AUTO */
#ifdef HAVE_AMU_FS_DIRECT
&amfs_direct_ops, /* direct-mount F/S */
#endif /* HAVE_AMU_FS_DIRECT */
#ifdef HAVE_AMU_FS_TOPLVL
&amfs_toplvl_ops, /* top-level mount F/S */
#endif /* HAVE_AMU_FS_TOPLVL */
#ifdef HAVE_AMU_FS_ERROR
&amfs_error_ops, /* error F/S */
#endif /* HAVE_AMU_FS_ERROR */
0
};
void
ops_showamfstypes(char *buf, size_t l)
{
struct am_ops **ap;
int linesize = 0;
buf[0] = '\0';
for (ap = vops; *ap; ap++) {
xstrlcat(buf, (*ap)->fs_type, l);
if (ap[1])
xstrlcat(buf, ", ", l);
linesize += strlen((*ap)->fs_type) + 2;
if (linesize > 62) {
linesize = 0;
xstrlcat(buf, "\n ", l);
}
}
}
static void
ops_show1(char *buf, size_t l, int *linesizep, const char *name)
{
xstrlcat(buf, name, l);
xstrlcat(buf, ", ", l);
*linesizep += strlen(name) + 2;
if (*linesizep > 60) {
xstrlcat(buf, "\t\n", l);
*linesizep = 0;
}
}
void
ops_showfstypes(char *buf, size_t l)
{
int linesize = 0;
buf[0] = '\0';
#ifdef MNTTAB_TYPE_AUTOFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_AUTOFS);
#endif /* MNTTAB_TYPE_AUTOFS */
#ifdef MNTTAB_TYPE_CACHEFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_CACHEFS);
#endif /* MNTTAB_TYPE_CACHEFS */
#ifdef MNTTAB_TYPE_CDFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_CDFS);
#endif /* MNTTAB_TYPE_CDFS */
#ifdef MNTTAB_TYPE_CFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_CFS);
#endif /* MNTTAB_TYPE_CFS */
#ifdef MNTTAB_TYPE_LOFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_LOFS);
#endif /* MNTTAB_TYPE_LOFS */
#ifdef MNTTAB_TYPE_EFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_EFS);
#endif /* MNTTAB_TYPE_EFS */
#ifdef MNTTAB_TYPE_MFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_MFS);
#endif /* MNTTAB_TYPE_MFS */
#ifdef MNTTAB_TYPE_NFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_NFS);
#endif /* MNTTAB_TYPE_NFS */
#ifdef MNTTAB_TYPE_NFS3
ops_show1(buf, l, &linesize, "nfs3"); /* always hard-code as nfs3 */
#endif /* MNTTAB_TYPE_NFS3 */
#ifdef MNTTAB_TYPE_NULLFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_NULLFS);
#endif /* MNTTAB_TYPE_NULLFS */
#ifdef MNTTAB_TYPE_PCFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_PCFS);
#endif /* MNTTAB_TYPE_PCFS */
#ifdef MNTTAB_TYPE_TFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_TFS);
#endif /* MNTTAB_TYPE_TFS */
#ifdef MNTTAB_TYPE_TMPFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_TMPFS);
#endif /* MNTTAB_TYPE_TMPFS */
#ifdef MNTTAB_TYPE_UFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_UFS);
#endif /* MNTTAB_TYPE_UFS */
#ifdef MNTTAB_TYPE_UMAPFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_UMAPFS);
#endif /* MNTTAB_TYPE_UMAPFS */
#ifdef MNTTAB_TYPE_UNIONFS
ops_show1(buf, l, &linesize, MNTTAB_TYPE_UNIONFS);
#endif /* MNTTAB_TYPE_UNIONFS */
#ifdef MNTTAB_TYPE_XFS
ops_show1(buf, l, &linesize, 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';
xstrlcat(buf, ".\n", l);
}
/*
* 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)) {
xstrlcpy(buf, &opt[2], sizeof(buf));
} else {
/* finally return a string prepended with 'no' */
xstrlcpy(buf, "no", sizeof(buf));
xstrlcat(buf, opt, sizeof(buf));
}
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(const char *opts1, const char *opts2)
{
mntent_t mnt2; /* place holder for opts2 */
char *newstr; /* new string to return (malloc'ed) */
char *tmpstr; /* temp */
char *eq; /* pointer to whatever follows '=' within temp */
char oneopt[80]; /* one option w/o value if any */
char *revoneopt; /* reverse of oneopt */
size_t len = strlen(opts1) + strlen(opts2) + 2; /* space for "," and NULL */
char *s1 = xstrdup(opts1); /* copy of opts1 to munge */
/* initialization */
mnt2.mnt_opts = (char *) opts2;
newstr = xmalloc(len);
newstr[0] = '\0';
for (tmpstr = strtok(s1, ",");
tmpstr;
tmpstr = strtok(NULL, ",")) {
/* copy option to temp buffer */
xstrlcpy(oneopt, tmpstr, sizeof(oneopt));
/* if option has a value such as rsize=1024, chop the value part */
if ((eq = strchr(oneopt, '=')))
*eq = '\0';
/* find reverse option of oneopt */
revoneopt = reverse_option(oneopt);
/* if option or its reverse exist in opts2, ignore it */
if (amu_hasmntopt(&mnt2, oneopt) || amu_hasmntopt(&mnt2, revoneopt))
continue;
/* add option to returned string */
if (newstr[0]) {
xstrlcat(newstr, ",", len);
xstrlcat(newstr, tmpstr, len);
} else {
xstrlcpy(newstr, tmpstr, len);
}
}
/* finally, append opts2 itself */
if (newstr[0]) {
xstrlcat(newstr, ",", len);
xstrlcat(newstr, opts2, len);
} else {
xstrlcpy(newstr, opts2, len);
}
XFREE(s1);
return newstr;
}
am_ops *
ops_search(char *type)
{
am_ops **vp;
am_ops *rop = NULL;
for (vp = vops; (rop = *vp); vp++)
if (STREQ(rop->fs_type, type))
break;
return rop;
}
am_ops *
ops_match(am_opts *fo, char *key, char *g_key, char *path, char *keym, char *map)
{
am_ops *rop = NULL;
char *link_dir;
/*
* 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
*/
rop = ops_search(fo->opt_type);
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 = xstrdup("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 = xstrdup(old + 1);
XFREE(old);
}
/*
* If addopts option was used, then append it to the
* current options and remote mount options.
*/
if (fo->opt_addopts) {
if (STREQ(fo->opt_opts, fo->opt_remopts)) {
/* optimize things for the common case where opts==remopts */
char *mergedstr;
mergedstr = merge_opts(fo->opt_opts, fo->opt_addopts);
plog(XLOG_INFO, "merge rem/opts \"%s\" add \"%s\" => \"%s\"",
fo->opt_opts, fo->opt_addopts, mergedstr);
XFREE(fo->opt_opts);
XFREE(fo->opt_remopts);
fo->opt_opts = mergedstr;
fo->opt_remopts = xstrdup(mergedstr);
} else {
char *mergedstr, *remmergedstr;
mergedstr = merge_opts(fo->opt_opts, fo->opt_addopts);
plog(XLOG_INFO, "merge opts \"%s\" add \"%s\" => \"%s\"",
fo->opt_opts, fo->opt_addopts, mergedstr);
XFREE(fo->opt_opts);
fo->opt_opts = mergedstr;
remmergedstr = merge_opts(fo->opt_remopts, fo->opt_addopts);
plog(XLOG_INFO, "merge remopts \"%s\" add \"%s\" => \"%s\"",
fo->opt_remopts, fo->opt_addopts, remmergedstr);
XFREE(fo->opt_remopts);
fo->opt_remopts = remmergedstr;
}
}
/*
* Initialize opt_mount_type to "nfs", if it's not initialized already
*/
if (!fo->opt_mount_type)
fo->opt_mount_type = "nfs";
/* Normalize the sublink and make it absolute */
link_dir = fo->opt_sublink;
if (link_dir && link_dir[0] && link_dir[0] != '/') {
link_dir = str3cat((char *) NULL, fo->opt_fs, "/", link_dir);
normalize_slash(link_dir);
XFREE(fo->opt_sublink);
fo->opt_sublink = link_dir;
}
/*
* Check the filesystem is happy
*/
XFREE(fo->fs_mtab);
fo->fs_mtab = rop->fs_match(fo);
if (fo->fs_mtab)
return rop;
/*
* Return error file system
*/
fo->fs_mtab = amfs_error_ops.fs_match(fo);
return &amfs_error_ops;
}

View File

@ -1,412 +0,0 @@
.\"
.\" Copyright (c) 1997-2014 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. 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.
.\"
.\"
.\" File: am-utils/amd/amd.8
.\" $FreeBSD$
.\"
.Dd November 22, 2019
.Dt AMD 8
.Os
.Sh NAME
.Nm amd
.Nd automatically mount file systems
.Sh SYNOPSIS
.Nm
.Fl H
.Nm
.Op Fl F Ar conf_file
.Nm
.Op Fl nprvHS
.Op Fl a Ar mount_point
.Op Fl c Ar duration
.Op Fl d Ar domain
.Op Fl k Ar kernel-arch
.Op Fl l Ar logfile
.Op Fl o Ar op_sys_ver
.Op Fl t Ar timeout.retransmit
.Op Fl w Ar interval
.Op Fl x Ar log-option
.Op Fl y Ar YP-domain
.Op Fl A Ar arch
.Op Fl C Ar cluster-name
.Op Fl D Ar option
.Op Fl F Ar conf_file
.Op Fl O Ar op_sys_name
.Op Fl T Ar tag
.Oo
.Ar directory mapname
.Op Fl map-options
.Oc
.Ar ...
.Sh DESCRIPTION
.Bf -symbolic
The
.Nm
daemon in the
.Fx
base system is deprecated and will be removed before
.Fx 13.0 .
Users are advised to use
.Xr autofs 5
or the
.Pa sysutils/am-utils
port or package instead.
.Ef
.Pp
The
.Nm
utility
is a daemon that automatically mounts file systems
whenever a file or directory
within that file system is accessed.
File systems are automatically unmounted when they
appear to be quiescent.
.Pp
The
.Nm
utility
operates by attaching itself as an
.Tn NFS
server to each of the specified
.Ar directories .
Lookups within the specified directories
are handled by
.Nm ,
which uses the map defined by
.Ar mapname
to determine how to resolve the lookup.
Generally, this will be a host name, some file system information
and some mount options for the given file system.
.Pp
In the first form depicted above,
.Nm
will print a short help string.
In the second form, if no options are
specified, or if the
.Fl F
is used,
.Nm
will read configuration parameters from the file
.Ar conf_file
which defaults to
.Pa /etc/amd.conf .
The last form is described below.
.Sh OPTIONS
.Bl -tag -width indent
.It Fl a Ar temporary-directory
Specify an alternative location for the real mount points.
The default is
.Pa /.amd_mnt .
.It Fl c Ar duration
Specify a
.Ar duration ,
in seconds, that a looked up name remains
cached when not in use.
The default is 5 minutes.
.It Fl d Ar domain
Specify the local domain name.
If this option is not
given the domain name is determined from the hostname.
.It Fl k Ar kernel-arch
Specifies the kernel architecture.
This is used solely
to set the ${karch} selector.
.It Fl l Ar logfile
Specify a logfile in which to record mount and unmount events.
If
.Ar logfile
is the string
.Dq Li syslog ,
then the log messages will be sent to the system log daemon by
.Xr syslog 3 .
The default syslog facility used is
.Dv LOG_DAEMON .
If you
wish to change it, append its name to the log file name, delimited by a
single colon.
For example, if
.Ar logfile
is the string
.Dq Li syslog:local7
then
.Nm
will log messages via
.Xr syslog 3
using the
.Dv LOG_LOCAL7
facility (if it exists on the system).
.It Fl n
Normalize hostnames.
The name referred to by ${rhost} is normalized relative to the
host database before being used.
The effect is to translate
aliases into
.Dq official
names.
.It Fl o Ar 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
.Dq Li 2.5.1 ,
you can override it to
.Dq Li 5.5.1 ,
and use older maps that were written with the latter in mind.
.It Fl p
Print PID.
Outputs the process ID of
.Nm
to standard output where it can be saved into a file.
.It Fl r
Restart existing mounts.
The
.Nm
utility
will scan the mount file table to determine which file systems
are currently mounted.
Whenever one of these would have
been auto-mounted,
.Nm
.Em inherits
it.
.It Fl t Ar timeout.retransmit
Specify the NFS
.Ar timeout
interval,
in tenths of a second, between
.Tn NFS/RPC
retries (for UDP only).
The default
is 0.8 seconds.
The second value alters the retransmit counter, which
defaults to 11 retransmissions.
Both of these values are used by the kernel
to communicate with amd.
Useful defaults are supplied if either or both
values are missing.
.Pp
The
.Xr amd 8
utility
relies on the kernel RPC retransmit mechanism to trigger mount retries.
The values of these parameters change the overall retry interval.
Too long
an interval gives poor interactive response; too short an interval causes
excessive retries.
.It Fl v
Version.
Displays version and configuration information on standard error.
.It Fl w Ar interval
Specify an
.Ar interval ,
in seconds, between attempts to dismount
file systems that have exceeded their cached times.
The default is 2 minutes.
.TP
.It Fl x Ar options
Specify run-time logging options. The options are a comma separated
list chosen from:
.Li fatal, error, user, warn, info, map, stats, defaults, all .
Note that "fatal" and "error" are mandatory and cannot be turned off.
.TP
.It Fl y Ar domain
Specify an alternative
.Tn NIS
domain from which to fetch the
.Tn NIS
maps.
The default is the system domain name. This option is ignored if NIS
support is not available.
.It Fl A Ar arch
Specifies the OS architecture.
This is used solely to set the ${arch}
selector.
.It Fl C Ar cluster-name
Specify an alternative HP-UX cluster name to use.
.It Fl D Ar option
Select from a variety of debug options.
Prefixing an
option with the string
.Dq Li no
reverses the effect of that option.
Options are cumulative.
The most useful option is
.Dq Li all .
.Pp
Since
.Fl D
is only used for debugging other options are not documented here:
the current supported set of options is listed by the
.Fl v
option
and a fuller description is available in the program source.
.It Fl F Ar conf_file
Specify an
.Nm
configuration file to use.
See
.Xr 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
.Xr amd.conf 5
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.
.It Fl H
Print help and usage string.
.It Fl O Ar 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
.Dq Li sunos5 ,
you can override it to
.Dq Li sos5
and use older maps which were written with the latter in mind.
.It Fl S
Do not lock the running executable pages of
.Nm
into memory.
To improve
.Nm Ns 's
performance, systems that support the
.Xr plock 3
call, could lock the
.Nm
process into memory.
This way there is less chance
the operating system will schedule, page out, and swap the
.Nm
process as
needed.
This tends to improve
.Nm Ns 's
performance, at the cost of reserving the
memory used by the
.Nm
process (making it unavailable for other processes).
If this behavior is not desired, use the
.Fl S
option.
.It Fl T Ar tag
Specify a tag to use with
.Xr amd.conf 5 .
All map entries tagged with
.Ar tag
will be processed.
Map entries that are not tagged are always processed.
Map entries that are tagged with a tag other than
.Ar tag
will not be processed.
.El
.Sh FILES
.Bl -tag -width ".Pa /etc/amd.conf"
.It Pa /.amd_mnt
directory under which file systems are dynamically mounted
.It Pa /etc/amd.conf
default configuration file
.El
.Sh CAVEATS
Some care may be required when creating a mount map.
.Pp
Symbolic links on an
.Tn NFS
file system can be incredibly inefficient.
In most implementations of
.Tn NFS ,
their interpolations are not cached
by the kernel and each time a symbolic link is encountered during a
.Em lookuppn
translation it costs an
.Tn RPC
call to the
.Tn 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.
.Pp
A weird imagination is most useful to gain full advantage of all
the features.
.Sh SEE ALSO
.Xr domainname 1 ,
.Xr hostname 1 ,
.Xr syslog 3 ,
.Xr amd.conf 5 ,
.Xr mtab 5 ,
.Xr amq 8 ,
.Xr automount 8 ,
.Xr mount 8 ,
.Xr umount 8
.Pp
.Dq am-utils
.Xr info 1
entry.
.Rs
.%A Erez Zadok
.%B "Linux NFS and Automounter Administration"
.%O ISBN 0-7821-2739-8
.%I Sybex
.%D 2001
.Re
.Pp
.Pa http://www.am-utils.org/
.Rs
.%T Amd \- The 4.4 BSD Automounter
.Re
.Sh HISTORY
The
.Nm
utility first appeared in
.Bx 4.4 .
.Sh AUTHORS
.An Jan-Simon Pendry Aq jsp@doc.ic.ac.uk ,
Department of Computing, Imperial College, London, UK.
.Pp
.An Erez Zadok Aq ezk@cs.sunysb.edu ,
Computer Science Department, Stony Brook
University, Stony Brook, New York, USA.
.Pp
Other authors and contributors to am-utils are listed in the
.Pa AUTHORS
file distributed with am-utils.

View File

@ -1,584 +0,0 @@
/*
* Copyright (c) 1997-2014 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. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* $Id: amd.c,v 1.8.2.6 2004/01/06 03:15:16 ezk Exp $
* File: am-utils/amd/amd.c
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* 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[SIZEOF_PID_FSNAME]; /* "kiska.southseas.nz:(pid%d)" */
char *hostdomain = "unknown.domain";
#define SIZEOF_HOSTD (2 * MAXHOSTNAMELEN + 1) /* Host+domain */
char hostd[SIZEOF_HOSTD]; /* 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 immediate_abort; /* Should close-down unmounts be retried */
int orig_umask = 022;
int select_intr_valid;
jmp_buf select_intr;
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_FS_AUTOFS
int amd_use_autofs = 0;
#endif /* HAVE_FS_AUTOFS */
#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 */
if (sig != SIGHUP)
dlog("spurious call to sighup");
/*
* Force a reload by zero'ing the timer
*/
if (amd_state == Run)
do_mapc_reload = 0;
}
static RETSIGTYPE
parent_exit(int sig)
{
/*
* This signal handler is called during Amd initialization. The parent
* forks a child to do all the hard automounting work, and waits for a
* SIGQUIT signal from the child. When the parent gets the signal it's
* supposed to call this handler and exit(3), thus completing the
* daemonizing process. Alas, on some systems, especially Linux 2.4/2.6
* with Glibc, exit(3) doesn't always terminate the parent process.
* Worse, the parent process now refuses to accept any more SIGQUIT
* signals -- they are blocked. What's really annoying is that this
* doesn't happen all the time, suggesting a race condition somewhere.
* (This happens even if I change the logic to use another signal.) I
* traced this to something which exit(3) does in addition to exiting the
* process, probably some atexit() stuff or other side-effects related to
* signal handling. Either way, since at this stage the parent process
* just needs to terminate, I'm simply calling _exit(2). Note also that
* the OpenGroup doesn't list exit(3) as a recommended "Base Interface"
* but they do list _exit(2) as one. This fix seems to work reliably all
* the time. -Erez (2/27/2005)
*/
_exit(0);
}
static int
daemon_mode(void)
{
int bgpid;
#ifdef HAVE_SIGACTION
struct sigaction sa, osa;
memset(&sa, 0, sizeof(sa));
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 reach 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) am_mypid);
/* flush stdout, just in case */
fflush(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) am_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) */
int i;
memset(&gopt, 0, sizeof(struct amu_global_options));
/* name of current architecture */
gopt.arch = HOST_ARCH;
/* automounter temp dir */
gopt.auto_dir = "/.amd_mnt";
/* toplevel attribute cache timeout */
gopt.auto_attrcache = 0;
/* cluster name */
gopt.cluster = NULL;
/* executable map timeout */
gopt.exec_map_timeout = AMFS_EXEC_MAP_TIMEOUT;
/*
* 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;
/* full OS name and version */
gopt.op_sys_full = HOST_OS;
/* OS version */
gopt.op_sys_vendor = HOST_VENDOR;
/* pid file */
gopt.pid_file = "/dev/stdout";
/* local domain */
gopt.sub_domain = NULL;
/* reset NFS (and toplvl) retransmit counter and retry interval */
for (i=0; i<AMU_TYPE_MAX; ++i) {
gopt.amfs_auto_retrans[i] = -1; /* -1 means "never set before" */
gopt.amfs_auto_timeo[i] = -1; /* -1 means "never set before" */
}
/* cache duration */
gopt.am_timeo = AM_TTL;
/* dismount interval */
gopt.am_timeo_w = AM_TTL_W;
/* map reload intervl */
gopt.map_reload_interval = ONE_HOUR;
/*
* various CFM_* flags that are on by default.
*/
gopt.flags = CFM_DEFAULT_FLAGS;
#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;
/* LDAP protocol version */
gopt.ldap_proto_version = 2;
#endif /* HAVE_MAP_LDAP */
#ifdef HAVE_MAP_NIS
/* YP domain name */
gopt.nis_domain = NULL;
#endif /* HAVE_MAP_NIS */
}
/*
* Lock process text and data segment in memory (after forking the daemon)
*/
static void
do_memory_locking(void)
{
#if defined(HAVE_PLOCK) || defined(HAVE_MLOCKALL)
int locked_ok = 0;
#else /* not HAVE_PLOCK and not HAVE_MLOCKALL */
plog(XLOG_WARNING, "Process memory locking not supported by the OS");
#endif /* not HAVE_PLOCK and not HAVE_MLOCKALL */
#ifdef HAVE_PLOCK
# ifdef _AIX
/*
* On AIX you must lower the stack size using ulimit() before calling
* plock. Otherwise plock will reserve a lot of memory space based on
* your maximum stack size limit. Since it is not easily possible to
* tell what should the limit be, I print a warning before calling
* plock(). See the manual pages for ulimit(1,3,4) on your AIX system.
*/
plog(XLOG_WARNING, "AIX: may need to lower stack size using ulimit(3) before calling plock");
# endif /* _AIX */
if (!locked_ok && plock(PROCLOCK) != 0)
plog(XLOG_WARNING, "Couldn't lock process pages in memory using plock(): %m");
else
locked_ok = 1;
#endif /* HAVE_PLOCK */
#ifdef HAVE_MLOCKALL
if (!locked_ok && mlockall(MCL_CURRENT|MCL_FUTURE) != 0)
plog(XLOG_WARNING, "Couldn't lock process pages in memory using mlockall(): %m");
else
locked_ok = 1;
#endif /* HAVE_MLOCKALL */
#if defined(HAVE_PLOCK) || defined(HAVE_MLOCKALL)
if (locked_ok)
plog(XLOG_INFO, "Locked process pages in memory");
#endif /* HAVE_PLOCK || HAVE_MLOCKALL */
#if defined(HAVE_MADVISE) && defined(MADV_PROTECT)
madvise(NULL, 0, MADV_PROTECT); /* may be redundant of the above worked out */
#endif /* defined(HAVE_MADVISE) && defined(MADV_PROTECT) */
}
int
main(int argc, char *argv[])
{
char *domdot, *verstr, *vertmp;
int ppid = 0;
int error;
char *progname = NULL; /* "amd" */
char hostname[MAXHOSTNAMELEN + 1] = "localhost"; /* Hostname */
/*
* 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";
am_set_progname(progname);
plog(XLOG_WARNING, "built-in amd in FreeBSD is deprecated and will be removed before FreeBSD 13");
/*
* Initialize process id. This is kept
* cached since it is used for generating
* and using file handles.
*/
am_set_mypid();
/*
* Get local machine name
*/
if (gethostname(hostname, sizeof(hostname)) < 0) {
plog(XLOG_FATAL, "gethostname: %m");
going_down(1);
return 1;
}
hostname[sizeof(hostname) - 1] = '\0';
/*
* Check it makes sense
*/
if (!*hostname) {
plog(XLOG_FATAL, "host name is not set");
going_down(1);
return 1;
}
/*
* Initialize global options structure.
*/
init_global_options();
/*
* Partially initialize 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;
}
xstrlcpy(hostd, hostname, sizeof(hostd));
am_set_hostname(hostname);
/*
* Setup signal handlers
*/
/* SIGINT: trap interrupts for shutdowns */
setup_sighandler(SIGINT, sigterm);
/* SIGTERM: trap terminate so we can shutdown cleanly (some chance) */
setup_sighandler(SIGTERM, sigterm);
/* SIGHUP: hangups tell us to reload the cache */
setup_sighandler(SIGHUP, sighup);
/*
* SIGCHLD: trap Death-of-a-child. These allow us to pick up the exit
* status of backgrounded mounts. See "sched.c".
*/
setup_sighandler(SIGCHLD, sigchld);
#ifdef HAVE_SIGACTION
/* construct global "masked_sigs" used in nfs_start.c */
sigemptyset(&masked_sigs);
sigaddset(&masked_sigs, SIGINT);
sigaddset(&masked_sigs, SIGTERM);
sigaddset(&masked_sigs, SIGHUP);
sigaddset(&masked_sigs, SIGCHLD);
#endif /* 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.
* (Also initialize amd.conf parameters, maps, and more.)
*/
get_args(argc, argv);
/*
* Log version information.
*/
vertmp = get_version_string();
verstr = strtok(vertmp, "\n");
plog(XLOG_INFO, "AM-UTILS VERSION INFORMATION:");
while (verstr) {
plog(XLOG_INFO, "%s", verstr);
verstr = strtok(NULL, "\n");
}
XFREE(vertmp);
/*
* Get our own IP address so that we can mount the automounter. We pass
* localhost_address which could be used as the default localhost
* name/address in amu_get_myaddress().
*/
amu_get_myaddress(&myipaddr, gopt.localhost_address);
plog(XLOG_INFO, "My ip addr is %s", inet_ntoa(myipaddr));
/* 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 = %ld)", (long) geteuid());
going_down(1);
return 1;
}
#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);
return 1;
}
#endif /* HAVE_MAP_NIS */
if (amuDebug(D_DAEMON))
ppid = daemon_mode();
/*
* Lock process text and data segment in memory.
*/
if (gopt.flags & CFM_PROCESS_LOCK) {
do_memory_locking();
}
do_mapc_reload = clocktime(NULL) + gopt.map_reload_interval;
/*
* Register automounter with system.
*/
error = mount_automounter(ppid);
if (error && ppid)
kill(ppid, SIGALRM);
#ifdef HAVE_FS_AUTOFS
/*
* XXX this should be part of going_down(), but I can't move it there
* because it would be calling non-library code from the library... ugh
*/
if (amd_use_autofs)
destroy_autofs_service();
#endif /* HAVE_FS_AUTOFS */
going_down(error);
abort();
return 1; /* should never get here */
}

View File

@ -1,923 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amd.h
*
*/
#ifndef _AMD_H
#define _AMD_H
/*
* MACROS:
*/
/*
* Define a default debug mtab path for systems
* that support mtab on file.
*/
#ifdef MOUNT_TABLE_ON_FILE
# define DEBUG_MNTTAB_FILE "/tmp/mtab"
#endif /* MOUNT_TABLE_ON_FILE */
/* Max line length that info services can handle */
#define INFO_MAX_LINE_LEN 1500
/* options for amd.conf */
#define CFM_BROWSABLE_DIRS 0x00000001
#define CFM_MOUNT_TYPE_AUTOFS 0x00000002 /* use kernel autofs support */
#define CFM_SELECTORS_IN_DEFAULTS 0x00000004
#define CFM_NORMALIZE_HOSTNAMES 0x00000008
#define CFM_PROCESS_LOCK 0x00000010
#define CFM_PRINT_PID 0x00000020
#define CFM_RESTART_EXISTING_MOUNTS 0x00000040
#define CFM_SHOW_STATFS_ENTRIES 0x00000080
#define CFM_FULLY_QUALIFIED_HOSTS 0x00000100
#define CFM_BROWSABLE_DIRS_FULL 0x00000200 /* allow '/' in readdir() */
#define CFM_UNMOUNT_ON_EXIT 0x00000400 /* when amd finishing */
#define CFM_USE_TCPWRAPPERS 0x00000800
#define CFM_AUTOFS_USE_LOFS 0x00001000
#define CFM_NFS_INSECURE_PORT 0x00002000
#define CFM_DOMAIN_STRIP 0x00004000
#define CFM_NORMALIZE_SLASHES 0x00008000 /* normalize slashes? */
#define CFM_FORCED_UNMOUNTS 0x00010000 /* forced unmounts? */
#define CFM_TRUNCATE_LOG 0x00020000 /* truncate log file? */
#define CFM_SUN_MAP_SYNTAX 0x00040000 /* Sun map syntax? */
#define CFM_NFS_ANY_INTERFACE 0x00080000 /* all interfaces are acceptable */
/* defaults global flags: plock, tcpwrappers, and autofs/lofs */
#define CFM_DEFAULT_FLAGS (CFM_PROCESS_LOCK|CFM_USE_TCPWRAPPERS|CFM_AUTOFS_USE_LOFS|CFM_DOMAIN_STRIP|CFM_NORMALIZE_SLASHES)
/*
* macro definitions for automounter vfs/vnode operations.
*/
#define VLOOK_CREATE 0x1
#define VLOOK_DELETE 0x2
#define VLOOK_LOOKUP 0x3
/*
* macro definitions for automounter vfs capabilities
*/
#define FS_DIRECTORY 0x0001 /* This looks like a dir, not a link */
#define FS_MBACKGROUND 0x0002 /* Should background this mount */
#define FS_NOTIMEOUT 0x0004 /* Don't bother with timeouts */
#define FS_MKMNT 0x0008 /* Need to make the mount point */
#define FS_UBACKGROUND 0x0010 /* Unmount in background */
#define FS_BACKGROUND (FS_MBACKGROUND|FS_UBACKGROUND)
#define FS_DISCARD 0x0020 /* Discard immediately on last reference */
#define FS_AMQINFO 0x0040 /* Amq is interested in this fs type */
#define FS_AUTOFS 0x0080 /* This filesystem can be an autofs f/s */
#define FS_DIRECT 0x0100 /* Direct mount */
#define FS_ON_AUTOFS 0x0200 /* This filesystem can be mounted directly
onto an autofs mountpoint */
/*
* macros for struct am_node (map of auto-mount points).
*/
#define AMF_NOTIMEOUT 0x0001 /* This node never times out */
#define AMF_ROOT 0x0002 /* This is a root node */
#define AMF_AUTOFS 0x0004 /* This node is part of an autofs filesystem */
#define AMF_REMOUNT 0x0008 /* This node needs to be remounted */
#define AMF_SOFTLOOKUP 0x0010 /* This node returns EIO if server is down */
/*
* macros for struct mntfs (list of mounted filesystems)
*/
#define MFF_MOUNTED 0x0001 /* Node is mounted */
#define MFF_MOUNTING 0x0002 /* Mount is in progress */
#define MFF_UNMOUNTING 0x0004 /* Unmount is in progress */
#define MFF_RESTART 0x0008 /* Restarted node */
#define MFF_MKMNT 0x0010 /* Delete this node's am_mount */
#define MFF_ERROR 0x0020 /* This node failed to mount */
#define MFF_LOGDOWN 0x0040 /* Logged that this mount is down */
#define MFF_RSTKEEP 0x0080 /* Don't timeout this filesystem - restarted */
#define MFF_WANTTIMO 0x0100 /* Need a timeout call when not busy */
#define MFF_NFSLINK 0x0200 /* nfsl type, and deemed a link */
#define MFF_IS_AUTOFS 0x0400 /* this filesystem is of type autofs */
#define MFF_NFS_SCALEDOWN 0x0800 /* the mount failed, retry with v2/UDP */
#define MFF_ON_AUTOFS 0x1000 /* autofs has a lofs/link to this f/s */
#define MFF_WEBNFS 0x2000 /* use public filehandle */
/*
* macros for struct fserver.
*/
#define FSF_VALID 0x0001 /* Valid information available */
#define FSF_DOWN 0x0002 /* This fileserver is thought to be down */
#define FSF_ERROR 0x0004 /* Permanent error has occurred */
#define FSF_WANT 0x0008 /* Want a wakeup call */
#define FSF_PINGING 0x0010 /* Already doing pings */
#define FSF_WEBNFS 0x0020 /* Don't try to contact portmapper */
#define FSF_PING_UNINIT 0x0040 /* ping values have not been initilized */
#define FSF_FORCE_UNMOUNT 0x0080 /* force umount of this fserver */
#define FSRV_ERROR(fs) ((fs) && (((fs)->fs_flags & FSF_ERROR) == FSF_ERROR))
#define FSRV_ISDOWN(fs) ((fs) && (((fs)->fs_flags & (FSF_DOWN|FSF_VALID)) == (FSF_DOWN|FSF_VALID)))
#define FSRV_ISUP(fs) (!(fs) || (((fs)->fs_flags & (FSF_DOWN|FSF_VALID)) == (FSF_VALID)))
/* 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 */
/*
* Error to return if remote host is not available.
* Try, in order, "host down", "host unreachable", "invalid argument".
*/
#ifdef EHOSTDOWN
# define AM_ERRNO_HOST_DOWN EHOSTDOWN
#else /* not EHOSTDOWN */
# ifdef EHOSTUNREACH
# define AM_ERRNO_HOST_DOWN EHOSTUNREACH
# else /* not EHOSTUNREACH */
# define AM_ERRNO_HOST_DOWN EINVAL
# endif /* not EHOSTUNREACH */
#endif /* not EHOSTDOWN */
/* Hash table size */
#define NKVHASH (1 << 2) /* Power of two */
/* Max entries to return in one call */
#define MAX_READDIR_ENTRIES 16
/*
* default amfs_auto retrans - 1/10th seconds
*/
#define AMFS_AUTO_RETRANS(x) ((ALLOWED_MOUNT_TIME*10+5*gopt.amfs_auto_timeo[(x)])/gopt.amfs_auto_timeo[(x)] * 2)
/*
* The following values can be tuned...
*/
#define AM_TTL (300) /* Default cache period (5 min) */
#define AM_TTL_W (120) /* Default unmount interval (2 min) */
#define AM_PINGER 30 /* NFS ping interval for live systems */
#define AMFS_AUTO_TIMEO 8 /* Default amfs_auto timeout - .8s */
#define AMFS_EXEC_MAP_TIMEOUT 10 /* default 10sec exec map timeout */
/* interval between forced retries of a mount */
#define RETRY_INTERVAL 2
#ifndef ROOT_MAP
# define ROOT_MAP "\"root\""
#endif /* not ROOT_MAP */
#define ereturn(x) do { *error_return = x; return 0; } while (0)
#define NEVER (time_t) 0
#if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
# define AMD_SERVICE_NAME "amd" /* for tcpwrappers */
#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
/*
* TYPEDEFS:
*/
typedef struct cf_map cf_map_t;
typedef struct kv kv;
typedef struct am_node am_node;
typedef struct mntfs mntfs;
typedef struct am_loc am_loc;
typedef struct am_opts am_opts;
typedef struct am_ops am_ops;
typedef struct am_stats am_stats;
typedef struct fserver fserver;
typedef voidp wchan_t;
typedef voidp opaque_t;
/*
* 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 *);
typedef int task_fun(opaque_t);
typedef void cb_fun(int, int, opaque_t);
typedef void fwd_fun(voidp, int, struct sockaddr_in *,
struct sockaddr_in *, opaque_t, int);
typedef int key_fun(char *, opaque_t);
typedef void callout_fun(opaque_t);
/*
* automounter vfs/vnode operations.
*/
typedef char *(*vfs_match) (am_opts *);
typedef int (*vfs_init) (mntfs *);
typedef int (*vmount_fs) (am_node *, mntfs *);
typedef int (*vumount_fs) (am_node *, mntfs *);
typedef am_node *(*vlookup_child) (am_node *, char *, int *, int);
typedef am_node *(*vmount_child) (am_node *, int *);
typedef int (*vreaddir) (am_node *, voidp, voidp, voidp, u_int);
typedef am_node *(*vreadlink) (am_node *, int *);
typedef void (*vmounted) (mntfs *);
typedef void (*vumounted) (mntfs *);
typedef fserver *(*vffserver) (mntfs *);
typedef wchan_t (*vget_wchan) (mntfs *);
/*
* NFS progran dispatcher
*/
typedef void (*dispatcher_t)(struct svc_req *rqstp, SVCXPRT *transp);
/*
* 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 */
int auto_attrcache; /* attribute cache timeout for auto dirs */
char *cluster; /* cluster name */
char *karch; /* kernel architecture */
char *logfile; /* amd log file */
char *op_sys; /* operating system name ${os} */
char *op_sys_ver; /* OS version ${osver} */
char *op_sys_full; /* full OS name ${full_os} */
char *op_sys_vendor; /* name of OS vendor ${vendor} */
char *pid_file; /* PID file */
char *sub_domain; /* local domain */
char *localhost_address; /* localhost address (NULL means use 127.0.0.1) */
char *map_defaults; /* global map /default options */
char *map_options; /* global map options */
int map_reload_interval; /* map reload interval */
char *map_type; /* global map type */
char *search_path; /* search path for maps */
char *mount_type; /* mount type for map */
char *debug_mtab_file; /* path for the mtab file during debug mode */
u_int flags; /* various CFM_* flags */
#define AMU_TYPE_NONE -1 /* for amfs_auto_{timeo,retrans,toplvl} */
#define AMU_TYPE_UDP 0 /* for amfs_auto_{timeo,retrans,toplvl} */
#define AMU_TYPE_TCP 1 /* for amfs_auto_{timeo,retrans,toplvl} */
/*
* Note: toplvl is only UDP, but we want to separate it from regular
* NFS mounts which Amd makes, because the toplvl mount is a localhost
* mount for which different timeo/retrans parameters may be desired.
*/
#define AMU_TYPE_TOPLVL 2 /* for amfs_auto_{timeo,retrans,toplvl} */
#define AMU_TYPE_MAX 3 /* for amfs_auto_{timeo,retrans,toplvl} */
int amfs_auto_retrans[AMU_TYPE_MAX]; /* NFS retransmit counter */
int amfs_auto_timeo[AMU_TYPE_MAX]; /* NFS retry interval */
int am_timeo; /* cache duration */
int am_timeo_w; /* dismount interval */
u_long portmap_program; /* amd RPC program number */
u_short preferred_amq_port; /* preferred amq service RPC port number (0 means "any") */
#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) */
long ldap_proto_version; /* LDAP protocol version */
#endif /* HAVE_MAP_LDAP */
#ifdef HAVE_MAP_NIS
char *nis_domain; /* YP domain name */
#endif /* HAVE_MAP_NIS */
char *nfs_proto; /* NFS protocol (NULL, udp, tcp) */
int nfs_vers; /* NFS version (0, 2, 3, 4) */
int nfs_vers_ping; /* NFS rpc ping version (0, 2, 3, 4) */
u_int exec_map_timeout; /* timeout (seconds) for executable maps */
};
/* 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_defaults; /* map /defaults options in amd.conf */
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? */
struct cf_map *cfm_next; /* pointer to next in list (if any) */
};
/*
* 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 */
u_int reloads; /* Number of times map was reloaded */
u_int nentries; /* Number of entries in the 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 */
cf_map_t *cfm; /* pointer to per-map amd.conf opts, if any */
void *map_data; /* Map data black box */
};
/*
* Options
*/
struct am_opts {
char *fs_glob; /* Smashed copy of global options */
char *fs_local; /* Expanded copy of local options */
char *fs_mtab; /* Mount table entry */
/* Other options ... */
char *opt_dev;
char *opt_delay;
char *opt_dir;
char *opt_fs;
char *opt_group;
char *opt_mount;
char *opt_opts;
char *opt_remopts;
char *opt_pref;
char *opt_cache;
char *opt_rfs;
char *opt_rhost;
char *opt_sublink;
char *opt_type;
char *opt_mount_type; /* "nfs" or "autofs" */
char *opt_unmount;
char *opt_umount; /* an "alias" for opt_unmount (type:=program) */
char *opt_user;
char *opt_maptype; /* map type: file, nis, hesiod, etc. */
char *opt_cachedir; /* cache directory */
char *opt_addopts; /* options to add to opt_opts */
};
struct am_ops {
char *fs_type; /* type of filesystems e.g. "nfsx" */
vfs_match fs_match; /* fxn: match */
vfs_init fs_init; /* fxn: initialization */
vmount_fs mount_fs; /* fxn: mount my own vnode */
vumount_fs umount_fs; /* fxn: unmount my own vnode */
vlookup_child lookup_child; /* fxn: lookup path-name */
vmount_child mount_child; /* fxn: mount path-name */
vreaddir readdir; /* fxn: read directory */
vreadlink readlink; /* fxn: read link */
vmounted mounted; /* fxn: after-mount extra actions */
vumounted umounted; /* fxn: after-umount extra actions */
vffserver ffserver; /* fxn: find a file server */
vget_wchan get_wchan; /* fxn: get the waiting channel */
int nfs_fs_flags; /* filesystem flags FS_* for nfs mounts */
#ifdef HAVE_FS_AUTOFS
int autofs_fs_flags;/* filesystem flags FS_* for autofs mounts */
#endif /* HAVE_FS_AUTOFS */
};
/*
* List of mounted filesystems
*/
struct mntfs {
qelem mf_q; /* List of mounted filesystems */
am_ops *mf_ops; /* Operations on this mountpoint */
am_opts *mf_fo; /* File opts */
char *mf_mount; /* "/a/kiska/home/kiska" */
char *mf_info; /* Mount info */
char *mf_auto; /* Mount info */
char *mf_mopts; /* FS mount opts */
char *mf_remopts; /* Remote FS mount opts */
char *mf_loopdev; /* loop device name for /dev/loop mounts */
fserver *mf_server; /* File server */
int mf_fsflags; /* Flags FS_* copied from mf_ops->*_fs_flags */
int mf_flags; /* Flags MFF_* */
int mf_error; /* Error code from background mount */
int mf_refc; /* Number of references to this node */
int mf_cid; /* Callout id */
void (*mf_prfree) (opaque_t); /* Free private space */
opaque_t mf_private; /* Private - per-fs data */
};
/*
* Locations: bindings between keys and mntfs
*/
struct am_loc {
am_opts *al_fo;
mntfs *al_mnt;
int al_refc;
};
/*
* List of fileservers
*/
struct fserver {
qelem fs_q; /* List of fileservers */
int fs_refc; /* Number of references to this server */
char *fs_host; /* Normalized hostname of server */
struct sockaddr_in *fs_ip; /* Network address of server */
int fs_cid; /* Callout id */
int fs_pinger; /* Ping (keepalive) interval */
int fs_flags; /* Flags */
char *fs_type; /* File server type */
u_long fs_version; /* NFS version of server (2, 3, etc.)*/
char *fs_proto; /* NFS protocol of server (tcp, udp, etc.) */
opaque_t fs_private; /* Private data */
void (*fs_prfree) (opaque_t); /* Free private data */
};
/*
* Per-mountpoint statistics
*/
struct am_stats {
time_t s_mtime; /* Mount time */
u_short s_uid; /* Uid of mounter */
int s_getattr; /* Count of getattrs */
int s_lookup; /* Count of lookups */
int s_readdir; /* Count of readdirs */
int s_readlink; /* Count of readlinks */
int s_statfs; /* Count of statfs */
int s_fsinfo; /* Count of fsinfo */
int s_pathconf; /* Count of pathconf */
};
/*
* System statistics
*/
struct amd_stats {
int d_drops; /* Dropped requests */
int d_stale; /* Stale NFS handles */
int d_mok; /* Successful mounts */
int d_merr; /* Failed mounts */
int d_uerr; /* Failed unmounts */
};
extern struct amd_stats amd_stats;
/*
* Map of auto-mount points.
*/
struct am_node {
int am_mapno; /* Map number */
am_loc *am_al; /* Mounted filesystem */
am_loc **am_alarray; /* Filesystem sources to try to mount */
char *am_name; /* "kiska": name of this node */
char *am_path; /* "/home/kiska": path of this node's mount point */
char *am_link; /* "/a/kiska/home/kiska/this/that": link to sub-dir */
am_node *am_parent; /* Parent of this node */
am_node *am_ysib; /* Younger sibling of this node */
am_node *am_osib; /* Older sibling of this node */
am_node *am_child; /* First child of this node */
nfsattrstat am_attr; /* File attributes */
#define am_fattr am_attr.ns_u.ns_attr_u
int am_flags; /* Boolean flags AMF_* */
int am_error; /* Specific mount error */
time_t am_ttl; /* Time to live */
int am_timeo_w; /* Dismount wait interval */
int am_timeo; /* Cache timeout interval */
u_int am_gen; /* Generation number */
char *am_pref; /* Mount info prefix */
am_stats am_stats; /* Statistics gathering */
SVCXPRT *am_transp; /* Info for quick reply */
dev_t am_dev; /* Device number */
dev_t am_rdev; /* Remote/real device number */
#ifdef HAVE_FS_AUTOFS
autofs_fh_t *am_autofs_fh;
time_t am_autofs_ttl; /* Time to expire autofs nodes */
#endif /* HAVE_FS_AUTOFS */
int am_fd[2]; /* parent child pipe fd's for sync umount */
};
/*
* 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 amq_string *amqproc_pawd_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 int *amqproc_umnt_1_svc(voidp argp, struct svc_req *rqstp);
extern int *amqproc_sync_umnt_1_svc_parent(voidp argp, struct svc_req *rqstp);
extern amq_sync_umnt *amqproc_sync_umnt_1_svc_child(voidp argp, struct svc_req *rqstp);
extern amq_sync_umnt *amqproc_sync_umnt_1_svc_async(voidp argp, struct svc_req *rqstp);
extern amq_map_info_list *amqproc_getmapinfo_1_svc(voidp argp, struct svc_req *rqstp);
/* other external definitions */
extern am_nfs_handle_t *get_root_nfs_fh(char *dir, am_nfs_handle_t *nfh);
extern am_node *find_ap(char *);
extern am_node *get_ap_child(am_node *, char *);
extern bool_t xdr_amq_mount_info_qelem(XDR *xdrs, qelem *qhead);
extern bool_t xdr_amq_map_info_qelem(XDR *xdrs, qelem *qhead);
extern fserver *find_nfs_srvr(mntfs *mf);
extern int mount_nfs_fh(am_nfs_handle_t *fhp, char *mntdir, char *fs_name, mntfs *mf);
extern int process_all_regular_maps(void);
extern cf_map_t *find_cf_map(const char *name);
extern int set_conf_kv(const char *section, const char *k, const char *v);
extern int mount_node(opaque_t arg);
extern int unmount_mp(am_node *mp);
extern int conf_parse(void); /* "yyparse" renamed */
extern FILE *conf_in; /* "yyin" renamed */
extern void amfs_mkcacheref(mntfs *mf);
extern int amfs_mount(am_node *mp, mntfs *mf, char *opts);
extern void assign_error_mntfs(am_node *mp);
extern am_node *next_nonerror_node(am_node *xp);
extern void flush_srvr_nfs_cache(fserver *fs);
extern void am_mounted(am_node *);
extern void mf_mounted(mntfs *mf, bool_t call_free_opts);
extern void am_unmounted(am_node *);
extern am_node *get_exported_ap(int index);
extern am_node *get_first_exported_ap(int *index);
extern am_node *get_next_exported_ap(int *index);
extern am_node *path_to_exported_ap(char *path);
extern am_node *exported_ap_alloc(void);
extern am_node *find_mf(mntfs *);
extern am_node *next_map(int *);
extern am_ops *ops_match(am_opts *, char *, char *, char *, char *, char *);
extern am_ops *ops_search(char *);
extern fserver *dup_srvr(fserver *);
extern void srvrlog(fserver *, char *);
extern int get_mountd_port(fserver *, u_short *, wchan_t);
extern void flush_nfs_fhandle_cache(fserver *);
extern mntfs *dup_mntfs(mntfs *);
extern am_loc *dup_loc(am_loc *);
extern mntfs *find_mntfs(am_ops *, am_opts *, char *, char *, char *, char *, char *);
extern mntfs *locate_mntfs(am_ops *, am_opts *, char *, char *, char *, char *, char *);
extern am_loc *new_loc(void);
extern mntfs *new_mntfs(void);
extern mntfs *realloc_mntfs(mntfs *, am_ops *, am_opts *, char *, char *, char *, char *, char *);
extern void flush_mntfs(void);
extern void free_mntfs(voidp);
extern void free_loc(voidp);
extern void amq_program_1(struct svc_req *rqstp, SVCXPRT *transp);
extern int background(void);
extern void deslashify(char *);
extern void do_task_notify(void);
extern int eval_fs_opts(am_opts *, char *, char *, char *, char *, char *);
extern int file_read_line(char *, int, FILE *);
extern void forcibly_timeout_mp(am_node *);
extern void free_map(am_node *);
extern void free_opts(am_opts *);
extern am_opts *copy_opts(am_opts *);
extern void free_srvr(fserver *);
extern int fwd_init(void);
extern int fwd_packet(int, char *, int, struct sockaddr_in *, struct sockaddr_in *, opaque_t, fwd_fun *);
extern void fwd_reply(void);
extern void get_args(int argc, char *argv[]);
extern wchan_t get_mntfs_wchan(mntfs *mf);
extern void host_normalize(char **);
extern void init_map(am_node *, char *);
extern void ins_que(qelem *, qelem *);
extern void insert_am(am_node *, am_node *);
extern int make_nfs_auth(void);
extern void make_root_node(void);
extern void map_flush_srvr(fserver *);
extern void mapc_add_kv(mnt_map *, char *, char *);
extern mnt_map *mapc_find(char *, char *, const char *, const char *);
extern void mapc_free(opaque_t);
extern int mapc_keyiter(mnt_map *, key_fun *, opaque_t);
extern void mapc_reload(void);
extern int mapc_search(mnt_map *, char *, char **);
extern void mapc_showtypes(char *buf, size_t l);
extern int mapc_type_exists(const char *type);
extern void mk_fattr(nfsfattr *, nfsftype);
extern int mount_auto_node(char *, opaque_t);
extern int mount_automounter(int);
extern int mount_exported(void);
extern void mp_to_fh(am_node *, am_nfs_fh *);
extern void mp_to_fh3(am_node *mp, am_nfs_fh3 *fhp);
extern void new_ttl(am_node *);
extern void nfs_quick_reply(am_node *mp, int error);
extern void normalize_slash(char *);
extern void notify_child(am_node *, au_etype, int, int);
extern void ops_showamfstypes(char *buf, size_t l);
extern void ops_showfstypes(char *outbuf, size_t l);
extern void rem_que(qelem *);
extern void reschedule_timeout_mp(void);
extern void restart(void);
extern void restart_automounter_nodes(void);
extern int root_keyiter(key_fun *, opaque_t);
extern void root_newmap(const char *, const char *, const char *, const cf_map_t *);
extern void run_task(task_fun *, opaque_t, cb_fun *, opaque_t);
extern void sched_task(cb_fun *, opaque_t, wchan_t);
extern int softclock(void);
extern int timeout(u_int, void (*fn)(opaque_t), opaque_t);
extern void timeout_mp(opaque_t);
extern void untimeout(int);
extern void umount_exported(void);
extern int valid_key(char *);
extern void wakeup(wchan_t);
extern void wakeup_srvr(fserver *);
extern void wakeup_task(int, int, wchan_t);
#define SIZEOF_PID_FSNAME (16 + MAXHOSTNAMELEN)
extern char pid_fsname[SIZEOF_PID_FSNAME]; /* "kiska.southseas.nz:(pid%d)" */
#define SIZEOF_HOSTD (2 * MAXHOSTNAMELEN + 1)
extern char hostd[SIZEOF_HOSTD]; /* Host+domain */
#define SIZEOF_OPTS 256 /* used for char opts[] and preopts[] */
/*
* Global variables.
*/
extern SVCXPRT *current_transp; /* For nfs_quick_reply() */
extern dispatcher_t nfs_dispatcher;
extern char *conf_tag;
#define SIZEOF_UID_STR 12
#define SIZEOF_GID_STR 12
extern char *opt_gid, gid_str[SIZEOF_GID_STR];
extern char *opt_uid, uid_str[SIZEOF_UID_STR];
extern int NumChildren;
extern int fwd_sock;
extern int select_intr_valid;
extern int immediate_abort; /* Should close-down unmounts be retried */
extern int usage;
extern int use_conf_file; /* use amd configuration file */
extern int task_notify_todo; /* Task notifier needs running */
extern jmp_buf select_intr;
extern qelem mfhead;
extern struct amu_global_options gopt; /* where global options are stored */
extern time_t do_mapc_reload; /* Flush & reload mount map cache */
extern time_t next_softclock; /* Time to call softclock() */
#ifdef HAVE_SIGACTION
extern sigset_t masked_sigs;
#endif /* HAVE_SIGACTION */
#if defined(HAVE_AMU_FS_LINK) || defined(HAVE_AMU_FS_LINKX)
extern char *amfs_link_match(am_opts *fo);
#endif /* defined(HAVE_AMU_FS_LINK) || defined(HAVE_AMU_FS_LINKX) */
#ifdef HAVE_FS_AUTOFS
extern int amd_use_autofs;
extern int autofs_get_fh(am_node *mp);
extern void autofs_release_fh(am_node *mp);
extern void autofs_get_mp(am_node *mp);
extern void autofs_release_mp(am_node *mp);
extern void autofs_add_fdset(fd_set *readfds);
extern int autofs_handle_fdset(fd_set *readfds, int nsel);
extern void autofs_mounted(am_node *mp);
extern void autofs_mount_succeeded(am_node *mp);
extern void autofs_mount_failed(am_node *mp);
extern int autofs_umount_succeeded(am_node *mp);
extern int autofs_umount_failed(am_node *mp);
extern int autofs_mount_fs(am_node *mp, mntfs *mf);
extern int autofs_umount_fs(am_node *mp, mntfs *mf);
extern void autofs_get_opts(char *opts, size_t l, autofs_fh_t *fh);
extern int autofs_compute_mount_flags(mntent_t *);
extern void autofs_timeout_mp(am_node *);
extern int create_autofs_service(void);
extern int destroy_autofs_service(void);
#endif /* HAVE_FS_AUTOFS */
/**************************************************************************/
/*** Generic file-system types, implemented as part of the native O/S. ***/
/**************************************************************************/
/*
* Loopback File System
* Many systems can't support this, and in any case most of the
* functionality is available with Symlink FS.
*/
#ifdef HAVE_FS_LOFS
extern am_ops lofs_ops;
extern int mount_lofs(char *mntdir, char *fs_name, char *opts, int on_autofs);
#endif /* HAVE_FS_LOFS */
/*
* CD-ROM File System (CD-ROM)
* (HSFS: High Sierra F/S on some machines)
* Many systems can't support this, and in any case most of the
* functionality is available with program FS.
*/
#ifdef HAVE_FS_CDFS
extern am_ops cdfs_ops;
#endif /* HAVE_FS_CDFS */
/*
* PC File System (MS-DOS)
* Many systems can't support this, and in any case most of the
* functionality is available with program FS.
*/
#ifdef HAVE_FS_PCFS
extern am_ops pcfs_ops;
#endif /* HAVE_FS_PCFS */
/*
* UDF File System
* Many systems can't support this, and in any case most of the
* functionality is available with program FS.
*/
#ifdef HAVE_FS_UDF
extern am_ops udf_ops;
#endif /* HAVE_FS_UDF */
#ifdef HAVE_FS_LUSTRE
extern am_ops lustre_ops;
#endif /* HAVE_FS_LUSTRE */
/*
* Caching File System (Solaris)
*/
#ifdef HAVE_FS_CACHEFS
extern am_ops cachefs_ops;
#endif /* HAVE_FS_CACHEFS */
/*
* In memory /tmp filesystem (Linux, NetBSD)
*/
#ifdef HAVE_FS_TMPFS
extern am_ops tmpfs_ops;
#endif /* HAVE_FS_TMPFS */
/*
* Network File System
* Good, slow, NFS V.2.
*/
#ifdef HAVE_FS_NFS
extern am_ops nfs_ops; /* NFS */
extern fserver *find_nfs_srvr (mntfs *);
extern qelem nfs_srvr_list;
#endif /* HAVE_FS_NFS */
/*
* Un*x File System
* Normal local disk file system.
*/
#ifdef HAVE_FS_UFS
extern am_ops ufs_ops; /* Un*x file system */
#endif /* HAVE_FS_UFS */
/* Unix file system (irix) */
#ifdef HAVE_FS_XFS
extern am_ops xfs_ops; /* Un*x file system */
#endif /* HAVE_FS_XFS */
/* Unix file system (ext*) */
#ifdef HAVE_FS_EXT
extern am_ops ext2_ops; /* Un*x file system */
extern am_ops ext3_ops; /* Un*x file system */
extern am_ops ext4_ops; /* Un*x file system */
#endif /* HAVE_FS_EXT */
/* Unix file system (irix) */
#ifdef HAVE_FS_EFS
extern am_ops efs_ops; /* Un*x file system */
#endif /* HAVE_FS_EFS */
/**************************************************************************/
/*** Automounter file-system types, implemented by amd. ***/
/**************************************************************************/
/*
* Root AMD File System
*/
extern am_ops amfs_root_ops; /* Root file system */
/*
* Generic amfs helper methods
*/
extern am_node *amfs_generic_lookup_child(am_node *mp, char *fname, int *error_return, int op);
extern am_node *amfs_generic_mount_child(am_node *ap, int *error_return);
extern int amfs_generic_readdir(am_node *mp, voidp cookie, voidp dp, voidp ep, u_int count);
extern int amfs_generic_umount(am_node *mp, mntfs *mf);
extern void amfs_generic_mounted(mntfs *mf);
extern char *amfs_generic_match(am_opts *fo);
extern fserver *amfs_generic_find_srvr(mntfs *);
/*
* Automount File System
*/
#ifdef HAVE_AMU_FS_AUTO
extern am_ops amfs_auto_ops; /* Automount file system (this!) */
#endif /* HAVE_AMU_FS_AUTO */
/*
* Toplvl Automount File System
*/
#ifdef HAVE_AMU_FS_TOPLVL
extern am_ops amfs_toplvl_ops; /* Toplvl Automount file system */
extern int amfs_toplvl_mount(am_node *mp, mntfs *mf);
extern int amfs_toplvl_umount(am_node *mp, mntfs *mf);
#endif /* HAVE_AMU_FS_TOPLVL */
/*
* Direct Automount File System
*/
#ifdef HAVE_AMU_FS_DIRECT
extern am_ops amfs_direct_ops; /* Direct Automount file system (this too) */
#endif /* HAVE_AMU_FS_DIRECT */
/*
* Error File System
*/
#ifdef HAVE_AMU_FS_ERROR
extern am_ops amfs_error_ops; /* Error file system */
extern am_node *amfs_error_lookup_child(am_node *mp, char *fname, int *error_return, int op);
extern am_node *amfs_error_mount_child(am_node *ap, int *error_return);
extern int amfs_error_readdir(am_node *mp, voidp cookie, voidp dp, voidp ep, u_int count);
#endif /* HAVE_AMU_FS_ERROR */
/*
* NFS mounts with local existence check.
*/
#ifdef HAVE_AMU_FS_NFSL
extern am_ops amfs_nfsl_ops; /* NFSL */
#endif /* HAVE_AMU_FS_NFSL */
/*
* Multi-nfs mounts.
*/
#ifdef HAVE_AMU_FS_NFSX
extern am_ops amfs_nfsx_ops; /* NFSX */
#endif /* HAVE_AMU_FS_NFSX */
/*
* NFS host - a whole tree.
*/
#ifdef HAVE_AMU_FS_HOST
extern am_ops amfs_host_ops; /* NFS host */
#endif /* HAVE_AMU_FS_HOST */
/*
* Program File System
* This is useful for things like RVD.
*/
#ifdef HAVE_AMU_FS_PROGRAM
extern am_ops amfs_program_ops; /* Program File System */
#endif /* HAVE_AMU_FS_PROGRAM */
/*
* Symbolic-link file system.
* A "filesystem" which is just a symbol link.
*/
#ifdef HAVE_AMU_FS_LINK
extern am_ops amfs_link_ops; /* Symlink FS */
#endif /* HAVE_AMU_FS_LINK */
/*
* Symbolic-link file system, which also checks that the target of
* the symlink exists.
* A "filesystem" which is just a symbol link.
*/
#ifdef HAVE_AMU_FS_LINKX
extern am_ops amfs_linkx_ops; /* Symlink FS with existence check */
#endif /* HAVE_AMU_FS_LINKX */
/*
* Union file system
*/
#ifdef HAVE_AMU_FS_UNION
extern am_ops amfs_union_ops; /* Union FS */
#endif /* HAVE_AMU_FS_UNION */
#endif /* not _AMD_H */

View File

@ -1,174 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amfs_auto.c
*
*/
/*
* Automount file system
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
/****************************************************************************
*** MACROS ***
****************************************************************************/
/****************************************************************************
*** STRUCTURES ***
****************************************************************************/
/****************************************************************************
*** FORWARD DEFINITIONS ***
****************************************************************************/
static int amfs_auto_mount(am_node *mp, mntfs *mf);
/****************************************************************************
*** OPS STRUCTURES ***
****************************************************************************/
am_ops amfs_auto_ops =
{
"auto",
amfs_generic_match,
0, /* amfs_auto_init */
amfs_auto_mount,
amfs_generic_umount,
amfs_generic_lookup_child,
amfs_generic_mount_child,
amfs_generic_readdir,
0, /* amfs_auto_readlink */
amfs_generic_mounted,
0, /* amfs_auto_umounted */
amfs_generic_find_srvr,
0, /* amfs_auto_get_wchan */
FS_AMQINFO | FS_DIRECTORY,
#ifdef HAVE_FS_AUTOFS
AUTOFS_AUTO_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/****************************************************************************
*** FUNCTIONS ***
****************************************************************************/
/*
* Mount a sub-mount
*/
static int
amfs_auto_mount(am_node *mp, mntfs *mf)
{
if (mp->am_parent == NULL)
return EINVAL;
/*
* Pseudo-directories are used to provide some structure
* to the automounted directories instead
* of putting them all in the top-level automount directory.
*
* Here, just increment the parent's link count.
*/
mp->am_parent->am_fattr.na_nlink++;
/*
* Info field of . means use parent's info field.
* Historical - not documented.
*/
if (mf->mf_info[0] == '.' && mf->mf_info[1] == '\0')
mf->mf_info = strealloc(mf->mf_info, mp->am_parent->am_al->al_mnt->mf_info);
/*
* Compute prefix:
*
* If there is an option prefix then use that else
* If the parent had a prefix then use that with name
* of this node appended else
* Use the name of this node.
*
* That means if you want no prefix you must say so
* in the map.
*/
if (mf->mf_fo->opt_pref) {
/* allow pref:=null to set a real null prefix */
if (STREQ(mf->mf_fo->opt_pref, "null")) {
mp->am_pref = xstrdup("");
} else {
/*
* the prefix specified as an option
*/
mp->am_pref = xstrdup(mf->mf_fo->opt_pref);
}
} else {
/*
* else the parent's prefix
* followed by the name
* followed by /
*/
char *ppref = mp->am_parent->am_pref;
if (ppref == 0)
ppref = "";
mp->am_pref = str3cat((char *) NULL, ppref, mp->am_name, "/");
}
#ifdef HAVE_FS_AUTOFS
if (mf->mf_flags & MFF_IS_AUTOFS) {
char opts[SIZEOF_OPTS];
int error;
autofs_get_opts(opts, sizeof(opts), mp->am_autofs_fh);
/* now do the mount */
error = amfs_mount(mp, mf, opts);
if (error) {
errno = error;
plog(XLOG_FATAL, "amfs_auto_mount: amfs_mount failed: %m");
return error;
}
}
#endif /* HAVE_FS_AUTOFS */
/*
* Attach a map cache
*/
amfs_mkcacheref(mf);
return 0;
}

View File

@ -1,106 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amfs_direct.c
*
*/
/*
* 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_generic_match,
0, /* amfs_direct_init */
amfs_toplvl_mount,
amfs_toplvl_umount,
amfs_generic_lookup_child,
amfs_generic_mount_child,
amfs_error_readdir,
amfs_direct_readlink,
amfs_generic_mounted,
0, /* amfs_direct_umounted */
amfs_generic_find_srvr,
0, /* amfs_direct_get_wchan */
FS_DIRECT | FS_MKMNT | FS_NOTIMEOUT | FS_BACKGROUND | FS_AMQINFO,
#ifdef HAVE_FS_AUTOFS
AUTOFS_DIRECT_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/****************************************************************************
*** 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_al->al_mnt->mf_private)
amfs_mkcacheref(mp->am_al->al_mnt);
xp = amfs_generic_lookup_child(mp, mp->am_path + 1, &rc, VLOOK_CREATE);
if (xp && rc < 0)
xp = amfs_generic_mount_child(xp, &rc);
}
if (xp) {
new_ttl(xp); /* (7/12/89) from Rein Tollevik */
return xp;
}
if (amd_state == Finishing)
rc = ENOENT;
*error_return = rc;
return 0;
}

View File

@ -1,147 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amfs_error.c
*
*/
/*
* 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_mount(am_node *am, mntfs *mf);
static int amfs_error_umount(am_node *am, mntfs *mf);
/*
* Ops structure
*/
am_ops amfs_error_ops =
{
"error",
amfs_error_match,
0, /* amfs_error_init */
amfs_error_mount,
amfs_error_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* amfs_error_readlink */
0, /* amfs_error_mounted */
0, /* amfs_error_umounted */
amfs_generic_find_srvr,
0, /* amfs_error_get_wchan */
FS_DISCARD, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_ERROR_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* EFS file system always matches
*/
static char *
amfs_error_match(am_opts *fo)
{
return xstrdup("(error-hook)");
}
static int
amfs_error_mount(am_node *am, mntfs *mf)
{
return ENOENT;
}
static int
amfs_error_umount(am_node *am, 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_lookup_child(am_node *mp, char *fname, int *error_return, int op)
{
*error_return = ESTALE;
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_mount_child(am_node *ap, int *error_return)
{
*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, voidp cookie, voidp dp, voidp ep, u_int count)
{
return ESTALE;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,710 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amfs_host.c
*
*/
/*
* 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_init(mntfs *mf);
static int amfs_host_mount(am_node *am, mntfs *mf);
static int amfs_host_umount(am_node *am, mntfs *mf);
static void amfs_host_umounted(mntfs *mf);
/*
* Ops structure
*/
am_ops amfs_host_ops =
{
"host",
amfs_host_match,
amfs_host_init,
amfs_host_mount,
amfs_host_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* amfs_host_readlink */
0, /* amfs_host_mounted */
amfs_host_umounted,
find_nfs_srvr,
0, /* amfs_host_get_wchan */
FS_MKMNT | FS_BACKGROUND | FS_AMQINFO,
#ifdef HAVE_FS_AUTOFS
AUTOFS_HOST_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* 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, size_t l, const exports ex, const char *mf_mount)
{
if (ex->ex_dir[0] == '/') {
if (ex->ex_dir[1] == 0)
xstrlcpy(mntpt, mf_mount, l);
else
xsnprintf(mntpt, l, "%s%s", 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)
xsnprintf(mntpt, l, "%s/%c%%", mf_mount, ex->ex_dir[0]);
else
xsnprintf(mntpt, l, "%s/%s", 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)
{
u_short mountd_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
* get_mountd_port with our mntfs passed as the wait channel.
* get_mountd_port will check some things and then schedule
* it so that when the fileserver is ready, a wakeup is done
* on this mntfs. amfs_cont() is already sleeping on this mntfs
* so as soon as that wakeup happens amfs_cont() is called and
* this mount is retried.
*/
if (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.
*/
get_mountd_port(mf->mf_server, &mountd_port, get_mntfs_wchan(mf));
return 0;
}
static int
do_mount(am_nfs_handle_t *fhp, char *mntdir, char *fs_name, mntfs *mf)
{
struct stat stb;
dlog("amfs_host: mounting fs %s on %s\n", fs_name, mntdir);
(void) mkdirs(mntdir, 0555);
if (stat(mntdir, &stb) < 0 || (stb.st_mode & S_IFMT) != S_IFDIR) {
plog(XLOG_ERROR, "No mount point for %s - skipping", mntdir);
return ENOENT;
}
return mount_nfs_fh(fhp, mntdir, fs_name, 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;
struct fhstatus res;
#ifdef HAVE_FS_NFS3
struct am_mountres3 res3;
#endif /* HAVE_FS_NFS3 */
/*
* Pick a number, any number...
*/
tv.tv_sec = 20;
tv.tv_usec = 0;
dlog("Fetching fhandle for %s", dir);
/*
* 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", (int) nfs_version);
#ifdef HAVE_FS_NFS3
if (nfs_version == NFS_VERSION3
#ifdef HAVE_FS_NFS4
#ifndef NO_FALLBACK
|| nfs_version == NFS_VERSION4
#endif /* NO_FALLBACK */
#endif /* HAVE_FS_NFS4 */
) {
memset((char *) &res3, 0, sizeof(res3));
clnt_stat = clnt_call(client,
MOUNTPROC_MNT,
(XDRPROC_T_TYPE) xdr_dirpath,
(SVC_IN_ARG_TYPE) &dir,
(XDRPROC_T_TYPE) xdr_am_mountres3,
(SVC_IN_ARG_TYPE) &res3,
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 = res3.fhs_status)) {
dlog("fhandle fetch for mount version 3 failed: %m");
return errno;
}
memset((voidp) &fhp->v3, 0, sizeof(am_nfs_fh3));
fhp->v3.am_fh3_length = res3.mountres3_u.mountinfo.fhandle.fhandle3_len;
memmove(fhp->v3.am_fh3_data,
res3.mountres3_u.mountinfo.fhandle.fhandle3_val,
fhp->v3.am_fh3_length);
} 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) &res,
tv);
if (clnt_stat != RPC_SUCCESS) {
plog(XLOG_ERROR, "mountd rpc failed: %s", clnt_sperrno(clnt_stat));
return EIO;
}
/* Check status of filehandle */
if (res.fhs_status) {
errno = res.fhs_status;
dlog("fhandle fetch for mount version 1 failed: %m");
return errno;
}
memmove(&fhp->v2, &res.fhs_fh, NFS_FHSIZE);
#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;
}
static int
amfs_host_mount(am_node *am, mntfs *mf)
{
struct timeval tv2;
CLIENT *client;
enum clnt_stat clnt_stat;
int n_export;
int j, k;
exports exlist = 0, ex;
exports *ep = NULL;
am_nfs_handle_t *fp = NULL;
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;
/*
* WebNFS servers don't necessarily run mountd.
*/
if (mf->mf_flags & MFF_WEBNFS) {
plog(XLOG_ERROR, "amfs_host_mount: cannot support WebNFS");
return EIO;
}
/*
* 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_mount: NFS version %d", (int) mf->mf_server->fs_version);
#ifdef HAVE_FS_NFS3
if (mf->mf_server->fs_version == NFS_VERSION3)
mnt_version = AM_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 transmit 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;
dlog("Fetching export list from %s", host);
/*
* 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) {
const char *msg = clnt_sperrno(clnt_stat);
plog(XLOG_ERROR, "host_mount 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) {
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, sizeof(mntpt), ex, mf->mf_mount);
if (already_mounted(mlist, mntpt))
/* we have at least one mounted f/s, so don't fail the mount */
ok = TRUE;
else
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)) {
dlog("avoiding dup fhandle requested for %s", ep[j]->ex_dir);
ep[j] = NULL;
} else {
k = j;
error = fetch_fhandle(client, ep[j]->ex_dir, &fp[j],
mf->mf_server->fs_version);
if (error)
ep[j] = NULL;
}
}
/*
* 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.
*/
xstrlcpy(fs_name, mf->mf_info, sizeof(fs_name));
if ((rfs_dir = strchr(fs_name, ':')) == (char *) NULL) {
plog(XLOG_FATAL, "amfs_host_mount: mf_info has no colon");
error = EINVAL;
goto out;
}
++rfs_dir;
for (j = 0; j < n_export; j++) {
ex = ep[j];
if (ex) {
/*
* Note: the sizeof space left in rfs_dir is what's left in fs_name
* after strchr() above returned a pointer _inside_ fs_name. The
* calculation below also takes into account that rfs_dir was
* incremented by the ++ above.
*/
xstrlcpy(rfs_dir, ex->ex_dir, sizeof(fs_name) - (rfs_dir - fs_name));
make_mntpt(mntpt, sizeof(mntpt), ex, mf->mf_mount);
if (do_mount(&fp[j], mntpt, fs_name, mf) == 0)
ok = TRUE;
}
}
/*
* Clean up and exit
*/
out:
discard_mntlist(mlist);
XFREE(ep);
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_umount(am_node *am, mntfs *mf)
{
mntlist *ml, *mprev;
int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
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 = NULL;
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;
dlog("amfs_host: unmounts %s", dir);
/*
* Unmount "dir"
*/
error = UMOUNT_FS(dir, mnttab_file_name, unmount_flags);
/*
* Keep track of errors
*/
if (error) {
/*
* If we have not already set xerror and error is not ENOENT,
* then set xerror equal to error and log it.
* 'xerror' is the return value for this function.
*
* We do not want to pass ENOENT as an error because if the
* directory does not exists our work is done anyway.
*/
if (!xerror && error != ENOENT)
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_mount(am, 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(mntfs *mf)
{
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;
/*
* WebNFS servers shouldn't ever get here.
*/
if (mf->mf_flags & MFF_WEBNFS) {
plog(XLOG_ERROR, "amfs_host_umounted: cannot support WebNFS");
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", (int) mf->mf_server->fs_version);
#ifdef HAVE_FS_NFS3
if (mf->mf_server->fs_version == NFS_VERSION3)
mnt_version = AM_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;
dlog("Unmounting all from %s", host);
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 ... */
const char *msg = clnt_sperrno(clnt_stat);
plog(XLOG_ERROR, "unmount all from %s rpc failed: %s", host, msg);
goto out;
}
out:
if (sock != RPC_ANYSOCK)
(void) amu_close(sock);
if (client)
clnt_destroy(client);
}

View File

@ -1,129 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amfs_link.c
*
*/
/*
* Symbol-link file system
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
/* forward declarations */
static int amfs_link_mount(am_node *mp, mntfs *mf);
static int amfs_link_umount(am_node *mp, mntfs *mf);
/*
* Ops structures
*/
am_ops amfs_link_ops =
{
"link",
amfs_link_match,
0, /* amfs_link_init */
amfs_link_mount,
amfs_link_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* amfs_link_readlink */
0, /* amfs_link_mounted */
0, /* amfs_link_umounted */
amfs_generic_find_srvr,
0, /* nfs_fs_flags */
0, /* amfs_link_get_wchan */
#ifdef HAVE_FS_AUTOFS
AUTOFS_LINK_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* SFS needs a link.
*/
char *
amfs_link_match(am_opts *fo)
{
if (!fo->opt_fs) {
plog(XLOG_USER, "link: no fs specified");
return 0;
}
/*
* If the link target points to another mount point, then we could
* end up with an unpleasant situation, where the link f/s simply
* "assumes" the mntfs of that mount point.
*
* For example, if the link points to /usr, and /usr is a real ufs
* filesystem, then the link f/s will use the inherited ufs mntfs,
* and the end result will be that it will become unmountable.
*
* To prevent this, we use a hack: we prepend a dot ('.') to opt_fs if
* its original value was an absolute path, so that it will never match
* any other mntfs.
*
* XXX: a less hacky solution should be used...
*/
if (fo->opt_fs[0] == '/') {
char *link_hack = str3cat(NULL, ".", fo->opt_fs, "");
if (fo->opt_sublink == NULL || fo->opt_sublink[0] == '\0')
fo->opt_sublink = xstrdup(fo->opt_fs);
XFREE(fo->opt_fs);
fo->opt_fs = link_hack;
}
return xstrdup(fo->opt_fs);
}
static int
amfs_link_mount(am_node *mp, mntfs *mf)
{
return 0;
}
static int
amfs_link_umount(am_node *mp, mntfs *mf)
{
return 0;
}

View File

@ -1,109 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amfs_linkx.c
*
*/
/*
* 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, mntfs *mf);
static int amfs_linkx_umount(am_node *mp, mntfs *mf);
/*
* linkx operations
*/
struct am_ops amfs_linkx_ops =
{
"linkx",
amfs_link_match,
0, /* amfs_linkx_init */
amfs_linkx_mount,
amfs_linkx_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* amfs_linkx_readlink */
0, /* amfs_linkx_mounted */
0, /* amfs_linkx_umounted */
amfs_generic_find_srvr,
0, /* amfs_linkx_get_wchan */
FS_MBACKGROUND,
#ifdef HAVE_FS_AUTOFS
AUTOFS_LINKX_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
static int
amfs_linkx_mount(am_node *mp, mntfs *mf)
{
/*
* Check for existence of target.
*/
struct stat stb;
char *ln;
if (mp->am_link)
ln = mp->am_link;
else /* should never occur */
ln = mf->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;
}
static int
amfs_linkx_umount(am_node *mp, mntfs *mf)
{
return 0;
}

View File

@ -1,241 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amfs_nfsl.c
*
*/
/*
* 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_mount(am_node *mp, mntfs *mf);
static int amfs_nfsl_umount(am_node *mp, mntfs *mf);
static void amfs_nfsl_umounted(mntfs *mf);
static fserver *amfs_nfsl_ffserver(mntfs *mf);
/*
* NFS-Link operations
*/
am_ops amfs_nfsl_ops =
{
"nfsl",
amfs_nfsl_match,
amfs_nfsl_init,
amfs_nfsl_mount,
amfs_nfsl_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* amfs_nfsl_readlink */
0, /* amfs_nfsl_mounted */
amfs_nfsl_umounted,
amfs_nfsl_ffserver,
0, /* amfs_nfsl_get_wchan */
FS_MKMNT | FS_BACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_NFSL_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* 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;
char *ho = fo->opt_rhost;
char *retval;
struct stat stb;
if (fo->opt_sublink && fo->opt_sublink[0])
cp = fo->opt_sublink;
else
cp = fo->opt_fs;
if (!cp || !ho) {
plog(XLOG_USER, "amfs_nfsl: host $fs and $rhost must be specified");
return NULL;
}
/*
* If this host is not the same as $rhost, or if link does not exist,
* call nfs_ops.fs_match().
* If link value exists (or same host), call amfs_link_ops.fs_match().
*/
if (!STRCEQ(ho, am_get_hostname()) && !STRCEQ(ho, hostd)) {
plog(XLOG_INFO, "amfs_nfsl: \"%s\" is not the local host \"%s\", "
"or \"%s\" using type:=nfs", ho, am_get_hostname(), hostd);
retval = nfs_ops.fs_match(fo);
} else if (lstat(cp, &stb) < 0) {
plog(XLOG_INFO, "amfs_nfsl: \"%s\" does not exist, using type:=nfs", cp);
retval = nfs_ops.fs_match(fo);
} else {
plog(XLOG_INFO, "amfs_nfsl: \"%s\" exists, using type:=link", cp);
retval = amfs_link_ops.fs_match(fo);
}
return retval;
}
/*
* Initialize.
* Returns: 0 if OK, non-zero (errno) if failed.
*/
static int
amfs_nfsl_init(mntfs *mf)
{
int ret = 0;
if (mf->mf_flags & MFF_NFSLINK) {
if (amfs_link_ops.fs_init)
ret = amfs_link_ops.fs_init(mf);
} else {
if (nfs_ops.fs_init)
ret = nfs_ops.fs_init(mf);
}
return ret;
}
/*
* Mount vfs.
* Returns: 0 if OK, non-zero (errno) if failed.
*/
static int
amfs_nfsl_mount(am_node *mp, mntfs *mf)
{
int ret = 0;
if (mf->mf_flags & MFF_NFSLINK) {
if (amfs_link_ops.mount_fs)
ret = amfs_link_ops.mount_fs(mp, mf);
} else {
if (nfs_ops.mount_fs)
ret = nfs_ops.mount_fs(mp, mf);
}
return ret;
}
/*
* Unmount VFS.
* Returns: 0 if OK, non-zero (errno) if failed.
*/
static int
amfs_nfsl_umount(am_node *mp, mntfs *mf)
{
int ret = 0;
if (mf->mf_flags & MFF_NFSLINK) {
if (amfs_link_ops.umount_fs)
ret = amfs_link_ops.umount_fs(mp, mf);
} else {
if (nfs_ops.umount_fs)
ret = nfs_ops.umount_fs(mp, mf);
}
return ret;
}
/*
* 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(mntfs *mf)
{
if (mf->mf_flags & MFF_NFSLINK) {
if (amfs_link_ops.umounted)
amfs_link_ops.umounted(mf);
} else {
if (nfs_ops.umounted)
nfs_ops.umounted(mf);
}
}
/*
* Find a file server.
* Returns: fserver of found server, or NULL if not found.
*/
static fserver *
amfs_nfsl_ffserver(mntfs *mf)
{
char *cp, *ho;
struct stat stb;
if (mf->mf_fo == NULL) {
plog(XLOG_ERROR, "%s: NULL mf_fo", __func__);
return NULL;
}
ho = mf->mf_fo->opt_rhost;
if (mf->mf_fo->opt_sublink && mf->mf_fo->opt_sublink[0])
cp = mf->mf_fo->opt_sublink;
else
cp = mf->mf_fo->opt_fs;
/*
* If this host is not the same as $rhost, or if link does not exist,
* call amfs_link_ops.ffserver().
* If link value exists (or same host), then call ops_nfs.ffserver().
*/
if ((!STRCEQ(ho, am_get_hostname()) &&
!STRCEQ(ho, hostd)) || lstat(cp, &stb) < 0) {
return nfs_ops.ffserver(mf);
} else {
mf->mf_flags |= MFF_NFSLINK;
/* remove the FS_MKMNT flag, we don't want amd touching the mountpoint */
mf->mf_fsflags &= ~FS_MKMNT;
return amfs_link_ops.ffserver(mf);
}
}

View File

@ -1,507 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amfs_nfsx.c
*
*/
/*
* 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;
am_node *nx_mp;
};
/* forward definitions */
static char *amfs_nfsx_match(am_opts *fo);
static int amfs_nfsx_mount(am_node *am, mntfs *mf);
static int amfs_nfsx_umount(am_node *am, mntfs *mf);
static int amfs_nfsx_init(mntfs *mf);
/*
* Ops structure
*/
am_ops amfs_nfsx_ops =
{
"nfsx",
amfs_nfsx_match,
amfs_nfsx_init,
amfs_nfsx_mount,
amfs_nfsx_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* amfs_nfsx_readlink */
0, /* amfs_nfsx_mounted */
0, /* amfs_nfsx_umounted */
find_nfs_srvr, /* XXX */
0, /* amfs_nfsx_get_wchan */
/* FS_UBACKGROUND| */ FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_NFSX_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
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 == NULL || fo->opt_sublink[0] == '\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 *) NULL, fo->opt_rhost, ":", fo->opt_rfs);
dlog("NFSX: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"",
fo->opt_rhost, fo->opt_rfs, fo->opt_fs);
return xmtab;
}
static void
amfs_nfsx_prfree(opaque_t 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 = NULL;
char *host;
char *pref;
int error = 0;
info = xstrdup(mf->mf_info);
if (info == NULL)
return errno;
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++)
/* nothing */;
nx = ALLOC(struct amfs_nfsx);
mf->mf_private = (opaque_t) 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));
nx->nx_mp = NULL;
{
char *mp = NULL;
char *xinfo = NULL;
char *fs = mf->mf_fo->opt_fs;
char *rfs = NULL;
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);
dlog("amfs_nfsx: init mount for %s on %s", xinfo, mp);
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);
/* propagate the on_autofs flag */
nx->nx_v[i].n_mnt->mf_flags |= mf->mf_flags & MFF_ON_AUTOFS;
}
XFREE(rfs);
XFREE(mp);
XFREE(xinfo);
}
XFREE(ivec);
errexit:
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 = 0;
if (m->mf_ops->fs_init && !(mf->mf_flags & MFF_RESTART))
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, (opaque_t) mf, get_mntfs_wchan(m));
}
}
}
return glob_error;
}
static void
amfs_nfsx_cont(int rc, int term, opaque_t arg)
{
mntfs *mf = (mntfs *) arg;
struct amfs_nfsx *nx = (struct amfs_nfsx *) mf->mf_private;
am_node *mp = nx->nx_mp;
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(get_mntfs_wchan(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, FALSE); /* FALSE => don't free the n_mnt->am_opts */
n->n_error = 0;
}
/*
* Do the remaining bits
*/
if (amfs_nfsx_mount(mp, mf) >= 0)
wakeup(get_mntfs_wchan(mf));
}
static int
try_amfs_nfsx_mount(opaque_t mv)
{
mntfs *mf = (mntfs *) mv;
struct amfs_nfsx *nx = (struct amfs_nfsx *) mf->mf_private;
am_node *mp = nx->nx_mp;
int error;
error = mf->mf_ops->mount_fs(mp, mf);
return error;
}
static int
amfs_nfsx_remount(am_node *am, mntfs *mf, int fg)
{
struct amfs_nfsx *nx = (struct amfs_nfsx *) mf->mf_private;
amfs_nfsx_mnt *n;
int glob_error = -1;
/* Save the am_node pointer for later use */
nx->nx_mp = am;
/*
* 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 (m->mf_flags & MFF_MOUNTING)
break;
if (m->mf_flags & MFF_MOUNTED) {
mf_mounted(m, FALSE); /* FALSE => don't free the m->am_opts */
n->n_error = glob_error = 0;
continue;
}
if (n->n_error < 0) {
/* Create the mountpoint, if and as required */
if (!(m->mf_flags & MFF_MKMNT) && m->mf_fsflags & FS_MKMNT) {
if (!mkdirs(m->mf_mount, 0555))
m->mf_flags |= MFF_MKMNT;
}
dlog("calling underlying mount on %s", m->mf_mount);
if (!fg && foreground && (m->mf_fsflags & FS_MBACKGROUND)) {
m->mf_flags |= MFF_MOUNTING;
dlog("backgrounding mount of \"%s\"", m->mf_info);
nx->nx_try = n;
run_task(try_amfs_nfsx_mount, (opaque_t) m, amfs_nfsx_cont, (opaque_t) mf);
n->n_error = -1;
return -1;
} else {
dlog("foreground mount of \"%s\" ...", mf->mf_info);
n->n_error = m->mf_ops->mount_fs(am, m);
}
if (n->n_error > 0)
dlog("underlying fmount of %s failed: %s", m->mf_mount, strerror(n->n_error));
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_mount(am_node *am, mntfs *mf)
{
return amfs_nfsx_remount(am, 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_umount(am_node *am, 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 occurred 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) {
dlog("calling underlying fumount on %s", m->mf_mount);
n->n_error = m->mf_ops->umount_fs(am, 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(am, 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;
dlog("calling underlying umounted on %s", m->mf_mount);
if (m->mf_ops->umounted)
m->mf_ops->umounted(m);
if (n->n_error < 0) {
if (m->mf_fsflags & FS_MKMNT) {
(void) rmdirs(m->mf_mount);
m->mf_flags &= ~MFF_MKMNT;
}
}
free_mntfs(m);
n->n_mnt = NULL;
n->n_error = -1;
}
}
return glob_error;
}

View File

@ -1,207 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amfs_program.c
*
*/
/*
* 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_mount(am_node *am, mntfs *mf);
static int amfs_program_umount(am_node *am, mntfs *mf);
static int amfs_program_init(mntfs *mf);
/*
* Ops structure
*/
am_ops amfs_program_ops =
{
"program",
amfs_program_match,
amfs_program_init,
amfs_program_mount,
amfs_program_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* amfs_program_readlink */
0, /* amfs_program_mounted */
0, /* amfs_program_umounted */
amfs_generic_find_srvr,
0, /* amfs_program_get_wchan */
FS_MKMNT | FS_BACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_PROGRAM_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* Execute needs a mount and unmount command.
*/
static char *
amfs_program_match(am_opts *fo)
{
char *prog;
if (fo->opt_unmount && fo->opt_umount) {
plog(XLOG_ERROR, "program: cannot specify both unmount and umount options");
return 0;
}
if (!fo->opt_mount) {
plog(XLOG_ERROR, "program: must specify mount command");
return 0;
}
if (!fo->opt_unmount && !fo->opt_umount) {
fo->opt_unmount = str3cat(NULL, UNMOUNT_PROGRAM, " umount ", fo->opt_fs);
plog(XLOG_INFO, "program: un/umount not specified; using default \"%s\"",
fo->opt_unmount);
}
prog = strchr(fo->opt_mount, ' ');
return xstrdup(prog ? prog + 1 : fo->opt_mount);
}
static int
amfs_program_init(mntfs *mf)
{
/* check if already saved value */
if (mf->mf_private != NULL)
return 0;
if (mf->mf_fo == NULL)
return 0;
/* save unmount (or umount) command */
if (mf->mf_fo->opt_unmount != NULL)
mf->mf_private = (opaque_t) xstrdup(mf->mf_fo->opt_unmount);
else
mf->mf_private = (opaque_t) xstrdup(mf->mf_fo->opt_umount);
mf->mf_prfree = (void (*)(opaque_t)) free;
return 0;
}
static int
amfs_program_exec(char *info)
{
char **xivec;
int error;
/*
* Split copy of command info string
*/
info = xstrdup(info);
xivec = strsplit(info, ' ', '\'');
/*
* Put stdout to stderr
*/
(void) fclose(stdout);
if (!logfp)
logfp = stderr; /* initialize before possible first use */
if (dup(fileno(logfp)) == -1)
goto out;
if (fileno(logfp) != fileno(stderr)) {
(void) fclose(stderr);
if (dup(fileno(logfp)) == -1)
goto out;
}
/*
* Try the exec
*/
if (amuDebug(D_FULL)) {
char **cp = xivec;
plog(XLOG_DEBUG, "executing (un)mount command...");
while (*cp) {
plog(XLOG_DEBUG, "arg[%ld] = '%s'", (long) (cp - xivec), *cp);
cp++;
}
}
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);
error = errno;
plog(XLOG_ERROR, "exec failed: %m");
errno = error;
}
out:
/*
* Save error number
*/
error = errno;
/*
* Free allocate memory
*/
XFREE(info);
XFREE(xivec);
/*
* Return error
*/
return error;
}
static int
amfs_program_mount(am_node *am, mntfs *mf)
{
return amfs_program_exec(mf->mf_fo->opt_mount);
}
static int
amfs_program_umount(am_node *am, mntfs *mf)
{
return amfs_program_exec((char *) mf->mf_private);
}

View File

@ -1,95 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amfs_root.c
*
*/
/*
* 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, mntfs *mf);
/****************************************************************************
*** OPS STRUCTURES ***
****************************************************************************/
am_ops amfs_root_ops =
{
"root",
0, /* amfs_root_match */
0, /* amfs_root_init */
amfs_root_mount,
amfs_generic_umount,
amfs_generic_lookup_child,
amfs_generic_mount_child,
amfs_generic_readdir,
0, /* amfs_root_readlink */
0, /* amfs_root_mounted */
0, /* amfs_root_umounted */
amfs_generic_find_srvr,
0, /* amfs_root_get_wchan */
FS_NOTIMEOUT | FS_AMQINFO | FS_DIRECTORY, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_ROOT_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/****************************************************************************
*** FUNCTIONS ***
****************************************************************************/
/*
* Mount the root...
*/
static int
amfs_root_mount(am_node *mp, mntfs *mf)
{
mf->mf_mount = strealloc(mf->mf_mount, pid_fsname);
mf->mf_private = (opaque_t) mapc_find(mf->mf_info, "", NULL, NULL);
mf->mf_prfree = mapc_free;
return 0;
}

View File

@ -1,319 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amfs_toplvl.c
*
*/
/*
* Top-level 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_toplvl_init(mntfs *mf);
/****************************************************************************
*** OPS STRUCTURES ***
****************************************************************************/
am_ops amfs_toplvl_ops =
{
"toplvl",
amfs_generic_match,
amfs_toplvl_init, /* amfs_toplvl_init */
amfs_toplvl_mount,
amfs_toplvl_umount,
amfs_generic_lookup_child,
amfs_generic_mount_child,
amfs_generic_readdir,
0, /* amfs_toplvl_readlink */
amfs_generic_mounted,
0, /* amfs_toplvl_umounted */
amfs_generic_find_srvr,
0, /* amfs_toplvl_get_wchan */
FS_MKMNT | FS_NOTIMEOUT | FS_BACKGROUND |
FS_AMQINFO | FS_DIRECTORY, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_TOPLVL_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/****************************************************************************
*** FUNCTIONS ***
****************************************************************************/
static void
set_auto_attrcache_timeout(char *preopts, char *opts, size_t l)
{
#ifdef MNTTAB_OPT_NOAC
/*
* Don't cache attributes - they are changing under the kernel's feet.
* For example, IRIX5.2 will dispense with nfs lookup calls and hand stale
* filehandles to getattr unless we disable attribute caching on the
* automount points.
*/
if (gopt.auto_attrcache == 0) {
xsnprintf(preopts, l, ",%s", MNTTAB_OPT_NOAC);
xstrlcat(opts, preopts, l);
}
#endif /* MNTTAB_OPT_NOAC */
/*
* XXX: note that setting these to 0 in the past resulted in an error on
* some systems, which is why it's better to use "noac" if possible. For
* now, we're setting everything possible, but if this will cause trouble,
* then we'll have to condition the remainder of this on OPT_NOAC.
*/
#ifdef MNTTAB_OPT_ACTIMEO
xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTIMEO, gopt.auto_attrcache);
xstrlcat(opts, preopts, l);
#else /* MNTTAB_OPT_ACTIMEO */
# ifdef MNTTAB_OPT_ACDIRMIN
xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTDIRMIN, gopt.auto_attrcache);
xstrlcat(opts, preopts, l);
# endif /* MNTTAB_OPT_ACDIRMIN */
# ifdef MNTTAB_OPT_ACDIRMAX
xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTDIRMAX, gopt.auto_attrcache);
xstrlcat(opts, preopts, l);
# endif /* MNTTAB_OPT_ACDIRMAX */
# ifdef MNTTAB_OPT_ACREGMIN
xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTREGMIN, gopt.auto_attrcache);
xstrlcat(opts, preopts, l);
# endif /* MNTTAB_OPT_ACREGMIN */
# ifdef MNTTAB_OPT_ACREGMAX
xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTREGMAX, gopt.auto_attrcache);
xstrlcat(opts, preopts, l);
# endif /* MNTTAB_OPT_ACREGMAX */
#endif /* MNTTAB_OPT_ACTIMEO */
}
/*
* Initialize a top-level mount. In our case, if the user asked for
* forced_unmounts, and the OS supports it, then we try forced/lazy unmounts
* on any previous toplvl mounts. This is useful if a previous Amd died and
* left behind toplvl mount points (this Amd will clean them up).
*
* WARNING: Don't use forced/lazy unmounts if you have another valid Amd
* running, because this code WILL force those valid toplvl mount points to
* be detached as well!
*/
static int
amfs_toplvl_init(mntfs *mf)
{
int error = 0;
#if (defined(MNT2_GEN_OPT_FORCE) || defined(MNT2_GEN_OPT_DETACH)) && (defined(HAVE_UVMOUNT) || defined(HAVE_UMOUNT2))
if (gopt.flags & CFM_FORCED_UNMOUNTS) {
plog(XLOG_INFO, "amfs_toplvl_init: trying forced/lazy unmount of %s",
mf->mf_mount);
error = umount2_fs(mf->mf_mount, AMU_UMOUNT_FORCE | AMU_UMOUNT_DETACH);
if (error)
plog(XLOG_INFO, "amfs_toplvl_init: forced/lazy unmount failed: %m");
else
dlog("amfs_toplvl_init: forced/lazy unmount succeeded");
}
#endif /* (MNT2_GEN_OPT_FORCE || MNT2_GEN_OPT_DETACH) && (HAVE_UVMOUNT || HAVE_UMOUNT2) */
return error;
}
/*
* Mount the top-level
*/
int
amfs_toplvl_mount(am_node *mp, mntfs *mf)
{
struct stat stb;
char opts[SIZEOF_OPTS], preopts[SIZEOF_OPTS], toplvl_opts[40];
int error;
/*
* 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;
}
/*
* Construct some mount options:
*
* Tack on magic map=<mapname> option in mtab to emulate
* SunOS automounter behavior.
*/
#ifdef HAVE_FS_AUTOFS
if (mf->mf_flags & MFF_IS_AUTOFS) {
autofs_get_opts(opts, sizeof(opts), mp->am_autofs_fh);
} else
#endif /* HAVE_FS_AUTOFS */
{
preopts[0] = '\0';
#ifdef MNTTAB_OPT_INTR
xstrlcat(preopts, MNTTAB_OPT_INTR, sizeof(preopts));
xstrlcat(preopts, ",", sizeof(preopts));
#endif /* MNTTAB_OPT_INTR */
#ifdef MNTTAB_OPT_IGNORE
xstrlcat(preopts, MNTTAB_OPT_IGNORE, sizeof(preopts));
xstrlcat(preopts, ",", sizeof(preopts));
#endif /* MNTTAB_OPT_IGNORE */
/* write most of the initial options + preopts */
xsnprintf(opts, sizeof(opts), "%s%s,%s=%d,%s,map=%s",
preopts,
MNTTAB_OPT_RW,
MNTTAB_OPT_PORT, nfs_port,
mf->mf_ops->fs_type, mf->mf_info);
/* process toplvl timeo/retrans options, if any */
if (gopt.amfs_auto_timeo[AMU_TYPE_TOPLVL] > 0) {
xsnprintf(toplvl_opts, sizeof(toplvl_opts), ",%s=%d",
MNTTAB_OPT_TIMEO, gopt.amfs_auto_timeo[AMU_TYPE_TOPLVL]);
xstrlcat(opts, toplvl_opts, sizeof(opts));
}
if (gopt.amfs_auto_retrans[AMU_TYPE_TOPLVL] > 0) {
xsnprintf(toplvl_opts, sizeof(toplvl_opts), ",%s=%d",
MNTTAB_OPT_RETRANS, gopt.amfs_auto_retrans[AMU_TYPE_TOPLVL]);
xstrlcat(opts, toplvl_opts, sizeof(opts));
}
#ifdef MNTTAB_OPT_NOLOCK
xstrlcat(opts, ",", sizeof(opts));
xstrlcat(opts, MNTTAB_OPT_NOLOCK, sizeof(opts));
#endif /* MNTTAB_OPT_NOLOCK */
#ifdef MNTTAB_OPT_NOAC
if (gopt.auto_attrcache == 0) {
xstrlcat(opts, ",", sizeof(opts));
xstrlcat(opts, MNTTAB_OPT_NOAC, sizeof(opts));
} else
#endif /* MNTTAB_OPT_NOAC */
set_auto_attrcache_timeout(preopts, opts, sizeof(preopts));
}
/* now do the mount */
error = amfs_mount(mp, mf, opts);
if (error) {
errno = error;
plog(XLOG_FATAL, "amfs_toplvl_mount: amfs_mount failed: %m");
return error;
}
return 0;
}
/*
* Unmount a top-level automount node
*/
int
amfs_toplvl_umount(am_node *mp, mntfs *mf)
{
struct stat stb;
int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
int error;
int count = 0; /* how many times did we try to unmount? */
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) {
error = errno;
dlog("lstat(%s): %m", mp->am_path);
goto out;
}
if ((stb.st_mode & S_IFMT) != S_IFDIR) {
plog(XLOG_ERROR, "amfs_toplvl_umount: %s is not a directory, aborting.", mp->am_path);
error = ENOTDIR;
goto out;
}
error = UMOUNT_FS(mp->am_path, mnttab_file_name, unmount_flags);
if (error == EBUSY) {
#ifdef HAVE_FS_AUTOFS
/*
* autofs mounts are "in place", so it is possible
* that we can't just unmount our mount points and go away.
* If that's the case, just give up.
*/
if (mf->mf_flags & MFF_IS_AUTOFS)
return error;
#endif /* HAVE_FS_AUTOFS */
plog(XLOG_WARNING, "amfs_toplvl_unmount retrying %s in 1s", mp->am_path);
count++;
sleep(1);
/*
* If user wants forced/lazy unmount semantics, then set those flags,
* but only after we've tried normal lstat/umount a few times --
* otherwise forced unmounts may hang this very same Amd (by preventing
* it from achieving a clean unmount).
*/
if (gopt.flags & CFM_FORCED_UNMOUNTS) {
if (count == 5) { /* after 5 seconds, try MNT_FORCE */
dlog("enabling forced unmounts for toplvl node %s", mp->am_path);
unmount_flags |= AMU_UMOUNT_FORCE;
}
if (count == 10) { /* after 10 seconds, try MNT_DETACH */
dlog("enabling detached unmounts for toplvl node %s", mp->am_path);
unmount_flags |= AMU_UMOUNT_DETACH;
}
}
goto again;
}
out:
return error;
}

View File

@ -1,128 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amfs_union.c
*
*/
/*
* 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 int create_amfs_union_node(char *dir, opaque_t arg);
static void amfs_union_mounted(mntfs *mf);
/****************************************************************************
*** OPS STRUCTURES ***
****************************************************************************/
am_ops amfs_union_ops =
{
"union",
amfs_generic_match,
0, /* amfs_union_init */
amfs_toplvl_mount,
amfs_toplvl_umount,
amfs_generic_lookup_child,
amfs_generic_mount_child,
amfs_generic_readdir,
0, /* amfs_union_readlink */
amfs_union_mounted,
0, /* amfs_union_umounted */
amfs_generic_find_srvr,
0, /* amfs_union_get_wchan */
FS_MKMNT | FS_NOTIMEOUT | FS_BACKGROUND | FS_AMQINFO | FS_DIRECTORY,
#ifdef HAVE_FS_AUTOFS
AUTOFS_UNION_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* Create a reference to a union'ed entry
* XXX: this function may not be used anywhere...
*/
static int
create_amfs_union_node(char *dir, opaque_t arg)
{
if (!STREQ(dir, "/defaults")) {
int error = 0;
am_node *am;
am = amfs_generic_lookup_child(arg, dir, &error, VLOOK_CREATE);
if (am && error < 0)
(void)amfs_generic_mount_child(am, &error);
if (error > 0) {
errno = error; /* XXX */
plog(XLOG_ERROR, "unionfs: could not mount %s: %m", dir);
}
return error;
}
return 0;
}
static void
amfs_union_mounted(mntfs *mf)
{
int index;
am_node *mp;
amfs_mkcacheref(mf);
/*
* Having made the union mount point,
* populate all the entries...
*/
for (mp = get_first_exported_ap(&index);
mp;
mp = get_next_exported_ap(&index)) {
if (mp->am_al->al_mnt == mf) {
/* return value from create_amfs_union_node is ignored by mapc_keyiter */
(void) mapc_keyiter((mnt_map *) mp->am_al->al_mnt->mf_private,
create_amfs_union_node,
mp);
break;
}
}
}

View File

@ -1,596 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amq_subr.c
*
*/
/*
* Auxiliary 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 *) ((void *)&mp);
}
/*
* Unmount a single node
*/
int *
amqproc_umnt_1_svc(voidp argp, struct svc_req *rqstp)
{
static int res = AMQ_UMNT_OK;
am_node *mp = find_ap(*(char **) argp);
if (mp)
forcibly_timeout_mp(mp);
return &res;
}
/*
* Synchronously unmount a single node - parent side.
*/
int *
amqproc_sync_umnt_1_svc_parent(voidp argp, struct svc_req *rqstp)
{
amqproc_umnt_1_svc(argp, rqstp);
return NULL;
}
/*
* Synchronously unmount a single node - child side.
*/
amq_sync_umnt *
amqproc_sync_umnt_1_svc_child(voidp argp, struct svc_req *rqstp)
{
static amq_sync_umnt rv;
amq_sync_umnt buf;
ssize_t n;
am_node *mp = find_ap(*(char **) argp);
memset(&rv, 0, sizeof(rv));
rv.au_etype = AMQ_UMNT_READ;
if (mp && mp->am_fd[0] >= 0) {
n = read(mp->am_fd[0], &buf, sizeof(buf));
if (n == sizeof(buf))
rv = buf;
}
return &rv;
}
/*
* Synchronously unmount a single node - use if we can't fork (asynchronous).
*/
amq_sync_umnt *
amqproc_sync_umnt_1_svc_async(voidp argp, struct svc_req *rqstp)
{
static amq_sync_umnt rv;
memset(&rv, 0, sizeof(rv));
rv.au_etype = AMQ_UMNT_FORK;
rv.au_errno = errno;
amqproc_umnt_1_svc(argp, rqstp);
return &rv;
}
/*
* Return global statistics
*/
amq_mount_stats *
amqproc_stats_1_svc(voidp argp, struct svc_req *rqstp)
{
return (amq_mount_stats *) ((void *)&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;
static am_node *mp;
mp = get_exported_ap(0);
aml.amq_mount_tree_list_val = (amq_mount_tree_p *) ((void *) &mp);
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:
if (debug_option(opt->as_str))
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, orig_umask, 0))
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 *) NULL);
flush_srvr_nfs_cache((fserver *) NULL);
}
break;
}
return &rc;
}
amq_mount_info_list *
amqproc_getmntfs_1_svc(voidp argp, struct svc_req *rqstp)
{
return (amq_mount_info_list *) ((void *)&mfhead); /* XXX */
}
extern qelem map_list_head;
amq_map_info_list *
amqproc_getmapinfo_1_svc(voidp argp, struct svc_req *rqstp)
{
return (amq_map_info_list *) ((void *)&map_list_head); /* XXX */
}
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;
}
/*
* Process PAWD string of remote pawd tool.
*
* We repeat the resolution of the string until the resolved string resolves
* to itself. This ensures that we follow path resolutions through all
* possible Amd mount points until we reach some sort of convergence. To
* prevent possible infinite loops, we break out of this loop if the strings
* do not converge after MAX_PAWD_TRIES times.
*/
amq_string *
amqproc_pawd_1_svc(voidp argp, struct svc_req *rqstp)
{
static amq_string res;
#define MAX_PAWD_TRIES 10
int index, len, maxagain = MAX_PAWD_TRIES;
am_node *mp;
char *mountpoint;
char *dir = *(char **) argp;
static char tmp_buf[MAXPATHLEN];
char prev_buf[MAXPATHLEN];
tmp_buf[0] = prev_buf[0] = '\0'; /* default is empty string: no match */
do {
for (mp = get_first_exported_ap(&index);
mp;
mp = get_next_exported_ap(&index)) {
if (STREQ(mp->am_al->al_mnt->mf_ops->fs_type, "toplvl"))
continue;
if (STREQ(mp->am_al->al_mnt->mf_ops->fs_type, "auto"))
continue;
mountpoint = (mp->am_link ? mp->am_link : mp->am_al->al_mnt->mf_mount);
len = strlen(mountpoint);
if (len == 0)
continue;
if (!NSTREQ(mountpoint, dir, len))
continue;
if (dir[len] != '\0' && dir[len] != '/')
continue;
xstrlcpy(tmp_buf, mp->am_path, sizeof(tmp_buf));
xstrlcat(tmp_buf, &dir[len], sizeof(tmp_buf));
break;
} /* end of "for" loop */
/* once tmp_buf and prev_buf are equal, break out of "do" loop */
if (STREQ(tmp_buf, prev_buf))
break;
else
xstrlcpy(prev_buf, tmp_buf, sizeof(prev_buf));
} while (--maxagain);
/* check if we couldn't resolve the string after MAX_PAWD_TRIES times */
if (maxagain <= 0)
plog(XLOG_WARNING, "path \"%s\" did not resolve after %d tries",
tmp_buf, MAX_PAWD_TRIES);
res = tmp_buf;
return &res;
}
/*
* XDR routines.
*/
bool_t
xdr_amq_setopt(XDR *xdrs, amq_setopt *objp)
{
if (!xdr_enum(xdrs, (enum_t *) ((voidp) &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;
long mtime;
if (!xdr_amq_string(xdrs, &mp->am_al->al_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_al->al_mnt->mf_mount)) {
return (FALSE);
}
if (!xdr_amq_string(xdrs, &mp->am_al->al_mnt->mf_ops->fs_type)) {
return (FALSE);
}
mtime = mp->am_stats.s_mtime;
if (!xdr_long(xdrs, &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 **) ((voidp) &mp->am_osib),
sizeof(amq_mount_tree),
(XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
return (FALSE);
}
if (!xdr_pointer(xdrs,
(char **) ((voidp) &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 = NULL;
if (!xdr_amq_mount_tree_node(xdrs, objp)) {
return (FALSE);
}
if (!xdr_pointer(xdrs,
(char **) ((voidp) &mnil),
sizeof(amq_mount_tree),
(XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
return (FALSE);
}
if (!xdr_pointer(xdrs,
(char **) ((voidp) &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 **) ((voidp) &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_info_qelem(XDR *xdrs, qelem *qhead)
{
mntfs *mf;
u_int len = 0;
/*
* Compute length of list
*/
for (mf = AM_LAST(mntfs, qhead); mf != HEAD(mntfs, qhead); mf = PREV(mntfs, mf)) {
if (!(mf->mf_fsflags & 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_fsflags & 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 (FSRV_ERROR(mf->mf_server) || FSRV_ISDOWN(mf->mf_server))
up = 0;
else if (FSRV_ISUP(mf->mf_server))
up = 1;
else
up = -1;
if (!xdr_int(xdrs, &up)) {
return (FALSE);
}
}
return (TRUE);
}
bool_t
xdr_amq_map_info_qelem(XDR *xdrs, qelem *qhead)
{
mnt_map *m;
u_int len = 0;
int x;
char *n;
/*
* Compute length of list
*/
ITER(m, mnt_map, qhead) {
len++;
}
if (!xdr_u_int(xdrs, &len))
return (FALSE);
/*
* Send individual data items
*/
ITER(m, mnt_map, qhead) {
if (!xdr_amq_string(xdrs, &m->map_name)) {
return (FALSE);
}
n = m->wildcard ? m->wildcard : "";
if (!xdr_amq_string(xdrs, &n)) {
return (FALSE);
}
if (!xdr_long(xdrs, (long *) &m->modify)) {
return (FALSE);
}
x = m->flags;
if (!xdr_int(xdrs, &x)) {
return (FALSE);
}
x = m->nentries;
if (!xdr_int(xdrs, &x)) {
return (FALSE);
}
x = m->reloads;
if (!xdr_int(xdrs, &x)) {
return (FALSE);
}
if (!xdr_int(xdrs, &m->refc)) {
return (FALSE);
}
if (m->isup)
x = (*m->isup)(m, m->map_name);
else
x = -1;
if (!xdr_int(xdrs, &x)) {
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));
}

View File

@ -1,310 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/amq_svc.c
*
*/
#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 *);
#if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
# ifdef NEED_LIBWRAP_SEVERITY_VARIABLES
/*
* Some systems that define libwrap already define these two variables
* in libwrap, while others don't: so I need to know precisely iff
* to define these two severity variables.
*/
int allow_severity=0, deny_severity=0, rfc931_timeout=0;
# endif /* NEED_LIBWRAP_SEVERITY_VARIABLES */
/*
* check if remote amq is authorized to access this amd.
* Returns: 1=allowed, 0=denied.
*/
static int
amqsvc_is_client_allowed(const struct sockaddr_in *addr)
{
struct request_info req;
request_init(&req, RQ_DAEMON, AMD_SERVICE_NAME, RQ_CLIENT_SIN, addr, 0);
sock_methods(&req);
if (hosts_access(&req))
return 1;
return 0;
}
#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
/*
* Prepare the parent and child:
* 1) Setup IPC pipe.
* 2) Set signal masks.
* 3) Fork by calling background() so that NumChildren is updated.
*/
static int
amq_fork(opaque_t argp)
{
#ifdef HAVE_SIGACTION
sigset_t new, mask;
#else /* not HAVE_SIGACTION */
int mask;
#endif /* not HAVE_SIGACTION */
am_node *mp;
pid_t pid;
mp = find_ap(*(char **) argp);
if (mp == NULL) {
errno = 0;
return -1;
}
if (pipe(mp->am_fd) == -1) {
mp->am_fd[0] = -1;
mp->am_fd[1] = -1;
return -1;
}
#ifdef HAVE_SIGACTION
sigemptyset(&new); /* initialize signal set we wish to block */
sigaddset(&new, SIGHUP);
sigaddset(&new, SIGINT);
sigaddset(&new, SIGQUIT);
sigaddset(&new, SIGCHLD);
sigprocmask(SIG_BLOCK, &new, &mask);
#else /* not HAVE_SIGACTION */
mask =
sigmask(SIGHUP) |
sigmask(SIGINT) |
sigmask(SIGQUIT) |
sigmask(SIGCHLD);
mask = sigblock(mask);
#endif /* not HAVE_SIGACTION */
switch ((pid = background())) {
case -1: /* error */
dlog("amq_fork failed");
return -1;
case 0: /* child */
close(mp->am_fd[1]); /* close output end of pipe */
mp->am_fd[1] = -1;
return 0;
default: /* parent */
close(mp->am_fd[0]); /* close input end of pipe */
mp->am_fd[0] = -1;
#ifdef HAVE_SIGACTION
sigprocmask(SIG_SETMASK, &mask, NULL);
#else /* not HAVE_SIGACTION */
sigsetmask(mask);
#endif /* not HAVE_SIGACTION */
return pid;
}
}
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;
} argument;
char *result;
xdrproc_t xdr_argument, xdr_result;
amqsvcproc_t local;
amqsvcproc_t child;
amqsvcproc_t parent;
pid_t pid;
#if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
if (gopt.flags & CFM_USE_TCPWRAPPERS) {
struct sockaddr_in *remote_addr = svc_getcaller(rqstp->rq_xprt);
char *remote_hostname = inet_ntoa(remote_addr->sin_addr);
if (!amqsvc_is_client_allowed(remote_addr)) {
plog(XLOG_WARNING, "Amd denied remote amq service to %s", remote_hostname);
svcerr_auth(transp, AUTH_FAILED);
return;
} else {
dlog("Amd allowed remote amq service to %s", remote_hostname);
}
}
#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
local = NULL;
child = NULL;
parent = NULL;
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_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;
case AMQPROC_PAWD:
xdr_argument = (xdrproc_t) xdr_amq_string;
xdr_result = (xdrproc_t) xdr_amq_string;
local = (amqsvcproc_t) amqproc_pawd_1_svc;
break;
case AMQPROC_SYNC_UMNT:
xdr_argument = (xdrproc_t) xdr_amq_string;
xdr_result = (xdrproc_t) xdr_amq_sync_umnt;
parent = (amqsvcproc_t) amqproc_sync_umnt_1_svc_parent;
child = (amqsvcproc_t) amqproc_sync_umnt_1_svc_child;
/* used if fork fails */
local = (amqsvcproc_t) amqproc_sync_umnt_1_svc_async;
break;
case AMQPROC_GETMAPINFO:
xdr_argument = (xdrproc_t) xdr_void;
xdr_result = (xdrproc_t) xdr_amq_map_info_qelem;
local = (amqsvcproc_t) amqproc_getmapinfo_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;
}
pid = -1;
result = NULL;
if (child) {
switch ((pid = amq_fork(&argument))) {
case -1: /* error */
break;
case 0: /* child */
result = (*child) (&argument, rqstp);
local = NULL;
break;
default: /* parent */
result = (*parent) (&argument, rqstp);
local = NULL;
break;
}
}
if (local)
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);
}
if (pid == 0)
exit(0); /* the child is done! */
}

View File

@ -1,800 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/autil.c
*
*/
/*
* 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 NumChildren = 0; /* number of children of primary amd */
static char invalid_keys[] = "\"'!;@ \t\n";
/****************************************************************************
*** MACROS ***
****************************************************************************/
#ifdef HAVE_TRANSPORT_TYPE_TLI
# define PARENT_USLEEP_TIME 100000 /* 0.1 seconds */
#endif /* HAVE_TRANSPORT_TYPE_TLI */
/****************************************************************************
*** FORWARD DEFINITIONS ***
****************************************************************************/
static void domain_strip(char *otherdom, char *localdom);
static int dofork(void);
/****************************************************************************
*** FUNCTIONS ***
****************************************************************************/
/*
* Copy s into p, reallocating p if necessary
*/
char *
strealloc(char *p, char *s)
{
size_t len = strlen(s) + 1;
p = (char *) xrealloc((voidp) p, len);
xstrlcpy(p, s, len);
#ifdef DEBUG_MEM
# if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY)
malloc_verify();
# endif /* not defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY) */
#endif /* DEBUG_MEM */
return p;
}
/*
* 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: replace cnames with real names, and decide if to
* strip domain name or not.
*/
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;
hp = gethostbyname(*chp);
if (hp && hp->h_addrtype == AF_INET) {
dlog("Hostname %s normalized to %s", *chp, hp->h_name);
*chp = strealloc(*chp, (char *) hp->h_name);
}
}
if (gopt.flags & CFM_DOMAIN_STRIP) {
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_al->al_mnt;
/*
* Arrange to timeout this node
*/
if (mf && ((mp->am_flags & AMF_ROOT) ||
(mf->mf_flags & (MFF_MOUNTING | MFF_UNMOUNTING)))) {
/*
* We aren't going to schedule a timeout, so we need to notify the
* child here unless we are already unmounting, in which case that
* process is responsible for notifying the child.
*/
if (mf->mf_flags & MFF_UNMOUNTING)
plog(XLOG_WARNING, "node %s is currently being unmounted, ignoring timeout request", mp->am_path);
else {
plog(XLOG_WARNING, "ignoring timeout request for active node %s", mp->am_path);
notify_child(mp, AMQ_UMNT_FAILED, EBUSY, 0);
}
} else {
plog(XLOG_INFO, "\"%s\" forcibly timed out", mp->am_path);
mp->am_flags &= ~AMF_NOTIMEOUT;
mp->am_ttl = clocktime(NULL);
/*
* Force mtime update of parent dir, to prevent DNLC/dcache from caching
* the old entry, which could result in ESTALE errors, bad symlinks, and
* more.
*/
clocktime(&mp->am_parent->am_fattr.na_mtime);
reschedule_timeout_mp();
}
}
void
mf_mounted(mntfs *mf, bool_t call_free_opts)
{
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);
/*
* We used to free the mf_mo (options) here, however they're now stored
* and managed with the mntfs and do not need to be free'd here (this ensures
* that we use the same options to monitor/unmount the system as we used
* to mount it).
*/
}
if (mf->mf_flags & MFF_RESTART) {
mf->mf_flags &= ~MFF_RESTART;
dlog("Restarted filesystem %s, flags 0x%x", mf->mf_mount, mf->mf_flags);
}
/*
* 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)
{
int notimeout = 0; /* assume normal timeouts initially */
mntfs *mf = mp->am_al->al_mnt;
/*
* This is the parent mntfs which does the mf->mf_fo (am_opts type), and
* we're passing TRUE here to tell mf_mounted to actually free the
* am_opts. See a related comment in mf_mounted().
*/
mf_mounted(mf, TRUE);
#ifdef HAVE_FS_AUTOFS
if (mf->mf_flags & MFF_IS_AUTOFS)
autofs_mounted(mp);
#endif /* HAVE_FS_AUTOFS */
/*
* Patch up path for direct mounts
*/
if (mp->am_parent && mp->am_parent->am_al->al_mnt->mf_fsflags & FS_DIRECT)
mp->am_path = str3cat(mp->am_path, mp->am_parent->am_path, "/", ".");
/*
* Check whether this mount should be cached permanently or not,
* and handle user-requested timeouts.
*/
/* first check if file system was set to never timeout */
if (mf->mf_fsflags & FS_NOTIMEOUT)
notimeout = 1;
/* next, alter that decision by map flags */
if (mf->mf_mopts) {
mntent_t mnt;
mnt.mnt_opts = mf->mf_mopts;
/* umount option: user wants to unmount this entry */
if (amu_hasmntopt(&mnt, "unmount") || amu_hasmntopt(&mnt, "umount"))
notimeout = 0;
/* noumount option: user does NOT want to unmount this entry */
if (amu_hasmntopt(&mnt, "nounmount") || amu_hasmntopt(&mnt, "noumount"))
notimeout = 1;
/* utimeout=N option: user wants to unmount this option AND set timeout */
if ((mp->am_timeo = hasmntval(&mnt, "utimeout")) == 0)
mp->am_timeo = gopt.am_timeo; /* otherwise use default timeout */
else
notimeout = 0;
/* special case: don't try to unmount "/" (it can never succeed) */
if (mf->mf_mount[0] == '/' && mf->mf_mount[1] == '\0')
notimeout = 1;
}
/* finally set actual flags */
if (notimeout) {
mp->am_flags |= AMF_NOTIMEOUT;
plog(XLOG_INFO, "%s set to never timeout", mp->am_path);
} else {
mp->am_flags &= ~AMF_NOTIMEOUT;
plog(XLOG_INFO, "%s set to timeout in %d seconds", mp->am_path, mp->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 : mf->mf_mount);
/*
* Record mount time, and update am_stats at the same time.
*/
mp->am_stats.s_mtime = clocktime(&mp->am_fattr.na_mtime);
new_ttl(mp);
/*
* Update mtime of parent node (copying "struct nfstime" in '=' below)
*/
if (mp->am_parent && mp->am_parent->am_al->al_mnt)
mp->am_parent->am_fattr.na_mtime = mp->am_fattr.na_mtime;
/*
* This is ugly, but essentially unavoidable
* Sublinks must be treated separately as type==link
* when the base type is different.
*/
if (mp->am_link && mf->mf_ops != &amfs_link_ops)
amfs_link_ops.mount_fs(mp, mf);
/*
* Now, if we can, do a reply to our client here
* to speed things up.
*/
#ifdef HAVE_FS_AUTOFS
if (mp->am_flags & AMF_AUTOFS)
autofs_mount_succeeded(mp);
else
#endif /* HAVE_FS_AUTOFS */
nfs_quick_reply(mp, 0);
/*
* Update stats
*/
amd_stats.d_mok++;
}
/*
* Replace mount point with a reference to an error filesystem.
* The mount point (struct mntfs) is NOT discarded,
* the caller must do it if it wants to _before_ calling this function.
*/
void
assign_error_mntfs(am_node *mp)
{
int error;
dlog("assign_error_mntfs");
if (mp->am_al == NULL) {
plog(XLOG_ERROR, "%s: Can't assign error", __func__);
return;
}
/*
* Save the old error code
*/
error = mp->am_error;
if (error <= 0)
error = mp->am_al->al_mnt->mf_error;
/*
* Allocate a new error reference
*/
free_loc(mp->am_al);
mp->am_al = new_loc();
/*
* Put back the error code
*/
mp->am_al->al_mnt->mf_error = error;
mp->am_al->al_mnt->mf_flags |= MFF_ERROR;
/*
* Zero the error in the mount point
*/
mp->am_error = 0;
}
/*
* Build a new map cache for this node, or re-use
* an existing cache for the same map.
*/
void
amfs_mkcacheref(mntfs *mf)
{
char *cache;
if (mf->mf_fo && mf->mf_fo->opt_cache)
cache = mf->mf_fo->opt_cache;
else
cache = "none";
mf->mf_private = (opaque_t) mapc_find(mf->mf_info,
cache,
(mf->mf_fo ? mf->mf_fo->opt_maptype : NULL),
mf->mf_mount);
mf->mf_prfree = mapc_free;
}
/*
* Locate next node in sibling list which is mounted
* and is not an error node.
*/
am_node *
next_nonerror_node(am_node *xp)
{
mntfs *mf;
/*
* Bug report (7/12/89) from Rein Tollevik <rein@ifi.uio.no>
* Fixes a race condition when mounting direct automounts.
* Also fixes a problem when doing a readdir on a directory
* containing hung automounts.
*/
while (xp &&
(!(mf = xp->am_al->al_mnt) || /* No mounted filesystem */
mf->mf_error != 0 || /* There was a mntfs error */
xp->am_error != 0 || /* There was a mount error */
!(mf->mf_flags & MFF_MOUNTED) || /* The fs is not mounted */
(mf->mf_server->fs_flags & FSF_DOWN)) /* The fs may be down */
)
xp = xp->am_osib;
return xp;
}
/*
* Mount an automounter directory.
* The automounter is connected into the system
* as a user-level NFS server. amfs_mount 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 (UDP).
*
* NEW: on certain systems, mounting can be done using the
* kernel-level automount (autofs) support. In that case,
* we don't need NFS at all here.
*/
int
amfs_mount(am_node *mp, mntfs *mf, char *opts)
{
char fs_hostname[MAXHOSTNAMELEN + MAXPATHLEN + 1];
int retry, error = 0, genflags;
int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
char *dir = mf->mf_mount;
mntent_t mnt;
MTYPE_TYPE type;
int forced_unmount = 0; /* are we using forced unmounts? */
u_long nfs_version = get_nfs_dispatcher_version(nfs_dispatcher);
memset(&mnt, 0, sizeof(mnt));
mnt.mnt_dir = dir;
mnt.mnt_fsname = pid_fsname;
mnt.mnt_opts = opts;
#ifdef HAVE_FS_AUTOFS
if (mf->mf_flags & MFF_IS_AUTOFS) {
type = MOUNT_TYPE_AUTOFS;
/*
* Make sure that amd's top-level autofs mounts are hidden by default
* from df.
* XXX: It works ok on Linux, might not work on other systems.
*/
mnt.mnt_type = "autofs";
} else
#endif /* HAVE_FS_AUTOFS */
{
type = MOUNT_TYPE_NFS;
/*
* 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: default to 2 retries */
/*
* SET MOUNT ARGS
*/
/*
* Make a ``hostname'' string for the kernel
*/
xsnprintf(fs_hostname, sizeof(fs_hostname), "pid%ld@%s:%s",
get_server_pid(), am_get_hostname(), dir);
/*
* Most kernels have a name length restriction (64 bytes)...
*/
if (strlen(fs_hostname) >= MAXHOSTNAMELEN)
xstrlcpy(fs_hostname + MAXHOSTNAMELEN - 3, "..",
sizeof(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)
xstrlcpy(fs_hostname + HOSTNAMESZ - 3, "..",
sizeof(fs_hostname) - HOSTNAMESZ + 3);
#endif /* HOSTNAMESZ */
/*
* Finally we can compute the mount genflags set above,
* and add any automounter specific flags.
*/
genflags = compute_mount_flags(&mnt);
#ifdef HAVE_FS_AUTOFS
if (on_autofs)
genflags |= autofs_compute_mount_flags(&mnt);
#endif /* HAVE_FS_AUTOFS */
genflags |= compute_automounter_mount_flags(&mnt);
again:
if (!(mf->mf_flags & MFF_IS_AUTOFS)) {
nfs_args_t nfs_args;
am_nfs_handle_t *fhp, anh;
#ifndef HAVE_TRANSPORT_TYPE_TLI
u_short port;
struct sockaddr_in sin;
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
/*
* get fhandle of remote path for automount point
*/
fhp = get_root_nfs_fh(dir, &anh);
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.
*/
memset(&sin, 0, sizeof(sin));
/* as per POSIX, sin_len need not be set (used internally by kernel) */
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 */
/* setup the many fields and flags within nfs_args */
#ifdef HAVE_TRANSPORT_TYPE_TLI
compute_nfs_args(&nfs_args,
&mnt,
genflags,
nfsncp,
NULL, /* remote host IP addr is set below */
nfs_version,
"udp",
fhp,
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,
NULL,
&sin,
nfs_version,
"udp",
fhp,
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 quite regular, and so some options must be *
* corrected by hand more carefully, *after* compute_nfs_args() runs. *
*************************************************************************/
compute_automounter_nfs_args(&nfs_args, &mnt);
if (amuDebug(D_TRACE)) {
print_nfs_args(&nfs_args, 0);
plog(XLOG_DEBUG, "Generic mount flags 0x%x", genflags);
}
/* This is it! Here we try to mount amd on its mount points */
error = mount_fs(&mnt, genflags, (caddr_t) &nfs_args,
retry, type, 0, NULL, mnttab_file_name, on_autofs);
#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 */
#ifdef HAVE_FS_AUTOFS
} else {
/* This is it! Here we try to mount amd on its mount points */
error = mount_fs(&mnt, genflags, (caddr_t) mp->am_autofs_fh,
retry, type, 0, NULL, mnttab_file_name, on_autofs);
#endif /* HAVE_FS_AUTOFS */
}
if (error == 0 || forced_unmount)
return error;
/*
* If user wants forced/lazy unmount semantics, then try it iff the
* current mount failed with EIO or ESTALE.
*/
if (gopt.flags & CFM_FORCED_UNMOUNTS) {
switch (errno) {
case ESTALE:
case EIO:
forced_unmount = errno;
plog(XLOG_WARNING, "Mount %s failed (%m); force unmount.", mp->am_path);
if ((error = UMOUNT_FS(mp->am_path, mnttab_file_name,
AMU_UMOUNT_FORCE | AMU_UMOUNT_DETACH)) < 0) {
plog(XLOG_WARNING, "Forced umount %s failed: %m.", mp->am_path);
errno = forced_unmount;
} else
goto again;
default:
break;
}
}
return error;
}
void
am_unmounted(am_node *mp)
{
mntfs *mf = mp->am_al->al_mnt;
if (!foreground) { /* firewall - should never happen */
/*
* This is a coding error. Make sure we hear about it!
*/
plog(XLOG_FATAL, "am_unmounted: illegal use in background (%s)",
mp->am_name);
notify_child(mp, AMQ_UMNT_OK, 0, 0); /* XXX - be safe? */
return;
}
/*
* Do unmounted callback
*/
if (mf->mf_ops->umounted)
mf->mf_ops->umounted(mf);
/*
* This is ugly, but essentially unavoidable.
* Sublinks must be treated separately as type==link
* when the base type is different.
*/
if (mp->am_link && mf->mf_ops != &amfs_link_ops)
amfs_link_ops.umount_fs(mp, mf);
#ifdef HAVE_FS_AUTOFS
if (mf->mf_flags & MFF_IS_AUTOFS)
autofs_release_fh(mp);
if (mp->am_flags & AMF_AUTOFS)
autofs_umount_succeeded(mp);
#endif /* HAVE_FS_AUTOFS */
/*
* Clean up any directories that were made
*
* If we remove the mount point of a pending mount, any queued access
* to it will fail. So don't do it in that case.
* Also don't do it if the refcount is > 1.
*/
if (mf->mf_flags & MFF_MKMNT &&
mf->mf_refc == 1 &&
!(mp->am_flags & AMF_REMOUNT)) {
plog(XLOG_INFO, "removing mountpoint directory '%s'", mf->mf_mount);
rmdirs(mf->mf_mount);
mf->mf_flags &= ~MFF_MKMNT;
}
/*
* If this is a pseudo-directory then adjust the link count
* in the parent
*/
if (mp->am_parent && mp->am_fattr.na_type == NFDIR)
--mp->am_parent->am_fattr.na_nlink;
/*
* Update mtime of parent node
*/
if (mp->am_parent && mp->am_parent->am_al->al_mnt)
clocktime(&mp->am_parent->am_fattr.na_mtime);
if (mp->am_parent && (mp->am_flags & AMF_REMOUNT)) {
char *fname = xstrdup(mp->am_name);
am_node *mp_parent = mp->am_parent;
mntfs *mf_parent = mp_parent->am_al->al_mnt;
am_node fake_mp;
int error = 0;
/*
* We need to use notify_child() after free_map(), so save enough
* to do that in fake_mp.
*/
fake_mp.am_fd[1] = mp->am_fd[1];
mp->am_fd[1] = -1;
free_map(mp);
plog(XLOG_INFO, "am_unmounted: remounting %s", fname);
mp = mf_parent->mf_ops->lookup_child(mp_parent, fname, &error, VLOOK_CREATE);
if (mp && error < 0)
(void)mf_parent->mf_ops->mount_child(mp, &error);
if (error > 0) {
errno = error;
plog(XLOG_ERROR, "am_unmounted: could not remount %s: %m", fname);
notify_child(&fake_mp, AMQ_UMNT_OK, 0, 0);
} else {
notify_child(&fake_mp, AMQ_UMNT_FAILED, EBUSY, 0);
}
XFREE(fname);
} else {
/*
* We have a race here.
* If this node has a pending mount and amd is going down (unmounting
* everything in the process), then we could potentially free it here
* while a struct continuation still has a reference to it. So when
* amfs_cont is called, it blows up.
* We avoid the race by refusing to free any nodes that have
* pending mounts (defined as having a non-NULL am_alarray).
*/
notify_child(mp, AMQ_UMNT_OK, 0, 0); /* do this regardless */
if (!mp->am_alarray)
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) */
am_set_mypid();
foreground = 0;
} else { /* parent process, has one more child */
NumChildren++;
}
return pid;
}
int
background(void)
{
int pid = dofork();
if (pid == 0) {
dlog("backgrounded");
foreground = 0;
} else
dlog("forked process %d", pid);
return pid;
}

View File

@ -1,240 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/clock.c
*
*/
/*
* Callouts.
*
* Modeled 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>
void reschedule_timeouts(time_t now, time_t then);
typedef struct callout callout;
struct callout {
callout *c_next; /* List of callouts */
callout_fun *c_fn; /* Function to call */
opaque_t c_arg; /* Argument 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() (++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)(fn_arg) will be called at clocktime(NULL) + secs
*/
int
timeout(u_int secs, callout_fun *fn, opaque_t fn_arg)
{
callout *cp, *cp2;
time_t t = clocktime(NULL) + secs;
/*
* Allocate and fill in a new callout structure
*/
callout *cpnew = alloc_callout();
cpnew->c_arg = fn_arg;
cpnew->c_fn = fn;
cpnew->c_time = t;
cpnew->c_id = CID_ALLOC();
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);
dlog("rescheduling job %d back %ld seconds",
cp->c_id, (long) (cp->c_time - now));
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(NULL);
/*
* While there are more callouts waiting...
*/
while ((cp = callouts.c_next) && cp->c_time <= now) {
/*
* Extract first from list, save fn & fn_arg 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
*/
callout_fun *fn = cp->c_fn;
opaque_t fn_arg = cp->c_arg;
callouts.c_next = cp->c_next;
free_callout(cp);
(*fn) (fn_arg);
}
} 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;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,154 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/conf_parse.y
*
*/
%{
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
extern char *yytext;
extern int ayylineno;
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), ayylineno, (s))
# define amu_return(v)
#else /* not PARSE_DEBUG */
# define dprintf(f,s)
# define amu_return(v) return((v))
#endif /* not 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, ayylineno,
(header_section ? header_section : "null"));
exit(1);
return 1; /* to full compilers that insist on a return statement */
}

View File

@ -1,189 +0,0 @@
%{
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/conf_tok.l
*
*/
/*
* 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 using GNU flex.
* These must not be defined if using standard lex
*/
#ifdef FLEX_SCANNER
# ifndef ECHO
# define ECHO __IGNORE(fwrite( yytext, yyleng, 1, yyout ))
# endif /* not ECHO */
#endif /* FLEX_SCANNER */
int ayylineno = 0;
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.
*/
#if !defined(yywrap) || defined(yylex)
int yywrap(void);
#endif /* not yywrap or yylex */
#define TOK_DEBUG 0
#if TOK_DEBUG
# define dprintf(f,s) fprintf(stderr, (f), ayylineno, (s))
# define amu_return(v)
#else /* not TOK_DEBUG */
# define dprintf(f,s)
# define amu_return(v) return((v))
#endif /* not TOK_DEBUG */
/* no need to use yywrap() */
#define YY_SKIP_YYWRAP
%}
/* This option causes Solaris lex to fail. Use flex. See BUGS file */
/* no need to use yyunput() */
%option nounput
%option noinput
/* allocate more output slots so lex scanners don't run out of mem */
%o 1024
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 {
ayylineno++;
amu_return(NEWLINE);
}
\[ {
dprintf("%8d: Left bracket \"%s\"\n", yytext);
conf_lval.strtype = xstrdup(yytext);
amu_return(LEFT_BRACKET);
}
\] {
dprintf("%8d: Right bracket \"%s\"\n", yytext);
conf_lval.strtype = xstrdup(yytext);
amu_return(RIGHT_BRACKET);
}
= {
dprintf("%8d: Equal \"%s\"\n", yytext);
conf_lval.strtype = xstrdup(yytext);
amu_return(EQUAL);
}
[ \t]* {
dprintf("%8d: Whitespace \"%s\"\n", yytext);
}
"#"[^\n]*\n {
/* a comment line includes the terminating \n */
ayylineno++;
yytext[strlen((char *)yytext)-1] = '\0';
dprintf("%8d: Comment \"%s\"\n", yytext);
}
{NONWSCHAR}{NONWSCHAR}* {
dprintf("%8d: Non-WS string \"%s\"\n", yytext);
conf_lval.strtype = xstrdup(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';
conf_lval.strtype = xstrdup(&yytext[1]);
amu_return(QUOTED_NONWSEQ_STRING);
}
{NONWSEQCHAR}{NONWSEQCHAR}* {
dprintf("%8d: Non-WS-EQ string \"%s\"\n", yytext);
conf_lval.strtype = xstrdup(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.
*/
#if !defined(yywrap) || defined(yylex)
int yywrap(void)
{
return 1;
}
#endif /* not yywrap or yylex */

View File

@ -1,440 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/get_args.c
*
*/
/*
* 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 *amu_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 */
/*
* Return the version string (dynamic buffer)
*/
char *
get_version_string(void)
{
char *vers = NULL;
char tmpbuf[1024];
char *wire_buf;
int wire_buf_len = 0;
size_t len; /* max allocated length (to avoid buf overflow) */
/*
* First get dynamic string listing all known networks.
* This could be a long list, if host has lots of interfaces.
*/
wire_buf = print_wires();
if (wire_buf)
wire_buf_len = strlen(wire_buf);
len = 2048 + wire_buf_len;
vers = xmalloc(len);
xsnprintf(vers, len, "%s\n%s\n%s\n%s\n",
"Copyright (c) 1997-2014 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.");
xsnprintf(tmpbuf, sizeof(tmpbuf), "%s version %s (build %d).\n",
PACKAGE_NAME, PACKAGE_VERSION, AMU_BUILD_VERSION);
xstrlcat(vers, tmpbuf, len);
xsnprintf(tmpbuf, sizeof(tmpbuf), "Report bugs to %s.\n", PACKAGE_BUGREPORT);
xstrlcat(vers, tmpbuf, len);
#if 0
/*
* XXX This block (between from the #if 0 to #endif was in the
* XXX original was in the original merge however in the interest
* XXX of reproduceable builds and the fact that this is redundant
* XXX information, it is effectively removed.
*/
xsnprintf(tmpbuf, sizeof(tmpbuf), "Configured by %s@%s on date %s.\n",
USER_NAME, HOST_NAME, CONFIG_DATE);
xstrlcat(vers, tmpbuf, len);
xsnprintf(tmpbuf, sizeof(tmpbuf), "Built by %s@%s on date %s.\n",
BUILD_USER, BUILD_HOST, BUILD_DATE);
xstrlcat(vers, tmpbuf, len);
#endif
xsnprintf(tmpbuf, sizeof(tmpbuf), "cpu=%s (%s-endian), arch=%s, karch=%s.\n",
cpu, endian, gopt.arch, gopt.karch);
xstrlcat(vers, tmpbuf, len);
xsnprintf(tmpbuf, sizeof(tmpbuf), "full_os=%s, os=%s, osver=%s, vendor=%s, distro=%s.\n",
gopt.op_sys_full, gopt.op_sys, gopt.op_sys_ver, gopt.op_sys_vendor, DISTRO_NAME);
xstrlcat(vers, tmpbuf, len);
xsnprintf(tmpbuf, sizeof(tmpbuf), "domain=%s, host=%s, hostd=%s.\n",
hostdomain, am_get_hostname(), hostd);
xstrlcat(vers, tmpbuf, len);
xstrlcat(vers, "Map support for: ", len);
mapc_showtypes(tmpbuf, sizeof(tmpbuf));
xstrlcat(vers, tmpbuf, len);
xstrlcat(vers, ".\nAMFS: ", len);
ops_showamfstypes(tmpbuf, sizeof(tmpbuf));
xstrlcat(vers, tmpbuf, len);
xstrlcat(vers, ", inherit.\nFS: ", len); /* hack: "show" that we support type:=inherit */
ops_showfstypes(tmpbuf, sizeof(tmpbuf));
xstrlcat(vers, tmpbuf, len);
/* append list of networks if available */
if (wire_buf) {
xstrlcat(vers, wire_buf, len);
XFREE(wire_buf);
}
return vers;
}
static void
show_usage(void)
{
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] [-A arch] [-C cluster_name]\n\
\t[-o op_sys_ver] [-O op_sys_name]\n\
\t[-F conf_file] [-T conf_tag]", am_get_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");
}
void
get_args(int argc, char *argv[])
{
int opt_ch, i;
FILE *fp = stdin;
char getopt_arguments[] = "+nprvSa:c:d:k:l:o:t:w:x:y:C:D:F:T:O:HA:";
char *getopt_args;
int print_version = 0; /* 1 means we should print version info */
#ifdef HAVE_GNU_GETOPT
getopt_args = getopt_arguments;
#else /* ! HAVE_GNU_GETOPT */
getopt_args = &getopt_arguments[1];
#endif /* HAVE_GNU_GETOPT */
/* 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, getopt_args)) != -1)
switch (opt_ch) {
case 'a':
if (*optarg != '/') {
fprintf(stderr, "%s: -a option must begin with a '/'\n",
am_get_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 (also affects toplvl mounts) */
{
char *dot = strchr(optarg, '.');
int i;
if (dot)
*dot = '\0';
if (*optarg) {
for (i=0; i<AMU_TYPE_MAX; ++i)
gopt.amfs_auto_timeo[i] = atoi(optarg);
}
if (dot) {
for (i=0; i<AMU_TYPE_MAX; ++i)
gopt.amfs_auto_retrans[i] = atoi(dot + 1);
*dot = '.';
}
}
break;
case 'v':
/*
* defer to print version info after every variable had been
* initialized.
*/
print_version++;
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 'A':
gopt.arch = optarg;
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",
am_get_progname());
#endif /* not DEBUG */
break;
case 'F':
amu_conf_file = optarg;
use_conf_file = 1;
break;
case 'H':
show_usage();
exit(1);
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 && amu_conf_file) {
fp = fopen(amu_conf_file, "r");
if (!fp) {
char buf[128];
xsnprintf(buf, sizeof(buf), "Amd configuration file (%s)",
amu_conf_file);
perror(buf);
exit(1);
}
conf_in = fp;
conf_parse();
fclose(fp);
if (process_all_regular_maps() != 0)
exit(1);
}
#ifdef DEBUG
usage += switch_option("debug");
/* initialize debug options */
if (!debug_flags)
debug_flags = D_CONTROL; /* CONTROL = "daemon,amq,fork" */
#endif /* DEBUG */
/* log information regarding amd.conf file */
if (use_conf_file && amu_conf_file)
plog(XLOG_INFO, "using configuration file %s", amu_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) {
show_usage();
exit(1);
}
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++;
xstrlcat(hostd, ".", sizeof(hostd));
xstrlcat(hostd, hostdomain, sizeof(hostd));
#ifdef MOUNT_TABLE_ON_FILE
if (amuDebug(D_MTAB))
if (gopt.debug_mtab_file)
mnttab_file_name = gopt.debug_mtab_file; /* user supplied debug mtab path */
else
mnttab_file_name = DEBUG_MNTTAB_FILE; /* default debug mtab path */
else
mnttab_file_name = MNTTAB_FILE_NAME;
#else /* not MOUNT_TABLE_ON_FILE */
if (amuDebug(D_MTAB))
dlog("-D mtab option ignored");
# ifdef MNTTAB_FILE_NAME
mnttab_file_name = MNTTAB_FILE_NAME;
# endif /* MNTTAB_FILE_NAME */
#endif /* not MOUNT_TABLE_ON_FILE */
/*
* If the kernel architecture was not specified
* then use the machine architecture.
*/
if (gopt.karch == NULL)
gopt.karch = gopt.arch;
if (gopt.cluster == NULL)
gopt.cluster = hostdomain;
/* sanity checking, normalize values just in case (toplvl too) */
for (i=0; i<AMU_TYPE_MAX; ++i) {
if (gopt.amfs_auto_timeo[i] == 0)
gopt.amfs_auto_timeo[i] = AMFS_AUTO_TIMEO;
if (gopt.amfs_auto_retrans[i] == 0)
gopt.amfs_auto_retrans[i] = AMFS_AUTO_RETRANS(i);
if (gopt.amfs_auto_retrans[i] == 0)
gopt.amfs_auto_retrans[i] = 3; /* under very unusual circumstances, could be zero */
}
}
/* finally print version string and exit, if asked for */
if (print_version) {
fputs(get_version_string(), stderr);
exit(0);
}
if (switch_to_logfile(gopt.logfile, orig_umask,
(gopt.flags & CFM_TRUNCATE_LOG)) != 0)
plog(XLOG_USER, "Cannot switch logfile");
return;
}

View File

@ -1,422 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/info_exec.c
*
*/
/*
* Get info from executable map
*
* Original from Erik Kline, 2004.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
#include <sun_map.h>
/* forward declarations */
int exec_init(mnt_map *m, char *map, time_t *tp);
int exec_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
/*
* a timed fgets()
*/
static char *
fgets_timed(char *s, int size, int rdfd, int secs)
{
fd_set fds;
struct timeval timeo;
time_t start, now;
int rval=0, i=0;
if (!s || size < 0 || rdfd < 0)
return 0;
s[0] = '\0';
if (size == 0)
return s;
start = clocktime(NULL);
while (s[i] != '\n' && i < size-1) {
s[i+1] = '\0'; /* places the requisite trailing '\0' */
/* ready for reading */
rval = read(rdfd, (void *)(s+i), 1);
if (rval == 1) {
if (s[i] == 0) {
rval = 0;
break;
}
i++;
continue;
} else if (rval == 0) {
break;
} else if (rval < 0 && errno != EAGAIN && errno != EINTR) {
plog(XLOG_WARNING, "fgets_timed read error: %m");
break;
}
timeo.tv_usec = 0;
now = clocktime(NULL) - start;
if (secs <= 0)
timeo.tv_sec = 0;
else if (now < secs)
timeo.tv_sec = secs - now;
else {
/* timed out (now>=secs) */
plog(XLOG_WARNING, "executable map read timed out (> %d secs)", secs);
rval = -1;
break;
}
FD_ZERO(&fds);
FD_SET(rdfd, &fds);
rval = select(rdfd+1, &fds, NULL, NULL, &timeo);
if (rval < 0) {
/* error selecting */
plog(XLOG_WARNING, "fgets_timed select error: %m");
if (errno == EINTR)
continue;
rval = -1;
break;
} else if (rval == 0) {
/* timed out */
plog(XLOG_WARNING, "executable map read timed out (> %d secs)", secs);
rval = -1;
break;
}
}
if (rval > 0)
return s;
close(rdfd);
return (rval == 0 ? s : 0);
}
static int
read_line(char *buf, int size, int fd)
{
int done = 0;
while (fgets_timed(buf, size, fd, gopt.exec_map_timeout)) {
int len = strlen(buf);
done += len;
if (len > 1 && buf[len - 2] == '\\' &&
buf[len - 1] == '\n') {
buf += len - 2;
size -= len - 2;
*buf = '\n';
buf[1] = '\0';
} else {
return done;
}
}
return done;
}
/*
* Try to locate a value in a query answer
*/
static int
exec_parse_qanswer(mnt_map *m, int fd, char *map, char *key, char **pval, time_t *tp)
{
char qanswer[INFO_MAX_LINE_LEN], *dc = NULL;
int chuck = 0;
int line_no = 0;
while (read_line(qanswer, sizeof(qanswer), fd)) {
char *cp;
char *hash;
int len = strlen(qanswer);
line_no++;
/*
* Make sure we got the whole line
*/
if (qanswer[len - 1] != '\n') {
plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map);
chuck = 1;
} else {
qanswer[len - 1] = '\0';
}
/*
* Strip comments
*/
hash = strchr(qanswer, '#');
if (hash)
*hash = '\0';
/*
* Find beginning of value (query answer)
*/
for (cp = qanswer; *cp && !isascii((unsigned char)*cp) && !isspace((unsigned char)*cp); cp++)
;;
/* Ignore blank lines */
if (!*cp)
goto again;
/*
* Return a copy of the data
*/
if (m->cfm && (m->cfm->cfm_flags & CFM_SUN_MAP_SYNTAX))
dc = sun_entry2amd(key, cp);
else
dc = xstrdup(cp);
*pval = dc;
dlog("%s returns %s", key, dc);
close(fd);
return 0;
again:
/*
* If the last read didn't get a whole line then
* throw away the remainder before continuing...
*/
if (chuck) {
while (fgets_timed(qanswer, sizeof(qanswer), fd, gopt.exec_map_timeout) &&
!strchr(qanswer, '\n')) ;
chuck = 0;
}
}
return ENOENT;
}
static int
set_nonblock(int fd)
{
int val;
if (fd < 0)
return 0;
if ((val = fcntl(fd, F_GETFL, 0)) < 0) {
plog(XLOG_WARNING, "set_nonblock fcntl F_GETFL error: %m");
return 0;
}
val |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, val) < 0) {
plog(XLOG_WARNING, "set_nonblock fcntl F_SETFL error: %m");
return 0;
}
return 1;
}
static int
exec_map_open(char *emap, char *key)
{
pid_t p1, p2;
int pdes[2], nullfd, i;
char *argv[3];
if (!emap)
return 0;
argv[0] = emap;
argv[1] = key;
argv[2] = NULL;
if ((nullfd = open("/dev/null", O_WRONLY|O_NOCTTY)) < 0)
return -1;
if (pipe(pdes) < 0) {
close(nullfd);
return -1;
}
switch ((p1 = vfork())) {
case -1:
/* parent: fork error */
close(nullfd);
close(pdes[0]);
close(pdes[1]);
return -1;
case 0:
/* child #1 */
p2 = vfork();
switch (p2) {
case -1:
/* child #1: fork error */
exit(errno);
case 0:
/* child #2: init will reap our status */
if (pdes[1] != STDOUT_FILENO) {
dup2(pdes[1], STDOUT_FILENO);
close(pdes[1]);
}
if (nullfd != STDERR_FILENO) {
dup2(nullfd, STDERR_FILENO);
close(nullfd);
}
for (i=0; i<FD_SETSIZE; i++)
if (i != STDOUT_FILENO && i != STDERR_FILENO)
close(i);
/* make the write descriptor non-blocking */
if (!set_nonblock(STDOUT_FILENO)) {
close(STDOUT_FILENO);
exit(-1);
}
execve(emap, argv, NULL);
exit(errno); /* in case execve failed */
}
/* child #1 */
exit(0);
}
/* parent */
close(nullfd);
close(pdes[1]);
/* anti-zombie insurance */
while (waitpid(p1, 0, 0) < 0)
if (errno != EINTR)
exit(errno);
/* make the read descriptor non-blocking */
if (!set_nonblock(pdes[0])) {
close(pdes[0]);
return -1;
}
return pdes[0];
}
/*
* Check for various permissions on executable map without trying to
* fork a new executable-map process.
*
* return: >0 (errno) if failed
* 0 if ok
*/
static int
exec_check_perm(char *map)
{
struct stat sb;
/* sanity and permission checks */
if (!map) {
dlog("exec_check_permission got a NULL map");
return EINVAL;
}
if (stat(map, &sb)) {
plog(XLOG_ERROR, "map \"%s\" stat failure: %m", map);
return errno;
}
if (!S_ISREG(sb.st_mode)) {
plog(XLOG_ERROR, "map \"%s\" should be regular file", map);
return EINVAL;
}
if (sb.st_uid != 0) {
plog(XLOG_ERROR, "map \"%s\" owned by uid %u (must be 0)", map, (u_int) sb.st_uid);
return EACCES;
}
if (!(sb.st_mode & S_IXUSR)) {
plog(XLOG_ERROR, "map \"%s\" should be executable", map);
return EACCES;
}
if (sb.st_mode & (S_ISUID|S_ISGID)) {
plog(XLOG_ERROR, "map \"%s\" should not be setuid/setgid", map);
return EACCES;
}
if (sb.st_mode & S_IWOTH) {
plog(XLOG_ERROR, "map \"%s\" should not be world writeable", map);
return EACCES;
}
return 0; /* all is well */
}
int
exec_init(mnt_map *m, char *map, time_t *tp)
{
/*
* Basically just test that the executable map can be found
* and has proper permissions.
*/
return exec_check_perm(map);
}
int
exec_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
{
int mapfd, ret;
if ((ret = exec_check_perm(map)) != 0) {
return ret;
}
if (!key)
return 0;
if (logfp)
fflush(logfp);
dlog("exec_search \"%s\", key: \"%s\"", map, key);
mapfd = exec_map_open(map, key);
if (mapfd >= 0) {
if (tp)
*tp = clocktime(NULL);
return exec_parse_qanswer(m, mapfd, map, key, pval, tp);
}
return errno;
}

View File

@ -1,254 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/info_file.c
*
*/
/*
* Get info from file
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
#include <sun_map.h>
/* forward declarations */
int file_init_or_mtime(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_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((unsigned char)ch) && isspace((unsigned char)ch)) ;
(void) ungetc(ch, fp);
} else {
return done;
}
}
} while (size > 0 && !feof(fp) && !ferror(fp));
return done;
}
/*
* Try to locate a key in a file
*/
static int
file_search_or_reload(mnt_map *m,
FILE *fp,
char *map,
char *key,
char **val,
void (*fn) (mnt_map *m, char *, char *))
{
char key_val[INFO_MAX_LINE_LEN];
int chuck = 0;
int line_no = 0;
while (file_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((unsigned char)*kp) && isspace((unsigned char)*kp); kp++) ;
/*
* Ignore blank lines
*/
if (!*kp)
goto again;
/*
* Find end of key
*/
for (cp = kp; *cp && (!isascii((unsigned char)*cp) || !isspace((unsigned char)*cp)); cp++) ;
/*
* Check whether key matches
*/
if (*cp)
*cp++ = '\0';
if (fn || (*key == *kp && STREQ(key, kp))) {
while (*cp && isascii((unsigned char)*cp) && isspace((unsigned char)*cp))
cp++;
if (*cp) {
/*
* Return a copy of the data
*/
char *dc;
/* if m->cfm == NULL, not using amd.conf file */
if (m->cfm && (m->cfm->cfm_flags & CFM_SUN_MAP_SYNTAX))
dc = sun_entry2amd(kp, cp);
else
dc = xstrdup(cp);
if (fn) {
(*fn) (m, xstrdup(kp), dc);
} else {
*val = dc;
dlog("%s returns %s", key, dc);
}
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(NULL);
else
*tp = stb.st_mtime;
}
return mapf;
}
int
file_init_or_mtime(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 *) NULL);
if (mapf) {
int error = file_search_or_reload(m, mapf, map, NULL, NULL, 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 = file_search_or_reload(m, mapf, map, key, pval, NULL);
}
(void) fclose(mapf);
return error;
}
return errno;
}

View File

@ -1,191 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/info_hesiod.c
*
*/
/*
* Get info from Hesiod
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
#include <sun_map.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);
extern int hesiod_init(void **context);
static voidp hesiod_context;
#endif /* HAVE_HESIOD_INIT */
/* forward declarations */
int amu_hesiod_init(mnt_map *m, char *map, time_t *tp);
int hesiod_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
int hesiod_isup(mnt_map *m, char *map);
/*
* 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)
{
dlog("amu_hesiod_init(%s)", map);
*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 */
dlog("hesiod_search(m=%lx, map=%s, key=%s, pval=%lx tp=%lx)",
(unsigned long) m, map, key, (unsigned long) pval, (unsigned long) tp);
if (key[0] == '.')
return ENOENT;
xsnprintf(hes_key, sizeof(hes_key), "%s.%s", key, map + HES_PREFLEN);
/*
* Call the resolver
*/
dlog("Hesiod base is: %s\n", gopt.hesiod_base);
dlog("hesiod_search: hes_resolve(%s, %s)", hes_key, gopt.hesiod_base);
if (amuDebug(D_INFO))
_res.options |= RES_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) {
if (m->cfm && (m->cfm->cfm_flags & CFM_SUN_MAP_SYNTAX)) {
*pval = sun_entry2amd(key, *rvec);
XFREE(*rvec);
} else
*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
*/
dlog("hesiod_search: Error: %d", hes_error());
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;
}
dlog("hesiod_search: Returning: %d", error);
return error;
#endif /* not HAVE_HESIOD_INIT */
}
/*
* Check if Hesiod is up, so we can determine if to clear the map or not.
* Test it by querying for /defaults.
* Returns: 0 if Hesiod is down, 1 if it is up.
*/
int
hesiod_isup(mnt_map *m, char *map)
{
int error;
char *val;
time_t mtime;
static int last_status = 1; /* assume up by default */
error = hesiod_search(m, map, "/defaults", &val, &mtime);
dlog("hesiod_isup(%s): %s", map, strerror(error));
if (error != 0 && error != ENOENT) {
plog(XLOG_ERROR,
"hesiod_isup: error getting `/defaults' entry in map %s: %m", map);
last_status = 0;
return 0; /* Hesiod is down */
}
if (last_status == 0) { /* if was down before */
plog(XLOG_INFO, "hesiod_isup: Hesiod came back up for map %s", map);
last_status = 1;
}
return 1; /* Hesiod is up */
}

View File

@ -1,592 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/info_ldap.c
*
*/
/*
* Get info from LDAP (Lightweight Directory Access Protocol)
* LDAP Home Page: http://www.umich.edu/~rsug/ldap/
*/
/*
* WARNING: as of Linux Fedora Core 5 (which comes with openldap-2.3.9), the
* ldap.h headers deprecate several functions used in this file, such as
* ldap_unbind. You get compile errors about missing extern definitions.
* Those externs are still in <ldap.h>, but surrounded by an ifdef
* LDAP_DEPRECATED. I am turning on that ifdef here, under the assumption
* that the functions may be deprecated, but they still work for this
* (older?) version of the LDAP API. It gets am-utils to compile, but it is
* not clear if it will work perfectly.
*/
#ifndef LDAP_DEPRECATED
# define LDAP_DEPRECATED 1
#endif /* not LDAP_DEPRECATED */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
#include <sun_map.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_ENT;
/*
* STRUCTURES:
*/
struct ald_ent {
LDAP *ldap;
HE_ENT *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;
};
static ALD *ldap_connection;
/*
* FORWARD DECLARATIONS:
*/
static int amu_ldap_rebind(ALD *a);
static int get_ldap_timestamp(ALD *a, char *map, time_t *ts);
int amu_ldap_init(mnt_map *m, char *map, time_t *tsu);
int amu_ldap_search(mnt_map *m, char *map, char *key, char **pval, time_t *ts);
int amu_ldap_mtime(mnt_map *m, char *map, time_t *ts);
/*
* FUNCTIONS:
*/
static void
he_free(HE_ENT *h)
{
XFREE(h->host);
if (h->next != NULL)
he_free(h->next);
XFREE(h);
}
static HE_ENT *
string2he(char *s_orig)
{
char *c, *p;
char *s;
HE_ENT *first = NULL, *cur = NULL;
if (NULL == s_orig)
return NULL;
s = xstrdup(s_orig);
for (p = strtok(s, ","); p; p = strtok(NULL, ",")) {
if (cur != NULL) {
cur->next = ALLOC(HE_ENT);
cur = cur->next;
} else
first = cur = ALLOC(HE_ENT);
cur->next = NULL;
c = strchr(p, ':');
if (c) { /* Host and port */
*c++ = '\0';
cur->host = xstrdup(p);
cur->port = atoi(c);
} else {
cur->host = xstrdup(p);
cur->port = LDAP_PORT;
}
plog(XLOG_USER, "Adding ldap server %s:%d",
cur->host, cur->port);
}
XFREE(s);
return first;
}
static void
cr_free(CR *c)
{
XFREE(c->who);
XFREE(c->pw);
XFREE(c);
}
/*
* Special ldap_unbind function to handle SIGPIPE.
* We first ignore SIGPIPE, in case a remote LDAP server was
* restarted, then we reinstall the handler.
*/
static int
amu_ldap_unbind(LDAP *ld)
{
int e;
#ifdef HAVE_SIGACTION
struct sigaction sa;
#else /* not HAVE_SIGACTION */
void (*handler)(int);
#endif /* not HAVE_SIGACTION */
dlog("amu_ldap_unbind()\n");
#ifdef HAVE_SIGACTION
sa.sa_handler = SIG_IGN;
sa.sa_flags = 0;
sigemptyset(&(sa.sa_mask));
sigaddset(&(sa.sa_mask), SIGPIPE);
sigaction(SIGPIPE, &sa, &sa); /* set IGNORE, and get old action */
#else /* not HAVE_SIGACTION */
handler = signal(SIGPIPE, SIG_IGN);
#endif /* not HAVE_SIGACTION */
e = ldap_unbind(ld);
#ifdef HAVE_SIGACTION
sigemptyset(&(sa.sa_mask));
sigaddset(&(sa.sa_mask), SIGPIPE);
sigaction(SIGPIPE, &sa, NULL);
#else /* not HAVE_SIGACTION */
(void) signal(SIGPIPE, handler);
#endif /* not HAVE_SIGACTION */
return e;
}
static void
ald_free(ALD *a)
{
he_free(a->hostent);
cr_free(a->credentials);
if (a->ldap != NULL)
amu_ldap_unbind(a->ldap);
XFREE(a);
}
int
amu_ldap_init(mnt_map *m, char *map, time_t *ts)
{
ALD *aldh;
CR *creds;
dlog("-> amu_ldap_init: map <%s>\n", map);
/*
* XXX: by checking that map_type must be defined, aren't we
* excluding the possibility of automatic searches through all
* map types?
*/
if (!gopt.map_type || !STREQ(gopt.map_type, AMD_LDAP_TYPE)) {
dlog("amu_ldap_init called with map_type <%s>\n",
(gopt.map_type ? gopt.map_type : "null"));
return ENOENT;
} else {
dlog("Map %s is ldap\n", map);
}
#ifndef LDAP_CONNECTION_PER_MAP
if (ldap_connection != NULL) {
m->map_data = (void *) ldap_connection;
return 0;
}
#endif
aldh = ALLOC(ALD);
creds = ALLOC(CR);
aldh->ldap = NULL;
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 ? gopt.ldap_hostports : "(null)", map);
XFREE(creds);
XFREE(aldh);
return (ENOENT);
}
creds->who = "";
creds->pw = "";
creds->method = LDAP_AUTH_SIMPLE;
aldh->credentials = creds;
aldh->timestamp = 0;
aldh->ldap = NULL;
dlog("Trying for %s:%d\n", aldh->hostent->host, aldh->hostent->port);
if (amu_ldap_rebind(aldh)) {
ald_free(aldh);
return (ENOENT);
}
dlog("Bound to %s:%d\n", aldh->hostent->host, aldh->hostent->port);
if (get_ldap_timestamp(aldh, map, ts)) {
ald_free(aldh);
return (ENOENT);
}
dlog("Got timestamp for map %s: %ld\n", map, (u_long) *ts);
ldap_connection = aldh;
m->map_data = (void *) ldap_connection;
return (0);
}
static int
amu_ldap_rebind(ALD *a)
{
LDAP *ld;
HE_ENT *h;
CR *c = a->credentials;
time_t now = clocktime(NULL);
int try;
dlog("-> amu_ldap_rebind\n");
if (a->ldap != NULL) {
if ((a->timestamp - now) > AMD_LDAP_TTL) {
dlog("Re-establishing ldap connection\n");
amu_ldap_unbind(a->ldap);
a->timestamp = now;
a->ldap = NULL;
} else {
/* Assume all is OK. If it wasn't we'll be back! */
dlog("amu_ldap_rebind: timestamp OK\n");
return (0);
}
}
for (try=0; try<10; try++) { /* XXX: try up to 10 times (makes sense?) */
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);
continue;
}
#if LDAP_VERSION_MAX > LDAP_VERSION2
/* handle LDAPv3 and heigher, if available and amd.conf-igured */
if (gopt.ldap_proto_version > LDAP_VERSION2) {
if (!ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &gopt.ldap_proto_version)) {
dlog("amu_ldap_rebind: LDAP protocol version set to %ld\n",
gopt.ldap_proto_version);
} else {
plog(XLOG_WARNING, "Unable to set ldap protocol version to %ld for "
"%s:%d\n", gopt.ldap_proto_version, h->host, h->port);
continue;
}
}
#endif /* LDAP_VERSION_MAX > LDAP_VERSION2 */
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);
continue;
}
if (gopt.ldap_cache_seconds > 0) {
#if defined(HAVE_LDAP_ENABLE_CACHE) && defined(HAVE_EXTERN_LDAP_ENABLE_CACHE)
ldap_enable_cache(ld, gopt.ldap_cache_seconds, gopt.ldap_cache_maxmem);
#else /* not defined(HAVE_LDAP_ENABLE_CACHE) && defined(HAVE_EXTERN_LDAP_ENABLE_CACHE) */
plog(XLOG_WARNING, "ldap_enable_cache(%ld) is not available on this system!\n", gopt.ldap_cache_seconds);
#endif /* not defined(HAVE_LDAP_ENABLE_CACHE) && defined(HAVE_EXTERN_LDAP_ENABLE_CACHE) */
}
a->ldap = ld;
a->timestamp = now;
return (0);
}
plog(XLOG_WARNING, "Exhausted 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(ALD *a, char *map, time_t *ts)
{
struct timeval tv;
char **vals, *end;
char filter[MAXPATHLEN];
int i, err = 0, nentries = 0;
LDAPMessage *res = NULL, *entry;
dlog("-> get_ldap_timestamp: map <%s>\n", map);
tv.tv_sec = 3;
tv.tv_usec = 0;
xsnprintf(filter, sizeof(filter), AMD_LDAP_TSFILTER, map);
dlog("Getting timestamp for map %s\n", map);
dlog("Filter is: %s\n", filter);
dlog("Base is: %s\n", gopt.ldap_base);
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;
if (res) {
ldap_msgfree(res);
res = NULL;
}
plog(XLOG_USER, "Timestamp LDAP search attempt %d failed: %s\n",
i + 1, ldap_err2string(err));
if (err != LDAP_TIMEOUT) {
dlog("get_ldap_timestamp: unbinding...\n");
amu_ldap_unbind(a->ldap);
a->ldap = NULL;
if (amu_ldap_rebind(a))
return (ENOENT);
}
dlog("Timestamp search failed, trying again...\n");
}
if (err != LDAP_SUCCESS) {
*ts = 0;
plog(XLOG_USER, "LDAP timestamp search failed: %s\n",
ldap_err2string(err));
if (res)
ldap_msgfree(res);
return (ENOENT);
}
nentries = ldap_count_entries(a->ldap, 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(a->ldap, res);
vals = ldap_get_values(a->ldap, 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);
return (ENOENT);
}
dlog("TS value is:%s:\n", vals[0]);
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 %ld for map %s\n",
(u_long) *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);
dlog("The timestamp for %s is %ld (err=%d)\n", map, (u_long) *ts, err);
return (err);
}
int
amu_ldap_search(mnt_map *m, char *map, char *key, char **pval, time_t *ts)
{
char **vals, filter[MAXPATHLEN], filter2[2 * MAXPATHLEN];
char *f1, *f2;
struct timeval tv;
int i, err = 0, nvals = 0, nentries = 0;
LDAPMessage *entry, *res = NULL;
ALD *a = (ALD *) (m->map_data);
dlog("-> amu_ldap_search: map <%s>, key <%s>\n", map, key);
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);
xsnprintf(filter, sizeof(filter), AMD_LDAP_FILTER, map, key);
/* "*" is special to ldap_search(); run through the filter escaping it. */
f1 = filter; f2 = filter2;
while (*f1) {
if (*f1 == '*') {
*f2++ = '\\'; *f2++ = '2'; *f2++ = 'a';
f1++;
} else {
*f2++ = *f1++;
}
}
*f2 = '\0';
dlog("Search with filter: <%s>\n", filter2);
for (i = 0; i < AMD_LDAP_RETRIES; i++) {
err = ldap_search_st(a->ldap,
gopt.ldap_base,
LDAP_SCOPE_SUBTREE,
filter2,
0,
0,
&tv,
&res);
if (err == LDAP_SUCCESS)
break;
if (res) {
ldap_msgfree(res);
res = NULL;
}
plog(XLOG_USER, "LDAP search attempt %d failed: %s\n",
i + 1, ldap_err2string(err));
if (err != LDAP_TIMEOUT) {
dlog("amu_ldap_search: unbinding...\n");
amu_ldap_unbind(a->ldap);
a->ldap = NULL;
if (amu_ldap_rebind(a))
return (ENOENT);
}
}
switch (err) {
case LDAP_SUCCESS:
break;
case LDAP_NO_SUCH_OBJECT:
dlog("No object\n");
if (res)
ldap_msgfree(res);
return (ENOENT);
default:
plog(XLOG_USER, "LDAP search failed: %s\n",
ldap_err2string(err));
if (res)
ldap_msgfree(res);
return (EIO);
}
nentries = ldap_count_entries(a->ldap, res);
dlog("Search found %d entries\n", nentries);
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);
return (EIO);
}
dlog("Map %s, %s => %s\n", map, key, vals[0]);
if (vals[0]) {
if (m->cfm && (m->cfm->cfm_flags & CFM_SUN_MAP_SYNTAX))
*pval = sun_entry2amd(key, vals[0]);
else
*pval = xstrdup(vals[0]);
err = 0;
} else {
plog(XLOG_USER, "Empty value for %s in map %s\n", key, map);
err = ENOENT;
}
ldap_msgfree(res);
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, map, ts)) {
return (ENOENT);
}
return (0);
}

View File

@ -1,140 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/info_ndbm.c
*
*/
/*
* Get info from NDBM map
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
#include <sun_map.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(mnt_map *m, 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) {
if (m->cfm && (m->cfm->cfm_flags & CFM_SUN_MAP_SYNTAX))
*val = sun_entry2amd(key, v.dptr);
else
*val = xstrdup(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];
xstrlcpy(dbfilename, map, sizeof(dbfilename));
xstrlcat(dbfilename, DBM_SUFFIX, sizeof(dbfilename));
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(m, 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];
xstrlcpy(dbfilename, map, sizeof(dbfilename));
xstrlcat(dbfilename, DBM_SUFFIX, sizeof(dbfilename));
error = stat(dbfilename, &stb);
#else /* not DBM_SUFFIX */
error = fstat(dbm_pagfno(db), &stb);
#endif /* not DBM_SUFFIX */
if (error < 0)
*tp = clocktime(NULL);
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);
}

View File

@ -1,447 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/info_nis.c
*
*/
/*
* Get info from NIS map
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
#include <sun_map.h>
/*
* NIS+ servers in NIS compat mode don't have yp_order()
*
* has_yp_order = 1 NIS server
* = 0 NIS+ server
* = -1 server is down
*/
static int has_yp_order = -1;
/* 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_isup(mnt_map *m, char *map);
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 = xstrdup(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);
plog(XLOG_ERROR, "yp enumeration of %s: %s, status=%d, e=%d",
ncdp->ncd_map, yperr_string(e), status, e);
}
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;
plog(XLOG_INFO, "NIS map %s reloading using yp_all", map);
/*
* 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;
char *master;
static int last_status = 1; /* assume up by default */
switch (has_yp_order) {
case 1:
/*
* NIS server with yp_order
*/
error = yp_order(gopt.nis_domain, map, &order);
if (error != 0) {
plog(XLOG_ERROR,
"nis_isup: error getting the order of map %s: %s",
map, yperr_string(ypprot_err(error)));
last_status = 0;
return 0; /* NIS is down */
}
break;
case 0:
/*
* NIS+ server without yp_order
*/
error = yp_master(gopt.nis_domain, map, &master);
if (error != 0) {
plog(XLOG_ERROR,
"nis_isup: error getting the master of map %s: %s",
map, yperr_string(ypprot_err(error)));
last_status = 0;
return 0; /* NIS+ is down */
}
break;
default:
/*
* server was down
*/
last_status = 0;
}
if (last_status == 0) { /* reinitialize if was down before */
time_t dummy;
error = nis_init(m, map, &dummy);
if (error)
return 0; /* still down */
plog(XLOG_INFO, "nis_isup: NIS came back up for map %s", map);
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 **pval, time_t *tp)
{
int outlen;
int res;
YP_ORDER_OUTORDER_TYPE order;
/*
* Make sure domain initialized
*/
if (!gopt.nis_domain) {
int error = determine_nis_domain();
if (error)
return error;
}
switch (has_yp_order) {
case 1:
/*
* NIS server with 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;
}
break;
case 0:
/*
* 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);
}
break;
default:
/*
* server was down
*/
if (nis_isup(m, map))
return -1;
return EIO;
}
/*
* Lookup key
*/
res = yp_match(gopt.nis_domain, map, key, strlen(key), pval, &outlen);
if (m->cfm && (m->cfm->cfm_flags & CFM_SUN_MAP_SYNTAX) && res == 0) {
char *oldval = *pval;
*pval = sun_entry2amd(key, oldval);
/* We always need to free the output of the yp_match call. */
XFREE(oldval);
if (*pval == NULL)
return -1; /* sun2amd parser error */
}
/*
* Do something interesting with the return code
*/
switch (res) {
case 0:
return 0;
case YPERR_KEY:
return ENOENT;
default:
plog(XLOG_ERROR, "nis_search: %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:
/* NIS server found */
has_yp_order = 1;
*tp = (time_t) order;
dlog("NIS master for %s@%s has order %lu", map, gopt.nis_domain, (unsigned long) order);
break;
case YPERR_YPERR:
/* NIS+ server found ! */
has_yp_order = 0;
/* try yp_master() instead */
if (yp_master(gopt.nis_domain, map, &master)) {
return ENOENT;
} else {
dlog("NIS master for %s@%s is a NIS+ server", map, gopt.nis_domain);
/* Use fake timestamps */
*tp = time(NULL);
}
break;
default:
/* server is down */
has_yp_order = -1;
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 eventually 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;
/*
* We have to manually free all char ** arguments to yp_first/yp_next
* outval must be freed *before* calling yp_next again, outkey can be
* freed as outkey_old *after* the call (this saves one call to
* strnsave).
*/
XFREE(outval);
outkey_old = outkey;
outkeylen_old = outkeylen;
i = yp_next(indomain,
inmap,
outkey_old,
outkeylen_old,
&outkey,
&outkeylen,
&outval,
&outvallen);
XFREE(outkey_old);
} while (!i);
if (i) {
dlog("yp_next() returned error: %s\n", yperr_string(i));
}
if (i == YPERR_NOMORE)
return 0;
return i;
}
#endif /* HAVE_BAD_YP_ALL */

View File

@ -1,309 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/info_nisplus.c
*
*/
/*
* 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>
#include <sun_map.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;
dlog("NISplus callback for <%s,%s>", kp, vp);
(*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;
size_t l;
org = strstr(map, NISPLUS_ORGDIR);
if (org == NULL)
org = NISPLUS_ORGDIR;
else
org = "";
/* make some room for the NIS map_name */
l = strlen(map) + sizeof(NISPLUS_ORGDIR);
map_name = xmalloc(l);
if (map_name == NULL) {
plog(XLOG_ERROR, "Unable to create map_name %s: %s",
map, strerror(ENOMEM));
return ENOMEM;
}
xsnprintf(map_name, l, "%s%s", map, org);
data.ncd_m = m;
data.ncd_map = map_name;
data.ncd_fn = fn;
dlog("NISplus reload for %s", map);
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;
dlog("NISplus search callback for <%s>", ENTRY_VAL(value, 0));
dlog("NISplus search callback value <%s>", ENTRY_VAL(value, 1));
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 */
size_t l;
org = strstr(map, NISPLUS_ORGDIR);
if (org == NULL)
org = NISPLUS_ORGDIR;
else
org = "";
/* make some room for the NIS index */
l = sizeof('[') /* for opening selection criteria */
+ sizeof(NISPLUS_KEY)
+ strlen(key)
+ sizeof(']') /* for closing selection criteria */
+ sizeof(',') /* + 1 for , separator */
+ strlen(map)
+ sizeof(NISPLUS_ORGDIR);
index = xmalloc(l);
if (index == NULL) {
plog(XLOG_ERROR,
"Unable to create index %s: %s",
map,
strerror(ENOMEM));
return ENOMEM;
}
xsnprintf(index, l, "[%s%s],%s%s", NISPLUS_KEY, key, map, org);
data.key = key;
data.value = NULL;
dlog("NISplus search for %s", index);
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, "nisplus_search: %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;
dlog("NISplus search found <nothing>");
dlog("NISplus search for %s: %s(%d)",
map, nis_sperrno(result->status), result->status);
if (value != NULL)
data.value = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1));
}
if (m->cfm && (m->cfm->cfm_flags & CFM_SUN_MAP_SYNTAX)) {
*val = sun_entry2amd(key, data.value);
XFREE(data.value); /* strnsave malloc'ed it above */
} else
*val = data.value;
if (*val) {
error = 0;
dlog("NISplus search found %s", *val);
} else {
error = ENOENT;
dlog("NISplus search found nothing");
}
*tp = 0;
break;
case NIS_NOSUCHNAME:
dlog("NISplus search returned %d", result->status);
error = ENOENT;
break;
default:
plog(XLOG_ERROR, "nisplus_search: %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;
size_t l;
org = strstr(map, NISPLUS_ORGDIR);
if (org == NULL)
org = NISPLUS_ORGDIR;
else
org = "";
/* make some room for the NIS map_name */
l = strlen(map) + sizeof(NISPLUS_ORGDIR);
map_name = xmalloc(l);
if (map_name == NULL) {
plog(XLOG_ERROR,
"Unable to create map_name %s: %s",
map,
strerror(ENOMEM));
return ENOMEM;
}
xsnprintf(map_name, l, "%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) {
dlog("NISplus init <%s>: %s (%d)",
map, nis_sperrno(result->status), result->status);
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);
}

View File

@ -1,187 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/info_passwd.c
*
*/
/*
* 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 = NULL;
struct passwd *pw;
if (STREQ(key, "/defaults")) {
*pval = xstrdup("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 = xstrdup(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) {
xstrlcat(rhost, q + 1, sizeof(rhost));
xstrlcat(rhost, ".", sizeof(rhost));
*q = '\0';
} else {
xstrlcat(rhost, p, sizeof(rhost));
}
} 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}";
xsnprintf(val, sizeof(val), "var0:=%s;var1:=%s;var2:=%s;var3:=%s;%s",
dir+1, rhost, user, pw->pw_dir, p);
dlog("passwd_search: map=%s key=%s -> %s", map, key, val);
if (q)
*q = '.';
*pval = xstrdup(val);
return 0;
}
enoent:
XFREE(dir);
return ENOENT;
}

View File

@ -1,53 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/info_sun.c
*
*/
/*
* Get info from Sun automount-style /etc/auto_master, possibly following
* into multiple info services (via /etc/nsswitch.conf).
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
#include <sun_map.h>
/* XXX: just a placeholder. fill in */

View File

@ -1,144 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/info_union.c
*
*/
/*
* 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 = xstrdup(map + UNION_PREFLEN);
char **v = strsplit(mapd, ':', '\"');
char **p;
size_t l;
for (p = v; p[1]; p++) ;
l = strlen(*p) + 5;
*pval = xmalloc(l);
xsnprintf(*pval, l, "fs:=%s", *p);
XFREE(mapd);
XFREE(v);
return 0;
}
int
union_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *))
{
static const char fseq[] = "fs:=";
char *mapd = xstrdup(map + UNION_PREFLEN);
char **v = strsplit(mapd, ':', '\"');
char **dir;
/*
* Add fake /defaults entry
*/
(*fn) (m, xstrdup("/defaults"), xstrdup("type:=link;opts:=nounmount;sublink:=${key}"));
for (dir = v; *dir; dir++) {
size_t l;
struct dirent *dp;
DIR *dirp = opendir(*dir);
if (!dirp) {
plog(XLOG_USER, "Cannot read directory %s: %m", *dir);
continue;
}
l = strlen(*dir) + sizeof(fseq);
dlog("Reading directory %s...", *dir);
while ((dp = readdir(dirp))) {
char *val, *dpname = &dp->d_name[0];
if (dpname[0] == '.' &&
(dpname[1] == '\0' ||
(dpname[1] == '.' && dpname[2] == '\0')))
continue;
dlog("... gives %s", dp->d_name);
val = xmalloc(l);
xsnprintf(val, l, "%s%s", fseq, *dir);
(*fn) (m, xstrdup(dp->d_name), val);
}
closedir(dirp);
}
/*
* Add wildcard entry
*/
{
size_t l = strlen(*(dir-1)) + sizeof(fseq);
char *val = xmalloc(l);
xsnprintf(val, l, "%s%s", fseq, *(dir-1));
(*fn) (m, xstrdup("*"), val);
}
XFREE(mapd);
XFREE(v);
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,410 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/mntfs.c
*
*/
#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;
am_loc *
dup_loc(am_loc *loc)
{
loc->al_refc++;
if (loc->al_mnt) {
dup_mntfs(loc->al_mnt);
}
return loc;
}
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_fsflags = ops->nfs_fs_flags;
mf->mf_fo = 0;
if (mo)
mf->mf_fo = copy_opts(mo);
mf->mf_mount = xstrdup(mp);
mf->mf_info = xstrdup(info);
mf->mf_auto = xstrdup(auto_opts);
mf->mf_mopts = xstrdup(mopts);
mf->mf_remopts = xstrdup(remopts);
mf->mf_loopdev = NULL;
mf->mf_refc = 1;
mf->mf_flags = 0;
mf->mf_error = -1;
mf->mf_cid = 0;
mf->mf_private = NULL;
mf->mf_prfree = NULL;
if (ops->ffserver)
mf->mf_server = (*ops->ffserver) (mf);
else
mf->mf_server = NULL;
}
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;
}
/* find a matching mntfs in our list */
mntfs *
locate_mntfs(am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)
{
mntfs *mf;
dlog("Locating mntfs reference to (%s,%s)", mp, info);
ITER(mf, mntfs, &mfhead) {
/*
* For backwards compatibility purposes, we treat already-mounted
* filesystems differently and only require a match of their mount point,
* not of their server info. After all, there is little we can do if
* the user asks us to mount two different things onto the same mount: one
* will always cover the other one.
*/
if (STREQ(mf->mf_mount, mp) &&
((mf->mf_flags & MFF_MOUNTED && !(mf->mf_fsflags & FS_DIRECT))
|| (STREQ(mf->mf_info, info) && mf->mf_ops == ops))) {
/*
* 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;
return dup_mntfs(mf);
}
dlog("mf->mf_flags = %#x", mf->mf_flags);
if ((mf->mf_flags & MFF_RESTART) && amd_state < Finishing) {
/*
* Restart a previously mounted filesystem.
*/
dlog("Restarting filesystem %s", mf->mf_mount);
/*
* If we are restarting an amd internal filesystem,
* we need to initialize it a bit.
*
* We know it's internal because it is marked as toplvl.
*/
if (mf->mf_ops == &amfs_toplvl_ops) {
mf->mf_ops = ops;
mf->mf_info = strealloc(mf->mf_info, info);
ops->mounted(mf); /* XXX: not right, but will do for now */
}
return mf;
}
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 = NULL;
}
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);
} /* end of "if (STREQ(mf-> ..." */
} /* end of ITER */
return 0;
}
/* find a matching mntfs in our list, create a new one if none is found */
mntfs *
find_mntfs(am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)
{
mntfs *mf = locate_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts);
if (mf)
return mf;
return alloc_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts);
}
mntfs *
new_mntfs(void)
{
return alloc_mntfs(&amfs_error_ops, (am_opts *) NULL, "//nil//", ".", "", "", "");
}
am_loc *
new_loc(void)
{
am_loc *loc = CALLOC(struct am_loc);
loc->al_fo = 0;
loc->al_mnt = new_mntfs();
loc->al_refc = 1;
return loc;
}
static void
uninit_mntfs(mntfs *mf)
{
if (mf->mf_fo) {
free_opts(mf->mf_fo);
XFREE(mf->mf_fo);
}
XFREE(mf->mf_auto);
XFREE(mf->mf_mopts);
XFREE(mf->mf_remopts);
XFREE(mf->mf_info);
if (mf->mf_private && mf->mf_prfree)
(*mf->mf_prfree) (mf->mf_private);
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);
XFREE(mf);
--mntfs_allocated;
}
static void
discard_loc(voidp v)
{
am_loc *loc = v;
if (loc->al_fo) {
free_opts(loc->al_fo);
XFREE(loc->al_fo);
}
XFREE(loc);
}
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_loc(opaque_t arg)
{
am_loc *loc = (am_loc *) arg;
dlog("free_loc %p", loc);
if (loc->al_refc <= 0) {
plog(XLOG_ERROR, "IGNORING free_loc for 0x%p", loc);
return;
}
if (loc->al_mnt)
free_mntfs(loc->al_mnt);
if (--loc->al_refc == 0) {
discard_loc(loc);
}
}
void
free_mntfs(opaque_t arg)
{
mntfs *mf = (mntfs *) arg;
dlog("free_mntfs <%s> type %s mf_refc %d flags %x",
mf->mf_mount, mf->mf_ops->fs_type, mf->mf_refc, mf->mf_flags);
/*
* We shouldn't ever be called to free something that has
* a non-positive refcount. Something is badly wrong if
* we have been! Ignore the request for now...
*/
if (mf->mf_refc <= 0) {
plog(XLOG_ERROR, "IGNORING free_mntfs for <%s>: refc %d, flags %x (bug?)",
mf->mf_mount, mf->mf_refc, mf->mf_flags);
return;
}
/* don't discard last reference of a restarted/kept mntfs */
if (mf->mf_refc == 1 && mf->mf_flags & MFF_RSTKEEP) {
plog(XLOG_ERROR, "IGNORING free_mntfs for <%s>: refc %d, flags %x (restarted)",
mf->mf_mount, mf->mf_refc, mf->mf_flags);
return;
}
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_fsflags & FS_DISCARD) {
dlog("Immediately discarding mntfs for %s", mf->mf_mount);
discard_mntfs(mf);
} else {
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);
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_flags & MFF_RESTART &&
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)) {
return mf;
}
mf2 = find_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts);
free_mntfs(mf);
return mf2;
}

View File

@ -1,488 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/nfs_prot_svc.c
*
*/
#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 *current_transp;
dispatcher_t nfs_dispatcher = nfs_program_2;
/* 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;
#ifdef HAVE_TRANSPORT_TYPE_TLI
/*
* On TLI systems we don't use an INET network type, but a "ticlts" (see
* /etc/netconfig and conf/transp_tli.c:create_nfs_service). This means
* that packets could only come from the loopback interface, and we don't
* need to check them and filter possibly spoofed packets. Therefore we
* only need to check if the UID caller is correct.
*/
# ifdef HAVE___RPC_GET_LOCAL_UID
uid_t u;
/* extern definition for an internal libnsl function */
extern int __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid);
if (__rpc_get_local_uid(transp, &u) >= 0 && u != 0) {
plog(XLOG_WARNING, "ignoring request from UID %ld, must be 0", (long) u);
return;
}
# else /* not HAVE___RPC_GET_LOCAL_UID */
dlog("cannot verify local uid for rpc request");
# endif /* HAVE___RPC_GET_LOCAL_UID */
#else /* not HAVE_TRANPORT_TYPE_TLI */
struct sockaddr_in *sinp;
char dq[20], dq2[28];
sinp = amu_svc_getcaller(rqstp->rq_xprt);
# ifdef MNT2_NFS_OPT_RESVPORT
/* Verify that the request comes from a reserved port */
if (sinp &&
ntohs(sinp->sin_port) >= IPPORT_RESERVED &&
!(gopt.flags & CFM_NFS_INSECURE_PORT)) {
plog(XLOG_WARNING, "ignoring request from %s:%u, port not reserved",
inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
ntohs(sinp->sin_port));
return;
}
# endif /* MNT2_NFS_OPT_RESVPORT */
/* if the address does not match, ignore the request */
if (sinp && (sinp->sin_addr.s_addr != myipaddr.s_addr)) {
if (gopt.flags & CFM_NFS_ANY_INTERFACE) {
if (!is_interface_local(sinp->sin_addr.s_addr)) {
plog(XLOG_WARNING, "ignoring request from %s:%u, not a local interface",
inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
ntohs(sinp->sin_port));
}
} else {
plog(XLOG_WARNING, "ignoring request from %s:%u, expected %s",
inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
ntohs(sinp->sin_port),
inet_dquad(dq2, sizeof(dq2), myipaddr.s_addr));
return;
}
}
#endif /* not HAVE_TRANPORT_TYPE_TLI */
current_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().
*/
current_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",
(int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc);
svcerr_decode(transp);
return;
}
result = (*local) (&argument, rqstp);
current_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);
}
}
void
nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
{
union {
am_GETATTR3args am_nfs3_getattr_3_arg;
am_SETATTR3args am_nfs3_setattr_3_arg;
am_LOOKUP3args am_nfs3_lookup_3_arg;
am_ACCESS3args am_nfs3_access_3_arg;
am_READLINK3args am_nfs3_readlink_3_arg;
am_READ3args am_nfs3_read_3_arg;
am_WRITE3args am_nfs3_write_3_arg;
am_CREATE3args am_nfs3_create_3_arg;
am_MKDIR3args am_nfs3_mkdir_3_arg;
am_SYMLINK3args am_nfs3_symlink_3_arg;
am_MKNOD3args am_nfs3_mknod_3_arg;
am_REMOVE3args am_nfs3_remove_3_arg;
am_RMDIR3args am_nfs3_rmdir_3_arg;
am_RENAME3args am_nfs3_rename_3_arg;
am_LINK3args am_nfs3_link_3_arg;
am_READDIR3args am_nfs3_readdir_3_arg;
am_READDIRPLUS3args am_nfs3_readdirplus_3_arg;
am_FSSTAT3args am_nfs3_fsstat_3_arg;
am_FSINFO3args am_nfs3_fsinfo_3_arg;
am_PATHCONF3args am_nfs3_pathconf_3_arg;
am_COMMIT3args am_nfs3_commit_3_arg;
} argument;
char *result;
xdrproc_t _xdr_argument, _xdr_result;
nfssvcproc_t local;
switch (rqstp->rq_proc) {
case AM_NFS3_NULL:
_xdr_argument = (xdrproc_t) xdr_void;
_xdr_result = (xdrproc_t) xdr_void;
local = (nfssvcproc_t) am_nfs3_null_3_svc;
break;
case AM_NFS3_GETATTR:
_xdr_argument = (xdrproc_t) xdr_am_GETATTR3args;
_xdr_result = (xdrproc_t) xdr_am_GETATTR3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_getattr_3_svc;
break;
case AM_NFS3_SETATTR:
_xdr_argument = (xdrproc_t) xdr_am_SETATTR3args;
_xdr_result = (xdrproc_t) xdr_am_SETATTR3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_setattr_3_svc;
break;
case AM_NFS3_LOOKUP:
_xdr_argument = (xdrproc_t) xdr_am_LOOKUP3args;
_xdr_result = (xdrproc_t) xdr_am_LOOKUP3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_lookup_3_svc;
break;
case AM_NFS3_ACCESS:
_xdr_argument = (xdrproc_t) xdr_am_ACCESS3args;
_xdr_result = (xdrproc_t) xdr_am_ACCESS3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_access_3_svc;
break;
case AM_NFS3_READLINK:
_xdr_argument = (xdrproc_t) xdr_am_READLINK3args;
_xdr_result = (xdrproc_t) xdr_am_READLINK3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_readlink_3_svc;
break;
case AM_NFS3_READ:
_xdr_argument = (xdrproc_t) xdr_am_READ3args;
_xdr_result = (xdrproc_t) xdr_am_READ3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_read_3_svc;
break;
case AM_NFS3_WRITE:
_xdr_argument = (xdrproc_t) xdr_am_WRITE3args;
_xdr_result = (xdrproc_t) xdr_am_WRITE3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_write_3_svc;
break;
case AM_NFS3_CREATE:
_xdr_argument = (xdrproc_t) xdr_am_CREATE3args;
_xdr_result = (xdrproc_t) xdr_am_CREATE3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_create_3_svc;
break;
case AM_NFS3_MKDIR:
_xdr_argument = (xdrproc_t) xdr_am_MKDIR3args;
_xdr_result = (xdrproc_t) xdr_am_MKDIR3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_mkdir_3_svc;
break;
case AM_NFS3_SYMLINK:
_xdr_argument = (xdrproc_t) xdr_am_SYMLINK3args;
_xdr_result = (xdrproc_t) xdr_am_SYMLINK3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_symlink_3_svc;
break;
case AM_NFS3_MKNOD:
_xdr_argument = (xdrproc_t) xdr_am_MKNOD3args;
_xdr_result = (xdrproc_t) xdr_am_MKNOD3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_mknod_3_svc;
break;
case AM_NFS3_REMOVE:
_xdr_argument = (xdrproc_t) xdr_am_REMOVE3args;
_xdr_result = (xdrproc_t) xdr_am_REMOVE3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_remove_3_svc;
break;
case AM_NFS3_RMDIR:
_xdr_argument = (xdrproc_t) xdr_am_RMDIR3args;
_xdr_result = (xdrproc_t) xdr_am_RMDIR3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_rmdir_3_svc;
break;
case AM_NFS3_RENAME:
_xdr_argument = (xdrproc_t) xdr_am_RENAME3args;
_xdr_result = (xdrproc_t) xdr_am_RENAME3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_rename_3_svc;
break;
case AM_NFS3_LINK:
_xdr_argument = (xdrproc_t) xdr_am_LINK3args;
_xdr_result = (xdrproc_t) xdr_am_LINK3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_link_3_svc;
break;
case AM_NFS3_READDIR:
_xdr_argument = (xdrproc_t) xdr_am_READDIR3args;
_xdr_result = (xdrproc_t) xdr_am_READDIR3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_readdir_3_svc;
break;
case AM_NFS3_READDIRPLUS:
_xdr_argument = (xdrproc_t) xdr_am_READDIRPLUS3args;
_xdr_result = (xdrproc_t) xdr_am_READDIRPLUS3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_readdirplus_3_svc;
break;
case AM_NFS3_FSSTAT:
_xdr_argument = (xdrproc_t) xdr_am_FSSTAT3args;
_xdr_result = (xdrproc_t) xdr_am_FSSTAT3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_fsstat_3_svc;
break;
case AM_NFS3_FSINFO:
_xdr_argument = (xdrproc_t) xdr_am_FSINFO3args;
_xdr_result = (xdrproc_t) xdr_am_FSINFO3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_fsinfo_3_svc;
break;
case AM_NFS3_PATHCONF:
_xdr_argument = (xdrproc_t) xdr_am_PATHCONF3args;
_xdr_result = (xdrproc_t) xdr_am_PATHCONF3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_pathconf_3_svc;
break;
case AM_NFS3_COMMIT:
_xdr_argument = (xdrproc_t) xdr_am_COMMIT3args;
_xdr_result = (xdrproc_t) xdr_am_COMMIT3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_commit_3_svc;
break;
default:
svcerr_noproc (transp);
return;
}
memset ((char *)&argument, 0, sizeof (argument));
if (!svc_getargs(transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
plog(XLOG_ERROR,
"NFS xdr decode failed for %d %d %d",
(int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc);
svcerr_decode(transp);
return;
}
result = (*local) (&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_3");
going_down(1);
}
return;
}

View File

@ -1,457 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/nfs_start.c
*
*/
#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 = NULL;
u_short nfs_port = 0;
#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 = NULL;
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("%#lx bytes of memory allocated; total is %#lx (%ld pages)",
(long) (next_mem - max_mem), (unsigned long) next_mem,
((long) next_mem + getpagesize() - 1) / (long) getpagesize());
#else /* not HAVE_GETPAGESIZE */
dlog("%#lx bytes of memory allocated; total is %#lx",
(long) (next_mem - max_mem), (unsigned long) next_mem);
#endif /* not HAVE_GETPAGESIZE */
max_mem = next_mem;
}
}
#else /* not DEBUG */
#define checkup()
#endif /* not 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;
/*
* 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 *) NULL, (fd_set *) NULL,
tvp->tv_sec ? tvp : (struct timeval *) NULL);
}
#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(NULL)) {
mapc_reload();
do_mapc_reload = clocktime(NULL) + gopt.map_reload_interval;
}
return nsel;
}
/*
* Determine whether anything is left in
* the RPC input queue.
*/
static int
rpc_pending_now(void)
{
struct timeval tvv;
int nsel;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fwd_sock, &readfds);
tvv.tv_sec = tvv.tv_usec = 0;
nsel = select(FD_SETSIZE, &readfds, (fd_set *) NULL, (fd_set *) NULL, &tvv);
if (nsel < 1)
return (0);
if (FD_ISSET(fwd_sock, &readfds))
return (1);
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(NULL);
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;
fd_set readfds;
#ifdef HAVE_SVC_GETREQSET
memmove(&readfds, &svc_fdset, sizeof(svc_fdset));
#else /* not HAVE_SVC_GETREQSET */
FD_ZERO(&readfds);
# ifdef HAVE_FD_SET_FDS_BITS
readfds.fds_bits[0] = svc_fds;
# else /* not HAVE_FD_SET_FDS_BITS */
readfds = svc_fds;
# endif /* not HAVE_FD_SET_FDS_BITS */
#endif /* not HAVE_SVC_GETREQSET */
FD_SET(fwd_sock, &readfds);
checkup();
/*
* If the full timeout code is not called,
* then recompute the time delta manually.
*/
now = clocktime(NULL);
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 && get_exported_ap(0) == NULL) {
flush_mntfs();
amd_state = Quit;
break;
}
#ifdef HAVE_FS_AUTOFS
autofs_add_fdset(&readfds);
#endif /* HAVE_FS_AUTOFS */
if (tvv.tv_sec <= 0)
tvv.tv_sec = SELECT_MAXWAIT;
if (tvv.tv_sec) {
dlog("Select waits for %ds", (int) tvv.tv_sec);
} else {
dlog("Select waits for Godot");
}
nsel = do_select(smask, FD_SETSIZE, &readfds, &tvv);
switch (nsel) {
case -1:
if (errno == EINTR) {
dlog("select interrupted");
continue;
}
plog(XLOG_ERROR, "select: %m");
break;
case 0:
break;
default:
/*
* Read all pending NFS responses at once to avoid having responses
* queue up as a consequence of retransmissions.
*/
if (FD_ISSET(fwd_sock, &readfds)) {
FD_CLR(fwd_sock, &readfds);
--nsel;
do {
fwd_reply();
} while (rpc_pending_now() > 0);
}
#ifdef HAVE_FS_AUTOFS
if (nsel)
nsel = autofs_handle_fdset(&readfds, nsel);
#endif /* HAVE_FS_AUTOFS */
if (nsel) {
/*
* Anything left must be a normal
* RPC request.
*/
#ifdef HAVE_SVC_GETREQSET
svc_getreqset(&readfds);
#else /* not HAVE_SVC_GETREQSET */
# ifdef HAVE_FD_SET_FDS_BITS
svc_getreq(readfds.fds_bits[0]);
# else /* not HAVE_FD_SET_FDS_BITS */
svc_getreq(readfds);
# endif /* not HAVE_FD_SET_FDS_BITS */
#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;
struct netconfig *udp_amqncp, *tcp_amqncp;
/*
* This must be done first, because it attempts to bind
* to various UDP ports and we don't want anything else
* potentially taking over those ports before we get a chance
* to reserve them.
*/
if (gopt.flags & CFM_RESTART_EXISTING_MOUNTS)
restart_automounter_nodes();
/*
* 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();
/*
* Create the nfs service for amd
* If nfs_port is already initialized, it means we
* already created the service during restart_automounter_nodes().
*/
if (nfs_port == 0) {
ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_dispatcher,
get_nfs_dispatcher_version(nfs_dispatcher));
if (ret != 0)
return ret;
}
xsnprintf(pid_fsname, sizeof(pid_fsname), "%s:(pid%ld,port%u)",
am_get_hostname(), (long) am_mypid, nfs_port);
/* security: if user sets -D noamq, don't even create listening socket */
if (amuDebug(D_AMQ)) {
ret = create_amq_service(&udp_soAMQ,
&udp_amqp,
&udp_amqncp,
&tcp_soAMQ,
&tcp_amqp,
&tcp_amqncp,
gopt.preferred_amq_port);
if (ret != 0)
return ret;
}
#ifdef HAVE_FS_AUTOFS
if (amd_use_autofs) {
/*
* Create the autofs service for amd.
*/
ret = create_autofs_service();
/* if autofs service fails it is OK if using a test amd */
if (ret != 0) {
plog(XLOG_WARNING, "autofs service registration failed, turning off autofs support");
amd_use_autofs = 0;
}
}
#endif /* HAVE_FS_AUTOFS */
/*
* 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;
}
if (amuDebug(D_AMQ)) {
/*
* Complete registration of amq (first TCP service then UDP)
*/
int tcp_ok = 0, udp_ok = 0;
unregister_amq(); /* unregister leftover Amd, if any, just in case */
tcp_ok = amu_svc_register(tcp_amqp, get_amd_program_number(), AMQ_VERSION,
amq_program_1, IPPROTO_TCP, tcp_amqncp);
if (!tcp_ok)
plog(XLOG_FATAL,
"unable to register (AMQ_PROGRAM=%lu, AMQ_VERSION, tcp)",
get_amd_program_number());
udp_ok = amu_svc_register(udp_amqp, get_amd_program_number(), AMQ_VERSION,
amq_program_1, IPPROTO_UDP, udp_amqncp);
if (!udp_ok)
plog(XLOG_FATAL,
"unable to register (AMQ_PROGRAM=%lu, AMQ_VERSION, udp)",
get_amd_program_number());
/* return error only if both failed */
if (!tcp_ok && !udp_ok) {
amd_state = Done;
return 3;
}
}
/*
* 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;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,301 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_TEMPLATE.c
*
*/
/*
* 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, mntfs *mf);
static int foofs_umount(am_node *mp, mntfs *mf);
static am_node *foofs_lookuppn(am_node *mp, char *fname, int *error_return, int op);
static int foofs_readdir(am_node *mp, void cookie, voidp dp, voidp ep, u_int count);
static am_node *foofs_readlink(am_node *mp, int *error_return);
static void foofs_mounted(am_node *am, mntfs *mf);
static void foofs_umounted(am_node *mp, mntfs *mf);
static 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_umount, /* unmount vnode */
foofs_lookup_child, /* lookup path-name */
foofs_mount_child, /* mount 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 */
foofs_get_wchan, /* return the waiting channel */
FS_MKMNT | FS_BACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_TEMPLATE_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* 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, void cookie, voidp dp, voidp ep, u_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.
*/
static fserver *
foofs_ffserver(mntfs *mf)
{
plog(XLOG_INFO, "entering foofs_ffserver...");
return NULL;
}
/*
* Normally just return mf. Only inherit needs to do special tricks.
*/
static wchan_t *
foofs_get_wchan(mntfs *mf)
{
plog(XLOG_INFO, "entering foofs_get_wchan...");
return mf;
}

View File

@ -1,256 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_cachefs.c
*
*/
/*
* 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_mount(am_node *am, mntfs *mf);
static int cachefs_umount(am_node *am, mntfs *mf);
/*
* Ops structure
*/
am_ops cachefs_ops =
{
"cachefs",
cachefs_match,
cachefs_init,
cachefs_mount,
cachefs_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* cachefs_readlink */
0, /* cachefs_mounted */
0, /* cachefs_umounted */
amfs_generic_find_srvr,
0, /* cachefs_get_wchan */
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_CACHEFS_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* 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;
}
dlog("CACHEFS: using cache directory \"%s\"", fo->opt_cachedir);
/* determine magic cookie to put in mtab */
return xstrdup(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_private) {
mf->mf_private = (voidp) xstrdup(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 *mntdir, char *backdir, char *cachedir,
char *opts, int on_autofs)
{
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 = mntdir;
mnt.mnt_fsname = backdir;
mnt.mnt_type = MNTTAB_TYPE_CACHEFS;
mnt.mnt_opts = opts;
flags = compute_mount_flags(&mnt);
#ifdef HAVE_FS_AUTOFS
if (on_autofs)
flags |= autofs_compute_mount_flags(&mnt);
#endif /* HAVE_FS_AUTOFS */
/* 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.
* sizeof(cfs_cacheid) should be C_MAX_MOUNT_FSCDIRNAME as per
* <sys/fs/cachefs_fs.h> (checked on Solaris 8).
*/
xsnprintf(ca.cfs_cacheid, sizeof(ca.cfs_cacheid),
"%s:%s", ca.cfs_fsid, mntdir);
/* 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, on_autofs);
}
static int
cachefs_mount(am_node *am, mntfs *mf)
{
int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
int error;
error = mount_cachefs(mf->mf_mount,
mf->mf_fo->opt_rfs,
mf->mf_fo->opt_cachedir,
mf->mf_mopts,
on_autofs);
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_umount(am_node *am, mntfs *mf)
{
int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
int error;
error = UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
/*
* 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);
xsnprintf(cmd, sizeof(cmd), "fsck -F cachefs %s", cachedir);
system(cmd);
}
return error;
}

View File

@ -1,241 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_cdfs.c
*
*/
/*
* 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_mount(am_node *am, mntfs *mf);
static int cdfs_umount(am_node *am, mntfs *mf);
/*
* Ops structure
*/
am_ops cdfs_ops =
{
"cdfs",
cdfs_match,
0, /* cdfs_init */
cdfs_mount,
cdfs_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* cdfs_readlink */
0, /* cdfs_mounted */
0, /* cdfs_umounted */
amfs_generic_find_srvr,
0, /* cdfs_get_wchan */
FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_CDFS_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* 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;
}
dlog("CDFS: mounting device \"%s\" on \"%s\"",
fo->opt_dev, fo->opt_fs);
/*
* Determine magic cookie to put in mtab
*/
return xstrdup(fo->opt_dev);
}
static int
mount_cdfs(char *mntdir, char *fs_name, char *opts, int on_autofs)
{
cdfs_args_t cdfs_args;
mntent_t mnt;
int genflags, cdfs_flags, retval;
/*
* 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 = mntdir;
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 (amu_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 (amu_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 (amu_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 (amu_hasmntopt(&mnt, MNTTAB_OPT_RRIP))
cdfs_flags |= MNT2_CDFS_OPT_RRIP;
#endif /* defined(MNT2_CDFS_OPT_RRIP) && defined(MNTTAB_OPT_RRIP) */
#if defined(MNT2_CDFS_OPT_NORRIP) && defined(MNTTAB_OPT_NORRIP)
if (amu_hasmntopt(&mnt, MNTTAB_OPT_NORRIP))
cdfs_flags |= MNT2_CDFS_OPT_NORRIP;
#endif /* defined(MNT2_CDFS_OPT_NORRIP) && defined(MNTTAB_OPT_NORRIP) */
#if defined(MNT2_CDFS_OPT_GENS) && defined(MNTTAB_OPT_GENS)
if (amu_hasmntopt(&mnt, MNTTAB_OPT_GENS))
cdfs_flags |= MNT2_CDFS_OPT_GENS;
#endif /* defined(MNT2_CDFS_OPT_GENS) && defined(MNTTAB_OPT_GENS) */
#if defined(MNT2_CDFS_OPT_EXTATT) && defined(MNTTAB_OPT_EXTATT)
if (amu_hasmntopt(&mnt, MNTTAB_OPT_EXTATT))
cdfs_flags |= MNT2_CDFS_OPT_EXTATT;
#endif /* defined(MNT2_CDFS_OPT_EXTATT) && defined(MNTTAB_OPT_EXTATT) */
#if defined(MNT2_CDFS_OPT_NOCASETRANS) && defined(MNTTAB_OPT_NOCASETRANS)
if (amu_hasmntopt(&mnt, MNTTAB_OPT_NOCASETRANS))
cdfs_flags |= MNT2_CDFS_OPT_NOCASETRANS;
#endif /* defined(MNT2_CDFS_OPT_NOCASETRANS) && defined(MNTTAB_OPT_NOCASETRANS) */
#if defined(MNT2_CDFS_OPT_NOJOLIET) && defined(MNTTAB_OPT_NOJOLIET)
if (amu_hasmntopt(&mnt, MNTTAB_OPT_NOJOLIET))
cdfs_flags |= MNT2_CDFS_OPT_NOJOLIET;
#endif /* defined(MNT2_CDFS_OPT_NOJOLIET) && defined(MNTTAB_OPT_NOJOLIET) */
#if defined(MNT2_CDFS_OPT_RRCASEINS) && defined(MNTTAB_OPT_RRCASEINS)
if (amu_hasmntopt(&mnt, MNTTAB_OPT_RRCASEINS))
cdfs_flags |= MNT2_CDFS_OPT_RRCASEINS;
#endif /* defined(MNT2_CDFS_OPT_RRCASEINS) && defined(MNTTAB_OPT_RRCASEINS) */
genflags = compute_mount_flags(&mnt);
#ifdef HAVE_FS_AUTOFS
if (on_autofs)
genflags |= autofs_compute_mount_flags(&mnt);
#endif /* HAVE_FS_AUTOFS */
#ifdef HAVE_CDFS_ARGS_T_FLAGS
cdfs_args.flags = cdfs_flags;
#endif /* HAVE_CDFS_ARGS_T_FLAGS */
#ifdef HAVE_CDFS_ARGS_T_ISO_FLAGS
cdfs_args.iso_flags = genflags | cdfs_flags;
#endif /* HAVE_CDFS_ARGS_T_ISO_FLAGS */
#ifdef HAVE_CDFS_ARGS_T_ISO_PGTHRESH
cdfs_args.iso_pgthresh = hasmntval(&mnt, MNTTAB_OPT_PGTHRESH);
#endif /* HAVE_CDFS_ARGS_T_ISO_PGTHRESH */
#ifdef HAVE_CDFS_ARGS_T_NORRIP
/* XXX: need to provide norrip mount opt */
cdfs_args.norrip = 0; /* use Rock-Ridge Protocol extensions */
#endif /* HAVE_CDFS_ARGS_T_NORRIP */
#ifdef HAVE_CDFS_ARGS_T_SSECTOR
/* XXX: need to provide ssector mount option */
cdfs_args.ssector = 0; /* use 1st session on disk */
#endif /* HAVE_CDFS_ARGS_T_SSECTOR */
#ifdef HAVE_CDFS_ARGS_T_FSPEC
cdfs_args.fspec = fs_name;
#endif /* HAVE_CDFS_ARGS_T_FSPEC */
/*
* Call generic mount routine
*/
retval = mount_fs(&mnt, genflags, (caddr_t) &cdfs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs);
return retval;
}
static int
cdfs_mount(am_node *am, mntfs *mf)
{
int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
int error;
error = mount_cdfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
if (error) {
errno = error;
plog(XLOG_ERROR, "mount_cdfs: %m");
return error;
}
return 0;
}
static int
cdfs_umount(am_node *am, mntfs *mf)
{
int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
}

View File

@ -1,171 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_efs.c
*
*/
/*
* 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_mount(am_node *am, mntfs *mf);
static int efs_umount(am_node *am, mntfs *mf);
/*
* Ops structure
*/
am_ops efs_ops =
{
"efs",
efs_match,
0, /* efs_init */
efs_mount,
efs_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* efs_readlink */
0, /* efs_mounted */
0, /* efs_umounted */
amfs_generic_find_srvr,
0, /* efs_get_wchan */
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_EFS_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* 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;
}
dlog("EFS: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs);
/*
* Determine magic cookie to put in mtab
*/
return xstrdup(fo->opt_dev);
}
static int
mount_efs(char *mntdir, char *fs_name, char *opts, int on_autofs)
{
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 = mntdir;
mnt.mnt_fsname = fs_name;
mnt.mnt_type = MNTTAB_TYPE_EFS;
mnt.mnt_opts = opts;
flags = compute_mount_flags(&mnt);
#ifdef HAVE_FS_AUTOFS
if (on_autofs)
flags |= autofs_compute_mount_flags(&mnt);
#endif /* HAVE_FS_AUTOFS */
#ifdef HAVE_EFS_ARGS_T_FLAGS
efs_args.flags = 0; /* XXX: fix this to correct flags */
#endif /* HAVE_EFS_ARGS_T_FLAGS */
#ifdef HAVE_EFS_ARGS_T_FSPEC
efs_args.fspec = fs_name;
#endif /* HAVE_EFS_ARGS_T_FSPEC */
#if defined(HAVE_EFS_ARGS_T_VERSION) && defined(EFS_MNT_VERSION)
efs_args.version = EFS_MNT_VERSION;
#endif /* HAVE_EFS_ARGS_T_VERSION && EFS_MNT_VERSION */
/*
* Call generic mount routine
*/
return mount_fs(&mnt, flags, (caddr_t) &efs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs);
}
static int
efs_mount(am_node *am, mntfs *mf)
{
int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
int error;
error = mount_efs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
if (error) {
errno = error;
plog(XLOG_ERROR, "mount_efs: %m");
return error;
}
return 0;
}
static int
efs_umount(am_node *am, mntfs *mf)
{
int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
}

View File

@ -1,223 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_ext.c
*
*/
/*
* Irix UN*X file system: EXT (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 *ext_match(am_opts *fo);
static int ext2_mount(am_node *am, mntfs *mf);
static int ext3_mount(am_node *am, mntfs *mf);
static int ext4_mount(am_node *am, mntfs *mf);
static int ext_umount(am_node *am, mntfs *mf);
/*
* Ops structure
*/
am_ops ext2_ops =
{
"ext2",
ext_match,
0, /* ext_init */
ext2_mount,
ext_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* ext_readlink */
0, /* ext_mounted */
0, /* ext_umounted */
amfs_generic_find_srvr,
0, /* ext_get_wchan */
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_EXT_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
am_ops ext3_ops =
{
"ext3",
ext_match,
0, /* ext_init */
ext3_mount,
ext_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* ext_readlink */
0, /* ext_mounted */
0, /* ext_umounted */
amfs_generic_find_srvr,
0, /* ext_get_wchan */
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_EXT_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
am_ops ext4_ops =
{
"ext4",
ext_match,
0, /* ext_init */
ext4_mount,
ext_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* ext_readlink */
0, /* ext_mounted */
0, /* ext_umounted */
amfs_generic_find_srvr,
0, /* ext_get_wchan */
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_EXT_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* EXT needs local filesystem and device.
*/
static char *
ext_match(am_opts *fo)
{
if (!fo->opt_dev) {
plog(XLOG_USER, "ext: no device specified");
return 0;
}
dlog("EXT: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs);
/*
* Determine magic cookie to put in mtab
*/
return xstrdup(fo->opt_dev);
}
static int
mount_ext(char *mntdir, char *fs_name, char *opts, int on_autofs, char *
mount_type, const char *mnttab_type)
{
ext_args_t ext_args;
mntent_t mnt;
int flags;
/*
* Figure out the name of the file system type.
*/
MTYPE_TYPE type = mount_type;
memset((voidp) &ext_args, 0, sizeof(ext_args)); /* Paranoid */
/*
* Fill in the mount structure
*/
memset((voidp) &mnt, 0, sizeof(mnt));
mnt.mnt_dir = mntdir;
mnt.mnt_fsname = fs_name;
mnt.mnt_type = mnttab_type;
mnt.mnt_opts = opts;
flags = compute_mount_flags(&mnt);
#ifdef HAVE_FS_AUTOFS
if (on_autofs)
flags |= autofs_compute_mount_flags(&mnt);
#endif /* HAVE_FS_AUTOFS */
/*
* Call generic mount routine
*/
return mount_fs(&mnt, flags, (caddr_t) &ext_args, 0, type, 0, NULL, mnttab_file_name, on_autofs);
}
static int
ext_mount(am_node *am, mntfs *mf, char *mount_type,
const char *mnttab_type)
{
int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
int error;
error = mount_ext(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs,
mount_type, mnttab_type);
if (error) {
errno = error;
plog(XLOG_ERROR, "mount_ext: %m");
return error;
}
return 0;
}
static int
ext2_mount(am_node *am, mntfs *mf)
{
return ext_mount(am, mf, MOUNT_TYPE_EXT2, MNTTAB_TYPE_EXT2);
}
static int
ext3_mount(am_node *am, mntfs *mf)
{
return ext_mount(am, mf, MOUNT_TYPE_EXT3, MNTTAB_TYPE_EXT3);
}
static int
ext4_mount(am_node *am, mntfs *mf)
{
return ext_mount(am, mf, MOUNT_TYPE_EXT4, MNTTAB_TYPE_EXT4);
}
static int
ext_umount(am_node *am, mntfs *mf)
{
int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
}

View File

@ -1,155 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_lofs.c
*
*/
/*
* 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_mount(am_node *am, mntfs *mf);
static int lofs_umount(am_node *am, mntfs *mf);
/*
* Ops structure
*/
am_ops lofs_ops =
{
"lofs",
lofs_match,
0, /* lofs_init */
lofs_mount,
lofs_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* lofs_readlink */
0, /* lofs_mounted */
0, /* lofs_umounted */
amfs_generic_find_srvr,
0, /* lofs_get_wchan */
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_LOFS_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* 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;
}
dlog("LOFS: mounting fs \"%s\" on \"%s\"",
fo->opt_rfs, fo->opt_fs);
/*
* Determine magic cookie to put in mtab
*/
return xstrdup(fo->opt_rfs);
}
int
mount_lofs(char *mntdir, char *fs_name, char *opts, int on_autofs)
{
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 = mntdir;
mnt.mnt_fsname = fs_name;
mnt.mnt_type = MNTTAB_TYPE_LOFS;
mnt.mnt_opts = opts;
flags = compute_mount_flags(&mnt);
#ifdef HAVE_FS_AUTOFS
if (on_autofs)
flags |= autofs_compute_mount_flags(&mnt);
#endif /* HAVE_FS_AUTOFS */
/*
* Call generic mount routine
*/
return mount_fs(&mnt, flags, NULL, 0, type, 0, NULL, mnttab_file_name, on_autofs);
}
static int
lofs_mount(am_node *am, mntfs *mf)
{
int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
int error;
error = mount_lofs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
if (error) {
errno = error;
plog(XLOG_ERROR, "mount_lofs: %m");
return error;
}
return 0;
}
static int
lofs_umount(am_node *am, mntfs *mf)
{
int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
}

View File

@ -1,203 +0,0 @@
/*
* Copyright (c) 2011 Christos Zoulas
* All rights reserved.
*
* 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.
*
* 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.
*
*
* File: am-utils/amd/ops_lustre.c
*
*/
/*
* Lustre file system
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#ifdef HAVE_FS_LUSTRE
#include <am_defs.h>
#include <amd.h>
/* forward declarations */
static char *lustre_match(am_opts *fo);
static int lustre_mount(am_node *am, mntfs *mf);
static int lustre_umount(am_node *am, mntfs *mf);
/*
* Ops structure
*/
am_ops lustre_ops =
{
"lustre",
lustre_match,
0, /* lustre_init */
lustre_mount,
lustre_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* lustre_readlink */
0, /* lustre_mounted */
0, /* lustre_umounted */
amfs_generic_find_srvr,
0, /* lustre_get_wchan */
FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_LUSTRE_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* Lustre needs remote filesystem and host.
*/
static char *
lustre_match(am_opts *fo)
{
char *xmtab, *cp;
size_t l;
char *rhost, *ptr, *remhost;
struct in_addr addr;
if (fo->opt_fs && !fo->opt_rfs)
fo->opt_rfs = fo->opt_fs;
if (!fo->opt_rfs) {
plog(XLOG_USER, "lustre: no remote filesystem specified");
return NULL;
}
if (!fo->opt_rhost) {
plog(XLOG_USER, "lustre: no remote host specified");
return NULL;
}
/*
* Determine magic cookie to put in mtab
*/
rhost = xstrdup(fo->opt_rhost);
remhost = NULL;
for (ptr = strtok(rhost, ":"); ptr; ptr = strtok(NULL, ":")) {
char *at = strchr(ptr, '@');
if (at == NULL) {
plog(XLOG_USER, "lustre: missing protocol in host `%s'", ptr);
XFREE(rhost);
return NULL;
}
*at = '\0';
/*
* Convert symbolic addresses to numbers that the kernel likes
*/
if (inet_aton(ptr, &addr) == 0) {
struct hostent *hp;
if ((hp = gethostbyname(ptr)) == NULL) {
plog(XLOG_USER, "lustre: unknown host `%s'", ptr);
XFREE(rhost);
return NULL;
}
if (hp->h_length != sizeof(addr.s_addr)) {
plog(XLOG_USER, "lustre: bad address length %zu != %d for %s",
sizeof(addr), hp->h_length, ptr);
XFREE(rhost);
return NULL;
}
memcpy(&addr.s_addr, hp->h_addr, sizeof(addr));
}
*at = '@';
cp = remhost;
if (remhost)
remhost = strvcat(cp, ":", inet_ntoa(addr), at, NULL);
else
remhost = strvcat(inet_ntoa(addr), at, NULL);
XFREE(cp);
}
if (remhost == NULL) {
plog(XLOG_USER, "lustre: empty host");
XFREE(rhost);
return NULL;
}
XFREE(rhost);
XFREE(fo->opt_rhost);
fo->opt_rhost = remhost;
l = strlen(fo->opt_rhost) + strlen(fo->opt_rfs) + 2;
xmtab = xmalloc(l);
xsnprintf(xmtab, l, "%s:%s", fo->opt_rhost, fo->opt_rfs);
dlog("lustre: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"",
fo->opt_rhost, fo->opt_rfs, fo->opt_fs);
return xmtab;
}
static int
lustre_mount(am_node *am, mntfs *mf)
{
mntent_t mnt;
int genflags, error;
int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
/*
* Figure out the name of the file system type.
*/
MTYPE_TYPE type = MOUNT_TYPE_LUSTRE;
/*
* Fill in the mount structure
*/
memset(&mnt, 0, sizeof(mnt));
mnt.mnt_dir = mf->mf_mount;
mnt.mnt_fsname = mf->mf_info;
mnt.mnt_type = MNTTAB_TYPE_LUSTRE;
mnt.mnt_opts = mf->mf_mopts;
genflags = compute_mount_flags(&mnt);
#ifdef HAVE_FS_AUTOFS
if (on_autofs)
genflags |= autofs_compute_mount_flags(&mnt);
#endif /* HAVE_FS_AUTOFS */
/*
* Call generic mount routine
*/
error = mount_fs(&mnt, genflags, NULL, 0, type, 0,
NULL, mnttab_file_name, on_autofs);
if (error) {
errno = error;
plog(XLOG_ERROR, "mount_lustre: %m");
return error;
}
return 0;
}
static int
lustre_umount(am_node *am, mntfs *mf)
{
int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
}
#endif

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_mfs.c
*
*/
/*
* 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 IMPLEMENT THIS... :-) */

File diff suppressed because it is too large Load Diff

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_nfs3.c
*
*/
/*
* 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 IMPLEMENT THIS... :-) */

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_nfs4.c
*
*/
/*
* Network file system version 4.0
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
/* FEEL FREE TO IMPLEMENT THIS... :-) */

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_nullfs.c
*
*/
/*
* 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 IMPLEMENT THIS... :-) */

View File

@ -1,222 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_pcfs.c
*
*/
/*
* 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_mount(am_node *am, mntfs *mf);
static int pcfs_umount(am_node *am, mntfs *mf);
/*
* Ops structure
*/
am_ops pcfs_ops =
{
"pcfs",
pcfs_match,
0, /* pcfs_init */
pcfs_mount,
pcfs_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* pcfs_readlink */
0, /* pcfs_mounted */
0, /* pcfs_umounted */
amfs_generic_find_srvr,
0, /* pcfs_get_wchan */
FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_PCFS_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* 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;
}
dlog("PCFS: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs);
/*
* Determine magic cookie to put in mtab
*/
return xstrdup(fo->opt_dev);
}
static int
mount_pcfs(char *mntdir, char *fs_name, char *opts, int on_autofs)
{
pcfs_args_t pcfs_args;
mntent_t mnt;
int flags;
#if defined(HAVE_PCFS_ARGS_T_MASK) || defined(HAVE_PCFS_ARGS_T_DIRMASK)
int mask;
#endif /* defined(HAVE_PCFS_ARGS_T_MASK) || defined(HAVE_PCFS_ARGS_T_DIRMASK) */
#if defined(HAVE_PCFS_ARGS_T_UID) || defined(HAVE_PCFS_ARGS_T_UID)
char *str;
#endif /* defined(HAVE_PCFS_ARGS_T_UID) || defined(HAVE_PCFS_ARGS_T_UID) */
/*
* 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 = mntdir;
mnt.mnt_fsname = fs_name;
mnt.mnt_type = MNTTAB_TYPE_PCFS;
mnt.mnt_opts = opts;
flags = compute_mount_flags(&mnt);
#ifdef HAVE_FS_AUTOFS
if (on_autofs)
flags |= autofs_compute_mount_flags(&mnt);
#endif /* HAVE_FS_AUTOFS */
if (amuDebug(D_TRACE))
plog(XLOG_DEBUG, "mount_pcfs: flags=0x%x", (u_int) flags);
#ifdef HAVE_PCFS_ARGS_T_FSPEC
pcfs_args.fspec = fs_name;
#endif /* HAVE_PCFS_ARGS_T_FSPEC */
#ifdef HAVE_PCFS_ARGS_T_MASK
pcfs_args.mask = 0777; /* this may be the msdos file modes */
if ((mask = hasmntval(&mnt, MNTTAB_OPT_MASK)) > 0)
pcfs_args.mask = mask;
if (amuDebug(D_TRACE))
plog(XLOG_DEBUG, "mount_pcfs: mask=%o (octal)", (u_int) pcfs_args.mask);
#endif /* HAVE_PCFS_ARGS_T_MASK */
#ifdef HAVE_PCFS_ARGS_T_DIRMASK
pcfs_args.dirmask = 0777; /* this may be the msdos dir modes */
if ((mask = hasmntval(&mnt, MNTTAB_OPT_DIRMASK)) > 0)
pcfs_args.dirmask = mask;
if (amuDebug(D_TRACE))
plog(XLOG_DEBUG, "mount_pcfs: dirmask=%o (octal)", (u_int) pcfs_args.dirmask);
#endif /* HAVE_PCFS_ARGS_T_DIRMASK */
#ifdef HAVE_PCFS_ARGS_T_UID
pcfs_args.uid = 0; /* default to root */
if ((str = hasmntstr(&mnt, MNTTAB_OPT_USER)) != NULL) {
struct passwd *pw;
if ((pw = getpwnam(str)) != NULL)
pcfs_args.uid = pw->pw_uid;
else /* maybe used passed a UID number, not user name */
pcfs_args.uid = atoi(str); /* atoi returns '0' if it failed */
XFREE(str);
}
if (amuDebug(D_TRACE))
plog(XLOG_DEBUG, "mount_pcfs: uid=%d", (int) pcfs_args.uid);
#endif /* HAVE_PCFS_ARGS_T_UID */
#ifdef HAVE_PCFS_ARGS_T_GID
pcfs_args.gid = 0; /* default to wheel/root group */
if ((str = hasmntstr(&mnt, MNTTAB_OPT_GROUP)) != NULL) {
struct group *gr;
if ((gr = getgrnam(str)) != NULL)
pcfs_args.gid = gr->gr_gid;
else /* maybe used passed a GID number, not group name */
pcfs_args.gid = atoi(str); /* atoi returns '0' if it failed */
XFREE(str);
}
if (amuDebug(D_TRACE))
plog(XLOG_DEBUG, "mount_pcfs: gid=%d", (int) pcfs_args.gid);
#endif /* HAVE_PCFS_ARGS_T_GID */
#ifdef HAVE_PCFS_ARGS_T_SECONDSWEST
pcfs_args.secondswest = 0; /* XXX: fill in correct values */
#endif /* HAVE_PCFS_ARGS_T_SECONDSWEST */
#ifdef HAVE_PCFS_ARGS_T_DSTTIME
pcfs_args.dsttime = 0; /* XXX: fill in correct values */
#endif /* HAVE_PCFS_ARGS_T_DSTTIME */
/*
* Call generic mount routine
*/
return mount_fs(&mnt, flags, (caddr_t) & pcfs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs);
}
static int
pcfs_mount(am_node *am, mntfs *mf)
{
int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
int error;
error = mount_pcfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
if (error) {
errno = error;
plog(XLOG_ERROR, "mount_pcfs: %m");
return error;
}
return 0;
}
static int
pcfs_umount(am_node *am, mntfs *mf)
{
int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
}

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_tfs.c
*
*/
/*
* Translucent file system
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
/* FEEL FREE TO IMPLEMENT THIS... :-) */

View File

@ -1,192 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_tmpfs.c
*
*/
/*
* 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>
/* forward declarations */
static char *tmpfs_match(am_opts *fo);
static int tmpfs_mount(am_node *am, mntfs *mf);
static int tmpfs_umount(am_node *am, mntfs *mf);
/*
* Ops structure
*/
am_ops tmpfs_ops =
{
"tmpfs",
tmpfs_match,
0, /* tmpfs_init */
tmpfs_mount,
tmpfs_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* tmpfs_readlink */
0, /* tmpfs_mounted */
0, /* tmpfs_umounted */
amfs_generic_find_srvr,
0, /* tmpfs_get_wchan */
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#if defined(HAVE_FS_AUTOFS) && defined(AUTOFS_TMPFS_FS_FLAGS)
AUTOFS_TMPFS_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* EFS needs local filesystem and device.
*/
static char *
tmpfs_match(am_opts *fo)
{
if (!fo->opt_dev) {
plog(XLOG_USER, "tmpfs: no device specified");
return 0;
}
dlog("EFS: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs);
/*
* Determine magic cookie to put in mtab
*/
return xstrdup(fo->opt_dev);
}
static int
mount_tmpfs(char *mntdir, char *fs_name, char *opts, int on_autofs)
{
tmpfs_args_t tmpfs_args;
mntent_t mnt;
int flags;
const char *p;
/*
* Figure out the name of the file system type.
*/
MTYPE_TYPE type = MOUNT_TYPE_TMPFS;
p = NULL;
memset((voidp) &tmpfs_args, 0, sizeof(tmpfs_args)); /* Paranoid */
/*
* Fill in the mount structure
*/
memset((voidp) &mnt, 0, sizeof(mnt));
mnt.mnt_dir = mntdir;
mnt.mnt_fsname = fs_name;
mnt.mnt_type = MNTTAB_TYPE_TMPFS;
mnt.mnt_opts = opts;
flags = compute_mount_flags(&mnt);
#ifdef HAVE_FS_AUTOFS
if (on_autofs)
flags |= autofs_compute_mount_flags(&mnt);
#endif /* HAVE_FS_AUTOFS */
#if defined(HAVE_TMPFS_ARGS_T_TA_VERSION) && defined(TMPFS_ARGS_VERSION)
tmpfs_args.ta_version = TMPFS_ARGS_VERSION;
#endif /* HAVE_TMPFS_ARGS_T_TA_VERSION && TMPFS_ARGS_VERSION */
#ifdef HAVE_TMPFS_ARGS_T_TA_NODES_MAX
if ((p = amu_hasmntopt(&mnt, "nodes")) == NULL)
p = "1000000";
tmpfs_args.ta_nodes_max = atoi(p);
#endif /* HAVE_TMPFS_ARGS_T_TA_SIZE_MAX */
#ifdef HAVE_TMPFS_ARGS_T_TA_SIZE_MAX
if ((p = amu_hasmntopt(&mnt, "size")) == NULL)
p = "10000000";
tmpfs_args.ta_size_max = atoi(p);
#endif /* HAVE_TMPFS_ARGS_T_TA_SIZE_MAX */
#ifdef HAVE_TMPFS_ARGS_T_TA_ROOT_UID
if ((p = amu_hasmntopt(&mnt, "uid")) == NULL)
p = "0";
tmpfs_args.ta_root_uid = atoi(p);
#endif /* HAVE_TMPFS_ARGS_T_TA_ROOT_UID */
#ifdef HAVE_TMPFS_ARGS_T_TA_ROOT_GID
if ((p = amu_hasmntopt(&mnt, "gid")) == NULL)
p = "0";
tmpfs_args.ta_root_gid = atoi(p);
#endif /* HAVE_TMPFS_ARGS_T_TA_ROOT_GID */
#ifdef HAVE_TMPFS_ARGS_T_TA_ROOT_MODE
if ((p = amu_hasmntopt(&mnt, "mode")) == NULL)
p = "01777";
tmpfs_args.ta_root_mode = strtol(p, NULL, 8);
#endif /* HAVE_TMPFS_ARGS_T_TA_ROOT_MODE */
/*
* Call generic mount routine
*/
return mount_fs(&mnt, flags, (caddr_t) &tmpfs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs);
}
static int
tmpfs_mount(am_node *am, mntfs *mf)
{
int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
int error;
error = mount_tmpfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
if (error) {
errno = error;
plog(XLOG_ERROR, "mount_tmpfs: %m");
return error;
}
return 0;
}
static int
tmpfs_umount(am_node *am, mntfs *mf)
{
int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
}

View File

@ -1,272 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_udf.c
*
*/
/*
* UDF file system
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
/* forward definitions */
static char *udf_match(am_opts *fo);
static int udf_mount(am_node *am, mntfs *mf);
static int udf_umount(am_node *am, mntfs *mf);
/*
* Ops structure
*/
am_ops udf_ops =
{
"udf",
udf_match,
0, /* udf_init */
udf_mount,
udf_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* udf_readlink */
0, /* udf_mounted */
0, /* udf_umounted */
amfs_generic_find_srvr,
0, /* udf_get_wchan */
FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_UDF_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
#if defined(HAVE_UDF_ARGS_T_NOBODY_GID) || defined(HAVE_UDF_ARGS_T_NOBODY_UID)
static int
a_num(const char *s, const char *id_type)
{
int id;
char *ep;
id = strtol(s, &ep, 0);
if (*ep || s == ep || id < 0) {
plog(XLOG_ERROR, "mount_udf: unknown %s: %s", id_type, s);
return 0;
}
return id;
}
#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_GID) || defined(HAVE_UDF_ARGS_T_NOBODY_UID) */
#if defined(HAVE_UDF_ARGS_T_NOBODY_GID)
static gid_t
a_gid(const char *s, const char *id_type)
{
struct group *gr;
if ((gr = getgrnam(s)) != NULL)
return gr->gr_gid;
return a_num(s, id_type);
}
#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_GID) */
#if defined(HAVE_UDF_ARGS_T_NOBODY_UID)
static uid_t
a_uid(const char *s, const char *id_type)
{
struct passwd *pw;
if ((pw = getpwnam(s)) != NULL)
return pw->pw_uid;
return a_num(s, id_type);
}
#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_UID) */
/*
* UDF needs remote filesystem.
*/
static char *
udf_match(am_opts *fo)
{
if (!fo->opt_dev) {
plog(XLOG_USER, "udf: no source device specified");
return 0;
}
dlog("UDF: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs);
/*
* Determine magic cookie to put in mtab
*/
return xstrdup(fo->opt_dev);
}
static int
mount_udf(char *mntdir, char *fs_name, char *opts, int on_autofs)
{
udf_args_t udf_args;
mntent_t mnt;
int flags;
char *str;
#if defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID)
uid_t uid_nobody;
gid_t gid_nobody;
#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID) */
/*
* Figure out the name of the file system type.
*/
MTYPE_TYPE type = MOUNT_TYPE_UDF;
#if defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID)
uid_nobody = a_uid("nobody", "user");
if (uid_nobody == 0) {
plog(XLOG_ERROR, "mount_udf: invalid uid for nobody");
return EPERM;
}
#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID) */
#if defined(HAVE_UDF_ARGS_T_NOBODY_GID) || defined(HAVE_UDF_ARGS_T_ANON_GID)
gid_nobody = a_gid("nobody", "group");
if (gid_nobody == 0) {
plog(XLOG_ERROR, "mount_udf: invalid gid for nobody");
return EPERM;
}
#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_GID) || defined(HAVE_UDF_ARGS_T_ANON_GID) */
str = NULL;
memset((voidp) &udf_args, 0, sizeof(udf_args)); /* Paranoid */
/*
* Fill in the mount structure
*/
memset((voidp)&mnt, 0, sizeof(mnt));
mnt.mnt_dir = mntdir;
mnt.mnt_fsname = fs_name;
mnt.mnt_type = MNTTAB_TYPE_UDF;
mnt.mnt_opts = opts;
flags = compute_mount_flags(&mnt);
#ifdef HAVE_UDF_ARGS_T_UDFMFLAGS
# if defined(MNT2_UDF_OPT_CLOSESESSION) && defined(MNTTAB_OPT_CLOSESESSION)
if (amu_hasmntopt(&mnt, MNTTAB_OPT_CLOSESESSION))
udf_args.udfmflags |= MNT2_UDF_OPT_CLOSESESSION;
# endif /* defined(MNT2_UDF_OPT_CLOSESESSION) && defined(MNTTAB_OPT_CLOSESESSION) */
#endif /* HAVE_UDF_ARGS_T_UDFMFLAGS */
#ifdef HAVE_UDF_ARGS_T_NOBODY_UID
udf_args.nobody_uid = uid_nobody;
#endif /* HAVE_UDF_ARGS_T_NOBODY_UID */
#ifdef HAVE_UDF_ARGS_T_NOBODY_GID
udf_args.nobody_gid = gid_nobody;
#endif /* HAVE_UDF_ARGS_T_NOBODY_GID */
#ifdef HAVE_UDF_ARGS_T_ANON_UID
udf_args.anon_uid = uid_nobody; /* default to nobody */
if ((str = hasmntstr(&mnt, MNTTAB_OPT_USER)) != NULL) {
udf_args.anon_uid = a_uid(str, MNTTAB_OPT_USER);
XFREE(str);
}
#endif /* HAVE_UDF_ARGS_T_ANON_UID */
#ifdef HAVE_UDF_ARGS_T_ANON_GID
udf_args.anon_gid = gid_nobody; /* default to nobody */
if ((str = hasmntstr(&mnt, MNTTAB_OPT_GROUP)) != NULL) {
udf_args.anon_gid = a_gid(str, MNTTAB_OPT_GROUP);
XFREE(str);
}
#endif /* HAVE_UDF_ARGS_T_ANON_GID */
#ifdef HAVE_UDF_ARGS_T_GMTOFF
udf_args.gmtoff = 0;
if ((str = hasmntstr(&mnt, MNTTAB_OPT_GMTOFF)) != NULL) {
udf_args.gmtoff = a_num(str, MNTTAB_OPT_GMTOFF);
XFREE(str);
}
#endif /* HAVE_UDF_ARGS_T_GMTOFF */
#ifdef HAVE_UDF_ARGS_T_SESSIONNR
udf_args.sessionnr = 0;
if ((str = hasmntstr(&mnt, MNTTAB_OPT_SESSIONNR)) != NULL) {
udf_args.sessionnr = a_num(str, MNTTAB_OPT_SESSIONNR);
XFREE(str);
}
#endif /* HAVE_UDF_ARGS_T_SESSIONNR */
#ifdef HAVE_UDF_ARGS_T_VERSION
# ifdef UDFMNT_VERSION
udf_args.version = UDFMNT_VERSION;
# endif /* UDFMNT_VERSION */
#endif /* HAVE_UDF_ARGS_T_VERSION */
#ifdef HAVE_UDF_ARGS_T_FSPEC
udf_args.fspec = fs_name;
#endif /* HAVE_UFS_ARGS_T_FSPEC */
/*
* Call generic mount routine
*/
return mount_fs(&mnt, flags, (caddr_t)&udf_args, 0, type, 0, NULL,
mnttab_file_name, on_autofs);
}
static int
udf_mount(am_node *am, mntfs *mf)
{
int on_autofs;
int error;
on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
error = mount_udf(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
if (error) {
errno = error;
plog(XLOG_ERROR, "mount_udf: %m");
return error;
}
return 0;
}
static int
udf_umount(am_node *am, mntfs *mf)
{
int unmount_flags;
unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
}

View File

@ -1,180 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_ufs.c
*
*/
/*
* 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_mount(am_node *am, mntfs *mf);
static int ufs_umount(am_node *am, mntfs *mf);
/*
* Ops structure
*/
am_ops ufs_ops =
{
#ifndef __NetBSD__
"ufs",
#else
"ffs",
#endif
ufs_match,
0, /* ufs_init */
ufs_mount,
ufs_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* ufs_readlink */
0, /* ufs_mounted */
0, /* ufs_umounted */
amfs_generic_find_srvr,
0, /* ufs_get_wchan */
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_UFS_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* 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;
}
dlog("UFS: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs);
/*
* Determine magic cookie to put in mtab
*/
return xstrdup(fo->opt_dev);
}
static int
mount_ufs(char *mntdir, char *fs_name, char *opts, int on_autofs)
{
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 = mntdir;
mnt.mnt_fsname = fs_name;
mnt.mnt_type = MNTTAB_TYPE_UFS;
mnt.mnt_opts = opts;
genflags = compute_mount_flags(&mnt);
#ifdef HAVE_FS_AUTOFS
if (on_autofs)
genflags |= autofs_compute_mount_flags(&mnt);
#endif /* HAVE_FS_AUTOFS */
#ifdef HAVE_UFS_ARGS_T_FLAGS
ufs_args.flags = genflags; /* XXX: is this correct? */
#endif /* HAVE_UFS_ARGS_T_FLAGS */
#ifdef HAVE_UFS_ARGS_T_UFS_FLAGS
ufs_args.ufs_flags = genflags;
#endif /* HAVE_UFS_ARGS_T_UFS_FLAGS */
#ifdef HAVE_UFS_ARGS_T_FSPEC
ufs_args.fspec = fs_name;
#endif /* HAVE_UFS_ARGS_T_FSPEC */
#ifdef HAVE_UFS_ARGS_T_UFS_PGTHRESH
ufs_args.ufs_pgthresh = hasmntval(&mnt, MNTTAB_OPT_PGTHRESH);
#endif /* HAVE_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, on_autofs);
}
static int
ufs_mount(am_node *am, mntfs *mf)
{
int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
int error;
error = mount_ufs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
if (error) {
errno = error;
plog(XLOG_ERROR, "mount_ufs: %m");
return error;
}
return 0;
}
static int
ufs_umount(am_node *am, mntfs *mf)
{
int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
}

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_umapfs.c
*
*/
/*
* 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 IMPLEMENT THIS... :-) */

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_unionfs.c
*
*/
/*
* 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 IMPLEMENT THIS... :-) */

View File

@ -1,167 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/ops_xfs.c
*
*/
/*
* 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_mount(am_node *am, mntfs *mf);
static int xfs_umount(am_node *am, mntfs *mf);
/*
* Ops structure
*/
am_ops xfs_ops =
{
"xfs",
xfs_match,
0, /* xfs_init */
xfs_mount,
xfs_umount,
amfs_error_lookup_child,
amfs_error_mount_child,
amfs_error_readdir,
0, /* xfs_readlink */
0, /* xfs_mounted */
0, /* xfs_umounted */
amfs_generic_find_srvr,
0, /* xfs_get_wchan */
FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
#ifdef HAVE_FS_AUTOFS
AUTOFS_XFS_FS_FLAGS,
#endif /* HAVE_FS_AUTOFS */
};
/*
* 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;
}
dlog("XFS: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs);
/*
* Determine magic cookie to put in mtab
*/
return xstrdup(fo->opt_dev);
}
static int
mount_xfs(char *mntdir, char *fs_name, char *opts, int on_autofs)
{
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 = mntdir;
mnt.mnt_fsname = fs_name;
mnt.mnt_type = MNTTAB_TYPE_XFS;
mnt.mnt_opts = opts;
flags = compute_mount_flags(&mnt);
#ifdef HAVE_FS_AUTOFS
if (on_autofs)
flags |= autofs_compute_mount_flags(&mnt);
#endif /* HAVE_FS_AUTOFS */
#ifdef HAVE_XFS_ARGS_T_FLAGS
xfs_args.flags = 0; /* XXX: fix this to correct flags */
#endif /* HAVE_XFS_ARGS_T_FLAGS */
#ifdef HAVE_XFS_ARGS_T_FSPEC
xfs_args.fspec = fs_name;
#endif /* HAVE_XFS_ARGS_T_FSPEC */
/*
* Call generic mount routine
*/
return mount_fs(&mnt, flags, (caddr_t) &xfs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs);
}
static int
xfs_mount(am_node *am, mntfs *mf)
{
int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
int error;
error = mount_xfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
if (error) {
errno = error;
plog(XLOG_ERROR, "mount_xfs: %m");
return error;
}
return 0;
}
static int
xfs_umount(am_node *am, mntfs *mf)
{
int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,952 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/readdir.c
*
*/
#include <stdint.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
/****************************************************************************
*** MACROS ***
****************************************************************************/
#define DOT_DOT_COOKIE (u_int) 1
#define MAX_CHAIN 2048
/****************************************************************************
*** FORWARD DEFINITIONS ***
****************************************************************************/
static int key_already_in_chain(char *keyname, const nfsentry *chain);
static nfsentry *make_entry_chain(am_node *mp, const nfsentry *current_chain, int fully_browsable);
static int amfs_readdir_browsable(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count, int fully_browsable);
static const u_int dotdotcookie = DOT_DOT_COOKIE;
/****************************************************************************
*** FUNCTIONS ***
****************************************************************************/
/*
* Was: NEW_TOPLVL_READDIR
* Search a chain for an entry with some name.
* -Erez Zadok <ezk@cs.columbia.edu>
*/
static int
key_already_in_chain(char *keyname, const nfsentry *chain)
{
const nfsentry *tmpchain = chain;
while (tmpchain) {
if (keyname && tmpchain->ne_name && STREQ(keyname, tmpchain->ne_name))
return 1;
tmpchain = tmpchain->ne_nextentry;
}
return 0;
}
/*
* Create a chain of entries which are not linked.
* -Erez Zadok <ezk@cs.columbia.edu>
*/
static nfsentry *
make_entry_chain(am_node *mp, const nfsentry *current_chain, int fully_browsable)
{
static u_int last_cookie = (u_int) 2; /* monotonically increasing */
static nfsentry chain[MAX_CHAIN];
static int max_entries = MAX_CHAIN;
char *key;
int num_entries = 0, i;
u_int preflen = 0;
nfsentry *retval = (nfsentry *) NULL;
mntfs *mf;
mnt_map *mmp;
if (!mp) {
plog(XLOG_DEBUG, "make_entry_chain: mp is (NULL)");
return retval;
}
mf = mp->am_al->al_mnt;
if (!mf) {
plog(XLOG_DEBUG, "make_entry_chain: mp->am_al->al_mnt is (NULL)");
return retval;
}
mmp = (mnt_map *) mf->mf_private;
if (!mmp) {
plog(XLOG_DEBUG, "make_entry_chain: mp->am_al->al_mnt->mf_private is (NULL)");
return retval;
}
if (mp->am_pref)
preflen = strlen(mp->am_pref);
/* iterate over keys */
for (i = 0; i < NKVHASH; i++) {
kv *k;
for (k = mmp->kvhash[i]; k ; k = k->next) {
/*
* Skip unwanted entries which are either not real entries or
* very difficult to interpret (wildcards...) This test needs
* lots of improvement. Any takers?
*/
key = k->key;
if (!key)
continue;
/* Skip '/defaults' */
if (STREQ(key, "/defaults"))
continue;
/* Skip '*' */
if (!fully_browsable && strchr(key, '*'))
continue;
/*
* If the map has a prefix-string then check if the key starts with
* this string, and if it does, skip over this prefix. If it has a
* prefix and it doesn't match the start of the key, skip it.
*/
if (preflen) {
if (preflen > strlen(key))
continue;
if (!NSTREQ(key, mp->am_pref, preflen))
continue;
key += preflen;
}
/* no more '/' are allowed, unless browsable_dirs=full was used */
if (!fully_browsable && strchr(key, '/'))
continue;
/* no duplicates allowed */
if (key_already_in_chain(key, current_chain))
continue;
/* fill in a cell and link the entry */
if (num_entries >= max_entries) {
/* out of space */
plog(XLOG_DEBUG, "make_entry_chain: no more space in chain");
if (num_entries > 0) {
chain[num_entries - 1].ne_nextentry = NULL;
retval = &chain[0];
}
return retval;
}
/* we have space. put entry in next cell */
++last_cookie;
chain[num_entries].ne_fileid = last_cookie;
(void)memcpy(chain[num_entries].ne_cookie, &last_cookie,
sizeof(last_cookie));
chain[num_entries].ne_name = key;
if (num_entries < max_entries - 1) { /* link to next one */
chain[num_entries].ne_nextentry = &chain[num_entries + 1];
}
++num_entries;
} /* end of "while (k)" */
} /* end of "for (i ... NKVHASH ..." */
/* terminate chain */
if (num_entries > 0) {
chain[num_entries - 1].ne_nextentry = NULL;
retval = &chain[0];
}
return retval;
}
/* This one is called only if map is browsable */
static int
amfs_readdir_browsable(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count, int fully_browsable)
{
u_int gen = *(u_int *) (uintptr_t) cookie;
int chain_length, i;
static nfsentry *te, *te_next;
static int j;
dp->dl_eof = FALSE; /* assume readdir not done */
if (amuDebug(D_READDIR))
plog(XLOG_DEBUG, "amfs_readdir_browsable gen=%u, count=%d",
gen, count);
if (gen == 0) {
/*
* In the default instance (which is used to start a search) we return
* "." and "..".
*
* This assumes that the count is big enough to allow both "." and ".."
* to be returned in a single packet. If it isn't (which would be
* fairly unbelievable) then tough.
*/
dlog("%s: default search", __func__);
/*
* Check for enough room. This is extremely approximate but is more
* than enough space. Really need 2 times:
* 4byte fileid
* 4byte cookie
* 4byte name length
* 4byte name
* plus the dirlist structure */
if (count < (2 * (2 * (sizeof(*ep) + sizeof("..") + 4) + sizeof(*dp))))
return EINVAL;
/*
* compute # of entries to send in this chain.
* heuristics: 128 bytes per entry.
* This is too much probably, but it seems to work better because
* of the re-entrant nature of nfs_readdir, and esp. on systems
* like OpenBSD 2.2.
*/
chain_length = count / 128;
/* reset static state counters */
te = te_next = NULL;
dp->dl_entries = ep;
/* construct "." */
ep[0].ne_fileid = mp->am_gen;
ep[0].ne_name = ".";
ep[0].ne_nextentry = &ep[1];
(void)memset(ep[0].ne_cookie, 0, sizeof(u_int));
/* construct ".." */
if (mp->am_parent)
ep[1].ne_fileid = mp->am_parent->am_gen;
else
ep[1].ne_fileid = mp->am_gen;
ep[1].ne_name = "..";
ep[1].ne_nextentry = NULL;
(void)memcpy(ep[1].ne_cookie, &dotdotcookie, sizeof(dotdotcookie));
/*
* If map is browsable, call a function make_entry_chain() to construct
* a linked list of unmounted keys, and return it. Then link the chain
* to the regular list. Get the chain only once, but return
* chunks of it each time.
*/
te = make_entry_chain(mp, dp->dl_entries, fully_browsable);
if (!te)
return 0;
if (amuDebug(D_READDIR)) {
nfsentry *ne;
for (j = 0, ne = te; ne; ne = ne->ne_nextentry)
plog(XLOG_DEBUG, "gen1 key %4d \"%s\"", j++, ne->ne_name);
}
/* return only "chain_length" entries */
te_next = te;
for (i=1; i<chain_length; ++i) {
te_next = te_next->ne_nextentry;
if (!te_next)
break;
}
if (te_next) {
nfsentry *te_saved = te_next->ne_nextentry;
te_next->ne_nextentry = NULL; /* terminate "te" chain */
te_next = te_saved; /* save rest of "te" for next iteration */
dp->dl_eof = FALSE; /* tell readdir there's more */
} else {
dp->dl_eof = TRUE; /* tell readdir that's it */
}
ep[1].ne_nextentry = te; /* append this chunk of "te" chain */
if (amuDebug(D_READDIR)) {
nfsentry *ne;
for (j = 0, ne = te; ne; ne = ne->ne_nextentry)
plog(XLOG_DEBUG, "gen2 key %4d \"%s\"", j++, ne->ne_name);
for (j = 0, ne = ep; ne; ne = ne->ne_nextentry) {
u_int cookie;
(void)memcpy(&cookie, ne->ne_cookie, sizeof(cookie));
plog(XLOG_DEBUG, "gen2+ key %4d \"%s\" fi=%d ck=%d",
j++, ne->ne_name, ne->ne_fileid, cookie);
}
plog(XLOG_DEBUG, "EOF is %d", dp->dl_eof);
}
return 0;
} /* end of "if (gen == 0)" statement */
dlog("%s: real child", __func__);
if (gen == DOT_DOT_COOKIE) {
dlog("%s: End of readdir in %s", __func__, mp->am_path);
dp->dl_eof = TRUE;
dp->dl_entries = NULL;
return 0;
}
/*
* If browsable directories, then continue serving readdir() with another
* chunk of entries, starting from where we left off (when gen was equal
* to 0). Once again, assume last chunk served to readdir.
*/
dp->dl_eof = TRUE;
dp->dl_entries = ep;
te = te_next; /* reset 'te' from last saved te_next */
if (!te) { /* another indicator of end of readdir */
dp->dl_entries = NULL;
return 0;
}
/*
* compute # of entries to send in this chain.
* heuristics: 128 bytes per entry.
*/
chain_length = count / 128;
/* return only "chain_length" entries */
for (i = 1; i < chain_length; ++i) {
te_next = te_next->ne_nextentry;
if (!te_next)
break;
}
if (te_next) {
nfsentry *te_saved = te_next->ne_nextentry;
te_next->ne_nextentry = NULL; /* terminate "te" chain */
te_next = te_saved; /* save rest of "te" for next iteration */
dp->dl_eof = FALSE; /* tell readdir there's more */
}
ep = te; /* send next chunk of "te" chain */
dp->dl_entries = ep;
if (amuDebug(D_READDIR)) {
nfsentry *ne;
plog(XLOG_DEBUG, "dl_entries=%p, te_next=%p, dl_eof=%d",
dp->dl_entries, te_next, dp->dl_eof);
for (ne = te; ne; ne = ne->ne_nextentry)
plog(XLOG_DEBUG, "gen3 key %4d \"%s\"", j++, ne->ne_name);
}
return 0;
}
static int
amfs_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count)
{
u_int gen = *(u_int *) (uintptr_t) cookie;
am_node *xp;
dp->dl_eof = FALSE; /* assume readdir not done */
/* when gen is 0, we start reading from the beginning of the directory */
if (gen == 0) {
/*
* In the default instance (which is used to start a search) we return
* "." and "..".
*
* This assumes that the count is big enough to allow both "." and ".."
* to be returned in a single packet. If it isn't (which would be
* fairly unbelievable) then tough.
*/
dlog("%s: default search", __func__);
/*
* Check for enough room. This is extremely approximate but is more
* than enough space. Really need 2 times:
* 4byte fileid
* 4byte cookie
* 4byte name length
* 4byte name
* plus the dirlist structure */
#define NEEDROOM (2 * (2 * (sizeof(*ep) + sizeof("..") + 4) + sizeof(*dp)))
if (count < NEEDROOM) {
dlog("%s: not enough room %u < %zu", __func__, count, NEEDROOM);
return EINVAL;
}
xp = next_nonerror_node(mp->am_child);
dp->dl_entries = ep;
/* construct "." */
ep[0].ne_fileid = mp->am_gen;
ep[0].ne_name = ".";
ep[0].ne_nextentry = &ep[1];
(void)memset(ep[0].ne_cookie, 0, sizeof(u_int));
/* construct ".." */
if (mp->am_parent)
ep[1].ne_fileid = mp->am_parent->am_gen;
else
ep[1].ne_fileid = mp->am_gen;
ep[1].ne_name = "..";
ep[1].ne_nextentry = NULL;
(void)memcpy(ep[1].ne_cookie, (xp ? &xp->am_gen : &dotdotcookie),
sizeof(dotdotcookie));
if (!xp)
dp->dl_eof = TRUE; /* by default assume readdir done */
if (amuDebug(D_READDIR)) {
nfsentry *ne;
int j;
for (j = 0, ne = ep; ne; ne = ne->ne_nextentry) {
u_int cookie;
(void)memcpy(&cookie, ne->ne_cookie, sizeof(cookie));
plog(XLOG_DEBUG, "gen1 key %4d \"%s\" fi=%d ck=%d",
j++, ne->ne_name, ne->ne_fileid, cookie);
}
}
return 0;
}
dlog("%s: real child", __func__);
if (gen == DOT_DOT_COOKIE) {
dlog("%s: End of readdir in %s", __func__, mp->am_path);
dp->dl_eof = TRUE;
dp->dl_entries = NULL;
if (amuDebug(D_READDIR))
plog(XLOG_DEBUG, "end of readdir eof=TRUE, dl_entries=0\n");
return 0;
}
/* non-browsable directories code */
xp = mp->am_child;
while (xp && xp->am_gen != gen)
xp = xp->am_osib;
if (xp) {
int nbytes = count / 2; /* conservative */
int todo = MAX_READDIR_ENTRIES;
dp->dl_entries = ep;
do {
am_node *xp_next = next_nonerror_node(xp->am_osib);
if (xp_next) {
(void)memcpy(ep->ne_cookie, &xp_next->am_gen, sizeof(xp_next->am_gen));
} else {
(void)memcpy(ep->ne_cookie, &dotdotcookie, sizeof(dotdotcookie));
dp->dl_eof = TRUE;
}
ep->ne_fileid = xp->am_gen;
ep->ne_name = xp->am_name;
nbytes -= sizeof(*ep) + 1;
if (xp->am_name)
nbytes -= strlen(xp->am_name);
xp = xp_next;
if (nbytes > 0 && !dp->dl_eof && todo > 1) {
ep->ne_nextentry = ep + 1;
ep++;
--todo;
} else {
todo = 0;
}
} while (todo > 0);
ep->ne_nextentry = NULL;
if (amuDebug(D_READDIR)) {
nfsentry *ne;
int j;
for (j=0,ne=ep; ne; ne=ne->ne_nextentry) {
u_int cookie;
(void)memcpy(&cookie, ne->ne_cookie, sizeof(cookie));
plog(XLOG_DEBUG, "gen2 key %4d \"%s\" fi=%d ck=%d",
j++, ne->ne_name, ne->ne_fileid, cookie);
}
}
return 0;
}
return ESTALE;
}
/*
* Search a chain for an entry with some name.
*/
static int
key_already_in_chain3(char *keyname, const am_entry3 *chain)
{
const am_entry3 *tmpchain = chain;
while (tmpchain) {
if (keyname && tmpchain->name && STREQ(keyname, tmpchain->name))
return 1;
tmpchain = tmpchain->nextentry;
}
return 0;
}
/*
* Create a chain of entries which are not linked.
*/
static am_entry3 *
make_entry_chain3(am_node *mp, const am_entry3 *current_chain, int fully_browsable)
{
static uint64 last_cookie = (uint64) 2; /* monotonically increasing */
static am_entry3 chain[MAX_CHAIN];
static int max_entries = MAX_CHAIN;
char *key;
int num_entries = 0, i;
u_int preflen = 0;
am_entry3 *retval = (am_entry3 *) NULL;
mntfs *mf;
mnt_map *mmp;
if (!mp) {
plog(XLOG_DEBUG, "make_entry_chain3: mp is (NULL)");
return retval;
}
mf = mp->am_al->al_mnt;
if (!mf) {
plog(XLOG_DEBUG, "make_entry_chain3: mp->am_al->al_mnt is (NULL)");
return retval;
}
mmp = (mnt_map *) mf->mf_private;
if (!mmp) {
plog(XLOG_DEBUG, "make_entry_chain3: mp->am_al->al_mnt->mf_private is (NULL)");
return retval;
}
if (mp->am_pref)
preflen = strlen(mp->am_pref);
/* iterate over keys */
for (i = 0; i < NKVHASH; i++) {
kv *k;
for (k = mmp->kvhash[i]; k ; k = k->next) {
/*
* Skip unwanted entries which are either not real entries or
* very difficult to interpret (wildcards...) This test needs
* lots of improvement. Any takers?
*/
key = k->key;
if (!key)
continue;
/* Skip '/defaults' */
if (STREQ(key, "/defaults"))
continue;
/* Skip '*' */
if (!fully_browsable && strchr(key, '*'))
continue;
/*
* If the map has a prefix-string then check if the key starts with
* this string, and if it does, skip over this prefix. If it has a
* prefix and it doesn't match the start of the key, skip it.
*/
if (preflen) {
if (preflen > strlen(key))
continue;
if (!NSTREQ(key, mp->am_pref, preflen))
continue;
key += preflen;
}
/* no more '/' are allowed, unless browsable_dirs=full was used */
if (!fully_browsable && strchr(key, '/'))
continue;
/* no duplicates allowed */
if (key_already_in_chain3(key, current_chain))
continue;
/* fill in a cell and link the entry */
if (num_entries >= max_entries) {
/* out of space */
plog(XLOG_DEBUG, "make_entry_chain3: no more space in chain");
if (num_entries > 0) {
chain[num_entries - 1].nextentry = NULL;
retval = &chain[0];
}
return retval;
}
/* we have space. put entry in next cell */
++last_cookie;
chain[num_entries].fileid = last_cookie;
chain[num_entries].cookie = last_cookie;
chain[num_entries].name = key;
if (num_entries < max_entries - 1) { /* link to next one */
chain[num_entries].nextentry = &chain[num_entries + 1];
}
++num_entries;
} /* end of "while (k)" */
} /* end of "for (i ... NKVHASH ..." */
/* terminate chain */
if (num_entries > 0) {
chain[num_entries - 1].nextentry = NULL;
retval = &chain[0];
}
return retval;
}
static size_t needroom3(void)
{
/*
* Check for enough room. This is extremely approximate but should
* be enough space. Really need 2 times:
* (8byte fileid
* 8byte cookie
* 8byte name pointer
* 8byte next entry addres) = sizeof(am_entry3)
* 2byte name + 1byte terminator
* plus the size of the am_dirlist3 structure */
return ((2 * ((sizeof(am_entry3) + sizeof("..") + 1))) + sizeof(am_dirlist3));
}
/* This one is called only if map is browsable */
static int
amfs_readdir3_browsable(am_node *mp, am_cookie3 cookie,
am_dirlist3 *dp, am_entry3 *ep, u_int count,
int fully_browsable)
{
uint64 gen = *(uint64 *) (uintptr_t) cookie;
int chain_length, i;
static am_entry3 *te, *te_next;
static int j;
dp->eof = FALSE; /* assume readdir not done */
if (amuDebug(D_READDIR))
plog(XLOG_DEBUG, "amfs_readdir3_browsable gen=%lu, count=%d", (long unsigned) gen, count);
if (gen == 0) {
size_t needed = needroom3();
/*
* In the default instance (which is used to start a search) we return
* "." and "..".
*
* This assumes that the count is big enough to allow both "." and ".."
* to be returned in a single packet. If it isn't (which would be
* fairly unbelievable) then tough.
*/
dlog("%s: default search", __func__);
if (count < needed) {
dlog("%s: not enough room %u < %zu", __func__, count, needed);
return EINVAL;
}
/*
* compute # of entries to send in this chain.
* heuristics: 128 bytes per entry.
* This is too much probably, but it seems to work better because
* of the re-entrant nature of nfs_readdir, and esp. on systems
* like OpenBSD 2.2.
*/
chain_length = count / 128;
/* reset static state counters */
te = te_next = NULL;
dp->entries = ep;
/* construct "." */
ep[0].fileid = mp->am_gen;
ep[0].name = ".";
ep[0].nextentry = &ep[1];
ep[0].cookie = 0;
/* construct ".." */
if (mp->am_parent)
ep[1].fileid = mp->am_parent->am_gen;
else
ep[1].fileid = mp->am_gen;
ep[1].name = "..";
ep[1].nextentry = NULL;
ep[1].cookie = dotdotcookie;
/*
* If map is browsable, call a function make_entry_chain() to construct
* a linked list of unmounted keys, and return it. Then link the chain
* to the regular list. Get the chain only once, but return
* chunks of it each time.
*/
te = make_entry_chain3(mp, dp->entries, fully_browsable);
if (!te)
return 0;
if (amuDebug(D_READDIR)) {
am_entry3 *ne;
for (j = 0, ne = te; ne; ne = ne->ne_nextentry)
plog(XLOG_DEBUG, "gen1 key %4d \"%s\"", j++, ne->ne_name);
}
/* return only "chain_length" entries */
te_next = te;
for (i=1; i<chain_length; ++i) {
te_next = te_next->nextentry;
if (!te_next)
break;
}
if (te_next) {
am_entry3 *te_saved = te_next->nextentry;
te_next->nextentry = NULL; /* terminate "te" chain */
te_next = te_saved; /* save rest of "te" for next iteration */
dp->eof = FALSE; /* tell readdir there's more */
} else {
dp->eof = TRUE; /* tell readdir that's it */
}
ep[1].nextentry = te; /* append this chunk of "te" chain */
if (amuDebug(D_READDIR)) {
am_entry3 *ne;
for (j = 0, ne = te; ne; ne = ne->ne_nextentry)
plog(XLOG_DEBUG, "gen2 key %4d \"%s\"", j++, ne->name);
for (j = 0, ne = ep; ne; ne = ne->ne_nextentry) {
plog(XLOG_DEBUG, "gen2+ key %4d \"%s\" fi=%lu ck=%lu",
j++, ne->name, (long unsigned) ne->fileid, (long unsigned) ne->cookie);
}
plog(XLOG_DEBUG, "EOF is %d", dp->eof);
}
return 0;
} /* end of "if (gen == 0)" statement */
dlog("%s: real child", __func__);
if (gen == DOT_DOT_COOKIE) {
dlog("%s: End of readdir in %s", __func__, mp->am_path);
dp->eof = TRUE;
dp->entries = NULL;
return 0;
}
/*
* If browsable directories, then continue serving readdir() with another
* chunk of entries, starting from where we left off (when gen was equal
* to 0). Once again, assume last chunk served to readdir.
*/
dp->eof = TRUE;
dp->entries = ep;
te = te_next; /* reset 'te' from last saved te_next */
if (!te) { /* another indicator of end of readdir */
dp->entries = NULL;
return 0;
}
/*
* compute # of entries to send in this chain.
* heuristics: 128 bytes per entry.
*/
chain_length = count / 128;
/* return only "chain_length" entries */
for (i = 1; i < chain_length; ++i) {
te_next = te_next->nextentry;
if (!te_next)
break;
}
if (te_next) {
am_entry3 *te_saved = te_next->nextentry;
te_next->nextentry = NULL; /* terminate "te" chain */
te_next = te_saved; /* save rest of "te" for next iteration */
dp->eof = FALSE; /* tell readdir there's more */
}
ep = te; /* send next chunk of "te" chain */
dp->entries = ep;
if (amuDebug(D_READDIR)) {
am_entry3 *ne;
plog(XLOG_DEBUG,
"entries=%p, te_next=%p, eof=%d", dp->entries, te_next, dp->eof);
for (ne = te; ne; ne = ne->nextentry)
plog(XLOG_DEBUG, "gen3 key %4d \"%s\"", j++, ne->name);
}
return 0;
}
static int
amfs_readdir3(am_node *mp, am_cookie3 cookie,
am_dirlist3 *dp, am_entry3 *ep, u_int count)
{
uint64 gen = *(uint64 *) (uintptr_t) cookie;
am_node *xp;
if (amuDebug(D_READDIR))
plog(XLOG_DEBUG, "amfs_readdir3 gen=%lu, count=%d", (long unsigned) gen, count);
dp->eof = FALSE; /* assume readdir not done */
/* when gen is 0, we start reading from the beginning of the directory */
if (gen == 0) {
size_t needed = needroom3();
/*
* In the default instance (which is used to start a search) we return
* "." and "..".
*
* This assumes that the count is big enough to allow both "." and ".."
* to be returned in a single packet. If it isn't (which would be
* fairly unbelievable) then tough.
*/
dlog("%s: default search", __func__);
if (count < needed) {
dlog("%s: not enough room %u < %zu", __func__, count, needed);
return EINVAL;
}
xp = next_nonerror_node(mp->am_child);
dp->entries = ep;
/* construct "." */
ep[0].fileid = mp->am_gen;
ep[0].name = ".";
ep[0].cookie = 0;
ep[0].nextentry = &ep[1];
/* construct ".." */
if (mp->am_parent)
ep[1].fileid = mp->am_parent->am_gen;
else
ep[1].fileid = mp->am_gen;
ep[1].name = "..";
ep[1].nextentry = NULL;
ep[1].cookie = (xp ? xp->am_gen : dotdotcookie);
if (!xp)
dp->eof = TRUE; /* by default assume readdir done */
if (amuDebug(D_READDIR)) {
am_entry3 *ne;
int j;
for (j = 0, ne = ep; ne; ne = ne->nextentry) {
plog(XLOG_DEBUG, "gen1 key %4d \"%s\" fi=%lu ck=%lu",
j++, ne->name, (long unsigned) ne->fileid, (long unsigned) ne->cookie);
}
}
return 0;
}
dlog("%s: real child", __func__);
if (gen == (uint64) DOT_DOT_COOKIE) {
dlog("%s: End of readdir in %s", __func__, mp->am_path);
dp->eof = TRUE;
dp->entries = NULL;
if (amuDebug(D_READDIR))
plog(XLOG_DEBUG, "end of readdir eof=TRUE, dl_entries=0\n");
return 0;
}
/* non-browsable directories code */
xp = mp->am_child;
while (xp && xp->am_gen != gen)
xp = xp->am_osib;
if (xp) {
int nbytes = count / 2; /* conservative */
int todo = MAX_READDIR_ENTRIES;
dp->entries = ep;
do {
am_node *xp_next = next_nonerror_node(xp->am_osib);
if (xp_next) {
ep->cookie = xp_next->am_gen;
} else {
ep->cookie = (uint64) dotdotcookie;
dp->eof = TRUE;
}
ep->fileid = xp->am_gen;
ep->name = xp->am_name;
nbytes -= sizeof(*ep) + 1;
if (xp->am_name)
nbytes -= strlen(xp->am_name);
xp = xp_next;
if (nbytes > 0 && !dp->dl_eof && todo > 1) {
ep->nextentry = ep + 1;
ep++;
--todo;
} else {
todo = 0;
}
} while (todo > 0);
ep->nextentry = NULL;
if (amuDebug(D_READDIR)) {
am_entry3 *ne;
int j;
for (j = 0, ne = ep; ne; ne = ne->nextentry) {
plog(XLOG_DEBUG, "gen2 key %4d \"%s\" fi=%lu ck=%lu",
j++, ne->name, (long unsigned) ne->fileid, (long unsigned) ne->cookie);
}
}
return 0;
}
return ESTALE;
}
/*
* This readdir function which call a special version of it that allows
* browsing if browsable_dirs=yes was set on the map.
*/
int
amfs_generic_readdir(am_node *mp, voidp cookie, voidp dp, voidp ep, u_int count)
{
int browsable, full;
/* check if map is browsable */
browsable = 0;
if (mp->am_al->al_mnt && mp->am_al->al_mnt->mf_mopts) {
mntent_t mnt;
mnt.mnt_opts = mp->am_al->al_mnt->mf_mopts;
if (amu_hasmntopt(&mnt, "fullybrowsable"))
browsable = 2;
else if (amu_hasmntopt(&mnt, "browsable"))
browsable = 1;
}
full = (browsable == 2);
if (nfs_dispatcher == nfs_program_2) {
if (browsable)
return amfs_readdir_browsable(mp, cookie, dp, ep, count, full);
else
return amfs_readdir(mp, cookie, dp, ep, count);
} else {
if (browsable)
return amfs_readdir3_browsable(mp, (am_cookie3) (uintptr_t) cookie, dp, ep, count, full);
else
return amfs_readdir3(mp, (am_cookie3) (uintptr_t) cookie, dp, ep, count);
}
}

View File

@ -1,282 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/restart.c
*
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
static void
restart_fake_mntfs(mntent_t *me, am_ops *fs_ops)
{
mntfs *mf;
am_opts mo;
char *cp;
/*
* Partially fake up an opts structure
*/
memset(&mo, 0, sizeof(mo));
mo.opt_rhost = NULL;
mo.opt_rfs = NULL;
cp = strchr(me->mnt_fsname, ':');
if (cp) {
*cp = '\0';
mo.opt_rhost = xstrdup(me->mnt_fsname);
mo.opt_rfs = xstrdup(cp + 1);
*cp = ':';
} else if (STREQ(me->mnt_type, MNTTAB_TYPE_NFS)) {
/*
* Hacky workaround for mnttab NFS entries that only list the server
*/
plog(XLOG_WARNING, "NFS server entry assumed to be %s:/", me->mnt_fsname);
mo.opt_rhost = xstrdup(me->mnt_fsname);
mo.opt_rfs = xstrdup("/");
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 */
/*
* Only timeout non-NFS entries
*/
if (!STREQ(me->mnt_type, MNTTAB_TYPE_NFS))
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, flags 0x%x",
me->mnt_fsname, fs_ops->fs_type, me->mnt_dir, mf->mf_flags);
} else {
/* Something strange happened - two mounts at the same place! */
free_mntfs(mf);
}
/*
* Clean up mo
*/
XFREE(mo.opt_rhost);
XFREE(mo.opt_rfs);
}
/*
* 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 module relies on internal details of other components. If
* you change something else make *sure* restart() still works.
*/
void
restart(void)
{
mntlist *ml, *mlp;
/*
* Read the existing mount table. 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 = NULL;
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"))
continue;
}
/* Search for the correct filesystem ops */
fs_ops = ops_search(me->mnt_type);
/*
* Catch everything else with symlinks to
* avoid recursive mounts. This is debatable...
*/
if (!fs_ops)
fs_ops = &amfs_link_ops;
restart_fake_mntfs(me, fs_ops);
}
/*
* Free the mount list
*/
free_mntlist(ml);
}
/*
* Handle an amd restart for amd's own mount points.
*
* Scan through the mount list finding all daemon mount points
* (determined by the presence of a pid inside the mount info).
* Next hack up partial data structures and add the mounted file
* system to the list of known filesystems.
*
* This module relies on internal details of other components. If
* you change something else make *sure* restart() still works.
*/
void
restart_automounter_nodes(void)
{
mntlist *ml, *mlp;
/* reasonably sized list of restarted nfs ports */
u_short old_ports[256];
memset((voidp) &old_ports, 0, sizeof(u_short) * 256);
/*
* Read the existing mount table. 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 = NULL;
char *colon;
long pid;
u_short port;
int err;
if (!STREQ(me->mnt_type, MNTTAB_TYPE_NFS))
continue; /* to next mlp */
/*
* NFS entry, or possibly an Amd entry...
* The mnt_fsname for daemon mount points is
* host:(pidXXX)
* or (seen on Solaris)
* host:daemon(pidXXX)
*/
colon = strchr(me->mnt_fsname, ':');
if (!colon || !strstr(colon, "(pid"))
continue;
/* if got here, then we matched an existing Amd mount point */
err = 1;
plog(XLOG_WARNING, "%s is an existing automount point", me->mnt_dir);
/* Is the old automounter still alive? */
if (sscanf(colon, "%*[^(](pid%ld%*[,)]", &pid) != 1) {
plog(XLOG_WARNING, "Can't parse pid in %s", me->mnt_fsname);
goto give_up;
}
if (kill(pid, 0) != -1 || errno != ESRCH) {
plog(XLOG_WARNING, "Automounter (pid: %ld) still alive", pid);
goto give_up;
}
/*
* Do we have a map for this mount point? Who cares, we'll restart
* anyway -- getting ESTALE is way better than hanging.
*/
/* Can we restart it? Only if it tells us what port it was using... */
if (sscanf(colon, "%*[^,],port%hu)", &port) != 1) {
plog(XLOG_WARNING, "No port specified for %s", me->mnt_fsname);
goto give_up;
}
/* Maybe we already own that port... */
if (port != nfs_port) {
int i;
for (i = 0; i < 256; i++) {
if (old_ports[i] == port ||
old_ports[i] == 0)
break;
}
if (i == 256) {
plog(XLOG_WARNING, "Too many open ports (256)");
goto give_up;
}
if (old_ports[i] == 0) {
int soNFS;
SVCXPRT *nfsxprt;
if (create_nfs_service(&soNFS, &port, &nfsxprt, nfs_dispatcher,
get_nfs_dispatcher_version(nfs_dispatcher)) != 0) {
plog(XLOG_WARNING, "Can't bind to port %u", port);
goto give_up;
}
old_ports[i] = nfs_port = port;
}
}
err = 0;
give_up:
if (err) {
plog(XLOG_WARNING, "Can't restart %s, leaving it alone", me->mnt_dir);
fs_ops = &amfs_link_ops;
} else {
fs_ops = &amfs_toplvl_ops;
}
restart_fake_mntfs(me, fs_ops);
} /* end of "for (mlp" */
/* free the mount list */
free_mntlist(ml);
}

View File

@ -1,474 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/rpc_fwd.c
*
*/
/*
* 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() (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(NULL);
rpc_forward *p = NULL, *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.
*/
dlog("Re-using packet forwarding slot - id %#x", p->rf_xid);
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 *) NULL) < 0)
plog(XLOG_ERROR, "can't bind privileged port (rpc_fwd)");
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, char *pkt, int len, struct sockaddr_in *fwdto, struct sockaddr_in *replyto, opaque_t cb_arg, 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.
*/
switch (type_id & RPC_XID_MASK) {
case RPC_XID_PORTMAP:
dlog("Sending PORTMAP request %#x", type_id);
break;
case RPC_XID_MOUNTD:
dlog("Sending MOUNTD request %#x", type_id);
break;
case RPC_XID_NFSPING:
dlog("Sending NFS ping %#x", type_id);
break;
case RPC_XID_WEBNFS:
dlog("Sending WebNFS lookup %#x", type_id);
break;
default:
dlog("UNKNOWN RPC XID %#x", type_id);
break;
}
if (type_id & ~RPC_XID_MASK) {
p = fwd_locate(type_id);
if (p) {
dlog("Discarding earlier rpc fwd handle");
fwd_free(p);
}
} else {
dlog("Allocating a new xid...");
type_id = MK_RPC_XID(type_id, XID_ALLOC());
}
p = fwd_alloc();
if (!p)
return ENOBUFS;
error = 0;
pkt_int = (u_int *) pkt;
/*
* Get the original packet id
*/
p->rf_oldid = ntohl(*pkt_int);
/*
* Replace with newly allocated id
*/
p->rf_xid = type_id;
*pkt_int = htonl(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, sizeof(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 = cb_arg;
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;
u_int pkt_xid;
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);
/*
* Clear error indication, otherwise the error condition persists and
* amd gets into an infinite loop.
*/
if (t_errno == TLOOK)
t_rcvuderr(fwd_sock, NULL);
}
#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;
pkt_xid = ntohl(*pkt_int);
switch (pkt_xid & RPC_XID_MASK) {
case RPC_XID_PORTMAP:
dlog("Receiving PORTMAP reply %#x", pkt_xid);
break;
case RPC_XID_MOUNTD:
dlog("Receiving MOUNTD reply %#x", pkt_xid);
break;
case RPC_XID_NFSPING:
dlog("Receiving NFS ping %#x", pkt_xid);
break;
case RPC_XID_WEBNFS:
dlog("Receiving WebNFS lookup %#x", pkt_xid);
break;
default:
dlog("UNKNOWN RPC XID %#x", pkt_xid);
break;
}
p = fwd_locate(pkt_xid);
if (!p) {
dlog("Can't forward reply id %#x", pkt_xid);
goto out;
}
if (p->rf_fwd) {
/*
* Put the original message id back
* into the packet.
*/
*pkt_int = htonl(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:;
}

View File

@ -1,300 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/sched.c
*
*/
/*
* 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 */
opaque_t cb_arg; /* Argument for callback */
int w; /* everyone these days uses int, not a "union wait" */
wchan_t 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, opaque_t ca)
{
pjob *p = ALLOC(struct pjob);
p->cb_fun = cf;
p->cb_arg = 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, opaque_t ta, cb_fun *cf, opaque_t 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 = (wchan_t) p;
#ifdef HAVE_SIGACTION
sigemptyset(&new); /* initialize 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 has returned to caller */
exit((*tf) (ta));
/* firewall... */
abort();
}
/*
* Schedule a task to be run when woken up
*/
void
sched_task(cb_fun *cf, opaque_t ca, wchan_t wchan)
{
/*
* Allocate a new task
*/
pjob *p = sched_job(cf, ca);
dlog("SLEEP on %p", wchan);
p->wchan = wchan;
p->pid = 0;
p->w = 0; /* was memset (when ->w was union) */
}
static void
wakeupjob(pjob *p)
{
rem_que(&p->hdr);
ins_que(&p->hdr, &proc_list_head);
task_notify_todo++;
}
void
wakeup(wchan_t wchan)
{
pjob *p, *p2;
if (!foreground)
return;
/*
* Can't use 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, wchan_t wchan)
{
wakeup(wchan);
}
wchan_t
get_mntfs_wchan(mntfs *mf)
{
if (mf &&
mf->mf_ops &&
mf->mf_ops->get_wchan)
return mf->mf_ops->get_wchan(mf);
return mf;
}
/*
* 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 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 compatibility with strict POSIX.1 */
p->cb_fun(WIFEXITED(p->w) ? WEXITSTATUS(p->w) : 0,
WIFSIGNALED(p->w) ? WTERMSIG(p->w) : 0,
p->cb_arg);
}
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 *) NULL)) > 0) {
#endif /* not HAVE_WAITPID */
pjob *p, *p2;
if (WIFSIGNALED(w))
plog(XLOG_ERROR, "Process %d exited with signal %d",
pid, WTERMSIG(w));
else
dlog("Process %d exited with status %d",
pid, WEXITSTATUS(w));
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 */
if (p == HEAD(pjob, &proc_wait_list))
dlog("can't locate task block for pid %d", pid);
/*
* Must count down children inside the while loop, otherwise we won't
* count them all, and NumChildren (and later backoff) will be set
* incorrectly. SH/RUNIT 940519.
*/
if (--NumChildren < 0)
NumChildren = 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);
}

View File

@ -1,205 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amd/srvr_amfs_auto.c
*
*/
/*
* Automount FS server ("localhost") modeling
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
/* globals */
/* statics */
static qelem amfs_auto_srvr_list = {&amfs_auto_srvr_list, &amfs_auto_srvr_list};
static fserver *localhost;
/*
* Find an nfs server for the local host
*/
fserver *
amfs_generic_find_srvr(mntfs *mf)
{
fserver *fs = localhost;
if (!fs) {
fs = ALLOC(struct fserver);
fs->fs_refc = 0;
fs->fs_host = xstrdup("localhost");
fs->fs_ip = NULL;
fs->fs_cid = 0;
fs->fs_pinger = AM_PINGER;
fs->fs_flags = FSF_VALID | FSF_PING_UNINIT;
fs->fs_type = "local";
fs->fs_private = NULL;
fs->fs_prfree = NULL;
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) {
dlog("Deleting file server %s", fs->fs_host);
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
*/
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 = (FSRV_ERROR(fs) || FSRV_ISDOWN(fs)) ? 19 : AM_TTL;
dlog("Last hard reference to file server %s - will timeout in %ds", fs->fs_host, ttl);
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, state %s", fs->fs_host, fs->fs_type, state);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,92 +0,0 @@
.\"
.\" Copyright (c) 1997-2014 Erez Zadok
.\" Copyright (c) 2005 Daniel P. Ottavio
.\" 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. 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.
.\"
.\"
.\" File: am-utils/amd/sun2amd.8
.\"
.TH SUN2AMD 8L "14 August 2005"
.SH NAME
sun2amd \- converts Sun automount maps to Amd maps
.SH SYNOPSIS
.B sun2amd
[-hH] [-i infile] [-o outfile]
.SH DESCRIPTION
.B sun2amd
is used to convert Sun style automount maps to Amd style automount
maps. By default
.B sun2amd
reads from stdin and writes to stdout.
.SH OPTIONS
.TP
.B -h
Help
.TP
.B -i
Read Sun map information from specified file.
.TP
.B -o
Write Amd map information to specified file.
.SH EXAMPLE
To convert a Sun automount file called auto_foo to an Amd file called
auto.amd type:
.B sun2amd
-i auto_foo -o auto.amd
.SH BUGS
* Can not convert master maps yet.
* NFS is the only automount type currently supported.
total_bug_count = number_found + 1;
.SH "SEE ALSO"
.BR automount(8),
.BR amd(8)
.I "Linux NFS and Automounter Administration"
by Erez Zadok, ISBN 0-7821-2739-8, (Sybex, 2001).
.LP
.I http://www.am-utils.org
.LP
.SH AUTHOR
Daniel P. Ottavio
.I <dottavio@ic.sunysb.edu>

View File

@ -1,203 +0,0 @@
/*
* Copyright (c) 1997-2014 Erez Zadok
* Copyright (c) 2005 Daniel P. Ottavio
* 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. 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.
*
*
* File: am-utils/amd/sun2amd.c
*
*/
/*
* Translate Sun-syntax maps to Amd maps
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
#include <sun_map.h>
/* dummies to make the program compile and link */
struct amu_global_options gopt;
#if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
# ifdef NEED_LIBWRAP_SEVERITY_VARIABLES
/*
* Some systems that define libwrap already define these two variables
* in libwrap, while others don't: so I need to know precisely iff
* to define these two severity variables.
*/
int allow_severity=0, deny_severity=0, rfc931_timeout=0;
# endif /* NEED_LIBWRAP_SEVERITY_VARIABLES */
#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
/*
* Parse the stream sun_in, convert the map information to amd, write
* the results to amd_out.
*/
static int
sun2amd_convert(FILE *sun_in, FILE *amd_out)
{
char line_buff[INFO_MAX_LINE_LEN], *tmp, *key, *entry;
int pos, line = 0, retval = 1;
/* just to be safe */
memset(line_buff, 0, sizeof(line_buff));
/* Read the input line by line and do the conversion. */
while ((pos = file_read_line(line_buff, sizeof(line_buff), sun_in))) {
line++;
line_buff[pos - 1] = '\0';
/* remove comments */
if ((tmp = strchr(line_buff, '#')) != NULL) {
*tmp = '\0';
}
/* find start of key */
key = line_buff;
while (*key != '\0' && isspace((unsigned char)*key)) {
key++;
}
/* ignore blank lines */
if (*key == '\0') {
continue;
}
/* find the end of the key and NULL terminate */
tmp = key;
while (*tmp != '\0' && isspace((unsigned char)*tmp) == 0) {
tmp++;
}
if (*tmp == '\0') {
plog(XLOG_ERROR, "map line %d has no entry", line);
goto err;
}
*tmp++ = '\0';
if (*tmp == '\0') {
plog(XLOG_ERROR, "map line %d has no entry", line);
goto err;
}
entry = tmp;
/* convert the sun entry to an amd entry */
if ((tmp = sun_entry2amd(key, entry)) == NULL) {
plog(XLOG_ERROR, "parse error on line %d", line);
goto err;
}
if (fprintf(amd_out, "%s %s\n", key, tmp) < 0) {
plog(XLOG_ERROR, "can't write to output stream: %s", strerror(errno));
goto err;
}
/* just to be safe */
memset(line_buff, 0, sizeof(line_buff));
}
/* success */
retval = 0;
err:
return retval;
}
/*
* wrapper open function
*/
static FILE *
sun2amd_open(const char *path, const char *mode)
{
FILE *retval = NULL;
if ((retval = fopen(path,mode)) == NULL) {
plog(XLOG_ERROR,"could not open file %s",path);
}
return retval;
}
/*
* echo the usage and exit
*/
static void
sun2amd_usage(void)
{
fprintf(stderr,
"usage : sun2amd [-hH] [-i infile] [-o outfile]\n"
"-h\thelp\n"
"-i\tspecify an infile (defaults to stdin)\n"
"-o\tspecify an outfile (defaults to stdout)\n");
}
int
main(int argc, char **argv)
{
/* default in/out to stdin/stdout */
FILE *sun_in = stdin, *amd_out = stdout;
int opt, retval = 1;
while ((opt = getopt(argc, argv , "i:o:hH")) != -1) {
switch (opt) {
case 'i':
if ((sun_in = sun2amd_open(optarg,"r")) == NULL) {
goto err;
}
break;
case 'o':
if ((amd_out = sun2amd_open(optarg,"w")) == NULL) {
goto err;
}
break;
case 'h':
case 'H':
sun2amd_usage();
goto err;
}
}
retval = sun2amd_convert(sun_in,amd_out);
err:
exit(retval);
}

View File

@ -1,595 +0,0 @@
/*
* Copyright (c) 1997-2014 Erez Zadok
* Copyright (c) 2005 Daniel P. Ottavio
* 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. 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.
*
*
* File: am-utils/amd/sun_map.c
*
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
#include <sun_map.h>
/*
* Add a data pointer to the end of the list.
*/
void
sun_list_add(struct sun_list *list, qelem *item)
{
if (list->last == NULL) {
list->last = item;
list->first = item;
item->q_back = NULL;
}
else {
list->last->q_forw = item;
item->q_back = list->last;
list->last = item;
}
item->q_forw = NULL;
}
/*
* Sun2Amd conversion routines
*/
/*
* AMD entry keywords
*/
#define AMD_OPTS_KW "addopts:=" /* add entry options */
#define AMD_RHOST_KW "rhost:=" /* remote host */
#define AMD_RFS_KW "rfs:=" /* remote file system */
#define AMD_FS_KW "fs:=" /* local file system */
#define AMD_DEV_KW "dev:=" /* device */
#define AMD_TYPE_NFS_KW "type:=nfs;" /* fs type nfs */
#define AMD_TYPE_AUTO_KW "type:=auto;" /* fs type auto */
#define AMD_TYPE_CDFS_KW "type:=cdfs;" /* fs type cd */
#define AMD_MAP_FS_KW "fs:=${map};" /* set the mount map as current map */
#define AMD_MAP_PREF_KW "pref:=${key}/" /* set the mount map as current map */
/*
* A set of string Sun fstypes.
*/
#define SUN_NFS_TYPE "nfs"
#define SUN_HSFS_TYPE "hsfs" /* CD fs */
#define SUN_AUTOFS_TYPE "autofs"
#define SUN_CACHEFS_TYPE "cachefs"
#define SUN_KEY_SUB "&" /* Sun key substitution */
/* a set a Sun variable substitutions for map entries */
#define SUN_ARCH "$ARCH" /* host architecture */
#define SUN_CPU "$CPU" /* processor type */
#define SUN_HOST "$HOST" /* host name */
#define SUN_OSNAME "$OSNAME" /* OS name */
#define SUN_OSREL "$OSREL" /* OS release */
#define SUN_OSVERS "$OSVERS" /* OS version */
#define SUN_NATISA "$NATISA" /* native instruction set */
/* a set of Amd variable substitutions */
#define AMD_ARCH "${arch}" /* host architecture */
#define AMD_HOST "${host}" /* host name */
#define AMD_OSNAME "${os}" /* OS name */
#define AMD_OSVER "${osver}" /* OS version */
/*
* Return a copy of src that has all occurrences of 'str' replaced
* with sub.
*
* param src - the original string
* param str - string that is the replaced with str
* param sub - string that replaces an occurrences of 'delim'
*
* return - new string with str substitutions, NULL on error
*/
static char *
sun_strsub(const char *src, const char *str, const char *sub)
{
char *retval = NULL, *str_start, *str_end, *src_end;
size_t total_size, first_half, second_half, sub_size;
/* assign pointers to the start and end of str */
if ((str_start = strstr(src, str)) == NULL) {
return retval;
}
str_end = (strlen(str) - 1) + str_start;
/* assign to the end of the src. */
src_end = (strlen(src) - 1) + (char*)src;
/* size from the beginning of src to the start of str */
first_half = (size_t)(str_start - src);
/* size from the end of str to the end of src */
second_half = (size_t)(src_end - str_end);
sub_size = strlen(sub);
total_size = (first_half + sub_size + second_half + 1);
retval = (char*)xmalloc(total_size);
memset(retval, 0, total_size);
/*
* Put together the string such that the first half is copied
* followed the sub and second half.
*
* We use strncpy instead of xstrlcpy because we are intentionally
* causing truncation and we don't want this to cause errors in the
* log.
*/
(void)strncpy(retval, src, first_half);
(void)strncat(retval, sub, sub_size);
(void)strncat(retval, str_end + 1, second_half);
if (strstr(retval, str) != NULL) {
/*
* If there is another occurrences of str call this function
* recursively.
*/
char* tmp;
if ((tmp = sun_strsub(retval, str, sub)) != NULL) {
XFREE(retval);
retval = tmp;
}
}
return retval;
}
/*
* Return a new string that is a copy of str, all occurrences of a Sun
* variable substitutions are replaced by there equivalent Amd
* substitutions.
*
* param str - source string
*
* return - A new string with the expansions, NULL if str does not
* exist in src or error.
*/
static char *
sun_expand2amd(const char *str)
{
char *retval = NULL, *tmp = NULL, *tmp2 = NULL;
const char *pos;
/*
* Iterator through the string looking for '$' chars. For each '$'
* found try to replace it with Sun variable substitutions. If we
* find a '$' that is not a substation each of the i.e $blah than
* each of the replace attempt will fail and we'll move on to the
* next char.
*/
tmp = xstrdup(str);
for (pos = str; *pos != '\0'; pos++) {
if (*pos != '$') {
continue;
}
if (tmp2 != NULL) {
XFREE(tmp);
tmp = tmp2;
}
/*
* If a 'replace' does not return NULL than a variable was
* successfully substituted.
*/
/* architecture */
if ((tmp2 = sun_strsub(tmp, SUN_ARCH, AMD_ARCH)) != NULL) {
continue;
}
/* cpu - there is not POSIX uname for cpu so just use machine */
if ((tmp2 = sun_strsub(tmp, SUN_CPU, AMD_ARCH)) != NULL) {
continue;
}
/* hostname */
if ((tmp2 = sun_strsub(tmp, SUN_HOST, AMD_HOST)) != NULL) {
continue;
}
/* os name */
if ((tmp2 = sun_strsub(tmp, SUN_OSNAME, AMD_OSNAME)) != NULL) {
continue;
}
/*
* os release - Amd doesn't hava a OS release var just usr os
* version or now.
*/
if ((tmp2 = sun_strsub(tmp, SUN_OSREL, AMD_OSVER)) != NULL) {
continue;
}
/* os version */
if ((tmp2 = sun_strsub(tmp, SUN_OSVERS, AMD_OSVER)) != NULL) {
continue;
}
/* native instruction set - there is no POSIX natisa so just use system */
if ((tmp2 = sun_strsub(tmp, SUN_NATISA, AMD_ARCH)) != NULL) {
continue;
}
}
if (tmp2 == NULL) {
retval = tmp;
}
else {
retval = tmp2;
XFREE(tmp);
}
return retval;
}
/*
* This is a wrapper function for appending Amd entry information to a
* buffer. Any Sun variable substitutions will be converted into Amd
* equivalents.
*
* param dest - destination buffer
* param deslen - destination buffer length
* param key - entry key, this might be needed for key substitutions
* param str - string to append
*/
static void
sun_append_str(char *dest,
size_t destlen,
const char *key,
const char *str)
{
char *sub = NULL, *sub2 = NULL, *out = NULL;
/* By default we are going to just write the original string. */
out = (char*)str;
/*
* Resolve variable substitutions in two steps; 1) replace any key
* map substitutions with the entry key 2) expand any variable
* substitutions i.e $HOST.
*
* Try to replace the key substitution '&'. If this function returns
* with a new string, one or more key subs. where replaced with the
* entry key.
*/
if ((sub = sun_strsub(str, SUN_KEY_SUB, "${key}")) != NULL) {
out = sub;
/*
* Try to convert any variable substitutions. If this function
* returns a new string one or more var subs where expanded.
*/
if ((sub2 = sun_expand2amd(sub)) != NULL) {
out = sub2;
}
}
/*
* Try to convert any variable substitutions. If this function
* returns a new string one or more var subs where expanded.
*/
else if (out != NULL && (sub = sun_expand2amd(out)) != NULL) {
out = sub;
}
if (out != NULL) {
xstrlcat(dest, out, destlen);
}
XFREE(sub);
XFREE(sub2);
}
/*
* Convert the list of Sun mount options to Amd mount options. The
* result is concatenated to dest.
*
* param dest - destination buffer
* param destlen - destination buffer length
* param key - automount key
* param opt_list - list of Sun mount options
*/
static void
sun_opts2amd(char *dest,
size_t destlen,
const char *key,
const struct sun_opt *opt_list)
{
const struct sun_opt *opt;
xstrlcat(dest, AMD_OPTS_KW, destlen);
/* Iterate through each option and append it to the buffer. */
for(opt = opt_list; opt != NULL; opt = NEXT(struct sun_opt, opt)) {
sun_append_str(dest, destlen, key, opt->str);
/* If there are more options add some commas. */
if (NEXT(struct sun_opt, opt) != NULL) {
xstrlcat(dest, ",", destlen);
}
}
xstrlcat(dest, ";", destlen);
}
/*
* Convert the list of Sun mount locations to a list of Amd mount
* locations. The result is concatenated to dest.
*
* param dest - destination buffer
* param destlen - destination buffer length
* param key - automount key
* param local_list - list of Sun mount locations
*/
static void
sun_locations2amd(char *dest,
size_t destlen,
const char *key,
const struct sun_location *local_list)
{
const struct sun_location *local;
const struct sun_host *host;
for (local = local_list;
local != NULL;
local = NEXT(struct sun_location,local)) {
/*
* Check to see if the list of hosts is empty. Some mount types
* i.e cd-rom may have mount location with no host.
*/
if (local->host_list != NULL) {
/* Write each host that belongs to this location. */
for (host = local->host_list;
host != NULL;
host = NEXT(struct sun_host, host)) {
/* set fstype NFS */
xstrlcat(dest, AMD_TYPE_NFS_KW, destlen);
/* add rhost key word */
xstrlcat(dest, AMD_RHOST_KW, destlen);
/* add host name */
sun_append_str(dest, destlen, key, host->name);
xstrlcat(dest, ";", destlen);
/* add remote fs key word */
xstrlcat(dest, AMD_RFS_KW, destlen);
/* add local path */
sun_append_str(dest, destlen, key, local->path);
if (NEXT(struct sun_host, host) != NULL) {
xstrlcat(dest, ";", destlen);
xstrlcat(dest, " ", destlen);
}
}
}
else {
/* no host location */
xstrlcat(dest, AMD_FS_KW, destlen);
sun_append_str(dest, destlen, key, local->path);
}
if (NEXT(struct sun_location, local) != NULL) {
/* add a space to separate each location */
xstrlcat(dest, " ", destlen);
}
}
}
/*
* Convert a Sun HSFS mount point to an Amd. The result is
* concatenated intp dest.
*
* param dest - destination buffer
* param destlen - destination buffer length
* param key - automount key
* param s_entry - Sun entry
*/
static void
sun_hsfs2amd(char *dest,
size_t destlen,
const char *key,
const struct sun_entry *s_entry)
{
/* set fstype CDFS */
xstrlcat(dest, AMD_TYPE_CDFS_KW, destlen);
/* set the cdrom device */
xstrlcat(dest, AMD_DEV_KW, destlen);
/* XXX: For now just assume that there is only one device. */
xstrlcat(dest, s_entry->location_list->path, destlen);
}
/*
* Convert a Sun NFS automount entry to an Amd. The result is concatenated
* into dest.
*
* param dest - destination buffer
* param destlen - destination buffer length
* param key - automount key
* param s_entry - Sun entry
*/
static void
sun_nfs2amd(char *dest,
size_t destlen,
const char *key,
const struct sun_entry *s_entry)
{
if (s_entry->location_list != NULL) {
/* write out the list of mountpoint locations */
sun_locations2amd(dest, destlen, key, s_entry->location_list);
}
}
/*
* Convert a Sun multi-mount point entry to an Amd. This is done
* using the Amd type auto. Each auto entry is separated with a \n.
*
* param dest - destination buffer
* param destlen - destination buffer length
* param key - automount key
* param s_entry - Sun entry
*/
static void
sun_multi2amd(char *dest,
size_t destlen,
const char *key,
const struct sun_entry *s_entry)
{
const struct sun_mountpt *mountpt;
/* We need to setup a auto fs Amd automount point. */
xstrlcat(dest, AMD_TYPE_AUTO_KW, destlen);
xstrlcat(dest, AMD_MAP_FS_KW, destlen);
xstrlcat(dest, AMD_MAP_PREF_KW, destlen);
/* write the mountpts to dest */
for (mountpt = s_entry->mountpt_list;
mountpt != NULL;
mountpt = NEXT(struct sun_mountpt, mountpt)) {
xstrlcat(dest, "\n", destlen);
/* write the key */
xstrlcat(dest, key, destlen);
/* write the mount path */
sun_append_str(dest, destlen, key, mountpt->path);
/* space */
xstrlcat(dest, " ", destlen);
/* Write all the host locations for this mount point. */
sun_locations2amd(dest, destlen, key, mountpt->location_list);
}
}
/*
* Convert the sun_entry into an Amd equivalent string.
*
* param key - automount key
* param s_entry - Sun style automap entry
*
* return - Amd entry on succes, NULL on error
*/
char *
sun_entry2amd(const char *key, const char *s_entry_str)
{
char *retval = NULL;
char line_buff[INFO_MAX_LINE_LEN];
int ws;
struct sun_entry *s_entry = NULL;
/* The key should not be NULL. */
if (key == NULL) {
plog(XLOG_ERROR,"Sun key value was null");
goto err;
}
/* The Sun entry string should never be NULL. */
if (s_entry_str == NULL) {
plog(XLOG_ERROR,"Sun entry value was null");
goto err;
}
/* Make sure there are no trailing white spaces or '\n'. */
xstrlcpy(line_buff, s_entry_str, sizeof(line_buff));
ws = strlen(line_buff) - 1;
while (ws >= 0 && (isspace((unsigned char)line_buff[ws]) || line_buff[ws] == '\n')) {
line_buff[ws--] = '\0';
}
/* Parse the sun entry line. */
s_entry = sun_map_parse_read(line_buff);
if (s_entry == NULL) {
plog(XLOG_ERROR,"could not parse Sun style map");
goto err;
}
memset(line_buff, 0, sizeof(line_buff));
if (s_entry->opt_list != NULL) {
/* write the mount options to the buffer */
sun_opts2amd(line_buff, sizeof(line_buff), key, s_entry->opt_list);
}
/* Check if this is a multi-mount entry. */
if (s_entry->mountpt_list != NULL) {
/* multi-mount point */
sun_multi2amd(line_buff, sizeof(line_buff), key, s_entry);
retval = xstrdup(line_buff);
}
else {
/* single mount point */
if (s_entry->fstype != NULL) {
if (NSTREQ(s_entry->fstype, SUN_NFS_TYPE, strlen(SUN_NFS_TYPE))) {
/* NFS Type */
sun_nfs2amd(line_buff, sizeof(line_buff), key, s_entry);
retval = xstrdup(line_buff);
}
else if (NSTREQ(s_entry->fstype, SUN_HSFS_TYPE, strlen(SUN_HSFS_TYPE))) {
/* HSFS Type (CD fs) */
sun_hsfs2amd(line_buff, sizeof(line_buff), key, s_entry);
retval = xstrdup(line_buff);
}
/*
* XXX: The following fstypes are not yet supported.
*/
else if (NSTREQ(s_entry->fstype, SUN_AUTOFS_TYPE, strlen(SUN_AUTOFS_TYPE))) {
/* AutoFS Type */
plog(XLOG_ERROR, "Sun fstype %s is currently not supported by Amd.",
s_entry->fstype);
goto err;
}
else if (NSTREQ(s_entry->fstype, SUN_CACHEFS_TYPE, strlen(SUN_CACHEFS_TYPE))) {
/* CacheFS Type */
plog(XLOG_ERROR, "Sun fstype %s is currently not supported by Amd.",
s_entry->fstype);
goto err;
}
else {
plog(XLOG_ERROR, "Sun fstype %s is currently not supported by Amd.",
s_entry->fstype);
goto err;
}
}
else {
plog(XLOG_INFO, "No SUN fstype specified defaulting to NFS.");
sun_nfs2amd(line_buff, sizeof(line_buff), key, s_entry);
retval = xstrdup(line_buff);
}
}
err:
XFREE(s_entry);
return retval;
}

View File

@ -1,123 +0,0 @@
/*
* Copyright (c) 1997-2014 Erez Zadok
* Copyright (c) 2005 Daniel P. Ottavio
* 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. 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.
*
*
* File: am-utils/amd/sun_map.h
*
*/
#ifndef _SUN_MAP_H
#define _SUN_MAP_H
/* host */
struct sun_host {
qelem head; /* link-list header */
char *name; /* hostname */
int weight; /* weight given to the host */
};
/* location */
struct sun_location {
qelem head; /* link-list header */
char *path; /* server path */
struct sun_host *host_list; /* list of hosts */
};
/* sun mount option */
struct sun_opt {
qelem head; /* link-list header */
char *str; /* option string */
};
/* mount point */
struct sun_mountpt {
qelem head; /* link-list header */
char *path; /* optional mount point path */
char *fstype; /* filesystem type */
struct sun_opt *opt_list; /* list of option strings */
struct sun_location *location_list; /* list of 'struct s2a_location' */
};
/* automount entry */
struct sun_entry {
qelem head; /* link-list header */
char *key; /* auto map key */
char *fstype; /* filesystem type */
struct sun_opt *opt_list; /* list of mount options */
struct sun_location *location_list; /* list of mount locations */
struct sun_mountpt *mountpt_list; /* list of mount points */
};
/*
* automount map file
*
* XXX: Only a place holder structure, not implemented yet.
*/
struct sun_map {
qelem head; /* link-list header */
char *path; /* directory path of the map file */
char *mount_dir; /* top level mount point for this map */
int lookup; /* lookup type i.e file, yp, program, etc. */
int direct_bool; /* set true if this map is a direct map */
struct sun_opt *opt_list; /* list of global map options */
struct sun_opt *include_list; /* list of included map files */
struct sun_entry *entry_list; /* list of 'struct s2a_entry' */
};
/*
* master map file
*
* XXX: Only a place holder structure, not implemented yet.
*/
struct sun_mmap {
qelem head; /* link-list header */
struct sun_opt *include_list; /* list of included master maps */
struct sun_map *amap_list; /* list of 'struct s2a_amap' */
};
struct sun_list {
qelem *first;
qelem *last;
};
/*
* EXTERNS
*/
extern char *sun_entry2amd(const char *, const char *);
extern struct sun_entry *sun_map_parse_read(const char *);
extern void sun_list_add(struct sun_list *, qelem *);
#endif /* not _SUN_MAP_H */

View File

@ -1,492 +0,0 @@
%{
/*
* Copyright (c) 1997-2014 Erez Zadok
* Copyright (c) 2005 Daniel P. Ottavio
* 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. 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.
*
*
* File: am-utils/amd/sun_map_parse.y
*
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
#include <sun_map.h>
#define SUN_FSTYPE_STR "fstype="
extern int sun_map_lex(void);
extern int sun_map_error(const char *);
extern void sun_map_tok_setbuff(const char *);
extern int sun_map_parse(void);
struct sun_entry *sun_map_parse_read(const char *);
static struct sun_list *sun_entry_list = NULL;
static struct sun_list *sun_opt_list = NULL;
static struct sun_list *sun_host_list = NULL;
static struct sun_list *sun_location_list = NULL;
static struct sun_list *mountpt_list = NULL;
static char *tmpFsType = NULL;
/*
* Each get* function returns a pointer to the corresponding global
* list structure. If the structure is NULL than a new instance is
* returned.
*/
static struct sun_list *get_sun_opt_list(void);
static struct sun_list *get_sun_host_list(void);
static struct sun_list *get_sun_location_list(void);
static struct sun_list *get_mountpt_list(void);
static struct sun_list *get_sun_entry_list(void);
%}
%union {
char strval[2048];
}
%token NEWLINE COMMENT WSPACE
%token <strval> WORD
%%
amap : file
;
file : new_lines entries
| entries
;
entries : entry
| entry new_lines
| entry new_lines entries
;
new_lines : NEWLINE
| NEWLINE new_lines
;
entry : locations {
struct sun_list *list;
struct sun_entry *entry;
/* allocate an entry */
entry = CALLOC(struct sun_entry);
/*
* Assign the global location list to this entry and reset the
* global pointer. Reseting the global pointer will create a new
* list instance next time get_sun_location_list() is called.
*/
list = get_sun_location_list();
entry->location_list = (struct sun_location *)list->first;
sun_location_list = NULL;
/* Add this entry to the entry list. */
sun_list_add(get_sun_entry_list(), (qelem *)entry);
}
| '-' options WSPACE locations {
struct sun_list *list;
struct sun_entry *entry;
entry = CALLOC(struct sun_entry);
/* An fstype may have been defined in the 'options'. */
if (tmpFsType != NULL) {
entry->fstype = tmpFsType;
tmpFsType = NULL;
}
/*
* Assign the global location list to this entry and reset the
* global pointer. Reseting the global pointer will create a new
* list instance next time get_sun_location_list() is called.
*/
list = get_sun_location_list();
entry->location_list = (struct sun_location *)list->first;
sun_location_list = NULL;
/*
* Assign the global opt list to this entry and reset the global
* pointer. Reseting the global pointer will create a new list
* instance next time get_sun_opt_list() is called.
*/
list = get_sun_opt_list();
entry->opt_list = (struct sun_opt *)list->first;
sun_opt_list = NULL;
/* Add this entry to the entry list. */
sun_list_add(get_sun_entry_list(), (qelem *)entry);
}
| mountpoints {
struct sun_list *list;
struct sun_entry *entry;
/* allocate an entry */
entry = CALLOC(struct sun_entry);
/*
* Assign the global mountpt list to this entry and reset the global
* pointer. Reseting the global pointer will create a new list
* instance next time get_mountpt_list() is called.
*/
list = get_mountpt_list();
entry->mountpt_list = (struct sun_mountpt *)list->first;
mountpt_list = NULL;
/* Add this entry to the entry list. */
sun_list_add(get_sun_entry_list(), (qelem *)entry);
}
| '-' options WSPACE mountpoints {
struct sun_list *list;
struct sun_entry *entry;
/* allocate an entry */
entry = CALLOC(struct sun_entry);
/* An fstype may have been defined in the 'options'. */
if (tmpFsType != NULL) {
entry->fstype = tmpFsType;
tmpFsType = NULL;
}
/*
* Assign the global mountpt list to this entry and reset the global
* pointer. Reseting the global pointer will create a new list
* instance next time get_mountpt_list() is called.
*/
list = get_mountpt_list();
entry->mountpt_list = (struct sun_mountpt *)list->first;
mountpt_list = NULL;
/*
* Assign the global opt list to this entry and reset the global
* pointer. Reseting the global pointer will create a new list
* instance next time get_sun_opt_list() is called.
*/
list = get_sun_opt_list();
entry->opt_list = (struct sun_opt *)list->first;
sun_opt_list = NULL;
/* Add this entry to the entry list. */
sun_list_add(get_sun_entry_list(), (qelem *)entry);
}
;
mountpoints : mountpoint
| mountpoint WSPACE mountpoints
;
mountpoint : WORD WSPACE location {
struct sun_list *list;
struct sun_mountpt *mountpt;
/* allocate a mountpt */
mountpt = CALLOC(struct sun_mountpt);
/*
* Assign the global loaction list to this entry and reset the
* global pointer. Reseting the global pointer will create a new
* list instance next time get_sun_location_list() is called.
*/
list = get_sun_location_list();
mountpt->location_list = (struct sun_location *)list->first;
sun_location_list = NULL;
mountpt->path = xstrdup($1);
/* Add this mountpt to the mountpt list. */
sun_list_add(get_mountpt_list(), (qelem *)mountpt);
}
| WORD WSPACE '-' options WSPACE location {
struct sun_list *list;
struct sun_mountpt *mountpt;
/* allocate a mountpt */
mountpt = CALLOC(struct sun_mountpt);
/* An fstype may have been defined in the 'options'. */
if (tmpFsType != NULL) {
mountpt->fstype = tmpFsType;
tmpFsType = NULL;
}
/*
* Assign the global location list to this entry and reset the
* global pointer. Reseting the global pointer will create a new
* list instance next time get_sun_location_list() is called.
*/
list = get_sun_location_list();
mountpt->location_list = (struct sun_location *)list->first;
sun_location_list = NULL;
/*
* Assign the global opt list to this entry and reset the global
* pointer. Reseting the global pointer will create a new list
* instance next time get_sun_opt_list() is called.
*/
list = get_sun_opt_list();
mountpt->opt_list = (struct sun_opt *)list->first;
sun_opt_list = NULL;
mountpt->path = xstrdup($1);
/* Add this mountpt to the mountpt list. */
sun_list_add(get_mountpt_list(), (qelem *)mountpt);
}
;
locations : location
| location WSPACE locations
;
location : hosts ':' WORD {
struct sun_list *list;
struct sun_location *location;
/* allocate a new location */
location = CALLOC(struct sun_location);
/*
* Assign the global opt list to this entry and reset the global
* pointer. Reseting the global pointer will create a new list
* instance next time get_sun_opt_list() is called.
*/
list = get_sun_host_list();
location->host_list = (struct sun_host *)list->first;
sun_host_list = NULL;
location->path = xstrdup($3);
/* Add this location to the location list. */
sun_list_add(get_sun_location_list(), (qelem *)location);
}
| ':' WORD {
struct sun_location *location;
/* allocate a new location */
location = CALLOC(struct sun_location);
location->path = xstrdup($2);
/* Add this location to the location list. */
sun_list_add(get_sun_location_list(), (qelem *)location);
}
;
hosts : host
| host ',' hosts
;
host : WORD {
/* allocate a new host */
struct sun_host *host = CALLOC(struct sun_host);
host->name = xstrdup($1);
/* Add this host to the host list. */
sun_list_add(get_sun_host_list(),(qelem *)host);
}
| WORD weight {
/*
* It is assumed that the host for this rule was allocated by the
* 'weight' rule and assigned to be the last host item on the host
* list.
*/
struct sun_host *host = (struct sun_host *)sun_host_list->last;
host->name = xstrdup($1);
}
;
weight : '(' WORD ')' {
int val;
/* allocate a new host */
struct sun_host *host = CALLOC(struct sun_host);
val = atoi($2);
host->weight = val;
/* Add this host to the host list. */
sun_list_add(get_sun_host_list(), (qelem *)host);
}
;
options : option
| option ',' options
;
option : WORD {
char *type;
/* check if this is an fstype option */
if ((type = strstr($1,SUN_FSTYPE_STR)) != NULL) {
/* parse out the fs type from the Sun fstype keyword */
if ((type = type + strlen(SUN_FSTYPE_STR)) != NULL) {
/*
* This global fstype str will be assigned to the current being
* parsed later in the parsing.
*/
tmpFsType = xstrdup(type);
}
}
else {
/*
* If it is not an fstype option allocate an opt struct and assign
* the value.
*/
struct sun_opt *opt = CALLOC(struct sun_opt);
opt->str = xstrdup($1);
/* Add this opt to the opt list. */
sun_list_add(get_sun_opt_list(), (qelem *)opt);
}
}
;
%%
/*
* Parse 'map_data' which is assumed to be a Sun-syle map. If
* successful a sun_entry is returned.
*
* The parser is designed to parse map entries with out the keys. For
* example the entry:
*
* usr -ro pluto:/usr/local
*
* should be passed to the parser as:
*
* -ro pluto:/usr/local
*
* The reason for this is that the Amd info services already strip off
* the key when they read map info.
*/
struct sun_entry *
sun_map_parse_read(const char *map_data)
{
struct sun_entry *retval = NULL;
/* pass map_data to lex */
sun_map_tok_setbuff(map_data);
/* call yacc */
sun_map_parse();
if (sun_entry_list != NULL) {
/* return the first Sun entry in the list */
retval = (struct sun_entry*)sun_entry_list->first;
sun_entry_list = NULL;
}
else {
plog(XLOG_ERROR, "Sun map parser did not produce data structs.");
}
return retval;
}
static struct sun_list *
get_sun_entry_list(void)
{
if (sun_entry_list == NULL) {
sun_entry_list = CALLOC(struct sun_list);
}
return sun_entry_list;
}
static struct sun_list *
get_mountpt_list(void)
{
if (mountpt_list == NULL) {
mountpt_list = CALLOC(struct sun_list);
}
return mountpt_list;
}
static struct sun_list *
get_sun_location_list(void)
{
if (sun_location_list == NULL) {
sun_location_list = CALLOC(struct sun_list);
}
return sun_location_list;
}
static struct sun_list *
get_sun_host_list(void)
{
if (sun_host_list == NULL) {
sun_host_list = CALLOC(struct sun_list);
}
return sun_host_list;
}
static struct sun_list *
get_sun_opt_list(void)
{
if (sun_opt_list == NULL) {
sun_opt_list = CALLOC(struct sun_list);
}
return sun_opt_list;
}

View File

@ -1,233 +0,0 @@
%{
/*
* Copyright (c) 1997-2014 Erez Zadok
* Copyright (c) 2005 Daniel P. Ottavio
* 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. 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.
*
*
* File: am-utils/amd/sun_map_tok.l
*
*/
#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 <sun_map_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 using GNU flex.
* These must not be defined if using standard lex
*/
#ifdef FLEX_SCANNER
# ifndef ECHO
# define ECHO __IGNORE(fwrite( yytext, yyleng, 1, yyout ))
# endif /* not ECHO */
#endif /* FLEX_SCANNER */
int yylex(void);
int sun_map_error(const char *);
/*
* We need to configure lex to parse from a string
* instead of a file. Each version of lex has it's
* own way of doing this (sigh).
*/
/* assign the buffer to parse */
void sun_map_tok_setbuff(const char* buff);
/* buffer that contains the string to parse */
const char *sun_map_tok_buff = NULL;
#ifdef FLEX_SCANNER
/*
* The flex scanner uses the YY_INPUT to parse the input.
* We need to redefine it so that it can parse strings.
* In addition to the above string buffer we need to have
* a position pointer and a end pointer.
*/
/* current position of the buffer */
const char *sun_map_tok_pos = NULL;
/* size of the buffer */
const char *sun_map_tok_end = NULL;
/* copies the current position + maxsize into buff */
int sun_map_input(char *buff, int maxsize);
# undef YY_INPUT
# define YY_INPUT(buff,result,maxsize) (result = sun_map_input(buff,maxsize))
#else
/*
* If this is not Flex than fall back to an AT&T style lex.
* We can parse strings by redefining input and unput.
*/
#undef input
#undef unput
#define input() (*(char *)sun_map_tok_buff++)
#define unput(c) (*(char *)--sun_map_tok_buff = c)
#endif /* FLEX_SCANNER */
/*
* 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.
*/
#if !defined(yywrap) || defined(yylex)
int yywrap(void);
#endif /* not yywrap or yylex */
/* no need to use yywrap() */
#define YY_SKIP_YYWRAP
int sun_map_line = 1;
int sun_map_tokpos = 1;
%}
/* This option causes Solaris lex to fail. Use flex. See BUGS file */
/* no need to use yyunput() */
%option nounput
%option noinput
/* allocate more output slots so lex scanners don't run out of mem */
%o 1024
WORD_REX [A-Za-z0-9_/&\.$=]+[A-Za-z0-9_/&\.$=-]*
COMMENT_REX ^#.*\n
WSPACE_REX [ \t]*
NEWLINE_REX [ \t]*\n
CONTINUE_REX "\\"\n
%%
{WORD_REX} {
sun_map_tokpos += yyleng;
xstrlcpy((char *)sun_map_lval.strval,(const char *)yytext,sizeof(sun_map_lval.strval));
return WORD;
}
{WSPACE_REX} {
sun_map_tokpos += yyleng;
return WSPACE;
}
{NEWLINE_REX} {
sun_map_tokpos = 0;
sun_map_line++;
return NEWLINE;
}
{CONTINUE_REX} {
sun_map_tokpos = 0;
sun_map_line++;
}
{COMMENT_REX} {
sun_map_line++;
}
. {
return yytext[0];
}
%%
int
sun_map_error(const char* s)
{
return 1;
}
#ifdef FLEX_SCANNER
void
sun_map_tok_setbuff(const char* buff)
{
sun_map_tok_end = buff + strlen(buff);
sun_map_tok_pos = buff;
sun_map_tok_buff = buff;
}
int
sun_map_input(char *buff, int maxsize)
{
int size = MIN(maxsize, (sun_map_tok_end - sun_map_tok_pos));
if (size > 0) {
memcpy(buff,sun_map_tok_pos,size);
sun_map_tok_pos += size;
}
return size;
}
#else
void
sun_map_tok_setbuff(const char* buff)
{
sun_map_tok_buff = buff;
}
#endif /* FLEX_SCANNER */
/*
* 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.
*/
#if !defined(yywrap) || defined(yylex)
int yywrap(void)
{
return 1;
}
#endif /* not yywrap or yylex */

View File

@ -1,2 +0,0 @@
#!/bin/sh
./amd -v 2> /dev/null

View File

@ -1,307 +0,0 @@
.\"
.\" Copyright (c) 1997-2014 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. 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.
.\"
.\"
.\" File: am-utils/amq/amq.8
.\" $FreeBSD$
.\"
.Dd August 31, 2016
.Dt AMQ 8
.Os
.Sh NAME
.Nm amq
.Nd automounter query tool
.Sh SYNOPSIS
.Nm
.Op Fl fimpqsvwHTU
.Op Fl h Ar hostname
.Op Fl l Ar log_file
.Op Fl x Ar log_options
.Op Fl D Ar debug_options
.Op Fl P Ar program_number
.Op Oo Fl u Oc Ar directory ...
.Sh DESCRIPTION
.Bf -symbolic
This command is obsolete.
Users are advised to use
.Xr autofs 5
instead.
.Ef
.Pp
The
.Nm
utility
provides a simple way of determining the current state of the
.Xr amd 8
program.
Communication is by
.Tn RPC .
Three modes of operation are supported by the current protocol.
By default
a list of mount points and auto-mounted file systems is output.
An
alternative host can be specified using the
.Fl h
option.
.Pp
If
.Ar directory
names are given, as output by default, then per file system
information is displayed.
.Sh OPTIONS
.Bl -tag -width indent
.It Fl f
Ask the automounter to flush the internal caches and reload all the maps.
.It Fl h Ar hostname
Specify an alternate host to query.
By default the local host is used.
In
an
.Tn HP-UX
cluster, the root server is queried by default, since that is the system on
which the automounter is normally run.
.TP
.It Fl i
Print information about the mount maps.
.TP
.It Fl l Ar log_file
Tell
.Xr amd 8
to use
.Ar log_file
as the log file name.
For security reasons, this must be the same log file
which
.Xr amd 8
used when started.
This option is therefore only useful to
refresh
.Nm amd Ns 's
open file handle on the log file, so that it can be rotated
and compressed via daily cron jobs.
.It Fl m
Ask the automounter to provide a list of mounted file systems, including the
number of references to each file system and any error which occurred while
mounting.
.It Fl p
Return the process ID of the remote or locally running
.Xr amd 8 .
Useful when you
need to send a signal to the local
.Xr amd 8
process, and would rather not have to
search through the process table.
This option is used in the
.Pa ctl-amd
script.
.TP
.It Fl q
Suppress error messages produced when attempting synchronous unmounts
with the
.B \-u
option.
.TP
.It Fl s
Ask the automounter to provide system-wide mount statistics.
.It Fl u
Ask the automounter to unmount the file systems named in
.Ar directory
instead of providing
information about them.
Unmounts are requested, not forced.
They merely
cause the mounted file system to timeout, which will be picked up by
.Nm amd Ns 's
main scheduler thus causing the normal timeout action to be taken.
If the
.B \-u
option is repeated,
.B amq
will attempt to unmount the file system synchronously by waiting until
the timeout action is taken and returning an error if the unmount
fails.
Any error messages produced may be suppressed with the
.B \-q
option.
.TP
.It Fl v
Ask the automounter for its version information. This is a subset of the
information output by
.Xr amd 8 Ns 's
.Fl v
option.
.It Fl w
Translate a full pathname as returned by
.Xr getcwd 3
into a short
.Xr amd 8
pathname that goes through its mount points.
This option requires that
.Xr amd 8
is running.
.It Fl x Ar log_options
Ask the automounter to use the logging options specified in
.Ar log_options
from now on. Note that the "fatal" and "error" options cannot be turned
off.
.It Fl D Ar debug_options
.BI \-D " debug_options"
Ask the automounter to use the debugging options specified in
.Ar debug_options
from now on.
.It Fl H
Display short usage message.
.It Fl P Ar program_number
Contact an alternate running
.Xr amd 8
that had registered itself on a different
.Tn RPC
.Ar program_number
and apply all other operations to that instance of the automounter.
This is
useful when you run multiple copies of
.Xr amd 8 ,
and need to manage each
one separately.
If not specified,
.Nm
will use the default program number for
.Xr amd 8 ,
300019.
For security reasons, the only alternate program numbers
.Xr amd 8
can use range from 300019 to 300029, inclusive.
.It Fl T
Contact
.Xr amd 8
using the TCP transport only.
Normally
.Nm
will try TCP, and if that failed, will try UDP.
.It Fl U
Contact
.Xr amd 8
using UDP (connectionless) transport only.
Normally
.Nm
will try TCP, and if that failed, will try UDP.
.El
.Sh FILES
.Bl -tag -width ".Pa amq.x" -compact
.It Pa amq.x
.Tn RPC
protocol description.
.El
.Sh CAVEATS
The
.Nm
utility
uses a Sun registered
.Tn RPC
program number (300019 decimal) which may not
be in the
.Xr rpc 5
database.
.Pp
If the TCP wrappers library is available, and the
.Va use_tcpwrappers
global
.Xr amd.conf 5
option is set to
.Dq Li yes ,
then
.Xr amd 8
will verify that the host running
.Nm
is authorized to connect.
The
.Dq Li amd
service name must be used in the
.Pa /etc/hosts.allow
and
.Pa /etc/hosts.deny
files.
For example, to allow only localhost to connect to
.Xr amd 8 ,
add this line to
.Pa /etc/hosts.allow :
.Pp
.Dl "amd: localhost"
.Pp
and this line to
.Pa /etc/hosts.deny :
.Pp
.RS
.Dl "amd: ALL"
.Sh SEE ALSO
.Xr amd.conf 5 ,
.Xr hosts_access 5 .
.Xr amd 8 ,
.\" .Xr ctl-amd 8 ,
.Pp
.Dq am-utils
.Xr info 1
entry.
.Rs
.%A Erez Zadok
.%B "Linux NFS and Automounter Administration"
.%O ISBN 0-7821-2739-8
.%I Sybex
.%D 2001
.Re
.Pp
.Pa http://www.am-utils.org/
.Rs
.%T Amd \- The 4.4 BSD Automounter
.Re
.Sh HISTORY
The
.Nm
utility
first appeared in
.Bx 4.4 .
.Sh AUTHORS
.An Jan-Simon Pendry Aq jsp@doc.ic.ac.uk ,
Department of Computing, Imperial College, London, UK.
.Pp
.An Erez Zadok Aq ezk@cs.sunysb.edu ,
Computer Science Department, Stony Brook
University, Stony Brook, New York, USA.
.Pp
Other authors and contributors to
.Nm am-utils
are listed in the
.Pa AUTHORS
file distributed with
.Nm am-utils .

View File

@ -1,851 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amq/amq.c
*
*/
/*
* Automounter query tool
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amq.h>
/* locals */
static int flush_flag;
static int getpid_flag;
static int getpwd_flag;
static int getvers_flag;
static int minfo_flag;
static int mapinfo_flag;
static int quiet_flag;
static int stats_flag;
static int unmount_flag;
static int use_tcp_flag;
static int use_udp_flag;
static u_long amd_program_number = AMQ_PROGRAM;
static char *debug_opts;
static char *amq_logfile;
static char *xlog_optstr;
static char localhost[] = "localhost";
static char *def_server = localhost;
/* externals */
extern int optind;
extern char *optarg;
/* structures */
enum show_opt {
Full, Stats, Calc, Short, ShowDone
};
static void
time_print(time_type tt)
{
time_t t = (time_t)(intptr_t)tt;
struct tm *tp = localtime(&t);
printf("%02d/%02d/%04d %02d:%02d:%02d",
tp->tm_mon + 1, tp->tm_mday,
tp->tm_year < 1900 ? tp->tm_year + 1900 : tp->tm_year,
tp->tm_hour, tp->tm_min, tp->tm_sec);
}
/*
* 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:
{
printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d",
*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);
time_print(mt->mt_mounttime);
printf("\n");
}
break;
case Stats:
{
printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d ",
*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);
time_print(mt->mt_mounttime);
printf("\n");
}
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 pwd data
*/
static void
show_pwd(amq_mount_tree *mt, char *path, size_t l, int *flag)
{
int len;
while (mt) {
len = strlen(mt->mt_mountpoint);
if (NSTREQ(path, mt->mt_mountpoint, len) &&
!STREQ(mt->mt_directory, mt->mt_mountpoint)) {
char buf[MAXPATHLEN+1]; /* must be same size as 'path' */
xstrlcpy(buf, mt->mt_directory, sizeof(buf));
xstrlcat(buf, &path[len], sizeof(buf));
xstrlcpy(path, buf, l);
*flag = 1;
}
show_pwd(mt->mt_next, path, l, flag);
mt = mt->mt_child;
}
}
/*
* 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)
{
u_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) {
printf(" (%s)", strerror(mi->mi_error));
} else if (mi->mi_error < 0) {
fputs(" (in progress)", stdout);
}
fputc('\n', stdout);
}
}
break;
default:
break;
}
}
static void
show_map(amq_map_info *mi)
{
}
static void
show_mapinfo(amq_map_info_list *ml, enum show_opt e, int *nwid, int *wwid)
{
u_int i;
switch (e) {
case Calc:
{
for (i = 0; i < ml->amq_map_info_list_len; i++) {
amq_map_info *mi = &ml->amq_map_info_list_val[i];
int nw = strlen(mi->mi_name);
int ww = strlen(mi->mi_wildcard ? mi->mi_wildcard : "(null");
if (nw > *nwid)
*nwid = nw;
if (ww > *wwid)
*wwid = ww;
}
}
break;
case Full:
{
printf("%-*.*s %-*.*s %-8.8s %-7.7s %-7.7s %-7.7s %-s Modified\n",
*nwid, *nwid, "Name",
*wwid, *wwid, "Wild",
"Flags", "Refcnt", "Entries", "Reloads", "Stat");
for (i = 0; i < ml->amq_map_info_list_len; i++) {
amq_map_info *mi = &ml->amq_map_info_list_val[i];
printf("%-*.*s %*.*s %-8x %-7d %-7d %-7d %s ",
*nwid, *nwid, mi->mi_name,
*wwid, *wwid, mi->mi_wildcard,
mi->mi_flags, mi->mi_refc, mi->mi_nentries, mi->mi_reloads,
mi->mi_up == -1 ? "root" : (mi->mi_up ? " up" : "down"));
time_print(mi->mi_modify);
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) */
static void
print_umnt_error(amq_sync_umnt *rv, const char *fs)
{
switch (rv->au_etype) {
case AMQ_UMNT_OK:
break;
case AMQ_UMNT_FAILED:
printf("unmount failed: %s\n", strerror(rv->au_errno));
break;
case AMQ_UMNT_FORK:
if (rv->au_errno == 0)
printf("%s is not mounted\n", fs);
else
printf("falling back to asynchronous unmount: %s\n",
strerror(rv->au_errno));
break;
case AMQ_UMNT_READ:
printf("pipe read error: %s\n", strerror(rv->au_errno));
break;
case AMQ_UMNT_SERVER:
printf("amd server down\n");
break;
case AMQ_UMNT_SIGNAL:
printf("got signal: %d\n", rv->au_signal);
break;
/*
* Omit default so the compiler can check for missing cases.
*
default:
break;
*/
}
}
static int
amu_sync_umnt_to_retval(amq_sync_umnt *rv)
{
switch (rv->au_etype) {
case AMQ_UMNT_FORK:
if (rv->au_errno == 0) {
/*
* We allow this error so that things like:
* amq -uu /l/cd0d && eject cd0
* will work when /l/cd0d is not mounted.
* XXX - We still print an error message.
*/
return 0;
}
/*FALLTHROUGH*/
default:
return rv->au_etype;
}
}
static int
clnt_failed(CLIENT *clnt, char *server)
{
fprintf(stderr, "%s: ", am_get_progname());
clnt_perror(clnt, server);
return 1;
}
/*
* MAIN
*/
int
main(int argc, char *argv[])
{
int opt_ch;
int errs = 0;
char *server;
struct sockaddr_in server_addr;
CLIENT *clnt = NULL;
struct hostent *hp;
int nodefault = 0;
struct timeval tv;
char *progname = NULL;
/*
* Compute program name
*/
if (argv[0]) {
progname = strrchr(argv[0], '/');
if (progname && progname[1])
progname++;
else
progname = argv[0];
}
if (!progname)
progname = "amq";
am_set_progname(progname);
/*
* Parse arguments
*/
while ((opt_ch = getopt(argc, argv, "Hfh:il:mqsuvx:D:pP:TUw")) != -1)
switch (opt_ch) {
case 'H':
goto show_usage;
break;
case 'f':
flush_flag = 1;
nodefault = 1;
break;
case 'h':
def_server = optarg;
break;
case 'i':
mapinfo_flag = 1;
nodefault = 1;
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 'q':
quiet_flag = 1;
nodefault = 1;
break;
case 's':
stats_flag = 1;
nodefault = 1;
break;
case 'u':
unmount_flag++;
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 'P':
amd_program_number = atoi(optarg);
break;
case 'T':
use_tcp_flag = 1;
break;
case 'U':
use_udp_flag = 1;
break;
case 'w':
getpwd_flag = 1;
break;
default:
errs = 1;
break;
}
if (optind == argc) {
if (unmount_flag)
errs = 1;
}
if (errs) {
show_usage:
fprintf(stderr, "\
Usage: %s [-fimpqsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\
\t[-x log_options] [-D debug_options]\n\
\t[-P program_number] [[-u[u]] directory ...]\n",
am_get_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",
am_get_progname(), server);
exit(1);
}
memset(&server_addr, 0, sizeof(server_addr));
/* as per POSIX, sin_len need not be set (used internally by kernel) */
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;
if (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);
}
if (!clnt) {
fprintf(stderr, "%s: ", am_get_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",
am_get_progname());
errs = 1;
} else if (!rc || *rc > 0) {
fprintf(stderr, "%s: debug setting for \"%s\" failed\n",
am_get_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",
am_get_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",
am_get_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",
am_get_progname(), server);
errs = 1;
}
}
/*
* getpwd info
*/
if (getpwd_flag) {
char path[MAXPATHLEN+1];
char *wd;
amq_mount_tree_list *mlp;
amq_mount_tree_p mt;
u_int i;
int flag;
wd = getcwd(path, MAXPATHLEN+1);
if (!wd) {
fprintf(stderr, "%s: getcwd failed (%s)", am_get_progname(),
strerror(errno));
exit(1);
}
mlp = amqproc_export_1((voidp) 0, clnt);
for (i = 0; mlp && i < mlp->amq_mount_tree_list_len; i++) {
mt = mlp->amq_mount_tree_list_val[i];
while (1) {
flag = 0;
show_pwd(mt, path, sizeof(path), &flag);
if (!flag) {
printf("%s\n", path);
break;
}
}
}
exit(0);
}
/*
* 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",
am_get_progname(), server);
}
}
/*
* Map
*/
if (mapinfo_flag) {
int dummy;
amq_map_info_list *ml = amqproc_getmapinfo_1(&dummy, clnt);
if (ml) {
int mwid = 0, wwid = 0;
show_mapinfo(ml, Calc, &mwid, &wwid);
mwid++;
if (wwid)
wwid++;
show_mapinfo(ml, Full, &mwid, &wwid);
} else {
fprintf(stderr, "%s: amd on %s cannot provide map info\n",
am_get_progname(), server);
}
}
/*
* 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",
am_get_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", am_get_progname());
errs = 1;
}
}
/*
* Apply required operation to all remaining arguments
*/
if (optind < argc) {
do {
char *fs = argv[optind++];
if (unmount_flag > 1) {
amq_sync_umnt *sup;
/*
* Synchronous unmount request
*/
sup = amqproc_sync_umnt_1(&fs, clnt);
if (sup) {
if (quiet_flag == 0)
print_umnt_error(sup, fs);
errs = amu_sync_umnt_to_retval(sup);
} else {
errs = clnt_failed(clnt, server);
}
} else 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", am_get_progname(), fs);
}
xdr_pri_free((XDRPROC_T_TYPE) xdr_amq_mount_tree_p, (caddr_t) mtp);
} else {
errs = clnt_failed(clnt, server);
}
}
} 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 {
errs = clnt_failed(clnt, server);
}
} 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) {
u_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 {
errs = clnt_failed(clnt, server);
}
}
exit(errs);
return errs; /* should never reach here */
}

View File

@ -1,61 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amq/amq.h
*
*/
#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_sync_umnt *amqproc_sync_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 amq_map_info_list *amqproc_getmapinfo_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);
extern amq_string *amqproc_pawd_1(amq_string *argp, CLIENT *rqstp);
#endif /* not _AMQ_H */

View File

@ -1,250 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amq/amq_clnt.c
*
*/
#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_sync_umnt *
amqproc_sync_umnt_1(amq_string *argp, CLIENT *clnt)
{
static amq_sync_umnt res;
enum clnt_stat rv;
memset((char *) &res, 0, sizeof(res));
if ((rv = clnt_call(clnt, AMQPROC_SYNC_UMNT,
(XDRPROC_T_TYPE) xdr_amq_string, (SVC_IN_ARG_TYPE) argp,
(XDRPROC_T_TYPE) xdr_amq_sync_umnt, (SVC_IN_ARG_TYPE) &res,
TIMEOUT)) != RPC_SUCCESS) {
return (NULL);
}
return &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);
}
amq_map_info_list *
amqproc_getmapinfo_1(voidp argp, CLIENT *clnt)
{
static amq_map_info_list res;
memset((char *) &res, 0, sizeof(res));
if (clnt_call(clnt, AMQPROC_GETMAPINFO, (XDRPROC_T_TYPE) xdr_void, argp,
(XDRPROC_T_TYPE) xdr_amq_map_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);
}
amq_string *
amqproc_pawd_1(amq_string *argp, CLIENT *clnt)
{
static amq_string res;
memset((char *) &res, 0, sizeof(res));
if (clnt_call(clnt, AMQPROC_PAWD,
(XDRPROC_T_TYPE) xdr_amq_string, (SVC_IN_ARG_TYPE) argp,
(XDRPROC_T_TYPE) xdr_amq_string, (SVC_IN_ARG_TYPE) &res,
TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&res);
}

View File

@ -1,316 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amq/amq_xdr.c
*
*/
#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 **) ((voidp) &objp->mt_next),
sizeof(amq_mount_tree),
(XDRPROC_T_TYPE) xdr_amq_mount_tree)) {
return (FALSE);
}
if (!xdr_pointer(xdrs,
(char **) ((voidp) &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 **) ((voidp) &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_map_info(XDR *xdrs, amq_map_info *objp)
{
if (!xdr_amq_string(xdrs, &objp->mi_name)) {
return (FALSE);
}
if (!xdr_amq_string(xdrs, &objp->mi_wildcard)) {
return (FALSE);
}
if (!xdr_time_type(xdrs, &objp->mi_modify)) {
return (FALSE);
}
if (!xdr_int(xdrs, &objp->mi_flags)) {
return (FALSE);
}
if (!xdr_int(xdrs, &objp->mi_nentries)) {
return (FALSE);
}
if (!xdr_int(xdrs, &objp->mi_reloads)) {
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_map_info_list(XDR *xdrs, amq_map_info_list *objp)
{
if (!xdr_array(xdrs,
(char **) ((voidp) &objp->amq_map_info_list_val),
(u_int *) &objp->amq_map_info_list_len,
~0,
sizeof(amq_map_info),
(XDRPROC_T_TYPE) xdr_amq_map_info)) {
return (FALSE);
}
return (TRUE);
}
bool_t
xdr_amq_mount_tree_list(XDR *xdrs, amq_mount_tree_list *objp)
{
if (!xdr_array(xdrs,
(char **) ((voidp) &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));
}

View File

@ -1,111 +0,0 @@
.\"
.\" Copyright (c) 1997-2014 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. 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.
.\"
.\"
.\" File: am-utils/amq/pawd.1
.\" $FreeBSD$
.\"
.Dd February 26, 2016
.Dt PAWD 1
.Os
.Sh NAME
.Nm pawd
.Nd print automounter working directory
.Sh SYNOPSIS
.Nm
.Op Ar path ...
.Sh DESCRIPTION
.Bf -symbolic
This command is obsolete.
Users are advised to use
.Xr autofs 5
instead.
.Ef
.Pp
The
.Nm
utility
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
.Xr amd 8 Ns 's
local mount points.
Using them is unsafe, because
.Xr amd 8
may unmount managed file systems from the mount points, and thus including
them in paths may not always find the files within.
.Pp
Without any arguments,
.Nm
will print the automounter adjusted current working directory.
With any
number of arguments, it will print the adjusted
.Ar path
of each one of the
arguments.
.Sh SEE ALSO
.Xr pwd 1 ,
.Xr amd 8 ,
.Xr amq 8
.Pp
.Dq am-utils
.Xr info 1
entry.
.Rs
.%A Erez Zadok
.%B "Linux NFS and Automounter Administration"
.%O ISBN 0-7821-2739-8
.%I Sybex
.%D 2001
.Re
.Pp
.Pa http://www.am-utils.org/
.Rs
.%T Amd \- The 4.4 BSD Automounter
.Re
.Sh HISTORY
The
.Nm
utility first appeared in
.Fx 3.0 .
.Sh AUTHORS
.An Erez Zadok Aq ezk@cs.sunysb.edu ,
Computer Science Department, Stony Brook
University, Stony Brook, New York, USA.
.Pp
Other authors and contributors to am-utils are listed in the
.Pa AUTHORS
file distributed with am-utils.

View File

@ -1,257 +0,0 @@
/*
* Copyright (c) 1997-2014 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. 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.
*
*
* File: am-utils/amq/pawd.c
*
*/
/*
* 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>
/* statics */
static char *localhost = "localhost";
static char transform[MAXPATHLEN];
#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 */
xsnprintf(hesiod_lookup, sizeof(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 */
xstrlcpy(transform, "/home/", sizeof(transform));
xstrlcat(transform, username, sizeof(transform));
if (*ch)
xstrlcat(transform, ch, sizeof(transform));
#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;
struct timeval tmo = {10, 0};
char *dummystr;
amq_string *spp;
#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)) == NULL)
return dir;
memset(&server_addr, 0, sizeof(server_addr));
/* as per POSIX, sin_len need not be set (used internally by kernel) */
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 == NULL)
clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0);
if (clnt == NULL)
return dir;
xstrlcpy(transform, dir, sizeof(transform));
dummystr = transform;
spp = amqproc_pawd_1((amq_string *) &dummystr, clnt);
if (spp && *spp && **spp) {
xstrlcpy(transform, *spp, sizeof(transform));
XFREE(*spp);
}
clnt_destroy(clnt);
return transform;
}
/* getawd() is a substitute for getwd() which transforms the path */
static char *
getawd(char *path, size_t l)
{
#ifdef HAVE_GETCWD
char *wd = getcwd(path, MAXPATHLEN);
#else /* not HAVE_GETCWD */
char *wd = getwd(path);
#endif /* not HAVE_GETCWD */
if (wd == NULL) {
return NULL;
}
xstrlcpy(path, transform_dir(wd), l);
return path;
}
int
main(int argc, char *argv[])
{
char tmp_buf[MAXPATHLEN], *wd;
if (argc == 1) {
wd = getawd(tmp_buf, sizeof(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);
}

Some files were not shown because too many files have changed in this diff Show More