aboutsummaryrefslogtreecommitdiff
path: root/contrib/amd
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2016-11-11 02:42:53 +0000
committerCy Schubert <cy@FreeBSD.org>2016-11-11 02:42:53 +0000
commit449287a2a5ee4743d1e51b1cef8423cd5ac0703b (patch)
treecfabbc28c7e41c1de011661677a062cfd196415f /contrib/amd
parent3b49535a5a124165d6521ca19e12c0a457ca13b8 (diff)
parentca57057f598bfc7119f79f71bf38ec88244ab396 (diff)
downloadsrc-449287a2a5ee4743d1e51b1cef8423cd5ac0703b.tar.gz
src-449287a2a5ee4743d1e51b1cef8423cd5ac0703b.zip
MFV r305100: Update amd from am-utils 6.1.5 to 6.2.
Used extensively on my network over the past month. Reviewed by: pfg, brooks Suggested by: pfg Obtained from: ftp://ftp.am-utils.org/pub/am-utils/ MFC after: 6 weeks Relnotes: yes Differential Revision: D8405
Notes
Notes: svn path=/head/; revision=308493
Diffstat (limited to 'contrib/amd')
-rw-r--r--contrib/amd/AUTHORS145
-rw-r--r--contrib/amd/BUGS8
-rw-r--r--contrib/amd/COPYING9
-rw-r--r--contrib/amd/ChangeLog1118
-rw-r--r--contrib/amd/FAQ2
-rw-r--r--contrib/amd/INSTALL494
-rw-r--r--contrib/amd/MIRRORS.html28
-rw-r--r--contrib/amd/MIRRORS.txt30
-rw-r--r--contrib/amd/NEWS170
-rw-r--r--contrib/amd/README8
-rw-r--r--contrib/amd/README.attrcache4
-rw-r--r--contrib/amd/README.ldap10
-rw-r--r--contrib/amd/README.y2k5
-rw-r--r--contrib/amd/amd/am_ops.c45
-rw-r--r--contrib/amd/amd/amd.840
-rw-r--r--contrib/amd/amd/amd.c19
-rw-r--r--contrib/amd/amd/amd.h98
-rw-r--r--contrib/amd/amd/amfs_auto.c18
-rw-r--r--contrib/amd/amd/amfs_direct.c12
-rw-r--r--contrib/amd/amd/amfs_error.c12
-rw-r--r--contrib/amd/amd/amfs_generic.c243
-rw-r--r--contrib/amd/amd/amfs_host.c37
-rw-r--r--contrib/amd/amd/amfs_link.c14
-rw-r--r--contrib/amd/amd/amfs_linkx.c8
-rw-r--r--contrib/amd/amd/amfs_nfsl.c29
-rw-r--r--contrib/amd/amd/amfs_nfsx.c41
-rw-r--r--contrib/amd/amd/amfs_program.c30
-rw-r--r--contrib/amd/amd/amfs_root.c10
-rw-r--r--contrib/amd/amd/amfs_toplvl.c17
-rw-r--r--contrib/amd/amd/amfs_union.c14
-rw-r--r--contrib/amd/amd/amq_subr.c155
-rw-r--r--contrib/amd/amd/amq_svc.c175
-rw-r--r--contrib/amd/amd/autil.c123
-rw-r--r--contrib/amd/amd/clock.c8
-rw-r--r--contrib/amd/amd/conf.c145
-rw-r--r--contrib/amd/amd/conf_parse.y8
-rw-r--r--contrib/amd/amd/conf_tok.l31
-rw-r--r--contrib/amd/amd/get_args.c59
-rw-r--r--contrib/amd/amd/info_exec.c31
-rw-r--r--contrib/amd/amd/info_file.c45
-rw-r--r--contrib/amd/amd/info_hesiod.c15
-rw-r--r--contrib/amd/amd/info_ldap.c81
-rw-r--r--contrib/amd/amd/info_ndbm.c18
-rw-r--r--contrib/amd/amd/info_nis.c24
-rw-r--r--contrib/amd/amd/info_nisplus.c16
-rw-r--r--contrib/amd/amd/info_passwd.c19
-rw-r--r--contrib/amd/amd/info_sun.c53
-rw-r--r--contrib/amd/amd/info_union.c27
-rw-r--r--contrib/amd/amd/map.c294
-rw-r--r--contrib/amd/amd/mapc.c160
-rw-r--r--contrib/amd/amd/mntfs.c102
-rw-r--r--contrib/amd/amd/nfs_prot_svc.c199
-rw-r--r--contrib/amd/amd/nfs_start.c62
-rw-r--r--contrib/amd/amd/nfs_subr.c1197
-rw-r--r--contrib/amd/amd/ops_TEMPLATE.c12
-rw-r--r--contrib/amd/amd/ops_cachefs.c12
-rw-r--r--contrib/amd/amd/ops_cdfs.c27
-rw-r--r--contrib/amd/amd/ops_efs.c13
-rw-r--r--contrib/amd/amd/ops_ext.c223
-rw-r--r--contrib/amd/amd/ops_lofs.c10
-rw-r--r--contrib/amd/amd/ops_lustre.c203
-rw-r--r--contrib/amd/amd/ops_mfs.c8
-rw-r--r--contrib/amd/amd/ops_nfs.c138
-rw-r--r--contrib/amd/amd/ops_nfs3.c8
-rw-r--r--contrib/amd/amd/ops_nfs4.c50
-rw-r--r--contrib/amd/amd/ops_nullfs.c8
-rw-r--r--contrib/amd/amd/ops_pcfs.c10
-rw-r--r--contrib/amd/amd/ops_tfs.c8
-rw-r--r--contrib/amd/amd/ops_tmpfs.c152
-rw-r--r--contrib/amd/amd/ops_udf.c272
-rw-r--r--contrib/amd/amd/ops_ufs.c14
-rw-r--r--contrib/amd/amd/ops_umapfs.c8
-rw-r--r--contrib/amd/amd/ops_unionfs.c8
-rw-r--r--contrib/amd/amd/ops_xfs.c10
-rw-r--r--contrib/amd/amd/opts.c73
-rw-r--r--contrib/amd/amd/readdir.c528
-rw-r--r--contrib/amd/amd/restart.c34
-rw-r--r--contrib/amd/amd/rpc_fwd.c12
-rw-r--r--contrib/amd/amd/sched.c10
-rw-r--r--contrib/amd/amd/srvr_amfs_auto.c19
-rw-r--r--contrib/amd/amd/srvr_nfs.c159
-rw-r--r--contrib/amd/amd/sun2amd.892
-rw-r--r--contrib/amd/amd/sun2amd.c203
-rw-r--r--contrib/amd/amd/sun_map.c595
-rw-r--r--contrib/amd/amd/sun_map.h123
-rw-r--r--contrib/amd/amd/sun_map_parse.y492
-rw-r--r--contrib/amd/amd/sun_map_tok.l233
-rwxr-xr-xcontrib/amd/amd/test1.sh2
-rw-r--r--contrib/amd/amq/amq.850
-rw-r--r--contrib/amd/amq/amq.c247
-rw-r--r--contrib/amd/amq/amq.h10
-rw-r--r--contrib/amd/amq/amq_clnt.c39
-rw-r--r--contrib/amd/amq/amq_xdr.c61
-rw-r--r--contrib/amd/amq/pawd.111
-rw-r--r--contrib/amd/amq/pawd.c8
-rwxr-xr-xcontrib/amd/bootstrap74
-rw-r--r--contrib/amd/conf/checkmount/checkmount_bsd44.c11
-rw-r--r--contrib/amd/conf/mtab/mtab_bsd.c21
-rw-r--r--contrib/amd/conf/nfs_prot/nfs_prot_freebsd2.h10
-rw-r--r--contrib/amd/conf/nfs_prot/nfs_prot_freebsd3.h10
-rw-r--r--contrib/amd/conf/transp/transp_sockets.c137
-rw-r--r--contrib/amd/conf/umount/umount_bsd44.c9
-rw-r--r--contrib/amd/doc/am-utils.texi281
-rw-r--r--contrib/amd/doc/stamp-vti8
-rw-r--r--contrib/amd/doc/texinfo.tex5565
-rw-r--r--contrib/amd/doc/version.texi8
-rw-r--r--contrib/amd/fixmount/fixmount.811
-rw-r--r--contrib/amd/fixmount/fixmount.c20
-rw-r--r--contrib/amd/fsinfo/fsi_analyze.c64
-rw-r--r--contrib/amd/fsinfo/fsi_data.h8
-rw-r--r--contrib/amd/fsinfo/fsi_dict.c8
-rw-r--r--contrib/amd/fsinfo/fsi_gram.y12
-rw-r--r--contrib/amd/fsinfo/fsi_lex.l37
-rw-r--r--contrib/amd/fsinfo/fsi_util.c36
-rw-r--r--contrib/amd/fsinfo/fsinfo.833
-rw-r--r--contrib/amd/fsinfo/fsinfo.c12
-rw-r--r--contrib/amd/fsinfo/fsinfo.h14
-rw-r--r--contrib/amd/fsinfo/null_gram.c1414
-rw-r--r--contrib/amd/fsinfo/null_gram.h56
-rw-r--r--contrib/amd/fsinfo/null_gram.y8
-rw-r--r--contrib/amd/fsinfo/null_lex.c1716
-rw-r--r--contrib/amd/fsinfo/null_lex.l9
-rw-r--r--contrib/amd/fsinfo/wr_atab.c8
-rw-r--r--contrib/amd/fsinfo/wr_bparam.c10
-rw-r--r--contrib/amd/fsinfo/wr_dumpset.c8
-rw-r--r--contrib/amd/fsinfo/wr_exportfs.c8
-rw-r--r--contrib/amd/fsinfo/wr_fstab.c28
-rw-r--r--contrib/amd/hlfsd/hlfsd.821
-rw-r--r--contrib/amd/hlfsd/hlfsd.c51
-rw-r--r--contrib/amd/hlfsd/hlfsd.h8
-rw-r--r--contrib/amd/hlfsd/homedir.c28
-rw-r--r--contrib/amd/hlfsd/nfs_prot_svc.c8
-rw-r--r--contrib/amd/hlfsd/stubs.c27
-rw-r--r--contrib/amd/include/am_compat.h91
-rw-r--r--contrib/amd/include/am_defs.h80
-rw-r--r--contrib/amd/include/am_utils.h121
-rw-r--r--contrib/amd/include/am_xdr_func.h1049
-rw-r--r--contrib/amd/include/amq_defs.h48
-rw-r--r--contrib/amd/include/mount_headers1.h96
-rw-r--r--contrib/amd/include/mount_headers2.h8
-rw-r--r--contrib/amd/include/nfs_common.h99
-rw-r--r--contrib/amd/ldap-id.ms2
-rw-r--r--contrib/amd/ldap-id.txt2
-rw-r--r--contrib/amd/libamu/amu.h13
-rw-r--r--contrib/amd/libamu/hasmntopt.c12
-rw-r--r--contrib/amd/libamu/misc_rpc.c8
-rw-r--r--contrib/amd/libamu/mount_fs.c1097
-rw-r--r--contrib/amd/libamu/mtab.c12
-rw-r--r--contrib/amd/libamu/nfs_prot_xdr.c19
-rw-r--r--contrib/amd/libamu/strerror.c10
-rw-r--r--contrib/amd/libamu/strutil.c42
-rw-r--r--contrib/amd/libamu/wire.c19
-rw-r--r--contrib/amd/libamu/xdr_func.c2060
-rw-r--r--contrib/amd/libamu/xutil.c192
-rw-r--r--contrib/amd/mk-amd-map/mk-amd-map.812
-rw-r--r--contrib/amd/mk-amd-map/mk-amd-map.c16
-rw-r--r--contrib/amd/scripts/amd.conf-sample8
-rw-r--r--contrib/amd/scripts/amd.conf.541
-rw-r--r--contrib/amd/scripts/automount2amd.811
-rwxr-xr-xcontrib/amd/scripts/fixrmtab.in20
-rw-r--r--contrib/amd/vers.m42
-rw-r--r--contrib/amd/wire-test/wire-test.811
-rw-r--r--contrib/amd/wire-test/wire-test.c15
163 files changed, 20750 insertions, 4223 deletions
diff --git a/contrib/amd/AUTHORS b/contrib/amd/AUTHORS
index 3c241d016bb9..1ae6dcd2d72e 100644
--- a/contrib/amd/AUTHORS
+++ b/contrib/amd/AUTHORS
@@ -6,22 +6,22 @@ This file lists the ones who contributed major code changes, in no
particular order, and I thank them all. This is of course not to diminish
the smaller contributes of the many others. Thank you all.
-* Erez Zadok <ezk@cs.sunysb.edu>
+* 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@cs.columbia.edu>
+* 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@glue.umd.edu>
+* 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@deshaw.com>. I (Erez) ported these changes to am-utils.
+<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.
@@ -35,12 +35,12 @@ February 1, 1998: fixes for NetBSD to better detect its features.
September 4, 1999: assorted fixes for NetBSD 1.4+.
-* Hannes Reinecke <hare@MathI.UNI-Heidelberg.DE>
+* 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@matematik.su.se>
+* Leif Johansson <leifj AT matematik.su.se>
June 22, 1997: minor patch to ensure that systems without an RE library work.
@@ -52,7 +52,7 @@ functions. Contributed scripts/amd2ldif.pl.
August 4, 1997: info_ldap.c fixes and adding two new amd.conf ldap
variables: ldap_cache_seconds and ldap_cache_maxmem.
-* Andreas Stolcke <stolcke@speech.sri.com>
+* 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
@@ -68,11 +68,11 @@ message.
December 19, 1997: detected an FMR (Free Memory Read) in amd/mntfs.c,
uninit_mntfs().
-* Danny Braniss <danny@cs.huji.ac.il>
+* Danny Braniss <danny AT cs.huji.ac.il>
July, 6 1997: contributed patches to hesiod on bsdi3.
-* Tom Schmidt <tschmidt@micron.com>
+* 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
@@ -86,7 +86,7 @@ IFF_ROUTE instead of IFF_LOOPBACK.
May 30, 2000: correct logging types for addopts/mergeopts messages.
-* Daniel S. Riley <dsr@mail.lns.cornell.edu>
+* 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.
@@ -99,15 +99,15 @@ 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@informatik.uni-erlangen.de>
+* 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@debian.org>
-and Dominik Kubla <dominik@debian.org>.
+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@TechFak.Uni-Bielefeld.DE>
+* 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
@@ -132,34 +132,34 @@ mount tables in Solaris 8.
February 9, 2000: new debug options hrtime (hi-res timer) and xdrtrace. bug
fixes.
-* Jason Thorpe <thorpej@nas.nasa.gov>
+* 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@laas.fr>.
+<matthieu AT laas.fr>.
-* Chris Metcalf <metcalf@catfish.lcs.mit.edu>
+* 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@cv.sony.co.jp>
+* 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@mail.lns.cornell.edu>
+* 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@wsrcc.com>
+* 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@zoulas.com>
+* Christos Zoulas <christos AT zoulas.com>
September 25, 1997: fix to initialize uid/gid fields of pcfs_args_t on
netbsd.
@@ -181,7 +181,7 @@ 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@ctr.columbia.edu>
+* 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,
@@ -189,26 +189,26 @@ sizes, alignment, etc.
January 15, 1999: small ldap bug fixes.
-* Stefan Vogel <vogel@physik-rzu.unizh.ch>
+* Stefan Vogel <vogel AT physik-rzu.unizh.ch>
November 14, 1997: typo in the subscription instructions to amd-dev.
-* Guntram Wolski <gwolsk@sei.com>
+* Guntram Wolski <gwolsk AT sei.com>
November 15, 1997: pointed out mismatching documentation for the -o option.
-* Michael Hucka <hucka@eecs.umich.edu>
+* Michael Hucka <hucka AT eecs.umich.edu>
January 11, 1997: pointed out reversed definition of NFS mount options vers
and proto.
-* Albert Chin <china@pprd.abbott.com>
+* 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@chemie.fu-berlin.de>
+* 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).
@@ -216,11 +216,11 @@ 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@smarts.com>
+* Fred Korz <korz AT smarts.com>
January 30, 1998: minor typo fixed to tftp example in am-utils.texi.
-* Donald Buczek <buczek@MPIMG-Berlin-Dahlem.MPG.DE>
+* Donald Buczek <buczek AT MPIMG-Berlin-Dahlem.MPG.DE>
March 6, 1998: correctly inherit existing NFS V.3 mounts upon restart.
@@ -230,36 +230,36 @@ March 20, 1998: do not close stdout in case it gets reused elsewhere and to
allow startup script to redirect it. Set a temporary secure umask(0022)
before writing log file and restore it afterwards.
-* Matthew Crosby <mcrosby@ms.com>
+* Matthew Crosby <mcrosby AT ms.com>
April 20, 1998: allow arbitrary number of interfaces in wire listing.
-* David O'Brien <obrien@NUXI.com>
+* 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@cs.fiu.edu>
+* Danny Rathjens <dkr AT cs.fiu.edu>
October 29, 1998: swap arguments to kill(2) in amd.c.
-* Mike Mitchell <mcm@unx.sas.com>
+* 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@aero.und.edu>
+* Douglas K. Rand" <rand AT aero.und.edu>
December 3, 1998: case insensitive host name match for nfsl.
-* David Wolfskill <dhw@whistle.com>
+* 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@BSDI.COM>
+* 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
@@ -271,30 +271,30 @@ detection for bsdi4.
September 17, 1999: fixes to expn.
-* Paul Balyoz <pbalyoz@sedona.ch.intel.com>
+* Paul Balyoz <pbalyoz AT sedona.ch.intel.com>
March 26, 1999: ensure lostaltmail displays Y2K compliant dates.
-* Jon Peatfield <J.S.Peatfield@damtp.cam.ac.uk>
+* 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@mppmu.mpg.de>
+* 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@quest.cc.purdue.edu>
+* Dale Talcott <aeh AT quest.cc.purdue.edu>
July 26, 1999: added NFS3 support for AIX mounting.
-* Christophe Kalt <Christophe-Kalt@deshaw.com>
+* Christophe Kalt <Christophe-Kalt AT deshaw.com>
July 14, 1999: add netgrpd() syntax function which uses FQHN.
-* Andrew J. Korty <ajk@purdue.edu>
+* Andrew J. Korty <ajk AT purdue.edu>
September 5, 1999: pawd works for type:=nfsl.
-* Nick Williams <njw@ms.com>
+* Nick Williams <njw AT ms.com>
September 1, 1999: bug fix for incorrect symlinks when two locations are
requested simultaneously.
@@ -306,38 +306,38 @@ 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@germany.agfa.com>
+* 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@cs.rpi.edu>
+* Amitha Perera <perera AT cs.rpi.edu>
December 9, 1999: detect all wire() interfaces correctly.
-* Steven Danz <sdanz@awc.kc.noaa.gov>
+* Steven Danz <sdanz AT awc.kc.noaa.gov>
January 25, 2000: allow browsable auto maps.
-* Wolfram Klaus <klaus@physik.fu-berlin.de>.
+* Wolfram Klaus <klaus AT physik.fu-berlin.de>.
November 21, 2000: recognize proplist mnttab flag.
-* Thomas Klausner <tk@giga.or.at>
+* 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@caldera.de>
+* Olaf Kirch <okir AT caldera.de>
February 1, 2001: important Linux NFS error number mapping fixed
-* Ahmon Dancy <dancy@franz.com>
+* Ahmon Dancy <dancy AT franz.com>
February 9, 2001: Apple Rhapsody/Darwin/OS X port
-* Sebastien Bahloul <sebastien.bahloul@mangoosta.fr>
+* 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@fifi.org>
+* 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.
@@ -348,65 +348,65 @@ 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@fys.uio.no>
+* 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@dcs.ed.ac.uk>
+* 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@inf.ed.ac.uk>).
+protocol version parameter (with Tim Colles <timc AT inf.ed.ac.uk>).
-* Matthias Scheler <tron@zhadum.de>
+* Matthias Scheler <tron AT zhadum.de>
June 14, 2002: patch to use "xlatecookie" NFS mount option.
-* Jun-ichiro itojun Hagino <itojun@iijlab.net>.
+* Jun-ichiro itojun Hagino <itojun AT iijlab.net>.
June 11, 2002: minor fixes to support NetBSD 1.6A.
-* Sean Fagan <sef@apple.com>
+* 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@raisdorf.net>
+* Hendrik Scholz <hscholz AT raisdorf.net>
June 9, 2003: mk-amd-map should open temp db file using O_EXCL.
-* Mark Davies <mark@mcs.vuw.ac.nz>
+* 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@thyrsus.com>
+* Eric S. Raymond <esr AT thyrsus.com>
December 9, 2003: fix unbalanced [] typo in fsinfo man page.
-* Martin Blapp <mb@imp.ch>
+* Martin Blapp <mb AT imp.ch>
July 6, 2004: recognize fields in pcfs_args_t in FreeBSD 5.
-* Dan Nelson <dnelson@allantgroup.com>
+* Dan Nelson <dnelson AT allantgroup.com>
August 2, 2004: pawd to recognize "host" type mounts.
-* Hauke Fath <hauke@Espresso.Rhein-Neckar.DE>
+* Hauke Fath <hauke AT Espresso.Rhein-Neckar.DE>
August 3, 2004: pawd to recognize "linkx" type mounts.
-* Michael van Elst <M.van.Elst@science-computing.de>
+* 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@spock.org>
+* 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@ucl.ac.uk>
+* 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@franz.com>
+* Kevin Layer <layer AT franz.com>
January 28, 2005: basic instructions how to setup Amd on Mac OS-X.
-* Dan Ottavio <dottavio@ic.sunysb.edu>
+* 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
@@ -415,16 +415,13 @@ 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@gmail.com>
+* 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@surrey.ac.uk>
+* Graeme Wilford <G.Wilford AT surrey.ac.uk>
July 4, 2005: buffer overflow in pawd.
-* Steve Plite <splite-amutils@sigint.cs.purdue.edu>
-September 22, 2005: repair reversed meaning of D_AMQ, so amq will unregister
-on exit.
diff --git a/contrib/amd/BUGS b/contrib/amd/BUGS
index 3a3ba6b367d4..8e87e859cbac 100644
--- a/contrib/amd/BUGS
+++ b/contrib/amd/BUGS
@@ -1,7 +1,7 @@
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@am-utils.org mailing list.
+by email to the am-utils mailing list (see www.am-utils.org).
(1) mips-sgi-irix*
@@ -98,11 +98,11 @@ diff -u -r1.1 utsname.h
(4) powerpc-ibm-aix4.2.1.0
-[4A] "Randall S. Winchester" <rsw@Glue.umd.edu> reports that for amd to
+[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@physik.unizh.ch> reports that if your amq
+[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.
@@ -123,7 +123,7 @@ but it is not yet in the glibc-2.0.7-19 RPM.
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 am-utils@am-utils.org know if you know of a fix.)
+time. (Please let us know if you have a fix; see www.am-utils.org.)
(7) *-aix4.3.2.0
diff --git a/contrib/amd/COPYING b/contrib/amd/COPYING
index 035f6239c935..f54191d75fea 100644
--- a/contrib/amd/COPYING
+++ b/contrib/amd/COPYING
@@ -1,4 +1,4 @@
-Copyright (c) 1997-2006 Erez Zadok
+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.
@@ -15,12 +15,7 @@ are met:
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgment:
- This product includes software developed by the University of
- California, Berkeley and its contributors, as well as the Trustees of
- Columbia University.
-4. Neither the name of the University nor the names of its contributors
+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.
diff --git a/contrib/amd/ChangeLog b/contrib/amd/ChangeLog
index 12f2c5fb8e65..d996f8e75082 100644
--- a/contrib/amd/ChangeLog
+++ b/contrib/amd/ChangeLog
@@ -1,14 +1,564 @@
-2006-05-11 Erez Zadok <ezk@cs.sunysb.edu>
+2014-10-28 Christos Zoulas <christos@zoulas.com>
*******************************************************************
- *** Released am-utils-6.1.5 ***
+ *** Released am-utils-6.2 ***
*******************************************************************
-2006-05-10 Erez Zadok <ezk@cs.sunysb.edu>
+ * add ylwrap.amd, sick and tired of patching broken ylwrap.
+
+2014-09-05 Christos Zoulas <christos@zoulas.com>
+
+ * factor out the size check for both readdir methods
+ (raven at themaw.net)
+
+2014-09-03 Christos Zoulas <christos@zoulas.com>
+
+ * configure test for 64 bit xdr function (raven at themaw.net)
+
+2014-09-01 Christos Zoulas <christos@zoulas.com>
+
+ * bug fix from raven at themaw.net to prevent writing v3 handle
+ to a v2 structure.
+
+2014-07-21 Christos Zoulas <christos@zoulas.com>
+
+ * fix permission problems with access
+ * auto_nfs_version = 3 now works for me.
+
+2014-07-20 Christos Zoulas <christos@zoulas.com>
+
+ * refresh some autoconf files
+ * force autoconf version since earlier versions don't work
+ * changes from raven at themaw.net to support NFSv3 for automounted
+ toplevel filesystems presented to the list in May. A few bug fixes
+ and integration changes by me. The code now works well enough to
+ mount the filesystem with NFSv3 and automount children but readdir
+ does not work yet (so no listing of automounted filesystems).
+ The new code is not enabled by default. To enable use
+ auto_nfs_version = 3
+ in your configuration file.
+
+2014-03-26 Christos Zoulas <christos@zoulas.com>
+
+ From Ian Kent <ikent@redhat.com>
+
+ * use mktemp in scripts/fixrmtab
+ * fix documentatio nits
+ * [linux] Add ext2, ext3, ext4 specific mount options
+ * fix tcpwrappers (hosts.{allow,deny} problems for specific host
+ entries
+
+2014-03-20 Christos Zoulas <christos@zoulas.com>
+
+
+ * don't background autofs umount
+ * avoid fh NULL dereference on umount
+ * handle ENOENT umount return for autofs mounts
+ * fix error message in get_nfs_version
+ * fix debug log deadlock
+ * [linux] retry umount on EBUSY
+ * handle failed umount on exit
+
+2014-03-09 Christos Zoulas <christos@zoulas.com>
+
+ * Remove BSD advertising clause.
+ * Remove expn program which is not used by anything
+
+2013-12-05 Christos Zoulas <christos@zoulas.com>
+
+ * Change the way we handle multiple lex scanners and yacc parsers
+ in a single program. Our old patch to ylwrap does not work anymore
+ because the bison parsers need shared symbols that start with yy
+ and we can't easily select which ones work. So now we use -P and
+ -p to let lex and yacc do the work for us. This requires a patch
+ to ylwrap, but it is smaller.
+
+
+2013-12-05 Christos Zoulas <christos@zoulas.com>
+
+ * Change the way we handle multiple lex scanners and yacc parsers
+ in a single program. Our old patch to ylwrap does not work anymore
+ because the bison parsers need shared symbols that start with yy
+ and we can't easily select which ones work. So now we use -P and
+ -p to let lex and yacc do the work for us. This requires a patch
+ to ylwrap, but it is smaller.
+
+2013-05-14 Christos Zoulas <christos@zoulas.com>
+
+ * update to handle new autoconf and regen files
+
+2012-11-23 Christos Zoulas <christos@zoulas.com>
+
+ * recognize mountport=, noacl options
+ * simplify the bootstrap process, by forcing
+ all the files to be rebuild with autoreconf -f - i
+
+2012-10-03 Christos Zoulas <christos@zoulas.com>
+
+ * add missing ops_nfs4.c to the Makefile.am
+
+2012-09-14 Christos Zoulas <christos@zoulas.com>
+
+ * add locking option handling for lustre
+ * fix noatime, nodiratime, mandlock for linux
+
+2012-07-25 Christos Zoulas <christos@zoulas.com>
+
+ * bug fixes for lustre rhost parsing
+
+2012-06-27 Christos Zoulas <christos@zoulas.com>
+
+ * Disable 1/2-baked sun map support to avoid SIGSEGV
+
+2012-06-16 Christos Zoulas <christos@zoulas.com>
+
+ *******************************************************************
+ *** Released am-utils-6.2-rc1 ***
+ *******************************************************************
+
+ * Fix libtool.m4 to work with later versions of autoconf.
+ * In buildall, use eval so that quoted strings work
+ * Centralize nfs version checking function, and introduce
+ new configuration variable nfs_vers_ping, which is the
+ max version we ping for. This is not documented yet, because
+ there might be a better way separate the max version we can
+ use vs the max version we ping for.
+
+2012-06-09 Christos Zoulas <christos@zoulas.com>
+
+ * fix issue with parsing nfsv4 security option strings
+
+2012-05-01 Christos Zoulas <christos@zoulas.com>
+
+ * Handle EPERM return from v4 file handles
+ in old linux kernels
+
+2012-03-09 Christos Zoulas <christos@zoulas.com>
+
+ * fix linux autofs detection
+ * fix wrong types in new amq mount xdr processing
+
+2012-01-25 Christos Zoulas <christos@zoulas.com>
+
+ * FreeBSD portability fixes
+
+2012-01-23 Christos Zoulas <christos@zoulas.com>
+
+ * Avoid type punned warnings
+
+2011-12-29 Christos Zoulas <christos@zoulas.com>
+
+ * fix bug I introduced in get_nfs_version that caused it to return 0
+ * add direct support for ext{2,3,4}
+
+2011-12-15 Christos Zoulas <christos@zoulas.com>
+
+ * Include <linux/fs.h> on linux, to grab extra mount flags
+ * Add support for lustre
+
+2011-11-28 Christos Zoulas <christos@zoulas.com>
+
+ * For nfsl mounts, match against either the short local
+ host name or the fqdn name.
+
+2011-10-06 Christos Zoulas <christos@zoulas.com>
+
+ * Add NFSv4 support (loosely based on Ramya's code).
+ Currently if the NFSv4 mount fails with ENOENT we fail
+ back to NFSv3, unless -DNO_FALLBACK.
+ * Replace strdup with xstrdup. It is not nice to replace
+ system functions with ones that behave differently.
+ * Add various consistency checks (caller function checks
+ variable for NULL, but callee does not).
+ * Fix error handling in various paths.
+ * Don't check before using XFREE(). free(NULL) works.
+
+2011-09-15 Christos Zoulas <christos@zoulas.com>
+
+ * amq -i addition (prints info about the map files)
+
+2011-09-14 Christos Zoulas <christos@zoulas.com>
+
+ * Solaris OS and compiler fixes from:
+ Hofmann, Frank <Frank.Hofmann@morganstanley.com>
+ Sayle, Alex <Alex.Sayle@morganstanley.com>
+ - (void)&var generates warnings, removed
+ - __inline is invalid, changed with inline
+ - <sys/socket.h> and other headers have extra dependendcies
+ `
+2011-08-11 Christos Zoulas <christos@zoulas.com>
+
+ * fix potential buffer overflow in expand_error()
+ (Richard Kettlewell). Does not seem to be exploitable.
+
+ * simplify %option parsing to appease ancient flex.
+
+2011-06-21 Christos Zoulas <christos@zoulas.com>
+
+ * add support for linux autofs version 5 (untested)
+
+2011-06-18 Christos Zoulas <christos@zoulas.com>
+
+ * roll back to an older version of libtool that works
+
+ * newer versions of config.guess and config.sub
+
+ * minor fixes to buildall
+
+2011-05-19 Christos Zoulas <christos@zoulas.com>
+
+ * m4/macros/libtool.m4: for AIX AC_LANG_PROGRAM is incorrectly
+ used and the latest autoconf gives an error. For now just
+ quote it.
+
+ * configure.in: Fedora Core 15 and RedHat 6 now don't define
+ af_family_t in <linux/socket.h>, but in <bits/sockaddr.h>.
+ Include <sys/socket.h> so that we get <bits/sockaddr.h>
+ indirectly. This caused the <linux/nfs_mount.h> detection
+ test to fail.
+
+2010-11-24 Erez Zadok <ezk@fsl.cs.sunysb.edu>
+
+ * m4/macros/os_cflags.m4: for linux, define _GNU_SOURCE (to get
+ definitions for O_LARGEFILE and more).
+
+2010-11-20 Christos Zoulas <christos@zoulas.com>
+
+ * Update news items, add release readme, mark as rc1
+
+ * Fix addopts code to work with options that are key=value
+ when the built-in hasmntopt() code is not used. The problem
+ was that the code passed "key=" to hasmntopt not "key".
+
+2009-12-10 Christos Zoulas <christos@zoulas.com>
+
+ * Copy all fields of the am_opts structure
+ When we introduced am_loc we also added a function to
+ create a duplicate of an am_opts structure. As it turns
+ out, that only made a partial copy of the struct and some
+ fields (e.g. opt_cache) was left blank in the new structure.
+ Unfortunately any code that was checking the options
+ through the mntfs structure was mislead by the partial
+ copy: caching was disabled completely, for example, and
+ since browsing relies on caching being enabled it wasn't
+ working either.
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+ * Initialize RPC authentication flavor to AUTH_UNIX instead
+ of zero. RHEL 5 uses version 6 of the mount_arg structure
+ that includes the desired RPC authorization flavour.
+ Unfortunately amd initializes that value to zero, meaning
+ AUTH_NULL, resulting in all NFS servers denying operations.
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+ * Make sure to remove nodes in the proper order when going
+ down. Depending on what order the nodes got created it's
+ possible that the parent of a node has a bigger am_mapno
+ (index in exported_ap[]) so that it gets freed before
+ its child while the child's am_parent pointer is still
+ pointing to the already freed block of memory.
+ This change makes sure that umount_exported() cleans up
+ all children of a node first before freeing the node.
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+ * Fix Linux-specific stuff in ops_tmpfs.c
+ AUTOFS_TMPFS_FS_FLAGS is defined only in the Linux-specific
+ conf_linux.c file, so it cannot be built on Solaris.
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+ * Add missing parenthesis to fix defined(XXX
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+ * In the previous commit we've already made a change that
+ makes this code unnecessary since the node is returned
+ even if the backing file server is known to be down.
+ Since the code path is unused it should be removed.
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+ * amfs_generic_lookup_child() tries to find an alternate
+ file server if it detects that the current one is down.
+ However, in the comparison used to decide if a possible
+ mount is the same as the current one it compares the am_loc
+ pointers instead of the actual mntfs pointers. Since
+ amfs_lookup_one_location() creates a brand new am_loc
+ structure for the returned mntfs structure the am_loc
+ pointer will be different even if the mntfs it's pointing
+ to is the same.
+ This tricks amfs_generic_lookup_child() think it has
+ found an alternate file server while it hasn't and thus
+ starts multiple racing mounts for the very same node and
+ mntfs.
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+ * In the new am_loc scheme mounted mntfs structures still
+ have their mf_fo structure left intact. So when restart
+ creates a fake mntfs for an already mounted filesystem it
+ should not free mf_fo right away.
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+ * Setting the error flag of the mntfs for which the share
+ is already mounted results in the mount point not being
+ removed when it times out. (Amd considers it an error
+ mntfs and thus umount becomse a no-op.)
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+ * Right now AMD sets all timeout values to their defaults
+ even if you explicitly set them to zero. This patch
+ introduces separate flags that store if the respective
+ values have been set and the code path setting default
+ values checks these flags instead of testing the values
+ for zero. [Linux only]
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+ * Fix mntfs related lookup/(un)mount race conditions, by
+ introducing a new structure linking an mntfs to a node.
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+ * We have to free the buffers allocated by the XDR routines when
+ decoding the mount response after copying them to their final place.
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+2009-12-09 Christos Zoulas <christos@zoulas.com>
+
+ * Free continuation in amfs_retry() if we don't call amfs_bgmount()
+ Normally it's amfs_bgmount() which frees the continuation. However, if
+ the mount is already in progress and we're in amfs_retry() for another
+ node we don't try mounting the filesystem once again. Still, we have
+ to free the continuation as we won't get called again and thus would
+ leak the continuation structure and our am_loc references.
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+ * Fix use-after-free and double free of mntfs private data
+ ops_nfs.c(nfs_init) does not clear private data pointer after free().
+ This leads to use-after-free and double free in case mount() fails.
+ (found by valgrind)
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+2009-11-23 Christos Zoulas <christos@zoulas.com>
+
+ * The temporary filename buffer was leaked in lock_mtab().
+ From: Krisztian Kovacs <Kris.Kovacs@morganstanley.com>
+
+2009-10-27 Christos Zoulas <christos@zoulas.com>
+
+ * Deal with errno.h->sys/errno.h better
+
+2009-10-26 Christos Zoulas <christos@zoulas.com>
+
+ * Fix issue with autoconf 2.63
+
+ * Fix compile warnings for gcc-4.4.x
+
+2009-04-15 Christos Zoulas <christos@zoulas.com>
+
+ * Share the LDAP connection between different maps to save resources
+ on the LDAP server. (Olaf Flebbe <o.flebbe@science-computing.de>)
+
+2009-03-20 Christos Zoulas <christos@zoulas.com>
+
+ * Fix largefile re-definitions
+
+ * Fix compilation error caused in previous patch
+
+2009-02-19 Christos Zoulas <christos@zoulas.com>
+
+ * Add a synchronous unmount amq rpc that will wait for the remote
+ filesystem to be unmounted, or return an error. Enabled by amq -uu
+
+2009-01-11 Erez Zadok <ezk@fsl.cs.sunysb.edu>
+
+ * amd/ops_udf.c: don't define functions/variables which may not be
+ used.
+
+ * amd/ops_tmpfs.c (mount_tmpfs): force gcc not to complain about
+ unused variables.
+
+ * config.guess.long: properly support Fedora Core.
+
+2009-01-09 Christos Zoulas <christos@zoulas.com>
+
+ * Fix nfs mounts on linux 2.6.26 by explicitly initializing context.
+
+ * Treat an empty sublink as an unset sublink; this allows us to
+ say sublink:=; in a spec to override the default. (This produces
+ Bad selector error, but it works. XXX: We need to decide how to
+ unset a selector. I proposed an unset keyword a while ago).
+
+2009-01-06 Christos Zoulas <christos@zoulas.com>
+
+ * re-renerate all generated files with newer versions of the
+ auto-tools.
+
+ * move INSTALL to INSTALL.am-utils to avoid conflicts
+
+ * fix incompatibilities with new m4 and new autoconf.
+
+ * add UDF filesystem support.
+
+ * fix NetBSD nfs file handle detection.
+
+2009-01-02 Christos Zoulas <christos@zoulas.com>
+
+ * add nocasetrans, nojoliet, rrcaseins for cd9660 filesystems
+
+2008-12-03 Christos Zoulas <christos@zoulas.com>
+
+ * allow ldap queries try a comma-separated list of servers given as:
+
+ ldap_hostports = host1:port1,host2,host3:port3
+
+ original patch from Florian Geyer
+
+2008-09-19 Christos Zoulas <christos@zoulas.com>
+
+ * the auth_create gid on NetBSD is int
+
+ * deal with lossage from flex -P
+
+ * fix missing/incorrect prototypes
+
+2008-09-17 Christos Zoulas <christos@zoulas.com>
+
+ * fix manual page section issues (sorting, non-existant)
+
+ * add missing forward declarations
+
+ * avoid null pointer derefs (coverity)
+
+ * more portable endian detection support
+
+ * implement tmpfs support
+
+ * use sizeof var instead of constant
+
+ * fix yyerror declaration and definition
+
+ * fix yy function renaming, and correct some renaming issues.
+
+ * work around automake < 1.9 issue where ylwrap is not being run
+ for a single yacc or lex file.
+
+ * NetBSD
+ - handle headers that need other headers to compile
+ - add exfs and tmpfs specific glue
+ - add options log, noatime, nocoredump, nodevmtime, softdep,
+ symperm, union
+ - NetBSD's new mount system call needs the size of the opaque
+ filesystem specific structure, but passing 0 for now works.
+ We would need to change a lot more code to pass the size from
+ the fs-specific calls, so for now punt.
+ - recvfrom takes socklen_t * on NetBSD
+ - handle newer NetBSD using statvfs
+ - NetBSD calls its ufs ffs
+
+ * Linux
+ - Most recent kernels have trouble with trying to parse the pid
+ hostname and do locking. What before was a silent failure, now
+ there is a warning printed and the mount is rejected. This is
+ the simplest fix:
+ (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=479884)
+
+2007-04-13 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * amd/sun_map.c (sun_append_str): When translating '&' from Sun
+ automounter maps, replace it with "${key}" in the Amd map, not
+ with the value of the key at the time. This way '*' maps work
+ too.
+
+ * config.guess.long: don't use -q option to grep because some
+ systems don't support it. Bug fix for solaris.
+
+2007-03-11 Christos Zoulas <christos@zoulas.com>
+
+ * amd/opts.c (expand_op): Don't call xstrlcpy() to truncate a
+ string. It causes spurious xstrlcpy() syslog() errors. Use
+ memcpy() and explicitly terminate the string.
+
+2007-01-20 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * updated copyright year to 2007 on all files.
+
+2006-12-27 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * minor new port: ia64-hp-hpux11.23
+
+ * m4/macros/check_libwrap_severity.m4 (LIBS): also test if caller
+ needs to define rfc931_timeout.
+
+ * amd/sun2amd.c: define rfc931_timeout and allow/deny_severity for
+ libwrap.
+
+ * amd/amq_svc.c: some versions of libwrap require the caller to
+ define rfc931_timeout in addition to allow/deny_severity.
+
+ * amd/amfs_toplvl.c (amfs_toplvl_init): properly detect when
+ forced unmount functionality exists for all systems.
+
+ * libamu/mount_fs.c (compute_nfs_args): reset nfs_args_t->pathconf
+ only if field exists.
+
+ * conf/nfs_prot/nfs_prot_hpux11.h: prevent HPUX 11.23 from
+ including <tiuser> or <sys/tiuser> (TLI definitions are already
+ included from elsewhere).
+
+ * configure.in: detect nfs_args_t->pathconf field.
+
+2006-11-27 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * doc/Makefile.am: properly publish html files using newer
+ text2html.
+
+2006-11-27 Erez Zadok <ezk@shekel.local>
+
+ * doc/Makefile.am: obfuscate emails in ChangeLog before it is
+ published on web site.
+
+ * obfuscate many more emails in the distro, esp. of files which get
+ posted on the am-utils web site.
+
+2006-11-26 Erez Zadok <ezk@shekel.local>
+
+ * minor new port: i386-apple-darwin8.8.1.
+
+ * doc/am-utils.texi: remove obvious URLs used by spammers, and
+ replace them with links to the am-utils web site, which uses PNG
+ images to obfuscate the actual email/mailman URLs.
+
+2006-10-30 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * doc/am-utils.texi (Password maps): minor typo reported by
+ Christoph P. Kukulies.
+
+2006-10-26 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * minor new port: i386-pc-linux-fc6.
+
+ * m4/macros/linux_headers.m4: handle newer Linux kernels which
+ removed UTS_RELEASE from <linux/version.h>.
+
+2006-10-25 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * minor new ports: i386-pc-linux-centos4.4 and
+ powerpc-apple-darwin8.7.0.
+
+ * config.guess.long: recognize CentOS Linux.
+
+2006-06-20 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * minor new port: i386-pc-solaris2.11-nexentaos (GNU/OpenSolaris).
+
+ * config.guess.long: recognize NexentaOS (GNU/OpenSolaris)
- * Minor new ports: i386-unknown-freebsd6.1 (RELEASE)
+ * config.guess, config.sub: updates from latest official GNU
+ distributions.
+
+2006-05-11 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * Minor new ports: i386-unknown-freebsd6.1 (RELEASE),
powerpc-apple-darwin8.6.0, and i386-unknown-openbsd3.9.
+2006-05-10 Erez Zadok <ezk@cs.sunysb.edu>
+
* libamu/mount_fs.c (compute_nfs_attrcache_flags): fix signedness
problems on IRIX-6.5.
@@ -188,11 +738,14 @@
same $ac_cv_* variable name). Some systems support one header or
another. Patch inspired by work Debian did.
-2006-02-10 Erez Zadok <ezk@cs.sunysb.edu>
+2006-02-16 Daniel P. Ottavio <ottavio@vm.fsl.cs.sunysb.edu>
- *******************************************************************
- *** Released am-utils-6.1.4 ***
- *******************************************************************
+ * amd/sum_map_tok.l: Fixed a bug in a regular expression that
+ prevented dashes in hostnames. This was posted in BZ by Thomas
+ A. Fine.
+
+ * README.sun2amd: Fixed a typo. Sentence mentions use of autofs
+ type when it should be host type.
2006-01-04 Erez Zadok <ezk@cs.sunysb.edu>
@@ -302,9 +855,31 @@
2005-10-10 Erez Zadok <ezk@cs.sunysb.edu>
*******************************************************************
- *** Released am-utils-6.1.3 ***
+ *** Released am-utils-6.1a1 ***
*******************************************************************
+ * README.sun2amd: revised.
+
+2005-10-09 Daniel P. Ottavio <dottavio@ic.sunysb.edu>
+
+ * amd/info_nis.c (nis_search): Bug fix for bugzilla #428; make
+ sure that sun_entry2amd() is not called when yp_match() returns an
+ error, this is done by checking that 'res' is 0. Bug fix (same
+ BZ#); free the output allocated by yp_match() instead of freeing
+ the return value of sun_entry2amd().
+
+ * amd/sun_map.c (sun_entry2amd): Fix a comment.
+
+ * README.sun2amd: Made a first pass at describing the status of
+ the sun2amd feature.
+ Moved the date.
+
+2005-10-09 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * README.sun2amd: place holder.
+
+ * Makefile.am (EXTRA_DIST): distribute new README.sun2amd file.
+
2005-10-07 Erez Zadok <ezk@cs.sunysb.edu>
* m4/macros/check_mnttab_type.m4: move the test for MOUNT_* to the
@@ -343,6 +918,10 @@
* amd/info_exec.c (exec_map_open): break assignment from inside
conditional, to work around an IRIX-6.5 cc bug.
+ * amd/Makefile.am (amd_LDADD, sun2amd_LDADD): put libaminfo.a
+ before libamu.la. Some linkers (e.g., IRIX-6.5) incorrectly
+ complain about undefined symbols.
+
* fsinfo/fsi_util.c (set_ether_if), amd/map.c (unmount_mp),
libamu/xutil.c (expand_error), libamu/strutil.c (xsnprintf): avoid
comparison between signed and unsigned integers.
@@ -479,15 +1058,10 @@
2005-10-02 Erez Zadok <ezk@cs.sunysb.edu>
- * include/am_utils.h: extern for xvsnprintf().
-
- * amd/autil.c: move strsplit() to libamu/strutil.c.
-
* libamu/Makefile.am: use strutil.c, not util.c.
* libamu/strutil.c: rename from util.c to explain better purpose
- of file. Move xvsnprintf and xsnprintf from xutil.c to this
- file. Sync up with 6.2 version of file.
+ of file. Move xvsnprintf and xsnprintf from xutil.c to this file.
* libamu/xutil.c: explain purpose of file. Move mkdirs/rmdirs
code from old util.c.
@@ -555,22 +1129,13 @@
2005-09-26 Erez Zadok <ezk@cs.sunysb.edu>
- * libamu/xutil.c (unregister_amq): repair broken meaning of D_AMQ,
- which was reversed in am-utils-6.2. Bug fix from Steve Plite
- <splite-amutils at sigint.cs.purdue.edu>.
-
* hlfsd/stubs.c (nfsproc_getattr_2_svc, nfsproc_lookup_2_svc,
nfsproc_readlink_2_svc, nfsproc_readdir_2_svc), hlfsd/hlfsd.c
(hlfsd_init): use new clocktime() function.
2005-09-18 Erez Zadok <ezk@cs.sunysb.edu>
- *******************************************************************
- *** Released am-utils-6.1.2.1 ***
- *******************************************************************
-
- * README.attrcache: Update status of freebsd and openbsd.
- Document netbsd's patchs to support noac.
+ * README.attrcache: document netbsd's patchs to support noac.
* libamu/mount_fs.c (compute_nfs_attrcache_flags): cleanup the
code that sets the ac{reg,dir}{min,max} fields so it also sets the
@@ -578,13 +1143,10 @@
* configure.in: check for nfs_args fields acregmax and acdirmax.
- *******************************************************************
- *** Released am-utils-6.1.2 ***
- *******************************************************************
-
* README.attrcache: new file documenting in detail OS bugs
relating to attribute caching, which can affect Amd's reliability
under heavy load.
+ Update status of freebsd and openbsd.
* doc/Makefile.am: install README.attrcache file as attrache.txt
file on am-utils Web site.
@@ -665,6 +1227,54 @@
amfs_bgmount, amfs_generic_mount_child), amd/amd.c (main): pass
NULL to clocktime().
+2005-09-15 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * amd/nfs_subr.c (nfsproc_getattr_2_svc): initialize 'retry', just
+ in case.
+ (fh_to_mp3): increment amd_stats.d_stale counter only if we are
+ actually returning ESTALE.
+
+ * amd/info_exec.c (exec_parse_qanswer), amd/info_file.c
+ (file_search_or_reload), amd/info_hesiod.c (hesiod_search),
+ amd/info_ldap.c (amu_ldap_search), amd/info_ndbm.c (search_ndbm),
+ amd/info_nis.c (nis_search), amd/info_nisplus.c (nisplus_search,
+ nisplus_search): don't dereference mnt_map->cfm which may be null
+ if we're not using an amd.conf file.
+
+2005-09-14 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * libamu/xutil.c (unregister_amq): if failed to de-register Amd
+ from portmapper, report it under dlog (debugging), not as an
+ annoying plog that always shows up.
+
+2005-09-13 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * mk-amd-map/mk-amd-map.c (read_file_file), libamu/util.c
+ (strsplit), libamu/hasmntopt.c (nextmntopt), amd/sun_map.c
+ (sun_entry2amd), amd/sun2amd.c (sun2amd_convert_convert),
+ amd/mapc.c (mapc_add_kv), amd/info_file.c (file_search_or_reload),
+ amd/info_exec.c (exec_parse_qanswer): cast isspace() and isascii()
+ arg to unsigned char, which is safer as per Christos.
+
+ * amd/sun_map.c (sun_entry2amd): isspace takes an int, not a char.
+
+ * configure.in: keep a dummy unused AM_PROG_LEX, because old
+ Automake (1.6.3) looks for it if you refer to LEX in your
+ Makefile.am files. Silly thing, fixed in newer versions of
+ Automake (1.9.2).
+
+2005-09-11 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * Makefile.am (EXTRA_DIST_M4): add prog_{lex,yacc}.m4 to distro.
+
+ * configure.in: use new macros AMU_PROG_YACC and AMU_PROG_LEX.
+
+ * m4/macros/prog_yacc.m4: new macro to check if bison/yacc/byacc
+ exist, but exist with an error if none found.
+
+ * m4/macros/prog_lex.m4: new macro to check if f/lex exist, but
+ exit with an error if not found (am-utils requires f/lex).
+
2005-09-07 Erez Zadok <ezk@cs.sunysb.edu>
* minor new port: powerpc-apple-darwin8.2.0.
@@ -683,8 +1293,48 @@
file system on this system (probably because /proc isn't mounted),
then provide some default definition for this file to compile.
+2005-08-28 Daniel P. Ottavio <dottavio@ic.sunysb.edu>
+
+ * amd/sun_map.c (sun_entry2amd) : Wipe out any trailing white
+ spaces or '\n' before passing strings to the parser.
+
+ * amd/amd.h : oops, reverting bad changes
+
+ * amd/info_file.c : oops, reverting bad changes
+
+ * amd/mapc.c : oops, reverting bad changes
+
+ * amd/sun_map_parse.y : oops, reverting bad changes
+
2005-08-27 Erez Zadok <ezk@cs.sunysb.edu>
+ * libamu/xutil.c: amd_program_number is a u_long now.
+ (unregister_amq): if pmap_unset failed to de-register Amd from the
+ portmapper, print an error message.
+ (get_amd_program_number): returns a u_long now.
+ (set_amd_program_number): take a u_long now.
+
+ * include/am_utils.h: get_amd_program_number() returns u_long now.
+ set_amd_program_number() takes a u_long now.
+
+ * amq/amq.c: amd_program_number is a u_long, not int.
+
+ * amd/nfs_start.c (mount_automounter): when registering Amd with
+ the portmapper (for Amq service), don't fail if just one of TCP or
+ UDP failed to register, but only if both transports failed. That
+ way Amq can still contact Amd using the transport that did
+ register correctly. However, now, if both transports failed to
+ register, then set amd_state to "Done" so it would shutdown
+ cleanly.
+
+ * conf/transp/transp_{sockets,tli{}.c (amu_svc_register): better
+ comments.
+
+ * libamu/xutil.c: debug_flags should always be initialized to
+ D_CONTROL (amq,daemon,fork).
+ (debug_option): allow setting initial immutable debug_flags via
+ amd.conf; afterward, prevent it (i.e., one tries it via "amq -D").
+
* Makefile.am (DISTCLEANFILES): also remove amu_autofs_prot.h,
config.cache.old, and dbgcf.h on "make distclean".
(CLEANFILES): remove dbgcf on plain "make clean".
@@ -692,13 +1342,199 @@
* amd/Makefile.am (DISTCLEANFILES): also remove ops_autofs.c on
"make distclean".
+2005-08-27 Daniel P. Ottavio <dottavio@ic.sunysb.edu>
+
+ * amd/info_file.c (file_search_or_reload): Changed the key
+ variable that is passed to the sun_entry2amd.
+
+ * amd/mapc.c (mapc_add_kv): Add support for multiple entries
+ packed into one line. This is a workaround for handling Sun style
+ mounts that contains multiple entries on one line: "multi-mount
+ entries". The sun2amd conversion tools will convert such entries
+ into type:=auto and pack each of the auto-entries into one line
+ separated by '\n'. The mapc_add_kv function will now recognize
+ such entries and add then.
+
+ * amd/sun2amd.c (sun2amd_convert): Add print statement that
+ includes the line number during a parser failure.
+
+ * sun_map.c: Fix the AMD_MAP_PREF_KW definition. Fix spelling.
+ (sun_mountpts2amd): removed this function
+ (sun_hsfs2amd): added some more comments
+ (sun_nfs2amd): moved support for multi-mount entries from this
+ function to sun_multi2amd().
+ (sun_multi2amd): New function to handle multi-mount entries. This
+ function will convert the Sun version to an Amd type:=auto. Each
+ extra auto entry will be appended to the same line separated by a
+ '\n'.
+ (sun_entry2amd): Fixed a bug if-statement. This function now
+ checks for multi-mount entries.
+
+ * amd/sun_map.h: Add a fstype member to the sun_mountpt struct.
+
+ * amd/sun_map_parse.y: Parser now supports fstype for multi-mount
+ entries.
+
+ * amd/sun_map_tok.l: No longer print the line and column number
+ when parsing. This is because the parser is handed strings not
+ files. Therefore, the line number will always be 1. It is now up
+ to the higher level tools to echo line information during error
+ when they feed the parser.
+
2005-08-24 Erez Zadok <ezk@cs.sunysb.edu>
* configure.in: wrap all LDAP and HESIOD tests in test whether
--with-OPT was used.
+2005-08-20 Daniel P. Ottavio <dottavio@ic.sunysb.edu>
+
+ * amd/sun_map.c: Clean up #defines
+ (sun_entry2amd) : Verify that the key and entry values passed are
+ not NULL. Free the Sun entry struct when done.
+
+ * amd/sun_map.h: Add some "not implemented yet" comments to the
+ map and mmap structures.
+
+ * amd/sun_map_parse.y: Removed automap include functionality, it
+ will need to be re-implemented using a pre-processor.
+ Clean up function calls.
+
+2005-08-16 Daniel P. Ottavio <dottavio@ic.sunysb.edu>
+
+ * amd/sun2amd.c (sun2amd_convert): If the input line is too long
+ don't return an error just null terminate and continue. Fix bug:
+ the map key was not written.
+
+ * amd/sun_map.c: Add a new Amd device, and cdfs constant.
+ (sun_locations2amd): Write the NFS type keyword
+ for each host of the mount entry. Add a space between each mount
+ location.
+ (sun_hsfs2amd): New function to support hsfs to
+ cdfs.
+ (sun_nfs2amd): Don't write the nfs type here. Fix
+ comments.
+ (sun_entry2amd): Change function parameter var for
+ clarity. Add support for hsfs.
+
+ * amd/sun_map_parse.y (sun_map_parse_read): Reset the entry list
+ after it has been returned.
+
2005-08-16 Erez Zadok <ezk@cs.sunysb.edu>
+ * amd/get_args.c (get_args): initialize debug_flags if they've
+ never been set.
+
+2005-08-15 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * amd/mapc.c (mapc_create): mapc find takes 4th arg, the mount
+ point. Now, we can properly initialize the cfm structure of the
+ mnt_map, so we can have access to the flags (e.g., SUN_MAP_SYNTAX)
+ inside each info_*.c file.
+ (mapc_find): takes 4rd arg (mntpt) and passes it to calls to
+ mapc_create.
+ (root_newmap): pass NULL as 4th arg (mntpt).
+
+ * amd/amfs_generic.c (amfs_parse_defaults): remove ugly hack to
+ initialize map cfm structure (including flags) so late.
+
+ * amd/autil.c (amfs_mkcacheref): pass mount point as 4th arg to
+ mapc_find.
+
+ * amd/amfs_root.c (amfs_root_mount): pass NULL as new 4th arg to
+ mapc_find.
+
+ * amd/amd.h: extern for mapc_find changed to pass the mount point.
+
+ * libamu/xutil.c: debug_flags should be unsigned.
+ (dbg_opt): fix comments for updated debug_flags, add "defaults".
+ (debug_option): Don't allow "immutable" (D_IMMUTABLE) flags to be
+ changed, because they could mess Amd's state and only make sense
+ to be set once when Amd starts. Currently these immutable flags
+ are "daemon," "fork," "amq," and "mtab." If Amd not compiled with
+ debugging, set default "control" options (daemon,fork,amq).
+ (unregister_amq): proper use of D_AMQ.
+
+ * include/am_utils.h: define new D_BASIC, D_CONTROL, D_DEFAULT,
+ D_IMMUTABLE, and D_MASK. Updated definitions of D_ALL and D_TEST.
+ debug_flags extern should be unsigned.
+
+ * scripts/amd.conf-sample (debug_options): mention new "defaults"
+ option.
+
+ * scripts/amd.conf.5,doc/am-utils.texi: document new debug option
+ "defaults" and properly explain the corrected meanings of
+ "daemon," "fork," "amq," and their "no" inversions. Better
+ explain "all" and "test" too. Correct default debug_mtab file to
+ /tmp/mtab.
+
+ * hlfsd/stubs.c (nfsproc_readlink_2_svc): proper use of D_FORK.
+
+ * hlfsd/homedir.c (homedir): proper use of D_FORK.
+
+ * hlfsd/hlfsd.c (main, hlfsd_init, cleanup): proper use of
+ D_DAEMON.
+
+ * amd/nfs_start.c (mount_automounter): proper use of D_AMQ.
+
+ * amd/amd.h (DEBUG_MNTTAB_FILE): change default to /tmp/mtab,
+ which is more common on more systems (instead of /tmp/mnttab).
+
+ * amd/amd.c (main): properly use D_DAEMON.
+
+2005-08-14 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * libamu/xutil.c (xlog_opt): define new pseudo log_option named
+ "defaults", which is an alias for "fatal,error,user,warning,info".
+
+ * scripts/amd.conf.5, doc/am-utils.texi, amd/amd.8: document new
+ log_option "defaults".
+
+ * amq/amq.8: typo. Arg name for -D is "debug_options" not
+ "log_options".
+
+ * libamu/xutil.c: make xlog_level static, and initialize it to
+ XLOG_DEFAULT.
+ (cmdoption): take unsigned int as flags argument, and print any
+ errors as XLOG_ERROR (which cannot be turned off).
+ (switch_option): remove old code which disallowed you from turning
+ off flags that were set when Amd started up. Now, you can turn
+ any log option on/off at start time or later on (via amq -x),
+ other than the two mandatory options (fatal+error).
+
+ * include/am_utils.h (XLOG_*): remove unused XLOG_DEFSTR. Define
+ XLOG_MASK to mask out unused flag bits. Define XLOG_DEFAULT to be
+ what it was before (fatal + error + user + warning + info), but
+ use the new mask. Remove extern's for xlog_level and
+ xlog_level_init. Change extern for cmdoption() to take an
+ unsigned flags argument.
+
+ * doc/am-utils.texi, amq/amq.8, scripts/amd.conf.5, amd/amd.8:
+ document mandatory log options
+ (fatal+error) which cannot be turned off and are always on by
+ default. They must be on so that Amd can report crucial errors,
+ including those related to setting flags on/off.
+
+ * hlfsd/hlfsd.c (main): remove hack to initialize log_options.
+
+ * wire-test/wire-test.c: remove reference to unused xlog_level.
+
+ * amd/mapc.c (mapc_create): 'alloc' flags variable should be
+ unsigned.
+
+ * amd/get_args.c (get_args): no need for hack using
+ xlog_level_init.
+
+ * amd/Makefile.am: separate sources common to amd and sun2amd into
+ a special, locally-built only, static library called libaminfo.a.
+
+ * libamu/xutil.c (real_plog, xsnprintf): call new xvsnprintf()
+ wrapper function.
+ (xvsnprintf): new function which already gets a va_list. This was
+ needed to avoid nesting va_list's (which apparently isn't
+ allowed).
+
+ * include/am_utils.h: prototype for new xvsnprintf wrapper.
+
* configure.in: sinclude([vers.m4]) version number file.
* vers.m4: new file to separate version number out of
@@ -707,24 +1543,248 @@
* Makefile.am (EXTRA_DIST_M4): include vers.m4 in distro.
+2005-08-14 Daniel P. Ottavio <dottavio@ic.sunysb.edu>
+
+ * amd/info_file.c: add key to sun_entry2amd()'s parameters
+
+ * amd/info_hesiod.c: add key to sun_entry2amd()'s parameters
+
+ * amd/info_ldap.c: add key to sun_entry2amd()'s parameters
+
+ * amd/info_ndbm.c: add key to sun_entry2amd()'s parameters
+
+ * amd/info_nis.c: add key to sun_entry2amd()'s parameters
+
+ * amd/info_nisplus.c: add key to sun_entry2amd()'s parameters
+
+ * amd/sun_map.c: New functions to support sun translation to amd.
+ The function sun_entry2amd's parameters were expanded to include
+ the key value. sun_entry_2amd() now returns NULL on error.
+
+ * amd/sun_map.h: Expand sun_entry2amd's parameters to include key
+ value.
+
+ * amd/sun_map_parse.y: Change how file system types are parsed out
+ of the list of options for each entry. The previous way was not
+ working properly so now we just look for the 'fstype' keyword in
+ each option. If it exists we copy its key value.
+ Added some comments to sun_map_parse_read().
+
+ * amd/amd.h: Added an extern from info_file.c called
+ file_read_line(). Previously this function was static but is now
+ used in sun2amd.c.
+
+ * amd/info_file.c: Changed the static function read_line() to a
+ public function called file_read_line(). This function is now
+ used in sun2amd.c
+
+ * amd/sun2amd.8: Filled in the contents of this man page. This is
+ a conversion utility that converts Sun maps to Amd maps.
+
+ * amd/sun2amd.c: Implemented a working version of this utility.
+
2005-08-11 Erez Zadok <ezk@cs.sunysb.edu>
+ * amd/sun_map_parse.y: instead of using a custom FOO_alloc()
+ function, use Amd's CALLOC(struct FOO) macro.
+
+ * amd/sun_map.h: remove extern definitions to functions no longer
+ needed.
+
+ * amd/sun_map.c: removed superfluous *_alloc() functions, some of
+ which caused conflicts with same-named symbols in the parser
+ (since we rename 'yyalloc' to 'sun_map_alloc').
+
* configure.in: keep AC_INIT on same line, for nightly snapshot
build script.
+ * amd/Makefile.am: f/lex libraries are incompatible with multiple
+ scanners, so don't link Amd with libl.a/libfl.a.
+
+2005-08-10 Daniel P. Ottavio <dottavio@ic.sunysb.edu>
+
+ * amd/sun_map_tok.l: Clean up regular expression so HPUX stops
+ whining.
+
+2005-08-09 Daniel P. Ottavio <dottavio@ic.sunysb.edu>
+
+ * amd/sun_map_parse.y: Moved license below special yacc bracket to
+ be portable with HPUX's yacc. Clean up externs.
+
+ * amd/sun_map_tok.l: Moved license below special lex bracket to be
+ portable with HPUX's lex. Fixed definitions to allow for a
+ non-flex lex to parse strings instead of files. Added some casts
+ to strlcpy usage to silence warnings. Moved the % options because
+ HPUX was complaining,
+
+2005-08-08 Daniel P. Ottavio <dottavio@ic.sunysb.edu>
+
+ * amd/sun_map_tok.l: Applied some definition goop to handle the
+ ECHO symbol that lex defines. This symbol causes problems on
+ RedHat-EL-powerPC platforms. Replaced strncpy with strlcpy.
+ Renamed the function sun_map_yyinput to sun_map_input. This
+ function is a utility function that is not generated by lex.
+ Therefore, the 'yy' may cause confusion.
+
+2005-08-08 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * amd/sun_map_tok.l: allocate more output slots so lex scanners
+ don't run out of memory.
+
+ * amd/sun_map_parse.y: declare extern for sun_map_parse().
+
+ * libamu/xutil.c (xsnprintf): ensure proper comparisons between
+ signed and unsigned quantities.
+
+2005-08-06 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * libamu/util.c, amd/autil.c (strsplit): moved strsplit() function
+ from Amd code to to libamu, so sun2amd could use it.
+
+ * amd/Makefile.am (sbin_PROGRAMS): build sun2amd binary and man
+ page.
+ (EXTRA_sun2amd_OBJECTS): sun2amd needs to link with all info_*.c files
+
+ * amd/sun2amd.8: placeholder for man page.
+
+ * amd/sun2amd.c: placeholder for C version of translator from Sun
+ syntax maps to Amd maps.
+
+ * */*.[0-9]: include file name in nroff source comment.
+
+ * ALL: use '0' properly when assigning or passing it to functions.
+ If in the context pointer, use NULL. If in the context of a
+ single char (say within a string), the use '\0'. This is just to
+ make the code clearer.
+
+ * m4/macros/header_templates.m4: template for HAVE_MAP_SUN.
+
+ * amd/mapc.c (maptypes): add placeholder for Sun-syntax map
+ methods.
+
+ * amd/Makefile.am (EXTRA_amd_SOURCES): compile info_sun.c
+
+ * amd/info_sun.c: placeholder for meta info parser to get info
+ from Sun automount-style /etc/auto_master, possibly following
+ into multiple info services (via /etc/nsswitch.conf).
+
+ * libamu/xutil.c (xsnprintf): if vsnprintf truncated the output
+ string to avoid an overflow, print an error. Include some code to
+ break out any possible infinite loop between plog() and
+ xsnprintf().
+ (real_plog): now we can use (carefully) xsnprintf() directly.
+
+ * amd/sun_map.[hc]: cleanup and formatting.
+
+ * amd/sun_map_parse.y: to match the literal string "fstype=" use
+ double quotes, not single quotes.
+
+ * amd/get_args.c (get_args): call conf_parse() using conf_in.
+
+ * amd/amd.h: use renamed parser symbols (yyparse -> conf_parse;
+ yyin -> conf_in).
+
+ * ylwrap: Enhance wrapper to avoid the #define hacks done by Gdb,
+ and suggested by the Automake manual. This enhanced parser will
+ prefix each conflicting yacc/lex symbol with a unique name
+ produced from INPUT. For example, if INPUT is foo_parse.y, then
+ yyparse() becomes foo_parse(). This requires that both your .l
+ and corresponding .y files have the same prefix (e.g., foo_parse.y
+ and foo_tok.l).
+
+ * amd/Makefile.am (BUILT_SOURCES): define which yacc/lex .h/.c
+ source files are built automatically, and therefore should not be
+ in the distro (IMHO), and should be cleaned upon "make clean".
+ (amd_SOURCES): include new sun_map_parse.y and sun_map_tok.l files.
+
+ * ylwrap: new file needed because we have two parsers now.
+
+ * amd/sun_map_{parse.y,tok.l}: cleanup and formatting.
+
+2005-08-06 Daniel P. Ottavio <dottavio@ic.sunysb.edu>
+
+ * amd/Makefile.am: Added new files sun_map.h, sun_map.c,
+ sun_map_parse.y, and sun_map_tok.l. These files add support for
+ parsing Sun style maps. The yacc/lex files needed custom rules so
+ they don't cause symbol conflicts with each other.
+
+ * amd/amd.h: Added "#define INFO_MAX_LINE_LEN" that specifies the
+ line limit for info services.
+
+ * amd/info_exec.c: Replaced MAX_LINE_LEN with INFO_MAX_LINE_LEN
+
+ * amd/info_file.c: Replaced MAX_LINE_LEN with INFO_MAX_LINE_LEN,
+ added support for parsing Sun style maps. The support for Sun
+ maps is done using the sun_entry2amd() function. This function is
+ called for each entry line that is read only when Sun parsing is
+ enabled. For each entry line that is passed to the function a
+ copy of the Amd equivalent is returned.
+
+ * amd/sun_map.h: new header file for Sun style map support
+
+ * amd/sun_map.c: new source file for Sun style map support, clean
+ up comments, additional sun2amd conversion routines
+
+ * amd/sun_map_parse.y: new yacc file for parsing Sun style maps,
+ fix copyright notice, put filename below license.
+
+ * amd/sun_map_tok.l: new lex file for parsing Sun style maps, fix
+ copyright notice, put filename below license.
+
+ * amd/get_args.c: replace usage of strlcat with xstrlcat
+
+ * include/am_utils.h: added 'extern void xstrlcat()'
+
+ * libamu/util.c: Added a xstrlcat() function that wraps the
+ syscall strlcat() so that string truncations can be logged.
+
2005-08-06 Erez Zadok <ezk@cs.sunysb.edu>
+ * amd/info_file.c (file_search, file_reload): pass mnt_map to
+ file_search_or_reload.
+ (file_search_or_reload): ensure that mnt_map is never NULL.
+
+ * amd/info_nis.c (nis_search): call sun_entry2amd() if
+ sun_map_syntax=yes.
+
+ * amd/info_ldap.c (amu_ldap_search): call sun_entry2amd() if
+ sun_map_syntax=yes.
+
+ * amd/info_hesiod.c (hesiod_search): call sun_entry2amd() if
+ sun_map_syntax=yes.
+
+ * amd/info_ndbm.c (ndbm_search): pass mnt_map to search_ndbm.
+ (search_ndbm): call sun_entry2amd() if sun_map_syntax=yes.
+
+ * amd/info_nisplus.c (nisplus_search): call sun_entry2amd() if
+ sun_map_syntax=yes.
+
+ * amd/info_exec.c (exec_search): pass mnt_map to
+ exec_parse_qanswer.
+ (exec_parse_qanswer): call sun_entry2amd() if sun_map_syntax=yes.
+
+ * doc/am-utils.texi (sun_map_syntax Parameter): document new
+ common parameter.
+
* scripts/amd.conf.5: selectors_in_defaults is a common parameter,
not just [global]. Use consistent capitalization of Amd/Amq.
+ Document new sun_map_syntax parameter.
* scripts/amd.conf-sample: properly list all of the parameters
which are common to both the [global] and the per-map sections.
+ (sun_map_syntax): example of new parameter.
* doc/am-utils.texi (Common Parameters): selectors_in_defaults is
a common parameter, not just [global].
* scripts/amd.conf-sample (sun_map_syntax): example of new flag.
+ * amd/conf.c ({ropt,gopt}_sun_map_syntax): new function to parse
+ sun_map_syntax flag (global or per map).
+
+ * amd/amd.h (CFM_SUN_MAP_SYNTAX): new flag for users to say if the
+ map uses Sun automounter syntax.
+
* cvs-server.txt: update instructions after branching 6.1-stable.
2005-08-02 Erez Zadok <ezk@cs.sunysb.edu>
diff --git a/contrib/amd/FAQ b/contrib/amd/FAQ
index 18e73a3fab20..3fbcb4cdb1d0 100644
--- a/contrib/amd/FAQ
+++ b/contrib/amd/FAQ
@@ -26,7 +26,7 @@ answer your questions, see information in the following sources:
listed in bugzilla in https://bugzilla.am-utils.org/
If you have additions to this FAQ, please let us know at
-am-utils@am-utils.org.
+the am-utils list (see www.am-utils.org).
Thank you,
The Am-utils development team.
diff --git a/contrib/amd/INSTALL b/contrib/amd/INSTALL
index 273fe02f4548..2099840756e6 100644
--- a/contrib/amd/INSTALL
+++ b/contrib/amd/INSTALL
@@ -1,124 +1,370 @@
- am-utils 6.1 compatibility list
-
-For each system, list if it autoconfigures, compiles, or runs. Fill in
-email id of person who confirms the fact. A missing entry means unverified.
-A 'no' or 'X' means verified broken or nonexistent (static library).
-
-SYSTEM CONFIG COMPILE RUN SHLIB AUTOFS
-========================= ======= ======= ======= ======= ======
-alpha-dec-osf4.0f ro ro ro - -
-alpha-dec-osf5.1 ro ro ro - -
-alpha-unknown-linux-gentoo1.4.16 ezk ezk ezk ezk -
-alphaev56-dec-osf4.0f ezk ezk ezk ezk -
-i386-apple-darwin6.0 ezk ezk ezk ezk -
-i386-pc-bsdi2.1 ion ion ion ion[X] ion[X]
-i386-pc-linux-deb3.0 ezk ezk ezk ezk -
-i386-pc-linux-deb3.1 ezk ezk ezk ezk -
-i386-pc-linux-fc1 ezk ezk ezk ezk -
-i386-pc-linux-fc2 ezk ezk ezk ezk -
-i386-pc-linux-fc3 ezk ezk ezk ezk -
-i386-pc-linux-fc4 ezk ezk ezk ezk -
-i386-pc-linux-gentoo1.4.16 ezk ezk ezk ezk -
-i386-pc-linux-rh6.2 ion ion ion ion ion
-i386-pc-linux-rh7.1 ion ion ion ion ion
-i386-pc-linux-rh7.2 ion ion ion ion ion
-i386-pc-linux-rh7.3 ion ion ion ion ion
-i386-pc-linux-rh8.0 ezk ezk ezk ezk -
-i386-pc-linux-rh9 ion ion ion ion ion
-i386-pc-linux-rhel3 ezk ezk ezk ezk -
-i386-pc-linux-rhel4 ezk ezk ezk ezk -
-i386-pc-linux-suse8.2 ezk ezk ezk ezk -
-i386-pc-linux-suse9.1 ezk ezk ezk ezk -
-i386-pc-linux-suse9.2 ezk ezk ezk ezk -
-i386-pc-linux-suse9.3 ezk ezk ezk ezk -
-i386-pc-solaris2.10 ro ro ro - -
-i386-pc-solaris2.9 ro ro ro - -
-i386-unknown-freebsd4.10 ezk ezk ezk ezk -
-i386-unknown-freebsd4.11 ezk ezk ezk ezk -
-i386-unknown-freebsd4.8 ezk ezk ezk ezk -
-i386-unknown-freebsd4.9 ezk ezk ezk ezk -
-i386-unknown-freebsd5.0 ezk ezk - ezk -
-i386-unknown-freebsd5.1 ezk ezk ezk ezk -
-i386-unknown-freebsd5.2 ezk ezk ezk ezk -
-i386-unknown-freebsd5.2.1 ezk ezk ezk ezk -
-i386-unknown-freebsd5.3 ezk ezk ezk ezk -
-i386-unknown-freebsd5.4 ezk ezk ezk ezk -
-i386-unknown-freebsd6 (BETA5) ezk ezk ezk ezk -
-i386-unknown-netbsd1.6A ezk ezk ezk ezk -
-i386-unknown-netbsdelf1.6.1 ezk ezk ezk ezk -
-i386-unknown-netbsdelf1.6.2 ezk ezk ezk ezk -
-i386-unknown-netbsdelf2.0 ezk ezk ezk ezk -
-i386-unknown-netbsdelf2.0.2 ezk ezk ezk ezk -
-i386-unknown-netbsdelf3.0 ezk ezk ezk ezk -
-i386-unknown-openbsd3.3 ezk ezk ezk ezk -
-i386-unknown-openbsd3.6 ezk ezk ezk ezk -
-i386-unknown-openbsd3.7 ezk ezk ezk ezk -
-i686-apple-darwin6.6 ezk ezk ezk ezk -
-ia64-hp-hpux11.20 ezk ezk ezk ezk -
-ia64-unknown-linux-rh2.1AS ezk ezk - ezk -
-ia64-unknown-linux-rh2.1AW ezk ezk ezk ezk -
-ia64-unknown-linux-rhel4 ezk ezk ezk ezk -
-mips-sgi-irix6.2 ro ro ro - -[3]
-mips-sgi-irix6.5 ro ro ro - -[3]
-mips-unknown-linux-gentoo1.4.16 ezk ezk ezk ezk -
-mipsel-unknown-linux-rhPS2 ezk ezk ezk ezk -
-powerpc-apple-darwin7.6.0 ezk ezk ezk ezk -
-powerpc-apple-darwin7.7.0 ezk ezk ezk ezk -
-powerpc-apple-darwin7.8.0 ezk ezk ezk ezk -
-powerpc-apple-darwin7.9.0 ezk ezk ezk ezk -
-powerpc-apple-darwin8.2.0 ezk ezk ezk ezk -
-powerpc-ibm-aix5.1.0.0 ion ion ion ion[X] ion[1,2]
-powerpc-ibm-aix5.2.0.0 ezk ezk ezk ezk -
-powerpc-ibm-aix5.3.0.0 ezk ezk ezk ezk -
-powerpc-unknown-linux-yellowdog2.3 ezk ezk ezk ezk -
-sparc-sun-solaris2.10 ro ro ro - -
-sparc-sun-solaris2.5.1 ion ion ion ion ion[1]
-sparc-sun-solaris2.6 ion ion ion ion ion
-sparc-sun-solaris2.7 ion ion ion ion ion
-sparc-sun-solaris2.8 ion ion ion ion ion
-sparc-sun-solaris2.9 ro ro ro - -
-sparc-unknown-linux-rh62 ion ion ion ion ion
-sparc64-unknown-linux-aurora10 ion ion ion ion ion
-sparc64-unknown-linux-deb3.0 ezk ezk ezk ezk -
-sparc64-unknown-linux-gentoo1.4.16 ezk ezk ezk ezk -
-sparc64-unknown-linux-rh62 ion ion ion ion ion
-sparc64-unknown-linux-suse7.3 ezk ezk - ezk -
-x86_64-unknown-linux-rh2.9.5AS ezk ezk ezk ezk -
-x86_64-unknown-linux-rh3.0.0AS ion ion ion ion ion
-
-
-EMAIL ID LEGEND:
-
-bking: Bevis R W King <B.King@ee.surrey.ac.uk>
-dsr: Dan Riley <dsr@mail.lns.cornell.edu>
-ezk: Erez Zadok <ezk@cs.columbia.edu>
-finkel: Raphael Finkel <raphael@cs.uky.edu>
-ion: Ion Badulescu <ion@cs.columbia.edu>
-jose: Jose Nazario <jose@biocserver.BIOC.CWRU.Edu>
-nrh: Nick Hall <nrh@dcs.ed.ac.uk>
-ro: Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
-stolke: Andreas Stolcke <stolcke@speech.sri.com>
-wpaul: Bill Paul <wpaul@ctr.columbia.edu>
-
-
-FOOTNOTES:
-
-[1] Due to limitations in the Sun autofs v1 implementation, some amd features
-cannot be properly supported. More precisely, trying to access a link mount
-pointing to another amd entry will result in failure and/or deadlock.
-Ordinary nfs and link mounts work well, however.
-
-[2] AIX autofs appears to be a variant of the Sun autofs v1 protocol, but
-IBM don't provide any sort of documentation or even header files from it.
-It is currently unsupported; we may add some experimental support for it at
-some point, though it won't be pretty. Assistance from IBM-ers would be
-highly appreciated, hint hint.
-
-[3] IRIX 6 autofs uses the Sun autofs v1 protocol, too. The header files
-are part of the onc3_eoe.sw.autofs (IRIX 6.2) or nfs.sw.autofs (IRIX 6.5)
-package, which may not be installed. The autofs code is known to compile,
-but hasn't been run yet. SGI's autofsd uses a barely documented system
-call, syssgi(SGI_AUTOFS_SYS, ...), which may be required to get working
-autofs support. Additional help from SGI would be highly appreciated.
-
-Erez & Ion
+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.
diff --git a/contrib/amd/MIRRORS.html b/contrib/amd/MIRRORS.html
index 0deeefe32c77..511df2b905cc 100644
--- a/contrib/amd/MIRRORS.html
+++ b/contrib/amd/MIRRORS.html
@@ -11,8 +11,8 @@
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 <A
-HREF="mailto:am-utils-developers@am-utils.org">am-utils-developers@am-utils.org</A> with 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>
@@ -24,8 +24,8 @@ full URL, maintainer's email, and geographical location.
<UL>
<LI> FTP: <A
HREF="ftp://ftp.am-utils.org/pub/am-utils">ftp.am-utils.org</A>.
- Contact person in case of problems <A
- HREF="mailto:am-utils-developers@am-utils.org">am-utils-developers@am-utils.org</A>.
+ Contact person in case of problems
+"am-utils-developers AT am-utils.org".
</LI>
</UL>
@@ -33,14 +33,14 @@ full URL, maintainer's email, and geographical location.
<UL>
<LI> FTP: <A
HREF="ftp://ftp.cs.umn.edu/pub/am-utils">ftp.cs.umn.edu</A>.
- Maintainer <A HREF="mailto:dokas@cs.umn.edu">dokas@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@cise.ufl.edu">mirror@cise.ufl.edu</A>.
+ Maintainer <A HREF="mailto:mirror AT cise.ufl.edu">mirror AT cise.ufl.edu</A>.
</LI>
</UL>
@@ -52,24 +52,24 @@ full URL, maintainer's email, and geographical location.
<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@ftp.fu-berlin.de">ftp-adm@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@ftp.tu-darmstadt.de">networking@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@ftp.sunet.se">archive@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@icparc.ic.ac.uk">lmjm@icparc.ic.ac.uk</A>.
+ Maintainer <A HREF="mailto:lmjm AT icparc.ic.ac.uk">lmjm AT icparc.ic.ac.uk</A>.
</LI>
</UL>
@@ -81,21 +81,21 @@ full URL, maintainer's email, and geographical location.
<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@u-aizu.ac.jp">ftp-admin@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@ring.gr.jp">ftpadmin@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@ring.gr.jp">ftpadmin@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: Jan 5, 2004</I>
+<I> Last updated: 2006-11-27</I>
</BODY>
</HTML>
diff --git a/contrib/amd/MIRRORS.txt b/contrib/amd/MIRRORS.txt
index b5093e8f4aa4..087c6ccd0cce 100644
--- a/contrib/amd/MIRRORS.txt
+++ b/contrib/amd/MIRRORS.txt
@@ -2,59 +2,59 @@
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@am-utils.org
+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@am-utils.org
+ Maintainer: ezk AT am-utils.org
Minnesota:
ftp://ftp.cs.umn.edu/pub/am-utils
- Maintainer: dokas@cs.umn.edu
+ 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@FergInc.com
+# 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@mcs.kent.edu
+# Maintainer: root AT mcs.kent.edu
Florida (University of Florida)
ftp://ftp.cise.ufl.edu/pub/mirrors/am-utils
- Maintainer: mirror@cise.ufl.edu
+ Maintainer: mirror AT cise.ufl.edu
Europe:
Germany:
ftp://ftp.fu-berlin.de/unix/network/am-utils
- Maintainer: ftp-adm@ftp.fu-berlin.de
+ Maintainer: ftp-adm AT ftp.fu-berlin.de
Germany:
ftp://ftp.tu-darmstadt.de/pub/networking/filesystems/am-utils/
- Maintainer: networking@ftp.tu-darmstadt.de
+ Maintainer: networking AT ftp.tu-darmstadt.de
Sweden:
ftp://ftp.sunet.se/pub/unix/admin/am-utils
- Maintainer: archive@ftp.sunet.se
+ 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@matematik.su.se
+# Maintainer: leifj AT matematik.su.se
UK:
ftp://sunsite.org.uk/package/am-utils
- Maintainer: lmjm@icparc.ic.ac.uk
+ Maintainer: lmjm AT icparc.ic.ac.uk
Asia:
Japan:
ftp://ftp.u-aizu.ac.jp/pub/net/amd/am-utils
- Maintainer: ftp-admin@u-aizu.ac.jp
+ Maintainer: ftp-admin AT u-aizu.ac.jp
Japan:
ftp://core.ring.gr.jp/pub/net/am-utils/
- Maintainer: ftpadmin@ring.gr.jp
+ Maintainer: ftpadmin AT ring.gr.jp
Japan:
ftp://ftp.ring.gr.jp/pub/net/am-utils/
- Maintainer: ftpadmin@ring.gr.jp
+ 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@ftp.sage-au.org.au
+# Maintainer: mirror AT ftp.sage-au.org.au
diff --git a/contrib/amd/NEWS b/contrib/amd/NEWS
index 5cde984ed518..b7fbedac6d02 100644
--- a/contrib/amd/NEWS
+++ b/contrib/amd/NEWS
@@ -1,4 +1,44 @@
-*** Notes specific to am-utils version 6.1.5
+*** Notes specific to am-utils version 6.2
+
+ - Removed license advertising clause
+ - Removed expn program
+
+*** Notes specific to am-utils version 6.2-rc1
+
+Filesystem Support:
+ - Add support for NFSv4
+ - Add support for Lustre
+ - Add support for ext{2,3,4}
+ - Add support for linux autofs version 5
+ - Add support for TMPFS and UDF
+New features:
+ - Add amq -i (prints information about maps)
+ - Add synchronous unmount code for amq -uu
+ - Allow a comma-separated list of LDAP servers for failover
+Changes in behavior:
+ - Empty variable assignments, now unset the variable value.
+ - Share LDAP connections between different maps to save resources
+Portability fixes:
+ - Changes to work with Linux-2.6.x, Linux-3.x and NetBSD-5.x, NetBSD-6.x,
+ FreeBSD 7.x, Solaris
+Bug fixes:
+ - Many bug fixes, see ChangeLog
+
+*** Notes specific to am-utils version 6.2a3
+
+- minor new ports:
+ i386-apple-darwin8.8.1
+ i386-pc-linux-centos4.4 (RHEL4 clone)
+ i386-pc-linux-fc6 (Fedora Core 6)
+ i386-pc-solaris2.11-nexentaos (GNU/OpenSolaris)
+ ia64-hp-hpux11.23 (gcc and cc)
+ powerpc-apple-darwin8.7.0
+
+- Bugs fixed:
+ * reduce annoying warnings from xstrlcpy when expanding options.
+ * translate '*' Sun maps correctly with "${key}"
+
+*** Notes specific to am-utils version 6.2a2
New amd.conf global parameter: nfs_allow_any_interface. By default it is
set to 'no' which means that Amd accepts local NFS packets only from
@@ -11,21 +51,6 @@ Add support for specifying the host to match in the mount selectors netgrp
and netgrpd. Now one can use either netgrp(<group-name>) or
netgrp(<group-name>,<host-name>).
-- Bugs fixed:
- * handle old-style filehandles correctly (for mount points longer
- than 28 chars)
- * don't turn off attribute cache for regular NFS mounts (improves
- performance)
- * detect G/DBM support via gdbm_compat library (Debian)
- * detect NDBM support in libc (FreeBSD 6)
-
-- minor new ports:
- i386-unknown-freebsd6.1 (RELEASE)
- i386-unknown-openbsd3.9
- powerpc-apple-darwin8.6.0
-
-*** Notes specific to am-utils version 6.1.4
-
Support new mount options for type:=pcfs mounts: longname, nowin95,
shortname, user=N, group=N, mask=N, and dirmask=N.
@@ -41,44 +66,28 @@ better tune Amd's responsiveness under heavy scheduler loads.
i386-pc-linux-fc5 (Fedora Core 5)
i386-pc-linux-suse10.1 (beta 8)
i386-unknown-freebsd6.0 (RELEASE)
+ i386-unknown-freebsd6.1 (RELEASE)
i386-unknown-netbsdelf2.1
i386-unknown-netbsdelf3.0 (RELEASE)
i386-unknown-openbsd3.8
+ i386-unknown-openbsd3.9
powerpc-apple-darwin8.5.0
+ powerpc-apple-darwin8.6.0
- Bugs fixed:
* one serious memory leak in amfs_generic (caught by Coverity)
* assorted potential (but rare) NULL pointer dereferences (Coverity)
* correctly print nfs_args->addr info (sin_family/port/addr)
* pawd should resolve path repeatedly until no more to do
+ * handle old-style filehandles correctly (for mount points longer
+ than 28 chars)
* use-after-free bug in amfs_lookup_mntfs (Coverity)
+ * don't turn off attribute cache for regular NFS mounts (improves
+ performance)
+ * detect G/DBM support via gdbm_compat library (Debian)
+ * detect NDBM support in libc (FreeBSD 6)
-*** Notes specific to am-utils version 6.1.3
-
-- Bugs fixed:
- * amq should de-register properly on exit
- * convert all sprintf to safer xsnprintf
- * convert all strcat to safer xstrlcat
- * convert all strcpy to safer xstrlcpy
- * fix three buffer overruns in expand_op (amd/opts.c)
- * pawd was trying UDP only, now try TCP if UDP failed
-
-Moved pawd's path-matching functionality into Amd, where it can be done a
-lot more efficiently (we no longer need to construct and send the whole
-mounted tree, only to match small parts of it). This will lessen the CPU
-and network load on systems that use pawd heavily, and also minimize the
-chance that we exceed default or hard-coded UDP/TCP RPC packet sizes.
-
-*** Notes specific to am-utils version 6.1.2.1
-
-- Bugs fixed:
- * properly turn off the attrcache in freebsd and openbsd
- * can turn off attrcache on netbsd, but need kernel patch, see
- README.attrcache
- * pawd goes into an infinite loop on type:=auto
- * consistent search for file system mnttab/mount names
-
-*** Notes specific to am-utils version 6.1.2
+*** Notes specific to am-utils version 6.2a1
MAJOR BUG FIXES: Synchronize Amd's view of its file systems with the
kernel's NFS client-side DNLC/dcache. Amd changes its view when it reloads
@@ -114,13 +123,82 @@ Amd.
Tell syslog not to log automatically to /dev/console; it's unfriendly. If
user really wants to, they can set it in /etc/syslog.conf.
+Moved pawd's path-matching functionality into Amd, where it can be done a
+lot more efficiently (we no longer need to construct and send the whole
+mounted tree, only to match small parts of it). This will lessen the CPU
+and network load on systems that use pawd heavily, and also minimize the
+chance that we exceed default or hard-coded UDP/TCP RPC packet sizes.
+
+Changed slightly how Amd behaves when you try to change log_options after
+Amd started (options can be turned on/off via "amq -x ARG"). It used to be
+that Amd won't let you turn off options which were on when Amd started.
+That limited users' ability to reduce Amd's logging levels to a minimum.
+Now, Amd will allow you to turn on/off any option, other than the two
+options "fatal" and "error." Both are on by default and considered
+mandatory. These two don't produce a lot of log messages, so your logs will
+remain small, but they are important to keep on, so Amd can report serious
+problems (including errors relating to incorrectly setting other log
+options).
+
+Amd now understands a new log_option called "defaults" which is synonymous
+with "fatal,error,user,warning,info" (and is also what logging happens by
+default).
+
+Amd now understands a new debug_option called "defaults" which is synonymous
+with "all,nohrtime,nomtab,noxdrtrace".
+
+Changed the misleading inverted logic of certain debug_options:
+
+1. "xdrtrace" is included in "all" because "all" (as the name implies),
+ should be *all* options, not just a subset. If you want the old behavior
+ of "all" then use "defaults" (all only adds "xdrtrace" which can be
+ chatty on some systems).
+
+2. Certain debug options are hereby declared immutable: they may not be
+ changed by "amq -D" after Amd starts, because it doesn't make much sense
+ to change them after Amd starts, and it could really mess up Amd. These
+ immutable flags are currently "daemon," "fork," "amq," and "mtab."
+
+3. the debug option "daemon" *will* cause Amd to daemonize. Before, it was
+ causing Amd NOT to daemonize. This was greatly confusing, especially
+ since the code, documentation, and comments often conflicted with each
+ other. If you don't want Amd to daemonize, which is useful for debugging
+ it, then use the debug option "nodaemon" -- it makes a lot more sense.
+
+4. Similarly, the "fork" option *will* cause Hlfsd to fork. Use "nofork" if
+ you don't want Hlfsd to fork. This option is only applicable to Hlfsd.
+
+5. Similarly, the "amq" option, which is now on by default, will cause Amd
+ to register itself with the RPC portmapper (for Amq), as is done
+ normally. If you don't want Amd to register with the portmapper, use
+ "noamq" -- this naming convention makes more sense. This was also
+ confusingly documented and coded in places.
+
+ Note: unfortunately, these changes to the "daemon," "fork," and "amq"
+ debug options may be incompatible with people's previous use of Amd.
+ Some of you may have to update your amd.conf slightly or your startup
+ options (if they're hard-coded in your amd startup script). Sorry, but
+ we have to fix those old problems sooner or later. However, if you never
+ set any debug_options, or you used to "all," then you won't be affected
+ by the change in meaning of these three flags.
+
- minor new ports:
i386-pc-linux-deb3.1
- i386-unknown-netbsdelf3.0
+ i386-unknown-netbsdelf3.0 (BETA)
powerpc-apple-darwin8.2.0
-- bugs fixed:
- * minor documentation corrections
+- Bugs fixed:
+ * abort with an error if yacc/lex programs not found
+ * properly turn off the attrcache in freebsd and openbsd
+ * can turn off attrcache on netbsd, but need kernel patch, see
+ README.attrcache
+ * pawd goes into an infinite loop on type:=auto
+ * consistent search for file system mnttab/mount names
+ * convert all sprintf to safer xsnprintf
+ * convert all strcat to safer xstrlcat
+ * convert all strcpy to safer xstrlcpy
+ * fix three buffer overruns in expand_op (amd/opts.c)
+ * pawd was trying UDP only, now try TCP if UDP failed
*** Notes specific to am-utils version 6.1.1
@@ -328,7 +406,7 @@ version (10.3.x) than uname(3) reports.
Useful with firewalls and NAT'ed environments.
- new amd.conf option "debug_mtab_file". Allows user to define the mtab
- file during debug-mtab mode. The default path is "/tmp/mnttab".
+ file during debug-mtab mode. The default path is "/tmp/mtab".
- new function selector xhost(ARG) which will match ARG against the current
host name. This works even if ARG is a CNAME (unlike the host==ARG
diff --git a/contrib/amd/README b/contrib/amd/README
index 0b3ce46beb63..4b4aec0e8c0c 100644
--- a/contrib/amd/README
+++ b/contrib/amd/README
@@ -81,7 +81,7 @@ or
./buildall -K
To be a developer and be able to run "bootstrap", you must have
-autoconf-2.50, automake-1.5, and libtool 1.4 installed on your system (or
+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.
@@ -94,9 +94,9 @@ before. Let me know if you are having any problems with them. I fully
expect, at least initially, to have to be the sole developers of the M4
macros and let others concentrate on C sources.
-[E] Report all bugs to am-utils@am-utils.org. Avoid reporting to my
-personal email address. It is important to involve the whole list in bug
-fixes etc.
+[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.
diff --git a/contrib/amd/README.attrcache b/contrib/amd/README.attrcache
index e8522d226ebe..7bd10874bf8c 100644
--- a/contrib/amd/README.attrcache
+++ b/contrib/amd/README.attrcache
@@ -122,8 +122,8 @@ OS. You can run this script as root as follows:
# sh test-attrcache
If you run this script on an OS whose status is known (and not listed
-above), please report it to am-utils@am-utils.org, so we can record it in
-this file.
+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.
diff --git a/contrib/amd/README.ldap b/contrib/amd/README.ldap
index 715113442552..24095cafa9ca 100644
--- a/contrib/amd/README.ldap
+++ b/contrib/amd/README.ldap
@@ -1,12 +1,12 @@
LDAP support for am-utils was originally done by Leif Johansson
-<leifj@it.su.se>. He no longer maintains it.
+<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@am-utils.org
+ 10180 Am-utils Organization Erez Zadok ezk AT am-utils.org
There are three files in this directory that relate to LDAP:
@@ -33,8 +33,8 @@ Erez.
------- Forwarded Message
-From: "IANA Private Enterprise Number" <iana-pen@icann.org>
-To: "Erez Zadok" <ezk@cs.columbia.edu>
+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
@@ -43,7 +43,7 @@ Dear Erez,
The IANA has assigned the following Private Enterprise
Number to:
-10180 Am-utils Organization Erez Zadok ezk@am-utils.org
+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.
diff --git a/contrib/amd/README.y2k b/contrib/amd/README.y2k
index e75bd122590e..b0b887c500a9 100644
--- a/contrib/amd/README.y2k
+++ b/contrib/amd/README.y2k
@@ -8,10 +8,10 @@ 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@ms.com>
+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@sedona.ch.intel.com> submitted a
+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.
@@ -23,5 +23,4 @@ CERTIFY AM-UTILS AS Y2K COMPLIANT. USE AT YOUR OWN RISK.
---
Erez Zadok.
Maintainer, am-utils package and am-utils list.
-Email: am-utils@am-utils.org
WWW: http://www.am-utils.org
diff --git a/contrib/amd/amd/am_ops.c b/contrib/amd/amd/am_ops.c
index 5a5c33650eca..4d07dc807d90 100644
--- a/contrib/amd/amd/am_ops.c
+++ b/contrib/amd/amd/am_ops.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -96,6 +92,11 @@ static am_ops *vops[] =
#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 */
@@ -111,6 +112,9 @@ static am_ops *vops[] =
#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 */
@@ -120,6 +124,12 @@ static am_ops *vops[] =
#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:
@@ -316,7 +326,7 @@ merge_opts(const char *opts1, const char *opts2)
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 = strdup(opts1); /* copy of opts1 to munge */
+ char *s1 = xstrdup(opts1); /* copy of opts1 to munge */
/* initialization */
mnt2.mnt_opts = (char *) opts2;
@@ -327,13 +337,13 @@ merge_opts(const char *opts1, const char *opts2)
tmpstr;
tmpstr = strtok(NULL, ",")) {
/* copy option to temp buffer */
- xstrlcpy(oneopt, tmpstr, 80);
+ xstrlcpy(oneopt, tmpstr, sizeof(oneopt));
/* if option has a value such as rsize=1024, chop the value part */
- if ((eq = haseq(oneopt)))
+ if ((eq = strchr(oneopt, '=')))
*eq = '\0';
/* find reverse option of oneopt */
revoneopt = reverse_option(oneopt);
- /* if option orits reverse exist in opts2, ignore it */
+ /* 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 */
@@ -362,7 +372,7 @@ am_ops *
ops_search(char *type)
{
am_ops **vp;
- am_ops *rop = 0;
+ am_ops *rop = NULL;
for (vp = vops; (rop = *vp); vp++)
if (STREQ(rop->fs_type, type))
break;
@@ -373,7 +383,7 @@ ops_search(char *type)
am_ops *
ops_match(am_opts *fo, char *key, char *g_key, char *path, char *keym, char *map)
{
- am_ops *rop = 0;
+ am_ops *rop = NULL;
char *link_dir;
/*
@@ -400,7 +410,7 @@ ops_match(am_opts *fo, char *key, char *g_key, char *path, char *keym, char *map
* Otherwise skip past any leading '-'.
*/
if (fo->opt_opts == 0)
- fo->opt_opts = strdup("rw,defaults");
+ fo->opt_opts = xstrdup("rw,defaults");
else if (*fo->opt_opts == '-') {
/*
* We cannot simply do fo->opt_opts++ here since the opts
@@ -408,7 +418,7 @@ ops_match(am_opts *fo, char *key, char *g_key, char *path, char *keym, char *map
* So just reallocate the thing -- stolcke 11/11/94
*/
char *old = fo->opt_opts;
- fo->opt_opts = strdup(old + 1);
+ fo->opt_opts = xstrdup(old + 1);
XFREE(old);
}
@@ -426,7 +436,7 @@ ops_match(am_opts *fo, char *key, char *g_key, char *path, char *keym, char *map
XFREE(fo->opt_opts);
XFREE(fo->opt_remopts);
fo->opt_opts = mergedstr;
- fo->opt_remopts = strdup(mergedstr);
+ fo->opt_remopts = xstrdup(mergedstr);
} else {
char *mergedstr, *remmergedstr;
mergedstr = merge_opts(fo->opt_opts, fo->opt_addopts);
@@ -451,7 +461,7 @@ ops_match(am_opts *fo, char *key, char *g_key, char *path, char *keym, char *map
/* 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 *) 0, fo->opt_fs, "/", link_dir);
+ link_dir = str3cat((char *) NULL, fo->opt_fs, "/", link_dir);
normalize_slash(link_dir);
XFREE(fo->opt_sublink);
fo->opt_sublink = link_dir;
@@ -460,8 +470,7 @@ ops_match(am_opts *fo, char *key, char *g_key, char *path, char *keym, char *map
/*
* Check the filesystem is happy
*/
- if (fo->fs_mtab)
- XFREE(fo->fs_mtab);
+ XFREE(fo->fs_mtab);
fo->fs_mtab = rop->fs_match(fo);
if (fo->fs_mtab)
diff --git a/contrib/amd/amd/amd.8 b/contrib/amd/amd/amd.8
index ca6b6de39f59..35eba4c5baa8 100644
--- a/contrib/amd/amd/amd.8
+++ b/contrib/amd/amd/amd.8
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 1997-2006 Erez Zadok
+.\" 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.
@@ -16,11 +16,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 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.
.\"
@@ -36,9 +32,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" %W% (Berkeley) %G%
.\"
-.\" $Id: amd.8,v 1.14.2.1 2006/01/02 18:48:23 ezk Exp $
+.\" File: am-utils/amd/amd.8
.\" $FreeBSD$
.\"
.Dd February 26, 2016
@@ -232,20 +227,20 @@ Specify an
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
+Specify run-time logging options. The options are a comma separated
list chosen from:
-.Li fatal , error , user , warn , info , map , stats , all .
+.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
-.Tn NIS
+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.
@@ -367,14 +362,15 @@ number of process context switches.
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 mount 8 ,
-.Xr umount 8
+.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
diff --git a/contrib/amd/amd/amd.c b/contrib/amd/amd/amd.c
index 3fc25f833dbb..7ec49ce1cec5 100644
--- a/contrib/amd/amd/amd.c
+++ b/contrib/amd/amd/amd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -379,7 +375,7 @@ do_memory_locking(void)
#endif /* HAVE_PLOCK || HAVE_MLOCKALL */
#if defined(HAVE_MADVISE) && defined(MADV_PROTECT)
- madvise(0, 0, MADV_PROTECT); /* may be redundant of the above worked out */
+ madvise(NULL, 0, MADV_PROTECT); /* may be redundant of the above worked out */
#endif /* defined(HAVE_MADVISE) && defined(MADV_PROTECT) */
}
@@ -431,6 +427,7 @@ main(int argc, char *argv[])
if (gethostname(hostname, sizeof(hostname)) < 0) {
plog(XLOG_FATAL, "gethostname: %m");
going_down(1);
+ return 1;
}
hostname[sizeof(hostname) - 1] = '\0';
@@ -440,6 +437,7 @@ main(int argc, char *argv[])
if (!*hostname) {
plog(XLOG_FATAL, "host name is not set");
going_down(1);
+ return 1;
}
/*
@@ -498,7 +496,8 @@ main(int argc, char *argv[])
getwire(&PrimNetName, &PrimNetNum);
/*
- * Determine command-line arguments
+ * Determine command-line arguments.
+ * (Also initialize amd.conf parameters, maps, and more.)
*/
get_args(argc, argv);
@@ -532,6 +531,7 @@ main(int argc, char *argv[])
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
@@ -543,10 +543,11 @@ main(int argc, char *argv[])
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))
+ if (amuDebug(D_DAEMON))
ppid = daemon_mode();
/*
diff --git a/contrib/amd/amd/amd.h b/contrib/amd/amd/amd.h
index 0e371b72a5b0..f66f5b75169f 100644
--- a/contrib/amd/amd/amd.h
+++ b/contrib/amd/amd/amd.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -54,9 +50,12 @@
* that support mtab on file.
*/
#ifdef MOUNT_TABLE_ON_FILE
-# define DEBUG_MNTTAB_FILE "/tmp/mnttab"
+# 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 */
@@ -76,10 +75,7 @@
#define CFM_NORMALIZE_SLASHES 0x00008000 /* normalize slashes? */
#define CFM_FORCED_UNMOUNTS 0x00010000 /* forced unmounts? */
#define CFM_TRUNCATE_LOG 0x00020000 /* truncate log file? */
-#if 0
-/* XXX: reserved to sync up with am-utils-6.2 */
#define CFM_SUN_MAP_SYNTAX 0x00040000 /* Sun map syntax? */
-#endif
#define CFM_NFS_ANY_INTERFACE 0x00080000 /* all interfaces are acceptable */
/* defaults global flags: plock, tcpwrappers, and autofs/lofs */
@@ -212,6 +208,7 @@ 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;
@@ -245,13 +242,17 @@ 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 *, nfscookie, nfsdirlist *, nfsentry *, u_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);
/*
@@ -314,6 +315,7 @@ struct amu_global_options {
#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 */
};
@@ -349,6 +351,7 @@ struct mnt_map {
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 */
@@ -420,7 +423,7 @@ struct mntfs {
am_opts *mf_fo; /* File opts */
char *mf_mount; /* "/a/kiska/home/kiska" */
char *mf_info; /* Mount info */
- char *mf_auto; /* Automount opts */
+ char *mf_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 */
@@ -435,6 +438,16 @@ struct mntfs {
};
/*
+ * Locations: bindings between keys and mntfs
+ */
+struct am_loc {
+ am_opts *al_fo;
+ mntfs *al_mnt;
+ int al_refc;
+};
+
+
+/*
* List of fileservers
*/
struct fserver {
@@ -463,6 +476,8 @@ struct am_stats {
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 */
};
/*
@@ -482,8 +497,8 @@ extern struct amd_stats amd_stats;
*/
struct am_node {
int am_mapno; /* Map number */
- mntfs *am_mnt; /* Mounted filesystem */
- mntfs **am_mfarray; /* Filesystem sources to try to mount */
+ 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 */
@@ -508,6 +523,7 @@ struct am_node {
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 */
};
/*
@@ -527,13 +543,18 @@ extern int *amqproc_getpid_1_svc(voidp argp, struct svc_req *rqstp);
extern int *amqproc_mount_1_svc(voidp argp, struct svc_req *rqstp);
extern int *amqproc_setopt_1_svc(voidp argp, struct svc_req *rqstp);
extern voidp amqproc_null_1_svc(voidp argp, struct svc_req *rqstp);
-extern voidp amqproc_umnt_1_svc(voidp argp, struct svc_req *rqstp);
+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_fh *get_root_nfs_fh(char *dir);
+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);
@@ -541,7 +562,8 @@ 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 yyparse (void);
+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);
@@ -566,12 +588,15 @@ 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);
@@ -579,9 +604,11 @@ 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 *);
@@ -596,7 +623,7 @@ 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 *);
+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);
@@ -608,9 +635,11 @@ 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 *);
@@ -639,8 +668,8 @@ extern char hostd[SIZEOF_HOSTD]; /* Host+domain */
/*
* Global variables.
*/
-extern FILE *yyin;
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
@@ -724,6 +753,19 @@ 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
@@ -731,6 +773,12 @@ 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.
*/
@@ -753,6 +801,13 @@ extern am_ops ufs_ops; /* Un*x file system */
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 */
@@ -772,7 +827,7 @@ extern am_ops amfs_root_ops; /* Root file system */
*/
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, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count);
+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);
@@ -808,7 +863,8 @@ extern am_ops amfs_direct_ops; /* Direct Automount file system (this too) */
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, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count);
+extern int amfs_error_readdir(am_node *mp, voidp cookie, voidp dp, voidp ep, u_int count);
+
#endif /* HAVE_AMU_FS_ERROR */
/*
diff --git a/contrib/amd/amd/amfs_auto.c b/contrib/amd/amd/amfs_auto.c
index 75a451fd111d..34fdb00f501c 100644
--- a/contrib/amd/amd/amfs_auto.c
+++ b/contrib/amd/amd/amfs_auto.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -101,6 +97,8 @@ am_ops amfs_auto_ops =
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
@@ -115,7 +113,7 @@ amfs_auto_mount(am_node *mp, mntfs *mf)
* Historical - not documented.
*/
if (mf->mf_info[0] == '.' && mf->mf_info[1] == '\0')
- mf->mf_info = strealloc(mf->mf_info, mp->am_parent->am_mnt->mf_info);
+ mf->mf_info = strealloc(mf->mf_info, mp->am_parent->am_al->al_mnt->mf_info);
/*
* Compute prefix:
@@ -131,12 +129,12 @@ amfs_auto_mount(am_node *mp, mntfs *mf)
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 = strdup("");
+ mp->am_pref = xstrdup("");
} else {
/*
* the prefix specified as an option
*/
- mp->am_pref = strdup(mf->mf_fo->opt_pref);
+ mp->am_pref = xstrdup(mf->mf_fo->opt_pref);
}
} else {
/*
@@ -147,7 +145,7 @@ amfs_auto_mount(am_node *mp, mntfs *mf)
char *ppref = mp->am_parent->am_pref;
if (ppref == 0)
ppref = "";
- mp->am_pref = str3cat((char *) 0, ppref, mp->am_name, "/");
+ mp->am_pref = str3cat((char *) NULL, ppref, mp->am_name, "/");
}
#ifdef HAVE_FS_AUTOFS
diff --git a/contrib/amd/amd/amfs_direct.c b/contrib/amd/amd/amfs_direct.c
index dbef743d0d7e..b911c2a1e2ce 100644
--- a/contrib/amd/amd/amfs_direct.c
+++ b/contrib/amd/amd/amfs_direct.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -93,8 +89,8 @@ amfs_direct_readlink(am_node *mp, int *error_return)
xp = next_nonerror_node(mp->am_child);
if (!xp) {
- if (!mp->am_mnt->mf_private)
- amfs_mkcacheref(mp->am_mnt); /* XXX */
+ 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);
diff --git a/contrib/amd/amd/amfs_error.c b/contrib/amd/amd/amfs_error.c
index 51bdaa6db14d..58a623102c1e 100644
--- a/contrib/amd/amd/amfs_error.c
+++ b/contrib/amd/amd/amfs_error.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -92,7 +88,7 @@ am_ops amfs_error_ops =
static char *
amfs_error_match(am_opts *fo)
{
- return strdup("(error-hook)");
+ return xstrdup("(error-hook)");
}
@@ -145,7 +141,7 @@ amfs_error_mount_child(am_node *ap, int *error_return)
* If we do then just give an error.
*/
int
-amfs_error_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count)
+amfs_error_readdir(am_node *mp, voidp cookie, voidp dp, voidp ep, u_int count)
{
return ESTALE;
}
diff --git a/contrib/amd/amd/amfs_generic.c b/contrib/amd/amd/amfs_generic.c
index 0d5996969cf8..25d734bbde00 100644
--- a/contrib/amd/amd/amfs_generic.c
+++ b/contrib/amd/amd/amfs_generic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -55,7 +51,7 @@
/****************************************************************************
*** MACROS ***
****************************************************************************/
-#define IN_PROGRESS(cp) ((cp)->mp->am_mnt->mf_flags & MFF_MOUNTING)
+#define IN_PROGRESS(cp) ((cp)->mp->am_al->al_mnt->mf_flags & MFF_MOUNTING)
/****************************************************************************
@@ -80,7 +76,7 @@ struct continuation {
int retry; /* Try again? */
time_t start; /* Time we started this mount */
int callout; /* Callout identifier */
- mntfs **mf; /* Current mntfs */
+ am_loc **al; /* Current location */
};
@@ -88,9 +84,9 @@ struct continuation {
*** FORWARD DEFINITIONS ***
****************************************************************************/
static am_node *amfs_lookup_node(am_node *mp, char *fname, int *error_return);
-static mntfs *amfs_lookup_one_mntfs(am_node *new_mp, mntfs *mf, char *ivec,
+static am_loc *amfs_lookup_one_location(am_node *new_mp, mntfs *mf, char *ivec,
char *def_opts, char *pfname);
-static mntfs **amfs_lookup_mntfs(am_node *new_mp, int *error_return);
+static am_loc **amfs_lookup_loc(am_node *new_mp, int *error_return);
static void amfs_cont(int rc, int term, opaque_t arg);
static void amfs_retry(int rc, int term, opaque_t arg);
static void free_continuation(struct continuation *cp);
@@ -108,7 +104,7 @@ amfs_lookup_node(am_node *mp, char *fname, int *error_return)
int error = 0; /* Error so far */
int in_progress = 0; /* # of (un)mount in progress */
mntfs *mf;
- char *expanded_fname = 0;
+ char *expanded_fname = NULL;
dlog("in amfs_lookup_node");
@@ -118,7 +114,7 @@ amfs_lookup_node(am_node *mp, char *fname, int *error_return)
* about the mount point.
*/
if (amd_state == Finishing) {
- if (mp->am_mnt == 0 || mp->am_mnt->mf_fsflags & FS_DIRECT) {
+ if (mp->am_al == NULL || mp->am_al->al_mnt == NULL || mp->am_al->al_mnt->mf_fsflags & FS_DIRECT) {
dlog("%s mount ignored - going down", fname);
} else {
dlog("%s/%s mount ignored - going down", mp->am_path, fname);
@@ -170,7 +166,7 @@ amfs_lookup_node(am_node *mp, char *fname, int *error_return)
* If the error code is undefined then it must be
* in progress.
*/
- mf = new_mp->am_mnt;
+ mf = new_mp->am_al->al_mnt;
if (mf->mf_error < 0)
goto in_progrss;
@@ -240,7 +236,7 @@ amfs_lookup_node(am_node *mp, char *fname, int *error_return)
*/
new_mp = get_ap_child(mp, expanded_fname);
XFREE(expanded_fname);
- if (new_mp == 0)
+ if (new_mp == NULL)
ereturn(ENOSPC);
*error_return = -1;
@@ -249,19 +245,25 @@ amfs_lookup_node(am_node *mp, char *fname, int *error_return)
-static mntfs *
-amfs_lookup_one_mntfs(am_node *new_mp, mntfs *mf, char *ivec,
- char *def_opts, char *pfname)
+static am_loc *
+amfs_lookup_one_location(am_node *new_mp, mntfs *mf, char *ivec,
+ char *def_opts, char *pfname)
{
am_ops *p;
am_opts *fs_opts;
+ am_loc *new_al;
mntfs *new_mf;
- char *mp_dir = 0;
+ char *mp_dir = NULL;
#ifdef HAVE_FS_AUTOFS
int on_autofs = 1;
#endif /* HAVE_FS_AUTOFS */
/* match the operators */
+ /*
+ * although we alloc the fs_opts here, the pointer is 'owned' by the am_loc and will
+ * be free'd on destruction of the am_loc. If we don't allocate a loc, then we need
+ * to free this.
+ */
fs_opts = CALLOC(am_opts);
p = ops_match(fs_opts, ivec, def_opts, new_mp->am_path,
pfname, mf->mf_info);
@@ -269,7 +271,7 @@ amfs_lookup_one_mntfs(am_node *new_mp, mntfs *mf, char *ivec,
/* XXX: this should be factored out into an autofs-specific function */
if (new_mp->am_flags & AMF_AUTOFS) {
/* ignore user-provided fs if we're using autofs */
- if (fs_opts->opt_sublink) {
+ if (fs_opts->opt_sublink && fs_opts->opt_sublink[0]) {
/*
* For sublinks we need to use a hack with autofs:
* mount the filesystem on the original opt_fs (which is NOT an
@@ -292,6 +294,9 @@ amfs_lookup_one_mntfs(am_node *new_mp, mntfs *mf, char *ivec,
/*
* Find or allocate a filesystem for this node.
+ * we search for a matching backend share, since
+ * we will construct our own al_loc to handle
+ * any customisations for this usage.
*/
new_mf = find_mntfs(p, fs_opts,
mp_dir,
@@ -300,6 +305,7 @@ amfs_lookup_one_mntfs(am_node *new_mp, mntfs *mf, char *ivec,
fs_opts->opt_opts,
fs_opts->opt_remopts);
+
/*
* See whether this is a real filesystem
*/
@@ -307,10 +313,16 @@ amfs_lookup_one_mntfs(am_node *new_mp, mntfs *mf, char *ivec,
if (p == &amfs_error_ops) {
plog(XLOG_MAP, "Map entry %s for %s did not match", ivec, new_mp->am_path);
free_mntfs(new_mf);
+ free_opts(fs_opts);
+ XFREE(fs_opts);
return NULL;
}
dlog("Got a hit with %s", p->fs_type);
+ new_al = new_loc();
+ free_mntfs(new_al->al_mnt);
+ new_al->al_mnt = new_mf;
+ new_al->al_fo = fs_opts; /* now the loc is in charge of free'ing this mem */
#ifdef HAVE_FS_AUTOFS
if (new_mp->am_flags & AMF_AUTOFS && on_autofs) {
@@ -332,12 +344,12 @@ amfs_lookup_one_mntfs(am_node *new_mp, mntfs *mf, char *ivec,
new_mf->mf_flags |= MFF_IS_AUTOFS;
#endif /* HAVE_FS_AUTOFS */
- return new_mf;
+ return new_al;
}
-static mntfs **
-amfs_lookup_mntfs(am_node *new_mp, int *error_return)
+static am_loc **
+amfs_lookup_loc(am_node *new_mp, int *error_return)
{
am_node *mp;
char *info; /* Mount info - where to get the file system */
@@ -348,10 +360,11 @@ amfs_lookup_mntfs(am_node *new_mp, int *error_return)
int error = 0; /* Error so far */
char path_name[MAXPATHLEN]; /* General path name buffer */
char *pfname; /* Path for database lookup */
- mntfs *mf, **mf_array;
+ mntfs* mf; /* The mntfs for the map of our parent */
+ am_loc **al_array; /* the generated list of locations */
int count;
- dlog("in amfs_lookup_mntfs");
+ dlog("in amfs_lookup_loc");
mp = new_mp->am_parent;
@@ -369,7 +382,7 @@ amfs_lookup_mntfs(am_node *new_mp, int *error_return)
pfname = new_mp->am_name;
}
- mf = mp->am_mnt;
+ mf = mp->am_al->al_mnt;
dlog("will search map info in %s to find %s", mf->mf_info, pfname);
/*
@@ -404,8 +417,8 @@ amfs_lookup_mntfs(am_node *new_mp, int *error_return)
else
def_opts = "";
- orig_def_opts = amfs_parse_defaults(mp, mf, strdup(def_opts));
- def_opts = strdup(orig_def_opts);
+ orig_def_opts = amfs_parse_defaults(mp, mf, xstrdup(def_opts));
+ def_opts = xstrdup(orig_def_opts);
/* first build our defaults */
num_ivecs = 0;
@@ -423,11 +436,11 @@ amfs_lookup_mntfs(am_node *new_mp, int *error_return)
num_ivecs++;
}
- mf_array = calloc(num_ivecs + 1, sizeof(mntfs *));
+ al_array = calloc(num_ivecs + 1, sizeof(am_loc *));
- /* construct the array of struct mntfs for this mount point */
+ /* construct the array of struct locations for this key */
for (count = 0, cur_ivec = ivecs; *cur_ivec; cur_ivec++) {
- mntfs *new_mf;
+ am_loc *new_al;
if (**cur_ivec == '-') {
XFREE(def_opts);
@@ -436,18 +449,18 @@ amfs_lookup_mntfs(am_node *new_mp, int *error_return)
* If we have a single dash '-' than we need to reset the
* default options.
*/
- def_opts = strdup(orig_def_opts);
+ def_opts = xstrdup(orig_def_opts);
dlog("Resetting the default options, a single dash '-' was found.");
} else {
/* append options to /default options */
- def_opts = str3cat((char *) 0, orig_def_opts, ";", *cur_ivec + 1);
+ def_opts = str3cat((char *) NULL, orig_def_opts, ";", *cur_ivec + 1);
dlog("Resetting def_opts to \"%s\"", def_opts);
}
continue;
}
/*
- * If a mntfs has already been found, and we find
+ * If a loc has already been found, and we find
* a cut then don't try any more locations.
*
* XXX: we do not know when the "/" was added as an equivalent for "||".
@@ -455,16 +468,16 @@ amfs_lookup_mntfs(am_node *new_mp, int *error_return)
*/
if (STREQ(*cur_ivec, "/") || STREQ(*cur_ivec, "||")) {
if (count > 0) {
- dlog("Cut: not trying any more locations for %s", mp->am_path);
+ dlog("Cut: not trying any more locations for %s", pfname);
break;
}
continue;
}
- new_mf = amfs_lookup_one_mntfs(new_mp, mf, *cur_ivec, def_opts, pfname);
- if (new_mf == NULL)
+ new_al = amfs_lookup_one_location(new_mp, mf, *cur_ivec, def_opts, pfname);
+ if (new_al == NULL)
continue;
- mf_array[count++] = new_mf;
+ al_array[count++] = new_al;
}
/* We're done with ivecs */
@@ -473,11 +486,11 @@ amfs_lookup_mntfs(am_node *new_mp, int *error_return)
XFREE(orig_def_opts);
XFREE(def_opts);
if (count == 0) { /* no match */
- XFREE(mf_array);
+ XFREE(al_array);
ereturn(ENOENT);
}
- return mf_array;
+ return al_array;
}
@@ -491,7 +504,7 @@ amfs_cont(int rc, int term, opaque_t arg)
{
struct continuation *cp = (struct continuation *) arg;
am_node *mp = cp->mp;
- mntfs *mf = mp->am_mnt;
+ mntfs *mf = mp->am_al->al_mnt;
dlog("amfs_cont: '%s'", mp->am_path);
@@ -556,7 +569,7 @@ amfs_cont(int rc, int term, opaque_t arg)
mf->mf_error = rc;
mf->mf_flags |= MFF_ERROR;
errno = rc; /* XXX */
- if (!STREQ(mp->am_mnt->mf_ops->fs_type, "linkx"))
+ if (!STREQ(mp->am_al->al_mnt->mf_ops->fs_type, "linkx"))
plog(XLOG_ERROR, "%s: mount (amfs_cont): %m", mp->am_path);
}
}
@@ -568,7 +581,7 @@ amfs_cont(int rc, int term, opaque_t arg)
* call the background mount routine again
*/
amd_stats.d_merr++;
- cp->mf++;
+ cp->al++;
}
amfs_bgmount(cp);
if (mp->am_error > 0)
@@ -608,13 +621,21 @@ amfs_retry(int rc, int term, opaque_t arg)
*/
plog(XLOG_INFO, "mount of \"%s\" has timed out", mp->am_path);
error = ETIMEDOUT;
- while (*cp->mf)
- cp->mf++;
+ while (*cp->al)
+ cp->al++;
/* explicitly forbid further retries after timeout */
cp->retry = FALSE;
}
if (error || !IN_PROGRESS(cp))
error = amfs_bgmount(cp);
+ else
+ /* Normally it's amfs_bgmount() which frees the continuation. However, if
+ * the mount is already in progress and we're in amfs_retry() for another
+ * node we don't try mounting the filesystem once again. Still, we have
+ * to free the continuation as we won't get called again and thus would
+ * leak the continuation structure and our am_loc references.
+ */
+ free_continuation(cp);
reschedule_timeout_mp();
}
@@ -626,7 +647,7 @@ amfs_retry(int rc, int term, opaque_t arg)
static void
free_continuation(struct continuation *cp)
{
- mntfs **mfp;
+ am_loc **alp;
dlog("free_continuation");
if (cp->callout)
@@ -634,13 +655,12 @@ free_continuation(struct continuation *cp)
/*
* we must free the mntfs's in the list.
* so free all of them if there was an error,
- * or free all but the used one, if the mount succeeded.
*/
- for (mfp = cp->mp->am_mfarray; *mfp; mfp++) {
- free_mntfs(*mfp);
+ for (alp = cp->mp->am_alarray; *alp; alp++) {
+ free_loc(*alp);
}
- XFREE(cp->mp->am_mfarray);
- cp->mp->am_mfarray = 0;
+ XFREE(cp->mp->am_alarray);
+ cp->mp->am_alarray = 0;
XFREE(cp);
}
@@ -690,12 +710,13 @@ static int
amfs_bgmount(struct continuation *cp)
{
am_node *mp = cp->mp;
- mntfs *mf; /* Current mntfs */
+ am_loc *loc;
+ mntfs *mf;
int this_error = -1; /* Per-mount error */
int hard_error = -1; /* Cumulative per-node error */
- if (mp->am_mnt)
- free_mntfs(mp->am_mnt);
+ if (mp->am_al)
+ free_loc(mp->am_al);
/*
* Try to mount each location.
@@ -704,10 +725,11 @@ amfs_bgmount(struct continuation *cp)
* hard_error > 0 indicates everything failed with a hard error
* hard_error < 0 indicates nothing could be mounted now
*/
- for (mp->am_mnt = *cp->mf; *cp->mf; cp->mf++, mp->am_mnt = *cp->mf) {
+ for (mp->am_al = *cp->al; *cp->al; cp->al++, mp->am_al = *cp->al) {
am_ops *p;
- mf = dup_mntfs(mp->am_mnt);
+ loc = dup_loc(mp->am_al);
+ mf = loc->al_mnt;
p = mf->mf_ops;
if (hard_error < 0)
@@ -737,12 +759,11 @@ amfs_bgmount(struct continuation *cp)
goto failed;
}
- if (mp->am_link) {
- XFREE(mp->am_link);
- mp->am_link = NULL;
- }
- if (mf->mf_fo && mf->mf_fo->opt_sublink)
- mp->am_link = strdup(mf->mf_fo->opt_sublink);
+ XFREE(mp->am_link);
+ mp->am_link = NULL;
+
+ if (loc->al_fo && loc->al_fo->opt_sublink && loc->al_fo->opt_sublink[0])
+ mp->am_link = xstrdup(loc->al_fo->opt_sublink);
/*
* Will usually need to play around with the mount nodes
@@ -784,13 +805,13 @@ amfs_bgmount(struct continuation *cp)
if (this_error < 0)
goto retry;
- if (mf->mf_fo && mf->mf_fo->opt_delay) {
+ if (loc->al_fo && loc->al_fo->opt_delay) {
/*
- * If there is a delay timer on the mount
+ * If there is a delay timer on the location
* then don't try to mount if the timer
* has not expired.
*/
- int i = atoi(mf->mf_fo->opt_delay);
+ int i = atoi(loc->al_fo->opt_delay);
time_t now = clocktime(NULL);
if (i > 0 && now < (cp->start + i)) {
dlog("Mount of %s delayed by %lds", mf->mf_mount, (long) (i - now + cp->start));
@@ -866,22 +887,25 @@ amfs_bgmount(struct continuation *cp)
return -1;
failed:
- amd_stats.d_merr++;
- mf->mf_error = this_error;
- mf->mf_flags |= MFF_ERROR;
+ if (!FSRV_ISDOWN(mf->mf_server)) {
+ /* mark the mount as failed unless the server is down */
+ amd_stats.d_merr++;
+ mf->mf_error = this_error;
+ mf->mf_flags |= MFF_ERROR;
#ifdef HAVE_FS_AUTOFS
- if (mp->am_autofs_fh)
- autofs_release_fh(mp);
+ if (mp->am_autofs_fh)
+ autofs_release_fh(mp);
#endif /* HAVE_FS_AUTOFS */
- if (mf->mf_flags & MFF_MKMNT) {
- rmdirs(mf->mf_mount);
- mf->mf_flags &= ~MFF_MKMNT;
+ if (mf->mf_flags & MFF_MKMNT) {
+ rmdirs(mf->mf_mount);
+ mf->mf_flags &= ~MFF_MKMNT;
+ }
}
/*
* Wakeup anything waiting for this mount
*/
wakeup(get_mntfs_wchan(mf));
- free_mntfs(mf);
+ free_loc(loc);
/* continue */
}
@@ -890,7 +914,10 @@ amfs_bgmount(struct continuation *cp)
* there is no more mount information available.
*/
if (this_error) {
- mp->am_mnt = mf = new_mntfs();
+ if (mp->am_al)
+ free_loc(mp->am_al);
+ mp->am_al = loc = new_loc();
+ mf = loc->al_mnt;
#ifdef HAVE_FS_AUTOFS
if (mp->am_flags & AMF_AUTOFS)
@@ -920,7 +947,7 @@ amfs_bgmount(struct continuation *cp)
}
new_ttl(mp);
} else {
- mf = mp->am_mnt;
+ mf = loc->al_mnt;
/*
* Wakeup anything waiting for this mount
*/
@@ -959,19 +986,10 @@ amfs_parse_defaults(am_node *mp, mntfs *mf, char *def_opts)
/*
* Find out if amd.conf overrode any map-specific /defaults.
- *
- * HACK ALERT: there's no easy way to find out what the map mount point is
- * at this point, so I am forced to initialize the mnt_map->cfm field here
- * for the first time, upon the very first search for a /defaults entry in
- * this map. This initialization is much better done in mapc_create(),
- * but it's impossible to do that there with the current code structure.
*/
- if (mm->cfm == NULL) { /* then initialize it for first time */
- mm->cfm = find_cf_map(mf->mf_mount);
- }
if (mm->cfm && mm->cfm->cfm_defaults) {
dlog("map %s map_defaults override: %s", mf->mf_mount, mm->cfm->cfm_defaults);
- dflts = strdup(mm->cfm->cfm_defaults);
+ dflts = xstrdup(mm->cfm->cfm_defaults);
} else if (mapc_search(mm, "/defaults", &dflts) == 0) {
dlog("/defaults gave %s", dflts);
} else {
@@ -1009,7 +1027,7 @@ amfs_parse_defaults(am_node *mp, mntfs *mf, char *def_opts)
* get expanded to "/defaults"
*/
pt = ops_match(&ap, *sp, "", mp->am_path, "/defaults",
- mp->am_parent->am_mnt->mf_info);
+ mp->am_parent->am_al->al_mnt->mf_info);
free_opts(&ap); /* don't leak */
if (pt == &amfs_error_ops) {
plog(XLOG_MAP, "did not match defaults for \"%s\"", *sp);
@@ -1076,8 +1094,9 @@ amfs_generic_mount_child(am_node *new_mp, int *error_return)
*error_return = error = 0; /* Error so far */
/* we have an errorfs attached to the am_node, free it */
- free_mntfs(new_mp->am_mnt);
- new_mp->am_mnt = 0;
+ if (new_mp->am_al)
+ free_loc(new_mp->am_al);
+ new_mp->am_al = NULL;
/*
* Construct a continuation
@@ -1087,7 +1106,7 @@ amfs_generic_mount_child(am_node *new_mp, int *error_return)
cp->mp = new_mp;
cp->retry = TRUE;
cp->start = clocktime(NULL);
- cp->mf = new_mp->am_mfarray;
+ cp->al = new_mp->am_alarray;
/*
* Try and mount the file system. If this succeeds immediately (possible
@@ -1101,7 +1120,7 @@ amfs_generic_mount_child(am_node *new_mp, int *error_return)
/*
* Code for quick reply. If current_transp is set, then it's the
- * transp that's been passed down from nfs_program_2() or from
+ * transp that's been passed down from nfs_dispatcher() or from
* autofs_program_[123]().
* If new_mp->am_transp is not already set, set it by copying in
* current_transp. Once am_transp is set, nfs_quick_reply() and
@@ -1113,7 +1132,8 @@ amfs_generic_mount_child(am_node *new_mp, int *error_return)
new_mp->am_transp = (SVCXPRT *) xmalloc(sizeof(SVCXPRT));
*(new_mp->am_transp) = *current_transp;
}
- if (error && new_mp->am_mnt && (new_mp->am_mnt->mf_ops == &amfs_error_ops))
+ if (error && new_mp->am_al && new_mp->am_al->al_mnt &&
+ (new_mp->am_al->al_mnt->mf_ops == &amfs_error_ops))
new_mp->am_error = error;
if (new_mp->am_error > 0)
@@ -1132,7 +1152,7 @@ am_node *
amfs_generic_lookup_child(am_node *mp, char *fname, int *error_return, int op)
{
am_node *new_mp;
- mntfs **mf_array;
+ am_loc **al_array;
int mp_error;
dlog("in amfs_generic_lookup_child");
@@ -1145,7 +1165,7 @@ amfs_generic_lookup_child(am_node *mp, char *fname, int *error_return, int op)
return new_mp;
/* also return if it's already mounted and known to be up */
- if (*error_return == 0 && FSRV_ISUP(new_mp->am_mnt->mf_server))
+ if (*error_return == 0 && FSRV_ISUP(new_mp->am_al->al_mnt->mf_server))
return new_mp;
switch (op) {
@@ -1161,42 +1181,15 @@ amfs_generic_lookup_child(am_node *mp, char *fname, int *error_return, int op)
/* save error_return */
mp_error = *error_return;
- mf_array = amfs_lookup_mntfs(new_mp, error_return);
- if (!mf_array) {
- new_mp->am_error = new_mp->am_mnt->mf_error = *error_return;
+ al_array = amfs_lookup_loc(new_mp, error_return);
+ if (!al_array) {
+ new_mp->am_error = new_mp->am_al->al_mnt->mf_error = *error_return;
free_map(new_mp);
return NULL;
}
- /*
- * Already mounted but known to be down:
- * check if we have any alternatives to mount
- */
- if (mp_error == 0) {
- mntfs **mfp;
- for (mfp = mf_array; *mfp; mfp++)
- if (*mfp != new_mp->am_mnt)
- break;
- if (*mfp != NULL) {
- /*
- * we found an alternative, so try mounting again.
- */
- *error_return = -1;
- } else {
- for (mfp = mf_array; *mfp; mfp++)
- free_mntfs(*mfp);
- XFREE(mf_array);
- if (new_mp->am_flags & AMF_SOFTLOOKUP) {
- ereturn(EIO);
- } else {
- *error_return = 0;
- return new_mp;
- }
- }
- }
-
/* store the array inside the am_node */
- new_mp->am_mfarray = mf_array;
+ new_mp->am_alarray = al_array;
/*
* Note: while it might seem like a good idea to prioritize
@@ -1258,5 +1251,5 @@ amfs_generic_match(am_opts *fo)
/*
* mtab entry turns out to be the name of the mount map
*/
- return strdup(fo->opt_rfs ? fo->opt_rfs : ".");
+ return xstrdup(fo->opt_rfs ? fo->opt_rfs : ".");
}
diff --git a/contrib/amd/amd/amfs_host.c b/contrib/amd/amd/amfs_host.c
index 55423c46ea33..a3468ecd4b65 100644
--- a/contrib/amd/amd/amfs_host.c
+++ b/contrib/amd/amd/amfs_host.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -227,7 +223,14 @@ fetch_fhandle(CLIENT *client, char *dir, am_nfs_handle_t *fhp, u_long nfs_versio
plog(XLOG_INFO, "fetch_fhandle: NFS version %d", (int) nfs_version);
#ifdef HAVE_FS_NFS3
- if (nfs_version == NFS_VERSION3) {
+ 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,
@@ -303,8 +306,8 @@ amfs_host_mount(am_node *am, mntfs *mf)
int n_export;
int j, k;
exports exlist = 0, ex;
- exports *ep = 0;
- am_nfs_handle_t *fp = 0;
+ exports *ep = NULL;
+ am_nfs_handle_t *fp = NULL;
char *host;
int error = 0;
struct sockaddr_in sin;
@@ -449,13 +452,13 @@ amfs_host_mount(am_node *am, mntfs *mf)
/* 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] = 0;
+ 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] = 0;
+ ep[j] = NULL;
}
}
@@ -465,8 +468,8 @@ amfs_host_mount(am_node *am, mntfs *mf)
* error code 0 at the end. If they all fail then return
* the last error code.
*/
- xstrlcpy(fs_name, mf->mf_info, MAXPATHLEN);
- if ((rfs_dir = strchr(fs_name, ':')) == (char *) 0) {
+ 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;
@@ -493,10 +496,8 @@ amfs_host_mount(am_node *am, mntfs *mf)
*/
out:
discard_mntlist(mlist);
- if (ep)
- XFREE(ep);
- if (fp)
- XFREE(fp);
+ XFREE(ep);
+ XFREE(fp);
if (sock != RPC_ANYSOCK)
(void) amu_close(sock);
if (client)
@@ -554,7 +555,7 @@ amfs_host_umount(am_node *am, mntfs *mf)
* Reverse list...
*/
ml = mlist;
- mprev = 0;
+ mprev = NULL;
while (ml) {
mntlist *ml2 = ml->mnext;
ml->mnext = mprev;
diff --git a/contrib/amd/amd/amfs_link.c b/contrib/amd/amd/amfs_link.c
index e75ab862f8bc..0751dd7047a0 100644
--- a/contrib/amd/amd/amfs_link.c
+++ b/contrib/amd/amd/amfs_link.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -109,13 +105,13 @@ amfs_link_match(am_opts *fo)
*/
if (fo->opt_fs[0] == '/') {
char *link_hack = str3cat(NULL, ".", fo->opt_fs, "");
- if (!fo->opt_sublink)
- fo->opt_sublink = strdup(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 strdup(fo->opt_fs);
+ return xstrdup(fo->opt_fs);
}
diff --git a/contrib/amd/amd/amfs_linkx.c b/contrib/amd/amd/amfs_linkx.c
index e306eda91d3b..be95fe5e1a27 100644
--- a/contrib/amd/amd/amfs_linkx.c
+++ b/contrib/amd/amd/amfs_linkx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/amd/amfs_nfsl.c b/contrib/amd/amd/amfs_nfsl.c
index bb48f0efd255..c70a3eeb97c4 100644
--- a/contrib/amd/amd/amfs_nfsl.c
+++ b/contrib/amd/amd/amfs_nfsl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -101,7 +97,7 @@ amfs_nfsl_match(am_opts *fo)
char *retval;
struct stat stb;
- if (fo->opt_sublink)
+ if (fo->opt_sublink && fo->opt_sublink[0])
cp = fo->opt_sublink;
else
cp = fo->opt_fs;
@@ -116,8 +112,9 @@ amfs_nfsl_match(am_opts *fo)
* call nfs_ops.fs_match().
* If link value exists (or same host), call amfs_link_ops.fs_match().
*/
- if (!STRCEQ(ho, am_get_hostname())) {
- plog(XLOG_INFO, "amfs_nfsl: \"%s\" is not local host, using type:=nfs", ho);
+ 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);
@@ -213,11 +210,16 @@ amfs_nfsl_umounted(mntfs *mf)
static fserver *
amfs_nfsl_ffserver(mntfs *mf)
{
- char *cp;
- char *ho = mf->mf_fo->opt_rhost;
+ char *cp, *ho;
struct stat stb;
- if (mf->mf_fo->opt_sublink)
+ 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;
@@ -227,7 +229,8 @@ amfs_nfsl_ffserver(mntfs *mf)
* call amfs_link_ops.ffserver().
* If link value exists (or same host), then call ops_nfs.ffserver().
*/
- if (!STRCEQ(ho, am_get_hostname()) || lstat(cp, &stb) < 0) {
+ if ((!STRCEQ(ho, am_get_hostname()) &&
+ !STRCEQ(ho, hostd)) || lstat(cp, &stb) < 0) {
return nfs_ops.ffserver(mf);
} else {
mf->mf_flags |= MFF_NFSLINK;
diff --git a/contrib/amd/amd/amfs_nfsx.c b/contrib/amd/amd/amfs_nfsx.c
index 91be8af47e11..db1b9fafd119 100644
--- a/contrib/amd/amd/amfs_nfsx.c
+++ b/contrib/amd/amd/amfs_nfsx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -118,7 +114,7 @@ amfs_nfsx_match(am_opts *fo)
}
/* set default sublink */
- if (fo->opt_sublink == 0) {
+ 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);
@@ -149,7 +145,7 @@ amfs_nfsx_match(am_opts *fo)
/*
* Determine magic cookie to put in mtab
*/
- xmtab = str3cat((char *) 0, fo->opt_rhost, ":", fo->opt_rfs);
+ 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);
@@ -190,12 +186,15 @@ amfs_nfsx_init(mntfs *mf)
if (nx == 0) {
char **ivec;
- char *info = 0;
+ char *info = NULL;
char *host;
char *pref;
int error = 0;
- info = strdup(mf->mf_info);
+ info = xstrdup(mf->mf_info);
+ if (info == NULL)
+ return errno;
+
host = strchr(info, ':');
if (!host) {
error = EINVAL;
@@ -221,12 +220,12 @@ amfs_nfsx_init(mntfs *mf)
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 = 0;
+ nx->nx_mp = NULL;
{
- char *mp = 0;
- char *xinfo = 0;
+ char *mp = NULL;
+ char *xinfo = NULL;
char *fs = mf->mf_fo->opt_fs;
- char *rfs = 0;
+ char *rfs = NULL;
for (i = 0; i < nx->nx_c; i++) {
char *path = ivec[i + 1];
rfs = str3cat(rfs, pref, "/", path);
@@ -251,18 +250,14 @@ amfs_nfsx_init(mntfs *mf)
/* propagate the on_autofs flag */
nx->nx_v[i].n_mnt->mf_flags |= mf->mf_flags & MFF_ON_AUTOFS;
}
- if (rfs)
- XFREE(rfs);
- if (mp)
- XFREE(mp);
- if (xinfo)
- XFREE(xinfo);
+ XFREE(rfs);
+ XFREE(mp);
+ XFREE(xinfo);
}
XFREE(ivec);
errexit:
- if (info)
- XFREE(info);
+ XFREE(info);
if (error)
return error;
}
@@ -503,7 +498,7 @@ amfs_nfsx_umount(am_node *am, mntfs *mf)
}
}
free_mntfs(m);
- n->n_mnt = 0;
+ n->n_mnt = NULL;
n->n_error = -1;
}
}
diff --git a/contrib/amd/amd/amfs_program.c b/contrib/amd/amd/amfs_program.c
index b0aed3752d75..6bf003fb2cf7 100644
--- a/contrib/amd/amd/amfs_program.c
+++ b/contrib/amd/amd/amfs_program.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -105,7 +101,7 @@ amfs_program_match(am_opts *fo)
}
prog = strchr(fo->opt_mount, ' ');
- return strdup(prog ? prog + 1 : fo->opt_mount);
+ return xstrdup(prog ? prog + 1 : fo->opt_mount);
}
@@ -116,11 +112,14 @@ amfs_program_init(mntfs *mf)
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) strdup(mf->mf_fo->opt_unmount);
+ mf->mf_private = (opaque_t) xstrdup(mf->mf_fo->opt_unmount);
else
- mf->mf_private = (opaque_t) strdup(mf->mf_fo->opt_umount);
+ mf->mf_private = (opaque_t) xstrdup(mf->mf_fo->opt_umount);
mf->mf_prfree = (void (*)(opaque_t)) free;
return 0;
@@ -136,9 +135,7 @@ amfs_program_exec(char *info)
/*
* Split copy of command info string
*/
- info = strdup(info);
- if (info == 0)
- return ENOBUFS;
+ info = xstrdup(info);
xivec = strsplit(info, ' ', '\'');
/*
@@ -148,11 +145,11 @@ amfs_program_exec(char *info)
if (!logfp)
logfp = stderr; /* initialize before possible first use */
if (dup(fileno(logfp)) == -1)
- return errno;
+ goto out;
if (fileno(logfp) != fileno(stderr)) {
(void) fclose(stderr);
if (dup(fileno(logfp)) == -1)
- return errno;
+ goto out;
}
/*
@@ -172,13 +169,16 @@ amfs_program_exec(char *info)
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;
- plog(XLOG_ERROR, "exec failed: %m");
/*
* Free allocate memory
diff --git a/contrib/amd/amd/amfs_root.c b/contrib/amd/amd/amfs_root.c
index 243267e71e86..f06c43ce0bac 100644
--- a/contrib/amd/amd/amfs_root.c
+++ b/contrib/amd/amd/amfs_root.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -92,7 +88,7 @@ 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);
+ mf->mf_private = (opaque_t) mapc_find(mf->mf_info, "", NULL, NULL);
mf->mf_prfree = mapc_free;
return 0;
diff --git a/contrib/amd/amd/amfs_toplvl.c b/contrib/amd/amd/amfs_toplvl.c
index 1b968f197f55..1b143157b4c7 100644
--- a/contrib/amd/amd/amfs_toplvl.c
+++ b/contrib/amd/amd/amfs_toplvl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -148,7 +144,7 @@ amfs_toplvl_init(mntfs *mf)
{
int error = 0;
-#if defined(MNT2_GEN_OPT_FORCE) || defined(MNT2_GEN_OPT_DETACH)
+#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);
@@ -158,7 +154,7 @@ amfs_toplvl_init(mntfs *mf)
else
dlog("amfs_toplvl_init: forced/lazy unmount succeeded");
}
-#endif /* MNT2_GEN_OPT_FORCE || MNT2_GEN_OPT_DETACH */
+#endif /* (MNT2_GEN_OPT_FORCE || MNT2_GEN_OPT_DETACH) && (HAVE_UVMOUNT || HAVE_UMOUNT2) */
return error;
}
@@ -227,6 +223,11 @@ amfs_toplvl_mount(am_node *mp, mntfs *mf)
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));
diff --git a/contrib/amd/amd/amfs_union.c b/contrib/amd/amd/amfs_union.c
index 6adb5b0bd9cb..9f37a1b04dd1 100644
--- a/contrib/amd/amd/amfs_union.c
+++ b/contrib/amd/amd/amfs_union.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -95,7 +91,7 @@ create_amfs_union_node(char *dir, opaque_t arg)
am_node *am;
am = amfs_generic_lookup_child(arg, dir, &error, VLOOK_CREATE);
if (am && error < 0)
- am = amfs_generic_mount_child(am, &error);
+ (void)amfs_generic_mount_child(am, &error);
if (error > 0) {
errno = error; /* XXX */
plog(XLOG_ERROR, "unionfs: could not mount %s: %m", dir);
@@ -121,9 +117,9 @@ amfs_union_mounted(mntfs *mf)
for (mp = get_first_exported_ap(&index);
mp;
mp = get_next_exported_ap(&index)) {
- if (mp->am_mnt == mf) {
+ 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_mnt->mf_private,
+ (void) mapc_keyiter((mnt_map *) mp->am_al->al_mnt->mf_private,
create_amfs_union_node,
mp);
break;
diff --git a/contrib/amd/amd/amq_subr.c b/contrib/amd/amd/amq_subr.c
index 79ecafc3d9b3..ba85c68b7425 100644
--- a/contrib/amd/amd/amq_subr.c
+++ b/contrib/amd/amd/amq_subr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -80,16 +76,68 @@ amqproc_mnttree_1_svc(voidp argp, struct svc_req *rqstp)
/*
* Unmount a single node
*/
-voidp
+int *
amqproc_umnt_1_svc(voidp argp, struct svc_req *rqstp)
{
- static char res;
+ static int res = AMQ_UMNT_OK;
am_node *mp = find_ap(*(char **) argp);
if (mp)
forcibly_timeout_mp(mp);
- return (voidp) &res;
+ 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;
}
@@ -170,6 +218,12 @@ 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)
@@ -218,11 +272,11 @@ amqproc_pawd_1_svc(voidp argp, struct svc_req *rqstp)
for (mp = get_first_exported_ap(&index);
mp;
mp = get_next_exported_ap(&index)) {
- if (STREQ(mp->am_mnt->mf_ops->fs_type, "toplvl"))
+ if (STREQ(mp->am_al->al_mnt->mf_ops->fs_type, "toplvl"))
continue;
- if (STREQ(mp->am_mnt->mf_ops->fs_type, "auto"))
+ if (STREQ(mp->am_al->al_mnt->mf_ops->fs_type, "auto"))
continue;
- mountpoint = (mp->am_link ? mp->am_link : mp->am_mnt->mf_mount);
+ mountpoint = (mp->am_link ? mp->am_link : mp->am_al->al_mnt->mf_mount);
len = strlen(mountpoint);
if (len == 0)
continue;
@@ -277,16 +331,16 @@ 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_mnt->mf_info)) {
+ 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_mnt->mf_mount)) {
+ 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_mnt->mf_ops->fs_type)) {
+ if (!xdr_amq_string(xdrs, &mp->am_al->al_mnt->mf_ops->fs_type)) {
return (FALSE);
}
mtime = mp->am_stats.s_mtime;
@@ -412,16 +466,15 @@ xdr_amq_mount_tree_list(XDR *xdrs, amq_mount_tree_list *objp)
}
-
-/*
- * Compute length of list
- */
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;
@@ -468,6 +521,70 @@ xdr_amq_mount_info_qelem(XDR *xdrs, qelem *qhead)
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)
diff --git a/contrib/amd/amd/amq_svc.c b/contrib/amd/amd/amq_svc.c
index 6fadb160c121..1f2b3d6ff8d9 100644
--- a/contrib/amd/amd/amq_svc.c
+++ b/contrib/amd/amd/amq_svc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -57,7 +53,7 @@ typedef char *(*amqsvcproc_t)(voidp, struct svc_req *);
* 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;
+int allow_severity=0, deny_severity=0, rfc931_timeout=0;
# endif /* NEED_LIBWRAP_SEVERITY_VARIABLES */
/*
@@ -65,49 +61,88 @@ int allow_severity=0, deny_severity=0;
* Returns: 1=allowed, 0=denied.
*/
static int
-amqsvc_is_client_allowed(const struct sockaddr_in *addr, char *remote)
+amqsvc_is_client_allowed(const struct sockaddr_in *addr)
{
- struct hostent *h;
- char *name = NULL, **ad;
- int ret = 0; /* default is 0==denied */
-
- /* Check IP address */
- if (hosts_ctl(AMD_SERVICE_NAME, "", remote, "")) {
- ret = 1;
- goto out;
+ 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;
}
- /* Get address */
- if (!(h = gethostbyaddr((const char *)&(addr->sin_addr),
- sizeof(addr->sin_addr),
- AF_INET)))
- goto out;
- if (!(name = strdup(h->h_name)))
- goto out;
- /* Paranoia check */
- if (!(h = gethostbyname(name)))
- goto out;
- for (ad = h->h_addr_list; *ad; ad++)
- if (!memcmp(*ad, &(addr->sin_addr), h->h_length))
- break;
- if (!*ad)
- goto out;
- if (hosts_ctl(AMD_SERVICE_NAME, "", h->h_name, "")) {
- return 1;
- goto out;
+
+ if (pipe(mp->am_fd) == -1) {
+ mp->am_fd[0] = -1;
+ mp->am_fd[1] = -1;
+ return -1;
}
- /* Check aliases */
- for (ad = h->h_aliases; *ad; ad++)
- if (hosts_ctl(AMD_SERVICE_NAME, "", *ad, "")) {
- return 1;
- goto out;
- }
- out:
- if (name)
- XFREE(name);
- return ret;
+#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;
+ }
}
-#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
void
@@ -121,13 +156,16 @@ amq_program_1(struct svc_req *rqstp, SVCXPRT *transp)
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, remote_hostname)) {
+ 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;
@@ -137,6 +175,10 @@ amq_program_1(struct svc_req *rqstp, SVCXPRT *transp)
}
#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
+ local = NULL;
+ child = NULL;
+ parent = NULL;
+
switch (rqstp->rq_proc) {
case AMQPROC_NULL:
@@ -199,6 +241,21 @@ amq_program_1(struct svc_req *rqstp, SVCXPRT *transp)
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;
@@ -212,7 +269,28 @@ amq_program_1(struct svc_req *rqstp, SVCXPRT *transp)
return;
}
- result = (*local) (&argument, rqstp);
+ 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,
@@ -226,4 +304,7 @@ amq_program_1(struct svc_req *rqstp, SVCXPRT *transp)
plog(XLOG_FATAL, "unable to free rpc arguments in amqprog_1");
going_down(1);
}
+
+ if (pid == 0)
+ exit(0); /* the child is done! */
}
diff --git a/contrib/amd/amd/autil.c b/contrib/amd/amd/autil.c
index a5ecd6d0d1f3..cd9514d44ef4 100644
--- a/contrib/amd/amd/autil.c
+++ b/contrib/amd/amd/autil.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -160,16 +156,23 @@ valid_key(char *key)
void
forcibly_timeout_mp(am_node *mp)
{
- mntfs *mf = mp->am_mnt;
+ 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
+ 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;
@@ -207,24 +210,11 @@ mf_mounted(mntfs *mf, bool_t call_free_opts)
mf->mf_ops->mounted(mf);
/*
- * Be careful when calling free_ops and XFREE here. Some pseudo file
- * systems like nfsx call this function (mf_mounted), even though it
- * would be called by the lower-level amd file system functions. nfsx
- * needs to call this function because of the other actions it takes.
- * So we pass a boolean from the caller (yes, not so clean workaround)
- * to determine if we should free or not. If we're not freeing (often
- * because we're called from a callback function), then just to be sure,
- * we'll zero out the am_opts structure and set the pointer to NULL.
- * The parent mntfs node owns this memory and is going to free it with a
- * call to mf_mounted(mntfs,TRUE) (see comment in the am_mounted code).
+ * 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 (call_free_opts) {
- free_opts(mf->mf_fo); /* this free is needed to prevent leaks */
- XFREE(mf->mf_fo); /* (also this one) */
- } else {
- memset(mf->mf_fo, 0, sizeof(am_opts));
- mf->mf_fo = NULL;
- }
}
if (mf->mf_flags & MFF_RESTART) {
@@ -249,7 +239,7 @@ void
am_mounted(am_node *mp)
{
int notimeout = 0; /* assume normal timeouts initially */
- mntfs *mf = mp->am_mnt;
+ mntfs *mf = mp->am_al->al_mnt;
/*
* This is the parent mntfs which does the mf->mf_fo (am_opts type), and
@@ -266,7 +256,7 @@ am_mounted(am_node *mp)
/*
* Patch up path for direct mounts
*/
- if (mp->am_parent && mp->am_parent->am_mnt->mf_fsflags & FS_DIRECT)
+ 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, "/", ".");
/*
@@ -277,6 +267,7 @@ am_mounted(am_node *mp)
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;
@@ -321,7 +312,7 @@ am_mounted(am_node *mp)
/*
* Update mtime of parent node (copying "struct nfstime" in '=' below)
*/
- if (mp->am_parent && mp->am_parent->am_mnt)
+ if (mp->am_parent && mp->am_parent->am_al->al_mnt)
mp->am_parent->am_fattr.na_mtime = mp->am_fattr.na_mtime;
/*
@@ -360,21 +351,27 @@ 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_mnt->mf_error;
+ error = mp->am_al->al_mnt->mf_error;
/*
* Allocate a new error reference
*/
- mp->am_mnt = new_mntfs();
+ free_loc(mp->am_al);
+ mp->am_al = new_loc();
/*
* Put back the error code
*/
- mp->am_mnt->mf_error = error;
- mp->am_mnt->mf_flags |= MFF_ERROR;
+ mp->am_al->al_mnt->mf_error = error;
+ mp->am_al->al_mnt->mf_flags |= MFF_ERROR;
/*
* Zero the error in the mount point
*/
@@ -397,7 +394,8 @@ amfs_mkcacheref(mntfs *mf)
cache = "none";
mf->mf_private = (opaque_t) mapc_find(mf->mf_info,
cache,
- (mf->mf_fo ? mf->mf_fo->opt_maptype : NULL));
+ (mf->mf_fo ? mf->mf_fo->opt_maptype : NULL),
+ mf->mf_mount);
mf->mf_prfree = mapc_free;
}
@@ -418,7 +416,7 @@ next_nonerror_node(am_node *xp)
* containing hung automounts.
*/
while (xp &&
- (!(mf = xp->am_mnt) || /* No mounted filesystem */
+ (!(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 */
@@ -453,8 +451,9 @@ amfs_mount(am_node *mp, mntfs *mf, char *opts)
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((voidp) &mnt, 0, sizeof(mnt));
+ memset(&mnt, 0, sizeof(mnt));
mnt.mnt_dir = dir;
mnt.mnt_fsname = pid_fsname;
mnt.mnt_opts = opts;
@@ -525,8 +524,7 @@ amfs_mount(am_node *mp, mntfs *mf, char *opts)
again:
if (!(mf->mf_flags & MFF_IS_AUTOFS)) {
nfs_args_t nfs_args;
- am_nfs_fh *fhp;
- am_nfs_handle_t anh;
+ am_nfs_handle_t *fhp, anh;
#ifndef HAVE_TRANSPORT_TYPE_TLI
u_short port;
struct sockaddr_in sin;
@@ -535,7 +533,7 @@ again:
/*
* get fhandle of remote path for automount point
*/
- fhp = get_root_nfs_fh(dir);
+ fhp = get_root_nfs_fh(dir, &anh);
if (!fhp) {
plog(XLOG_FATAL, "Can't find root file handle for %s", dir);
return EINVAL;
@@ -545,7 +543,7 @@ again:
/*
* Create sockaddr to point to the local machine.
*/
- memset((voidp) &sin, 0, sizeof(sin));
+ 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;
@@ -559,16 +557,15 @@ again:
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
/* setup the many fields and flags within nfs_args */
- memmove(&anh.v2, fhp, sizeof(*fhp));
#ifdef HAVE_TRANSPORT_TYPE_TLI
compute_nfs_args(&nfs_args,
&mnt,
genflags,
nfsncp,
NULL, /* remote host IP addr is set below */
- NFS_VERSION, /* version 2 */
+ nfs_version,
"udp",
- &anh,
+ fhp,
fs_hostname,
pid_fsname);
/*
@@ -587,9 +584,9 @@ again:
genflags,
NULL,
&sin,
- NFS_VERSION, /* version 2 */
+ nfs_version,
"udp",
- &anh,
+ fhp,
fs_hostname,
pid_fsname);
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
@@ -656,10 +653,17 @@ again:
void
am_unmounted(am_node *mp)
{
- mntfs *mf = mp->am_mnt;
+ mntfs *mf = mp->am_al->al_mnt;
- if (!foreground) /* firewall - should never happen */
+ 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
@@ -707,26 +711,37 @@ am_unmounted(am_node *mp)
/*
* Update mtime of parent node
*/
- if (mp->am_parent && mp->am_parent->am_mnt)
+ 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 = strdup(mp->am_name);
+ char *fname = xstrdup(mp->am_name);
am_node *mp_parent = mp->am_parent;
- mntfs *mf_parent = mp_parent->am_mnt;
+ 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)
- mp = mf_parent->mf_ops->mount_child(mp, &error);
+ (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
+ } else {
/*
* We have a race here.
* If this node has a pending mount and amd is going down (unmounting
@@ -734,10 +749,12 @@ am_unmounted(am_node *mp)
* 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_mfarray).
+ * pending mounts (defined as having a non-NULL am_alarray).
*/
- if (!mp->am_mfarray)
+ notify_child(mp, AMQ_UMNT_OK, 0, 0); /* do this regardless */
+ if (!mp->am_alarray)
free_map(mp);
+ }
}
diff --git a/contrib/amd/amd/clock.c b/contrib/amd/amd/clock.c
index 0caa7dff2c73..4c6aa5413763 100644
--- a/contrib/amd/amd/clock.c
+++ b/contrib/amd/amd/clock.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/amd/conf.c b/contrib/amd/amd/conf.c
index 2fc587b0cadb..57e1b9ddbd02 100644
--- a/contrib/amd/amd/conf.c
+++ b/contrib/amd/amd/conf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -77,6 +73,7 @@ struct _func_map {
static int gopt_arch(const char *val);
static int gopt_auto_attrcache(const char *val);
static int gopt_auto_dir(const char *val);
+static int gopt_auto_nfs_version(const char *val);
static int gopt_autofs_use_lofs(const char *val);
static int gopt_browsable_dirs(const char *val);
static int gopt_cache_duration(const char *val);
@@ -120,6 +117,7 @@ static int gopt_nfs_retry_interval_udp(const char *val);
static int gopt_nfs_retry_interval_tcp(const char *val);
static int gopt_nfs_retry_interval_toplvl(const char *val);
static int gopt_nfs_vers(const char *val);
+static int gopt_nfs_vers_ping(const char *val);
static int gopt_nis_domain(const char *val);
static int gopt_normalize_hostnames(const char *val);
static int gopt_normalize_slashes(const char *val);
@@ -132,6 +130,7 @@ static int gopt_restart_mounts(const char *val);
static int gopt_search_path(const char *val);
static int gopt_selectors_in_defaults(const char *val);
static int gopt_show_statfs_entries(const char *val);
+static int gopt_sun_map_syntax(const char *val);
static int gopt_truncate_log(const char *val);
static int gopt_unmount_on_exit(const char *val);
static int gopt_use_tcpwrappers(const char *val);
@@ -146,6 +145,7 @@ static int ropt_map_options(const char *val, cf_map_t *cfm);
static int ropt_map_type(const char *val, cf_map_t *cfm);
static int ropt_mount_type(const char *val, cf_map_t *cfm);
static int ropt_search_path(const char *val, cf_map_t *cfm);
+static int ropt_sun_map_syntax(const char *val, cf_map_t *cfm);
static int ropt_tag(const char *val, cf_map_t *cfm);
static void init_cf_map(cf_map_t *cfm);
@@ -159,6 +159,7 @@ static struct _func_map glob_functable[] = {
{"arch", gopt_arch},
{"auto_attrcache", gopt_auto_attrcache},
{"auto_dir", gopt_auto_dir},
+ {"auto_nfs_version", gopt_auto_nfs_version},
{"autofs_use_lofs", gopt_autofs_use_lofs},
{"browsable_dirs", gopt_browsable_dirs},
{"cache_duration", gopt_cache_duration},
@@ -202,6 +203,7 @@ static struct _func_map glob_functable[] = {
{"nfs_retry_interval_tcp", gopt_nfs_retry_interval_tcp},
{"nfs_retry_interval_toplvl", gopt_nfs_retry_interval_toplvl},
{"nfs_vers", gopt_nfs_vers},
+ {"nfs_vers_ping", gopt_nfs_vers_ping},
{"nis_domain", gopt_nis_domain},
{"normalize_hostnames", gopt_normalize_hostnames},
{"normalize_slashes", gopt_normalize_slashes},
@@ -215,6 +217,7 @@ static struct _func_map glob_functable[] = {
{"selectors_on_default", gopt_selectors_in_defaults},
{"selectors_in_defaults", gopt_selectors_in_defaults},
{"show_statfs_entries", gopt_show_statfs_entries},
+ {"sun_map_syntax", gopt_sun_map_syntax},
{"truncate_log", gopt_truncate_log},
{"unmount_on_exit", gopt_unmount_on_exit},
{"use_tcpwrappers", gopt_use_tcpwrappers},
@@ -255,12 +258,14 @@ init_cf_map(cf_map_t *cfm)
cfm->cfm_search_path = gopt.search_path;
/*
- * Initialize flags that are common both to [global] and a local map.
+ * Initialize flags that are common both to [global] and a local map
+ * (that is, they could be inherited from the global section).
*/
cfm->cfm_flags = gopt.flags & (CFM_BROWSABLE_DIRS |
CFM_BROWSABLE_DIRS_FULL |
CFM_MOUNT_TYPE_AUTOFS |
- CFM_SELECTORS_IN_DEFAULTS);
+ CFM_SELECTORS_IN_DEFAULTS |
+ CFM_SUN_MAP_SYNTAX );
}
@@ -366,7 +371,7 @@ process_global_option(const char *key, const char *val)
static int
gopt_arch(const char *val)
{
- gopt.arch = strdup((char *)val);
+ gopt.arch = xstrdup(val);
return 0;
}
@@ -386,10 +391,23 @@ gopt_auto_attrcache(const char *val)
static int
gopt_auto_dir(const char *val)
{
- gopt.auto_dir = strdup((char *)val);
+ gopt.auto_dir = xstrdup(val);
return 0;
}
+static int
+gopt_auto_nfs_version(const char *val)
+{
+ if (strcmp(val, "2") == 0)
+ nfs_dispatcher = nfs_program_2;
+ else if (strcmp(val, "3") == 0)
+ nfs_dispatcher = nfs_program_3;
+ else {
+ fprintf(stderr, "conf: bad auto nfs version : \"%s\"\n", val);
+ return 1;
+ }
+ return 0;
+}
static int
gopt_autofs_use_lofs(const char *val)
@@ -439,7 +457,7 @@ gopt_cache_duration(const char *val)
static int
gopt_cluster(const char *val)
{
- gopt.cluster = strdup((char *)val);
+ gopt.cluster = xstrdup(val);
return 0;
}
@@ -447,7 +465,7 @@ gopt_cluster(const char *val)
static int
gopt_debug_mtab_file(const char *val)
{
- gopt.debug_mtab_file = strdup((char*)val);
+ gopt.debug_mtab_file = xstrdup(val);
return 0;
}
@@ -547,7 +565,7 @@ gopt_forced_unmounts(const char *val)
static int
gopt_full_os(const char *val)
{
- gopt.op_sys_full = strdup((char *)val);
+ gopt.op_sys_full = xstrdup(val);
return 0;
}
@@ -572,7 +590,7 @@ static int
gopt_hesiod_base(const char *val)
{
#ifdef HAVE_MAP_HESIOD
- gopt.hesiod_base = strdup((char *)val);
+ gopt.hesiod_base = xstrdup(val);
return 0;
#else /* not HAVE_MAP_HESIOD */
fprintf(stderr, "conf: hesiod_base option ignored. No Hesiod support available.\n");
@@ -584,7 +602,7 @@ gopt_hesiod_base(const char *val)
static int
gopt_karch(const char *val)
{
- gopt.karch = strdup((char *)val);
+ gopt.karch = xstrdup(val);
return 0;
}
@@ -592,7 +610,7 @@ gopt_karch(const char *val)
static int
gopt_pid_file(const char *val)
{
- gopt.pid_file = strdup((char *)val);
+ gopt.pid_file = xstrdup(val);
return 0;
}
@@ -600,7 +618,7 @@ gopt_pid_file(const char *val)
static int
gopt_local_domain(const char *val)
{
- gopt.sub_domain = strdup((char *)val);
+ gopt.sub_domain = xstrdup(val);
return 0;
}
@@ -608,7 +626,7 @@ gopt_local_domain(const char *val)
static int
gopt_localhost_address(const char *val)
{
- gopt.localhost_address = strdup((char *)val);
+ gopt.localhost_address = xstrdup(val);
return 0;
}
@@ -617,7 +635,7 @@ static int
gopt_ldap_base(const char *val)
{
#ifdef HAVE_MAP_LDAP
- gopt.ldap_base = strdup((char *)val);
+ gopt.ldap_base = xstrdup(val);
return 0;
#else /* not HAVE_MAP_LDAP */
fprintf(stderr, "conf: ldap_base option ignored. No LDAP support available.\n");
@@ -668,7 +686,7 @@ static int
gopt_ldap_hostports(const char *val)
{
#ifdef HAVE_MAP_LDAP
- gopt.ldap_hostports = strdup((char *)val);
+ gopt.ldap_hostports = xstrdup(val);
return 0;
#else /* not HAVE_MAP_LDAP */
fprintf(stderr, "conf: ldap_hostports option ignored. No LDAP support available.\n");
@@ -719,7 +737,7 @@ gopt_ldap_proto_version(const char *val)
static int
gopt_log_file(const char *val)
{
- gopt.logfile = strdup((char *)val);
+ gopt.logfile = xstrdup(val);
return 0;
}
@@ -735,7 +753,7 @@ gopt_log_options(const char *val)
static int
gopt_map_defaults(const char *val)
{
- gopt.map_defaults = strdup((char *)val);
+ gopt.map_defaults = xstrdup(val);
return 0;
}
@@ -743,7 +761,7 @@ gopt_map_defaults(const char *val)
static int
gopt_map_options(const char *val)
{
- gopt.map_options = strdup((char *)val);
+ gopt.map_options = xstrdup(val);
return 0;
}
@@ -766,7 +784,7 @@ gopt_map_type(const char *val)
fprintf(stderr, "conf: no such map type \"%s\"\n", val);
return 1;
}
- gopt.map_type = strdup((char *)val);
+ gopt.map_type = xstrdup(val);
return 0;
}
@@ -863,7 +881,7 @@ static int
gopt_nfs_proto(const char *val)
{
if (STREQ(val, "udp") || STREQ(val, "tcp")) {
- gopt.nfs_proto = strdup((char *)val);
+ gopt.nfs_proto = xstrdup(val);
return 0;
}
fprintf(stderr, "conf: illegal nfs_proto \"%s\"\n", val);
@@ -946,7 +964,7 @@ gopt_nfs_vers(const char *val)
{
int i = atoi(val);
- if (i == 2 || i == 3) {
+ if (i == 2 || i == 3 || i == 4) {
gopt.nfs_vers = i;
return 0;
}
@@ -956,10 +974,23 @@ gopt_nfs_vers(const char *val)
static int
+gopt_nfs_vers_ping(const char *val)
+{
+ int i = atoi(val);
+
+ if (i == 2 || i == 3 || i == 4) {
+ gopt.nfs_vers_ping = i;
+ return 0;
+ }
+ fprintf(stderr, "conf: illegal nfs_vers_ping \"%s\"\n", val);
+ return 1;
+}
+
+static int
gopt_nis_domain(const char *val)
{
#ifdef HAVE_MAP_NIS
- gopt.nis_domain = strdup((char *)val);
+ gopt.nis_domain = xstrdup(val);
return 0;
#else /* not HAVE_MAP_NIS */
fprintf(stderr, "conf: nis_domain option ignored. No NIS support available.\n");
@@ -1003,7 +1034,7 @@ gopt_normalize_slashes(const char *val)
static int
gopt_os(const char *val)
{
- gopt.op_sys = strdup((char *)val);
+ gopt.op_sys = xstrdup(val);
return 0;
}
@@ -1011,7 +1042,7 @@ gopt_os(const char *val)
static int
gopt_osver(const char *val)
{
- gopt.op_sys_ver = strdup((char *)val);
+ gopt.op_sys_ver = xstrdup(val);
return 0;
}
@@ -1084,7 +1115,7 @@ gopt_restart_mounts(const char *val)
static int
gopt_search_path(const char *val)
{
- gopt.search_path = strdup((char *)val);
+ gopt.search_path = xstrdup(val);
return 0;
}
@@ -1122,6 +1153,22 @@ gopt_show_statfs_entries(const char *val)
static int
+gopt_sun_map_syntax(const char *val)
+{
+ if (STREQ(val, "yes")) {
+ gopt.flags |= CFM_SUN_MAP_SYNTAX;
+ return 0;
+ } else if (STREQ(val, "no")) {
+ gopt.flags &= ~CFM_SUN_MAP_SYNTAX;
+ return 0;
+ }
+
+ fprintf(stderr, "conf: unknown value to sun_map_syntax \"%s\"\n", val);
+ return 1; /* unknown value */
+}
+
+
+static int
gopt_truncate_log(const char *val)
{
if (STREQ(val, "yes")) {
@@ -1177,7 +1224,7 @@ gopt_use_tcpwrappers(const char *val)
static int
gopt_vendor(const char *val)
{
- gopt.op_sys_vendor = strdup((char *)val);
+ gopt.op_sys_vendor = xstrdup(val);
return 0;
}
@@ -1199,7 +1246,7 @@ process_regular_option(const char *section, const char *key, const char *val, cf
/* check if initializing a new map */
if (!cfm->cfm_dir)
- cfm->cfm_dir = strdup((char *)section);
+ cfm->cfm_dir = xstrdup(section);
/* check for each possible field */
if (STREQ(key, "browsable_dirs"))
@@ -1223,6 +1270,9 @@ process_regular_option(const char *section, const char *key, const char *val, cf
if (STREQ(key, "search_path"))
return ropt_search_path(val, cfm);
+ if (STREQ(key, "sun_map_syntax"))
+ return ropt_sun_map_syntax(val, cfm);
+
if (STREQ(key, "tag"))
return ropt_tag(val, cfm);
@@ -1254,7 +1304,7 @@ ropt_browsable_dirs(const char *val, cf_map_t *cfm)
static int
ropt_map_name(const char *val, cf_map_t *cfm)
{
- cfm->cfm_name = strdup((char *)val);
+ cfm->cfm_name = xstrdup(val);
return 0;
}
@@ -1262,7 +1312,7 @@ ropt_map_name(const char *val, cf_map_t *cfm)
static int
ropt_map_defaults(const char *val, cf_map_t *cfm)
{
- cfm->cfm_defaults = strdup((char *)val);
+ cfm->cfm_defaults = xstrdup(val);
return 0;
}
@@ -1270,7 +1320,7 @@ ropt_map_defaults(const char *val, cf_map_t *cfm)
static int
ropt_map_options(const char *val, cf_map_t *cfm)
{
- cfm->cfm_opts = strdup((char *)val);
+ cfm->cfm_opts = xstrdup(val);
return 0;
}
@@ -1283,7 +1333,7 @@ ropt_map_type(const char *val, cf_map_t *cfm)
fprintf(stderr, "conf: no such map type \"%s\"\n", val);
return 1;
}
- cfm->cfm_type = strdup((char *)val);
+ cfm->cfm_type = xstrdup(val);
return 0;
}
@@ -1313,15 +1363,32 @@ ropt_mount_type(const char *val, cf_map_t *cfm)
static int
ropt_search_path(const char *val, cf_map_t *cfm)
{
- cfm->cfm_search_path = strdup((char *)val);
+ cfm->cfm_search_path = xstrdup(val);
return 0;
}
static int
+ropt_sun_map_syntax(const char *val, cf_map_t *cfm)
+{
+ if (STREQ(val, "yes")) {
+ cfm->cfm_flags |= CFM_SUN_MAP_SYNTAX;
+ return 0;
+
+ } else if (STREQ(val, "no")) {
+ cfm->cfm_flags &= ~CFM_SUN_MAP_SYNTAX;
+ return 0;
+ }
+
+ fprintf(stderr, "conf: unknown value to sun_map_syntax \"%s\"\n", val);
+ return 1; /* unknown value */
+}
+
+
+static int
ropt_tag(const char *val, cf_map_t *cfm)
{
- cfm->cfm_tag = strdup((char *)val);
+ cfm->cfm_tag = xstrdup(val);
return 0;
}
@@ -1397,7 +1464,7 @@ find_cf_map(const char *name)
return NULL;
while (tmp_map) {
- if (STREQ(tmp_map->cfm_dir,name)) {
+ if (STREQ(tmp_map->cfm_dir, name)) {
return tmp_map;
}
tmp_map = tmp_map->cfm_next;
diff --git a/contrib/amd/amd/conf_parse.y b/contrib/amd/amd/conf_parse.y
index b397b0573242..26c1b7ac7903 100644
--- a/contrib/amd/amd/conf_parse.y
+++ b/contrib/amd/amd/conf_parse.y
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/amd/conf_tok.l b/contrib/amd/amd/conf_tok.l
index b572e4d7d5a3..fea2d8bf43f5 100644
--- a/contrib/amd/amd/conf_tok.l
+++ b/contrib/amd/amd/conf_tok.l
@@ -1,6 +1,6 @@
%{
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -17,11 +17,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -74,7 +70,7 @@
*/
#ifdef FLEX_SCANNER
# ifndef ECHO
-# define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+# define ECHO __IGNORE(fwrite( yytext, yyleng, 1, yyout ))
# endif /* not ECHO */
#endif /* FLEX_SCANNER */
@@ -86,9 +82,9 @@ int yylex(void);
* which automatically generates yywrap macros and symbols. So I must
* distinguish between them and when yywrap is actually needed.
*/
-#ifndef yywrap
+#if !defined(yywrap) || defined(yylex)
int yywrap(void);
-#endif /* not yywrap */
+#endif /* not yywrap or yylex */
#define TOK_DEBUG 0
@@ -108,6 +104,7 @@ int yywrap(void);
/* 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
@@ -131,19 +128,19 @@ NONQUOTE [^\"]
\[ {
dprintf("%8d: Left bracket \"%s\"\n", yytext);
- yylval.strtype = strdup((char *)yytext);
+ conf_lval.strtype = xstrdup(yytext);
amu_return(LEFT_BRACKET);
}
\] {
dprintf("%8d: Right bracket \"%s\"\n", yytext);
- yylval.strtype = strdup((char *)yytext);
+ conf_lval.strtype = xstrdup(yytext);
amu_return(RIGHT_BRACKET);
}
= {
dprintf("%8d: Equal \"%s\"\n", yytext);
- yylval.strtype = strdup((char *)yytext);
+ conf_lval.strtype = xstrdup(yytext);
amu_return(EQUAL);
}
@@ -159,7 +156,7 @@ NONQUOTE [^\"]
{NONWSCHAR}{NONWSCHAR}* {
dprintf("%8d: Non-WS string \"%s\"\n", yytext);
- yylval.strtype = strdup((char *)yytext);
+ conf_lval.strtype = xstrdup(yytext);
amu_return(NONWS_STRING);
}
@@ -167,13 +164,13 @@ NONQUOTE [^\"]
dprintf("%8d: QUOTED-Non-WS-EQ string \"%s\"\n", yytext);
/* must strip quotes */
yytext[strlen((char *)yytext)-1] = '\0';
- yylval.strtype = strdup((char *)&yytext[1]);
+ conf_lval.strtype = xstrdup(&yytext[1]);
amu_return(QUOTED_NONWSEQ_STRING);
}
{NONWSEQCHAR}{NONWSEQCHAR}* {
dprintf("%8d: Non-WS-EQ string \"%s\"\n", yytext);
- yylval.strtype = strdup((char *)yytext);
+ conf_lval.strtype = xstrdup(yytext);
amu_return(NONWSEQ_STRING);
}
@@ -184,9 +181,9 @@ NONQUOTE [^\"]
* which automatically generates yywrap macros and symbols. So I must
* distinguish between them and when yywrap is actually needed.
*/
-#ifndef yywrap
+#if !defined(yywrap) || defined(yylex)
int yywrap(void)
{
return 1;
}
-#endif /* not yywrap */
+#endif /* not yywrap or yylex */
diff --git a/contrib/amd/amd/get_args.c b/contrib/amd/amd/get_args.c
index 8f743e6b2f3c..724eff7cdbb1 100644
--- a/contrib/amd/amd/get_args.c
+++ b/contrib/amd/amd/get_args.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -84,38 +80,52 @@ get_version_string(void)
len = 2048 + wire_buf_len;
vers = xmalloc(len);
xsnprintf(vers, len, "%s\n%s\n%s\n%s\n",
- "Copyright (c) 1997-2006 Erez Zadok",
+ "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);
- strlcat(vers, tmpbuf, len);
+ xstrlcat(vers, tmpbuf, len);
xsnprintf(tmpbuf, sizeof(tmpbuf), "Report bugs to %s.\n", PACKAGE_BUGREPORT);
- strlcat(vers, tmpbuf, len);
+ 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);
- strlcat(vers, tmpbuf, len);
+ 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);
- strlcat(vers, tmpbuf, len);
+ xstrlcat(vers, tmpbuf, len);
xsnprintf(tmpbuf, sizeof(tmpbuf), "domain=%s, host=%s, hostd=%s.\n",
hostdomain, am_get_hostname(), hostd);
- strlcat(vers, tmpbuf, len);
+ xstrlcat(vers, tmpbuf, len);
- strlcat(vers, "Map support for: ", len);
+ xstrlcat(vers, "Map support for: ", len);
mapc_showtypes(tmpbuf, sizeof(tmpbuf));
- strlcat(vers, tmpbuf, len);
- strlcat(vers, ".\nAMFS: ", len);
+ xstrlcat(vers, tmpbuf, len);
+ xstrlcat(vers, ".\nAMFS: ", len);
ops_showamfstypes(tmpbuf, sizeof(tmpbuf));
- strlcat(vers, tmpbuf, len);
- strlcat(vers, ", inherit.\nFS: ", len); /* hack: "show" that we support type:=inherit */
+ xstrlcat(vers, tmpbuf, len);
+ xstrlcat(vers, ", inherit.\nFS: ", len); /* hack: "show" that we support type:=inherit */
ops_showfstypes(tmpbuf, sizeof(tmpbuf));
- strlcat(vers, tmpbuf, len);
+ xstrlcat(vers, tmpbuf, len);
/* append list of networks if available */
if (wire_buf) {
- strlcat(vers, wire_buf, len);
+ xstrlcat(vers, wire_buf, len);
XFREE(wire_buf);
}
@@ -325,19 +335,18 @@ get_args(int argc, char *argv[])
perror(buf);
exit(1);
}
- yyin = fp;
- yyparse();
+ conf_in = fp;
+ conf_parse();
fclose(fp);
if (process_all_regular_maps() != 0)
exit(1);
}
- /* make sure there are some default options defined */
- if (xlog_level_init == ~0) {
- switch_option("");
- }
#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 */
diff --git a/contrib/amd/amd/info_exec.c b/contrib/amd/amd/info_exec.c
index 8ccab9aee579..95216c90e2e9 100644
--- a/contrib/amd/amd/info_exec.c
+++ b/contrib/amd/amd/info_exec.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -52,8 +48,8 @@
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
+#include <sun_map.h>
-#define MAX_LINE_LEN 1500
/* forward declarations */
int exec_init(mnt_map *m, char *map, time_t *tp);
@@ -74,13 +70,13 @@ fgets_timed(char *s, int size, int rdfd, int secs)
if (!s || size < 0 || rdfd < 0)
return 0;
- s[0] = 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' */
+ s[i+1] = '\0'; /* places the requisite trailing '\0' */
/* ready for reading */
rval = read(rdfd, (void *)(s+i), 1);
@@ -114,7 +110,7 @@ fgets_timed(char *s, int size, int rdfd, int secs)
FD_ZERO(&fds);
FD_SET(rdfd, &fds);
- rval = select(rdfd+1, &fds, 0, 0, &timeo);
+ rval = select(rdfd+1, &fds, NULL, NULL, &timeo);
if (rval < 0) {
/* error selecting */
plog(XLOG_WARNING, "fgets_timed select error: %m");
@@ -165,9 +161,9 @@ read_line(char *buf, int size, int fd)
* Try to locate a value in a query answer
*/
static int
-exec_parse_qanswer(int fd, char *map, char *key, char **pval, time_t *tp)
+exec_parse_qanswer(mnt_map *m, int fd, char *map, char *key, char **pval, time_t *tp)
{
- char qanswer[MAX_LINE_LEN], *dc = 0;
+ char qanswer[INFO_MAX_LINE_LEN], *dc = NULL;
int chuck = 0;
int line_no = 0;
@@ -197,7 +193,7 @@ exec_parse_qanswer(int fd, char *map, char *key, char **pval, time_t *tp)
/*
* Find beginning of value (query answer)
*/
- for (cp = qanswer; *cp && !isascii((int)*cp) && !isspace((int)*cp); cp++)
+ for (cp = qanswer; *cp && !isascii((unsigned char)*cp) && !isspace((unsigned char)*cp); cp++)
;;
/* Ignore blank lines */
@@ -207,7 +203,10 @@ exec_parse_qanswer(int fd, char *map, char *key, char **pval, time_t *tp)
/*
* Return a copy of the data
*/
- dc = strdup(cp);
+ 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);
@@ -324,7 +323,7 @@ exec_map_open(char *emap, char *key)
close(pdes[1]);
/* anti-zombie insurance */
- while (waitpid(p1,0,0) < 0)
+ while (waitpid(p1, 0, 0) < 0)
if (errno != EINTR)
exit(errno);
@@ -416,7 +415,7 @@ exec_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
if (tp)
*tp = clocktime(NULL);
- return exec_parse_qanswer(mapfd, map, key, pval, tp);
+ return exec_parse_qanswer(m, mapfd, map, key, pval, tp);
}
return errno;
diff --git a/contrib/amd/amd/info_file.c b/contrib/amd/amd/info_file.c
index 3777a2aebe94..738c7bfa5776 100644
--- a/contrib/amd/amd/info_file.c
+++ b/contrib/amd/amd/info_file.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -50,8 +46,8 @@
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
+#include <sun_map.h>
-#define MAX_LINE_LEN 1500
/* forward declarations */
int file_init_or_mtime(mnt_map *m, char *map, time_t *tp);
@@ -59,8 +55,8 @@ 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);
-static int
-read_line(char *buf, int size, FILE *fp)
+int
+file_read_line(char *buf, int size, FILE *fp)
{
int done = 0;
@@ -79,7 +75,7 @@ read_line(char *buf, int size, FILE *fp)
* Skip leading white space on next line
*/
while ((ch = getc(fp)) != EOF &&
- isascii(ch) && isspace(ch)) ;
+ isascii((unsigned char)ch) && isspace((unsigned char)ch)) ;
(void) ungetc(ch, fp);
} else {
return done;
@@ -95,18 +91,18 @@ read_line(char *buf, int size, FILE *fp)
* Try to locate a key in a file
*/
static int
-file_search_or_reload(FILE *fp,
+file_search_or_reload(mnt_map *m,
+ FILE *fp,
char *map,
char *key,
char **val,
- mnt_map *m,
void (*fn) (mnt_map *m, char *, char *))
{
- char key_val[MAX_LINE_LEN];
+ char key_val[INFO_MAX_LINE_LEN];
int chuck = 0;
int line_no = 0;
- while (read_line(key_val, sizeof(key_val), fp)) {
+ while (file_read_line(key_val, sizeof(key_val), fp)) {
char *kp;
char *cp;
char *hash;
@@ -133,7 +129,7 @@ file_search_or_reload(FILE *fp,
/*
* Find start of key
*/
- for (kp = key_val; *kp && isascii(*kp) && isspace((int)*kp); kp++) ;
+ for (kp = key_val; *kp && isascii((unsigned char)*kp) && isspace((unsigned char)*kp); kp++) ;
/*
* Ignore blank lines
@@ -144,7 +140,7 @@ file_search_or_reload(FILE *fp,
/*
* Find end of key
*/
- for (cp = kp; *cp && (!isascii(*cp) || !isspace((int)*cp)); cp++) ;
+ for (cp = kp; *cp && (!isascii((unsigned char)*cp) || !isspace((unsigned char)*cp)); cp++) ;
/*
* Check whether key matches
@@ -153,15 +149,20 @@ file_search_or_reload(FILE *fp,
*cp++ = '\0';
if (fn || (*key == *kp && STREQ(key, kp))) {
- while (*cp && isascii(*cp) && isspace((int)*cp))
+ while (*cp && isascii((unsigned char)*cp) && isspace((unsigned char)*cp))
cp++;
if (*cp) {
/*
* Return a copy of the data
*/
- char *dc = strdup(cp);
+ 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, strdup(kp), dc);
+ (*fn) (m, xstrdup(kp), dc);
} else {
*val = dc;
dlog("%s returns %s", key, dc);
@@ -221,10 +222,10 @@ 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 *))
{
- FILE *mapf = file_open(map, (time_t *) 0);
+ FILE *mapf = file_open(map, (time_t *) NULL);
if (mapf) {
- int error = file_search_or_reload(mapf, map, 0, 0, m, fn);
+ int error = file_search_or_reload(m, mapf, map, NULL, NULL, fn);
(void) fclose(mapf);
return error;
}
@@ -244,7 +245,7 @@ file_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
*tp = t;
error = -1;
} else {
- error = file_search_or_reload(mapf, map, key, pval, 0, 0);
+ error = file_search_or_reload(m, mapf, map, key, pval, NULL);
}
(void) fclose(mapf);
return error;
diff --git a/contrib/amd/amd/info_hesiod.c b/contrib/amd/amd/info_hesiod.c
index e345c9961508..0293f435a262 100644
--- a/contrib/amd/amd/info_hesiod.c
+++ b/contrib/amd/amd/info_hesiod.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -50,6 +46,7 @@
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
+#include <sun_map.h>
#define HES_PREFIX "hesiod."
#define HES_PREFLEN 7
@@ -127,7 +124,11 @@ hesiod_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
* it (and free subsequent replies)
*/
if (rvec && *rvec) {
- *pval = *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;
diff --git a/contrib/amd/amd/info_ldap.c b/contrib/amd/amd/info_ldap.c
index 36ce1c8693d3..cfed6fd773d7 100644
--- a/contrib/amd/amd/info_ldap.c
+++ b/contrib/amd/amd/info_ldap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -66,6 +62,7 @@
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
+#include <sun_map.h>
/*
@@ -118,12 +115,17 @@ struct he_ent {
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:
@@ -144,30 +146,33 @@ string2he(char *s_orig)
{
char *c, *p;
char *s;
- HE_ENT *new, *old = NULL;
+ HE_ENT *first = NULL, *cur = NULL;
- if (NULL == s_orig || NULL == (s = strdup(s_orig)))
+ if (NULL == s_orig)
return NULL;
- for (p = s; p; p = strchr(p, ',')) {
- if (old != NULL) {
- new = ALLOC(HE_ENT);
- old->next = new;
- old = new;
- } else {
- old = ALLOC(HE_ENT);
- old->next = 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';
- old->host = strdup(p);
- old->port = atoi(c);
- } else
- old->host = strdup(p);
-
+ 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 (old);
+ return first;
}
@@ -248,10 +253,18 @@ amu_ldap_init(mnt_map *m, char *map, time_t *ts)
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;
@@ -274,11 +287,14 @@ amu_ldap_init(mnt_map *m, char *map, time_t *ts)
ald_free(aldh);
return (ENOENT);
}
- m->map_data = (void *) aldh;
dlog("Bound to %s:%d\n", aldh->hostent->host, aldh->hostent->port);
- if (get_ldap_timestamp(aldh, map, ts))
+ 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);
}
@@ -312,7 +328,7 @@ amu_ldap_rebind(ALD *a)
for (h = a->hostent; h != NULL; h = h->next) {
if ((ld = ldap_open(h->host, h->port)) == NULL) {
plog(XLOG_WARNING, "Unable to ldap_open to %s:%d\n", h->host, h->port);
- break;
+ continue;
}
#if LDAP_VERSION_MAX > LDAP_VERSION2
/* handle LDAPv3 and heigher, if available and amd.conf-igured */
@@ -321,16 +337,16 @@ amu_ldap_rebind(ALD *a)
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\n",
- gopt.ldap_proto_version);
- break;
+ 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);
- break;
+ continue;
}
if (gopt.ldap_cache_seconds > 0) {
#if defined(HAVE_LDAP_ENABLE_CACHE) && defined(HAVE_EXTERN_LDAP_ENABLE_CACHE)
@@ -541,7 +557,10 @@ amu_ldap_search(mnt_map *m, char *map, char *key, char **pval, time_t *ts)
}
dlog("Map %s, %s => %s\n", map, key, vals[0]);
if (vals[0]) {
- *pval = strdup(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);
diff --git a/contrib/amd/amd/info_ndbm.c b/contrib/amd/amd/info_ndbm.c
index 8a52ba9e201d..5f2f52b5330e 100644
--- a/contrib/amd/amd/info_ndbm.c
+++ b/contrib/amd/amd/info_ndbm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -50,6 +46,7 @@
#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);
@@ -58,7 +55,7 @@ int ndbm_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
static int
-search_ndbm(DBM *db, char *key, char **val)
+search_ndbm(mnt_map *m, DBM *db, char *key, char **val)
{
datum k, v;
@@ -66,7 +63,10 @@ search_ndbm(DBM *db, char *key, char **val)
k.dsize = strlen(key) + 1;
v = dbm_fetch(db, k);
if (v.dptr) {
- *val = strdup(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;
@@ -95,7 +95,7 @@ ndbm_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
*tp = stb.st_mtime;
error = -1;
} else {
- error = search_ndbm(db, key, pval);
+ error = search_ndbm(m, db, key, pval);
}
(void) dbm_close(db);
return error;
diff --git a/contrib/amd/amd/info_nis.c b/contrib/amd/amd/info_nis.c
index bcb87d5d02aa..83dc4b7a84fc 100644
--- a/contrib/amd/amd/info_nis.c
+++ b/contrib/amd/amd/info_nis.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -50,6 +46,7 @@
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
+#include <sun_map.h>
/*
@@ -109,7 +106,7 @@ determine_nis_domain(void)
plog(XLOG_WARNING, "NIS domain name is not set. NIS ignored.");
return ENOENT;
}
- gopt.nis_domain = strdup(default_domain);
+ gopt.nis_domain = xstrdup(default_domain);
return 0;
}
@@ -167,6 +164,7 @@ nis_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *))
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
@@ -247,7 +245,7 @@ nis_isup(mnt_map *m, char *map)
* Try to locate a key using NIS.
*/
int
-nis_search(mnt_map *m, char *map, char *key, char **val, time_t *tp)
+nis_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
{
int outlen;
int res;
@@ -301,7 +299,15 @@ nis_search(mnt_map *m, char *map, char *key, char **val, time_t *tp)
/*
* Lookup key
*/
- res = yp_match(gopt.nis_domain, map, key, strlen(key), val, &outlen);
+ 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
diff --git a/contrib/amd/amd/info_nisplus.c b/contrib/amd/amd/info_nisplus.c
index d392b48fed6a..79df83614700 100644
--- a/contrib/amd/amd/info_nisplus.c
+++ b/contrib/amd/amd/info_nisplus.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -50,6 +46,7 @@
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amd.h>
+#include <sun_map.h>
#define NISPLUS_KEY "key="
#define NISPLUS_ORGDIR ".org_dir"
@@ -221,7 +218,12 @@ nisplus_search(mnt_map *m, char *map, char *key, char **val, time_t *tp)
if (value != NULL)
data.value = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1));
}
- *val = data.value;
+
+ 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;
diff --git a/contrib/amd/amd/info_passwd.c b/contrib/amd/amd/info_passwd.c
index c8bf388b1d65..3c4486693c60 100644
--- a/contrib/amd/amd/info_passwd.c
+++ b/contrib/amd/amd/info_passwd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -94,11 +90,11 @@ 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)
{
- char *dir = 0;
+ char *dir = NULL;
struct passwd *pw;
if (STREQ(key, "/defaults")) {
- *pval = strdup("type:=nfs");
+ *pval = xstrdup("type:=nfs");
return 0;
}
pw = getpwnam(key);
@@ -123,7 +119,7 @@ passwd_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
char *p, *q;
char val[MAXPATHLEN];
char rhost[MAXHOSTNAMELEN];
- dir = strdup(pw->pw_dir);
+ dir = xstrdup(pw->pw_dir);
/*
* Find user name. If no / then Invalid...
@@ -180,13 +176,12 @@ passwd_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
dlog("passwd_search: map=%s key=%s -> %s", map, key, val);
if (q)
*q = '.';
- *pval = strdup(val);
+ *pval = xstrdup(val);
return 0;
}
enoent:
- if (dir)
- XFREE(dir);
+ XFREE(dir);
return ENOENT;
}
diff --git a/contrib/amd/amd/info_sun.c b/contrib/amd/amd/info_sun.c
new file mode 100644
index 000000000000..3f56965ff747
--- /dev/null
+++ b/contrib/amd/amd/info_sun.c
@@ -0,0 +1,53 @@
+/*
+ * 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 */
diff --git a/contrib/amd/amd/info_union.c b/contrib/amd/amd/info_union.c
index 8f0631c64ac9..df480317bddf 100644
--- a/contrib/amd/amd/info_union.c
+++ b/contrib/amd/amd/info_union.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -77,7 +73,7 @@ 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)
{
- char *mapd = strdup(map + UNION_PREFLEN);
+ char *mapd = xstrdup(map + UNION_PREFLEN);
char **v = strsplit(mapd, ':', '\"');
char **p;
size_t l;
@@ -95,14 +91,15 @@ 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 *))
{
- char *mapd = strdup(map + UNION_PREFLEN);
+ static const char fseq[] = "fs:=";
+ char *mapd = xstrdup(map + UNION_PREFLEN);
char **v = strsplit(mapd, ':', '\"');
char **dir;
/*
* Add fake /defaults entry
*/
- (*fn) (m, strdup("/defaults"), strdup("type:=link;opts:=nounmount;sublink:=${key}"));
+ (*fn) (m, xstrdup("/defaults"), xstrdup("type:=link;opts:=nounmount;sublink:=${key}"));
for (dir = v; *dir; dir++) {
size_t l;
@@ -113,7 +110,7 @@ union_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *))
plog(XLOG_USER, "Cannot read directory %s: %m", *dir);
continue;
}
- l = strlen(*dir) + 5;
+ l = strlen(*dir) + sizeof(fseq);
dlog("Reading directory %s...", *dir);
while ((dp = readdir(dirp))) {
@@ -125,8 +122,8 @@ union_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *))
dlog("... gives %s", dp->d_name);
val = xmalloc(l);
- xsnprintf(val, l + 5, "fs:=%s", *dir);
- (*fn) (m, strdup(dp->d_name), val);
+ xsnprintf(val, l, "%s%s", fseq, *dir);
+ (*fn) (m, xstrdup(dp->d_name), val);
}
closedir(dirp);
}
@@ -135,11 +132,11 @@ union_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *))
* Add wildcard entry
*/
{
- size_t l = strlen(*(dir-1)) + 5;
+ size_t l = strlen(*(dir-1)) + sizeof(fseq);
char *val = xmalloc(l);
- xsnprintf(val, l, "fs:=%s", *(dir-1));
- (*fn) (m, strdup("*"), val);
+ xsnprintf(val, l, "%s%s", fseq, *(dir-1));
+ (*fn) (m, xstrdup("*"), val);
}
XFREE(mapd);
XFREE(v);
diff --git a/contrib/amd/amd/map.c b/contrib/amd/amd/map.c
index 8696dfd6984d..0d404cfdbd66 100644
--- a/contrib/amd/amd/map.c
+++ b/contrib/amd/amd/map.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -69,7 +65,7 @@ static u_int am_gen = 2; /* Initial generation number */
static int timeout_mp_id; /* Id from last call to timeout */
static am_node *root_node; /* The root of the mount tree */
-static am_node **exported_ap = (am_node **) 0;
+static am_node **exported_ap = (am_node **) NULL;
static int exported_ap_size = 0;
static int first_free_map = 0; /* First available free slot */
static int last_used_map = -1; /* Last unavailable used slot */
@@ -190,7 +186,7 @@ am_node *
get_ap_child(am_node *mp, char *fname)
{
am_node *new_mp;
- mntfs *mf = mp->am_mnt;
+ mntfs *mf = mp->am_al->al_mnt;
/*
* Allocate a new map
@@ -280,7 +276,7 @@ exported_ap_free(am_node *mp)
/*
* Zero the slot pointer to avoid double free's
*/
- exported_ap[mp->am_mapno] = 0;
+ exported_ap[mp->am_mapno] = NULL;
/*
* Update the free and last_used indices
@@ -325,7 +321,7 @@ insert_am(am_node *mp, am_node *p_mp)
mp->am_osib->am_ysib = mp;
p_mp->am_child = mp;
#ifdef HAVE_FS_AUTOFS
- if (p_mp->am_mnt->mf_flags & MFF_IS_AUTOFS)
+ if (p_mp->am_al->al_mnt->mf_flags & MFF_IS_AUTOFS)
mp->am_flags |= AMF_AUTOFS;
#endif /* HAVE_FS_AUTOFS */
}
@@ -408,13 +404,14 @@ init_map(am_node *mp, char *dir)
* mp->am_mapno is initialized by exported_ap_alloc
* other fields don't need to be set to zero.
*/
- mp->am_mnt = new_mntfs();
- mp->am_mfarray = 0;
- mp->am_name = strdup(dir);
- mp->am_path = strdup(dir);
+
+ mp->am_al = new_loc();
+ mp->am_alarray = NULL;
+ mp->am_name = xstrdup(dir);
+ mp->am_path = xstrdup(dir);
mp->am_gen = new_gen();
#ifdef HAVE_FS_AUTOFS
- mp->am_autofs_fh = 0;
+ mp->am_autofs_fh = NULL;
#endif /* HAVE_FS_AUTOFS */
mp->am_timeo = gopt.am_timeo;
@@ -430,6 +427,30 @@ init_map(am_node *mp, char *dir)
mp->am_stats.s_mtime = mp->am_fattr.na_atime.nt_seconds;
mp->am_dev = -1;
mp->am_rdev = -1;
+ mp->am_fd[0] = -1;
+ mp->am_fd[1] = -1;
+}
+
+
+void
+notify_child(am_node *mp, au_etype au_etype, int au_errno, int au_signal)
+{
+ amq_sync_umnt rv;
+ int err;
+
+ if (mp->am_fd[1] >= 0) { /* we have a child process */
+ rv.au_etype = au_etype;
+ rv.au_signal = au_signal;
+ rv.au_errno = au_errno;
+
+ err = write(mp->am_fd[1], &rv, sizeof(rv));
+ /* XXX: do something else on err? */
+ if (err < sizeof(rv))
+ plog(XLOG_INFO, "notify_child: write returned %d instead of %d.",
+ err, (int) sizeof(rv));
+ close(mp->am_fd[1]);
+ mp->am_fd[1] = -1;
+ }
}
@@ -442,25 +463,24 @@ free_map(am_node *mp)
{
remove_am(mp);
- if (mp->am_link)
- XFREE(mp->am_link);
- if (mp->am_name)
- XFREE(mp->am_name);
- if (mp->am_path)
- XFREE(mp->am_path);
- if (mp->am_pref)
- XFREE(mp->am_pref);
- if (mp->am_transp)
- XFREE(mp->am_transp);
-
- if (mp->am_mnt)
- free_mntfs(mp->am_mnt);
-
- if (mp->am_mfarray) {
- mntfs **temp_mf;
- for (temp_mf = mp->am_mfarray; *temp_mf; temp_mf++)
- free_mntfs(*temp_mf);
- XFREE(mp->am_mfarray);
+ if (mp->am_fd[1] != -1)
+ plog(XLOG_FATAL, "free_map: called prior to notifying the child for %s.",
+ mp->am_path);
+
+ XFREE(mp->am_link);
+ XFREE(mp->am_name);
+ XFREE(mp->am_path);
+ XFREE(mp->am_pref);
+ XFREE(mp->am_transp);
+
+ if (mp->am_al)
+ free_loc(mp->am_al);
+
+ if (mp->am_alarray) {
+ am_loc **temp_al;
+ for (temp_al = mp->am_alarray; *temp_al; temp_al++)
+ free_loc(*temp_al);
+ XFREE(mp->am_alarray);
}
#ifdef HAVE_FS_AUTOFS
@@ -480,8 +500,8 @@ find_ap_recursive(char *dir, am_node *mp)
if (STREQ(mp->am_path, dir))
return mp;
- if ((mp->am_mnt->mf_flags & MFF_MOUNTED) &&
- STREQ(mp->am_mnt->mf_mount, dir))
+ if ((mp->am_al->al_mnt->mf_flags & MFF_MOUNTED) &&
+ STREQ(mp->am_al->al_mnt->mf_mount, dir))
return mp;
mp2 = find_ap_recursive(dir, mp->am_osib);
@@ -518,37 +538,20 @@ find_ap(char *dir)
/*
- * Find the mount node corresponding
- * to the mntfs structure.
- */
-am_node *
-find_mf(mntfs *mf)
-{
- int i;
-
- for (i = last_used_map; i >= 0; --i) {
- am_node *mp = exported_ap[i];
- if (mp && mp->am_mnt == mf)
- return mp;
- }
-
- return 0;
-}
-
-
-/*
* Get the filehandle for a particular named directory.
* This is used during the bootstrap to tell the kernel
* the filehandles of the initial automount points.
*/
-am_nfs_fh *
-get_root_nfs_fh(char *dir)
+am_nfs_handle_t *
+get_root_nfs_fh(char *dir, am_nfs_handle_t *nfh)
{
- static am_nfs_fh nfh;
am_node *mp = get_root_ap(dir);
if (mp) {
- mp_to_fh(mp, &nfh);
- return &nfh;
+ if (nfs_dispatcher == nfs_program_2)
+ mp_to_fh(mp, &nfh->v2);
+ else
+ mp_to_fh3(mp, &nfh->v3);
+ return nfh;
}
/*
@@ -584,7 +587,8 @@ map_flush_srvr(fserver *fs)
for (i = last_used_map; i >= 0; --i) {
am_node *mp = exported_ap[i];
- if (mp && mp->am_mnt && mp->am_mnt->mf_server == fs) {
+
+ if (mp && mp->am_al->al_mnt && mp->am_al->al_mnt->mf_server == fs) {
plog(XLOG_INFO, "Flushed %s; dependent on %s", mp->am_path, fs->fs_host);
mp->am_ttl = clocktime(NULL);
done = 1;
@@ -608,7 +612,7 @@ mount_auto_node(char *dir, opaque_t arg)
am_node *mp = (am_node *) arg;
am_node *new_mp;
- new_mp = mp->am_mnt->mf_ops->lookup_child(mp, dir, &error, VLOOK_CREATE);
+ new_mp = mp->am_al->al_mnt->mf_ops->lookup_child(mp, dir, &error, VLOOK_CREATE);
if (new_mp && error < 0) {
/*
* We can't allow the fileid of the root node to change.
@@ -616,7 +620,7 @@ mount_auto_node(char *dir, opaque_t arg)
*/
new_mp->am_gen = new_mp->am_fattr.na_fileid = 1;
- new_mp = mp->am_mnt->mf_ops->mount_child(new_mp, &error);
+ (void) mp->am_al->al_mnt->mf_ops->mount_child(new_mp, &error);
}
if (error > 0) {
@@ -647,7 +651,7 @@ mount_exported(void)
void
make_root_node(void)
{
- mntfs *root_mnt;
+ mntfs *root_mf;
char *rootmap = ROOT_MAP;
root_node = exported_ap_alloc();
@@ -659,24 +663,24 @@ make_root_node(void)
/*
* Allocate a new mounted filesystem
*/
- root_mnt = find_mntfs(&amfs_root_ops, (am_opts *) 0, "", rootmap, "", "", "");
+ root_mf = find_mntfs(&amfs_root_ops, (am_opts *) NULL, "", rootmap, "", "", "");
/*
* Replace the initial null reference
*/
- free_mntfs(root_node->am_mnt);
- root_node->am_mnt = root_mnt;
+ free_mntfs(root_node->am_al->al_mnt);
+ root_node->am_al->al_mnt = root_mf;
/*
* Initialize the root
*/
- if (root_mnt->mf_ops->fs_init)
- (*root_mnt->mf_ops->fs_init) (root_mnt);
+ if (root_mf->mf_ops->fs_init)
+ (*root_mf->mf_ops->fs_init) (root_mf);
/*
* Mount the root
*/
- root_mnt->mf_error = root_mnt->mf_ops->mount_fs(root_node, root_mnt);
+ root_mf->mf_error = root_mf->mf_ops->mount_fs(root_node, root_mf);
}
@@ -687,68 +691,81 @@ make_root_node(void)
void
umount_exported(void)
{
- int i;
+ int i, work_done;
- for (i = last_used_map; i >= 0; --i) {
- am_node *mp = exported_ap[i];
- mntfs *mf;
+ do {
+ work_done = 0;
- if (!mp)
- continue;
+ for (i = last_used_map; i >= 0; --i) {
+ am_node *mp = exported_ap[i];
+ mntfs *mf;
- mf = mp->am_mnt;
- if (mf->mf_flags & MFF_UNMOUNTING) {
- /*
- * If this node is being unmounted then just ignore it. However,
- * this could prevent amd from finishing if the unmount gets blocked
- * since the am_node will never be free'd. am_unmounted needs
- * telling about this possibility. - XXX
- */
- continue;
- }
+ if (!mp)
+ continue;
- if (!(mf->mf_fsflags & FS_DIRECTORY))
/*
- * When shutting down this had better
- * look like a directory, otherwise it
- * can't be unmounted!
+ * Wait for children to be removed first
*/
- mk_fattr(&mp->am_fattr, NFDIR);
+ if (mp->am_child)
+ continue;
- if ((--immediate_abort < 0 &&
- !(mp->am_flags & AMF_ROOT) && mp->am_parent) ||
- (mf->mf_flags & MFF_RESTART)) {
+ mf = mp->am_al->al_mnt;
+ if (mf->mf_flags & MFF_UNMOUNTING) {
+ /*
+ * If this node is being unmounted then just ignore it. However,
+ * this could prevent amd from finishing if the unmount gets blocked
+ * since the am_node will never be free'd. am_unmounted needs
+ * telling about this possibility. - XXX
+ */
+ continue;
+ }
+
+ if (!(mf->mf_fsflags & FS_DIRECTORY))
+ /*
+ * When shutting down this had better
+ * look like a directory, otherwise it
+ * can't be unmounted!
+ */
+ mk_fattr(&mp->am_fattr, NFDIR);
+
+ if ((--immediate_abort < 0 &&
+ !(mp->am_flags & AMF_ROOT) && mp->am_parent) ||
+ (mf->mf_flags & MFF_RESTART)) {
+
+ work_done++;
- /*
- * Just throw this node away without bothering to unmount it. If
- * the server is not known to be up then don't discard the mounted
- * on directory or Amd might hang...
- */
- if (mf->mf_server &&
- (mf->mf_server->fs_flags & (FSF_DOWN | FSF_VALID)) != FSF_VALID)
- mf->mf_flags &= ~MFF_MKMNT;
- if (gopt.flags & CFM_UNMOUNT_ON_EXIT || mp->am_flags & AMF_AUTOFS) {
- plog(XLOG_INFO, "on-exit attempt to unmount %s", mf->mf_mount);
/*
- * use unmount_mp, not unmount_node, so that unmounts be
- * backgrounded as needed.
+ * Just throw this node away without bothering to unmount it. If
+ * the server is not known to be up then don't discard the mounted
+ * on directory or Amd might hang...
*/
- unmount_mp((opaque_t) mp);
+ if (mf->mf_server &&
+ (mf->mf_server->fs_flags & (FSF_DOWN | FSF_VALID)) != FSF_VALID)
+ mf->mf_flags &= ~MFF_MKMNT;
+ if (gopt.flags & CFM_UNMOUNT_ON_EXIT || mp->am_flags & AMF_AUTOFS) {
+ plog(XLOG_INFO, "on-exit attempt to unmount %s", mf->mf_mount);
+ /*
+ * use unmount_mp, not unmount_node, so that unmounts be
+ * backgrounded as needed.
+ */
+ unmount_mp((opaque_t) mp);
+ } else {
+ am_unmounted(mp);
+ }
+ if (!(mf->mf_flags & (MFF_UNMOUNTING|MFF_MOUNTED)))
+ exported_ap[i] = NULL;
} else {
- am_unmounted(mp);
+ /*
+ * Any other node gets forcibly timed out.
+ */
+ mp->am_flags &= ~AMF_NOTIMEOUT;
+ mp->am_al->al_mnt->mf_flags &= ~MFF_RSTKEEP;
+ mp->am_ttl = 0;
+ mp->am_timeo = 1;
+ mp->am_timeo_w = 0;
}
- exported_ap[i] = 0;
- } else {
- /*
- * Any other node gets forcibly timed out.
- */
- mp->am_flags &= ~AMF_NOTIMEOUT;
- mp->am_mnt->mf_flags &= ~MFF_RSTKEEP;
- mp->am_ttl = 0;
- mp->am_timeo = 1;
- mp->am_timeo_w = 0;
}
- }
+ } while (work_done);
}
@@ -762,7 +779,7 @@ int
mount_node(opaque_t arg)
{
am_node *mp = (am_node *) arg;
- mntfs *mf = mp->am_mnt;
+ mntfs *mf = mp->am_al->al_mnt;
int error = 0;
#ifdef HAVE_FS_AUTOFS
@@ -784,7 +801,7 @@ static int
unmount_node(opaque_t arg)
{
am_node *mp = (am_node *) arg;
- mntfs *mf = mp->am_mnt;
+ mntfs *mf = mp->am_al->al_mnt;
int error = 0;
if (mf->mf_flags & MFF_ERROR) {
@@ -805,7 +822,7 @@ unmount_node(opaque_t arg)
}
/* do this again, it might have changed */
- mf = mp->am_mnt;
+ mf = mp->am_al->al_mnt;
if (error) {
errno = error; /* XXX */
dlog("%s: unmount: %m", mf->mf_mount);
@@ -819,7 +836,7 @@ static void
free_map_if_success(int rc, int term, opaque_t arg)
{
am_node *mp = (am_node *) arg;
- mntfs *mf = mp->am_mnt;
+ mntfs *mf = mp->am_al->al_mnt;
wchan_t wchan = get_mntfs_wchan(mf);
/*
@@ -836,6 +853,7 @@ free_map_if_success(int rc, int term, opaque_t arg)
reschedule_timeout_mp();
}
if (term) {
+ notify_child(mp, AMQ_UMNT_SIGNAL, 0, term);
plog(XLOG_ERROR, "unmount for %s got signal %d", mp->am_path, term);
#if defined(DEBUG) && defined(SIGTRAP)
/*
@@ -852,18 +870,24 @@ free_map_if_success(int rc, int term, opaque_t arg)
#endif /* HAVE_FS_AUTOFS */
amd_stats.d_uerr++;
} else if (rc) {
+ notify_child(mp, AMQ_UMNT_FAILED, rc, 0);
if (mf->mf_ops == &amfs_program_ops || rc == EBUSY)
plog(XLOG_STATS, "\"%s\" on %s still active", mp->am_path, mf->mf_mount);
else
plog(XLOG_ERROR, "%s: unmount: %s", mp->am_path, strerror(rc));
#ifdef HAVE_FS_AUTOFS
- if (mf->mf_flags & MFF_IS_AUTOFS)
- autofs_get_mp(mp);
- if (mp->am_flags & AMF_AUTOFS)
- autofs_umount_failed(mp);
+ if (rc != ENOENT) {
+ if (mf->mf_flags & MFF_IS_AUTOFS)
+ autofs_get_mp(mp);
+ if (mp->am_flags & AMF_AUTOFS)
+ autofs_umount_failed(mp);
+ }
#endif /* HAVE_FS_AUTOFS */
amd_stats.d_uerr++;
} else {
+ /*
+ * am_unmounted() will call notify_child() appropriately.
+ */
am_unmounted(mp);
}
@@ -878,11 +902,11 @@ int
unmount_mp(am_node *mp)
{
int was_backgrounded = 0;
- mntfs *mf = mp->am_mnt;
+ mntfs *mf = mp->am_al->al_mnt;
#ifdef notdef
plog(XLOG_INFO, "\"%s\" on %s timed out (flags 0x%x)",
- mp->am_path, mp->am_mnt->mf_mount, (int) mf->mf_flags);
+ mp->am_path, mf->mf_mount, (int) mf->mf_flags);
#endif /* notdef */
#ifndef MNT2_NFS_OPT_SYMTTL
@@ -914,10 +938,11 @@ unmount_mp(am_node *mp)
plog(XLOG_STATS, "file server %s is down - timeout of \"%s\" ignored", mf->mf_server->fs_host, mp->am_path);
mf->mf_flags |= MFF_LOGDOWN;
}
+ notify_child(mp, AMQ_UMNT_SERVER, 0, 0);
return 0;
}
- dlog("\"%s\" on %s timed out", mp->am_path, mp->am_mnt->mf_mount);
+ dlog("\"%s\" on %s timed out", mp->am_path, mf->mf_mount);
mf->mf_flags |= MFF_UNMOUNTING;
#ifdef HAVE_FS_AUTOFS
@@ -926,7 +951,8 @@ unmount_mp(am_node *mp)
#endif /* HAVE_FS_AUTOFS */
if ((mf->mf_fsflags & FS_UBACKGROUND) &&
- (mf->mf_flags & MFF_MOUNTED)) {
+ (mf->mf_flags & MFF_MOUNTED) &&
+ !(mf->mf_flags & MFF_ON_AUTOFS)) {
dlog("Trying unmount in background");
run_task(unmount_node, (opaque_t) mp,
free_map_if_success, (opaque_t) mp);
@@ -964,7 +990,7 @@ timeout_mp(opaque_t v) /* argument not used?! */
/*
* Pick up mounted filesystem
*/
- mf = mp->am_mnt;
+ mf = mp->am_al->al_mnt;
if (!mf)
continue;
@@ -1056,7 +1082,7 @@ timeout_mp(opaque_t v) /* argument not used?! */
t = now + 1;
dlog("Next mount timeout in %lds", (long) (t - now));
- timeout_mp_id = timeout(t - now, timeout_mp, 0);
+ timeout_mp_id = timeout(t - now, timeout_mp, NULL);
}
@@ -1068,5 +1094,5 @@ reschedule_timeout_mp(void)
{
if (timeout_mp_id)
untimeout(timeout_mp_id);
- timeout_mp_id = timeout(0, timeout_mp, 0);
+ timeout_mp_id = timeout(0, timeout_mp, NULL);
}
diff --git a/contrib/amd/amd/mapc.c b/contrib/amd/amd/mapc.c
index d7efdbcfd217..cd4b9b956a05 100644
--- a/contrib/amd/amd/mapc.c
+++ b/contrib/amd/amd/mapc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -96,7 +92,7 @@ static struct opt_tab mapc_opt[] =
{"regexp", MAPC_RE},
#endif /* HAVE_REGEXEC */
{"sync", MAPC_SYNC},
- {0, 0}
+ {NULL, 0}
};
/*
@@ -137,6 +133,7 @@ static const char *get_full_path(const char *map, const char *path, const char *
static int mapc_meta_search(mnt_map *, char *, char **, int);
static void mapc_sync(mnt_map *);
static void mapc_clear(mnt_map *);
+static void mapc_clear_kvhash(kv **);
/* ROOT MAP */
static int root_init(mnt_map *, char *, time_t *);
@@ -198,12 +195,6 @@ extern int ndbm_search(mnt_map *, char *, char *, char **, time_t *);
extern int ndbm_mtime(mnt_map *, char *, time_t *);
#endif /* HAVE_MAP_NDBM */
-/* EXECUTABLE MAPS */
-#ifdef HAVE_MAP_EXEC
-extern int exec_init(mnt_map *, char *, time_t *);
-extern int exec_search(mnt_map *, char *, char *, char **, time_t *);
-#endif /* HAVE_MAP_EXEC */
-
/* FILE MAPS */
#ifdef HAVE_MAP_FILE
extern int file_init_or_mtime(mnt_map *, char *, time_t *);
@@ -211,6 +202,16 @@ extern int file_reload(mnt_map *, char *, add_fn *);
extern int file_search(mnt_map *, char *, char *, char **, time_t *);
#endif /* HAVE_MAP_FILE */
+/* EXECUTABLE MAPS */
+#ifdef HAVE_MAP_EXEC
+extern int exec_init(mnt_map *, char *, time_t *);
+extern int exec_search(mnt_map *, char *, char *, char **, time_t *);
+#endif /* HAVE_MAP_EXEC */
+
+/* Sun-syntax MAPS */
+#ifdef HAVE_MAP_SUN
+/* XXX: fill in */
+#endif /* HAVE_MAP_SUN */
/* note that the choice of MAPC_{INC,ALL} will affect browsable_dirs */
static map_type maptypes[] =
@@ -323,6 +324,20 @@ static map_type maptypes[] =
MAPC_INC
},
#endif /* HAVE_MAP_EXEC */
+#ifdef notyet /* probe function needs to be there or SEGV */
+#ifdef HAVE_MAP_SUN
+ {
+ /* XXX: fill in */
+ "sun",
+ NULL,
+ NULL,
+ NULL, /* isup function */
+ NULL,
+ NULL,
+ 0
+ },
+#endif /* HAVE_MAP_SUN */
+#endif
{
"error",
error_init,
@@ -412,6 +427,44 @@ mapc_add_kv(mnt_map *m, char *key, char *val)
dlog("add_kv: %s -> %s", key, val);
+ if (val != NULL && strchr(val, '\n') != NULL) {
+ /*
+ * If the entry value contains multiple lines we need to break
+ * them up and add them recursively. This is a workaround to
+ * support Sun style multi-mounts. Amd converts Sun style
+ * mulit-mounts to type:=auto. The problem is that Sun packs all
+ * the entries on one line. When Amd does the conversion it puts
+ * each type:=auto entry on the same line separated by '\n'.
+ */
+ char *entry, *tok;
+
+ /*
+ * The first line should contain the first entry. The key for
+ * this entry is the key passed into this function.
+ */
+ if ((tok = strtok(val, "\n")) != NULL) {
+ mapc_add_kv(m, key, xstrdup(tok));
+ }
+
+ /*
+ * For the rest of the entries we need to tokenize them by '\n'
+ * and separate the keys from there entries.
+ */
+ while ((tok = strtok(NULL, "\n")) != NULL) {
+ key = tok;
+ /* find the entry */
+ for (entry = key; *entry && !isspace((unsigned char)*entry); entry++);
+ if (*entry) {
+ *entry++ = '\0';
+ }
+
+ mapc_add_kv(m, xstrdup(key), xstrdup(entry));
+ }
+
+ XFREE(val);
+ return;
+ }
+
#ifdef HAVE_REGEXEC
if (MAPC_ISRE(m)) {
char pattern[MAXPATHLEN];
@@ -431,7 +484,8 @@ mapc_add_kv(mnt_map *m, char *key, char *val)
plog(XLOG_USER, "error compiling RE \"%s\": %s", pattern, errstr);
return;
}
- }
+ } else
+ memset(&re, 0, sizeof(re));
#endif /* HAVE_REGEXEC */
h = &m->kvhash[hash];
@@ -443,6 +497,7 @@ mapc_add_kv(mnt_map *m, char *key, char *val)
n->val = val;
n->next = *h;
*h = n;
+ m->nentries++;
}
@@ -506,7 +561,7 @@ mapc_find_wildcard(mnt_map *m)
int rc = search_map(m, wildcard, &m->wildcard);
if (rc != 0)
- m->wildcard = 0;
+ m->wildcard = NULL;
}
@@ -520,7 +575,7 @@ static int
mapc_reload_map(mnt_map *m)
{
int error, ret = 0;
- kv *maphash[NKVHASH], *tmphash[NKVHASH];
+ kv *maphash[NKVHASH];
time_t t;
error = (*m->mtime) (m, m->map_name, &t);
@@ -546,6 +601,7 @@ mapc_reload_map(mnt_map *m)
memset((voidp) m->kvhash, 0, sizeof(m->kvhash));
dlog("calling map reload on %s", m->map_name);
+ m->nentries = 0;
error = (*m->reload) (m, m->map_name, mapc_add_kv);
if (error) {
if (m->reloads == 0)
@@ -561,19 +617,19 @@ mapc_reload_map(mnt_map *m)
else
plog(XLOG_INFO, "reload #%d of map %s succeeded",
m->reloads, m->map_name);
- memcpy((voidp) tmphash, (voidp) m->kvhash, sizeof(m->kvhash));
- memcpy((voidp) m->kvhash, (voidp) maphash, sizeof(m->kvhash));
- mapc_clear(m);
- memcpy((voidp) m->kvhash, (voidp) tmphash, sizeof(m->kvhash));
+ mapc_clear_kvhash(maphash);
+ if (m->wildcard) {
+ XFREE(m->wildcard);
+ m->wildcard = NULL;
+ }
m->modify = t;
ret = 1;
}
- m->wildcard = 0;
dlog("calling mapc_search for wildcard");
error = mapc_search(m, wildcard, &m->wildcard);
if (error)
- m->wildcard = 0;
+ m->wildcard = NULL;
return ret;
}
@@ -582,12 +638,12 @@ mapc_reload_map(mnt_map *m)
* Create a new map
*/
static mnt_map *
-mapc_create(char *map, char *opt, const char *type)
+mapc_create(char *map, char *opt, const char *type, const char *mntpt)
{
mnt_map *m = ALLOC(struct mnt_map);
map_type *mt;
time_t modify = 0;
- int alloc = 0;
+ u_int alloc = 0;
cmdoption(opt, mapc_opt, &alloc);
@@ -632,6 +688,7 @@ mapc_create(char *map, char *opt, const char *type)
/* assert: mt in maptypes */
m->flags = alloc & ~MAPC_CACHE_MASK;
+ m->nentries = 0;
alloc &= MAPC_CACHE_MASK;
if (alloc == MAPC_DFLT)
@@ -678,12 +735,12 @@ mapc_create(char *map, char *opt, const char *type)
m->search = alloc >= MAPC_ALL ? error_search : mt->search;
m->mtime = mt->mtime;
memset((voidp) m->kvhash, 0, sizeof(m->kvhash));
- m->map_name = strdup(map);
+ m->map_name = xstrdup(map);
m->refc = 1;
- m->wildcard = 0;
+ m->wildcard = NULL;
m->reloads = 0;
- /* Unfortunately with current code structure, this cannot be initialized here */
- m->cfm = NULL;
+ /* initialize per-map information (flags, etc.) */
+ m->cfm = find_cf_map(mntpt);
/*
* synchronize cache with reality
@@ -695,10 +752,10 @@ mapc_create(char *map, char *opt, const char *type)
/*
- * Free the cached data in a map
+ * Free the cached data in a map hash
*/
static void
-mapc_clear(mnt_map *m)
+mapc_clear_kvhash(kv **kvhash)
{
int i;
@@ -707,16 +764,25 @@ mapc_clear(mnt_map *m)
* along free'ing the data.
*/
for (i = 0; i < NKVHASH; i++) {
- kv *k = m->kvhash[i];
+ kv *k = kvhash[i];
while (k) {
kv *n = k->next;
XFREE(k->key);
- if (k->val)
- XFREE(k->val);
+ XFREE(k->val);
XFREE(k);
k = n;
}
}
+}
+
+
+/*
+ * Free the cached data in a map
+ */
+static void
+mapc_clear(mnt_map *m)
+{
+ mapc_clear_kvhash(m->kvhash);
/*
* Zero the hash slots
@@ -726,10 +792,10 @@ mapc_clear(mnt_map *m)
/*
* Free the wildcard if it exists
*/
- if (m->wildcard) {
- XFREE(m->wildcard);
- m->wildcard = 0;
- }
+ XFREE(m->wildcard);
+ m->wildcard = NULL;
+
+ m->nentries = 0;
}
@@ -737,7 +803,7 @@ mapc_clear(mnt_map *m)
* Find a map, or create one if it does not exist
*/
mnt_map *
-mapc_find(char *map, char *opt, const char *maptype)
+mapc_find(char *map, char *opt, const char *maptype, const char *mntpt)
{
mnt_map *m;
@@ -751,7 +817,7 @@ mapc_find(char *map, char *opt, const char *maptype)
ITER(m, mnt_map, &map_list_head)
if (STREQ(m->map_name, map))
return mapc_dup(m);
- m = mapc_create(map, opt, maptype);
+ m = mapc_create(map, opt, maptype, mntpt);
ins_que(&m->hdr, &map_list_head);
return m;
@@ -788,7 +854,7 @@ static int
mapc_meta_search(mnt_map *m, char *key, char **pval, int recurse)
{
int error = 0;
- kv *k = 0;
+ kv *k = NULL;
/*
* Firewall
@@ -839,7 +905,7 @@ mapc_meta_search(mnt_map *m, char *key, char **pval, int recurse)
int retval;
/* XXX: this code was recently ported, and must be tested -Erez */
- retval = regexec(&k->re, key, 0, 0, 0);
+ retval = regexec(&k->re, key, 0, NULL, 0);
if (retval == 0) { /* succeeded */
break;
} else { /* failed to match, log error */
@@ -863,7 +929,7 @@ mapc_meta_search(mnt_map *m, char *key, char **pval, int recurse)
*/
if (k) {
if (k->val)
- *pval = strdup(k->val);
+ *pval = xstrdup(k->val);
else
error = ENOENT;
} else if (m->alloc >= MAPC_ALL) {
@@ -880,7 +946,7 @@ mapc_meta_search(mnt_map *m, char *key, char **pval, int recurse)
*/
error = search_map(m, key, pval);
if (!error && m->alloc == MAPC_INC)
- mapc_add_kv(m, strdup(key), strdup(*pval));
+ mapc_add_kv(m, xstrdup(key), xstrdup(*pval));
}
/*
@@ -911,11 +977,11 @@ mapc_meta_search(mnt_map *m, char *key, char **pval, int recurse)
dlog("mapc recurses on %s", wildname);
error = mapc_meta_search(m, wildname, pval, MREC_PART);
if (error)
- *subp = 0;
+ *subp = '\0';
}
if (error > 0 && m->wildcard) {
- *pval = strdup(m->wildcard);
+ *pval = xstrdup(m->wildcard);
error = 0;
}
}
@@ -1031,7 +1097,7 @@ root_newmap(const char *dir, const char *opts, const char *map, const cf_map_t *
* First make sure we have a root map to talk about...
*/
if (!root_map)
- root_map = mapc_find(ROOT_MAP, "mapdefault", NULL);
+ root_map = mapc_find(ROOT_MAP, "mapdefault", NULL, NULL);
/*
* Then add the entry...
@@ -1071,7 +1137,7 @@ root_newmap(const char *dir, const char *opts, const char *map, const cf_map_t *
else
xstrlcpy(str, opts, sizeof(str));
}
- mapc_repl_kv(root_map, strdup((char *)dir), strdup(str));
+ mapc_repl_kv(root_map, xstrdup(dir), xstrdup(str));
}
diff --git a/contrib/amd/amd/mntfs.c b/contrib/amd/amd/mntfs.c
index 6021838425c0..a26ff8f553f6 100644
--- a/contrib/amd/amd/mntfs.c
+++ b/contrib/amd/amd/mntfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -52,6 +48,16 @@ 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)
{
@@ -71,24 +77,27 @@ init_mntfs(mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *auto
{
mf->mf_ops = ops;
mf->mf_fsflags = ops->nfs_fs_flags;
- mf->mf_fo = mo;
- mf->mf_mount = strdup(mp);
- mf->mf_info = strdup(info);
- mf->mf_auto = strdup(auto_opts);
- mf->mf_mopts = strdup(mopts);
- mf->mf_remopts = strdup(remopts);
+ mf->mf_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 = 0;
- mf->mf_prfree = 0;
+ mf->mf_private = NULL;
+ mf->mf_prfree = NULL;
if (ops->ffserver)
mf->mf_server = (*ops->ffserver) (mf);
else
- mf->mf_server = 0;
+ mf->mf_server = NULL;
}
@@ -138,7 +147,7 @@ locate_mntfs(am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, ch
}
dlog("mf->mf_flags = %#x", mf->mf_flags);
- mf->mf_fo = mo;
+
if ((mf->mf_flags & MFF_RESTART) && amd_state < Finishing) {
/*
* Restart a previously mounted filesystem.
@@ -171,7 +180,7 @@ locate_mntfs(am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, ch
if (mf->mf_private && mf->mf_prfree) {
mf->mf_prfree(mf->mf_private);
- mf->mf_private = 0;
+ mf->mf_private = NULL;
}
fs = ops->ffserver ? (*ops->ffserver) (mf) : (fserver *) NULL;
@@ -202,26 +211,35 @@ find_mntfs(am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char
mntfs *
new_mntfs(void)
{
- return alloc_mntfs(&amfs_error_ops, (am_opts *) 0, "//nil//", ".", "", "", "");
+ 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_auto)
- XFREE(mf->mf_auto);
- if (mf->mf_mopts)
- XFREE(mf->mf_mopts);
- if (mf->mf_remopts)
- XFREE(mf->mf_remopts);
- if (mf->mf_info)
- XFREE(mf->mf_info);
+ if (mf->mf_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);
- if (mf->mf_mount)
- XFREE(mf->mf_mount);
+ XFREE(mf->mf_mount);
/*
* Clean up the file server
@@ -255,6 +273,16 @@ discard_mntfs(voidp v)
--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)
@@ -270,6 +298,23 @@ flush_mntfs(void)
}
}
+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)
@@ -356,7 +401,6 @@ realloc_mntfs(mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *a
if (mf->mf_ops != &amfs_error_ops &&
(mf->mf_flags & MFF_MOUNTED) &&
!FSRV_ISDOWN(mf->mf_server)) {
- mf->mf_fo = mo;
return mf;
}
diff --git a/contrib/amd/amd/nfs_prot_svc.c b/contrib/amd/amd/nfs_prot_svc.c
index 0dd6992cf9e7..cbde17274aea 100644
--- a/contrib/amd/amd/nfs_prot_svc.c
+++ b/contrib/amd/amd/nfs_prot_svc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -69,6 +65,7 @@ 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 *);
@@ -299,3 +296,193 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
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;
+}
diff --git a/contrib/amd/amd/nfs_start.c b/contrib/amd/amd/nfs_start.c
index f6aba94e2b6d..b6c544ddf178 100644
--- a/contrib/amd/amd/nfs_start.c
+++ b/contrib/amd/amd/nfs_start.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -65,12 +61,11 @@ u_short nfs_port = 0;
static void
checkup(void)
{
-
static int max_fd = 0;
- static char *max_mem = 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) {
@@ -135,8 +130,8 @@ do_select(int smask, int fds, fd_set *fdp, struct timeval *tvp)
/*
* Wait for input
*/
- nsel = select(fds, fdp, (fd_set *) 0, (fd_set *) 0,
- tvp->tv_sec ? tvp : (struct timeval *) 0);
+ nsel = select(fds, fdp, (fd_set *) NULL, (fd_set *) NULL,
+ tvp->tv_sec ? tvp : (struct timeval *) NULL);
}
#ifdef HAVE_SIGACTION
@@ -171,7 +166,7 @@ rpc_pending_now(void)
FD_SET(fwd_sock, &readfds);
tvv.tv_sec = tvv.tv_usec = 0;
- nsel = select(FD_SETSIZE, &readfds, (fd_set *) 0, (fd_set *) 0, &tvv);
+ nsel = select(FD_SETSIZE, &readfds, (fd_set *) NULL, (fd_set *) NULL, &tvv);
if (nsel < 1)
return (0);
if (FD_ISSET(fwd_sock, &readfds))
@@ -365,15 +360,16 @@ mount_automounter(int ppid)
* already created the service during restart_automounter_nodes().
*/
if (nfs_port == 0) {
- ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
+ 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 amq, don't even create listening socket */
- if (!amuDebug(D_AMQ)) {
+ /* 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,
@@ -416,25 +412,33 @@ mount_automounter(int ppid)
return 0;
}
- if (!amuDebug(D_AMQ)) {
+ if (amuDebug(D_AMQ)) {
/*
* Complete registration of amq (first TCP service then UDP)
*/
- unregister_amq();
-
- ret = amu_svc_register(tcp_amqp, get_amd_program_number(), AMQ_VERSION,
- amq_program_1, IPPROTO_TCP, tcp_amqncp);
- if (ret != 1) {
- plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM=%d, AMQ_VERSION, tcp)", get_amd_program_number());
+ 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;
}
-
- ret = amu_svc_register(udp_amqp, get_amd_program_number(), AMQ_VERSION,
- amq_program_1, IPPROTO_UDP, udp_amqncp);
- if (ret != 1) {
- plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM=%d, AMQ_VERSION, udp)", get_amd_program_number());
- return 4;
- }
}
/*
diff --git a/contrib/amd/amd/nfs_subr.c b/contrib/amd/amd/nfs_subr.c
index 80d3ca8e311c..734c69827a35 100644
--- a/contrib/amd/amd/nfs_subr.c
+++ b/contrib/amd/amd/nfs_subr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -78,6 +74,17 @@ struct am_fh {
} u;
};
+struct am_fh3 {
+ u_int fhh_gen; /* generation number */
+ union {
+ struct {
+ int fhh_type; /* old or new am_fh */
+ pid_t fhh_pid; /* process id */
+ int fhh_id; /* map id */
+ } s;
+ char fhh_path[AM_FHSIZE3-sizeof(u_int)]; /* path to am_node */
+ } u;
+};
/* forward declarations */
/* converting am-filehandles to mount-points */
@@ -96,10 +103,10 @@ do_readlink(am_node *mp, int *error_return)
* otherwise if a link exists use that,
* otherwise use the mount point.
*/
- if (mp->am_mnt->mf_ops->readlink) {
+ if (mp->am_al->al_mnt->mf_ops->readlink) {
int retry = 0;
- mp = (*mp->am_mnt->mf_ops->readlink) (mp, &retry);
- if (mp == 0) {
+ mp = (*mp->am_al->al_mnt->mf_ops->readlink) (mp, &retry);
+ if (mp == NULL) {
*error_return = retry;
return 0;
}
@@ -109,7 +116,7 @@ do_readlink(am_node *mp, int *error_return)
if (mp->am_link) {
ln = mp->am_link;
} else {
- ln = mp->am_mnt->mf_mount;
+ ln = mp->am_al->al_mnt->mf_mount;
}
return ln;
@@ -130,14 +137,14 @@ nfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
{
static nfsattrstat res;
am_node *mp;
- int retry;
+ int retry = 0;
time_t now = clocktime(NULL);
if (amuDebug(D_TRACE))
plog(XLOG_DEBUG, "getattr:");
mp = fh_to_mp3(argp, &retry, VLOOK_CREATE);
- if (mp == 0) {
+ if (mp == NULL) {
if (amuDebug(D_TRACE))
plog(XLOG_DEBUG, "\tretry=%d", retry);
@@ -209,7 +216,7 @@ nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
xsnprintf(opt_gid, sizeof(gid_str), "%d", (int) gid);
mp = fh_to_mp3(&argp->da_fhandle, &retry, VLOOK_CREATE);
- if (mp == 0) {
+ if (mp == NULL) {
if (retry < 0) {
amd_stats.d_drops++;
return 0;
@@ -220,9 +227,9 @@ nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
am_node *ap;
if (amuDebug(D_TRACE))
plog(XLOG_DEBUG, "\tlookup(%s, %s)", mp->am_path, argp->da_name);
- ap = mp->am_mnt->mf_ops->lookup_child(mp, argp->da_name, &error, VLOOK_CREATE);
+ ap = mp->am_al->al_mnt->mf_ops->lookup_child(mp, argp->da_name, &error, VLOOK_CREATE);
if (ap && error < 0)
- ap = mp->am_mnt->mf_ops->mount_child(ap, &error);
+ ap = mp->am_al->al_mnt->mf_ops->mount_child(ap, &error);
if (ap == 0) {
if (error < 0) {
amd_stats.d_drops++;
@@ -285,7 +292,7 @@ nfs_quick_reply(am_node *mp, int error)
* Free up transp. It's only used for one reply.
*/
XFREE(mp->am_transp);
- dlog("Quick reply sent for %s", mp->am_mnt->mf_mount);
+ dlog("Quick reply sent for %s", mp->am_al->al_mnt->mf_mount);
}
}
@@ -301,7 +308,7 @@ nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
plog(XLOG_DEBUG, "readlink:");
mp = fh_to_mp3(argp, &retry, VLOOK_CREATE);
- if (mp == 0) {
+ if (mp == NULL) {
readlink_retry:
if (retry < 0) {
amd_stats.d_drops++;
@@ -379,7 +386,7 @@ unlink_or_rmdir(nfsdiropargs *argp, struct svc_req *rqstp, int unlinkp)
int retry;
am_node *mp = fh_to_mp3(&argp->da_fhandle, &retry, VLOOK_DELETE);
- if (mp == 0) {
+ if (mp == NULL) {
if (retry < 0) {
amd_stats.d_drops++;
return 0;
@@ -396,8 +403,8 @@ unlink_or_rmdir(nfsdiropargs *argp, struct svc_req *rqstp, int unlinkp)
if (amuDebug(D_TRACE))
plog(XLOG_DEBUG, "\tremove(%s, %s)", mp->am_path, argp->da_name);
- mp = mp->am_mnt->mf_ops->lookup_child(mp, argp->da_name, &retry, VLOOK_DELETE);
- if (mp == 0) {
+ mp = mp->am_al->al_mnt->mf_ops->lookup_child(mp, argp->da_name, &retry, VLOOK_DELETE);
+ if (mp == NULL) {
/*
* Ignore retries...
*/
@@ -510,7 +517,7 @@ nfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp)
plog(XLOG_DEBUG, "readdir:");
mp = fh_to_mp3(&argp->rda_fhandle, &retry, VLOOK_CREATE);
- if (mp == 0) {
+ if (mp == NULL) {
if (retry < 0) {
amd_stats.d_drops++;
return 0;
@@ -519,7 +526,7 @@ nfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp)
} else {
if (amuDebug(D_TRACE))
plog(XLOG_DEBUG, "\treaddir(%s)", mp->am_path);
- res.rdr_status = nfs_error((*mp->am_mnt->mf_ops->readdir)
+ res.rdr_status = nfs_error((*mp->am_al->al_mnt->mf_ops->readdir)
(mp, argp->rda_cookie,
&res.rdr_u.rdr_reply_u, e_res, argp->rda_count));
mp->am_stats.s_readdir++;
@@ -541,7 +548,7 @@ nfsproc_statfs_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
plog(XLOG_DEBUG, "statfs:");
mp = fh_to_mp3(argp, &retry, VLOOK_CREATE);
- if (mp == 0) {
+ if (mp == NULL) {
if (retry < 0) {
amd_stats.d_drops++;
return 0;
@@ -562,8 +569,8 @@ nfsproc_statfs_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
/* check if map is browsable and show_statfs_entries=yes */
if ((gopt.flags & CFM_SHOW_STATFS_ENTRIES) &&
- mp->am_mnt && mp->am_mnt->mf_mopts) {
- mnt.mnt_opts = mp->am_mnt->mf_mopts;
+ mp->am_al->al_mnt && mp->am_al->al_mnt->mf_mopts) {
+ mnt.mnt_opts = mp->am_al->al_mnt->mf_mopts;
if (amu_hasmntopt(&mnt, "browsable")) {
count_map_entries(mp,
&fp->sfrok_blocks,
@@ -599,7 +606,7 @@ count_map_entries(const am_node *mp, u_int *out_blocks, u_int *out_bfree, u_int
blocks = bfree = bavail = 0;
if (!mp)
goto out;
- mf = mp->am_mnt;
+ mf = mp->am_al->al_mnt;
if (!mf)
goto out;
mmp = (mnt_map *) mf->mf_private;
@@ -625,58 +632,18 @@ out:
*out_bavail = bavail;
}
-
-/*
- * Convert from file handle to automount node.
- */
static am_node *
-fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop)
+validate_ap(am_node *node, int *rp, u_int fhh_gen)
{
- struct am_fh *fp = (struct am_fh *) fhp;
- am_node *ap = 0;
-
- if (fp->u.s.fhh_type != 0) {
- /* New filehandle type */
- int len = sizeof(*fhp) - sizeof(fp->fhh_gen);
- char *path = xmalloc(len+1);
- /*
- * Because fhp is treated as a filehandle we use memcpy
- * instead of xstrlcpy.
- */
- memcpy(path, (char *) fp->u.fhh_path, len);
- path[len] = '\0';
- /* dlog("fh_to_mp3: new filehandle: %s", path); */
-
- ap = path_to_exported_ap(path);
- XFREE(path);
- } else {
- /* dlog("fh_to_mp3: old filehandle: %d", fp->u.s.fhh_id); */
- /*
- * Check process id matches
- * If it doesn't then it is probably
- * from an old kernel-cached filehandle
- * which is now out of date.
- */
- if (fp->u.s.fhh_pid != get_server_pid()) {
- dlog("fh_to_mp3: wrong pid %ld != my pid %ld",
- (long) fp->u.s.fhh_pid, get_server_pid());
- goto drop;
- }
-
- /*
- * Get hold of the supposed mount node
- */
- ap = get_exported_ap(fp->u.s.fhh_id);
- }
-
+ am_node *ap = node;
/*
* Check the generation number in the node
* matches the one from the kernel. If not
* then the old node has been timed out and
* a new one allocated.
*/
- if (ap != NULL && ap->am_gen != fp->fhh_gen)
- ap = 0;
+ if (node != NULL && node->am_gen != fhh_gen)
+ ap = NULL;
/*
* If it doesn't exists then drop the request
@@ -690,12 +657,12 @@ fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop)
* for it. This implements the replicated filesystem
* retries.
*/
- if (ap->am_mnt && FSRV_ISDOWN(ap->am_mnt->mf_server) && ap->am_parent) {
+ if (ap->am_al->al_mnt && FSRV_ISDOWN(ap->am_al->al_mnt->mf_server) && ap->am_parent) {
int error;
am_node *orig_ap = ap;
- dlog("fh_to_mp3: %s (%s) is hung: lookup alternative file server",
- orig_ap->am_path, orig_ap->am_mnt->mf_info);
+ dlog("%s: %s (%s) is hung: lookup alternative file server", __func__,
+ orig_ap->am_path, orig_ap->am_al->al_mnt->mf_info);
/*
* Update modify time of parent node.
@@ -712,11 +679,11 @@ fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop)
* to the caller.
*/
if (vop == VLOOK_CREATE) {
- ap = orig_ap->am_parent->am_mnt->mf_ops->lookup_child(orig_ap->am_parent, orig_ap->am_name, &error, vop);
+ ap = orig_ap->am_parent->am_al->al_mnt->mf_ops->lookup_child(orig_ap->am_parent, orig_ap->am_name, &error, vop);
if (ap && error < 0)
- ap = orig_ap->am_parent->am_mnt->mf_ops->mount_child(ap, &error);
+ ap = orig_ap->am_parent->am_al->al_mnt->mf_ops->mount_child(ap, &error);
} else {
- ap = 0;
+ ap = NULL;
error = ESTALE;
}
if (ap == 0) {
@@ -735,13 +702,13 @@ fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop)
new_ttl(orig_ap);
}
-#endif
+#endif /* 0 */
/*
* Disallow references to objects being unmounted, unless
* they are automount points.
*/
- if (ap->am_mnt && (ap->am_mnt->mf_flags & MFF_UNMOUNTING) &&
+ if (ap->am_al->al_mnt && (ap->am_al->al_mnt->mf_flags & MFF_UNMOUNTING) &&
!(ap->am_flags & AMF_ROOT)) {
if (amd_state == Finishing)
*rp = ENOENT;
@@ -752,7 +719,7 @@ fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop)
new_ttl(ap);
drop:
- if (!ap || !ap->am_mnt) {
+ if (!ap || !ap->am_al->al_mnt) {
/*
* If we are shutting down then it is likely
* that this node has disappeared because of
@@ -764,14 +731,60 @@ drop:
*/
if (amd_state == Finishing)
*rp = ENOENT;
- else
+ else {
*rp = ESTALE;
- amd_stats.d_stale++;
+ amd_stats.d_stale++;
+ }
}
return ap;
}
+/*
+ * Convert from file handle to automount node.
+ */
+static am_node *
+fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop)
+{
+ struct am_fh *fp = (struct am_fh *) fhp;
+ am_node *ap = NULL;
+
+ if (fp->u.s.fhh_type != 0) {
+ /* New filehandle type */
+ int len = sizeof(*fhp) - sizeof(fp->fhh_gen);
+ char *path = xmalloc(len+1);
+ /*
+ * Because fhp is treated as a filehandle we use memcpy
+ * instead of xstrlcpy.
+ */
+ memcpy(path, (char *) fp->u.fhh_path, len);
+ path[len] = '\0';
+ dlog("%s: new filehandle: %s", __func__, path);
+
+ ap = path_to_exported_ap(path);
+ XFREE(path);
+ } else {
+ dlog("%s: old filehandle: %d", __func__, fp->u.s.fhh_id);
+ /*
+ * Check process id matches
+ * If it doesn't then it is probably
+ * from an old kernel-cached filehandle
+ * which is now out of date.
+ */
+ if (fp->u.s.fhh_pid != get_server_pid()) {
+ dlog("%s: wrong pid %ld != my pid %ld", __func__,
+ (long) fp->u.s.fhh_pid, get_server_pid());
+ goto done;
+ }
+
+ /*
+ * Get hold of the supposed mount node
+ */
+ ap = get_exported_ap(fp->u.s.fhh_id);
+ }
+done:
+ return validate_ap(ap, rp, fp->fhh_gen);
+}
static am_node *
fh_to_mp(am_nfs_fh *fhp)
@@ -781,6 +794,56 @@ fh_to_mp(am_nfs_fh *fhp)
return fh_to_mp3(fhp, &dummy, VLOOK_CREATE);
}
+static am_node *
+fh3_to_mp3(am_nfs_fh3 *fhp, int *rp, int vop)
+{
+ struct am_fh3 *fp = (struct am_fh3 *) fhp->am_fh3_data;
+ am_node *ap = NULL;
+
+ if (fp->u.s.fhh_type != 0) {
+ /* New filehandle type */
+ int len = sizeof(*fp) - sizeof(fp->fhh_gen);
+ char *path = xmalloc(len+1);
+ /*
+ * Because fhp is treated as a filehandle we use memcpy
+ * instead of xstrlcpy.
+ */
+ memcpy(path, (char *) fp->u.fhh_path, len);
+ path[len] = '\0';
+ dlog("%s: new filehandle: %s", __func__, path);
+
+ ap = path_to_exported_ap(path);
+ XFREE(path);
+ } else {
+ dlog("%s: old filehandle: %d", __func__, fp->u.s.fhh_id);
+ /*
+ * Check process id matches
+ * If it doesn't then it is probably
+ * from an old kernel-cached filehandle
+ * which is now out of date.
+ */
+ if (fp->u.s.fhh_pid != get_server_pid()) {
+ dlog("%s: wrong pid %ld != my pid %ld", __func__,
+ (long) fp->u.s.fhh_pid, get_server_pid());
+ goto done;
+ }
+
+ /*
+ * Get hold of the supposed mount node
+ */
+ ap = get_exported_ap(fp->u.s.fhh_id);
+ }
+done:
+ return validate_ap(ap, rp, fp->fhh_gen);
+}
+
+static am_node *
+fh3_to_mp(am_nfs_fh3 *fhp)
+{
+ int dummy;
+
+ return fh3_to_mp3(fhp, &dummy, VLOOK_CREATE);
+}
/*
* Convert from automount node to file handle.
@@ -826,3 +889,975 @@ mp_to_fh(am_node *mp, am_nfs_fh *fhp)
/* dlog("mp_to_fh: old filehandle: %d", fp->u.s.fhh_id); */
}
}
+void
+mp_to_fh3(am_node *mp, am_nfs_fh3 *fhp)
+{
+ u_int pathlen;
+ struct am_fh3 *fp = (struct am_fh3 *) fhp->am_fh3_data;
+
+ memset((char *) fhp, 0, sizeof(am_nfs_fh3));
+ fhp->am_fh3_length = AM_FHSIZE3;
+
+ /* Store the generation number */
+ fp->fhh_gen = mp->am_gen;
+
+ pathlen = strlen(mp->am_path);
+ if (pathlen <= sizeof(*fp) - sizeof(fp->fhh_gen)) {
+ /* dlog("mp_to_fh: new filehandle: %s", mp->am_path); */
+
+ /*
+ * Because fhp is treated as a filehandle we use memcpy instead of
+ * xstrlcpy.
+ */
+ memcpy(fp->u.fhh_path, mp->am_path, pathlen); /* making a filehandle */
+ } else {
+ /*
+ * Take the process id
+ */
+ fp->u.s.fhh_pid = get_server_pid();
+
+ /*
+ * ... the map number
+ */
+ fp->u.s.fhh_id = mp->am_mapno;
+
+ /*
+ * ... and the generation number (previously stored)
+ * to make a "unique" triple that will never
+ * be reallocated except across reboots (which doesn't matter)
+ * or if we are unlucky enough to be given the same
+ * pid as a previous amd (very unlikely).
+ */
+ /* dlog("mp_to_fh: old filehandle: %d", fp->u.s.fhh_id); */
+ }
+}
+
+#ifdef HAVE_FS_NFS3
+static am_ftype3 ftype_to_ftype3(nfsftype ftype)
+{
+ if (ftype == NFFIFO)
+ return AM_NF3FIFO;
+ else
+ return ftype;
+}
+
+static void nfstime_to_am_nfstime3(nfstime *time, am_nfstime3 *time3)
+{
+ time3->seconds = time->seconds;
+ time3->nseconds = time->useconds * 1000;
+}
+
+static void rdev_to_am_specdata3(u_int rdev, am_specdata3 *rdev3)
+{
+ /* No device node here */
+ rdev3->specdata1 = (u_int) -1;
+ rdev3->specdata2 = (u_int) -1;
+}
+
+static void fattr_to_fattr3(nfsfattr *fattr, am_fattr3 *fattr3)
+{
+ fattr3->type = ftype_to_ftype3(fattr->na_type);
+ fattr3->mode = (am_mode3) fattr->na_mode;
+ fattr3->nlink = fattr->na_nlink;
+ fattr3->uid = (am_uid3) fattr->na_uid;
+ fattr3->gid = (am_uid3) fattr->na_gid;
+ fattr3->size = (am_size3) fattr->na_size;
+ fattr3->used = (am_size3) fattr->na_size;
+ rdev_to_am_specdata3(fattr->na_rdev, &fattr3->rdev);
+ fattr3->fsid = (uint64) fattr->na_fsid;
+ fattr3->fileid = (uint64) fattr->na_fileid;
+ nfstime_to_am_nfstime3(&fattr->na_atime, &fattr3->atime);
+ nfstime_to_am_nfstime3(&fattr->na_mtime, &fattr3->mtime);
+ nfstime_to_am_nfstime3(&fattr->na_ctime, &fattr3->ctime);
+}
+
+static void fattr_to_wcc_attr(nfsfattr *fattr, am_wcc_attr *wcc_attr)
+{
+ wcc_attr->size = (am_size3) fattr->na_size;
+ nfstime_to_am_nfstime3(&fattr->na_mtime, &wcc_attr->mtime);
+ nfstime_to_am_nfstime3(&fattr->na_ctime, &wcc_attr->ctime);
+}
+
+static am_nfsstat3 return_estale_or_rofs(am_nfs_fh3 *fh,
+ am_pre_op_attr *pre_op,
+ am_post_op_attr *post_op)
+{
+ am_node *mp;
+
+ mp = fh3_to_mp(fh);
+ if (!mp) {
+ pre_op->attributes_follow = 0;
+ post_op->attributes_follow = 0;
+ return nfs_error(ESTALE);
+ } else {
+ am_fattr3 *fattr3 = &post_op->am_post_op_attr_u.attributes;
+ am_wcc_attr *wcc_attr = &pre_op->am_pre_op_attr_u.attributes;
+ nfsfattr *fattr = &mp->am_fattr;
+ pre_op->attributes_follow = 1;
+ fattr_to_wcc_attr(fattr, wcc_attr);
+ post_op->attributes_follow = 1;
+ fattr_to_fattr3(fattr, fattr3);
+ return nfs_error(EROFS);
+ }
+}
+
+static am_nfsstat3 unlink3_or_rmdir3(am_diropargs3 *argp,
+ am_wcc_data *wcc_data, int unlinkp)
+{
+ static am_nfsstat3 res;
+ am_nfs_fh3 *dir = &argp->dir;
+ am_filename3 name = argp->name;
+ am_pre_op_attr *pre_op_dir = &wcc_data->before;
+ am_post_op_attr *post_op_dir = &wcc_data->after;
+ nfsfattr *fattr;
+ am_wcc_attr *wcc_attr;
+ am_node *mp, *ap;
+ int retry;
+
+ post_op_dir->attributes_follow = 0;
+
+ mp = fh3_to_mp3(dir, &retry, VLOOK_DELETE);
+ if (!mp) {
+ pre_op_dir->attributes_follow = 0;
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ res = nfs_error(retry);
+ goto out;
+ }
+
+ pre_op_dir->attributes_follow = 1;
+ fattr = &mp->am_fattr;
+ wcc_attr = &pre_op_dir->am_pre_op_attr_u.attributes;
+ fattr_to_wcc_attr(fattr, wcc_attr);
+
+ if (mp->am_fattr.na_type != NFDIR) {
+ res = nfs_error(ENOTDIR);
+ goto out;
+ }
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tremove(%s, %s)", mp->am_path, name);
+
+ ap = mp->am_al->al_mnt->mf_ops->lookup_child(mp, name, &retry, VLOOK_DELETE);
+ if (!ap) {
+ /*
+ * Ignore retries...
+ */
+ if (retry < 0)
+ retry = 0;
+ /*
+ * Usual NFS workaround...
+ */
+ else if (retry == ENOENT)
+ retry = 0;
+ res = nfs_error(retry);
+ } else {
+ forcibly_timeout_mp(mp);
+ res = AM_NFS3_OK;
+ }
+
+out:
+ return res;
+}
+
+voidp
+am_nfs3_null_3_svc(voidp argp, struct svc_req *rqstp)
+{
+ static char * result;
+
+ return (voidp) &result;
+}
+
+am_GETATTR3res *
+am_nfs3_getattr_3_svc(am_GETATTR3args *argp, struct svc_req *rqstp)
+{
+ static am_GETATTR3res result;
+ am_nfs_fh3 *fh = (am_nfs_fh3 *) &argp->object;
+ am_fattr3 *fattr3;
+ nfsfattr *fattr;
+ am_node *mp;
+ int retry = 0;
+ time_t now = clocktime(NULL);
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "getattr_3:");
+
+ mp = fh3_to_mp3(fh, &retry, VLOOK_CREATE);
+ if (!mp) {
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tretry=%d", retry);
+
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ result.status = nfs_error(retry);
+ return &result;
+ }
+
+ fattr = &mp->am_fattr;
+ fattr3 = (am_fattr3 *) &result.res_u.ok.obj_attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ result.status = AM_NFS3_OK;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tstat(%s), size = %lu, mtime=%d.%d",
+ mp->am_path,
+ (u_long) fattr3->size,
+ (u_int) fattr3->mtime.seconds,
+ (u_int) fattr3->mtime.nseconds);
+
+ /* Delay unmount of what was looked up */
+ if (mp->am_timeo_w < 4 * gopt.am_timeo_w)
+ mp->am_timeo_w += gopt.am_timeo_w;
+ mp->am_ttl = now + mp->am_timeo_w;
+
+ mp->am_stats.s_getattr++;
+
+ return &result;
+}
+
+am_SETATTR3res *
+am_nfs3_setattr_3_svc(am_SETATTR3args *argp, struct svc_req *rqstp)
+{
+ static am_SETATTR3res result;
+ am_nfs_fh3 *fh = (am_nfs_fh3 *) &argp->object;
+ am_pre_op_attr *pre_op_obj = &result.res_u.fail.obj_wcc.before;
+ am_post_op_attr *post_op_obj = &result.res_u.fail.obj_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "setattr_3:");
+
+ result.status = return_estale_or_rofs(fh, pre_op_obj, post_op_obj);
+
+ return &result;
+}
+
+am_LOOKUP3res *
+am_nfs3_lookup_3_svc(am_LOOKUP3args *argp, struct svc_req *rqstp)
+{
+ static am_LOOKUP3res result;
+ am_nfs_fh3 *dir = &argp->what.dir;
+ am_post_op_attr *post_op_dir;
+ am_post_op_attr *post_op_obj;
+ am_node *mp;
+ int retry;
+ uid_t uid;
+ gid_t gid;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "lookup_3:");
+
+ /* finally, find the effective uid/gid from RPC request */
+ if (getcreds(rqstp, &uid, &gid, nfsxprt) < 0)
+ plog(XLOG_ERROR, "cannot get uid/gid from RPC credentials");
+ xsnprintf(opt_uid, sizeof(uid_str), "%d", (int) uid);
+ xsnprintf(opt_gid, sizeof(gid_str), "%d", (int) gid);
+
+ mp = fh3_to_mp3(dir, &retry, VLOOK_CREATE);
+ if (!mp) {
+ post_op_dir = &result.res_u.fail.dir_attributes;
+ post_op_dir->attributes_follow = 0;
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ result.status = nfs_error(retry);
+ } else {
+ post_op_dir = &result.res_u.ok.dir_attributes;
+ post_op_obj = &result.res_u.ok.obj_attributes;
+ am_filename3 name;
+ am_fattr3 *fattr3;
+ nfsfattr *fattr;
+ am_node *ap;
+ int error;
+
+ /* dir attributes */
+ post_op_dir->attributes_follow = 1;
+ fattr = &mp->am_fattr;
+ fattr3 = &post_op_dir->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ post_op_obj->attributes_follow = 0;
+
+ name = argp->what.name;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tlookup_3(%s, %s)", mp->am_path, name);
+
+ ap = mp->am_al->al_mnt->mf_ops->lookup_child(mp, name, &error, VLOOK_CREATE);
+ if (ap && error < 0)
+ ap = mp->am_al->al_mnt->mf_ops->mount_child(ap, &error);
+ if (ap == 0) {
+ if (error < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ result.status = nfs_error(error);
+ } else {
+ /*
+ * XXX: EXPERIMENTAL! Delay unmount of what was looked up. This
+ * should reduce the chance for race condition between unmounting an
+ * entry synchronously, and re-mounting it asynchronously.
+ */
+ if (ap->am_ttl < mp->am_ttl)
+ ap->am_ttl = mp->am_ttl;
+
+ mp_to_fh3(ap, &result.res_u.ok.object);
+
+ /* mount attributes */
+ post_op_obj->attributes_follow = 1;
+ fattr = &ap->am_fattr;
+ fattr3 = &post_op_obj->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ result.status = AM_NFS3_OK;
+ }
+ mp->am_stats.s_lookup++;
+ }
+ return &result;
+}
+
+am_ACCESS3res *
+am_nfs3_access_3_svc(am_ACCESS3args *argp, struct svc_req *rqstp)
+{
+ static am_ACCESS3res result;
+
+ am_nfs_fh3 *obj = &argp->object;
+ u_int accessbits = argp->access;
+ u_int accessmask = AM_ACCESS3_LOOKUP|AM_ACCESS3_READ;
+ am_post_op_attr *post_op_obj;
+ am_node *mp;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "access_3:");
+
+ mp = fh3_to_mp(obj);
+ if (!mp) {
+ post_op_obj = &result.res_u.fail.obj_attributes;
+ post_op_obj->attributes_follow = 0;
+ result.status = nfs_error(ENOENT);
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "access_3: ENOENT");
+ } else {
+ nfsfattr *fattr = &mp->am_fattr;
+ am_fattr3 *fattr3;
+ post_op_obj = &result.res_u.ok.obj_attributes;
+ fattr3 = &post_op_obj->am_post_op_attr_u.attributes;
+ post_op_obj->attributes_follow = 1;
+ fattr_to_fattr3(fattr, fattr3);
+
+ result.res_u.ok.access = accessbits & accessmask;
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "access_3: b=%x m=%x", accessbits, accessmask);
+
+ result.status = AM_NFS3_OK;
+ }
+
+ return &result;
+}
+
+am_READLINK3res *
+am_nfs3_readlink_3_svc(am_READLINK3args *argp, struct svc_req *rqstp)
+{
+ static am_READLINK3res result;
+
+ am_nfs_fh3 *symlink = (am_nfs_fh3 *) &argp->symlink;
+ am_post_op_attr *post_op_sym;
+ am_node *mp;
+ int retry = 0;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "readlink_3:");
+
+ mp = fh3_to_mp3(symlink, &retry, VLOOK_CREATE);
+ if (!mp) {
+ readlink_retry:
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ post_op_sym = &result.res_u.fail.symlink_attributes;
+ post_op_sym->attributes_follow = 0;
+ result.status = nfs_error(retry);
+ } else {
+ nfsfattr *fattr;
+ am_fattr3 *fattr3;
+ char *ln;
+
+ ln = do_readlink(mp, &retry);
+ if (!ln)
+ goto readlink_retry;
+
+ if (amuDebug(D_TRACE) && ln)
+ plog(XLOG_DEBUG, "\treadlink_3(%s) = %s", mp->am_path, ln);
+
+ result.res_u.ok.data = ln;
+
+ post_op_sym = &result.res_u.ok.symlink_attributes;
+ post_op_sym->attributes_follow = 1;
+ fattr = &mp->am_fattr;
+ fattr3 = &post_op_sym->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ mp->am_stats.s_readlink++;
+ result.status = AM_NFS3_OK;
+ }
+
+ return &result;
+}
+
+am_READ3res *
+am_nfs3_read_3_svc(am_READ3args *argp, struct svc_req *rqstp)
+{
+ static am_READ3res result;
+
+ am_nfs_fh3 *file = (am_nfs_fh3 *) &argp->file;
+ am_post_op_attr *post_op_file;
+ am_node *mp;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "read_3:");
+
+ post_op_file = &result.res_u.fail.file_attributes;
+ result.status = nfs_error(EACCES);
+
+ mp = fh3_to_mp(file);
+ if (!mp)
+ post_op_file->attributes_follow = 0;
+ else {
+ nfsfattr *fattr = &mp->am_fattr;
+ am_fattr3 *fattr3 = &post_op_file->am_post_op_attr_u.attributes;
+ post_op_file->attributes_follow = 1;
+ fattr_to_fattr3(fattr, fattr3);
+ }
+
+ return &result;
+}
+
+am_WRITE3res *
+am_nfs3_write_3_svc(am_WRITE3args *argp, struct svc_req *rqstp)
+{
+ static am_WRITE3res result;
+
+ am_nfs_fh3 *file = (am_nfs_fh3 *) &argp->file;
+ am_pre_op_attr *pre_op_file = &result.res_u.fail.file_wcc.before;
+ am_post_op_attr *post_op_file = &result.res_u.fail.file_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "write_3:");
+
+ result.status = return_estale_or_rofs(file, pre_op_file, post_op_file);
+
+ return &result;
+}
+
+am_CREATE3res *
+am_nfs3_create_3_svc(am_CREATE3args *argp, struct svc_req *rqstp)
+{
+ static am_CREATE3res result;
+
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->where.dir;
+ am_pre_op_attr *pre_op_dir = &result.res_u.fail.dir_wcc.before;
+ am_post_op_attr *post_op_dir = &result.res_u.fail.dir_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "create_3:");
+
+ result.status = return_estale_or_rofs(dir, pre_op_dir, post_op_dir);
+
+ return &result;
+}
+
+am_MKDIR3res *
+am_nfs3_mkdir_3_svc(am_MKDIR3args *argp, struct svc_req *rqstp)
+{
+ static am_MKDIR3res result;
+
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->where.dir;
+ am_pre_op_attr *pre_op_dir = &result.res_u.fail.dir_wcc.before;
+ am_post_op_attr *post_op_dir = &result.res_u.fail.dir_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "mkdir_3:");
+
+ result.status = return_estale_or_rofs(dir, pre_op_dir, post_op_dir);
+
+ return &result;
+}
+
+am_SYMLINK3res *
+am_nfs3_symlink_3_svc(am_SYMLINK3args *argp, struct svc_req *rqstp)
+{
+ static am_SYMLINK3res result;
+
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->where.dir;
+ am_pre_op_attr *pre_op_dir = &result.res_u.fail.dir_wcc.before;
+ am_post_op_attr *post_op_dir = &result.res_u.fail.dir_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "symlink_3:");
+
+ result.status = return_estale_or_rofs(dir, pre_op_dir, post_op_dir);
+
+ return &result;
+}
+
+am_MKNOD3res *
+am_nfs3_mknod_3_svc(am_MKNOD3args *argp, struct svc_req *rqstp)
+{
+ static am_MKNOD3res result;
+
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->where.dir;
+ am_pre_op_attr *pre_op_dir = &result.res_u.fail.dir_wcc.before;
+ am_post_op_attr *post_op_dir = &result.res_u.fail.dir_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "mknod_3:");
+
+ result.status = return_estale_or_rofs(dir, pre_op_dir, post_op_dir);
+ return &result;
+}
+
+am_REMOVE3res *
+am_nfs3_remove_3_svc(am_REMOVE3args *argp, struct svc_req *rqstp)
+{
+ static am_REMOVE3res result;
+
+ am_diropargs3 *obj = &argp->object;
+ am_wcc_data dir_wcc;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "remove_3:");
+
+ result.status = unlink3_or_rmdir3(obj, &dir_wcc, TRUE);
+
+ result.res_u.ok.dir_wcc = dir_wcc;
+
+ return &result;
+}
+
+am_RMDIR3res *
+am_nfs3_rmdir_3_svc(am_RMDIR3args *argp, struct svc_req *rqstp)
+{
+ static am_RMDIR3res result;
+
+ am_diropargs3 *obj = &argp->object;
+ am_wcc_data dir_wcc;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "rmdir_3:");
+
+ result.status = unlink3_or_rmdir3(obj, &dir_wcc, TRUE);
+
+ result.res_u.ok.dir_wcc = dir_wcc;
+
+ return &result;
+}
+
+am_RENAME3res *
+am_nfs3_rename_3_svc(am_RENAME3args *argp, struct svc_req *rqstp)
+{
+ static am_RENAME3res result;
+
+ am_nfs_fh3 *fromdir = (am_nfs_fh3 *) &argp->from.dir;
+ am_nfs_fh3 *todir = (am_nfs_fh3 *) &argp->to.dir;
+ am_filename3 name = argp->to.name;
+ am_node *to_mp, *from_mp;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "rename_3:");
+
+ if (!(from_mp = fh3_to_mp(fromdir)) || !(to_mp = fh3_to_mp(todir)))
+ result.status = nfs_error(ESTALE);
+ /*
+ * If the kernel is doing clever things with referenced files
+ * then let it pretend...
+ */
+ else {
+ am_wcc_attr *wcc_attr;
+ am_fattr3 *fattr3;
+ am_wcc_data *to_wcc_data, *from_wcc_data;
+ am_pre_op_attr *pre_op_to, *pre_op_from;
+ am_post_op_attr *post_op_to, *post_op_from;
+ nfsfattr *fattr;
+
+ to_wcc_data = &result.res_u.ok.todir_wcc;
+
+ pre_op_to = &to_wcc_data->before;
+ post_op_to = &to_wcc_data->after;
+
+ pre_op_to->attributes_follow = 1;
+ fattr = &to_mp->am_fattr;
+ wcc_attr = &pre_op_to->am_pre_op_attr_u.attributes;
+ fattr_to_wcc_attr(fattr, wcc_attr);
+ post_op_to->attributes_follow = 1;
+ fattr3 = &post_op_to->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ from_wcc_data = &result.res_u.ok.fromdir_wcc;
+
+ pre_op_from = &from_wcc_data->before;
+ post_op_from = &from_wcc_data->after;
+
+ pre_op_from->attributes_follow = 1;
+ fattr = &from_mp->am_fattr;
+ wcc_attr = &pre_op_from->am_pre_op_attr_u.attributes;
+ fattr_to_wcc_attr(fattr, wcc_attr);
+ post_op_from->attributes_follow = 1;
+ fattr3 = &post_op_from->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ if (NSTREQ(name, ".nfs", 4))
+ result.status = AM_NFS3_OK;
+ /*
+ * otherwise a failure
+ */
+ else
+ result.status = nfs_error(EROFS);
+ }
+
+ return &result;
+}
+
+am_LINK3res *
+am_nfs3_link_3_svc(am_LINK3args *argp, struct svc_req *rqstp)
+{
+ static am_LINK3res result;
+
+ am_nfs_fh3 *file = (am_nfs_fh3 *) &argp->file;
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->link.dir;
+ am_post_op_attr *post_op_file;
+ am_pre_op_attr *pre_op_dir;
+ am_post_op_attr *post_op_dir;
+ am_node *mp_file, *mp_dir;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "link_3:");
+
+ post_op_file = &result.res_u.fail.file_attributes;
+ post_op_file->attributes_follow = 0;
+
+ mp_file = fh3_to_mp(file);
+ if (mp_file) {
+ nfsfattr *fattr = &mp_file->am_fattr;
+ am_fattr3 *fattr3 = &post_op_file->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+ }
+
+ pre_op_dir = &result.res_u.fail.linkdir_wcc.before;
+ pre_op_dir->attributes_follow = 0;
+ post_op_dir = &result.res_u.fail.linkdir_wcc.after;
+ post_op_dir->attributes_follow = 0;
+
+ mp_dir = fh3_to_mp(dir);
+ if (mp_dir) {
+ nfsfattr *fattr = &mp_dir->am_fattr;
+ am_fattr3 *fattr3 = &post_op_dir->am_post_op_attr_u.attributes;
+ am_wcc_attr *wcc_attr = &pre_op_dir->am_pre_op_attr_u.attributes;
+
+ pre_op_dir->attributes_follow = 1;
+ fattr_to_wcc_attr(fattr, wcc_attr);
+ post_op_dir->attributes_follow = 1;
+ fattr_to_fattr3(fattr, fattr3);
+ }
+
+ if (!mp_file || !mp_dir)
+ result.status = nfs_error(ESTALE);
+ else
+ result.status = nfs_error(EROFS);
+
+ return &result;
+}
+
+am_READDIR3res *
+am_nfs3_readdir_3_svc(am_READDIR3args *argp, struct svc_req *rqstp)
+{
+ static am_READDIR3res result;
+ static am_entry3 entries[MAX_READDIR_ENTRIES];
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->dir;
+ am_cookie3 cookie = argp->cookie;
+ am_cookieverf3 cookieverf;
+ am_count3 count = argp->count;
+ am_post_op_attr *post_op_dir;
+ am_node *mp;
+ int retry;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "readdir_3:");
+
+ memcpy(&cookieverf, &argp->cookieverf, sizeof(am_cookieverf3));
+
+ mp = fh3_to_mp3(dir, &retry, VLOOK_CREATE);
+ if (mp == NULL) {
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ post_op_dir = &result.res_u.fail.dir_attributes;
+ post_op_dir->attributes_follow = 0;
+ result.status = nfs_error(retry);
+ } else {
+ am_dirlist3 *list = &result.res_u.ok.reply;
+ am_nfsstat3 status;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\treaddir_3(%s)", mp->am_path);
+
+ status = mp->am_al->al_mnt->mf_ops->readdir(mp,
+ (voidp)&cookie, list, entries, count);
+ if (status == 0) {
+ post_op_dir = &result.res_u.ok.dir_attributes;
+ nfsfattr *fattr;
+ am_fattr3 *fattr3;
+
+ fattr = &mp->am_fattr;
+ fattr3 = &post_op_dir->am_post_op_attr_u.attributes;
+ post_op_dir->attributes_follow = 1;
+ fattr_to_fattr3(fattr, fattr3);
+ result.status = AM_NFS3_OK;
+ } else {
+ post_op_dir = &result.res_u.fail.dir_attributes;
+ post_op_dir->attributes_follow = 0;
+ result.status = nfs_error(status);
+ }
+
+ mp->am_stats.s_readdir++;
+ }
+
+ return &result;
+}
+
+am_READDIRPLUS3res *
+am_nfs3_readdirplus_3_svc(am_READDIRPLUS3args *argp, struct svc_req *rqstp)
+{
+ static am_READDIRPLUS3res result;
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->dir;
+ am_post_op_attr *post_op_dir;
+ nfsfattr *fattr;
+ am_fattr3 *fattr3;
+ am_node *mp;
+ int retry;
+
+ mp = fh3_to_mp3(dir, &retry, VLOOK_CREATE);
+ if (mp == NULL) {
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ post_op_dir = &result.res_u.fail.dir_attributes;
+ post_op_dir->attributes_follow = 0;
+ result.status = nfs_error(retry);
+ } else {
+ post_op_dir = &result.res_u.ok.dir_attributes;
+ fattr = &mp->am_fattr;
+ fattr3 = &post_op_dir->am_post_op_attr_u.attributes;
+ post_op_dir->attributes_follow = 1;
+ fattr_to_fattr3(fattr, fattr3);
+ result.status = AM_NFS3ERR_NOTSUPP;
+ }
+
+ return &result;
+}
+
+am_FSSTAT3res *
+am_nfs3_fsstat_3_svc(am_FSSTAT3args *argp, struct svc_req *rqstp)
+{
+ static am_FSSTAT3res result;
+
+ am_nfs_fh3 *fsroot = (am_nfs_fh3 *) &argp->fsroot;
+ am_post_op_attr *post_op_fsroot;
+ am_node *mp;
+ int retry;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "fsstat_3:");
+
+ mp = fh3_to_mp3(fsroot, &retry, VLOOK_CREATE);
+ if (!mp) {
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ post_op_fsroot = &result.res_u.fail.obj_attributes;
+ post_op_fsroot->attributes_follow = 0;
+ result.status = nfs_error(retry);
+ } else {
+ am_FSSTAT3resok *ok = &result.res_u.ok;
+ u_int blocks, bfree, bavail;
+ nfsfattr *fattr;
+ am_fattr3 *fattr3;
+ mntent_t mnt;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tfsstat_3(%s)", mp->am_path);
+
+ fattr = &mp->am_fattr;
+ post_op_fsroot = &ok->obj_attributes;
+ post_op_fsroot->attributes_follow = 1;
+ fattr3 = &post_op_fsroot->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ /*
+ * just return faked up file system information
+ */
+ ok->tbytes = 1024;
+ ok->invarsec = 0;
+
+ /* check if map is browsable and show_statfs_entries=yes */
+ if ((gopt.flags & CFM_SHOW_STATFS_ENTRIES) &&
+ mp->am_al->al_mnt && mp->am_al->al_mnt->mf_mopts) {
+ mnt.mnt_opts = mp->am_al->al_mnt->mf_mopts;
+ if (amu_hasmntopt(&mnt, "browsable")) {
+ count_map_entries(mp, &blocks, &bfree, &bavail);
+ }
+ ok->fbytes = bfree;
+ ok->abytes = bavail;
+ ok->ffiles = bfree;
+ ok->afiles = bavail;
+ ok->tfiles = blocks;
+ } else {
+ ok->fbytes = 0;
+ ok->abytes = 0;
+ ok->ffiles = 0;
+ ok->afiles = 0;
+ ok->tfiles = 0; /* set to 1 if you don't want empty automounts */
+ }
+
+ result.status = AM_NFS3_OK;
+ mp->am_stats.s_statfs++;
+ }
+
+ return &result;
+}
+
+#define FSF3_HOMOGENEOUS 0x0008
+
+am_FSINFO3res *
+am_nfs3_fsinfo_3_svc(am_FSINFO3args *argp, struct svc_req *rqstp)
+{
+ static am_FSINFO3res result;
+
+ am_nfs_fh3 *fsroot = (am_nfs_fh3 *) &argp->fsroot;
+ am_post_op_attr *post_op_fsroot;
+ am_node *mp;
+ int retry;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "fsinfo_3:");
+
+ mp = fh3_to_mp3(fsroot, &retry, VLOOK_CREATE);
+ if (!mp) {
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ post_op_fsroot = &result.res_u.fail.obj_attributes;
+ post_op_fsroot->attributes_follow = 0;
+ result.status = nfs_error(retry);
+ } else {
+ am_FSINFO3resok *ok = &result.res_u.ok;
+ nfsfattr *fattr;
+ am_fattr3 *fattr3;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tfsinfo_3(%s)", mp->am_path);
+
+ fattr = &mp->am_fattr;
+ post_op_fsroot = &ok->obj_attributes;
+ post_op_fsroot->attributes_follow = 1;
+ fattr3 = &post_op_fsroot->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ /*
+ * just return faked up file system information
+ */
+ ok->rtmax = 0;
+ ok->rtpref = 0;
+ ok->rtmult = 0;
+ ok->wtmax = 0;
+ ok->wtpref = 0;
+ ok->wtmult = 0;
+ ok->dtpref = 1024;
+ ok->maxfilesize = 0;
+ ok->time_delta.seconds = 1;
+ ok->time_delta.nseconds = 0;
+ ok->properties = FSF3_HOMOGENEOUS;
+
+ result.status = AM_NFS3_OK;
+ mp->am_stats.s_fsinfo++;
+ }
+
+ return &result;
+}
+
+am_PATHCONF3res *
+am_nfs3_pathconf_3_svc(am_PATHCONF3args *argp, struct svc_req *rqstp)
+{
+ static am_PATHCONF3res result;
+
+ am_nfs_fh3 *obj = (am_nfs_fh3 *) &argp->object;
+ am_post_op_attr *post_op_obj;
+ am_node *mp;
+ int retry;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "pathconf_3:");
+
+ mp = fh3_to_mp3(obj, &retry, VLOOK_CREATE);
+ if (!mp) {
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ post_op_obj = &result.res_u.fail.obj_attributes;
+ post_op_obj->attributes_follow = 0;
+ result.status = nfs_error(retry);
+ } else {
+ am_PATHCONF3resok *ok = &result.res_u.ok;
+ nfsfattr *fattr;
+ am_fattr3 *fattr3;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tpathconf_3(%s)", mp->am_path);
+
+ fattr = &mp->am_fattr;
+ post_op_obj = &ok->obj_attributes;
+ post_op_obj->attributes_follow = 1;
+ fattr3 = &post_op_obj->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ ok->linkmax = 0;
+ ok->name_max = NAME_MAX;
+ ok->no_trunc = 1;
+ ok->chown_restricted = 1;
+ ok->case_insensitive = 0;
+ ok->case_preserving = 1;
+
+ result.status = AM_NFS3_OK;
+ mp->am_stats.s_pathconf++;
+ }
+
+ return &result;
+}
+
+am_COMMIT3res *
+am_nfs3_commit_3_svc(am_COMMIT3args *argp, struct svc_req *rqstp)
+{
+ static am_COMMIT3res result;
+
+ am_nfs_fh3 *file = (am_nfs_fh3 *) &argp->file;
+ am_pre_op_attr *pre_op_file = &result.res_u.fail.file_wcc.before;
+ am_post_op_attr *post_op_file = &result.res_u.fail.file_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "commit_3:");
+
+ result.status = return_estale_or_rofs(file, pre_op_file, post_op_file);
+
+ return &result;
+}
+#endif /* HAVE_FS_NFS3 */
diff --git a/contrib/amd/amd/ops_TEMPLATE.c b/contrib/amd/amd/ops_TEMPLATE.c
index 3f7421984412..b873c8ece271 100644
--- a/contrib/amd/amd/ops_TEMPLATE.c
+++ b/contrib/amd/amd/ops_TEMPLATE.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -64,7 +60,7 @@ 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, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count);
+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);
@@ -220,7 +216,7 @@ foofs_lookuppn(am_node *mp, char *fname, int *error_return, int op)
* If OK, fills in ep with chain of directory entries.
*/
static int
-foofs_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count)
+foofs_readdir(am_node *mp, void cookie, voidp dp, voidp ep, u_int count)
{
int error = 0;
diff --git a/contrib/amd/amd/ops_cachefs.c b/contrib/amd/amd/ops_cachefs.c
index d3e303bc2bf9..26a333527457 100644
--- a/contrib/amd/amd/ops_cachefs.c
+++ b/contrib/amd/amd/ops_cachefs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -99,7 +95,7 @@ cachefs_match(am_opts *fo)
dlog("CACHEFS: using cache directory \"%s\"", fo->opt_cachedir);
/* determine magic cookie to put in mtab */
- return strdup(fo->opt_cachedir);
+ return xstrdup(fo->opt_cachedir);
}
@@ -114,7 +110,7 @@ cachefs_init(mntfs *mf)
* Save cache directory name
*/
if (!mf->mf_private) {
- mf->mf_private = (voidp) strdup(mf->mf_fo->opt_cachedir);
+ mf->mf_private = (voidp) xstrdup(mf->mf_fo->opt_cachedir);
mf->mf_prfree = (void (*)(voidp)) free;
}
diff --git a/contrib/amd/amd/ops_cdfs.c b/contrib/amd/amd/ops_cdfs.c
index 40355ac5c078..6ceb76408b03 100644
--- a/contrib/amd/amd/ops_cdfs.c
+++ b/contrib/amd/amd/ops_cdfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -97,7 +93,7 @@ cdfs_match(am_opts *fo)
/*
* Determine magic cookie to put in mtab
*/
- return strdup(fo->opt_dev);
+ return xstrdup(fo->opt_dev);
}
@@ -148,6 +144,7 @@ mount_cdfs(char *mntdir, char *fs_name, char *opts, int on_autofs)
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;
@@ -157,11 +154,27 @@ mount_cdfs(char *mntdir, char *fs_name, char *opts, int on_autofs)
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)
diff --git a/contrib/amd/amd/ops_efs.c b/contrib/amd/amd/ops_efs.c
index 047fe1e4690c..58bf8f0b76cb 100644
--- a/contrib/amd/amd/ops_efs.c
+++ b/contrib/amd/amd/ops_efs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -98,7 +94,7 @@ efs_match(am_opts *fo)
/*
* Determine magic cookie to put in mtab
*/
- return strdup(fo->opt_dev);
+ return xstrdup(fo->opt_dev);
}
@@ -137,6 +133,9 @@ mount_efs(char *mntdir, char *fs_name, char *opts, int on_autofs)
#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
diff --git a/contrib/amd/amd/ops_ext.c b/contrib/amd/amd/ops_ext.c
new file mode 100644
index 000000000000..106ab31f3748
--- /dev/null
+++ b/contrib/amd/amd/ops_ext.c
@@ -0,0 +1,223 @@
+/*
+ * 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);
+}
diff --git a/contrib/amd/amd/ops_lofs.c b/contrib/amd/amd/ops_lofs.c
index 26fdc9f9b626..b04f64399c18 100644
--- a/contrib/amd/amd/ops_lofs.c
+++ b/contrib/amd/amd/ops_lofs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -97,7 +93,7 @@ lofs_match(am_opts *fo)
/*
* Determine magic cookie to put in mtab
*/
- return strdup(fo->opt_rfs);
+ return xstrdup(fo->opt_rfs);
}
diff --git a/contrib/amd/amd/ops_lustre.c b/contrib/amd/amd/ops_lustre.c
new file mode 100644
index 000000000000..1b321ce4e8c4
--- /dev/null
+++ b/contrib/amd/amd/ops_lustre.c
@@ -0,0 +1,203 @@
+/*
+ * 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
diff --git a/contrib/amd/amd/ops_mfs.c b/contrib/amd/amd/ops_mfs.c
index ccaa49c569cd..822a2659317b 100644
--- a/contrib/amd/amd/ops_mfs.c
+++ b/contrib/amd/amd/ops_mfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/amd/ops_nfs.c b/contrib/amd/amd/ops_nfs.c
index a6a85858d484..2dbfa5b5e2ee 100644
--- a/contrib/amd/amd/ops_nfs.c
+++ b/contrib/amd/amd/ops_nfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -113,6 +109,13 @@ static int call_mountd(fh_cache *fp, u_long proc, fwd_fun f, wchan_t wchan);
static int webnfs_lookup(fh_cache *fp, fwd_fun f, wchan_t wchan);
static int fh_id = 0;
+/*
+ * clamp the filehandle version to 3, so that we can fail back to nfsv3
+ * since nfsv4 does not have file handles
+ */
+#define SET_FH_VERSION(fs) \
+ (fs)->fs_version > NFS_VERSION3 ? NFS_VERSION3 : (fs)->fs_version;
+
/* globals */
AUTH *nfs_auth;
qelem fh_head = {&fh_head, &fh_head};
@@ -145,7 +148,7 @@ am_ops nfs_ops =
static fh_cache *
find_nfs_fhandle_cache(opaque_t arg, int done)
{
- fh_cache *fp, *fp2 = 0;
+ fh_cache *fp, *fp2 = NULL;
int id = (long) arg; /* for 64-bit archs */
ITER(fp, fh_cache, &fh_head) {
@@ -201,6 +204,10 @@ got_nfs_fh_mount(voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in
memmove(fp->fh_nfs_handle.v3.am_fh3_data,
res3.mountres3_u.mountinfo.fhandle.fhandle3_val,
fp->fh_nfs_handle.v3.am_fh3_length);
+
+ XFREE(res3.mountres3_u.mountinfo.fhandle.fhandle3_val);
+ if (res3.mountres3_u.mountinfo.auth_flavors.auth_flavors_val)
+ XFREE(res3.mountres3_u.mountinfo.auth_flavors.auth_flavors_val);
} else {
#endif /* HAVE_FS_NFS3 */
memset(&res, 0, sizeof(res));
@@ -326,8 +333,7 @@ discard_fh(opaque_t arg)
dlog("Discarding filehandle for %s:%s", fp->fh_fs->fs_host, fp->fh_path);
free_srvr(fp->fh_fs);
}
- if (fp->fh_path)
- XFREE(fp->fh_path);
+ XFREE(fp->fh_path);
XFREE(fp);
}
@@ -338,7 +344,7 @@ discard_fh(opaque_t arg)
static int
prime_nfs_fhandle_cache(char *path, fserver *fs, am_nfs_handle_t *fhbuf, mntfs *mf)
{
- fh_cache *fp, *fp_save = 0;
+ fh_cache *fp, *fp_save = NULL;
int error;
int reuse_id = FALSE;
@@ -466,11 +472,11 @@ prime_nfs_fhandle_cache(char *path, fserver *fs, am_nfs_handle_t *fhbuf, mntfs *
fp->fh_sin = *fs->fs_ip;
if (!(mf->mf_flags & MFF_WEBNFS))
fp->fh_sin.sin_port = 0;
- fp->fh_nfs_version = fs->fs_version;
+ fp->fh_nfs_version = SET_FH_VERSION(fs);
}
fp->fh_fs = dup_srvr(fs);
- fp->fh_path = strdup(path);
+ fp->fh_path = xstrdup(path);
if (mf->mf_flags & MFF_WEBNFS)
error = webnfs_lookup(fp, got_nfs_fh_webnfs, get_mntfs_wchan(mf));
@@ -544,7 +550,9 @@ call_mountd(fh_cache *fp, u_long proc, fwd_fun fun, wchan_t wchan)
if (error)
return error;
fp->fh_sin.sin_port = mountd_port;
- }
+ dlog("%s: New %d mountd port", __func__, fp->fh_sin.sin_port);
+ } else
+ dlog("%s: Already had %d mountd port", __func__, fp->fh_sin.sin_port);
/* find the right version of the mount protocol */
#ifdef HAVE_FS_NFS3
@@ -605,7 +613,7 @@ webnfs_lookup(fh_cache *fp, fwd_fun fun, wchan_t wchan)
nfsdiropargs args;
#ifdef HAVE_FS_NFS3
am_LOOKUP3args args3;
-#endif
+#endif /* HAVE_FS_NFS3 */
char *wnfs_path;
size_t l;
@@ -724,6 +732,17 @@ nfs_init(mntfs *mf)
am_nfs_handle_t fhs;
char *colon;
+#ifdef NO_FALLBACK
+ /*
+ * We don't need file handles for NFS version 4, but we can fall back to
+ * version 3, so we allocate anyway
+ */
+#ifdef HAVE_FS_NFS4
+ if (mf->mf_server->fs_version == NFS_VERSION4)
+ return 0;
+#endif /* HAVE_FS_NFS4 */
+#endif /* NO_FALLBACK */
+
if (mf->mf_private) {
if (mf->mf_flags & MFF_NFS_SCALEDOWN) {
fserver *fs;
@@ -732,6 +751,9 @@ nfs_init(mntfs *mf)
mf->mf_ops->umounted(mf);
mf->mf_prfree(mf->mf_private);
+ mf->mf_private = NULL;
+ mf->mf_prfree = NULL;
+
fs = mf->mf_ops->ffserver(mf);
free_srvr(mf->mf_server);
mf->mf_server = fs;
@@ -769,7 +791,11 @@ mount_nfs_fh(am_nfs_handle_t *fhp, char *mntdir, char *fs_name, mntfs *mf)
int retry;
int proto = AMU_TYPE_NONE;
mntent_t mnt;
+ void *argsp;
nfs_args_t nfs_args;
+#ifdef HAVE_FS_NFS4
+ nfs4_args_t nfs4_args;
+#endif /* HAVE_FS_NFS4 */
/*
* Extract HOST name to give to kernel.
@@ -829,10 +855,7 @@ mount_nfs_fh(am_nfs_handle_t *fhp, char *mntdir, char *fs_name, mntfs *mf)
/*
* Set mount types accordingly
*/
-#ifndef HAVE_FS_NFS3
- type = MOUNT_TYPE_NFS;
- mnt.mnt_type = MNTTAB_TYPE_NFS;
-#else /* HAVE_FS_NFS3 */
+#ifdef HAVE_FS_NFS3
if (nfs_version == NFS_VERSION3) {
type = MOUNT_TYPE_NFS3;
/*
@@ -843,16 +866,25 @@ mount_nfs_fh(am_nfs_handle_t *fhp, char *mntdir, char *fs_name, mntfs *mf)
* So on those systems, set it to "nfs".
* Note: MNTTAB_OPT_VERS is always set for NFS3 (see am_compat.h).
*/
+ argsp = &nfs_args;
# if defined(MNTTAB_OPT_VERS) && defined(MOUNT_TABLE_ON_FILE)
mnt.mnt_type = MNTTAB_TYPE_NFS;
# else /* defined(MNTTAB_OPT_VERS) && defined(MOUNT_TABLE_ON_FILE) */
mnt.mnt_type = MNTTAB_TYPE_NFS3;
# endif /* defined(MNTTAB_OPT_VERS) && defined(MOUNT_TABLE_ON_FILE) */
- } else {
+# ifdef HAVE_FS_NFS4
+ } else if (nfs_version == NFS_VERSION4) {
+ argsp = &nfs4_args;
+ type = MOUNT_TYPE_NFS4;
+ mnt.mnt_type = MNTTAB_TYPE_NFS4;
+# endif /* HAVE_FS_NFS4 */
+ } else
+#endif /* HAVE_FS_NFS3 */
+ {
+ argsp = &nfs_args;
type = MOUNT_TYPE_NFS;
mnt.mnt_type = MNTTAB_TYPE_NFS;
}
-#endif /* HAVE_FS_NFS3 */
plog(XLOG_INFO, "mount_nfs_fh: NFS version %d", (int) nfs_version);
plog(XLOG_INFO, "mount_nfs_fh: using NFS transport %s", nfs_proto);
@@ -866,32 +898,44 @@ mount_nfs_fh(am_nfs_handle_t *fhp, char *mntdir, char *fs_name, mntfs *mf)
genflags |= autofs_compute_mount_flags(&mnt);
#endif /* HAVE_FS_AUTOFS */
- /* setup the many fields and flags within nfs_args */
- compute_nfs_args(&nfs_args,
- &mnt,
- genflags,
- NULL, /* struct netconfig *nfsncp */
- fs->fs_ip,
- nfs_version,
- nfs_proto,
- fhp,
- host,
- fs_name);
+ /* setup the many fields and flags within nfs_args */
+ compute_nfs_args(argsp,
+ &mnt,
+ genflags,
+ NULL, /* struct netconfig *nfsncp */
+ fs->fs_ip,
+ nfs_version,
+ nfs_proto,
+ fhp,
+ host,
+ fs_name);
/* finally call the mounting function */
if (amuDebug(D_TRACE)) {
- print_nfs_args(&nfs_args, nfs_version);
+ print_nfs_args(argsp, nfs_version);
plog(XLOG_DEBUG, "Generic mount flags 0x%x used for NFS mount", genflags);
}
- error = mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type,
- nfs_version, nfs_proto, mnttab_file_name, on_autofs);
- XFREE(xopts);
+ error = mount_fs(&mnt, genflags, argsp, retry, type,
+ nfs_version, nfs_proto, mnttab_file_name, on_autofs);
+ XFREE(mnt.mnt_opts);
+ discard_nfs_args(argsp, nfs_version);
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- free_knetconfig(nfs_args.knconf);
- if (nfs_args.addr)
- XFREE(nfs_args.addr); /* allocated in compute_nfs_args() */
-#endif /* HAVE_TRANSPORT_TYPE_TLI */
+#ifdef HAVE_FS_NFS4
+# ifndef NO_FALLBACK
+ /*
+ * If we are using a v4 file handle, we try a v3 if we get back:
+ * ENOENT: NFS v4 has a different export list than v3
+ * EPERM: Kernels <= 2.6.18 return that, instead of ENOENT
+ */
+ if ((error == ENOENT || error == EPERM) && nfs_version == NFS_VERSION4) {
+ plog(XLOG_DEBUG, "Could not find NFS 4 mount, trying again with NFS 3");
+ fs->fs_version = NFS_VERSION3;
+ error = mount_nfs_fh(fhp, mntdir, fs_name, mf);
+ if (error)
+ fs->fs_version = NFS_VERSION4;
+ }
+# endif /* NO_FALLBACK */
+#endif /* HAVE_FS_NFS4 */
return error;
}
@@ -903,11 +947,16 @@ nfs_mount(am_node *am, mntfs *mf)
int error = 0;
mntent_t mnt;
- if (!mf->mf_private) {
+ if (!mf->mf_private && mf->mf_server->fs_version != 4) {
plog(XLOG_ERROR, "Missing filehandle for %s", mf->mf_info);
return EINVAL;
}
+ if (mf->mf_mopts == NULL) {
+ plog(XLOG_ERROR, "Missing mount options for %s", mf->mf_info);
+ return EINVAL;
+ }
+
mnt.mnt_opts = mf->mf_mopts;
if (amu_hasmntopt(&mnt, "softlookup") ||
(amu_hasmntopt(&mnt, "soft") && !amu_hasmntopt(&mnt, "nosoftlookup")))
@@ -932,6 +981,7 @@ nfs_umount(am_node *am, mntfs *mf)
{
int unmount_flags, new_unmount_flags, error;
+ dlog("attempting nfs umount");
unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
error = UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
@@ -1031,12 +1081,12 @@ nfs_umounted(mntfs *mf)
f.fh_path = path;
f.fh_sin = *fs->fs_ip;
f.fh_sin.sin_port = (u_short) 0;
- f.fh_nfs_version = fs->fs_version;
+ f.fh_nfs_version = SET_FH_VERSION(fs);
f.fh_fs = fs;
f.fh_id = 0;
f.fh_error = 0;
- prime_nfs_fhandle_cache(colon + 1, mf->mf_server, (am_nfs_handle_t *) 0, mf);
- call_mountd(&f, MOUNTPROC_UMNT, (fwd_fun *) 0, (wchan_t) 0);
+ prime_nfs_fhandle_cache(colon + 1, mf->mf_server, (am_nfs_handle_t *) NULL, mf);
+ call_mountd(&f, MOUNTPROC_UMNT, (fwd_fun *) NULL, (wchan_t) NULL);
*colon = ':';
}
}
diff --git a/contrib/amd/amd/ops_nfs3.c b/contrib/amd/amd/ops_nfs3.c
index db3c7f9d265d..e07811b808e2 100644
--- a/contrib/amd/amd/ops_nfs3.c
+++ b/contrib/amd/amd/ops_nfs3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/amd/ops_nfs4.c b/contrib/amd/amd/ops_nfs4.c
new file mode 100644
index 000000000000..3798590837f3
--- /dev/null
+++ b/contrib/amd/amd/ops_nfs4.c
@@ -0,0 +1,50 @@
+/*
+ * 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... :-) */
diff --git a/contrib/amd/amd/ops_nullfs.c b/contrib/amd/amd/ops_nullfs.c
index cf621ec33ff5..73d1f0e53f1c 100644
--- a/contrib/amd/amd/ops_nullfs.c
+++ b/contrib/amd/amd/ops_nullfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/amd/ops_pcfs.c b/contrib/amd/amd/ops_pcfs.c
index 527dc926ca77..b4c8dcd5fecc 100644
--- a/contrib/amd/amd/ops_pcfs.c
+++ b/contrib/amd/amd/ops_pcfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -97,7 +93,7 @@ pcfs_match(am_opts *fo)
/*
* Determine magic cookie to put in mtab
*/
- return strdup(fo->opt_dev);
+ return xstrdup(fo->opt_dev);
}
diff --git a/contrib/amd/amd/ops_tfs.c b/contrib/amd/amd/ops_tfs.c
index 142c32022937..3276a6e62ff1 100644
--- a/contrib/amd/amd/ops_tfs.c
+++ b/contrib/amd/amd/ops_tfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/amd/ops_tmpfs.c b/contrib/amd/amd/ops_tmpfs.c
index eddd75569e9e..d9a15ea0434d 100644
--- a/contrib/amd/amd/ops_tmpfs.c
+++ b/contrib/amd/amd/ops_tmpfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -51,4 +47,146 @@
#include <am_defs.h>
#include <amd.h>
-/* FEEL FREE TO IMPLEMENT THIS... :-) */
+/* 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);
+}
+
diff --git a/contrib/amd/amd/ops_udf.c b/contrib/amd/amd/ops_udf.c
new file mode 100644
index 000000000000..4230c5b12ff5
--- /dev/null
+++ b/contrib/amd/amd/ops_udf.c
@@ -0,0 +1,272 @@
+/*
+ * 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);
+}
diff --git a/contrib/amd/amd/ops_ufs.c b/contrib/amd/amd/ops_ufs.c
index fd82a5cd2228..0d8f3068dbe5 100644
--- a/contrib/amd/amd/ops_ufs.c
+++ b/contrib/amd/amd/ops_ufs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -61,7 +57,11 @@ static int ufs_umount(am_node *am, mntfs *mf);
*/
am_ops ufs_ops =
{
+#ifndef __NetBSD__
"ufs",
+#else
+ "ffs",
+#endif
ufs_match,
0, /* ufs_init */
ufs_mount,
@@ -98,7 +98,7 @@ ufs_match(am_opts *fo)
/*
* Determine magic cookie to put in mtab
*/
- return strdup(fo->opt_dev);
+ return xstrdup(fo->opt_dev);
}
diff --git a/contrib/amd/amd/ops_umapfs.c b/contrib/amd/amd/ops_umapfs.c
index 5ba735e39c61..6f9d39d9d5db 100644
--- a/contrib/amd/amd/ops_umapfs.c
+++ b/contrib/amd/amd/ops_umapfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/amd/ops_unionfs.c b/contrib/amd/amd/ops_unionfs.c
index 73f8d6676203..e6286133cbfa 100644
--- a/contrib/amd/amd/ops_unionfs.c
+++ b/contrib/amd/amd/ops_unionfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/amd/ops_xfs.c b/contrib/amd/amd/ops_xfs.c
index e0e740bc0a0e..6e1495e295f4 100644
--- a/contrib/amd/amd/ops_xfs.c
+++ b/contrib/amd/amd/ops_xfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -98,7 +94,7 @@ xfs_match(am_opts *fo)
/*
* Determine magic cookie to put in mtab
*/
- return strdup(fo->opt_dev);
+ return xstrdup(fo->opt_dev);
}
diff --git a/contrib/amd/amd/opts.c b/contrib/amd/amd/opts.c
index a3d35343adc0..4bc833a8dd85 100644
--- a/contrib/amd/amd/opts.c
+++ b/contrib/amd/amd/opts.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -539,7 +535,7 @@ eval_selectors(char *opts, char *mapkey)
char *f;
int ret = 0;
- o = old_o = strdup(opts);
+ o = old_o = xstrdup(opts);
/*
* For each user-specified option
@@ -570,7 +566,7 @@ eval_selectors(char *opts, char *mapkey)
/* null-terminate the argument */
*arg++ = '\0';
fx = strchr(arg, ')');
- if (!arg || fx == arg) {
+ if (fx == NULL || fx == arg) {
plog(XLOG_USER, "key %s: Malformed function in \"%s\"", mapkey, f);
continue;
}
@@ -606,8 +602,10 @@ eval_selectors(char *opts, char *mapkey)
}
} else {
if (eq[1] == '\0' || eq == f) {
- /* misformed selector */
+#ifdef notdef
+ /* We allow empty assignments */
plog(XLOG_USER, "key %s: Bad selector \"%s\"", mapkey, f);
+#endif
continue;
}
}
@@ -968,9 +966,7 @@ f_true(char *arg)
static void
free_op(opt_apply *p, int b)
{
- if (*p->opt) {
- XFREE(*p->opt);
- }
+ XFREE(*p->opt);
}
@@ -1016,7 +1012,7 @@ normalize_slash(char *p)
/* assert(*f == 0 || *f == '/'); */
} while (*f);
- *t = 0; /* derived from fix by Steven Glassman */
+ *t = '\0'; /* derived from fix by Steven Glassman */
}
}
@@ -1238,8 +1234,14 @@ expand_op(char *opt, int sel_p)
}
if (BUFSPACE(ep, vlen+1)) {
- xstrlcpy(ep, vptr, vlen+1);
+ /*
+ * Don't call xstrlcpy() to truncate a string here. It causes
+ * spurious xstrlcpy() syslog() errors. Use memcpy() and
+ * explicitly terminate the string.
+ */
+ memcpy(ep, vptr, vlen+1);
ep += vlen;
+ *ep = '\0';
} else {
plog(XLOG_ERROR, EXPAND_ERROR, opt);
goto out;
@@ -1292,7 +1294,7 @@ out:
* Handle common case - no expansion
*/
if (cp == opt) {
- opt = strdup(cp);
+ opt = xstrdup(cp);
} else {
/*
* Finish off the expansion
@@ -1308,7 +1310,7 @@ out:
/*
* Save the expansion
*/
- opt = strdup(expbuf);
+ opt = xstrdup(expbuf);
}
normalize_slash(opt);
@@ -1372,6 +1374,45 @@ free_opts(am_opts *fo)
apply_opts(free_op, to_free, FALSE);
}
+am_opts *
+copy_opts(am_opts *old)
+{
+ am_opts *newopts;
+ newopts = CALLOC(struct am_opts);
+
+#define _AM_OPT_COPY(field) do { \
+ if (old->field) \
+ newopts->field = xstrdup(old->field); \
+ } while (0)
+
+ _AM_OPT_COPY(fs_glob);
+ _AM_OPT_COPY(fs_local);
+ _AM_OPT_COPY(fs_mtab);
+ _AM_OPT_COPY(opt_dev);
+ _AM_OPT_COPY(opt_delay);
+ _AM_OPT_COPY(opt_dir);
+ _AM_OPT_COPY(opt_fs);
+ _AM_OPT_COPY(opt_group);
+ _AM_OPT_COPY(opt_mount);
+ _AM_OPT_COPY(opt_opts);
+ _AM_OPT_COPY(opt_remopts);
+ _AM_OPT_COPY(opt_pref);
+ _AM_OPT_COPY(opt_cache);
+ _AM_OPT_COPY(opt_rfs);
+ _AM_OPT_COPY(opt_rhost);
+ _AM_OPT_COPY(opt_sublink);
+ _AM_OPT_COPY(opt_type);
+ _AM_OPT_COPY(opt_mount_type);
+ _AM_OPT_COPY(opt_unmount);
+ _AM_OPT_COPY(opt_umount);
+ _AM_OPT_COPY(opt_user);
+ _AM_OPT_COPY(opt_maptype);
+ _AM_OPT_COPY(opt_cachedir);
+ _AM_OPT_COPY(opt_addopts);
+
+ return newopts;
+}
+
/*
* Expand selectors (variables that cannot be assigned to or overridden)
diff --git a/contrib/amd/amd/readdir.c b/contrib/amd/amd/readdir.c
index 49f89943cfb4..3d3c7add01a7 100644
--- a/contrib/amd/amd/readdir.c
+++ b/contrib/amd/amd/readdir.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -109,14 +105,14 @@ make_entry_chain(am_node *mp, const nfsentry *current_chain, int fully_browsable
plog(XLOG_DEBUG, "make_entry_chain: mp is (NULL)");
return retval;
}
- mf = mp->am_mnt;
+ mf = mp->am_al->al_mnt;
if (!mf) {
- plog(XLOG_DEBUG, "make_entry_chain: mp->am_mnt is (NULL)");
+ 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_mnt->mf_private is (NULL)");
+ plog(XLOG_DEBUG, "make_entry_chain: mp->am_al->al_mnt->mf_private is (NULL)");
return retval;
}
@@ -171,7 +167,7 @@ make_entry_chain(am_node *mp, const nfsentry *current_chain, int fully_browsable
/* out of space */
plog(XLOG_DEBUG, "make_entry_chain: no more space in chain");
if (num_entries > 0) {
- chain[num_entries - 1].ne_nextentry = 0;
+ chain[num_entries - 1].ne_nextentry = NULL;
retval = &chain[0];
}
return retval;
@@ -192,7 +188,7 @@ make_entry_chain(am_node *mp, const nfsentry *current_chain, int fully_browsable
/* terminate chain */
if (num_entries > 0) {
- chain[num_entries - 1].ne_nextentry = 0;
+ chain[num_entries - 1].ne_nextentry = NULL;
retval = &chain[0];
}
@@ -225,7 +221,7 @@ amfs_readdir_browsable(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *
* to be returned in a single packet. If it isn't (which would be
* fairly unbelievable) then tough.
*/
- dlog("amfs_readdir_browsable: default search");
+ dlog("%s: default search", __func__);
/*
* Check for enough room. This is extremely approximate but is more
* than enough space. Really need 2 times:
@@ -264,8 +260,8 @@ amfs_readdir_browsable(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *
ep[1].ne_fileid = mp->am_gen;
ep[1].ne_name = "..";
- ep[1].ne_nextentry = 0;
- *(u_int *) ep[1].ne_cookie = DOT_DOT_COOKIE;
+ 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
@@ -313,12 +309,12 @@ amfs_readdir_browsable(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *
return 0;
} /* end of "if (gen == 0)" statement */
- dlog("amfs_readdir_browsable: real child");
+ dlog("%s: real child", __func__);
if (gen == DOT_DOT_COOKIE) {
- dlog("amfs_readdir_browsable: End of readdir in %s", mp->am_path);
+ dlog("%s: End of readdir in %s", __func__, mp->am_path);
dp->dl_eof = TRUE;
- dp->dl_entries = 0;
+ dp->dl_entries = NULL;
return 0;
}
@@ -332,7 +328,7 @@ amfs_readdir_browsable(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *
te = te_next; /* reset 'te' from last saved te_next */
if (!te) { /* another indicator of end of readdir */
- dp->dl_entries = 0;
+ dp->dl_entries = NULL;
return 0;
}
/*
@@ -365,29 +361,14 @@ amfs_readdir_browsable(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *
return 0;
}
-
-/*
- * 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, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count)
+static int
+amfs_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count)
{
u_int gen = *(u_int *) cookie;
am_node *xp;
- mntent_t mnt;
dp->dl_eof = FALSE; /* assume readdir not done */
- /* check if map is browsable */
- if (mp->am_mnt && mp->am_mnt->mf_mopts) {
- mnt.mnt_opts = mp->am_mnt->mf_mopts;
- if (amu_hasmntopt(&mnt, "fullybrowsable"))
- return amfs_readdir_browsable(mp, cookie, dp, ep, count, TRUE);
- if (amu_hasmntopt(&mnt, "browsable"))
- return amfs_readdir_browsable(mp, cookie, dp, ep, count, FALSE);
- }
-
/* when gen is 0, we start reading from the beginning of the directory */
if (gen == 0) {
/*
@@ -398,7 +379,7 @@ amfs_generic_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep
* to be returned in a single packet. If it isn't (which would be
* fairly unbelievable) then tough.
*/
- dlog("amfs_generic_readdir: default search");
+ dlog("%s: default search", __func__);
/*
* Check for enough room. This is extremely approximate but is more
* than enough space. Really need 2 times:
@@ -407,8 +388,11 @@ amfs_generic_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep
* 4byte name length
* 4byte name
* plus the dirlist structure */
- if (count < (2 * (2 * (sizeof(*ep) + sizeof("..") + 4) + sizeof(*dp))))
+#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;
@@ -425,8 +409,9 @@ amfs_generic_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep
else
ep[1].ne_fileid = mp->am_gen;
ep[1].ne_name = "..";
- ep[1].ne_nextentry = 0;
- *(u_int *) ep[1].ne_cookie = (xp ? xp->am_gen : DOT_DOT_COOKIE);
+ 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 */
@@ -443,12 +428,12 @@ amfs_generic_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep
}
return 0;
}
- dlog("amfs_generic_readdir: real child");
+ dlog("%s: real child", __func__);
if (gen == DOT_DOT_COOKIE) {
- dlog("amfs_generic_readdir: End of readdir in %s", mp->am_path);
+ dlog("%s: End of readdir in %s", __func__, mp->am_path);
dp->dl_eof = TRUE;
- dp->dl_entries = 0;
+ dp->dl_entries = NULL;
if (amuDebug(D_READDIR))
plog(XLOG_DEBUG, "end of readdir eof=TRUE, dl_entries=0\n");
return 0;
@@ -491,7 +476,7 @@ amfs_generic_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep
}
} while (todo > 0);
- ep->ne_nextentry = 0;
+ ep->ne_nextentry = NULL;
if (amuDebug(D_READDIR)) {
nfsentry *ne;
@@ -507,3 +492,460 @@ amfs_generic_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep
}
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 *) 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 *) 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) cookie, dp, ep, count, full);
+ else
+ return amfs_readdir3(mp, (am_cookie3) cookie, dp, ep, count);
+ }
+}
diff --git a/contrib/amd/amd/restart.c b/contrib/amd/amd/restart.c
index 4f71e381e25a..de38bcfb2741 100644
--- a/contrib/amd/amd/restart.c
+++ b/contrib/amd/amd/restart.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -59,21 +55,21 @@ restart_fake_mntfs(mntent_t *me, am_ops *fs_ops)
* Partially fake up an opts structure
*/
memset(&mo, 0, sizeof(mo));
- mo.opt_rhost = 0;
- mo.opt_rfs = 0;
+ mo.opt_rhost = NULL;
+ mo.opt_rfs = NULL;
cp = strchr(me->mnt_fsname, ':');
if (cp) {
*cp = '\0';
- mo.opt_rhost = strdup(me->mnt_fsname);
- mo.opt_rfs = strdup(cp + 1);
+ 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 = strdup(me->mnt_fsname);
- mo.opt_rfs = strdup("/");
+ 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;
@@ -87,7 +83,6 @@ restart_fake_mntfs(mntent_t *me, am_ops *fs_ops)
if (mf->mf_refc == 1) {
mf->mf_flags |= MFF_RESTART | MFF_MOUNTED;
mf->mf_error = 0; /* Already mounted correctly */
- mf->mf_fo = 0;
/*
* Only timeout non-NFS entries
*/
@@ -110,10 +105,8 @@ restart_fake_mntfs(mntent_t *me, am_ops *fs_ops)
/*
* Clean up mo
*/
- if (mo.opt_rhost)
- XFREE(mo.opt_rhost);
- if (mo.opt_rfs)
- XFREE(mo.opt_rfs);
+ XFREE(mo.opt_rhost);
+ XFREE(mo.opt_rfs);
}
@@ -140,7 +133,7 @@ restart(void)
mlp;
mlp = mlp->mnext) {
mntent_t *me = mlp->mnt;
- am_ops *fs_ops = 0;
+ am_ops *fs_ops = NULL;
if (STREQ(me->mnt_type, MNTTAB_TYPE_NFS)) {
/*
@@ -203,7 +196,7 @@ restart_automounter_nodes(void)
mlp;
mlp = mlp->mnext) {
mntent_t *me = mlp->mnt;
- am_ops *fs_ops = 0;
+ am_ops *fs_ops = NULL;
char *colon;
long pid;
u_short port;
@@ -263,7 +256,8 @@ restart_automounter_nodes(void)
if (old_ports[i] == 0) {
int soNFS;
SVCXPRT *nfsxprt;
- if (create_nfs_service(&soNFS, &port, &nfsxprt, nfs_program_2) != 0) {
+ 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;
}
diff --git a/contrib/amd/amd/rpc_fwd.c b/contrib/amd/amd/rpc_fwd.c
index b3c8be4fa3b7..757b4371024a 100644
--- a/contrib/amd/amd/rpc_fwd.c
+++ b/contrib/amd/amd/rpc_fwd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -94,7 +90,7 @@ static rpc_forward *
fwd_alloc(void)
{
time_t now = clocktime(NULL);
- rpc_forward *p = 0, *p2;
+ rpc_forward *p = NULL, *p2;
/*
* First search for an existing expired one.
@@ -183,7 +179,7 @@ fwd_init(void)
/*
* Some things we talk to require a priv port - so make one here
*/
- if (bind_resv_port(fwd_sock, (u_short *) 0) < 0)
+ 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
diff --git a/contrib/amd/amd/sched.c b/contrib/amd/amd/sched.c
index 8efe57a3ab81..5c816b4c2058 100644
--- a/contrib/amd/amd/sched.c
+++ b/contrib/amd/amd/sched.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -262,7 +258,7 @@ sigchld(int sig)
#ifdef HAVE_WAITPID
while ((pid = waitpid((pid_t) -1, &w, WNOHANG)) > 0) {
#else /* not HAVE_WAITPID */
- while ((pid = wait3( &w, WNOHANG, (struct rusage *) 0)) > 0) {
+ while ((pid = wait3( &w, WNOHANG, (struct rusage *) NULL)) > 0) {
#endif /* not HAVE_WAITPID */
pjob *p, *p2;
diff --git a/contrib/amd/amd/srvr_amfs_auto.c b/contrib/amd/amd/srvr_amfs_auto.c
index 4742cf6f750d..44b130254d30 100644
--- a/contrib/amd/amd/srvr_amfs_auto.c
+++ b/contrib/amd/amd/srvr_amfs_auto.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -69,14 +65,14 @@ amfs_generic_find_srvr(mntfs *mf)
if (!fs) {
fs = ALLOC(struct fserver);
fs->fs_refc = 0;
- fs->fs_host = strdup("localhost");
- fs->fs_ip = 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 = 0;
- fs->fs_prfree = 0;
+ fs->fs_private = NULL;
+ fs->fs_prfree = NULL;
ins_que(&fs->fs_q, &amfs_auto_srvr_list);
@@ -135,8 +131,7 @@ timeout_srvr(voidp v)
/*
* Free the net address
*/
- if (fs->fs_ip)
- XFREE(fs->fs_ip);
+ XFREE(fs->fs_ip);
/*
* Free the host name.
diff --git a/contrib/amd/amd/srvr_nfs.c b/contrib/amd/amd/srvr_nfs.c
index 0c74a658e5ee..b7c852c9e1de 100644
--- a/contrib/amd/amd/srvr_nfs.c
+++ b/contrib/amd/amd/srvr_nfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -75,6 +71,7 @@
typedef struct nfs_private {
u_short np_mountd; /* Mount daemon port number */
char np_mountd_inval; /* Port *may* be invalid */
+ /* 'Y' invalid, 'N' valid, 'P' permanent */
int np_ping; /* Number of failed ping attempts */
time_t np_ttl; /* Time when server is thought dead */
int np_xid; /* RPC transaction id for pings */
@@ -88,7 +85,9 @@ qelem nfs_srvr_list = {&nfs_srvr_list, &nfs_srvr_list};
static int global_xid; /* For NFS pings */
#define XID_ALLOC() (++global_xid)
-#ifdef HAVE_FS_NFS3
+#if defined(HAVE_FS_NFS4)
+# define NUM_NFS_VERS 3
+#elif defined(HAVE_FS_NFS3)
# define NUM_NFS_VERS 2
#else /* not HAVE_FS_NFS3 */
# define NUM_NFS_VERS 1
@@ -124,8 +123,8 @@ flush_srvr_nfs_cache(fserver *fs)
ITER(fs2, fserver, &nfs_srvr_list) {
if (fs == NULL || fs == fs2) {
nfs_private *np = (nfs_private *) fs2->fs_private;
- if (np) {
- np->np_mountd_inval = TRUE;
+ if (np && np->np_mountd_inval != 'P') {
+ np->np_mountd_inval = 'Y';
np->np_error = -1;
}
}
@@ -147,9 +146,9 @@ create_ping_payload(u_long nfs_version)
*/
if (nfs_version == 0) {
nfs_version = NFS_VERSION;
- plog(XLOG_WARNING, "create_ping_payload: nfs_version = 0, changed to 2");
+ plog(XLOG_WARNING, "%s: nfs_version = 0, changed to 2", __func__);
} else
- plog(XLOG_INFO, "create_ping_payload: nfs_version: %d", (int) nfs_version);
+ plog(XLOG_INFO, "%s: nfs_version: %d", __func__, (int) nfs_version);
rpc_msg_init(&ping_msg, NFS_PROGRAM, nfs_version, NFSPROC_NULL);
@@ -164,6 +163,7 @@ create_ping_payload(u_long nfs_version)
if (!xdr_callmsg(&ping_xdr, &ping_msg)) {
plog(XLOG_ERROR, "Couldn't create ping RPC message");
going_down(3);
+ return;
}
/*
* Find out how long it is
@@ -184,7 +184,7 @@ static void
got_portmap(voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, voidp idv, int done)
{
fserver *fs2 = (fserver *) idv;
- fserver *fs = 0;
+ fserver *fs = NULL;
/*
* Find which fileserver we are talking about
@@ -207,7 +207,7 @@ got_portmap(voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia,
* network ordering.
*/
np->np_mountd = htons((u_short) port);
- np->np_mountd_inval = FALSE;
+ np->np_mountd_inval = 'N';
np->np_error = 0;
} else {
dlog("Error fetching port for mountd on %s", fs->fs_host);
@@ -291,9 +291,9 @@ recompute_portmap(fserver *fs)
}
if (fs->fs_version == 0)
- plog(XLOG_WARNING, "recompute_portmap: nfs_version = 0 fixed");
+ plog(XLOG_WARNING, "%s: nfs_version = 0 fixed", __func__);
- plog(XLOG_INFO, "recompute_portmap: NFS version %d on %s",
+ plog(XLOG_INFO, "%s: NFS version %d on %s", __func__,
(int) fs->fs_version, fs->fs_host);
#ifdef HAVE_FS_NFS3
if (fs->fs_version == NFS_VERSION3)
@@ -311,6 +311,7 @@ int
get_mountd_port(fserver *fs, u_short *port, wchan_t wchan)
{
int error = -1;
+
if (FSRV_ISDOWN(fs))
return EWOULDBLOCK;
@@ -329,10 +330,18 @@ get_mountd_port(fserver *fs, u_short *port, wchan_t wchan)
* indication that the mountd may be invalid, not
* that it is known to be invalid.
*/
- if (np->np_mountd_inval)
+ switch (np->np_mountd_inval) {
+ case 'Y':
recompute_portmap(fs);
- else
- np->np_mountd_inval = TRUE;
+ break;
+ case 'N':
+ np->np_mountd_inval = 'Y';
+ break;
+ case 'P':
+ break;
+ default:
+ abort();
+ }
}
if (error < 0 && wchan && !(fs->fs_flags & FSF_WANT)) {
/*
@@ -425,7 +434,7 @@ nfs_keepalive_callback(voidp pkt, int len, struct sockaddr_in *sp, struct sockad
/*
* Recompute portmap information if not known
*/
- if (np->np_mountd_inval)
+ if (np->np_mountd_inval == 'Y')
recompute_portmap(fs);
found_map++;
@@ -454,7 +463,7 @@ check_fs_addr_change(fserver *fs)
sizeof(fs->fs_ip->sin_addr)) == 0)
return;
/* if got here: downed server changed IP address */
- old_ipaddr = strdup(inet_ntoa(fs->fs_ip->sin_addr));
+ old_ipaddr = xstrdup(inet_ntoa(fs->fs_ip->sin_addr));
memmove((voidp) &ia, (voidp) hp->h_addr, sizeof(struct in_addr));
new_ipaddr = inet_ntoa(ia); /* ntoa uses static buf */
plog(XLOG_WARNING, "EZK: down fileserver %s changed ip: %s -> %s",
@@ -474,7 +483,7 @@ check_fs_addr_change(fserver *fs)
#if 0
flush_nfs_fhandle_cache(fs); /* done in caller: nfs_keepalive_timeout */
/* XXX: need to purge nfs_private so that somehow it will get re-initialized? */
-#endif
+#endif /* 0 */
}
@@ -562,22 +571,24 @@ nfs_keepalive(voidp v)
int error;
nfs_private *np = (nfs_private *) fs->fs_private;
int fstimeo = -1;
+ int fs_version = nfs_valid_version(gopt.nfs_vers_ping) &&
+ gopt.nfs_vers_ping < fs->fs_version ? gopt.nfs_vers_ping : fs->fs_version;
/*
* Send an NFS ping to this node
*/
- if (ping_len[fs->fs_version - NFS_VERSION] == 0)
- create_ping_payload(fs->fs_version);
+ if (ping_len[fs_version - NFS_VERSION] == 0)
+ create_ping_payload(fs_version);
/*
* Queue the packet...
*/
error = fwd_packet(MK_RPC_XID(RPC_XID_NFSPING, np->np_xid),
- ping_buf[fs->fs_version - NFS_VERSION],
- ping_len[fs->fs_version - NFS_VERSION],
+ ping_buf[fs_version - NFS_VERSION],
+ ping_len[fs_version - NFS_VERSION],
fs->fs_ip,
- (struct sockaddr_in *) 0,
+ (struct sockaddr_in *) NULL,
(voidp) ((long) np->np_xid), /* cast needed for 64-bit archs */
nfs_keepalive_callback);
@@ -673,7 +684,7 @@ start_nfs_pings(fserver *fs, int pingval)
fserver *
find_nfs_srvr(mntfs *mf)
{
- char *host = mf->mf_fo->opt_rhost;
+ char *host;
fserver *fs;
int pingval;
mntent_t mnt;
@@ -687,6 +698,11 @@ find_nfs_srvr(mntfs *mf)
int nfs_port_opt = 0;
int fserver_is_down = 0;
+ if (mf->mf_fo == NULL) {
+ plog(XLOG_ERROR, "%s: NULL mf_fo", __func__);
+ return NULL;
+ }
+ host = mf->mf_fo->opt_rhost;
/*
* Get ping interval from mount options.
* Current only used to decide whether pings
@@ -702,7 +718,8 @@ find_nfs_srvr(mntfs *mf)
*/
nfs_version = NFS_VERSION;
nfs_proto = "udp";
- plog(XLOG_WARNING, "find_nfs_srvr: NFS mount failed, trying again with NFSv2/UDP");
+ plog(XLOG_WARNING, "%s: NFS mount failed, trying again with NFSv2/UDP",
+ __func__);
mf->mf_flags &= ~MFF_NFS_SCALEDOWN;
} else {
/*
@@ -742,12 +759,13 @@ find_nfs_srvr(mntfs *mf)
/* check if we've globally overridden the NFS version/protocol */
if (gopt.nfs_vers) {
nfs_version = gopt.nfs_vers;
- plog(XLOG_INFO, "find_nfs_srvr: force NFS version to %d",
+ plog(XLOG_INFO, "%s: force NFS version to %d", __func__,
(int) nfs_version);
}
if (gopt.nfs_proto) {
nfs_proto = gopt.nfs_proto;
- plog(XLOG_INFO, "find_nfs_srvr: force NFS protocol transport to %s", nfs_proto);
+ plog(XLOG_INFO, "%s: force NFS protocol transport to %s", __func__,
+ nfs_proto);
}
}
@@ -769,7 +787,7 @@ find_nfs_srvr(mntfs *mf)
if (hp) {
switch (hp->h_addrtype) {
case AF_INET:
- ip = ALLOC(struct sockaddr_in);
+ ip = CALLOC(struct sockaddr_in);
memset((voidp) ip, 0, sizeof(*ip));
/* as per POSIX, sin_len need not be set (used internally by kernel) */
ip->sin_family = AF_INET;
@@ -795,8 +813,7 @@ find_nfs_srvr(mntfs *mf)
STREQ(host, fs->fs_host)) {
plog(XLOG_WARNING, "fileserver %s is already hung - not running NFS proto/version discovery", host);
fs->fs_refc++;
- if (ip)
- XFREE(ip);
+ XFREE(ip);
return fs;
}
}
@@ -821,10 +838,12 @@ find_nfs_srvr(mntfs *mf)
plog(XLOG_INFO, "%s option used, NOT contacting the portmapper on %s",
MNTTAB_OPT_PUBLIC, host);
/*
- * Prefer NFSv3/tcp if the client supports it (cf. RFC 2054, 7).
+ * Prefer NFSv4/tcp if the client supports it (cf. RFC 2054, 7).
*/
if (!nfs_version) {
-#ifdef HAVE_FS_NFS3
+#if defined(HAVE_FS_NFS4)
+ nfs_version = NFS_VERSION4;
+#elif defined(HAVE_FS_NFS3)
nfs_version = NFS_VERSION3;
#else /* not HAVE_FS_NFS3 */
nfs_version = NFS_VERSION;
@@ -833,11 +852,11 @@ find_nfs_srvr(mntfs *mf)
(int) nfs_version);
}
if (!nfs_proto) {
-#if defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3)
+#if defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) || defined(HAVE_FS_NFS4)
nfs_proto = "tcp";
-#else /* not defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) */
+#else /* not defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) || defined(HAVE_FS_NFS4) */
nfs_proto = "udp";
-#endif /* not defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) */
+#endif /* not defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) || defined(HAVE_FS_NFS4) */
plog(XLOG_INFO, "No NFS protocol transport specified, will use %s",
nfs_proto);
}
@@ -849,7 +868,8 @@ find_nfs_srvr(mntfs *mf)
*/
if (check_pmap_up(host, ip)) {
if (nfs_proto) {
- best_nfs_version = get_nfs_version(host, ip, nfs_version, nfs_proto);
+ best_nfs_version = get_nfs_version(host, ip, nfs_version, nfs_proto,
+ gopt.nfs_vers);
nfs_port = ip->sin_port;
}
#ifdef MNTTAB_OPT_PROTO
@@ -858,8 +878,8 @@ find_nfs_srvr(mntfs *mf)
char **p;
for (p = protocols; *p; p++) {
- proto_nfs_version = get_nfs_version(host, ip, nfs_version, *p);
-
+ proto_nfs_version = get_nfs_version(host, ip, nfs_version, *p,
+ gopt.nfs_vers);
if (proto_nfs_version > best_nfs_version) {
best_nfs_version = proto_nfs_version;
nfs_proto = *p;
@@ -908,8 +928,8 @@ find_nfs_srvr(mntfs *mf)
if (!nfs_port)
nfs_port = htons(NFS_PORT);
- dlog("find_nfs_srvr: using port %d for nfs on %s",
- (int) ntohs(nfs_port), host);
+ dlog("%s: using port %d for nfs on %s", __func__,
+ (int) ntohs(nfs_port), host);
ip->sin_port = nfs_port;
no_dns:
@@ -935,7 +955,7 @@ no_dns:
sizeof(fs->fs_ip->sin_addr)) != 0) {
struct in_addr ia;
char *old_ipaddr, *new_ipaddr;
- old_ipaddr = strdup(inet_ntoa(fs->fs_ip->sin_addr));
+ old_ipaddr = xstrdup(inet_ntoa(fs->fs_ip->sin_addr));
memmove((voidp) &ia, (voidp) hp->h_addr, sizeof(struct in_addr));
new_ipaddr = inet_ntoa(ia); /* ntoa uses static buf */
plog(XLOG_WARNING, "fileserver %s changed ip: %s -> %s",
@@ -962,24 +982,28 @@ no_dns:
*/
if (!(fs->fs_flags & FSF_PINGING)) {
np = (nfs_private *) fs->fs_private;
- np->np_mountd_inval = TRUE;
- np->np_xid = XID_ALLOC();
- np->np_error = -1;
- np->np_ping = 0;
- /*
- * Initially the server will be deemed dead
- * after MAX_ALLOWED_PINGS of the fast variety
- * have failed.
- */
- np->np_ttl = MAX_ALLOWED_PINGS * FAST_NFS_PING + clocktime(NULL) - 1;
- start_nfs_pings(fs, pingval);
- if (fserver_is_down)
- fs->fs_flags |= FSF_VALID | FSF_DOWN;
+ if (np->np_mountd_inval != 'P') {
+ np->np_mountd_inval = TRUE;
+ np->np_xid = XID_ALLOC();
+ np->np_error = -1;
+ np->np_ping = 0;
+ /*
+ * Initially the server will be deemed dead
+ * after MAX_ALLOWED_PINGS of the fast variety
+ * have failed.
+ */
+ np->np_ttl = MAX_ALLOWED_PINGS * FAST_NFS_PING + clocktime(NULL) - 1;
+ start_nfs_pings(fs, pingval);
+ if (fserver_is_down)
+ fs->fs_flags |= FSF_VALID | FSF_DOWN;
+ } else {
+ fs->fs_flags = FSF_VALID;
+ }
+
}
fs->fs_refc++;
- if (ip)
- XFREE(ip);
+ XFREE(ip);
return fs;
}
}
@@ -993,7 +1017,7 @@ no_dns:
*/
fs = ALLOC(struct fserver);
fs->fs_refc = 1;
- fs->fs_host = strdup(hp ? hp->h_name : "unknown_hostname");
+ fs->fs_host = xstrdup(hp ? hp->h_name : "unknown_hostname");
if (gopt.flags & CFM_NORMALIZE_HOSTNAMES)
host_normalize(&fs->fs_host);
fs->fs_ip = ip;
@@ -1014,9 +1038,18 @@ no_dns:
fs->fs_flags |= FSF_PING_UNINIT; /* pinger hasn't been initialized */
np = ALLOC(struct nfs_private);
memset((voidp) np, 0, sizeof(*np));
- np->np_mountd_inval = TRUE;
- np->np_xid = XID_ALLOC();
- np->np_error = -1;
+ np->np_mountd = htons(hasmntval(&mnt, "mountport"));
+ if (np->np_mountd == 0) {
+ np->np_mountd_inval = 'Y';
+ np->np_xid = XID_ALLOC();
+ np->np_error = -1;
+ } else {
+ plog(XLOG_INFO, "%s: using mountport: %d", __func__,
+ (int) ntohs(np->np_mountd));
+ np->np_mountd_inval = 'P';
+ np->np_xid = 0;
+ np->np_error = 0;
+ }
/*
* Initially the server will be deemed dead after
diff --git a/contrib/amd/amd/sun2amd.8 b/contrib/amd/amd/sun2amd.8
new file mode 100644
index 000000000000..67d241f32cdb
--- /dev/null
+++ b/contrib/amd/amd/sun2amd.8
@@ -0,0 +1,92 @@
+.\"
+.\" 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>
diff --git a/contrib/amd/amd/sun2amd.c b/contrib/amd/amd/sun2amd.c
new file mode 100644
index 000000000000..ee6fbb59626f
--- /dev/null
+++ b/contrib/amd/amd/sun2amd.c
@@ -0,0 +1,203 @@
+/*
+ * 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);
+}
diff --git a/contrib/amd/amd/sun_map.c b/contrib/amd/amd/sun_map.c
new file mode 100644
index 000000000000..8e3559960cd3
--- /dev/null
+++ b/contrib/amd/amd/sun_map.c
@@ -0,0 +1,595 @@
+/*
+ * 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;
+}
diff --git a/contrib/amd/amd/sun_map.h b/contrib/amd/amd/sun_map.h
new file mode 100644
index 000000000000..75e707ae7003
--- /dev/null
+++ b/contrib/amd/amd/sun_map.h
@@ -0,0 +1,123 @@
+/*
+ * 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 */
diff --git a/contrib/amd/amd/sun_map_parse.y b/contrib/amd/amd/sun_map_parse.y
new file mode 100644
index 000000000000..ccf258e2dcc8
--- /dev/null
+++ b/contrib/amd/amd/sun_map_parse.y
@@ -0,0 +1,492 @@
+%{
+/*
+ * 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;
+}
diff --git a/contrib/amd/amd/sun_map_tok.l b/contrib/amd/amd/sun_map_tok.l
new file mode 100644
index 000000000000..f979bea4cf1f
--- /dev/null
+++ b/contrib/amd/amd/sun_map_tok.l
@@ -0,0 +1,233 @@
+%{
+/*
+ * 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 */
diff --git a/contrib/amd/amd/test1.sh b/contrib/amd/amd/test1.sh
new file mode 100755
index 000000000000..44cafbcbc71e
--- /dev/null
+++ b/contrib/amd/amd/test1.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+./amd -v 2> /dev/null
diff --git a/contrib/amd/amq/amq.8 b/contrib/amd/amq/amq.8
index c9fb265e9ab2..4cfdf84423be 100644
--- a/contrib/amd/amq/amq.8
+++ b/contrib/amd/amq/amq.8
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 1997-2006 Erez Zadok
+.\" 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.
@@ -16,11 +16,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 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.
.\"
@@ -36,12 +32,11 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" %W% (Berkeley) %G%
.\"
-.\" $Id: amq.8,v 1.15.2.1 2006/01/02 18:48:24 ezk Exp $
+.\" File: am-utils/amq/amq.8
.\" $FreeBSD$
.\"
-.Dd February 26, 2016
+.Dd August 31, 2016
.Dt AMQ 8
.Os
.Sh NAME
@@ -49,7 +44,7 @@
.Nd automounter query tool
.Sh SYNOPSIS
.Nm
-.Op Fl fmpsvwHTU
+.Op Fl fimpqsvwHTU
.Op Fl h Ar hostname
.Op Fl l Ar log_file
.Op Fl x Ar log_options
@@ -96,6 +91,10 @@ 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
@@ -126,6 +125,13 @@ 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
@@ -138,9 +144,19 @@ 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
+Ask the automounter for its version information. This is a subset of the
information output by
.Xr amd 8 Ns 's
.Fl v
@@ -157,8 +173,10 @@ is running.
.It Fl x Ar log_options
Ask the automounter to use the logging options specified in
.Ar log_options
-from now on.
+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.
@@ -244,11 +262,13 @@ add this line to
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 hosts_access 5 .
+.Xr amd 8 ,
+.\" .Xr ctl-amd 8 ,
.Pp
.Dq am-utils
.Xr info 1
diff --git a/contrib/amd/amq/amq.c b/contrib/amd/amq/amq.c
index 2379b6214766..e99732fded5b 100644
--- a/contrib/amd/amq/amq.c
+++ b/contrib/amd/amq/amq.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -53,14 +49,17 @@
/* locals */
static int flush_flag;
-static int minfo_flag;
static int getpid_flag;
-static int unmount_flag;
-static int stats_flag;
-static int getvers_flag;
-static int amd_program_number = AMQ_PROGRAM;
-static int use_tcp_flag, use_udp_flag;
static 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;
@@ -77,6 +76,17 @@ enum show_opt {
};
+static void
+time_print(time_type tt)
+{
+ time_t t = (time_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
@@ -101,8 +111,7 @@ show_mti(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, int *twid)
case Full:
{
- struct tm *tp = localtime((time_t *) ((voidp) &mt->mt_mounttime));
- printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%04d %02d:%02d:%02d\n",
+ printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d",
*dwid, *dwid,
*mt->mt_directory ? mt->mt_directory : "/", /* XXX */
*twid, *twid,
@@ -116,18 +125,15 @@ show_mti(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, int *twid)
mt->mt_lookup,
mt->mt_readdir,
mt->mt_readlink,
- mt->mt_statfs,
-
- 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);
+ mt->mt_statfs);
+ time_print(mt->mt_mounttime);
+ printf("\n");
}
break;
case Stats:
{
- struct tm *tp = localtime((time_t *) ((voidp) &mt->mt_mounttime));
- printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%04d\n",
+ printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d ",
*dwid, *dwid,
*mt->mt_directory ? mt->mt_directory : "/", /* XXX */
@@ -136,11 +142,9 @@ show_mti(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, int *twid)
mt->mt_lookup,
mt->mt_readdir,
mt->mt_readlink,
- mt->mt_statfs,
-
- 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);
+ mt->mt_statfs);
+ time_print(mt->mt_mounttime);
+ printf("\n");
}
break;
@@ -229,7 +233,7 @@ show_mi(amq_mount_info_list *ml, enum show_opt e, int *mwid, int *dwid, int *twi
{
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",
+ printf("%-*.*s %-*.*s %-*.*s %-3d %s is %s ",
*mwid, *mwid, mi->mi_mountinfo,
*dwid, *dwid, mi->mi_mountpt,
*twid, *twid, mi->mi_type,
@@ -251,6 +255,55 @@ show_mi(amq_mount_info_list *ml, enum show_opt e, int *mwid, int *dwid, int *twi
}
}
+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
@@ -287,6 +340,72 @@ cluster_server(void)
#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
*/
@@ -320,7 +439,7 @@ main(int argc, char *argv[])
/*
* Parse arguments
*/
- while ((opt_ch = getopt(argc, argv, "Hfh:l:msuvx:D:pP:TUw")) != -1)
+ while ((opt_ch = getopt(argc, argv, "Hfh:il:mqsuvx:D:pP:TUw")) != -1)
switch (opt_ch) {
case 'H':
goto show_usage;
@@ -335,6 +454,11 @@ main(int argc, char *argv[])
def_server = optarg;
break;
+ case 'i':
+ mapinfo_flag = 1;
+ nodefault = 1;
+ break;
+
case 'l':
amq_logfile = optarg;
nodefault = 1;
@@ -350,13 +474,18 @@ main(int argc, char *argv[])
nodefault = 1;
break;
+ case 'q':
+ quiet_flag = 1;
+ nodefault = 1;
+ break;
+
case 's':
stats_flag = 1;
nodefault = 1;
break;
case 'u':
- unmount_flag = 1;
+ unmount_flag++;
nodefault = 1;
break;
@@ -403,9 +532,9 @@ main(int argc, char *argv[])
if (errs) {
show_usage:
fprintf(stderr, "\
-Usage: %s [-fmpsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\
+Usage: %s [-fimpqsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\
\t[-x log_options] [-D debug_options]\n\
-\t[-P program_number] [[-u] directory ...]\n",
+\t[-P program_number] [[-u[u]] directory ...]\n",
am_get_progname()
);
exit(1);
@@ -538,16 +667,19 @@ Usage: %s [-fmpsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\
*/
if (getpwd_flag) {
char path[MAXPATHLEN+1];
- char *wd = getcwd(path, MAXPATHLEN+1);
- amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt);
+ char *wd;
+ amq_mount_tree_list *mlp;
amq_mount_tree_p mt;
u_int i;
int flag;
+ wd = getcwd(path, MAXPATHLEN+1);
if (!wd) {
- perror("getcwd");
+ 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) {
@@ -582,6 +714,26 @@ Usage: %s [-fmpsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\
}
}
+
+ /*
+ * 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
*/
@@ -616,7 +768,20 @@ Usage: %s [-fmpsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\
if (optind < argc) {
do {
char *fs = argv[optind++];
- if (unmount_flag) {
+ 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
*/
@@ -641,9 +806,7 @@ Usage: %s [-fmpsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\
}
xdr_pri_free((XDRPROC_T_TYPE) xdr_amq_mount_tree_p, (caddr_t) mtp);
} else {
- fprintf(stderr, "%s: ", am_get_progname());
- clnt_perror(clnt, server);
- errs = 1;
+ errs = clnt_failed(clnt, server);
}
}
} while (optind < argc);
@@ -656,9 +819,7 @@ Usage: %s [-fmpsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\
if (ms) {
show_ms(ms);
} else {
- fprintf(stderr, "%s: ", am_get_progname());
- clnt_perror(clnt, server);
- errs = 1;
+ errs = clnt_failed(clnt, server);
}
} else if (!nodefault) {
@@ -682,9 +843,7 @@ Usage: %s [-fmpsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\
}
} else {
- fprintf(stderr, "%s: ", am_get_progname());
- clnt_perror(clnt, server);
- errs = 1;
+ errs = clnt_failed(clnt, server);
}
}
exit(errs);
diff --git a/contrib/amd/amq/amq.h b/contrib/amd/amq/amq.h
index 2f36b8194456..3c894d687f50 100644
--- a/contrib/amd/amq/amq.h
+++ b/contrib/amd/amq/amq.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -51,10 +47,12 @@
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);
diff --git a/contrib/amd/amq/amq_clnt.c b/contrib/amd/amq/amq_clnt.c
index ddfeb675c99b..c5f1e87d97f8 100644
--- a/contrib/amd/amq/amq_clnt.c
+++ b/contrib/amd/amq/amq_clnt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -99,6 +95,23 @@ amqproc_umnt_1(amq_string *argp, CLIENT *clnt)
}
+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)
{
@@ -161,6 +174,20 @@ amqproc_getmntfs_1(voidp argp, CLIENT *clnt)
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)
diff --git a/contrib/amd/amq/amq_xdr.c b/contrib/amd/amq/amq_xdr.c
index 692a0a408607..b9a1c20fbf11 100644
--- a/contrib/amd/amq/amq_xdr.c
+++ b/contrib/amd/amq/amq_xdr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -187,6 +183,59 @@ xdr_amq_mount_info_list(XDR *xdrs, amq_mount_info_list *objp)
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)
diff --git a/contrib/amd/amq/pawd.1 b/contrib/amd/amq/pawd.1
index 8549434b219c..5e5e84bc0913 100644
--- a/contrib/amd/amq/pawd.1
+++ b/contrib/amd/amq/pawd.1
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 1997-2006 Erez Zadok
+.\" 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.
@@ -16,11 +16,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 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.
.\"
@@ -36,9 +32,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" %W% (Berkeley) %G%
.\"
-.\" $Id: pawd.1,v 1.9.2.1 2006/01/02 18:48:24 ezk Exp $
+.\" File: am-utils/amq/pawd.1
.\" $FreeBSD$
.\"
.Dd February 26, 2016
diff --git a/contrib/amd/amq/pawd.c b/contrib/amd/amq/pawd.c
index c9a32b16189b..bab6657521ba 100644
--- a/contrib/amd/amq/pawd.c
+++ b/contrib/amd/amq/pawd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/bootstrap b/contrib/amd/bootstrap
index 6c351382caa5..000b01670abf 100755
--- a/contrib/amd/bootstrap
+++ b/contrib/amd/bootstrap
@@ -5,6 +5,16 @@
# this is not meant to go into the distributions
# Erez Zadok <ezk@cs.columbia.edu>
+validateversion() {
+ local v="$(autoreconf --version 2>&1 | head -1)"
+ case "$v" in
+ *2.69) ;;
+ *) echo "am-utils requires autoconf 2.69, you have:"
+ echo " $v"
+ exit 1;;
+ esac
+}
+
# test cwd
test -f ../amd/amd.c && cd ..
if [ ! -f amd/amd.c ]; then
@@ -37,67 +47,13 @@ test -f acinclude.m4 && mv -f acinclude.m4 acinclude.m4.old
cat TRAILER
) > acinclude.m4
-# generate aclocal.m4 file
-echo "AMU: aclocal..."
-test -f aclocal.m4 && mv -f aclocal.m4 aclocal.m4.old
-# show version
-aclocal --version 2>&1 | head -1
-if aclocal ; then
- :
-else
- echo "aclocal command failed. fix errors and rerun $0."
- exit 2
-fi
-
-# produce new configure.in (temp) script
-echo "AMU: autoconf..."
-# show version
-autoconf --version 2>&1 | head -1
-LOG=/tmp/amu-$$.log
-rm -f ${LOG}
-autoconf configure.in > configure.new 2> ${LOG}
-# until Automake requires Autoconf 2.50, manual says to ignore this
-CUTWARNMSG1="warning: AC_PROG_LEX invoked multiple times|do not use m4_(patsubst|regexp):"
-egrep -v "${CUTWARNMSG1}" ${LOG} > ${LOG}.new
-mv ${LOG}.new ${LOG}
-if test -s ${LOG}; then
- echo "AUTOCONF ERRORS (MUST FIX):"
- cat ${LOG}
- rm -f ${LOG}
- exit 2
-fi
-# now prepare the real configure script
-test -f configure && mv -f configure configure.old
-mv -f configure.new configure
-chmod a+rx configure
-rm -f configure.old
-
-# run autoheader to produce C header .in files
-echo "AMU: autoheader..."
-# show version
-autoheader --version 2>&1 | head -1
-autoheader configure.in > config.h.in 2> ${LOG}
-CUTWARNMSG2="autoheader: \`config.h.in' is updated"
-egrep -v "${CUTWARNMSG2}" ${LOG} > ${LOG}.new
-mv ${LOG}.new ${LOG}
-if test -s ${LOG}; then
- echo "AUTOHEADER ERRORS (MUST FIX):"
- cat ${LOG}
- rm -f ${LOG}
- exit 2
-fi
-rm -f ${LOG}
-
-# generate makefiles
-cmd="automake --add-missing --copy --ignore-deps"
-#cmd="automake --add-missing"
-echo "AMU: $cmd..."
-# show version
-automake --version 2>&1 | head -1
-if ${cmd} ; then
+# generate the rest of the scripts
+echo "AMU: autoreconf..."
+validateversion
+if autoreconf -f -i; then
:
else
- echo "automake command failed. fix errors and rerun $0."
+ echo "autoreconf command failed. fix errors and rerun $0."
exit 2
fi
diff --git a/contrib/amd/conf/checkmount/checkmount_bsd44.c b/contrib/amd/conf/checkmount/checkmount_bsd44.c
index a6ec2438da88..6c6b21dcb4a2 100644
--- a/contrib/amd/conf/checkmount/checkmount_bsd44.c
+++ b/contrib/amd/conf/checkmount/checkmount_bsd44.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -45,6 +41,9 @@
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
+#if __NetBSD_Version__ > 200030000
+#define statfs statvfs
+#endif
extern int is_same_host(char *name1, char *name2, struct in_addr addr2);
int fixmount_check_mount(char *host, struct in_addr hostaddr, char *path);
diff --git a/contrib/amd/conf/mtab/mtab_bsd.c b/contrib/amd/conf/mtab/mtab_bsd.c
index fe3991aa575d..203a265e13af 100644
--- a/contrib/amd/conf/mtab/mtab_bsd.c
+++ b/contrib/amd/conf/mtab/mtab_bsd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -53,6 +49,9 @@
#include <am_defs.h>
#include <amu.h>
+#if __NetBSD_Version__ > 200030000
+#define statfs statvfs
+#endif
static mntent_t *
mnt_dup(struct statfs *mp)
@@ -60,8 +59,8 @@ mnt_dup(struct statfs *mp)
mntent_t *new_mp = ALLOC(mntent_t);
char *ty;
- new_mp->mnt_fsname = strdup(mp->f_mntfromname);
- new_mp->mnt_dir = strdup(mp->f_mntonname);
+ new_mp->mnt_fsname = xstrdup(mp->f_mntfromname);
+ new_mp->mnt_dir = xstrdup(mp->f_mntonname);
#ifdef HAVE_STRUCT_STATFS_F_FSTYPENAME
ty = mp->f_fstypename;
@@ -93,8 +92,8 @@ mnt_dup(struct statfs *mp)
}
#endif /* not HAVE_STRUCT_STATFS_F_FSTYPENAME */
- new_mp->mnt_type = strdup(ty);
- new_mp->mnt_opts = strdup("unset");
+ new_mp->mnt_type = xstrdup(ty);
+ new_mp->mnt_opts = xstrdup("unset");
new_mp->mnt_freq = 0;
new_mp->mnt_passno = 0;
@@ -138,7 +137,7 @@ read_mtab(char *fs, const char *mnttabname)
/*
* Terminate the list
*/
- *mpp = 0;
+ *mpp = NULL;
return mhp;
}
diff --git a/contrib/amd/conf/nfs_prot/nfs_prot_freebsd2.h b/contrib/amd/conf/nfs_prot/nfs_prot_freebsd2.h
index cf7ba33ee47b..73661c9da3d8 100644
--- a/contrib/amd/conf/nfs_prot/nfs_prot_freebsd2.h
+++ b/contrib/amd/conf/nfs_prot/nfs_prot_freebsd2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -139,7 +135,7 @@ typedef writeargs nfswriteargs;
*/
#if 0
#define MOUNT_NFS3 MOUNT_NFS
-#endif
+#endif /* 0 */
#endif /* not _AMU_NFS_PROT_H */
diff --git a/contrib/amd/conf/nfs_prot/nfs_prot_freebsd3.h b/contrib/amd/conf/nfs_prot/nfs_prot_freebsd3.h
index 4e1e84a42f81..a415b8bab8f5 100644
--- a/contrib/amd/conf/nfs_prot/nfs_prot_freebsd3.h
+++ b/contrib/amd/conf/nfs_prot/nfs_prot_freebsd3.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -103,9 +99,11 @@ struct ufs_extattr_per_mount;
#define na_ctime ctime
#define na_fileid fileid
#define na_fsid fsid
+#define na_gid gid
#define na_mode mode
#define na_mtime mtime
#define na_nlink nlink
+#define na_rdev rdev
#define na_size size
#define na_type type
#define na_uid uid
diff --git a/contrib/amd/conf/transp/transp_sockets.c b/contrib/amd/conf/transp/transp_sockets.c
index 025e1f3e3cf2..b3ad5fc5cbd3 100644
--- a/contrib/amd/conf/transp/transp_sockets.c
+++ b/contrib/amd/conf/transp/transp_sockets.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -171,7 +167,7 @@ get_mount_client(char *unused_host, struct sockaddr_in *sin, struct timeval *tv,
/*
* Bind to a privileged port
*/
- if (bind_resv_port(*sock, (u_short *) 0) < 0)
+ if (bind_resv_port(*sock, (u_short *) NULL) < 0)
plog(XLOG_ERROR, "can't bind privileged port (socket)");
/*
@@ -198,7 +194,7 @@ get_mount_client(char *unused_host, struct sockaddr_in *sin, struct timeval *tv,
/*
* Bind to a privileged port
*/
- if (bind_resv_port(*sock, (u_short *) 0) < 0)
+ if (bind_resv_port(*sock, (u_short *) NULL) < 0)
plog(XLOG_ERROR, "can't bind privileged port");
/*
@@ -231,13 +227,15 @@ amu_svc_getcaller(SVCXPRT *xprt)
/*
- * register an RPC server
+ * Register an RPC server:
+ * return 1 on success, 0 otherwise.
*/
int
amu_svc_register(SVCXPRT *xprt, u_long prognum, u_long versnum,
void (*dispatch)(struct svc_req *rqstp, SVCXPRT *transp),
u_long protocol, struct netconfig *dummy)
{
+ /* on Sockets: svc_register returns 1 on success, 0 otherwise */
return svc_register(xprt, prognum, versnum, dispatch, protocol);
}
@@ -246,9 +244,8 @@ amu_svc_register(SVCXPRT *xprt, u_long prognum, u_long versnum,
* Create the nfs service for amd
*/
int
-create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp))
+create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp), u_long nfs_version)
{
-
*soNFSp = socket(AF_INET, SOCK_DGRAM, 0);
if (*soNFSp < 0 || bind_resv_port(*soNFSp, nfs_portp) < 0) {
@@ -268,9 +265,9 @@ create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*
close(*soNFSp);
return 1;
}
- if (!svc_register(*nfs_xprtp, NFS_PROGRAM, NFS_VERSION, dispatch_fxn, 0)) {
- plog(XLOG_FATAL, "unable to register (%ld, %ld, 0)",
- (u_long) NFS_PROGRAM, (u_long) NFS_VERSION);
+ if (!svc_register(*nfs_xprtp, NFS_PROGRAM, nfs_version, dispatch_fxn, 0)) {
+ plog(XLOG_FATAL, "unable to register (%lu, %lu, 0)",
+ (u_long) NFS_PROGRAM, nfs_version);
svc_destroy(*nfs_xprtp);
close(*soNFSp);
return 3;
@@ -386,8 +383,8 @@ int check_pmap_up(char *host, struct sockaddr_in* sin)
if (client == (CLIENT *) NULL) {
plog(XLOG_ERROR,
- "check_pmap_up: cannot create connection to contact portmapper on host \"%s\"%s",
- host, clnt_spcreateerror(""));
+ "%s: cannot create connection to contact portmapper on host \"%s\"%s",
+ __func__, host, clnt_spcreateerror(""));
return 0;
}
@@ -406,8 +403,8 @@ int check_pmap_up(char *host, struct sockaddr_in* sin)
if (clnt_stat == RPC_TIMEDOUT) {
plog(XLOG_ERROR,
- "check_pmap_up: failed to contact portmapper on host \"%s\": %s",
- host, clnt_sperrno(clnt_stat));
+ "%s: failed to contact portmapper on host \"%s\": %s",
+ __func__, host, clnt_sperrno(clnt_stat));
return 0;
}
return 1;
@@ -418,7 +415,7 @@ int check_pmap_up(char *host, struct sockaddr_in* sin)
* Find the best NFS version for a host and protocol.
*/
u_long
-get_nfs_version(char *host, struct sockaddr_in *sin, u_long nfs_version, const char *proto)
+get_nfs_version(char *host, struct sockaddr_in *sin, u_long nfs_version, const char *proto, u_long def)
{
CLIENT *clnt;
int again = 0;
@@ -431,68 +428,64 @@ get_nfs_version(char *host, struct sockaddr_in *sin, u_long nfs_version, const c
* If not set or set wrong, then try from NFS_VERS_MAX on down. If
* set, then try from nfs_version on down.
*/
- if (nfs_version <= 0 || nfs_version > NFS_VERS_MAX) {
- nfs_version = NFS_VERS_MAX;
+ if (!nfs_valid_version(nfs_version)) {
+ if (nfs_valid_version(def))
+ nfs_version = def;
+ else
+ nfs_version = NFS_VERS_MAX;
again = 1;
}
tv.tv_sec = 2; /* retry every 2 seconds, but also timeout */
tv.tv_usec = 0;
-#ifdef HAVE_FS_NFS3
-try_again:
-#endif /* HAVE_FS_NFS3 */
-
- sock = RPC_ANYSOCK;
- errstr = NULL;
- if (STREQ(proto, "tcp"))
- clnt = clnttcp_create(sin, NFS_PROGRAM, nfs_version, &sock, 0, 0);
- else if (STREQ(proto, "udp"))
- clnt = clntudp_create(sin, NFS_PROGRAM, nfs_version, tv, &sock);
- else
- clnt = NULL;
-
- if (clnt != NULL) {
- /* Try three times (6/2=3) to verify the CLIENT handle. */
- tv.tv_sec = 6;
- clnt_stat = clnt_call(clnt,
- NFSPROC_NULL,
- (XDRPROC_T_TYPE) xdr_void,
- 0,
- (XDRPROC_T_TYPE) xdr_void,
- 0,
- tv);
-
- if (clnt_stat != RPC_SUCCESS)
- errstr = clnt_sperrno(clnt_stat);
-
- close(sock);
- clnt_destroy(clnt);
- } else {
-#ifdef HAVE_CLNT_SPCREATEERROR
- errstr = clnt_spcreateerror("");
-#else /* not HAVE_CLNT_SPCREATEERROR */
- errstr = "";
-#endif /* not HAVE_CLNT_SPCREATEERROR */
- }
+ for (; nfs_version >= NFS_VERS_MIN; nfs_version--) {
+
+ sock = RPC_ANYSOCK;
+ errstr = NULL;
+ if (STREQ(proto, "tcp"))
+ clnt = clnttcp_create(sin, NFS_PROGRAM, nfs_version, &sock, 0, 0);
+ else if (STREQ(proto, "udp"))
+ clnt = clntudp_create(sin, NFS_PROGRAM, nfs_version, tv, &sock);
+ else
+ clnt = NULL;
+
+ if (clnt != NULL) {
+ /* Try three times (6/2=3) to verify the CLIENT handle. */
+ tv.tv_sec = 6;
+ clnt_stat = clnt_call(clnt,
+ NFSPROC_NULL,
+ (XDRPROC_T_TYPE) xdr_void,
+ 0,
+ (XDRPROC_T_TYPE) xdr_void,
+ 0,
+ tv);
+
+ if (clnt_stat != RPC_SUCCESS)
+ errstr = clnt_sperrno(clnt_stat);
+
+ close(sock);
+ clnt_destroy(clnt);
+ if (clnt_stat == RPC_SUCCESS)
+ break;
+ } else {
+ #ifdef HAVE_CLNT_SPCREATEERROR
+ errstr = clnt_spcreateerror("");
+ #else /* not HAVE_CLNT_SPCREATEERROR */
+ errstr = "";
+ #endif /* not HAVE_CLNT_SPCREATEERROR */
+ }
- if (errstr) {
- plog(XLOG_INFO, "get_nfs_version NFS(%d,%s) failed for %s%s",
- (int) nfs_version, proto, host, errstr);
- if (again) {
-#ifdef HAVE_FS_NFS3
- if (nfs_version == NFS_VERSION3) {
- nfs_version = NFS_VERSION;
- again = 0;
- plog(XLOG_INFO, "get_nfs_version trying a lower version: NFS(%d,%s)", (int) nfs_version, proto);
- }
- goto try_again;
-#endif /* HAVE_FS_NFS3 */
+ if (errstr) {
+ plog(XLOG_INFO, "%s: NFS(%lu,%s) failed for %s: %s", __func__,
+ nfs_version, proto, host, errstr);
}
- return 0;
}
- plog(XLOG_INFO, "get_nfs_version: returning NFS(%d,%s) on host %s",
- (int) nfs_version, proto, host);
+ if (nfs_version < NFS_VERS_MIN)
+ nfs_version = 0;
+
+ plog(XLOG_INFO, "%s: returning NFS(%lu,%s) on host %s", __func__,
+ nfs_version, proto, host);
return nfs_version;
}
diff --git a/contrib/amd/conf/umount/umount_bsd44.c b/contrib/amd/conf/umount/umount_bsd44.c
index d05944d8f788..da4412977989 100644
--- a/contrib/amd/conf/umount/umount_bsd44.c
+++ b/contrib/amd/conf/umount/umount_bsd44.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -105,6 +101,7 @@ int
umount2_fs(const char *mntdir, u_int unmount_flags)
{
int error = 0;
+
if (unmount_flags & AMU_UMOUNT_FORCE) {
plog(XLOG_INFO, "umount2_fs: trying unmount/forced on %s", mntdir);
error = unmount(mntdir, MNT2_GEN_OPT_FORCE);
diff --git a/contrib/amd/doc/am-utils.texi b/contrib/amd/doc/am-utils.texi
index 1cc46b608bae..2430bafa4821 100644
--- a/contrib/amd/doc/am-utils.texi
+++ b/contrib/amd/doc/am-utils.texi
@@ -1,6 +1,6 @@
\input texinfo @c -*-texinfo-*-
@c
-@c Copyright (c) 1997-2006 Erez Zadok
+@c Copyright (c) 1997-2014 Erez Zadok
@c Copyright (c) 1989 Jan-Simon Pendry
@c Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@c Copyright (c) 1989 The Regents of the University of California.
@@ -17,11 +17,7 @@
@c 2. Redistributions in binary form must reproduce the above copyright
@c notice, this list of conditions and the following disclaimer in the
@c documentation and/or other materials provided with the distribution.
-@c 3. All advertising materials mentioning features or use of this software
-@c must display the following acknowledgment:
-@c This product includes software developed by the University of
-@c California, Berkeley and its contributors.
-@c 4. Neither the name of the University nor the names of its contributors
+@c 3. Neither the name of the University nor the names of its contributors
@c may be used to endorse or promote products derived from this software
@c without specific prior written permission.
@c
@@ -60,14 +56,14 @@
(Originally by Jan-Simon Pendry and Nick Williams)
@page
-Copyright @copyright{} 1997-2006 Erez Zadok
+Copyright @copyright{} 1997-2014 Erez Zadok
@*
Copyright @copyright{} 1989 Jan-Simon Pendry
@*
Copyright @copyright{} 1989 Imperial College of Science, Technology & Medicine
@*
Copyright @copyright{} 1989 The Regents of the University of California.
-@sp
+@sp 1
All Rights Reserved.
@vskip 1ex
Permission to copy this document, or any portion of it, as
@@ -93,7 +89,7 @@ For version @value{VERSION}, @value{UPDATED}
@*
(Originally by Jan-Simon Pendry and Nick Williams)
-Copyright @copyright{} 1997-2006 Erez Zadok
+Copyright @copyright{} 1997-2014 Erez Zadok
@*
Copyright @copyright{} 1989 Jan-Simon Pendry
@*
@@ -179,16 +175,6 @@ notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
@item
-All advertising materials mentioning features or use of this software
-must display the following acknowledgment:
-
-@cartouche
-``This product includes software developed by the University of
-California, Berkeley and its contributors, as well as the Trustees of
-Columbia University.''
-@end cartouche
-
-@item
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.
@@ -234,7 +220,7 @@ Revision 5.3bsdnet, a late alpha version of 5.3, was part
of the BSD network version 2 distribution
Revision 6.0 was made independently by
-@email{ezk@@cs.columbia.edu,Erez Zadok} at the Computer Science
+Erez Zadok at the Computer Science
Department of @uref{http://www.cs.columbia.edu/,Columbia University},
as part of his
@uref{http://www.fsl.cs.sunysb.edu/docs/zadok-thesis-proposal/,PhD
@@ -262,7 +248,8 @@ If you find a problem and hopefully you can reproduce it, please
describe it in detail and
@uref{https://bugzilla.filesystems.org/,submit a bug report} via
@uref{http://www.bugzilla.org/,Bugzilla}. Alternatively, you can send
-your bug report to @email{am-utils@@am-utils.org} quoting the details
+your bug report to the ``am-utils'' list (see
+@url{http://www.am-utils.org/} under ``Mailing Lists'') quoting the details
of the release and your configuration. These details can be obtained
by running the command @samp{amd -v}. It would greatly help if you
could provide a reproducible procedure for detecting the bug you are
@@ -297,11 +284,10 @@ discussions of new features for am-utils
implementation and porting issues
@end itemize
-To subscribe, visit
-@url{http://lists.am-utils.org/mailman/listinfo/am-utils}. After
-subscribing, you can post a message to this list at
-@email{am-utils@@am-utils.org}. To avoid as much spam as
-possible, only subscribers to this list may post to it.
+To subscribe, visit @url{http://www.am-utils.org/} under ``Mailing
+Lists.'' After subscribing, you can post a message to this list. To
+avoid as much spam as possible, only subscribers to this list may post
+to it.
Subscribers of @samp{am-utils} are most helpful if they have the time
and resources to test new and development versions of amd, on as many
@@ -318,7 +304,7 @@ before January 1st, 2004. Please use the new name, @samp{am-utils}.
@item
The announcements mailing list, @samp{am-utils-announce} is for
announcements only (mostly new releases). To subscribe, visit
-@url{http://lists.am-utils.org/mailman/listinfo/am-utils-announce}.
+@url{http://www.am-utils.org/} under ``Mailing Lists.''
This list is read-only: only am-utils developers may post to it.
@item
@@ -326,17 +312,18 @@ We distribute nightly CVS snapshots in
@url{ftp://ftp.am-utils.org/pub/am-utils/snapshots/daily/}. If you
like to get email notices of commits to the am-utils CVS repository,
subscribe to the CVS logs mailing list, @samp{am-utils-cvs} at
-@url{http://lists.am-utils.org/mailman/listinfo/am-utils-cvs}.
+@url{http://www.am-utils.org/} under ``Mailing Lists.''
@item
The older list which was used to user discussions, @samp{amd-workers},
is defunct as of January 2004. (Its last address was
-@email{amd-workers@@majordomo.glue.umd.edu}.) Don't use
+@email{amd-workers AT majordomo.glue.umd.edu}.) Don't use
@samp{amd-workers}: use the newer, more active @samp{am-utils} list.
@item
For completeness, there's a developers-only closed list called
-@samp{am-utils-developers@@am-utils.org}.
+@samp{am-utils-developers} (see @url{http://www.am-utils.org/} under
+``Mailing Lists'').
@end enumerate
@@ -346,7 +333,7 @@ For completeness, there's a developers-only closed list called
@cindex Automounter book
@cindex book
-@email{ezk@@cs.sunysb.edu,Erez Zadok} wrote a
+@uref{http://www.cs.sunysb.edu/~ezk,Erez Zadok} wrote a
@uref{http://www.fsl.cs.sunysb.edu/docs/amd-book/,book}, titled @i{Linux NFS and
Automounter Administration}, ISBN 0-7821-2739-8, (Sybex, 2001). The
book is full of details and examples that go beyond what this manual
@@ -389,7 +376,7 @@ numerous flavors of Unix.
The @i{Amd} package has been without an official maintainer since 1992.
Several people have stepped in to maintain it unofficially. Most
notable were the `upl' (Unofficial Patch Level) releases of @i{Amd},
-created by me (@email{ezk@@cs.sunysb.edu,Erez Zadok}), and available from
+created by me (@uref{http://www.cs.sunysb.edu/~ezk,Erez Zadok}), and available from
@url{ftp://ftp.am-utils.org/pub/amd/}. The last such unofficial
release was `upl102'.
@@ -428,7 +415,7 @@ end-user, aside from the fact that @code{/bin/pwd} now always returns
the correct amd-ified path. The administrator can easily switch
between NFS and autofs mounts by changing one parameter in
@code{amd.conf}. Autofs support and maintenance was developed in
-conjunction with @email{ionut@@badula.org,Ion Badulescu}.
+conjunction with @email{ionut AT badula.org,Ion Badulescu}.
@c ################################################################
@node Overview, Supported Platforms, History, Top
@@ -1040,7 +1027,7 @@ Similarly, if the password file entry was
the map entry used by @i{Amd} would be
@example
-rfs:=/home/sugar;rhost:=sugar.cc;sublink:=jsp
+rfs:=/home/sugar;rhost:=sugar.cc;sublink:=mhj
@end example
@c ----------------------------------------------------------------
@@ -1795,8 +1782,8 @@ Always evaluates to false. @i{ARG} is ignored.
The argument @i{ARG} of this selector is a netgroup name followed
optionally by a comma and a host name. If the host name is not
specified, it defaults to @code{$@{host@}}. If the host name (short
-name) is a member of the netgroup, this selector evaluates to
-true. Otherwise it evaluates to false.
+name) is a member of the netgroup, this selector evaluates to true.
+Otherwise it evaluates to false.
For example, suppose you have a netgroup @samp{ppp-hosts}, and for
reasons of performance, these have a local @file{/home} partition,
@@ -2098,6 +2085,10 @@ Ignore this mount by @b{df}(1).
@cindex Mount flags; cache
Allow data to be cached from a remote server for this mount.
+@item closesession
+@cindex Mount flags; closesession
+For UDF mounts, close the session when unmounting.
+
@item compress
@cindex Mount flags; compress
Use NFS compression protocol.
@@ -2137,10 +2128,16 @@ Set ID of filesystem.
Enable generations in ISO-9660 file systems. Generations allow you to
see all versions of a given file.
+@item gmtoff=@var{n}
+@cindex Mount flags; gmtoff
+For UDF mounts, set the time zone offset from UTC to @var{n} seconds,
+with positive values indicating east of the Prime Meridian. If not
+set, the user's current time zone will be used.
+
@item group=@var{n}
@cindex Mount flags; group
-For PCFS mounts, set the group of the files in the file system to
-@var{n} (which can either be a group name or a GID number). The
+For PCFS and UDF mounts, set the group of the files in the file system
+to @var{n} (which can either be a group name or a GID number). The
default group is the group of the directory on which the file system
is being mounted.
@@ -2199,6 +2196,11 @@ is used.
Do not allow data to be cached from a remote server for this
mount.
+@item nocasetrans
+@cindex Mount flags; nocasetrans
+Don't do case translation. Useful for CD-ROMS formatted as
+ISO-9660.
+
@item noconn
@cindex Mount flags; noconn
Don't make a connection on datagram transports.
@@ -2226,6 +2228,10 @@ Don't allow program execution.
@cindex Mount flags; noint
Do not allow keyboard interrupts for this mount
+@item nojoliet
+@cindex Mount flags; nojoliet
+Turn off the Joliet extensions. Useful for CD-ROMS formatted as ISO-9660.
+
@item nolock
@cindex Mount flags; nolock
Do not use the NFS locking protocol
@@ -2320,6 +2326,11 @@ trying}.
@cindex Mount flags; retry
Set the NFS retry counter.
+@item rrcaseins
+@cindex Mount flags; rrcaseins
+Enable the Rock Ridge Interchange Protocol (RRIP) case insensitive extensions.
+Useful for CD-ROMS formatted as ISO-9660.
+
@item rrip
@cindex Mount flags; rrip
Uses the Rock Ridge Interchange Protocol (RRIP) extensions to ISO-9660.
@@ -2333,6 +2344,10 @@ NFS/UDP through a gateway or a slow link.
@cindex Mount flags; rw
Allow reads and writes on this filesystem.
+@item sessionnr=@var{n}
+@cindex Mount Flags; sessionnr
+For multisession UDF mounts, use session number @var{n} when mounting.
+
@item shortname
@cindex Mount Flags; longname
For PCFS mounts, force old DOS short names only.
@@ -2368,8 +2383,8 @@ The NFS timeout, in tenth-seconds, before a request is retransmitted.
@item user=@var{n}
@cindex Mount flags; user
-For PCFS mounts, set the owner of the files in the file system to
-@var{n} (which can either be a user name or a UID number). The
+For PCFS and UDF mounts, set the owner of the files in the file system
+to @var{n} (which can either be a user name or a UID number). The
default owner is the owner of the directory on which the file system
is being mounted.
@@ -2824,13 +2839,13 @@ 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.
am-utils version 6.0a15 (build 61).
-Built by ezk@@cs.columbia.edu on date Wed Oct 22 15:21:03 EDT 1997.
+Built by ezk@@example.com on date Wed Oct 22 15:21:03 EDT 1997.
cpu=sparc (big-endian), arch=sun4, karch=sun4u.
full_os=solaris2.5.1, os=sos5, osver=5.5.1, vendor=sun.
Map support for: root, passwd, union, nisplus, nis, ndbm, file, error.
AMFS: nfs, link, nfsx, nfsl, host, linkx, program, union, inherit,
ufs, lofs, hsfs, pcfs, auto, direct, toplvl, error.
-FS: autofs, cachefs, cdfs, lofs, nfs, nfs3, pcfs, tfs, tmpfs, ufs.
+FS: autofs, cachefs, cdfs, lofs, nfs, nfs3, pcfs, tfs, tmpfs, udf, ufs.
Network 1: wire="mcl-lab-net.cs.columbia.edu" (netnumber=128.59.13).
Network 2: wire="14-net.cs.columbia.edu" (netnumber=128.59.14).
Network 3: wire="old-net.cs.columbia.edu" (netnumber=128.59.16).
@@ -2879,9 +2894,9 @@ a comma separated list selected from the following options:
@table @code
@item fatal
-Fatal errors
+Fatal errors (cannot be turned off)
@item error
-Non-fatal errors
+Non-fatal errors (cannot be turned off)
@item user
Non-fatal user errors
@item warn
@@ -2896,10 +2911,15 @@ Mount map usage
Additional statistics
@item all
All of the above
+@item defaults
+An alias for "fatal,error,user,warning,info".
@end table
Initially a set of default logging flags is enabled. This is as if
-@samp{-x all,nomap,nostats} had been selected. The command line is
+@samp{-x defaults}
+or
+@samp{-x fatal,error,user,warning,info}
+had been selected. The command line is
parsed and logging is controlled by the @code{-x} option. The very first
set of logging flags is saved and can not be subsequently disabled using
@i{Amq}. This default set of options is useful for general production
@@ -2932,7 +2952,6 @@ of the message types.@refill
@samp{LOG_INFO}
@end table
-
The options can be prefixed by the string @samp{no} to indicate
that this option should be turned off. For example, to obtain all
but @samp{info} messages the option @samp{-x all,noinfo} would be used.
@@ -3011,13 +3030,17 @@ can be prefixed with @samp{no} to turn it off.
@table @code
@item all
-all ``reasonable'' options (currently trace|str|full|mem|info|readdir)
+all options (excluding hrtime and mtab)
+@item defaults
+``sensible'' default options (all--excluding hrtime, mtab, and xdrtrace)
+@item test
+full debug options plus mtab,nodaemon,nofork,noamq
@item amq
-do not register for amq
+register @i{Amd} with the RPC portmapper, for @i{Amq}
@item daemon
-do not enter daemon mode
+enter daemon mode
@item fork
-do not fork child worker (hlfsd only)
+fork child worker (hlfsd only)
@item full
program trace
@item hrtime
@@ -3028,16 +3051,14 @@ print high resolution time stamps (only if @b{syslog}(3) is not used)
info service specific debugging (hesiod, nis, etc.) In the case of
hesiod maps, turns on the hesiod RES_DEBUG internal debugging option.
@item mem
-trace memory allocations. Needs to be explicitly enabled at compile
+trace memory allocations. Needs to be explicitly enabled at compile
time with --enable-debug=mem.
@item mtab
-use local @file{./mtab} file
+use local mount-table file (defaults to @file{/tmp/mtab}, @pxref{debug_mtab_file Parameter})
@item readdir
show readdir progress
@item str
debug string munging
-@item test
-full debug but no daemon
@item trace
trace RPC protocol and NFS mount arguments
@item xdrtrace
@@ -3150,6 +3171,7 @@ effect visible to the user.@refill
* Unix Filesystem:: Native disk filesystem.
* Caching Filesystem:: Caching from remote server filesystem.
* CD-ROM Filesystem:: ISO9660 CD ROM.
+* UDF Filesystem:: Universal Disk Format filesystem.
* Loopback Filesystem:: Local loopback-mount filesystem.
* Memory/RAM Filesystem:: A memory or RAM-based filesystem.
* Null Filesystem:: 4.4BSD's loopback-mount filesystem.
@@ -3475,7 +3497,7 @@ inconsistent, requiring running the command @file{fsck -F cachefs
@end enumerate
@c ----------------------------------------------------------------
-@node CD-ROM Filesystem, Loopback Filesystem, Caching Filesystem, Filesystem Types
+@node CD-ROM Filesystem, UDF Filesystem, Caching Filesystem, Filesystem Types
@comment node-name, next, previous, up
@section CD-ROM Filesystem (@samp{cdfs})
@cindex CD-ROM Filesystem
@@ -3504,7 +3526,36 @@ cdfs os==sunos4;type:=cdfs;dev:=/dev/sr0 \
@end example
@c ----------------------------------------------------------------
-@node Loopback Filesystem, Memory/RAM Filesystem, CD-ROM Filesystem, Filesystem Types
+@node UDF Filesystem, Loopback Filesystem, CD-ROM Filesystem, Filesystem Types
+@comment node-name, next, previous, up
+@section CD-ROM Filesystem (@samp{udf})
+@cindex CD-ROM Filesystem
+@cindex udf, filesystem type
+@cindex Filesystem type; udf
+
+The @dfn{udf} (@samp{type:=udf}) filesystem mounts media with a
+Universal Disk Format (UDF) filesystem on it, e.g., a video DVD.
+
+@noindent
+The following option must be specified:
+
+@table @code
+@cindex dev, mount option
+@cindex Mount option; dev
+@item dev
+the block special device to be mounted.
+@end table
+
+Some operating systems will fail to mount read-only media unless the
+@samp{ro} option is specified. A udf entry might be:
+
+@example
+udf os==sunos4;type:=udf;dev:=/dev/sr0 \
+ os==sunos5;addopts:=ro;type:=udf;dev:=/dev/dsk/c0t6d0s2
+@end example
+
+@c ----------------------------------------------------------------
+@node Loopback Filesystem, Memory/RAM Filesystem, UDF Filesystem, Filesystem Types
@comment node-name, next, previous, up
@section Loopback Filesystem (@samp{lofs})
@cindex Loopback Filesystem
@@ -4203,6 +4254,7 @@ sections that follow.
* mount_type Parameter::
* search_path Parameter::
* selectors_in_defaults Parameter::
+* sun_map_syntax Parameter::
@end menu
@c ----------------------------------------------------------------
@@ -4326,7 +4378,7 @@ sites can allow for local map customizations and overrides, and can
distributed maps in several locations as needed.
@c ----------------------------------------------------------------
-@node selectors_in_defaults Parameter, , search_path Parameter, Common Parameters
+@node selectors_in_defaults Parameter, sun_map_syntax Parameter, search_path Parameter, Common Parameters
@comment node-name, next, previous, up
@subsection @t{selectors_in_defaults} Parameter
@cindex selectors_in_defaults Parameter
@@ -4346,6 +4398,15 @@ performance over slow slip-based networks as follows:
Deprecated form: selectors_on_default.
+@c ----------------------------------------------------------------
+@node sun_map_syntax Parameter, , selectors_in_defaults Parameter, Common Parameters
+@comment node-name, next, previous, up
+@subsection @t{sun_map_syntax} Parameter
+@cindex sun_map_syntax Parameter
+
+(type=boolean, default=@samp{no}). If @samp{yes}, then @i{Amd} will
+parse the map according to the Sun Automount syntax.
+
@c ================================================================
@node Global Parameters, Regular Map Parameters, Common Parameters, Amd Configuration File
@@ -4527,14 +4588,14 @@ remain in the cache.
(type=string, default no cluster). Same as the @code{-C} option to
@i{Amd}. Specifies the alternate HP-UX cluster to use.
-@c ----------------------------------------------------------------
-@node debug_mtab_file Parameter, debug_options Parameter, cluster Parameter, Global Parameters
-@comment node-name, next, previous, up
-@subsection @t{debug_mtab_file} Parameter
-@cindex debug_mtab_file Parameter
+@c ----------------------------------------------------------------
+@node debug_mtab_file Parameter, debug_options Parameter, cluster Parameter, Global Parameters
+@comment node-name, next, previous, up
+@subsection @t{debug_mtab_file} Parameter
+@cindex debug_mtab_file Parameter
-(type=string, default="/tmp/mnttab"). Path to mtab file that is used
-by @i{Amd} to store a list of mounted file systems during debug-mtab mode.
+(type=string, default="/tmp/mtab"). Path to mtab file that is used
+by @i{Amd} to store a list of mounted file systems during debug-mtab mode.
This option only applies to systems that store mtab information on disk.
@c ----------------------------------------------------------------
@@ -4774,7 +4835,7 @@ is generally a bad idea to use those reserved for other services such as
@subsection @t{log_options} Parameter
@cindex log_options Parameter
-(type=string, default no logging options). Same as the @code{-x}
+(type=string, default=``defaults''). Same as the @code{-x}
option to @i{Amd}. Specify any logging options for @i{Amd}. Options
are comma delimited, and can be preceded by the string @samp{no} to
negate their meaning. The @samp{debug} logging option is only available
@@ -4785,12 +4846,14 @@ values are:
@table @samp
@item all
all messages
+@item defaults
+an alias for "fatal,error,user,warning,info"
@item debug
debug messages
@item error
-non-fatal system errors
+non-fatal system errors (cannot be turned off)
@item fatal
-fatal errors
+fatal errors (cannot be turned off)
@item info
information
@item map
@@ -5271,7 +5334,7 @@ restart_mounts = yes
auto_dir = /n
log_file = /var/log/amd
log_options = all
-#debug_options = all
+#debug_options = defaults
plock = no
selectors_in_defaults = yes
# config.guess picks up "sunos5" and I don't want to edit my maps yet
@@ -5436,6 +5499,7 @@ mount point.
* Amq -m option:: Obtaining mount statistics.
* Amq -p option:: Getting Amd's process ID.
* Amq -P option:: Contacting alternate Amd processes.
+* Amq -q option:: Suppress synchronous unmounting errors.
* Amq -s option:: Obtaining global statistics.
* Amq -T option:: Use TCP transport.
* Amq -U option:: Use UDP transport.
@@ -5641,7 +5705,7 @@ rather not have to search through the process table. This option is
used in the @file{ctl-amd} script.
@c ----------------------------------------------------------------
-@node Amq -P option, Amq -s option, Amq -p option, Controlling Amd
+@node Amq -P option, Amq -q option, Amq -p option, Controlling Amd
@comment node-name, next, previous, up
@subsection @i{Amq} @code{-P} option
@cindex Multiple Amd processes
@@ -5664,7 +5728,16 @@ kill `amq -p -P 300020`
@end example
@c ----------------------------------------------------------------
-@node Amq -s option, Amq -T option, Amq -P option, Controlling Amd
+@node Amq -q option, Amq -s option, Amq -P option, Controlling Amd
+@comment node-name, next, previous, up
+@subsection @i{Amq} @code{-q} option
+@cindex Unmounting a filesystem
+
+Suppress any error messages produced when a synchronous unmount fails.
+See @ref{Amq -u option}.
+
+@c ----------------------------------------------------------------
+@node Amq -s option, Amq -T option, Amq -q option, Controlling Amd
@comment node-name, next, previous, up
@subsection @i{Amq} @code{-s} option
@cindex Global statistics
@@ -5729,11 +5802,19 @@ and if that failed, will try UDP.
@cindex Forcing filesystem to time out
@cindex Unmounting a filesystem
-The @code{-u} option causes the time-to-live interval of the named mount
-points to be expired, thus causing an unmount attempt. This is the only
-safe way to unmount an automounted filesystem. It is not possible to
-unmount a filesystem which has been mounted with the @samp{nounmount}
-flag.
+The @code{-u} option causes the time-to-live interval of the named
+mount points to be expired, thus causing an unmount attempt. This is
+the only safe way to unmount an automounted filesystem. If @code{-u}
+is repeated, then @i{Amd} will attempt to unmount the filesystem
+synchronously. This makes things like
+
+@example
+amq -uu /t/cd0d && eject cd0
+@end example
+
+@noindent
+work as expected. Any error messages this might produce can be
+suppressed with the @code{-q} option. See @ref{Amq -q option}.
@c The @code{-H} option informs @i{Amd} that the specified mount point
@c has hung - as if its keepalive timer had expired.
@@ -5769,11 +5850,10 @@ as a whole, rather than any particular filesystem. The @code{-x} and
@code{-D} options have exactly the same effect as @i{Amd}'s corresponding
command line options.
-When @i{Amd} receives a @code{-x} flag it limits the log options being
-modified to those which were not enabled at startup. This prevents a
-user turning @emph{off} any logging option which was specified at
-startup, though any which have been turned on since then can still be
-turned off. The @code{-D} option has a similar behavior.
+When @i{Amd} receives the @code{-x} flag, it disallows turning off the
+@samp{fatal} or @samp{error} flags. Both are on by default. They are
+mandatory so that @i{Amd} could report important errors, including
+errors relating to turning flags on/off.
@c ################################################################
@node FSinfo, Hlfsd, Run-time Administration, Top
@@ -6904,8 +6984,8 @@ symbolic link to subdirectory within a user's home directory, depending
on the user which accessed that link. It was primarily designed to
redirect incoming mail to users' home directories, so that it can be read
from anywhere. It was designed and implemented by
-@email{ezk@@cs.columbia.edu,Erez Zadok} and
-@email{dupuy@@cs.columbia.edu,Alexander Dupuy}, at the
+@uref{http://www.cs.sunysb.edu/~ezk,Erez Zadok} and
+@email{dupuy AT cs.columbia.edu,Alexander Dupuy}, at the
@uref{http://www.cs.columbia.edu/,Computer Science Department} of
@uref{http://www.columbia.edu/,Columbia University}. A
@uref{http://www.fsl.cs.sunysb.edu/docs/hlfsd/hlfsd.html,paper}
@@ -7522,7 +7602,6 @@ am-utils, and get installed.
* automount2amd::
* ctl-amd::
* ctl-hlfsd::
-* expn::
* fix-amd-map::
* fixmount::
* fixrmtab::
@@ -7649,7 +7728,7 @@ then start a new process --- only if the previous one died cleanly.
@xref{Run-time Administration}, for more details.
@c ----------------------------------------------------------------
-@node ctl-hlfsd, expn, ctl-amd, Assorted Tools
+@node ctl-hlfsd, fix-amd-map, ctl-amd, Assorted Tools
@comment node-name, next, previous, up
@section ctl-hlfsd
@pindex ctl-hlfsd
@@ -7671,27 +7750,7 @@ died cleanly.
@xref{Hlfsd}, for more details.
@c ----------------------------------------------------------------
-@node expn, fix-amd-map, ctl-hlfsd, Assorted Tools
-@comment node-name, next, previous, up
-@section expn
-@pindex expn
-
-A script to expand email addresses into their full name. It is
-generally useful when using with the @file{lostaltmail} script, but is a
-useful tools otherwise.
-
-@example
-$ expn -v ezk@@cs.columbia.edu
-ezk@@cs.columbia.edu ->
- ezk@@shekel.mcl.cs.columbia.edu
-ezk@@shekel.mcl.cs.columbia.edu ->
- Erez Zadok <"| /usr/local/mh/lib/slocal -user ezk || exit 75>
- Erez Zadok <\ezk>
- Erez Zadok </u/zing/ezk/.mailspool/backup>
-@end example
-
-@c ----------------------------------------------------------------
-@node fix-amd-map, fixmount, expn, Assorted Tools
+@node fix-amd-map, fixmount, ctl-hlfsd, Assorted Tools
@comment node-name, next, previous, up
@section fix-amd-map
@pindex fix-amd-map
@@ -8581,7 +8640,7 @@ XXX: This section needs to be updated
@comment node-name, next, previous, up
@unnumbered Acknowledgments & Trademarks
-Many thanks to the @email{am-utils@@am-utils.org,Am-Utils Users}
+Many thanks to the Am-Utils Users
mailing list through the months developing am-utils. These members
have contributed to the discussions, ideas, code and documentation,
and subjected their systems to alpha quality code. Special thanks go
@@ -8589,10 +8648,10 @@ to those @uref{http://www.am-utils.org/docs/am-utils/AUTHORS.txt,authors} who ha
submitted patches, and especially to the maintainers:
@itemize @bullet
-@item @email{ezk@@cs.sunysb.edu,Erez Zadok}
-@item @email{ib42@@cs.columbia.edu,Ion Badulescu}
-@item @email{ro@@techfak.uni-bielefeld.de,Rainer Orth}
-@item @email{nick.williams@@morganstanley.com,Nick Williams}
+@item @uref{http://www.cs.sunysb.edu/~ezk,Erez Zadok}
+@item @email{ionut AT badula.org,Ion Badulescu}
+@item @email{ro AT techfak.uni-bielefeld.de,Rainer Orth}
+@item @email{nick.williams AT morganstanley.com,Nick Williams}
@end itemize
Thanks to the Formal Methods Group at Imperial College for suffering
@@ -8602,7 +8661,7 @@ Thanks to the many people who have helped with the development of
@i{Amd}, especially Piete Brooks at the Cambridge University Computing
Lab for many hours of testing, experimentation and discussion.
-Thanks to the older @email{amd-workers@@majordomo.glue.umd.edu,Amd
+Thanks to the older @email{amd-workers AT majordomo.glue.umd.edu,Amd
Workers} mailing list (now defunct) members for many suggestions and
bug reports to @i{Amd}.
diff --git a/contrib/amd/doc/stamp-vti b/contrib/amd/doc/stamp-vti
index 41b19a30d5c6..9a4feda60f57 100644
--- a/contrib/amd/doc/stamp-vti
+++ b/contrib/amd/doc/stamp-vti
@@ -1,4 +1,4 @@
-@set UPDATED 20 April 2006
-@set UPDATED-MONTH April 2006
-@set EDITION 6.1.5
-@set VERSION 6.1.5
+@set UPDATED 28 October 2014
+@set UPDATED-MONTH October 2014
+@set EDITION 6.2
+@set VERSION 6.2
diff --git a/contrib/amd/doc/texinfo.tex b/contrib/amd/doc/texinfo.tex
index e758cedae7e6..85f184cc4cbb 100644
--- a/contrib/amd/doc/texinfo.tex
+++ b/contrib/amd/doc/texinfo.tex
@@ -1,18 +1,18 @@
% texinfo.tex -- TeX macros to handle Texinfo files.
-%
+%
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2004-09-06.16}
+\def\texinfoversion{2013-02-01.11}
%
-% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
-% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
-% Foundation, Inc.
+% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+% 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
%
-% This texinfo.tex file is free software; you can redistribute it and/or
+% This texinfo.tex file is free software: you can redistribute it and/or
% modify it under the terms of the GNU General Public License as
-% published by the Free Software Foundation; either version 2, or (at
-% your option) any later version.
+% published by the Free Software Foundation, either version 3 of the
+% License, or (at your option) any later version.
%
% This texinfo.tex file is distributed in the hope that it will be
% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
@@ -20,19 +20,18 @@
% General Public License for more details.
%
% You should have received a copy of the GNU General Public License
-% along with this texinfo.tex file; see the file COPYING. If not, write
-% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-% Boston, MA 02111-1307, USA.
+% along with this program. If not, see <http://www.gnu.org/licenses/>.
%
% As a special exception, when this file is read by TeX when processing
% a Texinfo source document, you may use the result without
-% restriction. (This has been our intent since Texinfo was invented.)
+% restriction. This Exception is an additional permission under section 7
+% of the GNU General Public License, version 3 ("GPLv3").
%
% Please try the latest version of texinfo.tex before submitting bug
% reports; you can get the latest version from:
-% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
-% ftp://tug.org/tex/texinfo.tex
-% (and all CTAN mirrors, see http://www.ctan.org).
+% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or
+% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or
+% http://www.gnu.org/software/texinfo/ (the Texinfo home page)
% The texinfo.tex in any given distribution could well be out
% of date, so if that's what you're using, please check.
%
@@ -67,7 +66,6 @@
\everyjob{\message{[Texinfo version \texinfoversion]}%
\catcode`+=\active \catcode`\_=\active}
-\message{Basics,}
\chardef\other=12
% We never want plain's \outer definition of \+ in Texinfo.
@@ -89,15 +87,19 @@
\let\ptexhat=^
\let\ptexi=\i
\let\ptexindent=\indent
-\let\ptexnoindent=\noindent
\let\ptexinsert=\insert
\let\ptexlbrace=\{
\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
\let\ptexplus=+
+\let\ptexraggedright=\raggedright
\let\ptexrbrace=\}
\let\ptexslash=\/
\let\ptexstar=\*
\let\ptext=\t
+\let\ptextop=\top
+{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode
% If this character appears in an error message or help string, it
% starts a new line in the output.
@@ -115,10 +117,11 @@
% Set up fixed words for English if not already set.
\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi
+\ifx\putworderror\undefined \gdef\putworderror{error}\fi
\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi
\ifx\putwordin\undefined \gdef\putwordin{in}\fi
-\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
-\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi
\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi
@@ -152,20 +155,25 @@
\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi
\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi
-% In some macros, we cannot use the `\? notation---the left quote is
-% in some cases the escape char.
+% Since the category of space is not known, we have to be careful.
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode`\ =\spacecat}
+
+% sometimes characters are active, so we need control sequences.
+\chardef\ampChar = `\&
\chardef\colonChar = `\:
\chardef\commaChar = `\,
+\chardef\dashChar = `\-
\chardef\dotChar = `\.
\chardef\exclamChar= `\!
+\chardef\hashChar = `\#
+\chardef\lquoteChar= `\`
\chardef\questChar = `\?
+\chardef\rquoteChar= `\'
\chardef\semiChar = `\;
+\chardef\slashChar = `\/
\chardef\underChar = `\_
-\chardef\spaceChar = `\ %
-\chardef\spacecat = 10
-\def\spaceisspace{\catcode\spaceChar=\spacecat}
-
% Ignore a token.
%
\def\gobble#1{}
@@ -194,36 +202,7 @@
% that mark overfull boxes (in case you have decided
% that the text looks ok even though it passes the margin).
%
-\def\finalout{\overfullrule=0pt}
-
-% @| inserts a changebar to the left of the current line. It should
-% surround any changed text. This approach does *not* work if the
-% change spans more than two lines of output. To handle that, we would
-% have adopt a much more difficult approach (putting marks into the main
-% vertical list for the beginning and end of each change).
-%
-\def\|{%
- % \vadjust can only be used in horizontal mode.
- \leavevmode
- %
- % Append this vertical mode material after the current line in the output.
- \vadjust{%
- % We want to insert a rule with the height and depth of the current
- % leading; that is exactly what \strutbox is supposed to record.
- \vskip-\baselineskip
- %
- % \vadjust-items are inserted at the left edge of the type. So
- % the \llap here moves out into the left-hand margin.
- \llap{%
- %
- % For a thicker or thinner bar, change the `1pt'.
- \vrule height\baselineskip width1pt
- %
- % This is the space between the bar and the text.
- \hskip 12pt
- }%
- }%
-}
+\def\finalout{\overfullrule=0pt }
% Sometimes it is convenient to have everything in the transcript file
% and nothing on the terminal. We don't just call \tracingall here,
@@ -241,7 +220,7 @@
\tracingmacros2
\tracingrestores1
\showboxbreadth\maxdimen \showboxdepth\maxdimen
- \ifx\eTeXversion\undefined\else % etex gives us more logging
+ \ifx\eTeXversion\thisisundefined\else % etex gives us more logging
\tracingscantokens1
\tracingifs1
\tracinggroups1
@@ -252,6 +231,13 @@
\errorcontextlines16
}%
+% @errormsg{MSG}. Do the index-like expansions on MSG, but if things
+% aren't perfect, it's not the end of the world, being an error message,
+% after all.
+%
+\def\errormsg{\begingroup \indexnofonts \doerrormsg}
+\def\doerrormsg#1{\errmessage{#1}}
+
% add check for \lastpenalty to plain's definitions. If the last thing
% we did was a \nobreak, we don't want to insert more space.
%
@@ -262,7 +248,6 @@
\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
\removelastskip\penalty-200\bigskip\fi\fi}
-% For @cropmarks command.
% Do @cropmarks to get crop marks.
%
\newif\ifcropmarks
@@ -276,6 +261,50 @@
\newdimen\cornerthick \cornerthick=.3pt
\newdimen\topandbottommargin \topandbottommargin=.75in
+% Output a mark which sets \thischapter, \thissection and \thiscolor.
+% We dump everything together because we only have one kind of mark.
+% This works because we only use \botmark / \topmark, not \firstmark.
+%
+% A mark contains a subexpression of the \ifcase ... \fi construct.
+% \get*marks macros below extract the needed part using \ifcase.
+%
+% Another complication is to let the user choose whether \thischapter
+% (\thissection) refers to the chapter (section) in effect at the top
+% of a page, or that at the bottom of a page. The solution is
+% described on page 260 of The TeXbook. It involves outputting two
+% marks for the sectioning macros, one before the section break, and
+% one after. I won't pretend I can describe this better than DEK...
+\def\domark{%
+ \toks0=\expandafter{\lastchapterdefs}%
+ \toks2=\expandafter{\lastsectiondefs}%
+ \toks4=\expandafter{\prevchapterdefs}%
+ \toks6=\expandafter{\prevsectiondefs}%
+ \toks8=\expandafter{\lastcolordefs}%
+ \mark{%
+ \the\toks0 \the\toks2
+ \noexpand\or \the\toks4 \the\toks6
+ \noexpand\else \the\toks8
+ }%
+}
+% \topmark doesn't work for the very first chapter (after the title
+% page or the contents), so we use \firstmark there -- this gets us
+% the mark with the chapter defs, unless the user sneaks in, e.g.,
+% @setcolor (or @url, or @link, etc.) between @contents and the very
+% first @chapter.
+\def\gettopheadingmarks{%
+ \ifcase0\topmark\fi
+ \ifx\thischapter\empty \ifcase0\firstmark\fi \fi
+}
+\def\getbottomheadingmarks{\ifcase1\botmark\fi}
+\def\getcolormarks{\ifcase2\topmark\fi}
+
+% Avoid "undefined control sequence" errors.
+\def\lastchapterdefs{}
+\def\lastsectiondefs{}
+\def\prevchapterdefs{}
+\def\prevsectiondefs{}
+\def\lastcolordefs{}
+
% Main output routine.
\chardef\PAGE = 255
\output = {\onepageout{\pagecontents\PAGE}}
@@ -293,7 +322,9 @@
%
% Do this outside of the \shipout so @code etc. will be expanded in
% the headline as they should be, not taken literally (outputting ''code).
+ \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
\setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+ \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
\setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
%
{%
@@ -301,10 +332,14 @@
% take effect in \write's, yet the group defined by the \vbox ends
% before the \shipout runs.
%
- \escapechar = `\\ % use backslash in output files.
\indexdummies % don't expand commands in the output.
\normalturnoffactive % \ in index entries must not stay \, e.g., if
- % the page break happens to be in the middle of an example.
+ % the page break happens to be in the middle of an example.
+ % We don't want .vr (or whatever) entries like this:
+ % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
+ % "\acronym" won't work when it's read back in;
+ % it needs to be
+ % {\code {{\tt \backslashcurfont }acronym}
\shipout\vbox{%
% Do this early so pdf references go to the beginning of the page.
\ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
@@ -332,9 +367,9 @@
\pagebody{#1}%
\ifdim\ht\footlinebox > 0pt
% Only leave this space if the footline is nonempty.
- % (We lessened \vsize for it in \oddfootingxxx.)
+ % (We lessened \vsize for it in \oddfootingyyy.)
% The \baselineskip=24pt in plain's \makefootline has no effect.
- \vskip 2\baselineskip
+ \vskip 24pt
\unvbox\footlinebox
\fi
%
@@ -355,7 +390,7 @@
\egroup % \vbox from first cropmarks clause
\fi
}% end of \shipout\vbox
- }% end of group with \normalturnoffactive
+ }% end of group with \indexdummies
\advancepageno
\ifnum\outputpenalty>-20000 \else\dosupereject\fi
}
@@ -368,7 +403,7 @@
% marginal hacks, juha@viisa.uucp (Juha Takala)
\ifvoid\margin\else % marginal info is present
\rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
-\dimen@=\dp#1 \unvbox#1
+\dimen@=\dp#1\relax \unvbox#1\relax
\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
}
@@ -390,7 +425,7 @@
%
\def\parsearg{\parseargusing{}}
\def\parseargusing#1#2{%
- \def\next{#2}%
+ \def\argtorun{#2}%
\begingroup
\obeylines
\spaceisspace
@@ -409,7 +444,7 @@
\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
-% Each occurence of `\^^M' or `<space>\^^M' is replaced by a single space.
+% Each occurrence of `\^^M' or `<space>\^^M' is replaced by a single space.
%
% \argremovec might leave us with trailing space, e.g.,
% @end itemize @c foo
@@ -421,8 +456,7 @@
\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
\def\temp{#3}%
\ifx\temp\empty
- % We cannot use \next here, as it holds the macro to run;
- % thus we reuse \temp.
+ % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
\let\temp\finishparsearg
\else
\let\temp\argcheckspaces
@@ -434,14 +468,14 @@
% If a _delimited_ argument is enclosed in braces, they get stripped; so
% to get _exactly_ the rest of the line, we had to prevent such situation.
% We prepended an \empty token at the very beginning and we expand it now,
-% just before passing the control to \next.
-% (Similarily, we have to think about #3 of \argcheckspacesY above: it is
+% just before passing the control to \argtorun.
+% (Similarly, we have to think about #3 of \argcheckspacesY above: it is
% either the null string, or it ends with \^^M---thus there is no danger
% that a pair of braces would be stripped.
%
% But first, we have to remove the trailing space token.
%
-\def\finishparsearg#1 \ArgTerm{\expandafter\next\expandafter{#1}}
+\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
% \parseargdef\foo{...}
% is roughly equivalent to
@@ -492,12 +526,12 @@
% used to check whether the current environment is the one expected.
%
% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
-% are not treated as enviroments; they don't open a group. (The
+% are not treated as environments; they don't open a group. (The
% implementation of @end takes care not to call \endgroup in this
% special case.)
-% At runtime, environments start with this:
+% At run-time, environments start with this:
\def\startenvironment#1{\begingroup\def\thisenv{#1}}
% initialize
\let\thisenv\empty
@@ -515,7 +549,7 @@
\fi
}
-% Evironment mismatch, #1 expected:
+% Environment mismatch, #1 expected:
\def\badenverr{%
\errhelp = \EMsimple
\errmessage{This command can appear only \inenvironment\temp,
@@ -523,7 +557,7 @@
}
\def\inenvironment#1{%
\ifx#1\empty
- out of any environment%
+ outside of any environment%
\else
in environment \expandafter\string#1%
\fi
@@ -535,7 +569,7 @@
\parseargdef\end{%
\if 1\csname iscond.#1\endcsname
\else
- % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+ % The general wording of \badenverr may not be ideal.
\expandafter\checkenv\csname#1\endcsname
\csname E#1\endcsname
\endgroup
@@ -545,85 +579,6 @@
\newhelp\EMsimple{Press RETURN to continue.}
-%% Simple single-character @ commands
-
-% @@ prints an @
-% Kludge this until the fonts are right (grr).
-\def\@{{\tt\char64}}
-
-% This is turned off because it was never documented
-% and you can use @w{...} around a quote to suppress ligatures.
-%% Define @` and @' to be the same as ` and '
-%% but suppressing ligatures.
-%\def\`{{`}}
-%\def\'{{'}}
-
-% Used to generate quoted braces.
-\def\mylbrace {{\tt\char123}}
-\def\myrbrace {{\tt\char125}}
-\let\{=\mylbrace
-\let\}=\myrbrace
-\begingroup
- % Definitions to produce \{ and \} commands for indices,
- % and @{ and @} for the aux file.
- \catcode`\{ = \other \catcode`\} = \other
- \catcode`\[ = 1 \catcode`\] = 2
- \catcode`\! = 0 \catcode`\\ = \other
- !gdef!lbracecmd[\{]%
- !gdef!rbracecmd[\}]%
- !gdef!lbraceatcmd[@{]%
- !gdef!rbraceatcmd[@}]%
-!endgroup
-
-% @comma{} to avoid , parsing problems.
-\let\comma = ,
-
-% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
-% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
-\let\, = \c
-\let\dotaccent = \.
-\def\ringaccent#1{{\accent23 #1}}
-\let\tieaccent = \t
-\let\ubaraccent = \b
-\let\udotaccent = \d
-
-% Other special characters: @questiondown @exclamdown @ordf @ordm
-% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
-\def\questiondown{?`}
-\def\exclamdown{!`}
-\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
-\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
-
-% Dotless i and dotless j, used for accents.
-\def\imacro{i}
-\def\jmacro{j}
-\def\dotless#1{%
- \def\temp{#1}%
- \ifx\temp\imacro \ptexi
- \else\ifx\temp\jmacro \j
- \else \errmessage{@dotless can be used only with i or j}%
- \fi\fi
-}
-
-% The \TeX{} logo, as in plain, but resetting the spacing so that a
-% period following counts as ending a sentence. (Idea found in latex.)
-%
-\edef\TeX{\TeX \spacefactor=1000 }
-
-% @LaTeX{} logo. Not quite the same results as the definition in
-% latex.ltx, since we use a different font for the raised A; it's most
-% convenient for us to use an explicitly smaller font, rather than using
-% the \scriptstyle font (since we don't reset \scriptstyle and
-% \scriptscriptstyle).
-%
-\def\LaTeX{%
- L\kern-.36em
- {\setbox0=\hbox{T}%
- \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
- \kern-.15em
- \TeX
-}
-
% Be sure we're in horizontal mode when doing a tie, since we make space
% equivalent to this in @example-like environments. Otherwise, a space
% at the beginning of a line will start with \penalty -- and
@@ -640,19 +595,34 @@
\def\:{\spacefactor=1000 }
% @* forces a line break.
-\def\*{\hfil\break\hbox{}\ignorespaces}
+\def\*{\unskip\hfil\break\hbox{}\ignorespaces}
% @/ allows a line break.
\let\/=\allowbreak
% @. is an end-of-sentence period.
-\def\.{.\spacefactor=3000 }
+\def\.{.\spacefactor=\endofsentencespacefactor\space}
% @! is an end-of-sentence bang.
-\def\!{!\spacefactor=3000 }
+\def\!{!\spacefactor=\endofsentencespacefactor\space}
% @? is an end-of-sentence query.
-\def\?{?\spacefactor=3000 }
+\def\?{?\spacefactor=\endofsentencespacefactor\space}
+
+% @frenchspacing on|off says whether to put extra space after punctuation.
+%
+\def\onword{on}
+\def\offword{off}
+%
+\parseargdef\frenchspacing{%
+ \def\temp{#1}%
+ \ifx\temp\onword \plainfrenchspacing
+ \else\ifx\temp\offword \plainnonfrenchspacing
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @frenchspacing option `\temp', must be on|off}%
+ \fi\fi
+}
% @w prevents a word break. Without the \leavevmode, @w at the
% beginning of a paragraph, when TeX is still in vertical mode, would
@@ -732,15 +702,6 @@ where each line of input produces a line of output.}
\newdimen\mil \mil=0.001in
-% Old definition--didn't work.
-%\parseargdef\need{\par %
-%% This method tries to make TeX break the page naturally
-%% if the depth of the box does not fit.
-%{\baselineskip=0pt%
-%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
-%\prevdepth=-1000pt
-%}}
-
\parseargdef\need{%
% Ensure vertical mode, so we don't make a big box in the middle of a
% paragraph.
@@ -804,7 +765,7 @@ where each line of input produces a line of output.}
% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
% paragraph. For more general purposes, use the \margin insertion
-% class. WHICH is `l' or `r'.
+% class. WHICH is `l' or `r'. Not documented, written for gawk manual.
%
\newskip\inmarginspacing \inmarginspacing=1cm
\def\strutdepth{\dp\strutbox}
@@ -851,15 +812,51 @@ where each line of input produces a line of output.}
\temp
}
-% @include file insert text of that file as input.
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change). This command
+% is not documented, not supported, and doesn't work.
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
+% @include FILE -- \input text of FILE.
%
\def\include{\parseargusing\filenamecatcodes\includezzz}
\def\includezzz#1{%
\pushthisfilestack
\def\thisfile{#1}%
{%
- \makevalueexpandable
- \def\temp{\input #1 }%
+ \makevalueexpandable % we want to expand any @value in FILE.
+ \turnoffactive % and allow special characters in the expansion
+ \indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @include of #1^^J}%
+ \edef\temp{\noexpand\input #1 }%
+ %
+ % This trickery is to read FILE outside of a group, in case it makes
+ % definitions, etc.
\expandafter
}\temp
\popthisfilestack
@@ -874,6 +871,8 @@ where each line of input produces a line of output.}
\catcode`>=\other
\catcode`+=\other
\catcode`-=\other
+ \catcode`\`=\other
+ \catcode`\'=\other
}
\def\pushthisfilestack{%
@@ -889,7 +888,7 @@ where each line of input produces a line of output.}
\def\popthisfilestack{\errthisfilestackempty}
\def\errthisfilestackempty{\errmessage{Internal error:
the stack of filenames is empty.}}
-
+%
\def\thisfile{}
% @center line
@@ -897,36 +896,46 @@ where each line of input produces a line of output.}
%
\parseargdef\center{%
\ifhmode
- \let\next\centerH
+ \let\centersub\centerH
\else
- \let\next\centerV
+ \let\centersub\centerV
\fi
- \next{\hfil \ignorespaces#1\unskip \hfil}%
+ \centersub{\hfil \ignorespaces#1\unskip \hfil}%
+ \let\centersub\relax % don't let the definition persist, just in case
}
-\def\centerH#1{%
- {%
- \hfil\break
- \advance\hsize by -\leftskip
- \advance\hsize by -\rightskip
- \line{#1}%
- \break
- }%
+\def\centerH#1{{%
+ \hfil\break
+ \advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \line{#1}%
+ \break
+}}
+%
+\newcount\centerpenalty
+\def\centerV#1{%
+ % The idea here is the same as in \startdefun, \cartouche, etc.: if
+ % @center is the first thing after a section heading, we need to wipe
+ % out the negative parskip inserted by \sectionheading, but still
+ % prevent a page break here.
+ \centerpenalty = \lastpenalty
+ \ifnum\centerpenalty>10000 \vskip\parskip \fi
+ \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi
+ \line{\kern\leftskip #1\kern\rightskip}%
}
-\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
% @sp n outputs n lines of vertical space
-
+%
\parseargdef\sp{\vskip #1\baselineskip}
% @comment ...line which is ignored...
% @c is the same as @comment
% @ignore ... @end ignore is another way to write a comment
-
+%
\def\comment{\begingroup \catcode`\^^M=\other%
\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
\commentxxx}
{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
-
+%
\let\c=\comment
% @paragraphindent NCHARS
@@ -1019,86 +1028,6 @@ where each line of input produces a line of output.}
}
-% @asis just yields its argument. Used with @table, for example.
-%
-\def\asis#1{#1}
-
-% @math outputs its argument in math mode.
-%
-% One complication: _ usually means subscripts, but it could also mean
-% an actual _ character, as in @math{@var{some_variable} + 1}. So make
-% _ active, and distinguish by seeing if the current family is \slfam,
-% which is what @var uses.
-{
- \catcode\underChar = \active
- \gdef\mathunderscore{%
- \catcode\underChar=\active
- \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
- }
-}
-% Another complication: we want \\ (and @\) to output a \ character.
-% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
-% this is not advertised and we don't care. Texinfo does not
-% otherwise define @\.
-%
-% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
-\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
-%
-\def\math{%
- \tex
- \mathunderscore
- \let\\ = \mathbackslash
- \mathactive
- $\finishmath
-}
-\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
-
-% Some active characters (such as <) are spaced differently in math.
-% We have to reset their definitions in case the @math was an argument
-% to a command which sets the catcodes (such as @item or @section).
-%
-{
- \catcode`^ = \active
- \catcode`< = \active
- \catcode`> = \active
- \catcode`+ = \active
- \gdef\mathactive{%
- \let^ = \ptexhat
- \let< = \ptexless
- \let> = \ptexgtr
- \let+ = \ptexplus
- }
-}
-
-% @bullet and @minus need the same treatment as @math, just above.
-\def\bullet{$\ptexbullet$}
-\def\minus{$-$}
-
-% @dots{} outputs an ellipsis using the current font.
-% We do .5em per period so that it has the same spacing in a typewriter
-% font as three actual period characters.
-%
-\def\dots{%
- \leavevmode
- \hbox to 1.5em{%
- \hskip 0pt plus 0.25fil
- .\hfil.\hfil.%
- \hskip 0pt plus 0.5fil
- }%
-}
-
-% @enddots{} is an end-of-sentence ellipsis.
-%
-\def\enddots{%
- \dots
- \spacefactor=3000
-}
-
-% @comma{} is so commas can be inserted into text without messing up
-% Texinfo's parsing.
-%
-\let\comma = ,
-
% @refill is a no-op.
\let\refill=\relax
@@ -1163,9 +1092,8 @@ where each line of input produces a line of output.}
\newif\ifpdfmakepagedest
% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
-% can be set). So we test for \relax and 0 as well as \undefined,
-% borrowed from ifpdf.sty.
-\ifx\pdfoutput\undefined
+% can be set). So we test for \relax and 0 as well as being undefined.
+\ifx\pdfoutput\thisisundefined
\else
\ifx\pdfoutput\relax
\else
@@ -1175,40 +1103,157 @@ where each line of input produces a line of output.}
\fi
\fi
\fi
-%
+
+% PDF uses PostScript string constants for the names of xref targets,
+% for display in the outlines, and in other places. Thus, we have to
+% double any backslashes. Otherwise, a name like "\node" will be
+% interpreted as a newline (\n), followed by o, d, e. Not good.
+%
+% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and
+% related messages. The final outcome is that it is up to the TeX user
+% to double the backslashes and otherwise make the string valid, so
+% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to
+% do this reliably, so we use it.
+
+% #1 is a control sequence in which to do the replacements,
+% which we \xdef.
+\def\txiescapepdf#1{%
+ \ifx\pdfescapestring\thisisundefined
+ % No primitive available; should we give a warning or log?
+ % Many times it won't matter.
+ \else
+ % The expandable \pdfescapestring primitive escapes parentheses,
+ % backslashes, and other special chars.
+ \xdef#1{\pdfescapestring{#1}}%
+ \fi
+}
+
+\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
+with PDF output, and none of those formats could be found. (.eps cannot
+be supported due to the design of the PDF format; use regular TeX (DVI
+output) for that.)}
+
\ifpdf
- \input pdfcolor
- \pdfcatalog{/PageMode /UseOutlines}%
+ %
+ % Color manipulation macros based on pdfcolor.tex,
+ % except using rgb instead of cmyk; the latter is said to render as a
+ % very dark gray on-screen and a very dark halftone in print, instead
+ % of actual black.
+ \def\rgbDarkRed{0.50 0.09 0.12}
+ \def\rgbBlack{0 0 0}
+ %
+ % k sets the color for filling (usual text, etc.);
+ % K sets the color for stroking (thin rules, e.g., normal _'s).
+ \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}}
+ %
+ % Set color, and create a mark which defines \thiscolor accordingly,
+ % so that \makeheadline knows which color to restore.
+ \def\setcolor#1{%
+ \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}%
+ \domark
+ \pdfsetcolor{#1}%
+ }
+ %
+ \def\maincolor{\rgbBlack}
+ \pdfsetcolor{\maincolor}
+ \edef\thiscolor{\maincolor}
+ \def\lastcolordefs{}
+ %
+ \def\makefootline{%
+ \baselineskip24pt
+ \line{\pdfsetcolor{\maincolor}\the\footline}%
+ }
+ %
+ \def\makeheadline{%
+ \vbox to 0pt{%
+ \vskip-22.5pt
+ \line{%
+ \vbox to8.5pt{}%
+ % Extract \thiscolor definition from the marks.
+ \getcolormarks
+ % Typeset the headline with \maincolor, then restore the color.
+ \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}%
+ }%
+ \vss
+ }%
+ \nointerlineskip
+ }
+ %
+ %
+ \pdfcatalog{/PageMode /UseOutlines}
+ %
+ % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
\def\dopdfimage#1#2#3{%
- \def\imagewidth{#2}%
- \def\imageheight{#3}%
- % without \immediate, pdftex seg faults when the same image is
+ \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+ \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+ %
+ % pdftex (and the PDF format) support .pdf, .png, .jpg (among
+ % others). Let's try in that order, PDF first since if
+ % someone has a scalable image, presumably better to use that than a
+ % bitmap.
+ \let\pdfimgext=\empty
+ \begingroup
+ \openin 1 #1.pdf \ifeof 1
+ \openin 1 #1.PDF \ifeof 1
+ \openin 1 #1.png \ifeof 1
+ \openin 1 #1.jpg \ifeof 1
+ \openin 1 #1.jpeg \ifeof 1
+ \openin 1 #1.JPG \ifeof 1
+ \errhelp = \nopdfimagehelp
+ \errmessage{Could not find image file #1 for pdf}%
+ \else \gdef\pdfimgext{JPG}%
+ \fi
+ \else \gdef\pdfimgext{jpeg}%
+ \fi
+ \else \gdef\pdfimgext{jpg}%
+ \fi
+ \else \gdef\pdfimgext{png}%
+ \fi
+ \else \gdef\pdfimgext{PDF}%
+ \fi
+ \else \gdef\pdfimgext{pdf}%
+ \fi
+ \closein 1
+ \endgroup
+ %
+ % without \immediate, ancient pdftex seg faults when the same image is
% included twice. (Version 3.14159-pre-1.0-unofficial-20010704.)
\ifnum\pdftexversion < 14
\immediate\pdfimage
\else
\immediate\pdfximage
\fi
- \ifx\empty\imagewidth\else width \imagewidth \fi
- \ifx\empty\imageheight\else height \imageheight \fi
+ \ifdim \wd0 >0pt width \pdfimagewidth \fi
+ \ifdim \wd2 >0pt height \pdfimageheight \fi
\ifnum\pdftexversion<13
- #1.pdf%
+ #1.\pdfimgext
\else
- {#1.pdf}%
+ {#1.\pdfimgext}%
\fi
\ifnum\pdftexversion < 14 \else
\pdfrefximage \pdflastximage
\fi}
+ %
\def\pdfmkdest#1{{%
- % We have to set dummies so commands such as @code in a section title
- % aren't expanded.
- \atdummies
- \normalturnoffactive
- \pdfdest name{#1} xyz%
+ % We have to set dummies so commands such as @code, and characters
+ % such as \, aren't expanded when present in a section title.
+ \indexnofonts
+ \turnoffactive
+ \makevalueexpandable
+ \def\pdfdestname{#1}%
+ \txiescapepdf\pdfdestname
+ \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
}}
+ %
+ % used to mark target names; must be expandable.
\def\pdfmkpgn#1{#1}
- \let\linkcolor = \Blue % was Cyan, but that seems light?
- \def\endlink{\Black\pdfendlink}
+ %
+ % by default, use a color that is dark enough to print on paper as
+ % nearly black, but still distinguishable for online viewing.
+ \def\urlcolor{\rgbDarkRed}
+ \def\linkcolor{\rgbDarkRed}
+ \def\endlink{\setcolor{\maincolor}\pdfendlink}
+ %
% Adding outlines to PDF; macros for calculating structure of outlines
% come from Petr Olsak
\def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
@@ -1217,38 +1262,44 @@ where each line of input produces a line of output.}
\advance\tempnum by 1
\expandafter\xdef\csname#1\endcsname{\the\tempnum}}
%
- % #1 is the section text. #2 is the pdf expression for the number
- % of subentries (or empty, for subsubsections). #3 is the node
- % text, which might be empty if this toc entry had no
- % corresponding node. #4 is the page number.
+ % #1 is the section text, which is what will be displayed in the
+ % outline by the pdf viewer. #2 is the pdf expression for the number
+ % of subentries (or empty, for subsubsections). #3 is the node text,
+ % which might be empty if this toc entry had no corresponding node.
+ % #4 is the page number
%
\def\dopdfoutline#1#2#3#4{%
% Generate a link to the node text if that exists; else, use the
% page number. We could generate a destination for the section
% text in the case where a section has no node, but it doesn't
- % seem worthwhile, since most documents are normally structured.
- \def\pdfoutlinedest{#3}%
- \ifx\pdfoutlinedest\empty \def\pdfoutlinedest{#4}\fi
+ % seem worth the trouble, since most documents are normally structured.
+ \edef\pdfoutlinedest{#3}%
+ \ifx\pdfoutlinedest\empty
+ \def\pdfoutlinedest{#4}%
+ \else
+ \txiescapepdf\pdfoutlinedest
+ \fi
+ %
+ % Also escape PDF chars in the display string.
+ \edef\pdfoutlinetext{#1}%
+ \txiescapepdf\pdfoutlinetext
%
- \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{#1}%
+ \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
}
%
\def\pdfmakeoutlines{%
\begingroup
- % Thanh's hack / proper braces in bookmarks
- \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
- \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
- %
% Read toc silently, to get counts of subentries for \pdfoutline.
+ \def\partentry##1##2##3##4{}% ignore parts in the outlines
\def\numchapentry##1##2##3##4{%
\def\thischapnum{##2}%
- \let\thissecnum\empty
- \let\thissubsecnum\empty
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
}%
\def\numsecentry##1##2##3##4{%
\advancenumber{chap\thischapnum}%
\def\thissecnum{##2}%
- \let\thissubsecnum\empty
+ \def\thissubsecnum{0}%
}%
\def\numsubsecentry##1##2##3##4{%
\advancenumber{sec\thissecnum}%
@@ -1257,9 +1308,9 @@ where each line of input produces a line of output.}
\def\numsubsubsecentry##1##2##3##4{%
\advancenumber{subsec\thissubsecnum}%
}%
- \let\thischapnum\empty
- \let\thissecnum\empty
- \let\thissubsecnum\empty
+ \def\thischapnum{0}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
%
% use \def rather than \let here because we redefine \chapentry et
% al. a second time, below.
@@ -1271,7 +1322,7 @@ where each line of input produces a line of output.}
\def\unnsecentry{\numsecentry}%
\def\unnsubsecentry{\numsubsecentry}%
\def\unnsubsubsecentry{\numsubsubsecentry}%
- \input \jobname.toc
+ \readdatafile{toc}%
%
% Read toc second time, this time actually producing the outlines.
% The `-' means take the \expnumber as the absolute number of
@@ -1293,64 +1344,63 @@ where each line of input produces a line of output.}
% Latin 2 (0xea) gets translated to a | character. Info from
% Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
%
- % xx to do this right, we have to translate 8-bit characters to
- % their "best" equivalent, based on the @documentencoding. Right
- % now, I guess we'll just let the pdf reader have its way.
+ % TODO this right, we have to translate 8-bit characters to
+ % their "best" equivalent, based on the @documentencoding. Too
+ % much work for too little return. Just use the ASCII equivalents
+ % we use for the index sort strings.
+ %
\indexnofonts
- \turnoffactive
- \input \jobname.toc
+ \setupdatafile
+ % We can have normal brace characters in the PDF outlines, unlike
+ % Texinfo index files. So set that up.
+ \def\{{\lbracecharliteral}%
+ \def\}{\rbracecharliteral}%
+ \catcode`\\=\active \otherbackslash
+ \input \tocreadfilename
\endgroup
}
+ {\catcode`[=1 \catcode`]=2
+ \catcode`{=\other \catcode`}=\other
+ \gdef\lbracecharliteral[{]%
+ \gdef\rbracecharliteral[}]%
+ ]
%
- \def\makelinks #1,{%
- \def\params{#1}\def\E{END}%
- \ifx\params\E
- \let\nextmakelinks=\relax
- \else
- \let\nextmakelinks=\makelinks
- \ifnum\lnkcount>0,\fi
- \picknum{#1}%
- \startlink attr{/Border [0 0 0]}
- goto name{\pdfmkpgn{\the\pgn}}%
- \linkcolor #1%
- \advance\lnkcount by 1%
- \endlink
- \fi
- \nextmakelinks
- }
- \def\picknum#1{\expandafter\pn#1}
- \def\pn#1{%
- \def\p{#1}%
- \ifx\p\lbrace
- \let\nextpn=\ppn
- \else
- \let\nextpn=\ppnn
- \def\first{#1}
- \fi
- \nextpn
- }
- \def\ppn#1{\pgn=#1\gobble}
- \def\ppnn{\pgn=\first}
- \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,}
\def\skipspaces#1{\def\PP{#1}\def\D{|}%
\ifx\PP\D\let\nextsp\relax
\else\let\nextsp\skipspaces
- \ifx\p\space\else\addtokens{\filename}{\PP}%
- \advance\filenamelength by 1
- \fi
+ \addtokens{\filename}{\PP}%
+ \advance\filenamelength by 1
\fi
\nextsp}
- \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
+ \def\getfilename#1{%
+ \filenamelength=0
+ % If we don't expand the argument now, \skipspaces will get
+ % snagged on things like "@value{foo}".
+ \edef\temp{#1}%
+ \expandafter\skipspaces\temp|\relax
+ }
\ifnum\pdftexversion < 14
\let \startlink \pdfannotlink
\else
\let \startlink \pdfstartlink
\fi
+ % make a live url in pdf output.
\def\pdfurl#1{%
\begingroup
- \normalturnoffactive\def\@{@}%
+ % it seems we really need yet another set of dummies; have not
+ % tried to figure out what each command should do in the context
+ % of @url. for now, just make @/ a no-op, that's the only one
+ % people have actually reported a problem with.
+ %
+ \normalturnoffactive
+ \def\@{@}%
+ \let\/=\empty
\makevalueexpandable
- \leavevmode\Red
+ % do we want to go so far as to use \indexnofonts instead of just
+ % special-casing \var here?
+ \def\var##1{##1}%
+ %
+ \leavevmode\setcolor{\urlcolor}%
\startlink attr{/Border [0 0 0]}%
user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
\endgroup}
@@ -1377,13 +1427,15 @@ where each line of input produces a line of output.}
{\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
\def\pdflink#1{%
\startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
- \linkcolor #1\endlink}
+ \setcolor{\linkcolor}#1\endlink}
\def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
\else
+ % non-pdf mode
\let\pdfmkdest = \gobble
\let\pdfurl = \gobble
\let\endlink = \relax
- \let\linkcolor = \relax
+ \let\setcolor = \gobble
+ \let\pdfsetcolor = \gobble
\let\pdfmakeoutlines = \relax
\fi % \ifx\pdfoutput
@@ -1406,9 +1458,13 @@ where each line of input produces a line of output.}
\def\rm{\fam=0 \setfontstyle{rm}}
\def\it{\fam=\itfam \setfontstyle{it}}
\def\sl{\fam=\slfam \setfontstyle{sl}}
-\def\bf{\fam=\bffam \setfontstyle{bf}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
\def\tt{\fam=\ttfam \setfontstyle{tt}}
+% Unfortunately, we have to override this for titles and the like, since
+% in those cases "rm" is bold. Sigh.
+\def\rmisbold{\rm\def\curfontstyle{bf}}
+
% Texinfo sort of supports the sans serif font style, which plain TeX does not.
% So we set up a \sf.
\newfam\sffam
@@ -1418,8 +1474,6 @@ where each line of input produces a line of output.}
% We don't need math for this font style.
\def\ttsl{\setfontstyle{ttsl}}
-% Default leading.
-\newdimen\textleading \textleading = 13.2pt
% Set the baselineskip to #1, and the lineskip and strut size
% correspondingly. There is no deep meaning behind these magic numbers
@@ -1429,8 +1483,13 @@ where each line of input produces a line of output.}
\def\strutheightpercent{.70833}
\def\strutdepthpercent {.29167}
%
+% can get a sort of poor man's double spacing by redefining this.
+\def\baselinefactor{1}
+%
+\newdimen\textleading
\def\setleading#1{%
- \normalbaselineskip = #1\relax
+ \dimen0 = #1\relax
+ \normalbaselineskip = \baselinefactor\dimen0
\normallineskip = \lineskipfactor\normalbaselineskip
\normalbaselines
\setbox\strutbox =\hbox{%
@@ -1439,20 +1498,295 @@ where each line of input produces a line of output.}
}%
}
-% Set the font macro #1 to the font named #2, adding on the
-% specified font prefix (normally `cm').
-% #3 is the font's design size, #4 is a scale factor
-\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
+% PDF CMaps. See also LaTeX's t1.cmap.
+%
+% do nothing with this by default.
+\expandafter\let\csname cmapOT1\endcsname\gobble
+\expandafter\let\csname cmapOT1IT\endcsname\gobble
+\expandafter\let\csname cmapOT1TT\endcsname\gobble
+
+% if we are producing pdf, and we have \pdffontattr, then define cmaps.
+% (\pdffontattr was introduced many years ago, but people still run
+% older pdftex's; it's easy to conditionalize, so we do.)
+\ifpdf \ifx\pdffontattr\thisisundefined \else
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1-0)
+%%Title: (TeX-OT1-0 TeX OT1 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<23> <26> <0023>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+40 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1IT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1IT-0)
+%%Title: (TeX-OT1IT-0 TeX OT1IT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1IT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1IT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<25> <26> <0025>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+42 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<23> <0023>
+<24> <00A3>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1IT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1TT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1TT-0)
+%%Title: (TeX-OT1TT-0 TeX OT1TT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1TT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1TT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+5 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<21> <26> <0021>
+<28> <5F> <0028>
+<61> <7E> <0061>
+endbfrange
+32 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <2191>
+<0C> <2193>
+<0D> <0027>
+<0E> <00A1>
+<0F> <00BF>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<20> <2423>
+<27> <2019>
+<60> <2018>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1TT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+\fi\fi
+
+
+% Set the font macro #1 to the font named \fontprefix#2.
+% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
+% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit).
+% Example:
+% #1 = \textrm
+% #2 = \rmshape
+% #3 = 10
+% #4 = \mainmagstep
+% #5 = OT1
+%
+\def\setfont#1#2#3#4#5{%
+ \font#1=\fontprefix#2#3 scaled #4
+ \csname cmap#5\endcsname#1%
+}
+% This is what gets called when #5 of \setfont is empty.
+\let\cmap\gobble
+%
+% (end of cmaps)
% Use cm as the default font prefix.
% To specify the font prefix, you must define \fontprefix
% before you read in texinfo.tex.
-\ifx\fontprefix\undefined
+\ifx\fontprefix\thisisundefined
\def\fontprefix{cm}
\fi
% Support font families that don't use the same naming scheme as CM.
\def\rmshape{r}
-\def\rmbshape{bx} %where the normal face is bold
+\def\rmbshape{bx} % where the normal face is bold
\def\bfshape{b}
\def\bxshape{bx}
\def\ttshape{tt}
@@ -1467,118 +1801,291 @@ where each line of input produces a line of output.}
\def\scshape{csc}
\def\scbshape{csc}
+% Definitions for a main text size of 11pt. (The default in Texinfo.)
+%
+\def\definetextfontsizexi{%
% Text fonts (11.2pt, magstep1).
-\newcount\mainmagstep
-\ifx\bigger\relax
- % not really supported.
- \mainmagstep=\magstep1
- \setfont\textrm\rmshape{12}{1000}
- \setfont\texttt\ttshape{12}{1000}
-\else
- \mainmagstep=\magstephalf
- \setfont\textrm\rmshape{10}{\mainmagstep}
- \setfont\texttt\ttshape{10}{\mainmagstep}
-\fi
-\setfont\textbf\bfshape{10}{\mainmagstep}
-\setfont\textit\itshape{10}{\mainmagstep}
-\setfont\textsl\slshape{10}{\mainmagstep}
-\setfont\textsf\sfshape{10}{\mainmagstep}
-\setfont\textsc\scshape{10}{\mainmagstep}
-\setfont\textttsl\ttslshape{10}{\mainmagstep}
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
\font\texti=cmmi10 scaled \mainmagstep
\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1095}
% A few fonts for @defun names and args.
-\setfont\defbf\bfshape{10}{\magstep1}
-\setfont\deftt\ttshape{10}{\magstep1}
-\setfont\defttsl\ttslshape{10}{\magstep1}
+\setfont\defbf\bfshape{10}{\magstep1}{OT1}
+\setfont\deftt\ttshape{10}{\magstep1}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT}
\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
% Fonts for indices, footnotes, small examples (9pt).
-\setfont\smallrm\rmshape{9}{1000}
-\setfont\smalltt\ttshape{9}{1000}
-\setfont\smallbf\bfshape{10}{900}
-\setfont\smallit\itshape{9}{1000}
-\setfont\smallsl\slshape{9}{1000}
-\setfont\smallsf\sfshape{9}{1000}
-\setfont\smallsc\scshape{10}{900}
-\setfont\smallttsl\ttslshape{10}{900}
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
\font\smalli=cmmi9
\font\smallsy=cmsy9
+\def\smallecsize{0900}
% Fonts for small examples (8pt).
-\setfont\smallerrm\rmshape{8}{1000}
-\setfont\smallertt\ttshape{8}{1000}
-\setfont\smallerbf\bfshape{10}{800}
-\setfont\smallerit\itshape{8}{1000}
-\setfont\smallersl\slshape{8}{1000}
-\setfont\smallersf\sfshape{8}{1000}
-\setfont\smallersc\scshape{10}{800}
-\setfont\smallerttsl\ttslshape{10}{800}
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
\font\smalleri=cmmi8
\font\smallersy=cmsy8
+\def\smallerecsize{0800}
% Fonts for title page (20.4pt):
-\setfont\titlerm\rmbshape{12}{\magstep3}
-\setfont\titleit\itbshape{10}{\magstep4}
-\setfont\titlesl\slbshape{10}{\magstep4}
-\setfont\titlett\ttbshape{12}{\magstep3}
-\setfont\titlettsl\ttslshape{10}{\magstep4}
-\setfont\titlesf\sfbshape{17}{\magstep1}
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
\let\titlebf=\titlerm
-\setfont\titlesc\scbshape{10}{\magstep4}
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
\font\titlei=cmmi12 scaled \magstep3
\font\titlesy=cmsy10 scaled \magstep4
-\def\authorrm{\secrm}
-\def\authortt{\sectt}
+\def\titleecsize{2074}
% Chapter (and unnumbered) fonts (17.28pt).
-\setfont\chaprm\rmbshape{12}{\magstep2}
-\setfont\chapit\itbshape{10}{\magstep3}
-\setfont\chapsl\slbshape{10}{\magstep3}
-\setfont\chaptt\ttbshape{12}{\magstep2}
-\setfont\chapttsl\ttslshape{10}{\magstep3}
-\setfont\chapsf\sfbshape{17}{1000}
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}{OT1}
+\setfont\chapit\itbshape{10}{\magstep3}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep3}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT}
+\setfont\chapsf\sfbshape{17}{1000}{OT1}
\let\chapbf=\chaprm
-\setfont\chapsc\scbshape{10}{\magstep3}
+\setfont\chapsc\scbshape{10}{\magstep3}{OT1}
\font\chapi=cmmi12 scaled \magstep2
\font\chapsy=cmsy10 scaled \magstep3
+\def\chapecsize{1728}
% Section fonts (14.4pt).
-\setfont\secrm\rmbshape{12}{\magstep1}
-\setfont\secit\itbshape{10}{\magstep2}
-\setfont\secsl\slbshape{10}{\magstep2}
-\setfont\sectt\ttbshape{12}{\magstep1}
-\setfont\secttsl\ttslshape{10}{\magstep2}
-\setfont\secsf\sfbshape{12}{\magstep1}
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}{OT1}
+\setfont\secit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep2}{OT1}
+\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\secsf\sfbshape{12}{\magstep1}{OT1}
\let\secbf\secrm
-\setfont\secsc\scbshape{10}{\magstep2}
+\setfont\secsc\scbshape{10}{\magstep2}{OT1}
\font\seci=cmmi12 scaled \magstep1
\font\secsy=cmsy10 scaled \magstep2
+\def\sececsize{1440}
% Subsection fonts (13.15pt).
-\setfont\ssecrm\rmbshape{12}{\magstephalf}
-\setfont\ssecit\itbshape{10}{1315}
-\setfont\ssecsl\slbshape{10}{1315}
-\setfont\ssectt\ttbshape{12}{\magstephalf}
-\setfont\ssecttsl\ttslshape{10}{1315}
-\setfont\ssecsf\sfbshape{12}{\magstephalf}
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1}
+\setfont\ssecit\itbshape{10}{1315}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1315}{OT1}
+\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1}
\let\ssecbf\ssecrm
-\setfont\ssecsc\scbshape{10}{1315}
+\setfont\ssecsc\scbshape{10}{1315}{OT1}
\font\sseci=cmmi12 scaled \magstephalf
\font\ssecsy=cmsy10 scaled 1315
+\def\ssececsize{1200}
% Reduced fonts for @acro in text (10pt).
-\setfont\reducedrm\rmshape{10}{1000}
-\setfont\reducedtt\ttshape{10}{1000}
-\setfont\reducedbf\bfshape{10}{1000}
-\setfont\reducedit\itshape{10}{1000}
-\setfont\reducedsl\slshape{10}{1000}
-\setfont\reducedsf\sfshape{10}{1000}
-\setfont\reducedsc\scshape{10}{1000}
-\setfont\reducedttsl\ttslshape{10}{1000}
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}{OT1}
+\setfont\reducedtt\ttshape{10}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{1000}{OT1}
+\setfont\reducedit\itshape{10}{1000}{OT1IT}
+\setfont\reducedsl\slshape{10}{1000}{OT1}
+\setfont\reducedsf\sfshape{10}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{1000}{OT1}
+\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT}
\font\reducedi=cmmi10
\font\reducedsy=cmsy10
+\def\reducedecsize{1000}
+
+\textleading = 13.2pt % line spacing for 11pt CM
+\textfonts % reset the current fonts
+\rm
+} % end of 11pt text font size definitions, \definetextfontsizexi
+
+
+% Definitions to make the main text be 10pt Computer Modern, with
+% section, chapter, etc., sizes following suit. This is for the GNU
+% Press printing of the Emacs 22 manual. Maybe other manuals in the
+% future. Used with @smallbook, which sets the leading to 12pt.
+%
+\def\definetextfontsizex{%
+% Text fonts (10pt).
+\def\textnominalsize{10pt}
+\edef\mainmagstep{1000}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1000}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstephalf}{OT1}
+\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\titleecsize{2074}
+
+% Chapter fonts (14.4pt).
+\def\chapnominalsize{14pt}
+\setfont\chaprm\rmbshape{12}{\magstep1}{OT1}
+\setfont\chapit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep2}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\chapsf\sfbshape{12}{\magstep1}{OT1}
+\let\chapbf\chaprm
+\setfont\chapsc\scbshape{10}{\magstep2}{OT1}
+\font\chapi=cmmi12 scaled \magstep1
+\font\chapsy=cmsy10 scaled \magstep2
+\def\chapecsize{1440}
+
+% Section fonts (12pt).
+\def\secnominalsize{12pt}
+\setfont\secrm\rmbshape{12}{1000}{OT1}
+\setfont\secit\itbshape{10}{\magstep1}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep1}{OT1}
+\setfont\sectt\ttbshape{12}{1000}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT}
+\setfont\secsf\sfbshape{12}{1000}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep1}{OT1}
+\font\seci=cmmi12
+\font\secsy=cmsy10 scaled \magstep1
+\def\sececsize{1200}
+
+% Subsection fonts (10pt).
+\def\ssecnominalsize{10pt}
+\setfont\ssecrm\rmbshape{10}{1000}{OT1}
+\setfont\ssecit\itbshape{10}{1000}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1000}{OT1}
+\setfont\ssectt\ttbshape{10}{1000}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT}
+\setfont\ssecsf\sfbshape{10}{1000}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1000}{OT1}
+\font\sseci=cmmi10
+\font\ssecsy=cmsy10
+\def\ssececsize{1000}
+
+% Reduced fonts for @acro in text (9pt).
+\def\reducednominalsize{9pt}
+\setfont\reducedrm\rmshape{9}{1000}{OT1}
+\setfont\reducedtt\ttshape{9}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{900}{OT1}
+\setfont\reducedit\itshape{9}{1000}{OT1IT}
+\setfont\reducedsl\slshape{9}{1000}{OT1}
+\setfont\reducedsf\sfshape{9}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{900}{OT1}
+\setfont\reducedttsl\ttslshape{10}{900}{OT1TT}
+\font\reducedi=cmmi9
+\font\reducedsy=cmsy9
+\def\reducedecsize{0900}
+
+\divide\parskip by 2 % reduce space between paragraphs
+\textleading = 12pt % line spacing for 10pt CM
+\textfonts % reset the current fonts
+\rm
+} % end of 10pt text font size definitions, \definetextfontsizex
+
+
+% We provide the user-level command
+% @fonttextsize 10
+% (or 11) to redefine the text font size. pt is assumed.
+%
+\def\xiword{11}
+\def\xword{10}
+\def\xwordpt{10pt}
+%
+\parseargdef\fonttextsize{%
+ \def\textsizearg{#1}%
+ %\wlog{doing @fonttextsize \textsizearg}%
+ %
+ % Set \globaldefs so that documents can use this inside @tex, since
+ % makeinfo 4.8 does not support it, but we need it nonetheless.
+ %
+ \begingroup \globaldefs=1
+ \ifx\textsizearg\xword \definetextfontsizex
+ \else \ifx\textsizearg\xiword \definetextfontsizexi
+ \else
+ \errhelp=\EMsimple
+ \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'}
+ \fi\fi
+ \endgroup
+}
+
% In order for the font changes to affect most math symbols and letters,
% we have to define the \textfont of the standard families. Since
@@ -1608,6 +2115,7 @@ where each line of input produces a line of output.}
\let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
\let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
\let\tenttsl=\textttsl
+ \def\curfontsize{text}%
\def\lsize{reduced}\def\lllsize{smaller}%
\resetmathfonts \setleading{\textleading}}
\def\titlefonts{%
@@ -1615,13 +2123,16 @@ where each line of input produces a line of output.}
\let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
\let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
\let\tenttsl=\titlettsl
+ \def\curfontsize{title}%
\def\lsize{chap}\def\lllsize{subsec}%
- \resetmathfonts \setleading{25pt}}
-\def\titlefont#1{{\titlefonts\rm #1}}
+ \resetmathfonts \setleading{27pt}}
+\def\titlefont#1{{\titlefonts\rmisbold #1}}
\def\chapfonts{%
\let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
\let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
- \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl
+ \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+ \let\tenttsl=\chapttsl
+ \def\curfontsize{chap}%
\def\lsize{sec}\def\lllsize{text}%
\resetmathfonts \setleading{19pt}}
\def\secfonts{%
@@ -1629,6 +2140,7 @@ where each line of input produces a line of output.}
\let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
\let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
\let\tenttsl=\secttsl
+ \def\curfontsize{sec}%
\def\lsize{subsec}\def\lllsize{reduced}%
\resetmathfonts \setleading{16pt}}
\def\subsecfonts{%
@@ -1636,6 +2148,7 @@ where each line of input produces a line of output.}
\let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
\let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
\let\tenttsl=\ssecttsl
+ \def\curfontsize{ssec}%
\def\lsize{text}\def\lllsize{small}%
\resetmathfonts \setleading{15pt}}
\let\subsubsecfonts = \subsecfonts
@@ -1644,6 +2157,7 @@ where each line of input produces a line of output.}
\let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
\let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
\let\tenttsl=\reducedttsl
+ \def\curfontsize{reduced}%
\def\lsize{small}\def\lllsize{smaller}%
\resetmathfonts \setleading{10.5pt}}
\def\smallfonts{%
@@ -1651,6 +2165,7 @@ where each line of input produces a line of output.}
\let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
\let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
\let\tenttsl=\smallttsl
+ \def\curfontsize{small}%
\def\lsize{smaller}\def\lllsize{smaller}%
\resetmathfonts \setleading{10.5pt}}
\def\smallerfonts{%
@@ -1658,9 +2173,20 @@ where each line of input produces a line of output.}
\let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
\let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
\let\tenttsl=\smallerttsl
+ \def\curfontsize{smaller}%
\def\lsize{smaller}\def\lllsize{smaller}%
\resetmathfonts \setleading{9.5pt}}
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}{OT1}
+\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}{OT1}
+\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
+
+% Define these just so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
% Set the fonts to use with the @small... environments.
\let\smallexamplefonts = \smallfonts
@@ -1674,55 +2200,219 @@ where each line of input produces a line of output.}
%
% By the way, for comparison, here's what fits with @example (10pt):
% 8.5x11=71 smallbook=60 a4=75 a5=58
-%
-% I wish the USA used A4 paper.
% --karl, 24jan03.
-
% Set up the default fonts, so we can use them for creating boxes.
%
-\textfonts \rm
+\definetextfontsizexi
-% Define these so they can be easily changed for other fonts.
-\def\angleleft{$\langle$}
-\def\angleright{$\rangle$}
+
+\message{markup,}
+
+% Check if we are currently using a typewriter font. Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will
+% define and register \INITMACRO to be called on markup style changes.
+% \INITMACRO can check \currentmarkupstyle for the innermost
+% style and the set of \ifmarkupSTYLE switches for all styles
+% currently in effect.
+\newif\ifmarkupvar
+\newif\ifmarkupsamp
+\newif\ifmarkupkey
+%\newif\ifmarkupfile % @file == @samp.
+%\newif\ifmarkupoption % @option == @samp.
+\newif\ifmarkupcode
+\newif\ifmarkupkbd
+%\newif\ifmarkupenv % @env == @code.
+%\newif\ifmarkupcommand % @command == @code.
+\newif\ifmarkuptex % @tex (and part of @math, for now).
+\newif\ifmarkupexample
+\newif\ifmarkupverb
+\newif\ifmarkupverbatim
+
+\let\currentmarkupstyle\empty
+
+\def\setupmarkupstyle#1{%
+ \csname markup#1true\endcsname
+ \def\currentmarkupstyle{#1}%
+ \markupstylesetup
+}
+
+\let\markupstylesetup\empty
+
+\def\defmarkupstylesetup#1{%
+ \expandafter\def\expandafter\markupstylesetup
+ \expandafter{\markupstylesetup #1}%
+ \def#1%
+}
+
+% Markup style setup for left and right quotes.
+\defmarkupstylesetup\markupsetuplq{%
+ \expandafter\let\expandafter \temp
+ \csname markupsetuplq\currentmarkupstyle\endcsname
+ \ifx\temp\relax \markupsetuplqdefault \else \temp \fi
+}
+
+\defmarkupstylesetup\markupsetuprq{%
+ \expandafter\let\expandafter \temp
+ \csname markupsetuprq\currentmarkupstyle\endcsname
+ \ifx\temp\relax \markupsetuprqdefault \else \temp \fi
+}
+
+{
+\catcode`\'=\active
+\catcode`\`=\active
+
+\gdef\markupsetuplqdefault{\let`\lq}
+\gdef\markupsetuprqdefault{\let'\rq}
+
+\gdef\markupsetcodequoteleft{\let`\codequoteleft}
+\gdef\markupsetcodequoteright{\let'\codequoteright}
+}
+
+\let\markupsetuplqcode \markupsetcodequoteleft
+\let\markupsetuprqcode \markupsetcodequoteright
+%
+\let\markupsetuplqexample \markupsetcodequoteleft
+\let\markupsetuprqexample \markupsetcodequoteright
+%
+\let\markupsetuplqkbd \markupsetcodequoteleft
+\let\markupsetuprqkbd \markupsetcodequoteright
+%
+\let\markupsetuplqsamp \markupsetcodequoteleft
+\let\markupsetuprqsamp \markupsetcodequoteright
+%
+\let\markupsetuplqverb \markupsetcodequoteleft
+\let\markupsetuprqverb \markupsetcodequoteright
+%
+\let\markupsetuplqverbatim \markupsetcodequoteleft
+\let\markupsetuprqverbatim \markupsetcodequoteright
+
+% Allow an option to not use regular directed right quote/apostrophe
+% (char 0x27), but instead the undirected quote from cmtt (char 0x0d).
+% The undirected quote is ugly, so don't make it the default, but it
+% works for pasting with more pdf viewers (at least evince), the
+% lilypond developers report. xpdf does work with the regular 0x27.
+%
+\def\codequoteright{%
+ \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
+ \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
+ '%
+ \else \char'15 \fi
+ \else \char'15 \fi
+}
+%
+% and a similar option for the left quote char vs. a grave accent.
+% Modern fonts display ASCII 0x60 as a grave accent, so some people like
+% the code environments to do likewise.
+%
+\def\codequoteleft{%
+ \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
+ \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
+ % [Knuth] pp. 380,381,391
+ % \relax disables Spanish ligatures ?` and !` of \tt font.
+ \relax`%
+ \else \char'22 \fi
+ \else \char'22 \fi
+}
+
+% Commands to set the quote options.
+%
+\parseargdef\codequoteundirected{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}%
+ \fi\fi
+}
+%
+\parseargdef\codequotebacktick{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}%
+ \fi\fi
+}
+
+% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font.
+\def\noligaturesquoteleft{\relax\lq}
% Count depth in font-changes, for error checks
\newcount\fontdepth \fontdepth=0
-% Fonts for short table of contents.
-\setfont\shortcontrm\rmshape{12}{1000}
-\setfont\shortcontbf\bfshape{10}{\magstep1} % no cmb12
-\setfont\shortcontsl\slshape{12}{1000}
-\setfont\shortconttt\ttshape{12}{1000}
-
-%% Add scribe-like font environments, plus @l for inline lisp (usually sans
-%% serif) and @ii for TeX italic
-
-% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
-% unless the following character is such as not to need one.
-\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
- \ptexslash\fi\fi\fi}
-\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
-\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
-
-% like \smartslanted except unconditionally uses \ttsl.
-% @var is set to this for defun arguments.
-\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
-
-% like \smartslanted except unconditionally use \sl. We never want
+% Font commands.
+
+% #1 is the font command (\sl or \it), #2 is the text to slant.
+% If we are in a monospaced environment, however, 1) always use \ttsl,
+% and 2) do not add an italic correction.
+\def\dosmartslant#1#2{%
+ \ifusingtt
+ {{\ttsl #2}\let\next=\relax}%
+ {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}%
+ \next
+}
+\def\smartslanted{\dosmartslant\sl}
+\def\smartitalic{\dosmartslant\it}
+
+% Output an italic correction unless \next (presumed to be the following
+% character) is such as not to need one.
+\def\smartitaliccorrection{%
+ \ifx\next,%
+ \else\ifx\next-%
+ \else\ifx\next.%
+ \else\ptexslash
+ \fi\fi\fi
+ \aftersmartic
+}
+
+% Unconditional use \ttsl, and no ic. @var is set to this for defuns.
+\def\ttslanted#1{{\ttsl #1}}
+
+% @cite is like \smartslanted except unconditionally use \sl. We never want
% ttsl for book titles, do we?
-\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
+\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection}
+
+\def\aftersmartic{}
+\def\var#1{%
+ \let\saveaftersmartic = \aftersmartic
+ \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}%
+ \smartslanted{#1}%
+}
\let\i=\smartitalic
\let\slanted=\smartslanted
-\let\var=\smartslanted
\let\dfn=\smartslanted
\let\emph=\smartitalic
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}} % roman font
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+% @b, explicit bold. Also @strong.
\def\b#1{{\bf #1}}
\let\strong=\b
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
% We can't just use \exhyphenpenalty, because that only has effect at
% the end of a paragraph. Restore normal hyphenation at the end of the
% group within which \nohyphenation is presumably called.
@@ -1735,35 +2425,34 @@ where each line of input produces a line of output.}
% sometimes \x has an active definition that messes things up.
%
\catcode`@=11
- \def\frenchspacing{%
+ \def\plainfrenchspacing{%
\sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
\sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+ \def\endofsentencespacefactor{1000}% for @. and friends
+ }
+ \def\plainnonfrenchspacing{%
+ \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
+ \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
+ \def\endofsentencespacefactor{3000}% for @. and friends
}
\catcode`@=\other
+\def\endofsentencespacefactor{3000}% default
+% @t, explicit typewriter.
\def\t#1{%
- {\tt \rawbackslash \frenchspacing #1}%
+ {\tt \rawbackslash \plainfrenchspacing #1}%
\null
}
-\def\samp#1{`\tclose{#1}'\null}
-\setfont\keyrm\rmshape{8}{1000}
-\font\keysy=cmsy9
-\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
- \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
- \vbox{\hrule\kern-0.4pt
- \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
- \kern-0.4pt\hrule}%
- \kern-.06em\raise0.4pt\hbox{\angleright}}}}
-% The old definition, with no lozenge:
-%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
-\def\ctrl #1{{\tt \rawbackslash \hat}#1}
-% @file, @option are the same as @samp.
-\let\file=\samp
-\let\option=\samp
+% @samp.
+\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}}
-% @code is a modification of @t,
-% which makes spaces the same size as normal in the surrounding text.
+% @indicateurl is \samp, that is, with quotes.
+\let\indicateurl=\samp
+
+% @code (and similar) prints in typewriter, but with spaces the same
+% size as normal in the surrounding text, without hyphenation, etc.
+% This is a subroutine for that.
\def\tclose#1{%
{%
% Change normal interword space to be same as for the current font.
@@ -1779,33 +2468,44 @@ where each line of input produces a line of output.}
\nohyphenation
%
\rawbackslash
- \frenchspacing
+ \plainfrenchspacing
#1%
}%
- \null
+ \null % reset spacefactor to 1000
}
% We *must* turn on hyphenation at `-' and `_' in @code.
% Otherwise, it is too hard to avoid overfull hboxes
% in the Emacs manual, the Library manual, etc.
-
+%
% Unfortunately, TeX uses one parameter (\hyphenchar) to control
% both hyphenation at - and hyphenation within words.
% We must therefore turn them both off (\tclose does that)
% and arrange explicitly to hyphenate at a dash.
% -- rms.
{
- \catcode`\-=\active
- \catcode`\_=\active
+ \catcode`\-=\active \catcode`\_=\active
+ \catcode`\'=\active \catcode`\`=\active
+ \global\let'=\rq \global\let`=\lq % default definitions
%
\global\def\code{\begingroup
- \catcode`\-=\active \let-\codedash
- \catcode`\_=\active \let_\codeunder
+ \setupmarkupstyle{code}%
+ % The following should really be moved into \setupmarkupstyle handlers.
+ \catcode\dashChar=\active \catcode\underChar=\active
+ \ifallowcodebreaks
+ \let-\codedash
+ \let_\codeunder
+ \else
+ \let-\normaldash
+ \let_\realunder
+ \fi
\codex
}
}
-\def\realdash{-}
+\def\codex #1{\tclose{#1}\endgroup}
+
+\def\normaldash{-}
\def\codedash{-\discretionary{}{}{}}
\def\codeunder{%
% this is all so @math{@code{var_name}+1} can work. In math mode, _
@@ -1818,53 +2518,44 @@ where each line of input produces a line of output.}
\discretionary{}{}{}}%
{\_}%
}
-\def\codex #1{\tclose{#1}\endgroup}
-% @kbd is like @code, except that if the argument is just one @key command,
-% then @kbd has no effect.
+% An additional complication: the above will allow breaks after, e.g.,
+% each of the four underscores in __typeof__. This is bad.
+% @allowcodebreaks provides a document-level way to turn breaking at -
+% and _ on and off.
+%
+\newif\ifallowcodebreaks \allowcodebreakstrue
-% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
-% `example' (@kbd uses ttsl only inside of @example and friends),
-% or `code' (@kbd uses normal tty font always).
-\parseargdef\kbdinputstyle{%
- \def\arg{#1}%
- \ifx\arg\worddistinct
- \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
- \else\ifx\arg\wordexample
- \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
- \else\ifx\arg\wordcode
- \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+\def\keywordtrue{true}
+\def\keywordfalse{false}
+
+\parseargdef\allowcodebreaks{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\keywordtrue
+ \allowcodebreakstrue
+ \else\ifx\txiarg\keywordfalse
+ \allowcodebreaksfalse
\else
\errhelp = \EMsimple
- \errmessage{Unknown @kbdinputstyle option `\arg'}%
- \fi\fi\fi
+ \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}%
+ \fi\fi
}
-\def\worddistinct{distinct}
-\def\wordexample{example}
-\def\wordcode{code}
-
-% Default is `distinct.'
-\kbdinputstyle distinct
-
-\def\xkey{\key}
-\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
-\ifx\one\xkey\ifx\threex\three \key{#2}%
-\else{\tclose{\kbdfont\look}}\fi
-\else{\tclose{\kbdfont\look}}\fi}
-% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
-\let\indicateurl=\code
-\let\env=\code
+% For @command, @env, @file, @option quotes seem unnecessary,
+% so use \code rather than \samp.
\let\command=\code
+\let\env=\code
+\let\file=\code
+\let\option=\code
% @uref (abbreviation for `urlref') takes an optional (comma-separated)
% second argument specifying the text to display and an optional third
% arg as text to display instead of (rather than in addition to) the url
-% itself. First (mandatory) arg is the url. Perhaps eventually put in
-% a hypertex \special here.
-%
-\def\uref#1{\douref #1,,,\finish}
-\def\douref#1,#2,#3,#4\finish{\begingroup
+% itself. First (mandatory) arg is the url.
+% (This \urefnobreak definition isn't used now, leaving it for a while
+% for comparison.)
+\def\urefnobreak#1{\dourefnobreak #1,,,\finish}
+\def\dourefnobreak#1,#2,#3,#4\finish{\begingroup
\unsepspaces
\pdfurl{#1}%
\setbox0 = \hbox{\ignorespaces #3}%
@@ -1885,6 +2576,103 @@ where each line of input produces a line of output.}
\endlink
\endgroup}
+% This \urefbreak definition is the active one.
+\def\urefbreak{\begingroup \urefcatcodes \dourefbreak}
+\let\uref=\urefbreak
+\def\dourefbreak#1{\urefbreakfinish #1,,,\finish}
+\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example
+ \unsepspaces
+ \pdfurl{#1}%
+ \setbox0 = \hbox{\ignorespaces #3}%
+ \ifdim\wd0 > 0pt
+ \unhbox0 % third arg given, show only that
+ \else
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \ifpdf
+ \unhbox0 % PDF: 2nd arg given, show only it
+ \else
+ \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url
+ \fi
+ \else
+ \urefcode{#1}% only url given, so show it
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% Allow line breaks around only a few characters (only).
+\def\urefcatcodes{%
+ \catcode\ampChar=\active \catcode\dotChar=\active
+ \catcode\hashChar=\active \catcode\questChar=\active
+ \catcode\slashChar=\active
+}
+{
+ \urefcatcodes
+ %
+ \global\def\urefcode{\begingroup
+ \setupmarkupstyle{code}%
+ \urefcatcodes
+ \let&\urefcodeamp
+ \let.\urefcodedot
+ \let#\urefcodehash
+ \let?\urefcodequest
+ \let/\urefcodeslash
+ \codex
+ }
+ %
+ % By default, they are just regular characters.
+ \global\def&{\normalamp}
+ \global\def.{\normaldot}
+ \global\def#{\normalhash}
+ \global\def?{\normalquest}
+ \global\def/{\normalslash}
+}
+
+% we put a little stretch before and after the breakable chars, to help
+% line breaking of long url's. The unequal skips make look better in
+% cmtt at least, especially for dots.
+\def\urefprestretch{\urefprebreak \hskip0pt plus.13em }
+\def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em }
+%
+\def\urefcodeamp{\urefprestretch \&\urefpoststretch}
+\def\urefcodedot{\urefprestretch .\urefpoststretch}
+\def\urefcodehash{\urefprestretch \#\urefpoststretch}
+\def\urefcodequest{\urefprestretch ?\urefpoststretch}
+\def\urefcodeslash{\futurelet\next\urefcodeslashfinish}
+{
+ \catcode`\/=\active
+ \global\def\urefcodeslashfinish{%
+ \urefprestretch \slashChar
+ % Allow line break only after the final / in a sequence of
+ % slashes, to avoid line break between the slashes in http://.
+ \ifx\next/\else \urefpoststretch \fi
+ }
+}
+
+% One more complication: by default we'll break after the special
+% characters, but some people like to break before the special chars, so
+% allow that. Also allow no breaking at all, for manual control.
+%
+\parseargdef\urefbreakstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\wordnone
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordbefore
+ \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordafter
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak}
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @urefbreakstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\wordafter{after}
+\def\wordbefore{before}
+\def\wordnone{none}
+
+\urefbreakstyle after
+
% @url synonym for @uref, since that's how everyone uses it.
%
\let\url=\uref
@@ -1906,34 +2694,81 @@ where each line of input produces a line of output.}
\let\email=\uref
\fi
-% Check if we are currently using a typewriter font. Since all the
-% Computer Modern typewriter fonts have zero interword stretch (and
-% shrink), and it is reasonable to expect all typewriter fonts to have
-% this property, we can check that font parameter.
-%
-\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+% `example' (@kbd uses ttsl only inside of @example and friends),
+% or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\worddistinct
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+ \else\ifx\txiarg\wordexample
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+ \else\ifx\txiarg\wordcode
+ \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @kbdinputstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct'.
+\kbdinputstyle distinct
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}}
+
+\def\xkey{\key}
+\def\kbdsub#1#2#3\par{%
+ \def\one{#1}\def\three{#3}\def\threex{??}%
+ \ifx\one\xkey\ifx\threex\three \key{#2}%
+ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+}
+
+% definition of @key that produces a lozenge. Doesn't adjust to text size.
+%\setfont\keyrm\rmshape{8}{1000}{OT1}
+%\font\keysy=cmsy9
+%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+% \vbox{\hrule\kern-0.4pt
+% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+% \kern-0.4pt\hrule}%
+% \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+
+% definition of @key with no lozenge. If the current font is already
+% monospace, don't change it; that way, we respect @kbdinputstyle. But
+% if it isn't monospace, then use \tt.
+%
+\def\key#1{{\setupmarkupstyle{key}%
+ \nohyphenation
+ \ifmonospace\else\tt\fi
+ #1}\null}
+
+% @clicksequence{File @click{} Open ...}
+\def\clicksequence#1{\begingroup #1\endgroup}
+
+% @clickstyle @arrow (by default)
+\parseargdef\clickstyle{\def\click{#1}}
+\def\click{\arrow}
% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
%
\def\dmn#1{\thinspace #1}
-\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
-
% @l was never documented to mean ``switch to the Lisp font'',
% and it is not used as such in any manual I can find. We need it for
% Polish suppressed-l. --karl, 22sep96.
%\def\l#1{{\li #1}\null}
-% Explicit font changes: @r, @sc, undocumented @ii.
-\def\r#1{{\rm #1}} % roman font
-\def\sc#1{{\smallcaps#1}} % smallcaps font
-\def\ii#1{{\it #1}} % italic font
-
% @acronym for "FBI", "NATO", and the like.
% We print this one point size smaller, since it's intended for
% all-uppercase.
-%
+%
\def\acronym#1{\doacronym #1,,\finish}
\def\doacronym#1,#2,#3\finish{%
{\selectfonts\lsize #1}%
@@ -1941,24 +2776,392 @@ where each line of input produces a line of output.}
\ifx\temp\empty \else
\space ({\unsepspaces \ignorespaces \temp \unskip})%
\fi
+ \null % reset \spacefactor=1000
}
% @abbr for "Comput. J." and the like.
% No font change, but don't do end-of-sentence spacing.
-%
+%
\def\abbr#1{\doabbr #1,,\finish}
\def\doabbr#1,#2,#3\finish{%
- {\frenchspacing #1}%
+ {\plainfrenchspacing #1}%
\def\temp{#2}%
\ifx\temp\empty \else
\space ({\unsepspaces \ignorespaces \temp \unskip})%
\fi
+ \null % reset \spacefactor=1000
+}
+
+% @asis just yields its argument. Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}. So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+ \catcode`\_ = \active
+ \gdef\mathunderscore{%
+ \catcode`\_=\active
+ \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+ }
+}
+% Another complication: we want \\ (and @\) to output a math (or tt) \.
+% FYI, plain.tex uses \\ as a temporary control sequence (for no
+% particular reason), but this is not advertised and we don't care.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+ \tex
+ \mathunderscore
+ \let\\ = \mathbackslash
+ \mathactive
+ % make the texinfo accent commands work in math mode
+ \let\"=\ddot
+ \let\'=\acute
+ \let\==\bar
+ \let\^=\hat
+ \let\`=\grave
+ \let\u=\breve
+ \let\v=\check
+ \let\~=\tilde
+ \let\dotaccent=\dot
+ $\finishmath
+}
+\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+ \catcode`^ = \active
+ \catcode`< = \active
+ \catcode`> = \active
+ \catcode`+ = \active
+ \catcode`' = \active
+ \gdef\mathactive{%
+ \let^ = \ptexhat
+ \let< = \ptexless
+ \let> = \ptexgtr
+ \let+ = \ptexplus
+ \let' = \ptexquoteright
+ }
+}
+
+% ctrl is no longer a Texinfo command, but leave this definition for fun.
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}.
+% Ignore unless FMTNAME == tex; then it is like @iftex and @tex,
+% except specified as a normal braced arg, so no newlines to worry about.
+%
+\def\outfmtnametex{tex}
+%
+\long\def\inlinefmt#1{\doinlinefmt #1,\finish}
+\long\def\doinlinefmt#1,#2,\finish{%
+ \def\inlinefmtname{#1}%
+ \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi
+}
+% For raw, must switch into @tex before parsing the argument, to avoid
+% setting catcodes prematurely. Doing it this way means that, for
+% example, @inlineraw{html, foo{bar} gets a parse error instead of being
+% ignored. But this isn't important because if people want a literal
+% *right* brace they would have to use a command anyway, so they may as
+% well use a command to get a left brace too. We could re-use the
+% delimiter character idea from \verb, but it seems like overkill.
+%
+\long\def\inlineraw{\tex \doinlineraw}
+\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish}
+\def\doinlinerawtwo#1,#2,\finish{%
+ \def\inlinerawname{#1}%
+ \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi
+ \endgroup % close group opened by \tex.
+}
+
+
+\message{glyphs,}
+% and logos.
+
+% @@ prints an @, as does @atchar{}.
+\def\@{\char64 }
+\let\atchar=\@
+
+% @{ @} @lbracechar{} @rbracechar{} all generate brace characters.
+% Unless we're in typewriter, use \ecfont because the CM text fonts do
+% not have braces, and we don't want to switch into math.
+\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}}
+\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}}
+\let\{=\mylbrace \let\lbracechar=\{
+\let\}=\myrbrace \let\rbracechar=\}
+\begingroup
+ % Definitions to produce \{ and \} commands for indices,
+ % and @{ and @} for the aux/toc files.
+ \catcode`\{ = \other \catcode`\} = \other
+ \catcode`\[ = 1 \catcode`\] = 2
+ \catcode`\! = 0 \catcode`\\ = \other
+ !gdef!lbracecmd[\{]%
+ !gdef!rbracecmd[\}]%
+ !gdef!lbraceatcmd[@{]%
+ !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \ptexc
+\let\dotaccent = \ptexdot
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \ptext
+\let\ubaraccent = \ptexb
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+ \def\temp{#1}%
+ \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi
+ \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi
+ \else \errmessage{@dotless can be used only with i or j}%
+ \fi\fi
}
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence. (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo. Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+ L\kern-.36em
+ {\setbox0=\hbox{T}%
+ \vbox to \ht0{\hbox{%
+ \ifx\textnominalsize\xwordpt
+ % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX.
+ % Revert to plain's \scriptsize, which is 7pt.
+ \count255=\the\fam $\fam\count255 \scriptstyle A$%
+ \else
+ % For 11pt, we can use our lllsize.
+ \selectfonts\lllsize A%
+ \fi
+ }%
+ \vss
+ }}%
+ \kern-.15em
+ \TeX
+}
+
+% Some math mode symbols.
+\def\bullet{$\ptexbullet$}
+\def\geq{\ifmmode \ge\else $\ge$\fi}
+\def\leq{\ifmmode \le\else $\le$\fi}
+\def\minus{\ifmmode -\else $-$\fi}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in the cm
+% typewriter fonts as three actual period characters; on the other hand,
+% in other typewriter fonts three periods are wider than 1.5em. So do
+% whichever is larger.
+%
+\def\dots{%
+ \leavevmode
+ \setbox0=\hbox{...}% get width of three periods
+ \ifdim\wd0 > 1.5em
+ \dimen0 = \wd0
+ \else
+ \dimen0 = 1.5em
+ \fi
+ \hbox to \dimen0{%
+ \hskip 0pt plus.25fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus.5fil
+ }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+ \dots
+ \spacefactor=\endofsentencespacefactor
+}
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, they should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}}
+\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+ \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+ \advance\hsize by -2\dimen2 % Rules.
+ \vbox{%
+ \hrule height\dimen2
+ \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
+ \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+ \kern3pt\vrule width\dimen2}% Space to right.
+ \hrule height\dimen2}
+ \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
%
\def\pounds{{\it\$}}
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+%
+% Although only regular is the truly official Euro symbol, we ignore
+% that. The Euro is designed to be slightly taller than the regular
+% font height.
+%
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+%
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+%
+% Also doesn't work in math. Do we need to do math with euro symbols?
+% Hope not.
+%
+%
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+ % We set the font at each command, rather than predefining it in
+ % \textfonts and the other font-switching commands, so that
+ % installations which never need the symbol don't have to have the
+ % font installed.
+ %
+ % There is only one designed size (nominal 10pt), so we always scale
+ % that to the current nominal size.
+ %
+ % By the way, simply using "at 1em" works for cmr10 and the like, but
+ % does not work for cmbx10 and other extended/shrunken fonts.
+ %
+ \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+ %
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+ \else
+ % regular:
+ \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+ \fi
+ \thiseurofont
+}
+
+% Glyphs from the EC fonts. We don't use \let for the aliases, because
+% sometimes we redefine the original macro, and the alias should reflect
+% the redefinition.
+%
+% Use LaTeX names for the Icelandic letters.
+\def\DH{{\ecfont \char"D0}} % Eth
+\def\dh{{\ecfont \char"F0}} % eth
+\def\TH{{\ecfont \char"DE}} % Thorn
+\def\th{{\ecfont \char"FE}} % thorn
+%
+\def\guillemetleft{{\ecfont \char"13}}
+\def\guillemotleft{\guillemetleft}
+\def\guillemetright{{\ecfont \char"14}}
+\def\guillemotright{\guillemetright}
+\def\guilsinglleft{{\ecfont \char"0E}}
+\def\guilsinglright{{\ecfont \char"0F}}
+\def\quotedblbase{{\ecfont \char"12}}
+\def\quotesinglbase{{\ecfont \char"0D}}
+%
+% This positioning is not perfect (see the ogonek LaTeX package), but
+% we have the precomposed glyphs for the most common cases. We put the
+% tests to use those glyphs in the single \ogonek macro so we have fewer
+% dummy definitions to worry about for index entries, etc.
+%
+% ogonek is also used with other letters in Lithuanian (IOU), but using
+% the precomposed glyphs for those is not so easy since they aren't in
+% the same EC font.
+\def\ogonek#1{{%
+ \def\temp{#1}%
+ \ifx\temp\macrocharA\Aogonek
+ \else\ifx\temp\macrochara\aogonek
+ \else\ifx\temp\macrocharE\Eogonek
+ \else\ifx\temp\macrochare\eogonek
+ \else
+ \ecfont \setbox0=\hbox{#1}%
+ \ifdim\ht0=1ex\accent"0C #1%
+ \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}%
+ \fi
+ \fi\fi\fi\fi
+ }%
+}
+\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A}
+\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a}
+\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E}
+\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e}
+%
+% Use the ec* fonts (cm-super in outline format) for non-CM glyphs.
+\def\ecfont{%
+ % We can't distinguish serif/sans and italic/slanted, but this
+ % is used for crude hacks anyway (like adding French and German
+ % quotes to documents typeset with CM, where we lose kerning), so
+ % hopefully nobody will notice/care.
+ \edef\ecsize{\csname\curfontsize ecsize\endcsname}%
+ \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
+ \ifmonospace
+ % typewriter:
+ \font\thisecfont = ectt\ecsize \space at \nominalsize
+ \else
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+ \else
+ % regular:
+ \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
+ \fi
+ \fi
+ \thisecfont
+}
+
% @registeredsymbol - R in a circle. The font for the R should really
% be smaller yet, but lllsize is the best we can do for now.
% Adapted from the plain.tex definition of \copyright.
@@ -1969,14 +3172,24 @@ where each line of input produces a line of output.}
}$%
}
+% @textdegree - the normal degrees sign.
+%
+\def\textdegree{$^\circ$}
+
% Laurent Siebenmann reports \Orb undefined with:
% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38
% so we'll define it if necessary.
-%
-\ifx\Orb\undefined
+%
+\ifx\Orb\thisisundefined
\def\Orb{\mathhexbox20D}
\fi
+% Quotes.
+\chardef\quotedblleft="5C
+\chardef\quotedblright=`\"
+\chardef\quoteleft=`\`
+\chardef\quoteright=`\'
+
\message{page headings,}
@@ -1995,8 +3208,9 @@ where each line of input produces a line of output.}
\newif\ifsetshortcontentsaftertitlepage
\let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
-\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
- \endgroup\page\hbox{}\page}
+\parseargdef\shorttitlepage{%
+ \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
\envdef\titlepage{%
% Open one extra group, as we want to close it in the middle of \Etitlepage.
@@ -2056,17 +3270,28 @@ where each line of input produces a line of output.}
\finishedtitlepagetrue
}
-%%% Macros to be used within @titlepage:
+% Settings used for typesetting titles: no hyphenation, no indentation,
+% don't worry much about spacing, ragged right. This should be used
+% inside a \vbox, and fonts need to be set appropriately first. Because
+% it is always used for titles, nothing else, we call \rmisbold. \par
+% should be specified before the end of the \vbox, since a vbox is a group.
+%
+\def\raggedtitlesettings{%
+ \rmisbold
+ \hyphenpenalty=10000
+ \parindent=0pt
+ \tolerance=5000
+ \ptexraggedright
+}
+
+% Macros to be used within @titlepage:
\let\subtitlerm=\tenrm
\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
-\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
- \let\tt=\authortt}
-
\parseargdef\title{%
\checkenv\titlepage
- \leftline{\titlefonts\rm #1}
+ \vbox{\titlefonts \raggedtitlesettings #1\par}%
% print a rule at the page bottom also.
\finishedtitlepagefalse
\vskip4pt \hrule height 4pt width \hsize \vskip4pt
@@ -2087,12 +3312,12 @@ where each line of input produces a line of output.}
\else
\checkenv\titlepage
\ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
- {\authorfont \leftline{#1}}%
+ {\secfonts\rmisbold \leftline{#1}}%
\fi
}
-%%% Set up page headings and footings.
+% Set up page headings and footings.
\let\thispage=\folio
@@ -2140,12 +3365,39 @@ where each line of input produces a line of output.}
%
% Leave some space for the footline. Hopefully ok to assume
% @evenfooting will not be used by itself.
- \global\advance\pageheight by -\baselineskip
- \global\advance\vsize by -\baselineskip
+ \global\advance\pageheight by -12pt
+ \global\advance\vsize by -12pt
}
\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+% @evenheadingmarks top \thischapter <- chapter at the top of a page
+% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page
+%
+% The same set of arguments for:
+%
+% @oddheadingmarks
+% @evenfootingmarks
+% @oddfootingmarks
+% @everyheadingmarks
+% @everyfootingmarks
+
+\def\evenheadingmarks{\headingmarks{even}{heading}}
+\def\oddheadingmarks{\headingmarks{odd}{heading}}
+\def\evenfootingmarks{\headingmarks{even}{footing}}
+\def\oddfootingmarks{\headingmarks{odd}{footing}}
+\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1}
+ \headingmarks{odd}{heading}{#1} }
+\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1}
+ \headingmarks{odd}{footing}{#1} }
+% #1 = even/odd, #2 = heading/footing, #3 = top/bottom.
+\def\headingmarks#1#2#3 {%
+ \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname
+ \global\expandafter\let\csname get#1#2marks\endcsname \temp
+}
+
+\everyheadingmarks bottom
+\everyfootingmarks bottom
% @headings double turns headings on for double-sided printing.
% @headings single turns headings on for single-sided printing.
@@ -2159,10 +3411,14 @@ where each line of input produces a line of output.}
\def\headings #1 {\csname HEADINGS#1\endcsname}
-\def\HEADINGSoff{%
-\global\evenheadline={\hfil} \global\evenfootline={\hfil}
-\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
-\HEADINGSoff
+\def\headingsoff{% non-global headings elimination
+ \evenheadline={\hfil}\evenfootline={\hfil}%
+ \oddheadline={\hfil}\oddfootline={\hfil}%
+}
+
+\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting
+\HEADINGSoff % it's the default
+
% When we turn headings on, set the page number to 1.
% For double-sided printing, put current file name in lower left corner,
% chapter name on inside top of right hand pages, document
@@ -2213,7 +3469,7 @@ where each line of input produces a line of output.}
% This produces Day Month Year style of output.
% Only define if not already defined, in case a txi-??.tex file has set
% up a different format (e.g., txi-cs.tex does this).
-\ifx\today\undefined
+\ifx\today\thisisundefined
\def\today{%
\number\day\space
\ifcase\month
@@ -2274,7 +3530,7 @@ where each line of input produces a line of output.}
\begingroup
\advance\leftskip by-\tableindent
\advance\hsize by\tableindent
- \advance\rightskip by0pt plus1fil
+ \advance\rightskip by0pt plus1fil\relax
\leavevmode\unhbox0\par
\endgroup
%
@@ -2288,7 +3544,7 @@ where each line of input produces a line of output.}
% cause the example and the item to crash together. So we use this
% bizarre value of 10001 as a signal to \aboveenvbreak to insert
% \parskip glue after all. Section titles are handled this way also.
- %
+ %
\penalty 10001
\endgroup
\itemxneedsnegativevskipfalse
@@ -2314,15 +3570,26 @@ where each line of input produces a line of output.}
% @table, @ftable, @vtable.
\envdef\table{%
\let\itemindex\gobble
- \tablex
+ \tablecheck{table}%
}
\envdef\ftable{%
\def\itemindex ##1{\doind {fn}{\code{##1}}}%
- \tablex
+ \tablecheck{ftable}%
}
\envdef\vtable{%
\def\itemindex ##1{\doind {vr}{\code{##1}}}%
- \tablex
+ \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+ \ifnum \the\catcode`\^^M=\active
+ \endgroup
+ \errmessage{This command won't work in this context; perhaps the problem is
+ that we are \inenvironment\thisenv}%
+ \def\next{\doignore{#1}}%
+ \else
+ \let\next\tablex
+ \fi
+ \next
}
\def\tablex#1{%
\def\itemindicate{#1}%
@@ -2371,9 +3638,18 @@ where each line of input produces a line of output.}
\parindent=0pt
\parskip=\smallskipamount
\ifdim\parskip=0pt \parskip=2pt \fi
+ %
+ % Try typesetting the item mark that if the document erroneously says
+ % something like @itemize @samp (intending @table), there's an error
+ % right away at the @itemize. It's not the best error message in the
+ % world, but it's better than leaving it to the @item. This means if
+ % the user wants an empty mark, they have to say @w{} not just @w.
\def\itemcontents{#1}%
+ \setbox0 = \hbox{\itemcontents}%
+ %
% @itemize with no arg is equivalent to @itemize @bullet.
\ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+ %
\let\item=\itemizeitem
}
@@ -2394,6 +3670,7 @@ where each line of input produces a line of output.}
\ifnum\lastpenalty<10000 \parskip=0in \fi
\noindent
\hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+ %
\vadjust{\penalty 1200}}% not good to break after first line of item.
\flushcr
}
@@ -2615,12 +3892,19 @@ where each line of input produces a line of output.}
%
% @headitem starts a heading row, which we typeset in bold.
% Assignments have to be global since we are inside the implicit group
-% of an alignment entry. Note that \everycr resets \everytab.
-\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}%
+% of an alignment entry. \everycr resets \everytab so we don't have to
+% undo it ourselves.
+\def\headitemfont{\b}% for people to use in the template row; not changeable
+\def\headitem{%
+ \checkenv\multitable
+ \crcr
+ \global\everytab={\bf}% can't use \headitemfont since the parsing differs
+ \the\everytab % for the first item
+}%
%
% A \tab used to include \hskip1sp. But then the space in a template
% line is not enough. That is bad. So let's go back to just `&' until
-% we encounter the problem it was intended to solve again.
+% we again encounter the problem the 1sp was intended to solve.
% --karl, nathan@acm.org, 20apr99.
\def\tab{\checkenv\multitable &\the\everytab}%
@@ -2721,31 +4005,29 @@ where each line of input produces a line of output.}
\global\setpercentfalse
}
-\def\setmultitablespacing{% test to see if user has set \multitablelinespace.
-% If so, do nothing. If not, give it an appropriate dimension based on
-% current baselineskip.
+\def\setmultitablespacing{%
+ \def\multistrut{\strut}% just use the standard line spacing
+ %
+ % Compute \multitablelinespace (if not defined by user) for use in
+ % \multitableparskip calculation. We used define \multistrut based on
+ % this, but (ironically) that caused the spacing to be off.
+ % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
\ifdim\multitablelinespace=0pt
\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
\global\advance\multitablelinespace by-\ht0
-%% strut to put in table in case some entry doesn't have descenders,
-%% to keep lines equally spaced
-\let\multistrut = \strut
-\else
-%% FIXME: what is \box0 supposed to be?
-\gdef\multistrut{\vrule height\multitablelinespace depth\dp0
-width0pt\relax} \fi
-%% Test to see if parskip is larger than space between lines of
-%% table. If not, do nothing.
-%% If so, set to same dimension as multitablelinespace.
+\fi
+% Test to see if parskip is larger than space between lines of
+% table. If not, do nothing.
+% If so, set to same dimension as multitablelinespace.
\ifdim\multitableparskip>\multitablelinespace
\global\multitableparskip=\multitablelinespace
-\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
- %% than skip between lines in the table.
+\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
+ % than skip between lines in the table.
\fi%
\ifdim\multitableparskip=0pt
\global\multitableparskip=\multitablelinespace
-\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
- %% than skip between lines in the table.
+\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
+ % than skip between lines in the table.
\fi}
@@ -2791,6 +4073,7 @@ width0pt\relax} \fi
\def\doignore#1{\begingroup
% Scan in ``verbatim'' mode:
+ \obeylines
\catcode`\@ = \other
\catcode`\{ = \other
\catcode`\} = \other
@@ -2811,16 +4094,16 @@ width0pt\relax} \fi
\gdef\dodoignore#1{%
% #1 contains the command name as a string, e.g., `ifinfo'.
%
- % Define a command to find the next `@end #1', which must be on a line
- % by itself.
- \long\def\doignoretext##1^^M@end #1{\doignoretextyyy##1^^M@#1\_STOP_}%
+ % Define a command to find the next `@end #1'.
+ \long\def\doignoretext##1^^M@end #1{%
+ \doignoretextyyy##1^^M@#1\_STOP_}%
+ %
% And this command to find another #1 command, at the beginning of a
% line. (Otherwise, we would consider a line `@c @ifset', for
% example, to count as an @ifset for nesting.)
\long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
%
% And now expand that command.
- \obeylines %
\doignoretext ^^M%
}%
}
@@ -2850,7 +4133,12 @@ width0pt\relax} \fi
}
% Finish off ignored text.
-\def\enddoignore{\endgroup\ignorespaces}
+{ \obeylines%
+ % Ignore anything after the last `@end #1'; this matters in verbatim
+ % environments, where otherwise the newline after an ignored conditional
+ % would result in a blank line in the output.
+ \gdef\enddoignore#1^^M{\endgroup\ignorespaces}%
+}
% @set VAR sets the variable VAR to an empty value.
@@ -2900,7 +4188,7 @@ width0pt\relax} \fi
% ..., but we might end up with active ones in the argument if
% we're called from @code, as @code{@value{foo-bar_}}, though.
% So \let them to their normal equivalents.
- \let-\realdash \let_\normalunderscore
+ \let-\normaldash \let_\normalunderscore
}
}
@@ -2940,7 +4228,7 @@ width0pt\relax} \fi
}
\def\ifsetfail{\doignore{ifset}}
-% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% @ifclear VAR ... @end executes the `...' iff VAR has never been
% defined with @set, or has been undefined with @clear.
%
% The `\else' inside the `\doifset' parameter is a trick to reuse the
@@ -2951,6 +4239,35 @@ width0pt\relax} \fi
\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
\def\ifclearfail{\doignore{ifclear}}
+% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written
+% without the @) is in fact defined. We can only feasibly check at the
+% TeX level, so something like `mathcode' is going to considered
+% defined even though it is not a Texinfo command.
+%
+\makecond{ifcommanddefined}
+\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}}
+%
+\def\doifcmddefined#1#2{{%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname #2\endcsname\relax
+ #1% If not defined, \let\next as above.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifcmddefinedfail{\doignore{ifcommanddefined}}
+
+% @ifcommandnotdefined CMD ... handled similar to @ifclear above.
+\makecond{ifcommandnotdefined}
+\def\ifcommandnotdefined{%
+ \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}}
+\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}}
+
+% Set the `txicommandconditionals' variable, so documents have a way to
+% test if the @ifcommand...defined conditionals are available.
+\set txicommandconditionals
+
% @dircategory CATEGORY -- specify a category of the dir file
% which this file should belong to. Ignore this in TeX.
\let\dircategory=\comment
@@ -2963,9 +4280,8 @@ width0pt\relax} \fi
% Index generation facilities
% Define \newwrite to be identical to plain tex's \newwrite
-% except not \outer, so it can be used within \newindex.
-{\catcode`\@=11
-\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}}
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
% \newindex {foo} defines an index named foo.
% It automatically defines \fooindex such that
@@ -3016,11 +4332,11 @@ width0pt\relax} \fi
\def\dosynindex#1#2#3{%
% Only do \closeout if we haven't already done it, else we'll end up
% closing the target index.
- \expandafter \ifx\csname donesynindex#2\endcsname \undefined
+ \expandafter \ifx\csname donesynindex#2\endcsname \relax
% The \closeout helps reduce unnecessary open files; the limit on the
% Acorn RISC OS is a mere 16 files.
\expandafter\closeout\csname#2indfile\endcsname
- \expandafter\let\csname\donesynindex#2\endcsname = 1
+ \expandafter\let\csname donesynindex#2\endcsname = 1
\fi
% redefine \fooindfile:
\expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
@@ -3051,42 +4367,53 @@ width0pt\relax} \fi
% we have to laboriously prevent expansion for those that we don't.
%
\def\indexdummies{%
+ \escapechar = `\\ % use backslash in output files.
\def\@{@}% change to @@ when we switch to @ as escape char in index files.
\def\ {\realbackslash\space }%
- % Need these in case \tex is in effect and \{ is a \delimiter again.
- % But can't use \lbracecmd and \rbracecmd because texindex assumes
- % braces and backslashes are used only as delimiters.
- \let\{ = \mylbrace
- \let\} = \myrbrace
- %
- % \definedummyword defines \#1 as \realbackslash #1\space, thus
- % effectively preventing its expansion. This is used only for control
- % words, not control letters, because the \space would be incorrect
- % for control characters, but is needed to separate the control word
- % from whatever follows.
%
- % For control letters, we have \definedummyletter, which omits the
- % space.
- %
- % These can be used both for control words that take an argument and
- % those that do not. If it is followed by {arg} in the input, then
- % that will dutifully get written to the index (or wherever).
- %
- \def\definedummyword##1{%
- \expandafter\def\csname ##1\endcsname{\realbackslash ##1\space}%
- }%
- \def\definedummyletter##1{%
- \expandafter\def\csname ##1\endcsname{\realbackslash ##1}%
- }%
- \let\definedummyaccent\definedummyletter
+ % Need these unexpandable (because we define \tt as a dummy)
+ % definitions when @{ or @} appear in index entry text. Also, more
+ % complicated, when \tex is in effect and \{ is a \delimiter again.
+ % We can't use \lbracecmd and \rbracecmd because texindex assumes
+ % braces and backslashes are used only as delimiters. Perhaps we
+ % should define @lbrace and @rbrace commands a la @comma.
+ \def\{{{\tt\char123}}%
+ \def\}{{\tt\char125}}%
+ %
+ % I don't entirely understand this, but when an index entry is
+ % generated from a macro call, the \endinput which \scanmacro inserts
+ % causes processing to be prematurely terminated. This is,
+ % apparently, because \indexsorttmp is fully expanded, and \endinput
+ % is an expandable command. The redefinition below makes \endinput
+ % disappear altogether for that purpose -- although logging shows that
+ % processing continues to some further point. On the other hand, it
+ % seems \endinput does not hurt in the printed index arg, since that
+ % is still getting written without apparent harm.
+ %
+ % Sample source (mac-idx3.tex, reported by Graham Percival to
+ % help-texinfo, 22may06):
+ % @macro funindex {WORD}
+ % @findex xyz
+ % @end macro
+ % ...
+ % @funindex commtest
+ %
+ % The above is not enough to reproduce the bug, but it gives the flavor.
+ %
+ % Sample whatsit resulting:
+ % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
+ %
+ % So:
+ \let\endinput = \empty
%
% Do the redefinitions.
\commondummies
}
-% For the aux file, @ is the escape character. So we want to redefine
-% everything using @ instead of \realbackslash. When everything uses
-% @, this will be simpler.
+% For the aux and toc files, @ is the escape character. So we want to
+% redefine everything using @ as the escape character (instead of
+% \realbackslash, still used for index files). When everything uses @,
+% this will be simpler.
%
\def\atdummies{%
\def\@{@@}%
@@ -3094,146 +4421,184 @@ width0pt\relax} \fi
\let\{ = \lbraceatcmd
\let\} = \rbraceatcmd
%
- % (See comments in \indexdummies.)
- \def\definedummyword##1{%
- \expandafter\def\csname ##1\endcsname{@##1\space}%
- }%
- \def\definedummyletter##1{%
- \expandafter\def\csname ##1\endcsname{@##1}%
- }%
- \let\definedummyaccent\definedummyletter
- %
% Do the redefinitions.
\commondummies
+ \otherbackslash
}
-% Called from \indexdummies and \atdummies. \definedummyword and
-% \definedummyletter must be defined first.
+% Called from \indexdummies and \atdummies.
%
\def\commondummies{%
%
- \normalturnoffactive
+ % \definedummyword defines \#1 as \string\#1\space, thus effectively
+ % preventing its expansion. This is used only for control words,
+ % not control letters, because the \space would be incorrect for
+ % control characters, but is needed to separate the control word
+ % from whatever follows.
+ %
+ % For control letters, we have \definedummyletter, which omits the
+ % space.
+ %
+ % These can be used both for control words that take an argument and
+ % those that do not. If it is followed by {arg} in the input, then
+ % that will dutifully get written to the index (or wherever).
+ %
+ \def\definedummyword ##1{\def##1{\string##1\space}}%
+ \def\definedummyletter##1{\def##1{\string##1}}%
+ \let\definedummyaccent\definedummyletter
%
\commondummiesnofonts
%
- \definedummyletter{_}%
+ \definedummyletter\_%
+ \definedummyletter\-%
%
% Non-English letters.
- \definedummyword{AA}%
- \definedummyword{AE}%
- \definedummyword{L}%
- \definedummyword{OE}%
- \definedummyword{O}%
- \definedummyword{aa}%
- \definedummyword{ae}%
- \definedummyword{l}%
- \definedummyword{oe}%
- \definedummyword{o}%
- \definedummyword{ss}%
- \definedummyword{exclamdown}%
- \definedummyword{questiondown}%
- \definedummyword{ordf}%
- \definedummyword{ordm}%
+ \definedummyword\AA
+ \definedummyword\AE
+ \definedummyword\DH
+ \definedummyword\L
+ \definedummyword\O
+ \definedummyword\OE
+ \definedummyword\TH
+ \definedummyword\aa
+ \definedummyword\ae
+ \definedummyword\dh
+ \definedummyword\exclamdown
+ \definedummyword\l
+ \definedummyword\o
+ \definedummyword\oe
+ \definedummyword\ordf
+ \definedummyword\ordm
+ \definedummyword\questiondown
+ \definedummyword\ss
+ \definedummyword\th
%
% Although these internal commands shouldn't show up, sometimes they do.
- \definedummyword{bf}%
- \definedummyword{gtr}%
- \definedummyword{hat}%
- \definedummyword{less}%
- \definedummyword{sf}%
- \definedummyword{sl}%
- \definedummyword{tclose}%
- \definedummyword{tt}%
- %
- \definedummyword{LaTeX}%
- \definedummyword{TeX}%
+ \definedummyword\bf
+ \definedummyword\gtr
+ \definedummyword\hat
+ \definedummyword\less
+ \definedummyword\sf
+ \definedummyword\sl
+ \definedummyword\tclose
+ \definedummyword\tt
+ %
+ \definedummyword\LaTeX
+ \definedummyword\TeX
%
% Assorted special characters.
- \definedummyword{bullet}%
- \definedummyword{comma}%
- \definedummyword{copyright}%
- \definedummyword{registeredsymbol}%
- \definedummyword{dots}%
- \definedummyword{enddots}%
- \definedummyword{equiv}%
- \definedummyword{error}%
- \definedummyword{expansion}%
- \definedummyword{minus}%
- \definedummyword{pounds}%
- \definedummyword{point}%
- \definedummyword{print}%
- \definedummyword{result}%
+ \definedummyword\arrow
+ \definedummyword\bullet
+ \definedummyword\comma
+ \definedummyword\copyright
+ \definedummyword\registeredsymbol
+ \definedummyword\dots
+ \definedummyword\enddots
+ \definedummyword\entrybreak
+ \definedummyword\equiv
+ \definedummyword\error
+ \definedummyword\euro
+ \definedummyword\expansion
+ \definedummyword\geq
+ \definedummyword\guillemetleft
+ \definedummyword\guillemetright
+ \definedummyword\guilsinglleft
+ \definedummyword\guilsinglright
+ \definedummyword\lbracechar
+ \definedummyword\leq
+ \definedummyword\minus
+ \definedummyword\ogonek
+ \definedummyword\pounds
+ \definedummyword\point
+ \definedummyword\print
+ \definedummyword\quotedblbase
+ \definedummyword\quotedblleft
+ \definedummyword\quotedblright
+ \definedummyword\quoteleft
+ \definedummyword\quoteright
+ \definedummyword\quotesinglbase
+ \definedummyword\rbracechar
+ \definedummyword\result
+ \definedummyword\textdegree
+ %
+ % We want to disable all macros so that they are not expanded by \write.
+ \macrolist
+ %
+ \normalturnoffactive
%
% Handle some cases of @value -- where it does not contain any
% (non-fully-expandable) commands.
\makevalueexpandable
- %
- % Normal spaces, not active ones.
- \unsepspaces
- %
- % No macro expansion.
- \turnoffmacros
}
% \commondummiesnofonts: common to \commondummies and \indexnofonts.
%
-% Better have this without active chars.
-{
- \catcode`\~=\other
- \gdef\commondummiesnofonts{%
- % Control letters and accents.
- \definedummyletter{!}%
- \definedummyaccent{"}%
- \definedummyaccent{'}%
- \definedummyletter{*}%
- \definedummyaccent{,}%
- \definedummyletter{.}%
- \definedummyletter{/}%
- \definedummyletter{:}%
- \definedummyaccent{=}%
- \definedummyletter{?}%
- \definedummyaccent{^}%
- \definedummyaccent{`}%
- \definedummyaccent{~}%
- \definedummyword{u}%
- \definedummyword{v}%
- \definedummyword{H}%
- \definedummyword{dotaccent}%
- \definedummyword{ringaccent}%
- \definedummyword{tieaccent}%
- \definedummyword{ubaraccent}%
- \definedummyword{udotaccent}%
- \definedummyword{dotless}%
- %
- % Texinfo font commands.
- \definedummyword{b}%
- \definedummyword{i}%
- \definedummyword{r}%
- \definedummyword{sc}%
- \definedummyword{t}%
- %
- % Commands that take arguments.
- \definedummyword{acronym}%
- \definedummyword{cite}%
- \definedummyword{code}%
- \definedummyword{command}%
- \definedummyword{dfn}%
- \definedummyword{emph}%
- \definedummyword{env}%
- \definedummyword{file}%
- \definedummyword{kbd}%
- \definedummyword{key}%
- \definedummyword{math}%
- \definedummyword{option}%
- \definedummyword{samp}%
- \definedummyword{strong}%
- \definedummyword{tie}%
- \definedummyword{uref}%
- \definedummyword{url}%
- \definedummyword{var}%
- \definedummyword{verb}%
- \definedummyword{w}%
- }
+\def\commondummiesnofonts{%
+ % Control letters and accents.
+ \definedummyletter\!%
+ \definedummyaccent\"%
+ \definedummyaccent\'%
+ \definedummyletter\*%
+ \definedummyaccent\,%
+ \definedummyletter\.%
+ \definedummyletter\/%
+ \definedummyletter\:%
+ \definedummyaccent\=%
+ \definedummyletter\?%
+ \definedummyaccent\^%
+ \definedummyaccent\`%
+ \definedummyaccent\~%
+ \definedummyword\u
+ \definedummyword\v
+ \definedummyword\H
+ \definedummyword\dotaccent
+ \definedummyword\ogonek
+ \definedummyword\ringaccent
+ \definedummyword\tieaccent
+ \definedummyword\ubaraccent
+ \definedummyword\udotaccent
+ \definedummyword\dotless
+ %
+ % Texinfo font commands.
+ \definedummyword\b
+ \definedummyword\i
+ \definedummyword\r
+ \definedummyword\sansserif
+ \definedummyword\sc
+ \definedummyword\slanted
+ \definedummyword\t
+ %
+ % Commands that take arguments.
+ \definedummyword\abbr
+ \definedummyword\acronym
+ \definedummyword\anchor
+ \definedummyword\cite
+ \definedummyword\code
+ \definedummyword\command
+ \definedummyword\dfn
+ \definedummyword\dmn
+ \definedummyword\email
+ \definedummyword\emph
+ \definedummyword\env
+ \definedummyword\file
+ \definedummyword\image
+ \definedummyword\indicateurl
+ \definedummyword\inforef
+ \definedummyword\kbd
+ \definedummyword\key
+ \definedummyword\math
+ \definedummyword\option
+ \definedummyword\pxref
+ \definedummyword\ref
+ \definedummyword\samp
+ \definedummyword\strong
+ \definedummyword\tie
+ \definedummyword\uref
+ \definedummyword\url
+ \definedummyword\var
+ \definedummyword\verb
+ \definedummyword\w
+ \definedummyword\xref
}
% \indexnofonts is used when outputting the strings to sort the index
@@ -3243,14 +4608,10 @@ width0pt\relax} \fi
%
\def\indexnofonts{%
% Accent commands should become @asis.
- \def\definedummyaccent##1{%
- \expandafter\let\csname ##1\endcsname\asis
- }%
+ \def\definedummyaccent##1{\let##1\asis}%
% We can just ignore other control letters.
- \def\definedummyletter##1{%
- \expandafter\def\csname ##1\endcsname{}%
- }%
- % Hopefully, all control words can become @asis.
+ \def\definedummyletter##1{\let##1\empty}%
+ % All control words become @asis by default; overrides below.
\let\definedummyword\definedummyaccent
%
\commondummiesnofonts
@@ -3262,50 +4623,95 @@ width0pt\relax} \fi
%
\def\ { }%
\def\@{@}%
- % how to handle braces?
\def\_{\normalunderscore}%
+ \def\-{}% @- shouldn't affect sorting
+ %
+ % Unfortunately, texindex is not prepared to handle braces in the
+ % content at all. So for index sorting, we map @{ and @} to strings
+ % starting with |, since that ASCII character is between ASCII { and }.
+ \def\{{|a}%
+ \def\lbracechar{|a}%
+ %
+ \def\}{|b}%
+ \def\rbracechar{|b}%
%
% Non-English letters.
\def\AA{AA}%
\def\AE{AE}%
+ \def\DH{DZZ}%
\def\L{L}%
\def\OE{OE}%
\def\O{O}%
+ \def\TH{ZZZ}%
\def\aa{aa}%
\def\ae{ae}%
+ \def\dh{dzz}%
+ \def\exclamdown{!}%
\def\l{l}%
\def\oe{oe}%
- \def\o{o}%
- \def\ss{ss}%
- \def\exclamdown{!}%
- \def\questiondown{?}%
\def\ordf{a}%
\def\ordm{o}%
+ \def\o{o}%
+ \def\questiondown{?}%
+ \def\ss{ss}%
+ \def\th{zzz}%
%
\def\LaTeX{LaTeX}%
\def\TeX{TeX}%
%
% Assorted special characters.
% (The following {} will end up in the sort string, but that's ok.)
+ \def\arrow{->}%
\def\bullet{bullet}%
\def\comma{,}%
\def\copyright{copyright}%
- \def\registeredsymbol{R}%
\def\dots{...}%
\def\enddots{...}%
\def\equiv{==}%
\def\error{error}%
+ \def\euro{euro}%
\def\expansion{==>}%
+ \def\geq{>=}%
+ \def\guillemetleft{<<}%
+ \def\guillemetright{>>}%
+ \def\guilsinglleft{<}%
+ \def\guilsinglright{>}%
+ \def\leq{<=}%
\def\minus{-}%
- \def\pounds{pounds}%
\def\point{.}%
+ \def\pounds{pounds}%
\def\print{-|}%
+ \def\quotedblbase{"}%
+ \def\quotedblleft{"}%
+ \def\quotedblright{"}%
+ \def\quoteleft{`}%
+ \def\quoteright{'}%
+ \def\quotesinglbase{,}%
+ \def\registeredsymbol{R}%
\def\result{=>}%
+ \def\textdegree{o}%
%
- % Don't write macro names.
- \emptyusermacros
+ \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax
+ \else \indexlquoteignore \fi
+ %
+ % We need to get rid of all macros, leaving only the arguments (if present).
+ % Of course this is not nearly correct, but it is the best we can do for now.
+ % makeinfo does not expand macros in the argument to @deffn, which ends up
+ % writing an index entry, and texindex isn't prepared for an index sort entry
+ % that starts with \.
+ %
+ % Since macro invocations are followed by braces, we can just redefine them
+ % to take a single TeX argument. The case of a macro invocation that
+ % goes to end-of-line is not handled.
+ %
+ \macrolist
}
+% Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us
+% ignore left quotes in the sort term.
+{\catcode`\`=\active
+ \gdef\indexlquoteignore{\let`=\empty}}
+
\let\indexbackslash=0 %overridden during \printindex.
\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
@@ -3331,11 +4737,7 @@ width0pt\relax} \fi
%
\edef\writeto{\csname#1indfile\endcsname}%
%
- \ifvmode
- \dosubindsanitize
- \else
- \dosubindwrite
- \fi
+ \safewhatsit\dosubindwrite
}%
\fi
}
@@ -3350,7 +4752,6 @@ width0pt\relax} \fi
%
% Remember, we are within a group.
\indexdummies % Must do this here, since \bf, etc expand at this stage
- \escapechar=`\\
\def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
% so it will be output as is; and it will print as backslash.
%
@@ -3373,13 +4774,13 @@ width0pt\relax} \fi
\temp
}
-% Take care of unwanted page breaks:
+% Take care of unwanted page breaks/skips around a whatsit:
%
% If a skip is the last thing on the list now, preserve it
% by backing up by \lastskip, doing the \write, then inserting
% the skip again. Otherwise, the whatsit generated by the
-% \write will make \lastskip zero. The result is that sequences
-% like this:
+% \write or \pdfdest will make \lastskip zero. The result is that
+% sequences like this:
% @end defun
% @tindex whatever
% @defun ...
@@ -3403,25 +4804,30 @@ width0pt\relax} \fi
%
\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
%
+\newskip\whatsitskip
+\newcount\whatsitpenalty
+%
% ..., ready, GO:
%
-\def\dosubindsanitize{%
+\def\safewhatsit#1{\ifhmode
+ #1%
+ \else
% \lastskip and \lastpenalty cannot both be nonzero simultaneously.
- \skip0 = \lastskip
+ \whatsitskip = \lastskip
\edef\lastskipmacro{\the\lastskip}%
- \count255 = \lastpenalty
+ \whatsitpenalty = \lastpenalty
%
% If \lastskip is nonzero, that means the last item was a
% skip. And since a skip is discardable, that means this
- % -\skip0 glue we're inserting is preceded by a
+ % -\whatsitskip glue we're inserting is preceded by a
% non-discardable item, therefore it is not a potential
% breakpoint, therefore no \nobreak needed.
\ifx\lastskipmacro\zeroskipmacro
\else
- \vskip-\skip0
+ \vskip-\whatsitskip
\fi
%
- \dosubindwrite
+ #1%
%
\ifx\lastskipmacro\zeroskipmacro
% If \lastskip was zero, perhaps the last item was a penalty, and
@@ -3429,20 +4835,19 @@ width0pt\relax} \fi
% to re-insert the same penalty (values >10000 are used for various
% signals); since we just inserted a non-discardable item, any
% following glue (such as a \parskip) would be a breakpoint. For example:
- %
% @deffn deffn-whatever
% @vindex index-whatever
% Description.
% would allow a break between the index-whatever whatsit
% and the "Description." paragraph.
- \ifnum\count255>9999 \penalty\count255 \fi
+ \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi
\else
% On the other hand, if we had a nonzero \lastskip,
% this make-up glue would be preceded by a non-discardable item
% (the whatsit from the \write), so we must insert a \nobreak.
- \nobreak\vskip\skip0
+ \nobreak\vskip\whatsitskip
\fi
-}
+\fi}
% The index entry written in the file actually looks like
% \entry {sortstring}{page}{topic}
@@ -3484,6 +4889,7 @@ width0pt\relax} \fi
%
\smallfonts \rm
\tolerance = 9500
+ \plainfrenchspacing
\everypar = {}% don't want the \kern\-parindent from indentation suppression.
%
% See if the index file exists and is nonempty.
@@ -3557,10 +4963,9 @@ width0pt\relax} \fi
%
% A straightforward implementation would start like this:
% \def\entry#1#2{...
-% But this frozes the catcodes in the argument, and can cause problems to
+% But this freezes the catcodes in the argument, and can cause problems to
% @code, which sets - active. This problem was fixed by a kludge---
% ``-'' was active throughout whole index, but this isn't really right.
-%
% The right solution is to prevent \entry from swallowing the whole text.
% --kasal, 21nov03
\def\entry{%
@@ -3597,10 +5002,17 @@ width0pt\relax} \fi
% columns.
\vskip 0pt plus1pt
%
+ % When reading the text of entry, convert explicit line breaks
+ % from @* into spaces. The user might give these in long section
+ % titles, for instance.
+ \def\*{\unskip\space\ignorespaces}%
+ \def\entrybreak{\hfil\break}%
+ %
% Swallow the left brace of the text (first parameter):
\afterassignment\doentry
\let\temp =
}
+\def\entrybreak{\unskip\space\ignorespaces}%
\def\doentry{%
\bgroup % Instead of the swallowed brace.
\noindent
@@ -3613,11 +5025,8 @@ width0pt\relax} \fi
% The following is kludged to not output a line of dots in the index if
% there are no page numbers. The next person who breaks this will be
% cursed by a Unix daemon.
- \def\tempa{{\rm }}%
- \def\tempb{#1}%
- \edef\tempc{\tempa}%
- \edef\tempd{\tempb}%
- \ifx\tempc\tempd
+ \setbox\boxA = \hbox{#1}%
+ \ifdim\wd\boxA = 0pt
\ %
\else
%
@@ -3641,9 +5050,9 @@ width0pt\relax} \fi
\endgroup
}
-% Like \dotfill except takes at least 1 em.
+% Like plain.tex's \dotfill, except uses up at least 1 em.
\def\indexdotfill{\cleaders
- \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
+ \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill}
\def\primary #1{\line{#1\hfil}}
@@ -3753,6 +5162,34 @@ width0pt\relax} \fi
%
% All done with double columns.
\def\enddoublecolumns{%
+ % The following penalty ensures that the page builder is exercised
+ % _before_ we change the output routine. This is necessary in the
+ % following situation:
+ %
+ % The last section of the index consists only of a single entry.
+ % Before this section, \pagetotal is less than \pagegoal, so no
+ % break occurs before the last section starts. However, the last
+ % section, consisting of \initial and the single \entry, does not
+ % fit on the page and has to be broken off. Without the following
+ % penalty the page builder will not be exercised until \eject
+ % below, and by that time we'll already have changed the output
+ % routine to the \balancecolumns version, so the next-to-last
+ % double-column page will be processed with \balancecolumns, which
+ % is wrong: The two columns will go to the main vertical list, with
+ % the broken-off section in the recent contributions. As soon as
+ % the output routine finishes, TeX starts reconsidering the page
+ % break. The two columns and the broken-off section both fit on the
+ % page, because the two columns now take up only half of the page
+ % goal. When TeX sees \eject from below which follows the final
+ % section, it invokes the new output routine that we've set after
+ % \balancecolumns below; \onepageout will try to fit the two columns
+ % and the final section into the vbox of \pageheight (see
+ % \pagebody), causing an overfull box.
+ %
+ % Note that glue won't work here, because glue does not exercise the
+ % page builder, unlike penalties (see The TeXbook, pp. 280-281).
+ \penalty0
+ %
\output = {%
% Split the last of the double-column material. Leave it on the
% current page, no automatic page break.
@@ -3808,7 +5245,22 @@ width0pt\relax} \fi
\message{sectioning,}
% Chapters, sections, etc.
-% \unnumberedno is an oxymoron, of course. But we count the unnumbered
+% Let's start with @part.
+\outer\parseargdef\part{\partzzz{#1}}
+\def\partzzz#1{%
+ \chapoddpage
+ \null
+ \vskip.3\vsize % move it down on the page a bit
+ \begingroup
+ \noindent \titlefonts\rmisbold #1\par % the text
+ \let\lastnode=\empty % no node to associate with
+ \writetocentry{part}{#1}{}% but put it in the toc
+ \headingsoff % no headline or footline on the part page
+ \chapoddpage
+ \endgroup
+}
+
+% \unnumberedno is an oxymoron. But we count the unnumbered
% sections so that we can refer to them unambiguously in the pdf
% outlines by their "section number". We avoid collisions with chapter
% numbers by starting them at 10000. (If a document ever has 10000
@@ -3862,11 +5314,15 @@ width0pt\relax} \fi
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
-% Each @chapter defines this as the name of the chapter.
-% page headings and footings can use it. @section does likewise.
-% However, they are not reliable, because we don't use marks.
+% Each @chapter defines these (using marks) as the number+name, number
+% and name of the chapter. Page headings and footings can use
+% these. @section does likewise.
\def\thischapter{}
+\def\thischapternum{}
+\def\thischaptername{}
\def\thissection{}
+\def\thissectionnum{}
+\def\thissectionname{}
\newcount\absseclevel % used to calculate proper heading level
\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
@@ -3883,8 +5339,8 @@ width0pt\relax} \fi
\chardef\maxseclevel = 3
%
% A numbered section within an unnumbered changes to unnumbered too.
-% To achive this, remember the "biggest" unnum. sec. we are currently in:
-\chardef\unmlevel = \maxseclevel
+% To achieve this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unnlevel = \maxseclevel
%
% Trace whether the current chapter is an appendix or not:
% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
@@ -3909,8 +5365,8 @@ width0pt\relax} \fi
% The heading type:
\def\headtype{#1}%
\if \headtype U%
- \ifnum \absseclevel < \unmlevel
- \chardef\unmlevel = \absseclevel
+ \ifnum \absseclevel < \unnlevel
+ \chardef\unnlevel = \absseclevel
\fi
\else
% Check for appendix sections:
@@ -3922,10 +5378,10 @@ width0pt\relax} \fi
\fi\fi
\fi
% Check for numbered within unnumbered:
- \ifnum \absseclevel > \unmlevel
+ \ifnum \absseclevel > \unnlevel
\def\headtype{U}%
\else
- \chardef\unmlevel = 3
+ \chardef\unnlevel = 3
\fi
\fi
% Now print the heading:
@@ -3979,7 +5435,9 @@ width0pt\relax} \fi
\gdef\chaplevelprefix{\the\chapno.}%
\resetallfloatnos
%
- \message{\putwordChapter\space \the\chapno}%
+ % \putwordChapter can contain complex things in translations.
+ \toks0=\expandafter{\putwordChapter}%
+ \message{\the\toks0 \space \the\chapno}%
%
% Write the actual heading.
\chapmacro{#1}{Ynumbered}{\the\chapno}%
@@ -3990,15 +5448,17 @@ width0pt\relax} \fi
\global\let\subsubsection = \numberedsubsubsec
}
-\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz
+%
\def\appendixzzz#1{%
\global\secno=0 \global\subsecno=0 \global\subsubsecno=0
\global\advance\appendixno by 1
\gdef\chaplevelprefix{\appendixletter.}%
\resetallfloatnos
%
- \def\appendixnum{\putwordAppendix\space \appendixletter}%
- \message{\appendixnum}%
+ % \putwordAppendix can contain complex things in translations.
+ \toks0=\expandafter{\putwordAppendix}%
+ \message{\the\toks0 \space \appendixletter}%
%
\chapmacro{#1}{Yappendix}{\appendixletter}%
%
@@ -4007,7 +5467,8 @@ width0pt\relax} \fi
\global\let\subsubsection = \appendixsubsubsec
}
-\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+% normally unnmhead0 calls unnumberedzzz:
+\outer\parseargdef\unnumbered{\unnmhead0{#1}}
\def\unnumberedzzz#1{%
\global\secno=0 \global\subsecno=0 \global\subsubsecno=0
\global\advance\unnumberedno by 1
@@ -4051,40 +5512,47 @@ width0pt\relax} \fi
\let\top\unnumbered
% Sections.
+%
\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
\def\seczzz#1{%
\global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
\sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
}
-\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
+% normally calls appendixsectionzzz:
+\outer\parseargdef\appendixsection{\apphead1{#1}}
\def\appendixsectionzzz#1{%
\global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
\sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
}
\let\appendixsec\appendixsection
-\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
+% normally calls unnumberedseczzz:
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}}
\def\unnumberedseczzz#1{%
\global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
\sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
}
% Subsections.
-\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
+%
+% normally calls numberedsubseczzz:
+\outer\parseargdef\numberedsubsec{\numhead2{#1}}
\def\numberedsubseczzz#1{%
\global\subsubsecno=0 \global\advance\subsecno by 1
\sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
}
-\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
+% normally calls appendixsubseczzz:
+\outer\parseargdef\appendixsubsec{\apphead2{#1}}
\def\appendixsubseczzz#1{%
\global\subsubsecno=0 \global\advance\subsecno by 1
\sectionheading{#1}{subsec}{Yappendix}%
{\appendixletter.\the\secno.\the\subsecno}%
}
-\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+% normally calls unnumberedsubseczzz:
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}}
\def\unnumberedsubseczzz#1{%
\global\subsubsecno=0 \global\advance\subsecno by 1
\sectionheading{#1}{subsec}{Ynothing}%
@@ -4092,21 +5560,25 @@ width0pt\relax} \fi
}
% Subsubsections.
-\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+%
+% normally numberedsubsubseczzz:
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}}
\def\numberedsubsubseczzz#1{%
\global\advance\subsubsecno by 1
\sectionheading{#1}{subsubsec}{Ynumbered}%
{\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
}
-\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
+% normally appendixsubsubseczzz:
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}}
\def\appendixsubsubseczzz#1{%
\global\advance\subsubsecno by 1
\sectionheading{#1}{subsubsec}{Yappendix}%
{\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
}
-\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+% normally unnumberedsubsubseczzz:
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}}
\def\unnumberedsubsubseczzz#1{%
\global\advance\subsubsecno by 1
\sectionheading{#1}{subsubsec}{Ynothing}%
@@ -4122,15 +5594,6 @@ width0pt\relax} \fi
% Define @majorheading, @heading and @subheading
-% NOTE on use of \vbox for chapter headings, section headings, and such:
-% 1) We use \vbox rather than the earlier \line to permit
-% overlong headings to fold.
-% 2) \hyphenpenalty is set to 10000 because hyphenation in a
-% heading is obnoxious; this forbids it.
-% 3) Likewise, headings look best if no \parindent is used, and
-% if justification is not attempted. Hence \raggedright.
-
-
\def\majorheading{%
{\advance\chapheadingskip by 10pt \chapbreak }%
\parsearg\chapheadingzzz
@@ -4138,10 +5601,8 @@ width0pt\relax} \fi
\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
\def\chapheadingzzz#1{%
- {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt\raggedright
- \rm #1\hfill}}%
- \bigskip \par\penalty 200\relax
+ \vbox{\chapfonts \raggedtitlesettings #1\par}%
+ \nobreak\bigskip \nobreak
\suppressfirstparagraphindent
}
@@ -4157,17 +5618,28 @@ width0pt\relax} \fi
% (including whitespace, linebreaking, etc. around it),
% given all the information in convenient, parsed form.
-%%% Args are the skip and penalty (usually negative)
+% Args are the skip and penalty (usually negative)
\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
-%%% Define plain chapter starts, and page on/off switching for it
% Parameter controlling skip before chapter headings (if needed)
-
\newskip\chapheadingskip
+% Define plain chapter starts, and page on/off switching for it.
\def\chapbreak{\dobreak \chapheadingskip {-4000}}
\def\chappager{\par\vfill\supereject}
-\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
+% Because \domark is called before \chapoddpage, the filler page will
+% get the headings for the next chapter, which is wrong. But we don't
+% care -- we just disable all headings on the filler page.
+\def\chapoddpage{%
+ \chappager
+ \ifodd\pageno \else
+ \begingroup
+ \headingsoff
+ \null
+ \chappager
+ \endgroup
+ \fi
+}
\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
@@ -4201,41 +5673,78 @@ width0pt\relax} \fi
\def\Yappendixkeyword{Yappendix}
%
\def\chapmacro#1#2#3{%
+ % Insert the first mark before the heading break (see notes for \domark).
+ \let\prevchapterdefs=\lastchapterdefs
+ \let\prevsectiondefs=\lastsectiondefs
+ \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}%
+ \gdef\thissection{}}%
+ %
+ \def\temptype{#2}%
+ \ifx\temptype\Ynothingkeyword
+ \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+ \gdef\thischapter{\thischaptername}}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+ \gdef\thischapter{}}%
+ \else\ifx\temptype\Yappendixkeyword
+ \toks0={#1}%
+ \xdef\lastchapterdefs{%
+ \gdef\noexpand\thischaptername{\the\toks0}%
+ \gdef\noexpand\thischapternum{\appendixletter}%
+ % \noexpand\putwordAppendix avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thischapter{\noexpand\putwordAppendix{}
+ \noexpand\thischapternum:
+ \noexpand\thischaptername}%
+ }%
+ \else
+ \toks0={#1}%
+ \xdef\lastchapterdefs{%
+ \gdef\noexpand\thischaptername{\the\toks0}%
+ \gdef\noexpand\thischapternum{\the\chapno}%
+ % \noexpand\putwordChapter avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thischapter{\noexpand\putwordChapter{}
+ \noexpand\thischapternum:
+ \noexpand\thischaptername}%
+ }%
+ \fi\fi\fi
+ %
+ % Output the mark. Pass it through \safewhatsit, to take care of
+ % the preceding space.
+ \safewhatsit\domark
+ %
+ % Insert the chapter heading break.
\pchapsepmacro
+ %
+ % Now the second mark, after the heading break. No break points
+ % between here and the heading.
+ \let\prevchapterdefs=\lastchapterdefs
+ \let\prevsectiondefs=\lastsectiondefs
+ \domark
+ %
{%
- \chapfonts \rm
+ \chapfonts \rmisbold
%
- % Have to define \thissection before calling \donoderef, because the
+ % Have to define \lastsection before calling \donoderef, because the
% xref code eventually uses it. On the other hand, it has to be called
% after \pchapsepmacro, or the headline will change too soon.
- \gdef\thissection{#1}%
- \gdef\thischaptername{#1}%
+ \gdef\lastsection{#1}%
%
% Only insert the separating space if we have a chapter/appendix
% number, and don't print the unnumbered ``number''.
- \def\temptype{#2}%
\ifx\temptype\Ynothingkeyword
\setbox0 = \hbox{}%
\def\toctype{unnchap}%
- \def\thischapter{#1}%
\else\ifx\temptype\Yomitfromtockeyword
\setbox0 = \hbox{}% contents like unnumbered, but no toc entry
\def\toctype{omit}%
- \xdef\thischapter{}%
\else\ifx\temptype\Yappendixkeyword
\setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
\def\toctype{app}%
- % We don't substitute the actual chapter name into \thischapter
- % because we don't want its macros evaluated now. And we don't
- % use \thissection because that changes with each section.
- %
- \xdef\thischapter{\putwordAppendix{} \appendixletter:
- \noexpand\thischaptername}%
\else
\setbox0 = \hbox{#3\enspace}%
\def\toctype{numchap}%
- \xdef\thischapter{\putwordChapter{} \the\chapno:
- \noexpand\thischaptername}%
\fi\fi\fi
%
% Write the toc entry for this chapter. Must come before the
@@ -4251,8 +5760,8 @@ width0pt\relax} \fi
\donoderef{#2}%
%
% Typeset the actual heading.
- \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
- \hangindent=\wd0 \centerparametersmaybe
+ \nobreak % Avoid page breaks at the interline glue.
+ \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe
\unhbox0 #1\par}%
}%
\nobreak\bigskip % no page break after a chapter title
@@ -4274,18 +5783,18 @@ width0pt\relax} \fi
\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
%
\def\unnchfopen #1{%
-\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt\raggedright
- \rm #1\hfill}}\bigskip \par\nobreak
+ \chapoddpage
+ \vbox{\chapfonts \raggedtitlesettings #1\par}%
+ \nobreak\bigskip\nobreak
}
\def\chfopen #1#2{\chapoddpage {\chapfonts
\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
\par\penalty 5000 %
}
\def\centerchfopen #1{%
-\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt
- \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
+ \chapoddpage
+ \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}%
+ \nobreak\bigskip \nobreak
}
\def\CHAPFopen{%
\global\let\chapmacro=\chfopen
@@ -4313,47 +5822,110 @@ width0pt\relax} \fi
% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
% section number.
%
+\def\seckeyword{sec}
+%
\def\sectionheading#1#2#3#4{%
{%
+ \checkenv{}% should not be in an environment.
+ %
% Switch to the right set of fonts.
- \csname #2fonts\endcsname \rm
+ \csname #2fonts\endcsname \rmisbold
+ %
+ \def\sectionlevel{#2}%
+ \def\temptype{#3}%
+ %
+ % Insert first mark before the heading break (see notes for \domark).
+ \let\prevsectiondefs=\lastsectiondefs
+ \ifx\temptype\Ynothingkeyword
+ \ifx\sectionlevel\seckeyword
+ \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}%
+ \gdef\thissection{\thissectionname}}%
+ \fi
+ \else\ifx\temptype\Yomitfromtockeyword
+ % Don't redefine \thissection.
+ \else\ifx\temptype\Yappendixkeyword
+ \ifx\sectionlevel\seckeyword
+ \toks0={#1}%
+ \xdef\lastsectiondefs{%
+ \gdef\noexpand\thissectionname{\the\toks0}%
+ \gdef\noexpand\thissectionnum{#4}%
+ % \noexpand\putwordSection avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thissection{\noexpand\putwordSection{}
+ \noexpand\thissectionnum:
+ \noexpand\thissectionname}%
+ }%
+ \fi
+ \else
+ \ifx\sectionlevel\seckeyword
+ \toks0={#1}%
+ \xdef\lastsectiondefs{%
+ \gdef\noexpand\thissectionname{\the\toks0}%
+ \gdef\noexpand\thissectionnum{#4}%
+ % \noexpand\putwordSection avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thissection{\noexpand\putwordSection{}
+ \noexpand\thissectionnum:
+ \noexpand\thissectionname}%
+ }%
+ \fi
+ \fi\fi\fi
+ %
+ % Go into vertical mode. Usually we'll already be there, but we
+ % don't want the following whatsit to end up in a preceding paragraph
+ % if the document didn't happen to have a blank line.
+ \par
+ %
+ % Output the mark. Pass it through \safewhatsit, to take care of
+ % the preceding space.
+ \safewhatsit\domark
%
% Insert space above the heading.
\csname #2headingbreak\endcsname
%
- % Only insert the space after the number if we have a section number.
- \def\sectionlevel{#2}%
- \def\temptype{#3}%
+ % Now the second mark, after the heading break. No break points
+ % between here and the heading.
+ \let\prevsectiondefs=\lastsectiondefs
+ \domark
%
+ % Only insert the space after the number if we have a section number.
\ifx\temptype\Ynothingkeyword
\setbox0 = \hbox{}%
\def\toctype{unn}%
- \gdef\thissection{#1}%
+ \gdef\lastsection{#1}%
\else\ifx\temptype\Yomitfromtockeyword
% for @headings -- no section number, don't include in toc,
- % and don't redefine \thissection.
+ % and don't redefine \lastsection.
\setbox0 = \hbox{}%
\def\toctype{omit}%
\let\sectionlevel=\empty
\else\ifx\temptype\Yappendixkeyword
\setbox0 = \hbox{#4\enspace}%
\def\toctype{app}%
- \gdef\thissection{#1}%
+ \gdef\lastsection{#1}%
\else
\setbox0 = \hbox{#4\enspace}%
\def\toctype{num}%
- \gdef\thissection{#1}%
+ \gdef\lastsection{#1}%
\fi\fi\fi
%
- % Write the toc entry (before \donoderef). See comments in \chfplain.
+ % Write the toc entry (before \donoderef). See comments in \chapmacro.
\writetocentry{\toctype\sectionlevel}{#1}{#4}%
%
% Write the node reference (= pdf destination for pdftex).
- % Again, see comments in \chfplain.
+ % Again, see comments in \chapmacro.
\donoderef{#3}%
%
+ % Interline glue will be inserted when the vbox is completed.
+ % That glue will be a valid breakpoint for the page, since it'll be
+ % preceded by a whatsit (usually from the \donoderef, or from the
+ % \writetocentry if there was no node). We don't want to allow that
+ % break, since then the whatsits could end up on page n while the
+ % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000.
+ \nobreak
+ %
% Output the actual section heading.
- \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright
\hangindent=\wd0 % zero if no section number
\unhbox0 #1}%
}%
@@ -4367,15 +5939,15 @@ width0pt\relax} \fi
%
% We'll almost certainly start a paragraph next, so don't let that
% glue accumulate. (Not a breakpoint because it's preceded by a
- % discardable item.)
+ % discardable item.) However, when a paragraph is not started next
+ % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out
+ % or the negative glue will cause weirdly wrong output, typically
+ % obscuring the section heading with something else.
\vskip-\parskip
- %
- % This is purely so the last item on the list is a known \penalty >
- % 10000. This is so \startdefun can avoid allowing breakpoints after
- % section headings. Otherwise, it would insert a valid breakpoint between:
- %
- % @section sec-whatever
- % @deffn def-whatever
+ %
+ % This is so the last item on the main vertical list is a known
+ % \penalty > 10000, so \startdefun, etc., can recognize the situation
+ % and do the needful.
\penalty 10001
}
@@ -4410,11 +5982,11 @@ width0pt\relax} \fi
\fi
%
\iflinks
- \toks0 = {#2}%
- \toks2 = \expandafter{\lastnode}%
- \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}{#3}%
- {\the\toks2}{\noexpand\folio}}}%
- \temp
+ {\atdummies
+ \edef\temp{%
+ \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}%
+ \temp
+ }%
\fi
\fi
%
@@ -4427,6 +5999,31 @@ width0pt\relax} \fi
\ifpdf \global\pdfmakepagedesttrue \fi
}
+
+% These characters do not print properly in the Computer Modern roman
+% fonts, so we must take special care. This is more or less redundant
+% with the Texinfo input format setup at the end of this file.
+%
+\def\activecatcodes{%
+ \catcode`\"=\active
+ \catcode`\$=\active
+ \catcode`\<=\active
+ \catcode`\>=\active
+ \catcode`\\=\active
+ \catcode`\^=\active
+ \catcode`\_=\active
+ \catcode`\|=\active
+ \catcode`\~=\active
+}
+
+
+% Read the toc file, which is essentially Texinfo input.
+\def\readtocfile{%
+ \setupdatafile
+ \activecatcodes
+ \input \tocreadfilename
+}
+
\newskip\contentsrightmargin \contentsrightmargin=1in
\newcount\savepageno
\newcount\lastnegativepageno \lastnegativepageno = -1
@@ -4443,29 +6040,29 @@ width0pt\relax} \fi
%
% Don't need to put `Contents' or `Short Contents' in the headline.
% It is abundantly clear what they are.
- \def\thischapter{}%
\chapmacro{#1}{Yomitfromtoc}{}%
%
\savepageno = \pageno
\begingroup % Set up to handle contents files properly.
- \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11
- % We can't do this, because then an actual ^ in a section
- % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97.
- %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
- \raggedbottom % Worry more about breakpoints than the bottom.
+ \raggedbottom % Worry more about breakpoints than the bottom.
\advance\hsize by -\contentsrightmargin % Don't use the full line length.
%
% Roman numerals for page numbers.
\ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
}
+% redefined for the two-volume lispref. We always output on
+% \jobname.toc even if this is redefined.
+%
+\def\tocreadfilename{\jobname.toc}
% Normal (long) toc.
+%
\def\contents{%
\startcontents{\putwordTOC}%
- \openin 1 \jobname.toc
+ \openin 1 \tocreadfilename\space
\ifeof 1 \else
- \input \jobname.toc
+ \readtocfile
\fi
\vfill \eject
\contentsalignmacro % in case @setchapternewpage odd is in effect
@@ -4482,6 +6079,7 @@ width0pt\relax} \fi
\def\summarycontents{%
\startcontents{\putwordShortTOC}%
%
+ \let\partentry = \shortpartentry
\let\numchapentry = \shortchapentry
\let\appentry = \shortchapentry
\let\unnchapentry = \shortunnchapentry
@@ -4501,9 +6099,9 @@ width0pt\relax} \fi
\let\numsubsubsecentry = \numsecentry
\let\appsubsubsecentry = \numsecentry
\let\unnsubsubsecentry = \numsecentry
- \openin 1 \jobname.toc
+ \openin 1 \tocreadfilename\space
\ifeof 1 \else
- \input \jobname.toc
+ \readtocfile
\fi
\closein 1
\vfill \eject
@@ -4537,6 +6135,19 @@ width0pt\relax} \fi
% The last argument is the page number.
% The arguments in between are the chapter number, section number, ...
+% Parts, in the main contents. Replace the part number, which doesn't
+% exist, with an empty box. Let's hope all the numbers have the same width.
+% Also ignore the page number, which is conventionally not printed.
+\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}}
+\def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}}
+%
+% Parts, in the short toc.
+\def\shortpartentry#1#2#3#4{%
+ \penalty-300
+ \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip
+ \shortchapentry{{\bf #1}}{\numeralbox}{}{}%
+}
+
% Chapters, in the main contents.
\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
%
@@ -4626,45 +6237,12 @@ width0pt\relax} \fi
\message{environments,}
% @foo ... @end foo.
-% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
-%
-% Since these characters are used in examples, it should be an even number of
-% \tt widths. Each \tt character is 1en, so two makes it 1em.
-%
-\def\point{$\star$}
-\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
-\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
-\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
-\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
-
-% The @error{} command.
-% Adapted from the TeXbook's \boxit.
-%
-\newbox\errorbox
-%
-{\tentt \global\dimen0 = 3em}% Width of the box.
-\dimen2 = .55pt % Thickness of rules
-% The text. (`r' is open on the right, `e' somewhat less so on the left.)
-\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
-%
-\setbox\errorbox=\hbox to \dimen0{\hfil
- \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
- \advance\hsize by -2\dimen2 % Rules.
- \vbox{%
- \hrule height\dimen2
- \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
- \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
- \kern3pt\vrule width\dimen2}% Space to right.
- \hrule height\dimen2}
- \hfil}
-%
-\def\error{\leavevmode\lower.7ex\copy\errorbox}
-
-% @tex ... @end tex escapes into raw Tex temporarily.
+% @tex ... @end tex escapes into raw TeX temporarily.
% One exception: @ is still an escape character, so that @end tex works.
-% But \@ or @@ will get a plain tex @ character.
+% But \@ or @@ will get a plain @ character.
\envdef\tex{%
+ \setupmarkupstyle{tex}%
\catcode `\\=0 \catcode `\{=1 \catcode `\}=2
\catcode `\$=3 \catcode `\&=4 \catcode `\#=6
\catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
@@ -4674,8 +6252,14 @@ width0pt\relax} \fi
\catcode `\|=\other
\catcode `\<=\other
\catcode `\>=\other
+ \catcode`\`=\other
+ \catcode`\'=\other
\escapechar=`\\
%
+ % ' is active in math mode (mathcode"8000). So reset it, and all our
+ % other math active characters (just in case), to plain's definitions.
+ \mathactive
+ %
\let\b=\ptexb
\let\bullet=\ptexbullet
\let\c=\ptexc
@@ -4693,6 +6277,8 @@ width0pt\relax} \fi
\let\/=\ptexslash
\let\*=\ptexstar
\let\t=\ptext
+ \expandafter \let\csname top\endcsname=\ptextop % outer
+ \let\frenchspacing=\plainfrenchspacing
%
\def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
\def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
@@ -4738,7 +6324,8 @@ width0pt\relax} \fi
\let\afterenvbreak = \aboveenvbreak
-% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins.
+% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will
+% also clear it, so that its embedded environments do the narrowing again.
\let\nonarrowing=\relax
% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
@@ -4775,7 +6362,13 @@ width0pt\relax} \fi
% each corner char, and rule thickness
\normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
% Flag to tell @lisp, etc., not to narrow margin.
- \let\nonarrowing=\comment
+ \let\nonarrowing = t%
+ %
+ % If this cartouche directly follows a sectioning command, we need the
+ % \parskip glue (backspaced over by default) or the cartouche can
+ % collide with the section heading.
+ \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi
+ %
\vbox\bgroup
\baselineskip=0pt\parskip=0pt\lineskip=0pt
\carttop
@@ -4789,7 +6382,7 @@ width0pt\relax} \fi
\lineskip=\normlskip
\parskip=\normpskip
\vskip -\parskip
- \comment % For explanation, see the end of \def\group.
+ \comment % For explanation, see the end of def\group.
}
\def\Ecartouche{%
\ifhmode\par\fi
@@ -4806,6 +6399,7 @@ width0pt\relax} \fi
% This macro is called at the beginning of all the @example variants,
% inside a group.
+\newdimen\nonfillparindent
\def\nonfillstart{%
\aboveenvbreak
\hfuzz = 12pt % Don't be fussy
@@ -4813,17 +6407,40 @@ width0pt\relax} \fi
\let\par = \lisppar % don't ignore blank lines
\obeylines % each line of input is a line of output
\parskip = 0pt
+ % Turn off paragraph indentation but redefine \indent to emulate
+ % the normal \indent.
+ \nonfillparindent=\parindent
\parindent = 0pt
+ \let\indent\nonfillindent
+ %
\emergencystretch = 0pt % don't try to avoid overfull boxes
- % @cartouche defines \nonarrowing to inhibit narrowing
- % at next level down.
\ifx\nonarrowing\relax
\advance \leftskip by \lispnarrowing
\exdentamount=\lispnarrowing
+ \else
+ \let\nonarrowing = \relax
\fi
\let\exdent=\nofillexdent
}
+\begingroup
+\obeyspaces
+% We want to swallow spaces (but not other tokens) after the fake
+% @indent in our nonfill-environments, where spaces are normally
+% active and set to @tie, resulting in them not being ignored after
+% @indent.
+\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}%
+\gdef\nonfillindentcheck{%
+\ifx\temp %
+\expandafter\nonfillindentgobble%
+\else%
+\leavevmode\nonfillindentbox%
+\fi%
+}%
+\endgroup
+\def\nonfillindentgobble#1{\nonfillindent}
+\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}}
+
% If you want all examples etc. small: @set dispenvsize small.
% If you want even small examples the full size: @set dispenvsize nosmall.
% This affects the following displayed environments:
@@ -4834,53 +6451,59 @@ width0pt\relax} \fi
\let\SETdispenvsize\relax
\def\setnormaldispenv{%
\ifx\SETdispenvsize\smallword
+ % end paragraph for sake of leading, in case document has no blank
+ % line. This is redundant with what happens in \aboveenvbreak, but
+ % we need to do it before changing the fonts, and it's inconvenient
+ % to change the fonts afterward.
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
\smallexamplefonts \rm
\fi
}
\def\setsmalldispenv{%
\ifx\SETdispenvsize\nosmallword
\else
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
\smallexamplefonts \rm
\fi
}
% We often define two environments, @foo and @smallfoo.
-% Let's do it by one command:
-\def\makedispenv #1#2{
- \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}
- \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}
+% Let's do it in one command. #1 is the env name, #2 the definition.
+\def\makedispenvdef#1#2{%
+ \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}%
+ \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}%
\expandafter\let\csname E#1\endcsname \afterenvbreak
\expandafter\let\csname Esmall#1\endcsname \afterenvbreak
}
-% Define two synonyms:
-\def\maketwodispenvs #1#2#3{
- \makedispenv{#1}{#3}
- \makedispenv{#2}{#3}
+% Define two environment synonyms (#1 and #2) for an environment.
+\def\maketwodispenvdef#1#2#3{%
+ \makedispenvdef{#1}{#3}%
+ \makedispenvdef{#2}{#3}%
}
-
-% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
+%
+% @lisp: indented, narrowed, typewriter font;
+% @example: same as @lisp.
%
% @smallexample and @smalllisp: use smaller fonts.
% Originally contributed by Pavel@xerox.
%
-\maketwodispenvs {lisp}{example}{%
+\maketwodispenvdef{lisp}{example}{%
\nonfillstart
- \tt
+ \tt\setupmarkupstyle{example}%
\let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
- \gobble % eat return
+ \gobble % eat return
}
-
% @display/@smalldisplay: same as @lisp except keep current font.
%
-\makedispenv {display}{%
+\makedispenvdef{display}{%
\nonfillstart
\gobble
}
% @format/@smallformat: same as @display except don't narrow margins.
%
-\makedispenv{format}{%
+\makedispenvdef{format}{%
\let\nonarrowing = t%
\nonfillstart
\gobble
@@ -4899,27 +6522,47 @@ width0pt\relax} \fi
\envdef\flushright{%
\let\nonarrowing = t%
\nonfillstart
- \advance\leftskip by 0pt plus 1fill
+ \advance\leftskip by 0pt plus 1fill\relax
\gobble
}
\let\Eflushright = \afterenvbreak
+% @raggedright does more-or-less normal line breaking but no right
+% justification. From plain.tex.
+\envdef\raggedright{%
+ \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax
+}
+\let\Eraggedright\par
+
+\envdef\raggedleft{%
+ \parindent=0pt \leftskip0pt plus2em
+ \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+ \hbadness=10000 % Last line will usually be underfull, so turn off
+ % badness reporting.
+}
+\let\Eraggedleft\par
+
+\envdef\raggedcenter{%
+ \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em
+ \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+ \hbadness=10000 % Last line will usually be underfull, so turn off
+ % badness reporting.
+}
+\let\Eraggedcenter\par
+
+
% @quotation does normal linebreaking (hence we can't use \nonfillstart)
% and narrows the margins. We keep \parskip nonzero in general, since
% we're doing normal filling. So, when using \aboveenvbreak and
% \afterenvbreak, temporarily make \parskip 0.
%
-\envdef\quotation{%
- {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
- \parindent=0pt
- %
- % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+\makedispenvdef{quotation}{\quotationstart}
+%
+\def\quotationstart{%
+ \indentedblockstart % same as \indentedblock, but increase right margin too.
\ifx\nonarrowing\relax
- \advance\leftskip by \lispnarrowing
\advance\rightskip by \lispnarrowing
- \exdentamount = \lispnarrowing
- \let\nonarrowing = \relax
\fi
\parsearg\quotationlabel
}
@@ -4929,12 +6572,13 @@ width0pt\relax} \fi
%
\def\Equotation{%
\par
- \ifx\quotationauthor\undefined\else
+ \ifx\quotationauthor\thisisundefined\else
% indent a bit.
\leftline{\kern 2\leftskip \sl ---\quotationauthor}%
\fi
{\parskip=0pt \afterenvbreak}%
}
+\def\Esmallquotation{\Equotation}
% If we're given an argument, typeset it in bold with a colon after.
\def\quotationlabel#1{%
@@ -4944,6 +6588,32 @@ width0pt\relax} \fi
\fi
}
+% @indentedblock is like @quotation, but indents only on the left and
+% has no optional argument.
+%
+\makedispenvdef{indentedblock}{\indentedblockstart}
+%
+\def\indentedblockstart{%
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \parindent=0pt
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+}
+
+% Keep a nonzero parskip for the environment, since we're doing normal filling.
+%
+\def\Eindentedblock{%
+ \par
+ {\parskip=0pt \afterenvbreak}%
+}
+\def\Esmallindentedblock{\Eindentedblock}
+
% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
% If we want to allow any <char> as delimiter,
@@ -4959,18 +6629,16 @@ width0pt\relax} \fi
\do\ \do\\\do\{\do\}\do\$\do\&%
\do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
\do\<\do\>\do\|\do\@\do+\do\"%
+ % Don't do the quotes -- if we do, @set txicodequoteundirected and
+ % @set txicodequotebacktick will not have effect on @verb and
+ % @verbatim, and ?` and !` ligatures won't get disabled.
+ %\do\`\do\'%
}
%
% [Knuth] p. 380
\def\uncatcodespecials{%
\def\do##1{\catcode`##1=\other}\dospecials}
%
-% [Knuth] pp. 380,381,391
-% Disable Spanish ligatures ?` and !` of \tt font
-\begingroup
- \catcode`\`=\active\gdef`{\relax\lq}
-\endgroup
-%
% Setup for the @verb command.
%
% Eight spaces for a tab
@@ -4982,7 +6650,7 @@ width0pt\relax} \fi
\def\setupverb{%
\tt % easiest (and conventionally used) font for verbatim
\def\par{\leavevmode\endgraf}%
- \catcode`\`=\active
+ \setupmarkupstyle{verb}%
\tabeightspaces
% Respect line breaks,
% print special symbols as themselves, and
@@ -4993,35 +6661,46 @@ width0pt\relax} \fi
% Setup for the @verbatim environment
%
-% Real tab expansion
+% Real tab expansion.
\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
%
-\def\starttabbox{\setbox0=\hbox\bgroup}
+% We typeset each line of the verbatim in an \hbox, so we can handle
+% tabs. The \global is in case the verbatim line starts with an accent,
+% or some other command that starts with a begin-group. Otherwise, the
+% entire \verbbox would disappear at the corresponding end-group, before
+% it is typeset. Meanwhile, we can't have nested verbatim commands
+% (can we?), so the \global won't be overwriting itself.
+\newbox\verbbox
+\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup}
+%
\begingroup
\catcode`\^^I=\active
\gdef\tabexpand{%
\catcode`\^^I=\active
\def^^I{\leavevmode\egroup
- \dimen0=\wd0 % the width so far, or since the previous tab
- \divide\dimen0 by\tabw
- \multiply\dimen0 by\tabw % compute previous multiple of \tabw
- \advance\dimen0 by\tabw % advance to next multiple of \tabw
- \wd0=\dimen0 \box0 \starttabbox
+ \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab
+ \divide\dimen\verbbox by\tabw
+ \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw
+ \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw
+ \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox
}%
}
\endgroup
+
+% start the verbatim environment.
\def\setupverbatim{%
+ \let\nonarrowing = t%
\nonfillstart
- \advance\leftskip by -\defbodyindent
- % Easiest (and conventionally used) font for verbatim
- \tt
- \def\par{\leavevmode\egroup\box0\endgraf}%
- \catcode`\`=\active
+ \tt % easiest (and conventionally used) font for verbatim
+ % The \leavevmode here is for blank lines. Otherwise, we would
+ % never \starttabox and the \egroup would end verbatim mode.
+ \def\par{\leavevmode\egroup\box\verbbox\endgraf}%
\tabexpand
+ \setupmarkupstyle{verbatim}%
% Respect line breaks,
% print special symbols as themselves, and
- % make each space count
- % must do in this order:
+ % make each space count.
+ % Must do in this order:
\obeylines \uncatcodespecials \sepspaces
\everypar{\starttabbox}%
}
@@ -5077,6 +6756,8 @@ width0pt\relax} \fi
{%
\makevalueexpandable
\setupverbatim
+ \indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}%
\input #1
\afterenvbreak
}%
@@ -5102,27 +6783,35 @@ width0pt\relax} \fi
\endgroup
}
+
\message{defuns,}
% @defun etc.
\newskip\defbodyindent \defbodyindent=.4in
\newskip\defargsindent \defargsindent=50pt
\newskip\deflastargmargin \deflastargmargin=18pt
+\newcount\defunpenalty
% Start the processing of @deffn:
\def\startdefun{%
\ifnum\lastpenalty<10000
\medbreak
+ \defunpenalty=10003 % Will keep this @deffn together with the
+ % following @def command, see below.
\else
% If there are two @def commands in a row, we'll have a \nobreak,
% which is there to keep the function description together with its
% header. But if there's nothing but headers, we need to allow a
% break somewhere. Check specifically for penalty 10002, inserted
- % by \defargscommonending, instead of 10000, since the sectioning
+ % by \printdefunline, instead of 10000, since the sectioning
% commands also insert a nobreak penalty, and we don't want to allow
% a break between a section heading and a defun.
- %
- \ifnum\lastpenalty=10002 \penalty2000 \fi
+ %
+ % As a further refinement, we avoid "club" headers by signalling
+ % with penalty of 10003 after the very first @deffn in the
+ % sequence (see above), and penalty of 10002 after any following
+ % @def command.
+ \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi
%
% Similarly, after a section heading, do not allow a break.
% But do insert the glue.
@@ -5140,7 +6829,7 @@ width0pt\relax} \fi
%
% As above, allow line break if we have multiple x headers in a row.
% It's not a great place, though.
- \ifnum\lastpenalty=10002 \penalty3000 \fi
+ \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi
%
% And now, it's time to reuse the body of the original defun:
\expandafter\gobbledefun#1%
@@ -5155,10 +6844,10 @@ width0pt\relax} \fi
#1#2 \endheader
% common ending:
\interlinepenalty = 10000
- \advance\rightskip by 0pt plus 1fil
+ \advance\rightskip by 0pt plus 1fil\relax
\endgraf
\nobreak\vskip -\parskip
- \penalty 10002 % signal to \startdefun and \dodefunx
+ \penalty\defunpenalty % signal to \startdefun and \dodefunx
% Some of the @defun-type tags do not enable magic parentheses,
% rendering the following check redundant. But we don't optimize.
\checkparencounts
@@ -5168,7 +6857,7 @@ width0pt\relax} \fi
\def\Edefun{\endgraf\medbreak}
% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
-% the only thing remainnig is to define \deffnheader.
+% the only thing remaining is to define \deffnheader.
%
\def\makedefun#1{%
\expandafter\let\csname E#1\endcsname = \Edefun
@@ -5185,13 +6874,36 @@ width0pt\relax} \fi
\def\domakedefun#1#2#3{%
\envdef#1{%
\startdefun
+ \doingtypefnfalse % distinguish typed functions from all else
\parseargusing\activeparens{\printdefunline#3}%
}%
\def#2{\dodefunx#1}%
\def#3%
}
-%%% Untyped functions:
+\newif\ifdoingtypefn % doing typed function?
+\newif\ifrettypeownline % typeset return type on its own line?
+
+% @deftypefnnewline on|off says whether the return type of typed functions
+% are printed on their own line. This affects @deftypefn, @deftypefun,
+% @deftypeop, and @deftypemethod.
+%
+\parseargdef\deftypefnnewline{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @txideftypefnnl value `\temp',
+ must be on|off}%
+ \fi\fi
+}
+
+% Untyped functions:
% @deffn category name args
\makedefun{deffn}{\deffngeneral{}}
@@ -5210,7 +6922,7 @@ width0pt\relax} \fi
\defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
}
-%%% Typed functions:
+% Typed functions:
% @deftypefn category type name args
\makedefun{deftypefn}{\deftypefngeneral{}}
@@ -5225,10 +6937,11 @@ width0pt\relax} \fi
%
\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
\dosubind{fn}{\code{#4}}{#1}%
+ \doingtypefntrue
\defname{#2}{#3}{#4}\defunargs{#5\unskip}%
}
-%%% Typed variables:
+% Typed variables:
% @deftypevr category type var args
\makedefun{deftypevr}{\deftypecvgeneral{}}
@@ -5246,7 +6959,7 @@ width0pt\relax} \fi
\defname{#2}{#3}{#4}\defunargs{#5\unskip}%
}
-%%% Untyped variables:
+% Untyped variables:
% @defvr category var args
\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
@@ -5257,7 +6970,8 @@ width0pt\relax} \fi
% \defcvof {category of}class var args
\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
-%%% Type:
+% Types:
+
% @deftp category name args
\makedefun{deftp}#1 #2 #3\endheader{%
\doind{tp}{\code{#2}}%
@@ -5285,25 +6999,49 @@ width0pt\relax} \fi
% We are followed by (but not passed) the arguments, if any.
%
\def\defname#1#2#3{%
+ \par
% Get the values of \leftskip and \rightskip as they were outside the @def...
\advance\leftskip by -\defbodyindent
%
- % How we'll format the type name. Putting it in brackets helps
+ % Determine if we are typesetting the return type of a typed function
+ % on a line by itself.
+ \rettypeownlinefalse
+ \ifdoingtypefn % doing a typed function specifically?
+ % then check user option for putting return type on its own line:
+ \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else
+ \rettypeownlinetrue
+ \fi
+ \fi
+ %
+ % How we'll format the category name. Putting it in brackets helps
% distinguish it from the body text that may end up on the next line
% just below it.
\def\temp{#1}%
\setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
%
- % Figure out line sizes for the paragraph shape.
+ % Figure out line sizes for the paragraph shape. We'll always have at
+ % least two.
+ \tempnum = 2
+ %
% The first line needs space for \box0; but if \rightskip is nonzero,
% we need only space for the part of \box0 which exceeds it:
\dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip
+ %
+ % If doing a return type on its own line, we'll have another line.
+ \ifrettypeownline
+ \advance\tempnum by 1
+ \def\maybeshapeline{0in \hsize}%
+ \else
+ \def\maybeshapeline{}%
+ \fi
+ %
% The continuations:
\dimen2=\hsize \advance\dimen2 by -\defargsindent
- % (plain.tex says that \dimen1 should be used only as global.)
- \parshape 2 0in \dimen0 \defargsindent \dimen2
%
- % Put the type name to the right margin.
+ % The final paragraph shape:
+ \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2
+ %
+ % Put the category name at the right margin.
\noindent
\hbox to 0pt{%
\hfil\box0 \kern-\hsize
@@ -5325,8 +7063,16 @@ width0pt\relax} \fi
% . this still does not fix the ?` and !` ligatures, but so far no
% one has made identifiers using them :).
\df \tt
- \def\temp{#2}% return value type
- \ifx\temp\empty\else \tclose{\temp} \fi
+ \def\temp{#2}% text of the return type
+ \ifx\temp\empty\else
+ \tclose{\temp}% typeset the return type
+ \ifrettypeownline
+ % put return type on its own line; prohibit line break following:
+ \hfil\vadjust{\nobreak}\break
+ \else
+ \space % type on same line, so just followed by a space
+ \fi
+ \fi % no return type
#3% output function name
}%
{\rm\enskip}% hskip 0.5 em of \tenrm
@@ -5346,8 +7092,11 @@ width0pt\relax} \fi
\df \sl \hyphenchar\font=0
%
% On the other hand, if an argument has two dashes (for instance), we
- % want a way to get ttsl. Let's try @var for that.
- \let\var=\ttslanted
+ % want a way to get ttsl. We used to recommend @var for that, so
+ % leave the code in, but it's strange for @var to lead to typewriter.
+ % Nowadays we recommend @code, since the difference between a ttsl hyphen
+ % and a tt hyphen is pretty tiny. @code also disables ?` !`.
+ \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}%
#1%
\sl\hyphenchar\font=45
}
@@ -5427,12 +7176,14 @@ width0pt\relax} \fi
\ifnum\parencount=0 \else \badparencount \fi
\ifnum\brackcount=0 \else \badbrackcount \fi
}
+% these should not use \errmessage; the glibc manual, at least, actually
+% has such constructs (when documenting function pointers).
\def\badparencount{%
- \errmessage{Unbalanced parentheses in @def}%
+ \message{Warning: unbalanced parentheses in @def...}%
\global\parencount=0
}
\def\badbrackcount{%
- \errmessage{Unbalanced square braces in @def}%
+ \message{Warning: unbalanced square brackets in @def...}%
\global\brackcount=0
}
@@ -5442,7 +7193,7 @@ width0pt\relax} \fi
% To do this right we need a feature of e-TeX, \scantokens,
% which we arrange to emulate with a temporary file in ordinary TeX.
-\ifx\eTeXversion\undefined
+\ifx\eTeXversion\thisisundefined
\newwrite\macscribble
\def\scantokens#1{%
\toks0={#1}%
@@ -5453,26 +7204,30 @@ width0pt\relax} \fi
}
\fi
-\def\scanmacro#1{%
- \begingroup
- \newlinechar`\^^M
- \let\xeatspaces\eatspaces
- % Undo catcode changes of \startcontents and \doprintindex
- % When called from @insertcopying or (short)caption, we need active
- % backslash to get it printed correctly. Previously, we had
- % \catcode`\\=\other instead. We'll see whether a problem appears
- % with macro expansion. --kasal, 19aug04
- \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
- % ... and \example
- \spaceisspace
- %
- % Append \endinput to make sure that TeX does not see the ending newline.
- %
- % I've verified that it is necessary both for e-TeX and for ordinary TeX
- % --kasal, 29nov03
- \scantokens{#1\endinput}%
- \endgroup
-}
+\def\scanmacro#1{\begingroup
+ \newlinechar`\^^M
+ \let\xeatspaces\eatspaces
+ %
+ % Undo catcode changes of \startcontents and \doprintindex
+ % When called from @insertcopying or (short)caption, we need active
+ % backslash to get it printed correctly. Previously, we had
+ % \catcode`\\=\other instead. We'll see whether a problem appears
+ % with macro expansion. --kasal, 19aug04
+ \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+ %
+ % ... and for \example:
+ \spaceisspace
+ %
+ % The \empty here causes a following catcode 5 newline to be eaten as
+ % part of reading whitespace after a control sequence. It does not
+ % eat a catcode 13 newline. There's no good way to handle the two
+ % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX
+ % would then have different behavior). See the Macro Details node in
+ % the manual for the workaround we recommend for macros and
+ % line-oriented commands.
+ %
+ \scantokens{#1\empty}%
+\endgroup}
\def\scanexp#1{%
\edef\temp{\noexpand\scanmacro{#1}}%
@@ -5482,14 +7237,25 @@ width0pt\relax} \fi
\newcount\paramno % Count of parameters
\newtoks\macname % Macro name
\newif\ifrecursive % Is it recursive?
-\def\macrolist{} % List of all defined macros in the form
- % \do\macro1\do\macro2...
+
+% List of all defined macros in the form
+% \definedummyword\macro1\definedummyword\macro2...
+% Currently is also contains all @aliases; the list can be split
+% if there is a need.
+\def\macrolist{}
+
+% Add the macro to \macrolist
+\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname}
+\def\addtomacrolistxxx#1{%
+ \toks0 = \expandafter{\macrolist\definedummyword#1}%
+ \xdef\macrolist{\the\toks0}%
+}
% Utility routines.
% This does \let #1 = #2, with \csnames; that is,
% \let \csname#1\endcsname = \csname#2\endcsname
% (except of course we have to play expansion games).
-%
+%
\def\cslet#1#2{%
\expandafter\let
\csname#1\expandafter\endcsname
@@ -5515,13 +7281,18 @@ width0pt\relax} \fi
% Macro bodies are absorbed as an argument in a context where
% all characters are catcode 10, 11 or 12, except \ which is active
-% (as in normal texinfo). It is necessary to change the definition of \.
-
+% (as in normal texinfo). It is necessary to change the definition of \
+% to recognize macro arguments; this is the job of \mbodybackslash.
+%
+% Non-ASCII encodings make 8-bit characters active, so un-activate
+% them to avoid their expansion. Must do this non-globally, to
+% confine the change to the current group.
+%
% It's necessary to have hard CRs when the macro is executed. This is
-% done by making ^^M (\endlinechar) catcode 12 when reading the macro
+% done by making ^^M (\endlinechar) catcode 12 when reading the macro
% body, and then making it the \newlinechar in \scanmacro.
-
-\def\scanctxt{%
+%
+\def\scanctxt{% used as subroutine
\catcode`\"=\other
\catcode`\+=\other
\catcode`\<=\other
@@ -5531,15 +7302,16 @@ width0pt\relax} \fi
\catcode`\_=\other
\catcode`\|=\other
\catcode`\~=\other
+ \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi
}
-\def\scanargctxt{%
+\def\scanargctxt{% used for copying and captions, not macros.
\scanctxt
\catcode`\\=\other
\catcode`\^^M=\other
}
-\def\macrobodyctxt{%
+\def\macrobodyctxt{% used for @macro definitions
\scanctxt
\catcode`\{=\other
\catcode`\}=\other
@@ -5547,32 +7319,56 @@ width0pt\relax} \fi
\usembodybackslash
}
-\def\macroargctxt{%
+\def\macroargctxt{% used when scanning invocations
\scanctxt
- \catcode`\\=\other
+ \catcode`\\=0
}
+% why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes"
+% for the single characters \ { }. Thus, we end up with the "commands"
+% that would be written @\ @{ @} in a Texinfo document.
+%
+% We already have @{ and @}. For @\, we define it here, and only for
+% this purpose, to produce a typewriter backslash (so, the @\ that we
+% define for @math can't be used with @macro calls):
+%
+\def\\{\normalbackslash}%
+%
+% We would like to do this for \, too, since that is what makeinfo does.
+% But it is not possible, because Texinfo already has a command @, for a
+% cedilla accent. Documents must use @comma{} instead.
+%
+% \anythingelse will almost certainly be an error of some kind.
+
% \mbodybackslash is the definition of \ in @macro bodies.
% It maps \foo\ => \csname macarg.foo\endcsname => #N
% where N is the macro parameter number.
% We define \csname macarg.\endcsname to be \realbackslash, so
% \\ in macro replacement text gets you a backslash.
-
+%
{\catcode`@=0 @catcode`@\=@active
@gdef@usembodybackslash{@let\=@mbodybackslash}
@gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
}
\expandafter\def\csname macarg.\endcsname{\realbackslash}
+\def\margbackslash#1{\char`\#1 }
+
\def\macro{\recursivefalse\parsearg\macroxxx}
\def\rmacro{\recursivetrue\parsearg\macroxxx}
\def\macroxxx#1{%
- \getargs{#1}% now \macname is the macname and \argl the arglist
+ \getargs{#1}% now \macname is the macname and \argl the arglist
\ifx\argl\empty % no arguments
- \paramno=0%
+ \paramno=0\relax
\else
\expandafter\parsemargdef \argl;%
+ \if\paramno>256\relax
+ \ifx\eTeXversion\thisisundefined
+ \errhelp = \EMsimple
+ \errmessage{You need eTeX to compile a file with macros with more than 256 arguments}
+ \fi
+ \fi
\fi
\if1\csname ismacro.\the\macname\endcsname
\message{Warning: redefining \the\macname}%
@@ -5581,10 +7377,7 @@ width0pt\relax} \fi
\else \errmessage{Macro name \the\macname\space already defined}\fi
\global\cslet{macsave.\the\macname}{\the\macname}%
\global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
- % Add the macroname to \macrolist
- \toks0 = \expandafter{\macrolist\do}%
- \xdef\macrolist{\the\toks0
- \expandafter\noexpand\csname\the\macname\endcsname}%
+ \addtomacrolist{\the\macname}%
\fi
\begingroup \macrobodyctxt
\ifrecursive \expandafter\parsermacbody
@@ -5598,7 +7391,7 @@ width0pt\relax} \fi
% Remove the macro name from \macrolist:
\begingroup
\expandafter\let\csname#1\endcsname \relax
- \let\do\unmacrodo
+ \let\definedummyword\unmacrodo
\xdef\macrolist{\macrolist}%
\endgroup
\else
@@ -5610,10 +7403,10 @@ width0pt\relax} \fi
% macro definitions that have been changed to \relax.
%
\def\unmacrodo#1{%
- \ifx#1\relax
+ \ifx #1\relax
% remove this
\else
- \noexpand\do \noexpand #1%
+ \noexpand\definedummyword \noexpand#1%
\fi
}
@@ -5622,46 +7415,269 @@ width0pt\relax} \fi
% an opening brace, and that opening brace is not consumed.
\def\getargs#1{\getargsxxx#1{}}
\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
-\def\getmacname #1 #2\relax{\macname={#1}}
+\def\getmacname#1 #2\relax{\macname={#1}}
\def\getmacargs#1{\def\argl{#1}}
+% For macro processing make @ a letter so that we can make Texinfo private macro names.
+\edef\texiatcatcode{\the\catcode`\@}
+\catcode `@=11\relax
+
% Parse the optional {params} list. Set up \paramno and \paramlist
-% so \defmacro knows what to do. Define \macarg.blah for each blah
-% in the params list, to be ##N where N is the position in that list.
+% so \defmacro knows what to do. Define \macarg.BLAH for each BLAH
+% in the params list to some hook where the argument si to be expanded. If
+% there are less than 10 arguments that hook is to be replaced by ##N where N
+% is the position in that list, that is to say the macro arguments are to be
+% defined `a la TeX in the macro body.
+%
% That gets used by \mbodybackslash (above).
-
+%
% We need to get `macro parameter char #' into several definitions.
-% The technique used is stolen from LaTeX: let \hash be something
+% The technique used is stolen from LaTeX: let \hash be something
% unexpandable, insert that wherever you need a #, and then redefine
% it to # just before using the token list produced.
%
% The same technique is used to protect \eatspaces till just before
% the macro is used.
-
-\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
- \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
+%
+% If there are 10 or more arguments, a different technique is used, where the
+% hook remains in the body, and when macro is to be expanded the body is
+% processed again to replace the arguments.
+%
+% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the
+% argument N value and then \edef the body (nothing else will expand because of
+% the catcode regime underwhich the body was input).
+%
+% If you compile with TeX (not eTeX), and you have macros with 10 or more
+% arguments, you need that no macro has more than 256 arguments, otherwise an
+% error is produced.
+\def\parsemargdef#1;{%
+ \paramno=0\def\paramlist{}%
+ \let\hash\relax
+ \let\xeatspaces\relax
+ \parsemargdefxxx#1,;,%
+ % In case that there are 10 or more arguments we parse again the arguments
+ % list to set new definitions for the \macarg.BLAH macros corresponding to
+ % each BLAH argument. It was anyhow needed to parse already once this list
+ % in order to count the arguments, and as macros with at most 9 arguments
+ % are by far more frequent than macro with 10 or more arguments, defining
+ % twice the \macarg.BLAH macros does not cost too much processing power.
+ \ifnum\paramno<10\relax\else
+ \paramno0\relax
+ \parsemmanyargdef@@#1,;,% 10 or more arguments
+ \fi
+}
\def\parsemargdefxxx#1,{%
\if#1;\let\next=\relax
\else \let\next=\parsemargdefxxx
- \advance\paramno by 1%
+ \advance\paramno by 1
\expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
{\xeatspaces{\hash\the\paramno}}%
\edef\paramlist{\paramlist\hash\the\paramno,}%
\fi\next}
+\def\parsemmanyargdef@@#1,{%
+ \if#1;\let\next=\relax
+ \else
+ \let\next=\parsemmanyargdef@@
+ \edef\tempb{\eatspaces{#1}}%
+ \expandafter\def\expandafter\tempa
+ \expandafter{\csname macarg.\tempb\endcsname}%
+ % Note that we need some extra \noexpand\noexpand, this is because we
+ % don't want \the to be expanded in the \parsermacbody as it uses an
+ % \xdef .
+ \expandafter\edef\tempa
+ {\noexpand\noexpand\noexpand\the\toks\the\paramno}%
+ \advance\paramno by 1\relax
+ \fi\next}
+
% These two commands read recursive and nonrecursive macro bodies.
% (They're different since rec and nonrec macros end differently.)
+%
+\catcode `\@\texiatcatcode
\long\def\parsemacbody#1@end macro%
{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
\long\def\parsermacbody#1@end rmacro%
{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\catcode `\@=11\relax
+
+\let\endargs@\relax
+\let\nil@\relax
+\def\nilm@{\nil@}%
+\long\def\nillm@{\nil@}%
+
+% This macro is expanded during the Texinfo macro expansion, not during its
+% definition. It gets all the arguments values and assigns them to macros
+% macarg.ARGNAME
+%
+% #1 is the macro name
+% #2 is the list of argument names
+% #3 is the list of argument values
+\def\getargvals@#1#2#3{%
+ \def\macargdeflist@{}%
+ \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion.
+ \def\paramlist{#2,\nil@}%
+ \def\macroname{#1}%
+ \begingroup
+ \macroargctxt
+ \def\argvaluelist{#3,\nil@}%
+ \def\@tempa{#3}%
+ \ifx\@tempa\empty
+ \setemptyargvalues@
+ \else
+ \getargvals@@
+ \fi
+}
+
+%
+\def\getargvals@@{%
+ \ifx\paramlist\nilm@
+ % Some sanity check needed here that \argvaluelist is also empty.
+ \ifx\argvaluelist\nillm@
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Too many arguments in macro `\macroname'!}%
+ \fi
+ \let\next\macargexpandinbody@
+ \else
+ \ifx\argvaluelist\nillm@
+ % No more arguments values passed to macro. Set remaining named-arg
+ % macros to empty.
+ \let\next\setemptyargvalues@
+ \else
+ % pop current arg name into \@tempb
+ \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\paramlist}%
+ % pop current argument value into \@tempc
+ \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\argvaluelist}%
+ % Here \@tempb is the current arg name and \@tempc is the current arg value.
+ % First place the new argument macro definition into \@tempd
+ \expandafter\macname\expandafter{\@tempc}%
+ \expandafter\let\csname macarg.\@tempb\endcsname\relax
+ \expandafter\def\expandafter\@tempe\expandafter{%
+ \csname macarg.\@tempb\endcsname}%
+ \edef\@tempd{\long\def\@tempe{\the\macname}}%
+ \push@\@tempd\macargdeflist@
+ \let\next\getargvals@@
+ \fi
+ \fi
+ \next
+}
+
+\def\push@#1#2{%
+ \expandafter\expandafter\expandafter\def
+ \expandafter\expandafter\expandafter#2%
+ \expandafter\expandafter\expandafter{%
+ \expandafter#1#2}%
+}
+
+% Replace arguments by their values in the macro body, and place the result
+% in macro \@tempa
+\def\macvalstoargs@{%
+ % To do this we use the property that token registers that are \the'ed
+ % within an \edef expand only once. So we are going to place all argument
+ % values into respective token registers.
+ %
+ % First we save the token context, and initialize argument numbering.
+ \begingroup
+ \paramno0\relax
+ % Then, for each argument number #N, we place the corresponding argument
+ % value into a new token list register \toks#N
+ \expandafter\putargsintokens@\saveparamlist@,;,%
+ % Then, we expand the body so that argument are replaced by their
+ % values. The trick for values not to be expanded themselves is that they
+ % are within tokens and that tokens expand only once in an \edef .
+ \edef\@tempc{\csname mac.\macroname .body\endcsname}%
+ % Now we restore the token stack pointer to free the token list registers
+ % which we have used, but we make sure that expanded body is saved after
+ % group.
+ \expandafter
+ \endgroup
+ \expandafter\def\expandafter\@tempa\expandafter{\@tempc}%
+ }
+
+\def\macargexpandinbody@{%
+ %% Define the named-macro outside of this group and then close this group.
+ \expandafter
+ \endgroup
+ \macargdeflist@
+ % First the replace in body the macro arguments by their values, the result
+ % is in \@tempa .
+ \macvalstoargs@
+ % Then we point at the \norecurse or \gobble (for recursive) macro value
+ % with \@tempb .
+ \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname
+ % Depending on whether it is recursive or not, we need some tailing
+ % \egroup .
+ \ifx\@tempb\gobble
+ \let\@tempc\relax
+ \else
+ \let\@tempc\egroup
+ \fi
+ % And now we do the real job:
+ \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}%
+ \@tempd
+}
+
+\def\putargsintokens@#1,{%
+ \if#1;\let\next\relax
+ \else
+ \let\next\putargsintokens@
+ % First we allocate the new token list register, and give it a temporary
+ % alias \@tempb .
+ \toksdef\@tempb\the\paramno
+ % Then we place the argument value into that token list register.
+ \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname
+ \expandafter\@tempb\expandafter{\@tempa}%
+ \advance\paramno by 1\relax
+ \fi
+ \next
+}
+
+% Save the token stack pointer into macro #1
+\def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}}
+% Restore the token stack pointer from number in macro #1
+\def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax}
+% newtoks that can be used non \outer .
+\def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi}
-% This defines the macro itself. There are six cases: recursive and
-% nonrecursive macros of zero, one, and many arguments.
+% Tailing missing arguments are set to empty
+\def\setemptyargvalues@{%
+ \ifx\paramlist\nilm@
+ \let\next\macargexpandinbody@
+ \else
+ \expandafter\setemptyargvaluesparser@\paramlist\endargs@
+ \let\next\setemptyargvalues@
+ \fi
+ \next
+}
+
+\def\setemptyargvaluesparser@#1,#2\endargs@{%
+ \expandafter\def\expandafter\@tempa\expandafter{%
+ \expandafter\def\csname macarg.#1\endcsname{}}%
+ \push@\@tempa\macargdeflist@
+ \def\paramlist{#2}%
+}
+
+% #1 is the element target macro
+% #2 is the list macro
+% #3,#4\endargs@ is the list value
+\def\pop@#1#2#3,#4\endargs@{%
+ \def#1{#3}%
+ \def#2{#4}%
+}
+\long\def\longpop@#1#2#3,#4\endargs@{%
+ \long\def#1{#3}%
+ \long\def#2{#4}%
+}
+
+% This defines a Texinfo @macro. There are eight cases: recursive and
+% nonrecursive macros of zero, one, up to nine, and many arguments.
% Much magic with \expandafter here.
% \xdef is used so that macro definitions will survive the file
% they're defined in; @include reads the file inside a group.
+%
\def\defmacro{%
\let\hash=##% convert placeholders to macro parameter chars
\ifrecursive
@@ -5676,17 +7692,25 @@ width0pt\relax} \fi
\expandafter\noexpand\csname\the\macname xxx\endcsname}%
\expandafter\xdef\csname\the\macname xxx\endcsname##1{%
\egroup\noexpand\scanmacro{\temp}}%
- \else % many
- \expandafter\xdef\csname\the\macname\endcsname{%
- \bgroup\noexpand\macroargctxt
- \noexpand\csname\the\macname xx\endcsname}%
- \expandafter\xdef\csname\the\macname xx\endcsname##1{%
- \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
- \expandafter\expandafter
- \expandafter\xdef
- \expandafter\expandafter
- \csname\the\macname xxx\endcsname
- \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+ \else
+ \ifnum\paramno<10\relax % at most 9
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+ \else % 10 or more
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble
+ \fi
\fi
\else
\ifcase\paramno
@@ -5703,63 +7727,57 @@ width0pt\relax} \fi
\egroup
\noexpand\norecurse{\the\macname}%
\noexpand\scanmacro{\temp}\egroup}%
- \else % many
- \expandafter\xdef\csname\the\macname\endcsname{%
- \bgroup\noexpand\macroargctxt
- \expandafter\noexpand\csname\the\macname xx\endcsname}%
- \expandafter\xdef\csname\the\macname xx\endcsname##1{%
- \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
- \expandafter\expandafter
- \expandafter\xdef
- \expandafter\expandafter
- \csname\the\macname xxx\endcsname
- \paramlist{%
- \egroup
- \noexpand\norecurse{\the\macname}%
- \noexpand\scanmacro{\temp}\egroup}%
+ \else % at most 9
+ \ifnum\paramno<10\relax
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \expandafter\noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % 10 or more:
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse
+ \fi
\fi
\fi}
+\catcode `\@\texiatcatcode\relax
+
\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
% \braceorline decides whether the next nonwhitespace character is a
% {. If so it reads up to the closing }, if not, it reads the whole
% line. Whatever was read is then fed to the next control sequence
-% as an argument (by \parsebrace or \parsearg)
-\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx}
+% as an argument (by \parsebrace or \parsearg).
+%
+\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
\def\braceorlinexxx{%
\ifx\nchar\bgroup\else
\expandafter\parsearg
- \fi \next}
-
-% We want to disable all macros during \shipout so that they are not
-% expanded by \write.
-\def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}%
- \edef\next{\macrolist}\expandafter\endgroup\next}
-
-% For \indexnofonts, we need to get rid of all macros, leaving only the
-% arguments (if present). Of course this is not nearly correct, but it
-% is the best we can do for now. makeinfo does not expand macros in the
-% argument to @deffn, which ends up writing an index entry, and texindex
-% isn't prepared for an index sort entry that starts with \.
-%
-% Since macro invocations are followed by braces, we can just redefine them
-% to take a single TeX argument. The case of a macro invocation that
-% goes to end-of-line is not handled.
-%
-\def\emptyusermacros{\begingroup
- \def\do##1{\let\noexpand##1=\noexpand\asis}%
- \edef\next{\macrolist}\expandafter\endgroup\next}
+ \fi \macnamexxx}
% @alias.
% We need some trickery to remove the optional spaces around the equal
-% sign. Just make them active and then expand them all to nothing.
+% sign. Make them active and then expand them all to nothing.
+%
\def\alias{\parseargusing\obeyspaces\aliasxxx}
\def\aliasxxx #1{\aliasyyy#1\relax}
\def\aliasyyy #1=#2\relax{%
{%
\expandafter\let\obeyedspace=\empty
+ \addtomacrolist{#1}%
\xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
}%
\next
@@ -5769,13 +7787,13 @@ width0pt\relax} \fi
\message{cross references,}
\newwrite\auxfile
-
\newif\ifhavexrefs % True if xref values are known.
\newif\ifwarnedxrefs % True if we warned once that they aren't known.
% @inforef is relatively simple.
\def\inforef #1{\inforefzzz #1,,,,**}
-\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+\def\inforefzzz #1,#2,#3,#4**{%
+ \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
node \samp{\ignorespaces#1{}}}
% @node's only job in TeX is to define \lastnode, which is used in
@@ -5814,7 +7832,7 @@ width0pt\relax} \fi
% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
% anchor), which consists of three parts:
-% 1) NAME-title - the current sectioning name taken from \thissection,
+% 1) NAME-title - the current sectioning name taken from \lastsection,
% or the anchor name.
% 2) NAME-snt - section number and type, passed as the SNT arg, or
% empty for anchors.
@@ -5829,20 +7847,39 @@ width0pt\relax} \fi
\iflinks
{%
\atdummies % preserve commands, but don't expand them
- \turnoffactive
- \otherbackslash
\edef\writexrdef##1##2{%
\write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
##1}{##2}}% these are parameters of \writexrdef
}%
- \toks0 = \expandafter{\thissection}%
+ \toks0 = \expandafter{\lastsection}%
\immediate \writexrdef{title}{\the\toks0 }%
\immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
- \writexrdef{pg}{\folio}% will be written later, during \shipout
+ \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout
}%
\fi
}
+% @xrefautosectiontitle on|off says whether @section(ing) names are used
+% automatically in xrefs, if the third arg is not explicitly specified.
+% This was provided as a "secret" @set xref-automatic-section-title
+% variable, now it's official.
+%
+\parseargdef\xrefautomaticsectiontitle{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @xrefautomaticsectiontitle value `\temp',
+ must be on|off}%
+ \fi\fi
+}
+
+%
% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is
% the node name, #2 the name of the Info cross-reference, #3 the printed
% node name, #4 the name of the Info file, #5 the name of the printed
@@ -5851,26 +7888,41 @@ width0pt\relax} \fi
\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
\def\ref#1{\xrefX[#1,,,,,,,]}
+%
+\newbox\toprefbox
+\newbox\printedrefnamebox
+\newbox\infofilenamebox
+\newbox\printedmanualbox
+%
\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
\unsepspaces
- \def\printedmanual{\ignorespaces #5}%
+ %
+ % Get args without leading/trailing spaces.
\def\printedrefname{\ignorespaces #3}%
- \setbox1=\hbox{\printedmanual\unskip}%
- \setbox0=\hbox{\printedrefname\unskip}%
- \ifdim \wd0 = 0pt
+ \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}%
+ %
+ \def\infofilename{\ignorespaces #4}%
+ \setbox\infofilenamebox = \hbox{\infofilename\unskip}%
+ %
+ \def\printedmanual{\ignorespaces #5}%
+ \setbox\printedmanualbox = \hbox{\printedmanual\unskip}%
+ %
+ % If the printed reference name (arg #3) was not explicitly given in
+ % the @xref, figure out what we want to use.
+ \ifdim \wd\printedrefnamebox = 0pt
% No printed node name was explicitly given.
- \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
- % Use the node name inside the square brackets.
+ \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax
+ % Not auto section-title: use node name inside the square brackets.
\def\printedrefname{\ignorespaces #1}%
\else
- % Use the actual chapter/section title appear inside
- % the square brackets. Use the real section title if we have it.
- \ifdim \wd1 > 0pt
- % It is in another manual, so we don't have it.
+ % Auto section-title: use chapter/section title inside
+ % the square brackets if we have it.
+ \ifdim \wd\printedmanualbox > 0pt
+ % It is in another manual, so we don't have it; use node name.
\def\printedrefname{\ignorespaces #1}%
\else
\ifhavexrefs
- % We know the real title if we have the xref values.
+ % We (should) know the real title if we have the xref values.
\def\printedrefname{\refx{#1-title}{}}%
\else
% Otherwise just copy the Info node name.
@@ -5882,18 +7934,32 @@ width0pt\relax} \fi
%
% Make link in pdf output.
\ifpdf
- \leavevmode
- \getfilename{#4}%
- {\turnoffactive \otherbackslash
+ {\indexnofonts
+ \turnoffactive
+ \makevalueexpandable
+ % This expands tokens, so do it after making catcode changes, so _
+ % etc. don't get their TeX definitions. This ignores all spaces in
+ % #4, including (wrongly) those in the middle of the filename.
+ \getfilename{#4}%
+ %
+ % This (wrongly) does not take account of leading or trailing
+ % spaces in #1, which should be ignored.
+ \edef\pdfxrefdest{#1}%
+ \ifx\pdfxrefdest\empty
+ \def\pdfxrefdest{Top}% no empty targets
+ \else
+ \txiescapepdf\pdfxrefdest % escape PDF special chars
+ \fi
+ %
+ \leavevmode
+ \startlink attr{/Border [0 0 0]}%
\ifnum\filenamelength>0
- \startlink attr{/Border [0 0 0]}%
- goto file{\the\filename.pdf} name{#1}%
+ goto file{\the\filename.pdf} name{\pdfxrefdest}%
\else
- \startlink attr{/Border [0 0 0]}%
- goto name{\pdfmkpgn{#1}}%
+ goto name{\pdfmkpgn{\pdfxrefdest}}%
\fi
}%
- \linkcolor
+ \setcolor{\linkcolor}%
\fi
%
% Float references are printed completely differently: "Figure 1.2"
@@ -5904,60 +7970,98 @@ width0pt\relax} \fi
% include an _ in the xref name, etc.
\indexnofonts
\turnoffactive
- \otherbackslash
\expandafter\global\expandafter\let\expandafter\Xthisreftitle
\csname XR#1-title\endcsname
}%
\iffloat\Xthisreftitle
% If the user specified the print name (third arg) to the ref,
% print it instead of our usual "Figure 1.2".
- \ifdim\wd0 = 0pt
- \refx{#1-snt}%
+ \ifdim\wd\printedrefnamebox = 0pt
+ \refx{#1-snt}{}%
\else
\printedrefname
\fi
%
- % if the user also gave the printed manual name (fifth arg), append
+ % If the user also gave the printed manual name (fifth arg), append
% "in MANUALNAME".
- \ifdim \wd1 > 0pt
+ \ifdim \wd\printedmanualbox > 0pt
\space \putwordin{} \cite{\printedmanual}%
\fi
\else
% node/anchor (non-float) references.
+ %
+ % If we use \unhbox to print the node names, TeX does not insert
+ % empty discretionaries after hyphens, which means that it will not
+ % find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens,
+ % this is a loss. Therefore, we give the text of the node name
+ % again, so it is as if TeX is seeing it for the first time.
+ %
+ \ifdim \wd\printedmanualbox > 0pt
+ % Cross-manual reference with a printed manual name.
+ %
+ \crossmanualxref{\cite{\printedmanual\unskip}}%
+ %
+ \else\ifdim \wd\infofilenamebox > 0pt
+ % Cross-manual reference with only an info filename (arg 4), no
+ % printed manual name (arg 5). This is essentially the same as
+ % the case above; we output the filename, since we have nothing else.
+ %
+ \crossmanualxref{\code{\infofilename\unskip}}%
%
- % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
- % insert empty discretionaries after hyphens, which means that it will
- % not find a line break at a hyphen in a node names. Since some manuals
- % are best written with fairly long node names, containing hyphens, this
- % is a loss. Therefore, we give the text of the node name again, so it
- % is as if TeX is seeing it for the first time.
- \ifdim \wd1 > 0pt
- \putwordsection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
\else
+ % Reference within this manual.
+ %
% _ (for example) has to be the character _ for the purposes of the
% control sequence corresponding to the node, but it has to expand
% into the usual \leavevmode...\vrule stuff for purposes of
% printing. So we \turnoffactive for the \refx-snt, back on for the
% printing, back off for the \refx-pg.
- {\turnoffactive \otherbackslash
+ {\turnoffactive
% Only output a following space if the -snt ref is nonempty; for
% @unnumbered and @anchor, it won't be.
\setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
\ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
}%
- % output the `[mynode]' via a macro so it can be overridden.
+ % output the `[mynode]' via the macro below so it can be overridden.
\xrefprintnodename\printedrefname
%
% But we always want a comma and a space:
,\space
%
% output the `page 3'.
- \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}%
- \fi
+ \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+ \fi\fi
\fi
\endlink
\endgroup}
+% Output a cross-manual xref to #1. Used just above (twice).
+%
+% Only include the text "Section ``foo'' in" if the foo is neither
+% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply
+% "see The Foo Manual", the idea being to refer to the whole manual.
+%
+% But, this being TeX, we can't easily compare our node name against the
+% string "Top" while ignoring the possible spaces before and after in
+% the input. By adding the arbitrary 7sp below, we make it much less
+% likely that a real node name would have the same width as "Top" (e.g.,
+% in a monospaced font). Hopefully it will never happen in practice.
+%
+% For the same basic reason, we retypeset the "Top" at every
+% reference, since the current font is indeterminate.
+%
+\def\crossmanualxref#1{%
+ \setbox\toprefbox = \hbox{Top\kern7sp}%
+ \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}%
+ \ifdim \wd2 > 7sp % nonempty?
+ \ifdim \wd2 = \wd\toprefbox \else % same as Top?
+ \putwordSection{} ``\printedrefname'' \putwordin{}\space
+ \fi
+ \fi
+ #1%
+}
+
% This macro is called from \xrefX for the `[nodename]' part of xref
% output. It's a separate macro only so it can be changed more easily,
% since square brackets don't work well in some documents. Particularly
@@ -6008,7 +8112,8 @@ width0pt\relax} \fi
\angleleft un\-de\-fined\angleright
\iflinks
\ifhavexrefs
- \message{\linenumber Undefined cross reference `#1'.}%
+ {\toks0 = {#1}% avoid expansion of possibly-complex value
+ \message{\linenumber Undefined cross reference `\the\toks0'.}}%
\else
\ifwarnedxrefs\else
\global\warnedxrefstrue
@@ -6028,10 +8133,18 @@ width0pt\relax} \fi
% collisions). But if this is a float type, we have more work to do.
%
\def\xrdef#1#2{%
- \expandafter\gdef\csname XR#1\endcsname{#2}% remember this xref value.
+ {% The node name might contain 8-bit characters, which in our current
+ % implementation are changed to commands like @'e. Don't let these
+ % mess up the control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safexrefname{#1}%
+ }%
+ %
+ \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref
%
% Was that xref control sequence that we just defined for a float?
- \expandafter\iffloat\csname XR#1\endcsname
+ \expandafter\iffloat\csname XR\safexrefname\endcsname
% it was a float, and we have the (safe) float type in \iffloattype.
\expandafter\let\expandafter\floatlist
\csname floatlist\iffloattype\endcsname
@@ -6046,7 +8159,8 @@ width0pt\relax} \fi
%
% Remember this xref in the control sequence \floatlistFLOATTYPE,
% for later use in \listoffloats.
- \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0{#1}}%
+ \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
+ {\safexrefname}}%
\fi
}
@@ -6055,13 +8169,13 @@ width0pt\relax} \fi
\def\tryauxfile{%
\openin 1 \jobname.aux
\ifeof 1 \else
- \readauxfile
+ \readdatafile{aux}%
\global\havexrefstrue
\fi
\closein 1
}
-\def\readauxfile{\begingroup
+\def\setupdatafile{%
\catcode`\^^@=\other
\catcode`\^^A=\other
\catcode`\^^B=\other
@@ -6130,11 +8244,11 @@ width0pt\relax} \fi
%
% Make the characters 128-255 be printing characters.
{%
- \count 1=128
+ \count1=128
\def\loop{%
- \catcode\count 1=\other
- \advance\count 1 by 1
- \ifnum \count 1<256 \loop \fi
+ \catcode\count1=\other
+ \advance\count1 by 1
+ \ifnum \count1<256 \loop \fi
}%
}%
%
@@ -6142,8 +8256,12 @@ width0pt\relax} \fi
\catcode`\{=1
\catcode`\}=2
\catcode`\@=0
- %
- \input \jobname.aux
+}
+
+\def\readdatafile#1{%
+\begingroup
+ \setupdatafile
+ \input\jobname.#1
\endgroup}
@@ -6159,7 +8277,7 @@ width0pt\relax} \fi
% space to prevent strange expansion errors.)
\def\supereject{\par\penalty -20000\footnoteno =0 }
-% @footnotestyle is meaningful for info output only.
+% @footnotestyle is meaningful for Info output only.
\let\footnotestyle=\comment
{\catcode `\@=11
@@ -6222,6 +8340,8 @@ width0pt\relax} \fi
% expands into a box, it must come within the paragraph, lest it
% provide a place where TeX can split the footnote.
\footstrut
+ %
+ % Invoke rest of plain TeX footnote routine.
\futurelet\next\fo@t
}
}%end \catcode `\@=11
@@ -6229,7 +8349,7 @@ width0pt\relax} \fi
% In case a @footnote appears in a vbox, save the footnote text and create
% the real \insert just after the vbox finished. Otherwise, the insertion
% would be lost.
-% Similarily, if a @footnote appears inside an alignment, save the footnote
+% Similarly, if a @footnote appears inside an alignment, save the footnote
% text to a box and make the \insert when a row of the table is finished.
% And the same can be done for other insert classes. --kasal, 16nov03.
@@ -6309,7 +8429,7 @@ width0pt\relax} \fi
it from ftp://tug.org/tex/epsf.tex.}
%
\def\image#1{%
- \ifx\epsfbox\undefined
+ \ifx\epsfbox\thisisundefined
\ifwarnednoepsf \else
\errhelp = \noepsfhelp
\errmessage{epsf.tex not found, images will be ignored}%
@@ -6325,7 +8445,7 @@ width0pt\relax} \fi
% #2 is (optional) width, #3 is (optional) height.
% #4 is (ignored optional) html alt text.
% #5 is (ignored optional) extension.
-% #6 is just the usual extra ignored arg for parsing this stuff.
+% #6 is just the usual extra ignored arg for parsing stuff.
\newif\ifimagevmode
\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
\catcode`\^^M = 5 % in case we're inside an example
@@ -6333,15 +8453,30 @@ width0pt\relax} \fi
% If the image is by itself, center it.
\ifvmode
\imagevmodetrue
- \nobreak\bigskip
+ \else \ifx\centersub\centerV
+ % for @center @image, we need a vbox so we can have our vertical space
+ \imagevmodetrue
+ \vbox\bgroup % vbox has better behavior than vtop herev
+ \fi\fi
+ %
+ \ifimagevmode
+ \nobreak\medskip
% Usually we'll have text after the image which will insert
% \parskip glue, so insert it here too to equalize the space
% above and below.
\nobreak\vskip\parskip
\nobreak
- \line\bgroup\hss
\fi
%
+ % Leave vertical mode so that indentation from an enclosing
+ % environment such as @quotation is respected.
+ % However, if we're at the top level, we don't want the
+ % normal paragraph indentation.
+ % On the other hand, if we are in the case of @center @image, we don't
+ % want to start a paragraph, which will create a hsize-width box and
+ % eradicate the centering.
+ \ifx\centersub\centerV\else \noindent \fi
+ %
% Output the image.
\ifpdf
\dopdfimage{#1}{#2}{#3}%
@@ -6352,7 +8487,10 @@ width0pt\relax} \fi
\epsfbox{#1.eps}%
\fi
%
- \ifimagevmode \hss \egroup \bigbreak \fi % space after the image
+ \ifimagevmode
+ \medskip % space after a standalone image
+ \fi
+ \ifx\centersub\centerV \egroup \fi
\endgroup}
@@ -6419,13 +8557,13 @@ width0pt\relax} \fi
\global\advance\floatno by 1
%
{%
- % This magic value for \thissection is output by \setref as the
+ % This magic value for \lastsection is output by \setref as the
% XREFLABEL-title value. \xrefX uses it to distinguish float
% labels (which have a completely different output format) from
% node and anchor labels. And \xrdef uses it to construct the
% lists of floats.
%
- \edef\thissection{\floatmagic=\safefloattype}%
+ \edef\lastsection{\floatmagic=\safefloattype}%
\setref{\floatlabel}{Yfloat}%
}%
\fi
@@ -6492,7 +8630,8 @@ width0pt\relax} \fi
% \floatlabel-lof. Besides \floatident, we include the short
% caption if specified, else the full caption if specified, else nothing.
{%
- \atdummies \turnoffactive \otherbackslash
+ \atdummies
+ %
% since we read the caption text in the macro world, where ^^M
% is turned into a normal character, we have to scan it back, so
% we don't write the literal three characters "^^M" into the aux file.
@@ -6513,8 +8652,9 @@ width0pt\relax} \fi
%
% place the captured inserts
%
- % BEWARE: when the floats start float, we have to issue warning whenever an
- % insert appears inside a float which could possibly float. --kasal, 26may04
+ % BEWARE: when the floats start floating, we have to issue warning
+ % whenever an insert appears inside a float which could possibly
+ % float. --kasal, 26may04
%
\checkinserts
}
@@ -6558,7 +8698,7 @@ width0pt\relax} \fi
% #1 is the control sequence we are passed; we expand into a conditional
% which is true if #1 represents a float ref. That is, the magic
-% \thissection value which we \setref above.
+% \lastsection value which we \setref above.
%
\def\iffloat#1{\expandafter\doiffloat#1==\finish}
%
@@ -6619,39 +8759,909 @@ width0pt\relax} \fi
\writeentry
}}
+
\message{localization,}
-% and i18n.
-% @documentlanguage is usually given very early, just after
-% @setfilename. If done too late, it may not override everything
-% properly. Single argument is the language abbreviation.
-% It would be nice if we could set up a hyphenation file here.
+% For single-language documents, @documentlanguage is usually given very
+% early, just after @documentencoding. Single argument is the language
+% (de) or locale (de_DE) abbreviation.
%
-\parseargdef\documentlanguage{%
+{
+ \catcode`\_ = \active
+ \globaldefs=1
+\parseargdef\documentlanguage{\begingroup
+ \let_=\normalunderscore % normal _ character for filenames
\tex % read txi-??.tex file in plain TeX.
- % Read the file if it exists.
+ % Read the file by the name they passed if it exists.
\openin 1 txi-#1.tex
\ifeof 1
- \errhelp = \nolanghelp
- \errmessage{Cannot read language file txi-#1.tex}%
+ \documentlanguagetrywithoutunderscore{#1_\finish}%
\else
+ \globaldefs = 1 % everything in the txi-LL files needs to persist
\input txi-#1.tex
\fi
\closein 1
- \endgroup
+ \endgroup % end raw TeX
+\endgroup}
+%
+% If they passed de_DE, and txi-de_DE.tex doesn't exist,
+% try txi-de.tex.
+%
+\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{%
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \errhelp = \nolanghelp
+ \errmessage{Cannot read language file txi-#1.tex}%
+ \else
+ \globaldefs = 1 % everything in the txi-LL files needs to persist
+ \input txi-#1.tex
+ \fi
+ \closein 1
}
+}% end of special _ catcode
+%
\newhelp\nolanghelp{The given language definition file cannot be found or
-is empty. Maybe you need to install it? In the current directory
-should work if nowhere else does.}
+is empty. Maybe you need to install it? Putting it in the current
+directory should work if nowhere else does.}
+% This macro is called from txi-??.tex files; the first argument is the
+% \language name to set (without the "\lang@" prefix), the second and
+% third args are \{left,right}hyphenmin.
+%
+% The language names to pass are determined when the format is built.
+% See the etex.log file created at that time, e.g.,
+% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log.
+%
+% With TeX Live 2008, etex now includes hyphenation patterns for all
+% available languages. This means we can support hyphenation in
+% Texinfo, at least to some extent. (This still doesn't solve the
+% accented characters problem.)
+%
+\catcode`@=11
+\def\txisetlanguage#1#2#3{%
+ % do not set the language if the name is undefined in the current TeX.
+ \expandafter\ifx\csname lang@#1\endcsname \relax
+ \message{no patterns for #1}%
+ \else
+ \global\language = \csname lang@#1\endcsname
+ \fi
+ % but there is no harm in adjusting the hyphenmin values regardless.
+ \global\lefthyphenmin = #2\relax
+ \global\righthyphenmin = #3\relax
+}
-% @documentencoding should change something in TeX eventually, most
-% likely, but for now just recognize it.
-\let\documentencoding = \comment
+% Helpers for encodings.
+% Set the catcode of characters 128 through 255 to the specified number.
+%
+\def\setnonasciicharscatcode#1{%
+ \count255=128
+ \loop\ifnum\count255<256
+ \global\catcode\count255=#1\relax
+ \advance\count255 by 1
+ \repeat
+}
+\def\setnonasciicharscatcodenonglobal#1{%
+ \count255=128
+ \loop\ifnum\count255<256
+ \catcode\count255=#1\relax
+ \advance\count255 by 1
+ \repeat
+}
-% Page size parameters.
+% @documentencoding sets the definition of non-ASCII characters
+% according to the specified encoding.
%
+\parseargdef\documentencoding{%
+ % Encoding being declared for the document.
+ \def\declaredencoding{\csname #1.enc\endcsname}%
+ %
+ % Supported encodings: names converted to tokens in order to be able
+ % to compare them with \ifx.
+ \def\ascii{\csname US-ASCII.enc\endcsname}%
+ \def\latnine{\csname ISO-8859-15.enc\endcsname}%
+ \def\latone{\csname ISO-8859-1.enc\endcsname}%
+ \def\lattwo{\csname ISO-8859-2.enc\endcsname}%
+ \def\utfeight{\csname UTF-8.enc\endcsname}%
+ %
+ \ifx \declaredencoding \ascii
+ \asciichardefs
+ %
+ \else \ifx \declaredencoding \lattwo
+ \setnonasciicharscatcode\active
+ \lattwochardefs
+ %
+ \else \ifx \declaredencoding \latone
+ \setnonasciicharscatcode\active
+ \latonechardefs
+ %
+ \else \ifx \declaredencoding \latnine
+ \setnonasciicharscatcode\active
+ \latninechardefs
+ %
+ \else \ifx \declaredencoding \utfeight
+ \setnonasciicharscatcode\active
+ \utfeightchardefs
+ %
+ \else
+ \message{Unknown document encoding #1, ignoring.}%
+ %
+ \fi % utfeight
+ \fi % latnine
+ \fi % latone
+ \fi % lattwo
+ \fi % ascii
+}
+
+% A message to be logged when using a character that isn't available
+% the default font encoding (OT1).
+%
+\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
+
+% Take account of \c (plain) vs. \, (Texinfo) difference.
+\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi}
+
+% First, make active non-ASCII characters in order for them to be
+% correctly categorized when TeX reads the replacement text of
+% macros containing the character definitions.
+\setnonasciicharscatcode\active
+%
+% Latin1 (ISO-8859-1) character definitions.
+\def\latonechardefs{%
+ \gdef^^a0{\tie}
+ \gdef^^a1{\exclamdown}
+ \gdef^^a2{\missingcharmsg{CENT SIGN}}
+ \gdef^^a3{{\pounds}}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\missingcharmsg{YEN SIGN}}
+ \gdef^^a6{\missingcharmsg{BROKEN BAR}}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\copyright}
+ \gdef^^aa{\ordf}
+ \gdef^^ab{\guillemetleft}
+ \gdef^^ac{$\lnot$}
+ \gdef^^ad{\-}
+ \gdef^^ae{\registeredsymbol}
+ \gdef^^af{\={}}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{$\pm$}
+ \gdef^^b2{$^2$}
+ \gdef^^b3{$^3$}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{$\mu$}
+ \gdef^^b6{\P}
+ %
+ \gdef^^b7{$^.$}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{$^1$}
+ \gdef^^ba{\ordm}
+ %
+ \gdef^^bb{\guillemetright}
+ \gdef^^bc{$1\over4$}
+ \gdef^^bd{$1\over2$}
+ \gdef^^be{$3\over4$}
+ \gdef^^bf{\questiondown}
+ %
+ \gdef^^c0{\`A}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\~A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\ringaccent A}
+ \gdef^^c6{\AE}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\`E}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\^E}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\`I}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\"I}
+ %
+ \gdef^^d0{\DH}
+ \gdef^^d1{\~N}
+ \gdef^^d2{\`O}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\~O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\O}
+ \gdef^^d9{\`U}
+ \gdef^^da{\'U}
+ \gdef^^db{\^U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\TH}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\`a}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\~a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\ringaccent a}
+ \gdef^^e6{\ae}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\`e}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\^e}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\`{\dotless i}}
+ \gdef^^ed{\'{\dotless i}}
+ \gdef^^ee{\^{\dotless i}}
+ \gdef^^ef{\"{\dotless i}}
+ %
+ \gdef^^f0{\dh}
+ \gdef^^f1{\~n}
+ \gdef^^f2{\`o}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\~o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\o}
+ \gdef^^f9{\`u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\^u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\th}
+ \gdef^^ff{\"y}
+}
+
+% Latin9 (ISO-8859-15) encoding character definitions.
+\def\latninechardefs{%
+ % Encoding is almost identical to Latin1.
+ \latonechardefs
+ %
+ \gdef^^a4{\euro}
+ \gdef^^a6{\v S}
+ \gdef^^a8{\v s}
+ \gdef^^b4{\v Z}
+ \gdef^^b8{\v z}
+ \gdef^^bc{\OE}
+ \gdef^^bd{\oe}
+ \gdef^^be{\"Y}
+}
+
+% Latin2 (ISO-8859-2) character definitions.
+\def\lattwochardefs{%
+ \gdef^^a0{\tie}
+ \gdef^^a1{\ogonek{A}}
+ \gdef^^a2{\u{}}
+ \gdef^^a3{\L}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\v L}
+ \gdef^^a6{\'S}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\v S}
+ \gdef^^aa{\cedilla S}
+ \gdef^^ab{\v T}
+ \gdef^^ac{\'Z}
+ \gdef^^ad{\-}
+ \gdef^^ae{\v Z}
+ \gdef^^af{\dotaccent Z}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{\ogonek{a}}
+ \gdef^^b2{\ogonek{ }}
+ \gdef^^b3{\l}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{\v l}
+ \gdef^^b6{\'s}
+ \gdef^^b7{\v{}}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{\v s}
+ \gdef^^ba{\cedilla s}
+ \gdef^^bb{\v t}
+ \gdef^^bc{\'z}
+ \gdef^^bd{\H{}}
+ \gdef^^be{\v z}
+ \gdef^^bf{\dotaccent z}
+ %
+ \gdef^^c0{\'R}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\u A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\'L}
+ \gdef^^c6{\'C}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\v C}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\ogonek{E}}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\v E}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\v D}
+ %
+ \gdef^^d0{\DH}
+ \gdef^^d1{\'N}
+ \gdef^^d2{\v N}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\H O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\v R}
+ \gdef^^d9{\ringaccent U}
+ \gdef^^da{\'U}
+ \gdef^^db{\H U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\cedilla T}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\'r}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\u a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\'l}
+ \gdef^^e6{\'c}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\v c}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\ogonek{e}}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\v e}
+ \gdef^^ed{\'{\dotless{i}}}
+ \gdef^^ee{\^{\dotless{i}}}
+ \gdef^^ef{\v d}
+ %
+ \gdef^^f0{\dh}
+ \gdef^^f1{\'n}
+ \gdef^^f2{\v n}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\H o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\v r}
+ \gdef^^f9{\ringaccent u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\H u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\cedilla t}
+ \gdef^^ff{\dotaccent{}}
+}
+
+% UTF-8 character definitions.
+%
+% This code to support UTF-8 is based on LaTeX's utf8.def, with some
+% changes for Texinfo conventions. It is included here under the GPL by
+% permission from Frank Mittelbach and the LaTeX team.
+%
+\newcount\countUTFx
+\newcount\countUTFy
+\newcount\countUTFz
+
+\gdef\UTFviiiTwoOctets#1#2{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\endcsname}
+%
+\gdef\UTFviiiThreeOctets#1#2#3{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
+%
+\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
+
+\gdef\UTFviiiDefined#1{%
+ \ifx #1\relax
+ \message{\linenumber Unicode char \string #1 not defined for Texinfo}%
+ \else
+ \expandafter #1%
+ \fi
+}
+
+\begingroup
+ \catcode`\~13
+ \catcode`\"12
+
+ \def\UTFviiiLoop{%
+ \global\catcode\countUTFx\active
+ \uccode`\~\countUTFx
+ \uppercase\expandafter{\UTFviiiTmp}%
+ \advance\countUTFx by 1
+ \ifnum\countUTFx < \countUTFy
+ \expandafter\UTFviiiLoop
+ \fi}
+
+ \countUTFx = "C2
+ \countUTFy = "E0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "E0
+ \countUTFy = "F0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "F0
+ \countUTFy = "F4
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiFourOctets\string~}}
+ \UTFviiiLoop
+\endgroup
+
+\begingroup
+ \catcode`\"=12
+ \catcode`\<=12
+ \catcode`\.=12
+ \catcode`\,=12
+ \catcode`\;=12
+ \catcode`\!=12
+ \catcode`\~=13
+
+ \gdef\DeclareUnicodeCharacter#1#2{%
+ \countUTFz = "#1\relax
+ %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
+ \begingroup
+ \parseXMLCharref
+ \def\UTFviiiTwoOctets##1##2{%
+ \csname u8:##1\string ##2\endcsname}%
+ \def\UTFviiiThreeOctets##1##2##3{%
+ \csname u8:##1\string ##2\string ##3\endcsname}%
+ \def\UTFviiiFourOctets##1##2##3##4{%
+ \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
+ \expandafter\expandafter\expandafter\expandafter
+ \expandafter\expandafter\expandafter
+ \gdef\UTFviiiTmp{#2}%
+ \endgroup}
+
+ \gdef\parseXMLCharref{%
+ \ifnum\countUTFz < "A0\relax
+ \errhelp = \EMsimple
+ \errmessage{Cannot define Unicode char value < 00A0}%
+ \else\ifnum\countUTFz < "800\relax
+ \parseUTFviiiA,%
+ \parseUTFviiiB C\UTFviiiTwoOctets.,%
+ \else\ifnum\countUTFz < "10000\relax
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
+ \else
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiA!%
+ \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
+ \fi\fi\fi
+ }
+
+ \gdef\parseUTFviiiA#1{%
+ \countUTFx = \countUTFz
+ \divide\countUTFz by 64
+ \countUTFy = \countUTFz
+ \multiply\countUTFz by 64
+ \advance\countUTFx by -\countUTFz
+ \advance\countUTFx by 128
+ \uccode `#1\countUTFx
+ \countUTFz = \countUTFy}
+
+ \gdef\parseUTFviiiB#1#2#3#4{%
+ \advance\countUTFz by "#10\relax
+ \uccode `#3\countUTFz
+ \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
+\endgroup
+
+\def\utfeightchardefs{%
+ \DeclareUnicodeCharacter{00A0}{\tie}
+ \DeclareUnicodeCharacter{00A1}{\exclamdown}
+ \DeclareUnicodeCharacter{00A3}{\pounds}
+ \DeclareUnicodeCharacter{00A8}{\"{ }}
+ \DeclareUnicodeCharacter{00A9}{\copyright}
+ \DeclareUnicodeCharacter{00AA}{\ordf}
+ \DeclareUnicodeCharacter{00AB}{\guillemetleft}
+ \DeclareUnicodeCharacter{00AD}{\-}
+ \DeclareUnicodeCharacter{00AE}{\registeredsymbol}
+ \DeclareUnicodeCharacter{00AF}{\={ }}
+
+ \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}
+ \DeclareUnicodeCharacter{00B4}{\'{ }}
+ \DeclareUnicodeCharacter{00B8}{\cedilla{ }}
+ \DeclareUnicodeCharacter{00BA}{\ordm}
+ \DeclareUnicodeCharacter{00BB}{\guillemetright}
+ \DeclareUnicodeCharacter{00BF}{\questiondown}
+
+ \DeclareUnicodeCharacter{00C0}{\`A}
+ \DeclareUnicodeCharacter{00C1}{\'A}
+ \DeclareUnicodeCharacter{00C2}{\^A}
+ \DeclareUnicodeCharacter{00C3}{\~A}
+ \DeclareUnicodeCharacter{00C4}{\"A}
+ \DeclareUnicodeCharacter{00C5}{\AA}
+ \DeclareUnicodeCharacter{00C6}{\AE}
+ \DeclareUnicodeCharacter{00C7}{\cedilla{C}}
+ \DeclareUnicodeCharacter{00C8}{\`E}
+ \DeclareUnicodeCharacter{00C9}{\'E}
+ \DeclareUnicodeCharacter{00CA}{\^E}
+ \DeclareUnicodeCharacter{00CB}{\"E}
+ \DeclareUnicodeCharacter{00CC}{\`I}
+ \DeclareUnicodeCharacter{00CD}{\'I}
+ \DeclareUnicodeCharacter{00CE}{\^I}
+ \DeclareUnicodeCharacter{00CF}{\"I}
+
+ \DeclareUnicodeCharacter{00D0}{\DH}
+ \DeclareUnicodeCharacter{00D1}{\~N}
+ \DeclareUnicodeCharacter{00D2}{\`O}
+ \DeclareUnicodeCharacter{00D3}{\'O}
+ \DeclareUnicodeCharacter{00D4}{\^O}
+ \DeclareUnicodeCharacter{00D5}{\~O}
+ \DeclareUnicodeCharacter{00D6}{\"O}
+ \DeclareUnicodeCharacter{00D8}{\O}
+ \DeclareUnicodeCharacter{00D9}{\`U}
+ \DeclareUnicodeCharacter{00DA}{\'U}
+ \DeclareUnicodeCharacter{00DB}{\^U}
+ \DeclareUnicodeCharacter{00DC}{\"U}
+ \DeclareUnicodeCharacter{00DD}{\'Y}
+ \DeclareUnicodeCharacter{00DE}{\TH}
+ \DeclareUnicodeCharacter{00DF}{\ss}
+
+ \DeclareUnicodeCharacter{00E0}{\`a}
+ \DeclareUnicodeCharacter{00E1}{\'a}
+ \DeclareUnicodeCharacter{00E2}{\^a}
+ \DeclareUnicodeCharacter{00E3}{\~a}
+ \DeclareUnicodeCharacter{00E4}{\"a}
+ \DeclareUnicodeCharacter{00E5}{\aa}
+ \DeclareUnicodeCharacter{00E6}{\ae}
+ \DeclareUnicodeCharacter{00E7}{\cedilla{c}}
+ \DeclareUnicodeCharacter{00E8}{\`e}
+ \DeclareUnicodeCharacter{00E9}{\'e}
+ \DeclareUnicodeCharacter{00EA}{\^e}
+ \DeclareUnicodeCharacter{00EB}{\"e}
+ \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}
+ \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{00F0}{\dh}
+ \DeclareUnicodeCharacter{00F1}{\~n}
+ \DeclareUnicodeCharacter{00F2}{\`o}
+ \DeclareUnicodeCharacter{00F3}{\'o}
+ \DeclareUnicodeCharacter{00F4}{\^o}
+ \DeclareUnicodeCharacter{00F5}{\~o}
+ \DeclareUnicodeCharacter{00F6}{\"o}
+ \DeclareUnicodeCharacter{00F8}{\o}
+ \DeclareUnicodeCharacter{00F9}{\`u}
+ \DeclareUnicodeCharacter{00FA}{\'u}
+ \DeclareUnicodeCharacter{00FB}{\^u}
+ \DeclareUnicodeCharacter{00FC}{\"u}
+ \DeclareUnicodeCharacter{00FD}{\'y}
+ \DeclareUnicodeCharacter{00FE}{\th}
+ \DeclareUnicodeCharacter{00FF}{\"y}
+
+ \DeclareUnicodeCharacter{0100}{\=A}
+ \DeclareUnicodeCharacter{0101}{\=a}
+ \DeclareUnicodeCharacter{0102}{\u{A}}
+ \DeclareUnicodeCharacter{0103}{\u{a}}
+ \DeclareUnicodeCharacter{0104}{\ogonek{A}}
+ \DeclareUnicodeCharacter{0105}{\ogonek{a}}
+ \DeclareUnicodeCharacter{0106}{\'C}
+ \DeclareUnicodeCharacter{0107}{\'c}
+ \DeclareUnicodeCharacter{0108}{\^C}
+ \DeclareUnicodeCharacter{0109}{\^c}
+ \DeclareUnicodeCharacter{0118}{\ogonek{E}}
+ \DeclareUnicodeCharacter{0119}{\ogonek{e}}
+ \DeclareUnicodeCharacter{010A}{\dotaccent{C}}
+ \DeclareUnicodeCharacter{010B}{\dotaccent{c}}
+ \DeclareUnicodeCharacter{010C}{\v{C}}
+ \DeclareUnicodeCharacter{010D}{\v{c}}
+ \DeclareUnicodeCharacter{010E}{\v{D}}
+
+ \DeclareUnicodeCharacter{0112}{\=E}
+ \DeclareUnicodeCharacter{0113}{\=e}
+ \DeclareUnicodeCharacter{0114}{\u{E}}
+ \DeclareUnicodeCharacter{0115}{\u{e}}
+ \DeclareUnicodeCharacter{0116}{\dotaccent{E}}
+ \DeclareUnicodeCharacter{0117}{\dotaccent{e}}
+ \DeclareUnicodeCharacter{011A}{\v{E}}
+ \DeclareUnicodeCharacter{011B}{\v{e}}
+ \DeclareUnicodeCharacter{011C}{\^G}
+ \DeclareUnicodeCharacter{011D}{\^g}
+ \DeclareUnicodeCharacter{011E}{\u{G}}
+ \DeclareUnicodeCharacter{011F}{\u{g}}
+
+ \DeclareUnicodeCharacter{0120}{\dotaccent{G}}
+ \DeclareUnicodeCharacter{0121}{\dotaccent{g}}
+ \DeclareUnicodeCharacter{0124}{\^H}
+ \DeclareUnicodeCharacter{0125}{\^h}
+ \DeclareUnicodeCharacter{0128}{\~I}
+ \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}
+ \DeclareUnicodeCharacter{012A}{\=I}
+ \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}
+ \DeclareUnicodeCharacter{012C}{\u{I}}
+ \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{0130}{\dotaccent{I}}
+ \DeclareUnicodeCharacter{0131}{\dotless{i}}
+ \DeclareUnicodeCharacter{0132}{IJ}
+ \DeclareUnicodeCharacter{0133}{ij}
+ \DeclareUnicodeCharacter{0134}{\^J}
+ \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}
+ \DeclareUnicodeCharacter{0139}{\'L}
+ \DeclareUnicodeCharacter{013A}{\'l}
+
+ \DeclareUnicodeCharacter{0141}{\L}
+ \DeclareUnicodeCharacter{0142}{\l}
+ \DeclareUnicodeCharacter{0143}{\'N}
+ \DeclareUnicodeCharacter{0144}{\'n}
+ \DeclareUnicodeCharacter{0147}{\v{N}}
+ \DeclareUnicodeCharacter{0148}{\v{n}}
+ \DeclareUnicodeCharacter{014C}{\=O}
+ \DeclareUnicodeCharacter{014D}{\=o}
+ \DeclareUnicodeCharacter{014E}{\u{O}}
+ \DeclareUnicodeCharacter{014F}{\u{o}}
+
+ \DeclareUnicodeCharacter{0150}{\H{O}}
+ \DeclareUnicodeCharacter{0151}{\H{o}}
+ \DeclareUnicodeCharacter{0152}{\OE}
+ \DeclareUnicodeCharacter{0153}{\oe}
+ \DeclareUnicodeCharacter{0154}{\'R}
+ \DeclareUnicodeCharacter{0155}{\'r}
+ \DeclareUnicodeCharacter{0158}{\v{R}}
+ \DeclareUnicodeCharacter{0159}{\v{r}}
+ \DeclareUnicodeCharacter{015A}{\'S}
+ \DeclareUnicodeCharacter{015B}{\'s}
+ \DeclareUnicodeCharacter{015C}{\^S}
+ \DeclareUnicodeCharacter{015D}{\^s}
+ \DeclareUnicodeCharacter{015E}{\cedilla{S}}
+ \DeclareUnicodeCharacter{015F}{\cedilla{s}}
+
+ \DeclareUnicodeCharacter{0160}{\v{S}}
+ \DeclareUnicodeCharacter{0161}{\v{s}}
+ \DeclareUnicodeCharacter{0162}{\cedilla{t}}
+ \DeclareUnicodeCharacter{0163}{\cedilla{T}}
+ \DeclareUnicodeCharacter{0164}{\v{T}}
+
+ \DeclareUnicodeCharacter{0168}{\~U}
+ \DeclareUnicodeCharacter{0169}{\~u}
+ \DeclareUnicodeCharacter{016A}{\=U}
+ \DeclareUnicodeCharacter{016B}{\=u}
+ \DeclareUnicodeCharacter{016C}{\u{U}}
+ \DeclareUnicodeCharacter{016D}{\u{u}}
+ \DeclareUnicodeCharacter{016E}{\ringaccent{U}}
+ \DeclareUnicodeCharacter{016F}{\ringaccent{u}}
+
+ \DeclareUnicodeCharacter{0170}{\H{U}}
+ \DeclareUnicodeCharacter{0171}{\H{u}}
+ \DeclareUnicodeCharacter{0174}{\^W}
+ \DeclareUnicodeCharacter{0175}{\^w}
+ \DeclareUnicodeCharacter{0176}{\^Y}
+ \DeclareUnicodeCharacter{0177}{\^y}
+ \DeclareUnicodeCharacter{0178}{\"Y}
+ \DeclareUnicodeCharacter{0179}{\'Z}
+ \DeclareUnicodeCharacter{017A}{\'z}
+ \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}
+ \DeclareUnicodeCharacter{017C}{\dotaccent{z}}
+ \DeclareUnicodeCharacter{017D}{\v{Z}}
+ \DeclareUnicodeCharacter{017E}{\v{z}}
+
+ \DeclareUnicodeCharacter{01C4}{D\v{Z}}
+ \DeclareUnicodeCharacter{01C5}{D\v{z}}
+ \DeclareUnicodeCharacter{01C6}{d\v{z}}
+ \DeclareUnicodeCharacter{01C7}{LJ}
+ \DeclareUnicodeCharacter{01C8}{Lj}
+ \DeclareUnicodeCharacter{01C9}{lj}
+ \DeclareUnicodeCharacter{01CA}{NJ}
+ \DeclareUnicodeCharacter{01CB}{Nj}
+ \DeclareUnicodeCharacter{01CC}{nj}
+ \DeclareUnicodeCharacter{01CD}{\v{A}}
+ \DeclareUnicodeCharacter{01CE}{\v{a}}
+ \DeclareUnicodeCharacter{01CF}{\v{I}}
+
+ \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}
+ \DeclareUnicodeCharacter{01D1}{\v{O}}
+ \DeclareUnicodeCharacter{01D2}{\v{o}}
+ \DeclareUnicodeCharacter{01D3}{\v{U}}
+ \DeclareUnicodeCharacter{01D4}{\v{u}}
+
+ \DeclareUnicodeCharacter{01E2}{\={\AE}}
+ \DeclareUnicodeCharacter{01E3}{\={\ae}}
+ \DeclareUnicodeCharacter{01E6}{\v{G}}
+ \DeclareUnicodeCharacter{01E7}{\v{g}}
+ \DeclareUnicodeCharacter{01E8}{\v{K}}
+ \DeclareUnicodeCharacter{01E9}{\v{k}}
+
+ \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}
+ \DeclareUnicodeCharacter{01F1}{DZ}
+ \DeclareUnicodeCharacter{01F2}{Dz}
+ \DeclareUnicodeCharacter{01F3}{dz}
+ \DeclareUnicodeCharacter{01F4}{\'G}
+ \DeclareUnicodeCharacter{01F5}{\'g}
+ \DeclareUnicodeCharacter{01F8}{\`N}
+ \DeclareUnicodeCharacter{01F9}{\`n}
+ \DeclareUnicodeCharacter{01FC}{\'{\AE}}
+ \DeclareUnicodeCharacter{01FD}{\'{\ae}}
+ \DeclareUnicodeCharacter{01FE}{\'{\O}}
+ \DeclareUnicodeCharacter{01FF}{\'{\o}}
+
+ \DeclareUnicodeCharacter{021E}{\v{H}}
+ \DeclareUnicodeCharacter{021F}{\v{h}}
+
+ \DeclareUnicodeCharacter{0226}{\dotaccent{A}}
+ \DeclareUnicodeCharacter{0227}{\dotaccent{a}}
+ \DeclareUnicodeCharacter{0228}{\cedilla{E}}
+ \DeclareUnicodeCharacter{0229}{\cedilla{e}}
+ \DeclareUnicodeCharacter{022E}{\dotaccent{O}}
+ \DeclareUnicodeCharacter{022F}{\dotaccent{o}}
+
+ \DeclareUnicodeCharacter{0232}{\=Y}
+ \DeclareUnicodeCharacter{0233}{\=y}
+ \DeclareUnicodeCharacter{0237}{\dotless{j}}
+
+ \DeclareUnicodeCharacter{02DB}{\ogonek{ }}
+
+ \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
+ \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
+ \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
+ \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}
+ \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}
+ \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}
+ \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}
+ \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}
+ \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}
+ \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}
+ \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}
+ \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}
+
+ \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}
+ \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}
+
+ \DeclareUnicodeCharacter{1E20}{\=G}
+ \DeclareUnicodeCharacter{1E21}{\=g}
+ \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}
+ \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}
+ \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}
+ \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}
+ \DeclareUnicodeCharacter{1E26}{\"H}
+ \DeclareUnicodeCharacter{1E27}{\"h}
+
+ \DeclareUnicodeCharacter{1E30}{\'K}
+ \DeclareUnicodeCharacter{1E31}{\'k}
+ \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}
+ \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}
+ \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}
+ \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}
+ \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}
+ \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}
+ \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}
+ \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}
+ \DeclareUnicodeCharacter{1E3E}{\'M}
+ \DeclareUnicodeCharacter{1E3F}{\'m}
+
+ \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}
+ \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}
+ \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}
+ \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}
+ \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}
+ \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}
+ \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}
+ \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}
+ \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}
+ \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}
+
+ \DeclareUnicodeCharacter{1E54}{\'P}
+ \DeclareUnicodeCharacter{1E55}{\'p}
+ \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}
+ \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}
+ \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}
+ \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}
+ \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}
+ \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}
+ \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}
+ \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}
+
+ \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}
+ \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}
+ \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}
+ \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}
+ \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}
+ \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}
+ \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}
+ \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}
+ \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}
+ \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}
+
+ \DeclareUnicodeCharacter{1E7C}{\~V}
+ \DeclareUnicodeCharacter{1E7D}{\~v}
+ \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}
+ \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}
+
+ \DeclareUnicodeCharacter{1E80}{\`W}
+ \DeclareUnicodeCharacter{1E81}{\`w}
+ \DeclareUnicodeCharacter{1E82}{\'W}
+ \DeclareUnicodeCharacter{1E83}{\'w}
+ \DeclareUnicodeCharacter{1E84}{\"W}
+ \DeclareUnicodeCharacter{1E85}{\"w}
+ \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}
+ \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}
+ \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}
+ \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}
+ \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}
+ \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}
+ \DeclareUnicodeCharacter{1E8C}{\"X}
+ \DeclareUnicodeCharacter{1E8D}{\"x}
+ \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}
+ \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}
+
+ \DeclareUnicodeCharacter{1E90}{\^Z}
+ \DeclareUnicodeCharacter{1E91}{\^z}
+ \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}
+ \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}
+ \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}
+ \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}
+ \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}
+ \DeclareUnicodeCharacter{1E97}{\"t}
+ \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}
+ \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}
+
+ \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}
+ \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}
+
+ \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}
+ \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}
+ \DeclareUnicodeCharacter{1EBC}{\~E}
+ \DeclareUnicodeCharacter{1EBD}{\~e}
+
+ \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}
+ \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}
+ \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}
+ \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}
+
+ \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}
+ \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}
+
+ \DeclareUnicodeCharacter{1EF2}{\`Y}
+ \DeclareUnicodeCharacter{1EF3}{\`y}
+ \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}
+
+ \DeclareUnicodeCharacter{1EF8}{\~Y}
+ \DeclareUnicodeCharacter{1EF9}{\~y}
+
+ \DeclareUnicodeCharacter{2013}{--}
+ \DeclareUnicodeCharacter{2014}{---}
+ \DeclareUnicodeCharacter{2018}{\quoteleft}
+ \DeclareUnicodeCharacter{2019}{\quoteright}
+ \DeclareUnicodeCharacter{201A}{\quotesinglbase}
+ \DeclareUnicodeCharacter{201C}{\quotedblleft}
+ \DeclareUnicodeCharacter{201D}{\quotedblright}
+ \DeclareUnicodeCharacter{201E}{\quotedblbase}
+ \DeclareUnicodeCharacter{2022}{\bullet}
+ \DeclareUnicodeCharacter{2026}{\dots}
+ \DeclareUnicodeCharacter{2039}{\guilsinglleft}
+ \DeclareUnicodeCharacter{203A}{\guilsinglright}
+ \DeclareUnicodeCharacter{20AC}{\euro}
+
+ \DeclareUnicodeCharacter{2192}{\expansion}
+ \DeclareUnicodeCharacter{21D2}{\result}
+
+ \DeclareUnicodeCharacter{2212}{\minus}
+ \DeclareUnicodeCharacter{2217}{\point}
+ \DeclareUnicodeCharacter{2261}{\equiv}
+}% end of \utfeightchardefs
+
+
+% US-ASCII character definitions.
+\def\asciichardefs{% nothing need be done
+ \relax
+}
+
+% Make non-ASCII characters printable again for compatibility with
+% existing Texinfo documents that may use them, even without declaring a
+% document encoding.
+%
+\setnonasciicharscatcode \other
+
+
+\message{formatting,}
+
\newdimen\defaultparindent \defaultparindent = 15pt
\chapheadingskip = 15pt plus 4pt minus 2pt
@@ -6661,10 +9671,10 @@ should work if nowhere else does.}
% Prevent underfull vbox error messages.
\vbadness = 10000
-% Don't be so finicky about underfull hboxes, either.
-\hbadness = 2000
+% Don't be very finicky about underfull hboxes, either.
+\hbadness = 6666
-% Following George Bush, just get rid of widows and orphans.
+% Following George Bush, get rid of widows and orphans.
\widowpenalty=10000
\clubpenalty=10000
@@ -6682,9 +9692,9 @@ should work if nowhere else does.}
\fi
}
-% Parameters in order: 1) textheight; 2) textwidth; 3) voffset;
-% 4) hoffset; 5) binding offset; 6) topskip; 7) physical page height; 8)
-% physical page width.
+% Parameters in order: 1) textheight; 2) textwidth;
+% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip;
+% 7) physical page height; 8) physical page width.
%
% We also call \setleading{\textleading}, so the caller should define
% \textleading. The caller should also set \parskip.
@@ -6711,6 +9721,10 @@ should work if nowhere else does.}
\ifpdf
\pdfpageheight #7\relax
\pdfpagewidth #8\relax
+ % if we don't reset these, they will remain at "1 true in" of
+ % whatever layout pdftex was dumped with.
+ \pdfhorigin = 1 true in
+ \pdfvorigin = 1 true in
\fi
%
\setleading{\textleading}
@@ -6725,19 +9739,19 @@ should work if nowhere else does.}
\textleading = 13.2pt
%
% If page is nothing but text, make it come out even.
- \internalpagesizes{46\baselineskip}{6in}%
+ \internalpagesizes{607.2pt}{6in}% that's 46 lines
{\voffset}{.25in}%
{\bindingoffset}{36pt}%
{11in}{8.5in}%
}}
-% Use @smallbook to reset parameters for 7x9.5 (or so) format.
+% Use @smallbook to reset parameters for 7x9.25 trim size.
\def\smallbook{{\globaldefs = 1
\parskip = 2pt plus 1pt
\textleading = 12pt
%
\internalpagesizes{7.5in}{5in}%
- {\voffset}{.25in}%
+ {-.2in}{0in}%
{\bindingoffset}{16pt}%
{9.25in}{7in}%
%
@@ -6748,6 +9762,24 @@ should work if nowhere else does.}
\defbodyindent = .5cm
}}
+% Use @smallerbook to reset parameters for 6x9 trim size.
+% (Just testing, parameters still in flux.)
+\def\smallerbook{{\globaldefs = 1
+ \parskip = 1.5pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.4in}{4.8in}%
+ {-.2in}{-.4in}%
+ {0pt}{14pt}%
+ {9in}{6in}%
+ %
+ \lispnarrowing = 0.25in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .4cm
+}}
+
% Use @afourpaper to print on European A4 paper.
\def\afourpaper{{\globaldefs = 1
\parskip = 3pt plus 2pt minus 1pt
@@ -6763,7 +9795,7 @@ should work if nowhere else does.}
% \global\normaloffset = -6mm
% \global\bindingoffset = 10mm
% @end tex
- \internalpagesizes{51\baselineskip}{160mm}
+ \internalpagesizes{673.2pt}{160mm}% that's 51 lines
{\voffset}{\hoffset}%
{\bindingoffset}{44pt}%
{297mm}{210mm}%
@@ -6828,7 +9860,7 @@ should work if nowhere else does.}
\parskip = 3pt plus 2pt minus 1pt
\setleading{\textleading}%
%
- \dimen0 = #1
+ \dimen0 = #1\relax
\advance\dimen0 by \voffset
%
\dimen2 = \hsize
@@ -6847,25 +9879,21 @@ should work if nowhere else does.}
\message{and turning on texinfo input format.}
+\def^^L{\par} % remove \outer, so ^L can appear in an @comment
+
+% DEL is a comment character, in case @c does not suffice.
+\catcode`\^^? = 14
+
% Define macros to output various characters with catcode for normal text.
-\catcode`\"=\other
-\catcode`\~=\other
-\catcode`\^=\other
-\catcode`\_=\other
-\catcode`\|=\other
-\catcode`\<=\other
-\catcode`\>=\other
-\catcode`\+=\other
-\catcode`\$=\other
-\def\normaldoublequote{"}
-\def\normaltilde{~}
-\def\normalcaret{^}
-\def\normalunderscore{_}
-\def\normalverticalbar{|}
-\def\normalless{<}
-\def\normalgreater{>}
-\def\normalplus{+}
-\def\normaldollar{$}%$ font-lock fix
+\catcode`\"=\other \def\normaldoublequote{"}
+\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix
+\catcode`\+=\other \def\normalplus{+}
+\catcode`\<=\other \def\normalless{<}
+\catcode`\>=\other \def\normalgreater{>}
+\catcode`\^=\other \def\normalcaret{^}
+\catcode`\_=\other \def\normalunderscore{_}
+\catcode`\|=\other \def\normalverticalbar{|}
+\catcode`\~=\other \def\normaltilde{~}
% This macro is used to make a character print one way in \tt
% (where it can probably be output as-is), and another way in other fonts,
@@ -6900,6 +9928,7 @@ should work if nowhere else does.}
\catcode`\_=\active
\def_{\ifusingtt\normalunderscore\_}
+\let\realunder=_
% Subroutine for the previous macro.
\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
@@ -6922,6 +9951,13 @@ should work if nowhere else does.}
% \otherifyactive is called near the end of this file.
\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+% Used sometimes to turn off (effectively) the active characters even after
+% parsing them.
+\def\turnoffactive{%
+ \normalturnoffactive
+ \otherbackslash
+}
+
\catcode`\@=0
% \backslashcurfont outputs one backslash character in current font,
@@ -6929,43 +9965,55 @@ should work if nowhere else does.}
\global\chardef\backslashcurfont=`\\
\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work
+% \realbackslash is an actual character `\' with catcode other, and
+% \doublebackslash is two of them (for the pdf outlines).
+{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}}
+
+% In texinfo, backslash is an active character; it prints the backslash
+% in fixed width font.
+\catcode`\\=\active % @ for escape char from now on.
+
+% The story here is that in math mode, the \char of \backslashcurfont
+% ends up printing the roman \ from the math symbol font (because \char
+% in math mode uses the \mathcode, and plain.tex sets
+% \mathcode`\\="026E). It seems better for @backslashchar{} to always
+% print a typewriter backslash, hence we use an explicit \mathchar,
+% which is the decimal equivalent of "715c (class 7, e.g., use \fam;
+% ignored family value; char position "5C). We can't use " for the
+% usual hex value because it has already been made active.
+@def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}}
+@let@backslashchar = @normalbackslash % @backslashchar{} is for user documents.
+
+% On startup, @fixbackslash assigns:
+% @let \ = @normalbackslash
% \rawbackslash defines an active \ to do \backslashcurfont.
% \otherbackslash defines an active \ to be a literal `\' character with
-% catcode other.
-{\catcode`\\=\active
- @gdef@rawbackslash{@let\=@backslashcurfont}
- @gdef@otherbackslash{@let\=@realbackslash}
-}
-
-% \realbackslash is an actual character `\' with catcode other.
-{\catcode`\\=\other @gdef@realbackslash{\}}
-
-% \normalbackslash outputs one backslash in fixed width font.
-\def\normalbackslash{{\tt\backslashcurfont}}
-
-\catcode`\\=\active
-
-% Used sometimes to turn off (effectively) the active characters
-% even after parsing them.
-@def@turnoffactive{%
- @let"=@normaldoublequote
- @let\=@realbackslash
- @let~=@normaltilde
- @let^=@normalcaret
- @let_=@normalunderscore
- @let|=@normalverticalbar
- @let<=@normalless
- @let>=@normalgreater
- @let+=@normalplus
- @let$=@normaldollar %$ font-lock fix
- @unsepspaces
-}
+% catcode other. We switch back and forth between these.
+@gdef@rawbackslash{@let\=@backslashcurfont}
+@gdef@otherbackslash{@let\=@realbackslash}
% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
-% the literal character `\'. (Thus, \ is not expandable when this is in
-% effect.)
-%
-@def@normalturnoffactive{@turnoffactive @let\=@normalbackslash}
+% the literal character `\'. Also revert - to its normal character, in
+% case the active - from code has slipped in.
+%
+{@catcode`- = @active
+ @gdef@normalturnoffactive{%
+ @let-=@normaldash
+ @let"=@normaldoublequote
+ @let$=@normaldollar %$ font-lock fix
+ @let+=@normalplus
+ @let<=@normalless
+ @let>=@normalgreater
+ @let\=@normalbackslash
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let~=@normaltilde
+ @markupsetuplqdefault
+ @markupsetuprqdefault
+ @unsepspaces
+ }
+}
% Make _ and + \other characters, temporarily.
% This is canceled by @fixbackslash.
@@ -6979,9 +10027,9 @@ should work if nowhere else does.}
@global@let\ = @eatinput
% On the other hand, perhaps the file did not have a `\input texinfo'. Then
-% the first `\{ in the file would cause an error. This macro tries to fix
+% the first `\' in the file would cause an error. This macro tries to fix
% that, assuming it is called before the first `\' could plausibly occur.
-% Also back turn on active characters that might appear in the input
+% Also turn back on active characters that might appear in the input
% file name, in case not using a pre-dumped format.
%
@gdef@fixbackslash{%
@@ -6993,11 +10041,28 @@ should work if nowhere else does.}
% Say @foo, not \foo, in error messages.
@escapechar = `@@
-% These look ok in all fonts, so just make them not special.
-@catcode`@& = @other
-@catcode`@# = @other
-@catcode`@% = @other
+% These (along with & and #) are made active for url-breaking, so need
+% active definitions as the normal characters.
+@def@normaldot{.}
+@def@normalquest{?}
+@def@normalslash{/}
+% These look ok in all fonts, so just make them not special.
+% @hashchar{} gets its own user-level command, because of #line.
+@catcode`@& = @other @def@normalamp{&}
+@catcode`@# = @other @def@normalhash{#}
+@catcode`@% = @other @def@normalpercent{%}
+
+@let @hashchar = @normalhash
+
+@c Finally, make ` and ' active, so that txicodequoteundirected and
+@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we
+@c don't make ` and ' active, @code will not get them as active chars.
+@c Do this last of all since we use ` in the previous @catcode assignments.
+@catcode`@'=@active
+@catcode`@`=@active
+@markupsetuplqdefault
+@markupsetuprqdefault
@c Local variables:
@c eval: (add-hook 'write-file-hooks 'time-stamp)
diff --git a/contrib/amd/doc/version.texi b/contrib/amd/doc/version.texi
index 41b19a30d5c6..9a4feda60f57 100644
--- a/contrib/amd/doc/version.texi
+++ b/contrib/amd/doc/version.texi
@@ -1,4 +1,4 @@
-@set UPDATED 20 April 2006
-@set UPDATED-MONTH April 2006
-@set EDITION 6.1.5
-@set VERSION 6.1.5
+@set UPDATED 28 October 2014
+@set UPDATED-MONTH October 2014
+@set EDITION 6.2
+@set VERSION 6.2
diff --git a/contrib/amd/fixmount/fixmount.8 b/contrib/amd/fixmount/fixmount.8
index 03673e90661a..462984cbe442 100644
--- a/contrib/amd/fixmount/fixmount.8
+++ b/contrib/amd/fixmount/fixmount.8
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 1997-2006 Erez Zadok
+.\" 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.
@@ -16,11 +16,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 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.
.\"
@@ -36,9 +32,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" %W% (Berkeley) %G%
.\"
-.\" $Id: fixmount.8,v 1.12.2.1 2006/01/02 18:48:25 ezk Exp $
+.\" File: am-utils/fixmount/fixmount.8
.\" $FreeBSD$
.\"
.Dd February 26, 2016
diff --git a/contrib/amd/fixmount/fixmount.c b/contrib/amd/fixmount/fixmount.c
index c7c69102a55b..9465f30d7584 100644
--- a/contrib/amd/fixmount/fixmount.c
+++ b/contrib/amd/fixmount/fixmount.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -115,7 +111,7 @@ is_same_host(char *name1, char *name2, struct in_addr addr2)
} else if (!(he = gethostbyname(name1))) {
return 0;
} else {
- xstrlcpy(lasthost, name1, MAXHOSTNAMELEN);
+ xstrlcpy(lasthost, name1, sizeof(lasthost));
memcpy(&addr1, he->h_addr, sizeof(addr1));
return (addr1.s_addr == addr2.s_addr);
}
@@ -176,7 +172,7 @@ remove_mount(CLIENT *client, char *host, mountlist ml, int fixit)
(XDRPROC_T_TYPE) xdr_dirpath,
(char *) &pathp,
(XDRPROC_T_TYPE) xdr_void,
- (char *) 0,
+ (char *) NULL,
tv)) != RPC_SUCCESS) {
fprintf(stderr, "%s:%s MOUNTPROC_UMNT: ",
host, ml->ml_directory);
@@ -235,9 +231,9 @@ remove_all(CLIENT *client, char *host)
if ((estat = clnt_call(client,
MOUNTPROC_UMNTALL,
(XDRPROC_T_TYPE) xdr_void,
- (char *) 0,
+ (char *) NULL,
(XDRPROC_T_TYPE) xdr_void,
- (char *) 0,
+ (char *) NULL,
tv)) != RPC_SUCCESS) {
/*
* RPC_SYSTEMERROR is returned even if all went well
@@ -389,7 +385,7 @@ main(int argc, char *argv[])
if ((estat = clnt_call(client,
MOUNTPROC_DUMP,
(XDRPROC_T_TYPE) xdr_void,
- (char *) 0,
+ (char *) NULL,
(XDRPROC_T_TYPE) xdr_mountlist,
(char *) &mntdump,
tv)) != RPC_SUCCESS) {
@@ -403,7 +399,7 @@ main(int argc, char *argv[])
if ((estat = clnt_call(client,
MOUNTPROC_EXPORT,
(XDRPROC_T_TYPE) xdr_void,
- (char *) 0,
+ (char *) NULL,
(XDRPROC_T_TYPE) xdr_exports,
(char *) &mntexports,
tv)) != RPC_SUCCESS) {
diff --git a/contrib/amd/fsinfo/fsi_analyze.c b/contrib/amd/fsinfo/fsi_analyze.c
index 9da40978e621..78598b854647 100644
--- a/contrib/amd/fsinfo/fsi_analyze.c
+++ b/contrib/amd/fsinfo/fsi_analyze.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -56,27 +52,27 @@
char *disk_fs_strings[] =
{
- "fstype", "opts", "dumpset", "passno", "freq", "mount", "log", 0,
+ "fstype", "opts", "dumpset", "passno", "freq", "mount", "log", NULL,
};
char *mount_strings[] =
{
- "volname", "exportfs", 0,
+ "volname", "exportfs", NULL,
};
char *fsmount_strings[] =
{
- "as", "volname", "fstype", "opts", "from", 0,
+ "as", "volname", "fstype", "opts", "from", NULL,
};
char *host_strings[] =
{
- "host", "netif", "config", "arch", "cluster", "os", 0,
+ "host", "netif", "config", "arch", "cluster", "os", NULL,
};
char *ether_if_strings[] =
{
- "inaddr", "netmask", "hwaddr", 0,
+ "inaddr", "netmask", "hwaddr", NULL,
};
@@ -122,7 +118,7 @@ compute_hostpath(char *hn)
do {
d = strrchr(p, '.');
if (d) {
- *d = 0;
+ *d = '\0';
xstrlcat(path, d + 1, sizeof(path));
xstrlcat(path, "/", sizeof(path));
} else {
@@ -141,7 +137,7 @@ static dict_ent *
find_volname(char *nn)
{
dict_ent *de;
- char *p = strdup(nn);
+ char *p = xstrdup(nn);
char *q;
do {
@@ -186,7 +182,7 @@ check_exportfs(qelem *q, fsi_mount *e)
lwarning(mp->m_ioloc, "%s has duplicate exportfs data", mp->m_name);
mp->m_exported = mp;
if (!ISSET(mp->m_mask, DM_VOLNAME))
- set_mount(mp, DM_VOLNAME, strdup(mp->m_name));
+ set_mount(mp, DM_VOLNAME, xstrdup(mp->m_name));
} else {
mp->m_exported = e;
}
@@ -228,7 +224,7 @@ analyze_dkmount_tree(qelem *q, fsi_mount *parent, disk_fs *dk)
lwarning(mp->m_ioloc, "sub-directory of %s is named \"default\"", parent->m_name);
fsi_log("Changing name %s to %s", mp->m_name, n);
XFREE(mp->m_name);
- mp->m_name = strdup(n);
+ mp->m_name = xstrdup(n);
}
mp->m_name_len = strlen(mp->m_name);
@@ -251,7 +247,7 @@ static int
analyze_dkmounts(disk_fs *dk, qelem *q)
{
int errors = 0;
- fsi_mount *mp, *mp2 = 0;
+ fsi_mount *mp, *mp2 = NULL;
int i = 0;
/*
@@ -286,7 +282,7 @@ analyze_dkmounts(disk_fs *dk, qelem *q)
char nbuf[1024];
compute_automount_point(nbuf, sizeof(nbuf), dk->d_host, mp2->m_volname);
XFREE(mp2->m_name);
- mp2->m_name = strdup(nbuf);
+ mp2->m_name = xstrdup(nbuf);
fsi_log("%s:%s has default mount on %s", dk->d_host->h_hostname, dk->d_dev, mp2->m_name);
} else {
lerror(dk->d_ioloc, "no volname given for %s:%s", dk->d_host->h_hostname, dk->d_dev);
@@ -298,19 +294,19 @@ analyze_dkmounts(disk_fs *dk, qelem *q)
* Fill in the disk mount point
*/
if (!errors && mp2 && mp2->m_name)
- dk->d_mountpt = strdup(mp2->m_name);
+ dk->d_mountpt = xstrdup(mp2->m_name);
else
- dk->d_mountpt = strdup("error");
+ dk->d_mountpt = xstrdup("error");
/*
* Analyze the mount tree
*/
- errors += analyze_dkmount_tree(q, 0, dk);
+ errors += analyze_dkmount_tree(q, NULL, dk);
/*
* Analyze the export tree
*/
- errors += check_exportfs(q, 0);
+ errors += check_exportfs(q, NULL);
return errors;
}
@@ -353,7 +349,7 @@ fixup_required_disk_info(disk_fs *dp)
* "opts"
*/
if (!ISSET(dp->d_mask, DF_OPTS))
- set_disk_fs(dp, DF_OPTS, strdup("swap"));
+ set_disk_fs(dp, DF_OPTS, xstrdup("swap"));
/*
* "mount"
@@ -362,7 +358,7 @@ fixup_required_disk_info(disk_fs *dp)
qelem *q = new_que();
fsi_mount *m = new_mount();
- m->m_name = strdup("swap");
+ m->m_name = xstrdup("swap");
m->m_mount = new_que();
ins_que(&m->m_q, q->q_back);
dp->d_mount = q;
@@ -400,7 +396,7 @@ fixup_required_disk_info(disk_fs *dp)
* "opts"
*/
if (!ISSET(dp->d_mask, DF_OPTS))
- set_disk_fs(dp, DF_OPTS, strdup("rw,defaults"));
+ set_disk_fs(dp, DF_OPTS, xstrdup("rw,defaults"));
}
}
@@ -415,7 +411,7 @@ fixup_required_mount_info(fsmount *fp, dict_ent *de)
lerror(fp->f_ioloc, "ambiguous mount: %s is a replicated filesystem", fp->f_volname);
} else {
dict_data *dd;
- fsi_mount *mp = 0;
+ fsi_mount *mp = NULL;
dd = AM_FIRST(dict_data, &de->de_q);
mp = (fsi_mount *) dd->dd_data;
if (!mp)
@@ -427,18 +423,18 @@ fixup_required_mount_info(fsmount *fp, dict_ent *de)
}
if (!ISSET(fp->f_mask, FM_FSTYPE)) {
- set_fsmount(fp, FM_FSTYPE, strdup("nfs"));
+ set_fsmount(fp, FM_FSTYPE, xstrdup("nfs"));
fsi_log("set: fstype is %s", fp->f_fstype);
}
if (!ISSET(fp->f_mask, FM_OPTS)) {
- set_fsmount(fp, FM_OPTS, strdup("rw,nosuid,grpid,defaults"));
+ set_fsmount(fp, FM_OPTS, xstrdup("rw,nosuid,grpid,defaults"));
fsi_log("set: opts are %s", fp->f_opts);
}
if (!ISSET(fp->f_mask, FM_LOCALNAME)) {
if (fp->f_ref) {
- set_fsmount(fp, FM_LOCALNAME, strdup(fp->f_volname));
+ set_fsmount(fp, FM_LOCALNAME, xstrdup(fp->f_volname));
fsi_log("set: localname is %s", fp->f_localname);
} else {
lerror(fp->f_ioloc, "cannot determine localname since volname %s is not uniquely defined", fp->f_volname);
@@ -485,7 +481,7 @@ analyze_mounts(host *hp)
ITER(fp, fsmount, q) {
char *p;
- char *nn = strdup(fp->f_volname);
+ char *nn = xstrdup(fp->f_volname);
int req;
dict_ent *de = (dict_ent *) NULL;
int found = 0;
@@ -496,7 +492,7 @@ analyze_mounts(host *hp)
matched = 1;
} else
do {
- p = 0;
+ p = NULL;
de = find_volname(nn);
fsi_log("Mount: %s (trying %s)", fp->f_volname, nn);
@@ -511,7 +507,7 @@ analyze_mounts(host *hp)
*/
if (ISSET(fp->f_mask, FM_FROM) && !ISSET(fp->f_mask, FM_DIRECT)) {
dict_data *dd;
- fsi_mount *mp2 = 0;
+ fsi_mount *mp2 = NULL;
ITER(dd, dict_data, &de->de_q) {
fsi_mount *mp = (fsi_mount *) dd->dd_data;
@@ -535,7 +531,7 @@ analyze_mounts(host *hp)
}
p = strrchr(nn, '/');
if (p)
- *p = 0;
+ *p = '\0';
} while (de && p);
XFREE(nn);
@@ -635,7 +631,7 @@ analyze_automount_tree(qelem *q, char *pref, int lvl)
lerror(ap->a_ioloc, "not allowed '/' in a directory name");
xsnprintf(nname, sizeof(nname), "%s/%s", pref, ap->a_name);
XFREE(ap->a_name);
- ap->a_name = strdup(nname[1] == '/' ? nname + 1 : nname);
+ ap->a_name = xstrdup(nname[1] == '/' ? nname + 1 : nname);
fsi_log("automount point %s:", ap->a_name);
show_new("ana-automount");
@@ -649,7 +645,7 @@ analyze_automount_tree(qelem *q, char *pref, int lvl)
} else if (ap->a_symlink) {
fsi_log("\tsymlink to %s", ap->a_symlink);
} else {
- ap->a_volname = strdup(ap->a_name);
+ ap->a_volname = xstrdup(ap->a_name);
fsi_log("\timplicit automount from %s", ap->a_volname);
analyze_automount(ap);
}
diff --git a/contrib/amd/fsinfo/fsi_data.h b/contrib/amd/fsinfo/fsi_data.h
index 8276caf36cba..4cc341d85a69 100644
--- a/contrib/amd/fsinfo/fsi_data.h
+++ b/contrib/amd/fsinfo/fsi_data.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/fsinfo/fsi_dict.c b/contrib/amd/fsinfo/fsi_dict.c
index 29cd1a3ed08a..b909783b61eb 100644
--- a/contrib/amd/fsinfo/fsi_dict.c
+++ b/contrib/amd/fsinfo/fsi_dict.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/fsinfo/fsi_gram.y b/contrib/amd/fsinfo/fsi_gram.y
index 961a89f1af45..85d19aa5cdab 100644
--- a/contrib/amd/fsinfo/fsi_gram.y
+++ b/contrib/amd/fsinfo/fsi_gram.y
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -200,7 +196,7 @@ automount :
opt_auto_opts :
/* empty */
- { $$ = strdup(""); }
+ { $$ = xstrdup(""); }
| tOPTS tSTR
{ $$ = $2; }
@@ -233,7 +229,7 @@ filesystem :
{ $4->d_dev = $2; $$ = $4; }
| tFS error '}'
- { $$ = (disk_fs *) 0; }
+ { $$ = (disk_fs *) NULL; }
;
/*
diff --git a/contrib/amd/fsinfo/fsi_lex.l b/contrib/amd/fsinfo/fsi_lex.l
index 6bca59b4deeb..4d09e2c55e74 100644
--- a/contrib/amd/fsinfo/fsi_lex.l
+++ b/contrib/amd/fsinfo/fsi_lex.l
@@ -1,6 +1,6 @@
%{
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -17,11 +17,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -102,7 +98,7 @@ static int ayylineno;
*/
#ifdef FLEX_SCANNER
# ifndef ECHO
-# define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+# define ECHO __IGNORE(fwrite( yytext, yyleng, 1, yyout ))
# endif /* not ECHO */
#endif /* FLEX_SCANNER */
@@ -111,9 +107,11 @@ static int ayylineno;
* which automatically generates yywrap macros and symbols. So I must
* distinguish between them and when yywrap is actually needed.
*/
-#ifndef yywrap
+#if !defined(yywrap) || defined(yylex)
int yywrap(void);
-#endif /* not yywrap */
+#endif /* not yywrap or yylex */
+
+int fsi_error(const char *, ...);
YYSTYPE yylval;
static char *fsi_filename;
@@ -153,7 +151,7 @@ struct r {
{ "passno", tPASSNO },
{ "sel", tSEL },
{ "volname", tVOLNAME },
- { 0, 0 },
+ { NULL, 0 },
};
#define NRES_WORDS (sizeof(rr)/sizeof(rr[0])-1)
@@ -162,6 +160,7 @@ struct r {
/* 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
@@ -177,7 +176,7 @@ struct r {
<F>[={}] { return *yytext; }
<F>\" { BEGIN Q; optr = ostr; quoted = 1; }
-<Q>\n { ayylineno++; yyerror("\" expected"); BEGIN F; }
+<Q>\n { ayylineno++; fsi_error("\" expected"); BEGIN F; }
<Q>\\b { *optr++ = '\b'; /* escape */ }
<Q>\\t { *optr++ = '\t'; /* escape */ }
<Q>\\\" { *optr++ = '\"'; /* escape */ }
@@ -187,11 +186,11 @@ struct r {
<Q>\\n { *optr++ = '\n'; /* escape */ }
<Q>\\f { *optr++ = '\f'; /* escape */ }
<Q>"\\ " { *optr++ = ' '; /* force space */ }
-<Q>\\. { yyerror("Unknown \\ sequence"); }
+<Q>\\. { fsi_error("Unknown \\ sequence"); }
<Q>([ \t]|"\\\n"){2,} { char *p = (char *) yytext-1; while ((p = strchr(p+1, '\n'))) ayylineno++; }
<Q>\" { BEGIN F; quoted = 0;
*optr = '\0';
- yylval.s = strdup(ostr);
+ yylval.s = xstrdup(ostr);
return tSTR;
}
<Q>. { *optr++ = *yytext; }
@@ -224,11 +223,11 @@ find_resword(char *s)
switch (tok) {
case tLOCALHOST:
s = "${host}";
- /* fall through... */
+ /*FALLTHROUGH*/
case 0:
- yylval.s = strdup(s);
+ yylval.s = xstrdup(s);
tok = tSTR;
- /* fall through... */
+ /*FALLTHROUGH*/
default:
return tok;
}
@@ -236,7 +235,7 @@ find_resword(char *s)
int
-yyerror(char *fmt, ...)
+fsi_error(const char *fmt, ...)
{
va_list ap;
@@ -266,9 +265,9 @@ current_location(void)
* which automatically generates yywrap macros and symbols. So I must
* distinguish between them and when yywrap is actually needed.
*/
-#ifndef yywrap
+#if !defined(yywrap) || defined(yylex)
int yywrap(void)
{
return 1;
}
-#endif /* not yywrap */
+#endif /* not yywrap or yylex */
diff --git a/contrib/amd/fsinfo/fsi_util.c b/contrib/amd/fsinfo/fsi_util.c
index 5e7571fd4db2..f8ff313cc426 100644
--- a/contrib/amd/fsinfo/fsi_util.c
+++ b/contrib/amd/fsinfo/fsi_util.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -13,11 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -201,7 +197,7 @@ gen_hdr(FILE *ef, char *hn)
static void
make_banner(FILE *fp)
{
- time_t t = time((time_t *) 0);
+ time_t t = time((time_t *) NULL);
char *cp = ctime(&t);
fprintf(fp,
@@ -235,7 +231,7 @@ show_new(char *msg)
void
show_area_being_processed(char *area, int n)
{
- static char *last_area = 0;
+ static char *last_area = NULL;
if (verbose < 0)
return;
@@ -316,9 +312,9 @@ new_automount(char *name)
ap->a_ioloc = current_location();
ap->a_name = name;
- ap->a_volname = 0;
- ap->a_mount = 0;
- ap->a_opts = 0;
+ ap->a_volname = NULL;
+ ap->a_mount = NULL;
+ ap->a_opts = NULL;
show_new("automount");
return ap;
}
@@ -355,7 +351,7 @@ set_host(host *hp, int k, char *v)
int m = 1 << k;
if (hp->h_mask & m) {
- yyerror("host field \"%s\" already set", host_strings[k]);
+ fsi_error("host field \"%s\" already set", host_strings[k]);
return;
}
hp->h_mask |= m;
@@ -363,11 +359,11 @@ set_host(host *hp, int k, char *v)
switch (k) {
case HF_HOST:{
- char *p = strdup(v);
+ char *p = xstrdup(v);
dict_ent *de = dict_locate(dict_of_hosts, v);
if (de)
- yyerror("duplicate host %s!", v);
+ fsi_error("duplicate host %s!", v);
else
dict_add(dict_of_hosts, v, (char *) hp);
hp->h_hostname = v;
@@ -442,7 +438,7 @@ set_ether_if(ether_if *ep, int k, char *v)
int m = 1 << k;
if (ep->e_mask & m) {
- yyerror("netif field \"%s\" already set", ether_if_strings[k]);
+ fsi_error("netif field \"%s\" already set", ether_if_strings[k]);
return;
}
ep->e_mask |= m;
@@ -452,7 +448,7 @@ set_ether_if(ether_if *ep, int k, char *v)
case EF_INADDR:{
ep->e_inaddr.s_addr = inet_addr(v);
if ((int) ep->e_inaddr.s_addr == (int) INADDR_NONE)
- yyerror("malformed IP dotted quad: %s", v);
+ fsi_error("malformed IP dotted quad: %s", v);
XFREE(v);
}
break;
@@ -463,7 +459,7 @@ set_ether_if(ether_if *ep, int k, char *v)
if ((sscanf(v, "0x%lx", &nm) == 1 || sscanf(v, "%lx", &nm) == 1) && nm != 0)
ep->e_netmask = htonl(nm);
else
- yyerror("malformed netmask: %s", v);
+ fsi_error("malformed netmask: %s", v);
XFREE(v);
}
break;
@@ -485,7 +481,7 @@ set_disk_fs(disk_fs *dp, int k, char *v)
int m = 1 << k;
if (dp->d_mask & m) {
- yyerror("fs field \"%s\" already set", disk_fs_strings[k]);
+ fsi_error("fs field \"%s\" already set", disk_fs_strings[k]);
return;
}
dp->d_mask |= m;
@@ -546,7 +542,7 @@ set_mount(fsi_mount *mp, int k, char *v)
int m = 1 << k;
if (mp->m_mask & m) {
- yyerror("mount tree field \"%s\" already set", mount_strings[k]);
+ fsi_error("mount tree field \"%s\" already set", mount_strings[k]);
return;
}
mp->m_mask |= m;
@@ -590,7 +586,7 @@ set_fsmount(fsmount *fp, int k, char *v)
int m = 1 << k;
if (fp->f_mask & m) {
- yyerror("mount field \"%s\" already set", fsmount_strings[k]);
+ fsi_error("mount field \"%s\" already set", fsmount_strings[k]);
return;
}
fp->f_mask |= m;
diff --git a/contrib/amd/fsinfo/fsinfo.8 b/contrib/amd/fsinfo/fsinfo.8
index b1750f003840..f4a1afa94bfb 100644
--- a/contrib/amd/fsinfo/fsinfo.8
+++ b/contrib/amd/fsinfo/fsinfo.8
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 1997-2006 Erez Zadok
+.\" Copyright (c) 1997-2014 Erez Zadok
.\" Copyright (c) 1993 Jan-Simon Pendry.
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@@ -12,11 +12,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 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.
.\"
@@ -32,32 +28,33 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" from: @(#)fsinfo.8 8.1 (Berkeley) 6/28/93
-.\" $Id: fsinfo.8,v 1.13.2.1 2006/01/02 18:48:25 ezk Exp $
.\" $FreeBSD$
.\"
-.Dd February 26, 2016
-.Dt FSINFO 8
-.Os
+.\" File: am-utils/fsinfo/fsinfo.8
+.\"
+.Dd August 31, 2016
.Sh NAME
.Nm fsinfo
.Nd co-ordinate site-wide file system information
.Sh SYNOPSIS
.Nm
-.Op Fl qv
+.Op fl qv
.Op Fl a Ar autodir
-.Op Fl b Ar bootparams_prefix
-.Op Fl d Ar dumpsets_prefix
-.Op Fl e Ar exports_prefix
-.Op Fl f Ar fstabs_prefix
+.Op Fl b Ar bootparams
+.Op Fl d Ar dumpsets
+.Op Fl e Ar exports
+.Op Fl f Ar fstabs
.Op Fl h Ar hostname
-.Op Fl m Ar automounts_prefix
+.Op Fl m Ar automounts
.Op Fl I Ar dir
.Oo
.Fl D
.Ar name Ns Op = Ns Ar string
.Oc
-.Op Fl U Ar name
+.Oo
+.Fl U
+.Ar name Ns Op = Ns Ar string
+.Oc
.Ar config ...
.Sh DESCRIPTION
.Bf -symbolic
diff --git a/contrib/amd/fsinfo/fsinfo.c b/contrib/amd/fsinfo/fsinfo.c
index e441a47fab4b..93122eabbbb2 100644
--- a/contrib/amd/fsinfo/fsinfo.c
+++ b/contrib/amd/fsinfo/fsinfo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -213,7 +209,7 @@ find_username(void)
if (!u)
u = "root";
- return strdup(u);
+ return xstrdup(u);
}
@@ -258,7 +254,7 @@ main(int argc, char *argv[])
* Parse input
*/
show_area_being_processed("read config", 11);
- if (yyparse())
+ if (fsi_parse())
errors = 1;
errors += file_io_errors + parse_errors;
diff --git a/contrib/amd/fsinfo/fsinfo.h b/contrib/amd/fsinfo/fsinfo.h
index 99b407b04bf0..7a871631a0c6 100644
--- a/contrib/amd/fsinfo/fsinfo.h
+++ b/contrib/amd/fsinfo/fsinfo.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -104,7 +100,7 @@ extern void show_area_being_processed(char *area, int n);
extern void show_new(char *msg);
extern void warning(void);
-extern int yyerror(char *fmt, ...)
+extern int fsi_error(const char *fmt, ...)
__attribute__((__format__(__printf__, 1, 2)));
extern void domain_strip(char *otherdom, char *localdom);
/*
@@ -115,7 +111,7 @@ extern void domain_strip(char *otherdom, char *localdom);
#ifndef yywrap
extern int yywrap(void);
#endif /* not yywrap */
-extern int yyparse(void);
+extern int fsi_parse(void);
extern int write_atab(qelem *q);
extern int write_bootparams(qelem *q);
extern int write_dumpset(qelem *q);
@@ -124,7 +120,7 @@ extern int write_fstab(qelem *q);
extern void col_cleanup(int eoj);
extern void set_host(host *hp, int k, char *v);
extern void set_ether_if(ether_if *ep, int k, char *v);
-extern int yylex(void);
+extern int fsi_lex(void);
#define BITSET(m,b) ((m) |= (1<<(b)))
diff --git a/contrib/amd/fsinfo/null_gram.c b/contrib/amd/fsinfo/null_gram.c
new file mode 100644
index 000000000000..9b4e9f4a1cc6
--- /dev/null
+++ b/contrib/amd/fsinfo/null_gram.c
@@ -0,0 +1,1414 @@
+/* A Bison parser, made by GNU Bison 3.0.2. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "3.0.2"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+
+/* Substitute the variable and function names. */
+#define yyparse null_parse
+#define yylex null_lex
+#define yyerror null_error
+#define yydebug null_debug
+#define yynerrs null_nerrs
+
+#define yylval null_lval
+#define yychar null_char
+
+/* Copy the first part of user declarations. */
+#line 1 "../../fsinfo/null_gram.y" /* yacc.c:339 */
+
+void yyerror(const char *fmt, ...);
+extern int yylex(void);
+
+#line 79 "null_gram.c" /* yacc.c:339 */
+
+# ifndef YY_NULLPTR
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* In a future release of Bison, this section will be replaced
+ by #include "y.tab.h". */
+#ifndef YY_NULL_NULL_GRAM_H_INCLUDED
+# define YY_NULL_NULL_GRAM_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int null_debug;
+#endif
+
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef int YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE null_lval;
+
+int null_parse (void);
+
+#endif /* !YY_NULL_NULL_GRAM_H_INCLUDED */
+
+/* Copy the second part of user declarations. */
+
+#line 126 "null_gram.c" /* yacc.c:358 */
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__ \
+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+# define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 2
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 0
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 3
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 2
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 2
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 3
+
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+ by yylex, with out-of-bounds checking. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 257
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, without out-of-bounds checking. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2
+};
+
+#if YYDEBUG
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_uint8 yyrline[] =
+{
+ 0, 8, 8
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || 0
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "$accept", "token", YY_NULLPTR
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+ (internal) symbol number NUM (which must be that of a token). */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257
+};
+# endif
+
+#define YYPACT_NINF -1
+
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-1)))
+
+#define YYTABLE_NINF -1
+
+#define yytable_value_is_error(Yytable_value) \
+ 0
+
+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int8 yypact[] =
+{
+ -1, 0, -1
+};
+
+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 2, 0, 1
+};
+
+ /* YYPGOTO[NTERM-NUM]. */
+static const yytype_int8 yypgoto[] =
+{
+ -1, -1
+};
+
+ /* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int8 yydefgoto[] =
+{
+ -1, 1
+};
+
+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+static const yytype_uint8 yytable[] =
+{
+ 2
+};
+
+static const yytype_uint8 yycheck[] =
+{
+ 0
+};
+
+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 4, 0
+};
+
+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 3, 4
+};
+
+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 0
+};
+
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (0)
+
+/* Error token number */
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
+
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value on YYOUTPUT. |
+`----------------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ YYUSE (yytype);
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+{
+ YYFPRINTF (yyoutput, "%s %s (",
+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
+{
+ unsigned long int yylno = yyrline[yyrule];
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr,
+ yystos[yyssp[yyi + 1 - yynrhs]],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyssp, yyvsp, Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+yystrlen (const char *yystr)
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP.
+
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = YY_NULLPTR;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "expected"). */
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yychar) is if
+ this state is a consistent state with a default action. Thus,
+ detecting the absence of a lookahead is sufficient to determine
+ that there is no unexpected or expected token to report. In that
+ case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is a
+ consistent state with a default action. There might have been a
+ previous inconsistent state, consistent state with a non-default
+ action, or user semantic action that manipulated yychar.
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.
+ */
+ if (yytoken != YYEMPTY)
+ {
+ int yyn = yypact[*yyssp];
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yyx;
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+ }
+ }
+ }
+
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+ }
+
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+
+ if (*yymsg_alloc < yysize)
+ {
+ *yymsg_alloc = 2 * yysize;
+ if (! (yysize <= *yymsg_alloc
+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+ return 1;
+ }
+
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ {
+ char *yyp = *yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyformat) != '\0')
+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyformat += 2;
+ }
+ else
+ {
+ yyp++;
+ yyformat++;
+ }
+ }
+ return 0;
+}
+#endif /* YYERROR_VERBOSE */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+{
+ YYUSE (yyvaluep);
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int
+yyparse (void)
+{
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ 'yyss': related to states.
+ 'yyvs': related to semantic values.
+
+ Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default (yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = yylex ();
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+
+#line 1188 "null_gram.c" /* yacc.c:1646 */
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+ /* Now 'shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyssp, yytoken)
+ {
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ if (yysyntax_error_status == 0)
+ yymsgp = yymsg;
+ else if (yysyntax_error_status == 1)
+ {
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+ if (!yymsg)
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ yysyntax_error_status = 2;
+ }
+ else
+ {
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ yymsgp = yymsg;
+ }
+ }
+ yyerror (yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
+ }
+# undef YYSYNTAX_ERROR
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default (yyn))
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined yyoverflow || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ }
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ return yyresult;
+}
diff --git a/contrib/amd/fsinfo/null_gram.h b/contrib/amd/fsinfo/null_gram.h
new file mode 100644
index 000000000000..77c4ac78ff49
--- /dev/null
+++ b/contrib/amd/fsinfo/null_gram.h
@@ -0,0 +1,56 @@
+/* A Bison parser, made by GNU Bison 3.0.2. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+#ifndef YY_NULL_NULL_GRAM_H_INCLUDED
+# define YY_NULL_NULL_GRAM_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int null_debug;
+#endif
+
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef int YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE null_lval;
+
+int null_parse (void);
+
+#endif /* !YY_NULL_NULL_GRAM_H_INCLUDED */
diff --git a/contrib/amd/fsinfo/null_gram.y b/contrib/amd/fsinfo/null_gram.y
new file mode 100644
index 000000000000..d7313b9c49c2
--- /dev/null
+++ b/contrib/amd/fsinfo/null_gram.y
@@ -0,0 +1,8 @@
+%{
+void yyerror(const char *fmt, ...);
+extern int yylex(void);
+%}
+
+%%
+
+token:
diff --git a/contrib/amd/fsinfo/null_lex.c b/contrib/amd/fsinfo/null_lex.c
new file mode 100644
index 000000000000..b890445686e1
--- /dev/null
+++ b/contrib/amd/fsinfo/null_lex.c
@@ -0,0 +1,1716 @@
+
+#line 3 "lex.null_.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define yy_create_buffer null__create_buffer
+#define yy_delete_buffer null__delete_buffer
+#define yy_flex_debug null__flex_debug
+#define yy_init_buffer null__init_buffer
+#define yy_flush_buffer null__flush_buffer
+#define yy_load_buffer_state null__load_buffer_state
+#define yy_switch_to_buffer null__switch_to_buffer
+#define yyin null_in
+#define yyleng null_leng
+#define yylex null_lex
+#define yylineno null_lineno
+#define yyout null_out
+#define yyrestart null_restart
+#define yytext null_text
+#define yywrap null_wrap
+#define yyalloc null_alloc
+#define yyrealloc null_realloc
+#define yyfree null_free
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE null_restart(null_in )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int null_leng;
+
+extern FILE *null_in, *null_out;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up null_text. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up null_text again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via null_restart()), so that the user can continue scanning by
+ * just pointing null_in at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when null_text is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int null_leng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow null_wrap()'s to do buffer switches
+ * instead of setting up a fresh null_in. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void null_restart (FILE *input_file );
+void null__switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE null__create_buffer (FILE *file,int size );
+void null__delete_buffer (YY_BUFFER_STATE b );
+void null__flush_buffer (YY_BUFFER_STATE b );
+void null_push_buffer_state (YY_BUFFER_STATE new_buffer );
+void null_pop_buffer_state (void );
+
+static void null_ensure_buffer_stack (void );
+static void null__load_buffer_state (void );
+static void null__init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER null__flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE null__scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE null__scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE null__scan_bytes (yyconst char *bytes,int len );
+
+void *null_alloc (yy_size_t );
+void *null_realloc (void *,yy_size_t );
+void null_free (void * );
+
+#define yy_new_buffer null__create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ null_ensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ null__create_buffer(null_in,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ null_ensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ null__create_buffer(null_in,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+
+FILE *null_in = (FILE *) 0, *null_out = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int null_lineno;
+
+int null_lineno = 1;
+
+extern char *null_text;
+#define yytext_ptr null_text
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up null_text.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ null_leng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 1
+#define YY_END_OF_BUFFER 2
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[6] =
+ { 0,
+ 0, 0, 2, 1, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[2] =
+ { 0,
+ 1
+ } ;
+
+static yyconst flex_int16_t yy_base[7] =
+ { 0,
+ 0, 0, 2, 3, 3, 0
+ } ;
+
+static yyconst flex_int16_t yy_def[7] =
+ { 0,
+ 6, 6, 5, 5, 0, 5
+ } ;
+
+static yyconst flex_int16_t yy_nxt[5] =
+ { 0,
+ 4, 5, 3, 5
+ } ;
+
+static yyconst flex_int16_t yy_chk[5] =
+ { 0,
+ 6, 3, 5, 5
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int null__flex_debug;
+int null__flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *null_text;
+#line 1 "../../fsinfo/null_lex.l"
+#line 2 "../../fsinfo/null_lex.l"
+#include "null_gram.h"
+
+void null_error(const char *fmt, ...) {}
+int null_wrap(void) { return 0; }
+#define YY_NO_INPUT 1
+#line 481 "lex.null_.c"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int null_lex_destroy (void );
+
+int null_get_debug (void );
+
+void null_set_debug (int debug_flag );
+
+YY_EXTRA_TYPE null_get_extra (void );
+
+void null_set_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *null_get_in (void );
+
+void null_set_in (FILE * in_str );
+
+FILE *null_get_out (void );
+
+void null_set_out (FILE * out_str );
+
+int null_get_leng (void );
+
+char *null_get_text (void );
+
+int null_get_lineno (void );
+
+void null_set_lineno (int line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int null_wrap (void );
+#else
+extern int null_wrap (void );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( null_text, null_leng, 1, null_out )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( null_in )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( null_in ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, null_in))==0 && ferror(null_in)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(null_in); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int null_lex (void);
+
+#define YY_DECL int null_lex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after null_text and null_leng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 9 "../../fsinfo/null_lex.l"
+
+#line 668 "lex.null_.c"
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! null_in )
+ null_in = stdin;
+
+ if ( ! null_out )
+ null_out = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ null_ensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ null__create_buffer(null_in,YY_BUF_SIZE );
+ }
+
+ null__load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of null_text. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 6 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 3 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 10 "../../fsinfo/null_lex.l"
+ECHO;
+ YY_BREAK
+#line 756 "lex.null_.c"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed null_in at a new source and called
+ * null_lex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = null_in;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( null_wrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * null_text, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of null_lex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ null_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ null_restart(null_in );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) null_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 6 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ register int yy_is_jam;
+ register char *yy_cp = (yy_c_buf_p);
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 6 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 5);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ null_restart(null_in );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( null_wrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve null_text */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void null_restart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ null_ensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ null__create_buffer(null_in,YY_BUF_SIZE );
+ }
+
+ null__init_buffer(YY_CURRENT_BUFFER,input_file );
+ null__load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void null__switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * null_pop_buffer_state();
+ * null_push_buffer_state(new_buffer);
+ */
+ null_ensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ null__load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (null_wrap()) processing, but the only time this flag
+ * is looked at is after null_wrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void null__load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ null_in = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE null__create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) null_alloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in null__create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) null_alloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in null__create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ null__init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with null__create_buffer()
+ *
+ */
+ void null__delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ null_free((void *) b->yy_ch_buf );
+
+ null_free((void *) b );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a null_restart() or at EOF.
+ */
+ static void null__init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ null__flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then null__init_buffer was _probably_
+ * called from null_restart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void null__flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ null__load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void null_push_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ null_ensure_buffer_stack();
+
+ /* This block is copied from null__switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from null__switch_to_buffer. */
+ null__load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void null_pop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ null__delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ null__load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void null_ensure_buffer_stack (void)
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)null_alloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in null_ensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)null_realloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in null_ensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE null__scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) null_alloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in null__scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ null__switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to null_lex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * null__scan_bytes() instead.
+ */
+YY_BUFFER_STATE null__scan_string (yyconst char * yystr )
+{
+
+ return null__scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to null_lex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE null__scan_bytes (yyconst char * yybytes, int _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) null_alloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in null__scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = null__scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in null__scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up null_text. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ null_text[null_leng] = (yy_hold_char); \
+ (yy_c_buf_p) = null_text + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ null_leng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int null_get_lineno (void)
+{
+
+ return null_lineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *null_get_in (void)
+{
+ return null_in;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *null_get_out (void)
+{
+ return null_out;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int null_get_leng (void)
+{
+ return null_leng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *null_get_text (void)
+{
+ return null_text;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void null_set_lineno (int line_number )
+{
+
+ null_lineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see null__switch_to_buffer
+ */
+void null_set_in (FILE * in_str )
+{
+ null_in = in_str ;
+}
+
+void null_set_out (FILE * out_str )
+{
+ null_out = out_str ;
+}
+
+int null_get_debug (void)
+{
+ return null__flex_debug;
+}
+
+void null_set_debug (int bdebug )
+{
+ null__flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from null_lex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ null_in = stdin;
+ null_out = stdout;
+#else
+ null_in = (FILE *) 0;
+ null_out = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * null_lex_init()
+ */
+ return 0;
+}
+
+/* null_lex_destroy is for both reentrant and non-reentrant scanners. */
+int null_lex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ null__delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ null_pop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ null_free((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * null_lex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *null_alloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *null_realloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void null_free (void * ptr )
+{
+ free( (char *) ptr ); /* see null_realloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 10 "../../fsinfo/null_lex.l"
diff --git a/contrib/amd/fsinfo/null_lex.l b/contrib/amd/fsinfo/null_lex.l
new file mode 100644
index 000000000000..46bb46381e43
--- /dev/null
+++ b/contrib/amd/fsinfo/null_lex.l
@@ -0,0 +1,9 @@
+%{
+#include "null_gram.h"
+
+void null_error(const char *fmt, ...) {}
+int yywrap(void) { return 0; }
+%}
+%option nounput
+%option noinput
+%%
diff --git a/contrib/amd/fsinfo/wr_atab.c b/contrib/amd/fsinfo/wr_atab.c
index e02db07f05f5..ac132aa76dc4 100644
--- a/contrib/amd/fsinfo/wr_atab.c
+++ b/contrib/amd/fsinfo/wr_atab.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/fsinfo/wr_bparam.c b/contrib/amd/fsinfo/wr_bparam.c
index 9220762f2b10..00befa9cf582 100644
--- a/contrib/amd/fsinfo/wr_bparam.c
+++ b/contrib/amd/fsinfo/wr_bparam.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -56,7 +52,7 @@ static int
write_nfsname(FILE *ef, fsmount *fp, char *hn)
{
int errors = 0;
- char *h = strdup(fp->f_ref->m_dk->d_host->h_hostname);
+ char *h = xstrdup(fp->f_ref->m_dk->d_host->h_hostname);
domain_strip(h, hn);
fprintf(ef, "%s:%s", h, fp->f_volname);
diff --git a/contrib/amd/fsinfo/wr_dumpset.c b/contrib/amd/fsinfo/wr_dumpset.c
index 69c1257e2659..916f95a5a23d 100644
--- a/contrib/amd/fsinfo/wr_dumpset.c
+++ b/contrib/amd/fsinfo/wr_dumpset.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/fsinfo/wr_exportfs.c b/contrib/amd/fsinfo/wr_exportfs.c
index 818d893687cd..c6e7936dd16d 100644
--- a/contrib/amd/fsinfo/wr_exportfs.c
+++ b/contrib/amd/fsinfo/wr_exportfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/fsinfo/wr_fstab.c b/contrib/amd/fsinfo/wr_fstab.c
index 52cebbf27e11..166353eb00f1 100644
--- a/contrib/amd/fsinfo/wr_fstab.c
+++ b/contrib/amd/fsinfo/wr_fstab.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -89,7 +85,7 @@ static struct os_fstab_type {
"u4_0", write_ultrix_dkfstab, write_ultrix_dkrmount
}, /* Ultrix */
{
- 0, 0, 0
+ NULL, NULL, NULL
}
};
@@ -102,7 +98,7 @@ static struct os_fstab_type {
static void
write_aix1_dkfstab(FILE *ef, disk_fs *dp)
{
- char *hp = strdup(dp->d_host->h_hostname);
+ char *hp = xstrdup(dp->d_host->h_hostname);
char *p = strchr(hp, '.');
if (p)
@@ -123,8 +119,8 @@ write_aix1_dkfstab(FILE *ef, disk_fs *dp)
static void
write_aix1_dkrmount(FILE *ef, char *hn, fsmount *fp)
{
- char *h = strdup(fp->f_ref->m_dk->d_host->h_hostname);
- char *hp = strdup(h);
+ char *h = xstrdup(fp->f_ref->m_dk->d_host->h_hostname);
+ char *hp = xstrdup(h);
char *p = strchr(hp, '.');
if (p)
@@ -172,7 +168,7 @@ write_aix3_dkfstab(FILE *ef, disk_fs *dp)
static void
write_aix3_dkrmount(FILE *ef, char *hn, fsmount *fp)
{
- char *h = strdup(fp->f_ref->m_dk->d_host->h_hostname);
+ char *h = xstrdup(fp->f_ref->m_dk->d_host->h_hostname);
domain_strip(h, hn);
fprintf(ef, "\n%s:\n\tdev = %s:%s\n\tvfs = %s\n\ttype = %s\n\tvol = %s\n\topts = %s\n\tmount = true\n\tcheck = true\n\tfree = false\n",
@@ -206,7 +202,7 @@ write_ultrix_dkfstab(FILE *ef, disk_fs *dp)
static void
write_ultrix_dkrmount(FILE *ef, char *hn, fsmount *fp)
{
- char *h = strdup(fp->f_ref->m_dk->d_host->h_hostname);
+ char *h = xstrdup(fp->f_ref->m_dk->d_host->h_hostname);
domain_strip(h, hn);
fprintf(ef, "%s@%s:%s:%s:%s:0:0\n",
@@ -243,9 +239,9 @@ write_generic_dkrmount(FILE *ef, char *hn, fsmount *fp)
char *h;
if (fp->f_ref) {
- h = strdup(fp->f_ref->m_dk->d_host->h_hostname);
+ h = xstrdup(fp->f_ref->m_dk->d_host->h_hostname);
} else {
- h = strdup(fp->f_from);
+ h = xstrdup(fp->f_from);
}
domain_strip(h, hn);
fprintf(ef, "%s:%s %s %s %s 0 0\n",
@@ -261,8 +257,8 @@ write_generic_dkrmount(FILE *ef, char *hn, fsmount *fp)
static struct os_fstab_type *
find_fstab_type(host *hp)
{
- struct os_fstab_type *op = 0;
- char *os_name = 0;
+ struct os_fstab_type *op = NULL;
+ char *os_name = NULL;
again:;
if (os_name == 0) {
diff --git a/contrib/amd/hlfsd/hlfsd.8 b/contrib/amd/hlfsd/hlfsd.8
index d0a04c1439ef..1732a446d60c 100644
--- a/contrib/amd/hlfsd/hlfsd.8
+++ b/contrib/amd/hlfsd/hlfsd.8
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 1997-2006 Erez Zadok
+.\" 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.
@@ -16,11 +16,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 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.
.\"
@@ -36,9 +32,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: hlfsd.8,v 1.11.2.1 2006/01/02 18:48:25 ezk Exp $
.\" $FreeBSD$
.\"
+.\" File: am-utils/hlfsd/hlfsd.8
+.\"
.\" HLFSD was written at Columbia University Computer Science Department, by
.\" Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@smarts.com>
.\" It is distributed under the same terms and conditions as AMD.
@@ -337,14 +334,16 @@ symbolic link returned by
points if it is unable to verify the that
user's home directory is accessible.
.El
-.Sh SEE ALSO
-.Xr mail 1 ,
+.SH "SEE ALSO"
+.Xr mail1 ,
.Xr getgrent 3 ,
.Xr getpwent 3 ,
+.Xr mnttab 4 ,
+.Xr passwd 4 ,
.Xr mtab 5 ,
-.Xr passwd 5 ,
.Xr amd 8 ,
-.Xr cron 8 ,
+.Xr automount 8 ,
+.Xr cron8 ,
.Xr mount 8 ,
.Xr sendmail 8 ,
.Xr umount 8
diff --git a/contrib/amd/hlfsd/hlfsd.c b/contrib/amd/hlfsd/hlfsd.c
index 8703f5982c5e..686bb63db239 100644
--- a/contrib/amd/hlfsd/hlfsd.c
+++ b/contrib/amd/hlfsd/hlfsd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -82,7 +78,7 @@ char *alt_spooldir = ALT_SPOOLDIR;
char *home_subdir = HOME_SUBDIR;
char *logfile = DEFAULT_LOGFILE;
char *passwdfile = NULL; /* alternate passwd file to use */
-char *slinkname = 0;
+char *slinkname = NULL;
char hostname[MAXHOSTNAMELEN + 1] = "localhost";
u_int cache_interval = DEFAULT_CACHE_INTERVAL;
gid_t hlfs_gid = (gid_t) INVALIDID;
@@ -102,6 +98,7 @@ char *mnttab_file_name = NULL;
/* forward declarations */
void hlfsd_going_down(int rc);
+void fatalerror(char *str);
static void
@@ -260,9 +257,6 @@ main(int argc, char *argv[])
opterrs++;
}
- /* set some default debugging options */
- if (xlog_level_init == ~0)
- switch_option("");
/* need my pid before any dlog/plog */
am_set_mypid();
#ifdef DEBUG
@@ -312,7 +306,11 @@ main(int argc, char *argv[])
}
/* get hostname for logging and open log before we reset umask */
- gethostname(hostname, sizeof(hostname));
+ if (gethostname(hostname, sizeof(hostname)) == -1) {
+ fprintf(stderr, "%s: gethostname failed \"%s\".\n",
+ am_get_progname(), strerror(errno));
+ exit(1);
+ }
hostname[sizeof(hostname) - 1] = '\0';
if ((dot = strchr(hostname, '.')) != NULL)
*dot = '\0';
@@ -418,11 +416,8 @@ main(int argc, char *argv[])
/*
* Register hlfsd as an nfs service with the portmapper.
*/
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
-#else /* not HAVE_TRANSPORT_TYPE_TLI */
- ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
-#endif /* not HAVE_TRANSPORT_TYPE_TLI */
+ ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2,
+ NFS_VERSION);
if (ret != 0)
fatal("cannot create NFS service");
@@ -450,10 +445,10 @@ main(int argc, char *argv[])
#endif /* not HAVE_SIGACTION */
/*
- * In the parent, if -D daemon, we don't need to
+ * In the parent, if -D nodaemon, we don't need to
* set this signal handler.
*/
- if (!amuDebug(D_DAEMON)) {
+ if (amuDebug(D_DAEMON)) {
s = -99;
while (stoplight != SIGUSR2) {
plog(XLOG_INFO, "parent waits for child to setup (stoplight=%d)", stoplight);
@@ -628,10 +623,10 @@ main(int argc, char *argv[])
plog(XLOG_INFO, "hlfsd ready to serve");
/*
- * If asked not to fork a daemon (-D daemon), then hlfsd_init()
+ * If asked not to fork a daemon (-D nodaemon), then hlfsd_init()
* will not run svc_run. We must start svc_run here.
*/
- if (amuDebug(D_DAEMON)) {
+ if (!amuDebug(D_DAEMON)) {
plog(XLOG_DEBUG, "starting no-daemon debugging svc_run");
svc_run();
}
@@ -656,9 +651,9 @@ hlfsd_init(void)
hlfsd_init_filehandles();
/*
- * If not -D daemon then we must fork.
+ * If -D daemon then we must fork.
*/
- if (!amuDebug(D_DAEMON))
+ if (amuDebug(D_DAEMON))
child = fork();
if (child < 0)
@@ -745,17 +740,17 @@ hlfsd_init(void)
# endif /* not defined(DEBUG) || defined(DEBUG_PRINT) */
#endif /* not HAVE_SIGACTION */
- if (setitimer(ITIMER_REAL, &reloadinterval, (struct itimerval *) 0) < 0)
+ if (setitimer(ITIMER_REAL, &reloadinterval, (struct itimerval *) NULL) < 0)
fatal("setitimer: %m");
clocktime(&startup);
/*
- * If not -D daemon, then start serving here in the child,
- * and the parent will exit. But if -D daemon, then
+ * If -D daemon, then start serving here in the child,
+ * and the parent will exit. But if -D nodaemon, then
* skip this code and make sure svc_run is entered elsewhere.
*/
- if (!amuDebug(D_DAEMON)) {
+ if (amuDebug(D_DAEMON)) {
/*
* Dissociate from the controlling terminal
*/
@@ -839,7 +834,7 @@ cleanup(int signum)
struct stat stbuf;
int umount_result;
- if (!amuDebug(D_DAEMON)) {
+ if (amuDebug(D_DAEMON)) {
if (getpid() != masterpid)
return;
@@ -865,7 +860,7 @@ cleanup(int signum)
break;
}
- if (!amuDebug(D_DAEMON)) {
+ if (amuDebug(D_DAEMON)) {
plog(XLOG_INFO, "cleanup(): killing processes and terminating");
kill(masterpid, SIGKILL);
kill(serverpid, SIGKILL);
diff --git a/contrib/amd/hlfsd/hlfsd.h b/contrib/amd/hlfsd/hlfsd.h
index ed136b6f2306..d5eefedfa61b 100644
--- a/contrib/amd/hlfsd/hlfsd.h
+++ b/contrib/amd/hlfsd/hlfsd.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/hlfsd/homedir.c b/contrib/amd/hlfsd/homedir.c
index d60c39f2c2cb..462b42380ca3 100644
--- a/contrib/amd/hlfsd/homedir.c
+++ b/contrib/amd/hlfsd/homedir.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -133,9 +129,10 @@ homedir(int userid, int groupid)
}
/*
- * only run this forking code if did not ask for -D fork
+ * Only run this forking code if ask for -D fork (default).
+ * Disable forking using -D nofork.
*/
- if (!amuDebug(D_FORK)) {
+ if (amuDebug(D_FORK)) {
/* fork child to process request if none in progress */
if (found->child && kill(found->child, 0))
found->child = 0;
@@ -265,13 +262,14 @@ delay(uid2home_t *found, int secs)
{
struct timeval tv;
- dlog("delaying on child %ld for %d seconds", (long) found->child, secs);
+ if (found)
+ dlog("delaying on child %ld for %d seconds", (long) found->child, secs);
tv.tv_usec = 0;
do {
tv.tv_sec = secs;
- if (select(0, 0, 0, 0, &tv) == 0)
+ if (select(0, NULL, NULL, NULL, &tv) == 0)
break;
} while (--secs && found->child);
}
@@ -292,7 +290,7 @@ interlock(int signum)
#ifdef HAVE_WAITPID
while ((child = waitpid((pid_t) -1, &status, WNOHANG)) > 0) {
#else /* not HAVE_WAITPID */
- while ((child = wait3(&status, WNOHANG, (struct rusage *) 0)) > 0) {
+ while ((child = wait3(&status, WNOHANG, (struct rusage *) NULL)) > 0) {
#endif /* not HAVE_WAITPID */
/* high chances this was the last child forked */
@@ -560,7 +558,7 @@ plt_init(void)
int len;
if (root_home)
XFREE(root_home);
- root_home = strdup(pent_p->pw_dir);
+ root_home = xstrdup(pent_p->pw_dir);
len = strlen(root_home);
/* remove any trailing '/' chars from root's home (even if just one) */
while (len > 0 && root_home[len - 1] == '/') {
@@ -577,7 +575,7 @@ plt_init(void)
unt_compare_fxn);
if (!root_home)
- root_home = strdup("");
+ root_home = xstrdup("");
plog(XLOG_INFO, "password map read and sorted");
}
@@ -672,14 +670,14 @@ table_add(u_int u, const char *h, const char *n)
}
/* add new password entry */
- pwtab[cur_pwtab_num].home = strdup(h);
+ pwtab[cur_pwtab_num].home = xstrdup(h);
pwtab[cur_pwtab_num].child = 0;
pwtab[cur_pwtab_num].last_access_time = 0;
pwtab[cur_pwtab_num].last_status = 0; /* assume best: used homedir */
pwtab[cur_pwtab_num].uid = u;
/* add new userhome entry */
- untab[cur_pwtab_num].username = strdup(n);
+ untab[cur_pwtab_num].username = xstrdup(n);
/* just a second pointer */
pwtab[cur_pwtab_num].uname = untab[cur_pwtab_num].username;
diff --git a/contrib/amd/hlfsd/nfs_prot_svc.c b/contrib/amd/hlfsd/nfs_prot_svc.c
index 8cea0dca700d..babaa846a224 100644
--- a/contrib/amd/hlfsd/nfs_prot_svc.c
+++ b/contrib/amd/hlfsd/nfs_prot_svc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/hlfsd/stubs.c b/contrib/amd/hlfsd/stubs.c
index 3b31043efc20..b26e5f4dc637 100644
--- a/contrib/amd/hlfsd/stubs.c
+++ b/contrib/amd/hlfsd/stubs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -137,7 +133,7 @@ nfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
clocktime(&rootfattr.na_mtime);
rootfattr.na_uid = uid;
}
-#endif
+#endif /* 0 */
res.ns_status = NFS_OK;
res.ns_u.ns_attr_u = rootfattr;
} else if (eq_fh(argp, &slink)) {
@@ -240,7 +236,7 @@ nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
clocktime(&rootfattr.na_mtime);
rootfattr.na_uid = uid;
}
-#endif
+#endif /* 0 */
res.dr_u.dr_drok_u.drok_fhandle = root;
res.dr_u.dr_drok_u.drok_attributes = rootfattr;
res.dr_status = NFS_OK;
@@ -306,7 +302,7 @@ nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
uid_t userid = (uid_t) INVALIDID;
gid_t groupid = hlfs_gid + 1; /* anything not hlfs_gid */
int retval = 0;
- char *path_val = (char *) NULL;
+ char *path_val = NULL;
char *username;
static uid_t last_uid = (uid_t) INVALIDID;
@@ -327,7 +323,7 @@ nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
* processing, by getting a NULL returned as a
* "special". Child returns result.
*/
- return (nfsreadlinkres *) NULL;
+ return NULL;
}
} else { /* check if asked for user mailbox */
@@ -373,14 +369,15 @@ nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
retval = 0;
/*
- * If asked for -D fork, then must return the value,
+ * If asked for -D nofork, then must return the value,
* NOT exit, or else the main hlfsd server exits.
+ * If -D fork (default), then we do want to exit from the process.
* Bug: where is that status information being collected?
*/
if (amuDebug(D_FORK))
+ exit(retval);
+ else
return &res;
-
- exit(retval);
}
@@ -478,7 +475,7 @@ nfsreaddirres *
nfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp)
{
static nfsreaddirres res;
- static nfsentry slinkent = {SLINKID, 0, {SLINKCOOKIE}};
+ static nfsentry slinkent = {SLINKID, NULL, {SLINKCOOKIE}};
static nfsentry dotdotent = {ROOTID, "..", {DOTDOTCOOKIE}, &slinkent};
static nfsentry dotent = {ROOTID, ".", {DOTCOOKIE}, &dotdotent};
@@ -501,7 +498,7 @@ nfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp)
res.rdr_u.rdr_reply_u.dl_entries = &slinkent;
break;
case SLINKCOOKIE:
- res.rdr_u.rdr_reply_u.dl_entries = (nfsentry *) 0;
+ res.rdr_u.rdr_reply_u.dl_entries = (nfsentry *) NULL;
break;
}
res.rdr_u.rdr_reply_u.dl_eof = TRUE;
diff --git a/contrib/amd/include/am_compat.h b/contrib/amd/include/am_compat.h
index dc3b71d74468..3463f3fa591c 100644
--- a/contrib/amd/include/am_compat.h
+++ b/contrib/amd/include/am_compat.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -90,6 +86,10 @@
# define MNTTAB_OPT_NOAC "noac"
#endif /* defined(MNT2_NFS_OPT_NOAC) && !defined(MNTTAB_OPT_NOAC) */
+#if defined(MNT2_NFS_OPT_NOACL) && !defined(MNTTAB_OPT_NOACL)
+# define MNTTAB_OPT_NOACL "noacl"
+#endif /* defined(MNT2_NFS_OPT_NOACL) && !defined(MNTTAB_OPT_NOACL) */
+
#if defined(MNT2_NFS_OPT_NOCONN) && !defined(MNTTAB_OPT_NOCONN)
# define MNTTAB_OPT_NOCONN "noconn"
# ifndef MNTTAB_OPT_CONN
@@ -176,10 +176,30 @@
#if defined(MNT2_CDFS_OPT_GENS) && !defined(MNTTAB_OPT_GENS)
# define MNTTAB_OPT_GENS "gens"
#endif /* defined(MNT2_CDFS_OPT_GENS) && !defined(MNTTAB_OPT_GENS) */
+
#if defined(MNT2_CDFS_OPT_EXTATT) && !defined(MNTTAB_OPT_EXTATT)
# define MNTTAB_OPT_EXTATT "extatt"
#endif /* defined(MNT2_CDFS_OPT_EXTATT) && !defined(MNTTAB_OPT_EXTATT) */
+#if defined(MNT2_CDFS_OPT_NOJOLIET) && !defined(MNTTAB_OPT_NOJOLIET)
+# define MNTTAB_OPT_NOJOLIET "nojoliet"
+#endif /* defined(MNT2_CDFS_OPT_NOJOLIET) && !defined(MNTTAB_OPT_NOJOLIET) */
+
+#if defined(MNT2_CDFS_OPT_NOCASETRANS) && !defined(MNTTAB_OPT_NOCASETRANS)
+# define MNTTAB_OPT_NOCASETRANS "nocasetrans"
+#endif /* defined(MNT2_CDFS_OPT_NOCASETRANS) && !defined(MNTTAB_OPT_NOCASETRANS) */
+
+#if defined(MNT2_CDFS_OPT_RRCASEINS) && !defined(MNTTAB_OPT_RRCASEINS)
+# define MNTTAB_OPT_RRCASEINS "rrcaseins"
+#endif /* defined(MNT2_CDFS_OPT_RRCASEINS) && !defined(MNTTAB_OPT_RRCASEINS) */
+
+/*
+ * Complete MNTTAB_OPT_* options based on MNT2_UDF_OPT_* mount options.
+ */
+#if defined(MNT2_UDF_OPT_CLOSESESSION) && !defined(MNTTAB_OPT_CLOSESESSION)
+# define MNTTAB_OPT_CLOSESESSION "closesession"
+#endif /* defined(MNT2_UDF_OPT_CLOSESESSION) && !defined(MNTTAB_OPT_CLOSESESSION) */
+
/*
* Complete MNTTAB_OPT_* options based on MNT2_PCFS_OPT_* mount options.
*/
@@ -236,6 +256,29 @@
# define MNTTAB_OPT_SYNC "sync"
#endif /* defined(MNT2_GEN_OPT_SYNC) && !defined(MNTTAB_OPT_SYNC) */
+#if defined(MNT2_GEN_OPT_LOG) && !defined(MNTTAB_OPT_LOG)
+# define MNTTAB_OPT_LOG "log"
+#endif /* defined(MNT2_GEN_OPT_LOG) && !defined(MNTTAB_OPT_LOG) */
+
+#if defined(MNT2_GEN_OPT_NOATIME) && !defined(MNTTAB_OPT_NOATIME)
+# define MNTTAB_OPT_NOATIME "noatime"
+#endif /* defined(MNT2_GEN_OPT_NOATIME) && !defined(MNTTAB_OPT_NOATIME) */
+
+#if defined(MNT2_GEN_OPT_NODEVMTIME) && !defined(MNTTAB_OPT_NODEVMTIME)
+# define MNTTAB_OPT_NODEVMTIME "nodevmtime"
+#endif /* defined(MNT2_GEN_OPT_NODEVMTIME) && !defined(MNTTAB_OPT_NODEVMTIME) */
+
+#if defined(MNT2_GEN_OPT_SOFTDEP) && !defined(MNTTAB_OPT_SOFTDEP)
+# define MNTTAB_OPT_SOFTDEP "softdep"
+#endif /* defined(MNT2_GEN_OPT_SOFTDEP) && !defined(MNTTAB_OPT_SOFTDEP) */
+
+#if defined(MNT2_GEN_OPT_SYMPERM) && !defined(MNTTAB_OPT_SYMPERM)
+# define MNTTAB_OPT_SYMPERM "symperm"
+#endif /* defined(MNT2_GEN_OPT_SYMPERM) && !defined(MNTTAB_OPT_SYMPERM) */
+
+#if defined(MNT2_GEN_OPT_UNION) && !defined(MNTTAB_OPT_UNION)
+# define MNTTAB_OPT_UNION "union"
+#endif /* defined(MNT2_GEN_OPT_UNION) && !defined(MNTTAB_OPT_UNION) */
/*
* Add missing MNTTAB_OPT_* options.
@@ -298,6 +341,20 @@
# define MNTTAB_OPT_DIRMASK "dirmask"
#endif /* not MNTTAB_OPT_DIRMASK */
+/* useful for udf mounts */
+#ifndef MNTTAB_OPT_USER
+# define MNTTAB_OPT_USER "user"
+#endif /* not MNTTAB_OPT_USER */
+#ifndef MNTTAB_OPT_GROUP
+# define MNTTAB_OPT_GROUP "group"
+#endif /* not MNTTAB_OPT_GROUP */
+#ifndef MNTTAB_OPT_GMTOFF
+# define MNTTAB_OPT_GMTOFF "gmtoff"
+#endif /* not MNTTAB_OPT_GMTOFF */
+#ifndef MNTTAB_OPT_SESSIONNR
+# define MNTTAB_OPT_SESSIONNR "sessionnr"
+#endif /* not MNTTAB_OPT_SESSIONNR */
+
/*
* Incomplete filesystem definitions (sunos4, irix6, solaris2)
*/
@@ -335,18 +392,32 @@ struct hsfs_args {
#endif /* defined(HAVE_FS_UFS) && !defined(ufs_args_t) */
/*
+ * if does not define struct udf_args, assume integer bit-field (linux)
+ */
+#if defined(HAVE_FS_UDF) && !defined(udf_args_t)
+# define udf_args_t u_int
+#endif /* defined(HAVE_FS_UDF) && !defined(udf_args_t) */
+
+/*
* if does not define struct efs_args, assume integer bit-field (linux)
*/
#if defined(HAVE_FS_EFS) && !defined(efs_args_t)
# define efs_args_t u_int
#endif /* defined(HAVE_FS_EFS) && !defined(efs_args_t) */
+#if defined(HAVE_FS_TMPFS) && !defined(tmpfs_args_t)
+# define tmpfs_args_t u_int
+#endif /* defined(HAVE_FS_TMPFS) && !defined(tmpfs_args_t) */
+
/*
* if does not define struct xfs_args, assume integer bit-field (linux)
*/
#if defined(HAVE_FS_XFS) && !defined(xfs_args_t)
# define xfs_args_t u_int
#endif /* defined(HAVE_FS_XFS) && !defined(xfs_args_t) */
+#if defined(HAVE_FS_EXT) && !defined(ext_args_t)
+# define ext_args_t u_int
+#endif /* defined(HAVE_FS_EXT) && !defined(ext_args_t) */
#if defined(HAVE_FS_AUTOFS) && defined(MOUNT_TYPE_AUTOFS) && !defined(MNTTYPE_AUTOFS)
# define MNTTYPE_AUTOFS "autofs"
@@ -366,6 +437,14 @@ struct hsfs_args {
#endif /* not HAVE_FS_NFS3 */
/*
+ * If NFS4, then make sure that the "sec" mnttab option is available.
+ */
+#ifdef HAVE_FS_NFS4
+# ifndef MNTTAB_OPT_SEC
+# define MNTTAB_OPT_SEC "sec"
+# endif /* not MNTTAB_OPT_SEC */
+#endif /* not HAVE_FS_NFS4 */
+/*
* If loop device (header file) exists, define mount table option
*/
#if defined(HAVE_LOOP_DEVICE) && !defined(MNTTAB_OPT_LOOP)
diff --git a/contrib/amd/include/am_defs.h b/contrib/amd/include/am_defs.h
index f3767f5b905e..bb867a49b5a5 100644
--- a/contrib/amd/include/am_defs.h
+++ b/contrib/amd/include/am_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -67,7 +63,7 @@
# define strchr index
# define strrchr rindex
# endif /* not HAVE_STRCHR */
-char *strchr(), *strrchr(), *strdup();
+char *strchr(), *strrchr();
#endif /* not STDC_HEADERS */
/*
@@ -88,6 +84,14 @@ char *strchr(), *strrchr(), *strdup();
# endif /* __GNUC__ < 2 ... */
#endif /* not __attribute__ */
+#define __IGNORE(result) \
+ __ignore((unsigned long)result)
+
+static inline void
+__ignore(unsigned long result) {
+ (void)&result;
+}
+
/*
* How to handle signals of any type
*/
@@ -134,11 +138,19 @@ struct sigevent;
/*
* Big-endian or little-endian?
*/
-#ifdef WORDS_BIGENDIAN
-# define ARCH_ENDIAN "big"
-#else /* not WORDS_BIGENDIAN */
-# define ARCH_ENDIAN "little"
-#endif /* not WORDS_BIGENDIAN */
+#ifndef BYTE_ORDER
+# if defined(WORDS_BIGENDIAN)
+# define ARCH_ENDIAN "big"
+# else /* not WORDS_BIGENDIAN */
+# define ARCH_ENDIAN "little"
+# endif /* not WORDS_BIGENDIAN */
+#else
+# if BYTE_ORDER == BIG_ENDIAN
+# define ARCH_ENDIAN "big"
+# else
+# define ARCH_ENDIAN "little"
+# endif
+#endif
/*
* Actions to take if HAVE_SYS_TYPES_H is defined.
@@ -209,12 +221,6 @@ struct sigevent;
* Actions to take if HAVE_FCNTL_H is defined.
*/
#if HAVE_FCNTL_H
-# ifdef HAVE_LINUX_LOOP_H
-/* so I can mount large files as loop devices */
-/* XXX: need to move these two LARGEFILE defines to a better place */
-# define _LARGEFILE64_SOURCE
-# define __USE_LARGEFILE64
-# endif /* HAVE_LINUX_LOOP_H */
# include <fcntl.h>
#endif /* HAVE_FCNTL_H */
@@ -318,14 +324,6 @@ typedef bool_t (*xdrproc_t) __P ((XDR *, __ptr_t, ...));
#endif /* HAVE_MNTENT_H */
/*
- * Actions to take if <sys/errno.h> exists.
- */
-#ifdef HAVE_SYS_ERRNO_H
-# include <sys/errno.h>
-extern int errno;
-#endif /* HAVE_SYS_ERRNO_H */
-
-/*
* Actions to take if <sys/fsid.h> exists.
*/
#ifdef HAVE_SYS_FSID_H
@@ -864,6 +862,10 @@ struct sockaddr_dl;
#ifdef HAVE_SYS_FS_TMP_H
# include <sys/fs/tmp.h>
#endif /* HAVE_SYS_FS_TMP_H */
+#ifdef HAVE_FS_TMPFS_TMPFS_ARGS_H
+# include <fs/tmpfs/tmpfs_args.h>
+#endif /* HAVE_FS_TMPFS_TMPFS_ARGS_H */
+
/*
* Actions to take if <sys/fs/ufs_mount.h> exists.
@@ -886,6 +888,9 @@ struct sockaddr_dl;
#ifdef HAVE_SYS_FS_EFS_CLNT_H
# include <sys/fs/efs_clnt.h>
#endif /* HAVE_SYS_FS_EFS_CLNT_H */
+#ifdef HAVE_FS_EFS_EFS_MOUNT_H
+# include <fs/efs/efs_mount.h>
+#endif /* HAVE_FS_EFS_EFS_MOUNT_H */
/*
* Actions to take if <sys/fs/xfs_clnt.h> exists.
@@ -927,6 +932,14 @@ struct sockaddr_dl;
*/
#ifdef HAVE_ERRNO_H
# include <errno.h>
+#else
+/*
+ * Actions to take if <sys/errno.h> exists.
+ */
+# ifdef HAVE_SYS_ERRNO_H
+# include <sys/errno.h>
+extern int errno;
+# endif /* HAVE_SYS_ERRNO_H */
#endif /* HAVE_ERRNO_H */
/*
@@ -958,6 +971,13 @@ struct sockaddr_dl;
#endif /* HAVE_ISOFS_CD9660_CD9660_MOUNT_H */
/*
+ * Actions to take if <fs/udf/udf_mount.h> exists.
+ */
+#ifdef HAVE_FS_UDF_UDF_MOUNT_H
+# include <fs/udf/udf_mount.h>
+#endif /* HAVE_FS_UDF_UDF_MOUNT_H */
+
+/*
* Actions to take if <mount.h> exists.
*/
#ifdef HAVE_MOUNT_H
@@ -1517,14 +1537,6 @@ extern unsigned int sleep(unsigned int seconds);
extern int strcasecmp(const char *s1, const char *s2);
#endif /* not HAVE_EXTERN_STRCASECMP */
-#ifndef HAVE_EXTERN_STRDUP
-/*
- * define this extern even if function does not exist, for it will
- * be filled in by libamu/strdup.c
- */
-extern char *strdup(const char *s);
-#endif /* not HAVE_EXTERN_STRDUP */
-
#ifndef HAVE_EXTERN_STRLCAT
/*
* define this extern even if function does not exist, for it will
diff --git a/contrib/amd/include/am_utils.h b/contrib/amd/include/am_utils.h
index b7e55ce33e2c..0de881ad8c85 100644
--- a/contrib/amd/include/am_utils.h
+++ b/contrib/amd/include/am_utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -109,8 +105,14 @@
#define XLOG_DEBUG 0x0020
#define XLOG_MAP 0x0040
#define XLOG_STATS 0x0080
-#define XLOG_DEFSTR "all,nomap,nostats" /* Default log options */
+/* log option compositions */
+#define XLOG_MASK 0x00ff /* mask for all flags */
+#define XLOG_MANDATORY (XLOG_FATAL|XLOG_ERROR) /* cannot turn these off */
#define XLOG_ALL (XLOG_FATAL|XLOG_ERROR|XLOG_USER|XLOG_WARNING|XLOG_INFO|XLOG_MAP|XLOG_STATS)
+/* default: fatal + error + user + warning + info */
+#define XLOG_DEFAULT (XLOG_MASK & (XLOG_ALL & ~XLOG_MAP & ~XLOG_STATS))
+
+/* default: no logging options */
#define NO_SUBNET "notknown" /* default subnet name for no subnet */
#define NEXP_AP (1022) /* gdmr: was 254 */
@@ -258,8 +260,6 @@ extern pid_t am_mypid;
extern int foreground; /* Foreground process */
extern int orig_umask; /* umask() on startup */
-extern int xlog_level; /* Logging level */
-extern int xlog_level_init;
extern serv_state amd_state; /* Should we go now */
extern struct in_addr myipaddr; /* (An) IP address of this host */
extern struct opt_tab xlog_opt[];
@@ -278,15 +278,17 @@ extern char *get_version_string(void);
extern char *inet_dquad(char *, size_t, u_long);
extern char *print_wires(void);
extern char *str3cat(char *, char *, char *, char *);
+extern char *strvcat(const char *, ...);
extern char *strealloc(char *, char *);
extern char *strip_selectors(char *, char *);
extern char *strnsave(const char *, int);
extern int amu_close(int fd);
extern int bind_resv_port(int, u_short *);
-extern int cmdoption(char *, struct opt_tab *, int *);
+extern int cmdoption(char *, struct opt_tab *, u_int *);
extern int compute_automounter_mount_flags(mntent_t *);
extern int compute_mount_flags(mntent_t *);
-extern int get_amd_program_number(void);
+extern void discard_nfs_args(void *, u_long);
+extern u_long get_amd_program_number(void);
extern int getcreds(struct svc_req *, uid_t *, gid_t *, SVCXPRT *);
extern int hasmntval(mntent_t *, char *);
extern unsigned int hasmntvalerr(mntent_t *, char *, int *);
@@ -300,6 +302,9 @@ extern int make_rpc_packet(char *, int, u_long, struct rpc_msg *, voidp, XDRPROC
extern int mkdirs(char *, int);
extern int mount_fs(mntent_t *, int, caddr_t, int, MTYPE_TYPE, u_long, const char *, const char *, int);
extern void nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp);
+extern void nfs_program_3(struct svc_req *rqstp, SVCXPRT *transp);
+#define get_nfs_dispatcher_version(a) \
+ ((a) == nfs_program_2 ? NFS_VERSION : NFS_VERSION3)
extern int pickup_rpc_reply(voidp, int, voidp, XDRPROC_T_TYPE);
extern int switch_option(char *);
extern int switch_to_logfile(char *logfile, int orig_umask, int truncate_log);
@@ -320,14 +325,16 @@ extern void plog(int, const char *,...)
__attribute__ ((__format__ (__printf__, 2, 3)));
extern void rmdirs(char *);
extern void rpc_msg_init(struct rpc_msg *, u_long, u_long, u_long);
-extern void set_amd_program_number(int program);
+extern void set_amd_program_number(u_long program);
extern void show_opts(int ch, struct opt_tab *);
extern void unregister_amq(void);
extern voidp xmalloc(int);
extern voidp xrealloc(voidp, int);
extern voidp xzalloc(int);
+extern char *xstrdup(const char *);
extern int check_pmap_up(char *host, struct sockaddr_in* sin);
-extern u_long get_nfs_version(char *host, struct sockaddr_in *sin, u_long nfs_version, const char *proto);
+extern u_long get_nfs_version(char *host, struct sockaddr_in *sin, u_long nfs_version, const char *proto, u_long def);
+extern int nfs_valid_version(u_long vers);
extern long get_server_pid(void);
extern void setup_sighandler(int signum, void (*handler)(int));
extern time_t clocktime(nfstime *nt);
@@ -367,9 +374,10 @@ extern void write_mntent(mntent_t *, const char *);
extern int syslogging;
#endif /* defined(HAVE_SYSLOG_H) || defined(HAVE_SYS_SYSLOG_H) */
-extern void compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct netconfig *nfsncp, struct sockaddr_in *ip_addr, u_long nfs_version, char *nfs_proto, am_nfs_handle_t *fhp, char *host_name, char *fs_name);
+extern void compute_nfs_args(void *nap, mntent_t *mntp, int genflags, struct netconfig *nfsncp, struct sockaddr_in *ip_addr, u_long nfs_version, char *nfs_proto, am_nfs_handle_t *fhp, char *host_name, char *fs_name);
+extern void destroy_nfs_args(void *nap, u_long nfs_version);
extern int create_amq_service(int *udp_soAMQp, SVCXPRT **udp_amqpp, struct netconfig **udp_amqncpp, int *tcp_soAMQp, SVCXPRT **tcp_amqpp, struct netconfig **tcp_amqncpp, u_short preferred_amq_port);
-extern int create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp));
+extern int create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp), u_long nfs_version);
extern int amu_svc_register(SVCXPRT *, u_long, u_long, void (*)(struct svc_req *, SVCXPRT *), u_long, struct netconfig *);
#ifdef HAVE_TRANSPORT_TYPE_TLI
@@ -392,8 +400,14 @@ extern int unregister_autofs_service(char *autofs_conftype);
/*
- * Network File System: the new generation
- * NFS V.3
+ * Network File System: the old faithful generation NFS V.2
+ */
+#ifndef NFS_VERSION2
+# define NFS_VERSION2 ((u_int) 2)
+#endif /* not NFS_VERSION2 */
+
+/*
+ * Network File System: the not so new anymore generation NFS V.3
*/
#ifdef HAVE_FS_NFS3
# ifndef NFS_VERSION3
@@ -401,6 +415,14 @@ extern int unregister_autofs_service(char *autofs_conftype);
# endif /* not NFS_VERSION3 */
#endif /* HAVE_FS_NFS3 */
+/*
+ * Network File System: the new generation NFS V.4
+ */
+#ifdef HAVE_FS_NFS4
+# ifndef NFS_VERSION4
+# define NFS_VERSION4 ((u_int) 4)
+# endif /* not NFS_VERSION4 */
+#endif /* HAVE_FS_NFS4 */
/**************************************************************************/
/*** DEBUGGING ***/
@@ -412,30 +434,32 @@ extern int unregister_autofs_service(char *autofs_conftype);
#ifdef DEBUG
-# define D_ALL (~(D_MTAB|D_HRTIME|D_XDRTRACE|D_DAEMON|D_FORK|D_AMQ))
-# define D_DAEMON 0x0001 /* Don't enter daemon mode */
+# define D_DAEMON 0x0001 /* Enter daemon mode */
# define D_TRACE 0x0002 /* Do protocol trace */
# define D_FULL 0x0004 /* Do full trace */
# define D_MTAB 0x0008 /* Use local mtab */
-# define D_AMQ 0x0010 /* Don't register amq program */
+# define D_AMQ 0x0010 /* Register amq program */
# define D_STR 0x0020 /* Debug string munging */
# ifdef DEBUG_MEM
# define D_MEM 0x0040 /* Trace memory allocations */
# else /* not DEBUG_MEM */
# define D_MEM 0x0000 /* Dummy */
# endif /* not DEBUG_MEM */
-# define D_FORK 0x0080 /* Don't fork server */
- /* info service specific debugging (hesiod, nis, etc) */
-# define D_INFO 0x0100
+# define D_FORK 0x0080 /* Fork server (hlfsd only) */
+# define D_INFO 0x0100 /* info service specific debugging (hesiod, nis, etc) */
# define D_HRTIME 0x0200 /* Print high resolution time stamps */
# define D_XDRTRACE 0x0400 /* Trace xdr routines */
# define D_READDIR 0x0800 /* Show browsable_dir progress */
-
-/*
- * Test mode is test mode: don't daemonize, don't register amq, don't fork,
- * don't touch system mtab, etc.
- */
-# define D_TEST (~(D_MEM|D_STR|D_XDRTRACE))
+/* debug option compositions */
+# define D_MASK 0x0fff /* mask of known flags */
+# define D_BASIC (D_TRACE|D_FULL|D_STR|D_MEM|D_INFO|D_XDRTRACE|D_READDIR)
+# define D_CONTROL (D_DAEMON|D_AMQ|D_FORK)
+/* immutable flags: cannot be changed via "amq -D" */
+# define D_IMMUTABLE (D_MTAB | D_CONTROL)
+# define D_ALL (D_BASIC | D_CONTROL)
+# define D_DEFAULT (D_MASK & D_ALL & ~D_XDRTRACE)
+/* test mode: nodaemon, noamq, nofork, (local) mtab */
+# define D_TEST (D_BASIC | D_MTAB)
# define amuDebug(x) (debug_flags & (x))
# define dlog if (amuDebug(D_FULL)) dplog
@@ -460,34 +484,49 @@ extern void malloc_verify(void);
# endif /* not DEBUG_MEM */
/* functions that depend solely on debugging */
-extern void print_nfs_args(const nfs_args_t *nap, u_long nfs_version);
+extern void print_nfs_args(const void *, u_long nfs_version);
extern int debug_option (char *opt);
extern void dplog(const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
#else /* not DEBUG */
+/* set dummy flags to zero */
+# define D_DAEMON 0x0001 /* Enter daemon mode */
+# define D_TRACE 0x0000 /* dummy: Do protocol trace */
+# define D_FULL 0x0000 /* dummy: Do full trace */
+# define D_MTAB 0x0000 /* dummy: Use local mtab */
+# define D_AMQ 0x0010 /* Register amq program */
+# define D_STR 0x0000 /* dummy: Debug string munging */
+# define D_MEM 0x0000 /* dummy: Trace memory allocations */
+# define D_FORK 0x0080 /* Fork server (hlfsd only) */
+# define D_INFO 0x0000 /* dummy: info service debugging */
+# define D_HRTIME 0x0000 /* dummy: hi-res time stamps */
+# define D_XDRTRACE 0x0000 /* dummy: Trace xdr routines */
+# define D_READDIR 0x0000 /* dummy: browsable_dir progress */
+# define D_CONTROL (D_DAEMON|D_AMQ|D_FORK)
+# define amuDebug(x) (debug_flags & (x))
/*
* If not debugging, then also reset the pointer.
* It's safer -- and besides, free() should do that anyway.
*/
-# define XFREE(x) do { free((voidp)x); x = NULL;} while (0)
-
-#define amuDebug(x) (0)
+# define XFREE(x) do { free((voidp)x); x = NULL;} while (0)
-#ifdef __GNUC__
-#define dlog(fmt...)
-#else /* not __GNUC__ */
+# if defined(HAVE_GCC_VARARGS_MACROS)
+# define dlog(fmt...)
+# elif defined(HAVE_C99_VARARGS_MACROS)
+# define dlog(...)
+# else /* no c99 varargs */
/* this define means that we CCP leaves code behind the (list,of,args) */
-#define dlog
-#endif /* not __GNUC__ */
+# define dlog
+# endif /* no c99 varargs */
-#define print_nfs_args(nap, nfs_version)
-#define debug_option(x) (1)
+# define print_nfs_args(nap, nfs_version)
+# define debug_option(x) (1)
#endif /* not DEBUG */
-extern int debug_flags; /* Debug options */
+extern u_int debug_flags; /* Debug options */
extern struct opt_tab dbg_opt[];
/**************************************************************************/
diff --git a/contrib/amd/include/am_xdr_func.h b/contrib/amd/include/am_xdr_func.h
index c4159188c799..3659942ecb6a 100644
--- a/contrib/amd/include/am_xdr_func.h
+++ b/contrib/amd/include/am_xdr_func.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -43,8 +39,26 @@
#ifdef HAVE_FS_NFS3
+#define AM_MOUNTVERS3 ((unsigned long)(3))
+
#define AM_FHSIZE3 64 /* size in bytes of a file handle (v3) */
-#define AM_MOUNTVERS3 ((unsigned long)(3))
+#define AM_NFS3_WRITEVERFSIZE 8
+#define AM_NFS3_CREATEVERFSIZE 8
+#define AM_NFS3_COOKIEVERFSIZE 8
+#define AM_ACCESS3_READ 0x0001
+#define AM_ACCESS3_LOOKUP 0x0002
+#define AM_ACCESS3_MODIFY 0x0004
+#define AM_ACCESS3_EXTEND 0x0008
+#define AM_ACCESS3_DELETE 0x0010
+#define AM_ACCESS3_EXECUTE 0x0020
+#define AM_FSF3_LINK 0x0001
+#define AM_FSF3_SYMLINK 0x0002
+#define AM_FSF3_HOMOGENEOUS 0x0008
+#define AM_FSF3_CANSETTIME 0x0010
+
+typedef char am_cookieverf3[AM_NFS3_COOKIEVERFSIZE];
+
+typedef uint64 am_cookie3;
/* NFSv3 handle */
struct am_nfs_fh3 {
@@ -131,37 +145,830 @@ struct am_diropargs3 {
};
typedef struct am_diropargs3 am_diropargs3;
+enum am_ftype3 {
+ AM_NF3REG = 1,
+ AM_NF3DIR = 2,
+ AM_NF3BLK = 3,
+ AM_NF3CHR = 4,
+ AM_NF3LNK = 5,
+ AM_NF3SOCK = 6,
+ AM_NF3FIFO = 7,
+};
+typedef enum am_ftype3 am_ftype3;
+
+typedef u_int am_mode3;
+
+typedef u_int am_uid3;
+
+typedef u_int am_gid3;
+
+typedef uint64 am_size3;
+
+typedef uint64 am_fileid3;
+
+struct am_specdata3 {
+ u_int specdata1;
+ u_int specdata2;
+};
+typedef struct am_specdata3 am_specdata3;
+
+struct am_nfstime3 {
+ u_int seconds;
+ u_int nseconds;
+};
+typedef struct am_nfstime3 am_nfstime3;
+
+struct am_fattr3 {
+ am_ftype3 type;
+ am_mode3 mode;
+ u_int nlink;
+ am_uid3 uid;
+ am_gid3 gid;
+ am_size3 size;
+ am_size3 used;
+ am_specdata3 rdev;
+ uint64 fsid;
+ am_fileid3 fileid;
+ am_nfstime3 atime;
+ am_nfstime3 mtime;
+ am_nfstime3 ctime;
+};
+typedef struct am_fattr3 am_fattr3;
+
+struct am_post_op_attr {
+ bool_t attributes_follow;
+ union {
+ am_fattr3 attributes;
+ } am_post_op_attr_u;
+};
+typedef struct am_post_op_attr am_post_op_attr;
+
+enum am_stable_how {
+ AM_UNSTABLE = 0,
+ AM_DATA_SYNC = 1,
+ AM_FILE_SYNC = 2,
+};
+typedef enum am_stable_how am_stable_how;
+
+typedef uint64 am_offset3;
+
+typedef u_int am_count3;
+
+struct am_wcc_attr {
+ am_size3 size;
+ am_nfstime3 mtime;
+ am_nfstime3 ctime;
+};
+typedef struct am_wcc_attr am_wcc_attr;
+
+struct am_pre_op_attr {
+ bool_t attributes_follow;
+ union {
+ am_wcc_attr attributes;
+ } am_pre_op_attr_u;
+};
+typedef struct am_pre_op_attr am_pre_op_attr;
+
+struct am_wcc_data {
+ am_pre_op_attr before;
+ am_post_op_attr after;
+};
+typedef struct am_wcc_data am_wcc_data;
+
+struct am_WRITE3args {
+ am_nfs_fh3 file;
+ am_offset3 offset;
+ am_count3 count;
+ am_stable_how stable;
+ struct {
+ u_int data_len;
+ char *data_val;
+ } data;
+};
+typedef struct am_WRITE3args am_WRITE3args;
+
+typedef char am_writeverf3[AM_NFS3_WRITEVERFSIZE];
+
+struct am_WRITE3resok {
+ am_wcc_data file_wcc;
+ am_count3 count;
+ am_stable_how committed;
+ am_writeverf3 verf;
+};
+typedef struct am_WRITE3resok am_WRITE3resok;
+
+struct am_WRITE3resfail {
+ am_wcc_data file_wcc;
+};
+typedef struct am_WRITE3resfail am_WRITE3resfail;
+
+struct am_WRITE3res {
+ am_nfsstat3 status;
+ union {
+ am_WRITE3resok ok;
+ am_WRITE3resfail fail;
+ } res_u;
+};
+typedef struct am_WRITE3res am_WRITE3res;
+
struct am_LOOKUP3args {
- am_diropargs3 what;
+ am_diropargs3 what;
};
typedef struct am_LOOKUP3args am_LOOKUP3args;
struct am_LOOKUP3resok {
- am_nfs_fh3 object;
-#if 0
- post_op_attr obj_attributes;
- post_op_attr dir_attributes;
-#endif
+ am_nfs_fh3 object;
+ am_post_op_attr obj_attributes;
+ am_post_op_attr dir_attributes;
};
typedef struct am_LOOKUP3resok am_LOOKUP3resok;
struct am_LOOKUP3resfail {
-#if 0
- post_op_attr dir_attributes;
-#else
- char dummy; /* cannot have an empty declaration */
-#endif
+ am_post_op_attr dir_attributes;
};
typedef struct am_LOOKUP3resfail am_LOOKUP3resfail;
struct am_LOOKUP3res {
- am_nfsstat3 status;
- union {
- am_LOOKUP3resok ok;
- am_LOOKUP3resfail fail;
- } res_u;
+ am_nfsstat3 status;
+ union {
+ am_LOOKUP3resok ok;
+ am_LOOKUP3resfail fail;
+ } res_u;
};
typedef struct am_LOOKUP3res am_LOOKUP3res;
+
+struct am_COMMIT3args {
+ am_nfs_fh3 file;
+ am_offset3 offset;
+ am_count3 count;
+};
+typedef struct am_COMMIT3args am_COMMIT3args;
+
+struct am_COMMIT3resok {
+ am_wcc_data file_wcc;
+ am_writeverf3 verf;
+};
+typedef struct am_COMMIT3resok am_COMMIT3resok;
+
+struct am_COMMIT3resfail {
+ am_wcc_data file_wcc;
+};
+typedef struct am_COMMIT3resfail am_COMMIT3resfail;
+
+struct am_COMMIT3res {
+ am_nfsstat3 status;
+ union {
+ am_COMMIT3resok ok;
+ am_COMMIT3resfail fail;
+ } res_u;
+};
+typedef struct am_COMMIT3res am_COMMIT3res;
+
+struct am_ACCESS3args {
+ am_nfs_fh3 object;
+ u_int access;
+};
+typedef struct am_ACCESS3args am_ACCESS3args;
+
+struct am_ACCESS3resok {
+ am_post_op_attr obj_attributes;
+ u_int access;
+};
+typedef struct am_ACCESS3resok am_ACCESS3resok;
+
+struct am_ACCESS3resfail {
+ am_post_op_attr obj_attributes;
+};
+typedef struct am_ACCESS3resfail am_ACCESS3resfail;
+
+struct am_ACCESS3res {
+ am_nfsstat3 status;
+ union {
+ am_ACCESS3resok ok;
+ am_ACCESS3resfail fail;
+ } res_u;
+};
+typedef struct am_ACCESS3res am_ACCESS3res;
+
+struct am_GETATTR3args {
+ am_nfs_fh3 object;
+};
+typedef struct am_GETATTR3args am_GETATTR3args;
+
+struct am_GETATTR3resok {
+ am_fattr3 obj_attributes;
+};
+typedef struct am_GETATTR3resok am_GETATTR3resok;
+
+struct am_GETATTR3res {
+ am_nfsstat3 status;
+ union {
+ am_GETATTR3resok ok;
+ } res_u;
+};
+typedef struct am_GETATTR3res am_GETATTR3res;
+
+enum am_time_how {
+ AM_DONT_CHANGE = 0,
+ AM_SET_TO_SERVER_TIME = 1,
+ AM_SET_TO_CLIENT_TIME = 2,
+};
+typedef enum am_time_how am_time_how;
+
+struct am_set_mode3 {
+ bool_t set_it;
+ union {
+ am_mode3 mode;
+ } am_set_mode3_u;
+};
+typedef struct am_set_mode3 am_set_mode3;
+
+struct am_set_uid3 {
+ bool_t set_it;
+ union {
+ am_uid3 uid;
+ } am_set_uid3_u;
+};
+typedef struct am_set_uid3 am_set_uid3;
+
+struct am_set_gid3 {
+ bool_t set_it;
+ union {
+ am_gid3 gid;
+ } am_set_gid3_u;
+};
+typedef struct am_set_gid3 am_set_gid3;
+
+struct am_set_size3 {
+ bool_t set_it;
+ union {
+ am_size3 size;
+ } am_set_size3_u;
+};
+typedef struct am_set_size3 am_set_size3;
+
+struct am_set_atime {
+ am_time_how set_it;
+ union {
+ am_nfstime3 atime;
+ } am_set_atime_u;
+};
+typedef struct am_set_atime am_set_atime;
+
+struct am_set_mtime {
+ am_time_how set_it;
+ union {
+ am_nfstime3 mtime;
+ } am_set_mtime_u;
+};
+typedef struct am_set_mtime am_set_mtime;
+
+struct am_sattr3 {
+ am_set_mode3 mode;
+ am_set_uid3 uid;
+ am_set_gid3 gid;
+ am_set_size3 size;
+ am_set_atime atime;
+ am_set_mtime mtime;
+};
+typedef struct am_sattr3 am_sattr3;
+
+enum am_createmode3 {
+ AM_UNCHECKED = 0,
+ AM_GUARDED = 1,
+ AM_EXCLUSIVE = 2,
+};
+typedef enum am_createmode3 am_createmode3;
+
+typedef char am_createverf3[AM_NFS3_CREATEVERFSIZE];
+
+struct am_createhow3 {
+ am_createmode3 mode;
+ union {
+ am_sattr3 obj_attributes;
+ am_sattr3 g_obj_attributes;
+ am_createverf3 verf;
+ } am_createhow3_u;
+};
+typedef struct am_createhow3 am_createhow3;
+
+struct am_CREATE3args {
+ am_diropargs3 where;
+ am_createhow3 how;
+};
+typedef struct am_CREATE3args am_CREATE3args;
+
+struct am_post_op_fh3 {
+ bool_t handle_follows;
+ union {
+ am_nfs_fh3 handle;
+ } am_post_op_fh3_u;
+};
+typedef struct am_post_op_fh3 am_post_op_fh3;
+
+struct am_CREATE3resok {
+ am_post_op_fh3 obj;
+ am_post_op_attr obj_attributes;
+ am_wcc_data dir_wcc;
+};
+typedef struct am_CREATE3resok am_CREATE3resok;
+
+struct am_CREATE3resfail {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_CREATE3resfail am_CREATE3resfail;
+
+struct am_CREATE3res {
+ am_nfsstat3 status;
+ union {
+ am_CREATE3resok ok;
+ am_CREATE3resfail fail;
+ } res_u;
+};
+typedef struct am_CREATE3res am_CREATE3res;
+
+struct am_REMOVE3args {
+ am_diropargs3 object;
+};
+typedef struct am_REMOVE3args am_REMOVE3args;
+
+struct am_REMOVE3resok {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_REMOVE3resok am_REMOVE3resok;
+
+struct am_REMOVE3resfail {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_REMOVE3resfail am_REMOVE3resfail;
+
+struct am_REMOVE3res {
+ am_nfsstat3 status;
+ union {
+ am_REMOVE3resok ok;
+ am_REMOVE3resfail fail;
+ } res_u;
+};
+typedef struct am_REMOVE3res am_REMOVE3res;
+
+struct am_READ3args {
+ am_nfs_fh3 file;
+ am_offset3 offset;
+ am_count3 count;
+};
+typedef struct am_READ3args am_READ3args;
+
+struct am_READ3resok {
+ am_post_op_attr file_attributes;
+ am_count3 count;
+ bool_t eof;
+ struct {
+ u_int data_len;
+ char *data_val;
+ } data;
+};
+typedef struct am_READ3resok am_READ3resok;
+
+struct am_READ3resfail {
+ am_post_op_attr file_attributes;
+};
+typedef struct am_READ3resfail am_READ3resfail;
+
+struct am_READ3res {
+ am_nfsstat3 status;
+ union {
+ am_READ3resok ok;
+ am_READ3resfail fail;
+ } res_u;
+};
+typedef struct am_READ3res am_READ3res;
+
+struct am_FSINFO3args {
+ am_nfs_fh3 fsroot;
+};
+typedef struct am_FSINFO3args am_FSINFO3args;
+
+struct am_FSINFO3resok {
+ am_post_op_attr obj_attributes;
+ u_int rtmax;
+ u_int rtpref;
+ u_int rtmult;
+ u_int wtmax;
+ u_int wtpref;
+ u_int wtmult;
+ u_int dtpref;
+ am_size3 maxfilesize;
+ am_nfstime3 time_delta;
+ u_int properties;
+};
+typedef struct am_FSINFO3resok am_FSINFO3resok;
+
+struct am_FSINFO3resfail {
+ am_post_op_attr obj_attributes;
+};
+typedef struct am_FSINFO3resfail am_FSINFO3resfail;
+
+struct am_FSINFO3res {
+ am_nfsstat3 status;
+ union {
+ am_FSINFO3resok ok;
+ am_FSINFO3resfail fail;
+ } res_u;
+};
+typedef struct am_FSINFO3res am_FSINFO3res;
+
+struct am_FSSTAT3args {
+ am_nfs_fh3 fsroot;
+};
+typedef struct am_FSSTAT3args am_FSSTAT3args;
+
+struct am_FSSTAT3resok {
+ am_post_op_attr obj_attributes;
+ am_size3 tbytes;
+ am_size3 fbytes;
+ am_size3 abytes;
+ am_size3 tfiles;
+ am_size3 ffiles;
+ am_size3 afiles;
+ u_int invarsec;
+};
+typedef struct am_FSSTAT3resok am_FSSTAT3resok;
+
+struct am_FSSTAT3resfail {
+ am_post_op_attr obj_attributes;
+};
+typedef struct am_FSSTAT3resfail am_FSSTAT3resfail;
+
+struct am_FSSTAT3res {
+ am_nfsstat3 status;
+ union {
+ am_FSSTAT3resok ok;
+ am_FSSTAT3resfail fail;
+ } res_u;
+};
+typedef struct am_FSSTAT3res am_FSSTAT3res;
+
+struct am_PATHCONF3args {
+ am_nfs_fh3 object;
+};
+typedef struct am_PATHCONF3args am_PATHCONF3args;
+
+struct am_PATHCONF3resok {
+ am_post_op_attr obj_attributes;
+ u_int linkmax;
+ u_int name_max;
+ bool_t no_trunc;
+ bool_t chown_restricted;
+ bool_t case_insensitive;
+ bool_t case_preserving;
+};
+typedef struct am_PATHCONF3resok am_PATHCONF3resok;
+
+struct am_PATHCONF3resfail {
+ am_post_op_attr obj_attributes;
+};
+typedef struct am_PATHCONF3resfail am_PATHCONF3resfail;
+
+struct am_PATHCONF3res {
+ am_nfsstat3 status;
+ union {
+ am_PATHCONF3resok ok;
+ am_PATHCONF3resfail fail;
+ } res_u;
+};
+typedef struct am_PATHCONF3res am_PATHCONF3res;
+
+typedef char *am_nfspath3;
+
+struct am_symlinkdata3 {
+ am_sattr3 symlink_attributes;
+ am_nfspath3 symlink_data;
+};
+typedef struct am_symlinkdata3 am_symlinkdata3;
+
+struct am_SYMLINK3args {
+ am_diropargs3 where;
+ am_symlinkdata3 symlink;
+};
+typedef struct am_SYMLINK3args am_SYMLINK3args;
+
+struct am_SYMLINK3resok {
+ am_post_op_fh3 obj;
+ am_post_op_attr obj_attributes;
+ am_wcc_data dir_wcc;
+};
+typedef struct am_SYMLINK3resok am_SYMLINK3resok;
+
+struct am_SYMLINK3resfail {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_SYMLINK3resfail am_SYMLINK3resfail;
+
+struct am_SYMLINK3res {
+ am_nfsstat3 status;
+ union {
+ am_SYMLINK3resok ok;
+ am_SYMLINK3resfail fail;
+ } res_u;
+};
+typedef struct am_SYMLINK3res am_SYMLINK3res;
+
+struct am_READLINK3args {
+ am_nfs_fh3 symlink;
+};
+typedef struct am_READLINK3args am_READLINK3args;
+
+struct am_READLINK3resok {
+ am_post_op_attr symlink_attributes;
+ am_nfspath3 data;
+};
+typedef struct am_READLINK3resok am_READLINK3resok;
+
+struct am_READLINK3resfail {
+ am_post_op_attr symlink_attributes;
+};
+typedef struct am_READLINK3resfail am_READLINK3resfail;
+
+struct am_READLINK3res {
+ am_nfsstat3 status;
+ union {
+ am_READLINK3resok ok;
+ am_READLINK3resfail fail;
+ } res_u;
+};
+typedef struct am_READLINK3res am_READLINK3res;
+
+struct am_devicedata3 {
+ am_sattr3 dev_attributes;
+ am_specdata3 spec;
+};
+typedef struct am_devicedata3 am_devicedata3;
+
+struct am_mknoddata3 {
+ am_ftype3 type;
+ union {
+ am_devicedata3 chr_device;
+ am_devicedata3 blk_device;
+ am_sattr3 sock_attributes;
+ am_sattr3 pipe_attributes;
+ } am_mknoddata3_u;
+};
+typedef struct am_mknoddata3 am_mknoddata3;
+
+struct am_MKNOD3args {
+ am_diropargs3 where;
+ am_mknoddata3 what;
+};
+typedef struct am_MKNOD3args am_MKNOD3args;
+
+struct am_MKNOD3resok {
+ am_post_op_fh3 obj;
+ am_post_op_attr obj_attributes;
+ am_wcc_data dir_wcc;
+};
+typedef struct am_MKNOD3resok am_MKNOD3resok;
+
+struct am_MKNOD3resfail {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_MKNOD3resfail am_MKNOD3resfail;
+
+struct am_MKNOD3res {
+ am_nfsstat3 status;
+ union {
+ am_MKNOD3resok ok;
+ am_MKNOD3resfail fail;
+ } res_u;
+};
+typedef struct am_MKNOD3res am_MKNOD3res;
+
+struct am_MKDIR3args {
+ am_diropargs3 where;
+ am_sattr3 attributes;
+};
+typedef struct am_MKDIR3args am_MKDIR3args;
+
+struct am_MKDIR3resok {
+ am_post_op_fh3 obj;
+ am_post_op_attr obj_attributes;
+ am_wcc_data dir_wcc;
+};
+typedef struct am_MKDIR3resok am_MKDIR3resok;
+
+struct am_MKDIR3resfail {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_MKDIR3resfail am_MKDIR3resfail;
+
+struct am_MKDIR3res {
+ am_nfsstat3 status;
+ union {
+ am_MKDIR3resok ok;
+ am_MKDIR3resfail fail;
+ } res_u;
+};
+typedef struct am_MKDIR3res am_MKDIR3res;
+
+struct am_RMDIR3args {
+ am_diropargs3 object;
+};
+typedef struct am_RMDIR3args am_RMDIR3args;
+
+struct am_RMDIR3resok {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_RMDIR3resok am_RMDIR3resok;
+
+struct am_RMDIR3resfail {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_RMDIR3resfail am_RMDIR3resfail;
+
+struct am_RMDIR3res {
+ am_nfsstat3 status;
+ union {
+ am_RMDIR3resok ok;
+ am_RMDIR3resfail fail;
+ } res_u;
+};
+typedef struct am_RMDIR3res am_RMDIR3res;
+
+struct am_RENAME3args {
+ am_diropargs3 from;
+ am_diropargs3 to;
+};
+typedef struct am_RENAME3args am_RENAME3args;
+
+struct am_RENAME3resok {
+ am_wcc_data fromdir_wcc;
+ am_wcc_data todir_wcc;
+};
+typedef struct am_RENAME3resok am_RENAME3resok;
+
+struct am_RENAME3resfail {
+ am_wcc_data fromdir_wcc;
+ am_wcc_data todir_wcc;
+};
+typedef struct am_RENAME3resfail am_RENAME3resfail;
+
+struct am_RENAME3res {
+ am_nfsstat3 status;
+ union {
+ am_RENAME3resok ok;
+ am_RENAME3resfail fail;
+ } res_u;
+};
+typedef struct am_RENAME3res am_RENAME3res;
+
+struct am_READDIRPLUS3args {
+ am_nfs_fh3 dir;
+ am_cookie3 cookie;
+ am_cookieverf3 cookieverf;
+ am_count3 dircount;
+ am_count3 maxcount;
+};
+typedef struct am_READDIRPLUS3args am_READDIRPLUS3args;
+
+struct am_entryplus3 {
+ am_fileid3 fileid;
+ am_filename3 name;
+ am_cookie3 cookie;
+ am_post_op_attr name_attributes;
+ am_post_op_fh3 name_handle;
+ struct am_entryplus3 *nextentry;
+};
+typedef struct am_entryplus3 am_entryplus3;
+
+struct am_dirlistplus3 {
+ am_entryplus3 *entries;
+ bool_t eof;
+};
+typedef struct am_dirlistplus3 am_dirlistplus3;
+
+struct am_READDIRPLUS3resok {
+ am_post_op_attr dir_attributes;
+ am_cookieverf3 cookieverf;
+ am_dirlistplus3 reply;
+};
+typedef struct am_READDIRPLUS3resok am_READDIRPLUS3resok;
+
+struct am_READDIRPLUS3resfail {
+ am_post_op_attr dir_attributes;
+};
+typedef struct am_READDIRPLUS3resfail am_READDIRPLUS3resfail;
+
+struct am_READDIRPLUS3res {
+ am_nfsstat3 status;
+ union {
+ am_READDIRPLUS3resok ok;
+ am_READDIRPLUS3resfail fail;
+ } res_u;
+};
+typedef struct am_READDIRPLUS3res am_READDIRPLUS3res;
+
+struct am_READDIR3args {
+ am_nfs_fh3 dir;
+ am_cookie3 cookie;
+ am_cookieverf3 cookieverf;
+ am_count3 count;
+};
+typedef struct am_READDIR3args am_READDIR3args;
+
+struct am_entry3 {
+ am_fileid3 fileid;
+ am_filename3 name;
+ am_cookie3 cookie;
+ struct am_entry3 *nextentry;
+};
+typedef struct am_entry3 am_entry3;
+
+struct am_dirlist3 {
+ am_entry3 *entries;
+ bool_t eof;
+};
+typedef struct am_dirlist3 am_dirlist3;
+
+struct am_READDIR3resok {
+ am_post_op_attr dir_attributes;
+ am_cookieverf3 cookieverf;
+ am_dirlist3 reply;
+};
+typedef struct am_READDIR3resok am_READDIR3resok;
+
+struct am_READDIR3resfail {
+ am_post_op_attr dir_attributes;
+};
+typedef struct am_READDIR3resfail am_READDIR3resfail;
+
+struct am_READDIR3res {
+ am_nfsstat3 status;
+ union {
+ am_READDIR3resok ok;
+ am_READDIR3resfail fail;
+ } res_u;
+};
+typedef struct am_READDIR3res am_READDIR3res;
+
+struct am_LINK3args {
+ am_nfs_fh3 file;
+ am_diropargs3 link;
+};
+typedef struct am_LINK3args am_LINK3args;
+
+struct am_LINK3resok {
+ am_post_op_attr file_attributes;
+ am_wcc_data linkdir_wcc;
+};
+typedef struct am_LINK3resok am_LINK3resok;
+
+struct am_LINK3resfail {
+ am_post_op_attr file_attributes;
+ am_wcc_data linkdir_wcc;
+};
+typedef struct am_LINK3resfail am_LINK3resfail;
+
+struct am_LINK3res {
+ am_nfsstat3 status;
+ union {
+ am_LINK3resok ok;
+ am_LINK3resfail fail;
+ } res_u;
+};
+typedef struct am_LINK3res am_LINK3res;
+
+struct am_sattrguard3 {
+ bool_t check;
+ union {
+ am_nfstime3 obj_ctime;
+ } am_sattrguard3_u;
+};
+typedef struct am_sattrguard3 am_sattrguard3;
+
+struct am_SETATTR3args {
+ am_nfs_fh3 object;
+ am_sattr3 new_attributes;
+ am_sattrguard3 guard;
+};
+typedef struct am_SETATTR3args am_SETATTR3args;
+
+struct am_SETATTR3resok {
+ am_wcc_data obj_wcc;
+};
+typedef struct am_SETATTR3resok am_SETATTR3resok;
+
+struct am_SETATTR3resfail {
+ am_wcc_data obj_wcc;
+};
+typedef struct am_SETATTR3resfail am_SETATTR3resfail;
+
+struct am_SETATTR3res {
+ am_nfsstat3 status;
+ union {
+ am_SETATTR3resok ok;
+ am_SETATTR3resfail fail;
+ } res_u;
+};
+typedef struct am_SETATTR3res am_SETATTR3res;
#endif /* HAVE_FS_NFS3 */
/*
@@ -310,6 +1117,74 @@ bool_t xdr_writeargs(XDR *xdrs, nfswriteargs *objp);
* NFS3 XDR FUNCTIONS:
*/
#ifdef HAVE_FS_NFS3
+#define AM_NFS3_NULL 0
+void * am_nfs3_null_3(void *, CLIENT *);
+void * am_nfs3_null_3_svc(void *, struct svc_req *);
+#define AM_NFS3_GETATTR 1
+am_GETATTR3res * am_nfs3_getattr_3(am_GETATTR3args *, CLIENT *);
+am_GETATTR3res * am_nfs3_getattr_3_svc(am_GETATTR3args *, struct svc_req *);
+#define AM_NFS3_SETATTR 2
+am_SETATTR3res * am_nfs3_setattr_3(am_SETATTR3args *, CLIENT *);
+am_SETATTR3res * am_nfs3_setattr_3_svc(am_SETATTR3args *, struct svc_req *);
+#define AM_NFS3_LOOKUP 3
+am_LOOKUP3res * am_nfs3_lookup_3(am_LOOKUP3args *, CLIENT *);
+am_LOOKUP3res * am_nfs3_lookup_3_svc(am_LOOKUP3args *, struct svc_req *);
+#define AM_NFS3_ACCESS 4
+am_ACCESS3res * am_nfs3_access_3(am_ACCESS3args *, CLIENT *);
+am_ACCESS3res * am_nfs3_access_3_svc(am_ACCESS3args *, struct svc_req *);
+#define AM_NFS3_READLINK 5
+am_READLINK3res * am_nfs3_readlink_3(am_READLINK3args *, CLIENT *);
+am_READLINK3res * am_nfs3_readlink_3_svc(am_READLINK3args *, struct svc_req *);
+#define AM_NFS3_READ 6
+am_READ3res * am_nfs3_read_3(am_READ3args *, CLIENT *);
+am_READ3res * am_nfs3_read_3_svc(am_READ3args *, struct svc_req *);
+#define AM_NFS3_WRITE 7
+am_WRITE3res * am_nfs3_write_3(am_WRITE3args *, CLIENT *);
+am_WRITE3res * am_nfs3_write_3_svc(am_WRITE3args *, struct svc_req *);
+#define AM_NFS3_CREATE 8
+am_CREATE3res * am_nfs3_create_3(am_CREATE3args *, CLIENT *);
+am_CREATE3res * am_nfs3_create_3_svc(am_CREATE3args *, struct svc_req *);
+#define AM_NFS3_MKDIR 9
+am_MKDIR3res * am_nfs3_mkdir_3(am_MKDIR3args *, CLIENT *);
+am_MKDIR3res * am_nfs3_mkdir_3_svc(am_MKDIR3args *, struct svc_req *);
+#define AM_NFS3_SYMLINK 10
+am_SYMLINK3res * am_nfs3_symlink_3(am_SYMLINK3args *, CLIENT *);
+am_SYMLINK3res * am_nfs3_symlink_3_svc(am_SYMLINK3args *, struct svc_req *);
+#define AM_NFS3_MKNOD 11
+am_MKNOD3res * am_nfs3_mknod_3(am_MKNOD3args *, CLIENT *);
+am_MKNOD3res * am_nfs3_mknod_3_svc(am_MKNOD3args *, struct svc_req *);
+#define AM_NFS3_REMOVE 12
+am_REMOVE3res * am_nfs3_remove_3(am_REMOVE3args *, CLIENT *);
+am_REMOVE3res * am_nfs3_remove_3_svc(am_REMOVE3args *, struct svc_req *);
+#define AM_NFS3_RMDIR 13
+am_RMDIR3res * am_nfs3_rmdir_3(am_RMDIR3args *, CLIENT *);
+am_RMDIR3res * am_nfs3_rmdir_3_svc(am_RMDIR3args *, struct svc_req *);
+#define AM_NFS3_RENAME 14
+am_RENAME3res * am_nfs3_rename_3(am_RENAME3args *, CLIENT *);
+am_RENAME3res * am_nfs3_rename_3_svc(am_RENAME3args *, struct svc_req *);
+#define AM_NFS3_LINK 15
+am_LINK3res * am_nfs3_link_3(am_LINK3args *, CLIENT *);
+am_LINK3res * am_nfs3_link_3_svc(am_LINK3args *, struct svc_req *);
+#define AM_NFS3_READDIR 16
+am_READDIR3res * am_nfs3_readdir_3(am_READDIR3args *, CLIENT *);
+am_READDIR3res * am_nfs3_readdir_3_svc(am_READDIR3args *, struct svc_req *);
+#define AM_NFS3_READDIRPLUS 17
+am_READDIRPLUS3res * am_nfs3_readdirplus_3(am_READDIRPLUS3args *, CLIENT *);
+am_READDIRPLUS3res * am_nfs3_readdirplus_3_svc(am_READDIRPLUS3args *, struct svc_req *);
+#define AM_NFS3_FSSTAT 18
+am_FSSTAT3res * am_nfs3_fsstat_3(am_FSSTAT3args *, CLIENT *);
+am_FSSTAT3res * am_nfs3_fsstat_3_svc(am_FSSTAT3args *, struct svc_req *);
+#define AM_NFS3_FSINFO 19
+am_FSINFO3res * am_nfs3_fsinfo_3(am_FSINFO3args *, CLIENT *);
+am_FSINFO3res * am_nfs3_fsinfo_3_svc(am_FSINFO3args *, struct svc_req *);
+#define AM_NFS3_PATHCONF 20
+am_PATHCONF3res * am_nfs3_pathconf_3(am_PATHCONF3args *, CLIENT *);
+am_PATHCONF3res * am_nfs3_pathconf_3_svc(am_PATHCONF3args *, struct svc_req *);
+#define AM_NFS3_COMMIT 21
+am_COMMIT3res * am_nfs3_commit_3(am_COMMIT3args *, CLIENT *);
+am_COMMIT3res * am_nfs3_commit_3_svc(am_COMMIT3args *, struct svc_req *);
+int nfs_program_3_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
+
bool_t xdr_am_fhandle3(XDR *xdrs, am_fhandle3 *objp);
bool_t xdr_am_mountstat3(XDR *xdrs, am_mountstat3 *objp);
bool_t xdr_am_mountres3_ok(XDR *xdrs, am_mountres3_ok *objp);
@@ -322,6 +1197,134 @@ bool_t xdr_am_LOOKUP3resfail(XDR *xdrs, am_LOOKUP3resfail *objp);
bool_t xdr_am_LOOKUP3resok(XDR *xdrs, am_LOOKUP3resok *objp);
bool_t xdr_am_nfsstat3(XDR *xdrs, am_nfsstat3 *objp);
bool_t xdr_am_nfs_fh3(XDR *xdrs, am_nfs_fh3 *objp);
+bool_t xdr_am_cookieverf3 (XDR *, am_cookieverf3);
+bool_t xdr_uint64 (XDR *, uint64*);
+bool_t xdr_am_cookie3 (XDR *, am_cookie3*);
+bool_t xdr_am_nfs_fh3 (XDR *, am_nfs_fh3*);
+bool_t xdr_am_nfsstat3 (XDR *, am_nfsstat3*);
+bool_t xdr_am_filename3 (XDR *, am_filename3*);
+bool_t xdr_am_diropargs3 (XDR *, am_diropargs3*);
+bool_t xdr_am_ftype3 (XDR *, am_ftype3*);
+bool_t xdr_am_mode3 (XDR *, am_mode3*);
+bool_t xdr_am_uid3 (XDR *, am_uid3*);
+bool_t xdr_am_gid3 (XDR *, am_gid3*);
+bool_t xdr_am_size3 (XDR *, am_size3*);
+bool_t xdr_am_fileid3 (XDR *, am_fileid3*);
+bool_t xdr_am_specdata3 (XDR *, am_specdata3*);
+bool_t xdr_am_nfstime3 (XDR *, am_nfstime3*);
+bool_t xdr_am_fattr3 (XDR *, am_fattr3*);
+bool_t xdr_am_post_op_attr (XDR *, am_post_op_attr*);
+bool_t xdr_am_stable_how (XDR *, am_stable_how*);
+bool_t xdr_am_offset3 (XDR *, am_offset3*);
+bool_t xdr_am_count3 (XDR *, am_count3*);
+bool_t xdr_am_wcc_attr (XDR *, am_wcc_attr*);
+bool_t xdr_am_pre_op_attr (XDR *, am_pre_op_attr*);
+bool_t xdr_am_wcc_data (XDR *, am_wcc_data*);
+bool_t xdr_am_WRITE3args (XDR *, am_WRITE3args*);
+bool_t xdr_am_writeverf3 (XDR *, am_writeverf3);
+bool_t xdr_am_WRITE3resok (XDR *, am_WRITE3resok*);
+bool_t xdr_am_WRITE3resfail (XDR *, am_WRITE3resfail*);
+bool_t xdr_am_WRITE3res (XDR *, am_WRITE3res*);
+bool_t xdr_am_LOOKUP3args (XDR *, am_LOOKUP3args*);
+bool_t xdr_am_LOOKUP3resok (XDR *, am_LOOKUP3resok*);
+bool_t xdr_am_LOOKUP3resfail (XDR *, am_LOOKUP3resfail*);
+bool_t xdr_am_LOOKUP3res (XDR *, am_LOOKUP3res*);
+bool_t xdr_am_COMMIT3args (XDR *, am_COMMIT3args*);
+bool_t xdr_am_COMMIT3resok (XDR *, am_COMMIT3resok*);
+bool_t xdr_am_COMMIT3resfail (XDR *, am_COMMIT3resfail*);
+bool_t xdr_am_COMMIT3res (XDR *, am_COMMIT3res*);
+bool_t xdr_am_ACCESS3args (XDR *, am_ACCESS3args*);
+bool_t xdr_am_ACCESS3resok (XDR *, am_ACCESS3resok*);
+bool_t xdr_am_ACCESS3resfail (XDR *, am_ACCESS3resfail*);
+bool_t xdr_am_ACCESS3res (XDR *, am_ACCESS3res*);
+bool_t xdr_am_GETATTR3args (XDR *, am_GETATTR3args*);
+bool_t xdr_am_GETATTR3resok (XDR *, am_GETATTR3resok*);
+bool_t xdr_am_GETATTR3res (XDR *, am_GETATTR3res*);
+bool_t xdr_am_time_how (XDR *, am_time_how*);
+bool_t xdr_am_set_mode3 (XDR *, am_set_mode3*);
+bool_t xdr_am_set_uid3 (XDR *, am_set_uid3*);
+bool_t xdr_am_set_gid3 (XDR *, am_set_gid3*);
+bool_t xdr_am_set_size3 (XDR *, am_set_size3*);
+bool_t xdr_am_set_atime (XDR *, am_set_atime*);
+bool_t xdr_am_set_mtime (XDR *, am_set_mtime*);
+bool_t xdr_am_sattr3 (XDR *, am_sattr3*);
+bool_t xdr_am_createmode3 (XDR *, am_createmode3*);
+bool_t xdr_am_createverf3 (XDR *, am_createverf3);
+bool_t xdr_am_createhow3 (XDR *, am_createhow3*);
+bool_t xdr_am_CREATE3args (XDR *, am_CREATE3args*);
+bool_t xdr_am_post_op_fh3 (XDR *, am_post_op_fh3*);
+bool_t xdr_am_CREATE3resok (XDR *, am_CREATE3resok*);
+bool_t xdr_am_CREATE3resfail (XDR *, am_CREATE3resfail*);
+bool_t xdr_am_CREATE3res (XDR *, am_CREATE3res*);
+bool_t xdr_am_REMOVE3args (XDR *, am_REMOVE3args*);
+bool_t xdr_am_REMOVE3resok (XDR *, am_REMOVE3resok*);
+bool_t xdr_am_REMOVE3resfail (XDR *, am_REMOVE3resfail*);
+bool_t xdr_am_REMOVE3res (XDR *, am_REMOVE3res*);
+bool_t xdr_am_READ3args (XDR *, am_READ3args*);
+bool_t xdr_am_READ3resok (XDR *, am_READ3resok*);
+bool_t xdr_am_READ3resfail (XDR *, am_READ3resfail*);
+bool_t xdr_am_READ3res (XDR *, am_READ3res*);
+bool_t xdr_am_FSINFO3args (XDR *, am_FSINFO3args*);
+bool_t xdr_am_FSINFO3resok (XDR *, am_FSINFO3resok*);
+bool_t xdr_am_FSINFO3resfail (XDR *, am_FSINFO3resfail*);
+bool_t xdr_am_FSINFO3res (XDR *, am_FSINFO3res*);
+bool_t xdr_am_FSSTAT3args (XDR *, am_FSSTAT3args*);
+bool_t xdr_am_FSSTAT3resok (XDR *, am_FSSTAT3resok*);
+bool_t xdr_am_FSSTAT3resfail (XDR *, am_FSSTAT3resfail*);
+bool_t xdr_am_FSSTAT3res (XDR *, am_FSSTAT3res*);
+bool_t xdr_am_PATHCONF3args (XDR *, am_PATHCONF3args*);
+bool_t xdr_am_PATHCONF3resok (XDR *, am_PATHCONF3resok*);
+bool_t xdr_am_PATHCONF3resfail (XDR *, am_PATHCONF3resfail*);
+bool_t xdr_am_PATHCONF3res (XDR *, am_PATHCONF3res*);
+bool_t xdr_am_nfspath3 (XDR *, am_nfspath3*);
+bool_t xdr_am_symlinkdata3 (XDR *, am_symlinkdata3*);
+bool_t xdr_am_SYMLINK3args (XDR *, am_SYMLINK3args*);
+bool_t xdr_am_SYMLINK3resok (XDR *, am_SYMLINK3resok*);
+bool_t xdr_am_SYMLINK3resfail (XDR *, am_SYMLINK3resfail*);
+bool_t xdr_am_SYMLINK3res (XDR *, am_SYMLINK3res*);
+bool_t xdr_am_READLINK3args (XDR *, am_READLINK3args*);
+bool_t xdr_am_READLINK3resok (XDR *, am_READLINK3resok*);
+bool_t xdr_am_READLINK3resfail (XDR *, am_READLINK3resfail*);
+bool_t xdr_am_READLINK3res (XDR *, am_READLINK3res*);
+bool_t xdr_am_devicedata3 (XDR *, am_devicedata3*);
+bool_t xdr_am_mknoddata3 (XDR *, am_mknoddata3*);
+bool_t xdr_am_MKNOD3args (XDR *, am_MKNOD3args*);
+bool_t xdr_am_MKNOD3resok (XDR *, am_MKNOD3resok*);
+bool_t xdr_am_MKNOD3resfail (XDR *, am_MKNOD3resfail*);
+bool_t xdr_am_MKNOD3res (XDR *, am_MKNOD3res*);
+bool_t xdr_am_MKDIR3args (XDR *, am_MKDIR3args*);
+bool_t xdr_am_MKDIR3resok (XDR *, am_MKDIR3resok*);
+bool_t xdr_am_MKDIR3resfail (XDR *, am_MKDIR3resfail*);
+bool_t xdr_am_MKDIR3res (XDR *, am_MKDIR3res*);
+bool_t xdr_am_RMDIR3args (XDR *, am_RMDIR3args*);
+bool_t xdr_am_RMDIR3resok (XDR *, am_RMDIR3resok*);
+bool_t xdr_am_RMDIR3resfail (XDR *, am_RMDIR3resfail*);
+bool_t xdr_am_RMDIR3res (XDR *, am_RMDIR3res*);
+bool_t xdr_am_RENAME3args (XDR *, am_RENAME3args*);
+bool_t xdr_am_RENAME3resok (XDR *, am_RENAME3resok*);
+bool_t xdr_am_RENAME3resfail (XDR *, am_RENAME3resfail*);
+bool_t xdr_am_RENAME3res (XDR *, am_RENAME3res*);
+bool_t xdr_am_READDIRPLUS3args (XDR *, am_READDIRPLUS3args*);
+bool_t xdr_am_entryplus3 (XDR *, am_entryplus3*);
+bool_t xdr_am_dirlistplus3 (XDR *, am_dirlistplus3*);
+bool_t xdr_am_READDIRPLUS3resok (XDR *, am_READDIRPLUS3resok*);
+bool_t xdr_am_READDIRPLUS3resfail (XDR *, am_READDIRPLUS3resfail*);
+bool_t xdr_am_READDIRPLUS3res (XDR *, am_READDIRPLUS3res*);
+bool_t xdr_am_READDIR3args (XDR *, am_READDIR3args*);
+bool_t xdr_am_entry3 (XDR *, am_entry3*);
+bool_t xdr_am_dirlist3 (XDR *, am_dirlist3*);
+bool_t xdr_am_READDIR3resok (XDR *, am_READDIR3resok*);
+bool_t xdr_am_READDIR3resfail (XDR *, am_READDIR3resfail*);
+bool_t xdr_am_READDIR3res (XDR *, am_READDIR3res*);
+bool_t xdr_am_LINK3args (XDR *, am_LINK3args*);
+bool_t xdr_am_LINK3resok (XDR *, am_LINK3resok*);
+bool_t xdr_am_LINK3resfail (XDR *, am_LINK3resfail*);
+bool_t xdr_am_LINK3res (XDR *, am_LINK3res*);
+bool_t xdr_am_sattrguard3 (XDR *, am_sattrguard3*);
+bool_t xdr_am_SETATTR3args (XDR *, am_SETATTR3args*);
+bool_t xdr_am_SETATTR3resok (XDR *, am_SETATTR3resok*);
+bool_t xdr_am_SETATTR3resfail (XDR *, am_SETATTR3resfail*);
+bool_t xdr_am_SETATTR3res (XDR *, am_SETATTR3res*);
#endif /* HAVE_FS_NFS3 */
#endif /* not _AM_XDR_FUNC_H */
diff --git a/contrib/amd/include/amq_defs.h b/contrib/amd/include/amq_defs.h
index 75c465171033..89f61805fc60 100644
--- a/contrib/amd/include/amq_defs.h
+++ b/contrib/amd/include/amq_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -55,7 +51,7 @@
#define AMQ_VERSION ((u_long)1)
#define AMQPROC_NULL ((u_long)0)
#define AMQPROC_MNTTREE ((u_long)1)
-#define AMQPROC_UMNT ((u_long)2)
+#define AMQPROC_UMNT ((u_long)2) /* asynchronous unmount */
#define AMQPROC_STATS ((u_long)3)
#define AMQPROC_EXPORT ((u_long)4)
#define AMQPROC_SETOPT ((u_long)5)
@@ -64,15 +60,19 @@
#define AMQPROC_GETVERS ((u_long)8)
#define AMQPROC_GETPID ((u_long)9)
#define AMQPROC_PAWD ((u_long)10)
+#define AMQPROC_SYNC_UMNT ((u_long)11) /* synchronous unmount */
+#define AMQPROC_GETMAPINFO ((u_long)12)
/*
* TYPEDEFS
*/
typedef long *time_type;
typedef struct amq_mount_info amq_mount_info;
+typedef struct amq_map_info amq_map_info;
typedef struct amq_mount_stats amq_mount_stats;
typedef struct amq_mount_tree amq_mount_tree;
typedef struct amq_setopt amq_setopt;
+typedef struct amq_sync_umnt amq_sync_umnt;
typedef amq_mount_tree *amq_mount_tree_p;
/*
@@ -114,6 +114,22 @@ typedef struct {
amq_mount_tree_p *amq_mount_tree_list_val;
} amq_mount_tree_list;
+struct amq_map_info {
+ amq_string mi_name;
+ amq_string mi_wildcard;
+ time_type mi_modify;
+ int mi_flags;
+ int mi_refc;
+ int mi_up;
+ int mi_reloads;
+ int mi_nentries;
+};
+
+typedef struct {
+ u_int amq_map_info_list_len;
+ amq_map_info *amq_map_info_list_val;
+} amq_map_info_list;
+
struct amq_mount_stats {
int as_drops;
int as_stale;
@@ -122,6 +138,21 @@ struct amq_mount_stats {
int as_uerr;
};
+typedef enum {
+ AMQ_UMNT_OK = 0, /* must be zero! */
+ AMQ_UMNT_FAILED = 1, /* unmount failed */
+ AMQ_UMNT_FORK = 2, /* fork failed */
+ AMQ_UMNT_READ = 3, /* pipe read failed */
+ AMQ_UMNT_SERVER = 4, /* server down */
+ AMQ_UMNT_SIGNAL = 5 /* received signal */
+} au_etype;
+
+struct amq_sync_umnt {
+ au_etype au_etype; /* error type */
+ int au_errno; /* error number */
+ int au_signal; /* signal received */
+};
+
enum amq_opt {
AMOPT_DEBUG = 0,
AMOPT_LOGFILE = 1,
@@ -145,12 +176,15 @@ struct amq_setopt {
*/
extern bool_t xdr_amq_mount_info(XDR *xdrs, amq_mount_info *objp);
extern bool_t xdr_amq_mount_info_list(XDR *xdrs, amq_mount_info_list *objp);
+extern bool_t xdr_amq_map_info(XDR *xdrs, amq_map_info *objp);
+extern bool_t xdr_amq_map_info_list(XDR *xdrs, amq_map_info_list *objp);
extern bool_t xdr_amq_mount_stats(XDR *xdrs, amq_mount_stats *objp);
extern bool_t xdr_amq_mount_tree(XDR *xdrs, amq_mount_tree *objp);
extern bool_t xdr_amq_mount_tree_list(XDR *xdrs, amq_mount_tree_list *objp);
extern bool_t xdr_amq_mount_tree_p(XDR *xdrs, amq_mount_tree_p *objp);
extern bool_t xdr_amq_opt(XDR *xdrs, amq_opt *objp);
extern bool_t xdr_amq_setopt(XDR *xdrs, amq_setopt *objp);
+extern bool_t xdr_amq_sync_umnt(XDR *xdrs, amq_sync_umnt *objp);
extern bool_t xdr_pri_free(XDRPROC_T_TYPE xdr_args, caddr_t args_ptr);
extern bool_t xdr_time_type(XDR *xdrs, time_type *objp);
diff --git a/contrib/amd/include/mount_headers1.h b/contrib/amd/include/mount_headers1.h
index 41f26e59f99d..7d518a06aa26 100644
--- a/contrib/amd/include/mount_headers1.h
+++ b/contrib/amd/include/mount_headers1.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -123,50 +119,50 @@
# include <sys/vmount.h>
#endif /* HAVE_SYS_VMOUNT_H */
-/*
- * There is no point in including this on a glibc2 system
- * we're only asking for trouble
- */
-#if defined HAVE_LINUX_FS_H && (!defined __GLIBC__ || __GLIBC__ < 2)
+#if HAVE_LINUX_FS_H
+# if !defined(__GLIBC__) || __GLIBC__ < 2
/*
* There's a conflict of definitions on redhat alpha linux between
* <netinet/in.h> and <linux/fs.h>.
* Also a conflict in definitions of ntohl/htonl in RH-5.1 sparc64
* between <netinet/in.h> and <linux/byteorder/generic.h> (2.1 kernels).
*/
-# ifdef HAVE_SOCKETBITS_H
-# define _LINUX_SOCKET_H
-# undef BLKFLSBUF
-# undef BLKGETSIZE
-# undef BLKRAGET
-# undef BLKRASET
-# undef BLKROGET
-# undef BLKROSET
-# undef BLKRRPART
-# undef MS_MGC_VAL
-# undef MS_RMT_MASK
-# endif /* HAVE_SOCKETBITS_H */
-# ifdef HAVE_LINUX_POSIX_TYPES_H
-# include <linux/posix_types.h>
-# endif /* HAVE_LINUX_POSIX_TYPES_H */
-# ifndef _LINUX_BYTEORDER_GENERIC_H
-# define _LINUX_BYTEORDER_GENERIC_H
-# endif /* _LINUX_BYTEORDER_GENERIC_H */
-# ifndef _LINUX_STRING_H_
-# define _LINUX_STRING_H_
-# endif /* not _LINUX_STRING_H_ */
-# ifdef HAVE_LINUX_KDEV_T_H
-# define __KERNEL__
-# include <linux/kdev_t.h>
-# undef __KERNEL__
-# endif /* HAVE_LINUX_KDEV_T_H */
-# ifdef HAVE_LINUX_LIST_H
-# define __KERNEL__
-# include <linux/list.h>
-# undef __KERNEL__
-# endif /* HAVE_LINUX_LIST_H */
-# include <linux/fs.h>
-#endif /* HAVE_LINUX_FS_H && (!__GLIBC__ || __GLIBC__ < 2) */
+# ifdef HAVE_SOCKETBITS_H
+# define _LINUX_SOCKET_H
+# undef BLKFLSBUF
+# undef BLKGETSIZE
+# undef BLKRAGET
+# undef BLKRASET
+# undef BLKROGET
+# undef BLKROSET
+# undef BLKRRPART
+# undef MS_MGC_VAL
+# undef MS_RMT_MASK
+# endif /* HAVE_SOCKETBITS_H */
+# ifdef HAVE_LINUX_POSIX_TYPES_H
+# include <linux/posix_types.h>
+# endif /* HAVE_LINUX_POSIX_TYPES_H */
+# ifndef _LINUX_BYTEORDER_GENERIC_H
+# define _LINUX_BYTEORDER_GENERIC_H
+# endif /* _LINUX_BYTEORDER_GENERIC_H */
+# ifndef _LINUX_STRING_H_
+# define _LINUX_STRING_H_
+# endif /* not _LINUX_STRING_H_ */
+# ifdef HAVE_LINUX_KDEV_T_H
+# define __KERNEL__
+# include <linux/kdev_t.h>
+# undef __KERNEL__
+# endif /* HAVE_LINUX_KDEV_T_H */
+# ifdef HAVE_LINUX_LIST_H
+# define __KERNEL__
+# include <linux/list.h>
+# undef __KERNEL__
+# endif /* HAVE_LINUX_LIST_H */
+# include <linux/fs.h>
+# else
+# include <linux/fs.h>
+# endif/* (!__GLIBC__ || __GLIBC__ < 2) */
+#endif /* HAVE_LINUX_FS_H */
#ifdef HAVE_SYS_FS_TYPES_H
# include <sys/fs_types.h>
@@ -192,6 +188,10 @@
# include <isofs/cd9660/cd9660_mount.h>
#endif /* HAVE_ISOFS_CD9660_CD9660_MOUNT_H */
+#ifdef HAVE_FS_UDF_UDF_MOUNT_H
+# include <fs/udf/udf_mount.h>
+#endif /* HAVE_FS_UDF_UDF_MOUNT_H */
+
#ifdef HAVE_SYS_FS_PC_FS_H
# include <sys/fs/pc_fs.h>
#endif /* HAVE_SYS_FS_PC_FS_H */
@@ -202,6 +202,14 @@
# include <fs/msdosfs/msdosfsmount.h>
#endif /* HAVE_FS_MSDOSFS_MSDOSFSMOUNT_H */
+#ifdef HAVE_FS_TMPFS_TMPFS_ARGS_H
+# include <fs/tmpfs/tmpfs_args.h>
+#endif /* HAVE_FS_TMPFS_TMPFS_ARGS_H */
+
+#ifdef HAVE_FS_EFS_EFS_MOUNT_H
+# include <fs/efs/efs_mount.h>
+#endif /* HAVE_FS_EFS_EFS_MOUNT_H */
+
#ifdef HAVE_RPC_RPC_H
# include <rpc/rpc.h>
#endif /* HAVE_RPC_RPC_H */
diff --git a/contrib/amd/include/mount_headers2.h b/contrib/amd/include/mount_headers2.h
index 273e89cae10c..87bf18efd8bb 100644
--- a/contrib/amd/include/mount_headers2.h
+++ b/contrib/amd/include/mount_headers2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/include/nfs_common.h b/contrib/amd/include/nfs_common.h
new file mode 100644
index 000000000000..d89632b59330
--- /dev/null
+++ b/contrib/amd/include/nfs_common.h
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ * 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/include/nfs_common.c
+ *
+ */
+struct nfs_common_args {
+ u_long flags;
+ u_long acdirmin;
+ u_long acdirmax;
+ u_long acregmin;
+ u_long acregmax;
+ u_long timeo;
+ u_long retrans;
+ u_long rsize;
+ u_long wsize;
+};
+
+#ifdef HAVE_NFS_ARGS_T_ACREGMIN
+#define GET_ACREGMIN(nap, a) nap->acregmin = a.acregmin;
+#define PUT_ACREGMIN(nap, a) a.acregmin = nap->acregmin;
+#else
+#define GET_ACREGMIN(nap, a)
+#define PUT_ACREGMIN(nap, a)
+#endif
+#ifdef HAVE_NFS_ARGS_T_ACREGMAX
+#define GET_ACREGMAX(nap, a) nap->acregmax = a.acregmax;
+#define PUT_ACREGMAX(nap, a) a.acregmax = nap->acregmax;
+#else
+#define GET_ACREGMAX(nap, a)
+#define PUT_ACREGMAX(nap, a)
+#endif
+
+#ifdef HAVE_NFS_ARGS_T_ACDIRMIN
+#define GET_ACDIRMIN(nap, a) nap->acdirmin = a.acdirmin;
+#define PUT_ACDIRMIN(nap, a) a.acdirmin = nap->acdirmin;
+#else
+#define GET_ACDIRMIN(nap, a)
+#define PUT_ACDIRMIN(nap, a)
+#endif
+#ifdef HAVE_NFS_ARGS_T_ACDIRMAX
+#define GET_ACDIRMAX(nap, a) nap->acdirmax = a.acdirmax;
+#define PUT_ACDIRMAX(nap, a) a.acdirmax = nap->acdirmax;
+#else
+#define GET_ACDIRMAX(nap, a)
+#define PUT_ACDIRMAX(nap, a)
+#endif
+
+#define get_nfs_common_args(nap, a) \
+ do { \
+ nap->flags = a.flags; \
+ GET_ACREGMIN(nap, a) \
+ GET_ACREGMAX(nap, a) \
+ GET_ACDIRMIN(nap, a) \
+ GET_ACDIRMAX(nap, a) \
+ nap->timeo = a.timeo; \
+ nap->retrans = a.retrans; \
+ nap->rsize = a.rsize; \
+ nap->wsize = a.wsize; \
+ } while (/*CONSTCOND*/0)
+
+#define put_nfs_common_args(nap, a) \
+ do { \
+ a.flags = nap->flags; \
+ PUT_ACREGMIN(nap, a) \
+ PUT_ACREGMAX(nap, a) \
+ PUT_ACDIRMIN(nap, a) \
+ PUT_ACDIRMAX(nap, a) \
+ a.timeo = nap->timeo; \
+ a.retrans = nap->retrans; \
+ a.rsize = nap->rsize; \
+ a.wsize = nap->wsize; \
+ } while (/*CONSTCOND*/0)
diff --git a/contrib/amd/ldap-id.ms b/contrib/amd/ldap-id.ms
index 3c0d30856645..77ff4ba1cb2b 100644
--- a/contrib/amd/ldap-id.ms
+++ b/contrib/amd/ldap-id.ms
@@ -303,4 +303,4 @@ Stockholm University
S-106 91 Stockholm
SWEDEN
-Email: leifj@matematik.su.se
+Email: leifj AT matematik.su.se
diff --git a/contrib/amd/ldap-id.txt b/contrib/amd/ldap-id.txt
index 162f66351850..33a9187b7684 100644
--- a/contrib/amd/ldap-id.txt
+++ b/contrib/amd/ldap-id.txt
@@ -333,7 +333,7 @@ Author's Address
S-106 91 Stockholm
SWEDEN
- Email: leifj@matematik.su.se
+ Email: leifj AT matematik.su.se
diff --git a/contrib/amd/libamu/amu.h b/contrib/amd/libamu/amu.h
index 1e7834a15261..9415fc404ea4 100644
--- a/contrib/amd/libamu/amu.h
+++ b/contrib/amd/libamu/amu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -47,11 +43,14 @@
/*
* Decide what maximum level of NFS server to try and mount with.
*/
-#ifdef HAVE_FS_NFS3
+#if defined(HAVE_FS_NFS4)
+# define NFS_VERS_MAX NFS_VERSION4
+#elif defined(HAVE_FS_NFS3)
# define NFS_VERS_MAX NFS_VERSION3
#else /* not HAVE_FS_NFS3 */
# define NFS_VERS_MAX NFS_VERSION
#endif /* not HAVE_FS_NFS3 */
+# define NFS_VERS_MIN NFS_VERSION
/* some systems like ncr2 do not define this in <rpcsvc/mount.h> */
#ifndef MNTPATHLEN
diff --git a/contrib/amd/libamu/hasmntopt.c b/contrib/amd/libamu/hasmntopt.c
index 14cceb53b5cb..e5a6f2e80dfe 100644
--- a/contrib/amd/libamu/hasmntopt.c
+++ b/contrib/amd/libamu/hasmntopt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@ n * modification, are permitted provided that the following conditions
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -67,7 +63,7 @@ nextmntopt(char **p)
/*
* Skip past white space
*/
- while (*cp && isspace((int) *cp))
+ while (*cp && isspace((unsigned char) *cp))
cp++;
/*
@@ -106,7 +102,7 @@ amu_hasmntopt(mntent_t *mnt, char *opt)
char t[MNTMAXSTR];
char *f;
char *o = t;
- int l = strlen(opt);
+ size_t l = strlen(opt);
xstrlcpy(t, mnt->mnt_opts, sizeof(t));
diff --git a/contrib/amd/libamu/misc_rpc.c b/contrib/amd/libamu/misc_rpc.c
index de0a92036b7f..c6ad4486d7d9 100644
--- a/contrib/amd/libamu/misc_rpc.c
+++ b/contrib/amd/libamu/misc_rpc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/libamu/mount_fs.c b/contrib/amd/libamu/mount_fs.c
index 74f064ede648..b5576bdc6d14 100644
--- a/contrib/amd/libamu/mount_fs.c
+++ b/contrib/amd/libamu/mount_fs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -46,6 +42,7 @@
#endif /* HAVE_CONFIG_H */
#include <am_defs.h>
#include <amu.h>
+#include <nfs_common.h>
/* ensure that mount table options are delimited by a comma */
@@ -105,6 +102,30 @@ struct opt_tab mnt_flags[] =
{MNTTAB_OPT_OVERLAY, MNT2_GEN_OPT_OVERLAY},
#endif /* defined(MNT2_GEN_OPT_OVERLAY) && defined(MNTTAB_OPT_OVERLAY) */
+#if defined(MNT2_GEN_OPT_LOG) && defined(MNTTAB_OPT_LOG)
+ {MNTTAB_OPT_LOG, MNT2_GEN_OPT_LOG},
+#endif /* defined(MNT2_GEN_OPT_LOG) && defined(MNTTAB_OPT_LOG) */
+
+#if defined(MNT2_GEN_OPT_NOATIME) && defined(MNTTAB_OPT_NOATIME)
+ {MNTTAB_OPT_NOATIME, MNT2_GEN_OPT_NOATIME},
+#endif /* defined(MNT2_GEN_OPT_NOATIME) && defined(MNTTAB_OPT_NOATIME) */
+
+#if defined(MNT2_GEN_OPT_NODEVMTIME) && defined(MNTTAB_OPT_NODEVMTIME)
+ {MNTTAB_OPT_NODEVMTIME, MNT2_GEN_OPT_NODEVMTIME},
+#endif /* defined(MNT2_GEN_OPT_NODEVMTIME) && defined(MNTTAB_OPT_NODEVMTIME) */
+
+#if defined(MNT2_GEN_OPT_SOFTDEP) && defined(MNTTAB_OPT_SOFTDEP)
+ {MNTTAB_OPT_SOFTDEP, MNT2_GEN_OPT_SOFTDEP},
+#endif /* defined(MNT2_GEN_OPT_SOFTDEP) && defined(MNTTAB_OPT_SOFTDEP) */
+
+#if defined(MNT2_GEN_OPT_SYMPERM) && defined(MNTTAB_OPT_SYMPERM)
+ {MNTTAB_OPT_SYMPERM, MNT2_GEN_OPT_SYMPERM},
+#endif /* defined(MNT2_GEN_OPT_SYMPERM) && defined(MNTTAB_OPT_SYMPERM) */
+
+#if defined(MNT2_GEN_OPT_UNION) && defined(MNTTAB_OPT_UNION)
+ {MNTTAB_OPT_UNION, MNT2_GEN_OPT_UNION},
+#endif /* defined(MNT2_GEN_OPT_UNION) && defined(MNTTAB_OPT_UNION) */
+
/*
* Do not define MNT2_NFS_OPT_* entries here! This is for generic
* mount(2) options only, not for NFS mount options. If you need to put
@@ -158,6 +179,25 @@ compute_automounter_mount_flags(mntent_t *mntp)
}
+#if defined(MOUNT_TABLE_ON_FILE) && defined(MNTTAB_OPT_VERS)
+/*
+ * add the extra vers={2,3} field to the mount table,
+ * unless already specified by user
+ */
+static void
+addvers(char *zopts, size_t l, mntent_t *mnt, u_long have_vers,
+ u_long want_vers)
+{
+ if (have_vers == want_vers &&
+ hasmntval(mnt, MNTTAB_OPT_VERS) != want_vers) {
+ char optsbuf[48];
+ xsnprintf(optsbuf, sizeof(optsbuf),
+ "%s=%d", MNTTAB_OPT_VERS, want_vers);
+ append_opts(zopts, l, optsbuf);
+ }
+}
+#endif /* MOUNT_TABLE_ON_FILE && MNTTAB_OPT_VERS */
+
int
mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, u_long nfs_version, const char *nfs_proto, const char *mnttabname, int on_autofs)
{
@@ -166,17 +206,17 @@ mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type,
char *zopts = NULL, *xopts = NULL;
size_t l;
#endif /* MOUNT_TABLE_ON_FILE */
- char *mnt_dir = 0;
+ char *mnt_dir = NULL;
#ifdef NEED_AUTOFS_SPACE_HACK
- char *old_mnt_dir = 0;
+ char *old_mnt_dir = NULL;
/* perform space hack */
if (on_autofs) {
old_mnt_dir = mnt->mnt_dir;
mnt->mnt_dir = mnt_dir = autofs_strdup_space_hack(old_mnt_dir);
} else
#endif /* NEED_AUTOFS_SPACE_HACK */
- mnt_dir = strdup(mnt->mnt_dir);
+ mnt_dir = xstrdup(mnt->mnt_dir);
dlog("'%s' fstype " MTYPE_PRINTF_TYPE " (%s) flags %#x (%s)",
mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);
@@ -256,19 +296,15 @@ again:
}
# endif /* MNTTAB_OPT_DEV */
+# if defined(HAVE_FS_NFS4) && defined(MNTTAB_OPT_VERS)
+ addvers(zopts, l, mnt, nfs_version, NFS_VERSION4);
+# endif /* defined(HAVE_FS_NFS4) && defined(MNTTAB_OPT_VERS) */
# if defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS)
- /*
- * add the extra vers={2,3} field to the mount table,
- * unless already specified by user
- */
- if (nfs_version == NFS_VERSION3 &&
- hasmntval(mnt, MNTTAB_OPT_VERS) != NFS_VERSION3) {
- char optsbuf[48];
- xsnprintf(optsbuf, sizeof(optsbuf),
- "%s=%d", MNTTAB_OPT_VERS, NFS_VERSION3);
- append_opts(zopts, l, optsbuf);
- }
+ addvers(zopts, l, mnt, nfs_version, NFS_VERSION3);
# endif /* defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS) */
+# ifdef MNTTAB_OPT_VERS
+ addvers(zopts, l, mnt, nfs_version, NFS_VERSION2);
+# endif /* MNTTAB_OPT_VERS */
# ifdef MNTTAB_OPT_PROTO
/*
@@ -333,7 +369,7 @@ again:
* with caution.
*/
static void
-compute_nfs_attrcache_flags(nfs_args_t *nap, mntent_t *mntp)
+compute_nfs_attrcache_flags(struct nfs_common_args *nap, mntent_t *mntp)
{
int acval = 0;
int err_acval = 1; /* 1 means we found no 'actimeo' value */
@@ -365,7 +401,9 @@ compute_nfs_attrcache_flags(nfs_args_t *nap, mntent_t *mntp)
nap->acregmin = acval; /* min ac timeout for reg files (sec) */
} else {
# ifdef MNTTAB_OPT_ACREGMIN
- err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMIN, (int *) &nap->acregmin);
+ int tmp;
+ err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMIN, &tmp);
+ nap->acregmin = tmp;
# else /* not MNTTAB_OPT_ACREGMIN */
nap->acregmin = 0;
# endif /* not MNTTAB_OPT_ACREGMIN */
@@ -384,7 +422,9 @@ compute_nfs_attrcache_flags(nfs_args_t *nap, mntent_t *mntp)
nap->acregmax = acval; /* max ac timeout for reg files (sec) */
} else {
# ifdef MNTTAB_OPT_ACREGMAX
- err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMAX, (int *) &nap->acregmax);
+ int tmp;
+ err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMAX, &tmp);
+ nap->acregmax = tmp;
# else /* not MNTTAB_OPT_ACREGMAX */
nap->acregmax = 0;
# endif /* not MNTTAB_OPT_ACREGMAX */
@@ -403,7 +443,9 @@ compute_nfs_attrcache_flags(nfs_args_t *nap, mntent_t *mntp)
nap->acdirmin = acval; /* min ac timeout for dirs (sec) */
} else {
# ifdef MNTTAB_OPT_ACDIRMIN
- err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMIN, (int *) &nap->acdirmin);
+ int tmp;
+ err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMIN, &tmp);
+ nap->acdirmin = tmp;
# else /* not MNTTAB_OPT_ACDIRMIN */
nap->acdirmin = 0;
# endif /* not MNTTAB_OPT_ACDIRMIN */
@@ -422,7 +464,9 @@ compute_nfs_attrcache_flags(nfs_args_t *nap, mntent_t *mntp)
nap->acdirmax = acval; /* max ac timeout for dirs (sec) */
} else {
# ifdef MNTTAB_OPT_ACDIRMAX
- err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMAX, (int *) &nap->acdirmax);
+ int tmp;
+ err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMAX, &tmp);
+ nap->acdirmax = tmp;
# else /* not MNTTAB_OPT_ACDIRMAX */
nap->acdirmax = 0;
# endif /* not MNTTAB_OPT_ACDIRMAX */
@@ -443,148 +487,16 @@ compute_nfs_attrcache_flags(nfs_args_t *nap, mntent_t *mntp)
}
-/*
- * Fill in the many possible fields and flags of struct nfs_args.
- *
- * nap: pre-allocated structure to fill in.
- * mntp: mount entry structure (includes options)
- * genflags: generic mount flags already determined
- * nfsncp: (TLI only) netconfig entry for this NFS mount
- * ip_addr: IP address of file server
- * nfs_version: 2, 3, (4 in the future), or 0 if unknown
- * nfs_proto: "udp", "tcp", or NULL.
- * fhp: file handle structure pointer
- * host_name: name of remote NFS host
- * fs_name: remote file system name to mount
- */
-void
-compute_nfs_args(nfs_args_t *nap,
- mntent_t *mntp,
- int genflags,
- struct netconfig *nfsncp,
- struct sockaddr_in *ip_addr,
- u_long nfs_version,
- char *nfs_proto,
- am_nfs_handle_t *fhp,
- char *host_name,
- char *fs_name)
-{
- /* initialize just in case */
- memset((voidp) nap, 0, sizeof(nfs_args_t));
-
- /* compute all of the NFS attribute-cache flags */
- compute_nfs_attrcache_flags(nap, mntp);
-
- /************************************************************************/
- /*** FILEHANDLE DATA AND LENGTH ***/
- /************************************************************************/
-#ifdef HAVE_FS_NFS3
- if (nfs_version == NFS_VERSION3) {
-# if defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN)
- /*
- * Some systems (Irix/bsdi3) have a separate field in nfs_args for
- * the length of the file handle for NFS V3. They insist that
- * the file handle set in nfs_args be plain bytes, and not
- * include the length field.
- */
- NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3.am_fh3_data);
-# else /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */
- NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3);
-# endif /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */
-# ifdef MNT2_NFS_OPT_NFSV3
- nap->flags |= MNT2_NFS_OPT_NFSV3;
-# endif /* MNT2_NFS_OPT_NFSV3 */
-# ifdef MNT2_NFS_OPT_VER3
- nap->flags |= MNT2_NFS_OPT_VER3;
-# endif /* MNT2_NFS_OPT_VER3 */
- } else
-#endif /* HAVE_FS_NFS3 */
- NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v2);
-
-#ifdef HAVE_NFS_ARGS_T_FHSIZE
-# ifdef HAVE_FS_NFS3
- if (nfs_version == NFS_VERSION3)
- nap->fhsize = fhp->v3.am_fh3_length;
- else
-# endif /* HAVE_FS_NFS3 */
- nap->fhsize = FHSIZE;
-#endif /* HAVE_NFS_ARGS_T_FHSIZE */
-
- /* this is the version of the nfs_args structure, not of NFS! */
-#ifdef HAVE_NFS_ARGS_T_FH_LEN
-# ifdef HAVE_FS_NFS3
- if (nfs_version == NFS_VERSION3)
- nap->fh_len = fhp->v3.am_fh3_length;
- else
-# endif /* HAVE_FS_NFS3 */
- nap->fh_len = FHSIZE;
-#endif /* HAVE_NFS_ARGS_T_FH_LEN */
- /************************************************************************/
- /*** HOST NAME ***/
- /************************************************************************/
- /*
- * XXX: warning, using xstrlcpy in NFS_HN_DREF, which may corrupt a
- * struct nfs_args, or truncate our concocted "hostname:/path"
- * string prematurely.
- */
- NFS_HN_DREF(nap->hostname, host_name);
-#ifdef MNT2_NFS_OPT_HOSTNAME
- nap->flags |= MNT2_NFS_OPT_HOSTNAME;
-#endif /* MNT2_NFS_OPT_HOSTNAME */
-
- /************************************************************************/
- /*** IP ADDRESS OF REMOTE HOST ***/
- /************************************************************************/
- if (ip_addr) {
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- nap->addr = ALLOC(struct netbuf); /* free()'ed at end of mount_nfs_fh() */
-#endif /* HAVE_TRANSPORT_TYPE_TLI */
- NFS_SA_DREF(nap, ip_addr);
- }
-
- /************************************************************************/
- /*** NFS PROTOCOL (UDP, TCP) AND VERSION ***/
- /************************************************************************/
+static void
+compute_nfs_common_args(struct nfs_common_args *nap, mntent_t *mntp,
+ const char *nfs_proto, u_long nfs_version)
+{
#ifdef MNT2_NFS_OPT_TCP
if (nfs_proto && STREQ(nfs_proto, "tcp"))
nap->flags |= MNT2_NFS_OPT_TCP;
#endif /* MNT2_NFS_OPT_TCP */
-#ifdef HAVE_NFS_ARGS_T_SOTYPE
- /* bsdi3 uses this */
- if (nfs_proto) {
- if (STREQ(nfs_proto, "tcp"))
- nap->sotype = SOCK_STREAM;
- else if (STREQ(nfs_proto, "udp"))
- nap->sotype = SOCK_DGRAM;
- }
-#endif /* HAVE_NFS_ARGS_T_SOTYPE */
-
-#ifdef HAVE_NFS_ARGS_T_PROTO
- nap->proto = 0; /* bsdi3 sets this field to zero */
-# ifdef IPPROTO_TCP
- if (nfs_proto) {
- if (STREQ(nfs_proto, "tcp")) /* AIX 4.2.x needs this */
- nap->proto = IPPROTO_TCP;
- else if (STREQ(nfs_proto, "udp"))
- nap->proto = IPPROTO_UDP;
- }
-# endif /* IPPROTO_TCP */
-#endif /* HAVE_NFS_ARGS_T_SOTYPE */
-
-#ifdef HAVE_NFS_ARGS_T_VERSION
-# ifdef NFS_ARGSVERSION
- nap->version = NFS_ARGSVERSION; /* BSDI 3.0 and OpenBSD 2.2 */
-# endif /* NFS_ARGSVERSION */
-# ifdef DG_MOUNT_NFS_VERSION
- nap->version = DG_MOUNT_NFS_VERSION; /* dg-ux */
-# endif /* DG_MOUNT_NFS_VERSION */
-#endif /* HAVE_NFS_ARGS_VERSION */
-
- /************************************************************************/
- /*** OTHER NFS SOCKET RELATED OPTIONS AND FLAGS ***/
- /************************************************************************/
#ifdef MNT2_NFS_OPT_NOCONN
/* check if user specified to use unconnected or connected sockets */
if (amu_hasmntopt(mntp, MNTTAB_OPT_NOCONN) != NULL)
@@ -624,28 +536,6 @@ compute_nfs_args(nfs_args_t *nap,
# endif /* not MNTTAB_OPT_RESVPORT */
#endif /* MNT2_NFS_OPT_RESVPORT */
- /************************************************************************/
- /*** OTHER FLAGS AND OPTIONS ***/
- /************************************************************************/
-
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- /* set up syncaddr field */
- nap->syncaddr = (struct netbuf *) NULL;
-
- /* set up knconf field */
- if (get_knetconfig(&nap->knconf, nfsncp, nfs_proto) < 0) {
- plog(XLOG_FATAL, "cannot fill knetconfig structure for nfs_args");
- going_down(1);
- }
- /* update the flags field for knconf */
- nap->flags |= MNT2_NFS_OPT_KNCONF;
-#endif /* HAVE_TRANSPORT_TYPE_TLI */
-
-#ifdef MNT2_NFS_OPT_FSNAME
- nap->fsname = fs_name;
- nap->flags |= MNT2_NFS_OPT_FSNAME;
-#endif /* MNT2_NFS_OPT_FSNAME */
-
nap->rsize = hasmntval(mntp, MNTTAB_OPT_RSIZE);
#ifdef MNT2_NFS_OPT_RSIZE
if (nap->rsize)
@@ -674,11 +564,6 @@ compute_nfs_args(nfs_args_t *nap,
nap->flags |= MNT2_NFS_OPT_RETRANS;
#endif /* MNT2_NFS_OPT_RETRANS */
-#ifdef MNT2_NFS_OPT_BIODS
- if ((nap->biods = hasmntval(mntp, MNTTAB_OPT_BIODS)))
- nap->flags |= MNT2_NFS_OPT_BIODS;
-#endif /* MNT2_NFS_OPT_BIODS */
-
#ifdef MNT2_NFS_OPT_SOFT
if (amu_hasmntopt(mntp, MNTTAB_OPT_SOFT) != NULL)
nap->flags |= MNT2_NFS_OPT_SOFT;
@@ -687,7 +572,7 @@ compute_nfs_args(nfs_args_t *nap,
#ifdef MNT2_NFS_OPT_SPONGY
if (amu_hasmntopt(mntp, MNTTAB_OPT_SPONGY) != NULL) {
nap->flags |= MNT2_NFS_OPT_SPONGY;
- if (nap->flags & MNT2_NFS_OPT_SOFT) {
+ if (*flags & MNT2_NFS_OPT_SOFT) {
plog(XLOG_USER, "Mount opts soft and spongy are incompatible - soft ignored");
nap->flags &= ~MNT2_NFS_OPT_SOFT;
}
@@ -720,6 +605,11 @@ compute_nfs_args(nfs_args_t *nap,
# endif /* MNT2_NFS_OPT_NOINT */
#endif /* MNTTAB_OPT_INTR */
+#ifdef MNT2_NFS_OPT_NOACL
+ if (amu_hasmntopt(mntp, MNTTAB_OPT_NOACL) != NULL)
+ nap->flags |= MNT2_NFS_OPT_NOACL;
+#endif /* MNT2_NFS_OPT_NOACL */
+
#ifdef MNTTAB_OPT_NODEVS
if (amu_hasmntopt(mntp, MNTTAB_OPT_NODEVS) != NULL)
nap->flags |= MNT2_NFS_OPT_NODEVS;
@@ -735,39 +625,17 @@ compute_nfs_args(nfs_args_t *nap,
nap->flags |= MNT2_NFS_OPT_PRIVATE;
#endif /* MNTTAB_OPT_PRIVATE */
-#ifdef MNTTAB_OPT_SYMTTL /* symlink cache time-to-live */
- if ((nap->symttl = hasmntval(mntp, MNTTAB_OPT_SYMTTL)))
- nap->flags |= MNT2_NFS_OPT_SYMTTL;
-#endif /* MNTTAB_OPT_SYMTTL */
-
-#ifdef MNT2_NFS_OPT_PGTHRESH /* paging threshold */
- if ((nap->pg_thresh = hasmntval(mntp, MNTTAB_OPT_PGTHRESH)))
- nap->flags |= MNT2_NFS_OPT_PGTHRESH;
-#endif /* MNT2_NFS_OPT_PGTHRESH */
#if defined(MNT2_NFS_OPT_NOCTO) && defined(MNTTAB_OPT_NOCTO)
if (amu_hasmntopt(mntp, MNTTAB_OPT_NOCTO) != NULL)
nap->flags |= MNT2_NFS_OPT_NOCTO;
#endif /* defined(MNT2_NFS_OPT_NOCTO) && defined(MNTTAB_OPT_NOCTO) */
-#if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX)
- if (amu_hasmntopt(mntp, MNTTAB_OPT_POSIX) != NULL) {
- nap->flags |= MNT2_NFS_OPT_POSIX;
- nap->pathconf = NULL;
- }
-#endif /* MNT2_NFS_OPT_POSIX && MNTTAB_OPT_POSIX */
-
#if defined(MNT2_NFS_OPT_PROPLIST) && defined(MNTTAB_OPT_PROPLIST)
if (amu_hasmntopt(mntp, MNTTAB_OPT_PROPLIST) != NULL)
nap->flags |= MNT2_NFS_OPT_PROPLIST;
#endif /* defined(MNT2_NFS_OPT_PROPLIST) && defined(MNTTAB_OPT_PROPLIST) */
-#if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS)
- nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS);
- if (nap->maxgrouplist != 0)
- nap->flags |= MNT2_NFS_OPT_MAXGRPS;
-#endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */
-
#if defined(MNT2_NFS_OPT_NONLM) && defined(MNTTAB_OPT_NOLOCK)
if (amu_hasmntopt(mntp, MNTTAB_OPT_NOLOCK) != NULL)
nap->flags |= MNT2_NFS_OPT_NONLM;
@@ -777,77 +645,35 @@ compute_nfs_args(nfs_args_t *nap,
if (amu_hasmntopt(mntp, MNTTAB_OPT_XLATECOOKIE) != NULL)
nap->flags |= MNT2_NFS_OPT_XLATECOOKIE;
#endif /* defined(MNT2_NFS_OPT_XLATECOOKIE) && defined(MNTTAB_OPT_XLATECOOKIE) */
-
-#ifdef HAVE_NFS_ARGS_T_OPTSTR
- nap->optstr = mntp->mnt_opts;
-#endif /* HAVE_NFS_ARGS_T_OPTSTR */
-
- /************************************************************************/
- /*** FINAL ACTIONS ***/
- /************************************************************************/
-
-#ifdef HAVE_NFS_ARGS_T_GFS_FLAGS
- /* Ultrix stores generic flags in nfs_args.gfs_flags. */
- nap->gfs_flags = genflags;
-#endif /* HAVE_NFS_ARGS_T_FLAGS */
-
- return; /* end of compute_nfs_args() function */
}
-
-/*
- * Fill in special values for flags and fields of nfs_args, for an
- * automounter NFS mount.
- */
-void
-compute_automounter_nfs_args(nfs_args_t *nap, mntent_t *mntp)
+static void
+print_nfs_common_args(const struct nfs_common_args *a)
{
-#ifdef MNT2_NFS_OPT_SYMTTL
- /*
- * Don't let the kernel cache symbolic links we generate, or else lookups
- * will bypass amd and fail to remount stuff as needed.
- */
- plog(XLOG_INFO, "turning on NFS option symttl and setting value to 0");
- nap->flags |= MNT2_NFS_OPT_SYMTTL;
- nap->symttl = 0;
-#endif /* MNT2_NFS_OPT_SYMTTL */
-
- /*
- * This completes the flags for the HIDE_MOUNT_TYPE code in the
- * mount_amfs_toplvl() function in amd/amfs_toplvl.c.
- * Some systems don't have a mount type, but a mount flag.
- */
-#ifdef MNT2_NFS_OPT_AUTO
- nap->flags |= MNT2_NFS_OPT_AUTO;
-#endif /* MNT2_NFS_OPT_AUTO */
-#ifdef MNT2_NFS_OPT_IGNORE
- nap->flags |= MNT2_NFS_OPT_IGNORE;
-#endif /* MNT2_NFS_OPT_IGNORE */
-#ifdef MNT2_GEN_OPT_AUTOMNTFS
- nap->flags |= MNT2_GEN_OPT_AUTOMNTFS;
-#endif /* not MNT2_GEN_OPT_AUTOMNTFS */
+ plog(XLOG_DEBUG, "NA->flags = 0x%lx", a->flags);
-#ifdef MNT2_NFS_OPT_DUMBTIMR
- /*
- * Don't let the kernel start computing throughput of Amd. The numbers
- * will be meaningless because of the way Amd does mount retries.
- */
- plog(XLOG_INFO, "%s: disabling nfs congestion window", mntp->mnt_dir);
- nap->flags |= MNT2_NFS_OPT_DUMBTIMR;
-#endif /* MNT2_NFS_OPT_DUMBTIMR */
-
- /* compute all of the NFS attribute-cache flags */
- compute_nfs_attrcache_flags(nap, mntp);
+ plog(XLOG_DEBUG, "NA->rsize = %lu", a->rsize);
+ plog(XLOG_DEBUG, "NA->wsize = %lu", a->wsize);
+ plog(XLOG_DEBUG, "NA->timeo = %lu", a->timeo);
+ plog(XLOG_DEBUG, "NA->retrans = %lu", a->retrans);
- /*
- * Provide a slight bit more security by requiring the kernel to use
- * reserved ports.
- */
-#ifdef MNT2_NFS_OPT_RESVPORT
- nap->flags |= MNT2_NFS_OPT_RESVPORT;
-#endif /* MNT2_NFS_OPT_RESVPORT */
+#ifdef HAVE_NFS_ARGS_T_ACREGMIN
+ plog(XLOG_DEBUG, "NA->acregmin = %lu", a->acregmin);
+ plog(XLOG_DEBUG, "NA->acregmax = %lu", a->acregmax);
+ plog(XLOG_DEBUG, "NA->acdirmin = %lu", a->acdirmin);
+ plog(XLOG_DEBUG, "NA->acdirmax = %lu", a->acdirmax);
+#endif /* HAVE_NFS_ARGS_T_ACREGMIN */
}
+static void
+discard_nfs23_args(nfs_args_t *nap)
+{
+#ifdef HAVE_TRANSPORT_TYPE_TLI
+ free_knetconfig(nap->knconf);
+ if (nap->addr)
+ XFREE(nap->addr); /* allocated in compute_nfs_args() */
+#endif /* HAVE_TRANSPORT_TYPE_TLI */
+}
#ifdef DEBUG
/* get string version (in hex) of identifier */
@@ -855,29 +681,48 @@ static char *
get_hex_string(u_int len, const char *fhdata)
{
u_int i;
- static char buf[128]; /* better not go over it! */
+ static u_int xlen;
+ static char *buf;
+ static u_short *arr;
char str[16];
- short int arr[64];
- if (!fhdata)
+ if (!fhdata || len == 0 || len > 10240)
return NULL;
+ i = len * 4 + 1;
+ if (xlen < i) {
+ buf = xrealloc(buf, i);
+ arr = xrealloc(arr, len * sizeof(*arr));
+ xlen = i;
+ }
+
buf[0] = '\0';
- memset(&arr[0], 0, (64 * sizeof(short int)));
- memcpy(&arr[0], &fhdata[0], len);
- for (i=0; i<len/sizeof(unsigned short int); i++) {
+ memset(arr, 0, len * sizeof(*arr));
+ memcpy(arr, fhdata, len);
+ len /= sizeof(*arr);
+ for (i = 0; i < len; i++) {
xsnprintf(str, sizeof(str), "%04x", ntohs(arr[i]));
- xstrlcat(buf, str, sizeof(buf));
+ xstrlcat(buf, str, xlen);
}
return buf;
}
+static void
+print_nfs_sockaddr_in(const char *tag, const struct sockaddr_in *sap)
+{
+ char name[64];
+ plog(XLOG_DEBUG, "NA->%s.sin_family = %d", tag, sap->sin_family);
+ plog(XLOG_DEBUG, "NA->%s.sin_port = %d", tag, ntohs(sap->sin_port));
+ if (inet_ntop(AF_INET, &sap->sin_addr, name, sizeof(name)) == NULL)
+ return;
+ plog(XLOG_DEBUG, "NA->%s.sin_addr = \"%s\"", tag, name);
+}
/*
* print a subset of fields from "struct nfs_args" that are otherwise
* not being provided anywhere else.
*/
-void
-print_nfs_args(const nfs_args_t *nap, u_long nfs_version)
+static void
+print_nfs23_args(const nfs_args_t *nap, u_long nfs_version)
{
int fhlen = 32; /* default: NFS V.2 file handle length is 32 */
#ifdef HAVE_TRANSPORT_TYPE_TLI
@@ -886,6 +731,7 @@ print_nfs_args(const nfs_args_t *nap, u_long nfs_version)
#else /* not HAVE_TRANSPORT_TYPE_TLI */
struct sockaddr_in *sap;
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
+ struct nfs_common_args a;
if (!nap) {
plog(XLOG_DEBUG, "NULL nfs_args!");
@@ -919,17 +765,11 @@ print_nfs_args(const nfs_args_t *nap, u_long nfs_version)
# else /* not NFS_ARGS_T_ADDR_IS_POINTER */
sap = (struct sockaddr_in *) &nap->addr;
# endif /* not NFS_ARGS_T_ADDR_IS_POINTER */
- plog(XLOG_DEBUG, "NA->addr {sockaddr_in} (len=%d) = \"%s\"",
- (int) sizeof(struct sockaddr_in),
- get_hex_string(sizeof(struct sockaddr_in), (const char *)sap));
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
/* as per POSIX, sin_len need not be set (used internally by kernel) */
plog(XLOG_DEBUG, "NA->addr.sin_len = %d", sap->sin_len);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
- plog(XLOG_DEBUG, "NA->addr.sin_family = %d", sap->sin_family);
- plog(XLOG_DEBUG, "NA->addr.sin_port = %d", sap->sin_port);
- plog(XLOG_DEBUG, "NA->addr.sin_addr = \"%s\"",
- get_hex_string(sizeof(struct in_addr), (const char *) &sap->sin_addr));
+ print_nfs_sockaddr_in("addr", sap);
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
#ifdef HAVE_NFS_ARGS_T_ADDRLEN
plog(XLOG_DEBUG, "NA->addrlen = %d", nap->addrlen);
@@ -972,22 +812,13 @@ print_nfs_args(const nfs_args_t *nap, u_long nfs_version)
plog(XLOG_DEBUG, "NA->version = %d", nap->version);
#endif /* HAVE_NFS_ARGS_T_VERSION */
- plog(XLOG_DEBUG, "NA->flags = 0x%x", (int) nap->flags);
+ put_nfs_common_args(nap, a);
+ print_nfs_common_args(&a);
- plog(XLOG_DEBUG, "NA->rsize = %d", (int) nap->rsize);
- plog(XLOG_DEBUG, "NA->wsize = %d", (int) nap->wsize);
#ifdef HAVE_NFS_ARGS_T_BSIZE
plog(XLOG_DEBUG, "NA->bsize = %d", nap->bsize);
#endif /* HAVE_NFS_ARGS_T_BSIZE */
- plog(XLOG_DEBUG, "NA->timeo = %d", (int) nap->timeo);
- plog(XLOG_DEBUG, "NA->retrans = %d", (int) nap->retrans);
-#ifdef HAVE_NFS_ARGS_T_ACREGMIN
- plog(XLOG_DEBUG, "NA->acregmin = %d", (int) nap->acregmin);
- plog(XLOG_DEBUG, "NA->acregmax = %d", (int) nap->acregmax);
- plog(XLOG_DEBUG, "NA->acdirmin = %d", (int) nap->acdirmin);
- plog(XLOG_DEBUG, "NA->acdirmax = %d", (int) nap->acdirmax);
-#endif /* HAVE_NFS_ARGS_T_ACREGMIN */
#ifdef MNTTAB_OPT_SYMTTL
plog(XLOG_DEBUG, "NA->symttl = %d", nap->symttl);
#endif /* MNTTAB_OPT_SYMTTL */
@@ -1001,3 +832,665 @@ print_nfs_args(const nfs_args_t *nap, u_long nfs_version)
}
#endif /* DEBUG */
+
+/*
+ * Fill in the many possible fields and flags of struct nfs_args.
+ *
+ * nap: pre-allocated structure to fill in.
+ * mntp: mount entry structure (includes options)
+ * genflags: generic mount flags already determined
+ * nfsncp: (TLI only) netconfig entry for this NFS mount
+ * ip_addr: IP address of file server
+ * nfs_version: 2, 3, or 0 if unknown
+ * nfs_proto: "udp", "tcp", or NULL.
+ * fhp: file handle structure pointer
+ * host_name: name of remote NFS host
+ * fs_name: remote file system name to mount
+ */
+static void
+compute_nfs23_args(nfs_args_t *nap,
+ mntent_t *mntp,
+ int genflags,
+ struct netconfig *nfsncp,
+ struct sockaddr_in *ip_addr,
+ u_long nfs_version,
+ char *nfs_proto,
+ am_nfs_handle_t *fhp,
+ char *host_name,
+ char *fs_name)
+{
+ struct nfs_common_args a;
+ /* initialize just in case */
+ memset((voidp) nap, 0, sizeof(nfs_args_t));
+
+ /* compute all of the NFS attribute-cache flags */
+ memset(&a, 0, sizeof(a));
+ compute_nfs_attrcache_flags(&a, mntp);
+ compute_nfs_common_args(&a, mntp, nfs_proto, nfs_version);
+ get_nfs_common_args(nap, a);
+
+ /************************************************************************/
+ /*** FILEHANDLE DATA AND LENGTH ***/
+ /************************************************************************/
+#ifdef HAVE_FS_NFS3
+ if (nfs_version == NFS_VERSION3) {
+ if (fhp == NULL) {
+ plog(XLOG_FATAL, "cannot pass NULL fh for NFSv%lu", nfs_version);
+ going_down(1);
+ return;
+ }
+
+# if defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN)
+ /*
+ * Some systems (Irix/bsdi3) have a separate field in nfs_args for
+ * the length of the file handle for NFS V3. They insist that
+ * the file handle set in nfs_args be plain bytes, and not
+ * include the length field.
+ */
+ NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3.am_fh3_data);
+# else /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */
+ NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3);
+# endif /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */
+# ifdef MNT2_NFS_OPT_NFSV3
+ nap->flags |= MNT2_NFS_OPT_NFSV3;
+# endif /* MNT2_NFS_OPT_NFSV3 */
+# ifdef MNT2_NFS_OPT_VER3
+ nap->flags |= MNT2_NFS_OPT_VER3;
+# endif /* MNT2_NFS_OPT_VER3 */
+ } else
+#endif /* HAVE_FS_NFS3 */
+ {
+ if (fhp == NULL) {
+ plog(XLOG_FATAL, "cannot pass NULL fh for NFSv%lu", nfs_version);
+ going_down(1);
+ return;
+ }
+ NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v2);
+ }
+
+#ifdef HAVE_NFS_ARGS_T_FHSIZE
+# ifdef HAVE_FS_NFS3
+ if (nfs_version == NFS_VERSION3)
+ nap->fhsize = fhp->v3.am_fh3_length;
+ else
+# endif /* HAVE_FS_NFS3 */
+ nap->fhsize = FHSIZE;
+#endif /* HAVE_NFS_ARGS_T_FHSIZE */
+
+ /* this is the version of the nfs_args structure, not of NFS! */
+#ifdef HAVE_NFS_ARGS_T_FH_LEN
+# ifdef HAVE_FS_NFS3
+ if (nfs_version == NFS_VERSION3)
+ nap->fh_len = fhp->v3.am_fh3_length;
+ else
+# endif /* HAVE_FS_NFS3 */
+ nap->fh_len = FHSIZE;
+#endif /* HAVE_NFS_ARGS_T_FH_LEN */
+
+ /************************************************************************/
+ /*** HOST NAME ***/
+ /************************************************************************/
+ /*
+ * XXX: warning, using xstrlcpy in NFS_HN_DREF, which may corrupt a
+ * struct nfs_args, or truncate our concocted "hostname:/path"
+ * string prematurely.
+ */
+ NFS_HN_DREF(nap->hostname, host_name);
+#ifdef MNT2_NFS_OPT_HOSTNAME
+ nap->flags |= MNT2_NFS_OPT_HOSTNAME;
+#endif /* MNT2_NFS_OPT_HOSTNAME */
+
+ /************************************************************************/
+ /*** IP ADDRESS OF REMOTE HOST ***/
+ /************************************************************************/
+ if (ip_addr) {
+#ifdef HAVE_TRANSPORT_TYPE_TLI
+ nap->addr = ALLOC(struct netbuf); /* free()'ed at end of mount_nfs_fh() */
+#endif /* HAVE_TRANSPORT_TYPE_TLI */
+ NFS_SA_DREF(nap, ip_addr);
+ }
+
+ /************************************************************************/
+ /*** NFS PROTOCOL (UDP, TCP) AND VERSION ***/
+ /************************************************************************/
+#ifdef HAVE_NFS_ARGS_T_SOTYPE
+ /* bsdi3 uses this */
+ if (nfs_proto) {
+ if (STREQ(nfs_proto, "tcp"))
+ nap->sotype = SOCK_STREAM;
+ else if (STREQ(nfs_proto, "udp"))
+ nap->sotype = SOCK_DGRAM;
+ }
+#endif /* HAVE_NFS_ARGS_T_SOTYPE */
+
+#ifdef HAVE_NFS_ARGS_T_PROTO
+ nap->proto = 0; /* bsdi3 sets this field to zero */
+# ifdef IPPROTO_TCP
+ if (nfs_proto) {
+ if (STREQ(nfs_proto, "tcp")) /* AIX 4.2.x needs this */
+ nap->proto = IPPROTO_TCP;
+ else if (STREQ(nfs_proto, "udp"))
+ nap->proto = IPPROTO_UDP;
+ }
+# endif /* IPPROTO_TCP */
+#endif /* HAVE_NFS_ARGS_T_SOTYPE */
+
+#ifdef HAVE_NFS_ARGS_T_VERSION
+# ifdef NFS_ARGSVERSION
+ nap->version = NFS_ARGSVERSION; /* BSDI 3.0 and OpenBSD 2.2 */
+# endif /* NFS_ARGSVERSION */
+# ifdef DG_MOUNT_NFS_VERSION
+ nap->version = DG_MOUNT_NFS_VERSION; /* dg-ux */
+# endif /* DG_MOUNT_NFS_VERSION */
+#endif /* HAVE_NFS_ARGS_VERSION */
+
+ /************************************************************************/
+ /*** OTHER NFS SOCKET RELATED OPTIONS AND FLAGS ***/
+ /************************************************************************/
+
+ /************************************************************************/
+ /*** OTHER FLAGS AND OPTIONS ***/
+ /************************************************************************/
+
+#ifdef MNT2_NFS_OPT_BIODS
+ if ((nap->biods = hasmntval(mntp, MNTTAB_OPT_BIODS)))
+ nap->flags |= MNT2_NFS_OPT_BIODS;
+#endif /* MNT2_NFS_OPT_BIODS */
+
+#ifdef MNTTAB_OPT_SYMTTL /* symlink cache time-to-live */
+ if ((nap->symttl = hasmntval(mntp, MNTTAB_OPT_SYMTTL)))
+ nap->args.flags |= MNT2_NFS_OPT_SYMTTL;
+#endif /* MNTTAB_OPT_SYMTTL */
+
+#ifdef MNT2_NFS_OPT_PGTHRESH /* paging threshold */
+ if ((nap->pg_thresh = hasmntval(mntp, MNTTAB_OPT_PGTHRESH)))
+ nap->args.flags |= MNT2_NFS_OPT_PGTHRESH;
+#endif /* MNT2_NFS_OPT_PGTHRESH */
+
+#if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX)
+ if (amu_hasmntopt(mntp, MNTTAB_OPT_POSIX) != NULL) {
+ nap->flags |= MNT2_NFS_OPT_POSIX;
+# ifdef HAVE_NFS_ARGS_T_PATHCONF
+ nap->pathconf = NULL;
+# endif /* HAVE_NFS_ARGS_T_PATHCONF */
+ }
+#endif /* MNT2_NFS_OPT_POSIX && MNTTAB_OPT_POSIX */
+
+#ifdef HAVE_TRANSPORT_TYPE_TLI
+ /* set up syncaddr field */
+ nap->syncaddr = (struct netbuf *) NULL;
+
+ /* set up knconf field */
+ if (get_knetconfig(&nap->knconf, nfsncp, nfs_proto) < 0) {
+ plog(XLOG_FATAL, "cannot fill knetconfig structure for nfs_args");
+ going_down(1);
+ return;
+ }
+ /* update the flags field for knconf */
+ nap->args.flags |= MNT2_NFS_OPT_KNCONF;
+#endif /* HAVE_TRANSPORT_TYPE_TLI */
+
+#ifdef MNT2_NFS_OPT_FSNAME
+ nap->fsname = fs_name;
+ nap->args.flags |= MNT2_NFS_OPT_FSNAME;
+#endif /* MNT2_NFS_OPT_FSNAME */
+
+
+#ifdef HAVE_NFS_ARGS_T_OPTSTR
+ nap->optstr = mntp->mnt_opts;
+#endif /* HAVE_NFS_ARGS_T_OPTSTR */
+
+#if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS)
+ nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS);
+ if (nap->maxgrouplist != 0)
+ nap->flags |= MNT2_NFS_OPT_MAXGRPS;
+#endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */
+
+ /************************************************************************/
+ /*** FINAL ACTIONS ***/
+ /************************************************************************/
+
+#ifdef HAVE_NFS_ARGS_T_GFS_FLAGS
+ /* Ultrix stores generic flags in nfs_args.gfs_flags. */
+ nap->gfs_flags = genflags;
+#endif /* HAVE_NFS_ARGS_T_FLAGS */
+
+ return; /* end of compute_nfs_args() function */
+}
+
+#ifdef HAVE_FS_NFS4
+
+#define RPC_AUTH_GSS_KRB5 390003
+#define RPC_AUTH_GSS_KRB5I 390004
+#define RPC_AUTH_GSS_KRB5P 390005
+#define RPC_AUTH_GSS_LKEY 390006
+#define RPC_AUTH_GSS_LKEYI 390007
+#define RPC_AUTH_GSS_LKEYP 390008
+#define RPC_AUTH_GSS_SPKM 390009
+#define RPC_AUTH_GSS_SPKMI 390010
+#define RPC_AUTH_GSS_SPKMP 390011
+
+struct {
+ const char *name;
+ int num;
+} flavours[] = {
+ { "unix", AUTH_UNIX },
+ { "krb5", RPC_AUTH_GSS_KRB5 },
+ { "krb5i", RPC_AUTH_GSS_KRB5I },
+ { "krb5p", RPC_AUTH_GSS_KRB5P },
+ { "lkey", RPC_AUTH_GSS_LKEY },
+ { "lkeyi", RPC_AUTH_GSS_LKEYI },
+ { "lkeyp", RPC_AUTH_GSS_LKEYP },
+ { "spkm", RPC_AUTH_GSS_SPKM },
+ { "spkmi", RPC_AUTH_GSS_SPKMI },
+ { "spkmp", RPC_AUTH_GSS_SPKMP },
+};
+
+static char *
+set_nfs4_security(nfs4_args_t *nap, mntent_t *mntp)
+{
+ const char *o = hasmnteq(mntp, MNTTAB_OPT_SEC);
+ char *q, *s, *ss;
+ size_t l, i;
+
+ if (o == NULL)
+ o = "unix";
+
+ for (l = 1, q = strchr(o, ','); q; q = strchr(q + 1, ','))
+ l++;
+
+ nap->auth_flavours = xmalloc(l * sizeof(*nap->auth_flavours));
+
+ s = ss = xstrdup(o);
+ for (;;) {
+ q = strchr(s, ',');
+ if (q)
+ *q = '\0';
+
+ for (l = 0, i = 0; i < sizeof(flavours) / sizeof(flavours[0]); i++)
+ if (strcmp(flavours[i].name, s) == 0) {
+ nap->auth_flavours[l++] = flavours[i].num;
+ break;
+ }
+
+ if (i == sizeof(flavours) / sizeof(flavours[0]))
+ plog(XLOG_ERROR, "Unknown NFSv4 security mechanism %s\n", s);
+
+ if (q == NULL)
+ break;
+
+ *q = ':';
+ s = ++q;
+ }
+
+ nap->auth_flavourlen = l;
+ return ss;
+}
+
+static int
+get_my_ipv4addr(struct nfs_string *ns)
+{
+ struct hostent *hp;
+ char myname[MAXHOSTNAMELEN];
+
+ if (gethostname(myname, sizeof(myname)) == -1)
+ return -1;
+ if ((hp = gethostbyname(myname)) == NULL)
+ return -1;
+ if (inet_ntop(AF_INET, hp->h_addr, myname, sizeof(myname)) == NULL)
+ return -1;
+ ns->len = strlen(myname);
+ ns->data = xmalloc(ns->len + 1);
+ memcpy(ns->data, myname, ns->len + 1);
+ return 0;
+}
+
+static void
+add_nfs4_mntopts(const nfs4_args_t *nap, mntent_t *mntp, char *sec)
+{
+ char *opts = mntp->mnt_opts;
+ char buf[1024], addr[128];
+ size_t len = strlen(mntp->mnt_opts);
+
+ if (inet_ntop(AF_INET,
+ &((const struct sockaddr_in *)nap->host_addr)->sin_addr,
+ addr, sizeof(addr)) == NULL)
+ return;
+
+ xsnprintf(buf, sizeof(buf), ",clientaddr=%s,addr=%s", nap->client_addr.data,
+ addr);
+
+ len += strlen(buf) + 1;
+
+ if (sec && strcmp(sec, "unix") != 0) {
+ len += strlen(sec) + strlen(MNTTAB_OPT_SEC) + 2; /* 2 = ",=" */
+ } else
+ sec = NULL;
+
+ opts = xrealloc(mntp->mnt_opts, len);
+ xstrlcat(opts, buf, len);
+
+ if (sec) {
+ xstrlcat(opts, ",", len);
+ xstrlcat(opts, MNTTAB_OPT_SEC, len);
+ xstrlcat(opts, "=", len);
+ xstrlcat(opts, sec, len);
+ }
+
+ mntp->mnt_opts = opts;
+}
+
+static void
+print_nfs4_security(const nfs4_args_t *nap)
+{
+ char buf[1024];
+ char num[64];
+ size_t i, j;
+
+ buf[0] = '\0';
+
+ for (i = 0; i < nap->auth_flavourlen; i++) {
+
+ for (j = 0; j < sizeof(flavours) / sizeof(flavours[0]); j++)
+ if (flavours[j].num == nap->auth_flavours[i]) {
+ xstrlcpy(num, flavours[j].name, sizeof(num));
+ break;
+ }
+
+ if (j == sizeof(flavours) / sizeof(flavours[0])) {
+ plog(XLOG_ERROR, "Unknown NFSv4 security mechanism %d\n",
+ nap->auth_flavours[i]);
+ xsnprintf(num, sizeof(num), "*%d*", nap->auth_flavours[i]);
+ }
+
+ if (buf[0])
+ xstrlcat(buf, ":", sizeof(buf));
+
+ xstrlcat(buf, num, sizeof(buf));
+ }
+
+ plog(XLOG_DEBUG, "NA->auth_flavours \"%s\"\n", buf);
+}
+
+static void
+discard_nfs4_args(nfs4_args_t *nap)
+{
+ if (nap->client_addr.data)
+ free(nap->client_addr.data);
+ if (nap->hostname.data)
+ free(nap->hostname.data);
+ if (nap->mnt_path.data)
+ free(nap->mnt_path.data);
+ if (nap->host_addr)
+ free(nap->host_addr);
+ if (nap->auth_flavours)
+ free(nap->auth_flavours);
+}
+
+/*
+ * Fill in the many possible fields and flags of struct nfs4_args.
+ *
+ * nap: pre-allocated structure to fill in.
+ * mntp: mount entry structure (includes options)
+ * genflags: generic mount flags already determined
+ * nfsncp: (TLI only) netconfig entry for this NFS mount
+ * ip_addr: IP address of file server
+ * nfs_version: 4, or 0 if unknown
+ * nfs_proto: "udp", "tcp", or NULL.
+ * fhp: file handle structure pointer
+ * host_name: name of remote NFS host
+ * fs_name: remote file system name to mount
+ */
+static void
+compute_nfs4_args(nfs4_args_t *nap,
+ mntent_t *mntp,
+ int genflags,
+ struct netconfig *nfsncp,
+ struct sockaddr_in *ip_addr,
+ u_long nfs_version,
+ char *nfs_proto,
+ am_nfs_handle_t *fhp,
+ char *host_name,
+ char *fs_name)
+{
+ char *s;
+ struct nfs_common_args a;
+ uint16_t nfs_port;
+
+ /* initialize just in case */
+ memset((voidp) nap, 0, sizeof(nfs4_args_t));
+
+ /* compute all of the NFS attribute-cache flags */
+ memset(&a, 0, sizeof(a));
+ compute_nfs_attrcache_flags(&a, mntp);
+ compute_nfs_common_args(&a, mntp, nfs_proto, nfs_version);
+ get_nfs_common_args(nap, a);
+
+ get_my_ipv4addr(&nap->client_addr);
+
+ /************************************************************************/
+ /*** HOST NAME ***/
+ /************************************************************************/
+ nap->hostname.len = strlen(host_name);
+ nap->hostname.data = xmalloc(nap->hostname.len + 1);
+ memcpy(nap->hostname.data, host_name, nap->hostname.len + 1);
+
+ if ((s = strchr(fs_name, ':')) != NULL)
+ s++;
+ else
+ s = fs_name;
+
+ nap->mnt_path.len = strlen(s);
+ nap->mnt_path.data = xmalloc(nap->mnt_path.len + 1);
+ memcpy(nap->mnt_path.data, s, nap->mnt_path.len + 1);
+ plog(XLOG_DEBUG, "dir name %s\n", nap->mnt_path.data);
+
+ /************************************************************************/
+ /*** IP ADDRESS OF REMOTE HOST ***/
+ /************************************************************************/
+ nap->host_addrlen = sizeof(*ip_addr);
+ nap->host_addr = xmalloc(nap->host_addrlen);
+ memcpy(nap->host_addr, ip_addr, nap->host_addrlen);
+
+ nfs_port = hasmntval(mntp, MNTTAB_OPT_PORT);
+ if (nfs_port == 0)
+ nfs_port = htons(NFS_PORT);
+ else
+ nfs_port = htons(nfs_port);
+
+ ((struct sockaddr_in *)nap->host_addr)->sin_port = nfs_port;
+
+ nap->proto = 0; /* bsdi3 sets this field to zero */
+ if (nfs_proto) {
+ if (STREQ(nfs_proto, "tcp")) /* AIX 4.2.x needs this */
+ nap->proto = IPPROTO_TCP;
+ else if (STREQ(nfs_proto, "udp"))
+ nap->proto = IPPROTO_UDP;
+ }
+
+ nap->version = NFS4_MOUNT_VERSION; /* BSDI 3.0 and OpenBSD 2.2 */
+
+ /************************************************************************/
+ /*** OTHER NFS SOCKET RELATED OPTIONS AND FLAGS ***/
+ /************************************************************************/
+
+
+ /************************************************************************/
+ /*** OTHER FLAGS AND OPTIONS ***/
+ /************************************************************************/
+
+#if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX)
+ if (amu_hasmntopt(mntp, MNTTAB_OPT_POSIX) != NULL) {
+ nap->args.flags |= MNT2_NFS_OPT_POSIX;
+# ifdef HAVE_NFS_ARGS_T_PATHCONF
+ nap->pathconf = NULL;
+# endif /* HAVE_NFS_ARGS_T_PATHCONF */
+ }
+#endif /* MNT2_NFS_OPT_POSIX && MNTTAB_OPT_POSIX */
+
+#if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS)
+ nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS);
+ if (nap->maxgrouplist != 0)
+ nap->args.flags |= MNT2_NFS_OPT_MAXGRPS;
+#endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */
+
+#ifdef HAVE_NFS_ARGS_T_OPTSTR
+ nap->optstr = mntp->mnt_opts;
+#endif /* HAVE_NFS_ARGS_T_OPTSTR */
+
+ /************************************************************************/
+ /*** FINAL ACTIONS ***/
+ /************************************************************************/
+
+#ifdef HAVE_NFS_ARGS_T_GFS_FLAGS
+ /* Ultrix stores generic flags in nfs_args.gfs_flags. */
+ nap->gfs_flags = genflags;
+#endif /* HAVE_NFS_ARGS_T_FLAGS */
+
+ s = set_nfs4_security(nap, mntp);
+
+ /* Add addresses to the mount options */
+ add_nfs4_mntopts(nap, mntp, s);
+
+ return; /* end of compute_nfs4_args() function */
+}
+
+#ifdef DEBUG
+static void
+print_nfs4_args(const nfs4_args_t *nap, u_long nfs_version)
+{
+ struct sockaddr_in *sap;
+ struct nfs_common_args a;
+
+ if (!nap) {
+ plog(XLOG_DEBUG, "NULL nfs_args!");
+ return;
+ }
+
+ plog(XLOG_DEBUG, "NA->client_addr \"%s\"\n", nap->client_addr.data);
+ plog(XLOG_DEBUG, "NA->mnt_path = \"%s\"", nap->mnt_path.data);
+ plog(XLOG_DEBUG, "NA->hostname = \"%s\"", nap->hostname.data);
+ sap = (struct sockaddr_in *) nap->host_addr;
+ print_nfs_sockaddr_in("host_addr", sap);
+ plog(XLOG_DEBUG, "NA->proto = %d", (int) nap->proto);
+#ifdef HAVE_NFS_ARGS_T_VERSION
+ plog(XLOG_DEBUG, "NA->version = %d", nap->version);
+#endif /* HAVE_NFS_ARGS_T_VERSION */
+ print_nfs4_security(nap);
+
+ put_nfs_common_args(nap, a);
+ print_nfs_common_args(&a);
+}
+#endif
+#endif /* HAVE_FS_NFS4 */
+
+void
+compute_nfs_args(void *nap,
+ mntent_t *mntp,
+ int genflags,
+ struct netconfig *nfsncp,
+ struct sockaddr_in *ip_addr,
+ u_long nfs_version,
+ char *nfs_proto,
+ am_nfs_handle_t *fhp,
+ char *host_name,
+ char *fs_name)
+{
+#ifdef HAVE_FS_NFS4
+ if (nfs_version == NFS_VERSION4)
+ compute_nfs4_args(nap, mntp, genflags, nfsncp, ip_addr, nfs_version,
+ nfs_proto, fhp, host_name, fs_name);
+ else
+#endif /* HAVE_FS_NFS4 */
+ compute_nfs23_args(nap, mntp, genflags, nfsncp, ip_addr, nfs_version,
+ nfs_proto, fhp, host_name, fs_name);
+}
+
+void
+discard_nfs_args(void *nap, u_long nfs_version)
+{
+#ifdef HAVE_FS_NFS4
+ if (nfs_version == NFS_VERSION4)
+ discard_nfs4_args(nap);
+ else
+#endif /* HAVE_FS_NFS4 */
+ discard_nfs23_args(nap);
+}
+
+#ifdef DEBUG
+void
+print_nfs_args(const void *nap, u_long nfs_version)
+{
+#ifdef HAVE_FS_NFS4
+ if (nfs_version == NFS_VERSION4)
+ print_nfs4_args(nap, nfs_version);
+ else
+#endif /* HAVE_FS_NFS4 */
+ print_nfs23_args(nap, nfs_version);
+}
+#endif
+
+
+/*
+ * Fill in special values for flags and fields of nfs_args, for an
+ * automounter NFS mount.
+ */
+void
+compute_automounter_nfs_args(nfs_args_t *nap, mntent_t *mntp)
+{
+ struct nfs_common_args a;
+
+#ifdef MNT2_NFS_OPT_SYMTTL
+ /*
+ * Don't let the kernel cache symbolic links we generate, or else lookups
+ * will bypass amd and fail to remount stuff as needed.
+ */
+ plog(XLOG_INFO, "turning on NFS option symttl and setting value to 0");
+ nap->flags |= MNT2_NFS_OPT_SYMTTL;
+ nap->symttl = 0;
+#endif /* MNT2_NFS_OPT_SYMTTL */
+
+ /*
+ * This completes the flags for the HIDE_MOUNT_TYPE code in the
+ * mount_amfs_toplvl() function in amd/amfs_toplvl.c.
+ * Some systems don't have a mount type, but a mount flag.
+ */
+#ifdef MNT2_NFS_OPT_AUTO
+ nap->flags |= MNT2_NFS_OPT_AUTO;
+#endif /* MNT2_NFS_OPT_AUTO */
+#ifdef MNT2_NFS_OPT_IGNORE
+ nap->flags |= MNT2_NFS_OPT_IGNORE;
+#endif /* MNT2_NFS_OPT_IGNORE */
+#ifdef MNT2_GEN_OPT_AUTOMNTFS
+ nap->flags |= MNT2_GEN_OPT_AUTOMNTFS;
+#endif /* not MNT2_GEN_OPT_AUTOMNTFS */
+
+#ifdef MNT2_NFS_OPT_DUMBTIMR
+ /*
+ * Don't let the kernel start computing throughput of Amd. The numbers
+ * will be meaningless because of the way Amd does mount retries.
+ */
+ plog(XLOG_INFO, "%s: disabling nfs congestion window", mntp->mnt_dir);
+ nap->flags |= MNT2_NFS_OPT_DUMBTIMR;
+#endif /* MNT2_NFS_OPT_DUMBTIMR */
+
+ /* compute all of the NFS attribute-cache flags */
+ memset(&a, 0, sizeof(a));
+ a.flags = nap->flags;
+ compute_nfs_attrcache_flags(&a, mntp);
+ get_nfs_common_args(nap, a);
+
+ /*
+ * Provide a slight bit more security by requiring the kernel to use
+ * reserved ports.
+ */
+#ifdef MNT2_NFS_OPT_RESVPORT
+ nap->flags |= MNT2_NFS_OPT_RESVPORT;
+#endif /* MNT2_NFS_OPT_RESVPORT */
+}
+
+int
+nfs_valid_version(u_long v)
+{
+ return v >= NFS_VERS_MIN && v <= NFS_VERS_MAX;
+}
diff --git a/contrib/amd/libamu/mtab.c b/contrib/amd/libamu/mtab.c
index 50ba994733f0..ee603af34359 100644
--- a/contrib/amd/libamu/mtab.c
+++ b/contrib/amd/libamu/mtab.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -233,9 +229,9 @@ hasmntstr(mntent_t *mnt, char *opt)
char *endptr = strchr(eq, ',');
- /* if saw no comma, return strdup'd string */
+ /* if saw no comma, return xstrdup'd string */
if (!endptr)
- return strdup(eq);
+ return xstrdup(eq);
else {
/* else we need to copy only the chars needed */
int len = endptr - eq;
diff --git a/contrib/amd/libamu/nfs_prot_xdr.c b/contrib/amd/libamu/nfs_prot_xdr.c
index df8a0b006b55..bfdc7b2492a3 100644
--- a/contrib/amd/libamu/nfs_prot_xdr.c
+++ b/contrib/amd/libamu/nfs_prot_xdr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -56,3 +52,14 @@ xdr_amq_string(XDR *xdrs, amq_string *objp)
}
return (TRUE);
}
+
+
+bool_t
+xdr_amq_sync_umnt(XDR *xdrs, amq_sync_umnt *objp)
+{
+
+ if (!xdr_opaque(xdrs, (char *) objp, sizeof(*objp))) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
diff --git a/contrib/amd/libamu/strerror.c b/contrib/amd/libamu/strerror.c
index 49dd2fc3ce9f..faf2916f31e6 100644
--- a/contrib/amd/libamu/strerror.c
+++ b/contrib/amd/libamu/strerror.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2002-2006 Ion Badulescu
- * Copyright (c) 1997-2006 Erez Zadok
+ * Copyright (c) 2002-2014 Ion Badulescu
+ * 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.
@@ -17,11 +17,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
diff --git a/contrib/amd/libamu/strutil.c b/contrib/amd/libamu/strutil.c
index 5a1e759bff67..03a8e88f6080 100644
--- a/contrib/amd/libamu/strutil.c
+++ b/contrib/amd/libamu/strutil.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -268,3 +264,37 @@ xvsnprintf(char *str, size_t size, const char *format, va_list ap)
return ret;
}
+
+static size_t
+vstrlen(const char *src, va_list ap)
+{
+ size_t len = strlen(src);
+ while ((src = va_arg(ap, const char *)) != NULL)
+ len += strlen(src);
+ return len;
+}
+
+static void
+vstrcpy(char *dst, const char *src, va_list ap)
+{
+ strcpy(dst, src);
+ while ((src = va_arg(ap, const char *)) != NULL)
+ strcat(dst, src);
+}
+
+char *
+strvcat(const char *src, ...)
+{
+ size_t len;
+ char *dst;
+ va_list ap;
+
+ va_start(ap, src);
+ len = vstrlen(src, ap);
+ va_end(ap);
+ dst = xmalloc(len + 1);
+ va_start(ap, src);
+ vstrcpy(dst, src, ap);
+ va_end(ap);
+ return dst;
+}
diff --git a/contrib/amd/libamu/wire.c b/contrib/amd/libamu/wire.c
index c1852cdca7f1..c9da0fe276a5 100644
--- a/contrib/amd/libamu/wire.c
+++ b/contrib/amd/libamu/wire.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -226,7 +222,7 @@ getwire_lookup(u_long address, u_long netmask, int ishost)
}
/* fill in network number (string) */
- al->ip_net_num = strdup(netNumberBuf);
+ al->ip_net_num = xstrdup(netNumberBuf);
if (np != NULL)
s = np->n_name;
@@ -242,7 +238,7 @@ getwire_lookup(u_long address, u_long netmask, int ishost)
}
/* fill in network name (string) */
- al->ip_net_name = strdup(s);
+ al->ip_net_name = xstrdup(s);
/* Let's be cautious here about buffer overflows -Ion */
if (strlen(s) > MAXHOSTNAMELEN) {
al->ip_net_name[MAXHOSTNAMELEN] = '\0';
@@ -318,9 +314,14 @@ is_network_member(const char *net)
if (STREQ(net, al->ip_net_name) || STREQ(net, al->ip_net_num))
return TRUE;
} else {
- char *netstr = strdup(net), *maskstr;
+ char *netstr = xstrdup(net), *maskstr;
u_long netnum, masknum = 0;
maskstr = strchr(netstr, '/');
+ if (maskstr == NULL) {
+ plog(XLOG_ERROR, "%s: netstr %s does not have a `/'", __func__, netstr);
+ XFREE(netstr);
+ return FALSE;
+ }
maskstr[0] = '\0'; /* null terminate netstr */
maskstr++;
if (*maskstr == '\0') /* if empty string, make it NULL */
diff --git a/contrib/amd/libamu/xdr_func.c b/contrib/amd/libamu/xdr_func.c
index 6bd0254318c6..e437dd49d567 100644
--- a/contrib/amd/libamu/xdr_func.c
+++ b/contrib/amd/libamu/xdr_func.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -951,7 +947,6 @@ xdr_am_mountres3_ok(XDR *xdrs, am_mountres3_ok *objp)
return (TRUE);
}
-
bool_t
xdr_am_mountres3(XDR *xdrs, am_mountres3 *objp)
{
@@ -968,6 +963,78 @@ xdr_am_mountres3(XDR *xdrs, am_mountres3 *objp)
return (TRUE);
}
+bool_t
+xdr_am_cookieverf3(XDR *xdrs, am_cookieverf3 objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_cookieverf3:");
+
+ if (!xdr_opaque(xdrs, objp, AM_NFS3_COOKIEVERFSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+#if 0
+/* In FreeBSD xdr_uint64() is defined in ../../../include/rpcsvc/nfs_prot.x */
+/*
+ * Not ideal, xdr_u_int64_t() is not defined in Linux glibc RPC
+ * but xdr_u_quad_t() is. But in libtirpc xdr_u_quad_t() is not
+ * defined and xdr_u_int64_t() is. So xdr_u_int64_t() is probably
+ * an expected standard xdr function so, if it isn't defined use
+ * an internal xdr_u_int64_t() that uses xdr_u_quad_t().
+ */
+#ifndef HAVE_XDR_U_INT64_T
+#define xdr_u_int64_t(xdrs, objp) xdr_u_quad_t(xdrs, objp)
+#endif /* HAVE_XDR_U_INT64_T */
+
+bool_t
+xdr_uint64(XDR *xdrs, uint64 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_uint64:");
+
+ if (!xdr_u_int64_t(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+#endif
+
+bool_t
+xdr_am_cookie3(XDR *xdrs, am_cookie3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_cookie3:");
+
+ if (!xdr_uint64(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_nfs_fh3(XDR *xdrs, am_nfs_fh3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_nfs_fh3:");
+
+ if (!xdr_u_int(xdrs, &objp->am_fh3_length))
+ return (FALSE);
+ if (objp->am_fh3_length > AM_FHSIZE3)
+ return (FALSE);
+ if (!xdr_opaque(xdrs, objp->am_fh3_data, objp->am_fh3_length))
+ return (FALSE);
+ return (TRUE);
+}
+
+bool_t
+xdr_am_nfsstat3(XDR *xdrs, am_nfsstat3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_nfsstat3:");
+
+ if (!xdr_enum(xdrs, (enum_t *)objp))
+ return (FALSE);
+ return (TRUE);
+}
bool_t
xdr_am_diropargs3(XDR *xdrs, am_diropargs3 *objp)
@@ -982,7 +1049,6 @@ xdr_am_diropargs3(XDR *xdrs, am_diropargs3 *objp)
return (TRUE);
}
-
bool_t
xdr_am_filename3(XDR *xdrs, am_filename3 *objp)
{
@@ -994,6 +1060,315 @@ xdr_am_filename3(XDR *xdrs, am_filename3 *objp)
return (TRUE);
}
+bool_t
+xdr_am_ftype3(XDR *xdrs, am_ftype3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_ftype3:");
+
+ if (!xdr_enum(xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_mode3(XDR *xdrs, am_mode3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_mode3:");
+
+ if (!xdr_u_int(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_uid3(XDR *xdrs, am_uid3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_uid3:");
+
+ if (!xdr_u_int(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_gid3(XDR *xdrs, am_gid3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_gid3:");
+
+ if (!xdr_u_int(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_size3(XDR *xdrs, am_size3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_size3:");
+
+ if (!xdr_uint64(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_fileid3(XDR *xdrs, am_fileid3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_fileid3:");
+
+ if (!xdr_uint64(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_specdata3(XDR *xdrs, am_specdata3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_specdata3:");
+
+ if (!xdr_u_int(xdrs, &objp->specdata1))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->specdata2))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_nfstime3(XDR *xdrs, am_nfstime3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_nfstime3:");
+
+ if (!xdr_u_int(xdrs, &objp->seconds))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->nseconds))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_fattr3(XDR *xdrs, am_fattr3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_fattr3:");
+
+ if (!xdr_am_ftype3(xdrs, &objp->type))
+ return FALSE;
+ if (!xdr_am_mode3(xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->nlink))
+ return FALSE;
+ if (!xdr_am_uid3(xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_am_gid3(xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->used))
+ return FALSE;
+ if (!xdr_am_specdata3(xdrs, &objp->rdev))
+ return FALSE;
+ if (!xdr_uint64(xdrs, &objp->fsid))
+ return FALSE;
+ if (!xdr_am_fileid3(xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->mtime))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->ctime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_post_op_attr(XDR *xdrs, am_post_op_attr *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_post_op_attr:");
+
+ if (!xdr_bool(xdrs, &objp->attributes_follow))
+ return FALSE;
+ switch (objp->attributes_follow) {
+ case TRUE:
+ if (!xdr_am_fattr3(xdrs, &objp->am_post_op_attr_u.attributes))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_stable_how(XDR *xdrs, am_stable_how *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_stable_how:");
+
+ if (!xdr_enum(xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_offset3(XDR *xdrs, am_offset3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_offset3:");
+
+ if (!xdr_uint64(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_count3(XDR *xdrs, am_count3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_count3:");
+
+ if (!xdr_u_int(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_wcc_attr(XDR *xdrs, am_wcc_attr *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_wcc_attr:");
+
+ if (!xdr_am_size3(xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->mtime))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->ctime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_pre_op_attr(XDR *xdrs, am_pre_op_attr *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, ":xdr_am_pre_op_attr");
+
+ if (!xdr_bool(xdrs, &objp->attributes_follow))
+ return FALSE;
+ switch (objp->attributes_follow) {
+ case TRUE:
+ if (!xdr_am_wcc_attr(xdrs, &objp->am_pre_op_attr_u.attributes))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_wcc_data(XDR *xdrs, am_wcc_data *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_wcc_data:");
+
+ if (!xdr_am_pre_op_attr(xdrs, &objp->before))
+ return FALSE;
+ if (!xdr_am_post_op_attr(xdrs, &objp->after))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_WRITE3args(XDR *xdrs, am_WRITE3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_WRITE3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_am_offset3(xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_am_stable_how(xdrs, &objp->stable))
+ return FALSE;
+ if (!xdr_bytes(xdrs, (char **)&objp->data.data_val,
+ (u_int *) &objp->data.data_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_writeverf3(XDR *xdrs, am_writeverf3 objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_writeverf3:");
+
+ if (!xdr_opaque(xdrs, objp, AM_NFS3_WRITEVERFSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_WRITE3resok(XDR *xdrs, am_WRITE3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_WRITE3resok:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->file_wcc))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_am_stable_how(xdrs, &objp->committed))
+ return FALSE;
+ if (!xdr_am_writeverf3(xdrs, objp->verf))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_WRITE3resfail(XDR *xdrs, am_WRITE3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_WRITE3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->file_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_WRITE3res(XDR *xdrs, am_WRITE3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_WRITE3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_WRITE3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_WRITE3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
bool_t
xdr_am_LOOKUP3args(XDR *xdrs, am_LOOKUP3args *objp)
@@ -1006,7 +1381,6 @@ xdr_am_LOOKUP3args(XDR *xdrs, am_LOOKUP3args *objp)
return (TRUE);
}
-
bool_t
xdr_am_LOOKUP3res(XDR *xdrs, am_LOOKUP3res *objp)
{
@@ -1028,25 +1402,17 @@ xdr_am_LOOKUP3res(XDR *xdrs, am_LOOKUP3res *objp)
return (TRUE);
}
-
bool_t
xdr_am_LOOKUP3resfail(XDR *xdrs, am_LOOKUP3resfail *objp)
{
if (amuDebug(D_XDRTRACE))
plog(XLOG_DEBUG, "xdr_am_LOOKUP3resfail:");
- /*
- * Don't xdr post_op_attr: amd doesn't need them, but they require many
- * additional xdr functions.
- */
-#if 0
- if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
+ if (!xdr_am_post_op_attr(xdrs, &objp->dir_attributes))
return (FALSE);
-#endif
return (TRUE);
}
-
bool_t
xdr_am_LOOKUP3resok(XDR *xdrs, am_LOOKUP3resok *objp)
{
@@ -1055,44 +1421,1656 @@ xdr_am_LOOKUP3resok(XDR *xdrs, am_LOOKUP3resok *objp)
if (!xdr_am_nfs_fh3(xdrs, &objp->object))
return (FALSE);
- /*
- * Don't xdr post_op_attr: amd doesn't need them, but they require many
- * additional xdr functions.
- */
-#if 0
- if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
return (FALSE);
- if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
+ if (!xdr_am_post_op_attr(xdrs, &objp->dir_attributes))
return (FALSE);
-#endif
return (TRUE);
}
+bool_t
+xdr_am_COMMIT3args(XDR *xdrs, am_COMMIT3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_COMMIT3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_am_offset3(xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->count))
+ return FALSE;
+ return TRUE;
+}
bool_t
-xdr_am_nfs_fh3(XDR *xdrs, am_nfs_fh3 *objp)
+xdr_am_COMMIT3resok(XDR *xdrs, am_COMMIT3resok *objp)
{
if (amuDebug(D_XDRTRACE))
- plog(XLOG_DEBUG, "xdr_am_nfs_fh3:");
+ plog(XLOG_DEBUG, "xdr_am_COMMIT3resok:");
- if (!xdr_u_int(xdrs, &objp->am_fh3_length))
- return (FALSE);
- if (objp->am_fh3_length > AM_FHSIZE3)
- return (FALSE);
- if (!xdr_opaque(xdrs, objp->am_fh3_data, objp->am_fh3_length))
- return (FALSE);
- return (TRUE);
+ if (!xdr_am_wcc_data(xdrs, &objp->file_wcc))
+ return FALSE;
+ if (!xdr_am_writeverf3(xdrs, objp->verf))
+ return FALSE;
+ return TRUE;
}
+bool_t
+xdr_am_COMMIT3resfail(XDR *xdrs, am_COMMIT3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_COMMIT3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->file_wcc))
+ return FALSE;
+ return TRUE;
+}
bool_t
-xdr_am_nfsstat3(XDR *xdrs, am_nfsstat3 *objp)
+xdr_am_COMMIT3res(XDR *xdrs, am_COMMIT3res *objp)
{
if (amuDebug(D_XDRTRACE))
- plog(XLOG_DEBUG, "xdr_am_nfsstat3:");
+ plog(XLOG_DEBUG, "xdr_am_COMMIT3res:");
- if (!xdr_enum(xdrs, (enum_t *)objp))
- return (FALSE);
- return (TRUE);
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_COMMIT3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_COMMIT3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_ACCESS3args(XDR *xdrs, am_ACCESS3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_ACCESS3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->object))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->access))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_ACCESS3resok(XDR *xdrs, am_ACCESS3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_ACCESS3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->access))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_ACCESS3resfail(XDR *xdrs, am_ACCESS3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_ACCESS3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_ACCESS3res(XDR *xdrs, am_ACCESS3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_ACCESS3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_ACCESS3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_ACCESS3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_GETATTR3args(XDR *xdrs, am_GETATTR3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_GETATTR3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_GETATTR3resok(XDR *xdrs, am_GETATTR3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_GETATTR3resok:");
+
+ if (!xdr_am_fattr3(xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_GETATTR3res(XDR *xdrs, am_GETATTR3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_GETATTR3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_GETATTR3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_time_how(XDR *xdrs, am_time_how *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_time_how:");
+
+ if (!xdr_enum(xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_set_mode3(XDR *xdrs, am_set_mode3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_set_mode3:");
+
+ if (!xdr_bool(xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_am_mode3(xdrs, &objp->am_set_mode3_u.mode))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_set_uid3(XDR *xdrs, am_set_uid3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_set_uid3:");
+
+ if (!xdr_bool(xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_am_uid3(xdrs, &objp->am_set_uid3_u.uid))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_set_gid3(XDR *xdrs, am_set_gid3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_set_gid3:");
+
+ if (!xdr_bool(xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_am_gid3(xdrs, &objp->am_set_gid3_u.gid))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_set_size3(XDR *xdrs, am_set_size3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_set_size3:");
+
+ if (!xdr_bool(xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_am_size3(xdrs, &objp->am_set_size3_u.size))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_set_atime(XDR *xdrs, am_set_atime *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_set_atime:");
+
+ if (!xdr_am_time_how(xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case AM_SET_TO_CLIENT_TIME:
+ if (!xdr_am_nfstime3(xdrs, &objp->am_set_atime_u.atime))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_set_mtime(XDR *xdrs, am_set_mtime *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_set_mtime:");
+
+ if (!xdr_am_time_how(xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case AM_SET_TO_CLIENT_TIME:
+ if (!xdr_am_nfstime3(xdrs, &objp->am_set_mtime_u.mtime))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_sattr3(XDR *xdrs, am_sattr3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_sattr3:");
+
+ if (!xdr_am_set_mode3(xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_am_set_uid3(xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_am_set_gid3(xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_am_set_size3(xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_am_set_atime(xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_am_set_mtime(xdrs, &objp->mtime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_createmode3(XDR *xdrs, am_createmode3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_createmode3:");
+
+ if (!xdr_enum(xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_createverf3(XDR *xdrs, am_createverf3 objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_createverf3:");
+
+ if (!xdr_opaque(xdrs, objp, AM_NFS3_CREATEVERFSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_createhow3(XDR *xdrs, am_createhow3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_createhow3:");
+
+ if (!xdr_am_createmode3(xdrs, &objp->mode))
+ return FALSE;
+ switch (objp->mode) {
+ case AM_UNCHECKED:
+ if (!xdr_am_sattr3(xdrs, &objp->am_createhow3_u.obj_attributes))
+ return FALSE;
+ break;
+ case AM_GUARDED:
+ if (!xdr_am_sattr3(xdrs, &objp->am_createhow3_u.g_obj_attributes))
+ return FALSE;
+ break;
+ case AM_EXCLUSIVE:
+ if (!xdr_am_createverf3(xdrs, objp->am_createhow3_u.verf))
+ return FALSE;
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_CREATE3args(XDR *xdrs, am_CREATE3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_CREATE3args:");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_am_createhow3(xdrs, &objp->how))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_post_op_fh3(XDR *xdrs, am_post_op_fh3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_post_op_fh3:");
+
+ if (!xdr_bool(xdrs, &objp->handle_follows))
+ return FALSE;
+ switch (objp->handle_follows) {
+ case TRUE:
+ if (!xdr_am_nfs_fh3(xdrs, &objp->am_post_op_fh3_u.handle))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_CREATE3resok(XDR *xdrs, am_CREATE3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_CREATE3resok:");
+
+ if (!xdr_am_post_op_fh3(xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_CREATE3resfail(XDR *xdrs, am_CREATE3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_CREATE3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_CREATE3res(XDR *xdrs, am_CREATE3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_CREATE3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_CREATE3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_CREATE3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_REMOVE3args(XDR *xdrs, am_REMOVE3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_REMOVE3args:");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_REMOVE3resok(XDR *xdrs, am_REMOVE3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_REMOVE3resok:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_REMOVE3resfail(XDR *xdrs, am_REMOVE3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_REMOVE3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_REMOVE3res(XDR *xdrs, am_REMOVE3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_REMOVE3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_REMOVE3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_REMOVE3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_READ3args(XDR *xdrs, am_READ3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READ3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_am_offset3(xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->count))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READ3resok(XDR *xdrs, am_READ3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READ3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->file_attributes))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->eof))
+ return FALSE;
+ if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READ3resfail(XDR *xdrs, am_READ3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READ3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->file_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READ3res(XDR *xdrs, am_READ3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READ3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_READ3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_READ3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSINFO3args(XDR *xdrs, am_FSINFO3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSINFO3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->fsroot))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSINFO3resok(XDR *xdrs, am_FSINFO3resok *objp)
+{
+ register int32_t *buf;
+
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSINFO3resok:");
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ buf = XDR_INLINE(xdrs, 7 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int(xdrs, &objp->rtmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->rtpref))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->rtmult))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtpref))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtmult))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->dtpref))
+ return FALSE;
+ } else {
+ IXDR_PUT_U_LONG(buf, objp->rtmax);
+ IXDR_PUT_U_LONG(buf, objp->rtpref);
+ IXDR_PUT_U_LONG(buf, objp->rtmult);
+ IXDR_PUT_U_LONG(buf, objp->wtmax);
+ IXDR_PUT_U_LONG(buf, objp->wtpref);
+ IXDR_PUT_U_LONG(buf, objp->wtmult);
+ IXDR_PUT_U_LONG(buf, objp->dtpref);
+ }
+ if (!xdr_am_size3(xdrs, &objp->maxfilesize))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->time_delta))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->properties))
+ return FALSE;
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ buf = XDR_INLINE(xdrs, 7 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->rtmax))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->rtpref))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->rtmult))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->wtmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtpref))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtmult))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->dtpref))
+ return FALSE;
+ } else {
+ objp->rtmax = IXDR_GET_U_LONG(buf);
+ objp->rtpref = IXDR_GET_U_LONG(buf);
+ objp->rtmult = IXDR_GET_U_LONG(buf);
+ objp->wtmax = IXDR_GET_U_LONG(buf);
+ objp->wtpref = IXDR_GET_U_LONG(buf);
+ objp->wtmult = IXDR_GET_U_LONG(buf);
+ objp->dtpref = IXDR_GET_U_LONG(buf);
+ }
+ if (!xdr_am_size3(xdrs, &objp->maxfilesize))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->time_delta))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->properties))
+ return FALSE;
+ return TRUE;
+ }
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->rtmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->rtpref))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->rtmult))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtpref))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtmult))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->dtpref))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->maxfilesize))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->time_delta))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->properties))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSINFO3resfail(XDR *xdrs, am_FSINFO3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSINFO3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSINFO3res(XDR *xdrs, am_FSINFO3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSINFO3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_FSINFO3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_FSINFO3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSSTAT3args(XDR *xdrs, am_FSSTAT3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSSTAT3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->fsroot))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSSTAT3resok(XDR *xdrs, am_FSSTAT3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSSTAT3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->tbytes))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->fbytes))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->abytes))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->tfiles))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->ffiles))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->afiles))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->invarsec))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSSTAT3resfail(XDR *xdrs, am_FSSTAT3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSSTAT3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSSTAT3res(XDR *xdrs, am_FSSTAT3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSSTAT3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_FSSTAT3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_FSSTAT3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_PATHCONF3args(XDR *xdrs, am_PATHCONF3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_PATHCONF3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_PATHCONF3resok(XDR *xdrs, am_PATHCONF3resok *objp)
+{
+ register int32_t *buf;
+
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_PATHCONF3resok:");
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int(xdrs, &objp->linkmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->name_max))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->no_trunc))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->chown_restricted))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->case_insensitive))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->case_preserving))
+ return FALSE;
+ } else {
+ IXDR_PUT_U_LONG(buf, objp->linkmax);
+ IXDR_PUT_U_LONG(buf, objp->name_max);
+ IXDR_PUT_BOOL(buf, objp->no_trunc);
+ IXDR_PUT_BOOL(buf, objp->chown_restricted);
+ IXDR_PUT_BOOL(buf, objp->case_insensitive);
+ IXDR_PUT_BOOL(buf, objp->case_preserving);
+ }
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int(xdrs, &objp->linkmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->name_max))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->no_trunc))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->chown_restricted))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->case_insensitive))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->case_preserving))
+ return FALSE;
+ } else {
+ objp->linkmax = IXDR_GET_U_LONG(buf);
+ objp->name_max = IXDR_GET_U_LONG(buf);
+ objp->no_trunc = IXDR_GET_BOOL(buf);
+ objp->chown_restricted = IXDR_GET_BOOL(buf);
+ objp->case_insensitive = IXDR_GET_BOOL(buf);
+ objp->case_preserving = IXDR_GET_BOOL(buf);
+ }
+ return TRUE;
+ }
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->linkmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->name_max))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->no_trunc))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->chown_restricted))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->case_insensitive))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->case_preserving))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_PATHCONF3resfail(XDR *xdrs, am_PATHCONF3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_PATHCONF3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_PATHCONF3res(XDR *xdrs, am_PATHCONF3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_PATHCONF3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_PATHCONF3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_PATHCONF3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_nfspath3(XDR *xdrs, am_nfspath3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_nfspath3:");
+
+ if (!xdr_string(xdrs, objp, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_symlinkdata3(XDR *xdrs, am_symlinkdata3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_symlinkdata3:");
+
+ if (!xdr_am_sattr3(xdrs, &objp->symlink_attributes))
+ return FALSE;
+ if (!xdr_am_nfspath3(xdrs, &objp->symlink_data))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SYMLINK3args(XDR *xdrs, am_SYMLINK3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SYMLINK3args:");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_am_symlinkdata3(xdrs, &objp->symlink))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SYMLINK3resok(XDR *xdrs, am_SYMLINK3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SYMLINK3resok:");
+
+ if (!xdr_am_post_op_fh3(xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SYMLINK3resfail(XDR *xdrs, am_SYMLINK3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SYMLINK3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SYMLINK3res(XDR *xdrs, am_SYMLINK3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SYMLINK3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_SYMLINK3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_SYMLINK3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_READLINK3args(XDR *xdrs, am_READLINK3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READLINK3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->symlink))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READLINK3resok(XDR *xdrs, am_READLINK3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READLINK3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->symlink_attributes))
+ return FALSE;
+ if (!xdr_am_nfspath3(xdrs, &objp->data))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READLINK3resfail(XDR *xdrs, am_READLINK3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READLINK3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->symlink_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READLINK3res(XDR *xdrs, am_READLINK3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READLINK3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_READLINK3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_READLINK3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_devicedata3(XDR *xdrs, am_devicedata3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_devicedata3:");
+
+ if (!xdr_am_sattr3(xdrs, &objp->dev_attributes))
+ return FALSE;
+ if (!xdr_am_specdata3(xdrs, &objp->spec))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_mknoddata3(XDR *xdrs, am_mknoddata3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_mknoddata3:");
+
+ if (!xdr_am_ftype3(xdrs, &objp->type))
+ return FALSE;
+ switch (objp->type) {
+ case AM_NF3CHR:
+ if (!xdr_am_devicedata3(xdrs, &objp->am_mknoddata3_u.chr_device))
+ return FALSE;
+ break;
+ case AM_NF3BLK:
+ if (!xdr_am_devicedata3(xdrs, &objp->am_mknoddata3_u.blk_device))
+ return FALSE;
+ break;
+ case AM_NF3SOCK:
+ if (!xdr_am_sattr3(xdrs, &objp->am_mknoddata3_u.sock_attributes))
+ return FALSE;
+ break;
+ case AM_NF3FIFO:
+ if (!xdr_am_sattr3(xdrs, &objp->am_mknoddata3_u.pipe_attributes))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKNOD3args(XDR *xdrs, am_MKNOD3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_MKNOD3args:");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_am_mknoddata3(xdrs, &objp->what))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKNOD3resok(XDR *xdrs, am_MKNOD3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_MKNOD3resok:");
+
+ if (!xdr_am_post_op_fh3(xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKNOD3resfail(XDR *xdrs, am_MKNOD3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_MKNOD3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKNOD3res(XDR *xdrs, am_MKNOD3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, ":");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_MKNOD3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_MKNOD3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKDIR3args(XDR *xdrs, am_MKDIR3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, ":");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_am_sattr3(xdrs, &objp->attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKDIR3resok(XDR *xdrs, am_MKDIR3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_MKDIR3resok:");
+
+ if (!xdr_am_post_op_fh3(xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKDIR3resfail(XDR *xdrs, am_MKDIR3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_MKDIR3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKDIR3res(XDR *xdrs, am_MKDIR3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_MKDIR3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_MKDIR3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_MKDIR3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_RMDIR3args(XDR *xdrs, am_RMDIR3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RMDIR3args:");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_RMDIR3resok(XDR *xdrs, am_RMDIR3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RMDIR3resok:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_RMDIR3resfail(XDR *xdrs, am_RMDIR3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RMDIR3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_RMDIR3res(XDR *xdrs, am_RMDIR3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RMDIR3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_RMDIR3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_RMDIR3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_RENAME3args(XDR *xdrs, am_RENAME3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RENAME3args:");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->from))
+ return FALSE;
+ if (!xdr_am_diropargs3(xdrs, &objp->to))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_RENAME3resok(XDR *xdrs, am_RENAME3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RENAME3resok:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->fromdir_wcc))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->todir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_RENAME3resfail(XDR *xdrs, am_RENAME3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RENAME3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->fromdir_wcc))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->todir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_RENAME3res(XDR *xdrs, am_RENAME3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RENAME3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_RENAME3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_RENAME3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIRPLUS3args(XDR *xdrs, am_READDIRPLUS3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIRPLUS3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->dir))
+ return FALSE;
+ if (!xdr_am_cookie3(xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_am_cookieverf3(xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->dircount))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->maxcount))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_entryplus3(XDR *xdrs, am_entryplus3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_entryplus3:");
+
+ if (!xdr_am_fileid3(xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_am_filename3(xdrs, &objp->name))
+ return FALSE;
+ if (!xdr_am_cookie3(xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_am_post_op_attr(xdrs, &objp->name_attributes))
+ return FALSE;
+ if (!xdr_am_post_op_fh3(xdrs, &objp->name_handle))
+ return FALSE;
+ if (!xdr_pointer(xdrs, (char **)&objp->nextentry,
+ sizeof(am_entryplus3), (xdrproc_t) xdr_am_entryplus3))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_dirlistplus3(XDR *xdrs, am_dirlistplus3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_dirlistplus3:");
+
+ if (!xdr_pointer(xdrs, (char **)&objp->entries,
+ sizeof(am_entryplus3), (xdrproc_t) xdr_am_entryplus3))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->eof))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIRPLUS3resok(XDR *xdrs, am_READDIRPLUS3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIRPLUS3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->dir_attributes))
+ return FALSE;
+ if (!xdr_am_cookieverf3(xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_am_dirlistplus3(xdrs, &objp->reply))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIRPLUS3resfail(XDR *xdrs, am_READDIRPLUS3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIRPLUS3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->dir_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIRPLUS3res(XDR *xdrs, am_READDIRPLUS3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIRPLUS3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_READDIRPLUS3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_READDIRPLUS3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIR3args(XDR *xdrs, am_READDIR3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIR3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->dir))
+ return FALSE;
+ if (!xdr_am_cookie3(xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_am_cookieverf3(xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->count))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_entry3(XDR *xdrs, am_entry3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_entry3:");
+
+ if (!xdr_am_fileid3(xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_am_filename3(xdrs, &objp->name))
+ return FALSE;
+ if (!xdr_am_cookie3(xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_pointer(xdrs, (char **)&objp->nextentry,
+ sizeof(am_entry3), (xdrproc_t) xdr_am_entry3))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_dirlist3(XDR *xdrs, am_dirlist3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_dirlist3:");
+
+ if (!xdr_pointer(xdrs, (char **)&objp->entries,
+ sizeof(am_entry3), (xdrproc_t) xdr_am_entry3))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->eof))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIR3resok(XDR *xdrs, am_READDIR3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIR3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->dir_attributes))
+ return FALSE;
+ if (!xdr_am_cookieverf3(xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_am_dirlist3(xdrs, &objp->reply))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIR3resfail(XDR *xdrs, am_READDIR3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIR3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->dir_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIR3res(XDR *xdrs, am_READDIR3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIR3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_READDIR3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_READDIR3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_LINK3args(XDR *xdrs, am_LINK3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_LINK3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_am_diropargs3(xdrs, &objp->link))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_LINK3resok(XDR *xdrs, am_LINK3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_LINK3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->file_attributes))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->linkdir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_LINK3resfail(XDR *xdrs, am_LINK3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_LINK3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->file_attributes))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->linkdir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_LINK3res(XDR *xdrs, am_LINK3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_LINK3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_LINK3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_LINK3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_sattrguard3(XDR *xdrs, am_sattrguard3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_sattrguard3:");
+
+ if (!xdr_bool(xdrs, &objp->check))
+ return FALSE;
+ switch (objp->check) {
+ case TRUE:
+ if (!xdr_am_nfstime3(xdrs, &objp->am_sattrguard3_u.obj_ctime))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_SETATTR3args(XDR *xdrs, am_SETATTR3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SETATTR3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->object))
+ return FALSE;
+ if (!xdr_am_sattr3(xdrs, &objp->new_attributes))
+ return FALSE;
+ if (!xdr_am_sattrguard3(xdrs, &objp->guard))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SETATTR3resok(XDR *xdrs, am_SETATTR3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SETATTR3resok:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->obj_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SETATTR3resfail(XDR *xdrs, am_SETATTR3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SETATTR3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->obj_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SETATTR3res(XDR *xdrs, am_SETATTR3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SETATTR3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_SETATTR3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_SETATTR3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
}
-#endif /* not HAVE_FS_NFS3 */
+#endif /* HAVE_FS_NFS3 */
diff --git a/contrib/amd/libamu/xutil.c b/contrib/amd/libamu/xutil.c
index 3a33b9c0b149..1159fe5ec83e 100644
--- a/contrib/amd/libamu/xutil.c
+++ b/contrib/amd/libamu/xutil.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -63,14 +59,13 @@ static char am_hostname[MAXHOSTNAMELEN] = "unknown"; /* Hostname */
pid_t am_mypid = -1; /* process ID */
serv_state amd_state; /* amd's state */
int foreground = 1; /* 1 == this is the top-level server */
-int debug_flags = 0;
+u_int debug_flags = D_CONTROL; /* set regardless if compiled with debugging */
#ifdef HAVE_SYSLOG
int syslogging;
#endif /* HAVE_SYSLOG */
-int xlog_level = XLOG_ALL & ~XLOG_MAP & ~XLOG_STATS;
-int xlog_level_init = ~0;
-static int amd_program_number = AMQ_PROGRAM;
+static u_int xlog_level = XLOG_DEFAULT;
+static u_long amd_program_number = AMQ_PROGRAM;
#ifdef DEBUG_MEM
# if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY)
@@ -92,23 +87,23 @@ static void real_plog(int lvl, const char *fmt, va_list vargs)
struct opt_tab dbg_opt[] =
{
{"all", D_ALL}, /* All non-disruptive options */
- {"amq", D_AMQ}, /* Don't register for AMQ program */
- {"daemon", D_DAEMON}, /* Don't enter daemon mode */
- {"fork", D_FORK}, /* Don't fork server */
+ {"defaults", D_DEFAULT}, /* Default options */
+ {"test", D_TEST}, /* Full debug - no daemon, no fork, no amq, local mtab */
+ {"amq", D_AMQ}, /* Register for AMQ program */
+ {"daemon", D_DAEMON}, /* Enter daemon mode */
+ {"fork", D_FORK}, /* Fork server (hlfsd only) */
{"full", D_FULL}, /* Program trace */
#ifdef HAVE_CLOCK_GETTIME
{"hrtime", D_HRTIME}, /* Print high resolution time stamps */
#endif /* HAVE_CLOCK_GETTIME */
- /* info service specific debugging (hesiod, nis, etc) */
- {"info", D_INFO},
+ {"info", D_INFO}, /* info service specific debugging (hesiod, nis, etc) */
{"mem", D_MEM}, /* Trace memory allocations */
{"mtab", D_MTAB}, /* Use local mtab file */
{"readdir", D_READDIR}, /* Check on browsable_dirs progress */
{"str", D_STR}, /* Debug string munging */
- {"test", D_TEST}, /* Full debug - no daemon, no amq, local mtab */
{"trace", D_TRACE}, /* Protocol trace */
{"xdrtrace", D_XDRTRACE}, /* Trace xdr routines */
- {0, 0}
+ {NULL, 0}
};
#endif /* DEBUG */
@@ -118,6 +113,7 @@ struct opt_tab dbg_opt[] =
struct opt_tab xlog_opt[] =
{
{"all", XLOG_ALL}, /* All messages */
+ {"defaults", XLOG_DEFAULT}, /* Default messages */
#ifdef DEBUG
{"debug", XLOG_DEBUG}, /* Debug messages */
#endif /* DEBUG */ /* DEBUG */
@@ -129,7 +125,7 @@ struct opt_tab xlog_opt[] =
{"user", XLOG_USER}, /* Non-fatal user errors */
{"warn", XLOG_WARNING}, /* Warnings */
{"warning", XLOG_WARNING}, /* Warnings */
- {0, 0}
+ {NULL, 0}
};
@@ -150,7 +146,7 @@ am_get_progname(void)
void
am_set_hostname(char *hn)
{
- xstrlcpy(am_hostname, hn, MAXHOSTNAMELEN);
+ xstrlcpy(am_hostname, hn, sizeof(am_hostname));
}
@@ -295,17 +291,23 @@ expand_error(const char *f, char *e, size_t maxlen)
const char *p;
char *q;
int error = errno;
- int len = 0;
+ size_t len = 0, l;
- for (p = f, q = e; (*q = *p) && (size_t) len < maxlen; len++, q++, p++) {
+ *e = '\0';
+ for (p = f, q = e; len < maxlen && (*q = *p); len++, q++, p++) {
if (p[0] == '%' && p[1] == 'm') {
- xstrlcpy(q, strerror(error), maxlen);
- len += strlen(q) - 1;
- q += strlen(q) - 1;
+ if (len >= maxlen)
+ break;
+ xstrlcpy(q, strerror(error), maxlen - len);
+ l = strlen(q);
+ if (l != 0)
+ l--;
+ len += l;
+ q += l;
p++;
}
}
- e[maxlen-1] = '\0'; /* null terminate, to be sure */
+ e[maxlen - 1] = '\0'; /* null terminate, to be sure */
return e;
}
@@ -317,7 +319,7 @@ static void
show_time_host_and_name(int lvl)
{
static time_t last_t = 0;
- static char *last_ctime = 0;
+ static char *last_ctime = NULL;
time_t t;
#if defined(HAVE_CLOCK_GETTIME) && defined(DEBUG)
struct timespec ts;
@@ -390,21 +392,63 @@ show_time_host_and_name(int lvl)
int
debug_option(char *opt)
{
- return cmdoption(opt, dbg_opt, &debug_flags);
+ u_int dl = debug_flags;
+ static int initialized_debug_flags = 0;
+ int rc = cmdoption(opt, dbg_opt, &dl);
+
+ if (rc) /* if got any error, don't update debug flags */
+ return EINVAL;
+
+ /*
+ * If we already initialized the debugging flags once (via amd.conf), then
+ * don't allow "immutable" flags to be changed again (via amq -D), because
+ * they could mess Amd's state and only make sense to be set once when Amd
+ * starts.
+ */
+ if (initialized_debug_flags &&
+ debug_flags != 0 &&
+ (dl & D_IMMUTABLE) != (debug_flags & D_IMMUTABLE)) {
+ plog(XLOG_ERROR, "cannot change immutable debug flags");
+ /* undo any attempted change to an immutable flag */
+ dl = (dl & ~D_IMMUTABLE) | (debug_flags & D_IMMUTABLE);
+ }
+ initialized_debug_flags = 1;
+ debug_flags = dl;
+
+ return rc;
}
void
dplog(const char *fmt, ...)
{
+#ifdef HAVE_SIGACTION
+ sigset_t old, chld;
+#else /* not HAVE_SIGACTION */
+ int mask;
+#endif /* not HAVE_SIGACTION */
va_list ap;
+#ifdef HAVE_SIGACTION
+ sigemptyset(&chld);
+ sigaddset(&chld, SIGCHLD);
+#else /* not HAVE_SIGACTION */
+ mask = sigblock(sigmask(SIGCHLD));
+#endif /* not HAVE_SIGACTION */
+
+ sigprocmask(SIG_BLOCK, &chld, &old);
if (!logfp)
logfp = stderr; /* initialize before possible first use */
va_start(ap, fmt);
real_plog(XLOG_DEBUG, fmt, ap);
va_end(ap);
+
+#ifdef HAVE_SIGACTION
+ sigprocmask(SIG_SETMASK, &old, NULL);
+#else /* not HAVE_SIGACTION */
+ mask = sigblock(sigmask(SIGCHLD));
+#endif /* not HAVE_SIGACTION */
}
#endif /* DEBUG */
@@ -412,14 +456,33 @@ dplog(const char *fmt, ...)
void
plog(int lvl, const char *fmt, ...)
{
+#ifdef HAVE_SIGACTION
+ sigset_t old, chld;
+#else /* not HAVE_SIGACTION */
+ int mask;
+#endif /* not HAVE_SIGACTION */
va_list ap;
+#ifdef HAVE_SIGACTION
+ sigemptyset(&chld);
+ sigaddset(&chld, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &chld, &old);
+#else /* not HAVE_SIGACTION */
+ mask = sigblock(sigmask(SIGCHLD));
+#endif /* not HAVE_SIGACTION */
+
if (!logfp)
logfp = stderr; /* initialize before possible first use */
va_start(ap, fmt);
real_plog(lvl, fmt, ap);
va_end(ap);
+
+#ifdef HAVE_SIGACTION
+ sigprocmask(SIG_SETMASK, &old, NULL);
+#else /* not HAVE_SIGACTION */
+ sigsetmask(mask);
+#endif /* not HAVE_SIGACTION */
}
@@ -497,11 +560,11 @@ real_plog(int lvl, const char *fmt, va_list vargs)
switch (last_count) {
case 0: /* never printed at all */
last_count = 1;
- if (strlcpy(last_msg, msg, 1024) >= 1024) /* don't use xstrlcpy here (recursive!) */
+ if (strlcpy(last_msg, msg, sizeof(last_msg)) >= sizeof(last_msg)) /* don't use xstrlcpy here (recursive!) */
fprintf(stderr, "real_plog: string \"%s\" truncated to \"%s\"\n", last_msg, msg);
last_lvl = lvl;
show_time_host_and_name(lvl); /* mimic syslog header */
- fwrite(msg, ptr - msg, 1, logfp);
+ __IGNORE(fwrite(msg, ptr - msg, 1, logfp));
fflush(logfp);
break;
@@ -510,11 +573,11 @@ real_plog(int lvl, const char *fmt, va_list vargs)
last_count++;
} else { /* last msg printed once, new one differs */
/* last_count remains at 1 */
- if (strlcpy(last_msg, msg, 1024) >= 1024) /* don't use xstrlcpy here (recursive!) */
+ if (strlcpy(last_msg, msg, sizeof(last_msg)) >= sizeof(last_msg)) /* don't use xstrlcpy here (recursive!) */
fprintf(stderr, "real_plog: string \"%s\" truncated to \"%s\"\n", last_msg, msg);
last_lvl = lvl;
show_time_host_and_name(lvl); /* mimic syslog header */
- fwrite(msg, ptr - msg, 1, logfp);
+ __IGNORE(fwrite(msg, ptr - msg, 1, logfp));
fflush(logfp);
}
break;
@@ -527,7 +590,7 @@ real_plog(int lvl, const char *fmt, va_list vargs)
show_time_host_and_name(last_lvl);
xsnprintf(last_msg, sizeof(last_msg),
"last message repeated %d times\n", last_count);
- fwrite(last_msg, strlen(last_msg), 1, logfp);
+ __IGNORE(fwrite(last_msg, strlen(last_msg), 1, logfp));
fflush(logfp);
last_count = 0; /* start from scratch */
break;
@@ -539,13 +602,13 @@ real_plog(int lvl, const char *fmt, va_list vargs)
show_time_host_and_name(last_lvl);
xsnprintf(last_msg, sizeof(last_msg),
"last message repeated %d times\n", last_count);
- fwrite(last_msg, strlen(last_msg), 1, logfp);
+ __IGNORE(fwrite(last_msg, strlen(last_msg), 1, logfp));
if (strlcpy(last_msg, msg, 1024) >= 1024) /* don't use xstrlcpy here (recursive!) */
fprintf(stderr, "real_plog: string \"%s\" truncated to \"%s\"\n", last_msg, msg);
last_count = 1;
last_lvl = lvl;
show_time_host_and_name(lvl); /* mimic syslog header */
- fwrite(msg, ptr - msg, 1, logfp);
+ __IGNORE(fwrite(msg, ptr - msg, 1, logfp));
fflush(logfp);
}
break;
@@ -573,7 +636,7 @@ show_opts(int ch, struct opt_tab *opts)
int
-cmdoption(char *s, struct opt_tab *optb, int *flags)
+cmdoption(char *s, struct opt_tab *optb, u_int *flags)
{
char *p = s;
int errs = 0;
@@ -581,7 +644,7 @@ cmdoption(char *s, struct opt_tab *optb, int *flags)
while (p && *p) {
int neg;
char *opt;
- struct opt_tab *dp, *dpn = 0;
+ struct opt_tab *dp, *dpn = NULL;
s = p;
p = strchr(p, ',');
@@ -624,7 +687,7 @@ cmdoption(char *s, struct opt_tab *optb, int *flags)
* This will log to stderr when parsing the command line
* since any -l option will not yet have taken effect.
*/
- plog(XLOG_USER, "option \"%s\" not recognized", s);
+ plog(XLOG_ERROR, "option \"%s\" not recognized", s);
errs++;
}
@@ -645,22 +708,22 @@ cmdoption(char *s, struct opt_tab *optb, int *flags)
int
switch_option(char *opt)
{
- int xl = xlog_level;
+ u_int xl = xlog_level;
int rc = cmdoption(opt, xlog_opt, &xl);
- if (rc) {
- rc = EINVAL;
- } else {
- /*
- * Keep track of initial log level, and
- * don't allow options to be turned off.
- */
- if (xlog_level_init == ~0)
- xlog_level_init = xl;
- else
- xl |= xlog_level_init;
- xlog_level = xl;
+ if (rc) /* if got any error, don't update flags */
+ return EINVAL;
+
+ /*
+ * Don't allow "mandatory" flags to be turned off, because
+ * we must always be able to report on flag re/setting errors.
+ */
+ if ((xl & XLOG_MANDATORY) != XLOG_MANDATORY) {
+ plog(XLOG_ERROR, "cannot turn off mandatory logging options");
+ xl |= XLOG_MANDATORY;
}
+ if (xlog_level != xl)
+ xlog_level = xl; /* set new flags */
return rc;
}
@@ -801,7 +864,7 @@ switch_to_logfile(char *logfile, int old_umask, int truncate_log)
} else { /* regular log file */
(void) umask(old_umask);
if (truncate_log)
- truncate(logfile, 0);
+ __IGNORE(truncate(logfile, 0));
new_logfp = fopen(logfile, "a");
umask(0);
}
@@ -834,7 +897,8 @@ switch_to_logfile(char *logfile, int old_umask, int truncate_log)
void
unregister_amq(void)
{
- if (!amuDebug(D_AMQ)) {
+
+ if (amuDebug(D_AMQ)) {
/* find which instance of amd to unregister */
u_long amd_prognum = get_amd_program_number();
@@ -875,7 +939,7 @@ going_down(int rc)
/* return the rpc program number under which amd was used */
-int
+u_long
get_amd_program_number(void)
{
return amd_program_number;
@@ -884,7 +948,7 @@ get_amd_program_number(void)
/* set the rpc program number used for amd */
void
-set_amd_program_number(int program)
+set_amd_program_number(u_long program)
{
amd_program_number = program;
}
@@ -955,9 +1019,9 @@ amu_release_controlling_tty(void)
close(fd);
}
return;
-#endif /* not TIOCNOTTY */
-
+#else
plog(XLOG_ERROR, "unable to release controlling tty");
+#endif /* not TIOCNOTTY */
}
@@ -1012,7 +1076,7 @@ mkdirs(char *path, int mode)
/*
* take a copy in case path is in readonly store
*/
- char *p2 = strdup(path);
+ char *p2 = xstrdup(path);
char *sp = p2;
struct stat stb;
int error_so_far = 0;
@@ -1056,7 +1120,7 @@ mkdirs(char *path, int mode)
void
rmdirs(char *dir)
{
- char *xdp = strdup(dir);
+ char *xdp = xstrdup(dir);
char *dp;
do {
@@ -1089,3 +1153,15 @@ rmdirs(char *dir)
XFREE(xdp);
}
+
+/*
+ * Dup a string
+ */
+char *
+xstrdup(const char *s)
+{
+ size_t len = strlen(s);
+ char *sp = xmalloc(len + 1);
+ memcpy(sp, s, len + 1);
+ return sp;
+}
diff --git a/contrib/amd/mk-amd-map/mk-amd-map.8 b/contrib/amd/mk-amd-map/mk-amd-map.8
index 28bbb9b84fe1..677f41a268fc 100644
--- a/contrib/amd/mk-amd-map/mk-amd-map.8
+++ b/contrib/amd/mk-amd-map/mk-amd-map.8
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 1997-2006 Erez Zadok
+.\" Copyright (c) 1997-2014 Erez Zadok
.\" Copyright (c) 1993 Jan-Simon Pendry
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@@ -12,11 +12,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 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.
.\"
@@ -32,10 +28,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" from: @(#)mk-amd-map.8 8.1 (Berkeley) 6/28/93
-.\" $Id: mk-amd-map.8,v 1.9.2.1 2006/01/02 18:48:26 ezk Exp $
.\" $FreeBSD$
.\"
+.\" File: am-utils/mk-amd-map/mk-amd-map.8
+.\"
.Dd January 2, 2006
.Dt MK-AMD-MAP 8
.Os
diff --git a/contrib/amd/mk-amd-map/mk-amd-map.c b/contrib/amd/mk-amd-map/mk-amd-map.c
index 48d82b0bd0d7..e6ca9d93983d 100644
--- a/contrib/amd/mk-amd-map/mk-amd-map.c
+++ b/contrib/amd/mk-amd-map/mk-amd-map.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -93,7 +89,7 @@ read_line(char *buf, int size, FILE *fp)
/*
* Skip leading white space on next line
*/
- while ((ch = getc(fp)) != EOF && isascii(ch) && isspace(ch)) ;
+ while ((ch = getc(fp)) != EOF && isascii((unsigned char)ch) && isspace((unsigned char)ch)) ;
(void) ungetc(ch, fp);
} else {
return done;
@@ -144,7 +140,7 @@ read_file(FILE *fp, char *map, voidp db)
/*
* Find start of key
*/
- for (kp = key_val; *kp && isascii(*kp) && isspace((int)*kp); kp++) ;
+ for (kp = key_val; *kp && isascii((unsigned char)*kp) && isspace((unsigned char)*kp); kp++) ;
/*
* Ignore blank lines
@@ -155,7 +151,7 @@ read_file(FILE *fp, char *map, voidp db)
/*
* Find end of key
*/
- for (cp = kp; *cp && (!isascii(*cp) || !isspace((int)*cp)); cp++) ;
+ for (cp = kp; *cp && (!isascii((unsigned char)*cp) || !isspace((unsigned char)*cp)); cp++) ;
/*
* Check whether key matches, or whether
@@ -163,7 +159,7 @@ read_file(FILE *fp, char *map, voidp db)
*/
if (*cp)
*cp++ = '\0';
- while (*cp && isascii(*cp) && isspace((int)*cp))
+ while (*cp && isascii((unsigned char)*cp) && isspace((unsigned char)*cp))
cp++;
if (*kp == '+') {
fprintf(stderr, "Can't interpolate %s\n", kp);
diff --git a/contrib/amd/scripts/amd.conf-sample b/contrib/amd/scripts/amd.conf-sample
index 880a74ba7552..4d965787099a 100644
--- a/contrib/amd/scripts/amd.conf-sample
+++ b/contrib/amd/scripts/amd.conf-sample
@@ -64,8 +64,8 @@ nis_domain = nisDom-CS.columbia.edu
# (amd -x)
log_options = fatal,error,user,warn,info,map,stats,all
# (amd -D)
-debug_options = all,amq,daemon,fork,full,hrtime,info,mem,mtab,\
- str,readdir,test,trace,xdrtrace
+debug_options = all,defaults,test,amq,daemon,fork,\
+ full,hrtime,info,mem,mtab,str,readdir,trace,xdrtrace
# path for mtab file during mtab debug mode
debug_mtab_file = /tmp/mnttab
# (amd -S)
@@ -108,7 +108,7 @@ exec_map_timeout = 10
normalize_slashes = yes | no
##############################################################################
-# these 8 global options can be overridden by each map individually
+# these 9 global options can be overridden by each map individually
browsable_dirs = no | yes | full
map_options = cache:=all
map_type = file|hesiod|ndbm|nis|nisplus|passwd|union|ldap
@@ -119,6 +119,8 @@ autofs_use_lofs = yes | no
search_path = /etc/local:/etc/amdmaps:/misc/yp
# selectors are not recognized by default in the /defaults entry
selectors_in_defaults = no | yes
+# does this map use Sun Automounter map syntax?
+sun_map_syntax = no | yes
##############################################################################
##############################################################################
diff --git a/contrib/amd/scripts/amd.conf.5 b/contrib/amd/scripts/amd.conf.5
index 5967e8ffd58b..1adc2ba85675 100644
--- a/contrib/amd/scripts/amd.conf.5
+++ b/contrib/amd/scripts/amd.conf.5
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 1997-2006 Erez Zadok
+.\" 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.
@@ -16,11 +16,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 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.
.\"
@@ -36,9 +32,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" %W% (Berkeley) %G%
.\"
-.\" $Id: amd.conf.5,v 1.39.2.5 2006/04/21 01:12:04 ezk Exp $
+.\" File: am-utils/scripts/amd.conf.5
.\" $FreeBSD$
.\"
.Dd February 26, 2016
@@ -274,8 +269,14 @@ slow slip-based networks as follows:
wire!=slip-net;opts:=intr,rsize=8192,wsize=8192
.Ed
Deprecated form: selectors_on_default
+.TP
+.BR sun_map_syntax " (boolean, default=no)"
+If "yes," then Amd will parse the map according to the Sun Automount syntax.
+
+.\" **************************************************************************
.El
.Ss "Parameters applicable to the global section only"
+
.Bl -tag -width 4n
.It Va arch Pq string, default to compiled in value
Same as the
@@ -345,12 +346,13 @@ option to
Specify any debugging options for
.Xr amd 8 .
Works only if
+Works only if
am-utils was configured for debugging using the
.Fl Fl enable-debug
option.
The
.Cm mem
-option alone can be turned on via
+option, as well as all other options, can be turned on via
.Fl Fl enable-debug Ns = Ns Cm mem .
Otherwise debugging options are ignored.
Options are
@@ -364,7 +366,9 @@ Possible values are:
.Pp
.Bl -tag -width ".Cm xdrtrace" -compact
.It Cm all
-all options
+all options (excludes hrtime and mtab)
+.It Cm defaults
+"sensible" default options (all--excluding hrtime, mtab, and xdrtrace)
.It Cm amq
register for
.Xr amq 8
@@ -374,6 +378,8 @@ enter daemon mode
fork server
.It Cm full
program trace
+.It Cm hrtime
+print high resolution time stamps (only if syslog(3) is not used)
.It Cm info
info service specific debugging
(hesiod, nis, etc.)
@@ -383,14 +389,16 @@ trace memory allocations
use local
.Pa ./mtab
file
+\fBreaddir\fR show browsable_dirs progress
.It Cm str
debug string munging
.It Cm test
-full debug but no daemon
+full debug options plus mtab,nodaemon,nofork,noamq
.It Cm trace
trace protocol and NFS mount arguments
.It Cm xdrtrace
trace XDR routines
+.BR dismount_interval " (numeric, default=120)"
.El
.It Va dismount_interval Pq numeric, default=120
Same as the
@@ -580,12 +588,14 @@ Possible values are:
.Bl -tag -width ".Cm warning" -compact
.It Cm all
all messages
+.It Cm defaults
+default messages (fatal,error,user,warning,info)
.It Cm debug
debug messages
.It Cm error
-non-fatal system errors
+non-fatal system errors (cannot be turned off)
.It Cm fatal
-fatal errors
+fatal errors (cannot be turned off)
.It Cm info
information
.It Cm map
@@ -596,6 +606,7 @@ additional statistical information
non-fatal user errors
.It Cm warn
warnings
+\fBwarning\fR warnings
.It Cm warning
warnings
.El
@@ -1074,7 +1085,9 @@ map_name = amd.tftpboot
.Sh SEE ALSO
.Xr hosts_access 5 ,
.Xr amd 8 ,
-.Xr amq 8
+.Xr amq 8 ,
+.xr automount 8 ,
+.Xr ctl-amd 8 .
.Pp
.Dq am-utils
.Xr info 1
diff --git a/contrib/amd/scripts/automount2amd.8 b/contrib/amd/scripts/automount2amd.8
index bd3b61230ab6..f9a04d928cd1 100644
--- a/contrib/amd/scripts/automount2amd.8
+++ b/contrib/amd/scripts/automount2amd.8
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 1997-2006 Erez Zadok
+.\" 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.
@@ -16,11 +16,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 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.
.\"
@@ -36,9 +32,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" %W% (Berkeley) %G%
.\"
-.\" $Id: automount2amd.8,v 1.8.2.1 2006/01/02 18:48:26 ezk Exp $
+.\" File: am-utils/scripts/automount2amd.8
.\"
.TH AUTOMOUNT2AMD 8L "24 May 1993"
.SH NAME
diff --git a/contrib/amd/scripts/fixrmtab.in b/contrib/amd/scripts/fixrmtab.in
index 23003806e4c0..a1fbebf61507 100755
--- a/contrib/amd/scripts/fixrmtab.in
+++ b/contrib/amd/scripts/fixrmtab.in
@@ -10,15 +10,23 @@
#set -x
-RMTAB=/etc/rmtab
-TMP=/tmp/rmtab.$$
+# allow user to pass RMTAB file name from environment
+if test -z "${RMTAB}" ; then
+ RMTAB=/etc/rmtab
+fi
-if [ ! -f /etc/rmtab ]; then
+if [ ! -f "$RMTAB" ]; then
exit 0
fi
-for host in $*
+TMP="$(mktemp ${RMTAB}.XXXXXX)"
+if [ -z "$TMP" ]; then
+ exit 1
+fi
+
+trap "rm -f $TMP" 0 1 2 3 15
+
+for host
do
- sed -e '/^'$host':/s/^./#/' $RMTAB > $TMP && cp $TMP $RMTAB
+ sed -e "/^$host:/s/^./#/" "$RMTAB" > "$TMP" && cp "$TMP" "$RMTAB"
done
-rm -f $TMP
diff --git a/contrib/amd/vers.m4 b/contrib/amd/vers.m4
index 7343910d5f2d..99d4f06750c7 100644
--- a/contrib/amd/vers.m4
+++ b/contrib/amd/vers.m4
@@ -1 +1 @@
-[6.1.5]dnl
+[6.2]dnl
diff --git a/contrib/amd/wire-test/wire-test.8 b/contrib/amd/wire-test/wire-test.8
index 65c15c5d4e64..b8d60d89d10f 100644
--- a/contrib/amd/wire-test/wire-test.8
+++ b/contrib/amd/wire-test/wire-test.8
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 1997-2006 Erez Zadok
+.\" 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.
@@ -16,11 +16,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 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.
.\"
@@ -36,9 +32,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" %W% (Berkeley) %G%
.\"
-.\" $Id: wire-test.8,v 1.10.2.1 2006/01/02 18:48:26 ezk Exp $
+.\" File: am-utils/wire-test/wire-test.8
.\" $FreeBSD$
.\"
.Dd February 26, 2016
diff --git a/contrib/amd/wire-test/wire-test.c b/contrib/amd/wire-test/wire-test.c
index bcaaf5a31519..0adcf5d66665 100644
--- a/contrib/amd/wire-test/wire-test.c
+++ b/contrib/amd/wire-test/wire-test.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2006 Erez Zadok
+ * 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.
@@ -16,11 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 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.
*
@@ -59,7 +55,7 @@ main(int argc, char **argv)
char *testhost, *proto, *tmp_buf;
int nv, ret;
struct sockaddr_in *ip;
- struct hostent *hp = 0;
+ struct hostent *hp = NULL;
am_set_progname(argv[0]);
@@ -102,12 +98,11 @@ main(int argc, char **argv)
memmove((voidp) &ip->sin_addr, (voidp) hp->h_addr, sizeof(ip->sin_addr));
ip->sin_port = htons(NFS_PORT);
- xlog_level = 0; /* turn off debugging */
fprintf(stderr, "NFS Version and protocol tests to host \"%s\"...\n", testhost);
proto = "udp";
for (nv=2; nv<=3; ++nv) {
fprintf(stderr, "\ttesting vers=%d, proto=\"%s\" -> ", nv, proto);
- ret = get_nfs_version(testhost, ip, nv, proto);
+ ret = get_nfs_version(testhost, ip, nv, proto, 0);
if (ret == 0)
fprintf(stderr, "failed!\n");
else
@@ -117,7 +112,7 @@ main(int argc, char **argv)
proto = "tcp";
for (nv=2; nv<=3; ++nv) {
fprintf(stderr, "\ttesting vers=%d, proto=\"%s\" -> ", nv, proto);
- ret = get_nfs_version(testhost, ip, nv, proto);
+ ret = get_nfs_version(testhost, ip, nv, proto, 0);
if (ret == 0)
fprintf(stderr, "failed!\n");
else