from amd5.3 alpha11
authorJan-Simon Pendry <pendry@ucbvax.Berkeley.EDU>
Mon, 18 Mar 1991 05:41:06 +0000 (21:41 -0800)
committerJan-Simon Pendry <pendry@ucbvax.Berkeley.EDU>
Mon, 18 Mar 1991 05:41:06 +0000 (21:41 -0800)
SCCS-vsn: usr.sbin/amd/amd/ChangeLog 1.2
SCCS-vsn: usr.sbin/amd/amd/Makefile 5.3
SCCS-vsn: usr.sbin/amd/amd/afs_ops.c 5.2
SCCS-vsn: usr.sbin/amd/amd/am_ops.c 5.2
SCCS-vsn: usr.sbin/amd/amd/amd.c 5.2
SCCS-vsn: usr.sbin/amd/amd/clock.c 5.2
SCCS-vsn: usr.sbin/amd/amd/amq_subr.c 5.2
SCCS-vsn: usr.sbin/amd/amd/efs_ops.c 5.2
SCCS-vsn: usr.sbin/amd/amd/ifs_ops.c 5.2
SCCS-vsn: usr.sbin/amd/amd/get_args.c 5.2
SCCS-vsn: usr.sbin/amd/amd/host_ops.c 5.2
SCCS-vsn: usr.sbin/amd/amd/map.c 5.2
SCCS-vsn: usr.sbin/amd/amd/info_file.c 5.2
SCCS-vsn: usr.sbin/amd/amd/info_hes.c 5.2
SCCS-vsn: usr.sbin/amd/amd/info_ndbm.c 5.2
SCCS-vsn: usr.sbin/amd/amd/info_nis.c 5.2
SCCS-vsn: usr.sbin/amd/amd/info_passwd.c 5.2
SCCS-vsn: usr.sbin/amd/amd/mapc.c 5.2
SCCS-vsn: usr.sbin/amd/amd/mntfs.c 5.2
SCCS-vsn: usr.sbin/amd/amd/misc_rpc.c 5.2
SCCS-vsn: usr.sbin/amd/amd/mtab.c 5.2
SCCS-vsn: usr.sbin/amd/amd/mount_fs.c 5.2
SCCS-vsn: usr.sbin/amd/amd/nfs_ops.c 5.2
SCCS-vsn: usr.sbin/amd/amd/opts.c 5.2
SCCS-vsn: usr.sbin/amd/amd/amd.8 5.3
SCCS-vsn: usr.sbin/amd/amd/nfs_start.c 5.2
SCCS-vsn: usr.sbin/amd/amd/nfs_subr.c 5.2
SCCS-vsn: usr.sbin/amd/amd/pfs_ops.c 5.2
SCCS-vsn: usr.sbin/amd/amd/restart.c 5.2
SCCS-vsn: usr.sbin/amd/amd/rpc_fwd.c 5.2
SCCS-vsn: usr.sbin/amd/amd/sched.c 5.2
SCCS-vsn: usr.sbin/amd/amd/sfs_ops.c 5.2
SCCS-vsn: usr.sbin/amd/amd/ufs_ops.c 5.2
SCCS-vsn: usr.sbin/amd/amd/srvr_afs.c 5.2
SCCS-vsn: usr.sbin/amd/amd/srvr_nfs.c 5.2
SCCS-vsn: usr.sbin/amd/amd/util.c 5.2
SCCS-vsn: usr.sbin/amd/amd/umount_fs.c 5.2
SCCS-vsn: usr.sbin/amd/amd/info_union.c 5.2
SCCS-vsn: usr.sbin/amd/amd/nfsx_ops.c 5.2
SCCS-vsn: usr.sbin/amd/amd/wire.c 5.2
SCCS-vsn: usr.sbin/amd/amd/xutil.c 5.2
SCCS-vsn: usr.sbin/amd/include/am.h 5.2
SCCS-vsn: usr.sbin/amd/include/fstype.h 5.2
SCCS-vsn: usr.sbin/amd/include/uwait.h 5.2

44 files changed:
usr/src/usr.sbin/amd/amd/ChangeLog
usr/src/usr.sbin/amd/amd/Makefile
usr/src/usr.sbin/amd/amd/afs_ops.c
usr/src/usr.sbin/amd/amd/am_ops.c
usr/src/usr.sbin/amd/amd/amd.8
usr/src/usr.sbin/amd/amd/amd.c
usr/src/usr.sbin/amd/amd/amq_subr.c
usr/src/usr.sbin/amd/amd/clock.c
usr/src/usr.sbin/amd/amd/efs_ops.c
usr/src/usr.sbin/amd/amd/get_args.c
usr/src/usr.sbin/amd/amd/host_ops.c
usr/src/usr.sbin/amd/amd/ifs_ops.c
usr/src/usr.sbin/amd/amd/info_file.c
usr/src/usr.sbin/amd/amd/info_hes.c
usr/src/usr.sbin/amd/amd/info_ndbm.c
usr/src/usr.sbin/amd/amd/info_nis.c
usr/src/usr.sbin/amd/amd/info_passwd.c
usr/src/usr.sbin/amd/amd/info_union.c
usr/src/usr.sbin/amd/amd/map.c
usr/src/usr.sbin/amd/amd/mapc.c
usr/src/usr.sbin/amd/amd/misc_rpc.c
usr/src/usr.sbin/amd/amd/mntfs.c
usr/src/usr.sbin/amd/amd/mount_fs.c
usr/src/usr.sbin/amd/amd/mtab.c
usr/src/usr.sbin/amd/amd/nfs_ops.c
usr/src/usr.sbin/amd/amd/nfs_start.c
usr/src/usr.sbin/amd/amd/nfs_subr.c
usr/src/usr.sbin/amd/amd/nfsx_ops.c
usr/src/usr.sbin/amd/amd/opts.c
usr/src/usr.sbin/amd/amd/pfs_ops.c
usr/src/usr.sbin/amd/amd/restart.c
usr/src/usr.sbin/amd/amd/rpc_fwd.c
usr/src/usr.sbin/amd/amd/sched.c
usr/src/usr.sbin/amd/amd/sfs_ops.c
usr/src/usr.sbin/amd/amd/srvr_afs.c
usr/src/usr.sbin/amd/amd/srvr_nfs.c
usr/src/usr.sbin/amd/amd/ufs_ops.c
usr/src/usr.sbin/amd/amd/umount_fs.c
usr/src/usr.sbin/amd/amd/util.c
usr/src/usr.sbin/amd/amd/wire.c
usr/src/usr.sbin/amd/amd/xutil.c
usr/src/usr.sbin/amd/include/am.h
usr/src/usr.sbin/amd/include/fstype.h
usr/src/usr.sbin/amd/include/uwait.h

index 7913af9..c3d5164 100644 (file)
@@ -1,3 +1,318 @@
+Sun Mar 17 12:05:27 1991  Jan-Simon Pendry  (jsp at forest)
+
+       * Release 5.3 Alpha 11.
+
+       * (amq.8) Updated.
+
+       * (amq.c) Added new -v option which displays the version number of
+       the target Amd.  Also added support to Amd and reworked newvers
+       script.  Got rid of rcs_info.c.
+
+       * (mk-amd-map.c) Changed name of remove function to avoid clash
+       with ANSI C.
+
+       * (wire.c) Fixed to work with new 4.4BSD sockaddr's.
+
+       * Changed const to Const everywhere and added new define in config.h.
+
+       * (mk-amd-map.c) New -p option which just writes the output to
+       stdout.  Useful for making NIS or Hesiod maps.
+
+       * (amdref) Small updates and clarifications.
+
+Sat Mar 16 20:35:17 1991  Jan-Simon Pendry  (jsp at forest)
+
+       * (amq_subr.c) Flush request now flushes all internal caches.
+
+       * (amq_subr.c) Changed xdr_amq_mount_tree to return only the
+       required sub-tree.
+
+       * (ifs_ops.c) Added missing return 0; to ifs_mount.
+
+Sat Mar  9 19:31:25 1991  Jan-Simon Pendry  (jsp at forest)
+
+       * (get_args.c) Output the primary network interface information
+       with the -v option.
+
+       * (mapc.c) Fixed spurious warning about "root" map not supporting
+       cache mode "all".  Added new (unnamed) cache mode MAPC_ROOT.
+
+       * (info_nis.c) Fixed order number testing which was the cause of a
+       loop.
+
+Sun Mar  3 17:57:03 1991  Jan-Simon Pendry  (jsp at forest)
+
+       * Release 5.3 Alpha 10.
+
+       * Introduced new inet_dquad routine which prints IP addresses in
+       dotted quad format.  The C library routine is not used because it
+       uses a static buffer and it takes a structure argument on some
+       machines and unsigned longs on others.  This confuses the hell out
+       of some compilers and causes SEGVs.
+
+       * task_notify becomes do_task_notify to avoid clash with Mach.
+
+       * (mntfs.c) In realloc_mntfs, the private data field wasn't being
+       cleared out when the mntfs object was being re-used.  This meant
+       that the data might be used for the wrong mount, so causing
+       various obscure errors.
+
+       * (info_file.c) Reworked to provide support for map cache "sync"
+       option.
+
+       * (mapc.c) Added new "sync" option to map cache.  This ensures
+       that the cached data doesn't become stale wrt the source.
+       Currently this isn't implemented for passwd and hesiod maps.
+
+Wed Feb 27 11:38:07 1991  Jan-Simon Pendry  (jsp at forest)
+
+       * (afs_ops.c) Fixed pid put in fs_hostname for toplvl mount.
+
+Sun Feb 24 19:37:55 1991  Jan-Simon Pendry  (jsp at forest)
+
+       * (wire.c) New module which determines the name of the primary
+       attached network.  This could be used to determine which
+       server to use.
+
+       * (srvr_nfs.c) Changed mount daemon port mapping caching.  This is
+       now much more eager to recompute the mapping than before.  Will
+       also now work even if pinging is switched off (for example "tcp").
+
+       * (info_nis.c) Added back old NIS reload code to allow NIS maps to
+       support "regexp" caching.
+
+       * (mapc.c) Added support for "regexp" caching.  This is a type of
+       map cache where the entries are all REs to be matched against the
+       requested key.  This implies "all" since all the keys must be
+       loaded for the search to work.
+
+Sat Feb 23 15:32:43 1991  Jan-Simon Pendry  (jsp at forest)
+
+       * (afs_ops.c) Avoid spurious error messages about discarding a
+       retry mntfs.
+
+       * (amq_subr.c) Removed inet_ntoa call due to disagreement between
+       gcc and libc about 4 byte structure passing.
+
+       * (xutil.c) Changed way initial logging is done to make command
+       line more usable.  Default logging flags are set statically and
+       can then be modified by -x options.  At the end an additional call
+       to switch_option is made to initialise xlog_level_init.
+
+       * (umount_fs.c) ENOENT now treated the same as EINVAL.  If the
+       filesystem gets removed and the mountpoint deleted then just
+       assume the filesystem isn't there - which it isn't.
+
+       * (host_ops.c) Now copes with unmount failures by attempting to
+       remount the filesystems which had been unmounted.
+
+       * (host_ops.c) Added check during fhandle collection to detect
+       duplicate entries in the export list (from Stefan Petri).
+
+       * (nfsx_ops.c) Reworked to correctly keep track of what is and
+       isn't mounted.
+
+Sun Jan 27 16:58:02 1991  Jan-Simon Pendry  (jsp at achilles)
+
+       * (misc-next.h) Added missing NeXT config file.
+
+       * Merged Harris HCX/UX support from Chris Metcalf.
+
+       * (ifs_ops.c) added ifs_fmount entry point to keep nfsx_ops happy.
+
+Sun Jan 13 18:19:19 1991  Jan-Simon Pendry  (jsp at beauty)
+
+       * (nfsx_ops.c) play with opt_fs field to make sure it is unique.
+
+Fri Dec 21 15:35:45 1990  Jan-Simon Pendry  (jsp at forest)
+
+       * Release 5.3 Alpha 9.  This is still not Beta!
+
+       * (host_ops.c) use normalized hostname in mtab entries, from
+       Chris Metcalf.
+
+       * (map.c) enum ftype -> ftype, from Andrew Findlay.
+
+Mon Dec 17 01:11:25 1990  Jan-Simon Pendry  (jsp at beauty)
+
+       * (amdref.texinfo) merged in fsinfo documentation from Nick.
+
+Sat Dec 15 15:39:07 1990  Jan-Simon Pendry  (jsp at beauty)
+
+       * (clock.c) minor tweaks to messages.
+
+       * (sfs_ops.c) make the opt_fs field unique, rather than always
+       ".", but make sure it still begins with a "." to avoid a clash
+       with any other existing mounts.
+
+       * (amd.c) changed way local IP address is obtained to avoid using
+       a call to the name server.  It was observed that if the power to
+       the building goes and everything reboots simultaneously then there
+       would be a good chance that the nameserver would not recover
+       before Amd on another machine required it.  This happened :-)  Now
+       use the RPC get_myaddress call.
+
+       * (info_hes.c) added hesiod_reload code from Bruce Cole.
+       Optionally compiled when HAS_HESIOD_RELOAD is defined.
+
+       * (amq_subr.c) fix "security" check.
+
+       * (amq.c) make sure a privileged port is allocated.  In fact
+       RPC3.9 and newer make this guarentee but older versions don't so
+       we do it here.
+
+Sun Dec  2 21:30:07 1990  Jan-Simon Pendry  (jsp at achilles)
+
+       * (afs_ops.c) fixed problem with pointer pre-increment.
+
+Mon Nov 19 00:31:28 1990  Jan-Simon Pendry  (jsp at achilles)
+
+       * (nfs_ops.c) saved filehandle with mntfs structure.  this allows
+       nfsx unmounts to be undone even if the filehandle cache has lost
+       the entry.  all of this is bogus and deserves a rewrite...
+
+Sun Nov 18 22:55:43 1990  Jan-Simon Pendry  (jsp at achilles)
+
+       * (nfsx_ops.c) now handles mounts of root filesystem correctly.
+
+       * (afs_ops.c) fixed dfs_ops definition to call toplvl_mounted when
+       done, so making sure that a map cache reference is set up.
+
+Sun Nov 11 21:09:34 1990  Jan-Simon Pendry  (jsp at achilles)
+
+       * (fsinfo/wr_fstab.c) has per-ostype fstab rules.
+
+       * (fsinfo/fsi_lex.l) now works correctly with flex.
+
+Mon Nov  5 00:08:30 1990  Jan-Simon Pendry  (jsp at achilles)
+
+       * Release 5.3 Alpha 8.  No more new features from now to 5.3Rel.
+       Call next one Beta.
+
+       * (amdref.texinfo) more updates.
+
+       * (info_union.c) reload routine now adds a wildcard pointing to
+       the last named directory so that new files get created correctly.
+
+Sun Nov  4 22:02:50 1990  Jan-Simon Pendry  (jsp at achilles)
+
+       * (os-u4_0.h) Ultrix 4.0 support merged.
+
+       * (os-utek.h) Utek 4.0 support merged.
+
+       * (amdref.texinfo) fixed & updated.
+
+       * (nfsx_ops.c) reworked string munging to prevent ..//.. strings
+       from occuring.
+
+       * (util.c) am_mounted now correctly updates the am_node for
+       duplicate mounts.
+
+       * (afs_ops.c) added union fstype.  derived from "toplvl" except it
+       causes all the filesystems to be mounted.  cannot be used for
+       filesystem types whose mounts may be defered (eg nfs) since it
+       doesn't retry the mounts.
+
+       * (info_union.c) map type for union fstype support.  currently
+       can't handle being given automounted filesystems - causes a
+       deadlock.
+
+Sun Oct 21 22:56:16 1990  Jan-Simon Pendry  (jsp at achilles)
+
+       * (fsinfo/*) finally integrated the fsinfo package.  currently no
+       documentation or man page.  this is a pre-req to getting mmd up.
+
+Sun Oct 14 20:02:11 1990  Jan-Simon Pendry  (jsp at achilles)
+
+       * (amdref.texinfo) reworking of documentation continues.
+
+       * (clock.c) reschedule_timeouts() now called in the event that the
+       system clock goes backwards.  this is possible during the average
+       bootstrap juggling act with timed/xntpd etc.  especially useful if
+       your machines TOY clock gets way ahead of time.
+
+Sat Oct  6 19:57:55 1990  Jan-Simon Pendry  (jsp at achilles)
+
+       * (map.c) when expanding the filehandle for a server which is
+       down, don't update the ttl on the original node unless a new node
+       gets allocated.  this should give the original mount a chance to
+       go away as soon as the server comes back.
+
+       * (arch, os-type) Updated.
+
+       * (nfs_ops.c) Added "noconn", "spongy" and "compress" mount
+       options for 4.4 BSD.
+
+Sun Sep 30 18:37:54 1990  Jan-Simon Pendry  (jsp at beauty)
+
+       * Release 5.3 Alpha 6.
+
+       * (util.c) domain_strip now doesn't leave partial domains behind.
+       if it can't strip the complete domain it leaves the string untouched.
+
+       * (restart.c) remember to initialise opt_opts field from mtab.
+
+       * (nfs_ops.c) supports "nocto" option for SunOS4.1.
+
+       * (os-irix.h) new SGI Iris port.
+
+       * (os-next.h) new NeXT port.
+
+       * (os-dgux.h) new DG/UX port.
+
+       * (many) fixed problem where mf_opts was being used for two
+       different purposes.  Now have two fields.
+
+       * (mapc.c) error map prints error message whenever used.
+
+       * (mapc.c) wildcard code rewritten.
+
+       * (util.c) slpit into two parts - some code now in xutil.c.  This
+       is used by mmd (not yet shipped).
+
+Sun Aug 19 19:58:16 1990  Jan-Simon Pendry  (jsp at achilles)
+
+       * (srvr_nfs.c) reduce verbosity of "nfs server yoyo is ok" messages.
+
+       * (opts.c) fix deslashification in expand.
+
+       * (nfs_start.c) amq registering done just before the server kicks
+       in.  running amd with nothing to do leaves the portmapper in peace.
+
+       * (mapc.c) bootstrap code abstracted to allow AMQ_MOUNT entry point.
+
+       * (nfsx_ops.c) new filesystem type, supporting groups of nfs
+       mounts.  needs abstracting to allow groups of (*) mounts.
+
+       * (am.h, *_ops.c) am_ops structure changed; corresponding changes
+       in the filesystem implemention source.  Change was to allow nfsx
+       filesystem implementation.
+
+       * (amd.c) hostname defaults to "localhost" startup code re-ordered
+       so that logging still works in case things go wrong early.
+
+       * (am_ops.c) new routine to print list of available fs types; used
+       by the -v option.
+
+       * (info_file.c) bug fix to make reloads work correctly.
+
+       * (mtab_file.c) does locking on single write, to avoid trashing
+       mount table when a mount and unmount are done at the same time.
+
+       * (mount_fs.c) automount hack removed since afs_ops no longer
+       needs it.
+
+       * (afs_ops.c) split "auto" into several other filesystem types.
+       Now much cleaner.
+
+       * (amq.c) new -M option.
+
+       * (amq_subr.c) support for AMQ_MOUNT added.
+
+       * (amq.x) new AMQ_MOUNT RPC call allows mount map entries to be
+       passed in at run-time.  Automount points can now be added
+       dynamically, but not yet deleted.
+
 Sat Jun 23 22:12:48 1990  Jan-Simon Pendry  (jsp at beauty)
 
        * Release 5.2 for Berkeley.
 Sat Jun 23 22:12:48 1990  Jan-Simon Pendry  (jsp at beauty)
 
        * Release 5.2 for Berkeley.
@@ -517,7 +832,7 @@ Wed Jul 19 16:14:52 1989  Jan-Simon Pendry  (jsp at achilles)
 
        * (nfs_ops.c) now implements a non-blocking rpc library.
        Everything in nfs_ops was changed to use it.  This should
 
        * (nfs_ops.c) now implements a non-blocking rpc library.
        Everything in nfs_ops was changed to use it.  This should
-       not be in this file and will be moved later. 
+       not be in this file and will be moved later.
 
        * (map.c) if a mount point times out and it is deferred then
        issue a wakeup so that it can be retried.
 
        * (map.c) if a mount point times out and it is deferred then
        issue a wakeup so that it can be retried.
@@ -614,7 +929,7 @@ Tue Jun  6 16:39:15 1989  Jan-Simon Pendry  (jsp at achilles)
 
        * (get_args.c, am.c) added new -r (restart) option.  Restart of
        mounted filesystems is only done if this option is specified.
 
        * (get_args.c, am.c) added new -r (restart) option.  Restart of
        mounted filesystems is only done if this option is specified.
-       Should *not* be specified in /etc/rc.local of course.
+       [Should *not* be specified in /etc/rc.local of course. - wrong]
 
        * (yp_master.c) make the enumeration error message more verbose
        when debugging is enabled.
 
        * (yp_master.c) make the enumeration error message more verbose
        when debugging is enabled.
@@ -626,7 +941,7 @@ Tue Jun  6 16:39:15 1989  Jan-Simon Pendry  (jsp at achilles)
 
        * (opts.c) make sure opt_key and opt_path are set to a zero
        length string unless otherwise specified.  Previously they
 
        * (opts.c) make sure opt_key and opt_path are set to a zero
        length string unless otherwise specified.  Previously they
-       were are source of dangling pointers.
+       were a source of dangling pointers.
 
        * (nfs_ops.c) make sure that the allocated nfs_private identifiers
        are unique even when some filesystem are being restarted.  This mean
 
        * (nfs_ops.c) make sure that the allocated nfs_private identifiers
        are unique even when some filesystem are being restarted.  This mean
index 2bfc4a8..0e7d3f1 100644 (file)
@@ -1,28 +1,31 @@
-#      @(#)Makefile    5.2 (Berkeley) %G%
+#      @(#)Makefile    5.3 (Berkeley) %G%
 
 PROG=  amd
 MAN8=  amd.0
 
 PROG=  amd
 MAN8=  amd.0
-SRCS=  afs_ops.c am_ops.c clock.c util.c efs_ops.c mapc.c info_file.c \
-       info_hes.c info_ndbm.c info_passwd.c info_nis.c map.c srvr_afs.c \
-       srvr_nfs.c mntfs.c misc_rpc.c mount_fs.c mount_xdr.c mtab.c \
-       mtab_aix.c mtab_bsd.c mtab_file.c mtab_ultrix.c nfs_ops.c \
-       nfs_prot_svc.c nfs_start.c nfs_subr.c nfs_prot_xdr.c opts.c \
-       pfs_ops.c rpc_fwd.c sched.c sfs_ops.c amq_svc.c amq_subr.c \
-       umount_fs.c host_ops.c ufs_ops.c ifs_ops.c amd.c get_args.c \
-       rcs_info.c restart.c
+OS=    bsd44
+SRCS=  afs_ops.c am_ops.c clock.c util.c xutil.c \
+       efs_ops.c mapc.c info_file.c info_hes.c \
+       info_ndbm.c info_passwd.c info_nis.c \
+       info_union.c map.c srvr_afs.c srvr_nfs.c \
+       mntfs.c misc_rpc.c mount_fs.c mount_xdr.c \
+       mtab.c mtab_bsd.c nfs_ops.c nfs_prot_svc.c \
+       nfs_start.c nfs_subr.c nfs_prot_xdr.c opts.c \
+       pfs_ops.c rpc_fwd.c sched.c sfs_ops.c amq_svc.c \
+       amq_subr.c umount_fs.c host_ops.c nfsx_ops.c \
+       ufs_ops.c ifs_ops.c amd.c get_args.c restart.c wire.c
 OBJS+= vers.${PROG}.o
 OBJS+= vers.${PROG}.o
-LDADD+=        -lrpc
+LDADD+= -lrpc
 CFLAGS+=-I${.CURDIR}/../rpcx
 CFLAGS+=-I${.CURDIR}/../config
 CFLAGS+=-I${.CURDIR}/../include
 CFLAGS+=-DARCH_REP=\"${MACHINE}\"
 CFLAGS+=-I${.CURDIR}/../rpcx
 CFLAGS+=-I${.CURDIR}/../config
 CFLAGS+=-I${.CURDIR}/../include
 CFLAGS+=-DARCH_REP=\"${MACHINE}\"
-CFLAGS+=-DOS_REP=\"bsd44\"
-CFLAGS+=-DOS_HDR=\"os-bsd44.h\"
+CFLAGS+=-DOS_REP=\"${OS}\"
+CFLAGS+=-DOS_HDR=\"os-${OS}.h\"
 CFLAGS+=${CONFIG}
 CLEANFILES+=vers.${PROG}.c vers.${PROG}.o
 
 CFLAGS+=${CONFIG}
 CLEANFILES+=vers.${PROG}.c vers.${PROG}.o
 
-vers.${PROG}.c: /tmp
-       @d=${.CURDIR}/ sh ${.CURDIR}/../config/newvers.sh ${PROG}
+vers.${PROG}.c: ${SRCS:.c=.o}
+       @d=${.CURDIR}/ sh ${.CURDIR}/../config/newvers.sh ${PROG} ${MACHINE} ${OS}
 
 .PATH: ${.CURDIR}/../rpcx ${.CURDIR}/../config
 .include "Makefile.config"
 
 .PATH: ${.CURDIR}/../rpcx ${.CURDIR}/../config
 .include "Makefile.config"
index 9dc36ce..c185d00 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: afs_ops.c,v 5.2 90/06/23 22:19:14 jsp Rel $
+ * $Id: afs_ops.c,v 5.2.1.6 91/03/17 17:49:10 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)afs_ops.c   5.1 (Berkeley) %G%
+ *     @(#)afs_ops.c   5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -31,6 +31,9 @@ typedef nfs_fh fhandle_t;
 
 /*
  * Automount file system
 
 /*
  * Automount file system
+ * Direct file system
+ * Root file system
+ * Top-level file system
  */
 
 /*
  */
 
 /*
@@ -41,7 +44,8 @@ typedef nfs_fh fhandle_t;
 /*
  * AFS needs nothing in particular.
  */
 /*
  * AFS needs nothing in particular.
  */
-static int afs_match(fo)
+static char *afs_match P((am_opts *fo));
+static char *afs_match(fo)
 am_opts *fo;
 {
        char *p = fo->opt_rfs;
 am_opts *fo;
 {
        char *p = fo->opt_rfs;
@@ -60,36 +64,21 @@ am_opts *fo;
        fo->opt_rfs = fo->opt_fs;
        fo->opt_fs = p;
        /*
        fo->opt_rfs = fo->opt_fs;
        fo->opt_fs = p;
        /*
-        * fs_mtab turns out to be the name of the mount map
+        * mtab entry turns out to be the name of the mount map
         */
         */
-       fo->fs_mtab = strealloc(fo->fs_mtab, fo->opt_rfs ? fo->opt_rfs : ".");
-       return 1;
-}
-
-static int afs_init(mf)
-mntfs *mf;
-{
-       /*
-        * Fill in attribute fields
-        */
-       mf->mf_fattr.type = NFDIR;
-       mf->mf_fattr.mode = NFSMODE_DIR | 0555;
-       mf->mf_fattr.nlink = 2;
-       mf->mf_fattr.size = 512;
-
-       return 0;
+       return strdup(fo->opt_rfs ? fo->opt_rfs : ".");
 }
 
 /*
 }
 
 /*
- * Mount the an automounter directory.
+ * Mount an automounter directory.
  * The automounter is connected into the system
  * The automounter is connected into the system
- * as a user-level NFS server.  mount_afs constructs
+ * as a user-level NFS server.  mount_toplvl constructs
  * the necessary NFS parameters to be given to the
  * kernel so that it will talk back to us.
  */
  * the necessary NFS parameters to be given to the
  * kernel so that it will talk back to us.
  */
-static int mount_afs(dir, fs_name, opts)
+static int mount_toplvl P((char *dir, char *opts));
+static int mount_toplvl(dir, opts)
 char *dir;
 char *dir;
-char *fs_name;
 char *opts;
 {
        struct nfs_args nfs_args;
 char *opts;
 {
        struct nfs_args nfs_args;
@@ -107,7 +96,7 @@ char *opts;
        bzero((voidp) &nfs_args, sizeof(nfs_args));     /* Paranoid */
 
        mnt.mnt_dir = dir;
        bzero((voidp) &nfs_args, sizeof(nfs_args));     /* Paranoid */
 
        mnt.mnt_dir = dir;
-       mnt.mnt_fsname = fs_name;
+       mnt.mnt_fsname = pid_fsname;
        mnt.mnt_type = MNTTYPE_AUTO;
        mnt.mnt_opts = opts;
        mnt.mnt_freq = 0;
        mnt.mnt_type = MNTTYPE_AUTO;
        mnt.mnt_opts = opts;
        mnt.mnt_freq = 0;
@@ -121,9 +110,9 @@ char *opts;
         * get fhandle of remote path for automount point
         */
        
         * get fhandle of remote path for automount point
         */
        
-       fhp = root_fh(fs_name);
+       fhp = root_fh(dir);
        if (!fhp) {
        if (!fhp) {
-               plog(XLOG_FATAL, "Can't find root file handle for %s", fs_name);
+               plog(XLOG_FATAL, "Can't find root file handle for %s", dir);
                return EINVAL;
        }
 
                return EINVAL;
        }
 
@@ -140,7 +129,7 @@ char *opts;
        if (port = hasmntval(&mnt, "port")) {
                sin.sin_port = htons(port);
        } else {
        if (port = hasmntval(&mnt, "port")) {
                sin.sin_port = htons(port);
        } else {
-               plog(XLOG_ERROR, "no port number specified for %s", fs_name);
+               plog(XLOG_ERROR, "no port number specified for %s", dir);
                return EINVAL;
        }
 
                return EINVAL;
        }
 
@@ -156,9 +145,9 @@ char *opts;
 #define        SHORT_MOUNT_NAME
 #endif /* HOSTNAMESZ */
 #ifdef SHORT_MOUNT_NAME
 #define        SHORT_MOUNT_NAME
 #endif /* HOSTNAMESZ */
 #ifdef SHORT_MOUNT_NAME
-       sprintf(fs_hostname, "amd:%d", mypid);
+       sprintf(fs_hostname, "amd:%d", foreground ? mypid : getppid());
 #else
 #else
-       sprintf(fs_hostname, "pid%d@%s:%s", mypid, hostname, dir);
+       sprintf(fs_hostname, "pid%d@%s:%s", foreground ? mypid : getppid(), hostname, dir);
 #endif /* SHORT_MOUNT_NAME */
        nfs_args.hostname = fs_hostname;
        nfs_args.flags |= NFSMNT_HOSTNAME;
 #endif /* SHORT_MOUNT_NAME */
        nfs_args.hostname = fs_hostname;
        nfs_args.flags |= NFSMNT_HOSTNAME;
@@ -215,171 +204,279 @@ char *opts;
        return mount_fs(&mnt, flags, (caddr_t) &nfs_args, retry, type);
 }
 
        return mount_fs(&mnt, flags, (caddr_t) &nfs_args, retry, type);
 }
 
+static void afs_mkcacheref P((mntfs *mf));
+static void afs_mkcacheref(mf)
+mntfs *mf;
+{
+       /*
+        * Build a new map cache for this node, or re-use
+        * an existing cache for the same map.
+        */
+       char *cache;
+       if (mf->mf_fo && mf->mf_fo->opt_cache)
+               cache = mf->mf_fo->opt_cache;
+       else
+               cache = "none";
+       mf->mf_private = (voidp) mapc_find(mf->mf_info, cache);
+       mf->mf_prfree = mapc_free;
+}
+
+/*
+ * Mount the root...
+ */
+static int root_mount P((am_node *mp));
+static int root_mount(mp)
+am_node *mp;
+{
+       mntfs *mf = mp->am_mnt;
+#ifdef notdef
+       /*
+        * Make sure fattr is set up correctly
+        */
+       mk_fattr(mp, NFDIR);
+#endif
+
+       mf->mf_mount = strealloc(mf->mf_mount, pid_fsname);
+       mf->mf_private = (voidp) mapc_find(mf->mf_info, "");
+       mf->mf_prfree = mapc_free;
+
+       return 0;
+}
+
+/*
+ * Mount a sub-mount
+ */
+static int afs_mount P((am_node *mp));
 static int afs_mount(mp)
 am_node *mp;
 {
        mntfs *mf = mp->am_mnt;
 
 static int afs_mount(mp)
 am_node *mp;
 {
        mntfs *mf = mp->am_mnt;
 
+#ifdef notdef
        /*
        /*
-        * There are two cases to consider...
+        * Make sure fattr is set up correctly
         */
         */
-       if (mp->am_parent && mp->am_parent->am_parent) {
-               /*
-                * If this am_node has a parent which is not the root node, in
-                * which case we are supplying a pseudo-directory, in which
-                * case no action is needed.  Pseudo-directories are used to
-                * provide some structure to the automounted directories instead
-                * of putting them all in the top-level automount directory.
-                */
-               mp->am_parent->am_mnt->mf_fattr.nlink++;
-               /*
-                * Info field of . means use parent's info field.
-                */
-               if (mf->mf_info[0] == '.' && mf->mf_info[1] == '\0')
-                       mf->mf_info = strealloc(mf->mf_info, mp->am_parent->am_mnt->mf_info);
+       mk_fattr(mp, NFDIR);
+#endif
+
+       /*
+        * Pseudo-directories are used to provide some structure
+        * to the automounted directories instead
+        * of putting them all in the top-level automount directory.
+        *
+        * Here, just increment the parent's link count.
+        */
+       mp->am_parent->am_fattr.nlink++;
+       /*
+        * Info field of . means use parent's info field.
+        * Historical - not documented.
+        */
+       if (mf->mf_info[0] == '.' && mf->mf_info[1] == '\0')
+               mf->mf_info = strealloc(mf->mf_info, mp->am_parent->am_mnt->mf_info);
+       /*
+        * Compute prefix:
+        *
+        * If there is an option prefix then use that else
+        * If the parent had a prefix then use that with name
+        *      of this node appended else
+        * Use the name of this node.
+        *
+        * That means if you want no prefix you must say so
+        * in the map.
+        */
+       if (mf->mf_fo->opt_pref) {
                /*
                /*
-                * Compute prefix:
-                *
-                * If there is an option prefix then use that else
-                * If the parent had a prefix then use that with name
-                *      of this node appended else
-                * Use the name of this node.
-                *
-                * That means if you want no prefix you must say so
-                * in the map.
+                * the prefix specified as an option
                 */
                 */
-               if (mf->mf_fo->opt_pref) {
-                       /*
-                        * the prefix specified as an option
-                        */
-                       mp->am_pref = strdup(mf->mf_fo->opt_pref);
-               } else {
-                       /*
-                        * else the parent's prefix
-                        * followed by the name
-                        * followed by /
-                        */
-                       char *ppref = mp->am_parent->am_pref;
-                       if (ppref == 0)
-                               ppref = "";
-                       mp->am_pref = str3cat((char *) 0, ppref, mp->am_name, "/");
-               }
+               mp->am_pref = strdup(mf->mf_fo->opt_pref);
        } else {
                /*
        } else {
                /*
-                * Otherwise, we are mounting the automounter.  In which case
-                * we need to make sure the mount directory exists, construct
-                * the mount options and call the mount_afs routine.
+                * else the parent's prefix
+                * followed by the name
+                * followed by /
                 */
                 */
-               struct stat stb;
-               char opts[256];
-               int error;
+               char *ppref = mp->am_parent->am_pref;
+               if (ppref == 0)
+                       ppref = "";
+               mp->am_pref = str3cat((char *) 0, ppref, mp->am_name, "/");
+       }
 
 
-               /*
-                * Top-level mount - so make
-                * sure the mount point exists
-                * and is a directory.
-                */
-               error = mkdirs(mp->am_path, 0555);
-               if (error)
-                       return error;
-               mp->am_flags |= AMF_MKPATH;
-
-               if (stat(mp->am_path, &stb) < 0) {
-                       return errno;
-               } else if ((stb.st_mode & S_IFMT) != S_IFDIR) {
-                       plog(XLOG_WARNING, "%s is not a directory", mp->am_path);
-                       return ENOTDIR;
-               }
+       /*
+        * Attach a map cache
+        */
+       afs_mkcacheref(mf);
 
 
-               mf->mf_mount = strealloc(mf->mf_mount, mp->am_path);
+       return 0;
+}
 
 
-               /*
-                * Construct some mount options
-                */
-               sprintf(opts,
+/*
+ * Mount the top-level
+ */
+static int toplvl_mount P((am_node *mp));
+static int toplvl_mount(mp)
+am_node *mp;
+{
+       mntfs *mf = mp->am_mnt;
+       struct stat stb;
+       char opts[256];
+       int error;
+       char *mnttype;
+
+       /*
+        * Mounting the automounter.
+        * Make sure the mount directory exists, construct
+        * the mount options and call the mount_toplvl routine.
+        */
+
+       if (stat(mp->am_path, &stb) < 0) {
+               return errno;
+       } else if ((stb.st_mode & S_IFMT) != S_IFDIR) {
+               plog(XLOG_WARNING, "%s is not a directory", mp->am_path);
+               return ENOTDIR;
+       }
+
+       if (mf->mf_ops == &toplvl_ops) mnttype = "indirect";
+       else if (mf->mf_ops == &dfs_ops) mnttype = "direct";
+#ifdef HAS_UNION_FS
+       else if (mf->mf_ops == &union_ops) mnttype = "union";
+#endif
+       else mnttype = "auto";
+
+       /*
+        * Construct some mount options
+        */
+       sprintf(opts,
 #ifdef MNTOPT_INTR
 #ifdef MNTOPT_INTR
-                       "%s,%s,%s=%d,%s=%d,%s=%d,%sdirect",
-                       MNTOPT_INTR,
+               "%s,%s,%s=%d,%s=%d,%s=%d,%s",
+               MNTOPT_INTR,
 #else
 #else
-                       "%s,%s=%d,%s=%d,%s=%d,%sdirect",
+               "%s,%s=%d,%s=%d,%s=%d,%s",
 #endif /* MNTOPT_INTR */
 #ifdef AUTOMOUNT_RO
 #endif /* MNTOPT_INTR */
 #ifdef AUTOMOUNT_RO
-                       MNTOPT_RO,      /* You don't really want this... */
+               MNTOPT_RO,      /* You don't really want this... */
 #else
 #else
-                       "rw",
+               "rw",
 #endif /* AUTOMOUNT_RO */
 #endif /* AUTOMOUNT_RO */
-                       "port", nfs_port,
-                       "timeo", afs_timeo,
-                       "retrans", afs_retrans,
-                       mf->mf_ops == &afs_ops ? "in" : "");
-
-               error = mount_afs(mp->am_path, mp->am_name, opts);
-               if (error) {
-                       errno = error;
-                       plog(XLOG_FATAL, "mount_afs: %m");
-                       return error;
+               "port", nfs_port,
+               "timeo", afs_timeo,
+               "retrans", afs_retrans,
+               mnttype);
+
+       error = mount_toplvl(mf->mf_mount, opts);
+       if (error) {
+               errno = error;
+               plog(XLOG_FATAL, "mount_toplvl: %m");
+               return error;
+       }
+
+       return 0;
+}
+
+static void toplvl_mounted P((mntfs *mf));
+static void toplvl_mounted(mf)
+mntfs *mf;
+{
+       afs_mkcacheref(mf);
+}
+
+#ifdef HAS_UNION_FS
+/*
+ * Create a reference to a union'ed entry
+ */
+static int create_union_node P((char *dir, voidp arg));
+static int create_union_node(dir, arg)
+char *dir;
+voidp arg;
+{
+       if (strcmp(dir, "/defaults") != 0) {
+               int error = 0;
+               (void) toplvl_ops.lookuppn(arg, dir, &error, VLOOK_CREATE);
+               if (error > 0) {
+                       errno = error; /* XXX */
+                       plog(XLOG_ERROR, "Could not mount %s: %m", dir);
                }
                }
-               mp->am_name = pid_fsname;
+               return error;
        }
        }
+       return 0;
+}
+
+static void union_mounted P((mntfs *mf));
+static void union_mounted(mf)
+mntfs *mf;
+{
+       int i;
+       
+       afs_mkcacheref(mf);
 
        /*
 
        /*
-        * Build a new map cache for this node, or re-use
-        * an existing cache for the same map.
+        * Having made the union mount point,
+        * populate all the entries...
         */
         */
-       { char *cache;
-         if (mf->mf_fo->opt_cache)
-               cache = mf->mf_fo->opt_cache;
-         else
-               cache = "none";
-         mf->mf_private = (voidp) mapc_find(mf->mf_info, cache);
-         mf->mf_prfree = mapc_free;
+       for (i = 0; i <= last_used_map; i++) {
+               am_node *mp = exported_ap[i];
+               if (mp && mp->am_mnt == mf) {
+                       /* return value from create_union_node is ignored by mapc_keyiter */
+                       (void) mapc_keyiter((mnt_map *) mp->am_mnt->mf_private,
+                               (void (*)P((char*,void*))) create_union_node, mp);
+                       break;
+               }
        }
 
        }
 
-       return 0;
+#ifdef notdef
+       /*
+        * would be nice to flush most of the cache, but we need to
+        * keep the wildcard and /defaults entries...
+        */
+       mapc_free(mf->mf_private);
+       mf->mf_private = (voidp) mapc_find(mf->mf_info, "inc");
+/*     mapc_add_kv(mf->mf_private, strdup("/defaults"),
+               strdup("type:=link;opts:=nounmount;sublink:=${key}")); */
+#endif
 }
 }
+#endif /* HAS_UNION_FS */
 
 /*
 
 /*
- * Unmount an automount node
+ * Unmount an automount sub-node
  */
  */
+static int afs_umount P((am_node *mp));
 static int afs_umount(mp)
 am_node *mp;
 static int afs_umount(mp)
 am_node *mp;
+{
+       return 0;
+}
+
+/*
+ * Unmount a top-level automount node
+ */
+static int toplvl_umount P((am_node *mp));
+static int toplvl_umount(mp)
+am_node *mp;
 {
        int error;
 
 {
        int error;
 
+       struct stat stb;
+again:
        /*
        /*
-        * If this is a pseudo-directory then just adjust the link count
-        * in the parent, otherwise call the generic unmount routine
+        * The lstat is needed if this mount is type=direct.
+        * When that happens, the kernel cache gets confused
+        * between the underlying type (dir) and the mounted
+        * type (link) and so needs to be re-synced before
+        * the unmount.  This is all because the unmount system
+        * call follows links and so can't actually unmount
+        * a link (stupid!).  It was noted that doing an ls -ld
+        * of the mount point to see why things were not working
+        * actually fixed the problem - so simulate an ls -ld here.
         */
         */
-       if (!mp->am_parent) {
-               error = 0;
-       } else if (mp->am_parent && mp->am_parent->am_parent) {
-               --mp->am_parent->am_mnt->mf_fattr.nlink;
-               error = 0;
-       } else {
-               struct stat stb;
-again:
-               /*
-                * The lstat is needed if this mount is type=direct.
-                * When that happens, the kernel cache gets confused
-                * between the underlying type (dir) and the mounted
-                * type (link) and so needs to be re-synced before
-                * the unmount.  This is all because the unmount system
-                * call follows links and so can't actually unmount
-                * a link (stupid!).  It was noted that doing an ls -ld
-                * of the mount point to see why things were not working
-                * actually fixed the problem - so simulate an ls -ld here.
-                */
-               if (lstat(mp->am_path, &stb) < 0) {
+       if (lstat(mp->am_path, &stb) < 0) {
 #ifdef DEBUG
 #ifdef DEBUG
-                       dlog("lstat(%s): %m", mp->am_path);
+               dlog("lstat(%s): %m", mp->am_path);
 #endif /* DEBUG */
 #endif /* DEBUG */
-               }
-               error = UMOUNT_FS(mp->am_path);
-               if (error == EBUSY) {
-                       plog(XLOG_WARNING, "afs_unmount retrying %s in 1s", mp->am_path);
-                       sleep(1);       /* XXX */
-                       goto again;
-               }
+       }
+       error = UMOUNT_FS(mp->am_path);
+       if (error == EBUSY) {
+               plog(XLOG_WARNING, "afs_unmount retrying %s in 1s", mp->am_path);
+               sleep(1);       /* XXX */
+               goto again;
        }
 
        return error;
        }
 
        return error;
@@ -388,6 +485,7 @@ again:
 /*
  * Unmount an automount node
  */
 /*
  * Unmount an automount node
  */
+static void afs_umounted P((am_node *mp));
 static void afs_umounted(mp)
 am_node *mp;
 {
 static void afs_umounted(mp)
 am_node *mp;
 {
@@ -396,7 +494,7 @@ am_node *mp;
         * in the parent, otherwise call the generic unmount routine
         */
        if (mp->am_parent && mp->am_parent->am_parent)
         * in the parent, otherwise call the generic unmount routine
         */
        if (mp->am_parent && mp->am_parent->am_parent)
-               --mp->am_parent->am_mnt->mf_fattr.nlink;
+               --mp->am_parent->am_fattr.nlink;
 }
 
 /*
 }
 
 /*
@@ -422,9 +520,9 @@ struct continuation {
        char *key;              /* Map key */
        char *info;             /* Info string */
        char **xivec;           /* Saved strsplit vector */
        char *key;              /* Map key */
        char *info;             /* Info string */
        char **xivec;           /* Saved strsplit vector */
-       char *opts;             /* Mount options */
+       char *auto_opts;        /* Automount options */
        am_opts fs_opts;        /* Filesystem options */
        am_opts fs_opts;        /* Filesystem options */
-       char *def_opts;         /* Default options */
+       char *def_opts;         /* Default automount options */
        int retry;              /* Try again? */
        int tried;              /* Have we tried any yet? */
        time_t start;           /* Time we started this mount */
        int retry;              /* Try again? */
        int tried;              /* Have we tried any yet? */
        time_t start;           /* Time we started this mount */
@@ -434,6 +532,7 @@ struct continuation {
 /*
  * Discard an old continuation
  */
 /*
  * Discard an old continuation
  */
+static void free_continuation P((struct continuation *cp));
 static void free_continuation(cp)
 struct continuation *cp;
 {
 static void free_continuation(cp)
 struct continuation *cp;
 {
@@ -442,7 +541,7 @@ struct continuation *cp;
        free((voidp) cp->key);
        free((voidp) cp->xivec);
        free((voidp) cp->info);
        free((voidp) cp->key);
        free((voidp) cp->xivec);
        free((voidp) cp->info);
-       free((voidp) cp->opts);
+       free((voidp) cp->auto_opts);
        free((voidp) cp->def_opts);
        free_opts(&cp->fs_opts);
        free((voidp) cp);
        free((voidp) cp->def_opts);
        free_opts(&cp->fs_opts);
        free((voidp) cp);
@@ -454,6 +553,7 @@ static int afs_bgmount P((struct continuation*, int));
  * Discard the underlying mount point and replace
  * with a reference to an error filesystem.
  */
  * Discard the underlying mount point and replace
  * with a reference to an error filesystem.
  */
+static void assign_error_mntfs P((am_node *mp));
 static void assign_error_mntfs(mp)
 am_node *mp;
 {
 static void assign_error_mntfs(mp)
 am_node *mp;
 {
@@ -462,6 +562,8 @@ am_node *mp;
                 * Save the old error code
                 */
                int error = mp->am_error;
                 * Save the old error code
                 */
                int error = mp->am_error;
+               if (error <= 0)
+                       error = mp->am_mnt->mf_error;
                /*
                 * Discard the old filesystem
                 */
                /*
                 * Discard the old filesystem
                 */
@@ -487,6 +589,7 @@ am_node *mp;
  * the task notifier when a background mount attempt
  * completes.
  */
  * the task notifier when a background mount attempt
  * completes.
  */
+static void afs_cont P((int rc, int term, voidp closure));
 static void afs_cont(rc, term, closure)
 int rc;
 int term;
 static void afs_cont(rc, term, closure)
 int rc;
 int term;
@@ -554,6 +657,7 @@ voidp closure;
  * Retry a mount
  */
 /*ARGSUSED*/
  * Retry a mount
  */
 /*ARGSUSED*/
+static void afs_retry P((int rc, int term, voidp closure));
 static void afs_retry(rc, term, closure)
 int rc;
 int term;
 static void afs_retry(rc, term, closure)
 int rc;
 int term;
@@ -590,17 +694,35 @@ voidp closure;
  * Try to mount a file system.  Can be called
  * directly or in a sub-process by run_task
  */
  * Try to mount a file system.  Can be called
  * directly or in a sub-process by run_task
  */
-static int try_mount(mp)
-am_node *mp;
+static int try_mount P((voidp mvp));
+static int try_mount(mvp)
+voidp mvp;
 {
        /*
         * Mount it!
         */
        int error;
 {
        /*
         * Mount it!
         */
        int error;
+       am_node *mp = (am_node *) mvp;
+       mntfs *mf = mp->am_mnt;
+
+       /*
+        * If the directory is not yet made and
+        * it needs to be made, then make it!
+        * This may be run in a backgroun process
+        * in which case the flag setting won't be
+        * noticed later - but it is set anyway
+        * just after run_task is called.  It
+        * should probably go away totally...
+        */
+       if (!(mf->mf_flags & MFF_MKMNT) && mf->mf_ops->fs_flags & FS_MKMNT) {
+               error = mkdirs(mf->mf_mount, 0555);
+               if (!error)
+                       mf->mf_flags |= MFF_MKMNT;
+       }
 
        error = mount_node(mp);
 #ifdef DEBUG
 
        error = mount_node(mp);
 #ifdef DEBUG
-       if (error) {
+       if (error > 0) {
                errno = error;
                dlog("afs call to mount_node failed: %m");
        }
                errno = error;
                dlog("afs call to mount_node failed: %m");
        }
@@ -667,6 +789,7 @@ For each location:
 endfor
  */
 
 endfor
  */
 
+static int afs_bgmount P((struct continuation *cp, int mpe));
 static int afs_bgmount(cp, mpe)
 struct continuation *cp;
 int mpe;
 static int afs_bgmount(cp, mpe)
 struct continuation *cp;
 int mpe;
@@ -699,8 +822,8 @@ int mpe;
                        /*
                         * Pick up new defaults
                         */
                        /*
                         * Pick up new defaults
                         */
-                       if (cp->opts && *cp->opts)
-                               cp->def_opts = str3cat(cp->def_opts, cp->opts, ";", *cp->ivec+1);
+                       if (cp->auto_opts && *cp->auto_opts)
+                               cp->def_opts = str3cat(cp->def_opts, cp->auto_opts, ";", *cp->ivec+1);
                        else
                                cp->def_opts = strealloc(cp->def_opts, *cp->ivec+1);
 #ifdef DEBUG
                        else
                                cp->def_opts = strealloc(cp->def_opts, *cp->ivec+1);
 #ifdef DEBUG
@@ -750,7 +873,7 @@ int mpe;
                 * Find a mounted filesystem for this node.
                 */
                mp->am_mnt = mf = realloc_mntfs(mf, p, &cp->fs_opts, cp->fs_opts.opt_fs,
                 * Find a mounted filesystem for this node.
                 */
                mp->am_mnt = mf = realloc_mntfs(mf, p, &cp->fs_opts, cp->fs_opts.opt_fs,
-                                               cp->fs_opts.fs_mtab, cp->opts);
+                                               cp->fs_opts.fs_mtab, cp->auto_opts, cp->fs_opts.opt_opts);
 
                p = mf->mf_ops;
 #ifdef DEBUG
 
                p = mf->mf_ops;
 #ifdef DEBUG
@@ -816,29 +939,47 @@ int mpe;
 #ifdef DEBUG
                        dlog("duplicate mount of \"%s\" ...", mf->mf_info);
 #endif /* DEBUG */
 #ifdef DEBUG
                        dlog("duplicate mount of \"%s\" ...", mf->mf_info);
 #endif /* DEBUG */
+                       /*
+                        * Just call mounted()
+                        */
+                       am_mounted(mp);
+
                        this_error = 0;
                        this_error = 0;
-                       new_ttl(mp);
                        break;
                }
 
                /*
                 * Will usually need to play around with the mount nodes
                 * file attribute structure.  This must be done here.
                        break;
                }
 
                /*
                 * Will usually need to play around with the mount nodes
                 * file attribute structure.  This must be done here.
+                * Try and get things initialised, even if the fileserver
+                * is not known to be up.  In the common case this will
+                * progress things faster.
                 */
                if (!this_error) {
                        /*
                 */
                if (!this_error) {
                        /*
-                        * Fill in attribute fields
+                        * Fill in attribute fields.
                         */
                         */
-                       mf->mf_fattr.type = NFLNK;
-                       mf->mf_fattr.mode = NFSMODE_LNK | 0777;
-                       mf->mf_fattr.nlink = 1;
-                       mf->mf_fattr.size = MAXPATHLEN / 4;     /* Conservative */
-                       mf->mf_fattr.fileid = mp->am_gen;
+                       if (mf->mf_ops->fs_flags & FS_DIRECTORY)
+                               mk_fattr(mp, NFDIR);
+                       else
+                               mk_fattr(mp, NFLNK);
+
+                       mp->am_fattr.fileid = mp->am_gen;
 
                        if (p->fs_init)
                                this_error = (*p->fs_init)(mf);
                }
 
 
                        if (p->fs_init)
                                this_error = (*p->fs_init)(mf);
                }
 
+               /*
+                * Make sure the fileserver is UP before doing any more work
+                */
+               if (!FSRV_ISUP(mf->mf_server)) {
+#ifdef DEBUG
+                       dlog("waiting for server %s to become available", mf->mf_server->fs_host);
+#endif
+                       this_error =  -1;
+               }
+
                if (!this_error && mf->mf_fo->opt_delay) {
                        /*
                         * If there is a delay timer on the mount
                if (!this_error && mf->mf_fo->opt_delay) {
                        /*
                         * If there is a delay timer on the mount
@@ -846,9 +987,9 @@ int mpe;
                         * has not expired.
                         */
                        int i = atoi(mf->mf_fo->opt_delay);
                         * has not expired.
                         */
                        int i = atoi(mf->mf_fo->opt_delay);
-                       if (i > 0 && (cp->start + i) < clocktime()) {
+                       if (i > 0 && clocktime() < (cp->start + i)) {
 #ifdef DEBUG
 #ifdef DEBUG
-                               dlog("Mount of %s delayed by %ds", mf->mf_mount, i);
+                               dlog("Mount of %s delayed by %ds", mf->mf_mount, i - clocktime() + cp->start);
 #endif /* DEBUG */
                                this_error = -1;
                        }
 #endif /* DEBUG */
                                this_error = -1;
                        }
@@ -860,37 +1001,25 @@ int mpe;
                        cp->retry = TRUE;
                }
 
                        cp->retry = TRUE;
                }
 
-               if (!this_error) {
-                       /*
-                        * If the directory is not yet made and
-                        * it needs to be made, then make it!
-                        */
-                        if (!(mf->mf_flags & MFF_MKMNT) &&
-                                       p->fs_flags & FS_MKMNT) {
-                               this_error = mkdirs(mf->mf_mount, 0555);
-                               if (!this_error)
-                                       mf->mf_flags |= MFF_MKMNT;
-                       }
-               }
-
                if (!this_error)
                if (p->fs_flags & FS_MBACKGROUND) {
                        mf->mf_flags |= MFF_MOUNTING;   /*XXX*/
 #ifdef DEBUG
                if (!this_error)
                if (p->fs_flags & FS_MBACKGROUND) {
                        mf->mf_flags |= MFF_MOUNTING;   /*XXX*/
 #ifdef DEBUG
-                       dlog("backgrounding mount of \"%s\"", mf->mf_info);
+                       dlog("backgrounding mount of \"%s\"", mf->mf_mount);
 #endif /* DEBUG */
                        if (cp->callout) {
                                untimeout(cp->callout);
                                cp->callout = 0;
                        }
                        run_task(try_mount, (voidp) mp, afs_cont, (voidp) cp);
 #endif /* DEBUG */
                        if (cp->callout) {
                                untimeout(cp->callout);
                                cp->callout = 0;
                        }
                        run_task(try_mount, (voidp) mp, afs_cont, (voidp) cp);
+                       mf->mf_flags |= MFF_MKMNT;      /* XXX */
                        if (mf_retry) free_mntfs(mf_retry);
                        return -1;
                } else {
 #ifdef DEBUG
                        dlog("foreground mount of \"%s\" ...", mf->mf_info);
 #endif /* DEBUG */
                        if (mf_retry) free_mntfs(mf_retry);
                        return -1;
                } else {
 #ifdef DEBUG
                        dlog("foreground mount of \"%s\" ...", mf->mf_info);
 #endif /* DEBUG */
-                       this_error = try_mount(mp);
+                       this_error = try_mount((voidp) mp);
                }
 
                if (this_error >= 0) {
                }
 
                if (this_error >= 0) {
@@ -922,7 +1051,7 @@ int mpe;
                 * reset the default options.
                 */
                cp->ivec = cp->xivec;
                 * reset the default options.
                 */
                cp->ivec = cp->xivec;
-               cp->def_opts = strealloc(cp->def_opts, cp->opts);
+               cp->def_opts = strealloc(cp->def_opts, cp->auto_opts);
                /*
                 * Arrange that afs_bgmount is called
                 * after anything else happens.
                /*
                 * Arrange that afs_bgmount is called
                 * after anything else happens.
@@ -943,19 +1072,20 @@ int mpe;
                return -1;
        }
 
                return -1;
        }
 
+       if (hard_error < 0 || this_error != 0)
+               hard_error = this_error;
+
        /*
         * Discard handle on duff filesystem.
         * This should never happen since it
         * should be caught by the case above.
         */
        if (mf_retry) {
        /*
         * Discard handle on duff filesystem.
         * This should never happen since it
         * should be caught by the case above.
         */
        if (mf_retry) {
-               plog(XLOG_ERROR, "discarding a retry mntfs for %s", mf_retry->mf_mount);
+               if (hard_error)
+                       plog(XLOG_ERROR, "discarding a retry mntfs for %s", mf_retry->mf_mount);
                free_mntfs(mf_retry);
        }
 
                free_mntfs(mf_retry);
        }
 
-       if (hard_error < 0 || !this_error)
-               hard_error = this_error;
-
        /*
         * If we get here, then either the mount succeeded or
         * there is no more mount information available.
        /*
         * If we get here, then either the mount succeeded or
         * there is no more mount information available.
@@ -1000,6 +1130,7 @@ int mpe;
 /*
  * Automount interface to RPC lookup routine
  */
 /*
  * Automount interface to RPC lookup routine
  */
+static am_node *afs_lookuppn P((am_node *mp, char *fname, int *error_return, int op));
 static am_node *afs_lookuppn(mp, fname, error_return, op)
 am_node *mp;
 char *fname;
 static am_node *afs_lookuppn(mp, fname, error_return, op)
 am_node *mp;
 char *fname;
@@ -1015,7 +1146,7 @@ int op;
        am_node *ap, *new_mp, *ap_hung;
        char *info;                     /* Mount info - where to get the file system */
        char **ivec, **xivec;           /* Split version of info */
        am_node *ap, *new_mp, *ap_hung;
        char *info;                     /* Mount info - where to get the file system */
        char **ivec, **xivec;           /* Split version of info */
-       char *opts;                     /* Mount options */
+       char *auto_opts;                /* Automount options */
        int error = 0;                  /* Error so far */
        char path_name[MAXPATHLEN];     /* General path name buffer */
        char *pfname;                   /* Path for database lookup */
        int error = 0;                  /* Error so far */
        char path_name[MAXPATHLEN];     /* General path name buffer */
        char *pfname;                   /* Path for database lookup */
@@ -1035,8 +1166,10 @@ int op;
         */
        if (amd_state == Finishing) {
 #ifdef DEBUG
         */
        if (amd_state == Finishing) {
 #ifdef DEBUG
-               dlog("%s/%s mount ignored - going down",
-                       mp->am_path, fname);
+               if ((mf = mp->am_mnt) == 0 || mf->mf_ops == &dfs_ops)
+                       dlog("%s mount ignored - going down", fname);
+               else
+                       dlog("%s/%s mount ignored - going down", mp->am_path, fname);
 #endif /* DEBUG */
                ereturn(ENOENT);
        }
 #endif /* DEBUG */
                ereturn(ENOENT);
        }
@@ -1212,7 +1345,10 @@ in_progrss:
         */
        error = mapc_search((mnt_map*) mf->mf_private, pfname, &info);
        if (error) {
         */
        error = mapc_search((mnt_map*) mf->mf_private, pfname, &info);
        if (error) {
-               plog(XLOG_MAP, "No map entry for %s", pfname);
+               if (error > 0)
+                       plog(XLOG_MAP, "No map entry for %s", pfname);
+               else
+                       plog(XLOG_MAP, "Waiting on map entry for %s", pfname);
                free(fname);
                ereturn(error);
        }
                free(fname);
                ereturn(error);
        }
@@ -1226,7 +1362,7 @@ in_progrss:
         * The vector is malloc'ed and belongs to
         * this routine.  It is free'd in free_continuation()
         */
         * The vector is malloc'ed and belongs to
         * this routine.  It is free'd in free_continuation()
         */
-       xivec = ivec = strsplit(info, '\"');
+       xivec = ivec = strsplit(info, ' ', '\"');
 
        /*
         * Default error code...
 
        /*
         * Default error code...
@@ -1247,12 +1383,12 @@ in_progrss:
                ereturn(ENOSPC);
        }
 
                ereturn(ENOSPC);
        }
 
-       if (mf->mf_opts)
-               opts = mf->mf_opts;
+       if (mf->mf_auto)
+               auto_opts = mf->mf_auto;
        else
        else
-               opts = "";
+               auto_opts = "";
 
 
-       opts = strdup(opts);
+       auto_opts = strdup(auto_opts);
 
 #ifdef DEBUG
        dlog("searching for /defaults entry");
 
 #ifdef DEBUG
        dlog("searching for /defaults entry");
@@ -1271,7 +1407,7 @@ in_progrss:
                /*
                 * Chop the defaults up
                 */
                /*
                 * Chop the defaults up
                 */
-               rvec = strsplit(dfl, '\"');
+               rvec = strsplit(dfl, ' ', '\"');
                /*
                 * Extract first value
                 */
                /*
                 * Extract first value
                 */
@@ -1300,13 +1436,13 @@ in_progrss:
                         * Prepend to existing defaults if they exist,
                         * otherwise just use these defaults.
                         */
                         * Prepend to existing defaults if they exist,
                         * otherwise just use these defaults.
                         */
-                       if (*opts && *dfl) {
-                               char *nopts = (char *) xmalloc(strlen(opts)+strlen(dfl)+2);
-                               sprintf(nopts, "%s;%s", dfl, opts);
-                               free(opts);
-                               opts = nopts;
+                       if (*auto_opts && *dfl) {
+                               char *nopts = (char *) xmalloc(strlen(auto_opts)+strlen(dfl)+2);
+                               sprintf(nopts, "%s;%s", dfl, auto_opts);
+                               free(auto_opts);
+                               auto_opts = nopts;
                        } else if (*dfl) {
                        } else if (*dfl) {
-                               opts = strealloc(opts, dfl);
+                               auto_opts = strealloc(auto_opts, dfl);
                        }
                }
                free(dflts);
                        }
                }
                free(dflts);
@@ -1324,9 +1460,14 @@ in_progrss:
 
        /*
         * Fill in some other fields,
 
        /*
         * Fill in some other fields,
-        * path and mount point
+        * path and mount point.
+        *
+        * bugfix: do not prepend old am_path if direct map
+        *         <wls@astro.umd.edu> William Sebok
         */
         */
-       new_mp->am_path = str3cat(new_mp->am_path, mp->am_path, *fname == '/' ? "" : "/", fname);
+       new_mp->am_path = str3cat(new_mp->am_path,
+               mf->mf_ops == &dfs_ops ? "" : mp->am_path,
+               *fname == '/' ? "" : "/", fname);
 
 #ifdef DEBUG
        dlog("setting path to %s", new_mp->am_path);
 
 #ifdef DEBUG
        dlog("setting path to %s", new_mp->am_path);
@@ -1346,11 +1487,11 @@ in_progrss:
        cp->ivec = ivec;
        cp->info = info;
        cp->key = pfname;
        cp->ivec = ivec;
        cp->info = info;
        cp->key = pfname;
-       cp->opts = opts;
+       cp->auto_opts = auto_opts;
        cp->retry = FALSE;
        cp->tried = FALSE;
        cp->start = clocktime();
        cp->retry = FALSE;
        cp->tried = FALSE;
        cp->start = clocktime();
-       cp->def_opts = strdup(opts);
+       cp->def_opts = strdup(auto_opts);
        bzero((voidp) &cp->fs_opts, sizeof(cp->fs_opts));
 
        /*
        bzero((voidp) &cp->fs_opts, sizeof(cp->fs_opts));
 
        /*
@@ -1379,6 +1520,7 @@ in_progrss:
  * Locate next node in sibling list which is mounted
  * and is not an error node.
  */
  * Locate next node in sibling list which is mounted
  * and is not an error node.
  */
+static am_node *next_nonerror_node P((am_node *xp));
 static am_node *next_nonerror_node(xp)
 am_node *xp;
 {
 static am_node *next_nonerror_node(xp)
 am_node *xp;
 {
@@ -1402,11 +1544,13 @@ am_node *xp;
        return xp;
 }
 
        return xp;
 }
 
-static int afs_readdir(mp, cookie, dp, ep)
+static int afs_readdir P((am_node *mp, nfscookie cookie, struct dirlist *dp, struct entry *ep, int count));
+static int afs_readdir(mp, cookie, dp, ep, count)
 am_node *mp;
 nfscookie cookie;
 struct dirlist *dp;
 struct entry *ep;
 am_node *mp;
 nfscookie cookie;
 struct dirlist *dp;
 struct entry *ep;
+int count;
 {
        unsigned int gen = *(unsigned int*) cookie;
        am_node *xp;
 {
        unsigned int gen = *(unsigned int*) cookie;
        am_node *xp;
@@ -1467,20 +1611,35 @@ struct entry *ep;
                xp = xp->am_osib;
 
        if (xp) {
                xp = xp->am_osib;
 
        if (xp) {
-               am_node *xp_next = next_nonerror_node(xp->am_osib);
+               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) {
-                       *(unsigned int *) ep->cookie = xp_next->am_gen;
-               } else {
-                       *(unsigned int *) ep->cookie = ~(unsigned int)0;
-                       dp->eof = TRUE;
-               }
+                       if (xp_next) {
+                               *(unsigned int *) ep->cookie = xp_next->am_gen;
+                       } else {
+                               *(unsigned int *) ep->cookie = ~(unsigned int)0;
+                               dp->eof = TRUE;
+                       }
+
+                       ep->fileid = xp->am_gen;
+                       ep->name = xp->am_name;
+                       nbytes -= sizeof(*ep) + strlen(xp->am_name) + 1;
 
 
-               ep->fileid = xp->am_gen;
-               ep->name = xp->am_name;
+                       xp = xp_next;
+
+                       if (nbytes > 0 && !dp->eof && todo > 1) {
+                               ep->nextentry = ep + 1;
+                               ep++;
+                               --todo;
+                       } else {
+                               todo = 0;
+                       }
+               } while (todo > 0);
 
                ep->nextentry = 0;
 
                ep->nextentry = 0;
-               dp->entries = ep;
 
                return 0;
        }
 
                return 0;
        }
@@ -1489,6 +1648,7 @@ struct entry *ep;
 
 }
 
 
 }
 
+static am_node *dfs_readlink P((am_node *mp, int *error_return));
 static am_node *dfs_readlink(mp, error_return)
 am_node *mp;
 int *error_return;
 static am_node *dfs_readlink(mp, error_return)
 am_node *mp;
 int *error_return;
@@ -1497,8 +1657,11 @@ int *error_return;
        int rc = 0;
 
        xp = next_nonerror_node(mp->am_child);
        int rc = 0;
 
        xp = next_nonerror_node(mp->am_child);
-       if (!xp)
+       if (!xp) {
+               if (!mp->am_mnt->mf_private)
+                       afs_mkcacheref(mp->am_mnt);     /* XXX */
                xp = afs_lookuppn(mp, mp->am_path+1, &rc, VLOOK_CREATE);
                xp = afs_lookuppn(mp, mp->am_path+1, &rc, VLOOK_CREATE);
+       }
 
        if (xp) {
                new_ttl(xp);    /* (7/12/89) from Rein Tollevik */
 
        if (xp) {
                new_ttl(xp);    /* (7/12/89) from Rein Tollevik */
@@ -1513,32 +1676,89 @@ int *error_return;
 /*
  * Ops structure
  */
 /*
  * Ops structure
  */
+am_ops root_ops = {
+       "root",
+       0, /* root_match */
+       0, /* root_init */
+       root_mount,
+       0,
+       afs_umount,
+       0,
+       afs_lookuppn,
+       afs_readdir,
+       0, /* root_readlink */
+       0, /* root_mounted */
+       0, /* root_umounted */
+       find_afs_srvr,
+       FS_NOTIMEOUT|FS_AMQINFO|FS_DIRECTORY
+};
+
 am_ops afs_ops = {
        "auto",
        afs_match,
 am_ops afs_ops = {
        "auto",
        afs_match,
-       afs_init,
+       0, /* afs_init */
        afs_mount,
        afs_mount,
+       0,
        afs_umount,
        afs_umount,
+       0,
        afs_lookuppn,
        afs_readdir,
        0, /* afs_readlink */
        0, /* afs_mounted */
        afs_umounted,
        find_afs_srvr,
        afs_lookuppn,
        afs_readdir,
        0, /* afs_readlink */
        0, /* afs_mounted */
        afs_umounted,
        find_afs_srvr,
-       FS_NOTIMEOUT|FS_UBACKGROUND|FS_AMQINFO
+       FS_AMQINFO|FS_DIRECTORY
+};
+
+am_ops toplvl_ops = {
+       "toplvl",
+       afs_match,
+       0, /* afs_init */
+       toplvl_mount,
+       0,
+       toplvl_umount,
+       0,
+       afs_lookuppn,
+       afs_readdir,
+       0, /* toplvl_readlink */
+       toplvl_mounted,
+       0, /* toplvl_umounted */
+       find_afs_srvr,
+       FS_MKMNT|FS_NOTIMEOUT|FS_BACKGROUND|FS_AMQINFO|FS_DIRECTORY
 };
 
 am_ops dfs_ops = {
        "direct",
        afs_match,
        0, /* dfs_init */
 };
 
 am_ops dfs_ops = {
        "direct",
        afs_match,
        0, /* dfs_init */
-       afs_mount,
-       afs_umount,
+       toplvl_mount,
+       0,
+       toplvl_umount,
+       0,
        efs_lookuppn,
        efs_readdir,
        dfs_readlink,
        efs_lookuppn,
        efs_readdir,
        dfs_readlink,
-       0, /* afs_mounted */
-       afs_umounted,
+       toplvl_mounted,
+       0, /* afs_umounted */
+       find_afs_srvr,
+       FS_MKMNT|FS_NOTIMEOUT|FS_BACKGROUND|FS_AMQINFO
+};
+
+#ifdef HAS_UNION_FS
+am_ops union_ops = {
+       "union",
+       afs_match,
+       0, /* afs_init */
+       toplvl_mount,
+       0,
+       toplvl_umount,
+       0,
+       afs_lookuppn,
+       afs_readdir,
+       0, /* toplvl_readlink */
+       union_mounted,
+       0, /* toplvl_umounted */
        find_afs_srvr,
        find_afs_srvr,
-       FS_NOTIMEOUT|FS_UBACKGROUND|FS_AMQINFO
+       FS_MKMNT|FS_NOTIMEOUT|FS_BACKGROUND|FS_AMQINFO|FS_DIRECTORY
 };
 };
+#endif /* HAS_UNION_FS */
index 3fc6389..d55d63c 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: am_ops.c,v 5.2 90/06/23 22:19:19 jsp Rel $
+ * $Id: am_ops.c,v 5.2.1.3 91/03/03 20:37:39 jsp Alpha $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)am_ops.c    5.1 (Berkeley) %G%
+ *     @(#)am_ops.c    5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
 static am_ops *vops[] = {
 #ifdef HAS_UFS
        &ufs_ops,
 static am_ops *vops[] = {
 #ifdef HAS_UFS
        &ufs_ops,
-#endif /* HAS_UFS */
+#endif
 #ifdef HAS_NFS
        &nfs_ops,
 #ifdef HAS_NFS
        &nfs_ops,
-#endif /* HAS_NFS */
+#endif
+#ifdef HAS_NFSX
+       &nfsx_ops,
+#endif
 #ifdef HAS_HOST
        &host_ops,
 #ifdef HAS_HOST
        &host_ops,
-#endif /* HAS_HOST */
+#endif
 #ifdef HAS_SFS
        &sfs_ops,
 #ifdef HAS_SFS
        &sfs_ops,
-#endif /* HAS_SFS */
+#endif
 #ifdef HAS_LOFS
        &lofs_ops,
 #ifdef HAS_LOFS
        &lofs_ops,
-#endif /* HAS_LOFS */
+#endif
 #ifdef HAS_PFS
        &pfs_ops,
 #ifdef HAS_PFS
        &pfs_ops,
-#endif /* HAS_PFS */
-       &afs_ops,       /* These three should be last ... */
+#endif
+#ifdef HAS_UNION_FS
+       &union_ops,
+#endif
+       &afs_ops,       /* These four should be last ... */
        &dfs_ops,       /* ... */
        &dfs_ops,       /* ... */
-       &efs_ops,       /* ... in the order afs; dfs; efs */
+       &toplvl_ops,    /* ... */
+       &efs_ops,       /* ... in the order afs; dfs; toplvl; efs */
        0
 };
 
        0
 };
 
+void ops_showfstypes P((FILE *fp));
+void ops_showfstypes(fp)
+FILE *fp;
+{
+       struct am_ops **ap;
+       char *sep = "";
+
+       for (ap = vops; *ap; ap++) {
+               fprintf(fp, "%s%s", sep, (*ap)->fs_type);
+               sep = ", ";
+       }
+}
+
 #ifdef SUNOS4_COMPAT
 /*
  * Crack a SunOS4-style host:fs:sub-link line
 #ifdef SUNOS4_COMPAT
 /*
  * Crack a SunOS4-style host:fs:sub-link line
@@ -85,7 +105,7 @@ char *map;
        if (!eval_fs_opts(fo, key, g_key, path, keym, map)) {
                rop = &efs_ops;
        } else if (fo->opt_type == 0) {
        if (!eval_fs_opts(fo, key, g_key, path, keym, map)) {
                rop = &efs_ops;
        } else if (fo->opt_type == 0) {
-               plog(XLOG_USER, "No fs type specified (somewhere!)");
+               plog(XLOG_USER, "No fs type specified (key = \"%s\", map = \"%s\")", keym, map);
                rop = &efs_ops;
        } else {
                /*
                rop = &efs_ops;
        } else {
                /*
@@ -113,12 +133,15 @@ char *map;
        /*
         * Check the filesystem is happy
         */
        /*
         * Check the filesystem is happy
         */
-       if ((*rop->fs_match)(fo))
+       if (fo->fs_mtab)
+               free((voidp) fo->fs_mtab);
+
+       if (fo->fs_mtab = (*rop->fs_match)(fo))
                return rop;
 
        /*
         * Return error file system
         */
                return rop;
 
        /*
         * Return error file system
         */
-       (void) (*efs_ops.fs_match)(fo);
+       fo->fs_mtab = (*efs_ops.fs_match)(fo);
        return &efs_ops;
 }
        return &efs_ops;
 }
index df864fe..15ae790 100644 (file)
@@ -8,9 +8,9 @@
 .\"
 .\" %sccs.include.redist.man%
 .\"
 .\"
 .\" %sccs.include.redist.man%
 .\"
-.\"     @(#)amd.8      5.2 (Berkeley) %G%
+.\"     @(#)amd.8      5.3 (Berkeley) %G%
 .\"
 .\"
-.Dd 
+.Dd March 17, 1991
 .Dt AMD 8
 .Os
 .Sh NAME
 .Dt AMD 8
 .Os
 .Sh NAME
@@ -50,16 +50,6 @@ Filesystems are automatically unmounted when they
 appear to be quiescent.
 .Pp
 .Nm Amd
 appear to be quiescent.
 .Pp
 .Nm Amd
-has been designed as a value-added replacement
-for the SunOS 4
-.Xr automount 8
-program.
-Considerable design effort has been expended in making
-.Nm amd
-robust in the face of
-.Tn NFS
-servers going down.
-.Nm Amd
 operates by attaching itself as an
 .Tn NFS
 server to each of the specified
 operates by attaching itself as an
 .Tn NFS
 server to each of the specified
@@ -67,7 +57,7 @@ server to each of the specified
 Lookups within the specified directories
 are handled by
 .Nm amd ,
 Lookups within the specified directories
 are handled by
 .Nm amd ,
-which uses the map contained in
+which uses the map defined by
 .Ar mapname
 to determine how to resolve the lookup.
 Generally, this will be a host name, some filesystem information
 .Ar mapname
 to determine how to resolve the lookup.
 Generally, this will be a host name, some filesystem information
@@ -97,13 +87,9 @@ is the string
 .Em syslog ,
 the log messages will be sent to the system log daemon by
 .Xr syslog 3 .
 .Em syslog ,
 the log messages will be sent to the system log daemon by
 .Xr syslog 3 .
-This is only available on certain systems (e.g.
-.Em not
-.Tn HP-UX
-and early versions of Ultrix).
 .It Fl n
 Normalize hostnames.
 .It Fl n
 Normalize hostnames.
-The name refered to by ${rhost} are normalized relative to the
+The name refered to by ${rhost} is normalized relative to the
 host database before being used.  The effect is to translate
 aliases into ``official'' names.
 .It Fl p
 host database before being used.  The effect is to translate
 aliases into ``official'' names.
 .It Fl p
@@ -133,10 +119,6 @@ Useful defaults are supplied if either or both
 values are missing.
 .It Fl v
 Version.  Displays version and configuration information on standard error.
 values are missing.
 .It Fl v
 Version.  Displays version and configuration information on standard error.
-If you send a bug report, this should be used to determine
-which version of
-.Nm amd
-you are using.
 .It Fl w Ar interval
 Specify an
 .Ar interval ,
 .It Fl w Ar interval
 Specify an
 .Ar interval ,
@@ -145,14 +127,17 @@ filesystems that have exceeded their cached times.
 The default is 2 minutes.
 .It Fl y Ar domain
 Specify an alternative
 The default is 2 minutes.
 .It Fl y Ar domain
 Specify an alternative
-.Tn YP
+.Tn NIS
 domain from which to fetch the
 domain from which to fetch the
-.Tn YP
+.Tn NIS
 maps.
 The default is the system domain name.
 maps.
 The default is the system domain name.
+This option is ignored if
+.Tn NIS
+support is not available.
 .It Fl x Ar options
 Specify run-time logging options.  The options are a comma separated
 .It Fl x Ar options
 Specify run-time logging options.  The options are a comma separated
-list chosen from: fatal, error, user, warn, info, all.
+list chosen from: fatal, error, user, warn, info, map, stats, all.
 .It Fl D Ar option
 Select from a variety of debug options.  Prefixing an
 option with the strings
 .It Fl D Ar option
 Select from a variety of debug options.  Prefixing an
 option with the strings
@@ -179,9 +164,9 @@ Some care may be required when creating a mount map.
 .Pp
 Symbolic links on an
 .Tn NFS
 .Pp
 Symbolic links on an
 .Tn NFS
-filesystem are incredibly inefficient.
-Their interpolations are not cached by the kernel and each time a symbolic
-link is
+filesystem can be incredibly inefficient.
+In most implementations of NFS, their interpolations are not cached by
+the kernel and each time a symbolic link is
 encountered during a
 .Em lookuppn
 translation it costs an
 encountered during a
 .Em lookuppn
 translation it costs an
@@ -189,7 +174,7 @@ translation it costs an
 call to the
 .Tn NFS
 server.
 call to the
 .Tn NFS
 server.
-It would appear that a large improvement in real-time
+A large improvement in real-time
 performance could be gained by adding a cache somewhere.
 Replacing
 .Xr symlinks 2
 performance could be gained by adding a cache somewhere.
 Replacing
 .Xr symlinks 2
@@ -208,12 +193,11 @@ the features.
 .Xr umount 8 ,
 .Xr mtab 5 ,
 .Rs
 .Xr umount 8 ,
 .Xr mtab 5 ,
 .Rs
-.%T Amd \- An Automounter
+.%T Amd \- The 4.4 BSD Automounter
 .Re
 .Sh AUTHOR
 .An Jan-Simon Pendry
 <jsp@doc.ic.ac.uk>, Department of Computing, Imperial College, London, UK.
 .Sh HISTORY
 .Re
 .Sh AUTHOR
 .An Jan-Simon Pendry
 <jsp@doc.ic.ac.uk>, Department of Computing, Imperial College, London, UK.
 .Sh HISTORY
-The
-.Nm
+.Nm Amd
 .At
 .At
index 76f7273..8687cee 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: amd.c,v 5.2 90/06/23 22:19:18 jsp Rel $
+ * $Id: amd.c,v 5.2.1.4 91/03/17 17:48:40 jsp Alpha $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)amd.c       5.1 (Berkeley) %G%
+ *     @(#)amd.c       5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -20,7 +20,6 @@
 
 #include "am.h"
 #include <sys/signal.h>
 
 #include "am.h"
 #include <sys/signal.h>
-#include <netdb.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include <setjmp.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include <setjmp.h>
 char pid_fsname[16 + MAXHOSTNAMELEN];  /* "kiska.southseas.nz:(pid%d)" */
 char *progname;                                /* "amd" */
 #ifdef HAS_HOST
 char pid_fsname[16 + MAXHOSTNAMELEN];  /* "kiska.southseas.nz:(pid%d)" */
 char *progname;                                /* "amd" */
 #ifdef HAS_HOST
+#ifdef HOST_EXEC
 char *host_helper;
 char *host_helper;
+#endif /* HOST_EXEC */
 #endif /* HAS_HOST */
 char *auto_dir = "/a";
 char *hostdomain = "unknown.domain";
 #endif /* HAS_HOST */
 char *auto_dir = "/a";
 char *hostdomain = "unknown.domain";
-char hostname[MAXHOSTNAMELEN];         /* Hostname */
+char hostname[MAXHOSTNAMELEN] = "localhost"; /* Hostname */
 char hostd[2*MAXHOSTNAMELEN];          /* Host+domain */
 char *op_sys = OS_REP;                 /* Name of current op_sys */
 char *arch = ARCH_REP;                 /* Name of current architecture */
 char *endian = ARCH_ENDIAN;            /* Big or Little endian */
 char hostd[2*MAXHOSTNAMELEN];          /* Host+domain */
 char *op_sys = OS_REP;                 /* Name of current op_sys */
 char *arch = ARCH_REP;                 /* Name of current architecture */
 char *endian = ARCH_ENDIAN;            /* Big or Little endian */
+char *wire;
 int foreground = 1;                    /* This is the top-level server */
 int mypid;                             /* Current process id */
 int immediate_abort;                   /* Should close-down unmounts be retried */
 struct in_addr myipaddr;               /* (An) IP address of this host */
 int foreground = 1;                    /* This is the top-level server */
 int mypid;                             /* Current process id */
 int immediate_abort;                   /* Should close-down unmounts be retried */
 struct in_addr myipaddr;               /* (An) IP address of this host */
-serv_state amd_state = Start;
+serv_state amd_state;
 struct amd_stats amd_stats;            /* Server statistics */
 time_t do_mapc_reload = 0;             /* mapc_reload() call required? */
 jmp_buf select_intr;
 struct amd_stats amd_stats;            /* Server statistics */
 time_t do_mapc_reload = 0;             /* mapc_reload() call required? */
 jmp_buf select_intr;
@@ -58,7 +60,7 @@ int sig;
 {
 #ifdef SYS5_SIGNALS
        signal(sig, sigterm);
 {
 #ifdef SYS5_SIGNALS
        signal(sig, sigterm);
-#endif * SYS5_SIGNALS */
+#endif /* SYS5_SIGNALS */
 
        switch (sig) {
        case SIGINT:
 
        switch (sig) {
        case SIGINT:
@@ -81,12 +83,13 @@ int sig;
  * Hook for cache reload.
  * When a SIGHUP arrives it schedules a call to mapc_reload
  */
  * Hook for cache reload.
  * When a SIGHUP arrives it schedules a call to mapc_reload
  */
+/*ARGSUSED*/
 static void sighup(sig)
 int sig;
 {
 #ifdef SYS5_SIGNALS
        signal(sig, sighup);
 static void sighup(sig)
 int sig;
 {
 #ifdef SYS5_SIGNALS
        signal(sig, sighup);
-#endif /* SUS5_SIGNALS */
+#endif /* SYS5_SIGNALS */
 
 #ifdef DEBUG
        if (sig != SIGHUP)
 
 #ifdef DEBUG
        if (sig != SIGHUP)
@@ -99,6 +102,7 @@ int sig;
                do_mapc_reload = 0;
 }
 
                do_mapc_reload = 0;
 }
 
+/*ARGSUSED*/
 static void parent_exit(sig)
 int sig;
 {
 static void parent_exit(sig)
 int sig;
 {
@@ -107,7 +111,10 @@ int sig;
 
 static int daemon_mode(P_void)
 {
 
 static int daemon_mode(P_void)
 {
-       int bgpid = background();
+       int bgpid;
+
+       signal(SIGQUIT, parent_exit);
+       bgpid = background();
 
        if (bgpid != 0) {
                if (print_pid) {
 
        if (bgpid != 0) {
                if (print_pid) {
@@ -118,23 +125,27 @@ static int daemon_mode(P_void)
                 * Now wait for the automount points to
                 * complete.
                 */
                 * Now wait for the automount points to
                 * complete.
                 */
-               signal(SIGQUIT, parent_exit);
                for (;;)
                        pause();
        }
 
                for (;;)
                        pause();
        }
 
+       signal(SIGQUIT, SIG_DFL);
+
        /*
         * Pretend we are in the foreground again
         */
        foreground = 1;
        /*
         * Pretend we are in the foreground again
         */
        foreground = 1;
+
 #ifdef TIOCNOTTY
        {
                int t = open("/dev/tty", O_RDWR);
                if (t < 0) {
                        if (errno != ENXIO)     /* not an error if already no controlling tty */
                                plog(XLOG_WARNING, "Could not open controlling tty: %m");
 #ifdef TIOCNOTTY
        {
                int t = open("/dev/tty", O_RDWR);
                if (t < 0) {
                        if (errno != ENXIO)     /* not an error if already no controlling tty */
                                plog(XLOG_WARNING, "Could not open controlling tty: %m");
-               } else if (ioctl(t, TIOCNOTTY, 0) < 0) {
-                       plog(XLOG_WARNING, "Could not disassociate tty (TIOCNOTTY): %m");
+               } else {
+                       if (ioctl(t, TIOCNOTTY, 0) < 0 && errno != ENOTTY)
+                               plog(XLOG_WARNING, "Could not disassociate tty (TIOCNOTTY): %m");
+                       (void) close(t);
                }
        }
 #else
                }
        }
 #else
@@ -148,7 +159,6 @@ main(argc, argv)
 int argc;
 char *argv[];
 {
 int argc;
 char *argv[];
 {
-       struct hostent *hp, *gethostbyname();
        char *domdot;
        int ppid = 0;
        int error;
        char *domdot;
        int ppid = 0;
        int error;
@@ -164,6 +174,27 @@ char *argv[];
         */
        amd_state = Start;
 
         */
        amd_state = Start;
 
+       /*
+        * Determine program name
+        */
+       if (argv[0]) {
+               progname = strrchr(argv[0], '/');
+               if (progname && progname[1])
+                       progname++;
+               else
+                       progname = argv[0];
+       }
+
+       if (!progname)
+               progname = "amd";
+
+       /*
+        * Initialise process id.  This is kept
+        * cached since it is used for generating
+        * and using file handles.
+        */
+       mypid = getpid();
+
        /*
         * Get local machine name
         */
        /*
         * Get local machine name
         */
@@ -214,31 +245,17 @@ char *argv[];
         */
        (void) signal(SIGCHLD, sigchld);
 
         */
        (void) signal(SIGCHLD, sigchld);
 
-       /*
-        * Initialise process id.  This is kept
-        * cached since it is used for generating
-        * and using file handles.
-        */
-       mypid = getpid();
-
-#ifdef notdef
-/*
- * XXX - Doing this plugs most of a memory leak in
- * gethostbyname on SunOS 4.  I see no good reason
- * why the host database needs to grab 1.5K of
- * private data space...  However, for the moment,
- * I will take its word that it is a _good thing_
- * (jsp)
- */
-       (void) sethostent(0);
-#endif /* notdef */
-
        /*
         * Fix-up any umask problems.  Most systems default
         * to 002 which is not too convenient for our purposes
         */
        orig_umask = umask(0);
 
        /*
         * Fix-up any umask problems.  Most systems default
         * to 002 which is not too convenient for our purposes
         */
        orig_umask = umask(0);
 
+       /*
+        * Figure out primary network name
+        */
+       wire = getwire();
+
        /*
         * Determine command-line arguments
         */
        /*
         * Determine command-line arguments
         */
@@ -246,18 +263,12 @@ char *argv[];
 
        /*
         * Get our own IP address so that we
 
        /*
         * Get our own IP address so that we
-        * can mount the automounter.  There
-        * is probably a better way of doing
-        * this, but messing about with SIOCGIFCONF
-        * seems to be heading towards the non-portable
-        * arena.
+        * can mount the automounter.
         */
         */
-       hp = gethostbyname(hostname);
-       if (!hp || hp->h_addrtype != AF_INET) {
-               plog(XLOG_FATAL, "Can't determine IP address of this host (%s)", hostname);
-               going_down(1);
+       { struct sockaddr_in sin;
+         get_myaddress(&sin);
+         myipaddr.s_addr = sin.sin_addr.s_addr;
        }
        }
-       myipaddr = *(struct in_addr *) hp->h_addr;
 
        /*
         * Now check we are root.
 
        /*
         * Now check we are root.
index 6f0340a..5ca2b88 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: amq_subr.c,v 5.2 90/06/23 22:19:20 jsp Rel $
+ * $Id: amq_subr.c,v 5.2.1.4 91/03/17 17:48:23 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)amq_subr.c  5.1 (Berkeley) %G%
+ *     @(#)amq_subr.c  5.2 (Berkeley) %G%
  */
 /*
  * Auxilliary routines for amq tool
  */
 /*
  * Auxilliary routines for amq tool
@@ -19,7 +19,7 @@
 
 #include "am.h"
 #include "amq.h"
 
 #include "am.h"
 #include "amq.h"
-
+#include <ctype.h>
 #include <sys/param.h>
 
 /*ARGSUSED*/
 #include <sys/param.h>
 
 /*ARGSUSED*/
@@ -87,25 +87,9 @@ struct svc_req *rqstp;
 {
        static amq_mount_tree_list aml;
 
 {
        static amq_mount_tree_list aml;
 
-#ifdef oldcode
-       static am_node **mvec;
-       int i;
-       int n = 0;
-
-       mvec = (struct am_node **)
-               xrealloc(mvec, (1+last_used_map) * sizeof(am_node *));
-       for (i = last_used_map; i >= 0; --i) {
-               am_node *mp = exported_ap[i];
-               if (mp && (mp->am_flags & AMF_ROOT))
-                       mvec[n++] = mp;
-       }
-
-       aml.amq_mount_tree_list_val = (amq_mount_tree_p *) mvec;
-       aml.amq_mount_tree_list_len = n;
-#else
        aml.amq_mount_tree_list_val = (amq_mount_tree_p *) &exported_ap[0];
        aml.amq_mount_tree_list_len = 1;        /* XXX */
        aml.amq_mount_tree_list_val = (amq_mount_tree_p *) &exported_ap[0];
        aml.amq_mount_tree_list_len = 1;        /* XXX */
-#endif /* oldcode */
+
        return &aml;
 }
 
        return &aml;
 }
 
@@ -147,6 +131,8 @@ struct svc_req *rqstp;
                if (amd_state == Run) {
                        plog(XLOG_INFO, "amq says flush cache");
                        do_mapc_reload = 0;
                if (amd_state == Run) {
                        plog(XLOG_INFO, "amq says flush cache");
                        do_mapc_reload = 0;
+                       flush_nfs_fhandle_cache((fserver *) 0);
+                       flush_srvr_nfs_cache();
                }
                break;
        }
                }
                break;
        }
@@ -162,6 +148,78 @@ extern qelem mfhead;
        return (amq_mount_info_list *) &mfhead; /* XXX */
 }
 
        return (amq_mount_info_list *) &mfhead; /* XXX */
 }
 
+static int ok_security(rqstp)
+struct svc_req *rqstp;
+{
+       struct sockaddr_in *sin;
+
+       sin = svc_getcaller(rqstp->rq_xprt);
+       if (ntohs(sin->sin_port) >= 1024 ||
+           !(sin->sin_addr.s_addr == htonl(0x7f000001) ||
+             sin->sin_addr.s_addr == myipaddr.s_addr)) {
+               char dq[20];
+               plog(XLOG_INFO, "AMQ request from %s.%d DENIED",
+                    inet_dquad(dq, sin->sin_addr.s_addr),
+                    ntohs(sin->sin_port));
+               return(0);
+       }
+       return(1);
+}
+
+int *
+amqproc_mount_1(argp, rqstp)
+voidp argp;
+struct svc_req *rqstp;
+{
+       static int rc;
+       char *s = *(amq_string *) argp;
+       char *cp;
+
+       plog(XLOG_INFO, "amq requested mount of %s", s);
+       /*
+        * Minimalist security check.
+        */
+       if (!ok_security(rqstp)) {
+               rc = EACCES;
+               return &rc;
+       }
+
+       /*
+        * Find end of key
+        */
+       for (cp = (char *) s; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++)
+               ;
+
+       if (!*cp) {
+               plog(XLOG_INFO, "amqproc_mount: Invalid arguments");
+               rc = EINVAL;
+               return &rc;
+       }
+       *cp++ = '\0';
+
+       /*
+        * Find start of value
+        */
+       while (*cp && isascii(*cp) && isspace(*cp))
+               cp++;
+
+       root_newmap(s, cp, (char *) 0);
+       rc = mount_auto_node(s, (voidp) root_node);
+       if (rc < 0)
+               return 0;
+       return &rc;
+}
+
+amq_string *
+amqproc_getvers_1(argp, rqstp)
+voidp argp;
+struct svc_req *rqstp;
+{
+static amq_string res;
+       res = version;
+       return &res;
+}
+
 /*
  * XDR routines.
  */
 /*
  * XDR routines.
  */
@@ -194,7 +252,7 @@ xdr_amq_setopt(xdrs, objp)
  * More XDR routines  - Should be used for OUTPUT ONLY.
  */
 bool_t
  * More XDR routines  - Should be used for OUTPUT ONLY.
  */
 bool_t
-xdr_amq_mount_tree(xdrs, objp)
+xdr_amq_mount_tree_node(xdrs, objp)
        XDR *xdrs;
        amq_mount_tree *objp;
 {
        XDR *xdrs;
        amq_mount_tree *objp;
 {
@@ -233,10 +291,43 @@ xdr_amq_mount_tree(xdrs, objp)
        if (!xdr_int(xdrs, &mp->am_stats.s_statfs)) {
                return (FALSE);
        }
        if (!xdr_int(xdrs, &mp->am_stats.s_statfs)) {
                return (FALSE);
        }
-       if (!xdr_pointer(xdrs, (char **)&mp->am_osib, sizeof(amq_mount_tree), xdr_amq_mount_tree)) {
+       return (TRUE);
+}
+
+bool_t
+xdr_amq_mount_subtree(xdrs, objp)
+       XDR *xdrs;
+       amq_mount_tree *objp;
+{
+       am_node *mp = (am_node *) objp;
+
+       if (!xdr_amq_mount_tree_node(xdrs, objp)) {
+               return (FALSE);
+       }
+       if (!xdr_pointer(xdrs, (char **)&mp->am_osib, sizeof(amq_mount_tree), xdr_amq_mount_subtree)) {
                return (FALSE);
        }
                return (FALSE);
        }
-       if (!xdr_pointer(xdrs, (char **)&mp->am_child, sizeof(amq_mount_tree), xdr_amq_mount_tree)) {
+       if (!xdr_pointer(xdrs, (char **)&mp->am_child, sizeof(amq_mount_tree), xdr_amq_mount_subtree)) {
+               return (FALSE);
+       }
+       return (TRUE);
+}
+
+bool_t
+xdr_amq_mount_tree(xdrs, objp)
+       XDR *xdrs;
+       amq_mount_tree *objp;
+{
+       am_node *mp = (am_node *) objp;
+       am_node *mnil = 0;
+
+       if (!xdr_amq_mount_tree_node(xdrs, objp)) {
+               return (FALSE);
+       }
+       if (!xdr_pointer(xdrs, (char **)&mnil, sizeof(amq_mount_tree), xdr_amq_mount_subtree)) {
+               return (FALSE);
+       }
+       if (!xdr_pointer(xdrs, (char **)&mp->am_child, sizeof(amq_mount_tree), xdr_amq_mount_subtree)) {
                return (FALSE);
        }
        return (TRUE);
                return (FALSE);
        }
        return (TRUE);
@@ -289,6 +380,7 @@ xdr_amq_mount_tree_list(xdrs, objp)
        return (TRUE);
 }
 
        return (TRUE);
 }
 
+bool_t
 xdr_amq_mount_info_qelem(xdrs, qhead)
        XDR *xdrs;
        qelem *qhead;
 xdr_amq_mount_info_qelem(xdrs, qhead)
        XDR *xdrs;
        qelem *qhead;
index c1d3ee5..b2e170e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: clock.c,v 5.2 90/06/23 22:19:21 jsp Rel $
+ * $Id: clock.c,v 5.2.1.4 91/03/03 20:41:36 jsp Alpha $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)clock.c     5.1 (Berkeley) %G%
+ *     @(#)clock.c     5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -21,8 +21,8 @@
  * See usual references.
  *
  * Use of a heap-based mechanism was rejected:
  * See usual references.
  *
  * Use of a heap-based mechanism was rejected:
- * 1.  more complext implementation needed.
- * 2.  not obvious that a list is too slow for amd.
+ * 1.  more complex implementation needed.
+ * 2.  not obvious that a list is too slow for Amd.
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -48,11 +48,12 @@ time_t next_softclock;                      /* Time of next call to softclock() */
 #define        CALLOUT_FREE_SLOP       10
 
 /*
 #define        CALLOUT_FREE_SLOP       10
 
 /*
- * Assumption: valid id's are non-zero.
+ * Global assumption: valid id's are non-zero.
  */
 #define        CID_ALLOC()     (++callout_id)
 #define        CID_UNDEF       (0)
 
  */
 #define        CID_ALLOC()     (++callout_id)
 #define        CID_UNDEF       (0)
 
+static callout *alloc_callout(P_void);
 static callout *alloc_callout()
 {
        callout *cp = free_callouts;
 static callout *alloc_callout()
 {
        callout *cp = free_callouts;
@@ -64,6 +65,7 @@ static callout *alloc_callout()
        return ALLOC(callout);
 }
 
        return ALLOC(callout);
 }
 
+static void free_callout P((callout *cp));
 static void free_callout(cp)
 callout *cp;
 {
 static void free_callout(cp)
 callout *cp;
 {
@@ -81,6 +83,7 @@ callout *cp;
  *
  * (*fn)(closure) will be called at clocktime() + secs
  */
  *
  * (*fn)(closure) will be called at clocktime() + secs
  */
+int timeout P((unsigned int secs, void (*fn)(), voidp closure));
 int timeout(secs, fn, closure)
 unsigned int secs;
 void (*fn)();
 int timeout(secs, fn, closure)
 unsigned int secs;
 void (*fn)();
@@ -123,6 +126,7 @@ voidp closure;
 /*
  * De-schedule a callout
  */
 /*
  * De-schedule a callout
  */
+void untimeout P((int id));
 void untimeout(id)
 int id;
 {
 void untimeout(id)
 int id;
 {
@@ -136,9 +140,32 @@ int id;
        }
 }
 
        }
 }
 
+/*
+ * Reschedule after clock changed
+ */
+void reschedule_timeouts P((time_t now, time_t then));
+void reschedule_timeouts(now, then)
+time_t now;
+time_t then;
+{
+       callout *cp;
+
+       for (cp = callouts.c_next; cp; cp = cp->c_next) {
+               if (cp->c_time >= now && cp->c_time <= then) {
+                       plog(XLOG_WARNING, "job %d rescheduled to run immediately", cp->c_id);
+#ifdef DEBUG
+                       dlog("rescheduling job %d back %d seconds",
+                               cp->c_id, cp->c_time - now);
+#endif
+                       next_softclock = cp->c_time = now;
+               }
+       }
+}
+
 /*
  * Clock handler
  */
 /*
  * Clock handler
  */
+int softclock(P_void);
 int softclock()
 {
        time_t now;
 int softclock()
 {
        time_t now;
@@ -146,7 +173,7 @@ int softclock()
 
        do {
                if (task_notify_todo)
 
        do {
                if (task_notify_todo)
-                       task_notify();
+                       do_task_notify();
 
                now = clocktime();
 
 
                now = clocktime();
 
index 2d92016..bacc77b 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: efs_ops.c,v 5.2 90/06/23 22:19:23 jsp Rel $
+ * $Id: efs_ops.c,v 5.2.1.2 90/11/04 23:17:14 jsp Exp $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)efs_ops.c   5.1 (Berkeley) %G%
+ *     @(#)efs_ops.c   5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
 /*
  * EFS file system always matches
  */
 /*
  * EFS file system always matches
  */
-static int efs_match(fo)
+static char *efs_match(fo)
 am_opts *fo;
 {
 am_opts *fo;
 {
-       fo->fs_mtab = strealloc(fo->fs_mtab, "(error-hook)");
-       return 1;
+       return strdup("(error-hook)");
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
-static int efs_mount(mp)
-am_node *mp;
+static int efs_fmount(mf)
+mntfs *mf;
 {
        return ENOENT;
 }
 
 /*ARGSUSED*/
 {
        return ENOENT;
 }
 
 /*ARGSUSED*/
-static int efs_umount(mp)
-am_node *mp;
+static int efs_fumount(mf)
+mntfs *mf;
 {
        /*
         * Always succeed
 {
        /*
         * Always succeed
@@ -76,11 +75,12 @@ int op;
  * If we do then just give an error.
  */
 /*ARGSUSED*/
  * If we do then just give an error.
  */
 /*ARGSUSED*/
-int efs_readdir(mp, cookie, dp, ep)
+int efs_readdir(mp, cookie, dp, ep, count)
 am_node *mp;
 nfscookie cookie;
 dirlist *dp;
 entry *ep;
 am_node *mp;
 nfscookie cookie;
 dirlist *dp;
 entry *ep;
+int count;
 {
        return ESTALE;
 }
 {
        return ESTALE;
 }
@@ -92,8 +92,10 @@ am_ops efs_ops = {
        "error",
        efs_match,
        0, /* efs_init */
        "error",
        efs_match,
        0, /* efs_init */
-       efs_mount,
-       efs_umount,
+       auto_fmount,
+       efs_fmount,
+       auto_fumount,
+       efs_fumount,
        efs_lookuppn,
        efs_readdir,
        0, /* efs_readlink */
        efs_lookuppn,
        efs_readdir,
        0, /* efs_readlink */
index 76b70a8..bb9738b 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: get_args.c,v 5.2 90/06/23 22:19:24 jsp Rel $
+ * $Id: get_args.c,v 5.2.1.4 91/03/17 17:48:02 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)get_args.c  5.1 (Berkeley) %G%
+ *     @(#)get_args.c  5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -41,35 +41,10 @@ char *domain;                       /* YP domain */
 #ifdef UPDATE_MTAB
 char *mtab;
 #endif /* UPDATE_MTAB */
 #ifdef UPDATE_MTAB
 char *mtab;
 #endif /* UPDATE_MTAB */
-FILE *logfp = stderr;          /* Log errors to stderr initially */
-#ifdef HAS_SYSLOG
-int syslogging;
-#endif /* HAS_SYSLOG */
 int afs_timeo = -1;
 int afs_retrans = -1;
 int am_timeo = AM_TTL;
 int am_timeo_w = AM_TTL_W;
 int afs_timeo = -1;
 int afs_retrans = -1;
 int am_timeo = AM_TTL;
 int am_timeo_w = AM_TTL_W;
-int xlog_level = 0;
-int xlog_level_init = ~0;
-
-/*
- * List of log options
- */
-static struct opt_tab xlog_opt[] = {
-       { "all", XLOG_ALL },            /* All messages */
-#ifdef DEBUG
-       { "debug", XLOG_DEBUG },        /* Debug messages */
-#endif /* DEBUG */
-       { "error", XLOG_ERROR },        /* Non-fatal system errors */
-       { "fatal", XLOG_FATAL },        /* Fatal errors */
-       { "info", XLOG_INFO },          /* Information */
-       { "map", XLOG_MAP },            /* Map errors */
-       { "stats", XLOG_STATS },        /* Additional statistical information */
-       { "user", XLOG_USER },          /* Non-fatal user errors */
-       { "warn", XLOG_WARNING },       /* Warnings */
-       { "warning", XLOG_WARNING },    /* Warnings */
-       { 0, 0 }
-};
 
 #ifdef DEBUG
 /*
 
 #ifdef DEBUG
 /*
@@ -91,171 +66,17 @@ static struct opt_tab dbg_opt[] = {
 int debug_flags = D_AMQ                        /* Register AMQ */
                 |D_DAEMON              /* Enter daemon mode */
                 ;
 int debug_flags = D_AMQ                        /* Register AMQ */
                 |D_DAEMON              /* Enter daemon mode */
                 ;
-#endif /* DEBUG */
-
-void show_opts(ch, opts)
-int ch;
-struct opt_tab *opts;
-{
-       /*
-        * Display current debug options
-        */
-       int i;
-       int s = '{';
-       fprintf(stderr, "\t[-%c {no}", ch);
-       for (i = 0; opts[i].opt; i++) {
-               fprintf(stderr, "%c%s", s, opts[i].opt);
-               s = ',';
-       }
-       fputs("}]\n", stderr);
-}
-
-static int option(s, optb, flags)
-char *s;
-struct opt_tab *optb;
-int *flags;
-{
-       char *p = s;
-       int errs = 0;
-
-       while (p && *p) {
-               int neg;
-               char *opt;
-               struct opt_tab *dp;
-
-               s = p;
-               p = strchr(p, ',');
-               if (p)
-                       *p = '\0';
-
-               if (s[0] == 'n' && s[1] == 'o') {
-                       opt = s + 2;
-                       neg = 1;
-               } else {
-                       opt = s;
-                       neg = 0;
-               }
-
-               /*
-                * Scan the array of debug options to find the
-                * corresponding flag value.  If it is found
-                * then set (or clear) the flag (depending on
-                * whether the option was prefixed with "no").
-                */
-               for (dp = optb; dp->opt; dp++) {
-                       if (strcmp(opt, dp->opt) == 0) {
-                               if (neg)
-                                       *flags &= ~dp->flag;
-                               else
-                                       *flags |= dp->flag;
-                               break;
-                       }
-               }
-
-               if (dp->opt == 0) {
-                       /*
-                        * This will log to stderr when parsing the command line
-                        * since any -l option will not yet have taken effect.
-                        */
-                       plog(XLOG_USER, "option \"%s\" not recognised", s);
-                       errs++;
-               }
-               /*
-                * Put the comma back
-                */
-               if (p)
-                       *p++ = ',';
-       }
-
-       return errs;
-}
 
 
-/*
- * Switch on/off logging options
- */
-int switch_option(opt)
-char *opt;
-{
-       int xl = xlog_level;
-       int rc = option(opt, xlog_opt, &xl);
-       if (rc) {
-               rc = EINVAL;
-       } else {
-               /*
-                * Keep track of initial log level, and
-                * don't allow options to be turned off.
-                */
-               if (xlog_level_init == ~0)
-                       xlog_level_init = xl;
-               else
-                       xl |= xlog_level_init;
-               xlog_level = xl;
-       }
-       return rc;
-}
-
-#ifdef DEBUG
 /*
  * Switch on/off debug options
  */
 int debug_option(opt)
 char *opt;
 {
 /*
  * Switch on/off debug options
  */
 int debug_option(opt)
 char *opt;
 {
-       return option(opt, dbg_opt, &debug_flags);
+       return cmdoption(opt, dbg_opt, &debug_flags);
 }
 #endif /* DEBUG */
 
 }
 #endif /* DEBUG */
 
-/*
- * Change current logfile
- */
-int switch_to_logfile(logfile)
-char *logfile;
-{
-       FILE *new_logfp = stderr;
-
-       if (logfile) {
-#ifdef HAS_SYSLOG
-               syslogging = 0;
-#endif /* HAS_SYSLOG */
-               if (strcmp(logfile, "/dev/stderr") == 0)
-                       new_logfp = stderr;
-               else if (strcmp(logfile, "syslog") == 0) {
-#ifdef HAS_SYSLOG
-                       syslogging = 1;
-                       new_logfp = stderr;
-#ifdef LOG_CONS
-                       openlog(progname, LOG_PID|LOG_CONS|LOG_NOWAIT,
-                               LOG_DAEMON);
-#else
-                       /* 4.2 compat mode - XXX */
-                       openlog(progname, LOG_PID);
-#endif /* LOG_CONS */
-#else
-                       plog(XLOG_WARNING, "syslog option not supported, logging unchanged");
-#endif /* HAS_SYSLOG */
-               } else {
-                       (void) umask(orig_umask);
-                       new_logfp = fopen(logfile, "a");
-                       umask(0);
-               }
-       }
-
-       /*
-        * If we couldn't open a new file, then continue using the old.
-        */
-       if (!new_logfp && logfile) {
-               plog(XLOG_USER, "%s: Can't open logfile: %m", logfile);
-               return 1;
-       }
-       /*
-        * Close the previous file
-        */
-       if (logfp && logfp != stderr)
-               (void) fclose(logfp);
-       logfp = new_logfp;
-       return 0;
-}
-
 void get_args(c, v)
 int c;
 char *v[];
 void get_args(c, v)
 int c;
 char *v[];
@@ -265,21 +86,6 @@ char *v[];
        char *logfile = 0;
        char *sub_domain = 0;
 
        char *logfile = 0;
        char *sub_domain = 0;
 
-#if defined(DEBUG) && defined(PARANOID)
-       gargv = v;
-       progname = v[0];                /* Use argv[0] to try to solve Piete's problem */
-#else
-       if (v[0]) {
-               progname = strrchr(v[0], '/');
-               if (progname && progname[1])
-                       progname++;
-               else
-                       progname = v[0];
-       }
-#endif /* defined(DEBUG) && defined(PARANOID) */
-       if (!progname)
-               progname = "amd";
-
        while ((opt_ch = getopt(c, v, "mnprva:c:d:h:k:l:t:w:x:y:C:D:")) != EOF)
        switch (opt_ch) {
        case 'a':
        while ((opt_ch = getopt(c, v, "mnprva:c:d:h:k:l:t:w:x:y:C:D:")) != EOF)
        switch (opt_ch) {
        case 'a':
@@ -349,17 +155,13 @@ char *v[];
                break;
 
        case 'v':
                break;
 
        case 'v':
-               { char buf[256];
-                 show_rcs_info(version, buf);
-                 fputs(buf, stderr);
-               }
-               fprintf(stderr,
-                       " for a%s %s running %s (%s-endian)\n",
-                                       strchr("aeiou", arch[0]) ? "n" : "",
-                                       arch, op_sys, endian);
+               fprintf(stderr, "%s%s (%s-endian).\n", copyright, version, endian);
                fputs("Map support for: ", stderr);
                mapc_showtypes(stderr);
                fputs("Map support for: ", stderr);
                mapc_showtypes(stderr);
+               fputs(".\nFS: ", stderr);
+               ops_showfstypes(stderr);
                fputs(".\n", stderr);
                fputs(".\n", stderr);
+               fprintf(stderr, "Primary network is %s.\n", wire);
                exit(0);
                break;
 
                exit(0);
                break;
 
@@ -398,11 +200,8 @@ char *v[];
                break;
        }
 
                break;
        }
 
-       if (xlog_level == 0) {
-               /* Take copy to avoid writable-strings problem */
-               char *dfstr = strdup(XLOG_DEFSTR);
-               usage += switch_option(dfstr);
-               free((voidp) dfstr);
+       if (xlog_level_init == ~0) {
+               (void) switch_option("");
 #ifdef DEBUG
                usage += switch_option("debug");
 #endif /* DEBUG */
 #ifdef DEBUG
                usage += switch_option("debug");
 #endif /* DEBUG */
index efbfa3a..1f16aed 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: host_ops.c,v 5.2 90/06/23 22:19:26 jsp Rel $
+ * $Id: host_ops.c,v 5.2.1.3 91/03/03 20:42:25 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)host_ops.c  5.1 (Berkeley) %G%
+ *     @(#)host_ops.c  5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
 #include <sys/stat.h>
 
 /*
 #include <sys/stat.h>
 
 /*
- * NFS host file system
+ * NFS host file system.
+ * Mounts all exported filesystems from a given host.
+ * This has now degenerated into a mess but will not
+ * be rewritten.  Amd 6 will support the abstractions
+ * needed to make this work correctly.
  */
 
 /*
  */
 
 /*
  */
 #define HOST_MKDIRS
 
  */
 #define HOST_MKDIRS
 
+/*
+ * Determine the mount point
+ */
+#define MAKE_MNTPT(mntpt, ex, mf) { \
+                       if (strcmp((ex)->ex_dir, "/") == 0) \
+                               strcpy((mntpt), (mf)->mf_mount); \
+                       else \
+                               sprintf((mntpt), "%s%s", (mf)->mf_mount, (ex)->ex_dir); \
+}
+
 /*
  * Execute needs the same as NFS plus a helper command
  */
 /*
  * Execute needs the same as NFS plus a helper command
  */
-static int host_match(fo)
+static char *host_match P((am_opts *fo));
+static char *host_match(fo)
 am_opts *fo;
 {
 #ifdef HOST_EXEC
 am_opts *fo;
 {
 #ifdef HOST_EXEC
@@ -56,10 +71,8 @@ am_opts *fo;
        if (!fo->opt_rfs)
                fo->opt_rfs = "/";
 
        if (!fo->opt_rfs)
                fo->opt_rfs = "/";
 
-       if (!(*nfs_ops.fs_match)(fo))
-               return FALSE;
-
-       return TRUE;
+       
+       return (*nfs_ops.fs_match)(fo);
 }
 
 static int host_init(mf)
 }
 
 static int host_init(mf)
@@ -92,6 +105,7 @@ caddr_t args_ptr;
        return ((*xdr_args)(&xdr, args_ptr));
 }
 
        return ((*xdr_args)(&xdr, args_ptr));
 }
 
+static int do_mount P((fhstatus *fhp, char *dir, char *fs_name, char *opts, mntfs *mf));
 static int do_mount(fhp, dir, fs_name, opts, mf)
 fhstatus *fhp;
 char *dir;
 static int do_mount(fhp, dir, fs_name, opts, mf)
 fhstatus *fhp;
 char *dir;
@@ -114,7 +128,8 @@ mntfs *mf;
        return mount_nfs_fh(fhp, dir, fs_name, opts, mf);
 }
 
        return mount_nfs_fh(fhp, dir, fs_name, opts, mf);
 }
 
-static sortfun(a, b)
+static int sortfun P((exports *a, exports *b));
+static int sortfun(a, b)
 exports *a,*b;
 {
        return strcmp((*a)->ex_dir, (*b)->ex_dir);
 exports *a,*b;
 {
        return strcmp((*a)->ex_dir, (*b)->ex_dir);
@@ -123,6 +138,7 @@ exports *a,*b;
 /*
  * Get filehandle
  */
 /*
  * Get filehandle
  */
+static int fetch_fhandle P((CLIENT *client, char *dir, fhstatus *fhp));
 static int fetch_fhandle(client, dir, fhp)
 CLIENT *client;
 char *dir;
 static int fetch_fhandle(client, dir, fhp)
 CLIENT *client;
 char *dir;
@@ -164,32 +180,61 @@ fhstatus *fhp;
        return 0;
 }
 
        return 0;
 }
 
+/*
+ * Scan mount table to see if something already mounted
+ */
+static int already_mounted P((mntlist *mlist, char*dir));
+static int already_mounted(mlist, dir)
+mntlist *mlist;
+char *dir;
+{
+       mntlist *ml;
+
+       for (ml = mlist; ml; ml = ml->mnext)
+               if (strcmp(ml->mnt->mnt_dir, dir) == 0)
+                       return 1;
+       return 0;
+}
+
 /*
  * Mount the export tree from a host
  */
 /*
  * Mount the export tree from a host
  */
-static int host_mount(mp)
-am_node *mp;
+static int host_fmount P((mntfs *mf));
+static int host_fmount(mf)
+mntfs *mf;
 {
        struct timeval tv2;
        CLIENT *client;
        enum clnt_stat clnt_stat;
        int n_export;
 {
        struct timeval tv2;
        CLIENT *client;
        enum clnt_stat clnt_stat;
        int n_export;
-       int j;
+       int j, k;
        exports exlist = 0, ex;
        exports *ep = 0;
        fhstatus *fp = 0;
        exports exlist = 0, ex;
        exports *ep = 0;
        fhstatus *fp = 0;
-       mntfs *mf = mp->am_mnt;
        char *host = mf->mf_server->fs_host;
        int error = 0;
        struct sockaddr_in sin;
        int sock = RPC_ANYSOCK;
        int ok = FALSE;
        char *host = mf->mf_server->fs_host;
        int error = 0;
        struct sockaddr_in sin;
        int sock = RPC_ANYSOCK;
        int ok = FALSE;
-       
+       mntlist *mlist;
+       char fs_name[MAXPATHLEN], *rfs_dir;
+       char mntpt[MAXPATHLEN];
+
 #ifdef HOST_RPC_UDP
        struct timeval tv;
        tv.tv_sec = 10; tv.tv_usec = 0;
 #endif /* HOST_RPC_UDP */
 
 #ifdef HOST_RPC_UDP
        struct timeval tv;
        tv.tv_sec = 10; tv.tv_usec = 0;
 #endif /* HOST_RPC_UDP */
 
+       /*
+        * Read the mount list
+        */
+       mlist = read_mtab(mf->mf_mount);
+
+       /*
+        * Unlock the mount list
+        */
+       unlock_mntlist();
+
        /*
         * Take a copy of the server address
         */
        /*
         * Take a copy of the server address
         */
@@ -251,11 +296,16 @@ am_node *mp;
 
        /*
         * Allocate an array of pointers into the list
 
        /*
         * Allocate an array of pointers into the list
-        * so that they can be sorted.
+        * so that they can be sorted.  If the filesystem
+        * is already mounted then ignore it.
         */
        ep = (exports *) xmalloc(n_export * sizeof(exports));
         */
        ep = (exports *) xmalloc(n_export * sizeof(exports));
-       for (j = 0, ex = exlist; ex; ex = ex->ex_next, j++)
-               ep[j] = ex;
+       for (j = 0, ex = exlist; ex; ex = ex->ex_next) {
+               MAKE_MNTPT(mntpt, ex, mf);
+               if (!already_mounted(mlist, mntpt))
+                       ep[j++] = ex;
+       }
+       n_export = j;
 
        /*
         * Sort into order.
 
        /*
         * Sort into order.
@@ -275,9 +325,18 @@ am_node *mp;
         * If a fetch fails then just zero out the array
         * reference but discard the error.
         */
         * If a fetch fails then just zero out the array
         * reference but discard the error.
         */
-       for (j = 0; j < n_export; j++) {
-               if (error = fetch_fhandle(client, ep[j]->ex_dir, &fp[j]))
+       for (j = k = 0; j < n_export; j++) {
+               /* Check and avoid a duplicated export entry */
+               if (j > k && ep[k] && strcmp(ep[j]->ex_dir, ep[k]->ex_dir) == 0) {
+#ifdef DEBUG
+                       dlog("avoiding dup fhandle requested for %s", ep[j]->ex_dir);
+#endif
                        ep[j] = 0;
                        ep[j] = 0;
+               } else {
+                       k = j;
+                       if (error = fetch_fhandle(client, ep[j]->ex_dir, &fp[j]))
+                               ep[j] = 0;
+               }
        }
 
        /*
        }
 
        /*
@@ -286,18 +345,19 @@ am_node *mp;
         * error code 0 at the end.  If they all fail then return
         * the last error code.
         */
         * error code 0 at the end.  If they all fail then return
         * the last error code.
         */
+       strncpy(fs_name, mf->mf_info, sizeof(fs_name));
+       if ((rfs_dir = strchr(fs_name, ':')) == (char *) 0) {
+               plog(XLOG_FATAL, "host_fmount: mf_info has no colon");
+               error = EINVAL;
+               goto out;
+       }
+       ++rfs_dir;
        for (j = 0; j < n_export; j++) {
                ex = ep[j];
                if (ex) {
        for (j = 0; j < n_export; j++) {
                ex = ep[j];
                if (ex) {
-                       char fs_name[MAXPATHLEN];
-                       char mntpt[MAXPATHLEN];
-                       sprintf(fs_name, "%s:%s", host, ex->ex_dir);
-                       if (strcmp(ex->ex_dir, "/") == 0)
-                               strcpy(mntpt, mf->mf_mount);
-                       else
-                               sprintf(mntpt, "%s%s", mf->mf_mount, ex->ex_dir);
-                       error = do_mount(&fp[j], mntpt, fs_name, mf->mf_fo->opt_opts, mf);
-                       if (!error)
+                       strcpy(rfs_dir, ex->ex_dir);
+                       MAKE_MNTPT(mntpt, ex, mf);
+                       if (do_mount(&fp[j], mntpt, fs_name, mf->mf_mopts, mf) == 0)
                                ok = TRUE;
                }
        }
                                ok = TRUE;
                }
        }
@@ -306,6 +366,7 @@ am_node *mp;
         * Clean up and exit
         */
 out:
         * Clean up and exit
         */
 out:
+       discard_mntlist(mlist);
        if (ep)
                free(ep);
        if (fp)
        if (ep)
                free(ep);
        if (fp)
@@ -325,6 +386,7 @@ out:
  * TODO:
  * Does not work if pref is "/".
  */
  * TODO:
  * Does not work if pref is "/".
  */
+static int directory_prefix P((char *pref, char *dir));
 static int directory_prefix(pref, dir)
 char *pref;
 char *dir;
 static int directory_prefix(pref, dir)
 char *pref;
 char *dir;
@@ -340,10 +402,10 @@ char *dir;
 /*
  * Unmount a mount tree
  */
 /*
  * Unmount a mount tree
  */
-static int host_umount(mp)
-am_node *mp;
+static int host_fumount P((mntfs *mf));
+static int host_fumount(mf)
+mntfs *mf;
 {
 {
-       mntfs *mf = mp->am_mnt;
        mntlist *ml, *mprev;
        int xerror = 0;
 
        mntlist *ml, *mprev;
        int xerror = 0;
 
@@ -373,7 +435,7 @@ am_node *mp;
        /*
         * Unmount all filesystems...
         */
        /*
         * Unmount all filesystems...
         */
-       for (ml = mlist; ml; ml = ml->mnext) {
+       for (ml = mlist; ml && !xerror; ml = ml->mnext) {
                char *dir = ml->mnt->mnt_dir;
                if (directory_prefix(mf->mf_mount, dir)) {
                        int error;
                char *dir = ml->mnt->mnt_dir;
                if (directory_prefix(mf->mf_mount, dir)) {
                        int error;
@@ -407,11 +469,22 @@ am_node *mp;
         */
        discard_mntlist(mlist);
 
         */
        discard_mntlist(mlist);
 
+       /*
+        * Try to remount, except when we are shutting down.
+        */
+       if (xerror && amd_state != Finishing) {
+               xerror = host_fmount(mf);
+               if (!xerror) {
+                       plog(XLOG_INFO, "Remounted host %s", mf->mf_info);
+                       xerror = EBUSY;
+               }
+       }
        return xerror;
 }
 
 #else /* HOST_EXEC */
 
        return xerror;
 }
 
 #else /* HOST_EXEC */
 
+static int host_exec P((char*op, char*host, char*fs, char*opts));
 static int host_exec(op, host, fs, opts)
 char *op;
 char *host;
 static int host_exec(op, host, fs, opts)
 char *op;
 char *host;
@@ -472,14 +545,16 @@ char *opts;
        return error;
 }
 
        return error;
 }
 
+static int host_mount P((am_node *mp));
 static int host_mount(mp)
 am_node *mp;
 {
        mntfs *mf = mp->am_mnt;
 
 static int host_mount(mp)
 am_node *mp;
 {
        mntfs *mf = mp->am_mnt;
 
-       return host_exec("mount", mf->mf_server->fs_host, mf->mf_mount, mf->mf_fo->opt_opts);
+       return host_exec("mount", mf->mf_server->fs_host, mf->mf_mount, mf->mf_opts);
 }
 
 }
 
+static int host_umount P((am_node *mp));
 static int host_umount(mp)
 am_node *mp;
 {
 static int host_umount(mp)
 am_node *mp;
 {
@@ -497,8 +572,10 @@ am_ops host_ops = {
        "host",
        host_match,
        host_init,
        "host",
        host_match,
        host_init,
-       host_mount,
-       host_umount,
+       auto_fmount,
+       host_fmount,
+       auto_fumount,
+       host_fumount,
        efs_lookuppn,
        efs_readdir,
        0, /* host_readlink */
        efs_lookuppn,
        efs_readdir,
        0, /* host_readlink */
index 7704063..6d31e3b 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: ifs_ops.c,v 5.2 90/06/23 22:19:28 jsp Rel $
+ * $Id: ifs_ops.c,v 5.2.1.3 91/03/17 17:47:48 jsp Alpha $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)ifs_ops.c   5.1 (Berkeley) %G%
+ *     @(#)ifs_ops.c   5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -30,12 +30,16 @@ static char not_a_filesystem[] = "Attempting to inherit not-a-filesystem";
 /*
  * This should never be called.
  */
 /*
  * This should never be called.
  */
-static int ifs_match()
+/*ARGSUSED*/
+static char *ifs_match P((am_opts *fo));
+static char *ifs_match(fo)
+am_opts *fo;
 {
        plog(XLOG_FATAL, "ifs_match called!");
 {
        plog(XLOG_FATAL, "ifs_match called!");
-       return FALSE;
+       return 0;
 }
 
 }
 
+static int ifs_init P((mntfs *mf));
 static int ifs_init(mf)
 mntfs *mf;
 {
 static int ifs_init(mf)
 mntfs *mf;
 {
@@ -44,6 +48,7 @@ mntfs *mf;
                plog(XLOG_FATAL, not_a_filesystem);
                return EINVAL;
        }
                plog(XLOG_FATAL, not_a_filesystem);
                return EINVAL;
        }
+#ifdef notdef
        /*
         * Fill in attribute fields
         */
        /*
         * Fill in attribute fields
         */
@@ -51,17 +56,16 @@ mntfs *mf;
        mf_link->mf_fattr.mode = NFSMODE_LNK | 0777;
        mf_link->mf_fattr.nlink = 1;
        mf_link->mf_fattr.size = MAXPATHLEN / 4;
        mf_link->mf_fattr.mode = NFSMODE_LNK | 0777;
        mf_link->mf_fattr.nlink = 1;
        mf_link->mf_fattr.size = MAXPATHLEN / 4;
+#endif
        if (mf_link->mf_ops->fs_init)
                return (*mf_link->mf_ops->fs_init)(mf_link);
        return 0;
 }
 
        if (mf_link->mf_ops->fs_init)
                return (*mf_link->mf_ops->fs_init)(mf_link);
        return 0;
 }
 
-/*ARGSUSED*/
-static int ifs_mount(mp)
-am_node *mp;
+static mntfs *ifs_inherit P((mntfs *mf));
+static mntfs *ifs_inherit(mf)
+mntfs *mf;
 {
 {
-       mntfs *mf = mp->am_mnt;
-
        /*
         * Take the linked mount point and
         * propogate.
        /*
         * Take the linked mount point and
         * propogate.
@@ -69,11 +73,13 @@ am_node *mp;
        mntfs *mf_link = (mntfs *) mf->mf_private;
        if (mf_link == 0) {
                plog(XLOG_FATAL, not_a_filesystem);
        mntfs *mf_link = (mntfs *) mf->mf_private;
        if (mf_link == 0) {
                plog(XLOG_FATAL, not_a_filesystem);
-               return EINVAL;  /*XXX*/
+               return 0;       /*XXX*/
        }
 
        mf_link->mf_fo = mf->mf_fo;
        }
 
        mf_link->mf_fo = mf->mf_fo;
+#ifdef notdef
        mf_link->mf_fattr.fileid = mf->mf_fattr.fileid;
        mf_link->mf_fattr.fileid = mf->mf_fattr.fileid;
+#endif /* notdef */
 
        /*
         * Discard the old map.
 
        /*
         * Discard the old map.
@@ -91,26 +97,47 @@ am_node *mp;
        /*
         * Get a hold of the other entry
         */
        /*
         * Get a hold of the other entry
         */
-       mp->am_mnt = mf = mf_link;
-       mf->mf_flags &= ~MFF_RESTART;
+       mf_link->mf_flags &= ~MFF_RESTART;
 
        /* Say what happened */
 
        /* Say what happened */
-       plog(XLOG_INFO, "restarting %s on %s", mf->mf_info, mf->mf_mount);
+       plog(XLOG_INFO, "restarting %s on %s", mf_link->mf_info, mf_link->mf_mount);
 
 
-       /*
-        * XXX - must do the am_mounted call here
-        */
-       if (mf->mf_ops->fs_flags & FS_MBACKGROUND)
-               am_mounted(mp);
+       return mf_link;
+}
 
 
-       new_ttl(mp);
+static int ifs_mount P((am_node *mp));
+static int ifs_mount(mp)
+am_node *mp;
+{
+       mntfs *newmf = ifs_inherit(mp->am_mnt);
+       if (newmf) {
+               mp->am_mnt = newmf;
+               /*
+                * XXX - must do the am_mounted call here
+                */
+               if (newmf->mf_ops->fs_flags & FS_MBACKGROUND)
+                       am_mounted(mp);
 
 
-       return 0;
+               new_ttl(mp);
+               return 0;
+       }
+       return EINVAL;
+}
+
+static int ifs_fmount P((mntfs *mf));
+static int ifs_fmount(mf)
+mntfs *mf;
+{
+       am_node *mp = find_mf(mf);
+       if (mp)
+               return ifs_mount(mp);
+       return ifs_inherit(mf) ? 0 : EINVAL;
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
-static int ifs_umount(mp)
-am_node *mp;
+static int ifs_fumount P((mntfs *mf));
+static int ifs_fumount(mf)
+mntfs *mf;
 {
        /*
         * Always succeed
 {
        /*
         * Always succeed
@@ -126,7 +153,9 @@ am_ops ifs_ops = {
        ifs_match,
        ifs_init,
        ifs_mount,
        ifs_match,
        ifs_init,
        ifs_mount,
-       ifs_umount,
+       ifs_fmount,
+       auto_fumount,
+       ifs_fumount,
        efs_lookuppn,
        efs_readdir,
        0, /* ifs_readlink */
        efs_lookuppn,
        efs_readdir,
        0, /* ifs_readlink */
index 1c16ebe..ff74326 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: info_file.c,v 5.2 90/06/23 22:19:29 jsp Rel $
+ * $Id: info_file.c,v 5.2.1.2 91/03/03 20:39:34 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)info_file.c 5.1 (Berkeley) %G%
+ *     @(#)info_file.c 5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -26,6 +26,7 @@
 
 #define        MAX_LINE_LEN    2048
 
 
 #define        MAX_LINE_LEN    2048
 
+static int read_line P((char *buf, int size, FILE *fp));
 static int read_line(buf, size, fp)
 char *buf;
 int size;
 static int read_line(buf, size, fp)
 char *buf;
 int size;
@@ -61,6 +62,7 @@ FILE *fp;
 /*
  * Try to locate a key in a file
  */
 /*
  * Try to locate a key in a file
  */
+static int search_or_reload_file P((FILE *fp, char *map, char *key, char **val, mnt_map *m, void (*fn)(mnt_map *m, char*, char*)));
 static int search_or_reload_file(fp, map, key, val, m, fn)
 FILE *fp;
 char *map;
 static int search_or_reload_file(fp, map, key, val, m, fn)
 FILE *fp;
 char *map;
@@ -121,7 +123,7 @@ void (*fn) P((mnt_map*, char*, char*));
                if (*cp)
                        *cp++ = '\0';
 
                if (*cp)
                        *cp++ = '\0';
 
-               if ((*key == *kp && strcmp(key, kp) == 0) || fn) {
+               if (fn || (*key == *kp && strcmp(key, kp) == 0)) {
                        while (*cp && isascii(*cp) && isspace(*cp))
                                cp++;
                        if (*cp) {
                        while (*cp && isascii(*cp) && isspace(*cp))
                                cp++;
                        if (*cp) {
@@ -129,13 +131,14 @@ void (*fn) P((mnt_map*, char*, char*));
                                 * Return a copy of the data
                                 */
                                char *dc = strdup(cp);
                                 * Return a copy of the data
                                 */
                                char *dc = strdup(cp);
-                               if (fn)
-                                       (*fn)(m, kp, dc);
-                               else
+                               if (fn) {
+                                       (*fn)(m, strdup(kp), dc);
+                               } else {
                                        *val = dc;
 #ifdef DEBUG
                                        *val = dc;
 #ifdef DEBUG
-                               dlog("%s returns %s", key, dc);
+                                       dlog("%s returns %s", key, dc);
 #endif /* DEBUG */
 #endif /* DEBUG */
+                               }
                                if (!fn)
                                        return 0;
                        } else {
                                if (!fn)
                                        return 0;
                        } else {
@@ -159,10 +162,28 @@ again:
        return fn ? 0 : ENOENT;
 }
 
        return fn ? 0 : ENOENT;
 }
 
-int file_init(map)
+static FILE *file_open P((char *map, time_t *tp));
+static FILE *file_open(map, tp)
 char *map;
 char *map;
+time_t *tp;
 {
        FILE *mapf = fopen(map, "r");
 {
        FILE *mapf = fopen(map, "r");
+       if (mapf && tp) {
+               struct stat stb;
+               if (fstat(fileno(mapf), &stb) < 0)
+                       *tp = clocktime();
+               else
+                       *tp = stb.st_mtime;
+       }
+       return mapf;
+}
+
+int file_init P((char *map, time_t *tp));
+int file_init(map, tp)
+char *map;
+time_t *tp;
+{
+       FILE *mapf = file_open(map, tp);
        if (mapf) {
                (void) fclose(mapf);
                return 0;
        if (mapf) {
                (void) fclose(mapf);
                return 0;
@@ -170,12 +191,13 @@ char *map;
        return errno;
 }
 
        return errno;
 }
 
+int file_reload P((mnt_map *m, char *map, void (*fn)()));
 int file_reload(m, map, fn)
 mnt_map *m;
 char *map;
 void (*fn)();
 {
 int file_reload(m, map, fn)
 mnt_map *m;
 char *map;
 void (*fn)();
 {
-       FILE *mapf = fopen(map, "r");
+       FILE *mapf = file_open(map, (time_t *) 0);
        if (mapf) {
                int error = search_or_reload_file(mapf, map, 0, 0, m, fn);
                (void) fclose(mapf);
        if (mapf) {
                int error = search_or_reload_file(mapf, map, 0, 0, m, fn);
                (void) fclose(mapf);
@@ -185,6 +207,7 @@ void (*fn)();
        return errno;
 }
 
        return errno;
 }
 
+int file_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp));
 int file_search(m, map, key, pval, tp)
 mnt_map *m;
 char *map;
 int file_search(m, map, key, pval, tp)
 mnt_map *m;
 char *map;
@@ -192,13 +215,12 @@ char *key;
 char **pval;
 time_t *tp;
 {
 char **pval;
 time_t *tp;
 {
-       FILE *mapf = fopen(map, "r");
+       time_t t;
+       FILE *mapf = file_open(map, &t);
        if (mapf) {
        if (mapf) {
-               struct stat stb;
                int error;
                int error;
-               error = fstat(fileno(mapf), &stb);
-               if (!error && *tp < stb.st_mtime) {
-                       *tp = stb.st_mtime;
+               if (*tp < t) {
+                       *tp = t;
                        error = -1;
                } else {
                        error = search_or_reload_file(mapf, map, key, pval, 0, 0);
                        error = -1;
                } else {
                        error = search_or_reload_file(mapf, map, key, pval, 0, 0);
@@ -209,4 +231,18 @@ time_t *tp;
 
        return errno;
 }
 
        return errno;
 }
+
+int file_mtime P((char *map, time_t *tp));
+int file_mtime(map, tp)
+char *map;
+time_t *tp;
+{
+       FILE *mapf = file_open(map, tp);
+       if (mapf) {
+               (void) fclose(mapf);
+               return 0;
+       }
+
+       return errno;
+}
 #endif /* HAS_FILE_MAPS */
 #endif /* HAS_FILE_MAPS */
index 6cb1e58..8d68be4 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: info_hes.c,v 5.2 90/06/23 22:19:30 jsp Rel $
+ * $Id: info_hes.c,v 5.2.1.3 91/03/03 20:39:41 jsp Alpha $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)info_hes.c  5.1 (Berkeley) %G%
+ *     @(#)info_hes.c  5.2 (Berkeley) %G%
  */
 
 /*
  * Get info from Hesiod
  */
 
 /*
  * Get info from Hesiod
+ *
+ * Zone transfer code from Bruce Cole <cole@cs.wisc.edu>
  */
 
 #include "am.h"
  */
 
 #include "am.h"
 #define        HES_PREFIX      "hesiod."
 #define        HES_PREFLEN     7
 
 #define        HES_PREFIX      "hesiod."
 #define        HES_PREFLEN     7
 
+#ifdef HAS_HESIOD_RELOAD
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <sys/uio.h>
+#include <netdb.h>
+
+/*
+ * Patch up broken system include files
+ */
+#ifndef C_HS
+#define C_HS   4
+#endif
+#ifndef T_TXT
+#define        T_TXT   16
+#endif
+
+static int soacnt;
+static struct timeval hs_timeout;
+static int servernum;
+#endif /* HAS_HESIOD_RELOAD */
+
 /*
 /*
- * No way to probe the server - check the map name begins with "hesiod."
+ * No easy way to probe the server - check the map name begins with "hesiod."
  */
  */
-hesiod_init(map)
+int hesiod_init P((char *map, time_t *tp));
+int hesiod_init(map, tp)
 char *map;
 char *map;
+time_t *tp;
 {
 {
+#ifdef DEBUG
+       dlog("hesiod_init(%s)", map);
+#endif
+       *tp = 0;
        return strncmp(map, HES_PREFIX, HES_PREFLEN) == 0 ? 0 : ENOENT;
 }
 
 
        return strncmp(map, HES_PREFIX, HES_PREFLEN) == 0 ? 0 : ENOENT;
 }
 
 
+/*
+ * Make Hesiod name.  Skip past the "hesiod."
+ * at the start of the map name and append
+ * ".automount".  The net effect is that a lookup
+ * of /defaults in hesiod.home will result in a
+ * call to hes_resolve("/defaults", "home.automount");
+ */
+#define MAKE_HES_NAME(dest, src) sprintf(dest, "%s%s", src + HES_PREFLEN, ".automount")
+
 /*
  * Do a Hesiod nameserver call.
  * Modify time is ignored by Hesiod - XXX
  */
 /*
  * Do a Hesiod nameserver call.
  * Modify time is ignored by Hesiod - XXX
  */
+int hesiod_search P((mnt_map *m, char *map, char **pval, time_t *tp));
 int hesiod_search(m, map, key, pval, tp)
 mnt_map *m;
 char *map;
 int hesiod_search(m, map, key, pval, tp)
 mnt_map *m;
 char *map;
@@ -50,17 +89,21 @@ time_t *tp;
        int error;
        char hes_map[MAXPATHLEN];
        char **rvec;
        int error;
        char hes_map[MAXPATHLEN];
        char **rvec;
-       /*
-        * Make Hesiod name.  Skip past the "hesiod."
-        * at the start of the map name and append
-        * ".automount".  The net effect is that a lookup
-        * of /defaults in hesiod.home will result in a
-        * call to hes_resolve("/defaults", "home.automount");
-        */
-       sprintf(hes_map, "%s%s", map + HES_PREFLEN, ".automount");
+#ifdef DEBUG
+       dlog("hesiod_search(m=%x, map=%s, key=%s, pval=%x tp=%x)", m, map, key, pval, tp);
+#endif
+       MAKE_HES_NAME(hes_map, map);
+
        /*
         * Call the resolver
         */
        /*
         * Call the resolver
         */
+#ifdef DEBUG
+       dlog("hesiod_search: hes_resolve(%s, %s)", key, hes_map);
+#ifdef HAS_HESIOD_RELOAD
+       if (debug_flags & D_FULL)
+               _res.options |= RES_DEBUG;
+#endif
+#endif
        rvec = hes_resolve(key, hes_map);
        /*
         * If a reply was forthcoming then return
        rvec = hes_resolve(key, hes_map);
        /*
         * If a reply was forthcoming then return
@@ -76,12 +119,551 @@ time_t *tp;
        /*
         * Otherwise reflect the hesiod error into a Un*x error
         */
        /*
         * Otherwise reflect the hesiod error into a Un*x error
         */
+#ifdef DEBUG
+       dlog("hesiod_search: Error: %d", hes_error());
+#endif
        switch (hes_error()) {
        case HES_ER_NOTFOUND:   error = ENOENT; break;
        case HES_ER_CONFIG:     error = EIO; break;
        case HES_ER_NET:        error = ETIMEDOUT; break;
        default:                error = EINVAL; break;
        }
        switch (hes_error()) {
        case HES_ER_NOTFOUND:   error = ENOENT; break;
        case HES_ER_CONFIG:     error = EIO; break;
        case HES_ER_NET:        error = ETIMEDOUT; break;
        default:                error = EINVAL; break;
        }
+#ifdef DEBUG
+       dlog("hesiod_search: Returning: %d", error);
+#endif
        return error;
 }
        return error;
 }
+
+#ifdef HAS_HESIOD_RELOAD
+/*
+ * Zone transfer...
+ */
+
+#define MAXHSNS 8
+#define MAX_NSADDR 16
+
+static char *hs_domain;
+static mnt_map *hs_map;
+static int hs_nscount;
+static char nsaddr_list[MAX_NSADDR][sizeof(struct in_addr)];
+
+int hesiod_reload P((mnt_map *m, char *map, void (*fn)()));
+int hesiod_reload(m, map, fn)
+mnt_map *m;
+char *map;
+void (*fn)();
+{
+       char hes_map[MAXPATHLEN];
+       char *zone_name, *cp;
+       short domainlen;
+       int status;
+
+#ifdef DEBUG
+       dlog("hesiod_reload (%x %s %x)", m, map, fn);
+#endif DEBUG
+       if (status = res_init()) {
+#ifdef DEBUG
+               dlog("hesiod_reload: res_init failed with %d", status);
+#endif
+               return(status);
+       }
+       _res.retrans = 90;
+       hs_map = m;
+       domainlen = strlen(hostdomain);
+       MAKE_HES_NAME(hes_map, map);
+       zone_name = hes_to_bind("", hes_map);
+       if (*zone_name == '.')
+               zone_name++;
+       hs_domain = zone_name;
+       /* Traverse the DNS tree until we find an SOA we can transfer from.
+        (Our initial zone_name is likely to just be a subtree of a
+        real zone). */
+       do {
+               /* If we can't find any NS records, go up a level in the
+                  DNS tree */
+               if (hs_get_ns_list(zone_name) == 0 &&
+                   hs_zone_transfer(zone_name) == 0)
+                       return(0);
+               /* Move up DNS tree by one component */
+               if (cp = strchr(zone_name, '.'))
+                       zone_name = ++cp;
+               else
+                       break;
+       } while (strlen(zone_name) >= domainlen);
+#ifdef DEBUG
+       dlog("hesiod_reload: Giving up on %s", hs_domain);
+#endif
+       return(-1);
+}
+
+hs_zone_transfer(domain)
+char *domain;
+{
+       int status, len;
+       char buf[PACKETSZ];
+       /* Want to make sure ansbuf is well alligned */
+       long ansbuf[PACKETSZ/sizeof(long)];
+
+#ifdef DEBUG
+       dlog("hs_zone_transfer (%s)", domain);
+#endif
+       if ((len = res_mkquery(QUERY, domain, C_HS, T_AXFR,
+                              (char *)NULL, 0, NULL, buf, PACKETSZ)) == -1) {
+#ifdef DEBUG
+               dlog("hs_zone_transfer: res_mkquery failed");
+#endif
+               errno = 0;
+               return(-1);
+       }
+       if ((status = hs_res_send(buf, len, (char *)ansbuf, PACKETSZ)) == -1) {
+#ifdef DEBUG
+           dlog("hs_zone_transfer: hs_res_send failed.  status %d errno %d",
+                status, errno);
+#endif
+               errno = 0;
+               return(-1);
+       }
+       return(0);
+}
+
+#define hs_server_addr(ns) ((struct in_addr *) nsaddr_list[ns])
+
+hs_res_send(buf, buflen, answer, anslen)
+char *buf;
+int buflen;
+char *answer;
+int anslen;
+{
+       int retry, ns;
+       u_short id, len;
+       HEADER *hp = (HEADER *) buf;
+       struct iovec iov[2];
+       static int s = -1;
+       int status;
+       struct sockaddr_in server;
+
+       soacnt = 0;
+       id = hp->id;
+       /*
+        * Send request, RETRY times, or until successful
+        */
+       for (retry = _res.retry; retry > 0; retry--) {
+               for (ns = 0; ns < hs_nscount; ns++) {
+                       hs_timeout.tv_sec =
+                               (_res.retrans << (_res.retry - retry))
+                               / hs_nscount;
+                       if (hs_timeout.tv_sec <= 0)
+                               hs_timeout.tv_sec = 1;
+                       hs_timeout.tv_usec = 0;
+                       if (s < 0) {
+                               s = socket(AF_INET, SOCK_STREAM, 0);
+                               if (s < 0) {
+                                       continue;
+                               }
+                               servernum = ns;
+                               bcopy(hs_server_addr(ns), &server.sin_addr,
+                                     sizeof(struct in_addr));
+                               server.sin_family = AF_INET;
+                               server.sin_port = htons(NAMESERVER_PORT);
+                                       
+                               if (connect(s, &server,
+                                           sizeof(struct sockaddr)) < 0) {
+                                       (void) close(s);
+                                       s = -1;
+                                       continue;
+                               }
+                       }
+                       /*
+                        * Send length & message
+                        */
+                       len = htons((u_short)buflen);
+                       iov[0].iov_base = (caddr_t)&len;
+                       iov[0].iov_len = sizeof(len);
+                       iov[1].iov_base = buf;
+                       iov[1].iov_len = buflen;
+                       if (writev(s, iov, 2) != sizeof(len) + buflen) {
+                               (void) close(s);
+                               s = -1;
+                               continue;
+                       }
+                       status = 0;
+                       while (s != -1 && soacnt < 2 && status != -2) {
+                               if ((status =
+                                    hs_readresp(s, answer, anslen)) == -1) {
+                                       (void) close(s);
+                                       s = -1;
+                                       continue;
+                               }
+                       }
+                       if (status == -2) {
+                               /* There was a permanent error transfering this
+                                  zone.  Give up. */
+                               if (s != -1) {
+                                       (void) close(s);
+                                       s = -1;
+                               }
+                               return(-1);
+                       }
+                       if (s == -1)
+                               continue;
+                       return (0);
+               }
+       }
+       if (errno == 0)
+               errno = ETIMEDOUT;
+       return (-1);
+}
+
+/* Returns:
+   0: Success
+   -1: Error
+   -2: Permanent failure
+*/
+hs_readresp(s, answer, anslen)
+int s;
+char *answer;
+int anslen;
+{
+       register int len, n;
+       char *cp;
+
+       cp = answer;
+       len = sizeof(short);
+       while (len != 0 &&
+              (n = hs_res_vcread(s, (char *)cp, (int)len, &hs_timeout)) > 0) {
+               cp += n;
+               len -= n;
+       }
+       if (n <= 0)
+               return(-1);
+       cp = answer;
+       if ((len = _getshort(cp)) > anslen) {
+#ifdef DEBUG
+               dlog("hs_readresp: response too long: %d", len);
+#endif
+               return(-1);
+       }
+       while (len != 0 &&
+              (n = hs_res_vcread(s, (char *)cp, (int)len, &hs_timeout)) > 0) {
+               cp += n;
+               len -= n;
+       }
+       if (n <= 0)
+               return(-1);
+       return(hs_parse(answer, answer+PACKETSZ));
+}
+
+hs_res_vcread(sock, buf, buflen, timeout)
+int sock, buflen;
+char *buf;
+struct timeval *timeout;
+{
+       register int n;
+
+       if ((n = hs_res_selwait(sock, timeout)) > 0)
+               return(read(sock, buf, buflen));
+       else
+               return(n);
+}
+
+hs_res_selwait(sock, timeout)
+int sock;
+struct timeval *timeout;
+{
+       fd_set dsmask;
+       register int n;
+
+       /*
+        * Wait for reply
+        */
+       FD_ZERO(&dsmask);
+       FD_SET(sock, &dsmask);
+       n = select(sock+1, &dsmask, (fd_set *)NULL,
+                  (fd_set *)NULL, timeout);
+       return(n);
+}
+
+/* Returns:
+   0: Success
+   -1: Error
+   -2: Permanent failure
+*/
+hs_parse(msg, eom)
+char *msg, *eom;
+{
+       register char *cp;
+       register HEADER *hp;
+       register int n, len;
+       int qdcount, ancount;
+       char key[PACKETSZ];
+       char *key_cpy, *value, *hs_make_value();
+       short type;
+
+       hp = (HEADER *)msg;
+       if (hp->rcode != NOERROR || hp->opcode != QUERY) {
+               char dq[20];
+#ifdef DEBUG
+               dlog("Bad response (%d) from nameserver %s", hp->rcode, inet_dquad(dq, hs_server_addr(servernum)->s_addr));
+#endif DEBUG
+               return(-1);
+       }
+       cp = msg + sizeof(HEADER);
+       ancount = ntohs(hp->ancount);
+       qdcount = ntohs(hp->qdcount);
+       while (qdcount-- > 0)
+               cp += dn_skipname(cp, eom) + QFIXEDSZ;
+       if (soacnt == 0 && ancount == 0) {
+               /* XXX We should look for NS records to find SOA */
+#ifdef DEBUG
+               dlog("No SOA found");
+#endif
+               return(-2);
+       }
+       while (ancount-- > 0 && cp < eom) {
+               if ((n = dn_expand(msg, eom, cp, key, PACKETSZ)) < 0)
+                       break;
+               cp += n;
+               if ((type = _getshort(cp)) == T_SOA) {
+                       soacnt++;
+               }
+               cp += 2*sizeof(u_short) + sizeof(u_long);
+               len = _getshort(cp);
+               cp += sizeof(u_short);
+               /* Check to see if key is in our domain */
+               if (type == T_TXT && hs_strip_our_domain(key)) {
+                       value = hs_make_value(cp, len);
+                       if (value == NULL)
+                               return(-1);
+                       key_cpy = strdup(key);
+#ifdef DEBUG
+                       dlog("hs_parse: Parsed key: %s, value: %s", key,
+                            value);
+#endif
+                       mapc_add_kv(hs_map, key_cpy, value);
+               }
+               cp += len;
+               errno = 0;
+       }
+       return(0);
+}
+
+/* Check to see if the domain name in the supplied argument matches
+   hs_domain.  Strip hs_domain from supplied argument if so. */
+hs_strip_our_domain(name)
+char *name;
+{
+       char *end_pos;
+       short targ_len, cur_len;
+       
+       targ_len = strlen(hs_domain);
+       cur_len = strlen(name);
+       if (cur_len <= targ_len)
+               return(0);
+       end_pos = &name[cur_len - targ_len];
+       if (strcmp(end_pos, hs_domain) != 0)
+               return(0);
+       if (*--end_pos != '.')
+               return(0);
+       *end_pos = '\0';
+       return(1);
+}
+
+#define MAXDATA 8*1024
+
+char *
+hs_make_value(cp, len)
+char *cp;
+int len;
+{
+       char *value, *cpcpy, *valuep;
+       int cnt, nextcnt, totalcnt, lencpy;
+#ifdef DEBUG
+       char *dbgname;
+
+       dbgname = &cp[1];
+#endif DEBUG
+
+       lencpy = len;
+       cpcpy = cp;
+       totalcnt = 0;
+       cnt = *cpcpy++;
+       while (cnt) {
+               totalcnt += cnt;
+               lencpy -= cnt+1;
+               if (lencpy == 0)
+                       break;
+               nextcnt = cpcpy[cnt];
+               cpcpy = &cpcpy[cnt+1];
+               cnt = nextcnt;
+       }
+       if (totalcnt < 1 || totalcnt > MAXDATA || totalcnt > len) {
+#ifdef DEBUG
+               dlog("TXT RR not of expected length (%d %d): %s", totalcnt,
+                    len, dbgname);
+#endif DEBUG
+               return(NULL);
+       }
+       /* Allocate null terminated string */
+       value = (char *) xmalloc(totalcnt+1);
+       value[totalcnt] = '\0';
+       cnt = *cp++;
+       valuep = value;
+       while (cnt) {
+               bcopy(cp, valuep, cnt);
+               len -= cnt+1;
+               if (len == 0)
+                       break;
+               valuep = &valuep[cnt];
+               nextcnt = cp[cnt];
+               cp = &cp[cnt+1];
+               cnt = nextcnt;
+       }
+       return(value);
+}
+
+hs_make_ns_query(domain, ansbuf)
+char *domain;
+char *ansbuf;
+{
+       int status, len;
+       char buf[PACKETSZ];
+
+       if ((len = res_mkquery(QUERY, domain, C_HS, T_NS,
+                              (char *)NULL, 0, NULL, buf, PACKETSZ)) == -1) {
+#ifdef DEBUG
+               dlog("hs_get_ns_list: res_mkquery failed");
+#endif
+               errno = 0;
+               return(-1);
+       }
+       if ((status = res_send(buf, len, (char *)ansbuf, PACKETSZ)) == -1) {
+#ifdef DEBUG
+           dlog("hs_get_ns_list: res_send failed.  status %d errno %d",
+                status, errno);
+#endif
+               errno = 0;
+               return(-1);
+       }
+       return(0);
+}
+
+static void
+add_address(addr)
+struct in_addr *addr;
+{
+       char dq[20];
+       bcopy((char *)addr, nsaddr_list[hs_nscount++], sizeof(struct in_addr));
+#ifdef DEBUG
+       dlog("Adding NS address %s", inet_dquad(dq, addr->s_addr));
+#endif DEBUG
+}
+
+hs_get_ns_list(domain)
+char *domain;
+{
+       register HEADER *hp;
+       int qdcount, nscount;
+       register char *cp;
+       register int n, len;
+       char key[PACKETSZ], name[PACKETSZ], msg[PACKETSZ], *eom;
+       register long **hptr;
+       struct hostent *ghp;
+       int numns;
+       char nsname[MAXHSNS][MAXDATA];
+       int nshaveaddr[MAXHSNS], i;
+       short type;
+
+       if (hs_make_ns_query(domain, msg) == -1)
+               return(-1);
+       numns = hs_nscount = 0;
+       eom = &msg[PACKETSZ];
+       bzero(nsname, sizeof(nsname));
+       hp = (HEADER *)msg;
+       if (hp->rcode != NOERROR || hp->opcode != QUERY) {
+#ifdef DEBUG
+               dlog("Bad response (%d) from nameserver %#x", hp->rcode,
+                     hs_server_addr(servernum)->s_addr);
+#endif DEBUG
+               return(-1);
+       }
+       cp = msg + sizeof(HEADER);
+       qdcount = ntohs(hp->qdcount);
+       while (qdcount-- > 0)
+               cp += dn_skipname(cp, eom) + QFIXEDSZ;
+       nscount = ntohs(hp->ancount) + ntohs(hp->nscount) + ntohs(hp->arcount);
+#ifdef DEBUG
+       dlog("hs_get_ns_list: Processing %d response records", nscount);
+#endif
+       for (;nscount; nscount--) {
+               if ((n = dn_expand(msg, eom, cp, key, PACKETSZ)) < 0)
+                       break;
+               cp += n;
+               type = _getshort(cp);
+               cp += 2*sizeof(u_short) + sizeof(u_long);
+               len = _getshort(cp);
+               cp += sizeof(u_short);
+#ifdef DEBUG
+               dlog("hs_get_ns_list: Record type: %d", type);
+#endif
+               switch (type) {
+               case T_NS:
+                       if (numns >= MAXHSNS || strcasecmp(domain, key) != 0)
+                               break;
+                       if ((n = dn_expand(msg, eom, cp, name, PACKETSZ)) < 0)
+                               break;
+#ifdef DEBUG
+                       dlog("hs_get_ns_list: NS name: %s", name);
+#endif
+                       for (i = 0; i < numns; i++)
+                               if (strcasecmp(nsname[i], name) == 0)
+                                       break;
+                       if (i == numns) {
+#ifdef DEBUG
+                               dlog("hs_get_ns_list: Saving name %s", name);
+#endif
+                               strncpy(nsname[numns], name, MAXDATA);
+                               nshaveaddr[numns] = 0;
+                               numns++;
+                       }
+                       break;
+               case T_A:
+                       if (hs_nscount == MAX_NSADDR)
+                               break;
+                       for (i = 0; i < numns; i++) {
+                               if (strcasecmp(nsname[i], domain) == 0) {
+                                       nshaveaddr[i]++;
+                                       add_address((struct in_addr *) cp);
+                                       break;
+                               }
+                       }
+                       break;
+               default:
+                       break;
+               }
+               if (hs_nscount == MAX_NSADDR)
+                       break;
+               cp += len;
+               errno = 0;
+       }
+#ifdef  DEBUG
+       dlog("hs_get_ns_list: Found %d NS records", numns);
+#endif
+       for (i = 0; i < numns; i++) {
+               if (nshaveaddr[i])
+                       continue;
+               if ((ghp = gethostbyname(nsname[i])) == 0)
+                       continue;
+               for (hptr = (long **)ghp->h_addr_list;
+                    *hptr && hs_nscount < MAX_NSADDR; hptr++) {
+                       add_address((struct in_addr *) *hptr);
+               }
+       }
+       if (hs_nscount)
+               return(0);
+#ifdef DEBUG
+       dlog("No NS records found for %s", domain);
+       return(-1);
+#endif DEBUG
+}
+#endif /* HAS_HESIOD_RELOAD */
 #endif /* HAS_HESIOD_MAPS */
 #endif /* HAS_HESIOD_MAPS */
index 2566380..0a0686e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: info_ndbm.c,v 5.2 90/06/23 22:19:31 jsp Rel $
+ * $Id: info_ndbm.c,v 5.2.1.2 91/03/03 20:39:40 jsp Alpha $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)info_ndbm.c 5.1 (Berkeley) %G%
+ *     @(#)info_ndbm.c 5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -26,6 +26,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 
 #include <fcntl.h>
 #include <sys/stat.h>
 
+static int search_ndbm P((DBM *db, char *key, char **val));
 static int search_ndbm(db, key, val)
 DBM *db;
 char *key;
 static int search_ndbm(db, key, val)
 DBM *db;
 char *key;
@@ -42,6 +43,7 @@ char **val;
        return ENOENT;
 }
 
        return ENOENT;
 }
 
+int ndbm_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp));
 int ndbm_search(m, map, key, pval, tp)
 mnt_map *m;
 char *map;
 int ndbm_search(m, map, key, pval, tp)
 mnt_map *m;
 char *map;
@@ -69,13 +71,21 @@ time_t *tp;
        return errno;
 }
 
        return errno;
 }
 
-int ndbm_init(map)
+int ndbm_init P((char *map, time_t *tp));
+int ndbm_init(map, tp)
 char *map;
 char *map;
+time_t *tp;
 {
        DBM *db;
 
        db = dbm_open(map, O_RDONLY, 0);
        if (db) {
 {
        DBM *db;
 
        db = dbm_open(map, O_RDONLY, 0);
        if (db) {
+               struct stat stb;
+
+               if (fstat(dbm_pagfno(db), &stb) < 0)
+                       *tp = clocktime();
+               else
+                       *tp = stb.st_mtime;
                dbm_close(db);
                return 0;
        }
                dbm_close(db);
                return 0;
        }
index e86328d..6cfef9e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: info_nis.c,v 5.2 90/06/23 22:19:32 jsp Rel $
+ * $Id: info_nis.c,v 5.2.1.3 91/03/17 17:47:31 jsp Alpha $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)info_nis.c  5.1 (Berkeley) %G%
+ *     @(#)info_nis.c  5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
  */
 static int determine_nis_domain(P_void)
 {
  */
 static int determine_nis_domain(P_void)
 {
-static  char default_domain[YPMAXDOMAIN];
+       char default_domain[YPMAXDOMAIN];
 
        if (getdomainname(default_domain, sizeof(default_domain)) < 0) {
                plog(XLOG_ERROR, "getdomainname: %m");
                return EIO;
        }
 
 
        if (getdomainname(default_domain, sizeof(default_domain)) < 0) {
                plog(XLOG_ERROR, "getdomainname: %m");
                return EIO;
        }
 
-       domain = default_domain;
-       if (!*domain) {
-               plog(XLOG_ERROR, "YP domain name is not set");
+       if (!*default_domain) {
+               plog(XLOG_ERROR, "NIS domain name is not set");
                return ENOENT;
        }
                return ENOENT;
        }
+       domain = strdup(default_domain);
 
        return 0;
 }
 
 
        return 0;
 }
 
+
+#ifdef HAS_NIS_RELOAD
+struct nis_callback_data {
+       mnt_map *ncd_m;
+       char *ncd_map;
+       void (*ncd_fn)();
+};
+
+/*
+ * Callback from yp_all
+ */
+static int callback(status, key, kl, val, vl, data)
+int status;
+char *key;
+int kl;
+char *val;
+int vl;
+struct nis_callback_data *data;
+{
+       if (status == YP_TRUE) {
+               /*
+                * Add to list of maps
+                */
+               char *kp = strnsave(key, kl);
+               char *vp = strnsave(val, vl);
+               (*data->ncd_fn)(data->ncd_m, kp, vp);
+
+               /*
+                * We want more ...
+                */
+               return FALSE;
+       } else {
+               /*
+                * NOMORE means end of map - otherwise log error
+                */
+               if (status != YP_NOMORE) {
+                       /*
+                        * Check what went wrong
+                        */
+                       int e = ypprot_err(status);
+
+#ifdef DEBUG
+                       plog(XLOG_ERROR, "yp enumeration of %s: %s, status=%d, e=%d",
+                                       data->ncd_map, yperr_string(e), status, e);
+#else
+                       plog(XLOG_ERROR, "yp enumeration of %s: %s", data->ncd_map, yperr_string(e));
+#endif
+               }
+
+               return TRUE;
+       }
+}
+
+int nis_reload P((mnt_map *m, char *map, void (*fn)()));
+int nis_reload(m, map, fn)
+mnt_map *m;
+char *map;
+void (*fn)();
+{
+       struct ypall_callback cbinfo;
+       int error;
+       struct nis_callback_data data;
+
+       if (!domain) {
+               error = determine_nis_domain();
+               if (error)
+                       return error;
+       }
+
+       data.ncd_m = m;
+       data.ncd_map = map;
+       data.ncd_fn = fn;
+       cbinfo.data = (voidp) &data;
+       cbinfo.foreach = callback;
+
+       error = yp_all(domain, map, &cbinfo);
+
+       if (error)
+               plog(XLOG_ERROR, "error grabbing nis map of %s: %s", map, yperr_string(ypprot_err(error)));
+
+       return error;
+}
+#endif /* HAS_NIS_RELOAD */
+
 /*
  * Try to locate a key using NIS.
 /*
  * Try to locate a key using NIS.
- * Modify time is ignored in NIS - XXX
  */
 int nis_search P((mnt_map *m, char *map, char *key, char **val, time_t *tp));
 int nis_search(m, map, key, val, tp)
  */
 int nis_search P((mnt_map *m, char *map, char *key, char **val, time_t *tp));
 int nis_search(m, map, key, val, tp)
@@ -59,13 +142,30 @@ time_t *tp;
 {
        int outlen;
        int res;
 {
        int outlen;
        int res;
+       int order;
 
 
+       /*
+        * Make sure domain initialised
+        */
        if (!domain) {
                int error = determine_nis_domain();
                if (error)
                        return error;
        }
 
        if (!domain) {
                int error = determine_nis_domain();
                if (error)
                        return error;
        }
 
+       /*
+        * Check if map has changed
+        */
+       if (yp_order(domain, map, &order))
+               return EIO;
+       if ((time_t) order > *tp) {
+               *tp = (time_t) order;
+               return -1;
+       }
+
+       /*
+        * Lookup key
+        */
        res = yp_match(domain, map, key, strlen(key), val, &outlen);
 
        /*
        res = yp_match(domain, map, key, strlen(key), val, &outlen);
 
        /*
@@ -84,11 +184,12 @@ time_t *tp;
        }
 }
 
        }
 }
 
-int nis_init P((char *map));
-int nis_init(map)
+int nis_init P((char *map, time_t *tp));
+int nis_init(map, tp)
 char *map;
 char *map;
+time_t *tp;
 {
 {
-       char *name = 0;
+       int order;
 
        if (!domain) {
                int error = determine_nis_domain();
 
        if (!domain) {
                int error = determine_nis_domain();
@@ -100,9 +201,12 @@ char *map;
         * To see if the map exists, try to find
         * a master for it.
         */
         * To see if the map exists, try to find
         * a master for it.
         */
-       if (yp_master(domain, map, &name))
+       if (yp_order(domain, map, &order))
                return ENOENT;
                return ENOENT;
-       free(name);
+       *tp = (time_t) order;
+#ifdef DEBUG
+       dlog("NIS master for %s@%s has order %d", map, domain, order);
+#endif
        return 0;
 }
 #endif /* HAS_NIS_MAPS */
        return 0;
 }
 #endif /* HAS_NIS_MAPS */
index 49617a1..a3f5e87 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: info_passwd.c,v 5.2 90/06/23 22:19:34 jsp Rel $
+ * $Id: info_passwd.c,v 5.2.1.2 91/03/03 20:39:38 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)info_passwd.c       5.1 (Berkeley) %G%
+ *     @(#)info_passwd.c       5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
 /*
  * Nothing to probe - check the map name is PASSWD_MAP.
  */
 /*
  * Nothing to probe - check the map name is PASSWD_MAP.
  */
-passwd_init(map)
+int passwd_init P((char *map, time_t *tp));
+int passwd_init(map, tp)
 char *map;
 char *map;
+time_t *tp;
 {
 {
+       *tp = 0;
        return strcmp(map, PASSWD_MAP) == 0 ? 0 : ENOENT;
 }
 
        return strcmp(map, PASSWD_MAP) == 0 ? 0 : ENOENT;
 }
 
@@ -42,6 +45,7 @@ char *map;
  * Grab the entry via the getpwname routine
  * Modify time is ignored by passwd - XXX
  */
  * Grab the entry via the getpwname routine
  * Modify time is ignored by passwd - XXX
  */
+int passwd_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp));
 int passwd_search(m, map, key, pval, tp)
 mnt_map *m;
 char *map;
 int passwd_search(m, map, key, pval, tp)
 mnt_map *m;
 char *map;
index 81f45c8..f33129d 100644 (file)
@@ -9,21 +9,9 @@
  * This code is derived from software contributed to Berkeley by
  * Jan-Simon Pendry at Imperial College, London.
  *
  * 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 are permitted provided
- * that: (1) source distributions retain this entire copyright notice and
- * comment, and (2) distributions including binaries display the following
- * acknowledgement:  ``This product includes software developed by the
- * University of California, Berkeley and its contributors'' in the
- * documentation or other materials provided with the distribution and in
- * all advertising materials mentioning features or use of this software.
- * Neither the name of the 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * %sccs.include.redist.c%
  *
  *
- *     @(#)info_union.c        5.1 (Berkeley) %G%
+ *     @(#)info_union.c        5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
index 6b20acb..1f51acc 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: map.c,v 5.2 90/06/23 22:19:35 jsp Rel $
+ * $Id: map.c,v 5.2.1.5 91/03/17 17:47:23 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)map.c       5.1 (Berkeley) %G%
+ *     @(#)map.c       5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
 static unsigned int am_gen = 2;        /* Initial generation number */
 #define new_gen() (am_gen++)
 
 static unsigned int am_gen = 2;        /* Initial generation number */
 #define new_gen() (am_gen++)
 
-struct am_node *exported_ap[NEXP_AP];
+am_node **exported_ap = (am_node **) 0;
+int exported_ap_size = 0;
 int first_free_map = 0;                /* First available free slot */
 int last_used_map = -1;                /* Last unavailable used slot */
 static int timeout_mp_id;      /* Id from last call to timeout */
 
 int first_free_map = 0;                /* First available free slot */
 int last_used_map = -1;                /* Last unavailable used slot */
 static int timeout_mp_id;      /* Id from last call to timeout */
 
+/*
+ * This is the default attributes field which
+ * is copied into every new node to be created.
+ * The individual filesystem fs_init() routines
+ * patch the copy to represent the particular
+ * details for the relevant filesystem type
+ */
+static struct fattr gen_fattr = {
+       NFLNK,                          /* type */
+       NFSMODE_LNK | 0777,             /* mode */
+       1,                              /* nlink */
+       0,                              /* uid */
+       0,                              /* gid */
+       0,                              /* size */
+       4096,                           /* blocksize */
+       0,                              /* rdev */
+       1,                              /* blocks */
+       0,                              /* fsid */
+       0,                              /* fileid */
+       { 0, 0 },                       /* atime */
+       { 0, 0 },                       /* mtime */
+       { 0, 0 },                       /* ctime */
+};
+
+/*
+ * Resize exported_ap map
+ */
+static int exported_ap_realloc_map P((int nsize));
+static int exported_ap_realloc_map(nsize)
+int nsize;
+{
+#ifdef notdef
+       /*
+        * If a second realloc occasionally causes Amd to die
+        * in then include this check.
+        */
+       if (exported_ap_size != 0)      /* XXX */
+               return 0;
+#endif
+
+       /*
+        * this shouldn't happen, but...
+        */
+       if (nsize < 0 || nsize == exported_ap_size)
+               return 0;
+
+       exported_ap = (am_node **) xrealloc((voidp) exported_ap, nsize * sizeof(am_node*));
+
+       if (nsize > exported_ap_size)
+               bzero((char*) (exported_ap+exported_ap_size),
+                       (nsize - exported_ap_size) * sizeof(am_node*));
+       exported_ap_size = nsize;
+
+       return 1;
+}
+
+       
 /*
  * The root of the mount tree.
  */
 /*
  * The root of the mount tree.
  */
-static am_node *root_node;
+am_node *root_node;
 
 /*
  * Allocate a new mount slot and create
 
 /*
  * Allocate a new mount slot and create
@@ -48,15 +106,16 @@ static am_node *root_node;
  * Fills in the map number of the node,
  * but leaves everything else uninitialised.
  */
  * Fills in the map number of the node,
  * but leaves everything else uninitialised.
  */
-struct am_node *exported_ap_alloc(P_void)
+am_node *exported_ap_alloc(P_void)
 {
 {
-       struct am_node *mp, **mpp;
+       am_node *mp, **mpp;
 
        /*
 
        /*
-        * First check if there are any slots left
+        * First check if there are any slots left, realloc if needed
         */
         */
-       if (first_free_map >= NEXP_AP)
-               return 0;
+       if (first_free_map >= exported_ap_size)
+               if (!exported_ap_realloc_map(exported_ap_size + NEXP_AP))
+                       return 0;
 
        /*
         * Grab the next free slot
 
        /*
         * Grab the next free slot
@@ -70,12 +129,18 @@ struct am_node *exported_ap_alloc(P_void)
        /*
         * Update free pointer
         */
        /*
         * Update free pointer
         */
-       while (first_free_map < NEXP_AP && exported_ap[first_free_map])
+       while (first_free_map < exported_ap_size && exported_ap[first_free_map])
                first_free_map++;
 
        if (first_free_map > last_used_map)
                last_used_map = first_free_map - 1;
 
                first_free_map++;
 
        if (first_free_map > last_used_map)
                last_used_map = first_free_map - 1;
 
+       /*
+        * Shrink exported_ap if reasonable
+        */
+       if (last_used_map < exported_ap_size - (NEXP_AP + NEXP_AP_MARGIN))
+               exported_ap_realloc_map(exported_ap_size - NEXP_AP);
+
 #ifdef DEBUG
        /*dlog("alloc_exp: last_used_map = %d, first_free_map = %d\n",
                last_used_map, first_free_map);*/
 #ifdef DEBUG
        /*dlog("alloc_exp: last_used_map = %d, first_free_map = %d\n",
                last_used_map, first_free_map);*/
@@ -87,8 +152,9 @@ struct am_node *exported_ap_alloc(P_void)
 /*
  * Free a mount slot
  */
 /*
  * Free a mount slot
  */
+void exported_ap_free P((am_node *mp));
 void exported_ap_free(mp)
 void exported_ap_free(mp)
-struct am_node *mp;
+am_node *mp;
 {
        /*
         * Sanity check
 {
        /*
         * Sanity check
@@ -119,7 +185,7 @@ struct am_node *mp;
        /*
         * Free the mount node
         */
        /*
         * Free the mount node
         */
-       free(mp);
+       free((voidp) mp);
 }
 
 /*
 }
 
 /*
@@ -186,10 +252,34 @@ am_node *mp;
        mp->am_timeo_w = 0;
 
        mp->am_ttl = clocktime();
        mp->am_timeo_w = 0;
 
        mp->am_ttl = clocktime();
-       mp->am_mnt->mf_fattr.atime.seconds = mp->am_ttl;
+       mp->am_fattr.atime.seconds = mp->am_ttl;
        mp->am_ttl += mp->am_timeo;     /* sun's -tl option */
 }
 
        mp->am_ttl += mp->am_timeo;     /* sun's -tl option */
 }
 
+void mk_fattr P((am_node *mp, ftype vntype));
+void mk_fattr(mp, vntype)
+am_node *mp;
+ftype vntype;
+{
+       switch (vntype) {
+       case NFDIR:
+               mp->am_fattr.type = NFDIR;
+               mp->am_fattr.mode = NFSMODE_DIR | 0555;
+               mp->am_fattr.nlink = 2;
+               mp->am_fattr.size = 512;
+               break;
+       case NFLNK:
+               mp->am_fattr.type = NFLNK;
+               mp->am_fattr.mode = NFSMODE_LNK | 0777;
+               mp->am_fattr.nlink = 1;
+               mp->am_fattr.size = 0;
+               break;
+       default:
+               plog(XLOG_FATAL, "Unknown fattr type %d - ignored", vntype);
+               break;
+       }
+}
+
 /*
  * Initialise an allocated mount node.
  * It is assumed that the mount node was bzero'd
 /*
  * Initialise an allocated mount node.
  * It is assumed that the mount node was bzero'd
@@ -215,8 +305,16 @@ char *dir;
        /*mp->am_pref = 0;*/
 
        mp->am_timeo = am_timeo;
        /*mp->am_pref = 0;*/
 
        mp->am_timeo = am_timeo;
+       mp->am_attr.status = NFS_OK;
+       mp->am_fattr = gen_fattr;
+       mp->am_fattr.fsid = 42;
+       mp->am_fattr.fileid = 0;
+       mp->am_fattr.atime.seconds = clocktime();
+       mp->am_fattr.atime.useconds = 0;
+       mp->am_fattr.mtime = mp->am_fattr.ctime = mp->am_fattr.atime;
+
        new_ttl(mp);
        new_ttl(mp);
-       mp->am_stats.s_mtime = mp->am_mnt->mf_fattr.atime.seconds;
+       mp->am_stats.s_mtime = mp->am_fattr.atime.seconds;
        /*mp->am_private = 0;*/
 }
 
        /*mp->am_private = 0;*/
 }
 
@@ -241,8 +339,6 @@ am_node *mp;
        if (mp->am_mnt)
                free_mntfs(mp->am_mnt);
 
        if (mp->am_mnt)
                free_mntfs(mp->am_mnt);
 
-       if (mp->am_flags & AMF_MKPATH)
-               rmdirs(mp->am_path);
        exported_ap_free(mp);
 }
 
        exported_ap_free(mp);
 }
 
@@ -271,7 +367,7 @@ int c_or_d;
         * Make sure the index is valid before
         * exported_ap is referenced.
         */
         * Make sure the index is valid before
         * exported_ap is referenced.
         */
-       if (fp->fhh_id < 0 || fp->fhh_id >= NEXP_AP)
+       if (fp->fhh_id < 0 || fp->fhh_id >= exported_ap_size)
                goto drop;
 
        /*
                goto drop;
 
        /*
@@ -301,15 +397,17 @@ int c_or_d;
                 */
                if (ap->am_mnt && FSRV_ISDOWN(ap->am_mnt->mf_server) && ap->am_parent) {
                        int error;
                 */
                if (ap->am_mnt && FSRV_ISDOWN(ap->am_mnt->mf_server) && ap->am_parent) {
                        int error;
+                       am_node *orig_ap = ap;
 #ifdef DEBUG
 #ifdef DEBUG
-                       dlog("fh_to_mp3: %s (%s) is hung:- call lookup", ap->am_path, ap->am_mnt->mf_info);
+                       dlog("fh_to_mp3: %s (%s) is hung:- call lookup",
+                                       orig_ap->am_path, orig_ap->am_mnt->mf_info);
 #endif /* DEBUG */
                        /*
 #endif /* DEBUG */
                        /*
-                        * Update last access to original node.  This
-                        * avoids timing it out and so sending ESTALE
-                        * back to the kernel.
+                        * Update modify time of parent node.
+                        * With any luck the kernel will re-stat
+                        * the child node and get new information.
                         */
                         */
-                       new_ttl(ap);
+                       orig_ap->am_fattr.mtime.seconds = clocktime();
 
                        /*
                         * Call the parent's lookup routine for an object
 
                        /*
                         * Call the parent's lookup routine for an object
@@ -319,8 +417,8 @@ int c_or_d;
                         * to the caller.
                         */
                        if (c_or_d == VLOOK_CREATE) {
                         * to the caller.
                         */
                        if (c_or_d == VLOOK_CREATE) {
-                               ap = (*ap->am_parent->am_mnt->mf_ops->lookuppn)(ap->am_parent,
-                                               ap->am_name, &error, c_or_d);
+                               ap = (*orig_ap->am_parent->am_mnt->mf_ops->lookuppn)(orig_ap->am_parent,
+                                               orig_ap->am_name, &error, c_or_d);
                        } else {
                                ap = 0;
                                error = ESTALE;
                        } else {
                                ap = 0;
                                error = ESTALE;
@@ -331,6 +429,14 @@ int c_or_d;
                                *rp = error;
                                return 0;
                        }
                                *rp = error;
                                return 0;
                        }
+                       /*
+                        * Update last access to original node.  This
+                        * avoids timing it out and so sending ESTALE
+                        * back to the kernel.
+                        * XXX - Not sure we need this anymore (jsp, 90/10/6).
+                        */
+                       new_ttl(orig_ap);
+
                }
                /*
                 * Disallow references to objects being unmounted, unless
                }
                /*
                 * Disallow references to objects being unmounted, unless
@@ -405,6 +511,7 @@ struct nfs_fh *fhp;
         */
 }
 
         */
 }
 
+static am_node *find_ap2 P((char *dir, am_node *mp));
 static am_node *find_ap2(dir, mp)
 char *dir;
 am_node *mp;
 static am_node *find_ap2(dir, mp)
 char *dir;
 am_node *mp;
@@ -433,6 +540,7 @@ am_node *mp;
  * automount path or, if the node is
  * mounted, the mount location.
  */
  * automount path or, if the node is
  * mounted, the mount location.
  */
+am_node *find_ap P((char *dir));
 am_node *find_ap(dir)
 char *dir;
 {
 am_node *find_ap(dir)
 char *dir;
 {
@@ -450,6 +558,24 @@ char *dir;
        return 0;
 }
 
        return 0;
 }
 
+/*
+ * Find the mount node corresponding
+ * to the mntfs structure.
+ */
+am_node *find_mf P((mntfs *mf));
+am_node *find_mf(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
 /*
  * Get the filehandle for a particular named directory.
  * This is used during the bootstrap to tell the kernel
@@ -462,6 +588,16 @@ char *dir;
        am_node *mp = root_ap(dir, TRUE);
        if (mp) {
                mp_to_fh(mp, &nfh);
        am_node *mp = root_ap(dir, TRUE);
        if (mp) {
                mp_to_fh(mp, &nfh);
+               /*
+                * Patch up PID to match main server...
+                */
+               if (!foreground) {
+                       long pid = getppid();
+                       ((struct am_fh *) &nfh)->fhh_pid = pid;
+#ifdef DEBUG
+                       dlog("root_fh substitutes pid %d", pid);
+#endif
+               }
                return &nfh;
        }
 
                return &nfh;
        }
 
@@ -487,49 +623,69 @@ int path;
  * Mount a top level automount node
  * by calling lookup in the parent
  * (root) node which will cause the
  * Mount a top level automount node
  * by calling lookup in the parent
  * (root) node which will cause the
- * automount node to be automounted (!)
+ * automount node to be automounted.
  */
  */
-static void mount_auto_node(dir)
+int mount_auto_node P((char *dir, voidp arg));
+int mount_auto_node(dir, arg)
 char *dir;
 char *dir;
+voidp arg;
 {
        int error = 0;
 {
        int error = 0;
-       (void) afs_ops.lookuppn(root_node, dir, &error, VLOOK_CREATE);
-       if (error) {
+       (void) afs_ops.lookuppn((am_node *) arg, dir, &error, VLOOK_CREATE);
+       if (error > 0) {
                errno = error; /* XXX */
                errno = error; /* XXX */
-               plog(XLOG_ERROR, "Could not start server on %s: %m", dir);
+               plog(XLOG_ERROR, "Could not mount %s: %m", dir);
        }
        }
+       return error;
 }
 
 /*
  * Cause all the top-level mount nodes
  * to be automounted
  */
 }
 
 /*
  * Cause all the top-level mount nodes
  * to be automounted
  */
+int mount_exported P((void));
 int mount_exported()
 {
        /*
         * Iterate over all the nodes to be started
         */
 int mount_exported()
 {
        /*
         * Iterate over all the nodes to be started
         */
-       return root_keyiter(mount_auto_node);
+       return root_keyiter((void (*)P((char*,void*))) mount_auto_node, root_node);
 }
 
 /*
  * Construct top-level node
  */
 }
 
 /*
  * Construct top-level node
  */
+void make_root_node P((void));
 void make_root_node()
 {
        mntfs *root_mnt;
        char *rootmap = ROOT_MAP;
        root_node = exported_ap_alloc();
 
 void make_root_node()
 {
        mntfs *root_mnt;
        char *rootmap = ROOT_MAP;
        root_node = exported_ap_alloc();
 
+       /*
+        * Allocate a new map
+        */
        init_map(root_node, "");
        init_map(root_node, "");
-       root_mnt = find_mntfs(&afs_ops, (am_opts *) 0, "", rootmap, "");
-       root_mnt->mf_mount = strealloc(root_mnt->mf_mount, pid_fsname);
-       root_mnt->mf_private = (voidp) mapc_find(rootmap, "");
-       root_mnt->mf_prfree = mapc_free;
+       /*
+        * Allocate a new mounted filesystem
+        */
+       root_mnt = find_mntfs(&root_ops, (am_opts *) 0, "", rootmap, "", "");
+       /*
+        * Replace the initial null reference
+        */
        free_mntfs(root_node->am_mnt);
        root_node->am_mnt = root_mnt;
        free_mntfs(root_node->am_mnt);
        root_node->am_mnt = root_mnt;
-       root_node->am_flags |= AMF_NOTIMEOUT;
-       root_mnt->mf_error = 0;
+
+       /*
+        * Initialise the root
+        */
+       if (root_mnt->mf_ops->fs_init)
+               (*root_mnt->mf_ops->fs_init)(root_mnt);
+
+       /*
+        * Mount the root
+        */
+       root_mnt->mf_error = (*root_mnt->mf_ops->mount_fs)(root_node);
 }
 
 /*
 }
 
 /*
@@ -554,14 +710,13 @@ void umount_exported(P_void)
                                 */
                                continue;
                        }
                                 */
                                continue;
                        }
-                       if (mf && mf->mf_ops == &dfs_ops) {
+                       if (mf && !(mf->mf_ops->fs_flags & FS_DIRECTORY)) {
                                /*
                                 * When shutting down this had better
                                 * look like a directory, otherwise it
                                 * can't be unmounted!
                                 */
                                /*
                                 * When shutting down this had better
                                 * look like a directory, otherwise it
                                 * can't be unmounted!
                                 */
-                               mf->mf_fattr.type = NFDIR;
-                               mf->mf_fattr.mode = NFSMODE_DIR | 0555;
+                               mk_fattr(mp, NFDIR);
                        }
                        if ((--immediate_abort < 0 && !(mp->am_flags & AMF_ROOT) && mp->am_parent) ||
                            (mf->mf_flags & MFF_RESTART)) {
                        }
                        if ((--immediate_abort < 0 && !(mp->am_flags & AMF_ROOT) && mp->am_parent) ||
                            (mf->mf_flags & MFF_RESTART)) {
@@ -625,6 +780,7 @@ am_node *mp;
 }
 
 #ifdef FLUSH_KERNEL_NAME_CACHE
 }
 
 #ifdef FLUSH_KERNEL_NAME_CACHE
+static void flush_kernel_name_cache P((am_node*));
 static void flush_kernel_name_cache(mp)
 am_node *mp;
 {
 static void flush_kernel_name_cache(mp)
 am_node *mp;
 {
@@ -718,7 +874,7 @@ voidp closure;
 
        if (term) {
                plog(XLOG_ERROR, "unmount for %s got signal %d", mp->am_path, term);
 
        if (term) {
                plog(XLOG_ERROR, "unmount for %s got signal %d", mp->am_path, term);
-#ifdef DEBUG
+#if defined(DEBUG) && defined(SIGTRAP)
                /*
                 * dbx likes to put a trap on exit().
                 * Pretend it succeeded for now...
                /*
                 * dbx likes to put a trap on exit().
                 * Pretend it succeeded for now...
index f2b1954..11f152f 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: mapc.c,v 5.2 90/06/23 22:19:37 jsp Rel $
+ * $Id: mapc.c,v 5.2.1.7 91/03/17 17:46:52 jsp Alpha $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)mapc.c      5.1 (Berkeley) %G%
+ *     @(#)mapc.c      5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -19,6 +19,9 @@
  */
 
 #include "am.h"
  */
 
 #include "am.h"
+#ifdef HAS_REGEXP
+#include RE_HDR
+#endif
 
 /*
  * Hash table size
 
 /*
  * Hash table size
@@ -32,26 +35,51 @@ static char wildcard[] = "*";
 
 /*
  * Map cache types
 
 /*
  * Map cache types
- * default, none, incremental, all
+ * default, none, incremental, all, regexp
+ * MAPC_RE implies MAPC_ALL and must be numerically
+ * greater.
  */
  */
-#define        MAPC_DFLT       -1
-#define        MAPC_NONE       0
-#define        MAPC_INC        1
-#define        MAPC_ALL        2
+#define        MAPC_DFLT       0x000
+#define        MAPC_NONE       0x001
+#define        MAPC_INC        0x002
+#define        MAPC_ROOT       0x004
+#define        MAPC_ALL        0x010
+#ifdef HAS_REGEXP
+#define MAPC_RE                0x020
+#define        MAPC_ISRE(m) ((m)->alloc == MAPC_RE)
+#else
+#define MAPC_ISRE(m) FALSE
+#endif
+#define        MAPC_CACHE_MASK 0x0ff
+#define        MAPC_SYNC       0x100
+
+static struct opt_tab mapc_opt[] = {
+       { "all", MAPC_ALL },
+       { "default", MAPC_DFLT },
+       { "inc", MAPC_INC },
+       { "mapdefault", MAPC_DFLT },
+       { "none", MAPC_NONE },
+       { "re", MAPC_RE },
+       { "regexp", MAPC_RE },
+       { "sync", MAPC_SYNC },
+       { 0, 0 }
+};
 
 /*
 
 /*
- * Do a map reload
+ * Lookup recursion
  */
  */
-#define mapc_reload_map(m) \
-       ((*(m)->reload)(m, m->map_name, mapc_add_kv))
+#define        MREC_FULL       2
+#define        MREC_PART       1
+#define        MREC_NONE       0
 
 /*
  * Cache map operations
  */
 typedef void add_fn P((mnt_map*, char*, char*));
 
 /*
  * Cache map operations
  */
 typedef void add_fn P((mnt_map*, char*, char*));
-typedef int init_fn P((char*));
+typedef int init_fn P((char*, time_t*));
 typedef int search_fn P((mnt_map*, char*, char*, char**, time_t*));
 typedef int reload_fn P((mnt_map*, char*, add_fn*));
 typedef int search_fn P((mnt_map*, char*, char*, char**, time_t*));
 typedef int reload_fn P((mnt_map*, char*, add_fn*));
+typedef int mtime_fn P((char*, time_t*));
 
 static void mapc_sync P((mnt_map*));
 
 
 static void mapc_sync P((mnt_map*));
 
@@ -64,6 +92,7 @@ struct map_type {
        init_fn *init;                  /* Initialisation */
        reload_fn *reload;              /* Reload or fill */
        search_fn *search;              /* Search for new entry */
        init_fn *init;                  /* Initialisation */
        reload_fn *reload;              /* Reload or fill */
        search_fn *search;              /* Search for new entry */
+       mtime_fn *mtime;                /* Find modify time */
        int def_alloc;                  /* Default allocation mode */
 };
 
        int def_alloc;                  /* Default allocation mode */
 };
 
@@ -80,12 +109,14 @@ struct kv {
 struct mnt_map {
        qelem hdr;
        int refc;                       /* Reference count */
 struct mnt_map {
        qelem hdr;
        int refc;                       /* Reference count */
-       int alloc;                      /* Allocation mode */
+       short flags;                    /* Allocation flags */
+       short alloc;                    /* Allocation mode */
        time_t modify;                  /* Modify time of map */
        char *map_name;                 /* Name of this map */
        char *wildcard;                 /* Wildcard value */
        reload_fn *reload;              /* Function to be used for reloads */
        search_fn *search;              /* Function to be used for searching */
        time_t modify;                  /* Modify time of map */
        char *map_name;                 /* Name of this map */
        char *wildcard;                 /* Wildcard value */
        reload_fn *reload;              /* Function to be used for reloads */
        search_fn *search;              /* Function to be used for searching */
+       mtime_fn *mtime;                /* Modify time function */
        kv *kvhash[NKVHASH];            /* Cached data */
 };
 
        kv *kvhash[NKVHASH];            /* Cached data */
 };
 
@@ -105,75 +136,101 @@ qelem map_list_head = { &map_list_head, &map_list_head };
  */
  
 /* ROOT MAP */
  */
  
 /* ROOT MAP */
-static int root_init P((char*));
+static int root_init P((char*, time_t*));
 
 /* FILE MAPS */
 #ifdef HAS_FILE_MAPS
 
 /* FILE MAPS */
 #ifdef HAS_FILE_MAPS
-extern int file_init P((char*));
+extern int file_init P((char*, time_t*));
 extern int file_reload P((mnt_map*, char*, add_fn*));
 extern int file_search P((mnt_map*, char*, char*, char**, time_t*));
 extern int file_reload P((mnt_map*, char*, add_fn*));
 extern int file_search P((mnt_map*, char*, char*, char**, time_t*));
+extern int file_mtime P((char*, time_t*));
 #endif /* HAS_FILE_MAPS */
 
 /* Network Information Service (NIS) MAPS */
 #ifdef HAS_NIS_MAPS
 #endif /* HAS_FILE_MAPS */
 
 /* Network Information Service (NIS) MAPS */
 #ifdef HAS_NIS_MAPS
-extern int nis_init P((char*));
+extern int nis_init P((char*, time_t*));
+#ifdef HAS_NIS_RELOAD
+extern int nis_reload P((mnt_map*, char*, add_fn*));
+#else
+#define nis_reload error_reload
+#endif
 extern int nis_search P((mnt_map*, char*, char*, char**, time_t*));
 extern int nis_search P((mnt_map*, char*, char*, char**, time_t*));
+#define nis_mtime nis_init
 #endif /* HAS_NIS_MAPS */
 
 /* NDBM MAPS */
 #ifdef HAS_NDBM_MAPS
 #ifdef OS_HAS_NDBM
 #endif /* HAS_NIS_MAPS */
 
 /* NDBM MAPS */
 #ifdef HAS_NDBM_MAPS
 #ifdef OS_HAS_NDBM
-extern int ndbm_init P((char*));
+extern int ndbm_init P((char*, time_t*));
 extern int ndbm_search P((mnt_map*, char*, char*, char**, time_t*));
 extern int ndbm_search P((mnt_map*, char*, char*, char**, time_t*));
+#define ndbm_mtime ndbm_init
 #endif /* OS_HAS_NDBM */
 #endif /* HAS_NDBM_MAPS */
 
 /* PASSWD MAPS */
 #ifdef HAS_PASSWD_MAPS
 #endif /* OS_HAS_NDBM */
 #endif /* HAS_NDBM_MAPS */
 
 /* PASSWD MAPS */
 #ifdef HAS_PASSWD_MAPS
-extern int passwd_init P((char*));
+extern int passwd_init P((char*, time_t*));
 extern int passwd_search P((mnt_map*, char*, char*, char**, time_t*));
 #endif /* HAS_PASSWD_MAPS */
 
 /* HESIOD MAPS */
 #ifdef HAS_HESIOD_MAPS
 extern int passwd_search P((mnt_map*, char*, char*, char**, time_t*));
 #endif /* HAS_PASSWD_MAPS */
 
 /* HESIOD MAPS */
 #ifdef HAS_HESIOD_MAPS
-extern int hesiod_init P((char*));
+extern int hesiod_init P((char*, time_t*));
+#ifdef HAS_HESIOD_RELOAD
+extern int hesiod_reload P((mnt_map*, char*, add_fn*));
+#else
+#define hesiod_reload error_reload
+#endif
 extern int hesiod_search P((mnt_map*, char*, char*, char**, time_t*));
 #endif /* HAS_HESIOD_MAPS */
 
 extern int hesiod_search P((mnt_map*, char*, char*, char**, time_t*));
 #endif /* HAS_HESIOD_MAPS */
 
+/* UNION MAPS */
+#ifdef HAS_UNION_MAPS
+extern int union_init P((char*, time_t*));
+extern int union_search P((mnt_map*, char*, char*, char**, time_t*));
+extern int union_reload P((mnt_map*, char*, add_fn*));
+#endif /* HAS_UNION_MAPS */
+
 /* ERROR MAP */
 /* ERROR MAP */
-static int error_init P((char*));
+static int error_init P((char*, time_t*));
 static int error_reload P((mnt_map*, char*, add_fn*));
 static int error_search P((mnt_map*, char*, char*, char**, time_t*));
 static int error_reload P((mnt_map*, char*, add_fn*));
 static int error_search P((mnt_map*, char*, char*, char**, time_t*));
+static int error_mtime P((char*, time_t*));
 
 static map_type maptypes[] = {
 
 static map_type maptypes[] = {
-       { "root", root_init, error_reload, error_search, MAPC_ALL },
+       { "root", root_init, error_reload, error_search, error_mtime, MAPC_ROOT },
 
 #ifdef HAS_PASSWD_MAPS
 
 #ifdef HAS_PASSWD_MAPS
-       { "passwd", passwd_init, error_reload, passwd_search, MAPC_INC },
-#endif /* HAS_PASSWD_MAPS */
+       { "passwd", passwd_init, error_reload, passwd_search, error_mtime, MAPC_INC },
+#endif
 
 #ifdef HAS_HESIOD_MAPS
 
 #ifdef HAS_HESIOD_MAPS
-       { "hesiod", hesiod_init, error_reload, hesiod_search, MAPC_INC },
-#endif /* HAS_HESIOD_MAPS */
+       { "hesiod", hesiod_init, hesiod_reload, hesiod_search, error_mtime, MAPC_ALL },
+#endif
+
+#ifdef HAS_UNION_MAPS
+       { "union", union_init, union_reload, union_search, error_mtime, MAPC_ALL },
+#endif
 
 #ifdef HAS_NIS_MAPS
 
 #ifdef HAS_NIS_MAPS
-       { "nis", nis_init, error_reload, nis_search, MAPC_INC },
-#endif /* HAS_NIS_MAPS */
+       { "nis", nis_init, nis_reload, nis_search, nis_mtime, MAPC_INC },
+#endif
 
 #ifdef HAS_NDBM_MAPS
 
 #ifdef HAS_NDBM_MAPS
-       { "ndbm", ndbm_init, error_reload, ndbm_search, MAPC_INC },
-#endif /* HAS_NDBM_MAPS */
+       { "ndbm", ndbm_init, error_reload, ndbm_search, ndbm_mtime, MAPC_INC },
+#endif
 
 #ifdef HAS_FILE_MAPS
 
 #ifdef HAS_FILE_MAPS
-       { "file", file_init, file_reload, file_search, MAPC_ALL },
-#endif /* HAS_FILE_MAPS */
+       { "file", file_init, file_reload, file_search, file_mtime, MAPC_ALL },
+#endif
 
 
-       { "error", error_init, error_reload, error_search, MAPC_NONE },
+       { "error", error_init, error_reload, error_search, error_mtime, MAPC_NONE },
 };
 
 /*
  * Hash function
  */
 };
 
 /*
  * Hash function
  */
+static unsigned int kvhash_of P((char *key));
 static unsigned int kvhash_of(key)
 char *key;
 {
 static unsigned int kvhash_of(key)
 char *key;
 {
@@ -185,6 +242,7 @@ char *key;
        return i % NKVHASH;
 }
 
        return i % NKVHASH;
 }
 
+void mapc_showtypes P((FILE *fp));
 void mapc_showtypes(fp)
 FILE *fp;
 {
 void mapc_showtypes(fp)
 FILE *fp;
 {
@@ -196,23 +254,93 @@ FILE *fp;
        }
 }
 
        }
 }
 
+static char *reg_error = "?";
+void regerror P((char *m));
+void regerror(m)
+char *m;
+{
+       reg_error = m;
+}
+
 /*
  * Add key and val to the map m.
  * key and val are assumed to be safe copies
  */
 /*
  * Add key and val to the map m.
  * key and val are assumed to be safe copies
  */
+void mapc_add_kv P((mnt_map *m, char *key, char *val));
 void mapc_add_kv(m, key, val)
 mnt_map *m;
 char *key;
 char *val;
 {
 void mapc_add_kv(m, key, val)
 mnt_map *m;
 char *key;
 char *val;
 {
-       kv **h = &m->kvhash[kvhash_of(key)];
-       kv *n = ALLOC(kv);
+       kv **h;
+       kv *n;
+       int hash = kvhash_of(key);
+
+#ifdef DEBUG
+       dlog("add_kv: %s -> %s", key, val);
+#endif
+
+#ifdef HAS_REGEXP
+       if (MAPC_ISRE(m)) {
+               char keyb[MAXPATHLEN];
+               regexp *re;
+               /*
+                * Make sure the string is bound to the start and end
+                */
+               sprintf(keyb, "^%s$", key);
+               re = regcomp(keyb);
+               if (re == 0) {
+                       plog(XLOG_USER, "error compiling RE \"%s\": %s", keyb, reg_error);
+                       return;
+               } else {
+                       free(key);
+                       key = (char *) re;
+               }
+       }
+#endif
+
+       h = &m->kvhash[hash];
+       n = ALLOC(kv);
        n->key = key;
        n->val = val;
        n->next = *h;
        *h = n;
 }
 
        n->key = key;
        n->val = val;
        n->next = *h;
        *h = n;
 }
 
+void mapc_repl_kv P((mnt_map *m, char *key, char *val));
+void mapc_repl_kv(m, key, val)
+mnt_map *m;
+char *key;
+char *val;
+{
+       kv *k;
+
+       /*
+        * Compute the hash table offset
+        */
+       k = m->kvhash[kvhash_of(key)];
+
+       /*
+        * Scan the linked list for the key
+        */
+       while (k && !FSTREQ(k->key, key))
+               k = k->next;
+
+       if (k) {
+               free(k->val);
+               k->val = val;
+       } else {
+               mapc_add_kv(m, key, val);
+       }
+
+}
+
+/*
+ * Search a map for a key.
+ * Calls map specific search routine.
+ * While map is out of date, keep re-syncing.
+ */
+static int search_map P((mnt_map *m, char *key, char **valp));
 static int search_map(m, key, valp)
 mnt_map *m;
 char *key;
 static int search_map(m, key, valp)
 mnt_map *m;
 char *key;
@@ -234,6 +362,7 @@ char **valp;
  * Do a wildcard lookup in the map and
  * save the result.
  */
  * Do a wildcard lookup in the map and
  * save the result.
  */
+static void mapc_find_wildcard P((mnt_map *m));
 static void mapc_find_wildcard(m)
 mnt_map *m;
 {
 static void mapc_find_wildcard(m)
 mnt_map *m;
 {
@@ -251,67 +380,108 @@ mnt_map *m;
  */
 #define mapc_dup(m) ((m)->refc++, (m))
 
  */
 #define mapc_dup(m) ((m)->refc++, (m))
 
+/*
+ * Do a map reload
+ */
+static int mapc_reload_map(m)
+mnt_map *m;
+{
+       int error;
+#ifdef DEBUG
+       dlog("calling map reload on %s", m->map_name);
+#endif
+       error = (*m->reload)(m, m->map_name, mapc_add_kv);
+       if (error)
+               return error;
+       m->wildcard = 0;
+#ifdef DEBUG
+       dlog("calling mapc_search for wildcard");
+#endif
+       error = mapc_search(m, wildcard, &m->wildcard);
+       if (error)
+               m->wildcard = 0;
+       return 0;
+}
+
 /*
  * Create a new map
  */
 /*
  * Create a new map
  */
+static mnt_map *mapc_create P((char *map, char *opt));
 static mnt_map *mapc_create(map, opt)
 char *map;
 char *opt;
 {
        mnt_map *m = ALLOC(mnt_map);
        map_type *mt;
 static mnt_map *mapc_create(map, opt)
 char *map;
 char *opt;
 {
        mnt_map *m = ALLOC(mnt_map);
        map_type *mt;
-       int alloc = STREQ(opt, "all") ? MAPC_ALL :
-                   (STREQ(opt, "inc") ? MAPC_INC :
-                   ((STREQ(opt, "default") || STREQ(opt, "mapdefault")) ? MAPC_DFLT :
-                   MAPC_NONE));
+       time_t modify;
+       int alloc = 0;
+
+       (void) cmdoption(opt, mapc_opt, &alloc);
 
        for (mt = maptypes; mt < maptypes+sizeof(maptypes)/sizeof(maptypes[0]); mt++)
 
        for (mt = maptypes; mt < maptypes+sizeof(maptypes)/sizeof(maptypes[0]); mt++)
-               if ((*mt->init)(map) == 0)
+               if ((*mt->init)(map, &modify) == 0)
                        break;
                        break;
+       /* assert: mt in maptypes */
+
+       m->flags = alloc & ~MAPC_CACHE_MASK;
+       alloc &= MAPC_CACHE_MASK;
+
+       if (alloc == MAPC_DFLT)
+               alloc = mt->def_alloc;
+       switch (alloc) {
+       default:
+               plog(XLOG_USER, "Ambiguous map cache type \"%s\"; using \"inc\"", opt);
+               alloc = MAPC_INC;
+               /* fallthrough... */
+       case MAPC_NONE:
+       case MAPC_INC:
+       case MAPC_ROOT:
+               break;
+       case MAPC_ALL:
+               /*
+                * If there is no support for reload and it was requested
+                * then back off to incremental instead.
+                */
+               if (mt->reload == error_reload) {
+                       plog(XLOG_WARNING, "Map type \"%s\" does not support cache type \"all\"; using \"inc\"", mt->name);
+                       alloc = MAPC_INC;
+               }
+               break;
+       case MAPC_RE:
+               if (mt->reload == error_reload) {
+                       plog(XLOG_WARNING, "Map type \"%s\" does not support cache type \"re\"", mt->name);
+                       mt = &maptypes[sizeof(maptypes)/sizeof(maptypes[0]) - 1];
+                       /* assert: mt->name == "error" */
+               }
+               break;
+       }
 
 #ifdef DEBUG
        dlog("Map for %s coming from maptype %s", map, mt->name);
 
 #ifdef DEBUG
        dlog("Map for %s coming from maptype %s", map, mt->name);
-#endif /* DEBUG */
-       /*
-        * If there is no support for reload and it was requested
-        * then back off to incremental instead.
-        */
-       if (mt->reload == error_reload && alloc == MAPC_ALL && mt->def_alloc != MAPC_ALL) {
-               plog(XLOG_WARNING, "Map type \"%s\" does not support cache type \"all\"",
-                                       mt->name);
-               alloc = MAPC_INC;
-       } else if (alloc == MAPC_DFLT)
-               alloc = mt->def_alloc;
+#endif
+
        m->alloc = alloc;
        m->reload = mt->reload;
        m->alloc = alloc;
        m->reload = mt->reload;
-       m->modify = clocktime();
-       m->search = alloc == MAPC_ALL ? error_search : mt->search;
+       m->modify = modify;
+       m->search = alloc >= MAPC_ALL ? error_search : mt->search;
+       m->mtime = mt->mtime;
        bzero((voidp) m->kvhash, sizeof(m->kvhash));
        m->map_name = strdup(map);
        m->refc = 1;
        bzero((voidp) m->kvhash, sizeof(m->kvhash));
        m->map_name = strdup(map);
        m->refc = 1;
+       m->wildcard = 0;
+
        /*
        /*
-        * Attempt to find the wildcard entry
+        * synchronize cache with reality
         */
         */
-       mapc_find_wildcard(m);
+       mapc_sync(m);
 
 
-       if (alloc == MAPC_ALL) {
-               /*
-                * If cache all is specified then load the cache
-                */
-               if (mapc_reload_map(m)) {
-                       /*
-                        * If that doesn't work then fallback to
-                        * incremental cache mode
-                        */
-                       m->alloc = MAPC_INC;
-               }
-       }
        return m;
 }
 
 /*
  * Free the cached data in a map
  */
        return m;
 }
 
 /*
  * Free the cached data in a map
  */
+static void mapc_clear P((mnt_map *m));
 static void mapc_clear(m)
 mnt_map *m;
 {
 static void mapc_clear(m)
 mnt_map *m;
 {
@@ -325,10 +495,10 @@ mnt_map *m;
                kv *k = m->kvhash[i];
                while (k) {
                        kv *n = k->next;
                kv *k = m->kvhash[i];
                while (k) {
                        kv *n = k->next;
-                       free(k->key);
+                       free((voidp) k->key);
                        if (k->val)
                        if (k->val)
-                               free(k->val);
-                       free(k);
+                               free((voidp) k->val);
+                       free((voidp) k);
                        k = n;
                }
        }
                        k = n;
                }
        }
@@ -348,6 +518,7 @@ mnt_map *m;
 /*
  * Find a map, or create one if it does not exist
  */
 /*
  * Find a map, or create one if it does not exist
  */
+mnt_map *mapc_find P((char *map, char *opt));
 mnt_map *mapc_find(map, opt)
 char *map;
 char *opt;
 mnt_map *mapc_find(map, opt)
 char *map;
 char *opt;
@@ -373,6 +544,7 @@ char *opt;
 /*
  * Free a map.
  */
 /*
  * Free a map.
  */
+void mapc_free P((mnt_map *m));
 void mapc_free(m)
 mnt_map *m;
 {
 void mapc_free(m)
 mnt_map *m;
 {
@@ -381,11 +553,11 @@ mnt_map *m;
         * If the reference count hits zero
         * then throw the map away.
         */
         * If the reference count hits zero
         * then throw the map away.
         */
-       if (--m->refc == 0) {
+       if (m && --m->refc == 0) {
                mapc_clear(m);
                mapc_clear(m);
-               free(m->map_name);
+               free((voidp) m->map_name);
                rem_que(&m->hdr);
                rem_que(&m->hdr);
-               free(m);
+               free((voidp) m);
        }
 }
 
        }
 }
 
@@ -394,24 +566,71 @@ mnt_map *m;
  * Put a safe copy in *pval or return
  * an error code
  */
  * Put a safe copy in *pval or return
  * an error code
  */
-int mapc_search(m, key, pval)
+int mapc_meta_search P((mnt_map *m, char *key, char **pval, int recurse));
+int mapc_meta_search(m, key, pval, recurse)
 mnt_map *m;
 char *key;
 char **pval;
 mnt_map *m;
 char *key;
 char **pval;
+int recurse;
 {
        int error = 0;
 {
        int error = 0;
-       kv *k;
+       kv *k = 0;
 
        /*
 
        /*
-        * Compute the hash table offset
+        * Firewall
         */
         */
-       k = m->kvhash[kvhash_of(key)];
+       if (!m) {
+               plog(XLOG_ERROR, "Null map request for %s", key);
+               return ENOENT;
+       }
 
 
-       /*
-        * Scan the linked list for the key
-        */
-       while (k && !FSTREQ(k->key, key))
-               k = k->next;
+       if (m->flags & MAPC_SYNC) {
+               /*
+                * Get modify time...
+                */
+               time_t t;
+               error = (*m->mtime)(m->map_name, &t);
+               if (error || t > m->modify) {
+                       m->modify = t;
+                       plog(XLOG_INFO, "Map %s is out of date", m->map_name);
+                       mapc_sync(m);
+               }
+       }
+
+       if (!MAPC_ISRE(m)) {
+               /*
+                * Compute the hash table offset
+                */
+               k = m->kvhash[kvhash_of(key)];
+
+               /*
+                * Scan the linked list for the key
+                */
+               while (k && !FSTREQ(k->key, key)) k = k->next;
+
+       }
+#ifdef HAS_REGEXP
+       else if (recurse == MREC_FULL) {
+               /*
+                * Try for an RE match against the entire map.
+                * Note that this will be done in a "random"
+                * order.
+                */
+
+               int i;
+
+               for (i = 0; i < NKVHASH; i++) {
+                       k = m->kvhash[i];
+                       while (k) {
+                               if (regexec(k->key, key))
+                                       break;
+                               k = k->next;
+                       }
+                       if (k)
+                               break;
+               }
+       }
+#endif
 
        /*
         * If found then take a copy
 
        /*
         * If found then take a copy
@@ -421,7 +640,7 @@ char **pval;
                        *pval = strdup(k->val);
                else
                        error = ENOENT;
                        *pval = strdup(k->val);
                else
                        error = ENOENT;
-       } else if (m->alloc == MAPC_ALL) {
+       } else if (m->alloc >= MAPC_ALL) {
                /*
                 * If the entire map is cached then this
                 * key does not exist.
                /*
                 * If the entire map is cached then this
                 * key does not exist.
@@ -443,29 +662,73 @@ char **pval;
         * and the key is not internal then
         * return a copy of the wildcard.
         */
         * and the key is not internal then
         * return a copy of the wildcard.
         */
-       if (error && m->wildcard && *key != '/') {
-               *pval = strdup(m->wildcard);
-               return 0;
+       if (error > 0) {
+               if (recurse == MREC_FULL && !MAPC_ISRE(m)) {
+                       char wildname[MAXPATHLEN];
+                       char *subp;
+                       if (*key == '/')
+                               return error;
+                       /*
+                        * Keep chopping sub-directories from the RHS
+                        * and replacing with "/ *" and repeat the lookup.
+                        * For example:
+                        * "src/gnu/gcc" -> "src / gnu / *" -> "src / *"
+                        */
+                       strcpy(wildname, key);
+                       while (error && (subp = strrchr(wildname, '/'))) {
+                               strcpy(subp, "/*");
+#ifdef DEBUG
+                               dlog("mapc recurses on %s", wildname);
+#endif
+                               error = mapc_meta_search(m, wildname, pval, MREC_PART);
+                               if (error)
+                                       *subp = 0;
+                       }
+                       if (error > 0 && m->wildcard) {
+                               *pval = strdup(m->wildcard);
+                               error = 0;
+                       }
+               }
        }
 
        return error;
 }
 
        }
 
        return error;
 }
 
+int mapc_search P((mnt_map *m, char *key, char **pval));
+int mapc_search(m, key, pval)
+mnt_map *m;
+char *key;
+char **pval;
+{
+       return mapc_meta_search(m, key, pval, MREC_FULL);
+}
+
+/*
+ * Get map cache in sync with physical representation
+ */
+static void mapc_sync P((mnt_map *m));
 static void mapc_sync(m)
 mnt_map *m;
 {
 static void mapc_sync(m)
 mnt_map *m;
 {
-       mapc_clear(m);
+       if (m->alloc != MAPC_ROOT) {
+               mapc_clear(m);
 
 
-       if (m->alloc == MAPC_ALL)
-               if (mapc_reload_map(m))
-                       m->alloc = MAPC_INC;
-       mapc_find_wildcard(m);
+               if (m->alloc >= MAPC_ALL)
+                       if (mapc_reload_map(m))
+                               m->alloc = MAPC_INC;
+               /*
+                * Attempt to find the wildcard entry
+                */
+               if (m->alloc < MAPC_ALL)
+                       mapc_find_wildcard(m);
+       }
 }
 
 /*
  * Reload all the maps
 }
 
 /*
  * Reload all the maps
- * Called when amd gets hit by a SIGHUP.
+ * Called when Amd gets hit by a SIGHUP.
  */
  */
+void mapc_reload(P_void);
 void mapc_reload()
 {
        mnt_map *m;
 void mapc_reload()
 {
        mnt_map *m;
@@ -489,9 +752,12 @@ void mapc_reload()
  * This causes the top level mounts to be automounted.
  */
 
  * This causes the top level mounts to be automounted.
  */
 
-static int root_init(map)
+static int root_init P((char *map, time_t *tp));
+static int root_init(map, tp)
 char *map;
 char *map;
+time_t *tp;
 {
 {
+       *tp = clocktime();
        return strcmp(map, ROOT_MAP) == 0 ? 0 : ENOENT;
 }
 
        return strcmp(map, ROOT_MAP) == 0 ? 0 : ENOENT;
 }
 
@@ -502,6 +768,7 @@ char *map;
  * opts - mount options
  * map - map name
  */
  * opts - mount options
  * map - map name
  */
+void root_newmap P((char *dir, char *opts, char *map));
 void root_newmap(dir, opts, map)
 char *dir;
 char *opts;
 void root_newmap(dir, opts, map)
 char *dir;
 char *opts;
@@ -513,14 +780,39 @@ char *map;
         * First make sure we have a root map to talk about...
         */
        if (!root_map)
         * First make sure we have a root map to talk about...
         */
        if (!root_map)
-               root_map = mapc_find(ROOT_MAP, "all");
+               root_map = mapc_find(ROOT_MAP, "mapdefault");
 
        /*
         * Then add the entry...
         */
        dir = strdup(dir);
 
        /*
         * Then add the entry...
         */
        dir = strdup(dir);
-       sprintf(str, "cache:=none;type:=auto;fs:=\"%s\";%s", map, opts ? opts : "");
-       mapc_add_kv(root_map, dir, strdup(str));
+       if (map)
+               sprintf(str, "cache:=mapdefault;type:=toplvl;fs:=\"%s\";%s",
+                       map, opts ? opts : "");
+       else
+               strcpy(str, opts);
+       mapc_repl_kv(root_map, dir, strdup(str));
+}
+
+int mapc_keyiter P((mnt_map *m, void (*fn)(char*,voidp), voidp arg));
+int mapc_keyiter(m, fn, arg)
+mnt_map *m;
+void (*fn)P((char*, voidp));
+voidp arg;
+{
+       int i;
+       int c = 0;
+
+       for (i = 0; i < NKVHASH; i++) {
+               kv *k = m->kvhash[i];
+               while (k) {
+                       (*fn)(k->key, arg);
+                       k = k->next;
+                       c++;
+               }
+       }
+
+       return c;
 }
 
 /*
 }
 
 /*
@@ -529,37 +821,37 @@ char *map;
  * of all the nodes.
  * Finally throw away the root map.
  */
  * of all the nodes.
  * Finally throw away the root map.
  */
-int root_keyiter(fn)
-void (*fn)P((char*));
+int root_keyiter P((void (*fn)(char*,voidp), voidp arg));
+int root_keyiter(fn, arg)
+void (*fn)P((char*,voidp));
+voidp arg;
 {
 {
-       int i;
-       int c = 0;
-
        if (root_map) {
        if (root_map) {
-               for (i = 0; i < NKVHASH; i++) {
-                       kv *k = root_map->kvhash[i];
-                       while (k) {
-                               (*fn)(k->key);
-                               k = k->next;
-                               c++;
-                       }
-               }
+               int c = mapc_keyiter(root_map, fn, arg);
+#ifdef notdef
                mapc_free(root_map);
                root_map = 0;
                mapc_free(root_map);
                root_map = 0;
+#endif
+               return c;
        }
        }
-       return c;
+       return 0;
 }
 
 /*
  * Error map
  */
 }
 
 /*
  * Error map
  */
-static int error_init(map)
+static int error_init P((char *map, time_t *tp));
+static int error_init(map, tp)
 char *map;
 char *map;
+time_t *tp;
 {
 {
+       plog(XLOG_USER, "No source data for map %s", map);
+       *tp = 0;
        return 0;
 }
 
 /*ARGSUSED*/
        return 0;
 }
 
 /*ARGSUSED*/
+static int error_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp));
 static int error_search(m, map, key, pval, tp)
 mnt_map *m;
 char *map;
 static int error_search(m, map, key, pval, tp)
 mnt_map *m;
 char *map;
@@ -571,6 +863,7 @@ time_t *tp;
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
+static int error_reload P((mnt_map *m, char *map, add_fn *fn));
 static int error_reload(m, map, fn)
 mnt_map *m;
 char *map;
 static int error_reload(m, map, fn)
 mnt_map *m;
 char *map;
@@ -578,3 +871,12 @@ add_fn *fn;
 {
        return ENOENT;
 }
 {
        return ENOENT;
 }
+
+static int error_mtime P((char *map, time_t *tp));
+static int error_mtime(map, tp)
+char *map;
+time_t *tp;
+{
+       *tp = 0;
+       return 0;
+}
index bc1ee75..5230d7f 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: misc_rpc.c,v 5.2 90/06/23 22:19:38 jsp Rel $
+ * $Id: misc_rpc.c,v 5.2.1.2 90/11/04 23:17:21 jsp Exp $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)misc_rpc.c  5.1 (Berkeley) %G%
+ *     @(#)misc_rpc.c  5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -130,12 +130,12 @@ AUTH *auth;
 }
 
 
 }
 
 
-#ifdef MISC_RPC
 /*
  * Early RPC seems to be missing these..
  * Extracted from the RPC 3.9 sources as indicated
  */
 
 /*
  * Early RPC seems to be missing these..
  * Extracted from the RPC 3.9 sources as indicated
  */
 
+#ifdef NEED_XDR_POINTER
 /* @(#)xdr_reference.c 1.1 87/11/04 3.9 RPCSRC */
 /*
  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
 /* @(#)xdr_reference.c 1.1 87/11/04 3.9 RPCSRC */
 /*
  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
@@ -206,7 +206,9 @@ xdr_pointer(xdrs,objpp,obj_size,xdr_obj)
        }
        return (xdr_reference(xdrs,objpp,obj_size,xdr_obj));
 }
        }
        return (xdr_reference(xdrs,objpp,obj_size,xdr_obj));
 }
+#endif /* NEED_XDR_POINTER */
 
 
+#ifdef NEED_CLNT_SPERRNO
 /* @(#)clnt_perror.c   1.1 87/11/04 3.9 RPCSRC */
 /*
  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
 /* @(#)clnt_perror.c   1.1 87/11/04 3.9 RPCSRC */
 /*
  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
@@ -299,5 +301,5 @@ clnt_sperrno(stat)
        return ("RPC: (unknown error code)");
 }
 
        return ("RPC: (unknown error code)");
 }
 
-#endif /* MISC_RPC */
+#endif /* NEED_CLNT_SPERRNO */
 
 
index e0eb31e..e8f3209 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: mntfs.c,v 5.2 90/06/23 22:19:40 jsp Rel $
+ * $Id: mntfs.c,v 5.2.1.4 91/03/17 17:46:40 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)mntfs.c     5.1 (Berkeley) %G%
+ *     @(#)mntfs.c     5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -21,6 +21,7 @@ qelem mfhead = { &mfhead, &mfhead };
 
 int mntfs_allocated;
 
 
 int mntfs_allocated;
 
+#ifdef notdef
 /*
  * This is the default attributes field which
  * is copied into every new node to be created.
 /*
  * This is the default attributes field which
  * is copied into every new node to be created.
@@ -44,39 +45,47 @@ static struct fattr gen_fattr = {
        { 0, 0 },                       /* mtime */
        { 0, 0 },                       /* ctime */
 };
        { 0, 0 },                       /* mtime */
        { 0, 0 },                       /* ctime */
 };
+#endif /* notdef */
 
 mntfs *dup_mntfs(mf)
 mntfs *mf;
 {
        if (mf->mf_refc == 0) {
 
 mntfs *dup_mntfs(mf)
 mntfs *mf;
 {
        if (mf->mf_refc == 0) {
-               untimeout(mf->mf_cid);
+               if (mf->mf_cid)
+                       untimeout(mf->mf_cid);
                mf->mf_cid = 0;
                mf->mf_cid = 0;
+#ifdef notdef
                mf->mf_error = -1;
                mf->mf_flags &= ~MFF_ERROR;
                mf->mf_error = -1;
                mf->mf_flags &= ~MFF_ERROR;
+#endif
        }
        mf->mf_refc++;
        return mf;
 }
 
        }
        mf->mf_refc++;
        return mf;
 }
 
-static init_mntfs(mf, ops, mo, mp, info, opts)
+static int init_mntfs P((mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts));
+static int init_mntfs(mf, ops, mo, mp, info, auto_opts, mopts)
 mntfs *mf;
 am_ops *ops;
 am_opts *mo;
 char *mp;
 char *info;
 mntfs *mf;
 am_ops *ops;
 am_opts *mo;
 char *mp;
 char *info;
-char *opts;
+char *auto_opts;
+char *mopts;
 {
        mf->mf_ops = ops;
        mf->mf_fo = mo;
        mf->mf_mount = strdup(mp);
        mf->mf_info = strdup(info);
 {
        mf->mf_ops = ops;
        mf->mf_fo = mo;
        mf->mf_mount = strdup(mp);
        mf->mf_info = strdup(info);
-       mf->mf_opts = strdup(opts);
+       mf->mf_auto = strdup(auto_opts);
+       mf->mf_mopts = strdup(mopts);
        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_refc = 1;
        mf->mf_flags = 0;
        mf->mf_error = -1;
        mf->mf_cid = 0;
        mf->mf_private = 0;
        mf->mf_prfree = 0;
+#ifdef notdef
        mf->mf_attr.status = NFS_OK;
        mf->mf_fattr = gen_fattr;
        mf->mf_fattr.fsid = 42;
        mf->mf_attr.status = NFS_OK;
        mf->mf_fattr = gen_fattr;
        mf->mf_fattr.fsid = 42;
@@ -84,6 +93,7 @@ char *opts;
        mf->mf_fattr.atime.seconds = clocktime();
        mf->mf_fattr.atime.useconds = 0;
        mf->mf_fattr.mtime = mf->mf_fattr.ctime = mf->mf_fattr.atime;
        mf->mf_fattr.atime.seconds = clocktime();
        mf->mf_fattr.atime.useconds = 0;
        mf->mf_fattr.mtime = mf->mf_fattr.ctime = mf->mf_fattr.atime;
+#endif
 
        if (ops->ffserver)
                mf->mf_server = (*ops->ffserver)(mf);
 
        if (ops->ffserver)
                mf->mf_server = (*ops->ffserver)(mf);
@@ -91,27 +101,31 @@ char *opts;
                mf->mf_server = 0;
 }
 
                mf->mf_server = 0;
 }
 
-static mntfs *alloc_mntfs(ops, mo, mp, info, opts)
+static mntfs *alloc_mntfs P((am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts));
+static mntfs *alloc_mntfs(ops, mo, mp, info, auto_opts, mopts)
 am_ops *ops;
 am_opts *mo;
 char *mp;
 char *info;
 am_ops *ops;
 am_opts *mo;
 char *mp;
 char *info;
-char *opts;
+char *auto_opts;
+char *mopts;
 {
        mntfs *mf = ALLOC(mntfs);
 {
        mntfs *mf = ALLOC(mntfs);
-       init_mntfs(mf, ops, mo, mp, info, opts);
+       init_mntfs(mf, ops, mo, mp, info, auto_opts, mopts);
        ins_que(&mf->mf_q, &mfhead);
        mntfs_allocated++;
 
        return mf;
 }
 
        ins_que(&mf->mf_q, &mfhead);
        mntfs_allocated++;
 
        return mf;
 }
 
-mntfs *find_mntfs(ops, mo, mp, info, opts)
+mntfs *find_mntfs P((am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts));
+mntfs *find_mntfs(ops, mo, mp, info, auto_opts, mopts)
 am_ops *ops;
 am_opts *mo;
 char *mp;
 char *info;
 am_ops *ops;
 am_opts *mo;
 char *mp;
 char *info;
-char *opts;
+char *auto_opts;
+char *mopts;
 {
        mntfs *mf;
 
 {
        mntfs *mf;
 
@@ -143,7 +157,7 @@ char *opts;
                                /*
                                 * Restart a previously mounted filesystem.
                                 */
                                /*
                                 * Restart a previously mounted filesystem.
                                 */
-                               mntfs *mf2 = alloc_mntfs(&ifs_ops, mo, mp, info, opts);
+                               mntfs *mf2 = alloc_mntfs(&ifs_ops, mo, mp, info, auto_opts, mopts);
 #ifdef DEBUG
                                dlog("Restarting filesystem %s", mf->mf_mount);
 #endif /* DEBUG */
 #ifdef DEBUG
                                dlog("Restarting filesystem %s", mf->mf_mount);
 #endif /* DEBUG */
@@ -157,8 +171,15 @@ char *opts;
                        mf->mf_fo = mo;
                        if (!(mf->mf_flags & (MFF_MOUNTED|MFF_MOUNTING|MFF_UNMOUNTING))) {
                                fserver *fs;
                        mf->mf_fo = mo;
                        if (!(mf->mf_flags & (MFF_MOUNTED|MFF_MOUNTING|MFF_UNMOUNTING))) {
                                fserver *fs;
-                               mf->mf_opts = strealloc(mf->mf_opts, opts);
+                               mf->mf_flags &= ~MFF_ERROR;
+                               mf->mf_error = -1;
+                               mf->mf_auto = strealloc(mf->mf_auto, auto_opts);
+                               mf->mf_mopts = strealloc(mf->mf_mopts, mopts);
                                mf->mf_info = strealloc(mf->mf_info, info);
                                mf->mf_info = strealloc(mf->mf_info, info);
+                               if (mf->mf_private && mf->mf_prfree) {
+                                       (*mf->mf_prfree)(mf->mf_private);
+                                       mf->mf_private = 0;
+                               }
                                fs = ops->ffserver ? (*ops->ffserver)(mf) : (fserver *) 0;
                                if (mf->mf_server)
                                        free_srvr(mf->mf_server);
                                fs = ops->ffserver ? (*ops->ffserver)(mf) : (fserver *) 0;
                                if (mf->mf_server)
                                        free_srvr(mf->mf_server);
@@ -168,12 +189,12 @@ char *opts;
                }
        }
 
                }
        }
 
-       return alloc_mntfs(ops, mo, mp, info, opts);
+       return alloc_mntfs(ops, mo, mp, info, auto_opts, mopts);
 }
 
 mntfs *new_mntfs()
 {
 }
 
 mntfs *new_mntfs()
 {
-       return alloc_mntfs(&efs_ops, (am_opts *) 0, "//nil//", ".", "");
+       return alloc_mntfs(&efs_ops, (am_opts *) 0, "//nil//", ".", "", "");
 }
 
 static void uninit_mntfs(mf, rmd)
 }
 
 static void uninit_mntfs(mf, rmd)
@@ -181,7 +202,8 @@ mntfs *mf;
 int rmd;
 {
        if (mf->mf_mount) free((voidp) mf->mf_mount);
 int rmd;
 {
        if (mf->mf_mount) free((voidp) mf->mf_mount);
-       if (mf->mf_opts) free((voidp) mf->mf_opts);
+       if (mf->mf_auto) free((voidp) mf->mf_auto);
+       if (mf->mf_mopts) free((voidp) mf->mf_mopts);
        if (mf->mf_info) free((voidp) mf->mf_info);
        if (mf->mf_private && mf->mf_prfree)
                (*mf->mf_prfree)(mf->mf_private);
        if (mf->mf_info) free((voidp) mf->mf_info);
        if (mf->mf_private && mf->mf_prfree)
                (*mf->mf_prfree)(mf->mf_private);
@@ -273,13 +295,15 @@ mntfs *mf;
        }
 }
 
        }
 }
 
-mntfs *realloc_mntfs(mf, ops, mo, mp, info, opts)
+mntfs *realloc_mntfs P((mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts));
+mntfs *realloc_mntfs(mf, ops, mo, mp, info, auto_opts, mopts)
 mntfs *mf;
 am_ops *ops;
 am_opts *mo;
 char *mp;
 char *info;
 mntfs *mf;
 am_ops *ops;
 am_opts *mo;
 char *mp;
 char *info;
-char *opts;
+char *auto_opts;
+char *mopts;
 {
        mntfs *mf2;
        if (mf->mf_refc == 1 && mf->mf_ops == &ifs_ops && STREQ(mf->mf_mount, mp)) {
 {
        mntfs *mf2;
        if (mf->mf_refc == 1 && mf->mf_ops == &ifs_ops && STREQ(mf->mf_mount, mp)) {
@@ -289,7 +313,7 @@ char *opts;
                 */
                return mf;
        }
                 */
                return mf;
        }
-       mf2 = find_mntfs(ops, mo, mp, info, opts);
+       mf2 = find_mntfs(ops, mo, mp, info, auto_opts, mopts);
        free_mntfs(mf);
        return mf2;
 }
        free_mntfs(mf);
        return mf2;
 }
index 12f76a6..7105a75 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: mount_fs.c,v 5.2 90/06/23 22:19:42 jsp Rel $
+ * $Id: mount_fs.c,v 5.2.1.3 91/03/03 20:43:32 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)mount_fs.c  5.1 (Berkeley) %G%
+ *     @(#)mount_fs.c  5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -20,13 +20,6 @@ typedef nfs_fh fhandle_t;
 #endif /* NFS_3 */
 #include <sys/mount.h>
 
 #endif /* NFS_3 */
 #include <sys/mount.h>
 
-/*
- * System Vr4 / SunOS 4.1 compatibility
- * - put dev= in the options list
- *
- * From: Brent Callaghan <brent@eng.sun.com>
- */
-#define        MNTINFO_DEV     "dev"
 #include <sys/stat.h>
 
 /*
 #include <sys/stat.h>
 
 /*
@@ -89,6 +82,7 @@ struct mntent *mnt;
        return flags;
 }
 
        return flags;
 }
 
+int mount_fs P((struct mntent *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type));
 int mount_fs(mnt, flags, mnt_data, retry, type)
 struct mntent *mnt;
 int flags;
 int mount_fs(mnt, flags, mnt_data, retry, type)
 struct mntent *mnt;
 int flags;
@@ -97,7 +91,6 @@ int retry;
 MTYPE_TYPE type;
 {
        int error = 0;
 MTYPE_TYPE type;
 {
        int error = 0;
-       int automount = 0;
 #ifdef MNTINFO_DEV
        struct stat stb;
        char *xopts = 0;
 #ifdef MNTINFO_DEV
        struct stat stb;
        char *xopts = 0;
@@ -116,31 +109,18 @@ MTYPE_TYPE type;
        /*
         * Fake some mount table entries for the automounter
         */
        /*
         * Fake some mount table entries for the automounter
         */
+#ifdef FASCIST_DF_COMMAND
+       /*
+        * Some systems have a df command which blows up when
+        * presented with an unknown mount type.
+        */
        if (STREQ(mnt->mnt_type, MNTTYPE_AUTO)) {
        if (STREQ(mnt->mnt_type, MNTTYPE_AUTO)) {
-               automount = 1;
-               mnt->mnt_fsname = pid_fsname;
                /*
                 * Try it with the normal name
                 */
                /*
                 * Try it with the normal name
                 */
-#ifdef notdef
-               /*
-                * This is notdef'ed because some systems use
-                * the mount table in getwd() (esp. SunOS4) and
-                * if all the mount points are not marked it can
-                * cause major confusion.  This can probably
-                * be changed when no-one is running SunOS 4.0
-                * any more.
-                */
-               mnt->mnt_type = MNTTYPE_IGNORE;
-#endif /* notdef */
                mnt->mnt_type = MNTTYPE_NFS;
                mnt->mnt_type = MNTTYPE_NFS;
-               /*
-                * Background the mount, so that the stat of the
-                * mountpoint is done in a background process.
-                */
-               if (background())
-                       return 0;
        }
        }
+#endif /* FASCIST_DF_COMMAND */
 
 again:
        clock_valid = 0;
 
 again:
        clock_valid = 0;
@@ -152,8 +132,10 @@ again:
                goto again;
        }
        if (error < 0) {
                goto again;
        }
        if (error < 0) {
+#ifdef notdef
                if (automount)
                        going_down(errno);
                if (automount)
                        going_down(errno);
+#endif
                return errno;
        }
 
                return errno;
        }
 
@@ -166,24 +148,26 @@ again:
                char *zopts = (char *) xmalloc(strlen(mnt->mnt_opts) + 32);
                xopts = mnt->mnt_opts;
                if (sizeof(stb.st_dev) == 2) {
                char *zopts = (char *) xmalloc(strlen(mnt->mnt_opts) + 32);
                xopts = mnt->mnt_opts;
                if (sizeof(stb.st_dev) == 2) {
-                       /* SunOS 4.1 */
-                       sprintf(zopts, "%s,%s=%04lx", xopts, MNTINFO_DEV,
-                                       (u_long) stb.st_dev & 0xffff);
+                       /* e.g. SunOS 4.1 */
+                       sprintf(zopts, "%s,%s=%s%04lx", xopts, MNTINFO_DEV,
+                                       MNTINFO_PREF, (u_long) stb.st_dev & 0xffff);
                } else {
                } else {
-                       /* System Vr4 */
-                       sprintf(zopts, "%s,%s=%08lx", xopts, MNTINFO_DEV,
-                                       (u_long) stb.st_dev);
+                       /* e.g. System Vr4 */
+                       sprintf(zopts, "%s,%s=%s%08lx", xopts, MNTINFO_DEV,
+                                       MNTINFO_PREF, (u_long) stb.st_dev);
                }
                mnt->mnt_opts = zopts;
        }
 #endif /* MNTINFO_DEV */
 
                }
                mnt->mnt_opts = zopts;
        }
 #endif /* MNTINFO_DEV */
 
-#ifdef hpux
+#ifdef FIXUP_MNTENT
        /*
        /*
-        * Yet another gratuitously incompatible change in HP-UX
+        * Additional fields in struct mntent
+        * are fixed up here
         */
         */
-       mnt->mnt_time = clocktime();
-#endif /* hpux */
+       FIXUP_MNTENT(mnt);
+#endif
+
        write_mntent(mnt);
 #ifdef MNTINFO_DEV
        if (xopts) {
        write_mntent(mnt);
 #ifdef MNTINFO_DEV
        if (xopts) {
@@ -193,12 +177,6 @@ again:
 #endif /* MNTINFO_DEV */
 #endif /* UPDATE_MTAB */
 
 #endif /* MNTINFO_DEV */
 #endif /* UPDATE_MTAB */
 
-       /*
-        * Needed this way since mnt may contain a pointer
-        * to a local variable in this stack frame.
-        */
-       if (automount)
-               going_down(0);
        return 0;
 }
 
        return 0;
 }
 
@@ -263,102 +241,6 @@ char *opt;
 }
 #endif /* NEED_MNTOPT_PARSER */
 
 }
 #endif /* NEED_MNTOPT_PARSER */
 
-#ifdef MOUNT_AIX3
-
-#include "aix3-nfs.h"
-
-static int aix3_mkvp(p, gfstype, flags, object, stub, host, info, info_size, args)
-char *p;
-int gfstype;
-int flags;
-char *object;
-char *stub;
-char *host;
-char *info;
-int info_size;
-char *args;
-{
-       struct vmount *vp = (struct vmount *) p;
-       bzero((voidp) vp, sizeof(*vp));
-       /*
-        * Fill in standard fields
-        */
-       vp->vmt_revision = VMT_REVISION;
-       vp->vmt_flags = flags;
-       vp->vmt_gfstype = gfstype;
-
-#define        VMT_ROUNDUP(len) (4 * ((len + 3) / 4))
-#define VMT_ASSIGN(vp, idx, data, size) \
-       vp->vmt_data[idx].vmt_off = p - (char *) vp; \
-       vp->vmt_data[idx].vmt_size = size; \
-       bcopy(data, p, size); \
-       p += VMT_ROUNDUP(size);
-
-       /*
-        * Fill in all variable length data
-        */
-       p += sizeof(*vp);
-
-       VMT_ASSIGN(vp, VMT_OBJECT, object, strlen(object) + 1);
-       VMT_ASSIGN(vp, VMT_STUB, stub, strlen(stub) + 1);
-       VMT_ASSIGN(vp, VMT_HOST, host, strlen(host) + 1);
-       VMT_ASSIGN(vp, VMT_HOSTNAME, host, strlen(host) + 1);
-       VMT_ASSIGN(vp, VMT_INFO, info, info_size);
-       VMT_ASSIGN(vp, VMT_ARGS, args, strlen(args) + 1);
-
-#undef VMT_ASSIGN
-#undef VMT_ROUNDUP
-
-       /*
-        * Return length
-        */
-       return vp->vmt_length = p - (char *) vp;
-}
-
-/*
- * Map from conventional mount arguments
- * to AIX 3-style arguments.
- */
-aix3_mount(fsname, dir, flags, type, data, args)
-char *fsname;
-char *dir;
-int flags;
-int type;
-void *data;
-char *args;
-{
-       char buf[4096];
-       int size;
-
-#ifdef DEBUG
-       dlog("aix3_mount: fsname %s, dir %s, type %d", fsname, dir, type);
-#endif /* DEBUG */
-
-/* aix3_mkvp(p, gfstype, flags, object, stub, host, info, info_size, args) */
-
-       switch (type) {
-
-       case MOUNT_TYPE_NFS: {
-               char *host = strdup(fsname);
-               char *rfs = strchr(host, ':');
-               *rfs++ = '\0';
-
-               size = aix3_mkvp(buf, type, flags, rfs, dir, host, data, sizeof(struct nfs_args), args);
-               free(host);
-
-               } break;
-
-       case MOUNT_TYPE_UFS:
-               /* Need to open block device and extract log device info from sblk. */
-               return EINVAL;
-
-       default:
-               return EINVAL;
-       }
-#ifdef DEBUG
-       /*dlog("aix3_mkvp: flags %#x, size %d, args %s", flags, size, args);*/
-#endif /* DEBUG */
-
-       return vmount(buf, size);
-}
-#endif /* MOUNT_AIX3 */
+#ifdef MOUNT_HELPER_SOURCE
+#include MOUNT_HELPER_SOURCE
+#endif /* MOUNT_HELPER_SOURCE */
index 436c151..84abd7d 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: mtab.c,v 5.2 90/06/23 22:19:44 jsp Rel $
+ * $Id: mtab.c,v 5.2.1.1 90/10/21 22:29:27 jsp Exp $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)mtab.c      5.1 (Berkeley) %G%
+ *     @(#)mtab.c      5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -19,6 +19,7 @@
 /*
  * Firewall /etc/mtab entries
  */
 /*
  * Firewall /etc/mtab entries
  */
+void mnt_free P((struct mntent *mp));
 void mnt_free(mp)
 struct mntent *mp;
 {
 void mnt_free(mp)
 struct mntent *mp;
 {
@@ -32,6 +33,7 @@ struct mntent *mp;
 /*
  * Discard memory allocated for mount list
  */
 /*
  * Discard memory allocated for mount list
  */
+void discard_mntlist P((mntlist *mp));
 void discard_mntlist(mp)
 mntlist *mp;
 {
 void discard_mntlist(mp)
 mntlist *mp;
 {
@@ -41,13 +43,14 @@ mntlist *mp;
                mp = mp->mnext;
                if (mp2->mnt)
                        mnt_free(mp2->mnt);
                mp = mp->mnext;
                if (mp2->mnt)
                        mnt_free(mp2->mnt);
-               free(mp2);
+               free((voidp) mp2);
        }
 }
 
 /*
  * Throw away a mount list
  */
        }
 }
 
 /*
  * Throw away a mount list
  */
+void free_mntlist P((mntlist *mp));
 void free_mntlist(mp)
 mntlist *mp;
 {
 void free_mntlist(mp)
 mntlist *mp;
 {
@@ -60,6 +63,7 @@ mntlist *mp;
  * numeric option in the mount options (such as port=%d).
  * Returns 0 if the option is not specified.
  */
  * numeric option in the mount options (such as port=%d).
  * Returns 0 if the option is not specified.
  */
+int hasmntval P((struct mntent *mnt, char *opt));
 int hasmntval(mnt, opt)
 struct mntent *mnt;
 char *opt;
 int hasmntval(mnt, opt)
 struct mntent *mnt;
 char *opt;
index 24d9355..8dd3bfa 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: nfs_ops.c,v 5.2 90/06/23 22:19:45 jsp Rel $
+ * $Id: nfs_ops.c,v 5.2.1.4 91/03/17 17:45:55 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)nfs_ops.c   5.1 (Berkeley) %G%
+ *     @(#)nfs_ops.c   5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -160,7 +160,7 @@ fserver *fs;
 {
        fh_cache *fp;
        ITER(fp, fh_cache, &fh_head) {
 {
        fh_cache *fp;
        ITER(fp, fh_cache, &fh_head) {
-               if (fp->fh_fs == fs) {
+               if (fp->fh_fs == fs || fs == 0) {
                        fp->fh_sin.sin_port = (u_short) 0;
                        fp->fh_error = -1;
                }
                        fp->fh_sin.sin_port = (u_short) 0;
                        fp->fh_error = -1;
                }
@@ -353,9 +353,10 @@ voidp wchan;
  * remote hostname.
  * Local filesystem defaults to remote and vice-versa.
  */
  * remote hostname.
  * Local filesystem defaults to remote and vice-versa.
  */
-static int nfs_match(fo)
+static char *nfs_match(fo)
 am_opts *fo;
 {
 am_opts *fo;
 {
+       char *xmtab;
        if (fo->opt_fs && !fo->opt_rfs)
                fo->opt_rfs = fo->opt_fs;
        if (!fo->opt_rfs) {
        if (fo->opt_fs && !fo->opt_rfs)
                fo->opt_rfs = fo->opt_fs;
        if (!fo->opt_rfs) {
@@ -369,15 +370,14 @@ am_opts *fo;
        /*
         * Determine magic cookie to put in mtab
         */
        /*
         * Determine magic cookie to put in mtab
         */
-       fo->fs_mtab = (char *) xrealloc(fo->fs_mtab, strlen(fo->opt_rhost) +
-                               strlen(fo->opt_rfs) + 2);
-       sprintf(fo->fs_mtab, "%s:%s", fo->opt_rhost, fo->opt_rfs);
+       xmtab = (char *) xmalloc(strlen(fo->opt_rhost) + strlen(fo->opt_rfs) + 2);
+       sprintf(xmtab, "%s:%s", fo->opt_rhost, fo->opt_rfs);
 #ifdef DEBUG
        dlog("NFS: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"",
                fo->opt_rhost, fo->opt_rfs, fo->opt_fs);
 #endif /* DEBUG */
 
 #ifdef DEBUG
        dlog("NFS: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"",
                fo->opt_rhost, fo->opt_rfs, fo->opt_fs);
 #endif /* DEBUG */
 
-       return TRUE;
+       return xmtab;
 }
 
 /*
 }
 
 /*
@@ -386,17 +386,27 @@ am_opts *fo;
 static int nfs_init(mf)
 mntfs *mf;
 {
 static int nfs_init(mf)
 mntfs *mf;
 {
-       int error;
-       char *colon = strchr(mf->mf_info, ':');
-       if (colon == 0)
-               return ENOENT;
-
-       error = prime_nfs_fhandle_cache(colon+1, mf->mf_server, (struct fhstatus *) 0, (voidp) mf);
+       if (!mf->mf_private) {
+               int error;
+               struct fhstatus fhs;
+       
+               char *colon = strchr(mf->mf_info, ':');
+               if (colon == 0)
+                       return ENOENT;
+
+               error = prime_nfs_fhandle_cache(colon+1, mf->mf_server, &fhs, (voidp) mf);
+               if (!error) {
+                       mf->mf_private = (voidp) ALLOC(fhstatus);
+                       mf->mf_prfree = (void (*)()) free;
+                       bcopy((voidp) &fhs, mf->mf_private, sizeof(fhs));
+               }
+               return error;
+       }
 
 
-       return error;
+       return 0;
 }
 
 }
 
-mount_nfs_fh(fhp, dir, fs_name, opts, mf)
+int mount_nfs_fh(fhp, dir, fs_name, opts, mf)
 struct fhstatus *fhp;
 char *dir;
 char *fs_name;
 struct fhstatus *fhp;
 char *dir;
 char *fs_name;
@@ -407,7 +417,7 @@ mntfs *mf;
        struct mntent mnt;
        int retry;
        char *colon;
        struct mntent mnt;
        int retry;
        char *colon;
-       char *path;
+       /*char *path;*/
        char host[MAXHOSTNAMELEN + MAXPATHLEN + 2];
        fserver *fs = mf->mf_server;
        int flags;
        char host[MAXHOSTNAMELEN + MAXPATHLEN + 2];
        fserver *fs = mf->mf_server;
        int flags;
@@ -431,7 +441,7 @@ mntfs *mf;
 #ifndef NFS_ARGS_NEEDS_PATH
        *colon = ':';
 #endif /* NFS_ARGS_NEEDS_PATH */
 #ifndef NFS_ARGS_NEEDS_PATH
        *colon = ':';
 #endif /* NFS_ARGS_NEEDS_PATH */
-       path = colon + 1;
+       /*path = colon + 1;*/
 
        bzero((voidp) &nfs_args, sizeof(nfs_args));
 
 
        bzero((voidp) &nfs_args, sizeof(nfs_args));
 
@@ -499,6 +509,16 @@ mntfs *mf;
        if (hasmntopt(&mnt, MNTOPT_SOFT) != NULL)
                nfs_args.flags |= NFSMNT_SOFT;
 
        if (hasmntopt(&mnt, MNTOPT_SOFT) != NULL)
                nfs_args.flags |= NFSMNT_SOFT;
 
+#ifdef NFSMNT_SPONGY
+       if (hasmntopt(&mnt, "spongy") != NULL) {
+               nfs_args.flags |= NFSMNT_SPONGY;
+               if (nfs_args.flags & NFSMNT_SOFT) {
+                       plog(XLOG_USER, "Mount opts soft and spongy are incompatible - soft ignored");
+                       nfs_args.flags &= ~NFSMNT_SOFT;
+               }
+       }
+#endif /* MNTOPT_SPONGY */
+
 #ifdef MNTOPT_INTR
        if (hasmntopt(&mnt, MNTOPT_INTR) != NULL)
                nfs_args.flags |= NFSMNT_INT;
 #ifdef MNTOPT_INTR
        if (hasmntopt(&mnt, MNTOPT_INTR) != NULL)
                nfs_args.flags |= NFSMNT_INT;
@@ -509,6 +529,16 @@ mntfs *mf;
                nfs_args.flags |= NFSMNT_NODEVS;
 #endif /* MNTOPT_NODEVS */
 
                nfs_args.flags |= NFSMNT_NODEVS;
 #endif /* MNTOPT_NODEVS */
 
+#ifdef MNTOPT_COMPRESS
+       if (hasmntopt(&mnt, "compress") != NULL)
+               nfs_args.flags |= NFSMNT_COMPRESS;
+#endif /* MNTOPT_COMPRESS */
+
+#ifdef MNTOPT_NOCONN
+       if (hasmntopt(&mnt, "noconn") != NULL)
+               nfs_args.flags |= NFSMNT_NOCONN;
+#endif /* MNTOPT_NOCONN */
+
 #ifdef NFSMNT_PGTHRESH
        if (nfs_args.pg_thresh = hasmntval(&mnt, "pgthresh"))
                nfs_args.flags |= NFSMNT_PGTHRESH;
 #ifdef NFSMNT_PGTHRESH
        if (nfs_args.pg_thresh = hasmntval(&mnt, "pgthresh"))
                nfs_args.flags |= NFSMNT_PGTHRESH;
@@ -518,6 +548,11 @@ mntfs *mf;
 
        flags = compute_mount_flags(&mnt);
 
 
        flags = compute_mount_flags(&mnt);
 
+#ifdef NFSMNT_NOCTO
+       if (hasmntopt(&mnt, "nocto") != NULL)
+               nfs_args.flags |= NFSMNT_NOCTO;
+#endif /* NFSMNT_NOCTO */
+
 #ifdef HAS_TCP_NFS
        if (hasmntopt(&mnt, "tcp") != NULL)
                nfs_args.sotype = SOCK_STREAM;
 #ifdef HAS_TCP_NFS
        if (hasmntopt(&mnt, "tcp") != NULL)
                nfs_args.sotype = SOCK_STREAM;
@@ -544,12 +579,13 @@ mntfs *mf;
        return mount_fs(&mnt, flags, (caddr_t) &nfs_args, retry, type);
 }
 
        return mount_fs(&mnt, flags, (caddr_t) &nfs_args, retry, type);
 }
 
-static mount_nfs(dir, fs_name, opts, mf)
+static int mount_nfs(dir, fs_name, opts, mf)
 char *dir;
 char *fs_name;
 char *opts;
 mntfs *mf;
 {
 char *dir;
 char *fs_name;
 char *opts;
 mntfs *mf;
 {
+#ifdef notdef
        int error;
        struct fhstatus fhs;
        char *colon;
        int error;
        struct fhstatus fhs;
        char *colon;
@@ -566,15 +602,21 @@ mntfs *mf;
                return error;
 
        return mount_nfs_fh(&fhs, dir, fs_name, opts, mf);
                return error;
 
        return mount_nfs_fh(&fhs, dir, fs_name, opts, mf);
+#endif
+       if (!mf->mf_private) {
+               plog(XLOG_ERROR, "Missing filehandle for %s", fs_name);
+               return EINVAL;
+       }
+
+       return mount_nfs_fh((struct fhstatus *) mf->mf_private, dir, fs_name, opts, mf);
 }
 
 }
 
-static int nfs_mount(mp)
-am_node *mp;
+static int nfs_fmount(mf)
+mntfs *mf;
 {
 {
-       mntfs *mf = mp->am_mnt;
+       int error;
 
 
-       int error = mount_nfs(mf->mf_mount, mf->mf_info,
-                       mf->mf_fo->opt_opts, mf);
+       error = mount_nfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, mf);
 
 #ifdef DEBUG
        if (error) {
 
 #ifdef DEBUG
        if (error) {
@@ -585,11 +627,9 @@ am_node *mp;
        return error;
 }
 
        return error;
 }
 
-static int nfs_umount(mp)
-am_node *mp;
+static int nfs_fumount(mf)
+mntfs *mf;
 {
 {
-       mntfs *mf = mp->am_mnt;
-
        int error = UMOUNT_FS(mf->mf_mount);
        if (error)
                return error;
        int error = UMOUNT_FS(mf->mf_mount);
        if (error)
                return error;
@@ -654,8 +694,10 @@ am_ops nfs_ops = {
        "nfs",
        nfs_match,
        nfs_init,
        "nfs",
        nfs_match,
        nfs_init,
-       nfs_mount,
-       nfs_umount,
+       auto_fmount,
+       nfs_fmount,
+       auto_fumount,
+       nfs_fumount,
        efs_lookuppn,
        efs_readdir,
        0, /* nfs_readlink */
        efs_lookuppn,
        efs_readdir,
        0, /* nfs_readlink */
index 37932ee..9f334ae 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: nfs_start.c,v 5.2 90/06/23 22:19:48 jsp Rel $
+ * $Id: nfs_start.c,v 5.2.1.2 90/12/21 16:41:40 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)nfs_start.c 5.1 (Berkeley) %G%
+ *     @(#)nfs_start.c 5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -128,6 +128,37 @@ struct timeval *tvp;
        return nsel;
 }
 
        return nsel;
 }
 
+/*
+ * Determine whether anything is left in
+ * the RPC input queue.
+ */
+static int rpc_pending_now()
+{
+       struct timeval tvv;
+       int nsel;
+#ifdef FD_SET
+       fd_set readfds;
+
+       FD_ZERO(&readfds);
+       FD_SET(fwd_sock, &readfds);
+#else
+       int readfds = (1 << fwd_sock);
+#endif /* FD_SET */
+
+       tvv.tv_sec = tvv.tv_usec = 0;
+       nsel = select(max_fds+1, &readfds, (int *) 0, (int *) 0, &tvv);
+       if (nsel < 1)
+               return(0);
+#ifdef FD_SET
+       if (FD_ISSET(fwd_sock, &readfds))
+               return(1);
+#else
+       if (readfds & (1 << fwd_sock))
+               return(1);
+#endif
+       return(0);
+}
+
 static serv_state run_rpc(P_void)
 {
        int dtbsz = max_fds + 1;
 static serv_state run_rpc(P_void)
 {
        int dtbsz = max_fds + 1;
@@ -214,19 +245,21 @@ static serv_state run_rpc(P_void)
                        break;
 
                default:
                        break;
 
                default:
+                       /* Read all pending NFS responses at once to avoid
+                          having responses queue up as a consequence of
+                          retransmissions. */
 #ifdef FD_SET
                        if (FD_ISSET(fwd_sock, &readfds)) {
                                FD_CLR(fwd_sock, &readfds);
 #ifdef FD_SET
                        if (FD_ISSET(fwd_sock, &readfds)) {
                                FD_CLR(fwd_sock, &readfds);
-                               fwd_reply();
-                               --nsel;
-                       }
 #else
                        if (readfds & (1 << fwd_sock)) {
                                readfds &= ~(1 << fwd_sock);
 #else
                        if (readfds & (1 << fwd_sock)) {
                                readfds &= ~(1 << fwd_sock);
-                               fwd_reply();
-                               --nsel;
+#endif
+                               --nsel; 
+                               do {
+                                       fwd_reply();
+                               } while (rpc_pending_now() > 0);
                        }
                        }
-#endif /* FD_SET */
 
                        if (nsel) {
                                /*
 
                        if (nsel) {
                                /*
@@ -280,8 +313,6 @@ int ppid;
        SVCXPRT *amqp;
        int nmount;
 
        SVCXPRT *amqp;
        int nmount;
 
-       unregister_amq();
-
        if (so < 0 || bindnfs_port(so) < 0) {
                perror("Can't create privileged nfs port");
                return 1;
        if (so < 0 || bindnfs_port(so) < 0) {
                perror("Can't create privileged nfs port");
                return 1;
@@ -298,14 +329,6 @@ int ppid;
                return 3;
        }
 
                return 3;
        }
 
-#ifdef DEBUG
-       Debug(D_AMQ)
-#endif /* DEBUG */
-       if (!svc_register(amqp, AMQ_PROGRAM, AMQ_VERSION, amq_program_1, IPPROTO_UDP)) {
-               plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM, AMQ_VERSION, udp)");
-               return 3;
-       }
-
        /*
         * Start RPC forwarding
         */
        /*
         * Start RPC forwarding
         */
@@ -352,6 +375,22 @@ int ppid;
                return 0;
        }
 
                return 0;
        }
 
+#ifdef DEBUG
+       Debug(D_AMQ) {
+#endif /* DEBUG */
+       /*
+        * Register with amq
+        */
+       unregister_amq();
+
+       if (!svc_register(amqp, AMQ_PROGRAM, AMQ_VERSION, amq_program_1, IPPROTO_UDP)) {
+               plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM, AMQ_VERSION, udp)");
+               return 3;
+       }
+#ifdef DEBUG
+       }
+#endif /* DEBUG */
+
        /*
         * Start timeout_mp rolling
         */
        /*
         * Start timeout_mp rolling
         */
index c167afd..ecf673e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: nfs_subr.c,v 5.2 90/06/23 22:19:50 jsp Rel $
+ * $Id: nfs_subr.c,v 5.2.1.4 91/03/03 20:46:34 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)nfs_subr.c  5.1 (Berkeley) %G%
+ *     @(#)nfs_subr.c  5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -28,6 +28,7 @@ NFS_ERROR_MAPPING
 #define nfs_error(e) ((nfsstat)(e))
 #endif /* NFS_ERROR_MAPPING */
 
 #define nfs_error(e) ((nfsstat)(e))
 #endif /* NFS_ERROR_MAPPING */
 
+static char *do_readlink P((am_node *mp, int *error_return, struct attrstat **attrpp));
 static char *do_readlink(mp, error_return, attrpp)
 am_node *mp;
 int *error_return;
 static char *do_readlink(mp, error_return, attrpp)
 am_node *mp;
 int *error_return;
@@ -55,7 +56,7 @@ struct attrstat **attrpp;
                ln = mp->am_mnt->mf_mount;
        }
        if (attrpp)
                ln = mp->am_mnt->mf_mount;
        }
        if (attrpp)
-               *attrpp = &mp->am_mnt->mf_attr;
+               *attrpp = &mp->am_attr;
        return ln;
 }
 
        return ln;
 }
 
@@ -96,9 +97,9 @@ getattr_retry:
                        return 0;
                res.status = nfs_error(retry);
        } else {
                        return 0;
                res.status = nfs_error(retry);
        } else {
-               struct attrstat *attrp = &mp->am_mnt->mf_attr;
+               struct attrstat *attrp = &mp->am_attr;
 #ifdef PRECISE_SYMLINKS
 #ifdef PRECISE_SYMLINKS
-               if (mp->am_mnt->mf_fattr.type == NFLNK) {
+               if (mp->am_fattr.type == NFLNK) {
                        /*
                         * Make sure we can read the link,
                         * and then determine the length.
                        /*
                         * Make sure we can read the link,
                         * and then determine the length.
@@ -187,12 +188,8 @@ struct svc_req *rqstp;
                        }
                        res.status = nfs_error(error);
                } else {
                        }
                        res.status = nfs_error(error);
                } else {
-#ifdef DEBUG
-                       if (ap->am_mnt->mf_fattr.size < 0)
-                               dlog("\tERROR: size = %d!", ap->am_mnt->mf_fattr.size);
-#endif /* DEBUG */
                        mp_to_fh(ap, &res.diropres_u.diropres.file);
                        mp_to_fh(ap, &res.diropres_u.diropres.file);
-                       res.diropres_u.diropres.attributes = ap->am_mnt->mf_fattr;
+                       res.diropres_u.diropres.attributes = ap->am_fattr;
                        res.status = NFS_OK;
                }
                mp->am_stats.s_lookup++;
                        res.status = NFS_OK;
                }
                mp->am_stats.s_lookup++;
@@ -225,7 +222,7 @@ readlink_retry:
                        return 0;
                res.status = nfs_error(retry);
        } else {
                        return 0;
                res.status = nfs_error(retry);
        } else {
-               char *ln = do_readlink(mp, &retry, (struct attrstat *) 0);
+               char *ln = do_readlink(mp, &retry, (struct attrstat **) 0);
                if (ln == 0)
                        goto readlink_retry;
                res.status = NFS_OK;
                if (ln == 0)
                        goto readlink_retry;
                res.status = NFS_OK;
@@ -309,10 +306,11 @@ static nfsstat *
 unlink_or_rmdir(argp, rqstp, unlinkp)
 struct diropargs *argp;
 struct svc_req *rqstp;
 unlink_or_rmdir(argp, rqstp, unlinkp)
 struct diropargs *argp;
 struct svc_req *rqstp;
+int unlinkp;
 {
        static nfsstat res;
        int retry;
 {
        static nfsstat res;
        int retry;
-       mntfs *mf;
+       /*mntfs *mf;*/
        am_node *mp = fh_to_mp3(&argp->dir, &retry, VLOOK_DELETE);
        if (mp == 0) {
                if (retry < 0)
        am_node *mp = fh_to_mp3(&argp->dir, &retry, VLOOK_DELETE);
        if (mp == 0) {
                if (retry < 0)
@@ -320,8 +318,8 @@ struct svc_req *rqstp;
                res = nfs_error(retry);
                goto out;
        }
                res = nfs_error(retry);
                goto out;
        }
-       mf = mp->am_mnt;
-       if (mf->mf_fattr.type != NFDIR) {
+       /*mf = mp->am_mnt;*/
+       if (mp->am_fattr.type != NFDIR) {
                res = nfs_error(ENOTDIR);
                goto out;
        }
                res = nfs_error(ENOTDIR);
                goto out;
        }
@@ -358,7 +356,7 @@ nfsproc_remove_2(argp, rqstp)
 struct diropargs *argp;
 struct svc_req *rqstp;
 {
 struct diropargs *argp;
 struct svc_req *rqstp;
 {
-       return unlink_or_rmdir(argp, rqstp, 1);
+       return unlink_or_rmdir(argp, rqstp, TRUE);
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
@@ -439,7 +437,7 @@ nfsproc_rmdir_2(argp, rqstp)
 struct diropargs *argp;
 struct svc_req *rqstp;
 {
 struct diropargs *argp;
 struct svc_req *rqstp;
 {
-       return unlink_or_rmdir(argp, rqstp, 0);
+       return unlink_or_rmdir(argp, rqstp, FALSE);
 }
 
 
 }
 
 
@@ -450,7 +448,7 @@ readdirargs *argp;
 struct svc_req *rqstp;
 {
        static readdirres res;
 struct svc_req *rqstp;
 {
        static readdirres res;
-       static entry e_res[2];
+       static entry e_res[MAX_READDIR_ENTRIES];
        am_node *mp;
        int retry;
 
        am_node *mp;
        int retry;
 
@@ -470,12 +468,10 @@ struct svc_req *rqstp;
                        plog(XLOG_DEBUG, "\treaddir(%s)", mp->am_path);
 #endif /* DEBUG */
                res.status = nfs_error((*mp->am_mnt->mf_ops->readdir)(mp, argp->cookie,
                        plog(XLOG_DEBUG, "\treaddir(%s)", mp->am_path);
 #endif /* DEBUG */
                res.status = nfs_error((*mp->am_mnt->mf_ops->readdir)(mp, argp->cookie,
-                                       &res.readdirres_u.reply, e_res));
+                                       &res.readdirres_u.reply, e_res, argp->count));
                mp->am_stats.s_readdir++;
        }
 
                mp->am_stats.s_readdir++;
        }
 
-       /* XXX - need to take argp->count into account */
-
        return &res;
 }
 
        return &res;
 }
 
@@ -512,8 +508,12 @@ struct svc_req *rqstp;
                fp = &res.statfsres_u.reply;
 
                fp->tsize = 1024;
                fp = &res.statfsres_u.reply;
 
                fp->tsize = 1024;
-               fp->bsize = 4192;
+               fp->bsize = 4096;
+#ifdef HAS_EMPTY_AUTOMOUNTS
+               fp->blocks = 0;
+#else
                fp->blocks = 1;
                fp->blocks = 1;
+#endif
                fp->bfree = 0;
                fp->bavail = 0;
 
                fp->bfree = 0;
                fp->bavail = 0;
 
index 980de69..902c8f8 100644 (file)
@@ -9,21 +9,9 @@
  * This code is derived from software contributed to Berkeley by
  * Jan-Simon Pendry at Imperial College, London.
  *
  * 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 are permitted provided
- * that: (1) source distributions retain this entire copyright notice and
- * comment, and (2) distributions including binaries display the following
- * acknowledgement:  ``This product includes software developed by the
- * University of California, Berkeley and its contributors'' in the
- * documentation or other materials provided with the distribution and in
- * all advertising materials mentioning features or use of this software.
- * Neither the name of the 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * %sccs.include.redist.c%
  *
  *
- *     @(#)nfsx_ops.c  5.1 (Berkeley) %G%
+ *     @(#)nfsx_ops.c  5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
index 17bfd49..2ccf26a 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: opts.c,v 5.2 90/06/23 22:19:51 jsp Rel $
+ * $Id: opts.c,v 5.2.1.5 91/03/17 17:45:34 jsp Alpha $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)opts.c      5.1 (Berkeley) %G%
+ *     @(#)opts.c      5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -36,7 +36,7 @@ static char *vars[8];
 /*
  * Length of longest option name
  */
 /*
  * Length of longest option name
  */
-#define        NLEN    16
+#define        NLEN    16      /* conservative */
 #define S(x) (x) , (sizeof(x)-1)
 static struct opt {
        char *name;             /* Name of the option */
 #define S(x) (x) , (sizeof(x)-1)
 static struct opt {
        char *name;             /* Name of the option */
@@ -64,6 +64,7 @@ static struct opt {
        { S("domain"), 0, &hostdomain },
        { S("karch"), 0, &karch },
        { S("cluster"), 0, &cluster },
        { S("domain"), 0, &hostdomain },
        { S("karch"), 0, &karch },
        { S("cluster"), 0, &cluster },
+       { S("wire"), 0, &wire },
        { S("byte"), 0, &endian },
        { S("os"), 0, &op_sys },
        { S("mount"), &fs_static.opt_mount, 0 },
        { S("byte"), 0, &endian },
        { S("os"), 0, &op_sys },
        { S("mount"), &fs_static.opt_mount, 0 },
@@ -184,9 +185,10 @@ top:
        return s;
 }
 
        return s;
 }
 
-static int eval_opts P((char*));
-static int eval_opts(opts)
+static int eval_opts P((char*, char*));
+static int eval_opts(opts, mapkey)
 char *opts;
 char *opts;
+char *mapkey;
 {
        /*
         * Fill in the global structure fs_static by
 {
        /*
         * Fill in the global structure fs_static by
@@ -208,7 +210,7 @@ char *opts;
                        /*
                         * No value, just continue
                         */
                        /*
                         * No value, just continue
                         */
-                       plog(XLOG_USER, "No value component in \"%s\"", f);
+                       plog(XLOG_USER, "key %s: No value component in \"%s\"", mapkey, f);
                        continue;
                }
 
                        continue;
                }
 
@@ -252,6 +254,7 @@ char *opts;
                                switch (vs_opt) {
 #if AMD_COMPAT <= 5000108
                                case OldSyn:
                                switch (vs_opt) {
 #if AMD_COMPAT <= 5000108
                                case OldSyn:
+                                       plog(XLOG_WARNING, "key %s: Old syntax selector found: %s=%s", mapkey, f, opt);
                                        if (!op->sel_p) {
                                                *op->optp = opt;
                                                break;
                                        if (!op->sel_p) {
                                                *op->optp = opt;
                                                break;
@@ -261,7 +264,8 @@ char *opts;
                                case SelEQ:
                                case SelNE:
                                        if (op->sel_p && (STREQ(*op->sel_p, opt) == (vs_opt == SelNE))) {
                                case SelEQ:
                                case SelNE:
                                        if (op->sel_p && (STREQ(*op->sel_p, opt) == (vs_opt == SelNE))) {
-                                               plog(XLOG_MAP, "map selector %s (=%s) did not %smatch %s",
+                                               plog(XLOG_MAP, "key %s: map selector %s (=%s) did not %smatch %s",
+                                                       mapkey,
                                                        op->name,
                                                        *op->sel_p,
                                                        vs_opt == SelNE ? "not " : "",
                                                        op->name,
                                                        *op->sel_p,
                                                        vs_opt == SelNE ? "not " : "",
@@ -272,7 +276,7 @@ char *opts;
 
                                case VarAss:
                                        if (op->sel_p) {
 
                                case VarAss:
                                        if (op->sel_p) {
-                                               plog(XLOG_USER, "Can't assign to a selector (%s)", op->name);
+                                               plog(XLOG_USER, "key %s: Can't assign to a selector (%s)", mapkey, op->name);
                                                return 0;
                                        }
                                        *op->optp = opt;
                                                return 0;
                                        }
                                        *op->optp = opt;
@@ -283,7 +287,7 @@ char *opts;
                }
 
                if (!op->name)
                }
 
                if (!op->name)
-                       plog(XLOG_USER, "Unrecognised key \"%s\"", f);
+                       plog(XLOG_USER, "key %s: Unrecognised key/option \"%s\"", mapkey, f);
        }
 
        return 1;
        }
 
        return 1;
@@ -304,6 +308,39 @@ int b;
        }
 }
 
        }
 }
 
+/*
+ * Normalize slashes in the string.
+ */
+void normalize_slash P((char *p));
+void normalize_slash(p)
+char *p;
+{
+       char *f = strchr(p, '/');
+       if (f) {
+               char *t = f;
+               do {
+                       /* assert(*f == '/'); */
+                       /* copy a single / across */
+                       *t++ = *f++;
+
+                       /* assert(f[-1] == '/'); */
+                       /* skip past more /'s */
+                       while (*f == '/')
+                               f++;
+
+                       /* assert(*f != '/'); */
+                       /* keep copying up to next / */
+                       do {
+                               *t++ = *f++;
+                       } while (*f && *f != '/');
+
+                       /* assert(*f == 0 || *f == '/'); */
+
+               } while (*f);
+               *t = 0;                 /* derived from fix by Steven Glassman */
+       }
+}
+
 /*
  * Macro-expand an option.  Note that this does not
  * handle recursive expansions.  They will go badly wrong.
 /*
  * Macro-expand an option.  Note that this does not
  * handle recursive expansions.  They will go badly wrong.
@@ -359,7 +396,7 @@ static char expand_error[] = "No space to expand \"%s\"";
                        }
                } else if (ch == '{') {
                        /* Expansion... */
                        }
                } else if (ch == '{') {
                        /* Expansion... */
-                       enum { E_All, E_Dir, E_File } todo;
+                       enum { E_All, E_Dir, E_File, E_Domain, E_Host } todo;
                        /*
                         * Find closing brace
                         */
                        /*
                         * Find closing brace
                         */
@@ -392,6 +429,19 @@ static char expand_error[] = "No space to expand \"%s\"";
                                 */
                                todo = E_Dir;
                                --len;
                                 */
                                todo = E_Dir;
                                --len;
+                       } else if (*cp == '.') {
+                               /*
+                                * Take domain name
+                                */
+                               todo = E_Domain;
+                               cp++;
+                               --len;
+                       } else if (br_p[-1] == '.') {
+                               /*
+                                * Take host name
+                                */
+                               todo = E_Host;
+                               --len;
                        } else {
                                /*
                                 * Take the whole lot
                        } else {
                                /*
                                 * Take the whole lot
@@ -434,9 +484,11 @@ static char expand_error[] = "No space to expand \"%s\"";
                                                 * Copy the string across unexpanded
                                                 */
                                                sprintf(xbuf, "${%s%s%s}",
                                                 * Copy the string across unexpanded
                                                 */
                                                sprintf(xbuf, "${%s%s%s}",
-                                                       todo == E_File ? "/" : "",
+                                                       todo == E_File ? "/" :
+                                                               todo == E_Domain ? "." : "",
                                                        nbuf,
                                                        nbuf,
-                                                       todo == E_Dir ? "/" : "");
+                                                       todo == E_Dir ? "/" :
+                                                               todo == E_Host ? "." : "");
                                                val = xbuf;
                                                /*
                                                 * Make sure expansion doesn't
                                                val = xbuf;
                                                /*
                                                 * Make sure expansion doesn't
@@ -453,6 +505,8 @@ static char expand_error[] = "No space to expand \"%s\"";
                                                 * Do expansion:
                                                 * ${/var} means take just the last part
                                                 * ${var/} means take all but the last part
                                                 * Do expansion:
                                                 * ${/var} means take just the last part
                                                 * ${var/} means take all but the last part
+                                                * ${.var} means take all but first part
+                                                * ${var.} means take just the first part
                                                 * ${var} means take the whole lot
                                                 */
                                                int vlen = strlen(val);
                                                 * ${var} means take the whole lot
                                                 */
                                                int vlen = strlen(val);
@@ -472,6 +526,24 @@ static char expand_error[] = "No space to expand \"%s\"";
                                                        } else
                                                                vptr = val;
                                                        break;
                                                        } else
                                                                vptr = val;
                                                        break;
+                                               case E_Domain:
+                                                       vptr = strchr(val, '.');
+                                                       if (vptr) {
+                                                               vptr++;
+                                                               vlen = strlen(vptr);
+                                                       } else {
+                                                               vptr = "";
+                                                               vlen = 0;
+                                                       }
+                                                       break;
+                                               case E_Host:
+                                                       vptr = strchr(val, '.');
+                                                       if (vptr)
+                                                               vlen = vptr - val;
+                                                       vptr = val;
+                                                       break;
+                                               case E_All:
+                                                       break;
                                                }
 #ifdef DEBUG
                                        /*dlog("Expanding \"%s\" to \"%s\"", nbuf, val);*/
                                                }
 #ifdef DEBUG
                                        /*dlog("Expanding \"%s\" to \"%s\"", nbuf, val);*/
@@ -549,33 +621,7 @@ out:
                *p->opt = strdup(expbuf);
        }
 
                *p->opt = strdup(expbuf);
        }
 
-       /*
-        * Normalize slashes in the string.
-        */
-       { char *f = strchr(*p->opt, '/');
-         if (f) {
-               char *t = f;
-               do {
-                       /* assert(*f == '/'); */
-                       /* copy a single / across */
-                       *t++ = *f++;
-
-                       /* assert(f[-1] == '/'); */
-                       /* skip past more /'s */
-                       while (*f == '/')
-                               f++;
-
-                       /* assert(*f != '/'); */
-                       /* keep copying up to next / */
-                       do {
-                               *t++ = *f++;
-                       } while (*f && *f != '/');
-
-                       /* assert(*f == 0 || *f == '/'); */
-
-               } while (*f);
-         }
-       }
+       normalize_slash(*p->opt);
 
 #ifdef DEBUG
        Debug(D_STR) {
 
 #ifdef DEBUG
        Debug(D_STR) {
@@ -652,14 +698,16 @@ char *key;
 }
 
 /*
 }
 
 /*
- * Remove trailing / from a string
+ * Remove trailing /'s from a string
+ * unless the string is a single / (Steven Glassman)
  */
  */
-static void deslashify(s)
+void deslashify P((char *s));
+void deslashify(s)
 char *s;
 {
 char *s;
 {
-       if (s) {
-               char *sl = strrchr(s, '/');
-               if (sl && sl[1] == '\0')
+       if (s && *s) {
+               char *sl = s + strlen(s);
+               while (*--sl == '/' && sl > s)
                        *sl = '\0';
        }
 }
                        *sl = '\0';
        }
 }
@@ -699,13 +747,13 @@ char *opts, *g_opts, *path, *key, *map;
        /*
         * Expand default (global) options
         */
        /*
         * Expand default (global) options
         */
-       if (!eval_opts(fs_static.fs_glob))
+       if (!eval_opts(fs_static.fs_glob, key))
                ok = FALSE;
 
        /*
         * Expand local options
         */
                ok = FALSE;
 
        /*
         * Expand local options
         */
-       if (ok && !eval_opts(fs_static.fs_local))
+       if (ok && !eval_opts(fs_static.fs_local, key))
                ok = FALSE;
 
        /*
                ok = FALSE;
 
        /*
index 47ad49c..e1f93d0 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: pfs_ops.c,v 5.2 90/06/23 22:19:53 jsp Rel $
+ * $Id: pfs_ops.c,v 5.2.1.1 90/10/21 22:29:36 jsp Exp $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)pfs_ops.c   5.1 (Berkeley) %G%
+ *     @(#)pfs_ops.c   5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
 /*
  * Execute needs a mount and unmount command.
  */
 /*
  * Execute needs a mount and unmount command.
  */
-static int pfs_match(fo)
+static char *pfs_match(fo)
 am_opts *fo;
 {
        char *prog;
        if (!fo->opt_mount || !fo->opt_unmount) {
                plog(XLOG_USER, "program: no mount/unmount specified");
 am_opts *fo;
 {
        char *prog;
        if (!fo->opt_mount || !fo->opt_unmount) {
                plog(XLOG_USER, "program: no mount/unmount specified");
-               return FALSE;
+               return 0;
        }
        prog = strchr(fo->opt_mount, ' ');
        }
        prog = strchr(fo->opt_mount, ' ');
-       if (fo->fs_mtab = strealloc(fo->fs_mtab, prog ? prog+1 : fo->opt_mount))
-               return TRUE;
-       return FALSE;
+       return strdup(prog ? prog+1 : fo->opt_mount);
 }
 
 static int pfs_init(mf)
 }
 
 static int pfs_init(mf)
@@ -63,7 +61,7 @@ char *info;
        info = strdup(info);
        if (info == 0)
                return ENOBUFS;
        info = strdup(info);
        if (info == 0)
                return ENOBUFS;
-       xivec = strsplit(info, '\'');
+       xivec = strsplit(info, ' ', '\'');
        /*
         * Put stdout to stderr
         */
        /*
         * Put stdout to stderr
         */
@@ -101,27 +99,23 @@ char *info;
        /*
         * Free allocate memory
         */
        /*
         * Free allocate memory
         */
-       free(info);
-       free(xivec);
+       free((voidp) info);
+       free((voidp) xivec);
        /*
         * Return error
         */
        return error;
 }
 
        /*
         * Return error
         */
        return error;
 }
 
-static int pfs_mount(mp)
-am_node *mp;
+static int pfs_fmount(mf)
+mntfs *mf;
 {
 {
-       mntfs *mf = mp->am_mnt;
-
        return pfs_exec(mf->mf_fo->opt_mount);
 }
 
        return pfs_exec(mf->mf_fo->opt_mount);
 }
 
-static int pfs_umount(mp)
-am_node *mp;
+static int pfs_fumount(mf)
+mntfs *mf;
 {
 {
-       mntfs *mf = mp->am_mnt;
-
        return pfs_exec((char *) mf->mf_private);
 }
 
        return pfs_exec((char *) mf->mf_private);
 }
 
@@ -132,8 +126,10 @@ am_ops pfs_ops = {
        "program",
        pfs_match,
        pfs_init,
        "program",
        pfs_match,
        pfs_init,
-       pfs_mount,
-       pfs_umount,
+       auto_fmount,
+       pfs_fmount,
+       auto_fumount,
+       pfs_fumount,
        efs_lookuppn,
        efs_readdir,
        0, /* pfs_readlink */
        efs_lookuppn,
        efs_readdir,
        0, /* pfs_readlink */
index 8773356..ad2e903 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: restart.c,v 5.2 90/06/23 22:19:55 jsp Rel $
+ * $Id: restart.c,v 5.2.1.2 90/11/04 23:17:27 jsp Exp $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)restart.c   5.1 (Berkeley) %G%
+ *     @(#)restart.c   5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -103,20 +103,22 @@ void restart()
                                me->mnt_fsname = str3cat(me->mnt_fsname, mo.opt_rhost, ":", "/");
                        }
                        mo.opt_fs = me->mnt_dir;
                                me->mnt_fsname = str3cat(me->mnt_fsname, mo.opt_rhost, ":", "/");
                        }
                        mo.opt_fs = me->mnt_dir;
+                       mo.opt_opts = me->mnt_opts;
 
                        /*
                         * Make a new mounted filesystem
                         */
                        mf = find_mntfs(fs_ops, &mo, me->mnt_dir,
 
                        /*
                         * Make a new mounted filesystem
                         */
                        mf = find_mntfs(fs_ops, &mo, me->mnt_dir,
-                               me->mnt_fsname, me->mnt_opts);
+                               me->mnt_fsname, "", me->mnt_opts);
                        if (mf->mf_refc == 1) {
                                mf->mf_flags |= MFF_RESTART|MFF_MOUNTED;
                                mf->mf_error = 0;       /* Already mounted correctly */
                        if (mf->mf_refc == 1) {
                                mf->mf_flags |= MFF_RESTART|MFF_MOUNTED;
                                mf->mf_error = 0;       /* Already mounted correctly */
+                               mf->mf_fo = 0;
                                /*
                                 * If the restarted type is a link then
                                 * don't time out.
                                 */
                                /*
                                 * If the restarted type is a link then
                                 * don't time out.
                                 */
-                               if (fs_ops == &sfs_ops)
+                               if (fs_ops == &sfs_ops || fs_ops == &ufs_ops)
                                        mf->mf_flags |= MFF_RSTKEEP;
                                if (fs_ops->fs_init) {
                                        /*
                                        mf->mf_flags |= MFF_RSTKEEP;
                                if (fs_ops->fs_init) {
                                        /*
index d096acf..8c1db46 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: rpc_fwd.c,v 5.2 90/06/23 22:19:57 jsp Rel $
+ * $Id: rpc_fwd.c,v 5.2.1.2 91/03/03 20:46:57 jsp Alpha $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)rpc_fwd.c   5.1 (Berkeley) %G%
+ *     @(#)rpc_fwd.c   5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -134,7 +134,7 @@ rpc_forward *p;
 #ifdef DEBUG
        /*dlog("fwd_free: rpc_head = %#x", rpc_head.q_forw);*/
 #endif /* DEBUG */
 #ifdef DEBUG
        /*dlog("fwd_free: rpc_head = %#x", rpc_head.q_forw);*/
 #endif /* DEBUG */
-       free(p);
+       free((voidp) p);
 }
 
 /*
 }
 
 /*
@@ -266,7 +266,9 @@ fwd_fun cb;
         * rest of "p" otherwise nasty things happen later...
         */
 #ifdef DEBUG
         * rest of "p" otherwise nasty things happen later...
         */
 #ifdef DEBUG
-       dlog("Sending packet id %#x to %#08x.%04x", p->rf_xid, ntohl(fwdto->sin_addr.s_addr), ntohs(fwdto->sin_port));
+       { char dq[20]; 
+       dlog("Sending packet id %#x to %s.%d", p->rf_xid, inet_dquad(dq, fwdto->sin_addr.s_addr), ntohs(fwdto->sin_port));
+       }
 #endif /* DEBUG */
        if (sendto(fwd_sock, (char *) pkt, len, 0,
                        (struct sockaddr *) fwdto, sizeof(*fwdto)) < 0)
 #endif /* DEBUG */
        if (sendto(fwd_sock, (char *) pkt, len, 0,
                        (struct sockaddr *) fwdto, sizeof(*fwdto)) < 0)
@@ -383,7 +385,7 @@ again:
                /*
                 * Call forwarding function
                 */
                /*
                 * Call forwarding function
                 */
-               (*p->rf_fwd)(pkt, rc, &src_addr, &p->rf_sin, p->rf_ptr, TRUE);
+               (*p->rf_fwd)((voidp) pkt, rc, &src_addr, &p->rf_sin, p->rf_ptr, TRUE);
        }
 
        /*
        }
 
        /*
@@ -396,6 +398,6 @@ out:;
        /*
         * Free the packet
         */
        /*
         * Free the packet
         */
-       free(pkt);
+       free((voidp) pkt);
 #endif /* DYNAMIC_BUFFERS */
 }
 #endif /* DYNAMIC_BUFFERS */
 }
index cdacbec..8c03107 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: sched.c,v 5.2 90/06/23 22:19:58 jsp Rel $
+ * $Id: sched.c,v 5.2.1.3 91/03/17 17:42:03 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)sched.c     5.1 (Berkeley) %G%
+ *     @(#)sched.c     5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -171,7 +171,7 @@ int sig;
 #ifdef SYS5_SIGNALS
        if ((pid = wait(&w)) > 0) {
 #else
 #ifdef SYS5_SIGNALS
        if ((pid = wait(&w)) > 0) {
 #else
-       while ((pid = wait3(&w, WNOHANG, (union wait *) 0)) > 0) {
+       while ((pid = wait3((int *) &w, WNOHANG, (struct rusage *) 0)) > 0) {
 #endif /* SYS5_SIGNALS */
                pjob *p, *p2;
 
 #endif /* SYS5_SIGNALS */
                pjob *p, *p2;
 
@@ -203,14 +203,14 @@ int sig;
        signal(sig, sigchld);
 #endif /* SYS5_SIGNALS */
        if (select_intr_valid)
        signal(sig, sigchld);
 #endif /* SYS5_SIGNALS */
        if (select_intr_valid)
-               longjmp(select_intr, sigchld);
+               longjmp(select_intr, sig);
 }
 
 /*
  * Run any pending tasks.
  * This must be called with SIGCHLD disabled
  */
 }
 
 /*
  * Run any pending tasks.
  * This must be called with SIGCHLD disabled
  */
-void task_notify(P_void)
+void do_task_notify(P_void)
 {
        /*
         * Keep taking the first item off the list and processing it.
 {
        /*
         * Keep taking the first item off the list and processing it.
@@ -234,6 +234,6 @@ void task_notify(P_void)
                        (*p->cb_fun)(p->w.w_retcode,
                                p->w.w_termsig, p->cb_closure);
 
                        (*p->cb_fun)(p->w.w_retcode,
                                p->w.w_termsig, p->cb_closure);
 
-               free(p);
+               free((voidp) p);
        }
 }
        }
 }
index 7c0f2cc..4088966 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: sfs_ops.c,v 5.2 90/06/23 22:19:59 jsp Rel $
+ * $Id: sfs_ops.c,v 5.2.1.2 90/12/21 16:41:47 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)sfs_ops.c   5.1 (Berkeley) %G%
+ *     @(#)sfs_ops.c   5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -25,7 +25,7 @@
 /*
  * SFS needs a link.
  */
 /*
  * SFS needs a link.
  */
-static int sfs_match(fo)
+static char *sfs_match(fo)
 am_opts *fo;
 {
        if (!fo->opt_fs) {
 am_opts *fo;
 {
        if (!fo->opt_fs) {
@@ -63,18 +63,15 @@ am_opts *fo;
                if (fo->opt_sublink)
                        free(fo->opt_sublink);
                fo->opt_sublink = fullpath;
                if (fo->opt_sublink)
                        free(fo->opt_sublink);
                fo->opt_sublink = fullpath;
-               free(fo->opt_fs);
-               fo->opt_fs = strdup(".");
+               fo->opt_fs = str3cat(fo->opt_fs, ".", fullpath, "");
        }
 
        }
 
-       fo->fs_mtab = strealloc(fo->fs_mtab, fo->opt_fs);
-
-       return 1;
+       return strdup(fo->opt_fs);
 }
 
 /*ARGUSED*/
 }
 
 /*ARGUSED*/
-static int sfs_mount(mp)
-am_node *mp;
+static int sfs_fmount(mf)
+mntfs *mf;
 {
        /*
         * Wow - this is hard to implement!
 {
        /*
         * Wow - this is hard to implement!
@@ -84,8 +81,8 @@ am_node *mp;
 }
 
 /*ARGUSED*/
 }
 
 /*ARGUSED*/
-static int sfs_umount(mp)
-am_node *mp;
+static int sfs_fumount(mf)
+mntfs *mf;
 {
        return 0;
 }
 {
        return 0;
 }
@@ -97,8 +94,10 @@ am_ops sfs_ops = {
        "link",
        sfs_match,
        0, /* sfs_init */
        "link",
        sfs_match,
        0, /* sfs_init */
-       sfs_mount,
-       sfs_umount,
+       auto_fmount,
+       sfs_fmount,
+       auto_fumount,
+       sfs_fumount,
        efs_lookuppn,
        efs_readdir,
        0, /* sfs_readlink */
        efs_lookuppn,
        efs_readdir,
        0, /* sfs_readlink */
index 832e697..569d9bf 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: srvr_afs.c,v 5.2 90/06/23 22:20:00 jsp Rel $
+ * $Id: srvr_afs.c,v 5.2.1.1 90/10/21 22:29:44 jsp Exp $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)srvr_afs.c  5.1 (Berkeley) %G%
+ *     @(#)srvr_afs.c  5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
index 2bd9f46..604221c 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: srvr_nfs.c,v 5.2 90/06/23 22:20:02 jsp Rel $
+ * $Id: srvr_nfs.c,v 5.2.1.3 91/03/17 17:44:37 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)srvr_nfs.c  5.1 (Berkeley) %G%
+ *     @(#)srvr_nfs.c  5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -28,7 +28,7 @@ qelem nfs_srvr_list = { &nfs_srvr_list, &nfs_srvr_list };
 
 typedef struct nfs_private {
        u_short np_mountd;      /* Mount daemon port number */
 
 typedef struct nfs_private {
        u_short np_mountd;      /* Mount daemon port number */
-       char np_mountd_inval;   /* Port may be invalid */
+       char np_mountd_inval;   /* Port *may* be invalid */
        int np_ping;            /* Number of failed ping attempts */
        time_t np_ttl;          /* Time when server is thought dead */
        int np_xid;             /* RPC transaction id for pings */
        int np_ping;            /* Number of failed ping attempts */
        time_t np_ttl;          /* Time when server is thought dead */
        int np_xid;             /* RPC transaction id for pings */
@@ -63,9 +63,27 @@ static int np_xid;   /* For NFS pings */
 static int ping_len;
 static char ping_buf[sizeof(struct rpc_msg) + 32];
 
 static int ping_len;
 static char ping_buf[sizeof(struct rpc_msg) + 32];
 
+/*
+ * Flush any cached data
+ */
+void flush_srvr_nfs_cache P((void));
+void flush_srvr_nfs_cache()
+{
+       fserver *fs = 0;
+
+       ITER(fs, fserver, &nfs_srvr_list) {
+               nfs_private *np = (nfs_private *) fs->fs_private;
+               if (np) {
+                       np->np_mountd_inval = TRUE;
+                       np->np_error = -1;
+               }
+       }
+}
+
 /*
  * Startup the NFS ping
  */
 /*
  * Startup the NFS ping
  */
+static void start_ping(P_void);
 static void start_ping()
 {
        XDR ping_xdr;
 static void start_ping()
 {
        XDR ping_xdr;
@@ -101,15 +119,22 @@ static void start_ping()
 /*
  * Called when a portmap reply arrives
  */
 /*
  * Called when a portmap reply arrives
  */
+/*ARGSUSED*/
+static void got_portmap P((voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, voidp idv, int done));
 static void got_portmap(pkt, len, sa, ia, idv, done)
 voidp pkt;
 int len;
 static void got_portmap(pkt, len, sa, ia, idv, done)
 voidp pkt;
 int len;
-struct sockaddr_in *sa, *ia;
+struct sockaddr_in *sa;
+struct sockaddr_in *ia;
 voidp idv;
 int done;
 {
        fserver *fs2 = (fserver *) idv;
        fserver *fs = 0;
 voidp idv;
 int done;
 {
        fserver *fs2 = (fserver *) idv;
        fserver *fs = 0;
+
+       /*
+        * Find which fileserver we are talking about
+        */
        ITER(fs, fserver, &nfs_srvr_list)
                if (fs == fs2)
                        break;
        ITER(fs, fserver, &nfs_srvr_list)
                if (fs == fs2)
                        break;
@@ -156,6 +181,7 @@ int done;
 /*
  * Obtain portmap information
  */
 /*
  * Obtain portmap information
  */
+static int call_portmap P((fserver *fs, AUTH *auth, unsigned long prog, unsigned long vers, unsigned long prot));
 static int call_portmap(fs, auth, prog, vers, prot)
 fserver *fs;
 AUTH *auth;
 static int call_portmap(fs, auth, prog, vers, prot)
 fserver *fs;
 AUTH *auth;
@@ -210,16 +236,20 @@ fserver *fs;
  * structure when the ping was transmitted.
  */
 /*ARGSUSED*/
  * structure when the ping was transmitted.
  */
 /*ARGSUSED*/
+static void nfs_pinged P((voidp pkt, int len, struct sockaddr_in *sp, struct sockaddr_in *tsp, voidp idv, int done));
 static void nfs_pinged(pkt, len, sp, tsp, idv, done)
 voidp pkt;
 int len;
 static void nfs_pinged(pkt, len, sp, tsp, idv, done)
 voidp pkt;
 int len;
-struct sockaddr_in *sp, *tsp;
+struct sockaddr_in *sp;
+struct sockaddr_in *tsp;
 voidp idv;
 int done;
 {
        int xid = (int) idv;
        fserver *fs;
 voidp idv;
 int done;
 {
        int xid = (int) idv;
        fserver *fs;
+#ifdef DEBUG
        int found_map = 0;
        int found_map = 0;
+#endif /* DEBUG */
 
        if (!done)
                return;
 
        if (!done)
                return;
@@ -240,7 +270,12 @@ int done;
                                if (fs->fs_flags & FSF_VALID) {
                                        srvrlog(fs, "is up");
                                } else {
                                if (fs->fs_flags & FSF_VALID) {
                                        srvrlog(fs, "is up");
                                } else {
-                                       srvrlog(fs, "ok");
+                                       if (np->np_ping > 1)
+                                               srvrlog(fs, "ok");
+#ifdef DEBUG
+                                       else
+                                               srvrlog(fs, "starts up");
+#endif
                                        fs->fs_flags |= FSF_VALID;
                                }
 
                                        fs->fs_flags |= FSF_VALID;
                                }
 
@@ -255,7 +290,8 @@ int done;
                                        dlog("file server %s type nfs is still up", fs->fs_host);
 #endif /* DEBUG */
                                } else {
                                        dlog("file server %s type nfs is still up", fs->fs_host);
 #endif /* DEBUG */
                                } else {
-                                       srvrlog(fs, "ok");
+                                       if (np->np_ping > 1)
+                                               srvrlog(fs, "ok");
                                        fs->fs_flags |= FSF_VALID;
                                }
                        }
                                        fs->fs_flags |= FSF_VALID;
                                }
                        }
@@ -288,7 +324,9 @@ int done;
                        if (np->np_mountd_inval)
                                recompute_portmap(fs);
 
                        if (np->np_mountd_inval)
                                recompute_portmap(fs);
 
+#ifdef DEBUG   
                        found_map++;
                        found_map++;
+#endif /* DEBUG */
                        break;
                }
        }
                        break;
                }
        }
@@ -308,19 +346,20 @@ fserver *fs;
 {
        nfs_private *np = (nfs_private *) fs->fs_private;
 
 {
        nfs_private *np = (nfs_private *) fs->fs_private;
 
+       /*
+        * Another ping has failed
+        */
+       np->np_ping++;
+
        /*
         * Not known to be up any longer
         */
        if (FSRV_ISUP(fs)) {
                fs->fs_flags &= ~FSF_VALID;
        /*
         * Not known to be up any longer
         */
        if (FSRV_ISUP(fs)) {
                fs->fs_flags &= ~FSF_VALID;
-               srvrlog(fs, "not responding");
+               if (np->np_ping > 1)
+                       srvrlog(fs, "not responding");
        }
 
        }
 
-       /*
-        * Another ping has failed
-        */
-       np->np_ping++;
-
        /*
         * If ttl has expired then guess that it is dead
         */
        /*
         * If ttl has expired then guess that it is dead
         */
@@ -331,8 +370,6 @@ fserver *fs;
                         */
                        srvrlog(fs, "is down");
                        fs->fs_flags |= FSF_DOWN|FSF_VALID;
                         */
                        srvrlog(fs, "is down");
                        fs->fs_flags |= FSF_DOWN|FSF_VALID;
-                       if (fs->fs_flags & FSF_WANT)
-                               wakeup_srvr(fs);
                        /*
                         * Since the server is down, the portmap
                         * information may now be wrong, so it
                        /*
                         * Since the server is down, the portmap
                         * information may now be wrong, so it
@@ -340,16 +377,23 @@ fserver *fs;
                         */
                        flush_nfs_fhandle_cache(fs);
                        np->np_error = -1;
                         */
                        flush_nfs_fhandle_cache(fs);
                        np->np_error = -1;
+#ifdef notdef
                        /*
                         * Pretend just one ping has failed now
                         */
                        np->np_ping = 1;
                        /*
                         * Pretend just one ping has failed now
                         */
                        np->np_ping = 1;
+#endif
                } else {
                        /*
                         * Known to be down
                         */
                        fs->fs_flags |= FSF_VALID;
                } else {
                        /*
                         * Known to be down
                         */
                        fs->fs_flags |= FSF_VALID;
+#ifdef DEBUG
+                       srvrlog(fs, "starts down");
+#endif
                }
                }
+               if (fs->fs_flags & FSF_WANT)
+                       wakeup_srvr(fs);
        } else {
 #ifdef DEBUG
                if (np->np_ping > 1)
        } else {
 #ifdef DEBUG
                if (np->np_ping > 1)
@@ -442,6 +486,7 @@ fserver *fs;
        fs->fs_cid = timeout(fstimeo, nfs_timed_out, (voidp) fs);
 }
 
        fs->fs_cid = timeout(fstimeo, nfs_timed_out, (voidp) fs);
 }
 
+int nfs_srvr_port P((fserver *fs, u_short *port, voidp wchan));
 int nfs_srvr_port(fs, port, wchan)
 fserver *fs;
 u_short *port;
 int nfs_srvr_port(fs, port, wchan)
 fserver *fs;
 u_short *port;
@@ -453,16 +498,21 @@ voidp wchan;
                        nfs_private *np = (nfs_private *) fs->fs_private;
                        if (np->np_error == 0) {
                                *port = np->np_mountd;
                        nfs_private *np = (nfs_private *) fs->fs_private;
                        if (np->np_error == 0) {
                                *port = np->np_mountd;
-                               /*
-                                * Now go get it again in case it changed
-                                */
-                               np->np_mountd_inval = TRUE;
                                error = 0;
                        } else {
                                error = 0;
                        } else {
-                               if (np->np_error < 0)
-                                       recompute_portmap(fs);
                                error = np->np_error;
                        }
                                error = np->np_error;
                        }
+                       /*
+                        * Now go get the port mapping again in case it changed.
+                        * Note that it is used even if (np_mountd_inval)
+                        * is True.  The flag is used simply as an
+                        * indication that the mountd may be invalid, not
+                        * that it is known to be invalid.
+                        */
+                       if (np->np_mountd_inval)
+                               recompute_portmap(fs);
+                       else
+                               np->np_mountd_inval = TRUE;
                } else {
                        error = EWOULDBLOCK;
                }
                } else {
                        error = EWOULDBLOCK;
                }
@@ -526,7 +576,7 @@ mntfs *mf;
         * are required or not.  < 0 = no pings.
         */
        { struct mntent mnt;
         * are required or not.  < 0 = no pings.
         */
        { struct mntent mnt;
-         mnt.mnt_opts = mf->mf_fo->opt_opts;
+         mnt.mnt_opts = mf->mf_mopts;
          pingval = hasmntval(&mnt, "ping");
 #ifdef HAS_TCP_NFS
          /*
          pingval = hasmntval(&mnt, "ping");
 #ifdef HAS_TCP_NFS
          /*
@@ -540,11 +590,20 @@ mntfs *mf;
        }
 
 
        }
 
 
-top:
        /*
        /*
-        * Scan the list of known servers looking
-        * for one with the same name
+        * lookup host address and canonical name
+        */
+       hp = gethostbyname(host);
+
+       /*
+        * New code from Bob Harris <harris@basil-rathbone.mit.edu>
+        * Use canonical name to keep track of file server
+        * information.  This way aliases do not generate
+        * multiple NFS pingers.  (Except when we're normalizing
+        * hosts.)
         */
         */
+       if (hp && !normalize_hosts) host = hp->h_name;
+
        ITER(fs, fserver, &nfs_srvr_list) {
                if (STREQ(host, fs->fs_host)) {
                        start_nfs_pings(fs, pingval);
        ITER(fs, fserver, &nfs_srvr_list) {
                if (STREQ(host, fs->fs_host)) {
                        start_nfs_pings(fs, pingval);
@@ -553,22 +612,7 @@ top:
                }
        }
 
                }
        }
 
-       /*
-        * If the name is not known, it may be
-        * because it was an alternate name for
-        * the same machine.  So do a lookup and
-        * try again with the primary name if that
-        * is different.
-        * All that assuming it wasn't normalized
-        * earlier of course...
-        */
-       if (hp == 0) {
-               hp = gethostbyname(host);
-               if (hp && !STREQ(host, hp->h_name) && !normalize_hosts) {
-                       host = hp->h_name;
-                       goto top;
-               }
-       }
+
 
        /*
         * Get here if we can't find an entry
 
        /*
         * Get here if we can't find an entry
@@ -579,7 +623,8 @@ top:
                        ip = ALLOC(sockaddr_in);
                        bzero((voidp) ip, sizeof(*ip));
                        ip->sin_family = AF_INET;
                        ip = ALLOC(sockaddr_in);
                        bzero((voidp) ip, sizeof(*ip));
                        ip->sin_family = AF_INET;
-                       ip->sin_addr = *(struct in_addr *) hp->h_addr;
+                       bcopy((voidp) hp->h_addr, (voidp) &ip->sin_addr, sizeof(ip->sin_addr));
+
                        ip->sin_port = htons(NFS_PORT);
                        break;
 
                        ip->sin_port = htons(NFS_PORT);
                        break;
 
@@ -588,6 +633,7 @@ top:
                        break;
                }
        } else {
                        break;
                }
        } else {
+               plog(XLOG_USER, "Unknown host: %s", host);
                ip = 0;
        }
 
                ip = 0;
        }
 
@@ -597,7 +643,7 @@ top:
        fs = ALLOC(fserver);
        fs->fs_refc = 1;
        fs->fs_host = strdup(hp ? hp->h_name : "unknown_hostname");
        fs = ALLOC(fserver);
        fs->fs_refc = 1;
        fs->fs_host = strdup(hp ? hp->h_name : "unknown_hostname");
-       host_normalize(&fs->fs_host);
+       if (normalize_hosts) host_normalize(&fs->fs_host);
        fs->fs_ip = ip;
        fs->fs_cid = 0;
        if (ip) {
        fs->fs_ip = ip;
        fs->fs_cid = 0;
        if (ip) {
index fdfdf6a..165cbd3 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: ufs_ops.c,v 5.2 90/06/23 22:20:03 jsp Rel $
+ * $Id: ufs_ops.c,v 5.2.1.1 90/10/21 22:29:47 jsp Exp $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)ufs_ops.c   5.1 (Berkeley) %G%
+ *     @(#)ufs_ops.c   5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
 #ifdef NFS_3
 typedef nfs_fh fhandle_t;
 #endif /* NFS_3 */
 #ifdef NFS_3
 typedef nfs_fh fhandle_t;
 #endif /* NFS_3 */
-#include <sys/mount.h>
 
 #ifdef UFS_HDR
 #include UFS_HDR
 #endif /* UFS_HDR */
 
 
 #ifdef UFS_HDR
 #include UFS_HDR
 #endif /* UFS_HDR */
 
+#include <sys/mount.h>
+
 /*
  * UN*X file system
  */
 /*
  * UN*X file system
  */
@@ -35,23 +36,24 @@ typedef nfs_fh fhandle_t;
 /*
  * UFS needs local filesystem and device.
  */
 /*
  * UFS needs local filesystem and device.
  */
-static int ufs_match(fo)
+static char *ufs_match P((am_opts *fo));
+static char *ufs_match(fo)
 am_opts *fo;
 {
        if (!fo->opt_dev) {
                plog(XLOG_USER, "ufs: no device specified");
                return 0;
        }
 am_opts *fo;
 {
        if (!fo->opt_dev) {
                plog(XLOG_USER, "ufs: no device specified");
                return 0;
        }
-       /*
-        * Determine magic cookie to put in mtab
-        */
-       fo->fs_mtab = strealloc(fo->fs_mtab, fo->opt_dev);
+
 #ifdef DEBUG
        dlog("UFS: mounting device \"%s\" on \"%s\"",
                fo->opt_dev, fo->opt_fs);
 #endif /* DEBUG */
 
 #ifdef DEBUG
        dlog("UFS: mounting device \"%s\" on \"%s\"",
                fo->opt_dev, fo->opt_fs);
 #endif /* DEBUG */
 
-       return 1;
+       /*
+        * Determine magic cookie to put in mtab
+        */
+       return strdup(fo->opt_dev);
 }
 
 static mount_ufs(dir, fs_name, opts)
 }
 
 static mount_ufs(dir, fs_name, opts)
@@ -101,14 +103,12 @@ char *opts;
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
-static int ufs_mount(mp)
-am_node *mp;
+static int ufs_fmount(mf)
+mntfs *mf;
 {
 {
-       mntfs *mf = mp->am_mnt;
-
        int error;
 
        int error;
 
-       error = mount_ufs(mf->mf_mount, mf->mf_info, mf->mf_fo->opt_opts);
+       error = mount_ufs(mf->mf_mount, mf->mf_info, mf->mf_mopts);
        if (error) {
                errno = error;
                plog(XLOG_ERROR, "mount_ufs: %m");
        if (error) {
                errno = error;
                plog(XLOG_ERROR, "mount_ufs: %m");
@@ -118,11 +118,9 @@ am_node *mp;
        return 0;
 }
 
        return 0;
 }
 
-static int ufs_umount(mp)
-am_node *mp;
+static int ufs_fumount(mf)
+mntfs *mf;
 {
 {
-       mntfs *mf = mp->am_mnt;
-
        return UMOUNT_FS(mf->mf_mount);
 }
 
        return UMOUNT_FS(mf->mf_mount);
 }
 
@@ -133,8 +131,10 @@ am_ops ufs_ops = {
        "ufs",
        ufs_match,
        0, /* ufs_init */
        "ufs",
        ufs_match,
        0, /* ufs_init */
-       ufs_mount,
-       ufs_umount,
+       auto_fmount,
+       ufs_fmount,
+       auto_fumount,
+       ufs_fumount,
        efs_lookuppn,
        efs_readdir,
        0, /* ufs_readlink */
        efs_lookuppn,
        efs_readdir,
        0, /* ufs_readlink */
index 2ba551b..e892735 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: umount_fs.c,v 5.2 90/06/23 22:20:04 jsp Rel $
+ * $Id: umount_fs.c,v 5.2.1.2 91/03/03 20:34:23 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)umount_fs.c 5.1 (Berkeley) %G%
+ *     @(#)umount_fs.c 5.2 (Berkeley) %G%
  */
 
 #include "am.h"
  */
 
 #include "am.h"
@@ -20,6 +20,7 @@
 
 #include <sys/mount.h>         /* For MNT_NOFORCE */
 
 
 #include <sys/mount.h>         /* For MNT_NOFORCE */
 
+int umount_fs P((char *fs_name));
 int umount_fs(fs_name)
 char *fs_name;
 {
 int umount_fs(fs_name)
 char *fs_name;
 {
@@ -33,14 +34,11 @@ eintr:
        switch (error) {
        case EINVAL:
        case ENOTBLK:
        switch (error) {
        case EINVAL:
        case ENOTBLK:
+       case ENOENT:
                plog(XLOG_WARNING, "unmount: %s is not mounted", fs_name);
                error = 0;      /* Not really an error */
                break;
 
                plog(XLOG_WARNING, "unmount: %s is not mounted", fs_name);
                error = 0;      /* Not really an error */
                break;
 
-       case ENOENT:
-               plog(XLOG_ERROR, "mount point %s: %m", fs_name);
-               break;
-
        case EINTR:
 #ifdef DEBUG
                /* not sure why this happens, but it does.  ask kirk one day... */
        case EINTR:
 #ifdef DEBUG
                /* not sure why this happens, but it does.  ask kirk one day... */
index 0b50bca..e8dbad8 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: util.c,v 5.2 90/06/23 22:20:06 jsp Rel $
+ * $Id: util.c,v 5.2.1.4 91/03/17 17:44:16 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)util.c      5.1 (Berkeley) %G%
+ *     @(#)util.c      5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
  */
 
 #include "am.h"
  */
 
 #include "am.h"
-#ifdef HAS_SYSLOG
-#include <syslog.h>
-#endif /* HAS_SYSLOG */
 #include <ctype.h>
 #include <sys/stat.h>
 #include <ctype.h>
 #include <sys/stat.h>
-
 #include <netdb.h>
 
 
 #include <netdb.h>
 
 
-INLINE
 char *strnsave(str, len)
 char *strnsave(str, len)
-const char *str;
+Const char *str;
 int len;
 {
        char *sp = (char *) xmalloc(len+1);
 int len;
 {
        char *sp = (char *) xmalloc(len+1);
@@ -42,7 +37,7 @@ int len;
 }
 
 char *strdup(s)
 }
 
 char *strdup(s)
-const char *s;
+Const char *s;
 {
        return strnsave(s, strlen(s));
 }
 {
        return strnsave(s, strlen(s));
 }
@@ -82,29 +77,10 @@ char *s;
        return p;
 }
 
        return p;
 }
 
-voidp xrealloc(ptr, len)
-voidp ptr;
-int len;
-{
-#if defined(DEBUG) && defined(DEBUG_MEM)
-       Debug(D_MEM) plog(XLOG_DEBUG, "Reallocated size %d; block %#x", len, ptr);
-#endif /* defined(DEBUG) && defined(DEBUG_MEM) */
-
-       if (ptr)
-               ptr = (voidp) realloc(ptr, (unsigned) len);
-       else
-               ptr = (voidp) xmalloc((unsigned) len);
-
-       if (!ptr) {
-               plog(XLOG_FATAL, "Out of memory in realloc");
-               going_down(1);
-               abort();
-       }
-       return ptr;
-}
-
-char **strsplit(s, qc)
+char **strsplit P((char *s, int ch, int qc));
+char **strsplit(s, ch, qc)
 char *s;
 char *s;
+int ch;
 int qc;
 {
        char **ivec;
 int qc;
 {
        char **ivec;
@@ -116,10 +92,10 @@ int qc;
        while (!done) {
                char *v;
                /*
        while (!done) {
                char *v;
                /*
-                * skip white space
+                * skip to split char
                 */
                 */
-               while (*s && isascii(*s) && isspace(*s))
-                       s++;
+               while (*s && (ch == ' ' ? (isascii(*s) && isspace(*s)) : *s == ch))
+                               s++;
 
                /*
                 * End of string?
 
                /*
                 * End of string?
@@ -133,9 +109,9 @@ int qc;
                v = s;
 
                /*
                v = s;
 
                /*
-                * skip to white space
+                * skip to split char
                 */
                 */
-               while (*s && (!isascii(*s) || !isspace(*s))) {
+               while (*s && !(ch == ' ' ? (isascii(*s) && isspace(*s)) : *s == ch)) {
                        if (*s++ == qc) {
                                /*
                                 * Skip past string.
                        if (*s++ == qc) {
                                /*
                                 * Skip past string.
@@ -156,7 +132,7 @@ int qc;
                 * save string in new ivec slot
                 */
                ivec[ic++] = v;
                 * save string in new ivec slot
                 */
                ivec[ic++] = v;
-               ivec = (char **) xrealloc(ivec, (ic+1)*sizeof(char *));
+               ivec = (char **) xrealloc((voidp) ivec, (ic+1)*sizeof(char *));
 #ifdef DEBUG
                Debug(D_STR)
                        plog(XLOG_DEBUG, "strsplit saved \"%s\"", v);
 #ifdef DEBUG
                Debug(D_STR)
                        plog(XLOG_DEBUG, "strsplit saved \"%s\"", v);
@@ -188,6 +164,7 @@ static void domain_strip P((char *otherdom, char *localdom));
 static void domain_strip(otherdom, localdom)
 char *otherdom, *localdom;
 {
 static void domain_strip(otherdom, localdom)
 char *otherdom, *localdom;
 {
+#ifdef PARTIAL_DOMAINS
         char *p1 = otherdom-1;
        char *p2 = localdom-1;
 
         char *p1 = otherdom-1;
        char *p2 = localdom-1;
 
@@ -199,6 +176,14 @@ char *otherdom, *localdom;
                         break;
                 }
         } while (p1 && p2);
                         break;
                 }
         } while (p1 && p2);
+#else
+       char *p1, *p2;
+
+       if ((p1 = strchr(otherdom, '.')) &&
+                       (p2 = strchr(localdom, '.')) &&
+                       (strcmp(p1+1, p2+1) == 0))
+               *p1 = '\0';
+#endif /* PARTIAL_DOMAINS */
 }
 
 /*
 }
 
 /*
@@ -227,6 +212,25 @@ char **chp;
        domain_strip(*chp, hostd);
 }
 
        domain_strip(*chp, hostd);
 }
 
+/*
+ * Make a dotted quad from a 32bit IP address
+ * addr is in network byte order.
+ * sizeof(buf) needs to be at least 16.
+ */
+char *inet_dquad P((char *buf, unsigned long addr));
+char *inet_dquad(buf, addr)
+char *buf;
+unsigned long addr;
+{
+       addr = ntohl(addr);
+       sprintf(buf, "%d.%d.%d.%d",
+               ((addr >> 24) & 0xff),
+               ((addr >> 16) & 0xff),
+               ((addr >> 8) & 0xff),
+               ((addr >> 0) & 0xff));
+       return buf;
+}
+
 /*
  * Keys are not allowed to contain " ' ! or ; to avoid
  * problems with macro expansions.
 /*
  * Keys are not allowed to contain " ' ! or ; to avoid
  * problems with macro expansions.
@@ -264,167 +268,6 @@ int rc;
        exit(rc);
 }
 
        exit(rc);
 }
 
-#ifdef DEBUG_MEM
-static int mem_bytes;
-static int orig_mem_bytes;
-static void checkup_mem(P_void)
-{
-extern struct mallinfo __mallinfo;
-       if (mem_bytes != __mallinfo.uordbytes) {
-               if (orig_mem_bytes == 0)
-                       mem_bytes = orig_mem_bytes = __mallinfo.uordbytes;
-               else {
-                       fprintf(logfp, "%s[%d]: ", progname, mypid);
-                       if (mem_bytes < __mallinfo.uordbytes) {
-                               fprintf(logfp, "ALLOC: %d bytes",
-                                       __mallinfo.uordbytes - mem_bytes);
-                       } else {
-                               fprintf(logfp, "FREE: %d bytes",
-                                       mem_bytes - __mallinfo.uordbytes);
-                       }
-                       mem_bytes = __mallinfo.uordbytes;
-                       fprintf(logfp, ", making %d missing\n",
-                               mem_bytes - orig_mem_bytes);
-               }
-       }
-       malloc_verify();
-}
-#endif /* DEBUG_MEM */
-
-/*
- * Take a log format string and expand occurences of %m
- * with the current error code take from errno.
- */
-INLINE
-static void expand_error(f, e)
-char *f;
-char *e;
-{
-       extern int sys_nerr;
-       extern char *sys_errlist[];
-       char *p;
-       int error = errno;
-
-       for (p = f; *e = *p; e++, p++) {
-               if (p[0] == '%' && p[1] == 'm') {
-                       char *errstr;
-                       if (error < 0 || error >= sys_nerr)
-                               errstr = 0;
-                       else
-                               errstr = sys_errlist[error];
-                       if (errstr)
-                               strcpy(e, errstr);
-                       else
-                               sprintf(e, "Error %d", error);
-                       e += strlen(e) - 1;
-                       p++;
-               }
-       }
-}
-
-/*
- * Output the time of day and hostname to the logfile
- */
-static void show_time_host_and_name(lvl)
-int lvl;
-{
-static time_t last_t = 0;
-static char *last_ctime = 0;
-       time_t t = clocktime();
-       char *sev;
-       extern char *ctime();
-
-#if defined(DEBUG) && defined(PARANOID)
-extern char **gargv;
-#endif /* defined(DEBUG) && defined(PARANOID) */
-
-       if (t != last_t) {
-               last_ctime = ctime(&t);
-               last_t = t;
-       }
-
-       switch (lvl) {
-       case XLOG_FATAL:        sev = "fatal:"; break;
-       case XLOG_ERROR:        sev = "error:"; break;
-       case XLOG_USER:         sev = "user: "; break;
-       case XLOG_WARNING:      sev = "warn: "; break;
-       case XLOG_INFO:         sev = "info: "; break;
-       case XLOG_DEBUG:        sev = "debug:"; break;
-       case XLOG_MAP:          sev = "map:  "; break;
-       case XLOG_STATS:        sev = "stats:"; break;
-       default:                sev = "hmm:  "; break;
-       }
-       fprintf(logfp, "%15.15s %s %s[%d]/%s ",
-               last_ctime+4, hostname,
-#if defined(DEBUG) && defined(PARANOID)
-               gargv[0],
-#else
-               progname,
-#endif /* defined(DEBUG) && defined(PARANOID) */
-               mypid,
-               sev);
-}
-
-#ifdef DEBUG
-/*VARARGS1*/
-void dplog(fmt, j,s,_,p,e,n,d,r,y)
-char *fmt;
-char *j, *s, *_, *p, *e, *n, *d, *r, *y;
-{
-       plog(XLOG_DEBUG, fmt, j,s,_,p,e,n,d,r,y);
-}
-
-#endif /* DEBUG */
-/*VARARGS1*/
-void plog(lvl, fmt, j,s,_,p,e,n,d,r,y)
-int lvl;
-char *fmt;
-char *j, *s, *_, *p, *e, *n, *d, *r, *y;
-{
-       char msg[1024];
-       char efmt[1024];
-       char *ptr = msg;
-
-       if (!(xlog_level & lvl))
-               return;
-
-#ifdef DEBUG_MEM
-       checkup_mem();
-#endif /* DEBUG_MEM */
-
-       expand_error(fmt, efmt);
-       sprintf(ptr, efmt, j,s,_,p,e,n,d,r,y);
-       ptr += strlen(ptr);
-       if (ptr[-1] == '\n')
-               *--ptr  = '\0';
-#ifdef HAS_SYSLOG
-       if (syslogging) {
-               switch(lvl) {   /* from mike <mcooper@usc.edu> */
-               case XLOG_FATAL:        lvl = LOG_CRIT; break;
-               case XLOG_ERROR:        lvl = LOG_ERR; break;
-               case XLOG_USER:         lvl = LOG_WARNING; break;
-               case XLOG_WARNING:      lvl = LOG_WARNING; break;
-               case XLOG_INFO:         lvl = LOG_INFO; break;
-               case XLOG_DEBUG:        lvl = LOG_DEBUG; break;
-               case XLOG_MAP:          lvl = LOG_DEBUG; break;
-               case XLOG_STATS:        lvl = LOG_INFO; break;
-               default:                lvl = LOG_ERR; break;
-               }
-               syslog(lvl, "%s", msg);
-               return;
-       }
-#endif /* HAS_SYSLOG */
-
-       *ptr++ = '\n';
-       *ptr = '\0';
-
-       /*
-        * Mimic syslog header
-        */
-       show_time_host_and_name(lvl);
-       fwrite(msg, ptr - msg, 1, logfp);
-       fflush(logfp);
-}
 
 int bind_resv_port P((int so, u_short *pp));
 int bind_resv_port(so, pp)
 
 int bind_resv_port P((int so, u_short *pp));
 int bind_resv_port(so, pp)
@@ -471,14 +314,48 @@ am_node *mp;
        }
 }
 
        }
 }
 
+void mf_mounted P((mntfs *mf));
+void mf_mounted(mf)
+mntfs *mf;
+{
+       int quoted;
+
+       if (!(mf->mf_flags & MFF_MOUNTED)) {
+               /*
+                * If this is a freshly mounted
+                * filesystem then update the
+                * mntfs structure...
+                */
+               mf->mf_flags |= MFF_MOUNTED;
+               mf->mf_error = 0;
+
+               /*
+                * Do mounted callback
+                */
+               if (mf->mf_ops->mounted)
+                       (*mf->mf_ops->mounted)(mf);
+
+               mf->mf_fo = 0;
+       }
+
+       /*
+        * Log message
+        */
+       quoted = strchr(mf->mf_info, ' ') != 0;
+       plog(XLOG_INFO, "%s%s%s mounted fstype %s on %s",
+               quoted ? "\"" : "",
+               mf->mf_info,
+               quoted ? "\"" : "",
+               mf->mf_ops->fs_type, mf->mf_mount);
+}
+
 void am_mounted P((am_node *mp));
 void am_mounted(mp)
 am_node *mp;
 {
        mntfs *mf = mp->am_mnt;
 void am_mounted P((am_node *mp));
 void am_mounted(mp)
 am_node *mp;
 {
        mntfs *mf = mp->am_mnt;
-       int quoted;
-       mf->mf_flags |= MFF_MOUNTED;
-       mf->mf_error = 0;
+
+       mf_mounted(mf);
 
        /*
         * Patch up path for direct mounts
 
        /*
         * Patch up path for direct mounts
@@ -495,49 +372,33 @@ am_node *mp;
                mp->am_flags |= AMF_NOTIMEOUT;
        } else {
                struct mntent mnt;
                mp->am_flags |= AMF_NOTIMEOUT;
        } else {
                struct mntent mnt;
-               mnt.mnt_opts = mf->mf_fo->opt_opts;
-               if (hasmntopt(&mnt, "nounmount"))
-                       mp->am_flags |= AMF_NOTIMEOUT;
-               if ((mp->am_timeo = hasmntval(&mnt, "utimeout")) == 0)
-                       mp->am_timeo = am_timeo;
-/*             if ((mf->mf_server->fs_pinger = hasmntval(&mnt, "ping")) == 0)
-                       mf->mf_server->fs_pinger = AM_PINGER;
-*/
+               if (mf->mf_mopts) {
+                       mnt.mnt_opts = mf->mf_mopts;
+                       if (hasmntopt(&mnt, "nounmount"))
+                               mp->am_flags |= AMF_NOTIMEOUT;
+                       if ((mp->am_timeo = hasmntval(&mnt, "utimeout")) == 0)
+                               mp->am_timeo = am_timeo;
+               }
        }
 
        }
 
-       /*
-        * Do mounted callback
-        */
-       if (mf->mf_ops->mounted)
-               (*mf->mf_ops->mounted)(mf);
-
        /*
         * If this node is a symlink then
         * compute the length of the returned string.
         */
        /*
         * If this node is a symlink then
         * compute the length of the returned string.
         */
-       if (mf->mf_fattr.type == NFLNK)
-               mf->mf_fattr.size = strlen(mp->am_link ? mp->am_link : mp->am_mnt->mf_mount);
+       if (mp->am_fattr.type == NFLNK)
+               mp->am_fattr.size = strlen(mp->am_link ? mp->am_link : mp->am_mnt->mf_mount);
 
        /*
         * Record mount time
         */
 
        /*
         * Record mount time
         */
-       mf->mf_fattr.mtime.seconds = mp->am_stats.s_mtime = clocktime();
+       mp->am_fattr.mtime.seconds = mp->am_stats.s_mtime = clocktime();
        new_ttl(mp);
        /*
         * Update mtime of parent node
         */
        if (mp->am_parent && mp->am_parent->am_mnt)
        new_ttl(mp);
        /*
         * Update mtime of parent node
         */
        if (mp->am_parent && mp->am_parent->am_mnt)
-               mp->am_parent->am_mnt->mf_fattr.mtime.seconds = mp->am_stats.s_mtime;
+               mp->am_parent->am_fattr.mtime.seconds = mp->am_stats.s_mtime;
 
 
-       /*
-        * Log message
-        */
-       quoted = strchr(mf->mf_info, ' ') != 0;
-       plog(XLOG_INFO, "%s%s%s mounted fstype %s on %s",
-               quoted ? "\"" : "",
-               mf->mf_info,
-               quoted ? "\"" : "",
-               mf->mf_ops->fs_type, mf->mf_mount);
 
        /*
         * Update stats
 
        /*
         * Update stats
@@ -587,11 +448,26 @@ am_node *mp;
         * Update mtime of parent node
         */
        if (mp->am_parent && mp->am_parent->am_mnt)
         * Update mtime of parent node
         */
        if (mp->am_parent && mp->am_parent->am_mnt)
-               mp->am_parent->am_mnt->mf_fattr.mtime.seconds = clocktime();
+               mp->am_parent->am_fattr.mtime.seconds = clocktime();
 
        free_map(mp);
 }
 
 
        free_map(mp);
 }
 
+int auto_fmount P((am_node *mp));
+int auto_fmount(mp)
+am_node *mp;
+{
+       mntfs *mf = mp->am_mnt;
+       return (*mf->mf_ops->fmount_fs)(mf);
+}
+
+int auto_fumount P((am_node *mp));
+int auto_fumount(mp)
+am_node *mp;
+{
+       mntfs *mf = mp->am_mnt;
+       return (*mf->mf_ops->fumount_fs)(mf);
+}
 
 /*
  * Fork the automounter
 
 /*
  * Fork the automounter
@@ -729,66 +605,3 @@ char *dir;
        } while (dp && dp > xdp);
        free(xdp);
 }
        } while (dp && dp > xdp);
        free(xdp);
 }
-
-/*
- * Because the internal clock is only used for
- * timing out mounts, it does not have to be
- * particularly accurate, so long as it does not run
- * ahead of the real time.  So, to reduce the system
- * call overhead, repeated calls to gettimeofday()
- * are replaced by calls to the macro clocktime().
- * If the global time (clock_valid) is zero then
- * update_clocktime() is called to obtain the real time.
- * Before any system calls that are likely to block for a
- * significant time, the clock_valid value is set
- * so that the clock is recomputed next time it is
- * needed.
- */
-
-time_t clock_valid = 0;
-#ifndef clocktime
-time_t clocktime(P_void)
-{
-       return time(&clock_valid);
-}
-#endif /* clocktime */
-
-voidp xmalloc(len)
-int len;
-{
-       voidp p;
-       int retries = 600;
-
-       do {
-               p = (voidp) malloc((unsigned) len);
-               if (p) {
-#if defined(DEBUG) && defined(DEBUG_MEM)
-                       Debug(D_MEM) plog(XLOG_DEBUG, "Allocated size %d; block %#x", len, p);
-#endif /* defined(DEBUG) && defined(DEBUG_MEM) */
-                       return p;
-               }
-               if (retries > 0) {
-                       plog(XLOG_ERROR, "Retrying memory allocation");
-                       sleep(1);
-               }
-       } while (--retries);
-
-       plog(XLOG_FATAL, "Out of memory");
-       going_down(1);
-
-       abort();
-
-       return 0;
-}
-
-#if defined(DEBUG) && defined(DEBUG_MEM)
-xfree(f, l, p)
-char *f;
-int l;
-voidp p;
-{
-       Debug(D_MEM) plog(XLOG_DEBUG, "Free in %s:%d: block %#x", f, l, p);
-#undef free
-       free(p);
-}
-#endif /* defined(DEBUG) && defined(DEBUG_MEM) */
index 814778a..206790c 100644 (file)
@@ -9,20 +9,9 @@
  * This code is derived from software contributed to Berkeley by
  * Jan-Simon Pendry at Imperial College, London.
  *
  * 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 are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Imperial College of Science, Technology and Medicine, London, UK.
- * The names of the College and University may not be used to endorse
- * or promote products derived from this software without specific
- * prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * %sccs.include.redist.c%
  *
  *
- *     @(#)wire.c      5.1 (Berkeley) %G%
+ *     @(#)wire.c      5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -172,4 +161,5 @@ char *getwire()
 {
        return strdup(NO_SUBNET);
 }
 {
        return strdup(NO_SUBNET);
 }
+ * %sccs.include.redist.c%
 #endif /* SIOCGIFFLAGS */
 #endif /* SIOCGIFFLAGS */
index 1cb8f79..4d6c9c2 100644 (file)
@@ -9,21 +9,9 @@
  * This code is derived from software contributed to Berkeley by
  * Jan-Simon Pendry at Imperial College, London.
  *
  * 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 are permitted provided
- * that: (1) source distributions retain this entire copyright notice and
- * comment, and (2) distributions including binaries display the following
- * acknowledgement:  ``This product includes software developed by the
- * University of California, Berkeley and its contributors'' in the
- * documentation or other materials provided with the distribution and in
- * all advertising materials mentioning features or use of this software.
- * Neither the name of the 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * %sccs.include.redist.c%
  *
  *
- *     @(#)xutil.c     5.1 (Berkeley) %G%
+ *     @(#)xutil.c     5.2 (Berkeley) %G%
  */
 
 #include "config.h"
  */
 
 #include "config.h"
index b4b9f7f..6e46d74 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: am.h,v 5.2 90/06/23 22:20:28 jsp Rel $
+ * $Id: am.h,v 5.2.1.5 91/03/17 17:38:03 jsp Alpha $
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)am.h        5.1 (Berkeley) %G%
+ *     @(#)am.h        5.2 (Berkeley) %G%
  */
 
  */
 
-/*
- * Get this in now so that OS_HDR can use it
- */
-#ifdef __STDC__
-#define        P(x) x
-#define        P_void void
-#else
-#define P(x) ()
-#define P_void /* as nothing */
-#define const /* as nothing */
-#endif /* __STDC__ */
-
-#ifdef __GNUC__
-#define INLINE /* __inline */
-#else
-#define        INLINE
-#endif /* __GNUC__ */
-
-/*
- * Pick up target dependent definitions
- */
-#include "os-defaults.h"
-#include OS_HDR
-
-#ifndef UPDATE_MTAB
-#define        unlock_mntlist()
-#endif /* UPDATE_MTAB */
-
-#ifdef VOIDP
-typedef void *voidp;
-#else
-typedef char *voidp;
-#endif /* VOIDP */
+#include "config.h"
 
 /*
  * Global declarations
  */
 
 /*
  * Global declarations
  */
-#include <stdio.h>
 #include <sys/param.h>
 #include <sys/param.h>
-#include <sys/errno.h>
-extern int errno;
 #include <sys/socket.h>
 #include <rpc/rpc.h>
 #include "nfs_prot.h"
 #ifdef MNTENT_HDR
 #include MNTENT_HDR
 #endif /* MNTENT_HDR */
 #include <sys/socket.h>
 #include <rpc/rpc.h>
 #include "nfs_prot.h"
 #ifdef MNTENT_HDR
 #include MNTENT_HDR
 #endif /* MNTENT_HDR */
-#include <sys/time.h>
 #include <assert.h>
 
 #ifdef DEBUG_MEM
 #include <assert.h>
 
 #ifdef DEBUG_MEM
@@ -94,64 +58,12 @@ extern int restart_existing_mounts;
 #ifdef HAS_NIS_MAPS
 extern char *domain;           /* NIS domain to use */
 #endif /* HAS_NIS_MAPS */
 #ifdef HAS_NIS_MAPS
 extern char *domain;           /* NIS domain to use */
 #endif /* HAS_NIS_MAPS */
-extern FILE *logfp;            /* Log file */
-extern int xlog_level;         /* Logging level */
-#ifdef HAS_SYSLOG
-extern int syslogging;         /* Really using syslog */
-#endif /* HAS_SYSLOG */
 extern int am_timeo;           /* Cache period */
 extern int afs_timeo;          /* AFS timeout */
 extern int afs_retrans;                /* AFS retrans */
 extern int am_timeo_w;         /* Unmount timeout */
 extern char *mtab;             /* Mount table */
 
 extern int am_timeo;           /* Cache period */
 extern int afs_timeo;          /* AFS timeout */
 extern int afs_retrans;                /* AFS retrans */
 extern int am_timeo_w;         /* Unmount timeout */
 extern char *mtab;             /* Mount table */
 
-#define        XLOG_FATAL      0x0001
-#define        XLOG_ERROR      0x0002
-#define        XLOG_USER       0x0004
-#define        XLOG_WARNING    0x0008
-#define        XLOG_INFO       0x0010
-#define        XLOG_DEBUG      0x0020
-#define        XLOG_MAP        0x0040
-#define        XLOG_STATS      0x0080
-
-#define XLOG_DEFSTR    "all,nomap,nostats"             /* Default log options */
-#define XLOG_ALL       (XLOG_FATAL|XLOG_ERROR|XLOG_USER|XLOG_WARNING|XLOG_INFO|XLOG_MAP|XLOG_STATS)
-
-#ifdef DEBUG
-#ifdef DEBUG_MEM
-#define free(x) xfree(__FILE__,__LINE__,x)
-#endif /* DEBUG_MEM */
-
-#define        DEBUG_MTAB      "./mtab"
-
-extern int debug_flags;                /* Debug options */
-
-#define        D_DAEMON        0x0001  /* Enter daemon mode */
-#define        D_TRACE         0x0002  /* Do protocol trace */
-#define        D_FULL          0x0004  /* Do full trace */
-#define        D_MTAB          0x0008  /* Use local mtab */
-#define        D_AMQ           0x0010  /* Register amq program */
-#define        D_STR           0x0020  /* Debug string munging */
-#define        D_MEM           0x0040  /* Trace memory allocations */
-
-/*
- * Normally, don't enter daemon mode, and don't register amq
- */
-#define        D_TEST  (~(D_DAEMON|D_MEM|D_STR))
-#define        D_ALL   (~0)
-
-#define Debug(x) if (!(debug_flags & (x))) ; else
-#define dlog Debug(D_FULL) dplog
-#endif /* DEBUG */
-
-/*
- * Option tables
- */
-struct opt_tab {
-       char *opt;
-       int flag;
-};
-
 typedef enum {
        Start,
        Run,
 typedef enum {
        Start,
        Run,
@@ -167,9 +79,7 @@ extern time_t do_mapc_reload;        /* Flush & reload mount map cache */
 /*
  * Useful constants
  */
 /*
  * Useful constants
  */
-extern char *progname;         /* "amd" */
 extern char pid_fsname[];      /* kiska.southseas.nz:(pid%d) */
 extern char pid_fsname[];      /* kiska.southseas.nz:(pid%d) */
-extern char hostname[];                /* "kiska" */
 extern char hostd[];           /* "kiska.southseas.nz" */
 extern char *hostdomain;       /* "southseas.nz" */
 extern char *op_sys;           /* "sos4" */
 extern char hostd[];           /* "kiska.southseas.nz" */
 extern char *hostdomain;       /* "southseas.nz" */
 extern char *op_sys;           /* "sos4" */
@@ -178,6 +88,7 @@ extern char *karch;          /* "sun4c" */
 extern char *cluster;          /* "r+d-kluster" */
 extern char *endian;           /* "big" */
 extern char *auto_dir;         /* "/a" */
 extern char *cluster;          /* "r+d-kluster" */
 extern char *endian;           /* "big" */
 extern char *auto_dir;         /* "/a" */
+extern char copyright[];       /* Copyright info */
 extern char version[];         /* Version info */
 
 typedef struct am_ops am_ops;
 extern char version[];         /* Version info */
 
 typedef struct am_ops am_ops;
@@ -187,18 +98,35 @@ typedef struct mntfs mntfs;
 typedef struct fserver fserver;
 typedef struct fsrvinfo fsrvinfo;
 
 typedef struct fserver fserver;
 typedef struct fsrvinfo fsrvinfo;
 
+/*
+ * Debug defns.
+ */
+#ifdef DEBUG
+#define        DEBUG_MTAB      "./mtab"
+
+extern int debug_flags;                /* Debug options */
+
+#define        D_DAEMON        0x0001  /* Enter daemon mode */
+#define        D_TRACE         0x0002  /* Do protocol trace */
+#define        D_FULL          0x0004  /* Do full trace */
+#define        D_MTAB          0x0008  /* Use local mtab */
+#define        D_AMQ           0x0010  /* Register amq program */
+#define        D_STR           0x0020  /* Debug string munging */
+#define        D_MEM           0x0040  /* Trace memory allocations */
+
+/*
+ * Normally, don't enter daemon mode, and don't register amq
+ */
+#define        D_TEST  (~(D_DAEMON|D_MEM|D_STR))
+#endif /* DEBUG */
+
 /*
  * Global variables.
  */
 extern unsigned short nfs_port;        /* Our NFS service port */
 /*
  * Global variables.
  */
 extern unsigned short nfs_port;        /* Our NFS service port */
-extern int mypid;              /* Current process id */
 extern struct in_addr myipaddr;        /* (An) IP address of this host */
 
 extern int foreground;         /* Foreground process */
 extern struct in_addr myipaddr;        /* (An) IP address of this host */
 
 extern int foreground;         /* Foreground process */
-extern int orig_umask;         /* umask() on startup */
-#define clocktime() (clock_valid ? clock_valid : time(&clock_valid))
-extern time_t time P((time_t *));
-extern time_t clock_valid;     /* Clock needs recalculating */
 extern time_t next_softclock;  /* Time to call softclock() */
 extern int task_notify_todo;   /* Task notifier needs running */
 #ifdef HAS_TFS
 extern time_t next_softclock;  /* Time to call softclock() */
 extern int task_notify_todo;   /* Task notifier needs running */
 #ifdef HAS_TFS
@@ -206,9 +134,12 @@ extern int nfs_server_code_available;
 #endif /* HAS_TFS */
 extern int last_used_map;      /* Last map being used for mounts */
 extern AUTH *nfs_auth;         /* Dummy uthorisation for remote servers */
 #endif /* HAS_TFS */
 extern int last_used_map;      /* Last map being used for mounts */
 extern AUTH *nfs_auth;         /* Dummy uthorisation for remote servers */
-extern am_node *exported_ap[]; /* List of nodes */
+extern am_node **exported_ap;  /* List of nodes */
 extern int first_free_map;     /* First free node */
 extern int first_free_map;     /* First free node */
-#define        NEXP_AP (256)
+extern am_node *root_node;     /* Node for "root" */
+extern char *wire;             /* Name of primary connected network */
+#define        NEXP_AP (254)
+#define NEXP_AP_MARGIN (128)
 
 typedef int (*task_fun)P((voidp));
 typedef void (*cb_fun)P((int, int, voidp));
 
 typedef int (*task_fun)P((voidp));
 typedef void (*cb_fun)P((int, int, voidp));
@@ -254,7 +185,7 @@ typedef struct mnt_map mnt_map;
 /*
  * Global routines
  */
 /*
  * Global routines
  */
-extern int atoi P((const char *)); /* C */
+extern int atoi P((Const char *)); /* C */
 extern void am_mounted P((am_node*));
 extern void am_unmounted P((am_node*));
 extern int background(P_void);
 extern void am_mounted P((am_node*));
 extern void am_unmounted P((am_node*));
 extern int background(P_void);
@@ -263,9 +194,8 @@ extern int compute_mount_flags P((struct mntent *));
 extern int softclock(P_void);
 #ifdef DEBUG
 extern int debug_option P((char*));
 extern int softclock(P_void);
 #ifdef DEBUG
 extern int debug_option P((char*));
-extern void dplog ();
-/*extern void dplog P((char*, ...));*/
 #endif /* DEBUG */
 #endif /* DEBUG */
+extern void deslashify P((char*));
 /*extern void domain_strip P((char*, char*));*/
 extern mntfs* dup_mntfs P((mntfs*));
 extern fserver* dup_srvr P((fserver*));
 /*extern void domain_strip P((char*, char*));*/
 extern mntfs* dup_mntfs P((mntfs*));
 extern fserver* dup_srvr P((fserver*));
@@ -273,24 +203,29 @@ extern int eval_fs_opts P((am_opts*, char*, char*, char*, char*, char*));
 extern char* expand_key P((char*));
 extern am_node* exported_ap_alloc(P_void);
 extern am_node* find_ap P((char*));
 extern char* expand_key P((char*));
 extern am_node* exported_ap_alloc(P_void);
 extern am_node* find_ap P((char*));
-extern mntfs* find_mntfs P((am_ops*, am_opts*, char*, char*, char*));
+extern am_node* find_mf P((mntfs*));
+extern mntfs* find_mntfs P((am_ops*, am_opts*, char*, char*, char*, char*));
 extern void flush_mntfs(P_void);
 extern void flush_mntfs(P_void);
+extern void flush_nfs_fhandle_cache P((fserver*));
+extern void forcibly_timeout_mp P((am_node*));
 extern FREE_RETURN_TYPE free P((voidp)); /* C */
 extern void free_mntfs P((mntfs*));
 extern void free_opts P((am_opts*));
 extern void free_map P((am_node*));
 extern void free_mntlist P((mntlist*));
 extern FREE_RETURN_TYPE free P((voidp)); /* C */
 extern void free_mntfs P((mntfs*));
 extern void free_opts P((am_opts*));
 extern void free_map P((am_node*));
 extern void free_mntlist P((mntlist*));
+extern void free_srvr P((fserver*));
 extern int fwd_init(P_void);
 extern int fwd_packet P((int, voidp, int, struct sockaddr_in *,
                struct sockaddr_in *, voidp, fwd_fun));
 extern void fwd_reply(P_void);
 extern void get_args P((int, char*[]));
 extern int fwd_init(P_void);
 extern int fwd_packet P((int, voidp, int, struct sockaddr_in *,
                struct sockaddr_in *, voidp, fwd_fun));
 extern void fwd_reply(P_void);
 extern void get_args P((int, char*[]));
-extern void going_down P((int));
+extern char *getwire P((void));
 #ifdef NEED_MNTOPT_PARSER
 extern char *hasmntopt P((struct mntent*, char*));
 #endif /* NEED_MNTOPT_PARSER */
 extern int hasmntval P((struct mntent*, char*));
 extern void host_normalize P((char **));
 #ifdef NEED_MNTOPT_PARSER
 extern char *hasmntopt P((struct mntent*, char*));
 #endif /* NEED_MNTOPT_PARSER */
 extern int hasmntval P((struct mntent*, char*));
 extern void host_normalize P((char **));
+extern char *inet_dquad P((char*, unsigned long));
 extern void init_map P((am_node*, char*));
 extern void insert_am P((am_node*, am_node*));
 extern void ins_que P((qelem*, qelem*));
 extern void init_map P((am_node*, char*));
 extern void insert_am P((am_node*, am_node*));
 extern void ins_que P((qelem*, qelem*));
@@ -299,23 +234,27 @@ extern int make_rpc_packet P((char*, int, u_long, struct rpc_msg*, voidp, xdrpro
 extern void mapc_add_kv P((mnt_map*, char*, char*));
 extern mnt_map* mapc_find P((char*, char*));
 extern void mapc_free P((mnt_map*));
 extern void mapc_add_kv P((mnt_map*, char*, char*));
 extern mnt_map* mapc_find P((char*, char*));
 extern void mapc_free P((mnt_map*));
+extern int mapc_keyiter P((mnt_map*, void (*)(char*,voidp), voidp));
 extern int mapc_search P((mnt_map*, char*, char**));
 extern void mapc_reload(P_void);
 extern void mapc_showtypes P((FILE*));
 extern int mkdirs P((char*, int));
 extern int mapc_search P((mnt_map*, char*, char**));
 extern void mapc_reload(P_void);
 extern void mapc_showtypes P((FILE*));
 extern int mkdirs P((char*, int));
+extern void mk_fattr P((am_node*, enum ftype));
 extern void mnt_free P((struct mntent*));
 extern void mnt_free P((struct mntent*));
+extern int mount_auto_node P((char*, voidp));
 extern int mount_automounter P((int));
 extern int mount_exported(P_void);
 extern int mount_automounter P((int));
 extern int mount_exported(P_void);
+extern int mount_fs P((struct mntent*, int, caddr_t, int, MTYPE_TYPE));
 extern int mount_node P((am_node*));
 extern mntfs* new_mntfs(P_void);
 extern void new_ttl P((am_node*));
 extern am_node* next_map P((int*));
 extern int nfs_srvr_port P((fserver*, u_short*, voidp));
 extern int mount_node P((am_node*));
 extern mntfs* new_mntfs(P_void);
 extern void new_ttl P((am_node*));
 extern am_node* next_map P((int*));
 extern int nfs_srvr_port P((fserver*, u_short*, voidp));
+extern void normalize_slash P((char*));
+extern void ops_showfstypes P((FILE*));
 extern int pickup_rpc_reply P((voidp, int, voidp, xdrproc_t));
 extern int pickup_rpc_reply P((voidp, int, voidp, xdrproc_t));
-extern void plog ();
-/*extern void plog P((int, char*, ...));*/
 extern mntlist* read_mtab P((char*));
 extern mntlist* read_mtab P((char*));
-extern mntfs* realloc_mntfs  P((mntfs*, am_ops*, am_opts*, char*, char*, char*));
+extern mntfs* realloc_mntfs  P((mntfs*, am_ops*, am_opts*, char*, char*, char*, char*));
 extern void rem_que P((qelem*));
 extern void reschedule_timeout_mp(P_void);
 extern void restart(P_void);
 extern void rem_que P((qelem*));
 extern void reschedule_timeout_mp(P_void);
 extern void restart(P_void);
@@ -324,28 +263,30 @@ extern void rewrite_mtab P((mntlist *));
 #endif /* UPDATE_MTAB */
 extern void rmdirs P((char*));
 extern am_node* root_ap P((char*, int));
 #endif /* UPDATE_MTAB */
 extern void rmdirs P((char*));
 extern am_node* root_ap P((char*, int));
+extern int root_keyiter P((void (*)(char*,voidp), voidp));
 extern void root_newmap P((char*, char*, char*));
 extern void rpc_msg_init P((struct rpc_msg*, u_long, u_long, u_long));
 extern void run_task P((task_fun, voidp, cb_fun, voidp));
 extern void sched_task P((cb_fun, voidp, voidp));
 extern void root_newmap P((char*, char*, char*));
 extern void rpc_msg_init P((struct rpc_msg*, u_long, u_long, u_long));
 extern void run_task P((task_fun, voidp, cb_fun, voidp));
 extern void sched_task P((cb_fun, voidp, voidp));
-extern void show_rcs_info P((const char*, char*));
+extern void show_rcs_info P((Const char*, char*));
 extern void sigchld P((int));
 extern void srvrlog P((fserver*, char*));
 extern char* str3cat P((char*, char*, char*, char*));
 extern void sigchld P((int));
 extern void srvrlog P((fserver*, char*));
 extern char* str3cat P((char*, char*, char*, char*));
-extern char* strcat P((char*, const char*)); /* C */
-extern char* strchr P((const char*, int)); /* C */
-extern int strcmp P((const char*, const char*)); /* C */
-extern char* strdup P((const char*));
-extern int strlen P((const char*)); /* C */
-extern char* strnsave P((const char*, int));
-extern char* strrchr P((const char*, int)); /* C */
+extern char* strcat P((char*, Const char*)); /* C */
+extern int strcmp P((Const char*, Const char*)); /* C */
+extern char* strdup P((Const char*));
+extern int strlen P((Const char*)); /* C */
+extern char* strnsave P((Const char*, int));
+extern char* strrchr P((Const char*, int)); /* C */
 extern char* strealloc P((char*, char *));
 extern char* strealloc P((char*, char *));
-extern char** strsplit P((char*, int));
+extern char** strsplit P((char*, int, int));
 extern int switch_option P((char*));
 extern int switch_option P((char*));
-extern void task_notify(P_void);
+extern int switch_to_logfile P((char*));
+extern void do_task_notify(P_void);
 extern int timeout P((unsigned int, void (*fn)(), voidp));
 extern void timeout_mp(P_void);
 extern void umount_exported(P_void);
 extern int timeout P((unsigned int, void (*fn)(), voidp));
 extern void timeout_mp(P_void);
 extern void umount_exported(P_void);
+extern int umount_fs P((char*));
 /*extern int unmount_node P((am_node*));
 extern int unmount_node_wrap P((voidp));*/
 extern void unregister_amq(P_void);
 /*extern int unmount_node P((am_node*));
 extern int unmount_node_wrap P((voidp));*/
 extern void unregister_amq(P_void);
@@ -355,8 +296,12 @@ extern void wakeup P((voidp));
 extern void wakeup_task P((int,int,voidp));
 extern void wakeup_srvr P((fserver*));
 extern void write_mntent P((struct mntent*));
 extern void wakeup_task P((int,int,voidp));
 extern void wakeup_srvr P((fserver*));
 extern void write_mntent P((struct mntent*));
-extern voidp xmalloc P((int));
-extern voidp xrealloc P((voidp, int));
+#ifdef UPDATE_MTAB
+extern void unlock_mntlist P((void));
+#else
+#define        unlock_mntlist()
+#endif /* UPDATE_MTAB */
+
 
 #define        ALLOC(ty)       ((struct ty *) xmalloc(sizeof(struct ty)))
 
 
 #define        ALLOC(ty)       ((struct ty *) xmalloc(sizeof(struct ty)))
 
@@ -404,15 +349,21 @@ extern am_node *fh_to_mp P((nfs_fh*));
 extern am_node *fh_to_mp3 P((nfs_fh*,int*,int));
 extern void mp_to_fh P((am_node*, nfs_fh*));
 #define        fh_to_mp2(fhp, rp) fh_to_mp3(fhp, rp, VLOOK_CREATE)
 extern am_node *fh_to_mp3 P((nfs_fh*,int*,int));
 extern void mp_to_fh P((am_node*, nfs_fh*));
 #define        fh_to_mp2(fhp, rp) fh_to_mp3(fhp, rp, VLOOK_CREATE)
+extern int auto_fmount P((am_node *mp));
+extern int auto_fumount P((am_node *mp));
+
+#define        MAX_READDIR_ENTRIES     16
 
 
-typedef int    (*vfs_match)P((am_opts*));
+typedef char*  (*vfs_match)P((am_opts*));
 typedef int    (*vfs_init)P((mntfs*));
 typedef int    (*vmount_fs)P((am_node*));
 typedef int    (*vfs_init)P((mntfs*));
 typedef int    (*vmount_fs)P((am_node*));
+typedef int    (*vfmount_fs)P((mntfs*));
 typedef int    (*vumount_fs)P((am_node*));
 typedef int    (*vumount_fs)P((am_node*));
+typedef int    (*vfumount_fs)P((mntfs*));
 typedef am_node*(*vlookuppn)P((am_node*, char*, int*, int));
 typedef am_node*(*vlookuppn)P((am_node*, char*, int*, int));
-typedef int    (*vreaddir)P((am_node*, nfscookie, dirlist*, entry*));
+typedef int    (*vreaddir)P((am_node*, nfscookie, dirlist*, entry*, int));
 typedef am_node*(*vreadlink)P((am_node*, int*));
 typedef am_node*(*vreadlink)P((am_node*, int*));
-typedef int    (*vmounted)P((mntfs*));
+typedef void   (*vmounted)P((mntfs*));
 typedef void   (*vumounted)P((am_node*));
 typedef fserver*(*vffserver)P((mntfs*));
 
 typedef void   (*vumounted)P((am_node*));
 typedef fserver*(*vffserver)P((mntfs*));
 
@@ -421,7 +372,9 @@ struct am_ops {
        vfs_match       fs_match;
        vfs_init        fs_init;
        vmount_fs       mount_fs;
        vfs_match       fs_match;
        vfs_init        fs_init;
        vmount_fs       mount_fs;
+       vfmount_fs      fmount_fs;
        vumount_fs      umount_fs;
        vumount_fs      umount_fs;
+       vfumount_fs     fumount_fs;
        vlookuppn       lookuppn;
        vreaddir        readdir;
        vreadlink       readlink;
        vlookuppn       lookuppn;
        vreaddir        readdir;
        vreadlink       readlink;
@@ -431,15 +384,15 @@ struct am_ops {
        int             fs_flags;
 };
 extern am_node *efs_lookuppn P((am_node*, char*, int*, int));
        int             fs_flags;
 };
 extern am_node *efs_lookuppn P((am_node*, char*, int*, int));
-extern int efs_readdir P((am_node*, nfscookie, dirlist*, entry*));
+extern int efs_readdir P((am_node*, nfscookie, dirlist*, entry*, int));
 
 #define        VLOOK_CREATE    0x1
 #define        VLOOK_DELETE    0x2
 
 
 #define        VLOOK_CREATE    0x1
 #define        VLOOK_DELETE    0x2
 
-#define        FS_RETRY        0x0001          /* Retry this type of mount */
+#define FS_DIRECTORY   0x0001          /* This looks like a dir, not a link */
 #define        FS_MBACKGROUND  0x0002          /* Should background this mount */
 #define        FS_NOTIMEOUT    0x0004          /* Don't bother with timeouts */
 #define        FS_MBACKGROUND  0x0002          /* Should background this mount */
 #define        FS_NOTIMEOUT    0x0004          /* Don't bother with timeouts */
-#define FS_MKMNT       0x0008          /* Need to make the mkdir point */
+#define FS_MKMNT       0x0008          /* Need to make the mount point */
 #define FS_UBACKGROUND 0x0010          /* Unmount in background */
 #define        FS_BACKGROUND   (FS_MBACKGROUND|FS_UBACKGROUND)
 #define        FS_DISCARD      0x0020          /* Discard immediately on last reference */
 #define FS_UBACKGROUND 0x0010          /* Unmount in background */
 #define        FS_BACKGROUND   (FS_MBACKGROUND|FS_UBACKGROUND)
 #define        FS_DISCARD      0x0020          /* Discard immediately on last reference */
@@ -507,11 +460,10 @@ struct mntfs {
        qelem           mf_q;           /* List of mounted filesystems */
        am_ops          *mf_ops;        /* Operations on this mountpoint */
        am_opts         *mf_fo;         /* File opts */
        qelem           mf_q;           /* List of mounted filesystems */
        am_ops          *mf_ops;        /* Operations on this mountpoint */
        am_opts         *mf_fo;         /* File opts */
-       struct attrstat mf_attr;        /* File attributes */
-#define mf_fattr       mf_attr.attrstat_u.attributes
        char            *mf_mount;      /* "/a/kiska/home/kiska" */
        char            *mf_info;       /* Mount info */
        char            *mf_mount;      /* "/a/kiska/home/kiska" */
        char            *mf_info;       /* Mount info */
-       char            *mf_opts;       /* Mount opts */
+       char            *mf_auto;       /* Automount opts */
+       char            *mf_mopts;      /* FS mount opts */
        fserver         *mf_server;     /* File server */
        int             mf_flags;       /* Flags */
        int             mf_error;       /* Error code from background mount */
        fserver         *mf_server;     /* File server */
        int             mf_flags;       /* Flags */
        int             mf_error;       /* Error code from background mount */
@@ -547,6 +499,8 @@ struct am_node {
                        *am_ysib,       /* Younger sibling of this node */
                        *am_osib,       /* Older sibling of this node */
                        *am_child;      /* First child of this node */
                        *am_ysib,       /* Younger sibling of this node */
                        *am_osib,       /* Older sibling of this node */
                        *am_child;      /* First child of this node */
+       struct attrstat am_attr;        /* File attributes */
+#define am_fattr       am_attr.attrstat_u.attributes
        int             am_flags;       /* Boolean flags */
        int             am_error;       /* Specific mount error */
        time_t          am_ttl;         /* Time to live */
        int             am_flags;       /* Boolean flags */
        int             am_error;       /* Specific mount error */
        time_t          am_ttl;         /* Time to live */
@@ -559,7 +513,6 @@ struct am_node {
 
 #define        AMF_NOTIMEOUT   0x0001          /* This node never times out */
 #define        AMF_ROOT        0x0002          /* This is a root node */
 
 #define        AMF_NOTIMEOUT   0x0001          /* This node never times out */
 #define        AMF_ROOT        0x0002          /* This is a root node */
-#define AMF_MKPATH     0x0004          /* Delete this node's am_path */
 
 #define        ONE_HOUR        (60 * 60)       /* One hour in seconds */
 
 
 #define        ONE_HOUR        (60 * 60)       /* One hour in seconds */
 
@@ -571,8 +524,8 @@ struct am_node {
 #define        AM_TTL_W                (2 * 60)        /* Default unmount interval */
 #define        AM_PINGER               30              /* NFS ping interval for live systems */
 #define        AFS_TIMEO               8               /* Default afs timeout - .8s */
 #define        AM_TTL_W                (2 * 60)        /* Default unmount interval */
 #define        AM_PINGER               30              /* NFS ping interval for live systems */
 #define        AFS_TIMEO               8               /* Default afs timeout - .8s */
-#define        AFS_RETRANS             ((ALLOWED_MOUNT_TIME*10+2*afs_timeo)/afs_timeo)
-                                               /* Default afs timeout - 1/10th seconds */
+#define        AFS_RETRANS             ((ALLOWED_MOUNT_TIME*10+5*afs_timeo)/afs_timeo * 2)
+                                               /* Default afs retrans - 1/10th seconds */
 
 #define        RPC_XID_PORTMAP         0
 #define        RPC_XID_MOUNTD          1
 
 #define        RPC_XID_PORTMAP         0
 #define        RPC_XID_MOUNTD          1
index d1cef0b..d41d329 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: fstype.h,v 5.2 90/06/23 22:20:30 jsp Rel $
+ * $Id: fstype.h,v 5.2.1.2 90/11/04 23:17:38 jsp Exp $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
@@ -11,7 +11,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)fstype.h    5.1 (Berkeley) %G%
+ *     @(#)fstype.h    5.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
  */
 #define HAS_AFS
 extern am_ops  afs_ops;        /* Automount file system (this!) */
  */
 #define HAS_AFS
 extern am_ops  afs_ops;        /* Automount file system (this!) */
+extern am_ops  toplvl_ops;     /* Top-level automount file system */
+extern am_ops  root_ops;       /* Root file system */
 extern qelem   afs_srvr_list;
 extern fserver *find_afs_srvr P((mntfs*));
 
 extern qelem   afs_srvr_list;
 extern fserver *find_afs_srvr P((mntfs*));
 
-
 /*
  * Direct Automount File System
  */
 /*
  * Direct Automount File System
  */
@@ -67,7 +68,9 @@ extern am_ops lofs_ops;
  */
 #define HAS_NFS
 #define        HAS_HOST
  */
 #define HAS_NFS
 #define        HAS_HOST
+#define HAS_NFSX
 extern am_ops  nfs_ops;        /* NFS */
 extern am_ops  nfs_ops;        /* NFS */
+extern am_ops  nfsx_ops;       /* NFS X */
 extern am_ops  host_ops;       /* NFS host */
 #ifdef HOST_EXEC
 extern char    *host_helper;   /* "/usr/local/etc/amd-host" */
 extern am_ops  host_ops;       /* NFS host */
 #ifdef HOST_EXEC
 extern char    *host_helper;   /* "/usr/local/etc/amd-host" */
@@ -106,3 +109,9 @@ extern am_ops       ufs_ops;        /* Un*x file system */
  */
 #define HAS_SFS
 extern am_ops  sfs_ops;        /* Symlink FS */
  */
 #define HAS_SFS
 extern am_ops  sfs_ops;        /* Symlink FS */
+
+/*
+ * Union file system
+ */
+#define        HAS_UNION_FS
+extern am_ops  union_ops;      /* Union FS */
index 17ee34e..f29ea5a 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: uwait.h,v 5.2 90/06/23 22:20:31 jsp Rel $
+ * $Id: uwait.h,v 5.2.1.1 90/10/21 22:30:35 jsp Exp $
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * Copyright (c) 1989 Jan-Simon Pendry
  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)uwait.h     5.1 (Berkeley) %G%
+ *     @(#)uwait.h     5.2 (Berkeley) %G%
  */
 
  */
 
-#if defined(mc68k) || defined(mc68000) || defined(mc68020) || defined(sparc) || defined(hp9000s300)
+#if defined(mc68k) || defined(mc68000) || defined(mc68020) || defined(sparc) || defined(hp9000s300) || defined(hp9000s800)
 #define BITS_BIGENDIAN
 #endif
 #if defined(vax) || defined(i386)
 #define BITS_BIGENDIAN
 #endif
 #if defined(vax) || defined(i386)