aboutsummaryrefslogtreecommitdiff
path: root/contrib/amd/amd
diff options
context:
space:
mode:
authorPedro F. Giffuni <pfg@FreeBSD.org>2015-01-28 22:55:06 +0000
committerPedro F. Giffuni <pfg@FreeBSD.org>2015-01-28 22:55:06 +0000
commite925d4a747df4a349c2baac436a71f606945baa5 (patch)
treee3a2ccc21623f0453c6f43f9016535205ba10d21 /contrib/amd/amd
parent509fcedcfec077a6070002f4059db0ae675be869 (diff)
downloadsrc-e925d4a747df4a349c2baac436a71f606945baa5.tar.gz
src-e925d4a747df4a349c2baac436a71f606945baa5.zip
amd: flatten the tree
Notes
Notes: svn path=/vendor/amd/dist/; revision=277863
Diffstat (limited to 'contrib/amd/amd')
-rw-r--r--contrib/amd/amd/am_ops.c475
-rw-r--r--contrib/amd/amd/amd.8371
-rw-r--r--contrib/amd/amd/amd.c577
-rw-r--r--contrib/amd/amd/amd.h867
-rw-r--r--contrib/amd/amd/amfs_auto.c176
-rw-r--r--contrib/amd/amd/amfs_direct.c110
-rw-r--r--contrib/amd/amd/amfs_error.c151
-rw-r--r--contrib/amd/amd/amfs_generic.c1262
-rw-r--r--contrib/amd/amd/amfs_host.c709
-rw-r--r--contrib/amd/amd/amfs_link.c133
-rw-r--r--contrib/amd/amd/amfs_linkx.c113
-rw-r--r--contrib/amd/amd/amfs_nfsl.c238
-rw-r--r--contrib/amd/amd/amfs_nfsx.c512
-rw-r--r--contrib/amd/amd/amfs_program.c205
-rw-r--r--contrib/amd/amd/amfs_root.c99
-rw-r--r--contrib/amd/amd/amfs_toplvl.c318
-rw-r--r--contrib/amd/amd/amfs_union.c132
-rw-r--r--contrib/amd/amd/amq_subr.c479
-rw-r--r--contrib/amd/amd/amq_svc.c229
-rw-r--r--contrib/amd/amd/autil.c783
-rw-r--r--contrib/amd/amd/clock.c244
-rw-r--r--contrib/amd/amd/conf.c1406
-rw-r--r--contrib/amd/amd/conf_parse.y158
-rw-r--r--contrib/amd/amd/conf_tok.l192
-rw-r--r--contrib/amd/amd/get_args.c437
-rw-r--r--contrib/amd/amd/info_exec.c423
-rw-r--r--contrib/amd/amd/info_file.c253
-rw-r--r--contrib/amd/amd/info_hesiod.c190
-rw-r--r--contrib/amd/amd/info_ldap.c573
-rw-r--r--contrib/amd/amd/info_ndbm.c140
-rw-r--r--contrib/amd/amd/info_nis.c441
-rw-r--r--contrib/amd/amd/info_nisplus.c307
-rw-r--r--contrib/amd/amd/info_passwd.c192
-rw-r--r--contrib/amd/amd/info_union.c147
-rw-r--r--contrib/amd/amd/map.c1072
-rw-r--r--contrib/amd/amd/mapc.c1192
-rw-r--r--contrib/amd/amd/mntfs.c366
-rw-r--r--contrib/amd/amd/nfs_prot_svc.c301
-rw-r--r--contrib/amd/amd/nfs_start.c453
-rw-r--r--contrib/amd/amd/nfs_subr.c828
-rw-r--r--contrib/amd/amd/ops_TEMPLATE.c305
-rw-r--r--contrib/amd/amd/ops_autofs.c1279
-rw-r--r--contrib/amd/amd/ops_cachefs.c260
-rw-r--r--contrib/amd/amd/ops_cdfs.c228
-rw-r--r--contrib/amd/amd/ops_efs.c172
-rw-r--r--contrib/amd/amd/ops_lofs.c159
-rw-r--r--contrib/amd/amd/ops_mfs.c54
-rw-r--r--contrib/amd/amd/ops_nfs.c1042
-rw-r--r--contrib/amd/amd/ops_nfs3.c54
-rw-r--r--contrib/amd/amd/ops_nullfs.c54
-rw-r--r--contrib/amd/amd/ops_pcfs.c226
-rw-r--r--contrib/amd/amd/ops_tfs.c54
-rw-r--r--contrib/amd/amd/ops_tmpfs.c54
-rw-r--r--contrib/amd/amd/ops_ufs.c180
-rw-r--r--contrib/amd/amd/ops_umapfs.c54
-rw-r--r--contrib/amd/amd/ops_unionfs.c54
-rw-r--r--contrib/amd/amd/ops_xfs.c171
-rw-r--r--contrib/amd/amd/opts.c1519
-rw-r--r--contrib/amd/amd/readdir.c498
-rw-r--r--contrib/amd/amd/restart.c288
-rw-r--r--contrib/amd/amd/rpc_fwd.c478
-rw-r--r--contrib/amd/amd/sched.c304
-rw-r--r--contrib/amd/amd/srvr_amfs_auto.c210
-rw-r--r--contrib/amd/amd/srvr_nfs.c1042
64 files changed, 0 insertions, 25993 deletions
diff --git a/contrib/amd/amd/am_ops.c b/contrib/amd/amd/am_ops.c
deleted file mode 100644
index 5a5c33650eca..000000000000
--- a/contrib/amd/amd/am_ops.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/am_ops.c
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-
-/*
- * The order of these entries matters, since lookups in this table are done
- * on a first-match basis. The entries below are a mixture of native
- * filesystems supported by the OS (HAVE_FS_FOO), and some meta-filesystems
- * supported by amd (HAVE_AMU_FS_FOO). The order is set here in expected
- * match-hit such that more popular filesystems are listed first (nfs is the
- * most popular, followed by a symlink F/S)
- */
-static am_ops *vops[] =
-{
-#ifdef HAVE_FS_NFS
- &nfs_ops, /* network F/S (version 2) */
-#endif /* HAVE_FS_NFS */
-#ifdef HAVE_AMU_FS_LINK
- &amfs_link_ops, /* symlink F/S */
-#endif /* HAVE_AMU_FS_LINK */
-
- /*
- * Other amd-supported meta-filesystems.
- */
-#ifdef HAVE_AMU_FS_NFSX
- &amfs_nfsx_ops, /* multiple-nfs F/S */
-#endif /* HAVE_AMU_FS_NFSX */
-#ifdef HAVE_AMU_FS_NFSL
- &amfs_nfsl_ops, /* NFS with local link existence check */
-#endif /* HAVE_AMU_FS_NFSL */
-#ifdef HAVE_AMU_FS_HOST
- &amfs_host_ops, /* multiple exported nfs F/S */
-#endif /* HAVE_AMU_FS_HOST */
-#ifdef HAVE_AMU_FS_LINKX
- &amfs_linkx_ops, /* symlink F/S with link target verify */
-#endif /* HAVE_AMU_FS_LINKX */
-#ifdef HAVE_AMU_FS_PROGRAM
- &amfs_program_ops, /* program F/S */
-#endif /* HAVE_AMU_FS_PROGRAM */
-#ifdef HAVE_AMU_FS_UNION
- &amfs_union_ops, /* union F/S */
-#endif /* HAVE_AMU_FS_UNION */
-
- /*
- * A few more native filesystems.
- */
-#ifdef HAVE_FS_UFS
- &ufs_ops, /* Unix F/S */
-#endif /* HAVE_FS_UFS */
-#ifdef HAVE_FS_XFS
- &xfs_ops, /* Unix (irix) F/S */
-#endif /* HAVE_FS_XFS */
-#ifdef HAVE_FS_EFS
- &efs_ops, /* Unix (irix) F/S */
-#endif /* HAVE_FS_EFS */
-#ifdef HAVE_FS_LOFS
- &lofs_ops, /* loopback F/S */
-#endif /* HAVE_FS_LOFS */
-#ifdef HAVE_FS_CDFS
- &cdfs_ops, /* CDROM/HSFS/ISO9960 F/S */
-#endif /* HAVE_FS_CDFS */
-#ifdef HAVE_FS_PCFS
- &pcfs_ops, /* Floppy/MSDOS F/S */
-#endif /* HAVE_FS_PCFS */
-#ifdef HAVE_FS_CACHEFS
- &cachefs_ops, /* caching F/S */
-#endif /* HAVE_FS_CACHEFS */
-#ifdef HAVE_FS_NULLFS
-/* FILL IN */ /* null (loopback) F/S */
-#endif /* HAVE_FS_NULLFS */
-#ifdef HAVE_FS_UNIONFS
-/* FILL IN */ /* union (bsd44) F/S */
-#endif /* HAVE_FS_UNIONFS */
-#ifdef HAVE_FS_UMAPFS
-/* FILL IN */ /* uid/gid mapping F/S */
-#endif /* HAVE_FS_UMAPFS */
-
- /*
- * These 4 should be last, in the order:
- * (1) amfs_auto
- * (2) amfs_direct
- * (3) amfs_toplvl
- * (4) amfs_error
- */
-#ifdef HAVE_AMU_FS_AUTO
- &amfs_auto_ops, /* Automounter F/S */
-#endif /* HAVE_AMU_FS_AUTO */
-#ifdef HAVE_AMU_FS_DIRECT
- &amfs_direct_ops, /* direct-mount F/S */
-#endif /* HAVE_AMU_FS_DIRECT */
-#ifdef HAVE_AMU_FS_TOPLVL
- &amfs_toplvl_ops, /* top-level mount F/S */
-#endif /* HAVE_AMU_FS_TOPLVL */
-#ifdef HAVE_AMU_FS_ERROR
- &amfs_error_ops, /* error F/S */
-#endif /* HAVE_AMU_FS_ERROR */
- 0
-};
-
-
-void
-ops_showamfstypes(char *buf, size_t l)
-{
- struct am_ops **ap;
- int linesize = 0;
-
- buf[0] = '\0';
- for (ap = vops; *ap; ap++) {
- xstrlcat(buf, (*ap)->fs_type, l);
- if (ap[1])
- xstrlcat(buf, ", ", l);
- linesize += strlen((*ap)->fs_type) + 2;
- if (linesize > 62) {
- linesize = 0;
- xstrlcat(buf, "\n ", l);
- }
- }
-}
-
-
-static void
-ops_show1(char *buf, size_t l, int *linesizep, const char *name)
-{
- xstrlcat(buf, name, l);
- xstrlcat(buf, ", ", l);
- *linesizep += strlen(name) + 2;
- if (*linesizep > 60) {
- xstrlcat(buf, "\t\n", l);
- *linesizep = 0;
- }
-}
-
-
-void
-ops_showfstypes(char *buf, size_t l)
-{
- int linesize = 0;
-
- buf[0] = '\0';
-
-#ifdef MNTTAB_TYPE_AUTOFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_AUTOFS);
-#endif /* MNTTAB_TYPE_AUTOFS */
-
-#ifdef MNTTAB_TYPE_CACHEFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_CACHEFS);
-#endif /* MNTTAB_TYPE_CACHEFS */
-
-#ifdef MNTTAB_TYPE_CDFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_CDFS);
-#endif /* MNTTAB_TYPE_CDFS */
-
-#ifdef MNTTAB_TYPE_CFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_CFS);
-#endif /* MNTTAB_TYPE_CFS */
-
-#ifdef MNTTAB_TYPE_LOFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_LOFS);
-#endif /* MNTTAB_TYPE_LOFS */
-
-#ifdef MNTTAB_TYPE_EFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_EFS);
-#endif /* MNTTAB_TYPE_EFS */
-
-#ifdef MNTTAB_TYPE_MFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_MFS);
-#endif /* MNTTAB_TYPE_MFS */
-
-#ifdef MNTTAB_TYPE_NFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_NFS);
-#endif /* MNTTAB_TYPE_NFS */
-
-#ifdef MNTTAB_TYPE_NFS3
- ops_show1(buf, l, &linesize, "nfs3"); /* always hard-code as nfs3 */
-#endif /* MNTTAB_TYPE_NFS3 */
-
-#ifdef MNTTAB_TYPE_NULLFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_NULLFS);
-#endif /* MNTTAB_TYPE_NULLFS */
-
-#ifdef MNTTAB_TYPE_PCFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_PCFS);
-#endif /* MNTTAB_TYPE_PCFS */
-
-#ifdef MNTTAB_TYPE_TFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_TFS);
-#endif /* MNTTAB_TYPE_TFS */
-
-#ifdef MNTTAB_TYPE_TMPFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_TMPFS);
-#endif /* MNTTAB_TYPE_TMPFS */
-
-#ifdef MNTTAB_TYPE_UFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_UFS);
-#endif /* MNTTAB_TYPE_UFS */
-
-#ifdef MNTTAB_TYPE_UMAPFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_UMAPFS);
-#endif /* MNTTAB_TYPE_UMAPFS */
-
-#ifdef MNTTAB_TYPE_UNIONFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_UNIONFS);
-#endif /* MNTTAB_TYPE_UNIONFS */
-
-#ifdef MNTTAB_TYPE_XFS
- ops_show1(buf, l, &linesize, MNTTAB_TYPE_XFS);
-#endif /* MNTTAB_TYPE_XFS */
-
- /* terminate with a period, newline, and NULL */
- if (buf[strlen(buf)-1] == '\n')
- buf[strlen(buf) - 4] = '\0';
- else
- buf[strlen(buf) - 2] = '\0';
- xstrlcat(buf, ".\n", l);
-}
-
-
-/*
- * return string option which is the reverse of opt.
- * nosuid -> suid
- * quota -> noquota
- * ro -> rw
- * etc.
- * may return pointer to static buffer or subpointer within opt.
- */
-static char *
-reverse_option(const char *opt)
-{
- static char buf[80];
-
- /* sanity check */
- if (!opt)
- return NULL;
-
- /* check special cases */
- /* XXX: if this gets too long, rewrite the code more flexibly */
- if (STREQ(opt, "ro")) return "rw";
- if (STREQ(opt, "rw")) return "ro";
- if (STREQ(opt, "bg")) return "fg";
- if (STREQ(opt, "fg")) return "bg";
- if (STREQ(opt, "soft")) return "hard";
- if (STREQ(opt, "hard")) return "soft";
-
- /* check if string starts with 'no' and chop it */
- if (NSTREQ(opt, "no", 2)) {
- xstrlcpy(buf, &opt[2], sizeof(buf));
- } else {
- /* finally return a string prepended with 'no' */
- xstrlcpy(buf, "no", sizeof(buf));
- xstrlcat(buf, opt, sizeof(buf));
- }
- return buf;
-}
-
-
-/*
- * start with an empty string. for each opts1 option that is not
- * in opts2, add it to the string (make sure the reverse of it
- * isn't in either). finally add opts2. return new string.
- * Both opts1 and opts2 must not be null!
- * Caller must eventually free the string being returned.
- */
-static char *
-merge_opts(const char *opts1, const char *opts2)
-{
- mntent_t mnt2; /* place holder for opts2 */
- char *newstr; /* new string to return (malloc'ed) */
- char *tmpstr; /* temp */
- char *eq; /* pointer to whatever follows '=' within temp */
- char oneopt[80]; /* one option w/o value if any */
- char *revoneopt; /* reverse of oneopt */
- size_t len = strlen(opts1) + strlen(opts2) + 2; /* space for "," and NULL */
- char *s1 = strdup(opts1); /* copy of opts1 to munge */
-
- /* initialization */
- mnt2.mnt_opts = (char *) opts2;
- newstr = xmalloc(len);
- newstr[0] = '\0';
-
- for (tmpstr = strtok(s1, ",");
- tmpstr;
- tmpstr = strtok(NULL, ",")) {
- /* copy option to temp buffer */
- xstrlcpy(oneopt, tmpstr, 80);
- /* if option has a value such as rsize=1024, chop the value part */
- if ((eq = haseq(oneopt)))
- *eq = '\0';
- /* find reverse option of oneopt */
- revoneopt = reverse_option(oneopt);
- /* if option orits reverse exist in opts2, ignore it */
- if (amu_hasmntopt(&mnt2, oneopt) || amu_hasmntopt(&mnt2, revoneopt))
- continue;
- /* add option to returned string */
- if (newstr[0]) {
- xstrlcat(newstr, ",", len);
- xstrlcat(newstr, tmpstr, len);
- } else {
- xstrlcpy(newstr, tmpstr, len);
- }
- }
-
- /* finally, append opts2 itself */
- if (newstr[0]) {
- xstrlcat(newstr, ",", len);
- xstrlcat(newstr, opts2, len);
- } else {
- xstrlcpy(newstr, opts2, len);
- }
-
- XFREE(s1);
- return newstr;
-}
-
-
-am_ops *
-ops_search(char *type)
-{
- am_ops **vp;
- am_ops *rop = 0;
- for (vp = vops; (rop = *vp); vp++)
- if (STREQ(rop->fs_type, type))
- break;
- return rop;
-}
-
-
-am_ops *
-ops_match(am_opts *fo, char *key, char *g_key, char *path, char *keym, char *map)
-{
- am_ops *rop = 0;
- char *link_dir;
-
- /*
- * First crack the global opts and the local opts
- */
- if (!eval_fs_opts(fo, key, g_key, path, keym, map)) {
- rop = &amfs_error_ops;
- } else if (fo->opt_type == 0) {
- plog(XLOG_USER, "No fs type specified (key = \"%s\", map = \"%s\")", keym, map);
- rop = &amfs_error_ops;
- } else {
- /*
- * Next find the correct filesystem type
- */
- rop = ops_search(fo->opt_type);
- if (!rop) {
- plog(XLOG_USER, "fs type \"%s\" not recognized", fo->opt_type);
- rop = &amfs_error_ops;
- }
- }
-
- /*
- * Make sure we have a default mount option.
- * Otherwise skip past any leading '-'.
- */
- if (fo->opt_opts == 0)
- fo->opt_opts = strdup("rw,defaults");
- else if (*fo->opt_opts == '-') {
- /*
- * We cannot simply do fo->opt_opts++ here since the opts
- * module will try to free the pointer fo->opt_opts later.
- * So just reallocate the thing -- stolcke 11/11/94
- */
- char *old = fo->opt_opts;
- fo->opt_opts = strdup(old + 1);
- XFREE(old);
- }
-
- /*
- * If addopts option was used, then append it to the
- * current options and remote mount options.
- */
- if (fo->opt_addopts) {
- if (STREQ(fo->opt_opts, fo->opt_remopts)) {
- /* optimize things for the common case where opts==remopts */
- char *mergedstr;
- mergedstr = merge_opts(fo->opt_opts, fo->opt_addopts);
- plog(XLOG_INFO, "merge rem/opts \"%s\" add \"%s\" => \"%s\"",
- fo->opt_opts, fo->opt_addopts, mergedstr);
- XFREE(fo->opt_opts);
- XFREE(fo->opt_remopts);
- fo->opt_opts = mergedstr;
- fo->opt_remopts = strdup(mergedstr);
- } else {
- char *mergedstr, *remmergedstr;
- mergedstr = merge_opts(fo->opt_opts, fo->opt_addopts);
- plog(XLOG_INFO, "merge opts \"%s\" add \"%s\" => \"%s\"",
- fo->opt_opts, fo->opt_addopts, mergedstr);
- XFREE(fo->opt_opts);
- fo->opt_opts = mergedstr;
- remmergedstr = merge_opts(fo->opt_remopts, fo->opt_addopts);
- plog(XLOG_INFO, "merge remopts \"%s\" add \"%s\" => \"%s\"",
- fo->opt_remopts, fo->opt_addopts, remmergedstr);
- XFREE(fo->opt_remopts);
- fo->opt_remopts = remmergedstr;
- }
- }
-
- /*
- * Initialize opt_mount_type to "nfs", if it's not initialized already
- */
- if (!fo->opt_mount_type)
- fo->opt_mount_type = "nfs";
-
- /* Normalize the sublink and make it absolute */
- link_dir = fo->opt_sublink;
- if (link_dir && link_dir[0] && link_dir[0] != '/') {
- link_dir = str3cat((char *) 0, fo->opt_fs, "/", link_dir);
- normalize_slash(link_dir);
- XFREE(fo->opt_sublink);
- fo->opt_sublink = link_dir;
- }
-
- /*
- * Check the filesystem is happy
- */
- if (fo->fs_mtab)
- XFREE(fo->fs_mtab);
-
- fo->fs_mtab = rop->fs_match(fo);
- if (fo->fs_mtab)
- return rop;
-
- /*
- * Return error file system
- */
- fo->fs_mtab = amfs_error_ops.fs_match(fo);
- return &amfs_error_ops;
-}
diff --git a/contrib/amd/amd/amd.8 b/contrib/amd/amd/amd.8
deleted file mode 100644
index 565a5505b8c2..000000000000
--- a/contrib/amd/amd/amd.8
+++ /dev/null
@@ -1,371 +0,0 @@
-.\"
-.\" Copyright (c) 1997-2006 Erez Zadok
-.\" Copyright (c) 1989 Jan-Simon Pendry
-.\" Copyright (c) 1989 Imperial College of Science, Technology & Medicine
-.\" Copyright (c) 1989 The Regents of the University of California.
-.\" All rights reserved.
-.\"
-.\" This code is derived from software contributed to Berkeley by
-.\" Jan-Simon Pendry at Imperial College, London.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" %W% (Berkeley) %G%
-.\"
-.\" $Id: amd.8,v 1.14.2.1 2006/01/02 18:48:23 ezk Exp $
-.\"
-.TH AMD 8 "3 November 1989"
-.SH NAME
-amd \- automatically mount file systems
-.SH SYNOPSIS
-.B amd
-.B \-H
-.br
-.B amd
-[
-.BI \-F " conf_file"
-]
-.br
-.B amd
-[
-.B \-nprvHS
-] [
-.BI \-a " mount_point"
-] [
-.BI \-c " duration"
-] [
-.BI \-d " domain"
-] [
-.BI \-k " kernel-arch"
-] [
-.BI \-l " logfile"
-] [
-.BI \-o " op_sys_ver"
-] [
-.BI \-t " interval.interval"
-] [
-.BI \-w " interval"
-] [
-.BI \-x " log-option"
-] [
-.BI \-y " YP-domain"
-] [
-.BI \-A " arch"
-] [
-.BI \-C " cluster-name"
-] [
-.BI \-D " option"
-] [
-.BI \-F " conf_file"
-] [
-.BI \-O " op_sys_name"
-] [
-.BI \-T " tag"
-]
-[
-.I directory
-.I mapname
-.RI [ " \-map-options " ]
-] .\|.\|.
-.SH DESCRIPTION
-.B Amd
-is a daemon that automatically mounts filesystems
-whenever a file or directory
-within that filesystem is accessed.
-Filesystems are automatically unmounted when they
-appear to have become quiescent.
-.LP
-.B Amd
-operates by attaching itself as an
-.SM NFS
-server to each of the specified
-.IB directories .
-Lookups within the specified directories
-are handled by
-.BR amd ,
-which uses the map defined by
-.I mapname
-to determine how to resolve the lookup.
-Generally, this will be a host name, some filesystem information
-and some mount options for the given filesystem.
-.LP
-In the first form depicted above,
-.B amd
-will print a short help string. In the second form, if no options are
-specified, or the
-.B -F
-is used,
-.B amd
-will read configuration parameters from the file
-.I conf_file
-which defaults to
-.BR /etc/amd.conf .
-The last form is described below.
-.SH OPTIONS
-
-.\"*******************************************************"
-
-.TP
-.BI \-a " temporary-directory"
-Specify an alternative location for the real mount points.
-The default is
-.BR /a .
-
-.TP
-.BI \-c " duration"
-Specify a
-.IR duration ,
-in seconds, that a looked up name remains
-cached when not in use. The default is 5 minutes.
-
-.TP
-.BI \-d " domain"
-Specify the local domain name. If this option is not
-given the domain name is determined from the hostname.
-
-.TP
-.BI \-k " kernel-arch"
-Specifies the kernel architecture. This is used solely
-to set the ${karch} selector.
-
-.TP
-.BI \-l " logfile"
-Specify a logfile in which to record mount and unmount events.
-If
-.I logfile
-is the string
-.B syslog
-then the log messages will be sent to the system log daemon by
-.IR syslog (3).
-The default syslog facility used is LOG_DAEMON. If you
-wish to change it, append its name to the log file name, delimited by a
-single colon. For example, if
-.I logfile
-is the string
-.B syslog:local7
-then
-.B Amd
-will log messages via
-.IR syslog (3)
-using the LOG_LOCAL7 facility (if it exists on the system).
-
-.TP
-.B \-n
-Normalize hostnames.
-The name refereed to by ${rhost} is normalized relative to the
-host database before being used. The effect is to translate
-aliases into ``official'' names.
-
-.TP
-.BI \-o " op_sys_ver"
-Override the compiled-in version number of the operating system. Useful
-when the built in version is not desired for backward compatibility reasons.
-For example, if the build in version is ``2.5.1'', you can override it to
-``5.5.1'', and use older maps that were written with the latter in mind.
-
-.TP
-.B \-p
-Print PID.
-Outputs the process-id of
-.B amd
-to standard output where it can be saved into a file.
-
-.TP
-.B \-r
-Restart existing mounts.
-.B Amd
-will scan the mount file table to determine which filesystems
-are currently mounted. Whenever one of these would have
-been auto-mounted,
-.B amd
-.I inherits
-it.
-
-.TP
-.BI \-t " timeout.retransmit"
-Specify the NFS timeout
-.IR interval ,
-in tenths of a second, between NFS/RPC retries (for UDP only). The default
-is 0.8 seconds. The second value alters the retransmit counter, which
-defaults to 11 retransmissions. Both of these values are used by the kernel
-to communicate with amd. Useful defaults are supplied if either or both
-values are missing.
-
-Amd relies on the kernel RPC retransmit mechanism to trigger mount retries.
-The values of these parameters change the overall retry interval. Too long
-an interval gives poor interactive response; too short an interval causes
-excessive retries.
-
-.TP
-.B \-v
-Version. Displays version and configuration information on standard error.
-
-.TP
-.BI \-w " interval"
-Specify an
-.IR interval ,
-in seconds, between attempts to dismount
-filesystems that have exceeded their cached times.
-The default is 2 minutes.
-
-.TP
-.BI \-x " options"
-Specify run-time logging options. The options are a comma separated
-list chosen from: fatal, error, user, warn, info, map, stats, all.
-
-.TP
-.BI \-y " domain"
-Specify an alternative NIS domain from which to fetch the NIS maps.
-The default is the system domain name. This option is ignored if NIS
-support is not available.
-
-.TP
-.BI \-A " arch"
-Specifies the OS architecture. This is used solely to set the ${arch}
-selector.
-
-.TP
-.BI \-C " cluster-name"
-Specify an alternative HP-UX cluster name to use.
-
-.TP
-.BI \-D " option"
-Select from a variety of debug options. Prefixing an
-option with the strings
-.B no
-reverses the effect of that option. Options are cumulative.
-The most useful option is
-.BR all .
-Since
-.I \-D
-is only used for debugging other options are not documented here:
-the current supported set of options is listed by the \-v option
-and a fuller description is available in the program source.
-
-.TP
-.BI \-F " conf_file"
-Specify an amd configuration file to use. See
-.BR amd.conf (5)
-for description of this file's format. This configuration file is used to
-specify any options in lieu of typing many of them on the command line. The
-.I amd.conf
-file includes directives for every command line option amd has, and many
-more that are only available via the configuration file facility. The
-configuration file specified by this option is processed after all other
-options had been processed, regardless of the actual location of this option
-on the command line.
-
-.TP
-.B \-H
-Print help and usage string.
-
-.TP
-.BI \-O " op_sys_name"
-Override the compiled-in name of the operating system. Useful when the
-built in name is not desired for backward compatibility reasons. For
-example, if the build in name is ``sunos5'', you can override it to
-``sos5'', and use older maps which were written with the latter in mind.
-
-.TP
-.B \-S
-Do not lock the running executable pages of amd into memory. To improve
-amd's performance, systems that support the
-.BR plock (3)
-call, could lock the amd process into memory. This way there is less chance
-the operating system will schedule, page out, and swap the amd process as
-needed. This tends improves amd's performance, at the cost of reserving the
-memory used by the amd process (making it unavailable for other processes).
-If this behavior is not desired, use the
-.B \-S
-option.
-
-.TP
-.BI \-T " tag"
-Specify a tag to use with
-.BR amd.conf (5).
-All map entries tagged with
-.I tag
-will be processed. Map entries that are not tagged are always processed.
-Map entries that are tagged with a tag other than
-.I tag
-will not be processed.
-
-.SH FILES
-.TP 5
-.B /a
-directory under which filesystems are dynamically mounted
-.TP 5
-.B /etc/amd.conf
-default configuration file
-.SH CAVEATS
-Some care may be required when creating a mount map.
-.LP
-Symbolic links on an NFS filesystem can be incredibly inefficient.
-In most implementations of NFS, their interpolations are not cached
-by the kernel and each time a symlink is encountered during a
-.I lookuppn
-translation it costs an RPC call to the NFS server.
-It would appear that a large improvement in real-time
-performance could be gained by adding a cache somewhere.
-Replacing symlinks with a suitable incarnation of the auto-mounter
-results in a large real-time speedup, but also causes a large
-number of process context switches.
-.LP
-A weird imagination is most useful to gain full advantage of all
-the features.
-.SH "SEE ALSO"
-.BR amd.conf (5),
-.BR amq (8),
-.BR domainname (1),
-.BR hostname (1),
-.BR automount (8),
-.BR mount (8),
-.BR umount (8),
-.BR mtab (5),
-.BR syslog (3).
-.LP
-``am-utils''
-.BR info (1)
-entry.
-.LP
-.I "Linux NFS and Automounter Administration"
-by Erez Zadok, ISBN 0-7821-2739-8, (Sybex, 2001).
-.LP
-.I http://www.am-utils.org
-.LP
-.I "Amd \- The 4.4 BSD Automounter"
-.SH AUTHORS
-Jan-Simon Pendry <jsp@doc.ic.ac.uk>, Department of Computing, Imperial College, London, UK.
-.P
-Erez Zadok <ezk@cs.sunysb.edu>, Computer Science Department, Stony Brook
-University, Stony Brook, New York, USA.
-.P
-Other authors and contributors to am-utils are listed in the
-.B AUTHORS
-file distributed with am-utils.
diff --git a/contrib/amd/amd/amd.c b/contrib/amd/amd/amd.c
deleted file mode 100644
index 37eab5d8442c..000000000000
--- a/contrib/amd/amd/amd.c
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amd.c
- *
- */
-
-/*
- * Automounter
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-struct amu_global_options gopt; /* where global options are stored */
-
-char pid_fsname[SIZEOF_PID_FSNAME]; /* "kiska.southseas.nz:(pid%d)" */
-char *hostdomain = "unknown.domain";
-#define SIZEOF_HOSTD (2 * MAXHOSTNAMELEN + 1) /* Host+domain */
-char hostd[SIZEOF_HOSTD]; /* Host+domain */
-char *endian = ARCH_ENDIAN; /* Big or Little endian */
-char *cpu = HOST_CPU; /* CPU type */
-char *PrimNetName; /* name of primary network */
-char *PrimNetNum; /* number of primary network */
-
-int immediate_abort; /* Should close-down unmounts be retried */
-int orig_umask = 022;
-int select_intr_valid;
-
-jmp_buf select_intr;
-struct amd_stats amd_stats; /* Server statistics */
-struct in_addr myipaddr; /* (An) IP address of this host */
-time_t do_mapc_reload = 0; /* mapc_reload() call required? */
-
-#ifdef HAVE_FS_AUTOFS
-int amd_use_autofs = 0;
-#endif /* HAVE_FS_AUTOFS */
-
-#ifdef HAVE_SIGACTION
-sigset_t masked_sigs;
-#endif /* HAVE_SIGACTION */
-
-
-/*
- * Signal handler:
- * SIGINT - tells amd to do a full shutdown, including unmounting all
- * filesystem.
- * SIGTERM - tells amd to shutdown now. Just unmounts the automount nodes.
- */
-static RETSIGTYPE
-sigterm(int sig)
-{
-#ifdef REINSTALL_SIGNAL_HANDLER
- signal(sig, sigterm);
-#endif /* REINSTALL_SIGNAL_HANDLER */
-
- switch (sig) {
- case SIGINT:
- immediate_abort = 15;
- break;
-
- case SIGTERM:
- immediate_abort = -1;
- /* fall through... */
-
- default:
- plog(XLOG_WARNING, "WARNING: automounter going down on signal %d", sig);
- break;
- }
- if (select_intr_valid)
- longjmp(select_intr, sig);
-}
-
-
-/*
- * Hook for cache reload.
- * When a SIGHUP arrives it schedules a call to mapc_reload
- */
-static RETSIGTYPE
-sighup(int sig)
-{
-#ifdef REINSTALL_SIGNAL_HANDLER
- signal(sig, sighup);
-#endif /* REINSTALL_SIGNAL_HANDLER */
-
- if (sig != SIGHUP)
- dlog("spurious call to sighup");
- /*
- * Force a reload by zero'ing the timer
- */
- if (amd_state == Run)
- do_mapc_reload = 0;
-}
-
-
-static RETSIGTYPE
-parent_exit(int sig)
-{
- /*
- * This signal handler is called during Amd initialization. The parent
- * forks a child to do all the hard automounting work, and waits for a
- * SIGQUIT signal from the child. When the parent gets the signal it's
- * supposed to call this handler and exit(3), thus completing the
- * daemonizing process. Alas, on some systems, especially Linux 2.4/2.6
- * with Glibc, exit(3) doesn't always terminate the parent process.
- * Worse, the parent process now refuses to accept any more SIGQUIT
- * signals -- they are blocked. What's really annoying is that this
- * doesn't happen all the time, suggesting a race condition somewhere.
- * (This happens even if I change the logic to use another signal.) I
- * traced this to something which exit(3) does in addition to exiting the
- * process, probably some atexit() stuff or other side-effects related to
- * signal handling. Either way, since at this stage the parent process
- * just needs to terminate, I'm simply calling _exit(2). Note also that
- * the OpenGroup doesn't list exit(3) as a recommended "Base Interface"
- * but they do list _exit(2) as one. This fix seems to work reliably all
- * the time. -Erez (2/27/2005)
- */
- _exit(0);
-}
-
-
-static int
-daemon_mode(void)
-{
- int bgpid;
-
-#ifdef HAVE_SIGACTION
- struct sigaction sa, osa;
-
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = parent_exit;
- sa.sa_flags = 0;
- sigemptyset(&(sa.sa_mask));
- sigaddset(&(sa.sa_mask), SIGQUIT);
- sigaction(SIGQUIT, &sa, &osa);
-#else /* not HAVE_SIGACTION */
- signal(SIGQUIT, parent_exit);
-#endif /* not HAVE_SIGACTION */
-
- bgpid = background();
-
- if (bgpid != 0) {
- /*
- * Now wait for the automount points to
- * complete.
- */
- for (;;)
- pause();
- /* should never reach here */
- }
-#ifdef HAVE_SIGACTION
- sigaction(SIGQUIT, &osa, NULL);
-#else /* not HAVE_SIGACTION */
- signal(SIGQUIT, SIG_DFL);
-#endif /* not HAVE_SIGACTION */
-
- /*
- * Record our pid to make it easier to kill the correct amd.
- */
- if (gopt.flags & CFM_PRINT_PID) {
- if (STREQ(gopt.pid_file, "/dev/stdout")) {
- printf("%ld\n", (long) am_mypid);
- /* flush stdout, just in case */
- fflush(stdout);
- } else {
- FILE *f;
- mode_t prev_umask = umask(0022); /* set secure temporary umask */
-
- f = fopen(gopt.pid_file, "w");
- if (f) {
- fprintf(f, "%ld\n", (long) am_mypid);
- (void) fclose(f);
- } else {
- fprintf(stderr, "cannot open %s (errno=%d)\n", gopt.pid_file, errno);
- }
- umask(prev_umask); /* restore umask */
- }
- }
-
- /*
- * Pretend we are in the foreground again
- */
- foreground = 1;
-
- /*
- * Dissociate from the controlling terminal
- */
- amu_release_controlling_tty();
-
- return getppid();
-}
-
-
-/*
- * Initialize global options structure.
- */
-static void
-init_global_options(void)
-{
-#if defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME)
- static struct utsname un;
-#endif /* defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME) */
- int i;
-
- memset(&gopt, 0, sizeof(struct amu_global_options));
-
- /* name of current architecture */
- gopt.arch = HOST_ARCH;
-
- /* automounter temp dir */
- gopt.auto_dir = "/a";
-
- /* toplevel attribute cache timeout */
- gopt.auto_attrcache = 0;
-
- /* cluster name */
- gopt.cluster = NULL;
-
- /* executable map timeout */
- gopt.exec_map_timeout = AMFS_EXEC_MAP_TIMEOUT;
-
- /*
- * kernel architecture: this you must get from uname() if possible.
- */
-#if defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME)
- if (uname(&un) >= 0)
- gopt.karch = un.machine;
- else
-#endif /* defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME) */
- gopt.karch = HOST_ARCH;
-
- /* amd log file */
- gopt.logfile = NULL;
-
- /* operating system name */
- gopt.op_sys = HOST_OS_NAME;
-
- /* OS version */
- gopt.op_sys_ver = HOST_OS_VERSION;
-
- /* full OS name and version */
- gopt.op_sys_full = HOST_OS;
-
- /* OS version */
- gopt.op_sys_vendor = HOST_VENDOR;
-
- /* pid file */
- gopt.pid_file = "/dev/stdout";
-
- /* local domain */
- gopt.sub_domain = NULL;
-
- /* reset NFS (and toplvl) retransmit counter and retry interval */
- for (i=0; i<AMU_TYPE_MAX; ++i) {
- gopt.amfs_auto_retrans[i] = -1; /* -1 means "never set before" */
- gopt.amfs_auto_timeo[i] = -1; /* -1 means "never set before" */
- }
-
- /* cache duration */
- gopt.am_timeo = AM_TTL;
-
- /* dismount interval */
- gopt.am_timeo_w = AM_TTL_W;
-
- /* map reload intervl */
- gopt.map_reload_interval = ONE_HOUR;
-
- /*
- * various CFM_* flags that are on by default.
- */
- gopt.flags = CFM_DEFAULT_FLAGS;
-
-#ifdef HAVE_MAP_HESIOD
- /* Hesiod rhs zone */
- gopt.hesiod_base = "automount";
-#endif /* HAVE_MAP_HESIOD */
-
-#ifdef HAVE_MAP_LDAP
- /* LDAP base */
- gopt.ldap_base = NULL;
-
- /* LDAP host ports */
- gopt.ldap_hostports = NULL;
-
- /* LDAP cache */
- gopt.ldap_cache_seconds = 0;
- gopt.ldap_cache_maxmem = 131072;
-
- /* LDAP protocol version */
- gopt.ldap_proto_version = 2;
-#endif /* HAVE_MAP_LDAP */
-
-#ifdef HAVE_MAP_NIS
- /* YP domain name */
- gopt.nis_domain = NULL;
-#endif /* HAVE_MAP_NIS */
-}
-
-
-/*
- * Lock process text and data segment in memory (after forking the daemon)
- */
-static void
-do_memory_locking(void)
-{
-#if defined(HAVE_PLOCK) || defined(HAVE_MLOCKALL)
- int locked_ok = 0;
-#else /* not HAVE_PLOCK and not HAVE_MLOCKALL */
- plog(XLOG_WARNING, "Process memory locking not supported by the OS");
-#endif /* not HAVE_PLOCK and not HAVE_MLOCKALL */
-#ifdef HAVE_PLOCK
-# ifdef _AIX
- /*
- * On AIX you must lower the stack size using ulimit() before calling
- * plock. Otherwise plock will reserve a lot of memory space based on
- * your maximum stack size limit. Since it is not easily possible to
- * tell what should the limit be, I print a warning before calling
- * plock(). See the manual pages for ulimit(1,3,4) on your AIX system.
- */
- plog(XLOG_WARNING, "AIX: may need to lower stack size using ulimit(3) before calling plock");
-# endif /* _AIX */
- if (!locked_ok && plock(PROCLOCK) != 0)
- plog(XLOG_WARNING, "Couldn't lock process pages in memory using plock(): %m");
- else
- locked_ok = 1;
-#endif /* HAVE_PLOCK */
-#ifdef HAVE_MLOCKALL
- if (!locked_ok && mlockall(MCL_CURRENT|MCL_FUTURE) != 0)
- plog(XLOG_WARNING, "Couldn't lock process pages in memory using mlockall(): %m");
- else
- locked_ok = 1;
-#endif /* HAVE_MLOCKALL */
-#if defined(HAVE_PLOCK) || defined(HAVE_MLOCKALL)
- if (locked_ok)
- plog(XLOG_INFO, "Locked process pages in memory");
-#endif /* HAVE_PLOCK || HAVE_MLOCKALL */
-
-#if defined(HAVE_MADVISE) && defined(MADV_PROTECT)
- madvise(0, 0, MADV_PROTECT); /* may be redundant of the above worked out */
-#endif /* defined(HAVE_MADVISE) && defined(MADV_PROTECT) */
-}
-
-
-int
-main(int argc, char *argv[])
-{
- char *domdot, *verstr, *vertmp;
- int ppid = 0;
- int error;
- char *progname = NULL; /* "amd" */
- char hostname[MAXHOSTNAMELEN + 1] = "localhost"; /* Hostname */
-
- /*
- * Make sure some built-in assumptions are true before we start
- */
- assert(sizeof(nfscookie) >= sizeof(u_int));
- assert(sizeof(int) >= 4);
-
- /*
- * Set processing status.
- */
- amd_state = Start;
-
- /*
- * Determine program name
- */
- if (argv[0]) {
- progname = strrchr(argv[0], '/');
- if (progname && progname[1])
- progname++;
- else
- progname = argv[0];
- }
- if (!progname)
- progname = "amd";
- am_set_progname(progname);
-
- /*
- * Initialize process id. This is kept
- * cached since it is used for generating
- * and using file handles.
- */
- am_set_mypid();
-
- /*
- * Get local machine name
- */
- if (gethostname(hostname, sizeof(hostname)) < 0) {
- plog(XLOG_FATAL, "gethostname: %m");
- going_down(1);
- }
- hostname[sizeof(hostname) - 1] = '\0';
-
- /*
- * Check it makes sense
- */
- if (!*hostname) {
- plog(XLOG_FATAL, "host name is not set");
- going_down(1);
- }
-
- /*
- * Initialize global options structure.
- */
- init_global_options();
-
- /*
- * Partially initialize hostd[]. This
- * is completed in get_args().
- */
- if ((domdot = strchr(hostname, '.'))) {
- /*
- * Hostname already contains domainname.
- * Split out hostname and domainname
- * components
- */
- *domdot++ = '\0';
- hostdomain = domdot;
- }
- xstrlcpy(hostd, hostname, sizeof(hostd));
- am_set_hostname(hostname);
-
- /*
- * Setup signal handlers
- */
- /* SIGINT: trap interrupts for shutdowns */
- setup_sighandler(SIGINT, sigterm);
- /* SIGTERM: trap terminate so we can shutdown cleanly (some chance) */
- setup_sighandler(SIGTERM, sigterm);
- /* SIGHUP: hangups tell us to reload the cache */
- setup_sighandler(SIGHUP, sighup);
- /*
- * SIGCHLD: trap Death-of-a-child. These allow us to pick up the exit
- * status of backgrounded mounts. See "sched.c".
- */
- setup_sighandler(SIGCHLD, sigchld);
-#ifdef HAVE_SIGACTION
- /* construct global "masked_sigs" used in nfs_start.c */
- sigemptyset(&masked_sigs);
- sigaddset(&masked_sigs, SIGINT);
- sigaddset(&masked_sigs, SIGTERM);
- sigaddset(&masked_sigs, SIGHUP);
- sigaddset(&masked_sigs, SIGCHLD);
-#endif /* HAVE_SIGACTION */
-
- /*
- * Fix-up any umask problems. Most systems default
- * to 002 which is not too convenient for our purposes
- */
- orig_umask = umask(0);
-
- /*
- * Figure out primary network name
- */
- getwire(&PrimNetName, &PrimNetNum);
-
- /*
- * Determine command-line arguments
- */
- get_args(argc, argv);
-
- /*
- * Log version information.
- */
- vertmp = get_version_string();
- verstr = strtok(vertmp, "\n");
- plog(XLOG_INFO, "AM-UTILS VERSION INFORMATION:");
- while (verstr) {
- plog(XLOG_INFO, "%s", verstr);
- verstr = strtok(NULL, "\n");
- }
- XFREE(vertmp);
-
- /*
- * Get our own IP address so that we can mount the automounter. We pass
- * localhost_address which could be used as the default localhost
- * name/address in amu_get_myaddress().
- */
- amu_get_myaddress(&myipaddr, gopt.localhost_address);
- plog(XLOG_INFO, "My ip addr is %s", inet_ntoa(myipaddr));
-
- /* avoid hanging on other NFS servers if started elsewhere */
- if (chdir("/") < 0)
- plog(XLOG_INFO, "cannot chdir to /: %m");
-
- /*
- * Now check we are root.
- */
- if (geteuid() != 0) {
- plog(XLOG_FATAL, "Must be root to mount filesystems (euid = %ld)", (long) geteuid());
- going_down(1);
- }
-
-#ifdef HAVE_MAP_NIS
- /*
- * If the domain was specified then bind it here
- * to circumvent any default bindings that may
- * be done in the C library.
- */
- if (gopt.nis_domain && yp_bind(gopt.nis_domain)) {
- plog(XLOG_FATAL, "Can't bind to NIS domain \"%s\"", gopt.nis_domain);
- going_down(1);
- }
-#endif /* HAVE_MAP_NIS */
-
- if (!amuDebug(D_DAEMON))
- ppid = daemon_mode();
-
- /*
- * Lock process text and data segment in memory.
- */
- if (gopt.flags & CFM_PROCESS_LOCK) {
- do_memory_locking();
- }
-
- do_mapc_reload = clocktime(NULL) + gopt.map_reload_interval;
-
- /*
- * Register automounter with system.
- */
- error = mount_automounter(ppid);
- if (error && ppid)
- kill(ppid, SIGALRM);
-
-#ifdef HAVE_FS_AUTOFS
- /*
- * XXX this should be part of going_down(), but I can't move it there
- * because it would be calling non-library code from the library... ugh
- */
- if (amd_use_autofs)
- destroy_autofs_service();
-#endif /* HAVE_FS_AUTOFS */
-
- going_down(error);
-
- abort();
- return 1; /* should never get here */
-}
diff --git a/contrib/amd/amd/amd.h b/contrib/amd/amd/amd.h
deleted file mode 100644
index 0e371b72a5b0..000000000000
--- a/contrib/amd/amd/amd.h
+++ /dev/null
@@ -1,867 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amd.h
- *
- */
-
-#ifndef _AMD_H
-#define _AMD_H
-
-
-/*
- * MACROS:
- */
-
-/*
- * Define a default debug mtab path for systems
- * that support mtab on file.
- */
-#ifdef MOUNT_TABLE_ON_FILE
-# define DEBUG_MNTTAB_FILE "/tmp/mnttab"
-#endif /* MOUNT_TABLE_ON_FILE */
-
-/* options for amd.conf */
-#define CFM_BROWSABLE_DIRS 0x00000001
-#define CFM_MOUNT_TYPE_AUTOFS 0x00000002 /* use kernel autofs support */
-#define CFM_SELECTORS_IN_DEFAULTS 0x00000004
-#define CFM_NORMALIZE_HOSTNAMES 0x00000008
-#define CFM_PROCESS_LOCK 0x00000010
-#define CFM_PRINT_PID 0x00000020
-#define CFM_RESTART_EXISTING_MOUNTS 0x00000040
-#define CFM_SHOW_STATFS_ENTRIES 0x00000080
-#define CFM_FULLY_QUALIFIED_HOSTS 0x00000100
-#define CFM_BROWSABLE_DIRS_FULL 0x00000200 /* allow '/' in readdir() */
-#define CFM_UNMOUNT_ON_EXIT 0x00000400 /* when amd finishing */
-#define CFM_USE_TCPWRAPPERS 0x00000800
-#define CFM_AUTOFS_USE_LOFS 0x00001000
-#define CFM_NFS_INSECURE_PORT 0x00002000
-#define CFM_DOMAIN_STRIP 0x00004000
-#define CFM_NORMALIZE_SLASHES 0x00008000 /* normalize slashes? */
-#define CFM_FORCED_UNMOUNTS 0x00010000 /* forced unmounts? */
-#define CFM_TRUNCATE_LOG 0x00020000 /* truncate log file? */
-#if 0
-/* XXX: reserved to sync up with am-utils-6.2 */
-#define CFM_SUN_MAP_SYNTAX 0x00040000 /* Sun map syntax? */
-#endif
-#define CFM_NFS_ANY_INTERFACE 0x00080000 /* all interfaces are acceptable */
-
-/* defaults global flags: plock, tcpwrappers, and autofs/lofs */
-#define CFM_DEFAULT_FLAGS (CFM_PROCESS_LOCK|CFM_USE_TCPWRAPPERS|CFM_AUTOFS_USE_LOFS|CFM_DOMAIN_STRIP|CFM_NORMALIZE_SLASHES)
-
-/*
- * macro definitions for automounter vfs/vnode operations.
- */
-#define VLOOK_CREATE 0x1
-#define VLOOK_DELETE 0x2
-#define VLOOK_LOOKUP 0x3
-
-/*
- * macro definitions for automounter vfs capabilities
- */
-#define FS_DIRECTORY 0x0001 /* This looks like a dir, not a link */
-#define FS_MBACKGROUND 0x0002 /* Should background this mount */
-#define FS_NOTIMEOUT 0x0004 /* Don't bother with timeouts */
-#define FS_MKMNT 0x0008 /* Need to make the mount point */
-#define FS_UBACKGROUND 0x0010 /* Unmount in background */
-#define FS_BACKGROUND (FS_MBACKGROUND|FS_UBACKGROUND)
-#define FS_DISCARD 0x0020 /* Discard immediately on last reference */
-#define FS_AMQINFO 0x0040 /* Amq is interested in this fs type */
-#define FS_AUTOFS 0x0080 /* This filesystem can be an autofs f/s */
-#define FS_DIRECT 0x0100 /* Direct mount */
-#define FS_ON_AUTOFS 0x0200 /* This filesystem can be mounted directly
- onto an autofs mountpoint */
-
-/*
- * macros for struct am_node (map of auto-mount points).
- */
-#define AMF_NOTIMEOUT 0x0001 /* This node never times out */
-#define AMF_ROOT 0x0002 /* This is a root node */
-#define AMF_AUTOFS 0x0004 /* This node is part of an autofs filesystem */
-#define AMF_REMOUNT 0x0008 /* This node needs to be remounted */
-#define AMF_SOFTLOOKUP 0x0010 /* This node returns EIO if server is down */
-
-/*
- * macros for struct mntfs (list of mounted filesystems)
- */
-#define MFF_MOUNTED 0x0001 /* Node is mounted */
-#define MFF_MOUNTING 0x0002 /* Mount is in progress */
-#define MFF_UNMOUNTING 0x0004 /* Unmount is in progress */
-#define MFF_RESTART 0x0008 /* Restarted node */
-#define MFF_MKMNT 0x0010 /* Delete this node's am_mount */
-#define MFF_ERROR 0x0020 /* This node failed to mount */
-#define MFF_LOGDOWN 0x0040 /* Logged that this mount is down */
-#define MFF_RSTKEEP 0x0080 /* Don't timeout this filesystem - restarted */
-#define MFF_WANTTIMO 0x0100 /* Need a timeout call when not busy */
-#define MFF_NFSLINK 0x0200 /* nfsl type, and deemed a link */
-#define MFF_IS_AUTOFS 0x0400 /* this filesystem is of type autofs */
-#define MFF_NFS_SCALEDOWN 0x0800 /* the mount failed, retry with v2/UDP */
-#define MFF_ON_AUTOFS 0x1000 /* autofs has a lofs/link to this f/s */
-#define MFF_WEBNFS 0x2000 /* use public filehandle */
-
-/*
- * macros for struct fserver.
- */
-#define FSF_VALID 0x0001 /* Valid information available */
-#define FSF_DOWN 0x0002 /* This fileserver is thought to be down */
-#define FSF_ERROR 0x0004 /* Permanent error has occurred */
-#define FSF_WANT 0x0008 /* Want a wakeup call */
-#define FSF_PINGING 0x0010 /* Already doing pings */
-#define FSF_WEBNFS 0x0020 /* Don't try to contact portmapper */
-#define FSF_PING_UNINIT 0x0040 /* ping values have not been initilized */
-#define FSF_FORCE_UNMOUNT 0x0080 /* force umount of this fserver */
-#define FSRV_ERROR(fs) ((fs) && (((fs)->fs_flags & FSF_ERROR) == FSF_ERROR))
-#define FSRV_ISDOWN(fs) ((fs) && (((fs)->fs_flags & (FSF_DOWN|FSF_VALID)) == (FSF_DOWN|FSF_VALID)))
-#define FSRV_ISUP(fs) (!(fs) || (((fs)->fs_flags & (FSF_DOWN|FSF_VALID)) == (FSF_VALID)))
-
-/* some systems (SunOS 4.x) neglect to define the mount null message */
-#ifndef MOUNTPROC_NULL
-# define MOUNTPROC_NULL ((u_long)(0))
-#endif /* not MOUNTPROC_NULL */
-
-/*
- * Error to return if remote host is not available.
- * Try, in order, "host down", "host unreachable", "invalid argument".
- */
-#ifdef EHOSTDOWN
-# define AM_ERRNO_HOST_DOWN EHOSTDOWN
-#else /* not EHOSTDOWN */
-# ifdef EHOSTUNREACH
-# define AM_ERRNO_HOST_DOWN EHOSTUNREACH
-# else /* not EHOSTUNREACH */
-# define AM_ERRNO_HOST_DOWN EINVAL
-# endif /* not EHOSTUNREACH */
-#endif /* not EHOSTDOWN */
-
-/* Hash table size */
-#define NKVHASH (1 << 2) /* Power of two */
-
-/* Max entries to return in one call */
-#define MAX_READDIR_ENTRIES 16
-
-/*
- * default amfs_auto retrans - 1/10th seconds
- */
-#define AMFS_AUTO_RETRANS(x) ((ALLOWED_MOUNT_TIME*10+5*gopt.amfs_auto_timeo[(x)])/gopt.amfs_auto_timeo[(x)] * 2)
-
-/*
- * The following values can be tuned...
- */
-#define AM_TTL (300) /* Default cache period (5 min) */
-#define AM_TTL_W (120) /* Default unmount interval (2 min) */
-#define AM_PINGER 30 /* NFS ping interval for live systems */
-#define AMFS_AUTO_TIMEO 8 /* Default amfs_auto timeout - .8s */
-#define AMFS_EXEC_MAP_TIMEOUT 10 /* default 10sec exec map timeout */
-
-/* interval between forced retries of a mount */
-#define RETRY_INTERVAL 2
-
-#ifndef ROOT_MAP
-# define ROOT_MAP "\"root\""
-#endif /* not ROOT_MAP */
-
-#define ereturn(x) do { *error_return = x; return 0; } while (0)
-
-#define NEVER (time_t) 0
-
-#if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
-# define AMD_SERVICE_NAME "amd" /* for tcpwrappers */
-#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
-
-/*
- * TYPEDEFS:
- */
-
-typedef struct cf_map cf_map_t;
-typedef struct kv kv;
-typedef struct am_node am_node;
-typedef struct mntfs mntfs;
-typedef struct am_opts am_opts;
-typedef struct am_ops am_ops;
-typedef struct am_stats am_stats;
-typedef struct fserver fserver;
-
-typedef voidp wchan_t;
-typedef voidp opaque_t;
-
-/*
- * Cache map operations
- */
-typedef void add_fn(mnt_map *, char *, char *);
-typedef int init_fn(mnt_map *, char *, time_t *);
-typedef int mtime_fn(mnt_map *, char *, time_t *);
-typedef int isup_fn(mnt_map *, char *);
-typedef int reload_fn(mnt_map *, char *, add_fn *);
-typedef int search_fn(mnt_map *, char *, char *, char **, time_t *);
-typedef int task_fun(opaque_t);
-typedef void cb_fun(int, int, opaque_t);
-typedef void fwd_fun(voidp, int, struct sockaddr_in *,
- struct sockaddr_in *, opaque_t, int);
-typedef int key_fun(char *, opaque_t);
-typedef void callout_fun(opaque_t);
-
-/*
- * automounter vfs/vnode operations.
- */
-typedef char *(*vfs_match) (am_opts *);
-typedef int (*vfs_init) (mntfs *);
-typedef int (*vmount_fs) (am_node *, mntfs *);
-typedef int (*vumount_fs) (am_node *, mntfs *);
-typedef am_node *(*vlookup_child) (am_node *, char *, int *, int);
-typedef am_node *(*vmount_child) (am_node *, int *);
-typedef int (*vreaddir) (am_node *, nfscookie, nfsdirlist *, nfsentry *, u_int);
-typedef am_node *(*vreadlink) (am_node *, int *);
-typedef void (*vmounted) (mntfs *);
-typedef void (*vumounted) (mntfs *);
-typedef fserver *(*vffserver) (mntfs *);
-typedef wchan_t (*vget_wchan) (mntfs *);
-
-
-
-/*
- * STRUCTURES:
- */
-
-/* global amd options that are manipulated by conf.c */
-struct amu_global_options {
- char *arch; /* name of current architecture */
- char *auto_dir; /* automounter temp dir */
- int auto_attrcache; /* attribute cache timeout for auto dirs */
- char *cluster; /* cluster name */
- char *karch; /* kernel architecture */
- char *logfile; /* amd log file */
- char *op_sys; /* operating system name ${os} */
- char *op_sys_ver; /* OS version ${osver} */
- char *op_sys_full; /* full OS name ${full_os} */
- char *op_sys_vendor; /* name of OS vendor ${vendor} */
- char *pid_file; /* PID file */
- char *sub_domain; /* local domain */
- char *localhost_address; /* localhost address (NULL means use 127.0.0.1) */
- char *map_defaults; /* global map /default options */
- char *map_options; /* global map options */
- int map_reload_interval; /* map reload interval */
- char *map_type; /* global map type */
- char *search_path; /* search path for maps */
- char *mount_type; /* mount type for map */
- char *debug_mtab_file; /* path for the mtab file during debug mode */
- u_int flags; /* various CFM_* flags */
-
-#define AMU_TYPE_NONE -1 /* for amfs_auto_{timeo,retrans,toplvl} */
-#define AMU_TYPE_UDP 0 /* for amfs_auto_{timeo,retrans,toplvl} */
-#define AMU_TYPE_TCP 1 /* for amfs_auto_{timeo,retrans,toplvl} */
- /*
- * Note: toplvl is only UDP, but we want to separate it from regular
- * NFS mounts which Amd makes, because the toplvl mount is a localhost
- * mount for which different timeo/retrans parameters may be desired.
- */
-#define AMU_TYPE_TOPLVL 2 /* for amfs_auto_{timeo,retrans,toplvl} */
-#define AMU_TYPE_MAX 3 /* for amfs_auto_{timeo,retrans,toplvl} */
- int amfs_auto_retrans[AMU_TYPE_MAX]; /* NFS retransmit counter */
- int amfs_auto_timeo[AMU_TYPE_MAX]; /* NFS retry interval */
-
- int am_timeo; /* cache duration */
- int am_timeo_w; /* dismount interval */
- u_long portmap_program; /* amd RPC program number */
- u_short preferred_amq_port; /* preferred amq service RPC port number (0 means "any") */
-#ifdef HAVE_MAP_HESIOD
- char *hesiod_base; /* Hesiod rhs */
-#endif /* HAVE_MAP_HESIOD */
-#ifdef HAVE_MAP_LDAP
- char *ldap_base; /* LDAP base */
- char *ldap_hostports; /* LDAP host ports */
- long ldap_cache_seconds; /* LDAP internal cache - keep seconds */
- long ldap_cache_maxmem; /* LDAP internal cache - max memory (bytes) */
- long ldap_proto_version; /* LDAP protocol version */
-#endif /* HAVE_MAP_LDAP */
-#ifdef HAVE_MAP_NIS
- char *nis_domain; /* YP domain name */
-#endif /* HAVE_MAP_NIS */
- char *nfs_proto; /* NFS protocol (NULL, udp, tcp) */
- int nfs_vers; /* NFS version (0, 2, 3, 4) */
- u_int exec_map_timeout; /* timeout (seconds) for executable maps */
-};
-
-/* if you add anything here, update conf.c:reset_cf_map() */
-struct cf_map {
- char *cfm_dir; /* /home, /u, /src */
- char *cfm_name; /* amd.home, /etc/amd.home ... */
- char *cfm_type; /* file, hesiod, ndbm, nis ... */
- char *cfm_defaults; /* map /defaults options in amd.conf */
- char *cfm_opts; /* -cache:=all, etc. */
- char *cfm_search_path; /* /etc/local:/etc/amdmaps:/misc/yp */
- char *cfm_tag; /* optional map tag for amd -T */
- u_int cfm_flags; /* browsable_dirs? mount_type? */
- struct cf_map *cfm_next; /* pointer to next in list (if any) */
-};
-
-/*
- * Key-value pair
- */
-struct kv {
- kv *next;
- char *key;
-#ifdef HAVE_REGEXEC
- regex_t re; /* store the regexp from regcomp() */
-#endif /* HAVE_REGEXEC */
- char *val;
-};
-
-struct mnt_map {
- qelem hdr;
- int refc; /* Reference count */
- short flags; /* Allocation flags */
- short alloc; /* Allocation mode */
- time_t modify; /* Modify time of map */
- u_int reloads; /* Number of times map was reloaded */
- char *map_name; /* Name of this map */
- char *wildcard; /* Wildcard value */
- reload_fn *reload; /* Function to be used for reloads */
- isup_fn *isup; /* Is service up or not? (1=up, 0=down) */
- search_fn *search; /* Function to be used for searching */
- mtime_fn *mtime; /* Modify time function */
- kv *kvhash[NKVHASH]; /* Cached data */
- cf_map_t *cfm; /* pointer to per-map amd.conf opts, if any */
- void *map_data; /* Map data black box */
-};
-
-/*
- * Options
- */
-struct am_opts {
- char *fs_glob; /* Smashed copy of global options */
- char *fs_local; /* Expanded copy of local options */
- char *fs_mtab; /* Mount table entry */
- /* Other options ... */
- char *opt_dev;
- char *opt_delay;
- char *opt_dir;
- char *opt_fs;
- char *opt_group;
- char *opt_mount;
- char *opt_opts;
- char *opt_remopts;
- char *opt_pref;
- char *opt_cache;
- char *opt_rfs;
- char *opt_rhost;
- char *opt_sublink;
- char *opt_type;
- char *opt_mount_type; /* "nfs" or "autofs" */
- char *opt_unmount;
- char *opt_umount; /* an "alias" for opt_unmount (type:=program) */
- char *opt_user;
- char *opt_maptype; /* map type: file, nis, hesiod, etc. */
- char *opt_cachedir; /* cache directory */
- char *opt_addopts; /* options to add to opt_opts */
-};
-
-struct am_ops {
- char *fs_type; /* type of filesystems e.g. "nfsx" */
- vfs_match fs_match; /* fxn: match */
- vfs_init fs_init; /* fxn: initialization */
- vmount_fs mount_fs; /* fxn: mount my own vnode */
- vumount_fs umount_fs; /* fxn: unmount my own vnode */
- vlookup_child lookup_child; /* fxn: lookup path-name */
- vmount_child mount_child; /* fxn: mount path-name */
- vreaddir readdir; /* fxn: read directory */
- vreadlink readlink; /* fxn: read link */
- vmounted mounted; /* fxn: after-mount extra actions */
- vumounted umounted; /* fxn: after-umount extra actions */
- vffserver ffserver; /* fxn: find a file server */
- vget_wchan get_wchan; /* fxn: get the waiting channel */
- int nfs_fs_flags; /* filesystem flags FS_* for nfs mounts */
-#ifdef HAVE_FS_AUTOFS
- int autofs_fs_flags;/* filesystem flags FS_* for autofs mounts */
-#endif /* HAVE_FS_AUTOFS */
-};
-
-/*
- * List of mounted filesystems
- */
-struct mntfs {
- qelem mf_q; /* List of mounted filesystems */
- am_ops *mf_ops; /* Operations on this mountpoint */
- am_opts *mf_fo; /* File opts */
- char *mf_mount; /* "/a/kiska/home/kiska" */
- char *mf_info; /* Mount info */
- char *mf_auto; /* Automount opts */
- char *mf_mopts; /* FS mount opts */
- char *mf_remopts; /* Remote FS mount opts */
- char *mf_loopdev; /* loop device name for /dev/loop mounts */
- fserver *mf_server; /* File server */
- int mf_fsflags; /* Flags FS_* copied from mf_ops->*_fs_flags */
- int mf_flags; /* Flags MFF_* */
- int mf_error; /* Error code from background mount */
- int mf_refc; /* Number of references to this node */
- int mf_cid; /* Callout id */
- void (*mf_prfree) (opaque_t); /* Free private space */
- opaque_t mf_private; /* Private - per-fs data */
-};
-
-/*
- * List of fileservers
- */
-struct fserver {
- qelem fs_q; /* List of fileservers */
- int fs_refc; /* Number of references to this server */
- char *fs_host; /* Normalized hostname of server */
- struct sockaddr_in *fs_ip; /* Network address of server */
- int fs_cid; /* Callout id */
- int fs_pinger; /* Ping (keepalive) interval */
- int fs_flags; /* Flags */
- char *fs_type; /* File server type */
- u_long fs_version; /* NFS version of server (2, 3, etc.)*/
- char *fs_proto; /* NFS protocol of server (tcp, udp, etc.) */
- opaque_t fs_private; /* Private data */
- void (*fs_prfree) (opaque_t); /* Free private data */
-};
-
-/*
- * Per-mountpoint statistics
- */
-struct am_stats {
- time_t s_mtime; /* Mount time */
- u_short s_uid; /* Uid of mounter */
- int s_getattr; /* Count of getattrs */
- int s_lookup; /* Count of lookups */
- int s_readdir; /* Count of readdirs */
- int s_readlink; /* Count of readlinks */
- int s_statfs; /* Count of statfs */
-};
-
-/*
- * System statistics
- */
-struct amd_stats {
- int d_drops; /* Dropped requests */
- int d_stale; /* Stale NFS handles */
- int d_mok; /* Successful mounts */
- int d_merr; /* Failed mounts */
- int d_uerr; /* Failed unmounts */
-};
-extern struct amd_stats amd_stats;
-
-/*
- * Map of auto-mount points.
- */
-struct am_node {
- int am_mapno; /* Map number */
- mntfs *am_mnt; /* Mounted filesystem */
- mntfs **am_mfarray; /* Filesystem sources to try to mount */
- char *am_name; /* "kiska": name of this node */
- char *am_path; /* "/home/kiska": path of this node's mount point */
- char *am_link; /* "/a/kiska/home/kiska/this/that": link to sub-dir */
- am_node *am_parent; /* Parent of this node */
- am_node *am_ysib; /* Younger sibling of this node */
- am_node *am_osib; /* Older sibling of this node */
- am_node *am_child; /* First child of this node */
- nfsattrstat am_attr; /* File attributes */
-#define am_fattr am_attr.ns_u.ns_attr_u
- int am_flags; /* Boolean flags AMF_* */
- int am_error; /* Specific mount error */
- time_t am_ttl; /* Time to live */
- int am_timeo_w; /* Dismount wait interval */
- int am_timeo; /* Cache timeout interval */
- u_int am_gen; /* Generation number */
- char *am_pref; /* Mount info prefix */
- am_stats am_stats; /* Statistics gathering */
- SVCXPRT *am_transp; /* Info for quick reply */
- dev_t am_dev; /* Device number */
- dev_t am_rdev; /* Remote/real device number */
-#ifdef HAVE_FS_AUTOFS
- autofs_fh_t *am_autofs_fh;
- time_t am_autofs_ttl; /* Time to expire autofs nodes */
-#endif /* HAVE_FS_AUTOFS */
-};
-
-/*
- * EXTERNALS:
- */
-
-/*
- * Amq server global functions
- */
-extern amq_mount_info_list *amqproc_getmntfs_1_svc(voidp argp, struct svc_req *rqstp);
-extern amq_mount_stats *amqproc_stats_1_svc(voidp argp, struct svc_req *rqstp);
-extern amq_mount_tree_list *amqproc_export_1_svc(voidp argp, struct svc_req *rqstp);
-extern amq_mount_tree_p *amqproc_mnttree_1_svc(voidp argp, struct svc_req *rqstp);
-extern amq_string *amqproc_getvers_1_svc(voidp argp, struct svc_req *rqstp);
-extern amq_string *amqproc_pawd_1_svc(voidp argp, struct svc_req *rqstp);
-extern int *amqproc_getpid_1_svc(voidp argp, struct svc_req *rqstp);
-extern int *amqproc_mount_1_svc(voidp argp, struct svc_req *rqstp);
-extern int *amqproc_setopt_1_svc(voidp argp, struct svc_req *rqstp);
-extern voidp amqproc_null_1_svc(voidp argp, struct svc_req *rqstp);
-extern voidp amqproc_umnt_1_svc(voidp argp, struct svc_req *rqstp);
-
-/* other external definitions */
-extern am_nfs_fh *get_root_nfs_fh(char *dir);
-extern am_node *find_ap(char *);
-extern am_node *get_ap_child(am_node *, char *);
-extern bool_t xdr_amq_mount_info_qelem(XDR *xdrs, qelem *qhead);
-extern fserver *find_nfs_srvr(mntfs *mf);
-extern int mount_nfs_fh(am_nfs_handle_t *fhp, char *mntdir, char *fs_name, mntfs *mf);
-extern int process_all_regular_maps(void);
-extern cf_map_t *find_cf_map(const char *name);
-extern int set_conf_kv(const char *section, const char *k, const char *v);
-extern int mount_node(opaque_t arg);
-extern int unmount_mp(am_node *mp);
-extern int yyparse (void);
-
-extern void amfs_mkcacheref(mntfs *mf);
-extern int amfs_mount(am_node *mp, mntfs *mf, char *opts);
-extern void assign_error_mntfs(am_node *mp);
-extern am_node *next_nonerror_node(am_node *xp);
-extern void flush_srvr_nfs_cache(fserver *fs);
-extern void am_mounted(am_node *);
-extern void mf_mounted(mntfs *mf, bool_t call_free_opts);
-extern void am_unmounted(am_node *);
-extern am_node *get_exported_ap(int index);
-extern am_node *get_first_exported_ap(int *index);
-extern am_node *get_next_exported_ap(int *index);
-extern am_node *path_to_exported_ap(char *path);
-extern am_node *exported_ap_alloc(void);
-extern am_node *find_mf(mntfs *);
-extern am_node *next_map(int *);
-extern am_ops *ops_match(am_opts *, char *, char *, char *, char *, char *);
-extern am_ops *ops_search(char *);
-extern fserver *dup_srvr(fserver *);
-extern void srvrlog(fserver *, char *);
-extern int get_mountd_port(fserver *, u_short *, wchan_t);
-extern void flush_nfs_fhandle_cache(fserver *);
-
-extern mntfs *dup_mntfs(mntfs *);
-extern mntfs *find_mntfs(am_ops *, am_opts *, char *, char *, char *, char *, char *);
-extern mntfs *locate_mntfs(am_ops *, am_opts *, char *, char *, char *, char *, char *);
-extern mntfs *new_mntfs(void);
-extern mntfs *realloc_mntfs(mntfs *, am_ops *, am_opts *, char *, char *, char *, char *, char *);
-extern void flush_mntfs(void);
-extern void free_mntfs(voidp);
-
-
-extern void amq_program_1(struct svc_req *rqstp, SVCXPRT *transp);
-extern int background(void);
-extern void deslashify(char *);
-extern void do_task_notify(void);
-extern int eval_fs_opts(am_opts *, char *, char *, char *, char *, char *);
-extern void forcibly_timeout_mp(am_node *);
-extern void free_map(am_node *);
-extern void free_opts(am_opts *);
-extern void free_srvr(fserver *);
-extern int fwd_init(void);
-extern int fwd_packet(int, char *, int, struct sockaddr_in *, struct sockaddr_in *, opaque_t, fwd_fun *);
-extern void fwd_reply(void);
-extern void get_args(int argc, char *argv[]);
-extern wchan_t get_mntfs_wchan(mntfs *mf);
-extern void host_normalize(char **);
-extern void init_map(am_node *, char *);
-extern void ins_que(qelem *, qelem *);
-extern void insert_am(am_node *, am_node *);
-extern int make_nfs_auth(void);
-extern void make_root_node(void);
-extern void map_flush_srvr(fserver *);
-extern void mapc_add_kv(mnt_map *, char *, char *);
-extern mnt_map *mapc_find(char *, char *, const char *);
-extern void mapc_free(opaque_t);
-extern int mapc_keyiter(mnt_map *, key_fun, opaque_t);
-extern void mapc_reload(void);
-extern int mapc_search(mnt_map *, char *, char **);
-extern void mapc_showtypes(char *buf, size_t l);
-extern int mapc_type_exists(const char *type);
-extern void mk_fattr(nfsfattr *, nfsftype);
-extern int mount_auto_node(char *, opaque_t);
-extern int mount_automounter(int);
-extern int mount_exported(void);
-extern void mp_to_fh(am_node *, am_nfs_fh *);
-extern void new_ttl(am_node *);
-extern void nfs_quick_reply(am_node *mp, int error);
-extern void normalize_slash(char *);
-extern void ops_showamfstypes(char *buf, size_t l);
-extern void ops_showfstypes(char *outbuf, size_t l);
-extern void rem_que(qelem *);
-extern void reschedule_timeout_mp(void);
-extern void restart(void);
-extern void restart_automounter_nodes(void);
-extern int root_keyiter(key_fun *, opaque_t);
-extern void root_newmap(const char *, const char *, const char *, const cf_map_t *);
-extern void run_task(task_fun *, opaque_t, cb_fun *, opaque_t);
-extern void sched_task(cb_fun *, opaque_t, wchan_t);
-extern int softclock(void);
-extern int timeout(u_int, void (*fn)(opaque_t), opaque_t);
-extern void timeout_mp(opaque_t);
-extern void untimeout(int);
-extern void umount_exported(void);
-extern int valid_key(char *);
-extern void wakeup(wchan_t);
-extern void wakeup_srvr(fserver *);
-extern void wakeup_task(int, int, wchan_t);
-#define SIZEOF_PID_FSNAME (16 + MAXHOSTNAMELEN)
-extern char pid_fsname[SIZEOF_PID_FSNAME]; /* "kiska.southseas.nz:(pid%d)" */
-#define SIZEOF_HOSTD (2 * MAXHOSTNAMELEN + 1)
-extern char hostd[SIZEOF_HOSTD]; /* Host+domain */
-#define SIZEOF_OPTS 256 /* used for char opts[] and preopts[] */
-
-/*
- * Global variables.
- */
-extern FILE *yyin;
-extern SVCXPRT *current_transp; /* For nfs_quick_reply() */
-extern char *conf_tag;
-#define SIZEOF_UID_STR 12
-#define SIZEOF_GID_STR 12
-extern char *opt_gid, gid_str[SIZEOF_GID_STR];
-extern char *opt_uid, uid_str[SIZEOF_UID_STR];
-extern int NumChildren;
-extern int fwd_sock;
-extern int select_intr_valid;
-extern int immediate_abort; /* Should close-down unmounts be retried */
-extern int usage;
-extern int use_conf_file; /* use amd configuration file */
-extern int task_notify_todo; /* Task notifier needs running */
-extern jmp_buf select_intr;
-extern qelem mfhead;
-extern struct amu_global_options gopt; /* where global options are stored */
-extern time_t do_mapc_reload; /* Flush & reload mount map cache */
-extern time_t next_softclock; /* Time to call softclock() */
-
-#ifdef HAVE_SIGACTION
-extern sigset_t masked_sigs;
-#endif /* HAVE_SIGACTION */
-
-#if defined(HAVE_AMU_FS_LINK) || defined(HAVE_AMU_FS_LINKX)
-extern char *amfs_link_match(am_opts *fo);
-#endif /* defined(HAVE_AMU_FS_LINK) || defined(HAVE_AMU_FS_LINKX) */
-
-#ifdef HAVE_FS_AUTOFS
-extern int amd_use_autofs;
-
-extern int autofs_get_fh(am_node *mp);
-extern void autofs_release_fh(am_node *mp);
-extern void autofs_get_mp(am_node *mp);
-extern void autofs_release_mp(am_node *mp);
-extern void autofs_add_fdset(fd_set *readfds);
-extern int autofs_handle_fdset(fd_set *readfds, int nsel);
-extern void autofs_mounted(am_node *mp);
-extern void autofs_mount_succeeded(am_node *mp);
-extern void autofs_mount_failed(am_node *mp);
-extern int autofs_umount_succeeded(am_node *mp);
-extern int autofs_umount_failed(am_node *mp);
-extern int autofs_mount_fs(am_node *mp, mntfs *mf);
-extern int autofs_umount_fs(am_node *mp, mntfs *mf);
-extern void autofs_get_opts(char *opts, size_t l, autofs_fh_t *fh);
-extern int autofs_compute_mount_flags(mntent_t *);
-extern void autofs_timeout_mp(am_node *);
-extern int create_autofs_service(void);
-extern int destroy_autofs_service(void);
-#endif /* HAVE_FS_AUTOFS */
-
-/**************************************************************************/
-/*** Generic file-system types, implemented as part of the native O/S. ***/
-/**************************************************************************/
-
-/*
- * Loopback File System
- * Many systems can't support this, and in any case most of the
- * functionality is available with Symlink FS.
- */
-#ifdef HAVE_FS_LOFS
-extern am_ops lofs_ops;
-extern int mount_lofs(char *mntdir, char *fs_name, char *opts, int on_autofs);
-#endif /* HAVE_FS_LOFS */
-
-/*
- * CD-ROM File System (CD-ROM)
- * (HSFS: High Sierra F/S on some machines)
- * Many systems can't support this, and in any case most of the
- * functionality is available with program FS.
- */
-#ifdef HAVE_FS_CDFS
-extern am_ops cdfs_ops;
-#endif /* HAVE_FS_CDFS */
-
-/*
- * PC File System (MS-DOS)
- * Many systems can't support this, and in any case most of the
- * functionality is available with program FS.
- */
-#ifdef HAVE_FS_PCFS
-extern am_ops pcfs_ops;
-#endif /* HAVE_FS_PCFS */
-
-/*
- * Caching File System (Solaris)
- */
-#ifdef HAVE_FS_CACHEFS
-extern am_ops cachefs_ops;
-#endif /* HAVE_FS_CACHEFS */
-
-/*
- * Network File System
- * Good, slow, NFS V.2.
- */
-#ifdef HAVE_FS_NFS
-extern am_ops nfs_ops; /* NFS */
-extern fserver *find_nfs_srvr (mntfs *);
-extern qelem nfs_srvr_list;
-#endif /* HAVE_FS_NFS */
-
-/*
- * Un*x File System
- * Normal local disk file system.
- */
-#ifdef HAVE_FS_UFS
-extern am_ops ufs_ops; /* Un*x file system */
-#endif /* HAVE_FS_UFS */
-
-/* Unix file system (irix) */
-#ifdef HAVE_FS_XFS
-extern am_ops xfs_ops; /* Un*x file system */
-#endif /* HAVE_FS_XFS */
-
-/* Unix file system (irix) */
-#ifdef HAVE_FS_EFS
-extern am_ops efs_ops; /* Un*x file system */
-#endif /* HAVE_FS_EFS */
-
-/**************************************************************************/
-/*** Automounter file-system types, implemented by amd. ***/
-/**************************************************************************/
-
-/*
- * Root AMD File System
- */
-extern am_ops amfs_root_ops; /* Root file system */
-
-/*
- * Generic amfs helper methods
- */
-extern am_node *amfs_generic_lookup_child(am_node *mp, char *fname, int *error_return, int op);
-extern am_node *amfs_generic_mount_child(am_node *ap, int *error_return);
-extern int amfs_generic_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count);
-extern int amfs_generic_umount(am_node *mp, mntfs *mf);
-extern void amfs_generic_mounted(mntfs *mf);
-extern char *amfs_generic_match(am_opts *fo);
-extern fserver *amfs_generic_find_srvr(mntfs *);
-
-/*
- * Automount File System
- */
-#ifdef HAVE_AMU_FS_AUTO
-extern am_ops amfs_auto_ops; /* Automount file system (this!) */
-#endif /* HAVE_AMU_FS_AUTO */
-
-/*
- * Toplvl Automount File System
- */
-#ifdef HAVE_AMU_FS_TOPLVL
-extern am_ops amfs_toplvl_ops; /* Toplvl Automount file system */
-extern int amfs_toplvl_mount(am_node *mp, mntfs *mf);
-extern int amfs_toplvl_umount(am_node *mp, mntfs *mf);
-#endif /* HAVE_AMU_FS_TOPLVL */
-
-/*
- * Direct Automount File System
- */
-#ifdef HAVE_AMU_FS_DIRECT
-extern am_ops amfs_direct_ops; /* Direct Automount file system (this too) */
-#endif /* HAVE_AMU_FS_DIRECT */
-
-/*
- * Error File System
- */
-#ifdef HAVE_AMU_FS_ERROR
-extern am_ops amfs_error_ops; /* Error file system */
-extern am_node *amfs_error_lookup_child(am_node *mp, char *fname, int *error_return, int op);
-extern am_node *amfs_error_mount_child(am_node *ap, int *error_return);
-extern int amfs_error_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count);
-#endif /* HAVE_AMU_FS_ERROR */
-
-/*
- * NFS mounts with local existence check.
- */
-#ifdef HAVE_AMU_FS_NFSL
-extern am_ops amfs_nfsl_ops; /* NFSL */
-#endif /* HAVE_AMU_FS_NFSL */
-
-/*
- * Multi-nfs mounts.
- */
-#ifdef HAVE_AMU_FS_NFSX
-extern am_ops amfs_nfsx_ops; /* NFSX */
-#endif /* HAVE_AMU_FS_NFSX */
-
-/*
- * NFS host - a whole tree.
- */
-#ifdef HAVE_AMU_FS_HOST
-extern am_ops amfs_host_ops; /* NFS host */
-#endif /* HAVE_AMU_FS_HOST */
-
-/*
- * Program File System
- * This is useful for things like RVD.
- */
-#ifdef HAVE_AMU_FS_PROGRAM
-extern am_ops amfs_program_ops; /* Program File System */
-#endif /* HAVE_AMU_FS_PROGRAM */
-
-/*
- * Symbolic-link file system.
- * A "filesystem" which is just a symbol link.
- */
-#ifdef HAVE_AMU_FS_LINK
-extern am_ops amfs_link_ops; /* Symlink FS */
-#endif /* HAVE_AMU_FS_LINK */
-
-/*
- * Symbolic-link file system, which also checks that the target of
- * the symlink exists.
- * A "filesystem" which is just a symbol link.
- */
-#ifdef HAVE_AMU_FS_LINKX
-extern am_ops amfs_linkx_ops; /* Symlink FS with existence check */
-#endif /* HAVE_AMU_FS_LINKX */
-
-/*
- * Union file system
- */
-#ifdef HAVE_AMU_FS_UNION
-extern am_ops amfs_union_ops; /* Union FS */
-#endif /* HAVE_AMU_FS_UNION */
-
-#endif /* not _AMD_H */
diff --git a/contrib/amd/amd/amfs_auto.c b/contrib/amd/amd/amfs_auto.c
deleted file mode 100644
index 75a451fd111d..000000000000
--- a/contrib/amd/amd/amfs_auto.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amfs_auto.c
- *
- */
-
-/*
- * Automount file system
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/****************************************************************************
- *** MACROS ***
- ****************************************************************************/
-
-
-/****************************************************************************
- *** STRUCTURES ***
- ****************************************************************************/
-
-
-/****************************************************************************
- *** FORWARD DEFINITIONS ***
- ****************************************************************************/
-static int amfs_auto_mount(am_node *mp, mntfs *mf);
-
-
-/****************************************************************************
- *** OPS STRUCTURES ***
- ****************************************************************************/
-am_ops amfs_auto_ops =
-{
- "auto",
- amfs_generic_match,
- 0, /* amfs_auto_init */
- amfs_auto_mount,
- amfs_generic_umount,
- amfs_generic_lookup_child,
- amfs_generic_mount_child,
- amfs_generic_readdir,
- 0, /* amfs_auto_readlink */
- amfs_generic_mounted,
- 0, /* amfs_auto_umounted */
- amfs_generic_find_srvr,
- 0, /* amfs_auto_get_wchan */
- FS_AMQINFO | FS_DIRECTORY,
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_AUTO_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/****************************************************************************
- *** FUNCTIONS ***
- ****************************************************************************/
-/*
- * Mount a sub-mount
- */
-static int
-amfs_auto_mount(am_node *mp, mntfs *mf)
-{
- /*
- * Pseudo-directories are used to provide some structure
- * to the automounted directories instead
- * of putting them all in the top-level automount directory.
- *
- * Here, just increment the parent's link count.
- */
- mp->am_parent->am_fattr.na_nlink++;
-
- /*
- * Info field of . means use parent's info field.
- * Historical - not documented.
- */
- if (mf->mf_info[0] == '.' && mf->mf_info[1] == '\0')
- mf->mf_info = strealloc(mf->mf_info, mp->am_parent->am_mnt->mf_info);
-
- /*
- * Compute prefix:
- *
- * If there is an option prefix then use that else
- * If the parent had a prefix then use that with name
- * of this node appended else
- * Use the name of this node.
- *
- * That means if you want no prefix you must say so
- * in the map.
- */
- if (mf->mf_fo->opt_pref) {
- /* allow pref:=null to set a real null prefix */
- if (STREQ(mf->mf_fo->opt_pref, "null")) {
- mp->am_pref = strdup("");
- } else {
- /*
- * 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, "/");
- }
-
-#ifdef HAVE_FS_AUTOFS
- if (mf->mf_flags & MFF_IS_AUTOFS) {
- char opts[SIZEOF_OPTS];
- int error;
-
- autofs_get_opts(opts, sizeof(opts), mp->am_autofs_fh);
-
- /* now do the mount */
- error = amfs_mount(mp, mf, opts);
- if (error) {
- errno = error;
- plog(XLOG_FATAL, "amfs_auto_mount: amfs_mount failed: %m");
- return error;
- }
- }
-#endif /* HAVE_FS_AUTOFS */
-
- /*
- * Attach a map cache
- */
- amfs_mkcacheref(mf);
-
- return 0;
-}
diff --git a/contrib/amd/amd/amfs_direct.c b/contrib/amd/amd/amfs_direct.c
deleted file mode 100644
index dbef743d0d7e..000000000000
--- a/contrib/amd/amd/amfs_direct.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amfs_direct.c
- *
- */
-
-/*
- * Direct file system
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/****************************************************************************
- *** FORWARD DEFINITIONS ***
- ****************************************************************************/
-static am_node *amfs_direct_readlink(am_node *mp, int *error_return);
-
-/****************************************************************************
- *** OPS STRUCTURES ***
- ****************************************************************************/
-am_ops amfs_direct_ops =
-{
- "direct",
- amfs_generic_match,
- 0, /* amfs_direct_init */
- amfs_toplvl_mount,
- amfs_toplvl_umount,
- amfs_generic_lookup_child,
- amfs_generic_mount_child,
- amfs_error_readdir,
- amfs_direct_readlink,
- amfs_generic_mounted,
- 0, /* amfs_direct_umounted */
- amfs_generic_find_srvr,
- 0, /* amfs_direct_get_wchan */
- FS_DIRECT | FS_MKMNT | FS_NOTIMEOUT | FS_BACKGROUND | FS_AMQINFO,
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_DIRECT_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/****************************************************************************
- *** FUNCTIONS ***
- ****************************************************************************/
-
-static am_node *
-amfs_direct_readlink(am_node *mp, int *error_return)
-{
- am_node *xp;
- int rc = 0;
-
- xp = next_nonerror_node(mp->am_child);
- if (!xp) {
- if (!mp->am_mnt->mf_private)
- amfs_mkcacheref(mp->am_mnt); /* XXX */
- xp = amfs_generic_lookup_child(mp, mp->am_path + 1, &rc, VLOOK_CREATE);
- if (xp && rc < 0)
- xp = amfs_generic_mount_child(xp, &rc);
- }
- if (xp) {
- new_ttl(xp); /* (7/12/89) from Rein Tollevik */
- return xp;
- }
- if (amd_state == Finishing)
- rc = ENOENT;
- *error_return = rc;
- return 0;
-}
diff --git a/contrib/amd/amd/amfs_error.c b/contrib/amd/amd/amfs_error.c
deleted file mode 100644
index 51bdaa6db14d..000000000000
--- a/contrib/amd/amd/amfs_error.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amfs_error.c
- *
- */
-
-/*
- * Error file system.
- * This is used as a last resort catchall if
- * nothing else worked. EFS just returns lots
- * of error codes, except for unmount which
- * always works of course.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-static char *amfs_error_match(am_opts *fo);
-static int amfs_error_mount(am_node *am, mntfs *mf);
-static int amfs_error_umount(am_node *am, mntfs *mf);
-
-
-/*
- * Ops structure
- */
-am_ops amfs_error_ops =
-{
- "error",
- amfs_error_match,
- 0, /* amfs_error_init */
- amfs_error_mount,
- amfs_error_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* amfs_error_readlink */
- 0, /* amfs_error_mounted */
- 0, /* amfs_error_umounted */
- amfs_generic_find_srvr,
- 0, /* amfs_error_get_wchan */
- FS_DISCARD, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_ERROR_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-
-/*
- * EFS file system always matches
- */
-static char *
-amfs_error_match(am_opts *fo)
-{
- return strdup("(error-hook)");
-}
-
-
-static int
-amfs_error_mount(am_node *am, mntfs *mf)
-{
- return ENOENT;
-}
-
-
-static int
-amfs_error_umount(am_node *am, mntfs *mf)
-{
- /*
- * Always succeed
- */
- return 0;
-}
-
-
-/*
- * EFS interface to RPC lookup() routine.
- * Should never get here in the automounter.
- * If we do then just give an error.
- */
-am_node *
-amfs_error_lookup_child(am_node *mp, char *fname, int *error_return, int op)
-{
- *error_return = ESTALE;
- return 0;
-}
-
-
-/*
- * EFS interface to RPC lookup() routine.
- * Should never get here in the automounter.
- * If we do then just give an error.
- */
-am_node *
-amfs_error_mount_child(am_node *ap, int *error_return)
-{
- *error_return = ESTALE;
- return 0;
-}
-
-
-/*
- * EFS interface to RPC readdir() routine.
- * Should never get here in the automounter.
- * If we do then just give an error.
- */
-int
-amfs_error_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count)
-{
- return ESTALE;
-}
diff --git a/contrib/amd/amd/amfs_generic.c b/contrib/amd/amd/amfs_generic.c
deleted file mode 100644
index 3e7c365a7593..000000000000
--- a/contrib/amd/amd/amfs_generic.c
+++ /dev/null
@@ -1,1262 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amfs_generic.c
- *
- */
-
-/*
- * generic functions used by amfs filesystems, ripped out of amfs_auto.c.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-
-/****************************************************************************
- *** MACROS ***
- ****************************************************************************/
-#define IN_PROGRESS(cp) ((cp)->mp->am_mnt->mf_flags & MFF_MOUNTING)
-
-
-/****************************************************************************
- *** STRUCTURES ***
- ****************************************************************************/
-/*
- * Mounting a file system may take a significant period of time. The
- * problem is that if this is done in the main process thread then the
- * entire automounter could be blocked, possibly hanging lots of processes
- * on the system. Instead we use a continuation scheme to allow mounts to
- * be attempted in a sub-process. When the sub-process exits we pick up the
- * exit status (by convention a UN*X error number) and continue in a
- * notifier. The notifier gets handed a data structure and can then
- * determine whether the mount was successful or not. If not, it updates
- * the data structure and tries again until there are no more ways to try
- * the mount, or some other permanent error occurs. In the mean time no RPC
- * reply is sent, even after the mount is successful. We rely on the RPC
- * retry mechanism to resend the lookup request which can then be handled.
- */
-struct continuation {
- am_node *mp; /* Node we are trying to mount */
- int retry; /* Try again? */
- time_t start; /* Time we started this mount */
- int callout; /* Callout identifier */
- mntfs **mf; /* Current mntfs */
-};
-
-
-/****************************************************************************
- *** FORWARD DEFINITIONS ***
- ****************************************************************************/
-static am_node *amfs_lookup_node(am_node *mp, char *fname, int *error_return);
-static mntfs *amfs_lookup_one_mntfs(am_node *new_mp, mntfs *mf, char *ivec,
- char *def_opts, char *pfname);
-static mntfs **amfs_lookup_mntfs(am_node *new_mp, int *error_return);
-static void amfs_cont(int rc, int term, opaque_t arg);
-static void amfs_retry(int rc, int term, opaque_t arg);
-static void free_continuation(struct continuation *cp);
-static int amfs_bgmount(struct continuation *cp);
-static char *amfs_parse_defaults(am_node *mp, mntfs *mf, char *def_opts);
-
-
-/****************************************************************************
- *** FUNCTIONS ***
- ****************************************************************************/
-static am_node *
-amfs_lookup_node(am_node *mp, char *fname, int *error_return)
-{
- am_node *new_mp;
- int error = 0; /* Error so far */
- int in_progress = 0; /* # of (un)mount in progress */
- mntfs *mf;
- char *expanded_fname = 0;
-
- dlog("in amfs_lookup_node");
-
- /*
- * If the server is shutting down
- * then don't return information
- * about the mount point.
- */
- if (amd_state == Finishing) {
- if (mp->am_mnt == 0 || mp->am_mnt->mf_fsflags & FS_DIRECT) {
- dlog("%s mount ignored - going down", fname);
- } else {
- dlog("%s/%s mount ignored - going down", mp->am_path, fname);
- }
- ereturn(ENOENT);
- }
-
- /*
- * Handle special case of "." and ".."
- */
- if (fname[0] == '.') {
- if (fname[1] == '\0')
- return mp; /* "." is the current node */
- if (fname[1] == '.' && fname[2] == '\0') {
- if (mp->am_parent) {
- dlog(".. in %s gives %s", mp->am_path, mp->am_parent->am_path);
- return mp->am_parent; /* ".." is the parent node */
- }
- ereturn(ESTALE);
- }
- }
-
- /*
- * Check for valid key name.
- * If it is invalid then pretend it doesn't exist.
- */
- if (!valid_key(fname)) {
- plog(XLOG_WARNING, "Key \"%s\" contains a disallowed character", fname);
- ereturn(ENOENT);
- }
-
- /*
- * Expand key name.
- * expanded_fname is now a private copy.
- */
- expanded_fname = expand_selectors(fname);
-
- /*
- * Search children of this node
- */
- for (new_mp = mp->am_child; new_mp; new_mp = new_mp->am_osib) {
- if (FSTREQ(new_mp->am_name, expanded_fname)) {
- if (new_mp->am_error) {
- error = new_mp->am_error;
- continue;
- }
-
- /*
- * If the error code is undefined then it must be
- * in progress.
- */
- mf = new_mp->am_mnt;
- if (mf->mf_error < 0)
- goto in_progrss;
-
- /*
- * If there was a previous error with this node
- * then return that error code.
- */
- if (mf->mf_flags & MFF_ERROR) {
- error = mf->mf_error;
- continue;
- }
- if (!(mf->mf_flags & MFF_MOUNTED) || (mf->mf_flags & MFF_UNMOUNTING)) {
- in_progrss:
- /*
- * If the fs is not mounted or it is unmounting then there
- * is a background (un)mount in progress. In this case
- * we just drop the RPC request (return nil) and
- * wait for a retry, by which time the (un)mount may
- * have completed.
- */
- dlog("ignoring mount of %s in %s -- %smounting in progress, flags %x",
- expanded_fname, mf->mf_mount,
- (mf->mf_flags & MFF_UNMOUNTING) ? "un" : "", mf->mf_flags);
- in_progress++;
- if (mf->mf_flags & MFF_UNMOUNTING) {
- dlog("will remount later");
- new_mp->am_flags |= AMF_REMOUNT;
- }
- continue;
- }
-
- /*
- * Otherwise we have a hit: return the current mount point.
- */
- dlog("matched %s in %s", expanded_fname, new_mp->am_path);
- XFREE(expanded_fname);
- return new_mp;
- }
- }
-
- if (in_progress) {
- dlog("Waiting while %d mount(s) in progress", in_progress);
- XFREE(expanded_fname);
- ereturn(-1);
- }
-
- /*
- * If an error occurred then return it.
- */
- if (error) {
- dlog("Returning error: %s", strerror(error));
- XFREE(expanded_fname);
- ereturn(error);
- }
-
- /*
- * If the server is going down then just return,
- * don't try to mount any more file systems
- */
- if ((int) amd_state >= (int) Finishing) {
- dlog("not found - server going down anyway");
- ereturn(ENOENT);
- }
-
- /*
- * Allocate a new map
- */
- new_mp = get_ap_child(mp, expanded_fname);
- XFREE(expanded_fname);
- if (new_mp == 0)
- ereturn(ENOSPC);
-
- *error_return = -1;
- return new_mp;
-}
-
-
-
-static mntfs *
-amfs_lookup_one_mntfs(am_node *new_mp, mntfs *mf, char *ivec,
- char *def_opts, char *pfname)
-{
- am_ops *p;
- am_opts *fs_opts;
- mntfs *new_mf;
- char *mp_dir = 0;
-#ifdef HAVE_FS_AUTOFS
- int on_autofs = 1;
-#endif /* HAVE_FS_AUTOFS */
-
- /* match the operators */
- fs_opts = CALLOC(am_opts);
- p = ops_match(fs_opts, ivec, def_opts, new_mp->am_path,
- pfname, mf->mf_info);
-#ifdef HAVE_FS_AUTOFS
- /* XXX: this should be factored out into an autofs-specific function */
- if (new_mp->am_flags & AMF_AUTOFS) {
- /* ignore user-provided fs if we're using autofs */
- if (fs_opts->opt_sublink) {
- /*
- * For sublinks we need to use a hack with autofs:
- * mount the filesystem on the original opt_fs (which is NOT an
- * autofs mountpoint) and symlink (or lofs-mount) to it from
- * the autofs mountpoint.
- */
- on_autofs = 0;
- mp_dir = fs_opts->opt_fs;
- } else {
- if (p->autofs_fs_flags & FS_ON_AUTOFS) {
- mp_dir = new_mp->am_path;
- } else {
- mp_dir = fs_opts->opt_fs;
- on_autofs = 0;
- }
- }
- } else
-#endif /* HAVE_FS_AUTOFS */
- mp_dir = fs_opts->opt_fs;
-
- /*
- * Find or allocate a filesystem for this node.
- */
- new_mf = find_mntfs(p, fs_opts,
- mp_dir,
- fs_opts->fs_mtab,
- def_opts,
- fs_opts->opt_opts,
- fs_opts->opt_remopts);
-
- /*
- * See whether this is a real filesystem
- */
- p = new_mf->mf_ops;
- if (p == &amfs_error_ops) {
- plog(XLOG_MAP, "Map entry %s for %s did not match", ivec, new_mp->am_path);
- free_mntfs(new_mf);
- return NULL;
- }
-
- dlog("Got a hit with %s", p->fs_type);
-
-#ifdef HAVE_FS_AUTOFS
- if (new_mp->am_flags & AMF_AUTOFS && on_autofs) {
- new_mf->mf_flags |= MFF_ON_AUTOFS;
- new_mf->mf_fsflags = new_mf->mf_ops->autofs_fs_flags;
- }
- /*
- * A new filesystem is an autofs filesystems if:
- * 1. it claims it can be one (has the FS_AUTOFS flag)
- * 2. autofs is enabled system-wide
- * 3. either has an autofs parent,
- * or it is explicitly requested to be autofs.
- */
- if (new_mf->mf_ops->autofs_fs_flags & FS_AUTOFS &&
- amd_use_autofs &&
- ((mf->mf_flags & MFF_IS_AUTOFS) ||
- (new_mf->mf_fo && new_mf->mf_fo->opt_mount_type &&
- STREQ(new_mf->mf_fo->opt_mount_type, "autofs"))))
- new_mf->mf_flags |= MFF_IS_AUTOFS;
-#endif /* HAVE_FS_AUTOFS */
-
- return new_mf;
-}
-
-
-static mntfs **
-amfs_lookup_mntfs(am_node *new_mp, int *error_return)
-{
- am_node *mp;
- char *info; /* Mount info - where to get the file system */
- char **ivecs, **cur_ivec; /* Split version of info */
- int num_ivecs;
- char *orig_def_opts; /* Original Automount options */
- char *def_opts; /* Automount options */
- int error = 0; /* Error so far */
- char path_name[MAXPATHLEN]; /* General path name buffer */
- char *pfname; /* Path for database lookup */
- mntfs *mf, **mf_array;
- int count;
-
- dlog("in amfs_lookup_mntfs");
-
- mp = new_mp->am_parent;
-
- /*
- * If we get here then this is a reference to an,
- * as yet, unknown name so we need to search the mount
- * map for it.
- */
- if (mp->am_pref) {
- if (strlen(mp->am_pref) + strlen(new_mp->am_name) >= sizeof(path_name))
- ereturn(ENAMETOOLONG);
- xsnprintf(path_name, sizeof(path_name), "%s%s", mp->am_pref, new_mp->am_name);
- pfname = path_name;
- } else {
- pfname = new_mp->am_name;
- }
-
- mf = mp->am_mnt;
-
- dlog("will search map info in %s to find %s", mf->mf_info, pfname);
- /*
- * Consult the oracle for some mount information.
- * info is malloc'ed and belongs to this routine.
- * It ends up being free'd in free_continuation().
- *
- * Note that this may return -1 indicating that information
- * is not yet available.
- */
- error = mapc_search((mnt_map *) mf->mf_private, pfname, &info);
- if (error) {
- if (error > 0)
- plog(XLOG_MAP, "No map entry for %s", pfname);
- else
- plog(XLOG_MAP, "Waiting on map entry for %s", pfname);
- ereturn(error);
- }
- dlog("mount info is %s", info);
-
- /*
- * Split info into an argument vector.
- * The vector is malloc'ed and belongs to
- * this routine. It is free'd further down.
- *
- * Note: the vector pointers point into info, so don't free it!
- */
- ivecs = strsplit(info, ' ', '\"');
-
- if (mf->mf_auto)
- def_opts = mf->mf_auto;
- else
- def_opts = "";
-
- orig_def_opts = amfs_parse_defaults(mp, mf, strdup(def_opts));
- def_opts = strdup(orig_def_opts);
-
- /* first build our defaults */
- num_ivecs = 0;
- for (cur_ivec = ivecs; *cur_ivec; cur_ivec++) {
- if (**cur_ivec == '-') {
- /*
- * Pick up new defaults
- */
- char *new_def_opts = str3cat(NULL, def_opts, ";", *cur_ivec + 1);
- XFREE(def_opts);
- def_opts = new_def_opts;
- dlog("Setting def_opts to \"%s\"", def_opts);
- continue;
- } else
- num_ivecs++;
- }
-
- mf_array = calloc(num_ivecs + 1, sizeof(mntfs *));
-
- /* construct the array of struct mntfs for this mount point */
- for (count = 0, cur_ivec = ivecs; *cur_ivec; cur_ivec++) {
- mntfs *new_mf;
-
- if (**cur_ivec == '-') {
- XFREE(def_opts);
- if ((*cur_ivec)[1] == '\0') {
- /*
- * If we have a single dash '-' than we need to reset the
- * default options.
- */
- def_opts = strdup(orig_def_opts);
- dlog("Resetting the default options, a single dash '-' was found.");
- } else {
- /* append options to /default options */
- def_opts = str3cat((char *) 0, orig_def_opts, ";", *cur_ivec + 1);
- dlog("Resetting def_opts to \"%s\"", def_opts);
- }
- continue;
- }
-
- /*
- * If a mntfs has already been found, and we find
- * a cut then don't try any more locations.
- *
- * XXX: we do not know when the "/" was added as an equivalent for "||".
- * It's undocumented, it might go away at any time. Caveat emptor.
- */
- if (STREQ(*cur_ivec, "/") || STREQ(*cur_ivec, "||")) {
- if (count > 0) {
- dlog("Cut: not trying any more locations for %s", mp->am_path);
- break;
- }
- continue;
- }
-
- new_mf = amfs_lookup_one_mntfs(new_mp, mf, *cur_ivec, def_opts, pfname);
- if (new_mf == NULL)
- continue;
- mf_array[count++] = new_mf;
- }
-
- /* We're done with ivecs */
- XFREE(ivecs);
- XFREE(info);
- XFREE(orig_def_opts);
- XFREE(def_opts);
- if (count == 0) { /* no match */
- XFREE(mf_array);
- ereturn(ENOENT);
- }
-
- return mf_array;
-}
-
-
-/*
- * The continuation function. This is called by
- * the task notifier when a background mount attempt
- * completes.
- */
-static void
-amfs_cont(int rc, int term, opaque_t arg)
-{
- struct continuation *cp = (struct continuation *) arg;
- am_node *mp = cp->mp;
- mntfs *mf = mp->am_mnt;
-
- dlog("amfs_cont: '%s'", mp->am_path);
-
- /*
- * Definitely not trying to mount at the moment
- */
- mf->mf_flags &= ~MFF_MOUNTING;
-
- /*
- * While we are mounting - try to avoid race conditions
- */
- new_ttl(mp);
-
- /*
- * Wakeup anything waiting for this mount
- */
- wakeup(get_mntfs_wchan(mf));
-
- /*
- * Check for termination signal or exit status...
- */
- if (rc || term) {
-#ifdef HAVE_FS_AUTOFS
- if (mf->mf_flags & MFF_IS_AUTOFS &&
- !(mf->mf_flags & MFF_MOUNTED))
- autofs_release_fh(mp);
-#endif /* HAVE_FS_AUTOFS */
-
- if (term) {
- /*
- * Not sure what to do for an error code.
- */
- mf->mf_error = EIO; /* XXX ? */
- mf->mf_flags |= MFF_ERROR;
- plog(XLOG_ERROR, "mount for %s got signal %d", mp->am_path, term);
- } else {
- /*
- * Check for exit status...
- */
-#ifdef __linux__
- /*
- * HACK ALERT!
- *
- * On Linux (and maybe not only) it's possible to run
- * an amd which "knows" how to mount certain combinations
- * of nfs_proto/nfs_version which the kernel doesn't grok.
- * So if we got an EINVAL and we have a server that's not
- * using NFSv2/UDP, try again with NFSv2/UDP.
- *
- * Too bad that there is no way to dynamically determine
- * what combinations the _client_ supports, as opposed to
- * what the _server_ supports...
- */
- if (rc == EINVAL &&
- mf->mf_server &&
- (mf->mf_server->fs_version != 2 ||
- !STREQ(mf->mf_server->fs_proto, "udp")))
- mf->mf_flags |= MFF_NFS_SCALEDOWN;
- else
-#endif /* __linux__ */
- {
- mf->mf_error = rc;
- mf->mf_flags |= MFF_ERROR;
- errno = rc; /* XXX */
- if (!STREQ(mp->am_mnt->mf_ops->fs_type, "linkx"))
- plog(XLOG_ERROR, "%s: mount (amfs_cont): %m", mp->am_path);
- }
- }
-
- if (!(mf->mf_flags & MFF_NFS_SCALEDOWN)) {
- /*
- * If we get here then that attempt didn't work, so
- * move the info vector pointer along by one and
- * call the background mount routine again
- */
- amd_stats.d_merr++;
- cp->mf++;
- }
- amfs_bgmount(cp);
- if (mp->am_error > 0)
- assign_error_mntfs(mp);
- } else {
- /*
- * The mount worked.
- */
- dlog("Mounting %s returned success", cp->mp->am_path);
- am_mounted(cp->mp);
- free_continuation(cp);
- }
-
- reschedule_timeout_mp();
-}
-
-
-/*
- * Retry a mount
- */
-static void
-amfs_retry(int rc, int term, opaque_t arg)
-{
- struct continuation *cp = (struct continuation *) arg;
- am_node *mp = cp->mp;
- int error = 0;
-
- dlog("Commencing retry for mount of %s", mp->am_path);
-
- new_ttl(mp);
-
- if ((cp->start + ALLOWED_MOUNT_TIME) < clocktime(NULL)) {
- /*
- * The entire mount has timed out. Set the error code and skip past all
- * the mntfs's so that amfs_bgmount will not have any more
- * ways to try the mount, thus causing an error.
- */
- plog(XLOG_INFO, "mount of \"%s\" has timed out", mp->am_path);
- error = ETIMEDOUT;
- while (*cp->mf)
- cp->mf++;
- /* explicitly forbid further retries after timeout */
- cp->retry = FALSE;
- }
- if (error || !IN_PROGRESS(cp))
- error = amfs_bgmount(cp);
-
- reschedule_timeout_mp();
-}
-
-
-/*
- * Discard an old continuation
- */
-static void
-free_continuation(struct continuation *cp)
-{
- mntfs **mfp;
-
- dlog("free_continuation");
- if (cp->callout)
- untimeout(cp->callout);
- /*
- * we must free the mntfs's in the list.
- * so free all of them if there was an error,
- * or free all but the used one, if the mount succeeded.
- */
- for (mfp = cp->mp->am_mfarray; *mfp; mfp++) {
- free_mntfs(*mfp);
- }
- XFREE(cp->mp->am_mfarray);
- cp->mp->am_mfarray = 0;
- XFREE(cp);
-}
-
-
-/*
- * Pick a file system to try mounting and
- * do that in the background if necessary
- *
-For each location:
- discard previous mount location if required
- fetch next mount location
- if the filesystem failed to be mounted then
- this_error = error from filesystem
- goto failed
- if the filesystem is mounting or unmounting then
- goto retry;
- if the fileserver is down then
- this_error = EIO
- continue;
- if the filesystem is already mounted
- break
- fi
-
- this_error = initialize mount point
-
- if no error on this mount and mount is delayed then
- this_error = -1
- fi
- if this_error < 0 then
- retry = true
- fi
- if no error on this mount then
- if mount in background then
- run mount in background
- return -1
- else
- this_error = mount in foreground
- fi
- fi
- if an error occurred on this mount then
- update stats
- save error in mount point
- fi
-endfor
- */
-static int
-amfs_bgmount(struct continuation *cp)
-{
- am_node *mp = cp->mp;
- mntfs *mf; /* Current mntfs */
- int this_error = -1; /* Per-mount error */
- int hard_error = -1; /* Cumulative per-node error */
-
- if (mp->am_mnt)
- free_mntfs(mp->am_mnt);
-
- /*
- * Try to mount each location.
- * At the end:
- * hard_error == 0 indicates something was mounted.
- * hard_error > 0 indicates everything failed with a hard error
- * hard_error < 0 indicates nothing could be mounted now
- */
- for (mp->am_mnt = *cp->mf; *cp->mf; cp->mf++, mp->am_mnt = *cp->mf) {
- am_ops *p;
-
- mf = dup_mntfs(mp->am_mnt);
- p = mf->mf_ops;
-
- if (hard_error < 0)
- hard_error = this_error;
- this_error = 0;
-
- if (mf->mf_error > 0) {
- this_error = mf->mf_error;
- goto failed;
- }
-
- if (mf->mf_flags & (MFF_MOUNTING | MFF_UNMOUNTING)) {
- /*
- * Still mounting - retry later
- */
- dlog("mount of \"%s\" already pending", mf->mf_info);
- goto retry;
- }
-
- if (FSRV_ISDOWN(mf->mf_server)) {
- /*
- * Would just mount from the same place
- * as a hung mount - so give up
- */
- dlog("%s is already hung - giving up", mf->mf_server->fs_host);
- this_error = EIO;
- goto failed;
- }
-
- if (mp->am_link) {
- XFREE(mp->am_link);
- mp->am_link = NULL;
- }
- if (mf->mf_fo && mf->mf_fo->opt_sublink)
- mp->am_link = strdup(mf->mf_fo->opt_sublink);
-
- /*
- * Will usually need to play around with the mount nodes
- * file attribute structure. This must be done here.
- * Try and get things initialized, even if the fileserver
- * is not known to be up. In the common case this will
- * progress things faster.
- */
-
- /*
- * Fill in attribute fields.
- */
- if (mf->mf_fsflags & FS_DIRECTORY)
- mk_fattr(&mp->am_fattr, NFDIR);
- else
- mk_fattr(&mp->am_fattr, NFLNK);
-
- if (mf->mf_flags & MFF_MOUNTED) {
- dlog("duplicate mount of \"%s\" ...", mf->mf_info);
- /*
- * Skip initial processing of the mountpoint if already mounted.
- * This could happen if we have multiple sublinks into the same f/s,
- * or if we are restarting an already-mounted filesystem.
- */
- goto already_mounted;
- }
-
- if (mf->mf_fo && mf->mf_fo->fs_mtab) {
- plog(XLOG_MAP, "Trying mount of %s on %s fstype %s mount_type %s",
- mf->mf_fo->fs_mtab, mf->mf_mount, p->fs_type,
- mp->am_flags & AMF_AUTOFS ? "autofs" : "non-autofs");
- }
-
- if (p->fs_init && !(mf->mf_flags & MFF_RESTART))
- this_error = p->fs_init(mf);
-
- if (this_error > 0)
- goto failed;
- if (this_error < 0)
- goto retry;
-
- if (mf->mf_fo && mf->mf_fo->opt_delay) {
- /*
- * If there is a delay timer on the mount
- * then don't try to mount if the timer
- * has not expired.
- */
- int i = atoi(mf->mf_fo->opt_delay);
- time_t now = clocktime(NULL);
- if (i > 0 && now < (cp->start + i)) {
- dlog("Mount of %s delayed by %lds", mf->mf_mount, (long) (i - now + cp->start));
- goto retry;
- }
- }
-
- /*
- * If the directory is not yet made and it needs to be made, then make it!
- */
- if (!(mf->mf_flags & MFF_MKMNT) && mf->mf_fsflags & FS_MKMNT) {
- plog(XLOG_INFO, "creating mountpoint directory '%s'", mf->mf_mount);
- this_error = mkdirs(mf->mf_mount, 0555);
- if (this_error) {
- plog(XLOG_ERROR, "mkdirs failed: %s", strerror(this_error));
- goto failed;
- }
- mf->mf_flags |= MFF_MKMNT;
- }
-
-#ifdef HAVE_FS_AUTOFS
- if (mf->mf_flags & MFF_IS_AUTOFS)
- if ((this_error = autofs_get_fh(mp)))
- goto failed;
-#endif /* HAVE_FS_AUTOFS */
-
- already_mounted:
- mf->mf_flags |= MFF_MOUNTING;
- if (mf->mf_fsflags & FS_MBACKGROUND) {
- dlog("backgrounding mount of \"%s\"", mf->mf_mount);
- if (cp->callout) {
- untimeout(cp->callout);
- cp->callout = 0;
- }
-
- /* actually run the task, backgrounding as necessary */
- run_task(mount_node, (opaque_t) mp, amfs_cont, (opaque_t) cp);
- return -1;
- } else {
- dlog("foreground mount of \"%s\" ...", mf->mf_mount);
- this_error = mount_node((opaque_t) mp);
- }
-
- mf->mf_flags &= ~MFF_MOUNTING;
- if (this_error > 0)
- goto failed;
- if (this_error == 0) {
- am_mounted(mp);
- break; /* Success */
- }
-
- retry:
- if (!cp->retry)
- continue;
- dlog("will retry ...\n");
-
- /*
- * Arrange that amfs_bgmount is called
- * after anything else happens.
- */
- dlog("Arranging to retry mount of %s", mp->am_path);
- sched_task(amfs_retry, (opaque_t) cp, get_mntfs_wchan(mf));
- if (cp->callout)
- untimeout(cp->callout);
- cp->callout = timeout(RETRY_INTERVAL, wakeup,
- (opaque_t) get_mntfs_wchan(mf));
-
- mp->am_ttl = clocktime(NULL) + RETRY_INTERVAL;
-
- /*
- * Not done yet - so don't return anything
- */
- return -1;
-
- failed:
- amd_stats.d_merr++;
- mf->mf_error = this_error;
- mf->mf_flags |= MFF_ERROR;
-#ifdef HAVE_FS_AUTOFS
- if (mp->am_autofs_fh)
- autofs_release_fh(mp);
-#endif /* HAVE_FS_AUTOFS */
- if (mf->mf_flags & MFF_MKMNT) {
- rmdirs(mf->mf_mount);
- mf->mf_flags &= ~MFF_MKMNT;
- }
- /*
- * Wakeup anything waiting for this mount
- */
- wakeup(get_mntfs_wchan(mf));
- free_mntfs(mf);
- /* continue */
- }
-
- /*
- * If we get here, then either the mount succeeded or
- * there is no more mount information available.
- */
- if (this_error) {
- mp->am_mnt = mf = new_mntfs();
-
-#ifdef HAVE_FS_AUTOFS
- if (mp->am_flags & AMF_AUTOFS)
- autofs_mount_failed(mp);
- else
-#endif /* HAVE_FS_AUTOFS */
- nfs_quick_reply(mp, this_error);
-
- if (hard_error <= 0)
- hard_error = this_error;
- if (hard_error < 0)
- hard_error = ETIMEDOUT;
-
- /*
- * Set a small(ish) timeout on an error node if
- * the error was not a time out.
- */
- switch (hard_error) {
- case ETIMEDOUT:
- case EWOULDBLOCK:
- case EIO:
- mp->am_timeo = 17;
- break;
- default:
- mp->am_timeo = 5;
- break;
- }
- new_ttl(mp);
- } else {
- mf = mp->am_mnt;
- /*
- * Wakeup anything waiting for this mount
- */
- wakeup(get_mntfs_wchan(mf));
- hard_error = 0;
- }
-
- /*
- * Make sure that the error value in the mntfs has a
- * reasonable value.
- */
- if (mf->mf_error < 0) {
- mf->mf_error = hard_error;
- if (hard_error)
- mf->mf_flags |= MFF_ERROR;
- }
-
- /*
- * In any case we don't need the continuation any more
- */
- free_continuation(cp);
-
- return hard_error;
-}
-
-
-static char *
-amfs_parse_defaults(am_node *mp, mntfs *mf, char *def_opts)
-{
- char *dflts;
- char *dfl;
- char **rvec = NULL;
- struct mnt_map *mm = (mnt_map *) mf->mf_private;
-
- dlog("determining /defaults entry value");
-
- /*
- * Find out if amd.conf overrode any map-specific /defaults.
- *
- * HACK ALERT: there's no easy way to find out what the map mount point is
- * at this point, so I am forced to initialize the mnt_map->cfm field here
- * for the first time, upon the very first search for a /defaults entry in
- * this map. This initialization is much better done in mapc_create(),
- * but it's impossible to do that there with the current code structure.
- */
- if (mm->cfm == NULL) { /* then initialize it for first time */
- mm->cfm = find_cf_map(mf->mf_mount);
- }
- if (mm->cfm && mm->cfm->cfm_defaults) {
- dlog("map %s map_defaults override: %s", mf->mf_mount, mm->cfm->cfm_defaults);
- dflts = strdup(mm->cfm->cfm_defaults);
- } else if (mapc_search(mm, "/defaults", &dflts) == 0) {
- dlog("/defaults gave %s", dflts);
- } else {
- return def_opts; /* if nothing found */
- }
-
- /* trim leading '-' in case thee's one */
- if (*dflts == '-')
- dfl = dflts + 1;
- else
- dfl = dflts;
-
- /*
- * Chop the defaults up
- */
- rvec = strsplit(dfl, ' ', '\"');
-
- if (gopt.flags & CFM_SELECTORS_IN_DEFAULTS) {
- /*
- * Pick whichever first entry matched the list of selectors.
- * Strip the selectors from the string, and assign to dfl the
- * rest of the string.
- */
- if (rvec) {
- am_opts ap;
- am_ops *pt;
- char **sp = rvec;
- while (*sp) { /* loop until you find something, if any */
- memset((char *) &ap, 0, sizeof(am_opts));
- /*
- * This next routine cause many spurious "expansion of ... is"
- * messages, which are ignored, b/c all we need out of this
- * routine is to match selectors. These spurious messages may
- * be wrong, esp. if they try to expand ${key} b/c it will
- * get expanded to "/defaults"
- */
- pt = ops_match(&ap, *sp, "", mp->am_path, "/defaults",
- mp->am_parent->am_mnt->mf_info);
- free_opts(&ap); /* don't leak */
- if (pt == &amfs_error_ops) {
- plog(XLOG_MAP, "did not match defaults for \"%s\"", *sp);
- } else {
- dfl = strip_selectors(*sp, "/defaults");
- plog(XLOG_MAP, "matched default selectors \"%s\"", dfl);
- break;
- }
- ++sp;
- }
- }
- } else { /* not selectors_in_defaults */
- /*
- * Extract first value
- */
- dfl = rvec[0];
- }
-
- /*
- * If there were any values at all...
- */
- if (dfl) {
- /*
- * Log error if there were other values
- */
- if (!(gopt.flags & CFM_SELECTORS_IN_DEFAULTS) && rvec[1]) {
- dlog("/defaults chopped into %s", dfl);
- plog(XLOG_USER, "More than a single value for /defaults in %s", mf->mf_info);
- }
-
- /*
- * Prepend to existing defaults if they exist,
- * otherwise just use these defaults.
- */
- if (*def_opts && *dfl) {
- size_t l = strlen(def_opts) + strlen(dfl) + 2;
- char *nopts = (char *) xmalloc(l);
- xsnprintf(nopts, l, "%s;%s", dfl, def_opts);
- XFREE(def_opts);
- def_opts = nopts;
- } else if (*dfl) {
- def_opts = strealloc(def_opts, dfl);
- }
- }
-
- XFREE(dflts);
-
- /* don't need info vector any more */
- if (rvec)
- XFREE(rvec);
-
- return def_opts;
-}
-
-
-am_node *
-amfs_generic_mount_child(am_node *new_mp, int *error_return)
-{
- int error;
- struct continuation *cp; /* Continuation structure if need to mount */
-
- dlog("in amfs_generic_mount_child");
-
- *error_return = error = 0; /* Error so far */
-
- /* we have an errorfs attached to the am_node, free it */
- free_mntfs(new_mp->am_mnt);
- new_mp->am_mnt = 0;
-
- /*
- * Construct a continuation
- */
- cp = ALLOC(struct continuation);
- cp->callout = 0;
- cp->mp = new_mp;
- cp->retry = TRUE;
- cp->start = clocktime(NULL);
- cp->mf = new_mp->am_mfarray;
-
- /*
- * Try and mount the file system. If this succeeds immediately (possible
- * for a ufs file system) then return the attributes, otherwise just
- * return an error.
- */
- error = amfs_bgmount(cp);
- reschedule_timeout_mp();
- if (!error)
- return new_mp;
-
- /*
- * Code for quick reply. If current_transp is set, then it's the
- * transp that's been passed down from nfs_program_2() or from
- * autofs_program_[123]().
- * If new_mp->am_transp is not already set, set it by copying in
- * current_transp. Once am_transp is set, nfs_quick_reply() and
- * autofs_mount_succeeded() can use it to send a reply to the
- * client that requested this mount.
- */
- if (current_transp && !new_mp->am_transp) {
- dlog("Saving RPC transport for %s", new_mp->am_path);
- new_mp->am_transp = (SVCXPRT *) xmalloc(sizeof(SVCXPRT));
- *(new_mp->am_transp) = *current_transp;
- }
- if (error && (new_mp->am_mnt->mf_ops == &amfs_error_ops))
- new_mp->am_error = error;
-
- if (new_mp->am_error > 0)
- assign_error_mntfs(new_mp);
-
- ereturn(error);
-}
-
-
-/*
- * Automount interface to RPC lookup routine
- * Find the corresponding entry and return
- * the file handle for it.
- */
-am_node *
-amfs_generic_lookup_child(am_node *mp, char *fname, int *error_return, int op)
-{
- am_node *new_mp;
- mntfs **mf_array;
- int mp_error;
-
- dlog("in amfs_generic_lookup_child");
-
- *error_return = 0;
- new_mp = amfs_lookup_node(mp, fname, error_return);
-
- /* return if we got an error */
- if (!new_mp || *error_return > 0)
- return new_mp;
-
- /* also return if it's already mounted and known to be up */
- if (*error_return == 0 && FSRV_ISUP(new_mp->am_mnt->mf_server))
- return new_mp;
-
- switch (op) {
- case VLOOK_DELETE:
- /*
- * If doing a delete then don't create again!
- */
- ereturn(ENOENT);
- case VLOOK_LOOKUP:
- return new_mp;
- }
-
- /* save error_return */
- mp_error = *error_return;
-
- mf_array = amfs_lookup_mntfs(new_mp, error_return);
- if (!mf_array) {
- new_mp->am_error = new_mp->am_mnt->mf_error = *error_return;
- free_map(new_mp);
- return NULL;
- }
-
- /*
- * Already mounted but known to be down:
- * check if we have any alternatives to mount
- */
- if (mp_error == 0) {
- mntfs **mfp;
- for (mfp = mf_array; *mfp; mfp++)
- if (*mfp != new_mp->am_mnt)
- break;
- if (*mfp != NULL) {
- /*
- * we found an alternative, so try mounting again.
- */
- *error_return = -1;
- } else {
- for (mfp = mf_array; *mfp; mfp++)
- free_mntfs(*mfp);
- XFREE(mf_array);
- if (new_mp->am_flags & AMF_SOFTLOOKUP) {
- ereturn(EIO);
- } else {
- *error_return = 0;
- return new_mp;
- }
- }
- }
-
- /* store the array inside the am_node */
- new_mp->am_mfarray = mf_array;
-
- /*
- * Note: while it might seem like a good idea to prioritize
- * the list of mntfs's we got here, it probably isn't.
- * It would ignore the ordering of entries specified by the user,
- * which is counterintuitive and confusing.
- */
- return new_mp;
-}
-
-
-void
-amfs_generic_mounted(mntfs *mf)
-{
- amfs_mkcacheref(mf);
-}
-
-
-/*
- * Unmount an automount sub-node
- */
-int
-amfs_generic_umount(am_node *mp, mntfs *mf)
-{
- int error = 0;
-
-#ifdef HAVE_FS_AUTOFS
- int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
- if (mf->mf_flags & MFF_IS_AUTOFS)
- error = UMOUNT_FS(mp->am_path, mnttab_file_name, unmount_flags);
-#endif /* HAVE_FS_AUTOFS */
-
- return error;
-}
-
-
-char *
-amfs_generic_match(am_opts *fo)
-{
- char *p;
-
- if (!fo->opt_rfs) {
- plog(XLOG_USER, "amfs_generic_match: no mount point named (rfs:=)");
- return 0;
- }
- if (!fo->opt_fs) {
- plog(XLOG_USER, "amfs_generic_match: no map named (fs:=)");
- return 0;
- }
-
- /*
- * Swap round fs:= and rfs:= options
- * ... historical (jsp)
- */
- p = fo->opt_rfs;
- fo->opt_rfs = fo->opt_fs;
- fo->opt_fs = p;
-
- /*
- * mtab entry turns out to be the name of the mount map
- */
- return strdup(fo->opt_rfs ? fo->opt_rfs : ".");
-}
diff --git a/contrib/amd/amd/amfs_host.c b/contrib/amd/amd/amfs_host.c
deleted file mode 100644
index 55423c46ea33..000000000000
--- a/contrib/amd/amd/amfs_host.c
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amfs_host.c
- *
- */
-
-/*
- * NFS host file system.
- * Mounts all exported filesystems from a given host.
- * This has now degenerated into a mess but will not
- * be rewritten. Amd 6 will support the abstractions
- * needed to make this work correctly.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-static char *amfs_host_match(am_opts *fo);
-static int amfs_host_init(mntfs *mf);
-static int amfs_host_mount(am_node *am, mntfs *mf);
-static int amfs_host_umount(am_node *am, mntfs *mf);
-static void amfs_host_umounted(mntfs *mf);
-
-/*
- * Ops structure
- */
-am_ops amfs_host_ops =
-{
- "host",
- amfs_host_match,
- amfs_host_init,
- amfs_host_mount,
- amfs_host_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* amfs_host_readlink */
- 0, /* amfs_host_mounted */
- amfs_host_umounted,
- find_nfs_srvr,
- 0, /* amfs_host_get_wchan */
- FS_MKMNT | FS_BACKGROUND | FS_AMQINFO,
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_HOST_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/*
- * Determine the mount point:
- *
- * The next change we put in to better handle PCs. This is a bit
- * disgusting, so you'd better sit down. We change the make_mntpt function
- * to look for exported file systems without a leading '/'. If they don't
- * have a leading '/', we add one. If the export is 'a:' through 'z:'
- * (without a leading slash), we change it to 'a%' (or b% or z%). This
- * allows the entire PC disk to be mounted.
- */
-static void
-make_mntpt(char *mntpt, size_t l, const exports ex, const char *mf_mount)
-{
- if (ex->ex_dir[0] == '/') {
- if (ex->ex_dir[1] == 0)
- xstrlcpy(mntpt, mf_mount, l);
- else
- xsnprintf(mntpt, l, "%s%s", mf_mount, ex->ex_dir);
- } else if (ex->ex_dir[0] >= 'a' &&
- ex->ex_dir[0] <= 'z' &&
- ex->ex_dir[1] == ':' &&
- ex->ex_dir[2] == '/' &&
- ex->ex_dir[3] == 0)
- xsnprintf(mntpt, l, "%s/%c%%", mf_mount, ex->ex_dir[0]);
- else
- xsnprintf(mntpt, l, "%s/%s", mf_mount, ex->ex_dir);
-}
-
-
-/*
- * Execute needs the same as NFS plus a helper command
- */
-static char *
-amfs_host_match(am_opts *fo)
-{
- extern am_ops nfs_ops;
-
- /*
- * Make sure rfs is specified to keep nfs_match happy...
- */
- if (!fo->opt_rfs)
- fo->opt_rfs = "/";
-
- return (*nfs_ops.fs_match) (fo);
-}
-
-
-static int
-amfs_host_init(mntfs *mf)
-{
- u_short mountd_port;
-
- if (strchr(mf->mf_info, ':') == 0)
- return ENOENT;
-
- /*
- * This is primarily to schedule a wakeup so that as soon
- * as our fileserver is ready, we can continue setting up
- * the host filesystem. If we don't do this, the standard
- * amfs_auto code will set up a fileserver structure, but it will
- * have to wait for another nfs request from the client to come
- * in before finishing. Our way is faster since we don't have
- * to wait for the client to resend its request (which could
- * take a second or two).
- */
- /*
- * First, we find the fileserver for this mntfs and then call
- * get_mountd_port with our mntfs passed as the wait channel.
- * get_mountd_port will check some things and then schedule
- * it so that when the fileserver is ready, a wakeup is done
- * on this mntfs. amfs_cont() is already sleeping on this mntfs
- * so as soon as that wakeup happens amfs_cont() is called and
- * this mount is retried.
- */
- if (mf->mf_server)
- /*
- * We don't really care if there's an error returned.
- * Since this is just to help speed things along, the
- * error will get handled properly elsewhere.
- */
- get_mountd_port(mf->mf_server, &mountd_port, get_mntfs_wchan(mf));
-
- return 0;
-}
-
-
-static int
-do_mount(am_nfs_handle_t *fhp, char *mntdir, char *fs_name, mntfs *mf)
-{
- struct stat stb;
-
- dlog("amfs_host: mounting fs %s on %s\n", fs_name, mntdir);
-
- (void) mkdirs(mntdir, 0555);
- if (stat(mntdir, &stb) < 0 || (stb.st_mode & S_IFMT) != S_IFDIR) {
- plog(XLOG_ERROR, "No mount point for %s - skipping", mntdir);
- return ENOENT;
- }
-
- return mount_nfs_fh(fhp, mntdir, fs_name, mf);
-}
-
-
-static int
-sortfun(const voidp x, const voidp y)
-{
- exports *a = (exports *) x;
- exports *b = (exports *) y;
-
- return strcmp((*a)->ex_dir, (*b)->ex_dir);
-}
-
-
-/*
- * Get filehandle
- */
-static int
-fetch_fhandle(CLIENT *client, char *dir, am_nfs_handle_t *fhp, u_long nfs_version)
-{
- struct timeval tv;
- enum clnt_stat clnt_stat;
- struct fhstatus res;
-#ifdef HAVE_FS_NFS3
- struct am_mountres3 res3;
-#endif /* HAVE_FS_NFS3 */
-
- /*
- * Pick a number, any number...
- */
- tv.tv_sec = 20;
- tv.tv_usec = 0;
-
- dlog("Fetching fhandle for %s", dir);
-
- /*
- * Call the mount daemon on the remote host to
- * get the filehandle. Use NFS version specific call.
- */
-
- plog(XLOG_INFO, "fetch_fhandle: NFS version %d", (int) nfs_version);
-#ifdef HAVE_FS_NFS3
- if (nfs_version == NFS_VERSION3) {
- memset((char *) &res3, 0, sizeof(res3));
- clnt_stat = clnt_call(client,
- MOUNTPROC_MNT,
- (XDRPROC_T_TYPE) xdr_dirpath,
- (SVC_IN_ARG_TYPE) &dir,
- (XDRPROC_T_TYPE) xdr_am_mountres3,
- (SVC_IN_ARG_TYPE) &res3,
- tv);
- if (clnt_stat != RPC_SUCCESS) {
- plog(XLOG_ERROR, "mountd rpc failed: %s", clnt_sperrno(clnt_stat));
- return EIO;
- }
- /* Check the status of the filehandle */
- if ((errno = res3.fhs_status)) {
- dlog("fhandle fetch for mount version 3 failed: %m");
- return errno;
- }
- memset((voidp) &fhp->v3, 0, sizeof(am_nfs_fh3));
- fhp->v3.am_fh3_length = res3.mountres3_u.mountinfo.fhandle.fhandle3_len;
- memmove(fhp->v3.am_fh3_data,
- res3.mountres3_u.mountinfo.fhandle.fhandle3_val,
- fhp->v3.am_fh3_length);
- } else { /* not NFS_VERSION3 mount */
-#endif /* HAVE_FS_NFS3 */
- clnt_stat = clnt_call(client,
- MOUNTPROC_MNT,
- (XDRPROC_T_TYPE) xdr_dirpath,
- (SVC_IN_ARG_TYPE) &dir,
- (XDRPROC_T_TYPE) xdr_fhstatus,
- (SVC_IN_ARG_TYPE) &res,
- tv);
- if (clnt_stat != RPC_SUCCESS) {
- plog(XLOG_ERROR, "mountd rpc failed: %s", clnt_sperrno(clnt_stat));
- return EIO;
- }
- /* Check status of filehandle */
- if (res.fhs_status) {
- errno = res.fhs_status;
- dlog("fhandle fetch for mount version 1 failed: %m");
- return errno;
- }
- memmove(&fhp->v2, &res.fhs_fh, NFS_FHSIZE);
-#ifdef HAVE_FS_NFS3
- } /* end of "if (nfs_version == NFS_VERSION3)" statement */
-#endif /* HAVE_FS_NFS3 */
-
- /* all is well */
- return 0;
-}
-
-
-/*
- * Scan mount table to see if something already mounted
- */
-static int
-already_mounted(mntlist *mlist, char *dir)
-{
- mntlist *ml;
-
- for (ml = mlist; ml; ml = ml->mnext)
- if (STREQ(ml->mnt->mnt_dir, dir))
- return 1;
- return 0;
-}
-
-
-static int
-amfs_host_mount(am_node *am, mntfs *mf)
-{
- struct timeval tv2;
- CLIENT *client;
- enum clnt_stat clnt_stat;
- int n_export;
- int j, k;
- exports exlist = 0, ex;
- exports *ep = 0;
- am_nfs_handle_t *fp = 0;
- char *host;
- int error = 0;
- struct sockaddr_in sin;
- int sock = RPC_ANYSOCK;
- int ok = FALSE;
- mntlist *mlist;
- char fs_name[MAXPATHLEN], *rfs_dir;
- char mntpt[MAXPATHLEN];
- struct timeval tv;
- u_long mnt_version;
-
- /*
- * WebNFS servers don't necessarily run mountd.
- */
- if (mf->mf_flags & MFF_WEBNFS) {
- plog(XLOG_ERROR, "amfs_host_mount: cannot support WebNFS");
- return EIO;
- }
-
- /*
- * Read the mount list
- */
- mlist = read_mtab(mf->mf_mount, mnttab_file_name);
-
-#ifdef MOUNT_TABLE_ON_FILE
- /*
- * Unlock the mount list
- */
- unlock_mntlist();
-#endif /* MOUNT_TABLE_ON_FILE */
-
- /*
- * Take a copy of the server hostname, address, and nfs version
- * to mount version conversion.
- */
- host = mf->mf_server->fs_host;
- sin = *mf->mf_server->fs_ip;
- plog(XLOG_INFO, "amfs_host_mount: NFS version %d", (int) mf->mf_server->fs_version);
-#ifdef HAVE_FS_NFS3
- if (mf->mf_server->fs_version == NFS_VERSION3)
- mnt_version = AM_MOUNTVERS3;
- else
-#endif /* HAVE_FS_NFS3 */
- mnt_version = MOUNTVERS;
-
- /*
- * The original 10 second per try timeout is WAY too large, especially
- * if we're only waiting 10 or 20 seconds max for the response.
- * That would mean we'd try only once in 10 seconds, and we could
- * lose the transmit or receive packet, and never try again.
- * A 2-second per try timeout here is much more reasonable.
- * 09/28/92 Mike Mitchell, mcm@unx.sas.com
- */
- tv.tv_sec = 2;
- tv.tv_usec = 0;
-
- /*
- * Create a client attached to mountd
- */
- client = get_mount_client(host, &sin, &tv, &sock, mnt_version);
- if (client == NULL) {
-#ifdef HAVE_CLNT_SPCREATEERROR
- plog(XLOG_ERROR, "get_mount_client failed for %s: %s",
- host, clnt_spcreateerror(""));
-#else /* not HAVE_CLNT_SPCREATEERROR */
- plog(XLOG_ERROR, "get_mount_client failed for %s", host);
-#endif /* not HAVE_CLNT_SPCREATEERROR */
- error = EIO;
- goto out;
- }
- if (!nfs_auth) {
- error = make_nfs_auth();
- if (error)
- goto out;
- }
- client->cl_auth = nfs_auth;
-
- dlog("Fetching export list from %s", host);
-
- /*
- * Fetch the export list
- */
- tv2.tv_sec = 10;
- tv2.tv_usec = 0;
- clnt_stat = clnt_call(client,
- MOUNTPROC_EXPORT,
- (XDRPROC_T_TYPE) xdr_void,
- 0,
- (XDRPROC_T_TYPE) xdr_exports,
- (SVC_IN_ARG_TYPE) & exlist,
- tv2);
- if (clnt_stat != RPC_SUCCESS) {
- const char *msg = clnt_sperrno(clnt_stat);
- plog(XLOG_ERROR, "host_mount rpc failed: %s", msg);
- /* clnt_perror(client, "rpc"); */
- error = EIO;
- goto out;
- }
-
- /*
- * Figure out how many exports were returned
- */
- for (n_export = 0, ex = exlist; ex; ex = ex->ex_next) {
- n_export++;
- }
-
- /*
- * Allocate an array of pointers into the list
- * so that they can be sorted. If the filesystem
- * is already mounted then ignore it.
- */
- ep = (exports *) xmalloc(n_export * sizeof(exports));
- for (j = 0, ex = exlist; ex; ex = ex->ex_next) {
- make_mntpt(mntpt, sizeof(mntpt), ex, mf->mf_mount);
- if (already_mounted(mlist, mntpt))
- /* we have at least one mounted f/s, so don't fail the mount */
- ok = TRUE;
- else
- ep[j++] = ex;
- }
- n_export = j;
-
- /*
- * Sort into order.
- * This way the mounts are done in order down the tree,
- * instead of any random order returned by the mount
- * daemon (the protocol doesn't specify...).
- */
- qsort(ep, n_export, sizeof(exports), sortfun);
-
- /*
- * Allocate an array of filehandles
- */
- fp = (am_nfs_handle_t *) xmalloc(n_export * sizeof(am_nfs_handle_t));
-
- /*
- * Try to obtain filehandles for each directory.
- * If a fetch fails then just zero out the array
- * reference but discard the error.
- */
- for (j = k = 0; j < n_export; j++) {
- /* Check and avoid a duplicated export entry */
- if (j > k && ep[k] && STREQ(ep[j]->ex_dir, ep[k]->ex_dir)) {
- dlog("avoiding dup fhandle requested for %s", ep[j]->ex_dir);
- ep[j] = 0;
- } else {
- k = j;
- error = fetch_fhandle(client, ep[j]->ex_dir, &fp[j],
- mf->mf_server->fs_version);
- if (error)
- ep[j] = 0;
- }
- }
-
- /*
- * Mount each filesystem for which we have a filehandle.
- * If any of the mounts succeed then mark "ok" and return
- * error code 0 at the end. If they all fail then return
- * the last error code.
- */
- xstrlcpy(fs_name, mf->mf_info, MAXPATHLEN);
- if ((rfs_dir = strchr(fs_name, ':')) == (char *) 0) {
- plog(XLOG_FATAL, "amfs_host_mount: mf_info has no colon");
- error = EINVAL;
- goto out;
- }
- ++rfs_dir;
- for (j = 0; j < n_export; j++) {
- ex = ep[j];
- if (ex) {
- /*
- * Note: the sizeof space left in rfs_dir is what's left in fs_name
- * after strchr() above returned a pointer _inside_ fs_name. The
- * calculation below also takes into account that rfs_dir was
- * incremented by the ++ above.
- */
- xstrlcpy(rfs_dir, ex->ex_dir, sizeof(fs_name) - (rfs_dir - fs_name));
- make_mntpt(mntpt, sizeof(mntpt), ex, mf->mf_mount);
- if (do_mount(&fp[j], mntpt, fs_name, mf) == 0)
- ok = TRUE;
- }
- }
-
- /*
- * Clean up and exit
- */
-out:
- discard_mntlist(mlist);
- if (ep)
- XFREE(ep);
- if (fp)
- XFREE(fp);
- if (sock != RPC_ANYSOCK)
- (void) amu_close(sock);
- if (client)
- clnt_destroy(client);
- if (exlist)
- xdr_pri_free((XDRPROC_T_TYPE) xdr_exports, (caddr_t) &exlist);
- if (ok)
- return 0;
- return error;
-}
-
-
-/*
- * Return true if pref is a directory prefix of dir.
- *
- * XXX TODO:
- * Does not work if pref is "/".
- */
-static int
-directory_prefix(char *pref, char *dir)
-{
- int len = strlen(pref);
-
- if (!NSTREQ(pref, dir, len))
- return FALSE;
- if (dir[len] == '/' || dir[len] == '\0')
- return TRUE;
- return FALSE;
-}
-
-
-/*
- * Unmount a mount tree
- */
-static int
-amfs_host_umount(am_node *am, mntfs *mf)
-{
- mntlist *ml, *mprev;
- int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
- int xerror = 0;
-
- /*
- * Read the mount list
- */
- mntlist *mlist = read_mtab(mf->mf_mount, mnttab_file_name);
-
-#ifdef MOUNT_TABLE_ON_FILE
- /*
- * Unlock the mount list
- */
- unlock_mntlist();
-#endif /* MOUNT_TABLE_ON_FILE */
-
- /*
- * Reverse list...
- */
- ml = mlist;
- mprev = 0;
- while (ml) {
- mntlist *ml2 = ml->mnext;
- ml->mnext = mprev;
- mprev = ml;
- ml = ml2;
- }
- mlist = mprev;
-
- /*
- * Unmount all filesystems...
- */
- for (ml = mlist; ml && !xerror; ml = ml->mnext) {
- char *dir = ml->mnt->mnt_dir;
- if (directory_prefix(mf->mf_mount, dir)) {
- int error;
- dlog("amfs_host: unmounts %s", dir);
- /*
- * Unmount "dir"
- */
- error = UMOUNT_FS(dir, mnttab_file_name, unmount_flags);
- /*
- * Keep track of errors
- */
- if (error) {
- /*
- * If we have not already set xerror and error is not ENOENT,
- * then set xerror equal to error and log it.
- * 'xerror' is the return value for this function.
- *
- * We do not want to pass ENOENT as an error because if the
- * directory does not exists our work is done anyway.
- */
- if (!xerror && error != ENOENT)
- xerror = error;
- if (error != EBUSY) {
- errno = error;
- plog(XLOG_ERROR, "Tree unmount of %s failed: %m", ml->mnt->mnt_dir);
- }
- } else {
- (void) rmdirs(dir);
- }
- }
- }
-
- /*
- * Throw away mount list
- */
- discard_mntlist(mlist);
-
- /*
- * Try to remount, except when we are shutting down.
- */
- if (xerror && amd_state != Finishing) {
- xerror = amfs_host_mount(am, mf);
- if (!xerror) {
- /*
- * Don't log this - it's usually too verbose
- plog(XLOG_INFO, "Remounted host %s", mf->mf_info);
- */
- xerror = EBUSY;
- }
- }
- return xerror;
-}
-
-
-/*
- * Tell mountd we're done.
- * This is not quite right, because we may still
- * have other filesystems mounted, but the existing
- * mountd protocol is badly broken anyway.
- */
-static void
-amfs_host_umounted(mntfs *mf)
-{
- char *host;
- CLIENT *client;
- enum clnt_stat clnt_stat;
- struct sockaddr_in sin;
- int sock = RPC_ANYSOCK;
- struct timeval tv;
- u_long mnt_version;
-
- if (mf->mf_error || mf->mf_refc > 1 || !mf->mf_server)
- return;
-
- /*
- * WebNFS servers shouldn't ever get here.
- */
- if (mf->mf_flags & MFF_WEBNFS) {
- plog(XLOG_ERROR, "amfs_host_umounted: cannot support WebNFS");
- return;
- }
-
- /*
- * Take a copy of the server hostname, address, and NFS version
- * to mount version conversion.
- */
- host = mf->mf_server->fs_host;
- sin = *mf->mf_server->fs_ip;
- plog(XLOG_INFO, "amfs_host_umounted: NFS version %d", (int) mf->mf_server->fs_version);
-#ifdef HAVE_FS_NFS3
- if (mf->mf_server->fs_version == NFS_VERSION3)
- mnt_version = AM_MOUNTVERS3;
- else
-#endif /* HAVE_FS_NFS3 */
- mnt_version = MOUNTVERS;
-
- /*
- * Create a client attached to mountd
- */
- tv.tv_sec = 10;
- tv.tv_usec = 0;
- client = get_mount_client(host, &sin, &tv, &sock, mnt_version);
- if (client == NULL) {
-#ifdef HAVE_CLNT_SPCREATEERROR
- plog(XLOG_ERROR, "get_mount_client failed for %s: %s",
- host, clnt_spcreateerror(""));
-#else /* not HAVE_CLNT_SPCREATEERROR */
- plog(XLOG_ERROR, "get_mount_client failed for %s", host);
-#endif /* not HAVE_CLNT_SPCREATEERROR */
- goto out;
- }
-
- if (!nfs_auth) {
- if (make_nfs_auth())
- goto out;
- }
- client->cl_auth = nfs_auth;
-
- dlog("Unmounting all from %s", host);
-
- clnt_stat = clnt_call(client,
- MOUNTPROC_UMNTALL,
- (XDRPROC_T_TYPE) xdr_void,
- 0,
- (XDRPROC_T_TYPE) xdr_void,
- 0,
- tv);
- if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_SYSTEMERROR) {
- /* RPC_SYSTEMERROR seems to be returned for no good reason ... */
- const char *msg = clnt_sperrno(clnt_stat);
- plog(XLOG_ERROR, "unmount all from %s rpc failed: %s", host, msg);
- goto out;
- }
-
-out:
- if (sock != RPC_ANYSOCK)
- (void) amu_close(sock);
- if (client)
- clnt_destroy(client);
-}
diff --git a/contrib/amd/amd/amfs_link.c b/contrib/amd/amd/amfs_link.c
deleted file mode 100644
index e75ab862f8bc..000000000000
--- a/contrib/amd/amd/amfs_link.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amfs_link.c
- *
- */
-
-/*
- * Symbol-link file system
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* forward declarations */
-static int amfs_link_mount(am_node *mp, mntfs *mf);
-static int amfs_link_umount(am_node *mp, mntfs *mf);
-
-/*
- * Ops structures
- */
-am_ops amfs_link_ops =
-{
- "link",
- amfs_link_match,
- 0, /* amfs_link_init */
- amfs_link_mount,
- amfs_link_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* amfs_link_readlink */
- 0, /* amfs_link_mounted */
- 0, /* amfs_link_umounted */
- amfs_generic_find_srvr,
- 0, /* nfs_fs_flags */
- 0, /* amfs_link_get_wchan */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_LINK_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/*
- * SFS needs a link.
- */
-char *
-amfs_link_match(am_opts *fo)
-{
-
- if (!fo->opt_fs) {
- plog(XLOG_USER, "link: no fs specified");
- return 0;
- }
-
- /*
- * If the link target points to another mount point, then we could
- * end up with an unpleasant situation, where the link f/s simply
- * "assumes" the mntfs of that mount point.
- *
- * For example, if the link points to /usr, and /usr is a real ufs
- * filesystem, then the link f/s will use the inherited ufs mntfs,
- * and the end result will be that it will become unmountable.
- *
- * To prevent this, we use a hack: we prepend a dot ('.') to opt_fs if
- * its original value was an absolute path, so that it will never match
- * any other mntfs.
- *
- * XXX: a less hacky solution should be used...
- */
- if (fo->opt_fs[0] == '/') {
- char *link_hack = str3cat(NULL, ".", fo->opt_fs, "");
- if (!fo->opt_sublink)
- fo->opt_sublink = strdup(fo->opt_fs);
- XFREE(fo->opt_fs);
- fo->opt_fs = link_hack;
- }
-
- return strdup(fo->opt_fs);
-}
-
-
-static int
-amfs_link_mount(am_node *mp, mntfs *mf)
-{
- return 0;
-}
-
-
-static int
-amfs_link_umount(am_node *mp, mntfs *mf)
-{
- return 0;
-}
diff --git a/contrib/amd/amd/amfs_linkx.c b/contrib/amd/amd/amfs_linkx.c
deleted file mode 100644
index e306eda91d3b..000000000000
--- a/contrib/amd/amd/amfs_linkx.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amfs_linkx.c
- *
- */
-
-/*
- * Symbol-link file system, with test that the target of the link exists.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* forward declarations */
-static int amfs_linkx_mount(am_node *mp, mntfs *mf);
-static int amfs_linkx_umount(am_node *mp, mntfs *mf);
-
-/*
- * linkx operations
- */
-struct am_ops amfs_linkx_ops =
-{
- "linkx",
- amfs_link_match,
- 0, /* amfs_linkx_init */
- amfs_linkx_mount,
- amfs_linkx_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* amfs_linkx_readlink */
- 0, /* amfs_linkx_mounted */
- 0, /* amfs_linkx_umounted */
- amfs_generic_find_srvr,
- 0, /* amfs_linkx_get_wchan */
- FS_MBACKGROUND,
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_LINKX_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-static int
-amfs_linkx_mount(am_node *mp, mntfs *mf)
-{
- /*
- * Check for existence of target.
- */
- struct stat stb;
- char *ln;
-
- if (mp->am_link)
- ln = mp->am_link;
- else /* should never occur */
- ln = mf->mf_mount;
-
- /*
- * Use lstat, not stat, since we don't
- * want to know if the ultimate target of
- * a symlink chain exists, just the first.
- */
- if (lstat(ln, &stb) < 0)
- return errno;
-
- return 0;
-}
-
-
-static int
-amfs_linkx_umount(am_node *mp, mntfs *mf)
-{
- return 0;
-}
diff --git a/contrib/amd/amd/amfs_nfsl.c b/contrib/amd/amd/amfs_nfsl.c
deleted file mode 100644
index bb48f0efd255..000000000000
--- a/contrib/amd/amd/amfs_nfsl.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amfs_nfsl.c
- *
- */
-
-/*
- * NFSL: Network file system with local existence check. If the local
- * path denoted by $rfs exists, it behaves as type:=link.
- *
- * Example:
- * pkg type:=nfsl;rhost:=jonny;rfs:=/n/johnny/src/pkg;fs:=${rfs}
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-
-/* forward declarations */
-static char *amfs_nfsl_match(am_opts *fo);
-static int amfs_nfsl_init(mntfs *mf);
-static int amfs_nfsl_mount(am_node *mp, mntfs *mf);
-static int amfs_nfsl_umount(am_node *mp, mntfs *mf);
-static void amfs_nfsl_umounted(mntfs *mf);
-static fserver *amfs_nfsl_ffserver(mntfs *mf);
-
-/*
- * NFS-Link operations
- */
-am_ops amfs_nfsl_ops =
-{
- "nfsl",
- amfs_nfsl_match,
- amfs_nfsl_init,
- amfs_nfsl_mount,
- amfs_nfsl_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* amfs_nfsl_readlink */
- 0, /* amfs_nfsl_mounted */
- amfs_nfsl_umounted,
- amfs_nfsl_ffserver,
- 0, /* amfs_nfsl_get_wchan */
- FS_MKMNT | FS_BACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_NFSL_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/*
- * Check that f/s has all needed fields.
- * Returns: matched string if found, NULL otherwise.
- */
-static char *
-amfs_nfsl_match(am_opts *fo)
-{
- char *cp;
- char *ho = fo->opt_rhost;
- char *retval;
- struct stat stb;
-
- if (fo->opt_sublink)
- cp = fo->opt_sublink;
- else
- cp = fo->opt_fs;
-
- if (!cp || !ho) {
- plog(XLOG_USER, "amfs_nfsl: host $fs and $rhost must be specified");
- return NULL;
- }
-
- /*
- * If this host is not the same as $rhost, or if link does not exist,
- * call nfs_ops.fs_match().
- * If link value exists (or same host), call amfs_link_ops.fs_match().
- */
- if (!STRCEQ(ho, am_get_hostname())) {
- plog(XLOG_INFO, "amfs_nfsl: \"%s\" is not local host, using type:=nfs", ho);
- retval = nfs_ops.fs_match(fo);
- } else if (lstat(cp, &stb) < 0) {
- plog(XLOG_INFO, "amfs_nfsl: \"%s\" does not exist, using type:=nfs", cp);
- retval = nfs_ops.fs_match(fo);
- } else {
- plog(XLOG_INFO, "amfs_nfsl: \"%s\" exists, using type:=link", cp);
- retval = amfs_link_ops.fs_match(fo);
- }
- return retval;
-}
-
-
-/*
- * Initialize.
- * Returns: 0 if OK, non-zero (errno) if failed.
- */
-static int
-amfs_nfsl_init(mntfs *mf)
-{
- int ret = 0;
- if (mf->mf_flags & MFF_NFSLINK) {
- if (amfs_link_ops.fs_init)
- ret = amfs_link_ops.fs_init(mf);
- } else {
- if (nfs_ops.fs_init)
- ret = nfs_ops.fs_init(mf);
- }
- return ret;
-}
-
-
-/*
- * Mount vfs.
- * Returns: 0 if OK, non-zero (errno) if failed.
- */
-static int
-amfs_nfsl_mount(am_node *mp, mntfs *mf)
-{
- int ret = 0;
- if (mf->mf_flags & MFF_NFSLINK) {
- if (amfs_link_ops.mount_fs)
- ret = amfs_link_ops.mount_fs(mp, mf);
- } else {
- if (nfs_ops.mount_fs)
- ret = nfs_ops.mount_fs(mp, mf);
- }
- return ret;
-}
-
-
-/*
- * Unmount VFS.
- * Returns: 0 if OK, non-zero (errno) if failed.
- */
-static int
-amfs_nfsl_umount(am_node *mp, mntfs *mf)
-{
- int ret = 0;
- if (mf->mf_flags & MFF_NFSLINK) {
- if (amfs_link_ops.umount_fs)
- ret = amfs_link_ops.umount_fs(mp, mf);
- } else {
- if (nfs_ops.umount_fs)
- ret = nfs_ops.umount_fs(mp, mf);
- }
- return ret;
-}
-
-
-/*
- * Async unmount callback function.
- * After the base umount() succeeds, we may want to take extra actions,
- * such as informing remote mount daemons that we've unmounted them.
- * See amfs_auto_umounted(), host_umounted(), nfs_umounted().
- */
-static void
-amfs_nfsl_umounted(mntfs *mf)
-{
- if (mf->mf_flags & MFF_NFSLINK) {
- if (amfs_link_ops.umounted)
- amfs_link_ops.umounted(mf);
- } else {
- if (nfs_ops.umounted)
- nfs_ops.umounted(mf);
- }
-}
-
-
-/*
- * Find a file server.
- * Returns: fserver of found server, or NULL if not found.
- */
-static fserver *
-amfs_nfsl_ffserver(mntfs *mf)
-{
- char *cp;
- char *ho = mf->mf_fo->opt_rhost;
- struct stat stb;
-
- if (mf->mf_fo->opt_sublink)
- cp = mf->mf_fo->opt_sublink;
- else
- cp = mf->mf_fo->opt_fs;
-
- /*
- * If this host is not the same as $rhost, or if link does not exist,
- * call amfs_link_ops.ffserver().
- * If link value exists (or same host), then call ops_nfs.ffserver().
- */
- if (!STRCEQ(ho, am_get_hostname()) || lstat(cp, &stb) < 0) {
- return nfs_ops.ffserver(mf);
- } else {
- mf->mf_flags |= MFF_NFSLINK;
- /* remove the FS_MKMNT flag, we don't want amd touching the mountpoint */
- mf->mf_fsflags &= ~FS_MKMNT;
- return amfs_link_ops.ffserver(mf);
- }
-}
diff --git a/contrib/amd/amd/amfs_nfsx.c b/contrib/amd/amd/amfs_nfsx.c
deleted file mode 100644
index 91be8af47e11..000000000000
--- a/contrib/amd/amd/amfs_nfsx.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amfs_nfsx.c
- *
- */
-
-/*
- * NFS hierarchical mounts
- *
- * TODO: Re-implement.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/*
- * The rfs field contains a list of mounts to be done from
- * the remote host.
- */
-typedef struct amfs_nfsx_mnt {
- mntfs *n_mnt;
- int n_error;
-} amfs_nfsx_mnt;
-
-struct amfs_nfsx {
- int nx_c; /* Number of elements in nx_v */
- amfs_nfsx_mnt *nx_v; /* Underlying mounts */
- amfs_nfsx_mnt *nx_try;
- am_node *nx_mp;
-};
-
-/* forward definitions */
-static char *amfs_nfsx_match(am_opts *fo);
-static int amfs_nfsx_mount(am_node *am, mntfs *mf);
-static int amfs_nfsx_umount(am_node *am, mntfs *mf);
-static int amfs_nfsx_init(mntfs *mf);
-
-/*
- * Ops structure
- */
-am_ops amfs_nfsx_ops =
-{
- "nfsx",
- amfs_nfsx_match,
- amfs_nfsx_init,
- amfs_nfsx_mount,
- amfs_nfsx_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* amfs_nfsx_readlink */
- 0, /* amfs_nfsx_mounted */
- 0, /* amfs_nfsx_umounted */
- find_nfs_srvr, /* XXX */
- 0, /* amfs_nfsx_get_wchan */
- /* FS_UBACKGROUND| */ FS_AMQINFO, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_NFSX_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-static char *
-amfs_nfsx_match(am_opts *fo)
-{
- char *xmtab;
- char *ptr;
- int len;
-
- if (!fo->opt_rfs) {
- plog(XLOG_USER, "amfs_nfsx: no remote filesystem specified");
- return FALSE;
- }
-
- if (!fo->opt_rhost) {
- plog(XLOG_USER, "amfs_nfsx: no remote host specified");
- return FALSE;
- }
-
- /* set default sublink */
- if (fo->opt_sublink == 0) {
- ptr = strchr(fo->opt_rfs, ',');
- if (ptr && ptr > (fo->opt_rfs + 1))
- fo->opt_sublink = strnsave(fo->opt_rfs + 1, ptr - fo->opt_rfs - 1);
- }
-
- /*
- * Remove trailing ",..." from ${fs}
- * After deslashifying, overwrite the end of ${fs} with "/"
- * to make sure it is unique.
- */
- if ((ptr = strchr(fo->opt_fs, ',')))
- *ptr = '\0';
- deslashify(fo->opt_fs);
-
- /*
- * Bump string length to allow trailing /
- */
- len = strlen(fo->opt_fs);
- fo->opt_fs = xrealloc(fo->opt_fs, len + 1 + 1);
- ptr = fo->opt_fs + len;
-
- /*
- * Make unique...
- */
- *ptr++ = '/';
- *ptr = '\0';
-
- /*
- * Determine magic cookie to put in mtab
- */
- xmtab = str3cat((char *) 0, fo->opt_rhost, ":", fo->opt_rfs);
- dlog("NFSX: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"",
- fo->opt_rhost, fo->opt_rfs, fo->opt_fs);
-
- return xmtab;
-}
-
-
-static void
-amfs_nfsx_prfree(opaque_t vp)
-{
- struct amfs_nfsx *nx = (struct amfs_nfsx *) vp;
- int i;
-
- for (i = 0; i < nx->nx_c; i++) {
- mntfs *m = nx->nx_v[i].n_mnt;
- if (m)
- free_mntfs(m);
- }
-
- XFREE(nx->nx_v);
- XFREE(nx);
-}
-
-
-static int
-amfs_nfsx_init(mntfs *mf)
-{
- /*
- * mf_info has the form:
- * host:/prefix/path,sub,sub,sub
- */
- int i;
- int glob_error;
- struct amfs_nfsx *nx;
- int asked_for_wakeup = 0;
-
- nx = (struct amfs_nfsx *) mf->mf_private;
-
- if (nx == 0) {
- char **ivec;
- char *info = 0;
- char *host;
- char *pref;
- int error = 0;
-
- info = strdup(mf->mf_info);
- host = strchr(info, ':');
- if (!host) {
- error = EINVAL;
- goto errexit;
- }
- pref = host + 1;
- host = info;
-
- /*
- * Split the prefix off from the suffices
- */
- ivec = strsplit(pref, ',', '\'');
-
- /*
- * Count array size
- */
- for (i = 0; ivec[i]; i++)
- /* nothing */;
-
- nx = ALLOC(struct amfs_nfsx);
- mf->mf_private = (opaque_t) nx;
- mf->mf_prfree = amfs_nfsx_prfree;
-
- nx->nx_c = i - 1; /* i-1 because we don't want the prefix */
- nx->nx_v = (amfs_nfsx_mnt *) xmalloc(nx->nx_c * sizeof(amfs_nfsx_mnt));
- nx->nx_mp = 0;
- {
- char *mp = 0;
- char *xinfo = 0;
- char *fs = mf->mf_fo->opt_fs;
- char *rfs = 0;
- for (i = 0; i < nx->nx_c; i++) {
- char *path = ivec[i + 1];
- rfs = str3cat(rfs, pref, "/", path);
- /*
- * Determine the mount point.
- * If this is the root, then don't remove
- * the trailing slash to avoid mntfs name clashes.
- */
- mp = str3cat(mp, fs, "/", rfs);
- normalize_slash(mp);
- deslashify(mp);
- /*
- * Determine the mount info
- */
- xinfo = str3cat(xinfo, host, *path == '/' ? "" : "/", path);
- normalize_slash(xinfo);
- if (pref[1] != '\0')
- deslashify(xinfo);
- dlog("amfs_nfsx: init mount for %s on %s", xinfo, mp);
- nx->nx_v[i].n_error = -1;
- nx->nx_v[i].n_mnt = find_mntfs(&nfs_ops, mf->mf_fo, mp, xinfo, "", mf->mf_mopts, mf->mf_remopts);
- /* propagate the on_autofs flag */
- nx->nx_v[i].n_mnt->mf_flags |= mf->mf_flags & MFF_ON_AUTOFS;
- }
- if (rfs)
- XFREE(rfs);
- if (mp)
- XFREE(mp);
- if (xinfo)
- XFREE(xinfo);
- }
-
- XFREE(ivec);
- errexit:
- if (info)
- XFREE(info);
- if (error)
- return error;
- }
-
- /*
- * Iterate through the mntfs's and call
- * the underlying init routine on each
- */
- glob_error = 0;
-
- for (i = 0; i < nx->nx_c; i++) {
- amfs_nfsx_mnt *n = &nx->nx_v[i];
- mntfs *m = n->n_mnt;
- int error = 0;
- if (m->mf_ops->fs_init && !(mf->mf_flags & MFF_RESTART))
- error = m->mf_ops->fs_init(m);
- /*
- * if you just "return error" here, you will have made a failure
- * in any submounts to fail the whole group. There was old unused code
- * here before.
- */
- if (error > 0)
- n->n_error = error;
-
- else if (error < 0) {
- glob_error = -1;
- if (!asked_for_wakeup) {
- asked_for_wakeup = 1;
- sched_task(wakeup_task, (opaque_t) mf, get_mntfs_wchan(m));
- }
- }
- }
-
- return glob_error;
-}
-
-
-static void
-amfs_nfsx_cont(int rc, int term, opaque_t arg)
-{
- mntfs *mf = (mntfs *) arg;
- struct amfs_nfsx *nx = (struct amfs_nfsx *) mf->mf_private;
- am_node *mp = nx->nx_mp;
- amfs_nfsx_mnt *n = nx->nx_try;
-
- n->n_mnt->mf_flags &= ~(MFF_ERROR | MFF_MOUNTING);
- mf->mf_flags &= ~MFF_ERROR;
-
- /*
- * Wakeup anything waiting for this mount
- */
- wakeup(get_mntfs_wchan(n->n_mnt));
-
- if (rc || term) {
- if (term) {
- /*
- * Not sure what to do for an error code.
- */
- plog(XLOG_ERROR, "mount for %s got signal %d", n->n_mnt->mf_mount, term);
- n->n_error = EIO;
- } else {
- /*
- * Check for exit status
- */
- errno = rc; /* XXX */
- plog(XLOG_ERROR, "%s: mount (amfs_nfsx_cont): %m", n->n_mnt->mf_mount);
- n->n_error = rc;
- }
- free_mntfs(n->n_mnt);
- n->n_mnt = new_mntfs();
- n->n_mnt->mf_error = n->n_error;
- n->n_mnt->mf_flags |= MFF_ERROR;
- } else {
- /*
- * The mount worked.
- */
- mf_mounted(n->n_mnt, FALSE); /* FALSE => don't free the n_mnt->am_opts */
- n->n_error = 0;
- }
-
- /*
- * Do the remaining bits
- */
- if (amfs_nfsx_mount(mp, mf) >= 0)
- wakeup(get_mntfs_wchan(mf));
-}
-
-
-static int
-try_amfs_nfsx_mount(opaque_t mv)
-{
- mntfs *mf = (mntfs *) mv;
- struct amfs_nfsx *nx = (struct amfs_nfsx *) mf->mf_private;
- am_node *mp = nx->nx_mp;
- int error;
-
- error = mf->mf_ops->mount_fs(mp, mf);
-
- return error;
-}
-
-
-static int
-amfs_nfsx_remount(am_node *am, mntfs *mf, int fg)
-{
- struct amfs_nfsx *nx = (struct amfs_nfsx *) mf->mf_private;
- amfs_nfsx_mnt *n;
- int glob_error = -1;
-
- /* Save the am_node pointer for later use */
- nx->nx_mp = am;
-
- /*
- * Iterate through the mntfs's and mount each filesystem
- * which is not yet mounted.
- */
- for (n = nx->nx_v; n < nx->nx_v + nx->nx_c; n++) {
- mntfs *m = n->n_mnt;
-
- if (m->mf_flags & MFF_MOUNTING)
- break;
-
- if (m->mf_flags & MFF_MOUNTED) {
- mf_mounted(m, FALSE); /* FALSE => don't free the m->am_opts */
- n->n_error = glob_error = 0;
- continue;
- }
-
- if (n->n_error < 0) {
- /* Create the mountpoint, if and as required */
- if (!(m->mf_flags & MFF_MKMNT) && m->mf_fsflags & FS_MKMNT) {
- if (!mkdirs(m->mf_mount, 0555))
- m->mf_flags |= MFF_MKMNT;
- }
-
- dlog("calling underlying mount on %s", m->mf_mount);
- if (!fg && foreground && (m->mf_fsflags & FS_MBACKGROUND)) {
- m->mf_flags |= MFF_MOUNTING;
- dlog("backgrounding mount of \"%s\"", m->mf_info);
- nx->nx_try = n;
- run_task(try_amfs_nfsx_mount, (opaque_t) m, amfs_nfsx_cont, (opaque_t) mf);
- n->n_error = -1;
- return -1;
- } else {
- dlog("foreground mount of \"%s\" ...", mf->mf_info);
- n->n_error = m->mf_ops->mount_fs(am, m);
- }
-
- if (n->n_error > 0)
- dlog("underlying fmount of %s failed: %s", m->mf_mount, strerror(n->n_error));
-
- if (n->n_error == 0) {
- glob_error = 0;
- } else if (glob_error < 0) {
- glob_error = n->n_error;
- }
- }
- }
-
- return glob_error < 0 ? 0 : glob_error;
-}
-
-
-static int
-amfs_nfsx_mount(am_node *am, mntfs *mf)
-{
- return amfs_nfsx_remount(am, mf, FALSE);
-}
-
-
-/*
- * Unmount an NFS hierarchy.
- * Note that this is called in the foreground
- * and so may hang under extremely rare conditions.
- */
-static int
-amfs_nfsx_umount(am_node *am, mntfs *mf)
-{
- struct amfs_nfsx *nx = (struct amfs_nfsx *) mf->mf_private;
- amfs_nfsx_mnt *n;
- int glob_error = 0;
-
- /*
- * Iterate in reverse through the mntfs's and unmount each filesystem
- * which is mounted.
- */
- for (n = nx->nx_v + nx->nx_c - 1; n >= nx->nx_v; --n) {
- mntfs *m = n->n_mnt;
- /*
- * If this node has not been messed with
- * and there has been no error so far
- * then try and unmount.
- * If an error had occurred then zero
- * the error code so that the remount
- * only tries to unmount those nodes
- * which had been successfully unmounted.
- */
- if (n->n_error == 0) {
- dlog("calling underlying fumount on %s", m->mf_mount);
- n->n_error = m->mf_ops->umount_fs(am, m);
- if (n->n_error) {
- glob_error = n->n_error;
- n->n_error = 0;
- } else {
- /*
- * Make sure remount gets this node
- */
- n->n_error = -1;
- }
- }
- }
-
- /*
- * If any unmounts failed then remount the
- * whole lot...
- */
- if (glob_error) {
- glob_error = amfs_nfsx_remount(am, mf, TRUE);
- if (glob_error) {
- errno = glob_error; /* XXX */
- plog(XLOG_USER, "amfs_nfsx: remount of %s failed: %m", mf->mf_mount);
- }
- glob_error = EBUSY;
- } else {
- /*
- * Remove all the mount points
- */
- for (n = nx->nx_v; n < nx->nx_v + nx->nx_c; n++) {
- mntfs *m = n->n_mnt;
- dlog("calling underlying umounted on %s", m->mf_mount);
- if (m->mf_ops->umounted)
- m->mf_ops->umounted(m);
-
- if (n->n_error < 0) {
- if (m->mf_fsflags & FS_MKMNT) {
- (void) rmdirs(m->mf_mount);
- m->mf_flags &= ~MFF_MKMNT;
- }
- }
- free_mntfs(m);
- n->n_mnt = 0;
- n->n_error = -1;
- }
- }
-
- return glob_error;
-}
diff --git a/contrib/amd/amd/amfs_program.c b/contrib/amd/amd/amfs_program.c
deleted file mode 100644
index 843e8050c11b..000000000000
--- a/contrib/amd/amd/amfs_program.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amfs_program.c
- *
- */
-
-/*
- * Program file system
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* forward definitions */
-static char *amfs_program_match(am_opts *fo);
-static int amfs_program_mount(am_node *am, mntfs *mf);
-static int amfs_program_umount(am_node *am, mntfs *mf);
-static int amfs_program_init(mntfs *mf);
-
-/*
- * Ops structure
- */
-am_ops amfs_program_ops =
-{
- "program",
- amfs_program_match,
- amfs_program_init,
- amfs_program_mount,
- amfs_program_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* amfs_program_readlink */
- 0, /* amfs_program_mounted */
- 0, /* amfs_program_umounted */
- amfs_generic_find_srvr,
- 0, /* amfs_program_get_wchan */
- FS_MKMNT | FS_BACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_PROGRAM_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/*
- * Execute needs a mount and unmount command.
- */
-static char *
-amfs_program_match(am_opts *fo)
-{
- char *prog;
-
- if (fo->opt_unmount && fo->opt_umount) {
- plog(XLOG_ERROR, "program: cannot specify both unmount and umount options");
- return 0;
- }
- if (!fo->opt_mount) {
- plog(XLOG_ERROR, "program: must specify mount command");
- return 0;
- }
- if (!fo->opt_unmount && !fo->opt_umount) {
- fo->opt_unmount = str3cat(NULL, UNMOUNT_PROGRAM, " umount ", fo->opt_fs);
- plog(XLOG_INFO, "program: un/umount not specified; using default \"%s\"",
- fo->opt_unmount);
- }
- prog = strchr(fo->opt_mount, ' ');
-
- return strdup(prog ? prog + 1 : fo->opt_mount);
-}
-
-
-static int
-amfs_program_init(mntfs *mf)
-{
- /* check if already saved value */
- if (mf->mf_private != NULL)
- return 0;
-
- /* save unmount (or umount) command */
- if (mf->mf_fo->opt_unmount != NULL)
- mf->mf_private = (opaque_t) strdup(mf->mf_fo->opt_unmount);
- else
- mf->mf_private = (opaque_t) strdup(mf->mf_fo->opt_umount);
- mf->mf_prfree = (void (*)(opaque_t)) free;
-
- return 0;
-}
-
-
-static int
-amfs_program_exec(char *info)
-{
- char **xivec;
- int error;
-
- /*
- * Split copy of command info string
- */
- info = strdup(info);
- if (info == 0)
- return ENOBUFS;
- xivec = strsplit(info, ' ', '\'');
-
- /*
- * Put stdout to stderr
- */
- (void) fclose(stdout);
- if (!logfp)
- logfp = stderr; /* initialize before possible first use */
- (void) dup(fileno(logfp));
- if (fileno(logfp) != fileno(stderr)) {
- (void) fclose(stderr);
- (void) dup(fileno(logfp));
- }
-
- /*
- * Try the exec
- */
- if (amuDebug(D_FULL)) {
- char **cp = xivec;
- plog(XLOG_DEBUG, "executing (un)mount command...");
- while (*cp) {
- plog(XLOG_DEBUG, "arg[%ld] = '%s'", (long) (cp - xivec), *cp);
- cp++;
- }
- }
-
- if (xivec[0] == 0 || xivec[1] == 0) {
- errno = EINVAL;
- plog(XLOG_USER, "1st/2nd args missing to (un)mount program");
- } else {
- (void) execv(xivec[0], xivec + 1);
- }
-
- /*
- * Save error number
- */
- error = errno;
- plog(XLOG_ERROR, "exec failed: %m");
-
- /*
- * Free allocate memory
- */
- XFREE(info);
- XFREE(xivec);
-
- /*
- * Return error
- */
- return error;
-}
-
-
-static int
-amfs_program_mount(am_node *am, mntfs *mf)
-{
- return amfs_program_exec(mf->mf_fo->opt_mount);
-}
-
-
-static int
-amfs_program_umount(am_node *am, mntfs *mf)
-{
- return amfs_program_exec((char *) mf->mf_private);
-}
diff --git a/contrib/amd/amd/amfs_root.c b/contrib/amd/amd/amfs_root.c
deleted file mode 100644
index 243267e71e86..000000000000
--- a/contrib/amd/amd/amfs_root.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amfs_root.c
- *
- */
-
-/*
- * Root file system
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/****************************************************************************
- *** FORWARD DEFINITIONS ***
- ****************************************************************************/
-static int amfs_root_mount(am_node *mp, mntfs *mf);
-
-/****************************************************************************
- *** OPS STRUCTURES ***
- ****************************************************************************/
-am_ops amfs_root_ops =
-{
- "root",
- 0, /* amfs_root_match */
- 0, /* amfs_root_init */
- amfs_root_mount,
- amfs_generic_umount,
- amfs_generic_lookup_child,
- amfs_generic_mount_child,
- amfs_generic_readdir,
- 0, /* amfs_root_readlink */
- 0, /* amfs_root_mounted */
- 0, /* amfs_root_umounted */
- amfs_generic_find_srvr,
- 0, /* amfs_root_get_wchan */
- FS_NOTIMEOUT | FS_AMQINFO | FS_DIRECTORY, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_ROOT_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/****************************************************************************
- *** FUNCTIONS ***
- ****************************************************************************/
-
-/*
- * Mount the root...
- */
-static int
-amfs_root_mount(am_node *mp, mntfs *mf)
-{
- mf->mf_mount = strealloc(mf->mf_mount, pid_fsname);
- mf->mf_private = (opaque_t) mapc_find(mf->mf_info, "", NULL);
- mf->mf_prfree = mapc_free;
-
- return 0;
-}
diff --git a/contrib/amd/amd/amfs_toplvl.c b/contrib/amd/amd/amfs_toplvl.c
deleted file mode 100644
index 1b968f197f55..000000000000
--- a/contrib/amd/amd/amfs_toplvl.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amfs_toplvl.c
- *
- */
-
-/*
- * Top-level file system
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/****************************************************************************
- *** FORWARD DEFINITIONS ***
- ****************************************************************************/
-static int amfs_toplvl_init(mntfs *mf);
-
-/****************************************************************************
- *** OPS STRUCTURES ***
- ****************************************************************************/
-am_ops amfs_toplvl_ops =
-{
- "toplvl",
- amfs_generic_match,
- amfs_toplvl_init, /* amfs_toplvl_init */
- amfs_toplvl_mount,
- amfs_toplvl_umount,
- amfs_generic_lookup_child,
- amfs_generic_mount_child,
- amfs_generic_readdir,
- 0, /* amfs_toplvl_readlink */
- amfs_generic_mounted,
- 0, /* amfs_toplvl_umounted */
- amfs_generic_find_srvr,
- 0, /* amfs_toplvl_get_wchan */
- FS_MKMNT | FS_NOTIMEOUT | FS_BACKGROUND |
- FS_AMQINFO | FS_DIRECTORY, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_TOPLVL_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/****************************************************************************
- *** FUNCTIONS ***
- ****************************************************************************/
-
-static void
-set_auto_attrcache_timeout(char *preopts, char *opts, size_t l)
-{
-
-#ifdef MNTTAB_OPT_NOAC
- /*
- * Don't cache attributes - they are changing under the kernel's feet.
- * For example, IRIX5.2 will dispense with nfs lookup calls and hand stale
- * filehandles to getattr unless we disable attribute caching on the
- * automount points.
- */
- if (gopt.auto_attrcache == 0) {
- xsnprintf(preopts, l, ",%s", MNTTAB_OPT_NOAC);
- xstrlcat(opts, preopts, l);
- }
-#endif /* MNTTAB_OPT_NOAC */
-
- /*
- * XXX: note that setting these to 0 in the past resulted in an error on
- * some systems, which is why it's better to use "noac" if possible. For
- * now, we're setting everything possible, but if this will cause trouble,
- * then we'll have to condition the remainder of this on OPT_NOAC.
- */
-#ifdef MNTTAB_OPT_ACTIMEO
- xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTIMEO, gopt.auto_attrcache);
- xstrlcat(opts, preopts, l);
-#else /* MNTTAB_OPT_ACTIMEO */
-# ifdef MNTTAB_OPT_ACDIRMIN
- xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTDIRMIN, gopt.auto_attrcache);
- xstrlcat(opts, preopts, l);
-# endif /* MNTTAB_OPT_ACDIRMIN */
-# ifdef MNTTAB_OPT_ACDIRMAX
- xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTDIRMAX, gopt.auto_attrcache);
- xstrlcat(opts, preopts, l);
-# endif /* MNTTAB_OPT_ACDIRMAX */
-# ifdef MNTTAB_OPT_ACREGMIN
- xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTREGMIN, gopt.auto_attrcache);
- xstrlcat(opts, preopts, l);
-# endif /* MNTTAB_OPT_ACREGMIN */
-# ifdef MNTTAB_OPT_ACREGMAX
- xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTREGMAX, gopt.auto_attrcache);
- xstrlcat(opts, preopts, l);
-# endif /* MNTTAB_OPT_ACREGMAX */
-#endif /* MNTTAB_OPT_ACTIMEO */
-}
-
-
-/*
- * Initialize a top-level mount. In our case, if the user asked for
- * forced_unmounts, and the OS supports it, then we try forced/lazy unmounts
- * on any previous toplvl mounts. This is useful if a previous Amd died and
- * left behind toplvl mount points (this Amd will clean them up).
- *
- * WARNING: Don't use forced/lazy unmounts if you have another valid Amd
- * running, because this code WILL force those valid toplvl mount points to
- * be detached as well!
- */
-static int
-amfs_toplvl_init(mntfs *mf)
-{
- int error = 0;
-
-#if defined(MNT2_GEN_OPT_FORCE) || defined(MNT2_GEN_OPT_DETACH)
- if (gopt.flags & CFM_FORCED_UNMOUNTS) {
- plog(XLOG_INFO, "amfs_toplvl_init: trying forced/lazy unmount of %s",
- mf->mf_mount);
- error = umount2_fs(mf->mf_mount, AMU_UMOUNT_FORCE | AMU_UMOUNT_DETACH);
- if (error)
- plog(XLOG_INFO, "amfs_toplvl_init: forced/lazy unmount failed: %m");
- else
- dlog("amfs_toplvl_init: forced/lazy unmount succeeded");
- }
-#endif /* MNT2_GEN_OPT_FORCE || MNT2_GEN_OPT_DETACH */
- return error;
-}
-
-
-/*
- * Mount the top-level
- */
-int
-amfs_toplvl_mount(am_node *mp, mntfs *mf)
-{
- struct stat stb;
- char opts[SIZEOF_OPTS], preopts[SIZEOF_OPTS], toplvl_opts[40];
- int error;
-
- /*
- * Mounting the automounter.
- * Make sure the mount directory exists, construct
- * the mount options and call the mount_amfs_toplvl routine.
- */
-
- if (stat(mp->am_path, &stb) < 0) {
- return errno;
- } else if ((stb.st_mode & S_IFMT) != S_IFDIR) {
- plog(XLOG_WARNING, "%s is not a directory", mp->am_path);
- return ENOTDIR;
- }
-
- /*
- * Construct some mount options:
- *
- * Tack on magic map=<mapname> option in mtab to emulate
- * SunOS automounter behavior.
- */
-
-#ifdef HAVE_FS_AUTOFS
- if (mf->mf_flags & MFF_IS_AUTOFS) {
- autofs_get_opts(opts, sizeof(opts), mp->am_autofs_fh);
- } else
-#endif /* HAVE_FS_AUTOFS */
- {
- preopts[0] = '\0';
-#ifdef MNTTAB_OPT_INTR
- xstrlcat(preopts, MNTTAB_OPT_INTR, sizeof(preopts));
- xstrlcat(preopts, ",", sizeof(preopts));
-#endif /* MNTTAB_OPT_INTR */
-#ifdef MNTTAB_OPT_IGNORE
- xstrlcat(preopts, MNTTAB_OPT_IGNORE, sizeof(preopts));
- xstrlcat(preopts, ",", sizeof(preopts));
-#endif /* MNTTAB_OPT_IGNORE */
- /* write most of the initial options + preopts */
- xsnprintf(opts, sizeof(opts), "%s%s,%s=%d,%s,map=%s",
- preopts,
- MNTTAB_OPT_RW,
- MNTTAB_OPT_PORT, nfs_port,
- mf->mf_ops->fs_type, mf->mf_info);
-
- /* process toplvl timeo/retrans options, if any */
- if (gopt.amfs_auto_timeo[AMU_TYPE_TOPLVL] > 0) {
- xsnprintf(toplvl_opts, sizeof(toplvl_opts), ",%s=%d",
- MNTTAB_OPT_TIMEO, gopt.amfs_auto_timeo[AMU_TYPE_TOPLVL]);
- xstrlcat(opts, toplvl_opts, sizeof(opts));
- }
- if (gopt.amfs_auto_retrans[AMU_TYPE_TOPLVL] > 0) {
- xsnprintf(toplvl_opts, sizeof(toplvl_opts), ",%s=%d",
- MNTTAB_OPT_RETRANS, gopt.amfs_auto_retrans[AMU_TYPE_TOPLVL]);
- xstrlcat(opts, toplvl_opts, sizeof(opts));
- }
-
-#ifdef MNTTAB_OPT_NOAC
- if (gopt.auto_attrcache == 0) {
- xstrlcat(opts, ",", sizeof(opts));
- xstrlcat(opts, MNTTAB_OPT_NOAC, sizeof(opts));
- } else
-#endif /* MNTTAB_OPT_NOAC */
- set_auto_attrcache_timeout(preopts, opts, sizeof(preopts));
- }
-
- /* now do the mount */
- error = amfs_mount(mp, mf, opts);
- if (error) {
- errno = error;
- plog(XLOG_FATAL, "amfs_toplvl_mount: amfs_mount failed: %m");
- return error;
- }
- return 0;
-}
-
-
-/*
- * Unmount a top-level automount node
- */
-int
-amfs_toplvl_umount(am_node *mp, mntfs *mf)
-{
- struct stat stb;
- int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
- int error;
- int count = 0; /* how many times did we try to unmount? */
-
-again:
- /*
- * The lstat is needed if this mount is type=direct.
- * When that happens, the kernel cache gets confused
- * between the underlying type (dir) and the mounted
- * type (link) and so needs to be re-synced before
- * the unmount. This is all because the unmount system
- * call follows links and so can't actually unmount
- * a link (stupid!). It was noted that doing an ls -ld
- * of the mount point to see why things were not working
- * actually fixed the problem - so simulate an ls -ld here.
- */
- if (lstat(mp->am_path, &stb) < 0) {
- error = errno;
- dlog("lstat(%s): %m", mp->am_path);
- goto out;
- }
- if ((stb.st_mode & S_IFMT) != S_IFDIR) {
- plog(XLOG_ERROR, "amfs_toplvl_umount: %s is not a directory, aborting.", mp->am_path);
- error = ENOTDIR;
- goto out;
- }
-
- error = UMOUNT_FS(mp->am_path, mnttab_file_name, unmount_flags);
- if (error == EBUSY) {
-#ifdef HAVE_FS_AUTOFS
- /*
- * autofs mounts are "in place", so it is possible
- * that we can't just unmount our mount points and go away.
- * If that's the case, just give up.
- */
- if (mf->mf_flags & MFF_IS_AUTOFS)
- return error;
-#endif /* HAVE_FS_AUTOFS */
- plog(XLOG_WARNING, "amfs_toplvl_unmount retrying %s in 1s", mp->am_path);
- count++;
- sleep(1);
- /*
- * If user wants forced/lazy unmount semantics, then set those flags,
- * but only after we've tried normal lstat/umount a few times --
- * otherwise forced unmounts may hang this very same Amd (by preventing
- * it from achieving a clean unmount).
- */
- if (gopt.flags & CFM_FORCED_UNMOUNTS) {
- if (count == 5) { /* after 5 seconds, try MNT_FORCE */
- dlog("enabling forced unmounts for toplvl node %s", mp->am_path);
- unmount_flags |= AMU_UMOUNT_FORCE;
- }
- if (count == 10) { /* after 10 seconds, try MNT_DETACH */
- dlog("enabling detached unmounts for toplvl node %s", mp->am_path);
- unmount_flags |= AMU_UMOUNT_DETACH;
- }
- }
- goto again;
- }
-out:
- return error;
-}
diff --git a/contrib/amd/amd/amfs_union.c b/contrib/amd/amd/amfs_union.c
deleted file mode 100644
index 6adb5b0bd9cb..000000000000
--- a/contrib/amd/amd/amfs_union.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amfs_union.c
- *
- */
-
-/*
- * Union automounter file system
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/****************************************************************************
- *** FORWARD DEFINITIONS ***
- ****************************************************************************/
-static int create_amfs_union_node(char *dir, opaque_t arg);
-static void amfs_union_mounted(mntfs *mf);
-
-
-/****************************************************************************
- *** OPS STRUCTURES ***
- ****************************************************************************/
-am_ops amfs_union_ops =
-{
- "union",
- amfs_generic_match,
- 0, /* amfs_union_init */
- amfs_toplvl_mount,
- amfs_toplvl_umount,
- amfs_generic_lookup_child,
- amfs_generic_mount_child,
- amfs_generic_readdir,
- 0, /* amfs_union_readlink */
- amfs_union_mounted,
- 0, /* amfs_union_umounted */
- amfs_generic_find_srvr,
- 0, /* amfs_union_get_wchan */
- FS_MKMNT | FS_NOTIMEOUT | FS_BACKGROUND | FS_AMQINFO | FS_DIRECTORY,
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_UNION_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/*
- * Create a reference to a union'ed entry
- * XXX: this function may not be used anywhere...
- */
-static int
-create_amfs_union_node(char *dir, opaque_t arg)
-{
- if (!STREQ(dir, "/defaults")) {
- int error = 0;
- am_node *am;
- am = amfs_generic_lookup_child(arg, dir, &error, VLOOK_CREATE);
- if (am && error < 0)
- am = amfs_generic_mount_child(am, &error);
- if (error > 0) {
- errno = error; /* XXX */
- plog(XLOG_ERROR, "unionfs: could not mount %s: %m", dir);
- }
- return error;
- }
- return 0;
-}
-
-
-static void
-amfs_union_mounted(mntfs *mf)
-{
- int index;
- am_node *mp;
-
- amfs_mkcacheref(mf);
-
- /*
- * Having made the union mount point,
- * populate all the entries...
- */
- for (mp = get_first_exported_ap(&index);
- mp;
- mp = get_next_exported_ap(&index)) {
- if (mp->am_mnt == mf) {
- /* return value from create_amfs_union_node is ignored by mapc_keyiter */
- (void) mapc_keyiter((mnt_map *) mp->am_mnt->mf_private,
- create_amfs_union_node,
- mp);
- break;
- }
- }
-}
diff --git a/contrib/amd/amd/amq_subr.c b/contrib/amd/amd/amq_subr.c
deleted file mode 100644
index 79ecafc3d9b3..000000000000
--- a/contrib/amd/amd/amq_subr.c
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amq_subr.c
- *
- */
-/*
- * Auxiliary routines for amq tool
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* forward definitions */
-bool_t xdr_amq_mount_tree_node(XDR *xdrs, amq_mount_tree *objp);
-bool_t xdr_amq_mount_subtree(XDR *xdrs, amq_mount_tree *objp);
-
-
-voidp
-amqproc_null_1_svc(voidp argp, struct svc_req *rqstp)
-{
- static char res;
-
- return (voidp) &res;
-}
-
-
-/*
- * Return a sub-tree of mounts
- */
-amq_mount_tree_p *
-amqproc_mnttree_1_svc(voidp argp, struct svc_req *rqstp)
-{
- static am_node *mp;
-
- mp = find_ap(*(char **) argp);
- return (amq_mount_tree_p *) ((void *)&mp);
-}
-
-
-/*
- * Unmount a single node
- */
-voidp
-amqproc_umnt_1_svc(voidp argp, struct svc_req *rqstp)
-{
- static char res;
- am_node *mp = find_ap(*(char **) argp);
-
- if (mp)
- forcibly_timeout_mp(mp);
-
- return (voidp) &res;
-}
-
-
-/*
- * Return global statistics
- */
-amq_mount_stats *
-amqproc_stats_1_svc(voidp argp, struct svc_req *rqstp)
-{
- return (amq_mount_stats *) ((void *)&amd_stats);
-}
-
-
-/*
- * Return the entire tree of mount nodes
- */
-amq_mount_tree_list *
-amqproc_export_1_svc(voidp argp, struct svc_req *rqstp)
-{
- static amq_mount_tree_list aml;
- static am_node *mp;
-
- mp = get_exported_ap(0);
- aml.amq_mount_tree_list_val = (amq_mount_tree_p *) ((void *) &mp);
- aml.amq_mount_tree_list_len = 1; /* XXX */
-
- return &aml;
-}
-
-
-int *
-amqproc_setopt_1_svc(voidp argp, struct svc_req *rqstp)
-{
- static int rc;
- amq_setopt *opt = (amq_setopt *) argp;
-
- rc = 0;
-
- switch (opt->as_opt) {
-
- case AMOPT_DEBUG:
- if (debug_option(opt->as_str))
- rc = EINVAL;
- break;
-
- case AMOPT_LOGFILE:
- if (gopt.logfile && opt->as_str
- && STREQ(gopt.logfile, opt->as_str)) {
- if (switch_to_logfile(opt->as_str, orig_umask, 0))
- rc = EINVAL;
- } else {
- rc = EACCES;
- }
- break;
-
- case AMOPT_XLOG:
- if (switch_option(opt->as_str))
- rc = EINVAL;
- break;
-
- case AMOPT_FLUSHMAPC:
- if (amd_state == Run) {
- plog(XLOG_INFO, "amq says flush cache");
- do_mapc_reload = 0;
- flush_nfs_fhandle_cache((fserver *) NULL);
- flush_srvr_nfs_cache((fserver *) NULL);
- }
- break;
- }
-
- return &rc;
-}
-
-
-amq_mount_info_list *
-amqproc_getmntfs_1_svc(voidp argp, struct svc_req *rqstp)
-{
- return (amq_mount_info_list *) ((void *)&mfhead); /* XXX */
-}
-
-
-amq_string *
-amqproc_getvers_1_svc(voidp argp, struct svc_req *rqstp)
-{
- static amq_string res;
-
- res = get_version_string();
- return &res;
-}
-
-
-/* get PID of remote amd */
-int *
-amqproc_getpid_1_svc(voidp argp, struct svc_req *rqstp)
-{
- static int res;
-
- res = getpid();
- return &res;
-}
-
-
-/*
- * Process PAWD string of remote pawd tool.
- *
- * We repeat the resolution of the string until the resolved string resolves
- * to itself. This ensures that we follow path resolutions through all
- * possible Amd mount points until we reach some sort of convergence. To
- * prevent possible infinite loops, we break out of this loop if the strings
- * do not converge after MAX_PAWD_TRIES times.
- */
-amq_string *
-amqproc_pawd_1_svc(voidp argp, struct svc_req *rqstp)
-{
- static amq_string res;
-#define MAX_PAWD_TRIES 10
- int index, len, maxagain = MAX_PAWD_TRIES;
- am_node *mp;
- char *mountpoint;
- char *dir = *(char **) argp;
- static char tmp_buf[MAXPATHLEN];
- char prev_buf[MAXPATHLEN];
-
- tmp_buf[0] = prev_buf[0] = '\0'; /* default is empty string: no match */
- do {
- for (mp = get_first_exported_ap(&index);
- mp;
- mp = get_next_exported_ap(&index)) {
- if (STREQ(mp->am_mnt->mf_ops->fs_type, "toplvl"))
- continue;
- if (STREQ(mp->am_mnt->mf_ops->fs_type, "auto"))
- continue;
- mountpoint = (mp->am_link ? mp->am_link : mp->am_mnt->mf_mount);
- len = strlen(mountpoint);
- if (len == 0)
- continue;
- if (!NSTREQ(mountpoint, dir, len))
- continue;
- if (dir[len] != '\0' && dir[len] != '/')
- continue;
- xstrlcpy(tmp_buf, mp->am_path, sizeof(tmp_buf));
- xstrlcat(tmp_buf, &dir[len], sizeof(tmp_buf));
- break;
- } /* end of "for" loop */
- /* once tmp_buf and prev_buf are equal, break out of "do" loop */
- if (STREQ(tmp_buf, prev_buf))
- break;
- else
- xstrlcpy(prev_buf, tmp_buf, sizeof(prev_buf));
- } while (--maxagain);
- /* check if we couldn't resolve the string after MAX_PAWD_TRIES times */
- if (maxagain <= 0)
- plog(XLOG_WARNING, "path \"%s\" did not resolve after %d tries",
- tmp_buf, MAX_PAWD_TRIES);
-
- res = tmp_buf;
- return &res;
-}
-
-
-/*
- * XDR routines.
- */
-
-
-bool_t
-xdr_amq_setopt(XDR *xdrs, amq_setopt *objp)
-{
- if (!xdr_enum(xdrs, (enum_t *) ((voidp) &objp->as_opt))) {
- return (FALSE);
- }
- if (!xdr_string(xdrs, &objp->as_str, AMQ_STRLEN)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-
-/*
- * More XDR routines - Should be used for OUTPUT ONLY.
- */
-bool_t
-xdr_amq_mount_tree_node(XDR *xdrs, amq_mount_tree *objp)
-{
- am_node *mp = (am_node *) objp;
- long mtime;
-
- if (!xdr_amq_string(xdrs, &mp->am_mnt->mf_info)) {
- return (FALSE);
- }
- if (!xdr_amq_string(xdrs, &mp->am_path)) {
- return (FALSE);
- }
- if (!xdr_amq_string(xdrs, mp->am_link ? &mp->am_link : &mp->am_mnt->mf_mount)) {
- return (FALSE);
- }
- if (!xdr_amq_string(xdrs, &mp->am_mnt->mf_ops->fs_type)) {
- return (FALSE);
- }
- mtime = mp->am_stats.s_mtime;
- if (!xdr_long(xdrs, &mtime)) {
- return (FALSE);
- }
- if (!xdr_u_short(xdrs, &mp->am_stats.s_uid)) {
- return (FALSE);
- }
- if (!xdr_int(xdrs, &mp->am_stats.s_getattr)) {
- return (FALSE);
- }
- if (!xdr_int(xdrs, &mp->am_stats.s_lookup)) {
- return (FALSE);
- }
- if (!xdr_int(xdrs, &mp->am_stats.s_readdir)) {
- return (FALSE);
- }
- if (!xdr_int(xdrs, &mp->am_stats.s_readlink)) {
- return (FALSE);
- }
- if (!xdr_int(xdrs, &mp->am_stats.s_statfs)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-
-bool_t
-xdr_amq_mount_subtree(XDR *xdrs, amq_mount_tree *objp)
-{
- am_node *mp = (am_node *) objp;
-
- if (!xdr_amq_mount_tree_node(xdrs, objp)) {
- return (FALSE);
- }
- if (!xdr_pointer(xdrs,
- (char **) ((voidp) &mp->am_osib),
- sizeof(amq_mount_tree),
- (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
- return (FALSE);
- }
- if (!xdr_pointer(xdrs,
- (char **) ((voidp) &mp->am_child),
- sizeof(amq_mount_tree),
- (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-
-bool_t
-xdr_amq_mount_tree(XDR *xdrs, amq_mount_tree *objp)
-{
- am_node *mp = (am_node *) objp;
- am_node *mnil = NULL;
-
- if (!xdr_amq_mount_tree_node(xdrs, objp)) {
- return (FALSE);
- }
- if (!xdr_pointer(xdrs,
- (char **) ((voidp) &mnil),
- sizeof(amq_mount_tree),
- (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
- return (FALSE);
- }
- if (!xdr_pointer(xdrs,
- (char **) ((voidp) &mp->am_child),
- sizeof(amq_mount_tree),
- (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-
-bool_t
-xdr_amq_mount_tree_p(XDR *xdrs, amq_mount_tree_p *objp)
-{
- if (!xdr_pointer(xdrs, (char **) objp, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_tree)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-
-bool_t
-xdr_amq_mount_stats(XDR *xdrs, amq_mount_stats *objp)
-{
- if (!xdr_int(xdrs, &objp->as_drops)) {
- return (FALSE);
- }
- if (!xdr_int(xdrs, &objp->as_stale)) {
- return (FALSE);
- }
- if (!xdr_int(xdrs, &objp->as_mok)) {
- return (FALSE);
- }
- if (!xdr_int(xdrs, &objp->as_merr)) {
- return (FALSE);
- }
- if (!xdr_int(xdrs, &objp->as_uerr)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-
-
-bool_t
-xdr_amq_mount_tree_list(XDR *xdrs, amq_mount_tree_list *objp)
-{
- if (!xdr_array(xdrs,
- (char **) ((voidp) &objp->amq_mount_tree_list_val),
- (u_int *) &objp->amq_mount_tree_list_len,
- ~0,
- sizeof(amq_mount_tree_p),
- (XDRPROC_T_TYPE) xdr_amq_mount_tree_p)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-
-
-/*
- * Compute length of list
- */
-bool_t
-xdr_amq_mount_info_qelem(XDR *xdrs, qelem *qhead)
-{
- mntfs *mf;
- u_int len = 0;
-
- for (mf = AM_LAST(mntfs, qhead); mf != HEAD(mntfs, qhead); mf = PREV(mntfs, mf)) {
- if (!(mf->mf_fsflags & FS_AMQINFO))
- continue;
- len++;
- }
- xdr_u_int(xdrs, &len);
-
- /*
- * Send individual data items
- */
- for (mf = AM_LAST(mntfs, qhead); mf != HEAD(mntfs, qhead); mf = PREV(mntfs, mf)) {
- int up;
- if (!(mf->mf_fsflags & FS_AMQINFO))
- continue;
-
- if (!xdr_amq_string(xdrs, &mf->mf_ops->fs_type)) {
- return (FALSE);
- }
- if (!xdr_amq_string(xdrs, &mf->mf_mount)) {
- return (FALSE);
- }
- if (!xdr_amq_string(xdrs, &mf->mf_info)) {
- return (FALSE);
- }
- if (!xdr_amq_string(xdrs, &mf->mf_server->fs_host)) {
- return (FALSE);
- }
- if (!xdr_int(xdrs, &mf->mf_error)) {
- return (FALSE);
- }
- if (!xdr_int(xdrs, &mf->mf_refc)) {
- return (FALSE);
- }
- if (FSRV_ERROR(mf->mf_server) || FSRV_ISDOWN(mf->mf_server))
- up = 0;
- else if (FSRV_ISUP(mf->mf_server))
- up = 1;
- else
- up = -1;
- if (!xdr_int(xdrs, &up)) {
- return (FALSE);
- }
- }
- return (TRUE);
-}
-
-
-bool_t
-xdr_pri_free(XDRPROC_T_TYPE xdr_args, caddr_t args_ptr)
-{
- XDR xdr;
-
- xdr.x_op = XDR_FREE;
- return ((*xdr_args) (&xdr, (caddr_t *) args_ptr));
-}
diff --git a/contrib/amd/amd/amq_svc.c b/contrib/amd/amd/amq_svc.c
deleted file mode 100644
index 6fadb160c121..000000000000
--- a/contrib/amd/amd/amq_svc.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/amq_svc.c
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* typedefs */
-typedef char *(*amqsvcproc_t)(voidp, struct svc_req *);
-
-#if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
-# ifdef NEED_LIBWRAP_SEVERITY_VARIABLES
-/*
- * Some systems that define libwrap already define these two variables
- * in libwrap, while others don't: so I need to know precisely iff
- * to define these two severity variables.
- */
-int allow_severity=0, deny_severity=0;
-# endif /* NEED_LIBWRAP_SEVERITY_VARIABLES */
-
-/*
- * check if remote amq is authorized to access this amd.
- * Returns: 1=allowed, 0=denied.
- */
-static int
-amqsvc_is_client_allowed(const struct sockaddr_in *addr, char *remote)
-{
- struct hostent *h;
- char *name = NULL, **ad;
- int ret = 0; /* default is 0==denied */
-
- /* Check IP address */
- if (hosts_ctl(AMD_SERVICE_NAME, "", remote, "")) {
- ret = 1;
- goto out;
- }
- /* Get address */
- if (!(h = gethostbyaddr((const char *)&(addr->sin_addr),
- sizeof(addr->sin_addr),
- AF_INET)))
- goto out;
- if (!(name = strdup(h->h_name)))
- goto out;
- /* Paranoia check */
- if (!(h = gethostbyname(name)))
- goto out;
- for (ad = h->h_addr_list; *ad; ad++)
- if (!memcmp(*ad, &(addr->sin_addr), h->h_length))
- break;
- if (!*ad)
- goto out;
- if (hosts_ctl(AMD_SERVICE_NAME, "", h->h_name, "")) {
- return 1;
- goto out;
- }
- /* Check aliases */
- for (ad = h->h_aliases; *ad; ad++)
- if (hosts_ctl(AMD_SERVICE_NAME, "", *ad, "")) {
- return 1;
- goto out;
- }
-
- out:
- if (name)
- XFREE(name);
- return ret;
-}
-#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
-
-
-void
-amq_program_1(struct svc_req *rqstp, SVCXPRT *transp)
-{
- union {
- amq_string amqproc_mnttree_1_arg;
- amq_string amqproc_umnt_1_arg;
- amq_setopt amqproc_setopt_1_arg;
- } argument;
- char *result;
- xdrproc_t xdr_argument, xdr_result;
- amqsvcproc_t local;
-
-#if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
- if (gopt.flags & CFM_USE_TCPWRAPPERS) {
- struct sockaddr_in *remote_addr = svc_getcaller(rqstp->rq_xprt);
- char *remote_hostname = inet_ntoa(remote_addr->sin_addr);
-
- if (!amqsvc_is_client_allowed(remote_addr, remote_hostname)) {
- plog(XLOG_WARNING, "Amd denied remote amq service to %s", remote_hostname);
- svcerr_auth(transp, AUTH_FAILED);
- return;
- } else {
- dlog("Amd allowed remote amq service to %s", remote_hostname);
- }
- }
-#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
-
- switch (rqstp->rq_proc) {
-
- case AMQPROC_NULL:
- xdr_argument = (xdrproc_t) xdr_void;
- xdr_result = (xdrproc_t) xdr_void;
- local = (amqsvcproc_t) amqproc_null_1_svc;
- break;
-
- case AMQPROC_MNTTREE:
- xdr_argument = (xdrproc_t) xdr_amq_string;
- xdr_result = (xdrproc_t) xdr_amq_mount_tree_p;
- local = (amqsvcproc_t) amqproc_mnttree_1_svc;
- break;
-
- case AMQPROC_UMNT:
- xdr_argument = (xdrproc_t) xdr_amq_string;
- xdr_result = (xdrproc_t) xdr_void;
- local = (amqsvcproc_t) amqproc_umnt_1_svc;
- break;
-
- case AMQPROC_STATS:
- xdr_argument = (xdrproc_t) xdr_void;
- xdr_result = (xdrproc_t) xdr_amq_mount_stats;
- local = (amqsvcproc_t) amqproc_stats_1_svc;
- break;
-
- case AMQPROC_EXPORT:
- xdr_argument = (xdrproc_t) xdr_void;
- xdr_result = (xdrproc_t) xdr_amq_mount_tree_list;
- local = (amqsvcproc_t) amqproc_export_1_svc;
- break;
-
- case AMQPROC_SETOPT:
- xdr_argument = (xdrproc_t) xdr_amq_setopt;
- xdr_result = (xdrproc_t) xdr_int;
- local = (amqsvcproc_t) amqproc_setopt_1_svc;
- break;
-
- case AMQPROC_GETMNTFS:
- xdr_argument = (xdrproc_t) xdr_void;
- xdr_result = (xdrproc_t) xdr_amq_mount_info_qelem;
- local = (amqsvcproc_t) amqproc_getmntfs_1_svc;
- break;
-
- case AMQPROC_GETVERS:
- xdr_argument = (xdrproc_t) xdr_void;
- xdr_result = (xdrproc_t) xdr_amq_string;
- local = (amqsvcproc_t) amqproc_getvers_1_svc;
- break;
-
- case AMQPROC_GETPID:
- xdr_argument = (xdrproc_t) xdr_void;
- xdr_result = (xdrproc_t) xdr_int;
- local = (amqsvcproc_t) amqproc_getpid_1_svc;
- break;
-
- case AMQPROC_PAWD:
- xdr_argument = (xdrproc_t) xdr_amq_string;
- xdr_result = (xdrproc_t) xdr_amq_string;
- local = (amqsvcproc_t) amqproc_pawd_1_svc;
- break;
-
- default:
- svcerr_noproc(transp);
- return;
- }
-
- memset((char *) &argument, 0, sizeof(argument));
- if (!svc_getargs(transp,
- (XDRPROC_T_TYPE) xdr_argument,
- (SVC_IN_ARG_TYPE) & argument)) {
- svcerr_decode(transp);
- return;
- }
-
- result = (*local) (&argument, rqstp);
-
- if (result != NULL && !svc_sendreply(transp,
- (XDRPROC_T_TYPE) xdr_result,
- result)) {
- svcerr_systemerr(transp);
- }
-
- if (!svc_freeargs(transp,
- (XDRPROC_T_TYPE) xdr_argument,
- (SVC_IN_ARG_TYPE) & argument)) {
- plog(XLOG_FATAL, "unable to free rpc arguments in amqprog_1");
- going_down(1);
- }
-}
diff --git a/contrib/amd/amd/autil.c b/contrib/amd/amd/autil.c
deleted file mode 100644
index a5ecd6d0d1f3..000000000000
--- a/contrib/amd/amd/autil.c
+++ /dev/null
@@ -1,783 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/autil.c
- *
- */
-
-/*
- * utilities specified to amd, taken out of the older amd/util.c.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-int NumChildren = 0; /* number of children of primary amd */
-static char invalid_keys[] = "\"'!;@ \t\n";
-
-/****************************************************************************
- *** MACROS ***
- ****************************************************************************/
-
-#ifdef HAVE_TRANSPORT_TYPE_TLI
-# define PARENT_USLEEP_TIME 100000 /* 0.1 seconds */
-#endif /* HAVE_TRANSPORT_TYPE_TLI */
-
-
-/****************************************************************************
- *** FORWARD DEFINITIONS ***
- ****************************************************************************/
-static void domain_strip(char *otherdom, char *localdom);
-static int dofork(void);
-
-
-/****************************************************************************
- *** FUNCTIONS ***
- ****************************************************************************/
-
-/*
- * Copy s into p, reallocating p if necessary
- */
-char *
-strealloc(char *p, char *s)
-{
- size_t len = strlen(s) + 1;
-
- p = (char *) xrealloc((voidp) p, len);
-
- xstrlcpy(p, s, len);
-#ifdef DEBUG_MEM
-# if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY)
- malloc_verify();
-# endif /* not defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY) */
-#endif /* DEBUG_MEM */
- return p;
-}
-
-
-/*
- * Strip off the trailing part of a domain
- * to produce a short-form domain relative
- * to the local host domain.
- * Note that this has no effect if the domain
- * names do not have the same number of
- * components. If that restriction proves
- * to be a problem then the loop needs recoding
- * to skip from right to left and do partial
- * matches along the way -- ie more expensive.
- */
-static void
-domain_strip(char *otherdom, char *localdom)
-{
- char *p1, *p2;
-
- if ((p1 = strchr(otherdom, '.')) &&
- (p2 = strchr(localdom, '.')) &&
- STREQ(p1 + 1, p2 + 1))
- *p1 = '\0';
-}
-
-
-/*
- * Normalize a host name: replace cnames with real names, and decide if to
- * strip domain name or not.
- */
-void
-host_normalize(char **chp)
-{
- /*
- * Normalize hosts is used to resolve host name aliases
- * and replace them with the standard-form name.
- * Invoked with "-n" command line option.
- */
- if (gopt.flags & CFM_NORMALIZE_HOSTNAMES) {
- struct hostent *hp;
- hp = gethostbyname(*chp);
- if (hp && hp->h_addrtype == AF_INET) {
- dlog("Hostname %s normalized to %s", *chp, hp->h_name);
- *chp = strealloc(*chp, (char *) hp->h_name);
- }
- }
- if (gopt.flags & CFM_DOMAIN_STRIP) {
- domain_strip(*chp, hostd);
- }
-}
-
-
-/*
- * Keys are not allowed to contain " ' ! or ; to avoid
- * problems with macro expansions.
- */
-int
-valid_key(char *key)
-{
- while (*key)
- if (strchr(invalid_keys, *key++))
- return FALSE;
- return TRUE;
-}
-
-
-void
-forcibly_timeout_mp(am_node *mp)
-{
- mntfs *mf = mp->am_mnt;
- /*
- * Arrange to timeout this node
- */
- if (mf && ((mp->am_flags & AMF_ROOT) ||
- (mf->mf_flags & (MFF_MOUNTING | MFF_UNMOUNTING)))) {
- if (mf->mf_flags & MFF_UNMOUNTING)
- plog(XLOG_WARNING, "node %s is currently being unmounted, ignoring timeout request", mp->am_path);
- else
- plog(XLOG_WARNING, "ignoring timeout request for active node %s", mp->am_path);
- } else {
- plog(XLOG_INFO, "\"%s\" forcibly timed out", mp->am_path);
- mp->am_flags &= ~AMF_NOTIMEOUT;
- mp->am_ttl = clocktime(NULL);
- /*
- * Force mtime update of parent dir, to prevent DNLC/dcache from caching
- * the old entry, which could result in ESTALE errors, bad symlinks, and
- * more.
- */
- clocktime(&mp->am_parent->am_fattr.na_mtime);
- reschedule_timeout_mp();
- }
-}
-
-
-void
-mf_mounted(mntfs *mf, bool_t call_free_opts)
-{
- int quoted;
- int wasmounted = mf->mf_flags & MFF_MOUNTED;
-
- if (!wasmounted) {
- /*
- * If this is a freshly mounted
- * filesystem then update the
- * mntfs structure...
- */
- mf->mf_flags |= MFF_MOUNTED;
- mf->mf_error = 0;
-
- /*
- * Do mounted callback
- */
- if (mf->mf_ops->mounted)
- mf->mf_ops->mounted(mf);
-
- /*
- * Be careful when calling free_ops and XFREE here. Some pseudo file
- * systems like nfsx call this function (mf_mounted), even though it
- * would be called by the lower-level amd file system functions. nfsx
- * needs to call this function because of the other actions it takes.
- * So we pass a boolean from the caller (yes, not so clean workaround)
- * to determine if we should free or not. If we're not freeing (often
- * because we're called from a callback function), then just to be sure,
- * we'll zero out the am_opts structure and set the pointer to NULL.
- * The parent mntfs node owns this memory and is going to free it with a
- * call to mf_mounted(mntfs,TRUE) (see comment in the am_mounted code).
- */
- if (call_free_opts) {
- free_opts(mf->mf_fo); /* this free is needed to prevent leaks */
- XFREE(mf->mf_fo); /* (also this one) */
- } else {
- memset(mf->mf_fo, 0, sizeof(am_opts));
- mf->mf_fo = NULL;
- }
- }
-
- if (mf->mf_flags & MFF_RESTART) {
- mf->mf_flags &= ~MFF_RESTART;
- dlog("Restarted filesystem %s, flags 0x%x", mf->mf_mount, mf->mf_flags);
- }
-
- /*
- * Log message
- */
- quoted = strchr(mf->mf_info, ' ') != 0;
- plog(XLOG_INFO, "%s%s%s %s fstype %s on %s",
- quoted ? "\"" : "",
- mf->mf_info,
- quoted ? "\"" : "",
- wasmounted ? "referenced" : "mounted",
- mf->mf_ops->fs_type, mf->mf_mount);
-}
-
-
-void
-am_mounted(am_node *mp)
-{
- int notimeout = 0; /* assume normal timeouts initially */
- mntfs *mf = mp->am_mnt;
-
- /*
- * This is the parent mntfs which does the mf->mf_fo (am_opts type), and
- * we're passing TRUE here to tell mf_mounted to actually free the
- * am_opts. See a related comment in mf_mounted().
- */
- mf_mounted(mf, TRUE);
-
-#ifdef HAVE_FS_AUTOFS
- if (mf->mf_flags & MFF_IS_AUTOFS)
- autofs_mounted(mp);
-#endif /* HAVE_FS_AUTOFS */
-
- /*
- * Patch up path for direct mounts
- */
- if (mp->am_parent && mp->am_parent->am_mnt->mf_fsflags & FS_DIRECT)
- mp->am_path = str3cat(mp->am_path, mp->am_parent->am_path, "/", ".");
-
- /*
- * Check whether this mount should be cached permanently or not,
- * and handle user-requested timeouts.
- */
- /* first check if file system was set to never timeout */
- if (mf->mf_fsflags & FS_NOTIMEOUT)
- notimeout = 1;
- /* next, alter that decision by map flags */
- if (mf->mf_mopts) {
- mntent_t mnt;
- mnt.mnt_opts = mf->mf_mopts;
-
- /* umount option: user wants to unmount this entry */
- if (amu_hasmntopt(&mnt, "unmount") || amu_hasmntopt(&mnt, "umount"))
- notimeout = 0;
- /* noumount option: user does NOT want to unmount this entry */
- if (amu_hasmntopt(&mnt, "nounmount") || amu_hasmntopt(&mnt, "noumount"))
- notimeout = 1;
- /* utimeout=N option: user wants to unmount this option AND set timeout */
- if ((mp->am_timeo = hasmntval(&mnt, "utimeout")) == 0)
- mp->am_timeo = gopt.am_timeo; /* otherwise use default timeout */
- else
- notimeout = 0;
- /* special case: don't try to unmount "/" (it can never succeed) */
- if (mf->mf_mount[0] == '/' && mf->mf_mount[1] == '\0')
- notimeout = 1;
- }
- /* finally set actual flags */
- if (notimeout) {
- mp->am_flags |= AMF_NOTIMEOUT;
- plog(XLOG_INFO, "%s set to never timeout", mp->am_path);
- } else {
- mp->am_flags &= ~AMF_NOTIMEOUT;
- plog(XLOG_INFO, "%s set to timeout in %d seconds", mp->am_path, mp->am_timeo);
- }
-
- /*
- * If this node is a symlink then
- * compute the length of the returned string.
- */
- if (mp->am_fattr.na_type == NFLNK)
- mp->am_fattr.na_size = strlen(mp->am_link ? mp->am_link : mf->mf_mount);
-
- /*
- * Record mount time, and update am_stats at the same time.
- */
- mp->am_stats.s_mtime = clocktime(&mp->am_fattr.na_mtime);
- new_ttl(mp);
-
- /*
- * Update mtime of parent node (copying "struct nfstime" in '=' below)
- */
- if (mp->am_parent && mp->am_parent->am_mnt)
- mp->am_parent->am_fattr.na_mtime = mp->am_fattr.na_mtime;
-
- /*
- * This is ugly, but essentially unavoidable
- * Sublinks must be treated separately as type==link
- * when the base type is different.
- */
- if (mp->am_link && mf->mf_ops != &amfs_link_ops)
- amfs_link_ops.mount_fs(mp, mf);
-
- /*
- * Now, if we can, do a reply to our client here
- * to speed things up.
- */
-#ifdef HAVE_FS_AUTOFS
- if (mp->am_flags & AMF_AUTOFS)
- autofs_mount_succeeded(mp);
- else
-#endif /* HAVE_FS_AUTOFS */
- nfs_quick_reply(mp, 0);
-
- /*
- * Update stats
- */
- amd_stats.d_mok++;
-}
-
-
-/*
- * Replace mount point with a reference to an error filesystem.
- * The mount point (struct mntfs) is NOT discarded,
- * the caller must do it if it wants to _before_ calling this function.
- */
-void
-assign_error_mntfs(am_node *mp)
-{
- int error;
- dlog("assign_error_mntfs");
- /*
- * Save the old error code
- */
- error = mp->am_error;
- if (error <= 0)
- error = mp->am_mnt->mf_error;
- /*
- * Allocate a new error reference
- */
- mp->am_mnt = new_mntfs();
- /*
- * Put back the error code
- */
- mp->am_mnt->mf_error = error;
- mp->am_mnt->mf_flags |= MFF_ERROR;
- /*
- * Zero the error in the mount point
- */
- mp->am_error = 0;
-}
-
-
-/*
- * Build a new map cache for this node, or re-use
- * an existing cache for the same map.
- */
-void
-amfs_mkcacheref(mntfs *mf)
-{
- char *cache;
-
- if (mf->mf_fo && mf->mf_fo->opt_cache)
- cache = mf->mf_fo->opt_cache;
- else
- cache = "none";
- mf->mf_private = (opaque_t) mapc_find(mf->mf_info,
- cache,
- (mf->mf_fo ? mf->mf_fo->opt_maptype : NULL));
- mf->mf_prfree = mapc_free;
-}
-
-
-/*
- * Locate next node in sibling list which is mounted
- * and is not an error node.
- */
-am_node *
-next_nonerror_node(am_node *xp)
-{
- mntfs *mf;
-
- /*
- * Bug report (7/12/89) from Rein Tollevik <rein@ifi.uio.no>
- * Fixes a race condition when mounting direct automounts.
- * Also fixes a problem when doing a readdir on a directory
- * containing hung automounts.
- */
- while (xp &&
- (!(mf = xp->am_mnt) || /* No mounted filesystem */
- mf->mf_error != 0 || /* There was a mntfs error */
- xp->am_error != 0 || /* There was a mount error */
- !(mf->mf_flags & MFF_MOUNTED) || /* The fs is not mounted */
- (mf->mf_server->fs_flags & FSF_DOWN)) /* The fs may be down */
- )
- xp = xp->am_osib;
-
- return xp;
-}
-
-
-/*
- * Mount an automounter directory.
- * The automounter is connected into the system
- * as a user-level NFS server. amfs_mount constructs
- * the necessary NFS parameters to be given to the
- * kernel so that it will talk back to us.
- *
- * NOTE: automounter mounts in themselves are using NFS Version 2 (UDP).
- *
- * NEW: on certain systems, mounting can be done using the
- * kernel-level automount (autofs) support. In that case,
- * we don't need NFS at all here.
- */
-int
-amfs_mount(am_node *mp, mntfs *mf, char *opts)
-{
- char fs_hostname[MAXHOSTNAMELEN + MAXPATHLEN + 1];
- int retry, error = 0, genflags;
- int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
- char *dir = mf->mf_mount;
- mntent_t mnt;
- MTYPE_TYPE type;
- int forced_unmount = 0; /* are we using forced unmounts? */
-
- memset((voidp) &mnt, 0, sizeof(mnt));
- mnt.mnt_dir = dir;
- mnt.mnt_fsname = pid_fsname;
- mnt.mnt_opts = opts;
-
-#ifdef HAVE_FS_AUTOFS
- if (mf->mf_flags & MFF_IS_AUTOFS) {
- type = MOUNT_TYPE_AUTOFS;
- /*
- * Make sure that amd's top-level autofs mounts are hidden by default
- * from df.
- * XXX: It works ok on Linux, might not work on other systems.
- */
- mnt.mnt_type = "autofs";
- } else
-#endif /* HAVE_FS_AUTOFS */
- {
- type = MOUNT_TYPE_NFS;
- /*
- * Make sure that amd's top-level NFS mounts are hidden by default
- * from df.
- * If they don't appear to support the either the "ignore" mnttab
- * option entry, or the "auto" one, set the mount type to "nfs".
- */
- mnt.mnt_type = HIDE_MOUNT_TYPE;
- }
-
- retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
- if (retry <= 0)
- retry = 2; /* XXX: default to 2 retries */
-
- /*
- * SET MOUNT ARGS
- */
-
- /*
- * Make a ``hostname'' string for the kernel
- */
- xsnprintf(fs_hostname, sizeof(fs_hostname), "pid%ld@%s:%s",
- get_server_pid(), am_get_hostname(), dir);
- /*
- * Most kernels have a name length restriction (64 bytes)...
- */
- if (strlen(fs_hostname) >= MAXHOSTNAMELEN)
- xstrlcpy(fs_hostname + MAXHOSTNAMELEN - 3, "..",
- sizeof(fs_hostname) - MAXHOSTNAMELEN + 3);
-#ifdef HOSTNAMESZ
- /*
- * ... and some of these restrictions are 32 bytes (HOSTNAMESZ)
- * If you need to get the definition for HOSTNAMESZ found, you may
- * add the proper header file to the conf/nfs_prot/nfs_prot_*.h file.
- */
- if (strlen(fs_hostname) >= HOSTNAMESZ)
- xstrlcpy(fs_hostname + HOSTNAMESZ - 3, "..",
- sizeof(fs_hostname) - HOSTNAMESZ + 3);
-#endif /* HOSTNAMESZ */
-
- /*
- * Finally we can compute the mount genflags set above,
- * and add any automounter specific flags.
- */
- genflags = compute_mount_flags(&mnt);
-#ifdef HAVE_FS_AUTOFS
- if (on_autofs)
- genflags |= autofs_compute_mount_flags(&mnt);
-#endif /* HAVE_FS_AUTOFS */
- genflags |= compute_automounter_mount_flags(&mnt);
-
-again:
- if (!(mf->mf_flags & MFF_IS_AUTOFS)) {
- nfs_args_t nfs_args;
- am_nfs_fh *fhp;
- am_nfs_handle_t anh;
-#ifndef HAVE_TRANSPORT_TYPE_TLI
- u_short port;
- struct sockaddr_in sin;
-#endif /* not HAVE_TRANSPORT_TYPE_TLI */
-
- /*
- * get fhandle of remote path for automount point
- */
- fhp = get_root_nfs_fh(dir);
- if (!fhp) {
- plog(XLOG_FATAL, "Can't find root file handle for %s", dir);
- return EINVAL;
- }
-
-#ifndef HAVE_TRANSPORT_TYPE_TLI
- /*
- * Create sockaddr to point to the local machine.
- */
- memset((voidp) &sin, 0, sizeof(sin));
- /* as per POSIX, sin_len need not be set (used internally by kernel) */
- sin.sin_family = AF_INET;
- sin.sin_addr = myipaddr;
- port = hasmntval(&mnt, MNTTAB_OPT_PORT);
- if (port) {
- sin.sin_port = htons(port);
- } else {
- plog(XLOG_ERROR, "no port number specified for %s", dir);
- return EINVAL;
- }
-#endif /* not HAVE_TRANSPORT_TYPE_TLI */
-
- /* setup the many fields and flags within nfs_args */
- memmove(&anh.v2, fhp, sizeof(*fhp));
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- compute_nfs_args(&nfs_args,
- &mnt,
- genflags,
- nfsncp,
- NULL, /* remote host IP addr is set below */
- NFS_VERSION, /* version 2 */
- "udp",
- &anh,
- fs_hostname,
- pid_fsname);
- /*
- * IMPORTANT: set the correct IP address AFTERWARDS. It cannot
- * be done using the normal mechanism of compute_nfs_args(), because
- * that one will allocate a new address and use NFS_SA_DREF() to copy
- * parts to it, while assuming that the ip_addr passed is always
- * a "struct sockaddr_in". That assumption is incorrect on TLI systems,
- * because they define a special macro HOST_SELF which is DIFFERENT
- * than localhost (127.0.0.1)!
- */
- nfs_args.addr = &nfsxprt->xp_ltaddr;
-#else /* not HAVE_TRANSPORT_TYPE_TLI */
- compute_nfs_args(&nfs_args,
- &mnt,
- genflags,
- NULL,
- &sin,
- NFS_VERSION, /* version 2 */
- "udp",
- &anh,
- fs_hostname,
- pid_fsname);
-#endif /* not HAVE_TRANSPORT_TYPE_TLI */
-
- /*************************************************************************
- * NOTE: while compute_nfs_args() works ok for regular NFS mounts *
- * the toplvl one is not quite regular, and so some options must be *
- * corrected by hand more carefully, *after* compute_nfs_args() runs. *
- *************************************************************************/
- compute_automounter_nfs_args(&nfs_args, &mnt);
-
- if (amuDebug(D_TRACE)) {
- print_nfs_args(&nfs_args, 0);
- plog(XLOG_DEBUG, "Generic mount flags 0x%x", genflags);
- }
-
- /* This is it! Here we try to mount amd on its mount points */
- error = mount_fs(&mnt, genflags, (caddr_t) &nfs_args,
- retry, type, 0, NULL, mnttab_file_name, on_autofs);
-
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- free_knetconfig(nfs_args.knconf);
- /*
- * local automounter mounts do not allocate a special address, so
- * no need to XFREE(nfs_args.addr) under TLI.
- */
-#endif /* HAVE_TRANSPORT_TYPE_TLI */
-
-#ifdef HAVE_FS_AUTOFS
- } else {
- /* This is it! Here we try to mount amd on its mount points */
- error = mount_fs(&mnt, genflags, (caddr_t) mp->am_autofs_fh,
- retry, type, 0, NULL, mnttab_file_name, on_autofs);
-#endif /* HAVE_FS_AUTOFS */
- }
- if (error == 0 || forced_unmount)
- return error;
-
- /*
- * If user wants forced/lazy unmount semantics, then try it iff the
- * current mount failed with EIO or ESTALE.
- */
- if (gopt.flags & CFM_FORCED_UNMOUNTS) {
- switch (errno) {
- case ESTALE:
- case EIO:
- forced_unmount = errno;
- plog(XLOG_WARNING, "Mount %s failed (%m); force unmount.", mp->am_path);
- if ((error = UMOUNT_FS(mp->am_path, mnttab_file_name,
- AMU_UMOUNT_FORCE | AMU_UMOUNT_DETACH)) < 0) {
- plog(XLOG_WARNING, "Forced umount %s failed: %m.", mp->am_path);
- errno = forced_unmount;
- } else
- goto again;
- default:
- break;
- }
- }
-
- return error;
-}
-
-
-void
-am_unmounted(am_node *mp)
-{
- mntfs *mf = mp->am_mnt;
-
- if (!foreground) /* firewall - should never happen */
- return;
-
- /*
- * Do unmounted callback
- */
- if (mf->mf_ops->umounted)
- mf->mf_ops->umounted(mf);
-
- /*
- * This is ugly, but essentially unavoidable.
- * Sublinks must be treated separately as type==link
- * when the base type is different.
- */
- if (mp->am_link && mf->mf_ops != &amfs_link_ops)
- amfs_link_ops.umount_fs(mp, mf);
-
-#ifdef HAVE_FS_AUTOFS
- if (mf->mf_flags & MFF_IS_AUTOFS)
- autofs_release_fh(mp);
- if (mp->am_flags & AMF_AUTOFS)
- autofs_umount_succeeded(mp);
-#endif /* HAVE_FS_AUTOFS */
-
- /*
- * Clean up any directories that were made
- *
- * If we remove the mount point of a pending mount, any queued access
- * to it will fail. So don't do it in that case.
- * Also don't do it if the refcount is > 1.
- */
- if (mf->mf_flags & MFF_MKMNT &&
- mf->mf_refc == 1 &&
- !(mp->am_flags & AMF_REMOUNT)) {
- plog(XLOG_INFO, "removing mountpoint directory '%s'", mf->mf_mount);
- rmdirs(mf->mf_mount);
- mf->mf_flags &= ~MFF_MKMNT;
- }
-
- /*
- * If this is a pseudo-directory then adjust the link count
- * in the parent
- */
- if (mp->am_parent && mp->am_fattr.na_type == NFDIR)
- --mp->am_parent->am_fattr.na_nlink;
-
- /*
- * Update mtime of parent node
- */
- if (mp->am_parent && mp->am_parent->am_mnt)
- clocktime(&mp->am_parent->am_fattr.na_mtime);
-
- if (mp->am_parent && (mp->am_flags & AMF_REMOUNT)) {
- char *fname = strdup(mp->am_name);
- am_node *mp_parent = mp->am_parent;
- mntfs *mf_parent = mp_parent->am_mnt;
- int error = 0;
-
- free_map(mp);
- plog(XLOG_INFO, "am_unmounted: remounting %s", fname);
- mp = mf_parent->mf_ops->lookup_child(mp_parent, fname, &error, VLOOK_CREATE);
- if (mp && error < 0)
- mp = mf_parent->mf_ops->mount_child(mp, &error);
- if (error > 0) {
- errno = error;
- plog(XLOG_ERROR, "am_unmounted: could not remount %s: %m", fname);
- }
- XFREE(fname);
- } else
- /*
- * We have a race here.
- * If this node has a pending mount and amd is going down (unmounting
- * everything in the process), then we could potentially free it here
- * while a struct continuation still has a reference to it. So when
- * amfs_cont is called, it blows up.
- * We avoid the race by refusing to free any nodes that have
- * pending mounts (defined as having a non-NULL am_mfarray).
- */
- if (!mp->am_mfarray)
- free_map(mp);
-}
-
-
-/*
- * Fork the automounter
- *
- * TODO: Need a better strategy for handling errors
- */
-static int
-dofork(void)
-{
- int pid;
-
-top:
- pid = fork();
-
- if (pid < 0) { /* fork error, retry in 1 second */
- sleep(1);
- goto top;
- }
- if (pid == 0) { /* child process (foreground==false) */
- am_set_mypid();
- foreground = 0;
- } else { /* parent process, has one more child */
- NumChildren++;
- }
-
- return pid;
-}
-
-
-int
-background(void)
-{
- int pid = dofork();
-
- if (pid == 0) {
- dlog("backgrounded");
- foreground = 0;
- } else
- dlog("forked process %d", pid);
- return pid;
-}
diff --git a/contrib/amd/amd/clock.c b/contrib/amd/amd/clock.c
deleted file mode 100644
index 0caa7dff2c73..000000000000
--- a/contrib/amd/amd/clock.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/clock.c
- *
- */
-
-/*
- * Callouts.
- *
- * Modeled on kernel object of the same name.
- * See usual references.
- *
- * Use of a heap-based mechanism was rejected:
- * 1. more complex implementation needed.
- * 2. not obvious that a list is too slow for Amd.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-void reschedule_timeouts(time_t now, time_t then);
-
-typedef struct callout callout;
-struct callout {
- callout *c_next; /* List of callouts */
- callout_fun *c_fn; /* Function to call */
- opaque_t c_arg; /* Argument to pass to call */
- time_t c_time; /* Time of call */
- int c_id; /* Unique identifier */
-};
-
-static callout callouts; /* List of pending callouts */
-static callout *free_callouts; /* Cache of free callouts */
-static int nfree_callouts; /* Number on free list */
-static int callout_id; /* Next free callout identifier */
-
-time_t next_softclock; /* Time of next call to softclock() */
-
-
-/*
- * Number of callout slots we keep on the free list
- */
-#define CALLOUT_FREE_SLOP 10
-
-/*
- * Global assumption: valid id's are non-zero.
- */
-#define CID_ALLOC() (++callout_id)
-#define CID_UNDEF (0)
-
-
-static callout *
-alloc_callout(void)
-{
- callout *cp = free_callouts;
-
- if (cp) {
- --nfree_callouts;
- free_callouts = free_callouts->c_next;
- return cp;
- }
- return ALLOC(struct callout);
-}
-
-
-static void
-free_callout(callout *cp)
-{
- if (nfree_callouts > CALLOUT_FREE_SLOP) {
- XFREE(cp);
- } else {
- cp->c_next = free_callouts;
- free_callouts = cp;
- nfree_callouts++;
- }
-}
-
-
-/*
- * Schedule a callout.
- *
- * (*fn)(fn_arg) will be called at clocktime(NULL) + secs
- */
-int
-timeout(u_int secs, callout_fun *fn, opaque_t fn_arg)
-{
- callout *cp, *cp2;
- time_t t = clocktime(NULL) + secs;
-
- /*
- * Allocate and fill in a new callout structure
- */
- callout *cpnew = alloc_callout();
- cpnew->c_arg = fn_arg;
- cpnew->c_fn = fn;
- cpnew->c_time = t;
- cpnew->c_id = CID_ALLOC();
-
- if (t < next_softclock)
- next_softclock = t;
-
- /*
- * Find the correct place in the list
- */
- for (cp = &callouts; (cp2 = cp->c_next); cp = cp2)
- if (cp2->c_time >= t)
- break;
-
- /*
- * And link it in
- */
- cp->c_next = cpnew;
- cpnew->c_next = cp2;
-
- /*
- * Return callout identifier
- */
- return cpnew->c_id;
-}
-
-
-/*
- * De-schedule a callout
- */
-void
-untimeout(int id)
-{
- callout *cp, *cp2;
- for (cp = &callouts; (cp2 = cp->c_next); cp = cp2) {
- if (cp2->c_id == id) {
- cp->c_next = cp2->c_next;
- free_callout(cp2);
- break;
- }
- }
-}
-
-
-/*
- * Reschedule after clock changed
- */
-void
-reschedule_timeouts(time_t now, time_t then)
-{
- callout *cp;
-
- for (cp = callouts.c_next; cp; cp = cp->c_next) {
- if (cp->c_time >= now && cp->c_time <= then) {
- plog(XLOG_WARNING, "job %d rescheduled to run immediately", cp->c_id);
- dlog("rescheduling job %d back %ld seconds",
- cp->c_id, (long) (cp->c_time - now));
- next_softclock = cp->c_time = now;
- }
- }
-}
-
-
-/*
- * Clock handler
- */
-int
-softclock(void)
-{
- time_t now;
- callout *cp;
-
- do {
- if (task_notify_todo)
- do_task_notify();
-
- now = clocktime(NULL);
-
- /*
- * While there are more callouts waiting...
- */
- while ((cp = callouts.c_next) && cp->c_time <= now) {
- /*
- * Extract first from list, save fn & fn_arg and
- * unlink callout from list and free.
- * Finally call function.
- *
- * The free is done first because
- * it is quite common that the
- * function will call timeout()
- * and try to allocate a callout
- */
- callout_fun *fn = cp->c_fn;
- opaque_t fn_arg = cp->c_arg;
-
- callouts.c_next = cp->c_next;
- free_callout(cp);
- (*fn) (fn_arg);
- }
-
- } while (task_notify_todo);
-
- /*
- * Return number of seconds to next event,
- * or 0 if there is no event.
- */
- if ((cp = callouts.c_next))
- return cp->c_time - now;
- return 0;
-}
diff --git a/contrib/amd/amd/conf.c b/contrib/amd/amd/conf.c
deleted file mode 100644
index 2fc587b0cadb..000000000000
--- a/contrib/amd/amd/conf.c
+++ /dev/null
@@ -1,1406 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/conf.c
- *
- */
-
-/*
- * Functions to handle the configuration file.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-
-/*
- * MACROS:
- */
-/* Turn on to show some info about maps being configured */
-/* #define DEBUG_CONF */
-
-/*
- * TYPEDEFS:
- */
-typedef int (*OptFuncPtr)(const char *);
-
-/*
- * STRUCTURES:
- */
-struct _func_map {
- char *name;
- OptFuncPtr func;
-};
-
-/*
- * FORWARD DECLARATIONS:
- */
-static int gopt_arch(const char *val);
-static int gopt_auto_attrcache(const char *val);
-static int gopt_auto_dir(const char *val);
-static int gopt_autofs_use_lofs(const char *val);
-static int gopt_browsable_dirs(const char *val);
-static int gopt_cache_duration(const char *val);
-static int gopt_cluster(const char *val);
-static int gopt_debug_mtab_file(const char *val);
-static int gopt_debug_options(const char *val);
-static int gopt_dismount_interval(const char *val);
-static int gopt_domain_strip(const char *val);
-static int gopt_exec_map_timeout(const char *val);
-static int gopt_forced_unmounts(const char *val);
-static int gopt_full_os(const char *val);
-static int gopt_fully_qualified_hosts(const char *val);
-static int gopt_hesiod_base(const char *val);
-static int gopt_karch(const char *val);
-static int gopt_ldap_base(const char *val);
-static int gopt_ldap_cache_maxmem(const char *val);
-static int gopt_ldap_cache_seconds(const char *val);
-static int gopt_ldap_hostports(const char *val);
-static int gopt_ldap_proto_version(const char *val);
-static int gopt_local_domain(const char *val);
-static int gopt_localhost_address(const char *val);
-static int gopt_log_file(const char *val);
-static int gopt_log_options(const char *val);
-static int gopt_map_defaults(const char *val);
-static int gopt_map_options(const char *val);
-static int gopt_map_reload_interval(const char *val);
-static int gopt_map_type(const char *val);
-static int gopt_mount_type(const char *val);
-static int gopt_pid_file(const char *val);
-static int gopt_portmap_program(const char *val);
-static int gopt_preferred_amq_port(const char *val);
-static int gopt_nfs_allow_any_interface(const char *val);
-static int gopt_nfs_allow_insecure_port(const char *val);
-static int gopt_nfs_proto(const char *val);
-static int gopt_nfs_retransmit_counter(const char *val);
-static int gopt_nfs_retransmit_counter_udp(const char *val);
-static int gopt_nfs_retransmit_counter_tcp(const char *val);
-static int gopt_nfs_retransmit_counter_toplvl(const char *val);
-static int gopt_nfs_retry_interval(const char *val);
-static int gopt_nfs_retry_interval_udp(const char *val);
-static int gopt_nfs_retry_interval_tcp(const char *val);
-static int gopt_nfs_retry_interval_toplvl(const char *val);
-static int gopt_nfs_vers(const char *val);
-static int gopt_nis_domain(const char *val);
-static int gopt_normalize_hostnames(const char *val);
-static int gopt_normalize_slashes(const char *val);
-static int gopt_os(const char *val);
-static int gopt_osver(const char *val);
-static int gopt_plock(const char *val);
-static int gopt_print_pid(const char *val);
-static int gopt_print_version(const char *val);
-static int gopt_restart_mounts(const char *val);
-static int gopt_search_path(const char *val);
-static int gopt_selectors_in_defaults(const char *val);
-static int gopt_show_statfs_entries(const char *val);
-static int gopt_truncate_log(const char *val);
-static int gopt_unmount_on_exit(const char *val);
-static int gopt_use_tcpwrappers(const char *val);
-static int gopt_vendor(const char *val);
-static int process_global_option(const char *key, const char *val);
-static int process_one_regular_map(const cf_map_t *cfm);
-static int process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm);
-static int ropt_browsable_dirs(const char *val, cf_map_t *cfm);
-static int ropt_map_name(const char *val, cf_map_t *cfm);
-static int ropt_map_defaults(const char *val, cf_map_t *cfm);
-static int ropt_map_options(const char *val, cf_map_t *cfm);
-static int ropt_map_type(const char *val, cf_map_t *cfm);
-static int ropt_mount_type(const char *val, cf_map_t *cfm);
-static int ropt_search_path(const char *val, cf_map_t *cfm);
-static int ropt_tag(const char *val, cf_map_t *cfm);
-static void init_cf_map(cf_map_t *cfm);
-
-
-/*
- * STATIC VARIABLES:
- */
-static cf_map_t *head_map, *cur_map;
-
-static struct _func_map glob_functable[] = {
- {"arch", gopt_arch},
- {"auto_attrcache", gopt_auto_attrcache},
- {"auto_dir", gopt_auto_dir},
- {"autofs_use_lofs", gopt_autofs_use_lofs},
- {"browsable_dirs", gopt_browsable_dirs},
- {"cache_duration", gopt_cache_duration},
- {"cluster", gopt_cluster},
- {"debug_mtab_file", gopt_debug_mtab_file},
- {"debug_options", gopt_debug_options},
- {"dismount_interval", gopt_dismount_interval},
- {"domain_strip", gopt_domain_strip},
- {"exec_map_timeout", gopt_exec_map_timeout},
- {"forced_unmounts", gopt_forced_unmounts},
- {"fully_qualified_hosts", gopt_fully_qualified_hosts},
- {"full_os", gopt_full_os},
- {"hesiod_base", gopt_hesiod_base},
- {"karch", gopt_karch},
- {"ldap_base", gopt_ldap_base},
- {"ldap_cache_maxmem", gopt_ldap_cache_maxmem},
- {"ldap_cache_seconds", gopt_ldap_cache_seconds},
- {"ldap_hostports", gopt_ldap_hostports},
- {"ldap_proto_version", gopt_ldap_proto_version},
- {"local_domain", gopt_local_domain},
- {"localhost_address", gopt_localhost_address},
- {"log_file", gopt_log_file},
- {"log_options", gopt_log_options},
- {"map_defaults", gopt_map_defaults},
- {"map_options", gopt_map_options},
- {"map_reload_interval", gopt_map_reload_interval},
- {"map_type", gopt_map_type},
- {"mount_type", gopt_mount_type},
- {"pid_file", gopt_pid_file},
- {"portmap_program", gopt_portmap_program},
- {"preferred_amq_port", gopt_preferred_amq_port},
- {"nfs_allow_any_interface", gopt_nfs_allow_any_interface},
- {"nfs_allow_insecure_port", gopt_nfs_allow_insecure_port},
- {"nfs_proto", gopt_nfs_proto},
- {"nfs_retransmit_counter", gopt_nfs_retransmit_counter},
- {"nfs_retransmit_counter_udp", gopt_nfs_retransmit_counter_udp},
- {"nfs_retransmit_counter_tcp", gopt_nfs_retransmit_counter_tcp},
- {"nfs_retransmit_counter_toplvl", gopt_nfs_retransmit_counter_toplvl},
- {"nfs_retry_interval", gopt_nfs_retry_interval},
- {"nfs_retry_interval_udp", gopt_nfs_retry_interval_udp},
- {"nfs_retry_interval_tcp", gopt_nfs_retry_interval_tcp},
- {"nfs_retry_interval_toplvl", gopt_nfs_retry_interval_toplvl},
- {"nfs_vers", gopt_nfs_vers},
- {"nis_domain", gopt_nis_domain},
- {"normalize_hostnames", gopt_normalize_hostnames},
- {"normalize_slashes", gopt_normalize_slashes},
- {"os", gopt_os},
- {"osver", gopt_osver},
- {"plock", gopt_plock},
- {"print_pid", gopt_print_pid},
- {"print_version", gopt_print_version},
- {"restart_mounts", gopt_restart_mounts},
- {"search_path", gopt_search_path},
- {"selectors_on_default", gopt_selectors_in_defaults},
- {"selectors_in_defaults", gopt_selectors_in_defaults},
- {"show_statfs_entries", gopt_show_statfs_entries},
- {"truncate_log", gopt_truncate_log},
- {"unmount_on_exit", gopt_unmount_on_exit},
- {"use_tcpwrappers", gopt_use_tcpwrappers},
- {"vendor", gopt_vendor},
- {NULL, NULL}
-};
-
-
-/*
- * Initialize a map from [global] defaults.
- */
-static void
-init_cf_map(cf_map_t *cfm)
-{
- if (!cfm)
- return;
-
- /*
- * Initialize a regular map's flags and other variables from the
- * global ones, so that they are applied to all maps. Of course, each map
- * can then override the flags individually.
- *
- * NOTES:
- * (1): Will only work for maps that appear after [global].
- * (2): I'm assigning pointers directly from the global map.
- */
-
- /* initialize map_type from [global] */
- cfm->cfm_type = gopt.map_type;
-
- /* initialize map_defaults from [global] */
- cfm->cfm_defaults = gopt.map_defaults;
-
- /* initialize map_opts from [global] */
- cfm->cfm_opts = gopt.map_options;
-
- /* initialize search_path from [global] */
- cfm->cfm_search_path = gopt.search_path;
-
- /*
- * Initialize flags that are common both to [global] and a local map.
- */
- cfm->cfm_flags = gopt.flags & (CFM_BROWSABLE_DIRS |
- CFM_BROWSABLE_DIRS_FULL |
- CFM_MOUNT_TYPE_AUTOFS |
- CFM_SELECTORS_IN_DEFAULTS);
-}
-
-
-/*
- * Process configuration file options (called from YACC parser).
- * Return 0 if OK, 1 otherwise.
- */
-int
-set_conf_kv(const char *section, const char *key, const char *val)
-{
- int ret;
-
-#ifdef DEBUG_CONF
- fprintf(stderr, "set_conf_kv: section=%s, key=%s, val=%s\n",
- section, key, val);
-#endif /* DEBUG_CONF */
-
- /*
- * If global section, process kv pairs one at a time.
- */
- if (STREQ(section, "global")) {
- /*
- * Check if a regular map was configured before "global",
- * and warn about it.
- */
- if (cur_map && cur_map->cfm_dir) {
- static short printed_this_error;
- if (!printed_this_error) {
- fprintf(stderr, "found regular map \"%s\" before global one.\n",
- cur_map->cfm_dir);
- printed_this_error = 1;
- }
- }
-
- /* process the global option first */
- ret = process_global_option(key, val);
-
- /* return status from the processing of the global option */
- return ret;
- }
-
- /*
- * Otherwise we found a non-global option: store it after some testing.
- */
-
- /* initialize (static) global list head and current map pointer */
- if (!head_map && !cur_map) {
- cur_map = CALLOC(cf_map_t);
- if (!cur_map) {
- perror("calloc");
- exit(1);
- }
- /* initialize first head map from global defaults */
- init_cf_map(cur_map);
- head_map = cur_map;
- }
-
- /* check if we found a new map, then allocate and initialize it */
- if (cur_map->cfm_dir && !STREQ(cur_map->cfm_dir, section)) {
- /* allocate new map struct */
- cf_map_t *tmp_map = CALLOC(cf_map_t);
- if (!tmp_map) {
- perror("calloc");
- exit(1);
- }
- /* initialize it from global defaults */
- init_cf_map(tmp_map);
- /* append it to end of linked list */
- cur_map->cfm_next = tmp_map;
- cur_map = tmp_map;
- }
-
- /* now process a single entry of a regular map */
- return process_regular_option(section, key, val, cur_map);
-}
-
-
-/*
- * Process global section of configuration file options.
- * Return 0 upon success, 1 otherwise.
- */
-static int
-process_global_option(const char *key, const char *val)
-{
- struct _func_map *gfp;
-
- /* ensure that val is valid */
- if (!val || val[0] == '\0')
- return 1;
-
- /*
- * search for global function.
- */
- for (gfp = glob_functable; gfp->name; gfp++)
- if (FSTREQ(gfp->name, key))
- return (gfp->func)(val);
-
- fprintf(stderr, "conf: unknown global key: \"%s\"\n", key);
- return 1; /* failed to match any command */
-}
-
-
-static int
-gopt_arch(const char *val)
-{
- gopt.arch = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_auto_attrcache(const char *val)
-{
- gopt.auto_attrcache = atoi(val);
- if (gopt.auto_attrcache < 0) {
- fprintf(stderr, "conf: bad attrcache value: \"%s\"\n", val);
- return 1;
- }
- return 0;
-}
-
-
-static int
-gopt_auto_dir(const char *val)
-{
- gopt.auto_dir = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_autofs_use_lofs(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_AUTOFS_USE_LOFS;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_AUTOFS_USE_LOFS;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to autofs_use_lofs \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_browsable_dirs(const char *val)
-{
- if (STREQ(val, "full")) {
- gopt.flags |= CFM_BROWSABLE_DIRS_FULL;
- return 0;
- } else if (STREQ(val, "yes")) {
- gopt.flags |= CFM_BROWSABLE_DIRS;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_BROWSABLE_DIRS;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_cache_duration(const char *val)
-{
- gopt.am_timeo = atoi(val);
- if (gopt.am_timeo <= 0)
- gopt.am_timeo = AM_TTL;
- return 0;
-}
-
-
-static int
-gopt_cluster(const char *val)
-{
- gopt.cluster = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_debug_mtab_file(const char *val)
-{
- gopt.debug_mtab_file = strdup((char*)val);
- return 0;
-}
-
-
-static int
-gopt_debug_options(const char *val)
-{
-#ifdef DEBUG
- usage += debug_option((char *)val);
- return 0;
-#else /* not DEBUG */
- fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n",
- am_get_progname());
- return 1;
-#endif /* not DEBUG */
-}
-
-
-static int
-gopt_dismount_interval(const char *val)
-{
- gopt.am_timeo_w = atoi(val);
- if (gopt.am_timeo_w <= 0)
- gopt.am_timeo_w = AM_TTL_W;
- return 0;
-}
-
-
-static int
-gopt_domain_strip(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_DOMAIN_STRIP;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_DOMAIN_STRIP;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to domain_strip \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_exec_map_timeout(const char *val)
-{
- gopt.exec_map_timeout = atoi(val);
- if (gopt.exec_map_timeout <= 0)
- gopt.exec_map_timeout = AMFS_EXEC_MAP_TIMEOUT; /* default exec map timeout */
- return 0;
-}
-
-
-static int
-gopt_forced_unmounts(const char *val)
-{
- if (STREQ(val, "yes")) {
-#if !defined(MNT2_GEN_OPT_DETACH) && !defined(MNT2_GEN_OPT_FORCE)
- fprintf(stderr, "conf: forced_unmounts unsupported on this system.\n");
- return 1;
-#else /* defined(MNT2_GEN_OPT_DETACH) || defined(MNT2_GEN_OPT_FORCE) */
-# ifdef __linux__
- /*
- * HACK ALERT: Linux has had MNT_FORCE since 2.2, but it hasn't gotten
- * stable until 2.4. And it had MNT_DETACH since 2.4, but it hasn't
- * gotten stable since 2.6. So alert users if they're trying to use a
- * feature that may not work well on their older kernel.
- */
- {
- struct utsname un;
- if (uname(&un) >= 0) {
-# ifdef MNT2_GEN_OPT_FORCE
- if (strcmp(un.release, "2.4.0") < 0)
- fprintf(stderr, "warning: forced-unmounts (MNT_FORCE) may not work well before 2.4.0\n");
-# endif /* MNT2_GEN_OPT_FORCE */
-# ifdef MNT2_GEN_OPT_DETACH
- if (strcmp(un.release, "2.6.0") < 0)
- fprintf(stderr, "warning: lazy-unmounts (MNT_DETACH) may not work well before 2.6.0\n");
-# endif /* MNT2_GEN_OPT_DETACH */
- }
- }
-# endif /* __linux__ */
- gopt.flags |= CFM_FORCED_UNMOUNTS;
- return 0;
-#endif /* defined(MNT2_GEN_OPT_DETACH) || defined(MNT2_GEN_OPT_FORCE) */
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_FORCED_UNMOUNTS;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to unmount_on_exit \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_full_os(const char *val)
-{
- gopt.op_sys_full = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_fully_qualified_hosts(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_FULLY_QUALIFIED_HOSTS;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_FULLY_QUALIFIED_HOSTS;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to fully_qualified_hosts \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_hesiod_base(const char *val)
-{
-#ifdef HAVE_MAP_HESIOD
- gopt.hesiod_base = strdup((char *)val);
- return 0;
-#else /* not HAVE_MAP_HESIOD */
- fprintf(stderr, "conf: hesiod_base option ignored. No Hesiod support available.\n");
- return 1;
-#endif /* not HAVE_MAP_HESIOD */
-}
-
-
-static int
-gopt_karch(const char *val)
-{
- gopt.karch = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_pid_file(const char *val)
-{
- gopt.pid_file = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_local_domain(const char *val)
-{
- gopt.sub_domain = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_localhost_address(const char *val)
-{
- gopt.localhost_address = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_ldap_base(const char *val)
-{
-#ifdef HAVE_MAP_LDAP
- gopt.ldap_base = strdup((char *)val);
- return 0;
-#else /* not HAVE_MAP_LDAP */
- fprintf(stderr, "conf: ldap_base option ignored. No LDAP support available.\n");
- return 1;
-#endif /* not HAVE_MAP_LDAP */
-}
-
-
-static int
-gopt_ldap_cache_seconds(const char *val)
-{
-#ifdef HAVE_MAP_LDAP
- char *end;
-
- gopt.ldap_cache_seconds = strtol((char *)val, &end, 10);
- if (end == val) {
- fprintf(stderr, "conf: bad LDAP cache (seconds) option: %s\n",val);
- return 1;
- }
- return 0;
-#else /* not HAVE_MAP_LDAP */
- fprintf(stderr, "conf: ldap_cache_seconds option ignored. No LDAP support available.\n");
- return 1;
-#endif /* not HAVE_MAP_LDAP */
-}
-
-
-static int
-gopt_ldap_cache_maxmem(const char *val)
-{
-#ifdef HAVE_MAP_LDAP
- char *end;
-
- gopt.ldap_cache_maxmem = strtol((char *)val, &end, 10);
- if (end == val) {
- fprintf(stderr, "conf: bad LDAP cache (maxmem) option: %s\n",val);
- return 1;
- }
- return 0;
-#else /* not HAVE_MAP_LDAP */
- fprintf(stderr, "conf: ldap_cache_maxmem option ignored. No LDAP support available.\n");
- return 1;
-#endif /* not HAVE_MAP_LDAP */
-}
-
-
-static int
-gopt_ldap_hostports(const char *val)
-{
-#ifdef HAVE_MAP_LDAP
- gopt.ldap_hostports = strdup((char *)val);
- return 0;
-#else /* not HAVE_MAP_LDAP */
- fprintf(stderr, "conf: ldap_hostports option ignored. No LDAP support available.\n");
- return 1;
-#endif /* not HAVE_MAP_LDAP */
-
-}
-
-
-static int
-gopt_ldap_proto_version(const char *val)
-{
-#ifdef HAVE_MAP_LDAP
- char *end;
-
- gopt.ldap_proto_version = strtol((char *)val, &end, 10);
- if (end == val) {
- fprintf(stderr, "conf: bad ldap_proto_version option: %s\n",val);
- return 1;
- }
-
- if (gopt.ldap_proto_version < 0 || gopt.ldap_proto_version > LDAP_VERSION_MAX) {
- fprintf(stderr, "conf: bad ldap_proto_version option value: %s\n",val);
- return 1;
- }
- switch (gopt.ldap_proto_version) {
- /* XXX: what about LDAP_VERSION1? */
- case LDAP_VERSION2:
-#ifdef LDAP_VERSION3
- case LDAP_VERSION3:
-#endif /* LDAP_VERSION3 */
-#ifdef LDAP_VERSION4
- case LDAP_VERSION4:
-#endif /* LDAP_VERSION4 */
- break;
- default:
- fprintf(stderr, "conf: unsupported ldap_proto_version option value: %s\n",val);
- return 1;
- }
- return 0;
-#else /* not HAVE_MAP_LDAP */
- fprintf(stderr, "conf: ldap_proto_version option ignored. No LDAP support available.\n");
- return 1;
-#endif /* not HAVE_MAP_LDAP */
-}
-
-
-static int
-gopt_log_file(const char *val)
-{
- gopt.logfile = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_log_options(const char *val)
-{
- usage += switch_option((char *)val);
- return 0;
-}
-
-
-static int
-gopt_map_defaults(const char *val)
-{
- gopt.map_defaults = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_map_options(const char *val)
-{
- gopt.map_options = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_map_reload_interval(const char *val)
-{
- gopt.map_reload_interval = atoi(val);
- if (gopt.map_reload_interval <= 0)
- gopt.map_reload_interval = ONE_HOUR;
- return 0;
-}
-
-
-static int
-gopt_map_type(const char *val)
-{
- /* check if map type exist */
- if (!mapc_type_exists(val)) {
- fprintf(stderr, "conf: no such map type \"%s\"\n", val);
- return 1;
- }
- gopt.map_type = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_mount_type(const char *val)
-{
- if (STREQ(val, "autofs")) {
-#ifdef HAVE_FS_AUTOFS
- gopt.flags |= CFM_MOUNT_TYPE_AUTOFS;
- amd_use_autofs++;
- return 0;
-#else /* not HAVE_FS_AUTOFS */
- fprintf(stderr, "conf: no autofs support available\n");
- return 1;
-#endif /* not HAVE_FS_AUTOFS */
- } else if (STREQ(val, "nfs")) {
- gopt.flags &= ~CFM_MOUNT_TYPE_AUTOFS;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_portmap_program(const char *val)
-{
- gopt.portmap_program = atol(val);
- /*
- * allow alternate program numbers to be no more than 10 offset from
- * official amd program number (300019).
- */
- if (gopt.portmap_program < AMQ_PROGRAM ||
- gopt.portmap_program > AMQ_PROGRAM + 10) {
- gopt.portmap_program = AMQ_PROGRAM;
- set_amd_program_number(gopt.portmap_program);
- fprintf(stderr, "conf: illegal amd program number \"%s\"\n", val);
- return 1;
- }
-
- set_amd_program_number(gopt.portmap_program);
- return 0; /* all is OK */
-}
-
-
-static int
-gopt_preferred_amq_port(const char *val)
-{
- gopt.preferred_amq_port = atoi(val);
-
- /*
- * No need to check value: preferred_amq_port is an unsigned short and 0
- * is a valid number, meaning "any port".
- */
- return 0; /* all is OK */
-}
-
-
-static int
-gopt_nfs_allow_any_interface(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_NFS_ANY_INTERFACE;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_NFS_ANY_INTERFACE;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to nfs_allow_insecure_port \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_nfs_allow_insecure_port(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_NFS_INSECURE_PORT;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_NFS_INSECURE_PORT;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to nfs_allow_insecure_port \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_nfs_proto(const char *val)
-{
- if (STREQ(val, "udp") || STREQ(val, "tcp")) {
- gopt.nfs_proto = strdup((char *)val);
- return 0;
- }
- fprintf(stderr, "conf: illegal nfs_proto \"%s\"\n", val);
- return 1;
-}
-
-
-static int
-gopt_nfs_retransmit_counter(const char *val)
-{
- int i;
-
- for (i=0; i<AMU_TYPE_MAX; ++i)
- gopt.amfs_auto_retrans[i] = atoi(val);
- return 0;
-}
-
-
-static int
-gopt_nfs_retransmit_counter_udp(const char *val)
-{
- gopt.amfs_auto_retrans[AMU_TYPE_UDP] = atoi(val);
- return 0;
-}
-
-
-static int
-gopt_nfs_retransmit_counter_tcp(const char *val)
-{
- gopt.amfs_auto_retrans[AMU_TYPE_TCP] = atoi(val);
- return 0;
-}
-
-
-static int
-gopt_nfs_retransmit_counter_toplvl(const char *val)
-{
- gopt.amfs_auto_retrans[AMU_TYPE_TOPLVL] = atoi(val);
- return 0;
-}
-
-
-static int
-gopt_nfs_retry_interval(const char *val)
-{
- int i;
-
- for (i=0; i<AMU_TYPE_MAX; ++i)
- gopt.amfs_auto_timeo[i] = atoi(val);
- return 0;
-}
-
-
-static int
-gopt_nfs_retry_interval_udp(const char *val)
-{
- gopt.amfs_auto_timeo[AMU_TYPE_UDP] = atoi(val);
- return 0;
-}
-
-
-static int
-gopt_nfs_retry_interval_tcp(const char *val)
-{
- gopt.amfs_auto_timeo[AMU_TYPE_TCP] = atoi(val);
- return 0;
-}
-
-
-static int
-gopt_nfs_retry_interval_toplvl(const char *val)
-{
- gopt.amfs_auto_timeo[AMU_TYPE_TOPLVL] = atoi(val);
- return 0;
-}
-
-
-static int
-gopt_nfs_vers(const char *val)
-{
- int i = atoi(val);
-
- if (i == 2 || i == 3) {
- gopt.nfs_vers = i;
- return 0;
- }
- fprintf(stderr, "conf: illegal nfs_vers \"%s\"\n", val);
- return 1;
-}
-
-
-static int
-gopt_nis_domain(const char *val)
-{
-#ifdef HAVE_MAP_NIS
- gopt.nis_domain = strdup((char *)val);
- return 0;
-#else /* not HAVE_MAP_NIS */
- fprintf(stderr, "conf: nis_domain option ignored. No NIS support available.\n");
- return 1;
-#endif /* not HAVE_MAP_NIS */
-}
-
-
-static int
-gopt_normalize_hostnames(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_NORMALIZE_HOSTNAMES;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_NORMALIZE_HOSTNAMES;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to normalize_hostnames \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_normalize_slashes(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_NORMALIZE_SLASHES;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_NORMALIZE_SLASHES;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to normalize_slashes \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_os(const char *val)
-{
- gopt.op_sys = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_osver(const char *val)
-{
- gopt.op_sys_ver = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_plock(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_PROCESS_LOCK;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_PROCESS_LOCK;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to plock \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_print_pid(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_PRINT_PID;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_PRINT_PID;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to print_pid \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_print_version(const char *val)
-{
- if (STREQ(val, "yes")) {
- char *vers = get_version_string();
- fputs(vers, stderr);
- XFREE(vers);
- return 0;
- } else if (STREQ(val, "no")) {
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to print_version \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_restart_mounts(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_RESTART_EXISTING_MOUNTS;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_RESTART_EXISTING_MOUNTS;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to restart_mounts \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_search_path(const char *val)
-{
- gopt.search_path = strdup((char *)val);
- return 0;
-}
-
-
-static int
-gopt_selectors_in_defaults(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_SELECTORS_IN_DEFAULTS;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_SELECTORS_IN_DEFAULTS;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to enable_default_selectors \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_show_statfs_entries(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_SHOW_STATFS_ENTRIES;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_SHOW_STATFS_ENTRIES;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to show_statfs_entries \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_truncate_log(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_TRUNCATE_LOG;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_TRUNCATE_LOG;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to truncate_log \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_unmount_on_exit(const char *val)
-{
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_UNMOUNT_ON_EXIT;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_UNMOUNT_ON_EXIT;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to unmount_on_exit \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_use_tcpwrappers(const char *val)
-{
-#if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
- if (STREQ(val, "yes")) {
- gopt.flags |= CFM_USE_TCPWRAPPERS;
- return 0;
- } else if (STREQ(val, "no")) {
- gopt.flags &= ~CFM_USE_TCPWRAPPERS;
- return 0;
- }
-#else /* not defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
- fprintf(stderr, "conf: no tcpd/libwrap support available\n");
- return 1;
-#endif /* not defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */
-
- fprintf(stderr, "conf: unknown value to use_tcpwrappers \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-gopt_vendor(const char *val)
-{
- gopt.op_sys_vendor = strdup((char *)val);
- return 0;
-}
-
-
-/*
- * Collect one entry for a regular map
- */
-static int
-process_regular_option(const char *section, const char *key, const char *val, cf_map_t *cfm)
-{
- /* ensure that val is valid */
- if (!section || section[0] == '\0' ||
- !key || key[0] == '\0' ||
- !val || val[0] == '\0' ||
- !cfm) {
- fprintf(stderr, "conf: process_regular_option: null entries\n");
- return 1;
- }
-
- /* check if initializing a new map */
- if (!cfm->cfm_dir)
- cfm->cfm_dir = strdup((char *)section);
-
- /* check for each possible field */
- if (STREQ(key, "browsable_dirs"))
- return ropt_browsable_dirs(val, cfm);
-
- if (STREQ(key, "map_name"))
- return ropt_map_name(val, cfm);
-
- if (STREQ(key, "map_defaults"))
- return ropt_map_defaults(val, cfm);
-
- if (STREQ(key, "map_options"))
- return ropt_map_options(val, cfm);
-
- if (STREQ(key, "map_type"))
- return ropt_map_type(val, cfm);
-
- if (STREQ(key, "mount_type"))
- return ropt_mount_type(val, cfm);
-
- if (STREQ(key, "search_path"))
- return ropt_search_path(val, cfm);
-
- if (STREQ(key, "tag"))
- return ropt_tag(val, cfm);
-
- fprintf(stderr, "conf: unknown regular key \"%s\" for section \"%s\"\n",
- key, section);
- return 1; /* failed to match any command */
-}
-
-
-static int
-ropt_browsable_dirs(const char *val, cf_map_t *cfm)
-{
- if (STREQ(val, "full")) {
- cfm->cfm_flags |= CFM_BROWSABLE_DIRS_FULL;
- return 0;
- } else if (STREQ(val, "yes")) {
- cfm->cfm_flags |= CFM_BROWSABLE_DIRS;
- return 0;
- } else if (STREQ(val, "no")) {
- cfm->cfm_flags &= ~CFM_BROWSABLE_DIRS;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to browsable_dirs \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-ropt_map_name(const char *val, cf_map_t *cfm)
-{
- cfm->cfm_name = strdup((char *)val);
- return 0;
-}
-
-
-static int
-ropt_map_defaults(const char *val, cf_map_t *cfm)
-{
- cfm->cfm_defaults = strdup((char *)val);
- return 0;
-}
-
-
-static int
-ropt_map_options(const char *val, cf_map_t *cfm)
-{
- cfm->cfm_opts = strdup((char *)val);
- return 0;
-}
-
-
-static int
-ropt_map_type(const char *val, cf_map_t *cfm)
-{
- /* check if map type exist */
- if (!mapc_type_exists(val)) {
- fprintf(stderr, "conf: no such map type \"%s\"\n", val);
- return 1;
- }
- cfm->cfm_type = strdup((char *)val);
- return 0;
-}
-
-
-static int
-ropt_mount_type(const char *val, cf_map_t *cfm)
-{
- if (STREQ(val, "autofs")) {
-#ifdef HAVE_FS_AUTOFS
- cfm->cfm_flags |= CFM_MOUNT_TYPE_AUTOFS;
- amd_use_autofs++;
- return 0;
-#else /* not HAVE_FS_AUTOFS */
- fprintf(stderr, "conf: no autofs support available\n");
- return 1;
-#endif /* not HAVE_FS_AUTOFS */
- } else if (STREQ(val, "nfs")) {
- cfm->cfm_flags &= ~CFM_MOUNT_TYPE_AUTOFS;
- return 0;
- }
-
- fprintf(stderr, "conf: unknown value to mount_type \"%s\"\n", val);
- return 1; /* unknown value */
-}
-
-
-static int
-ropt_search_path(const char *val, cf_map_t *cfm)
-{
- cfm->cfm_search_path = strdup((char *)val);
- return 0;
-}
-
-
-static int
-ropt_tag(const char *val, cf_map_t *cfm)
-{
- cfm->cfm_tag = strdup((char *)val);
- return 0;
-}
-
-
-/*
- * Process one collected map.
- */
-static int
-process_one_regular_map(const cf_map_t *cfm)
-{
- if (!cfm->cfm_name) {
- fprintf(stderr, "conf: map_name must be defined for map \"%s\"\n", cfm->cfm_dir);
- return 1;
- }
- /*
- * If map has no tag defined, process the map.
- * If no conf_tag was set in amd -T, process all untagged entries.
- * If a tag is defined, then process it only if it matches the map tag.
- */
- if (!cfm->cfm_tag ||
- (conf_tag && STREQ(cfm->cfm_tag, conf_tag))) {
-#ifdef DEBUG_CONF
- fprintf(stderr, "processing map %s (flags=0x%x)...\n",
- cfm->cfm_dir, cfm->cfm_flags);
-#endif /* DEBUG_CONF */
- root_newmap(cfm->cfm_dir,
- cfm->cfm_opts ? cfm->cfm_opts : "",
- cfm->cfm_name,
- cfm);
- } else {
- fprintf(stderr, "skipping map %s...\n", cfm->cfm_dir);
- }
-
- return 0;
-}
-
-
-/*
- * Process all regular maps in conf file (if any)
- */
-int
-process_all_regular_maps(void)
-{
- cf_map_t *tmp_map = head_map;
-
- /*
- * If the amd.conf file only has a [global] section (pretty useless
- * IMHO), there's nothing to process
- */
- if (!tmp_map)
- return 0;
-
- while (tmp_map) {
- if (process_one_regular_map(tmp_map) != 0)
- return 1;
- tmp_map = tmp_map->cfm_next;
- }
- return 0;
-}
-
-
-/*
- * Find a cf_map_t for a given map name.
- * Return NULL if not found.
- */
-cf_map_t *
-find_cf_map(const char *name)
-{
-
- cf_map_t *tmp_map = head_map;
-
- if (!tmp_map || !name)
- return NULL;
-
- while (tmp_map) {
- if (STREQ(tmp_map->cfm_dir,name)) {
- return tmp_map;
- }
- tmp_map = tmp_map->cfm_next;
- }
- return NULL;
-}
diff --git a/contrib/amd/amd/conf_parse.y b/contrib/amd/amd/conf_parse.y
deleted file mode 100644
index b397b0573242..000000000000
--- a/contrib/amd/amd/conf_parse.y
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/conf_parse.y
- *
- */
-
-%{
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-extern char *yytext;
-extern int ayylineno;
-extern int yylex(void);
-
-static int yyerror(const char *s);
-static int retval;
-static char *header_section = NULL; /* start with no header section */
-
-#define YYDEBUG 1
-
-#define PARSE_DEBUG 0
-
-#if PARSE_DEBUG
-# define dprintf(f,s) fprintf(stderr, (f), ayylineno, (s))
-# define amu_return(v)
-#else /* not PARSE_DEBUG */
-# define dprintf(f,s)
-# define amu_return(v) return((v))
-#endif /* not PARSE_DEBUG */
-
-%}
-
-%union {
-char *strtype;
-}
-
-%token LEFT_BRACKET RIGHT_BRACKET EQUAL
-%token NEWLINE
-%token <strtype> NONWS_STRING
-%token <strtype> NONWSEQ_STRING
-%token <strtype> QUOTED_NONWSEQ_STRING
-
-%start file
-%%
-
-/****************************************************************************/
-file : { yydebug = PARSE_DEBUG; } newlines map_sections
- | { yydebug = PARSE_DEBUG; } map_sections
- ;
-
-newlines : NEWLINE
- | NEWLINE newlines
- ;
-
-map_sections : map_section
- | map_section map_sections
- ;
-
-map_section : sec_header kv_pairs
- ;
-
-sec_header : LEFT_BRACKET NONWS_STRING RIGHT_BRACKET NEWLINE
- {
- if (yydebug)
- fprintf(stderr, "sec_header1 = \"%s\"\n", $2);
- header_section = $2;
- }
- ;
-
-kv_pairs : kv_pair
- | kv_pair kv_pairs
- ;
-
-kv_pair : NONWS_STRING EQUAL NONWS_STRING NEWLINE
- {
- if (yydebug)
- fprintf(stderr,"parse1: key=\"%s\", val=\"%s\"\n", $1, $3);
- retval = set_conf_kv(header_section, $1, $3);
- if (retval != 0) {
- yyerror("syntax error");
- YYABORT;
- }
- }
- | NONWS_STRING EQUAL NONWSEQ_STRING NEWLINE
- {
- if (yydebug)
- fprintf(stderr,"parse2: key=\"%s\", val=\"%s\"\n", $1, $3);
- retval = set_conf_kv(header_section, $1, $3);
- if (retval != 0) {
- yyerror("syntax error");
- YYABORT;
- }
- }
- | NONWS_STRING EQUAL QUOTED_NONWSEQ_STRING NEWLINE
- {
- if (yydebug)
- fprintf(stderr,"parse3: key=\"%s\", val=\"%s\"\n", $1, $3);
- retval = set_conf_kv(header_section, $1, $3);
- if (retval != 0) {
- yyerror("syntax error");
- YYABORT;
- }
- }
- | NEWLINE
- ;
-
-/****************************************************************************/
-%%
-
-static int
-yyerror(const char *s)
-{
- fprintf(stderr, "AMDCONF: %s on line %d (section %s)\n",
- s, ayylineno,
- (header_section ? header_section : "null"));
- exit(1);
- return 1; /* to full compilers that insist on a return statement */
-}
diff --git a/contrib/amd/amd/conf_tok.l b/contrib/amd/amd/conf_tok.l
deleted file mode 100644
index b572e4d7d5a3..000000000000
--- a/contrib/amd/amd/conf_tok.l
+++ /dev/null
@@ -1,192 +0,0 @@
-%{
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/conf_tok.l
- *
- */
-
-/*
- * Lexical analyzer for AMD configuration parser.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-/*
- * Some systems include a definition for the macro ECHO in <sys/ioctl.h>,
- * and their (bad) version of lex defines it too at the very beginning of
- * the generated lex.yy.c file (before it can be easily undefined),
- * resulting in a conflict. So undefine it here before needed.
- * Luckily, it does not appear that this macro is actually used in the rest
- * of the generated lex.yy.c file.
- */
-#ifdef ECHO
-# undef ECHO
-#endif /* ECHO */
-#include <am_defs.h>
-#include <amd.h>
-#include <conf_parse.h>
-/* and once again undefine this, just in case */
-#ifdef ECHO
-# undef ECHO
-#endif /* ECHO */
-
-/*
- * There are some things that need to be defined only if using GNU flex.
- * These must not be defined if using standard lex
- */
-#ifdef FLEX_SCANNER
-# ifndef ECHO
-# define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
-# endif /* not ECHO */
-#endif /* FLEX_SCANNER */
-
-int ayylineno = 0;
-
-int yylex(void);
-/*
- * some systems such as DU-4.x have a different GNU flex in /usr/bin
- * which automatically generates yywrap macros and symbols. So I must
- * distinguish between them and when yywrap is actually needed.
- */
-#ifndef yywrap
-int yywrap(void);
-#endif /* not yywrap */
-
-#define TOK_DEBUG 0
-
-#if TOK_DEBUG
-# define dprintf(f,s) fprintf(stderr, (f), ayylineno, (s))
-# define amu_return(v)
-#else /* not TOK_DEBUG */
-# define dprintf(f,s)
-# define amu_return(v) return((v))
-#endif /* not TOK_DEBUG */
-
-/* no need to use yywrap() */
-#define YY_SKIP_YYWRAP
-
-%}
-
-/* This option causes Solaris lex to fail. Use flex. See BUGS file */
-/* no need to use yyunput() */
-%option nounput
-
-/* allocate more output slots so lex scanners don't run out of mem */
-%o 1024
-
-DIGIT [0-9]
-ALPHA [A-Za-z]
-ALPHANUM [A-Za-z0-9]
-SYMBOL [A-Za-z0-9_-]
-PATH [A-Za-z0-9_-/]
-NONWSCHAR [^ \t\n\[\]=]
-NONWSEQCHAR [^ \t\n\[\]]
-NONNL [^\n]
-NONQUOTE [^\"]
-
-%%
-
-\n {
- ayylineno++;
- amu_return(NEWLINE);
- }
-
-\[ {
- dprintf("%8d: Left bracket \"%s\"\n", yytext);
- yylval.strtype = strdup((char *)yytext);
- amu_return(LEFT_BRACKET);
- }
-
-\] {
- dprintf("%8d: Right bracket \"%s\"\n", yytext);
- yylval.strtype = strdup((char *)yytext);
- amu_return(RIGHT_BRACKET);
- }
-
-= {
- dprintf("%8d: Equal \"%s\"\n", yytext);
- yylval.strtype = strdup((char *)yytext);
- amu_return(EQUAL);
- }
-
-[ \t]* {
- dprintf("%8d: Whitespace \"%s\"\n", yytext);
- }
-"#"[^\n]*\n {
- /* a comment line includes the terminating \n */
- ayylineno++;
- yytext[strlen((char *)yytext)-1] = '\0';
- dprintf("%8d: Comment \"%s\"\n", yytext);
- }
-
-{NONWSCHAR}{NONWSCHAR}* {
- dprintf("%8d: Non-WS string \"%s\"\n", yytext);
- yylval.strtype = strdup((char *)yytext);
- amu_return(NONWS_STRING);
- }
-
-\"{NONQUOTE}{NONQUOTE}*\" {
- dprintf("%8d: QUOTED-Non-WS-EQ string \"%s\"\n", yytext);
- /* must strip quotes */
- yytext[strlen((char *)yytext)-1] = '\0';
- yylval.strtype = strdup((char *)&yytext[1]);
- amu_return(QUOTED_NONWSEQ_STRING);
- }
-
-{NONWSEQCHAR}{NONWSEQCHAR}* {
- dprintf("%8d: Non-WS-EQ string \"%s\"\n", yytext);
- yylval.strtype = strdup((char *)yytext);
- amu_return(NONWSEQ_STRING);
- }
-
-%%
-
-/*
- * some systems such as DU-4.x have a different GNU flex in /usr/bin
- * which automatically generates yywrap macros and symbols. So I must
- * distinguish between them and when yywrap is actually needed.
- */
-#ifndef yywrap
-int yywrap(void)
-{
- return 1;
-}
-#endif /* not yywrap */
diff --git a/contrib/amd/amd/get_args.c b/contrib/amd/amd/get_args.c
deleted file mode 100644
index 12a7d07efd59..000000000000
--- a/contrib/amd/amd/get_args.c
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/get_args.c
- *
- */
-
-/*
- * Argument decode
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* include auto-generated version file */
-#include <build_version.h>
-
-char *amu_conf_file = "/etc/amd.conf"; /* default amd configuration file */
-char *conf_tag = NULL; /* default conf file tags to use */
-int usage = 0;
-int use_conf_file = 0; /* default don't use amd.conf file */
-char *mnttab_file_name = NULL; /* symbol must be available always */
-
-
-/*
- * Return the version string (dynamic buffer)
- */
-char *
-get_version_string(void)
-{
- char *vers = NULL;
- char tmpbuf[1024];
- char *wire_buf;
- int wire_buf_len = 0;
- size_t len; /* max allocated length (to avoid buf overflow) */
-
- /*
- * First get dynamic string listing all known networks.
- * This could be a long list, if host has lots of interfaces.
- */
- wire_buf = print_wires();
- if (wire_buf)
- wire_buf_len = strlen(wire_buf);
-
- len = 2048 + wire_buf_len;
- vers = xmalloc(len);
- xsnprintf(vers, len, "%s\n%s\n%s\n%s\n",
- "Copyright (c) 1997-2006 Erez Zadok",
- "Copyright (c) 1990 Jan-Simon Pendry",
- "Copyright (c) 1990 Imperial College of Science, Technology & Medicine",
- "Copyright (c) 1990 The Regents of the University of California.");
- xsnprintf(tmpbuf, sizeof(tmpbuf), "%s version %s (build %d).\n",
- PACKAGE_NAME, PACKAGE_VERSION, AMU_BUILD_VERSION);
- strlcat(vers, tmpbuf, len);
- xsnprintf(tmpbuf, sizeof(tmpbuf), "Report bugs to %s.\n", PACKAGE_BUGREPORT);
- strlcat(vers, tmpbuf, len);
- xsnprintf(tmpbuf, sizeof(tmpbuf), "Configured by %s@%s on date %s.\n",
- USER_NAME, HOST_NAME, CONFIG_DATE);
- strlcat(vers, tmpbuf, len);
- xsnprintf(tmpbuf, sizeof(tmpbuf), "Built by %s@%s on date %s.\n",
- BUILD_USER, BUILD_HOST, BUILD_DATE);
- strlcat(vers, tmpbuf, len);
- xsnprintf(tmpbuf, sizeof(tmpbuf), "cpu=%s (%s-endian), arch=%s, karch=%s.\n",
- cpu, endian, gopt.arch, gopt.karch);
- strlcat(vers, tmpbuf, len);
- xsnprintf(tmpbuf, sizeof(tmpbuf), "full_os=%s, os=%s, osver=%s, vendor=%s, distro=%s.\n",
- gopt.op_sys_full, gopt.op_sys, gopt.op_sys_ver, gopt.op_sys_vendor, DISTRO_NAME);
- strlcat(vers, tmpbuf, len);
- xsnprintf(tmpbuf, sizeof(tmpbuf), "domain=%s, host=%s, hostd=%s.\n",
- hostdomain, am_get_hostname(), hostd);
- strlcat(vers, tmpbuf, len);
-
- strlcat(vers, "Map support for: ", len);
- mapc_showtypes(tmpbuf, sizeof(tmpbuf));
- strlcat(vers, tmpbuf, len);
- strlcat(vers, ".\nAMFS: ", len);
- ops_showamfstypes(tmpbuf, sizeof(tmpbuf));
- strlcat(vers, tmpbuf, len);
- strlcat(vers, ", inherit.\nFS: ", len); /* hack: "show" that we support type:=inherit */
- ops_showfstypes(tmpbuf, sizeof(tmpbuf));
- strlcat(vers, tmpbuf, len);
-
- /* append list of networks if available */
- if (wire_buf) {
- strlcat(vers, wire_buf, len);
- XFREE(wire_buf);
- }
-
- return vers;
-}
-
-
-static void
-show_usage(void)
-{
- fprintf(stderr,
- "Usage: %s [-nprvHS] [-a mount_point] [-c cache_time] [-d domain]\n\
-\t[-k kernel_arch] [-l logfile%s\n\
-\t[-t timeout.retrans] [-w wait_timeout] [-A arch] [-C cluster_name]\n\
-\t[-o op_sys_ver] [-O op_sys_name]\n\
-\t[-F conf_file] [-T conf_tag]", am_get_progname(),
-#ifdef HAVE_SYSLOG
-# ifdef LOG_DAEMON
- "|\"syslog[:facility]\"]"
-# else /* not LOG_DAEMON */
- "|\"syslog\"]"
-# endif /* not LOG_DAEMON */
-#else /* not HAVE_SYSLOG */
- "]"
-#endif /* not HAVE_SYSLOG */
- );
-
-#ifdef HAVE_MAP_NIS
- fputs(" [-y nis-domain]\n", stderr);
-#else /* not HAVE_MAP_NIS */
- fputc('\n', stderr);
-#endif /* HAVE_MAP_NIS */
-
- show_opts('x', xlog_opt);
-#ifdef DEBUG
- show_opts('D', dbg_opt);
-#endif /* DEBUG */
- fprintf(stderr, "\t[directory mapname [-map_options]] ...\n");
-}
-
-
-void
-get_args(int argc, char *argv[])
-{
- int opt_ch, i;
- FILE *fp = stdin;
- char getopt_arguments[] = "+nprvSa:c:d:k:l:o:t:w:x:y:C:D:F:T:O:HA:";
- char *getopt_args;
- int print_version = 0; /* 1 means we should print version info */
-
-#ifdef HAVE_GNU_GETOPT
- getopt_args = getopt_arguments;
-#else /* ! HAVE_GNU_GETOPT */
- getopt_args = &getopt_arguments[1];
-#endif /* HAVE_GNU_GETOPT */
-
- /* if no arguments were passed, try to use /etc/amd.conf file */
- if (argc <= 1)
- use_conf_file = 1;
-
- while ((opt_ch = getopt(argc, argv, getopt_args)) != -1)
- switch (opt_ch) {
-
- case 'a':
- if (*optarg != '/') {
- fprintf(stderr, "%s: -a option must begin with a '/'\n",
- am_get_progname());
- exit(1);
- }
- gopt.auto_dir = optarg;
- break;
-
- case 'c':
- gopt.am_timeo = atoi(optarg);
- if (gopt.am_timeo <= 0)
- gopt.am_timeo = AM_TTL;
- break;
-
- case 'd':
- gopt.sub_domain = optarg;
- break;
-
- case 'k':
- gopt.karch = optarg;
- break;
-
- case 'l':
- gopt.logfile = optarg;
- break;
-
- case 'n':
- gopt.flags |= CFM_NORMALIZE_HOSTNAMES;
- break;
-
- case 'o':
- gopt.op_sys_ver = optarg;
- break;
-
- case 'p':
- gopt.flags |= CFM_PRINT_PID;
- break;
-
- case 'r':
- gopt.flags |= CFM_RESTART_EXISTING_MOUNTS;
- break;
-
- case 't':
- /* timeo.retrans (also affects toplvl mounts) */
- {
- char *dot = strchr(optarg, '.');
- int i;
- if (dot)
- *dot = '\0';
- if (*optarg) {
- for (i=0; i<AMU_TYPE_MAX; ++i)
- gopt.amfs_auto_timeo[i] = atoi(optarg);
- }
- if (dot) {
- for (i=0; i<AMU_TYPE_MAX; ++i)
- gopt.amfs_auto_retrans[i] = atoi(dot + 1);
- *dot = '.';
- }
- }
- break;
-
- case 'v':
- /*
- * defer to print version info after every variable had been
- * initialized.
- */
- print_version++;
- break;
-
- case 'w':
- gopt.am_timeo_w = atoi(optarg);
- if (gopt.am_timeo_w <= 0)
- gopt.am_timeo_w = AM_TTL_W;
- break;
-
- case 'x':
- usage += switch_option(optarg);
- break;
-
- case 'y':
-#ifdef HAVE_MAP_NIS
- gopt.nis_domain = optarg;
-#else /* not HAVE_MAP_NIS */
- plog(XLOG_USER, "-y: option ignored. No NIS support available.");
-#endif /* not HAVE_MAP_NIS */
- break;
-
- case 'A':
- gopt.arch = optarg;
- break;
-
- case 'C':
- gopt.cluster = optarg;
- break;
-
- case 'D':
-#ifdef DEBUG
- usage += debug_option(optarg);
-#else /* not DEBUG */
- fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n",
- am_get_progname());
-#endif /* not DEBUG */
- break;
-
- case 'F':
- amu_conf_file = optarg;
- use_conf_file = 1;
- break;
-
- case 'H':
- show_usage();
- exit(1);
- break;
-
- case 'O':
- gopt.op_sys = optarg;
- break;
-
- case 'S':
- gopt.flags &= ~CFM_PROCESS_LOCK; /* turn process locking off */
- break;
-
- case 'T':
- conf_tag = optarg;
- break;
-
- default:
- usage = 1;
- break;
- }
-
- /*
- * amd.conf file: if not command-line arguments were used, or if -F was
- * specified, then use that amd.conf file. If the file cannot be opened,
- * abort amd. If it can be found, open it, parse it, and then close it.
- */
- if (use_conf_file && amu_conf_file) {
- fp = fopen(amu_conf_file, "r");
- if (!fp) {
- char buf[128];
- xsnprintf(buf, sizeof(buf), "Amd configuration file (%s)",
- amu_conf_file);
- perror(buf);
- exit(1);
- }
- yyin = fp;
- yyparse();
- fclose(fp);
- if (process_all_regular_maps() != 0)
- exit(1);
- }
-
- /* make sure there are some default options defined */
- if (xlog_level_init == ~0) {
- switch_option("");
- }
-#ifdef DEBUG
- usage += switch_option("debug");
-#endif /* DEBUG */
-
- /* log information regarding amd.conf file */
- if (use_conf_file && amu_conf_file)
- plog(XLOG_INFO, "using configuration file %s", amu_conf_file);
-
-#ifdef HAVE_MAP_LDAP
- /* ensure that if ldap_base is specified, that also ldap_hostports is */
- if (gopt.ldap_hostports && !gopt.ldap_base) {
- fprintf(stderr, "must specify both ldap_hostports and ldap_base\n");
- exit(1);
- }
-#endif /* HAVE_MAP_LDAP */
-
- if (usage) {
- show_usage();
- exit(1);
- }
-
- while (optind <= argc - 2) {
- char *dir = argv[optind++];
- char *map = argv[optind++];
- char *opts = "";
- if (argv[optind] && *argv[optind] == '-')
- opts = &argv[optind++][1];
-
- root_newmap(dir, opts, map, NULL);
- }
-
- if (optind == argc) {
- /*
- * Append domain name to hostname.
- * sub_domain overrides hostdomain
- * if given.
- */
- if (gopt.sub_domain)
- hostdomain = gopt.sub_domain;
- if (*hostdomain == '.')
- hostdomain++;
- xstrlcat(hostd, ".", sizeof(hostd));
- xstrlcat(hostd, hostdomain, sizeof(hostd));
-
-#ifdef MOUNT_TABLE_ON_FILE
- if (amuDebug(D_MTAB))
- if (gopt.debug_mtab_file)
- mnttab_file_name = gopt.debug_mtab_file; /* user supplied debug mtab path */
- else
- mnttab_file_name = DEBUG_MNTTAB_FILE; /* default debug mtab path */
- else
- mnttab_file_name = MNTTAB_FILE_NAME;
-#else /* not MOUNT_TABLE_ON_FILE */
- if (amuDebug(D_MTAB))
- dlog("-D mtab option ignored");
-# ifdef MNTTAB_FILE_NAME
- mnttab_file_name = MNTTAB_FILE_NAME;
-# endif /* MNTTAB_FILE_NAME */
-#endif /* not MOUNT_TABLE_ON_FILE */
-
- /*
- * If the kernel architecture was not specified
- * then use the machine architecture.
- */
- if (gopt.karch == NULL)
- gopt.karch = gopt.arch;
-
- if (gopt.cluster == NULL)
- gopt.cluster = hostdomain;
-
- /* sanity checking, normalize values just in case (toplvl too) */
- for (i=0; i<AMU_TYPE_MAX; ++i) {
- if (gopt.amfs_auto_timeo[i] == 0)
- gopt.amfs_auto_timeo[i] = AMFS_AUTO_TIMEO;
- if (gopt.amfs_auto_retrans[i] == 0)
- gopt.amfs_auto_retrans[i] = AMFS_AUTO_RETRANS(i);
- if (gopt.amfs_auto_retrans[i] == 0)
- gopt.amfs_auto_retrans[i] = 3; /* under very unusual circumstances, could be zero */
- }
- }
-
- /* finally print version string and exit, if asked for */
- if (print_version) {
- fputs(get_version_string(), stderr);
- exit(0);
- }
-
- if (switch_to_logfile(gopt.logfile, orig_umask,
- (gopt.flags & CFM_TRUNCATE_LOG)) != 0)
- plog(XLOG_USER, "Cannot switch logfile");
-
- return;
-}
diff --git a/contrib/amd/amd/info_exec.c b/contrib/amd/amd/info_exec.c
deleted file mode 100644
index 8ccab9aee579..000000000000
--- a/contrib/amd/amd/info_exec.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/info_exec.c
- *
- */
-
-/*
- * Get info from executable map
- *
- * Original from Erik Kline, 2004.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-#define MAX_LINE_LEN 1500
-
-/* forward declarations */
-int exec_init(mnt_map *m, char *map, time_t *tp);
-int exec_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
-
-
-/*
- * a timed fgets()
- */
-static char *
-fgets_timed(char *s, int size, int rdfd, int secs)
-{
- fd_set fds;
- struct timeval timeo;
- time_t start, now;
- int rval=0, i=0;
-
- if (!s || size < 0 || rdfd < 0)
- return 0;
-
- s[0] = 0;
- if (size == 0)
- return s;
-
- start = clocktime(NULL);
- while (s[i] != '\n' && i < size-1) {
- s[i+1] = 0; /* places the requisite trailing '\0' */
-
- /* ready for reading */
- rval = read(rdfd, (void *)(s+i), 1);
- if (rval == 1) {
- if (s[i] == 0) {
- rval = 0;
- break;
- }
- i++;
- continue;
- } else if (rval == 0) {
- break;
- } else if (rval < 0 && errno != EAGAIN && errno != EINTR) {
- plog(XLOG_WARNING, "fgets_timed read error: %m");
- break;
- }
-
- timeo.tv_usec = 0;
- now = clocktime(NULL) - start;
- if (secs <= 0)
- timeo.tv_sec = 0;
- else if (now < secs)
- timeo.tv_sec = secs - now;
- else {
- /* timed out (now>=secs) */
- plog(XLOG_WARNING, "executable map read timed out (> %d secs)", secs);
- rval = -1;
- break;
- }
-
- FD_ZERO(&fds);
- FD_SET(rdfd, &fds);
-
- rval = select(rdfd+1, &fds, 0, 0, &timeo);
- if (rval < 0) {
- /* error selecting */
- plog(XLOG_WARNING, "fgets_timed select error: %m");
- if (errno == EINTR)
- continue;
- rval = -1;
- break;
- } else if (rval == 0) {
- /* timed out */
- plog(XLOG_WARNING, "executable map read timed out (> %d secs)", secs);
- rval = -1;
- break;
- }
- }
-
- if (rval > 0)
- return s;
-
- close(rdfd);
- return (rval == 0 ? s : 0);
-}
-
-
-static int
-read_line(char *buf, int size, int fd)
-{
- int done = 0;
-
- while (fgets_timed(buf, size, fd, gopt.exec_map_timeout)) {
- int len = strlen(buf);
- done += len;
- if (len > 1 && buf[len - 2] == '\\' &&
- buf[len - 1] == '\n') {
- buf += len - 2;
- size -= len - 2;
- *buf = '\n';
- buf[1] = '\0';
- } else {
- return done;
- }
- }
-
- return done;
-}
-
-
-/*
- * Try to locate a value in a query answer
- */
-static int
-exec_parse_qanswer(int fd, char *map, char *key, char **pval, time_t *tp)
-{
- char qanswer[MAX_LINE_LEN], *dc = 0;
- int chuck = 0;
- int line_no = 0;
-
- while (read_line(qanswer, sizeof(qanswer), fd)) {
- char *cp;
- char *hash;
- int len = strlen(qanswer);
- line_no++;
-
- /*
- * Make sure we got the whole line
- */
- if (qanswer[len - 1] != '\n') {
- plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map);
- chuck = 1;
- } else {
- qanswer[len - 1] = '\0';
- }
-
- /*
- * Strip comments
- */
- hash = strchr(qanswer, '#');
- if (hash)
- *hash = '\0';
-
- /*
- * Find beginning of value (query answer)
- */
- for (cp = qanswer; *cp && !isascii((int)*cp) && !isspace((int)*cp); cp++)
- ;;
-
- /* Ignore blank lines */
- if (!*cp)
- goto again;
-
- /*
- * Return a copy of the data
- */
- dc = strdup(cp);
- *pval = dc;
- dlog("%s returns %s", key, dc);
-
- close(fd);
- return 0;
-
- again:
- /*
- * If the last read didn't get a whole line then
- * throw away the remainder before continuing...
- */
- if (chuck) {
- while (fgets_timed(qanswer, sizeof(qanswer), fd, gopt.exec_map_timeout) &&
- !strchr(qanswer, '\n')) ;
- chuck = 0;
- }
- }
-
- return ENOENT;
-}
-
-
-static int
-set_nonblock(int fd)
-{
- int val;
-
- if (fd < 0)
- return 0;
-
- if ((val = fcntl(fd, F_GETFL, 0)) < 0) {
- plog(XLOG_WARNING, "set_nonblock fcntl F_GETFL error: %m");
- return 0;
- }
-
- val |= O_NONBLOCK;
- if (fcntl(fd, F_SETFL, val) < 0) {
- plog(XLOG_WARNING, "set_nonblock fcntl F_SETFL error: %m");
- return 0;
- }
-
- return 1;
-}
-
-
-static int
-exec_map_open(char *emap, char *key)
-{
- pid_t p1, p2;
- int pdes[2], nullfd, i;
- char *argv[3];
-
- if (!emap)
- return 0;
-
- argv[0] = emap;
- argv[1] = key;
- argv[2] = NULL;
-
- if ((nullfd = open("/dev/null", O_WRONLY|O_NOCTTY)) < 0)
- return -1;
-
- if (pipe(pdes) < 0) {
- close(nullfd);
- return -1;
- }
-
- switch ((p1 = vfork())) {
- case -1:
- /* parent: fork error */
- close(nullfd);
- close(pdes[0]);
- close(pdes[1]);
- return -1;
- case 0:
- /* child #1 */
- p2 = vfork();
- switch (p2) {
- case -1:
- /* child #1: fork error */
- exit(errno);
- case 0:
- /* child #2: init will reap our status */
- if (pdes[1] != STDOUT_FILENO) {
- dup2(pdes[1], STDOUT_FILENO);
- close(pdes[1]);
- }
-
- if (nullfd != STDERR_FILENO) {
- dup2(nullfd, STDERR_FILENO);
- close(nullfd);
- }
-
- for (i=0; i<FD_SETSIZE; i++)
- if (i != STDOUT_FILENO && i != STDERR_FILENO)
- close(i);
-
- /* make the write descriptor non-blocking */
- if (!set_nonblock(STDOUT_FILENO)) {
- close(STDOUT_FILENO);
- exit(-1);
- }
-
- execve(emap, argv, NULL);
- exit(errno); /* in case execve failed */
- }
-
- /* child #1 */
- exit(0);
- }
-
- /* parent */
- close(nullfd);
- close(pdes[1]);
-
- /* anti-zombie insurance */
- while (waitpid(p1,0,0) < 0)
- if (errno != EINTR)
- exit(errno);
-
- /* make the read descriptor non-blocking */
- if (!set_nonblock(pdes[0])) {
- close(pdes[0]);
- return -1;
- }
-
- return pdes[0];
-}
-
-
-/*
- * Check for various permissions on executable map without trying to
- * fork a new executable-map process.
- *
- * return: >0 (errno) if failed
- * 0 if ok
- */
-static int
-exec_check_perm(char *map)
-{
- struct stat sb;
-
- /* sanity and permission checks */
- if (!map) {
- dlog("exec_check_permission got a NULL map");
- return EINVAL;
- }
- if (stat(map, &sb)) {
- plog(XLOG_ERROR, "map \"%s\" stat failure: %m", map);
- return errno;
- }
- if (!S_ISREG(sb.st_mode)) {
- plog(XLOG_ERROR, "map \"%s\" should be regular file", map);
- return EINVAL;
- }
- if (sb.st_uid != 0) {
- plog(XLOG_ERROR, "map \"%s\" owned by uid %u (must be 0)", map, (u_int) sb.st_uid);
- return EACCES;
- }
- if (!(sb.st_mode & S_IXUSR)) {
- plog(XLOG_ERROR, "map \"%s\" should be executable", map);
- return EACCES;
- }
- if (sb.st_mode & (S_ISUID|S_ISGID)) {
- plog(XLOG_ERROR, "map \"%s\" should not be setuid/setgid", map);
- return EACCES;
- }
- if (sb.st_mode & S_IWOTH) {
- plog(XLOG_ERROR, "map \"%s\" should not be world writeable", map);
- return EACCES;
- }
-
- return 0; /* all is well */
-}
-
-
-int
-exec_init(mnt_map *m, char *map, time_t *tp)
-{
- /*
- * Basically just test that the executable map can be found
- * and has proper permissions.
- */
- return exec_check_perm(map);
-}
-
-
-int
-exec_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
-{
- int mapfd, ret;
-
- if ((ret = exec_check_perm(map)) != 0) {
- return ret;
- }
-
- if (!key)
- return 0;
-
- if (logfp)
- fflush(logfp);
- dlog("exec_search \"%s\", key: \"%s\"", map, key);
- mapfd = exec_map_open(map, key);
-
- if (mapfd >= 0) {
- if (tp)
- *tp = clocktime(NULL);
-
- return exec_parse_qanswer(mapfd, map, key, pval, tp);
- }
-
- return errno;
-}
diff --git a/contrib/amd/amd/info_file.c b/contrib/amd/amd/info_file.c
deleted file mode 100644
index 3777a2aebe94..000000000000
--- a/contrib/amd/amd/info_file.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/info_file.c
- *
- */
-
-/*
- * Get info from file
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-#define MAX_LINE_LEN 1500
-
-/* forward declarations */
-int file_init_or_mtime(mnt_map *m, char *map, time_t *tp);
-int file_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *));
-int file_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
-
-
-static int
-read_line(char *buf, int size, FILE *fp)
-{
- int done = 0;
-
- do {
- while (fgets(buf, size, fp)) {
- int len = strlen(buf);
- done += len;
- if (len > 1 && buf[len - 2] == '\\' &&
- buf[len - 1] == '\n') {
- int ch;
- buf += len - 2;
- size -= len - 2;
- *buf = '\n';
- buf[1] = '\0';
- /*
- * Skip leading white space on next line
- */
- while ((ch = getc(fp)) != EOF &&
- isascii(ch) && isspace(ch)) ;
- (void) ungetc(ch, fp);
- } else {
- return done;
- }
- }
- } while (size > 0 && !feof(fp) && !ferror(fp));
-
- return done;
-}
-
-
-/*
- * Try to locate a key in a file
- */
-static int
-file_search_or_reload(FILE *fp,
- char *map,
- char *key,
- char **val,
- mnt_map *m,
- void (*fn) (mnt_map *m, char *, char *))
-{
- char key_val[MAX_LINE_LEN];
- int chuck = 0;
- int line_no = 0;
-
- while (read_line(key_val, sizeof(key_val), fp)) {
- char *kp;
- char *cp;
- char *hash;
- int len = strlen(key_val);
- line_no++;
-
- /*
- * Make sure we got the whole line
- */
- if (key_val[len - 1] != '\n') {
- plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map);
- chuck = 1;
- } else {
- key_val[len - 1] = '\0';
- }
-
- /*
- * Strip comments
- */
- hash = strchr(key_val, '#');
- if (hash)
- *hash = '\0';
-
- /*
- * Find start of key
- */
- for (kp = key_val; *kp && isascii(*kp) && isspace((int)*kp); kp++) ;
-
- /*
- * Ignore blank lines
- */
- if (!*kp)
- goto again;
-
- /*
- * Find end of key
- */
- for (cp = kp; *cp && (!isascii(*cp) || !isspace((int)*cp)); cp++) ;
-
- /*
- * Check whether key matches
- */
- if (*cp)
- *cp++ = '\0';
-
- if (fn || (*key == *kp && STREQ(key, kp))) {
- while (*cp && isascii(*cp) && isspace((int)*cp))
- cp++;
- if (*cp) {
- /*
- * Return a copy of the data
- */
- char *dc = strdup(cp);
- if (fn) {
- (*fn) (m, strdup(kp), dc);
- } else {
- *val = dc;
- dlog("%s returns %s", key, dc);
- }
- if (!fn)
- return 0;
- } else {
- plog(XLOG_USER, "%s: line %d has no value field", map, line_no);
- }
- }
-
- again:
- /*
- * If the last read didn't get a whole line then
- * throw away the remainder before continuing...
- */
- if (chuck) {
- while (fgets(key_val, sizeof(key_val), fp) &&
- !strchr(key_val, '\n')) ;
- chuck = 0;
- }
- }
-
- return fn ? 0 : ENOENT;
-}
-
-
-static FILE *
-file_open(char *map, time_t *tp)
-{
- FILE *mapf = fopen(map, "r");
-
- if (mapf && tp) {
- struct stat stb;
- if (fstat(fileno(mapf), &stb) < 0)
- *tp = clocktime(NULL);
- else
- *tp = stb.st_mtime;
- }
- return mapf;
-}
-
-
-int
-file_init_or_mtime(mnt_map *m, char *map, time_t *tp)
-{
- FILE *mapf = file_open(map, tp);
-
- if (mapf) {
- fclose(mapf);
- return 0;
- }
- return errno;
-}
-
-
-int
-file_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *))
-{
- FILE *mapf = file_open(map, (time_t *) 0);
-
- if (mapf) {
- int error = file_search_or_reload(mapf, map, 0, 0, m, fn);
- (void) fclose(mapf);
- return error;
- }
- return errno;
-}
-
-
-int
-file_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
-{
- time_t t;
- FILE *mapf = file_open(map, &t);
-
- if (mapf) {
- int error;
- if (*tp < t) {
- *tp = t;
- error = -1;
- } else {
- error = file_search_or_reload(mapf, map, key, pval, 0, 0);
- }
- (void) fclose(mapf);
- return error;
- }
- return errno;
-}
diff --git a/contrib/amd/amd/info_hesiod.c b/contrib/amd/amd/info_hesiod.c
deleted file mode 100644
index e345c9961508..000000000000
--- a/contrib/amd/amd/info_hesiod.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/info_hesiod.c
- *
- */
-
-/*
- * Get info from Hesiod
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-#define HES_PREFIX "hesiod."
-#define HES_PREFLEN 7
-
-#ifdef HAVE_HESIOD_INIT
-/* bsdi3 does not define this extern in any header file */
-extern char **hesiod_resolve(void *context, const char *name, const char *type);
-extern int hesiod_init(void **context);
-static voidp hesiod_context;
-#endif /* HAVE_HESIOD_INIT */
-
-/* forward declarations */
-int amu_hesiod_init(mnt_map *m, char *map, time_t *tp);
-int hesiod_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
-int hesiod_isup(mnt_map *m, char *map);
-
-/*
- * No easy way to probe the server - check the map name begins with "hesiod."
- * Note: this name includes 'amu_' so as to not conflict with libhesiod's
- * hesiod_init() function.
- */
-int
-amu_hesiod_init(mnt_map *m, char *map, time_t *tp)
-{
- dlog("amu_hesiod_init(%s)", map);
- *tp = 0;
-
-#ifdef HAVE_HESIOD_INIT
- if (!hesiod_context && hesiod_init(&hesiod_context) != 0)
- return ENOENT;
-#endif /* HAVE_HESIOD_INIT */
-
- return NSTREQ(map, HES_PREFIX, HES_PREFLEN) ? 0 : ENOENT;
-}
-
-
-/*
- * Do a Hesiod nameserver call.
- * Modify time is ignored by Hesiod - XXX
- */
-int
-hesiod_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
-{
- char hes_key[MAXPATHLEN];
- char **rvec;
-#ifndef HAVE_HESIOD_INIT
- int error;
-#endif /* not HAVE_HESIOD_INIT */
-
- dlog("hesiod_search(m=%lx, map=%s, key=%s, pval=%lx tp=%lx)",
- (unsigned long) m, map, key, (unsigned long) pval, (unsigned long) tp);
-
- if (key[0] == '.')
- return ENOENT;
-
- xsnprintf(hes_key, sizeof(hes_key), "%s.%s", key, map + HES_PREFLEN);
-
- /*
- * Call the resolver
- */
- dlog("Hesiod base is: %s\n", gopt.hesiod_base);
- dlog("hesiod_search: hes_resolve(%s, %s)", hes_key, gopt.hesiod_base);
- if (amuDebug(D_INFO))
- _res.options |= RES_DEBUG;
-
-#ifdef HAVE_HESIOD_INIT
- /* new style hesiod */
- rvec = hesiod_resolve(hesiod_context, hes_key, gopt.hesiod_base);
-#else /* not HAVE_HESIOD_INIT */
- rvec = hes_resolve(hes_key, gopt.hesiod_base);
-#endif /* not HAVE_HESIOD_INIT */
-
- /*
- * If a reply was forthcoming then return
- * it (and free subsequent replies)
- */
- if (rvec && *rvec) {
- *pval = *rvec;
- while (*++rvec)
- XFREE(*rvec);
- return 0;
- }
-
-#ifdef HAVE_HESIOD_INIT
- /* new style hesiod */
- return errno;
-#else /* not HAVE_HESIOD_INIT */
- /*
- * Otherwise reflect the hesiod error into a Un*x error
- */
- dlog("hesiod_search: Error: %d", hes_error());
- switch (hes_error()) {
- case HES_ER_NOTFOUND:
- error = ENOENT;
- break;
- case HES_ER_CONFIG:
- error = EIO;
- break;
- case HES_ER_NET:
- error = ETIMEDOUT;
- break;
- default:
- error = EINVAL;
- break;
- }
- dlog("hesiod_search: Returning: %d", error);
- return error;
-#endif /* not HAVE_HESIOD_INIT */
-}
-
-
-/*
- * Check if Hesiod is up, so we can determine if to clear the map or not.
- * Test it by querying for /defaults.
- * Returns: 0 if Hesiod is down, 1 if it is up.
- */
-int
-hesiod_isup(mnt_map *m, char *map)
-{
- int error;
- char *val;
- time_t mtime;
- static int last_status = 1; /* assume up by default */
-
- error = hesiod_search(m, map, "/defaults", &val, &mtime);
- dlog("hesiod_isup(%s): %s", map, strerror(error));
- if (error != 0 && error != ENOENT) {
- plog(XLOG_ERROR,
- "hesiod_isup: error getting `/defaults' entry in map %s: %m", map);
- last_status = 0;
- return 0; /* Hesiod is down */
- }
- if (last_status == 0) { /* if was down before */
- plog(XLOG_INFO, "hesiod_isup: Hesiod came back up for map %s", map);
- last_status = 1;
- }
- return 1; /* Hesiod is up */
-}
diff --git a/contrib/amd/amd/info_ldap.c b/contrib/amd/amd/info_ldap.c
deleted file mode 100644
index 36ce1c8693d3..000000000000
--- a/contrib/amd/amd/info_ldap.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/info_ldap.c
- *
- */
-
-
-/*
- * Get info from LDAP (Lightweight Directory Access Protocol)
- * LDAP Home Page: http://www.umich.edu/~rsug/ldap/
- */
-
-/*
- * WARNING: as of Linux Fedora Core 5 (which comes with openldap-2.3.9), the
- * ldap.h headers deprecate several functions used in this file, such as
- * ldap_unbind. You get compile errors about missing extern definitions.
- * Those externs are still in <ldap.h>, but surrounded by an ifdef
- * LDAP_DEPRECATED. I am turning on that ifdef here, under the assumption
- * that the functions may be deprecated, but they still work for this
- * (older?) version of the LDAP API. It gets am-utils to compile, but it is
- * not clear if it will work perfectly.
- */
-#ifndef LDAP_DEPRECATED
-# define LDAP_DEPRECATED 1
-#endif /* not LDAP_DEPRECATED */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-
-/*
- * MACROS:
- */
-#define AMD_LDAP_TYPE "ldap"
-/* Time to live for an LDAP cached in an mnt_map */
-#define AMD_LDAP_TTL 3600
-#define AMD_LDAP_RETRIES 5
-#define AMD_LDAP_HOST "ldap"
-#ifndef LDAP_PORT
-# define LDAP_PORT 389
-#endif /* LDAP_PORT */
-
-/* How timestamps are searched */
-#define AMD_LDAP_TSFILTER "(&(objectClass=amdmapTimestamp)(amdmapName=%s))"
-/* How maps are searched */
-#define AMD_LDAP_FILTER "(&(objectClass=amdmap)(amdmapName=%s)(amdmapKey=%s))"
-/* How timestamps are stored */
-#define AMD_LDAP_TSATTR "amdmaptimestamp"
-/* How maps are stored */
-#define AMD_LDAP_ATTR "amdmapvalue"
-
-/*
- * TYPEDEFS:
- */
-typedef struct ald_ent ALD;
-typedef struct cr_ent CR;
-typedef struct he_ent HE_ENT;
-
-/*
- * STRUCTURES:
- */
-struct ald_ent {
- LDAP *ldap;
- HE_ENT *hostent;
- CR *credentials;
- time_t timestamp;
-};
-
-struct cr_ent {
- char *who;
- char *pw;
- int method;
-};
-
-struct he_ent {
- char *host;
- int port;
- struct he_ent *next;
-};
-
-/*
- * FORWARD DECLARATIONS:
- */
-static int amu_ldap_rebind(ALD *a);
-static int get_ldap_timestamp(ALD *a, char *map, time_t *ts);
-
-
-/*
- * FUNCTIONS:
- */
-
-static void
-he_free(HE_ENT *h)
-{
- XFREE(h->host);
- if (h->next != NULL)
- he_free(h->next);
- XFREE(h);
-}
-
-
-static HE_ENT *
-string2he(char *s_orig)
-{
- char *c, *p;
- char *s;
- HE_ENT *new, *old = NULL;
-
- if (NULL == s_orig || NULL == (s = strdup(s_orig)))
- return NULL;
- for (p = s; p; p = strchr(p, ',')) {
- if (old != NULL) {
- new = ALLOC(HE_ENT);
- old->next = new;
- old = new;
- } else {
- old = ALLOC(HE_ENT);
- old->next = NULL;
- }
- c = strchr(p, ':');
- if (c) { /* Host and port */
- *c++ = '\0';
- old->host = strdup(p);
- old->port = atoi(c);
- } else
- old->host = strdup(p);
-
- }
- XFREE(s);
- return (old);
-}
-
-
-static void
-cr_free(CR *c)
-{
- XFREE(c->who);
- XFREE(c->pw);
- XFREE(c);
-}
-
-
-/*
- * Special ldap_unbind function to handle SIGPIPE.
- * We first ignore SIGPIPE, in case a remote LDAP server was
- * restarted, then we reinstall the handler.
- */
-static int
-amu_ldap_unbind(LDAP *ld)
-{
- int e;
-#ifdef HAVE_SIGACTION
- struct sigaction sa;
-#else /* not HAVE_SIGACTION */
- void (*handler)(int);
-#endif /* not HAVE_SIGACTION */
-
- dlog("amu_ldap_unbind()\n");
-
-#ifdef HAVE_SIGACTION
- sa.sa_handler = SIG_IGN;
- sa.sa_flags = 0;
- sigemptyset(&(sa.sa_mask));
- sigaddset(&(sa.sa_mask), SIGPIPE);
- sigaction(SIGPIPE, &sa, &sa); /* set IGNORE, and get old action */
-#else /* not HAVE_SIGACTION */
- handler = signal(SIGPIPE, SIG_IGN);
-#endif /* not HAVE_SIGACTION */
-
- e = ldap_unbind(ld);
-
-#ifdef HAVE_SIGACTION
- sigemptyset(&(sa.sa_mask));
- sigaddset(&(sa.sa_mask), SIGPIPE);
- sigaction(SIGPIPE, &sa, NULL);
-#else /* not HAVE_SIGACTION */
- (void) signal(SIGPIPE, handler);
-#endif /* not HAVE_SIGACTION */
-
- return e;
-}
-
-
-static void
-ald_free(ALD *a)
-{
- he_free(a->hostent);
- cr_free(a->credentials);
- if (a->ldap != NULL)
- amu_ldap_unbind(a->ldap);
- XFREE(a);
-}
-
-
-int
-amu_ldap_init(mnt_map *m, char *map, time_t *ts)
-{
- ALD *aldh;
- CR *creds;
-
- dlog("-> amu_ldap_init: map <%s>\n", map);
-
- /*
- * XXX: by checking that map_type must be defined, aren't we
- * excluding the possibility of automatic searches through all
- * map types?
- */
- if (!gopt.map_type || !STREQ(gopt.map_type, AMD_LDAP_TYPE)) {
- dlog("amu_ldap_init called with map_type <%s>\n",
- (gopt.map_type ? gopt.map_type : "null"));
- } else {
- dlog("Map %s is ldap\n", map);
- }
-
- aldh = ALLOC(ALD);
- creds = ALLOC(CR);
- aldh->ldap = NULL;
- aldh->hostent = string2he(gopt.ldap_hostports);
- if (aldh->hostent == NULL) {
- plog(XLOG_USER, "Unable to parse hostport %s for ldap map %s",
- gopt.ldap_hostports ? gopt.ldap_hostports : "(null)", map);
- XFREE(creds);
- XFREE(aldh);
- return (ENOENT);
- }
- creds->who = "";
- creds->pw = "";
- creds->method = LDAP_AUTH_SIMPLE;
- aldh->credentials = creds;
- aldh->timestamp = 0;
- aldh->ldap = NULL;
- dlog("Trying for %s:%d\n", aldh->hostent->host, aldh->hostent->port);
- if (amu_ldap_rebind(aldh)) {
- ald_free(aldh);
- return (ENOENT);
- }
- m->map_data = (void *) aldh;
- dlog("Bound to %s:%d\n", aldh->hostent->host, aldh->hostent->port);
- if (get_ldap_timestamp(aldh, map, ts))
- return (ENOENT);
- dlog("Got timestamp for map %s: %ld\n", map, (u_long) *ts);
-
- return (0);
-}
-
-
-static int
-amu_ldap_rebind(ALD *a)
-{
- LDAP *ld;
- HE_ENT *h;
- CR *c = a->credentials;
- time_t now = clocktime(NULL);
- int try;
-
- dlog("-> amu_ldap_rebind\n");
-
- if (a->ldap != NULL) {
- if ((a->timestamp - now) > AMD_LDAP_TTL) {
- dlog("Re-establishing ldap connection\n");
- amu_ldap_unbind(a->ldap);
- a->timestamp = now;
- a->ldap = NULL;
- } else {
- /* Assume all is OK. If it wasn't we'll be back! */
- dlog("amu_ldap_rebind: timestamp OK\n");
- return (0);
- }
- }
-
- for (try=0; try<10; try++) { /* XXX: try up to 10 times (makes sense?) */
- for (h = a->hostent; h != NULL; h = h->next) {
- if ((ld = ldap_open(h->host, h->port)) == NULL) {
- plog(XLOG_WARNING, "Unable to ldap_open to %s:%d\n", h->host, h->port);
- break;
- }
-#if LDAP_VERSION_MAX > LDAP_VERSION2
- /* handle LDAPv3 and heigher, if available and amd.conf-igured */
- if (gopt.ldap_proto_version > LDAP_VERSION2) {
- if (!ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &gopt.ldap_proto_version)) {
- dlog("amu_ldap_rebind: LDAP protocol version set to %ld\n",
- gopt.ldap_proto_version);
- } else {
- plog(XLOG_WARNING, "Unable to set ldap protocol version to %ld\n",
- gopt.ldap_proto_version);
- break;
- }
- }
-#endif /* LDAP_VERSION_MAX > LDAP_VERSION2 */
- if (ldap_bind_s(ld, c->who, c->pw, c->method) != LDAP_SUCCESS) {
- plog(XLOG_WARNING, "Unable to ldap_bind to %s:%d as %s\n",
- h->host, h->port, c->who);
- break;
- }
- if (gopt.ldap_cache_seconds > 0) {
-#if defined(HAVE_LDAP_ENABLE_CACHE) && defined(HAVE_EXTERN_LDAP_ENABLE_CACHE)
- ldap_enable_cache(ld, gopt.ldap_cache_seconds, gopt.ldap_cache_maxmem);
-#else /* not defined(HAVE_LDAP_ENABLE_CACHE) && defined(HAVE_EXTERN_LDAP_ENABLE_CACHE) */
- plog(XLOG_WARNING, "ldap_enable_cache(%ld) is not available on this system!\n", gopt.ldap_cache_seconds);
-#endif /* not defined(HAVE_LDAP_ENABLE_CACHE) && defined(HAVE_EXTERN_LDAP_ENABLE_CACHE) */
- }
- a->ldap = ld;
- a->timestamp = now;
- return (0);
- }
- plog(XLOG_WARNING, "Exhausted list of ldap servers, looping.\n");
- }
-
- plog(XLOG_USER, "Unable to (re)bind to any ldap hosts\n");
- return (ENOENT);
-}
-
-
-static int
-get_ldap_timestamp(ALD *a, char *map, time_t *ts)
-{
- struct timeval tv;
- char **vals, *end;
- char filter[MAXPATHLEN];
- int i, err = 0, nentries = 0;
- LDAPMessage *res = NULL, *entry;
-
- dlog("-> get_ldap_timestamp: map <%s>\n", map);
-
- tv.tv_sec = 3;
- tv.tv_usec = 0;
- xsnprintf(filter, sizeof(filter), AMD_LDAP_TSFILTER, map);
- dlog("Getting timestamp for map %s\n", map);
- dlog("Filter is: %s\n", filter);
- dlog("Base is: %s\n", gopt.ldap_base);
- for (i = 0; i < AMD_LDAP_RETRIES; i++) {
- err = ldap_search_st(a->ldap,
- gopt.ldap_base,
- LDAP_SCOPE_SUBTREE,
- filter,
- 0,
- 0,
- &tv,
- &res);
- if (err == LDAP_SUCCESS)
- break;
- if (res) {
- ldap_msgfree(res);
- res = NULL;
- }
- plog(XLOG_USER, "Timestamp LDAP search attempt %d failed: %s\n",
- i + 1, ldap_err2string(err));
- if (err != LDAP_TIMEOUT) {
- dlog("get_ldap_timestamp: unbinding...\n");
- amu_ldap_unbind(a->ldap);
- a->ldap = NULL;
- if (amu_ldap_rebind(a))
- return (ENOENT);
- }
- dlog("Timestamp search failed, trying again...\n");
- }
-
- if (err != LDAP_SUCCESS) {
- *ts = 0;
- plog(XLOG_USER, "LDAP timestamp search failed: %s\n",
- ldap_err2string(err));
- if (res)
- ldap_msgfree(res);
- return (ENOENT);
- }
-
- nentries = ldap_count_entries(a->ldap, res);
- if (nentries == 0) {
- plog(XLOG_USER, "No timestamp entry for map %s\n", map);
- *ts = 0;
- ldap_msgfree(res);
- return (ENOENT);
- }
-
- entry = ldap_first_entry(a->ldap, res);
- vals = ldap_get_values(a->ldap, entry, AMD_LDAP_TSATTR);
- if (ldap_count_values(vals) == 0) {
- plog(XLOG_USER, "Missing timestamp value for map %s\n", map);
- *ts = 0;
- ldap_value_free(vals);
- ldap_msgfree(res);
- return (ENOENT);
- }
- dlog("TS value is:%s:\n", vals[0]);
-
- if (vals[0]) {
- *ts = (time_t) strtol(vals[0], &end, 10);
- if (end == vals[0]) {
- plog(XLOG_USER, "Unable to decode ldap timestamp %s for map %s\n",
- vals[0], map);
- err = ENOENT;
- }
- if (!*ts > 0) {
- plog(XLOG_USER, "Nonpositive timestamp %ld for map %s\n",
- (u_long) *ts, map);
- err = ENOENT;
- }
- } else {
- plog(XLOG_USER, "Empty timestamp value for map %s\n", map);
- *ts = 0;
- err = ENOENT;
- }
-
- ldap_value_free(vals);
- ldap_msgfree(res);
- dlog("The timestamp for %s is %ld (err=%d)\n", map, (u_long) *ts, err);
- return (err);
-}
-
-
-int
-amu_ldap_search(mnt_map *m, char *map, char *key, char **pval, time_t *ts)
-{
- char **vals, filter[MAXPATHLEN], filter2[2 * MAXPATHLEN];
- char *f1, *f2;
- struct timeval tv;
- int i, err = 0, nvals = 0, nentries = 0;
- LDAPMessage *entry, *res = NULL;
- ALD *a = (ALD *) (m->map_data);
-
- dlog("-> amu_ldap_search: map <%s>, key <%s>\n", map, key);
-
- tv.tv_sec = 2;
- tv.tv_usec = 0;
- if (a == NULL) {
- plog(XLOG_USER, "LDAP panic: no map data\n");
- return (EIO);
- }
- if (amu_ldap_rebind(a)) /* Check that's the handle is still valid */
- return (ENOENT);
-
- xsnprintf(filter, sizeof(filter), AMD_LDAP_FILTER, map, key);
- /* "*" is special to ldap_search(); run through the filter escaping it. */
- f1 = filter; f2 = filter2;
- while (*f1) {
- if (*f1 == '*') {
- *f2++ = '\\'; *f2++ = '2'; *f2++ = 'a';
- f1++;
- } else {
- *f2++ = *f1++;
- }
- }
- *f2 = '\0';
- dlog("Search with filter: <%s>\n", filter2);
- for (i = 0; i < AMD_LDAP_RETRIES; i++) {
- err = ldap_search_st(a->ldap,
- gopt.ldap_base,
- LDAP_SCOPE_SUBTREE,
- filter2,
- 0,
- 0,
- &tv,
- &res);
- if (err == LDAP_SUCCESS)
- break;
- if (res) {
- ldap_msgfree(res);
- res = NULL;
- }
- plog(XLOG_USER, "LDAP search attempt %d failed: %s\n",
- i + 1, ldap_err2string(err));
- if (err != LDAP_TIMEOUT) {
- dlog("amu_ldap_search: unbinding...\n");
- amu_ldap_unbind(a->ldap);
- a->ldap = NULL;
- if (amu_ldap_rebind(a))
- return (ENOENT);
- }
- }
-
- switch (err) {
- case LDAP_SUCCESS:
- break;
- case LDAP_NO_SUCH_OBJECT:
- dlog("No object\n");
- if (res)
- ldap_msgfree(res);
- return (ENOENT);
- default:
- plog(XLOG_USER, "LDAP search failed: %s\n",
- ldap_err2string(err));
- if (res)
- ldap_msgfree(res);
- return (EIO);
- }
-
- nentries = ldap_count_entries(a->ldap, res);
- dlog("Search found %d entries\n", nentries);
- if (nentries == 0) {
- ldap_msgfree(res);
- return (ENOENT);
- }
- entry = ldap_first_entry(a->ldap, res);
- vals = ldap_get_values(a->ldap, entry, AMD_LDAP_ATTR);
- nvals = ldap_count_values(vals);
- if (nvals == 0) {
- plog(XLOG_USER, "Missing value for %s in map %s\n", key, map);
- ldap_value_free(vals);
- ldap_msgfree(res);
- return (EIO);
- }
- dlog("Map %s, %s => %s\n", map, key, vals[0]);
- if (vals[0]) {
- *pval = strdup(vals[0]);
- err = 0;
- } else {
- plog(XLOG_USER, "Empty value for %s in map %s\n", key, map);
- err = ENOENT;
- }
- ldap_msgfree(res);
- ldap_value_free(vals);
-
- return (err);
-}
-
-
-int
-amu_ldap_mtime(mnt_map *m, char *map, time_t *ts)
-{
- ALD *aldh = (ALD *) (m->map_data);
-
- if (aldh == NULL) {
- dlog("LDAP panic: unable to find map data\n");
- return (ENOENT);
- }
- if (amu_ldap_rebind(aldh)) {
- return (ENOENT);
- }
- if (get_ldap_timestamp(aldh, map, ts)) {
- return (ENOENT);
- }
- return (0);
-}
diff --git a/contrib/amd/amd/info_ndbm.c b/contrib/amd/amd/info_ndbm.c
deleted file mode 100644
index 8a52ba9e201d..000000000000
--- a/contrib/amd/amd/info_ndbm.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/info_ndbm.c
- *
- */
-
-/*
- * Get info from NDBM map
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* forward declarations */
-int ndbm_init(mnt_map *m, char *map, time_t *tp);
-int ndbm_mtime(mnt_map *m, char *map, time_t *tp);
-int ndbm_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
-
-
-static int
-search_ndbm(DBM *db, char *key, char **val)
-{
- datum k, v;
-
- k.dptr = key;
- k.dsize = strlen(key) + 1;
- v = dbm_fetch(db, k);
- if (v.dptr) {
- *val = strdup(v.dptr);
- return 0;
- }
- return ENOENT;
-}
-
-
-int
-ndbm_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
-{
- DBM *db;
-
- db = dbm_open(map, O_RDONLY, 0);
- if (db) {
- struct stat stb;
- int error;
-#ifdef DBM_SUFFIX
- char dbfilename[256];
-
- xstrlcpy(dbfilename, map, sizeof(dbfilename));
- xstrlcat(dbfilename, DBM_SUFFIX, sizeof(dbfilename));
- error = stat(dbfilename, &stb);
-#else /* not DBM_SUFFIX */
- error = fstat(dbm_pagfno(db), &stb);
-#endif /* not DBM_SUFFIX */
- if (!error && *tp < stb.st_mtime) {
- *tp = stb.st_mtime;
- error = -1;
- } else {
- error = search_ndbm(db, key, pval);
- }
- (void) dbm_close(db);
- return error;
- }
- return errno;
-}
-
-
-int
-ndbm_init(mnt_map *m, char *map, time_t *tp)
-{
- DBM *db;
-
- db = dbm_open(map, O_RDONLY, 0);
- if (db) {
- struct stat stb;
- int error;
-#ifdef DBM_SUFFIX
- char dbfilename[256];
-
- xstrlcpy(dbfilename, map, sizeof(dbfilename));
- xstrlcat(dbfilename, DBM_SUFFIX, sizeof(dbfilename));
- error = stat(dbfilename, &stb);
-#else /* not DBM_SUFFIX */
- error = fstat(dbm_pagfno(db), &stb);
-#endif /* not DBM_SUFFIX */
- if (error < 0)
- *tp = clocktime(NULL);
- else
- *tp = stb.st_mtime;
- dbm_close(db);
- return 0;
- }
- return errno;
-}
-
-
-int
-ndbm_mtime(mnt_map *m, char *map, time_t *tp)
-{
- return ndbm_init(m,map, tp);
-}
diff --git a/contrib/amd/amd/info_nis.c b/contrib/amd/amd/info_nis.c
deleted file mode 100644
index bcb87d5d02aa..000000000000
--- a/contrib/amd/amd/info_nis.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/info_nis.c
- *
- */
-
-/*
- * Get info from NIS map
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-
-/*
- * NIS+ servers in NIS compat mode don't have yp_order()
- *
- * has_yp_order = 1 NIS server
- * = 0 NIS+ server
- * = -1 server is down
- */
-static int has_yp_order = -1;
-
-/* forward declarations */
-int nis_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *));
-int nis_search(mnt_map *m, char *map, char *key, char **val, time_t *tp);
-int nis_init(mnt_map *m, char *map, time_t *tp);
-int nis_isup(mnt_map *m, char *map);
-int nis_mtime(mnt_map *m, char *map, time_t *tp);
-
-/* typedefs */
-typedef void (*nis_callback_fxn_t)(mnt_map *, char *, char *);
-#ifndef DEFINED_YPALL_CALLBACK_FXN_T
-typedef int (*ypall_callback_fxn_t)();
-#endif /* DEFINED_YPALL_CALLBACK_FXN_T */
-
-struct nis_callback_data {
- mnt_map *ncd_m;
- char *ncd_map;
- nis_callback_fxn_t ncd_fn;
-};
-
-/* Map to the right version of yp_all */
-#ifdef HAVE_BAD_YP_ALL
-# define yp_all am_yp_all
-static int am_yp_all(char *indomain, char *inmap, struct ypall_callback *incallback);
-#endif /* HAVE_BAD_YP_ALL */
-
-
-/*
- * Figure out the nis domain name
- */
-static int
-determine_nis_domain(void)
-{
- static int nis_not_running = 0;
- char default_domain[YPMAXDOMAIN];
-
- if (nis_not_running)
- return ENOENT;
-
- if (getdomainname(default_domain, sizeof(default_domain)) < 0) {
- nis_not_running = 1;
- plog(XLOG_ERROR, "getdomainname: %m");
- return EIO;
- }
- if (!*default_domain) {
- nis_not_running = 1;
- plog(XLOG_WARNING, "NIS domain name is not set. NIS ignored.");
- return ENOENT;
- }
- gopt.nis_domain = strdup(default_domain);
-
- return 0;
-}
-
-
-/*
- * Callback from yp_all
- */
-static int
-callback(int status, char *key, int kl, char *val, int vl, char *data)
-{
- struct nis_callback_data *ncdp = (struct nis_callback_data *) data;
-
- if (status == YP_TRUE) {
-
- /* add to list of maps */
- char *kp = strnsave(key, kl);
- char *vp = strnsave(val, vl);
-
- (*ncdp->ncd_fn) (ncdp->ncd_m, kp, vp);
-
- /* we want more ... */
- return FALSE;
-
- } else {
-
- /* NOMORE means end of map - otherwise log error */
- if (status != YP_NOMORE) {
- /* check what went wrong */
- int e = ypprot_err(status);
-
- plog(XLOG_ERROR, "yp enumeration of %s: %s, status=%d, e=%d",
- ncdp->ncd_map, yperr_string(e), status, e);
- }
- return TRUE;
- }
-}
-
-
-int
-nis_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *))
-{
- int error;
- struct nis_callback_data data;
- struct ypall_callback cbinfo;
-
- if (!gopt.nis_domain) {
- error = determine_nis_domain();
- if (error)
- return error;
- }
- data.ncd_m = m;
- data.ncd_map = map;
- data.ncd_fn = fn;
- cbinfo.data = (voidp) &data;
- cbinfo.foreach = (ypall_callback_fxn_t) callback;
-
- /*
- * If you are using NIS and your yp_all function is "broken", you have to
- * get it fixed. The bug in yp_all() is that it does not close a TCP
- * connection to ypserv, and this ypserv runs out of open file descriptors,
- * getting into an infinite loop, thus all YP clients eventually unbind
- * and hang too.
- */
- error = yp_all(gopt.nis_domain, map, &cbinfo);
-
- if (error)
- plog(XLOG_ERROR, "error grabbing nis map of %s: %s", map, yperr_string(ypprot_err(error)));
- return error;
-}
-
-
-/*
- * Check if NIS is up, so we can determine if to clear the map or not.
- * Test it by checking the yp order.
- * Returns: 0 if NIS is down, 1 if it is up.
- */
-int
-nis_isup(mnt_map *m, char *map)
-{
- YP_ORDER_OUTORDER_TYPE order;
- int error;
- char *master;
- static int last_status = 1; /* assume up by default */
-
- switch (has_yp_order) {
- case 1:
- /*
- * NIS server with yp_order
- */
- error = yp_order(gopt.nis_domain, map, &order);
- if (error != 0) {
- plog(XLOG_ERROR,
- "nis_isup: error getting the order of map %s: %s",
- map, yperr_string(ypprot_err(error)));
- last_status = 0;
- return 0; /* NIS is down */
- }
- break;
-
- case 0:
- /*
- * NIS+ server without yp_order
- */
- error = yp_master(gopt.nis_domain, map, &master);
- if (error != 0) {
- plog(XLOG_ERROR,
- "nis_isup: error getting the master of map %s: %s",
- map, yperr_string(ypprot_err(error)));
- last_status = 0;
- return 0; /* NIS+ is down */
- }
- break;
-
- default:
- /*
- * server was down
- */
- last_status = 0;
- }
-
- if (last_status == 0) { /* reinitialize if was down before */
- time_t dummy;
- error = nis_init(m, map, &dummy);
- if (error)
- return 0; /* still down */
- plog(XLOG_INFO, "nis_isup: NIS came back up for map %s", map);
- last_status = 1;
- }
- return 1; /* NIS is up */
-}
-
-
-/*
- * Try to locate a key using NIS.
- */
-int
-nis_search(mnt_map *m, char *map, char *key, char **val, time_t *tp)
-{
- int outlen;
- int res;
- YP_ORDER_OUTORDER_TYPE order;
-
- /*
- * Make sure domain initialized
- */
- if (!gopt.nis_domain) {
- int error = determine_nis_domain();
- if (error)
- return error;
- }
-
-
- switch (has_yp_order) {
- case 1:
- /*
- * NIS server with yp_order
- * Check if map has changed
- */
- if (yp_order(gopt.nis_domain, map, &order))
- return EIO;
- if ((time_t) order > *tp) {
- *tp = (time_t) order;
- return -1;
- }
- break;
-
- case 0:
- /*
- * NIS+ server without yp_order
- * Check if timeout has expired to invalidate the cache
- */
- order = time(NULL);
- if ((time_t)order - *tp > gopt.am_timeo) {
- *tp = (time_t)order;
- return(-1);
- }
- break;
-
- default:
- /*
- * server was down
- */
- if (nis_isup(m, map))
- return -1;
- return EIO;
- }
-
- /*
- * Lookup key
- */
- res = yp_match(gopt.nis_domain, map, key, strlen(key), val, &outlen);
-
- /*
- * Do something interesting with the return code
- */
- switch (res) {
- case 0:
- return 0;
-
- case YPERR_KEY:
- return ENOENT;
-
- default:
- plog(XLOG_ERROR, "nis_search: %s: %s", map, yperr_string(res));
- return EIO;
- }
-}
-
-
-int
-nis_init(mnt_map *m, char *map, time_t *tp)
-{
- YP_ORDER_OUTORDER_TYPE order;
- int yp_order_result;
- char *master;
-
- if (!gopt.nis_domain) {
- int error = determine_nis_domain();
- if (error)
- return error;
- }
-
- /*
- * To see if the map exists, try to find
- * a master for it.
- */
- yp_order_result = yp_order(gopt.nis_domain, map, &order);
- switch (yp_order_result) {
- case 0:
- /* NIS server found */
- has_yp_order = 1;
- *tp = (time_t) order;
- dlog("NIS master for %s@%s has order %lu", map, gopt.nis_domain, (unsigned long) order);
- break;
- case YPERR_YPERR:
- /* NIS+ server found ! */
- has_yp_order = 0;
- /* try yp_master() instead */
- if (yp_master(gopt.nis_domain, map, &master)) {
- return ENOENT;
- } else {
- dlog("NIS master for %s@%s is a NIS+ server", map, gopt.nis_domain);
- /* Use fake timestamps */
- *tp = time(NULL);
- }
- break;
- default:
- /* server is down */
- has_yp_order = -1;
- return ENOENT;
- }
- return 0;
-}
-
-
-int
-nis_mtime(mnt_map *m, char *map, time_t *tp)
-{
- return nis_init(m, map, tp);
-}
-
-
-#ifdef HAVE_BAD_YP_ALL
-/*
- * If you are using NIS and your yp_all function is "broken", use an
- * alternate code which avoids a bug in yp_all(). The bug in yp_all() is
- * that it does not close a TCP connection to ypserv, and this ypserv runs
- * out of open filedescriptors, getting into an infinite loop, thus all YP
- * clients eventually unbind and hang too.
- *
- * Systems known to be plagued with this bug:
- * earlier SunOS 4.x
- * all irix systems (at this time, up to 6.4 was checked)
- *
- * -Erez Zadok <ezk@cs.columbia.edu>
- * -James Tanis <jtt@cs.columbia.edu> */
-static int
-am_yp_all(char *indomain, char *inmap, struct ypall_callback *incallback)
-{
- int i, j;
- char *outkey, *outval;
- int outkeylen, outvallen;
- char *outkey_old;
- int outkeylen_old;
-
- plog(XLOG_INFO, "NIS map %s reloading using am_yp_all", inmap);
-
- i = yp_first(indomain, inmap, &outkey, &outkeylen, &outval, &outvallen);
- if (i) {
- plog(XLOG_ERROR, "yp_first() returned error: %s\n", yperr_string(i));
- }
- do {
- j = (incallback->foreach)(YP_TRUE,
- outkey,
- outkeylen,
- outval,
- outvallen,
- incallback->data);
- if (j != FALSE) /* terminate loop */
- break;
-
- /*
- * We have to manually free all char ** arguments to yp_first/yp_next
- * outval must be freed *before* calling yp_next again, outkey can be
- * freed as outkey_old *after* the call (this saves one call to
- * strnsave).
- */
- XFREE(outval);
- outkey_old = outkey;
- outkeylen_old = outkeylen;
- i = yp_next(indomain,
- inmap,
- outkey_old,
- outkeylen_old,
- &outkey,
- &outkeylen,
- &outval,
- &outvallen);
- XFREE(outkey_old);
- } while (!i);
- if (i) {
- dlog("yp_next() returned error: %s\n", yperr_string(i));
- }
- if (i == YPERR_NOMORE)
- return 0;
- return i;
-}
-#endif /* HAVE_BAD_YP_ALL */
diff --git a/contrib/amd/amd/info_nisplus.c b/contrib/amd/amd/info_nisplus.c
deleted file mode 100644
index d392b48fed6a..000000000000
--- a/contrib/amd/amd/info_nisplus.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/info_nisplus.c
- *
- */
-
-/*
- * Get info from NIS+ (version 3) map
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-#define NISPLUS_KEY "key="
-#define NISPLUS_ORGDIR ".org_dir"
-
-struct nis_callback_data {
- mnt_map *ncd_m;
- char *ncd_map;
- void (*ncd_fn)();
-};
-
-struct nisplus_search_callback_data {
- nis_name key;
- char *value;
-};
-
-
-static int
-nisplus_callback(const nis_name key, const nis_object *value, voidp opaquedata)
-{
- char *kp = strnsave(ENTRY_VAL(value, 0), ENTRY_LEN(value, 0));
- char *vp = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1));
- struct nis_callback_data *data = (struct nis_callback_data *) opaquedata;
-
- dlog("NISplus callback for <%s,%s>", kp, vp);
-
- (*data->ncd_fn) (data->ncd_m, kp, vp);
-
- /*
- * We want more ...
- */
- return FALSE;
-}
-
-
-int
-nisplus_reload(mnt_map *m, char *map, void (*fn) ())
-{
- int error = 0;
- struct nis_callback_data data;
- nis_result *result;
- char *org; /* if map does not have ".org_dir" then append it */
- nis_name map_name;
- size_t l;
-
- org = strstr(map, NISPLUS_ORGDIR);
- if (org == NULL)
- org = NISPLUS_ORGDIR;
- else
- org = "";
-
- /* make some room for the NIS map_name */
- l = strlen(map) + sizeof(NISPLUS_ORGDIR);
- map_name = xmalloc(l);
- if (map_name == NULL) {
- plog(XLOG_ERROR, "Unable to create map_name %s: %s",
- map, strerror(ENOMEM));
- return ENOMEM;
- }
- xsnprintf(map_name, l, "%s%s", map, org);
-
- data.ncd_m = m;
- data.ncd_map = map_name;
- data.ncd_fn = fn;
-
- dlog("NISplus reload for %s", map);
-
- result = nis_list(map_name,
- EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH,
- (int (*)()) nisplus_callback,
- &data);
-
- /* free off the NIS map_name */
- XFREE(map_name);
-
- if (result->status != NIS_SUCCESS && result->status != NIS_CBRESULTS)
- error = 1;
-
- if (error)
- plog(XLOG_ERROR, "error grabbing nisplus map of %s: %s",
- map,
- nis_sperrno(result->status));
-
- nis_freeresult(result);
- return error;
-}
-
-
-static int
-nisplus_search_callback(const nis_name key, const nis_object *value, voidp opaquedata)
-{
- struct nisplus_search_callback_data *data = (struct nisplus_search_callback_data *) opaquedata;
-
- dlog("NISplus search callback for <%s>", ENTRY_VAL(value, 0));
- dlog("NISplus search callback value <%s>", ENTRY_VAL(value, 1));
-
- data->value = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1));
- return TRUE;
-}
-
-
-/*
- * Try to locate a key using NIS+.
- */
-int
-nisplus_search(mnt_map *m, char *map, char *key, char **val, time_t *tp)
-{
- nis_result *result;
- int error = 0;
- struct nisplus_search_callback_data data;
- nis_name index;
- char *org; /* if map does not have ".org_dir" then append it */
- size_t l;
-
- org = strstr(map, NISPLUS_ORGDIR);
- if (org == NULL)
- org = NISPLUS_ORGDIR;
- else
- org = "";
-
- /* make some room for the NIS index */
- l = sizeof('[') /* for opening selection criteria */
- + sizeof(NISPLUS_KEY)
- + strlen(key)
- + sizeof(']') /* for closing selection criteria */
- + sizeof(',') /* + 1 for , separator */
- + strlen(map)
- + sizeof(NISPLUS_ORGDIR);
- index = xmalloc(l);
- if (index == NULL) {
- plog(XLOG_ERROR,
- "Unable to create index %s: %s",
- map,
- strerror(ENOMEM));
- return ENOMEM;
- }
- xsnprintf(index, l, "[%s%s],%s%s", NISPLUS_KEY, key, map, org);
-
- data.key = key;
- data.value = NULL;
-
- dlog("NISplus search for %s", index);
-
- result = nis_list(index,
- EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH,
- (int (*)()) nisplus_search_callback,
- &data);
-
- /* free off the NIS index */
- XFREE(index);
-
- if (result == NULL) {
- plog(XLOG_ERROR, "nisplus_search: %s: %s", map, strerror(ENOMEM));
- return ENOMEM;
- }
-
- /*
- * Do something interesting with the return code
- */
- switch (result->status) {
- case NIS_SUCCESS:
- case NIS_CBRESULTS:
-
- if (data.value == NULL) {
- nis_object *value = result->objects.objects_val;
- dlog("NISplus search found <nothing>");
- dlog("NISplus search for %s: %s(%d)",
- map, nis_sperrno(result->status), result->status);
-
- if (value != NULL)
- data.value = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1));
- }
- *val = data.value;
-
- if (*val) {
- error = 0;
- dlog("NISplus search found %s", *val);
- } else {
- error = ENOENT;
- dlog("NISplus search found nothing");
- }
-
- *tp = 0;
- break;
-
- case NIS_NOSUCHNAME:
- dlog("NISplus search returned %d", result->status);
- error = ENOENT;
- break;
-
- default:
- plog(XLOG_ERROR, "nisplus_search: %s: %s", map, nis_sperrno(result->status));
- error = EIO;
- break;
- }
- nis_freeresult(result);
-
- return error;
-}
-
-
-int
-nisplus_init(mnt_map *m, char *map, time_t *tp)
-{
- nis_result *result;
- char *org; /* if map does not have ".org_dir" then append it */
- nis_name map_name;
- int error = 0;
- size_t l;
-
- org = strstr(map, NISPLUS_ORGDIR);
- if (org == NULL)
- org = NISPLUS_ORGDIR;
- else
- org = "";
-
- /* make some room for the NIS map_name */
- l = strlen(map) + sizeof(NISPLUS_ORGDIR);
- map_name = xmalloc(l);
- if (map_name == NULL) {
- plog(XLOG_ERROR,
- "Unable to create map_name %s: %s",
- map,
- strerror(ENOMEM));
- return ENOMEM;
- }
- xsnprintf(map_name, l, "%s%s", map, org);
-
- result = nis_lookup(map_name, (EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH));
-
- /* free off the NIS map_name */
- XFREE(map_name);
-
- if (result == NULL) {
- plog(XLOG_ERROR, "NISplus init <%s>: %s", map, strerror(ENOMEM));
- return ENOMEM;
- }
-
- if (result->status != NIS_SUCCESS) {
- dlog("NISplus init <%s>: %s (%d)",
- map, nis_sperrno(result->status), result->status);
-
- error = ENOENT;
- }
-
- *tp = 0; /* no time */
- nis_freeresult(result);
- return error;
-}
-
-
-int
-nisplus_mtime(mnt_map *m, char *map, time_t *tp)
-{
- return nisplus_init(m,map, tp);
-}
diff --git a/contrib/amd/amd/info_passwd.c b/contrib/amd/amd/info_passwd.c
deleted file mode 100644
index c8bf388b1d65..000000000000
--- a/contrib/amd/amd/info_passwd.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/info_passwd.c
- *
- */
-
-/*
- * Get info from password "file"
- *
- * This is experimental and probably doesn't do what you expect.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-#define PASSWD_MAP "/etc/passwd"
-
-/* forward declarations */
-int passwd_init(mnt_map *m, char *map, time_t *tp);
-int passwd_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
-
-
-/*
- * Nothing to probe - check the map name is PASSWD_MAP.
- */
-int
-passwd_init(mnt_map *m, char *map, time_t *tp)
-{
- *tp = 0;
-
- /*
- * Recognize the old format "PASSWD_MAP"
- * Uses default return string
- * "type:=nfs;rfs:=/${var0}/${var1};rhost:=${var1};sublink:=${var2};fs:=${autodir}${var3}"
- */
- if (STREQ(map, PASSWD_MAP))
- return 0;
- /*
- * Recognize the new format "PASSWD_MAP:pval-format"
- */
- if (!NSTREQ(map, PASSWD_MAP, sizeof(PASSWD_MAP) - 1))
- return ENOENT;
- if (map[sizeof(PASSWD_MAP)-1] != ':')
- return ENOENT;
-
- return 0;
-}
-
-
-/*
- * Grab the entry via the getpwname routine
- * Modify time is ignored by passwd - XXX
- */
-int
-passwd_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
-{
- char *dir = 0;
- struct passwd *pw;
-
- if (STREQ(key, "/defaults")) {
- *pval = strdup("type:=nfs");
- return 0;
- }
- pw = getpwnam(key);
-
- if (pw) {
- /*
- * We chop the home directory up as follows:
- * /anydir/dom1/dom2/dom3/user
- *
- * and return
- * rfs:=/anydir/dom3;rhost:=dom3.dom2.dom1;sublink:=user
- * and now have
- * var0:=pw-prefix:=anydir
- * var1:=pw-rhost:=dom3.dom2.dom1
- * var2:=pw-user:=user
- * var3:=pw-home:=/anydir/dom1/dom2/dom3/user
- *
- * This allows cross-domain entries in your passwd file.
- * ... but forget about security!
- */
- char *user;
- char *p, *q;
- char val[MAXPATHLEN];
- char rhost[MAXHOSTNAMELEN];
- dir = strdup(pw->pw_dir);
-
- /*
- * Find user name. If no / then Invalid...
- */
- user = strrchr(dir, '/');
- if (!user)
- goto enoent;
- *user++ = '\0';
-
- /*
- * Find start of host "path". If no / then Invalid...
- */
- p = strchr(dir + 1, '/');
- if (!p)
- goto enoent;
- *p++ = '\0';
-
- /*
- * At this point, p is dom1/dom2/dom3
- * Copy, backwards, into rhost replacing
- * / with .
- */
- rhost[0] = '\0';
- do {
- q = strrchr(p, '/');
- if (q) {
- xstrlcat(rhost, q + 1, sizeof(rhost));
- xstrlcat(rhost, ".", sizeof(rhost));
- *q = '\0';
- } else {
- xstrlcat(rhost, p, sizeof(rhost));
- }
- } while (q);
-
- /*
- * Sanity check
- */
- if (*rhost == '\0' || *user == '\0' || *dir == '\0')
- goto enoent;
-
- /*
- * Make up return string
- */
- q = strchr(rhost, '.');
- if (q)
- *q = '\0';
- p = strchr(map, ':');
- if (p)
- p++;
- else
- p = "type:=nfs;rfs:=/${var0}/${var1};rhost:=${var1};sublink:=${var2};fs:=${autodir}${var3}";
- xsnprintf(val, sizeof(val), "var0:=%s;var1:=%s;var2:=%s;var3:=%s;%s",
- dir+1, rhost, user, pw->pw_dir, p);
- dlog("passwd_search: map=%s key=%s -> %s", map, key, val);
- if (q)
- *q = '.';
- *pval = strdup(val);
- return 0;
- }
-
-enoent:
- if (dir)
- XFREE(dir);
-
- return ENOENT;
-}
diff --git a/contrib/amd/amd/info_union.c b/contrib/amd/amd/info_union.c
deleted file mode 100644
index 8f0631c64ac9..000000000000
--- a/contrib/amd/amd/info_union.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/info_union.c
- *
- */
-
-/*
- * Get info from the system namespace
- *
- * NOTE: Cannot handle reads back through the automounter.
- * THIS WILL CAUSE A DEADLOCK!
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-#define UNION_PREFIX "union:"
-#define UNION_PREFLEN 6
-
-/* forward declarations */
-int union_init(mnt_map *m, char *map, time_t *tp);
-int union_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
-int union_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *));
-
-
-/*
- * No way to probe - check the map name begins with "union:"
- */
-int
-union_init(mnt_map *m, char *map, time_t *tp)
-{
- *tp = 0;
- return NSTREQ(map, UNION_PREFIX, UNION_PREFLEN) ? 0 : ENOENT;
-}
-
-
-int
-union_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
-{
- char *mapd = strdup(map + UNION_PREFLEN);
- char **v = strsplit(mapd, ':', '\"');
- char **p;
- size_t l;
-
- for (p = v; p[1]; p++) ;
- l = strlen(*p) + 5;
- *pval = xmalloc(l);
- xsnprintf(*pval, l, "fs:=%s", *p);
- XFREE(mapd);
- XFREE(v);
- return 0;
-}
-
-
-int
-union_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *))
-{
- char *mapd = strdup(map + UNION_PREFLEN);
- char **v = strsplit(mapd, ':', '\"');
- char **dir;
-
- /*
- * Add fake /defaults entry
- */
- (*fn) (m, strdup("/defaults"), strdup("type:=link;opts:=nounmount;sublink:=${key}"));
-
- for (dir = v; *dir; dir++) {
- size_t l;
- struct dirent *dp;
-
- DIR *dirp = opendir(*dir);
- if (!dirp) {
- plog(XLOG_USER, "Cannot read directory %s: %m", *dir);
- continue;
- }
- l = strlen(*dir) + 5;
-
- dlog("Reading directory %s...", *dir);
- while ((dp = readdir(dirp))) {
- char *val, *dpname = &dp->d_name[0];
- if (dpname[0] == '.' &&
- (dpname[1] == '\0' ||
- (dpname[1] == '.' && dpname[2] == '\0')))
- continue;
-
- dlog("... gives %s", dp->d_name);
- val = xmalloc(l);
- xsnprintf(val, l + 5, "fs:=%s", *dir);
- (*fn) (m, strdup(dp->d_name), val);
- }
- closedir(dirp);
- }
-
- /*
- * Add wildcard entry
- */
- {
- size_t l = strlen(*(dir-1)) + 5;
- char *val = xmalloc(l);
-
- xsnprintf(val, l, "fs:=%s", *(dir-1));
- (*fn) (m, strdup("*"), val);
- }
- XFREE(mapd);
- XFREE(v);
- return 0;
-}
diff --git a/contrib/amd/amd/map.c b/contrib/amd/amd/map.c
deleted file mode 100644
index 8696dfd6984d..000000000000
--- a/contrib/amd/amd/map.c
+++ /dev/null
@@ -1,1072 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/map.c
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-#define smallest_t(t1, t2) (t1 != NEVER ? (t2 != NEVER ? (t1 < t2 ? t1 : t2) : t1) : t2)
-#define IGNORE_FLAGS (MFF_MOUNTING|MFF_UNMOUNTING|MFF_RESTART)
-#define new_gen() (am_gen++)
-
-/*
- * Generation Numbers.
- *
- * Generation numbers are allocated to every node created
- * by amd. When a filehandle is computed and sent to the
- * kernel, the generation number makes sure that it is safe
- * to reallocate a node slot even when the kernel has a cached
- * reference to its old incarnation.
- * No garbage collection is done, since it is assumed that
- * there is no way that 2^32 generation numbers could ever
- * be allocated by a single run of amd - there is simply
- * not enough cpu time available.
- * Famous last words... -Ion
- */
-static u_int am_gen = 2; /* Initial generation number */
-static int timeout_mp_id; /* Id from last call to timeout */
-
-static am_node *root_node; /* The root of the mount tree */
-static am_node **exported_ap = (am_node **) 0;
-static int exported_ap_size = 0;
-static int first_free_map = 0; /* First available free slot */
-static int last_used_map = -1; /* Last unavailable used slot */
-
-
-/*
- * 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 nfsfattr 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 */
-};
-
-/* forward declarations */
-static int unmount_node(opaque_t arg);
-static void exported_ap_free(am_node *mp);
-static void remove_am(am_node *mp);
-static am_node *get_root_ap(char *dir);
-
-
-/*
- * Iterator functions for exported_ap[]
- */
-am_node *
-get_first_exported_ap(int *index)
-{
- *index = -1;
- return get_next_exported_ap(index);
-}
-
-
-am_node *
-get_next_exported_ap(int *index)
-{
- (*index)++;
- while (*index < exported_ap_size) {
- if (exported_ap[*index] != NULL)
- return exported_ap[*index];
- (*index)++;
- }
- return NULL;
-}
-
-
-/*
- * Get exported_ap by index
- */
-am_node *
-get_exported_ap(int index)
-{
- if (index < 0 || index >= exported_ap_size)
- return 0;
- return exported_ap[index];
-}
-
-
-/*
- * Get exported_ap by path
- */
-am_node *
-path_to_exported_ap(char *path)
-{
- int index;
- am_node *mp;
-
- mp = get_first_exported_ap(&index);
- while (mp != NULL) {
- if (STREQ(mp->am_path, path))
- break;
- mp = get_next_exported_ap(&index);
- }
- return mp;
-}
-
-
-/*
- * Resize exported_ap map
- */
-static int
-exported_ap_realloc_map(int nsize)
-{
- /*
- * 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)
- memset((char *) (exported_ap + exported_ap_size), 0,
- (nsize - exported_ap_size) * sizeof(am_node *));
- exported_ap_size = nsize;
-
- return 1;
-}
-
-
-
-am_node *
-get_ap_child(am_node *mp, char *fname)
-{
- am_node *new_mp;
- mntfs *mf = mp->am_mnt;
-
- /*
- * Allocate a new map
- */
- new_mp = exported_ap_alloc();
- if (new_mp) {
- /*
- * Fill it in
- */
- init_map(new_mp, fname);
-
- /*
- * Put it in the table
- */
- insert_am(new_mp, mp);
-
- /*
- * Fill in some other fields,
- * 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,
- (mf->mf_fsflags & FS_DIRECT)
- ? ""
- : mp->am_path,
- *fname == '/' ? "" : "/", fname);
- dlog("setting path to %s", new_mp->am_path);
- }
-
- return new_mp;
-}
-
-/*
- * Allocate a new mount slot and create
- * a new node.
- * Fills in the map number of the node,
- * but leaves everything else uninitialized.
- */
-am_node *
-exported_ap_alloc(void)
-{
- am_node *mp, **mpp;
-
- /*
- * First check if there are any slots left, realloc if needed
- */
- if (first_free_map >= exported_ap_size)
- if (!exported_ap_realloc_map(exported_ap_size + NEXP_AP))
- return 0;
-
- /*
- * Grab the next free slot
- */
- mpp = exported_ap + first_free_map;
- mp = *mpp = ALLOC(struct am_node);
- memset((char *) mp, 0, sizeof(struct am_node));
-
- mp->am_mapno = first_free_map++;
-
- /*
- * Update free pointer
- */
- 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;
-
- return mp;
-}
-
-
-/*
- * Free a mount slot
- */
-static void
-exported_ap_free(am_node *mp)
-{
- /*
- * Sanity check
- */
- if (!mp)
- return;
-
- /*
- * Zero the slot pointer to avoid double free's
- */
- exported_ap[mp->am_mapno] = 0;
-
- /*
- * Update the free and last_used indices
- */
- if (mp->am_mapno == last_used_map)
- while (last_used_map >= 0 && exported_ap[last_used_map] == 0)
- --last_used_map;
-
- if (first_free_map > mp->am_mapno)
- first_free_map = mp->am_mapno;
-
- /*
- * Free the mount node, and zero out it's internal struct data.
- */
- memset((char *) mp, 0, sizeof(am_node));
- XFREE(mp);
-}
-
-
-/*
- * Insert mp into the correct place,
- * where p_mp is its parent node.
- * A new node gets placed as the youngest sibling
- * of any other children, and the parent's child
- * pointer is adjusted to point to the new child node.
- */
-void
-insert_am(am_node *mp, am_node *p_mp)
-{
- /*
- * If this is going in at the root then flag it
- * so that it cannot be unmounted by amq.
- */
- if (p_mp == root_node)
- mp->am_flags |= AMF_ROOT;
- /*
- * Fill in n-way links
- */
- mp->am_parent = p_mp;
- mp->am_osib = p_mp->am_child;
- if (mp->am_osib)
- mp->am_osib->am_ysib = mp;
- p_mp->am_child = mp;
-#ifdef HAVE_FS_AUTOFS
- if (p_mp->am_mnt->mf_flags & MFF_IS_AUTOFS)
- mp->am_flags |= AMF_AUTOFS;
-#endif /* HAVE_FS_AUTOFS */
-}
-
-
-/*
- * Remove am from its place in the mount tree
- */
-static void
-remove_am(am_node *mp)
-{
- /*
- * 1. Consistency check
- */
- if (mp->am_child && mp->am_parent) {
- plog(XLOG_WARNING, "children of \"%s\" still exist - deleting anyway", mp->am_path);
- }
-
- /*
- * 2. Update parent's child pointer
- */
- if (mp->am_parent && mp->am_parent->am_child == mp)
- mp->am_parent->am_child = mp->am_osib;
-
- /*
- * 3. Unlink from sibling chain
- */
- if (mp->am_ysib)
- mp->am_ysib->am_osib = mp->am_osib;
- if (mp->am_osib)
- mp->am_osib->am_ysib = mp->am_ysib;
-}
-
-
-/*
- * Compute a new time to live value for a node.
- */
-void
-new_ttl(am_node *mp)
-{
- mp->am_timeo_w = 0;
- mp->am_ttl = clocktime(&mp->am_fattr.na_atime);
- mp->am_ttl += mp->am_timeo; /* sun's -tl option */
-}
-
-
-void
-mk_fattr(nfsfattr *fattr, nfsftype vntype)
-{
- switch (vntype) {
- case NFDIR:
- fattr->na_type = NFDIR;
- fattr->na_mode = NFSMODE_DIR | 0555;
- fattr->na_nlink = 2;
- fattr->na_size = 512;
- break;
- case NFLNK:
- fattr->na_type = NFLNK;
- fattr->na_mode = NFSMODE_LNK | 0777;
- fattr->na_nlink = 1;
- fattr->na_size = 0;
- break;
- default:
- plog(XLOG_FATAL, "Unknown fattr type %d - ignored", vntype);
- break;
- }
-}
-
-
-/*
- * Initialize an allocated mount node.
- * It is assumed that the mount node was b-zero'd
- * before getting here so anything that would
- * be set to zero isn't done here.
- */
-void
-init_map(am_node *mp, char *dir)
-{
- /*
- * mp->am_mapno is initialized by exported_ap_alloc
- * other fields don't need to be set to zero.
- */
- mp->am_mnt = new_mntfs();
- mp->am_mfarray = 0;
- mp->am_name = strdup(dir);
- mp->am_path = strdup(dir);
- mp->am_gen = new_gen();
-#ifdef HAVE_FS_AUTOFS
- mp->am_autofs_fh = 0;
-#endif /* HAVE_FS_AUTOFS */
-
- mp->am_timeo = gopt.am_timeo;
- mp->am_attr.ns_status = NFS_OK;
- mp->am_fattr = gen_fattr;
- mp->am_fattr.na_fsid = 42;
- mp->am_fattr.na_fileid = mp->am_gen;
- clocktime(&mp->am_fattr.na_atime);
- /* next line copies a "struct nfstime" among several fields */
- mp->am_fattr.na_mtime = mp->am_fattr.na_ctime = mp->am_fattr.na_atime;
-
- new_ttl(mp);
- mp->am_stats.s_mtime = mp->am_fattr.na_atime.nt_seconds;
- mp->am_dev = -1;
- mp->am_rdev = -1;
-}
-
-
-/*
- * Free a mount node.
- * The node must be already unmounted.
- */
-void
-free_map(am_node *mp)
-{
- remove_am(mp);
-
- if (mp->am_link)
- XFREE(mp->am_link);
- if (mp->am_name)
- XFREE(mp->am_name);
- if (mp->am_path)
- XFREE(mp->am_path);
- if (mp->am_pref)
- XFREE(mp->am_pref);
- if (mp->am_transp)
- XFREE(mp->am_transp);
-
- if (mp->am_mnt)
- free_mntfs(mp->am_mnt);
-
- if (mp->am_mfarray) {
- mntfs **temp_mf;
- for (temp_mf = mp->am_mfarray; *temp_mf; temp_mf++)
- free_mntfs(*temp_mf);
- XFREE(mp->am_mfarray);
- }
-
-#ifdef HAVE_FS_AUTOFS
- if (mp->am_autofs_fh)
- autofs_release_fh(mp);
-#endif /* HAVE_FS_AUTOFS */
-
- exported_ap_free(mp);
-}
-
-
-static am_node *
-find_ap_recursive(char *dir, am_node *mp)
-{
- if (mp) {
- am_node *mp2;
- if (STREQ(mp->am_path, dir))
- return mp;
-
- if ((mp->am_mnt->mf_flags & MFF_MOUNTED) &&
- STREQ(mp->am_mnt->mf_mount, dir))
- return mp;
-
- mp2 = find_ap_recursive(dir, mp->am_osib);
- if (mp2)
- return mp2;
- return find_ap_recursive(dir, mp->am_child);
- }
-
- return 0;
-}
-
-
-/*
- * Find the mount node corresponding to dir. dir can match either the
- * automount path or, if the node is mounted, the mount location.
- */
-am_node *
-find_ap(char *dir)
-{
- int i;
-
- for (i = last_used_map; i >= 0; --i) {
- am_node *mp = exported_ap[i];
- if (mp && (mp->am_flags & AMF_ROOT)) {
- mp = find_ap_recursive(dir, exported_ap[i]);
- if (mp) {
- return mp;
- }
- }
- }
-
- return 0;
-}
-
-
-/*
- * Find the mount node corresponding
- * to the mntfs structure.
- */
-am_node *
-find_mf(mntfs *mf)
-{
- int i;
-
- for (i = last_used_map; i >= 0; --i) {
- am_node *mp = exported_ap[i];
- if (mp && mp->am_mnt == mf)
- return mp;
- }
-
- return 0;
-}
-
-
-/*
- * Get the filehandle for a particular named directory.
- * This is used during the bootstrap to tell the kernel
- * the filehandles of the initial automount points.
- */
-am_nfs_fh *
-get_root_nfs_fh(char *dir)
-{
- static am_nfs_fh nfh;
- am_node *mp = get_root_ap(dir);
- if (mp) {
- mp_to_fh(mp, &nfh);
- return &nfh;
- }
-
- /*
- * Should never get here...
- */
- plog(XLOG_ERROR, "Can't find root filehandle for %s", dir);
-
- return 0;
-}
-
-
-static am_node *
-get_root_ap(char *dir)
-{
- am_node *mp = find_ap(dir);
-
- if (mp && mp->am_parent == root_node)
- return mp;
-
- return 0;
-}
-
-
-/*
- * Timeout all nodes waiting on
- * a given Fserver.
- */
-void
-map_flush_srvr(fserver *fs)
-{
- int i;
- int done = 0;
-
- for (i = last_used_map; i >= 0; --i) {
- am_node *mp = exported_ap[i];
- if (mp && mp->am_mnt && mp->am_mnt->mf_server == fs) {
- plog(XLOG_INFO, "Flushed %s; dependent on %s", mp->am_path, fs->fs_host);
- mp->am_ttl = clocktime(NULL);
- done = 1;
- }
- }
- if (done)
- reschedule_timeout_mp();
-}
-
-
-/*
- * Mount a top level automount node
- * by calling lookup in the parent
- * (root) node which will cause the
- * automount node to be automounted.
- */
-int
-mount_auto_node(char *dir, opaque_t arg)
-{
- int error = 0;
- am_node *mp = (am_node *) arg;
- am_node *new_mp;
-
- new_mp = mp->am_mnt->mf_ops->lookup_child(mp, dir, &error, VLOOK_CREATE);
- if (new_mp && error < 0) {
- /*
- * We can't allow the fileid of the root node to change.
- * Should be ok to force it to 1, always.
- */
- new_mp->am_gen = new_mp->am_fattr.na_fileid = 1;
-
- new_mp = mp->am_mnt->mf_ops->mount_child(new_mp, &error);
- }
-
- if (error > 0) {
- errno = error; /* XXX */
- plog(XLOG_ERROR, "Could not mount %s: %m", dir);
- }
- return error;
-}
-
-
-/*
- * Cause all the top-level mount nodes
- * to be automounted
- */
-int
-mount_exported(void)
-{
- /*
- * Iterate over all the nodes to be started
- */
- return root_keyiter(mount_auto_node, root_node);
-}
-
-
-/*
- * Construct top-level node
- */
-void
-make_root_node(void)
-{
- mntfs *root_mnt;
- char *rootmap = ROOT_MAP;
- root_node = exported_ap_alloc();
-
- /*
- * Allocate a new map
- */
- init_map(root_node, "");
-
- /*
- * Allocate a new mounted filesystem
- */
- root_mnt = find_mntfs(&amfs_root_ops, (am_opts *) 0, "", rootmap, "", "", "");
-
- /*
- * Replace the initial null reference
- */
- free_mntfs(root_node->am_mnt);
- root_node->am_mnt = root_mnt;
-
- /*
- * Initialize 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, root_mnt);
-}
-
-
-/*
- * Cause all the nodes to be unmounted by timing
- * them out.
- */
-void
-umount_exported(void)
-{
- int i;
-
- for (i = last_used_map; i >= 0; --i) {
- am_node *mp = exported_ap[i];
- mntfs *mf;
-
- if (!mp)
- continue;
-
- mf = mp->am_mnt;
- if (mf->mf_flags & MFF_UNMOUNTING) {
- /*
- * If this node is being unmounted then just ignore it. However,
- * this could prevent amd from finishing if the unmount gets blocked
- * since the am_node will never be free'd. am_unmounted needs
- * telling about this possibility. - XXX
- */
- continue;
- }
-
- if (!(mf->mf_fsflags & FS_DIRECTORY))
- /*
- * When shutting down this had better
- * look like a directory, otherwise it
- * can't be unmounted!
- */
- mk_fattr(&mp->am_fattr, NFDIR);
-
- if ((--immediate_abort < 0 &&
- !(mp->am_flags & AMF_ROOT) && mp->am_parent) ||
- (mf->mf_flags & MFF_RESTART)) {
-
- /*
- * Just throw this node away without bothering to unmount it. If
- * the server is not known to be up then don't discard the mounted
- * on directory or Amd might hang...
- */
- if (mf->mf_server &&
- (mf->mf_server->fs_flags & (FSF_DOWN | FSF_VALID)) != FSF_VALID)
- mf->mf_flags &= ~MFF_MKMNT;
- if (gopt.flags & CFM_UNMOUNT_ON_EXIT || mp->am_flags & AMF_AUTOFS) {
- plog(XLOG_INFO, "on-exit attempt to unmount %s", mf->mf_mount);
- /*
- * use unmount_mp, not unmount_node, so that unmounts be
- * backgrounded as needed.
- */
- unmount_mp((opaque_t) mp);
- } else {
- am_unmounted(mp);
- }
- exported_ap[i] = 0;
- } else {
- /*
- * Any other node gets forcibly timed out.
- */
- mp->am_flags &= ~AMF_NOTIMEOUT;
- mp->am_mnt->mf_flags &= ~MFF_RSTKEEP;
- mp->am_ttl = 0;
- mp->am_timeo = 1;
- mp->am_timeo_w = 0;
- }
- }
-}
-
-
-/*
- * Try to mount a file system. Can be called directly or in a sub-process by run_task.
- *
- * Warning: this function might be running in a child process context.
- * Don't expect any changes made here to survive in the parent amd process.
- */
-int
-mount_node(opaque_t arg)
-{
- am_node *mp = (am_node *) arg;
- mntfs *mf = mp->am_mnt;
- int error = 0;
-
-#ifdef HAVE_FS_AUTOFS
- if (mp->am_flags & AMF_AUTOFS)
- error = autofs_mount_fs(mp, mf);
- else
-#endif /* HAVE_FS_AUTOFS */
- if (!(mf->mf_flags & MFF_MOUNTED))
- error = mf->mf_ops->mount_fs(mp, mf);
-
- if (error > 0)
- dlog("mount_node: call to mf_ops->mount_fs(%s) failed: %s",
- mp->am_path, strerror(error));
- return error;
-}
-
-
-static int
-unmount_node(opaque_t arg)
-{
- am_node *mp = (am_node *) arg;
- mntfs *mf = mp->am_mnt;
- int error = 0;
-
- if (mf->mf_flags & MFF_ERROR) {
- /*
- * Just unlink
- */
- dlog("No-op unmount of error node %s", mf->mf_info);
- } else {
- dlog("Unmounting <%s> <%s> (%s) flags %x",
- mp->am_path, mf->mf_mount, mf->mf_info, mf->mf_flags);
-#ifdef HAVE_FS_AUTOFS
- if (mp->am_flags & AMF_AUTOFS)
- error = autofs_umount_fs(mp, mf);
- else
-#endif /* HAVE_FS_AUTOFS */
- if (mf->mf_refc == 1)
- error = mf->mf_ops->umount_fs(mp, mf);
- }
-
- /* do this again, it might have changed */
- mf = mp->am_mnt;
- if (error) {
- errno = error; /* XXX */
- dlog("%s: unmount: %m", mf->mf_mount);
- }
-
- return error;
-}
-
-
-static void
-free_map_if_success(int rc, int term, opaque_t arg)
-{
- am_node *mp = (am_node *) arg;
- mntfs *mf = mp->am_mnt;
- wchan_t wchan = get_mntfs_wchan(mf);
-
- /*
- * Not unmounting any more
- */
- mf->mf_flags &= ~MFF_UNMOUNTING;
-
- /*
- * If a timeout was deferred because the underlying filesystem
- * was busy then arrange for a timeout as soon as possible.
- */
- if (mf->mf_flags & MFF_WANTTIMO) {
- mf->mf_flags &= ~MFF_WANTTIMO;
- reschedule_timeout_mp();
- }
- if (term) {
- plog(XLOG_ERROR, "unmount for %s got signal %d", mp->am_path, term);
-#if defined(DEBUG) && defined(SIGTRAP)
- /*
- * dbx likes to put a trap on exit().
- * Pretend it succeeded for now...
- */
- if (term == SIGTRAP) {
- am_unmounted(mp);
- }
-#endif /* DEBUG */
-#ifdef HAVE_FS_AUTOFS
- if (mp->am_flags & AMF_AUTOFS)
- autofs_umount_failed(mp);
-#endif /* HAVE_FS_AUTOFS */
- amd_stats.d_uerr++;
- } else if (rc) {
- if (mf->mf_ops == &amfs_program_ops || rc == EBUSY)
- plog(XLOG_STATS, "\"%s\" on %s still active", mp->am_path, mf->mf_mount);
- else
- plog(XLOG_ERROR, "%s: unmount: %s", mp->am_path, strerror(rc));
-#ifdef HAVE_FS_AUTOFS
- if (mf->mf_flags & MFF_IS_AUTOFS)
- autofs_get_mp(mp);
- if (mp->am_flags & AMF_AUTOFS)
- autofs_umount_failed(mp);
-#endif /* HAVE_FS_AUTOFS */
- amd_stats.d_uerr++;
- } else {
- am_unmounted(mp);
- }
-
- /*
- * Wakeup anything waiting for this unmount
- */
- wakeup(wchan);
-}
-
-
-int
-unmount_mp(am_node *mp)
-{
- int was_backgrounded = 0;
- mntfs *mf = mp->am_mnt;
-
-#ifdef notdef
- plog(XLOG_INFO, "\"%s\" on %s timed out (flags 0x%x)",
- mp->am_path, mp->am_mnt->mf_mount, (int) mf->mf_flags);
-#endif /* notdef */
-
-#ifndef MNT2_NFS_OPT_SYMTTL
- /*
- * This code is needed to defeat Solaris 2.4's (and newer) symlink
- * values cache. It forces the last-modified time of the symlink to be
- * current. It is not needed if the O/S has an nfs flag to turn off the
- * symlink-cache at mount time (such as Irix 5.x and 6.x). -Erez.
- *
- * Additionally, Linux currently ignores the nt_useconds field,
- * so we must update the nt_seconds field every time if clocktime(NULL)
- * didn't return a new number of seconds.
- */
- if (mp->am_parent) {
- time_t last = mp->am_parent->am_attr.ns_u.ns_attr_u.na_mtime.nt_seconds;
- clocktime(&mp->am_parent->am_attr.ns_u.ns_attr_u.na_mtime);
- /* defensive programming... can't we assert the above condition? */
- if (last == (time_t) mp->am_parent->am_attr.ns_u.ns_attr_u.na_mtime.nt_seconds)
- mp->am_parent->am_attr.ns_u.ns_attr_u.na_mtime.nt_seconds++;
- }
-#endif /* not MNT2_NFS_OPT_SYMTTL */
-
- if (mf->mf_refc == 1 && !FSRV_ISUP(mf->mf_server)) {
- /*
- * Don't try to unmount from a server that is known to be down
- */
- if (!(mf->mf_flags & MFF_LOGDOWN)) {
- /* Only log this once, otherwise gets a bit boring */
- plog(XLOG_STATS, "file server %s is down - timeout of \"%s\" ignored", mf->mf_server->fs_host, mp->am_path);
- mf->mf_flags |= MFF_LOGDOWN;
- }
- return 0;
- }
-
- dlog("\"%s\" on %s timed out", mp->am_path, mp->am_mnt->mf_mount);
- mf->mf_flags |= MFF_UNMOUNTING;
-
-#ifdef HAVE_FS_AUTOFS
- if (mf->mf_flags & MFF_IS_AUTOFS)
- autofs_release_mp(mp);
-#endif /* HAVE_FS_AUTOFS */
-
- if ((mf->mf_fsflags & FS_UBACKGROUND) &&
- (mf->mf_flags & MFF_MOUNTED)) {
- dlog("Trying unmount in background");
- run_task(unmount_node, (opaque_t) mp,
- free_map_if_success, (opaque_t) mp);
- was_backgrounded = 1;
- } else {
- dlog("Trying unmount in foreground");
- free_map_if_success(unmount_node((opaque_t) mp), 0, (opaque_t) mp);
- dlog("unmount attempt done");
- }
-
- return was_backgrounded;
-}
-
-
-void
-timeout_mp(opaque_t v) /* argument not used?! */
-{
- int i;
- time_t t = NEVER;
- time_t now = clocktime(NULL);
- int backoff = NumChildren / 4;
-
- dlog("Timing out automount points...");
-
- for (i = last_used_map; i >= 0; --i) {
- am_node *mp = exported_ap[i];
- mntfs *mf;
-
- /*
- * Just continue if nothing mounted
- */
- if (!mp)
- continue;
-
- /*
- * Pick up mounted filesystem
- */
- mf = mp->am_mnt;
- if (!mf)
- continue;
-
-#ifdef HAVE_FS_AUTOFS
- if (mf->mf_flags & MFF_IS_AUTOFS && mp->am_autofs_ttl != NEVER) {
- if (now >= mp->am_autofs_ttl)
- autofs_timeout_mp(mp);
- t = smallest_t(t, mp->am_autofs_ttl);
- }
-#endif /* HAVE_FS_AUTOFS */
-
- if (mp->am_flags & AMF_NOTIMEOUT)
- continue;
-
- /*
- * Don't delete last reference to a restarted filesystem.
- */
- if ((mf->mf_flags & MFF_RSTKEEP) && mf->mf_refc == 1)
- continue;
-
- /*
- * If there is action on this filesystem then ignore it
- */
- if (!(mf->mf_flags & IGNORE_FLAGS)) {
- int expired = 0;
- mf->mf_flags &= ~MFF_WANTTIMO;
- if (now >= mp->am_ttl) {
- if (!backoff) {
- expired = 1;
-
- /*
- * Move the ttl forward to avoid thrashing effects
- * on the next call to timeout!
- */
- /* sun's -tw option */
- if (mp->am_timeo_w < 4 * gopt.am_timeo_w)
- mp->am_timeo_w += gopt.am_timeo_w;
- mp->am_ttl = now + mp->am_timeo_w;
-
- } else {
- /*
- * Just backoff this unmount for
- * a couple of seconds to avoid
- * many multiple unmounts being
- * started in parallel.
- */
- mp->am_ttl = now + backoff + 1;
- }
- }
-
- /*
- * If the next ttl is smallest, use that
- */
- t = smallest_t(t, mp->am_ttl);
-
- if (!mp->am_child && mf->mf_error >= 0 && expired) {
- /*
- * If the unmount was backgrounded then
- * bump the backoff counter.
- */
- if (unmount_mp(mp)) {
- backoff = 2;
- }
- }
- } else if (mf->mf_flags & MFF_UNMOUNTING) {
- mf->mf_flags |= MFF_WANTTIMO;
- }
- }
-
- if (t == NEVER) {
- dlog("No further timeouts");
- t = now + ONE_HOUR;
- }
-
- /*
- * Sanity check to avoid runaways.
- * Absolutely should never get this but
- * if you do without this trap amd will thrash.
- */
- if (t <= now) {
- t = now + 6; /* XXX */
- plog(XLOG_ERROR, "Got a zero interval in timeout_mp()!");
- }
-
- /*
- * XXX - when shutting down, make things happen faster
- */
- if ((int) amd_state >= (int) Finishing)
- t = now + 1;
- dlog("Next mount timeout in %lds", (long) (t - now));
-
- timeout_mp_id = timeout(t - now, timeout_mp, 0);
-}
-
-
-/*
- * Cause timeout_mp to be called soonest
- */
-void
-reschedule_timeout_mp(void)
-{
- if (timeout_mp_id)
- untimeout(timeout_mp_id);
- timeout_mp_id = timeout(0, timeout_mp, 0);
-}
diff --git a/contrib/amd/amd/mapc.c b/contrib/amd/amd/mapc.c
deleted file mode 100644
index d7efdbcfd217..000000000000
--- a/contrib/amd/amd/mapc.c
+++ /dev/null
@@ -1,1192 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/mapc.c
- *
- */
-
-/*
- * Mount map cache
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/*
- * Make a duplicate reference to an existing map
- */
-#define mapc_dup(m) ((m)->refc++, (m))
-
-/*
- * Map cache types
- * default, none, incremental, all, regexp
- * MAPC_RE implies MAPC_ALL and must be numerically
- * greater.
- */
-#define MAPC_DFLT 0x000
-#define MAPC_NONE 0x001
-#define MAPC_INC 0x002
-#define MAPC_ROOT 0x004
-#define MAPC_ALL 0x010
-#define MAPC_CACHE_MASK 0x0ff
-#define MAPC_SYNC 0x100
-
-#ifdef HAVE_REGEXEC
-# define MAPC_RE 0x020
-# define MAPC_ISRE(m) ((m)->alloc == MAPC_RE)
-#else /* not HAVE_REGEXEC */
-# define MAPC_ISRE(m) FALSE
-#endif /* not HAVE_REGEXEC */
-
-/*
- * Lookup recursion
- */
-#define MREC_FULL 2
-#define MREC_PART 1
-#define MREC_NONE 0
-
-static struct opt_tab mapc_opt[] =
-{
- {"all", MAPC_ALL},
- {"default", MAPC_DFLT},
- {"inc", MAPC_INC},
- {"mapdefault", MAPC_DFLT},
- {"none", MAPC_NONE},
-#ifdef HAVE_REGEXEC
- {"re", MAPC_RE},
- {"regexp", MAPC_RE},
-#endif /* HAVE_REGEXEC */
- {"sync", MAPC_SYNC},
- {0, 0}
-};
-
-/*
- * Wildcard key
- */
-static char wildcard[] = "*";
-
-/*
- * Map type
- */
-typedef struct map_type map_type;
-struct map_type {
- char *name; /* Name of this map type */
- init_fn *init; /* Initialization */
- reload_fn *reload; /* Reload or fill */
- isup_fn *isup; /* Is service up or not? (1=up, 0=down) */
- search_fn *search; /* Search for new entry */
- mtime_fn *mtime; /* Find modify time */
- int def_alloc; /* Default allocation mode */
-};
-
-/*
- * Map for root node
- */
-static mnt_map *root_map;
-
-/*
- * List of known maps
- */
-qelem map_list_head = {&map_list_head, &map_list_head};
-
-/*
- * Configuration
- */
-
-/* forward definitions */
-static const char *get_full_path(const char *map, const char *path, const char *type);
-static int mapc_meta_search(mnt_map *, char *, char **, int);
-static void mapc_sync(mnt_map *);
-static void mapc_clear(mnt_map *);
-
-/* ROOT MAP */
-static int root_init(mnt_map *, char *, time_t *);
-
-/* ERROR MAP */
-static int error_init(mnt_map *, char *, time_t *);
-static int error_reload(mnt_map *, char *, add_fn *);
-static int error_search(mnt_map *, char *, char *, char **, time_t *);
-static int error_mtime(mnt_map *, char *, time_t *);
-
-/* PASSWD MAPS */
-#ifdef HAVE_MAP_PASSWD
-extern int passwd_init(mnt_map *, char *, time_t *);
-extern int passwd_search(mnt_map *, char *, char *, char **, time_t *);
-#endif /* HAVE_MAP_PASSWD */
-
-/* HESIOD MAPS */
-#ifdef HAVE_MAP_HESIOD
-extern int amu_hesiod_init(mnt_map *, char *map, time_t *tp);
-extern int hesiod_isup(mnt_map *, char *);
-extern int hesiod_search(mnt_map *, char *, char *, char **, time_t *);
-#endif /* HAVE_MAP_HESIOD */
-
-/* LDAP MAPS */
-#ifdef HAVE_MAP_LDAP
-extern int amu_ldap_init(mnt_map *, char *map, time_t *tp);
-extern int amu_ldap_search(mnt_map *, char *, char *, char **, time_t *);
-extern int amu_ldap_mtime(mnt_map *, char *, time_t *);
-#endif /* HAVE_MAP_LDAP */
-
-/* UNION MAPS */
-#ifdef HAVE_MAP_UNION
-extern int union_init(mnt_map *, char *, time_t *);
-extern int union_search(mnt_map *, char *, char *, char **, time_t *);
-extern int union_reload(mnt_map *, char *, add_fn *);
-#endif /* HAVE_MAP_UNION */
-
-/* Network Information Service PLUS (NIS+) */
-#ifdef HAVE_MAP_NISPLUS
-extern int nisplus_init(mnt_map *, char *, time_t *);
-extern int nisplus_reload(mnt_map *, char *, add_fn *);
-extern int nisplus_search(mnt_map *, char *, char *, char **, time_t *);
-extern int nisplus_mtime(mnt_map *, char *, time_t *);
-#endif /* HAVE_MAP_NISPLUS */
-
-/* Network Information Service (YP, Yellow Pages) */
-#ifdef HAVE_MAP_NIS
-extern int nis_init(mnt_map *, char *, time_t *);
-extern int nis_reload(mnt_map *, char *, add_fn *);
-extern int nis_isup(mnt_map *, char *);
-extern int nis_search(mnt_map *, char *, char *, char **, time_t *);
-extern int nis_mtime(mnt_map *, char *, time_t *);
-#endif /* HAVE_MAP_NIS */
-
-/* NDBM MAPS */
-#ifdef HAVE_MAP_NDBM
-extern int ndbm_init(mnt_map *, char *, time_t *);
-extern int ndbm_search(mnt_map *, char *, char *, char **, time_t *);
-extern int ndbm_mtime(mnt_map *, char *, time_t *);
-#endif /* HAVE_MAP_NDBM */
-
-/* EXECUTABLE MAPS */
-#ifdef HAVE_MAP_EXEC
-extern int exec_init(mnt_map *, char *, time_t *);
-extern int exec_search(mnt_map *, char *, char *, char **, time_t *);
-#endif /* HAVE_MAP_EXEC */
-
-/* FILE MAPS */
-#ifdef HAVE_MAP_FILE
-extern int file_init_or_mtime(mnt_map *, char *, time_t *);
-extern int file_reload(mnt_map *, char *, add_fn *);
-extern int file_search(mnt_map *, char *, char *, char **, time_t *);
-#endif /* HAVE_MAP_FILE */
-
-
-/* note that the choice of MAPC_{INC,ALL} will affect browsable_dirs */
-static map_type maptypes[] =
-{
- {
- "root",
- root_init,
- error_reload,
- NULL, /* isup function */
- error_search,
- error_mtime,
- MAPC_ROOT
- },
-#ifdef HAVE_MAP_PASSWD
- {
- "passwd",
- passwd_init,
- error_reload,
- NULL, /* isup function */
- passwd_search,
- error_mtime,
- MAPC_INC
- },
-#endif /* HAVE_MAP_PASSWD */
-#ifdef HAVE_MAP_HESIOD
- {
- "hesiod",
- amu_hesiod_init,
- error_reload,
- hesiod_isup, /* is Hesiod up or not? */
- hesiod_search,
- error_mtime,
- MAPC_INC
- },
-#endif /* HAVE_MAP_HESIOD */
-#ifdef HAVE_MAP_LDAP
- {
- "ldap",
- amu_ldap_init,
- error_reload,
- NULL, /* isup function */
- amu_ldap_search,
- amu_ldap_mtime,
- MAPC_INC
- },
-#endif /* HAVE_MAP_LDAP */
-#ifdef HAVE_MAP_UNION
- {
- "union",
- union_init,
- union_reload,
- NULL, /* isup function */
- union_search,
- error_mtime,
- MAPC_ALL
- },
-#endif /* HAVE_MAP_UNION */
-#ifdef HAVE_MAP_NISPLUS
- {
- "nisplus",
- nisplus_init,
- nisplus_reload,
- NULL, /* isup function */
- nisplus_search,
- nisplus_mtime,
- MAPC_INC
- },
-#endif /* HAVE_MAP_NISPLUS */
-#ifdef HAVE_MAP_NIS
- {
- "nis",
- nis_init,
- nis_reload,
- nis_isup, /* is NIS up or not? */
- nis_search,
- nis_mtime,
- MAPC_ALL
- },
-#endif /* HAVE_MAP_NIS */
-#ifdef HAVE_MAP_NDBM
- {
- "ndbm",
- ndbm_init,
- error_reload,
- NULL, /* isup function */
- ndbm_search,
- ndbm_mtime,
- MAPC_INC
- },
-#endif /* HAVE_MAP_NDBM */
-#ifdef HAVE_MAP_FILE
- {
- "file",
- file_init_or_mtime,
- file_reload,
- NULL, /* isup function */
- file_search,
- file_init_or_mtime,
- MAPC_ALL
- },
-#endif /* HAVE_MAP_FILE */
-#ifdef HAVE_MAP_EXEC
- {
- "exec",
- exec_init,
- error_reload,
- NULL, /* isup function */
- exec_search,
- error_mtime,
- MAPC_INC
- },
-#endif /* HAVE_MAP_EXEC */
- {
- "error",
- error_init,
- error_reload,
- NULL, /* isup function */
- error_search,
- error_mtime,
- MAPC_NONE
- },
-};
-
-
-/*
- * Hash function
- */
-static u_int
-kvhash_of(char *key)
-{
- u_int i, j;
-
- for (i = 0; (j = *key++); i += j) ;
-
- return i % NKVHASH;
-}
-
-
-void
-mapc_showtypes(char *buf, size_t l)
-{
- map_type *mt=NULL, *lastmt;
- int linesize = 0, i;
-
- i = sizeof(maptypes) / sizeof(maptypes[0]);
- lastmt = maptypes + i;
- buf[0] = '\0';
- for (mt = maptypes; mt < lastmt; mt++) {
- xstrlcat(buf, mt->name, l);
- if (mt == (lastmt-1))
- break; /* if last one, don't do xstrlcat's that follows */
- linesize += strlen(mt->name);
- if (--i > 0) {
- xstrlcat(buf, ", ", l);
- linesize += 2;
- }
- if (linesize > 54) {
- linesize = 0;
- xstrlcat(buf, "\n\t\t ", l);
- }
- }
-}
-
-
-/*
- * Check if a map of a certain type exists.
- * Return 1 (true) if exists, 0 (false) if not.
- */
-int
-mapc_type_exists(const char *type)
-{
- map_type *mt;
-
- if (!type)
- return 0;
- for (mt = maptypes;
- mt < maptypes + sizeof(maptypes) / sizeof(maptypes[0]);
- mt++) {
- if (STREQ(type, mt->name))
- return 1;
- }
- return 0; /* not found anywhere */
-}
-
-
-/*
- * Add key and val to the map m.
- * key and val are assumed to be safe copies
- */
-void
-mapc_add_kv(mnt_map *m, char *key, char *val)
-{
- kv **h;
- kv *n;
- int hash = kvhash_of(key);
-#ifdef HAVE_REGEXEC
- regex_t re;
-#endif /* HAVE_REGEXEC */
-
- dlog("add_kv: %s -> %s", key, val);
-
-#ifdef HAVE_REGEXEC
- if (MAPC_ISRE(m)) {
- char pattern[MAXPATHLEN];
- int retval;
-
- /*
- * Make sure the string is bound to the start and end
- */
- xsnprintf(pattern, sizeof(pattern), "^%s$", key);
- retval = regcomp(&re, pattern, REG_ICASE);
- if (retval != 0) {
- char errstr[256];
-
- /* XXX: this code was recently ported, and must be tested -Erez */
- errstr[0] = '\0';
- regerror(retval, &re, errstr, 256);
- plog(XLOG_USER, "error compiling RE \"%s\": %s", pattern, errstr);
- return;
- }
- }
-#endif /* HAVE_REGEXEC */
-
- h = &m->kvhash[hash];
- n = ALLOC(struct kv);
- n->key = key;
-#ifdef HAVE_REGEXEC
- memcpy(&n->re, &re, sizeof(regex_t));
-#endif /* HAVE_REGEXEC */
- n->val = val;
- n->next = *h;
- *h = n;
-}
-
-
-static void
-mapc_repl_kv(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) {
- XFREE(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(mnt_map *m, char *key, char **valp)
-{
- int rc;
-
- do {
- rc = (*m->search) (m, m->map_name, key, valp, &m->modify);
- if (rc < 0) {
- plog(XLOG_MAP, "Re-synchronizing cache for map %s", m->map_name);
- mapc_sync(m);
- }
- } while (rc < 0);
-
- return rc;
-}
-
-
-/*
- * Do a wildcard lookup in the map and
- * save the result.
- */
-static void
-mapc_find_wildcard(mnt_map *m)
-{
- /*
- * Attempt to find the wildcard entry
- */
- int rc = search_map(m, wildcard, &m->wildcard);
-
- if (rc != 0)
- m->wildcard = 0;
-}
-
-
-/*
- * Do a map reload.
- * Attempt to reload without losing current data by switching the hashes
- * round.
- * If reloading was needed and succeeded, return 1; else return 0.
- */
-static int
-mapc_reload_map(mnt_map *m)
-{
- int error, ret = 0;
- kv *maphash[NKVHASH], *tmphash[NKVHASH];
- time_t t;
-
- error = (*m->mtime) (m, m->map_name, &t);
- if (error) {
- t = m->modify;
- }
-
- /*
- * skip reloading maps that have not been modified, unless
- * amq -f was used (do_mapc_reload is 0)
- */
- if (m->reloads != 0 && do_mapc_reload != 0) {
- if (t <= m->modify) {
- plog(XLOG_INFO, "reload of map %s is not needed (in sync)", m->map_name);
- dlog("map %s last load time is %d, last modify time is %d",
- m->map_name, (int) m->modify, (int) t);
- return ret;
- }
- }
-
- /* copy the old hash and zero the map */
- memcpy((voidp) maphash, (voidp) m->kvhash, sizeof(m->kvhash));
- memset((voidp) m->kvhash, 0, sizeof(m->kvhash));
-
- dlog("calling map reload on %s", m->map_name);
- error = (*m->reload) (m, m->map_name, mapc_add_kv);
- if (error) {
- if (m->reloads == 0)
- plog(XLOG_FATAL, "first time load of map %s failed!", m->map_name);
- else
- plog(XLOG_ERROR, "reload of map %s failed - using old values",
- m->map_name);
- mapc_clear(m);
- memcpy((voidp) m->kvhash, (voidp) maphash, sizeof(m->kvhash));
- } else {
- if (m->reloads++ == 0)
- plog(XLOG_INFO, "first time load of map %s succeeded", m->map_name);
- else
- plog(XLOG_INFO, "reload #%d of map %s succeeded",
- m->reloads, m->map_name);
- memcpy((voidp) tmphash, (voidp) m->kvhash, sizeof(m->kvhash));
- memcpy((voidp) m->kvhash, (voidp) maphash, sizeof(m->kvhash));
- mapc_clear(m);
- memcpy((voidp) m->kvhash, (voidp) tmphash, sizeof(m->kvhash));
- m->modify = t;
- ret = 1;
- }
- m->wildcard = 0;
-
- dlog("calling mapc_search for wildcard");
- error = mapc_search(m, wildcard, &m->wildcard);
- if (error)
- m->wildcard = 0;
- return ret;
-}
-
-
-/*
- * Create a new map
- */
-static mnt_map *
-mapc_create(char *map, char *opt, const char *type)
-{
- mnt_map *m = ALLOC(struct mnt_map);
- map_type *mt;
- time_t modify = 0;
- int alloc = 0;
-
- cmdoption(opt, mapc_opt, &alloc);
-
- /*
- * If using a configuration file, and the map_type is defined, then look
- * for it, in the maptypes array. If found, initialize the map using that
- * map_type. If not found, return error. If no map_type was defined,
- * default to cycling through all maptypes.
- */
- if (use_conf_file && type) {
- /* find what type of map this one is */
- for (mt = maptypes;
- mt < maptypes + sizeof(maptypes) / sizeof(maptypes[0]);
- mt++) {
- if (STREQ(type, mt->name)) {
- plog(XLOG_INFO, "initializing amd.conf map %s of type %s", map, type);
- if ((*mt->init) (m, map, &modify) == 0) {
- break;
- } else {
- plog(XLOG_ERROR, "failed to initialize map %s", map);
- error_init(m, map, &modify);
- break;
- }
- }
- } /* end of "for (mt =" loop */
-
- } else { /* cycle through all known maptypes */
-
- /*
- * not using amd conf file or using it by w/o specifying map type
- */
- for (mt = maptypes;
- mt < maptypes + sizeof(maptypes) / sizeof(maptypes[0]);
- mt++) {
- dlog("trying to initialize map %s of type %s ...", map, mt->name);
- if ((*mt->init) (m, map, &modify) == 0) {
- break;
- }
- }
- } /* end of "if (use_conf_file && (colpos = strchr ..." statement */
-
- /* 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;
- /* fall-through... */
- 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;
-
-#ifdef HAVE_REGEXEC
- 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;
-#endif /* HAVE_REGEXEC */
- }
-
- dlog("Map for %s coming from maptype %s", map, mt->name);
-
- m->alloc = alloc;
- m->reload = mt->reload;
- m->isup = mt->isup;
- m->modify = modify;
- m->search = alloc >= MAPC_ALL ? error_search : mt->search;
- m->mtime = mt->mtime;
- memset((voidp) m->kvhash, 0, sizeof(m->kvhash));
- m->map_name = strdup(map);
- m->refc = 1;
- m->wildcard = 0;
- m->reloads = 0;
- /* Unfortunately with current code structure, this cannot be initialized here */
- m->cfm = NULL;
-
- /*
- * synchronize cache with reality
- */
- mapc_sync(m);
-
- return m;
-}
-
-
-/*
- * Free the cached data in a map
- */
-static void
-mapc_clear(mnt_map *m)
-{
- int i;
-
- /*
- * For each of the hash slots, chain
- * along free'ing the data.
- */
- for (i = 0; i < NKVHASH; i++) {
- kv *k = m->kvhash[i];
- while (k) {
- kv *n = k->next;
- XFREE(k->key);
- if (k->val)
- XFREE(k->val);
- XFREE(k);
- k = n;
- }
- }
-
- /*
- * Zero the hash slots
- */
- memset((voidp) m->kvhash, 0, sizeof(m->kvhash));
-
- /*
- * Free the wildcard if it exists
- */
- if (m->wildcard) {
- XFREE(m->wildcard);
- m->wildcard = 0;
- }
-}
-
-
-/*
- * Find a map, or create one if it does not exist
- */
-mnt_map *
-mapc_find(char *map, char *opt, const char *maptype)
-{
- mnt_map *m;
-
- /*
- * Search the list of known maps to see if
- * it has already been loaded. If it is found
- * then return a duplicate reference to it.
- * Otherwise make a new map as required and
- * add it to the list of maps
- */
- ITER(m, mnt_map, &map_list_head)
- if (STREQ(m->map_name, map))
- return mapc_dup(m);
- m = mapc_create(map, opt, maptype);
- ins_que(&m->hdr, &map_list_head);
-
- return m;
-}
-
-
-/*
- * Free a map.
- */
-void
-mapc_free(opaque_t arg)
-{
- mnt_map *m = (mnt_map *) arg;
-
- /*
- * Decrement the reference count.
- * If the reference count hits zero
- * then throw the map away.
- */
- if (m && --m->refc == 0) {
- mapc_clear(m);
- XFREE(m->map_name);
- rem_que(&m->hdr);
- XFREE(m);
- }
-}
-
-
-/*
- * Search the map for the key. Put a safe (malloc'ed) copy in *pval or
- * return an error code
- */
-static int
-mapc_meta_search(mnt_map *m, char *key, char **pval, int recurse)
-{
- int error = 0;
- kv *k = 0;
-
- /*
- * Firewall
- */
- if (!m) {
- plog(XLOG_ERROR, "Null map request for %s", key);
- return ENOENT;
- }
-
- if (m->flags & MAPC_SYNC) {
- /*
- * Get modify time...
- */
- time_t t;
- error = (*m->mtime) (m, m->map_name, &t);
- if (error || t > m->modify) {
- 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 HAVE_REGEXEC
- 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) {
- int retval;
-
- /* XXX: this code was recently ported, and must be tested -Erez */
- retval = regexec(&k->re, key, 0, 0, 0);
- if (retval == 0) { /* succeeded */
- break;
- } else { /* failed to match, log error */
- char errstr[256];
-
- errstr[0] = '\0';
- regerror(retval, &k->re, errstr, 256);
- plog(XLOG_USER, "error matching RE \"%s\" against \"%s\": %s",
- key, k->key, errstr);
- }
- k = k->next;
- }
- if (k)
- break;
- }
- }
-#endif /* HAVE_REGEXEC */
-
- /*
- * If found then take a copy
- */
- if (k) {
- if (k->val)
- *pval = strdup(k->val);
- else
- error = ENOENT;
- } else if (m->alloc >= MAPC_ALL) {
- /*
- * If the entire map is cached then this
- * key does not exist.
- */
- error = ENOENT;
- } else {
- /*
- * Otherwise search the map. If we are
- * in incremental mode then add the key
- * to the cache.
- */
- error = search_map(m, key, pval);
- if (!error && m->alloc == MAPC_INC)
- mapc_add_kv(m, strdup(key), strdup(*pval));
- }
-
- /*
- * If an error, and a wildcard exists,
- * and the key is not internal then
- * return a copy of the wildcard.
- */
- 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 / *"
- */
- xstrlcpy(wildname, key, sizeof(wildname));
- while (error && (subp = strrchr(wildname, '/'))) {
- /*
- * sizeof space left in subp is sizeof wildname minus what's left
- * after the strchr above returned a pointer inside wildname into
- * subp.
- */
- xstrlcpy(subp, "/*", sizeof(wildname) - (subp - wildname));
- dlog("mapc recurses on %s", wildname);
- 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;
-}
-
-
-int
-mapc_search(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(mnt_map *m)
-{
- int need_mtime_update = 0;
-
- if (m->alloc == MAPC_ROOT)
- return; /* nothing to do */
-
- /* do not clear map if map service is down */
- if (m->isup) {
- if (!((*m->isup)(m, m->map_name))) {
- plog(XLOG_ERROR, "mapc_sync: map %s is down: not clearing map", m->map_name);
- return;
- }
- }
-
- if (m->alloc >= MAPC_ALL) {
- /* mapc_reload_map() always works */
- need_mtime_update = mapc_reload_map(m);
- } else {
- mapc_clear(m);
- /*
- * Attempt to find the wildcard entry
- */
- mapc_find_wildcard(m);
- need_mtime_update = 1; /* because mapc_clear always works */
- }
-
- /*
- * To be safe, update the mtime of the mnt_map's own node, so that the
- * kernel will flush all of its cached entries.
- */
- if (need_mtime_update && m->cfm) {
- am_node *mp = find_ap(m->cfm->cfm_dir);
- if (mp) {
- clocktime(&mp->am_fattr.na_mtime);
- } else {
- plog(XLOG_ERROR, "cannot find map %s to update its mtime",
- m->cfm->cfm_dir);
- }
- }
-}
-
-
-/*
- * Reload all the maps
- * Called when Amd gets hit by a SIGHUP.
- */
-void
-mapc_reload(void)
-{
- mnt_map *m;
-
- /*
- * For all the maps,
- * Throw away the existing information.
- * Do a reload
- * Find the wildcard
- */
- ITER(m, mnt_map, &map_list_head)
- mapc_sync(m);
-}
-
-
-/*
- * Root map.
- * The root map is used to bootstrap amd.
- * All the require top-level mounts are added
- * into the root map and then the map is iterated
- * and a lookup is done on all the mount points.
- * This causes the top level mounts to be automounted.
- */
-static int
-root_init(mnt_map *m, char *map, time_t *tp)
-{
- *tp = clocktime(NULL);
- return STREQ(map, ROOT_MAP) ? 0 : ENOENT;
-}
-
-
-/*
- * Add a new entry to the root map
- *
- * dir - directory (key)
- * opts - mount options
- * map - map name
- * cfm - optional amd configuration file map section structure
- */
-void
-root_newmap(const char *dir, const char *opts, const char *map, const cf_map_t *cfm)
-{
- char str[MAXPATHLEN];
-
- /*
- * First make sure we have a root map to talk about...
- */
- if (!root_map)
- root_map = mapc_find(ROOT_MAP, "mapdefault", NULL);
-
- /*
- * Then add the entry...
- */
-
- /*
- * Here I plug in the code to process other amd.conf options like
- * map_type, search_path, and flags (browsable_dirs, mount_type).
- */
-
- if (cfm) {
- if (map) {
- xsnprintf(str, sizeof(str),
- "cache:=mapdefault;type:=toplvl;mount_type:=%s;fs:=\"%s\"",
- cfm->cfm_flags & CFM_MOUNT_TYPE_AUTOFS ? "autofs" : "nfs",
- get_full_path(map, cfm->cfm_search_path, cfm->cfm_type));
- if (opts && opts[0] != '\0') {
- xstrlcat(str, ";", sizeof(str));
- xstrlcat(str, opts, sizeof(str));
- }
- if (cfm->cfm_flags & CFM_BROWSABLE_DIRS_FULL)
- xstrlcat(str, ";opts:=rw,fullybrowsable", sizeof(str));
- if (cfm->cfm_flags & CFM_BROWSABLE_DIRS)
- xstrlcat(str, ";opts:=rw,browsable", sizeof(str));
- if (cfm->cfm_type) {
- xstrlcat(str, ";maptype:=", sizeof(str));
- xstrlcat(str, cfm->cfm_type, sizeof(str));
- }
- } else {
- xstrlcpy(str, opts, sizeof(str));
- }
- } else {
- if (map)
- xsnprintf(str, sizeof(str),
- "cache:=mapdefault;type:=toplvl;fs:=\"%s\";%s",
- map, opts ? opts : "");
- else
- xstrlcpy(str, opts, sizeof(str));
- }
- mapc_repl_kv(root_map, strdup((char *)dir), strdup(str));
-}
-
-
-int
-mapc_keyiter(mnt_map *m, key_fun *fn, opaque_t 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;
-}
-
-
-/*
- * Iterate on the root map and call (*fn)() on the key of all the nodes.
- * Returns the number of entries in the root map.
- */
-int
-root_keyiter(key_fun *fn, opaque_t arg)
-{
- if (root_map) {
- int c = mapc_keyiter(root_map, fn, arg);
- return c;
- }
-
- return 0;
-}
-
-
-/*
- * Error map
- */
-static int
-error_init(mnt_map *m, char *map, time_t *tp)
-{
- plog(XLOG_USER, "No source data for map %s", map);
- *tp = 0;
-
- return 0;
-}
-
-
-static int
-error_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
-{
- return ENOENT;
-}
-
-
-static int
-error_reload(mnt_map *m, char *map, add_fn *fn)
-{
- return ENOENT;
-}
-
-
-static int
-error_mtime(mnt_map *m, char *map, time_t *tp)
-{
- *tp = 0;
-
- return 0;
-}
-
-
-/*
- * Return absolute path of map, searched in a type-specific path.
- * Note: uses a static buffer for returned data.
- */
-static const char *
-get_full_path(const char *map, const char *path, const char *type)
-{
- char component[MAXPATHLEN], *str;
- static char full_path[MAXPATHLEN];
- int len;
-
- /* for now, only file-type search paths are implemented */
- if (type && !STREQ(type, "file"))
- return map;
-
- /* if null map, return it */
- if (!map)
- return map;
-
- /* if map includes a '/', return it (absolute or relative path) */
- if (strchr(map, '/'))
- return map;
-
- /* if path is empty, return map */
- if (!path)
- return map;
-
- /* now break path into components, and search in each */
- xstrlcpy(component, path, sizeof(component));
-
- str = strtok(component, ":");
- do {
- xstrlcpy(full_path, str, sizeof(full_path));
- len = strlen(full_path);
- if (full_path[len - 1] != '/') /* add trailing "/" if needed */
- xstrlcat(full_path, "/", sizeof(full_path));
- xstrlcat(full_path, map, sizeof(full_path));
- if (access(full_path, R_OK) == 0)
- return full_path;
- str = strtok(NULL, ":");
- } while (str);
-
- return map; /* if found nothing, return map */
-}
diff --git a/contrib/amd/amd/mntfs.c b/contrib/amd/amd/mntfs.c
deleted file mode 100644
index 6021838425c0..000000000000
--- a/contrib/amd/amd/mntfs.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/mntfs.c
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-qelem mfhead = {&mfhead, &mfhead};
-
-int mntfs_allocated;
-
-
-mntfs *
-dup_mntfs(mntfs *mf)
-{
- if (mf->mf_refc == 0) {
- if (mf->mf_cid)
- untimeout(mf->mf_cid);
- mf->mf_cid = 0;
- }
- mf->mf_refc++;
-
- return mf;
-}
-
-
-static void
-init_mntfs(mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)
-{
- mf->mf_ops = ops;
- mf->mf_fsflags = ops->nfs_fs_flags;
- mf->mf_fo = mo;
- mf->mf_mount = strdup(mp);
- mf->mf_info = strdup(info);
- mf->mf_auto = strdup(auto_opts);
- mf->mf_mopts = strdup(mopts);
- mf->mf_remopts = strdup(remopts);
- mf->mf_loopdev = NULL;
- mf->mf_refc = 1;
- mf->mf_flags = 0;
- mf->mf_error = -1;
- mf->mf_cid = 0;
- mf->mf_private = 0;
- mf->mf_prfree = 0;
-
- if (ops->ffserver)
- mf->mf_server = (*ops->ffserver) (mf);
- else
- mf->mf_server = 0;
-}
-
-
-static mntfs *
-alloc_mntfs(am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)
-{
- mntfs *mf = ALLOC(struct mntfs);
-
- init_mntfs(mf, ops, mo, mp, info, auto_opts, mopts, remopts);
- ins_que(&mf->mf_q, &mfhead);
- mntfs_allocated++;
-
- return mf;
-}
-
-
-/* find a matching mntfs in our list */
-mntfs *
-locate_mntfs(am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)
-{
- mntfs *mf;
-
- dlog("Locating mntfs reference to (%s,%s)", mp, info);
-
- ITER(mf, mntfs, &mfhead) {
- /*
- * For backwards compatibility purposes, we treat already-mounted
- * filesystems differently and only require a match of their mount point,
- * not of their server info. After all, there is little we can do if
- * the user asks us to mount two different things onto the same mount: one
- * will always cover the other one.
- */
- if (STREQ(mf->mf_mount, mp) &&
- ((mf->mf_flags & MFF_MOUNTED && !(mf->mf_fsflags & FS_DIRECT))
- || (STREQ(mf->mf_info, info) && mf->mf_ops == ops))) {
- /*
- * Handle cases where error ops are involved
- */
- if (ops == &amfs_error_ops) {
- /*
- * If the existing ops are not amfs_error_ops
- * then continue...
- */
- if (mf->mf_ops != &amfs_error_ops)
- continue;
- return dup_mntfs(mf);
- }
-
- dlog("mf->mf_flags = %#x", mf->mf_flags);
- mf->mf_fo = mo;
- if ((mf->mf_flags & MFF_RESTART) && amd_state < Finishing) {
- /*
- * Restart a previously mounted filesystem.
- */
- dlog("Restarting filesystem %s", mf->mf_mount);
-
- /*
- * If we are restarting an amd internal filesystem,
- * we need to initialize it a bit.
- *
- * We know it's internal because it is marked as toplvl.
- */
- if (mf->mf_ops == &amfs_toplvl_ops) {
- mf->mf_ops = ops;
- mf->mf_info = strealloc(mf->mf_info, info);
- ops->mounted(mf); /* XXX: not right, but will do for now */
- }
-
- return mf;
- }
-
- if (!(mf->mf_flags & (MFF_MOUNTED | MFF_MOUNTING | MFF_UNMOUNTING))) {
- fserver *fs;
- mf->mf_flags &= ~MFF_ERROR;
- mf->mf_error = -1;
- mf->mf_auto = strealloc(mf->mf_auto, auto_opts);
- mf->mf_mopts = strealloc(mf->mf_mopts, mopts);
- mf->mf_remopts = strealloc(mf->mf_remopts, remopts);
- mf->mf_info = strealloc(mf->mf_info, info);
-
- if (mf->mf_private && mf->mf_prfree) {
- mf->mf_prfree(mf->mf_private);
- mf->mf_private = 0;
- }
-
- fs = ops->ffserver ? (*ops->ffserver) (mf) : (fserver *) NULL;
- if (mf->mf_server)
- free_srvr(mf->mf_server);
- mf->mf_server = fs;
- }
- return dup_mntfs(mf);
- } /* end of "if (STREQ(mf-> ..." */
- } /* end of ITER */
-
- return 0;
-}
-
-
-/* find a matching mntfs in our list, create a new one if none is found */
-mntfs *
-find_mntfs(am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)
-{
- mntfs *mf = locate_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts);
- if (mf)
- return mf;
-
- return alloc_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts);
-}
-
-
-mntfs *
-new_mntfs(void)
-{
- return alloc_mntfs(&amfs_error_ops, (am_opts *) 0, "//nil//", ".", "", "", "");
-}
-
-
-static void
-uninit_mntfs(mntfs *mf)
-{
- if (mf->mf_auto)
- XFREE(mf->mf_auto);
- if (mf->mf_mopts)
- XFREE(mf->mf_mopts);
- if (mf->mf_remopts)
- XFREE(mf->mf_remopts);
- if (mf->mf_info)
- XFREE(mf->mf_info);
- if (mf->mf_private && mf->mf_prfree)
- (*mf->mf_prfree) (mf->mf_private);
-
- if (mf->mf_mount)
- XFREE(mf->mf_mount);
-
- /*
- * Clean up the file server
- */
- if (mf->mf_server)
- free_srvr(mf->mf_server);
-
- /*
- * Don't do a callback on this mount
- */
- if (mf->mf_cid) {
- untimeout(mf->mf_cid);
- mf->mf_cid = 0;
- }
-}
-
-
-static void
-discard_mntfs(voidp v)
-{
- mntfs *mf = v;
-
- rem_que(&mf->mf_q);
-
- /*
- * Free memory
- */
- uninit_mntfs(mf);
- XFREE(mf);
-
- --mntfs_allocated;
-}
-
-
-void
-flush_mntfs(void)
-{
- mntfs *mf;
-
- mf = AM_FIRST(mntfs, &mfhead);
- while (mf != HEAD(mntfs, &mfhead)) {
- mntfs *mf2 = mf;
- mf = NEXT(mntfs, mf);
- if (mf2->mf_refc == 0 && mf2->mf_cid)
- discard_mntfs(mf2);
- }
-}
-
-
-void
-free_mntfs(opaque_t arg)
-{
- mntfs *mf = (mntfs *) arg;
-
- dlog("free_mntfs <%s> type %s mf_refc %d flags %x",
- mf->mf_mount, mf->mf_ops->fs_type, mf->mf_refc, mf->mf_flags);
-
- /*
- * We shouldn't ever be called to free something that has
- * a non-positive refcount. Something is badly wrong if
- * we have been! Ignore the request for now...
- */
- if (mf->mf_refc <= 0) {
- plog(XLOG_ERROR, "IGNORING free_mntfs for <%s>: refc %d, flags %x (bug?)",
- mf->mf_mount, mf->mf_refc, mf->mf_flags);
- return;
- }
-
- /* don't discard last reference of a restarted/kept mntfs */
- if (mf->mf_refc == 1 && mf->mf_flags & MFF_RSTKEEP) {
- plog(XLOG_ERROR, "IGNORING free_mntfs for <%s>: refc %d, flags %x (restarted)",
- mf->mf_mount, mf->mf_refc, mf->mf_flags);
- return;
- }
-
- if (--mf->mf_refc == 0) {
- if (mf->mf_flags & MFF_MOUNTED) {
- int quoted;
- mf->mf_flags &= ~MFF_MOUNTED;
-
- /*
- * Record for posterity
- */
- quoted = strchr(mf->mf_info, ' ') != 0; /* cheap */
- plog(XLOG_INFO, "%s%s%s %sed fstype %s from %s",
- quoted ? "\"" : "",
- mf->mf_info,
- quoted ? "\"" : "",
- mf->mf_error ? "discard" : "unmount",
- mf->mf_ops->fs_type, mf->mf_mount);
- }
-
- if (mf->mf_fsflags & FS_DISCARD) {
- dlog("Immediately discarding mntfs for %s", mf->mf_mount);
- discard_mntfs(mf);
-
- } else {
-
- if (mf->mf_flags & MFF_RESTART) {
- dlog("Discarding remount hook for %s", mf->mf_mount);
- } else {
- dlog("Discarding last mntfs reference to %s fstype %s",
- mf->mf_mount, mf->mf_ops->fs_type);
- }
- if (mf->mf_flags & (MFF_MOUNTED | MFF_MOUNTING | MFF_UNMOUNTING))
- dlog("mntfs reference for %s still active", mf->mf_mount);
- mf->mf_cid = timeout(ALLOWED_MOUNT_TIME, discard_mntfs, (voidp) mf);
- }
- }
-}
-
-
-mntfs *
-realloc_mntfs(mntfs *mf, am_ops *ops, am_opts *mo, char *mp, char *info, char *auto_opts, char *mopts, char *remopts)
-{
- mntfs *mf2;
-
- if (mf->mf_refc == 1 &&
- mf->mf_flags & MFF_RESTART &&
- STREQ(mf->mf_mount, mp)) {
- /*
- * If we are inheriting then just return
- * the same node...
- */
- return mf;
- }
-
- /*
- * Re-use the existing mntfs if it is mounted.
- * This traps a race in nfsx.
- */
- if (mf->mf_ops != &amfs_error_ops &&
- (mf->mf_flags & MFF_MOUNTED) &&
- !FSRV_ISDOWN(mf->mf_server)) {
- mf->mf_fo = mo;
- return mf;
- }
-
- mf2 = find_mntfs(ops, mo, mp, info, auto_opts, mopts, remopts);
- free_mntfs(mf);
- return mf2;
-}
diff --git a/contrib/amd/amd/nfs_prot_svc.c b/contrib/amd/amd/nfs_prot_svc.c
deleted file mode 100644
index 0dd6992cf9e7..000000000000
--- a/contrib/amd/amd/nfs_prot_svc.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/nfs_prot_svc.c
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* external definitions */
-extern voidp nfsproc_null_2_svc(voidp, struct svc_req *);
-extern nfsattrstat *nfsproc_getattr_2_svc(am_nfs_fh *, struct svc_req *);
-extern nfsattrstat *nfsproc_setattr_2_svc(nfssattrargs *, struct svc_req *);
-extern voidp nfsproc_root_2_svc(voidp, struct svc_req *);
-extern nfsdiropres *nfsproc_lookup_2_svc(nfsdiropargs *, struct svc_req *);
-extern nfsreadlinkres *nfsproc_readlink_2_svc(am_nfs_fh *, struct svc_req *);
-extern nfsreadres *nfsproc_read_2_svc(nfsreadargs *, struct svc_req *);
-extern voidp nfsproc_writecache_2_svc(voidp, struct svc_req *);
-extern nfsattrstat *nfsproc_write_2_svc(nfswriteargs *, struct svc_req *);
-extern nfsdiropres *nfsproc_create_2_svc(nfscreateargs *, struct svc_req *);
-extern nfsstat *nfsproc_remove_2_svc(nfsdiropargs *, struct svc_req *);
-extern nfsstat *nfsproc_rename_2_svc(nfsrenameargs *, struct svc_req *);
-extern nfsstat *nfsproc_link_2_svc(nfslinkargs *, struct svc_req *);
-extern nfsstat *nfsproc_symlink_2_svc(nfssymlinkargs *, struct svc_req *);
-extern nfsdiropres *nfsproc_mkdir_2_svc(nfscreateargs *, struct svc_req *);
-extern nfsstat *nfsproc_rmdir_2_svc(nfsdiropargs *, struct svc_req *);
-extern nfsreaddirres *nfsproc_readdir_2_svc(nfsreaddirargs *, struct svc_req *);
-extern nfsstatfsres *nfsproc_statfs_2_svc(am_nfs_fh *, struct svc_req *);
-
-/* global variables */
-SVCXPRT *current_transp;
-
-/* typedefs */
-typedef char *(*nfssvcproc_t)(voidp, struct svc_req *);
-
-
-void
-nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
-{
- union {
- am_nfs_fh nfsproc_getattr_2_arg;
- nfssattrargs nfsproc_setattr_2_arg;
- nfsdiropargs nfsproc_lookup_2_arg;
- am_nfs_fh nfsproc_readlink_2_arg;
- nfsreadargs nfsproc_read_2_arg;
- nfswriteargs nfsproc_write_2_arg;
- nfscreateargs nfsproc_create_2_arg;
- nfsdiropargs nfsproc_remove_2_arg;
- nfsrenameargs nfsproc_rename_2_arg;
- nfslinkargs nfsproc_link_2_arg;
- nfssymlinkargs nfsproc_symlink_2_arg;
- nfscreateargs nfsproc_mkdir_2_arg;
- nfsdiropargs fsproc_rmdir_2_arg;
- nfsreaddirargs nfsproc_readdir_2_arg;
- am_nfs_fh nfsproc_statfs_2_arg;
- } argument;
- char *result;
- xdrproc_t xdr_argument, xdr_result;
- nfssvcproc_t local;
-
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- /*
- * On TLI systems we don't use an INET network type, but a "ticlts" (see
- * /etc/netconfig and conf/transp_tli.c:create_nfs_service). This means
- * that packets could only come from the loopback interface, and we don't
- * need to check them and filter possibly spoofed packets. Therefore we
- * only need to check if the UID caller is correct.
- */
-# ifdef HAVE___RPC_GET_LOCAL_UID
- uid_t u;
- /* extern definition for an internal libnsl function */
- extern int __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid);
- if (__rpc_get_local_uid(transp, &u) >= 0 && u != 0) {
- plog(XLOG_WARNING, "ignoring request from UID %ld, must be 0", (long) u);
- return;
- }
-# else /* not HAVE___RPC_GET_LOCAL_UID */
- dlog("cannot verify local uid for rpc request");
-# endif /* HAVE___RPC_GET_LOCAL_UID */
-#else /* not HAVE_TRANPORT_TYPE_TLI */
- struct sockaddr_in *sinp;
- char dq[20], dq2[28];
- sinp = amu_svc_getcaller(rqstp->rq_xprt);
-# ifdef MNT2_NFS_OPT_RESVPORT
- /* Verify that the request comes from a reserved port */
- if (sinp &&
- ntohs(sinp->sin_port) >= IPPORT_RESERVED &&
- !(gopt.flags & CFM_NFS_INSECURE_PORT)) {
- plog(XLOG_WARNING, "ignoring request from %s:%u, port not reserved",
- inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
- ntohs(sinp->sin_port));
- return;
- }
-# endif /* MNT2_NFS_OPT_RESVPORT */
- /* if the address does not match, ignore the request */
- if (sinp && (sinp->sin_addr.s_addr != myipaddr.s_addr)) {
- if (gopt.flags & CFM_NFS_ANY_INTERFACE) {
- if (!is_interface_local(sinp->sin_addr.s_addr)) {
- plog(XLOG_WARNING, "ignoring request from %s:%u, not a local interface",
- inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
- ntohs(sinp->sin_port));
- }
- } else {
- plog(XLOG_WARNING, "ignoring request from %s:%u, expected %s",
- inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
- ntohs(sinp->sin_port),
- inet_dquad(dq2, sizeof(dq2), myipaddr.s_addr));
- return;
- }
- }
-#endif /* not HAVE_TRANPORT_TYPE_TLI */
-
- current_transp = NULL;
-
- switch (rqstp->rq_proc) {
-
- case NFSPROC_NULL:
- xdr_argument = (xdrproc_t) xdr_void;
- xdr_result = (xdrproc_t) xdr_void;
- local = (nfssvcproc_t) nfsproc_null_2_svc;
- break;
-
- case NFSPROC_GETATTR:
- xdr_argument = (xdrproc_t) xdr_nfs_fh;
- xdr_result = (xdrproc_t) xdr_attrstat;
- local = (nfssvcproc_t) nfsproc_getattr_2_svc;
- break;
-
- case NFSPROC_SETATTR:
- xdr_argument = (xdrproc_t) xdr_sattrargs;
- xdr_result = (xdrproc_t) xdr_attrstat;
- local = (nfssvcproc_t) nfsproc_setattr_2_svc;
- break;
-
- case NFSPROC_ROOT:
- xdr_argument = (xdrproc_t) xdr_void;
- xdr_result = (xdrproc_t) xdr_void;
- local = (nfssvcproc_t) nfsproc_root_2_svc;
- break;
-
- case NFSPROC_LOOKUP:
- xdr_argument = (xdrproc_t) xdr_diropargs;
- xdr_result = (xdrproc_t) xdr_diropres;
- local = (nfssvcproc_t) nfsproc_lookup_2_svc;
- /*
- * Cheap way to pass transp down to amfs_auto_lookuppn so it can
- * be stored in the am_node structure and later used for
- * quick_reply().
- */
- current_transp = transp;
- break;
-
- case NFSPROC_READLINK:
- xdr_argument = (xdrproc_t) xdr_nfs_fh;
- xdr_result = (xdrproc_t) xdr_readlinkres;
- local = (nfssvcproc_t) nfsproc_readlink_2_svc;
- break;
-
- case NFSPROC_READ:
- xdr_argument = (xdrproc_t) xdr_readargs;
- xdr_result = (xdrproc_t) xdr_readres;
- local = (nfssvcproc_t) nfsproc_read_2_svc;
- break;
-
- case NFSPROC_WRITECACHE:
- xdr_argument = (xdrproc_t) xdr_void;
- xdr_result = (xdrproc_t) xdr_void;
- local = (nfssvcproc_t) nfsproc_writecache_2_svc;
- break;
-
- case NFSPROC_WRITE:
- xdr_argument = (xdrproc_t) xdr_writeargs;
- xdr_result = (xdrproc_t) xdr_attrstat;
- local = (nfssvcproc_t) nfsproc_write_2_svc;
- break;
-
- case NFSPROC_CREATE:
- xdr_argument = (xdrproc_t) xdr_createargs;
- xdr_result = (xdrproc_t) xdr_diropres;
- local = (nfssvcproc_t) nfsproc_create_2_svc;
- break;
-
- case NFSPROC_REMOVE:
- xdr_argument = (xdrproc_t) xdr_diropargs;
- xdr_result = (xdrproc_t) xdr_nfsstat;
- local = (nfssvcproc_t) nfsproc_remove_2_svc;
- break;
-
- case NFSPROC_RENAME:
- xdr_argument = (xdrproc_t) xdr_renameargs;
- xdr_result = (xdrproc_t) xdr_nfsstat;
- local = (nfssvcproc_t) nfsproc_rename_2_svc;
- break;
-
- case NFSPROC_LINK:
- xdr_argument = (xdrproc_t) xdr_linkargs;
- xdr_result = (xdrproc_t) xdr_nfsstat;
- local = (nfssvcproc_t) nfsproc_link_2_svc;
- break;
-
- case NFSPROC_SYMLINK:
- xdr_argument = (xdrproc_t) xdr_symlinkargs;
- xdr_result = (xdrproc_t) xdr_nfsstat;
- local = (nfssvcproc_t) nfsproc_symlink_2_svc;
- break;
-
- case NFSPROC_MKDIR:
- xdr_argument = (xdrproc_t) xdr_createargs;
- xdr_result = (xdrproc_t) xdr_diropres;
- local = (nfssvcproc_t) nfsproc_mkdir_2_svc;
- break;
-
- case NFSPROC_RMDIR:
- xdr_argument = (xdrproc_t) xdr_diropargs;
- xdr_result = (xdrproc_t) xdr_nfsstat;
- local = (nfssvcproc_t) nfsproc_rmdir_2_svc;
- break;
-
- case NFSPROC_READDIR:
- xdr_argument = (xdrproc_t) xdr_readdirargs;
- xdr_result = (xdrproc_t) xdr_readdirres;
- local = (nfssvcproc_t) nfsproc_readdir_2_svc;
- break;
-
- case NFSPROC_STATFS:
- xdr_argument = (xdrproc_t) xdr_nfs_fh;
- xdr_result = (xdrproc_t) xdr_statfsres;
- local = (nfssvcproc_t) nfsproc_statfs_2_svc;
- break;
-
- default:
- svcerr_noproc(transp);
- return;
- }
-
- memset((char *) &argument, 0, sizeof(argument));
- if (!svc_getargs(transp,
- (XDRPROC_T_TYPE) xdr_argument,
- (SVC_IN_ARG_TYPE) &argument)) {
- plog(XLOG_ERROR,
- "NFS xdr decode failed for %d %d %d",
- (int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc);
- svcerr_decode(transp);
- return;
- }
- result = (*local) (&argument, rqstp);
-
- current_transp = NULL;
-
- if (result != NULL && !svc_sendreply(transp,
- (XDRPROC_T_TYPE) xdr_result,
- result)) {
- svcerr_systemerr(transp);
- }
- if (!svc_freeargs(transp,
- (XDRPROC_T_TYPE) xdr_argument,
- (SVC_IN_ARG_TYPE) & argument)) {
- plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_2");
- going_down(1);
- }
-}
diff --git a/contrib/amd/amd/nfs_start.c b/contrib/amd/amd/nfs_start.c
deleted file mode 100644
index f6aba94e2b6d..000000000000
--- a/contrib/amd/amd/nfs_start.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/nfs_start.c
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-#ifndef SELECT_MAXWAIT
-# define SELECT_MAXWAIT 16
-#endif /* not SELECT_MAXWAIT */
-
-SVCXPRT *nfsxprt = NULL;
-u_short nfs_port = 0;
-
-#ifndef HAVE_SIGACTION
-# define MASKED_SIGS (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGCHLD)|sigmask(SIGHUP))
-#endif /* not HAVE_SIGACTION */
-
-#ifdef DEBUG
-/*
- * Check that we are not burning resources
- */
-static void
-checkup(void)
-{
-
- static int max_fd = 0;
- static char *max_mem = 0;
-
- int next_fd = dup(0);
- caddr_t next_mem = sbrk(0);
- close(next_fd);
-
- if (max_fd < next_fd) {
- dlog("%d new fds allocated; total is %d",
- next_fd - max_fd, next_fd);
- max_fd = next_fd;
- }
- if (max_mem < next_mem) {
-#ifdef HAVE_GETPAGESIZE
- dlog("%#lx bytes of memory allocated; total is %#lx (%ld pages)",
- (long) (next_mem - max_mem), (unsigned long) next_mem,
- ((long) next_mem + getpagesize() - 1) / (long) getpagesize());
-#else /* not HAVE_GETPAGESIZE */
- dlog("%#lx bytes of memory allocated; total is %#lx",
- (long) (next_mem - max_mem), (unsigned long) next_mem);
-#endif /* not HAVE_GETPAGESIZE */
- max_mem = next_mem;
-
- }
-}
-#else /* not DEBUG */
-#define checkup()
-#endif /* not DEBUG */
-
-
-static int
-#ifdef HAVE_SIGACTION
-do_select(sigset_t smask, int fds, fd_set *fdp, struct timeval *tvp)
-#else /* not HAVE_SIGACTION */
-do_select(int smask, int fds, fd_set *fdp, struct timeval *tvp)
-#endif /* not HAVE_SIGACTION */
-{
-
- int sig;
- int nsel;
-
- if ((sig = setjmp(select_intr))) {
- select_intr_valid = 0;
- /* Got a signal */
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- amd_state = Finishing;
- reschedule_timeout_mp();
- break;
- }
- nsel = -1;
- errno = EINTR;
- } else {
- select_intr_valid = 1;
- /*
- * Allow interrupts. If a signal
- * occurs, then it will cause a longjmp
- * up above.
- */
-#ifdef HAVE_SIGACTION
- sigprocmask(SIG_SETMASK, &smask, NULL);
-#else /* not HAVE_SIGACTION */
- (void) sigsetmask(smask);
-#endif /* not HAVE_SIGACTION */
-
- /*
- * Wait for input
- */
- nsel = select(fds, fdp, (fd_set *) 0, (fd_set *) 0,
- tvp->tv_sec ? tvp : (struct timeval *) 0);
- }
-
-#ifdef HAVE_SIGACTION
- sigprocmask(SIG_BLOCK, &masked_sigs, NULL);
-#else /* not HAVE_SIGACTION */
- (void) sigblock(MASKED_SIGS);
-#endif /* not HAVE_SIGACTION */
-
- /*
- * Perhaps reload the cache?
- */
- if (do_mapc_reload < clocktime(NULL)) {
- mapc_reload();
- do_mapc_reload = clocktime(NULL) + gopt.map_reload_interval;
- }
- return nsel;
-}
-
-
-/*
- * Determine whether anything is left in
- * the RPC input queue.
- */
-static int
-rpc_pending_now(void)
-{
- struct timeval tvv;
- int nsel;
- fd_set readfds;
-
- FD_ZERO(&readfds);
- FD_SET(fwd_sock, &readfds);
-
- tvv.tv_sec = tvv.tv_usec = 0;
- nsel = select(FD_SETSIZE, &readfds, (fd_set *) 0, (fd_set *) 0, &tvv);
- if (nsel < 1)
- return (0);
- if (FD_ISSET(fwd_sock, &readfds))
- return (1);
-
- return (0);
-}
-
-
-static serv_state
-run_rpc(void)
-{
-#ifdef HAVE_SIGACTION
- sigset_t smask;
- sigprocmask(SIG_BLOCK, &masked_sigs, &smask);
-#else /* not HAVE_SIGACTION */
- int smask = sigblock(MASKED_SIGS);
-#endif /* not HAVE_SIGACTION */
-
- next_softclock = clocktime(NULL);
-
- amd_state = Run;
-
- /*
- * Keep on trucking while we are in Run mode. This state
- * is switched to Quit after all the file systems have
- * been unmounted.
- */
- while ((int) amd_state <= (int) Finishing) {
- struct timeval tvv;
- int nsel;
- time_t now;
- fd_set readfds;
-
-#ifdef HAVE_SVC_GETREQSET
- memmove(&readfds, &svc_fdset, sizeof(svc_fdset));
-#else /* not HAVE_SVC_GETREQSET */
- FD_ZERO(&readfds);
-# ifdef HAVE_FD_SET_FDS_BITS
- readfds.fds_bits[0] = svc_fds;
-# else /* not HAVE_FD_SET_FDS_BITS */
- readfds = svc_fds;
-# endif /* not HAVE_FD_SET_FDS_BITS */
-#endif /* not HAVE_SVC_GETREQSET */
- FD_SET(fwd_sock, &readfds);
-
- checkup();
-
- /*
- * If the full timeout code is not called,
- * then recompute the time delta manually.
- */
- now = clocktime(NULL);
-
- if (next_softclock <= now) {
- if (amd_state == Finishing)
- umount_exported();
- tvv.tv_sec = softclock();
- } else {
- tvv.tv_sec = next_softclock - now;
- }
- tvv.tv_usec = 0;
-
- if (amd_state == Finishing && get_exported_ap(0) == NULL) {
- flush_mntfs();
- amd_state = Quit;
- break;
- }
-
-#ifdef HAVE_FS_AUTOFS
- autofs_add_fdset(&readfds);
-#endif /* HAVE_FS_AUTOFS */
-
- if (tvv.tv_sec <= 0)
- tvv.tv_sec = SELECT_MAXWAIT;
- if (tvv.tv_sec) {
- dlog("Select waits for %ds", (int) tvv.tv_sec);
- } else {
- dlog("Select waits for Godot");
- }
-
- nsel = do_select(smask, FD_SETSIZE, &readfds, &tvv);
-
- switch (nsel) {
- case -1:
- if (errno == EINTR) {
- dlog("select interrupted");
- continue;
- }
- plog(XLOG_ERROR, "select: %m");
- break;
-
- case 0:
- break;
-
- default:
- /*
- * Read all pending NFS responses at once to avoid having responses
- * queue up as a consequence of retransmissions.
- */
- if (FD_ISSET(fwd_sock, &readfds)) {
- FD_CLR(fwd_sock, &readfds);
- --nsel;
- do {
- fwd_reply();
- } while (rpc_pending_now() > 0);
- }
-
-#ifdef HAVE_FS_AUTOFS
- if (nsel)
- nsel = autofs_handle_fdset(&readfds, nsel);
-#endif /* HAVE_FS_AUTOFS */
-
- if (nsel) {
- /*
- * Anything left must be a normal
- * RPC request.
- */
-#ifdef HAVE_SVC_GETREQSET
- svc_getreqset(&readfds);
-#else /* not HAVE_SVC_GETREQSET */
-# ifdef HAVE_FD_SET_FDS_BITS
- svc_getreq(readfds.fds_bits[0]);
-# else /* not HAVE_FD_SET_FDS_BITS */
- svc_getreq(readfds);
-# endif /* not HAVE_FD_SET_FDS_BITS */
-#endif /* not HAVE_SVC_GETREQSET */
- }
- break;
- }
- }
-
-#ifdef HAVE_SIGACTION
- sigprocmask(SIG_SETMASK, &smask, NULL);
-#else /* not HAVE_SIGACTION */
- (void) sigsetmask(smask);
-#endif /* not HAVE_SIGACTION */
-
- if (amd_state == Quit)
- amd_state = Done;
-
- return amd_state;
-}
-
-
-int
-mount_automounter(int ppid)
-{
- /*
- * Old code replaced by rpc-trash patch.
- * Erez Zadok <ezk@cs.columbia.edu>
- int so = socket(AF_INET, SOCK_DGRAM, 0);
- */
- SVCXPRT *udp_amqp = NULL, *tcp_amqp = NULL;
- int nmount, ret;
- int soNFS;
- int udp_soAMQ, tcp_soAMQ;
- struct netconfig *udp_amqncp, *tcp_amqncp;
-
- /*
- * This must be done first, because it attempts to bind
- * to various UDP ports and we don't want anything else
- * potentially taking over those ports before we get a chance
- * to reserve them.
- */
- if (gopt.flags & CFM_RESTART_EXISTING_MOUNTS)
- restart_automounter_nodes();
-
- /*
- * Start RPC forwarding
- */
- if (fwd_init() != 0)
- return 3;
-
- /*
- * Construct the root automount node
- */
- make_root_node();
-
- /*
- * Pick up the pieces from a previous run
- * This is likely to (indirectly) need the rpc_fwd package
- * so it *must* come after the call to fwd_init().
- */
- if (gopt.flags & CFM_RESTART_EXISTING_MOUNTS)
- restart();
-
- /*
- * Create the nfs service for amd
- * If nfs_port is already initialized, it means we
- * already created the service during restart_automounter_nodes().
- */
- if (nfs_port == 0) {
- ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
- if (ret != 0)
- return ret;
- }
- xsnprintf(pid_fsname, sizeof(pid_fsname), "%s:(pid%ld,port%u)",
- am_get_hostname(), (long) am_mypid, nfs_port);
-
- /* security: if user sets -D amq, don't even create listening socket */
- if (!amuDebug(D_AMQ)) {
- ret = create_amq_service(&udp_soAMQ,
- &udp_amqp,
- &udp_amqncp,
- &tcp_soAMQ,
- &tcp_amqp,
- &tcp_amqncp,
- gopt.preferred_amq_port);
- if (ret != 0)
- return ret;
- }
-
-#ifdef HAVE_FS_AUTOFS
- if (amd_use_autofs) {
- /*
- * Create the autofs service for amd.
- */
- ret = create_autofs_service();
- /* if autofs service fails it is OK if using a test amd */
- if (ret != 0) {
- plog(XLOG_WARNING, "autofs service registration failed, turning off autofs support");
- amd_use_autofs = 0;
- }
- }
-#endif /* HAVE_FS_AUTOFS */
-
- /*
- * Mount the top-level auto-mountpoints
- */
- nmount = mount_exported();
-
- /*
- * Now safe to tell parent that we are up and running
- */
- if (ppid)
- kill(ppid, SIGQUIT);
-
- if (nmount == 0) {
- plog(XLOG_FATAL, "No work to do - quitting");
- amd_state = Done;
- return 0;
- }
-
- if (!amuDebug(D_AMQ)) {
- /*
- * Complete registration of amq (first TCP service then UDP)
- */
- unregister_amq();
-
- ret = amu_svc_register(tcp_amqp, get_amd_program_number(), AMQ_VERSION,
- amq_program_1, IPPROTO_TCP, tcp_amqncp);
- if (ret != 1) {
- plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM=%d, AMQ_VERSION, tcp)", get_amd_program_number());
- return 3;
- }
-
- ret = amu_svc_register(udp_amqp, get_amd_program_number(), AMQ_VERSION,
- amq_program_1, IPPROTO_UDP, udp_amqncp);
- if (ret != 1) {
- plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM=%d, AMQ_VERSION, udp)", get_amd_program_number());
- return 4;
- }
- }
-
- /*
- * Start timeout_mp rolling
- */
- reschedule_timeout_mp();
-
- /*
- * Start the server
- */
- if (run_rpc() != Done) {
- plog(XLOG_FATAL, "run_rpc failed");
- amd_state = Done;
- }
- return 0;
-}
diff --git a/contrib/amd/amd/nfs_subr.c b/contrib/amd/amd/nfs_subr.c
deleted file mode 100644
index 80d3ca8e311c..000000000000
--- a/contrib/amd/amd/nfs_subr.c
+++ /dev/null
@@ -1,828 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/nfs_subr.c
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/*
- * Convert from UN*X to NFS error code.
- * Some systems like linux define their own (see
- * conf/mount/mount_linux.h).
- */
-#ifndef nfs_error
-# define nfs_error(e) ((nfsstat)(e))
-#endif /* nfs_error */
-
-/*
- * File Handle structure
- *
- * This is interpreted by indexing the exported array
- * by fhh_id (for old-style filehandles), or by retrieving
- * the node name from fhh_path (for new-style filehandles).
- *
- * The whole structure is mapped onto a standard fhandle_t
- * when transmitted.
- */
-struct am_fh {
- u_int fhh_gen; /* generation number */
- union {
- struct {
- int fhh_type; /* old or new am_fh */
- pid_t fhh_pid; /* process id */
- int fhh_id; /* map id */
- } s;
- char fhh_path[NFS_FHSIZE-sizeof(u_int)]; /* path to am_node */
- } u;
-};
-
-
-/* forward declarations */
-/* converting am-filehandles to mount-points */
-static am_node *fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop);
-static am_node *fh_to_mp(am_nfs_fh *fhp);
-static void count_map_entries(const am_node *mp, u_int *out_blocks, u_int *out_bfree, u_int *out_bavail);
-
-
-static char *
-do_readlink(am_node *mp, int *error_return)
-{
- char *ln;
-
- /*
- * If there is a readlink method then use it,
- * otherwise if a link exists use that,
- * otherwise use the mount point.
- */
- if (mp->am_mnt->mf_ops->readlink) {
- int retry = 0;
- mp = (*mp->am_mnt->mf_ops->readlink) (mp, &retry);
- if (mp == 0) {
- *error_return = retry;
- return 0;
- }
- /* reschedule_timeout_mp(); */
- }
-
- if (mp->am_link) {
- ln = mp->am_link;
- } else {
- ln = mp->am_mnt->mf_mount;
- }
-
- return ln;
-}
-
-
-voidp
-nfsproc_null_2_svc(voidp argp, struct svc_req *rqstp)
-{
- static char res;
-
- return (voidp) &res;
-}
-
-
-nfsattrstat *
-nfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
-{
- static nfsattrstat res;
- am_node *mp;
- int retry;
- time_t now = clocktime(NULL);
-
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "getattr:");
-
- mp = fh_to_mp3(argp, &retry, VLOOK_CREATE);
- if (mp == 0) {
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "\tretry=%d", retry);
-
- if (retry < 0) {
- amd_stats.d_drops++;
- return 0;
- }
- res.ns_status = nfs_error(retry);
- return &res;
- }
-
- res = mp->am_attr;
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "\tstat(%s), size = %d, mtime=%ld.%ld",
- mp->am_path,
- (int) res.ns_u.ns_attr_u.na_size,
- (long) res.ns_u.ns_attr_u.na_mtime.nt_seconds,
- (long) res.ns_u.ns_attr_u.na_mtime.nt_useconds);
-
- /* Delay unmount of what was looked up */
- if (mp->am_timeo_w < 4 * gopt.am_timeo_w)
- mp->am_timeo_w += gopt.am_timeo_w;
- mp->am_ttl = now + mp->am_timeo_w;
-
- mp->am_stats.s_getattr++;
- return &res;
-}
-
-
-nfsattrstat *
-nfsproc_setattr_2_svc(nfssattrargs *argp, struct svc_req *rqstp)
-{
- static nfsattrstat res;
-
- if (!fh_to_mp(&argp->sag_fhandle))
- res.ns_status = nfs_error(ESTALE);
- else
- res.ns_status = nfs_error(EROFS);
-
- return &res;
-}
-
-
-voidp
-nfsproc_root_2_svc(voidp argp, struct svc_req *rqstp)
-{
- static char res;
-
- return (voidp) &res;
-}
-
-
-nfsdiropres *
-nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
-{
- static nfsdiropres res;
- am_node *mp;
- int retry;
- uid_t uid;
- gid_t gid;
-
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "lookup:");
-
- /* finally, find the effective uid/gid from RPC request */
- if (getcreds(rqstp, &uid, &gid, nfsxprt) < 0)
- plog(XLOG_ERROR, "cannot get uid/gid from RPC credentials");
- xsnprintf(opt_uid, sizeof(uid_str), "%d", (int) uid);
- xsnprintf(opt_gid, sizeof(gid_str), "%d", (int) gid);
-
- mp = fh_to_mp3(&argp->da_fhandle, &retry, VLOOK_CREATE);
- if (mp == 0) {
- if (retry < 0) {
- amd_stats.d_drops++;
- return 0;
- }
- res.dr_status = nfs_error(retry);
- } else {
- int error;
- am_node *ap;
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "\tlookup(%s, %s)", mp->am_path, argp->da_name);
- ap = mp->am_mnt->mf_ops->lookup_child(mp, argp->da_name, &error, VLOOK_CREATE);
- if (ap && error < 0)
- ap = mp->am_mnt->mf_ops->mount_child(ap, &error);
- if (ap == 0) {
- if (error < 0) {
- amd_stats.d_drops++;
- return 0;
- }
- res.dr_status = nfs_error(error);
- } else {
- /*
- * XXX: EXPERIMENTAL! Delay unmount of what was looked up. This
- * should reduce the chance for race condition between unmounting an
- * entry synchronously, and re-mounting it asynchronously.
- */
- if (ap->am_ttl < mp->am_ttl)
- ap->am_ttl = mp->am_ttl;
- mp_to_fh(ap, &res.dr_u.dr_drok_u.drok_fhandle);
- res.dr_u.dr_drok_u.drok_attributes = ap->am_fattr;
- res.dr_status = NFS_OK;
- }
- mp->am_stats.s_lookup++;
- /* reschedule_timeout_mp(); */
- }
-
- return &res;
-}
-
-
-void
-nfs_quick_reply(am_node *mp, int error)
-{
- SVCXPRT *transp = mp->am_transp;
- nfsdiropres res;
- xdrproc_t xdr_result = (xdrproc_t) xdr_diropres;
-
- /*
- * If there's a transp structure then we can reply to the client's
- * nfs lookup request.
- */
- if (transp) {
- if (error == 0) {
- /*
- * Construct a valid reply to a lookup request. Same
- * code as in nfsproc_lookup_2_svc() above.
- */
- mp_to_fh(mp, &res.dr_u.dr_drok_u.drok_fhandle);
- res.dr_u.dr_drok_u.drok_attributes = mp->am_fattr;
- res.dr_status = NFS_OK;
- } else
- /*
- * Return the error that was passed to us.
- */
- res.dr_status = nfs_error(error);
-
- /*
- * Send off our reply
- */
- if (!svc_sendreply(transp, (XDRPROC_T_TYPE) xdr_result, (SVC_IN_ARG_TYPE) & res))
- svcerr_systemerr(transp);
-
- /*
- * Free up transp. It's only used for one reply.
- */
- XFREE(mp->am_transp);
- dlog("Quick reply sent for %s", mp->am_mnt->mf_mount);
- }
-}
-
-
-nfsreadlinkres *
-nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
-{
- static nfsreadlinkres res;
- am_node *mp;
- int retry;
-
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "readlink:");
-
- mp = fh_to_mp3(argp, &retry, VLOOK_CREATE);
- if (mp == 0) {
- readlink_retry:
- if (retry < 0) {
- amd_stats.d_drops++;
- return 0;
- }
- res.rlr_status = nfs_error(retry);
- } else {
- char *ln = do_readlink(mp, &retry);
- if (ln == 0)
- goto readlink_retry;
- res.rlr_status = NFS_OK;
- if (amuDebug(D_TRACE) && ln)
- plog(XLOG_DEBUG, "\treadlink(%s) = %s", mp->am_path, ln);
- res.rlr_u.rlr_data_u = ln;
- mp->am_stats.s_readlink++;
- }
-
- return &res;
-}
-
-
-nfsreadres *
-nfsproc_read_2_svc(nfsreadargs *argp, struct svc_req *rqstp)
-{
- static nfsreadres res;
-
- memset((char *) &res, 0, sizeof(res));
- res.rr_status = nfs_error(EACCES);
-
- return &res;
-}
-
-
-voidp
-nfsproc_writecache_2_svc(voidp argp, struct svc_req *rqstp)
-{
- static char res;
-
- return (voidp) &res;
-}
-
-
-nfsattrstat *
-nfsproc_write_2_svc(nfswriteargs *argp, struct svc_req *rqstp)
-{
- static nfsattrstat res;
-
- if (!fh_to_mp(&argp->wra_fhandle))
- res.ns_status = nfs_error(ESTALE);
- else
- res.ns_status = nfs_error(EROFS);
-
- return &res;
-}
-
-
-nfsdiropres *
-nfsproc_create_2_svc(nfscreateargs *argp, struct svc_req *rqstp)
-{
- static nfsdiropres res;
-
- if (!fh_to_mp(&argp->ca_where.da_fhandle))
- res.dr_status = nfs_error(ESTALE);
- else
- res.dr_status = nfs_error(EROFS);
-
- return &res;
-}
-
-
-static nfsstat *
-unlink_or_rmdir(nfsdiropargs *argp, struct svc_req *rqstp, int unlinkp)
-{
- static nfsstat res;
- int retry;
-
- am_node *mp = fh_to_mp3(&argp->da_fhandle, &retry, VLOOK_DELETE);
- if (mp == 0) {
- if (retry < 0) {
- amd_stats.d_drops++;
- return 0;
- }
- res = nfs_error(retry);
- goto out;
- }
-
- if (mp->am_fattr.na_type != NFDIR) {
- res = nfs_error(ENOTDIR);
- goto out;
- }
-
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "\tremove(%s, %s)", mp->am_path, argp->da_name);
-
- mp = mp->am_mnt->mf_ops->lookup_child(mp, argp->da_name, &retry, VLOOK_DELETE);
- if (mp == 0) {
- /*
- * Ignore retries...
- */
- if (retry < 0)
- retry = 0;
- /*
- * Usual NFS workaround...
- */
- else if (retry == ENOENT)
- retry = 0;
- res = nfs_error(retry);
- } else {
- forcibly_timeout_mp(mp);
- res = NFS_OK;
- }
-
-out:
- return &res;
-}
-
-
-nfsstat *
-nfsproc_remove_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
-{
- return unlink_or_rmdir(argp, rqstp, TRUE);
-}
-
-
-nfsstat *
-nfsproc_rename_2_svc(nfsrenameargs *argp, struct svc_req *rqstp)
-{
- static nfsstat res;
-
- if (!fh_to_mp(&argp->rna_from.da_fhandle) || !fh_to_mp(&argp->rna_to.da_fhandle))
- res = nfs_error(ESTALE);
- /*
- * If the kernel is doing clever things with referenced files
- * then let it pretend...
- */
- else if (NSTREQ(argp->rna_to.da_name, ".nfs", 4))
- res = NFS_OK;
- /*
- * otherwise a failure
- */
- else
- res = nfs_error(EROFS);
-
- return &res;
-}
-
-
-nfsstat *
-nfsproc_link_2_svc(nfslinkargs *argp, struct svc_req *rqstp)
-{
- static nfsstat res;
-
- if (!fh_to_mp(&argp->la_fhandle) || !fh_to_mp(&argp->la_to.da_fhandle))
- res = nfs_error(ESTALE);
- else
- res = nfs_error(EROFS);
-
- return &res;
-}
-
-
-nfsstat *
-nfsproc_symlink_2_svc(nfssymlinkargs *argp, struct svc_req *rqstp)
-{
- static nfsstat res;
-
- if (!fh_to_mp(&argp->sla_from.da_fhandle))
- res = nfs_error(ESTALE);
- else
- res = nfs_error(EROFS);
-
- return &res;
-}
-
-
-nfsdiropres *
-nfsproc_mkdir_2_svc(nfscreateargs *argp, struct svc_req *rqstp)
-{
- static nfsdiropres res;
-
- if (!fh_to_mp(&argp->ca_where.da_fhandle))
- res.dr_status = nfs_error(ESTALE);
- else
- res.dr_status = nfs_error(EROFS);
-
- return &res;
-}
-
-
-nfsstat *
-nfsproc_rmdir_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
-{
- return unlink_or_rmdir(argp, rqstp, FALSE);
-}
-
-
-nfsreaddirres *
-nfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp)
-{
- static nfsreaddirres res;
- static nfsentry e_res[MAX_READDIR_ENTRIES];
- am_node *mp;
- int retry;
-
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "readdir:");
-
- mp = fh_to_mp3(&argp->rda_fhandle, &retry, VLOOK_CREATE);
- if (mp == 0) {
- if (retry < 0) {
- amd_stats.d_drops++;
- return 0;
- }
- res.rdr_status = nfs_error(retry);
- } else {
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "\treaddir(%s)", mp->am_path);
- res.rdr_status = nfs_error((*mp->am_mnt->mf_ops->readdir)
- (mp, argp->rda_cookie,
- &res.rdr_u.rdr_reply_u, e_res, argp->rda_count));
- mp->am_stats.s_readdir++;
- }
-
- return &res;
-}
-
-
-nfsstatfsres *
-nfsproc_statfs_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
-{
- static nfsstatfsres res;
- am_node *mp;
- int retry;
- mntent_t mnt;
-
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "statfs:");
-
- mp = fh_to_mp3(argp, &retry, VLOOK_CREATE);
- if (mp == 0) {
- if (retry < 0) {
- amd_stats.d_drops++;
- return 0;
- }
- res.sfr_status = nfs_error(retry);
- } else {
- nfsstatfsokres *fp;
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "\tstat_fs(%s)", mp->am_path);
-
- /*
- * just return faked up file system information
- */
- fp = &res.sfr_u.sfr_reply_u;
-
- fp->sfrok_tsize = 1024;
- fp->sfrok_bsize = 1024;
-
- /* check if map is browsable and show_statfs_entries=yes */
- if ((gopt.flags & CFM_SHOW_STATFS_ENTRIES) &&
- mp->am_mnt && mp->am_mnt->mf_mopts) {
- mnt.mnt_opts = mp->am_mnt->mf_mopts;
- if (amu_hasmntopt(&mnt, "browsable")) {
- count_map_entries(mp,
- &fp->sfrok_blocks,
- &fp->sfrok_bfree,
- &fp->sfrok_bavail);
- }
- } else {
- fp->sfrok_blocks = 0; /* set to 1 if you don't want empty automounts */
- fp->sfrok_bfree = 0;
- fp->sfrok_bavail = 0;
- }
-
- res.sfr_status = NFS_OK;
- mp->am_stats.s_statfs++;
- }
-
- return &res;
-}
-
-
-/*
- * count how many total entries there are in a map, and how many
- * of them are in use.
- */
-static void
-count_map_entries(const am_node *mp, u_int *out_blocks, u_int *out_bfree, u_int *out_bavail)
-{
- u_int blocks, bfree, bavail, i;
- mntfs *mf;
- mnt_map *mmp;
- kv *k;
-
- blocks = bfree = bavail = 0;
- if (!mp)
- goto out;
- mf = mp->am_mnt;
- if (!mf)
- goto out;
- mmp = (mnt_map *) mf->mf_private;
- if (!mmp)
- goto out;
-
- /* iterate over keys */
- for (i = 0; i < NKVHASH; i++) {
- for (k = mmp->kvhash[i]; k ; k = k->next) {
- if (!k->key)
- continue;
- blocks++;
- /*
- * XXX: Need to count how many are actively in use and recompute
- * bfree and bavail based on it.
- */
- }
- }
-
-out:
- *out_blocks = blocks;
- *out_bfree = bfree;
- *out_bavail = bavail;
-}
-
-
-/*
- * Convert from file handle to automount node.
- */
-static am_node *
-fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop)
-{
- struct am_fh *fp = (struct am_fh *) fhp;
- am_node *ap = 0;
-
- if (fp->u.s.fhh_type != 0) {
- /* New filehandle type */
- int len = sizeof(*fhp) - sizeof(fp->fhh_gen);
- char *path = xmalloc(len+1);
- /*
- * Because fhp is treated as a filehandle we use memcpy
- * instead of xstrlcpy.
- */
- memcpy(path, (char *) fp->u.fhh_path, len);
- path[len] = '\0';
- /* dlog("fh_to_mp3: new filehandle: %s", path); */
-
- ap = path_to_exported_ap(path);
- XFREE(path);
- } else {
- /* dlog("fh_to_mp3: old filehandle: %d", fp->u.s.fhh_id); */
- /*
- * Check process id matches
- * If it doesn't then it is probably
- * from an old kernel-cached filehandle
- * which is now out of date.
- */
- if (fp->u.s.fhh_pid != get_server_pid()) {
- dlog("fh_to_mp3: wrong pid %ld != my pid %ld",
- (long) fp->u.s.fhh_pid, get_server_pid());
- goto drop;
- }
-
- /*
- * Get hold of the supposed mount node
- */
- ap = get_exported_ap(fp->u.s.fhh_id);
- }
-
- /*
- * Check the generation number in the node
- * matches the one from the kernel. If not
- * then the old node has been timed out and
- * a new one allocated.
- */
- if (ap != NULL && ap->am_gen != fp->fhh_gen)
- ap = 0;
-
- /*
- * If it doesn't exists then drop the request
- */
- if (!ap)
- goto drop;
-
-#if 0
- /*
- * If the node is hung then locate a new node
- * for it. This implements the replicated filesystem
- * retries.
- */
- if (ap->am_mnt && FSRV_ISDOWN(ap->am_mnt->mf_server) && ap->am_parent) {
- int error;
- am_node *orig_ap = ap;
-
- dlog("fh_to_mp3: %s (%s) is hung: lookup alternative file server",
- orig_ap->am_path, orig_ap->am_mnt->mf_info);
-
- /*
- * Update modify time of parent node.
- * With any luck the kernel will re-stat
- * the child node and get new information.
- */
- clocktime(&orig_ap->am_fattr.na_mtime);
-
- /*
- * Call the parent's lookup routine for an object
- * with the same name. This may return -1 in error
- * if a mount is in progress. In any case, if no
- * mount node is returned the error code is propagated
- * to the caller.
- */
- if (vop == VLOOK_CREATE) {
- ap = orig_ap->am_parent->am_mnt->mf_ops->lookup_child(orig_ap->am_parent, orig_ap->am_name, &error, vop);
- if (ap && error < 0)
- ap = orig_ap->am_parent->am_mnt->mf_ops->mount_child(ap, &error);
- } else {
- ap = 0;
- error = ESTALE;
- }
- if (ap == 0) {
- if (error < 0 && amd_state == Finishing)
- error = ENOENT;
- *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);
-
- }
-#endif
-
- /*
- * Disallow references to objects being unmounted, unless
- * they are automount points.
- */
- if (ap->am_mnt && (ap->am_mnt->mf_flags & MFF_UNMOUNTING) &&
- !(ap->am_flags & AMF_ROOT)) {
- if (amd_state == Finishing)
- *rp = ENOENT;
- else
- *rp = -1;
- return 0;
- }
- new_ttl(ap);
-
-drop:
- if (!ap || !ap->am_mnt) {
- /*
- * If we are shutting down then it is likely
- * that this node has disappeared because of
- * a fast timeout. To avoid things thrashing
- * just pretend it doesn't exist at all. If
- * ESTALE is returned, some NFS clients just
- * keep retrying (stupid or what - if it's
- * stale now, what's it going to be in 5 minutes?)
- */
- if (amd_state == Finishing)
- *rp = ENOENT;
- else
- *rp = ESTALE;
- amd_stats.d_stale++;
- }
-
- return ap;
-}
-
-
-static am_node *
-fh_to_mp(am_nfs_fh *fhp)
-{
- int dummy;
-
- return fh_to_mp3(fhp, &dummy, VLOOK_CREATE);
-}
-
-
-/*
- * Convert from automount node to file handle.
- */
-void
-mp_to_fh(am_node *mp, am_nfs_fh *fhp)
-{
- u_int pathlen;
- struct am_fh *fp = (struct am_fh *) fhp;
-
- memset((char *) fhp, 0, sizeof(am_nfs_fh));
-
- /* Store the generation number */
- fp->fhh_gen = mp->am_gen;
-
- pathlen = strlen(mp->am_path);
- if (pathlen <= sizeof(*fhp) - sizeof(fp->fhh_gen)) {
- /* dlog("mp_to_fh: new filehandle: %s", mp->am_path); */
-
- /*
- * Because fhp is treated as a filehandle we use memcpy instead of
- * xstrlcpy.
- */
- memcpy(fp->u.fhh_path, mp->am_path, pathlen); /* making a filehandle */
- } else {
- /*
- * Take the process id
- */
- fp->u.s.fhh_pid = get_server_pid();
-
- /*
- * ... the map number
- */
- fp->u.s.fhh_id = mp->am_mapno;
-
- /*
- * ... and the generation number (previously stored)
- * to make a "unique" triple that will never
- * be reallocated except across reboots (which doesn't matter)
- * or if we are unlucky enough to be given the same
- * pid as a previous amd (very unlikely).
- */
- /* dlog("mp_to_fh: old filehandle: %d", fp->u.s.fhh_id); */
- }
-}
diff --git a/contrib/amd/amd/ops_TEMPLATE.c b/contrib/amd/amd/ops_TEMPLATE.c
deleted file mode 100644
index 3f7421984412..000000000000
--- a/contrib/amd/amd/ops_TEMPLATE.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_TEMPLATE.c
- *
- */
-
-/*
- * An empty template for an amd pseudo filesystem "foofs".
- */
-
-/*
- * NOTE: if this is an Amd file system, prepend "amfs_" to all foofs symbols
- * and renamed the file name to amfs_foofs.c. If it is a native file system
- * (such as pcfs, isofs, or ffs), then you can keep the names as is, and
- * just rename the file to ops_foofs.c.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* forward declarations */
-static char *foofs_match(am_opts *fo);
-static int foofs_init(mntfs *mf);
-static int foofs_mount(am_node *mp, mntfs *mf);
-static int foofs_umount(am_node *mp, mntfs *mf);
-static am_node *foofs_lookuppn(am_node *mp, char *fname, int *error_return, int op);
-static int foofs_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count);
-static am_node *foofs_readlink(am_node *mp, int *error_return);
-static void foofs_mounted(am_node *am, mntfs *mf);
-static void foofs_umounted(am_node *mp, mntfs *mf);
-static fserver *foofs_ffserver(mntfs *mf);
-
-
-/*
- * Foofs operations.
- * Define only those you need, others set to 0 (NULL)
- */
-am_ops foofs_ops =
-{
- "foofs", /* name of file system */
- foofs_match, /* match */
- foofs_init, /* initialize */
- foofs_mount, /* mount vnode */
- foofs_umount, /* unmount vnode */
- foofs_lookup_child, /* lookup path-name */
- foofs_mount_child, /* mount path-name */
- foofs_readdir, /* read directory */
- foofs_readlink, /* read link */
- foofs_mounted, /* after-mount extra actions */
- foofs_umounted, /* after-umount extra actions */
- foofs_ffserver, /* find a file server */
- foofs_get_wchan, /* return the waiting channel */
- FS_MKMNT | FS_BACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_TEMPLATE_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/*
- * Check that f/s has all needed fields.
- * Returns: matched string if found, NULL otherwise.
- */
-static char *
-foofs_match(am_opts *fo)
-{
- char *cp = "fill this with a way to find the match";
-
- plog(XLOG_INFO, "entering foofs_match...");
-
- if (cp)
- return cp; /* OK */
-
- return NULL; /* not OK */
-}
-
-
-/*
- * Initialize.
- * Returns: 0 if OK, non-zero (errno) if failed.
- */
-static int
-foofs_init(mntfs *mf)
-{
- int error = 0;
-
- plog(XLOG_INFO, "entering foofs_init...");
-
- error = EPERM; /* XXX: fixme */
- return error;
-}
-
-
-/*
- * Mount vnode.
- * Returns: 0 if OK, non-zero (errno) if failed.
- */
-static int
-foofs_mount(am_node *mp)
-{
- int error = 0;
-
- plog(XLOG_INFO, "entering foofs_mount...");
-
- error = EPERM; /* XXX: fixme */
- return error;
-}
-
-
-/*
- * Mount vfs.
- * Returns: 0 if OK, non-zero (errno) if failed.
- */
-static int
-foofs_fmount(mntfs *mf)
-{
- int error = 0;
-
- plog(XLOG_INFO, "entering foofs_fmount...");
-
- error = EPERM; /* XXX: fixme */
- return error;
-}
-
-
-/*
- * Unmount vnode.
- * Returns: 0 if OK, non-zero (errno) if failed.
- */
-static int
-foofs_umount(am_node *mp)
-{
- int error = 0;
-
- plog(XLOG_INFO, "entering foofs_umount...");
-
- error = EPERM; /* XXX: fixme */
- return error;
-}
-
-
-/*
- * Unmount VFS.
- * Returns: 0 if OK, non-zero (errno) if failed.
- */
-static int
-foofs_fumount(mntfs *mf)
-{
- int error = 0;
-
- plog(XLOG_INFO, "entering foofs_fumount...");
-
- error = EPERM; /* XXX: fixme */
- return error;
-}
-
-
-/*
- * Lookup path-name.
- * Returns: the am_node that was found, or NULL if failed.
- * If failed, also fills in errno in error_return.
- */
-static am_node *
-foofs_lookuppn(am_node *mp, char *fname, int *error_return, int op)
-{
- int error = 0;
-
- plog(XLOG_INFO, "entering foofs_lookuppn...");
-
- error = EPERM; /* XXX: fixme */
-
- *error_return = error;
- return NULL;
-}
-
-
-/*
- * Read directory.
- * Returns: 0 if OK, non-zero (errno) if failed.
- * If OK, fills in ep with chain of directory entries.
- */
-static int
-foofs_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count)
-{
- int error = 0;
-
- plog(XLOG_INFO, "entering foofs_readdir...");
-
- error = EPERM; /* XXX: fixme */
- return error;
-}
-
-
-/*
- * Read link.
- * Returns: am_node found, or NULL if not found.
- * If failed, fills in errno in error_return.
- */
-static am_node *
-foofs_readlink(am_node *mp, int *error_return)
-{
- int error = 0;
-
- plog(XLOG_INFO, "entering foofs_readlink...");
-
- error = EPERM; /* XXX: fixme */
-
- *error_return = error;
- return NULL;
-}
-
-
-/*
- * Async mount callback function.
- * After the base mount went OK, sometimes
- * there are additional actions that are needed. See union_mounted() and
- * toplvl_mounted().
- */
-static void
-foofs_mounted(mntfs *mf)
-{
- plog(XLOG_INFO, "entering foofs_mounted...");
-
- return;
-}
-
-
-/*
- * Async unmount callback function.
- * After the base umount() succeeds, we may want to take extra actions,
- * such as informing remote mount daemons that we've unmounted them.
- * See amfs_auto_umounted(), host_umounted(), nfs_umounted().
- */
-static void
-foofs_umounted(am_node *mp)
-{
- plog(XLOG_INFO, "entering foofs_umounted...");
-
- return;
-}
-
-
-/*
- * Find a file server.
- * Returns: fserver of found server, or NULL if not found.
- */
-static fserver *
-foofs_ffserver(mntfs *mf)
-{
- plog(XLOG_INFO, "entering foofs_ffserver...");
-
- return NULL;
-}
-
-
-/*
- * Normally just return mf. Only inherit needs to do special tricks.
- */
-static wchan_t *
-foofs_get_wchan(mntfs *mf)
-{
- plog(XLOG_INFO, "entering foofs_get_wchan...");
-
- return mf;
-}
diff --git a/contrib/amd/amd/ops_autofs.c b/contrib/amd/amd/ops_autofs.c
deleted file mode 100644
index bd0bb122fe03..000000000000
--- a/contrib/amd/amd/ops_autofs.c
+++ /dev/null
@@ -1,1279 +0,0 @@
-/*
- * Copyright (c) 1997-2001 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * %W% (Berkeley) %G%
- *
- * $Id: ops_autofs.c,v 1.7.2.4 2001/04/24 06:17:40 ib42 Exp $
- *
- */
-
-/*
- * Automounter filesystem
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/*
- * KLUDGE: wrap whole file in HAVE_FS_AUTOFS, because
- * not all systems with an automounter file system are supported
- * by am-utils yet...
- */
-
-#ifdef HAVE_FS_AUTOFS
-
-/*
- * MACROS:
- */
-#ifndef AUTOFS_NULL
-# define AUTOFS_NULL ((u_long)0)
-#endif /* not AUTOFS_NULL */
-
-/*
- * VARIABLES:
- */
-
-/* forward declarations */
-static int mount_autofs(char *dir, char *opts);
-static int autofs_mount_1_svc(struct mntrequest *mr, struct mntres *result, struct authunix_parms *cred);
-static int autofs_unmount_1_svc(struct umntrequest *ur, struct umntres *result, struct authunix_parms *cred);
-
-/* external declarations */
-extern bool_t xdr_mntrequest(XDR *, mntrequest *);
-extern bool_t xdr_mntres(XDR *, mntres *);
-extern bool_t xdr_umntrequest(XDR *, umntrequest *);
-extern bool_t xdr_umntres(XDR *, umntres *);
-
-/*
- * STRUCTURES:
- */
-
-/* Sun's kernel-based automounter-supporting file system */
-am_ops autofs_ops =
-{
- "autofs",
- amfs_auto_match,
- 0, /* amfs_auto_init */
- autofs_mount,
- 0,
- autofs_umount,
- 0,
- amfs_auto_lookuppn,
- amfs_auto_readdir, /* browsable version of readdir() */
- 0, /* autofs_readlink */
- autofs_mounted,
- 0, /* autofs_umounted */
- find_amfs_auto_srvr,
- FS_MKMNT | FS_NOTIMEOUT | FS_BACKGROUND | FS_AMQINFO | FS_DIRECTORY
-};
-
-
-/****************************************************************************
- *** FUNCTIONS ***
- ****************************************************************************/
-
-/*
- * Mount the top-level using autofs
- */
-int
-autofs_mount(am_node *mp)
-{
- mntfs *mf = mp->am_mnt;
- struct stat stb;
- char opts[256], preopts[256];
- int error;
- char *mnttype;
-
- /*
- * Mounting the automounter.
- * Make sure the mount directory exists, construct
- * the mount options and call the mount_autofs 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 == &autofs_ops)
- mnttype = "indirect";
- else if (mf->mf_ops == &amfs_direct_ops)
- mnttype = "direct";
-#ifdef HAVE_AMU_FS_UNION
- else if (mf->mf_ops == &amfs_union_ops)
- mnttype = "union";
-#endif /* HAVE_AMU_FS_UNION */
- else
- mnttype = "auto";
-
- /*
- * Construct some mount options:
- *
- * Tack on magic map=<mapname> option in mtab to emulate
- * SunOS automounter behavior.
- */
- preopts[0] = '\0';
-#ifdef MNTTAB_OPT_INTR
- strcat(preopts, MNTTAB_OPT_INTR);
- strcat(preopts, ",");
-#endif /* MNTTAB_OPT_INTR */
-#ifdef MNTTAB_OPT_IGNORE
- strcat(preopts, MNTTAB_OPT_IGNORE);
- strcat(preopts, ",");
-#endif /* MNTTAB_OPT_IGNORE */
- sprintf(opts, "%s%s,%s=%d,%s=%d,%s=%d,%s,map=%s",
- preopts,
- MNTTAB_OPT_RW,
- MNTTAB_OPT_PORT, nfs_port,
- MNTTAB_OPT_TIMEO, gopt.amfs_auto_timeo,
- MNTTAB_OPT_RETRANS, gopt.amfs_auto_retrans,
- mnttype, mf->mf_info);
-
- /* now do the mount */
- error = mount_autofs(mf->mf_mount, opts);
- if (error) {
- errno = error;
- plog(XLOG_FATAL, "mount_autofs: %m");
- return error;
- }
- return 0;
-}
-
-
-void
-autofs_mounted(mntfs *mf)
-{
- amfs_auto_mkcacheref(mf);
-}
-
-
-/*
- * Unmount a top-level automount node
- */
-int
-autofs_umount(am_node *mp)
-{
- int error;
- struct stat stb;
-
- /*
- * The lstat is needed if this mount is type=direct. When that happens,
- * the kernel cache gets confused between the underlying type (dir) and
- * the mounted type (link) and so needs to be re-synced before the
- * unmount. This is all because the unmount system call follows links and
- * so can't actually unmount a link (stupid!). It was noted that doing an
- * ls -ld of the mount point to see why things were not working actually
- * fixed the problem - so simulate an ls -ld here.
- */
- if (lstat(mp->am_path, &stb) < 0) {
-#ifdef DEBUG
- dlog("lstat(%s): %m", mp->am_path);
-#endif /* DEBUG */
- }
- error = UMOUNT_FS(mp->am_path, mnttab_file_name);
- if (error == EBUSY && mp->am_flags & AMF_AUTOFS) {
- plog(XLOG_WARNING, "autofs_unmount of %s busy (autofs). exit", mp->am_path);
- error = 0; /* fake unmount was ok */
- }
- return error;
-}
-
-
-/*
- * Mount an automounter directory.
- * The automounter is connected into the system
- * as a user-level NFS server. mount_autofs constructs
- * the necessary NFS parameters to be given to the
- * kernel so that it will talk back to us.
- */
-static int
-mount_autofs(char *dir, char *opts)
-{
- char fs_hostname[MAXHOSTNAMELEN + MAXPATHLEN + 1];
- char *map_opt, buf[MAXHOSTNAMELEN];
- int retry, error, flags;
- struct utsname utsname;
- mntent_t mnt;
- autofs_args_t autofs_args;
- MTYPE_TYPE type = MOUNT_TYPE_AUTOFS;
-
- memset((voidp) &autofs_args, 0, sizeof(autofs_args)); /* Paranoid */
-
- memset((voidp) &mnt, 0, sizeof(mnt));
- mnt.mnt_dir = dir;
- mnt.mnt_fsname = pid_fsname;
- mnt.mnt_opts = opts;
- mnt.mnt_type = type;
-
- retry = hasmntval(&mnt, "retry");
- if (retry <= 0)
- retry = 2; /* XXX */
-
- /*
- * SET MOUNT ARGS
- */
- if (uname(&utsname) < 0) {
- strcpy(buf, "localhost.autofs");
- } else {
- strcpy(buf, utsname.nodename);
- strcat(buf, ".autofs");
- }
-#ifdef HAVE_FIELD_AUTOFS_ARGS_T_ADDR
- autofs_args.addr.buf = buf;
- autofs_args.addr.len = strlen(autofs_args.addr.buf);
- autofs_args.addr.maxlen = autofs_args.addr.len;
-#endif /* HAVE_FIELD_AUTOFS_ARGS_T_ADDR */
-
- autofs_args.path = dir;
- autofs_args.opts = opts;
-
- map_opt = hasmntopt(&mnt, "map");
- if (map_opt) {
- map_opt += sizeof("map="); /* skip the "map=" */
- if (map_opt == NULL) {
- plog(XLOG_WARNING, "map= has a null map name. reset to amd.unknown");
- map_opt = "amd.unknown";
- }
- }
- autofs_args.map = map_opt;
-
- /* XXX: these I set arbitrarily... */
- autofs_args.mount_to = 300;
- autofs_args.rpc_to = 60;
- autofs_args.direct = 0;
-
- /*
- * Make a ``hostname'' string for the kernel
- */
- sprintf(fs_hostname, "pid%ld@%s:%s",
- (long) (foreground ? am_mypid : getppid()),
- am_get_hostname(), dir);
-
- /*
- * Most kernels have a name length restriction.
- */
- if (strlen(fs_hostname) >= MAXHOSTNAMELEN)
- strcpy(fs_hostname + MAXHOSTNAMELEN - 3, "..");
-
- /*
- * Finally we can compute the mount flags set above.
- */
- flags = compute_mount_flags(&mnt);
-
- /*
- * This is it! Here we try to mount amd on its mount points.
- */
- error = mount_fs(&mnt, flags, (caddr_t) &autofs_args, retry, type, 0, NULL, mnttab_file_name);
- return error;
-}
-
-
-/****************************************************************************/
-/* autofs program dispatcher */
-void
-autofs_program_1(struct svc_req *rqstp, SVCXPRT *transp)
-{
- int ret;
- union {
- mntrequest autofs_mount_1_arg;
- umntrequest autofs_umount_1_arg;
- } argument;
- union {
- mntres mount_res;
- umntres umount_res;
- } result;
-
- bool_t (*xdr_argument)(), (*xdr_result)();
- int (*local)();
-
- switch (rqstp->rq_proc) {
-
- case AUTOFS_NULL:
- svc_sendreply(transp,
- (XDRPROC_T_TYPE) xdr_void,
- (SVC_IN_ARG_TYPE) NULL);
- return;
-
- case AUTOFS_MOUNT:
- xdr_argument = xdr_mntrequest;
- xdr_result = xdr_mntres;
- local = (int (*)()) autofs_mount_1_svc;
- break;
-
- case AUTOFS_UNMOUNT:
- xdr_argument = xdr_umntrequest;
- xdr_result = xdr_umntres;
- local = (int (*)()) autofs_unmount_1_svc;
- break;
-
- default:
- svcerr_noproc(transp);
- return;
- }
-
- memset((char *) &argument, 0, sizeof(argument));
- if (!svc_getargs(transp,
- (XDRPROC_T_TYPE) xdr_argument,
- (SVC_IN_ARG_TYPE) &argument)) {
- plog(XLOG_ERROR,
- "AUTOFS xdr decode failed for %d %d %d",
- (int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc);
- svcerr_decode(transp);
- return;
- }
-
- ret = (*local) (&argument, &result, rqstp);
- if (!svc_sendreply(transp,
- (XDRPROC_T_TYPE) xdr_result,
- (SVC_IN_ARG_TYPE) &result)) {
- svcerr_systemerr(transp);
- }
-
- if (!svc_freeargs(transp,
- (XDRPROC_T_TYPE) xdr_argument,
- (SVC_IN_ARG_TYPE) &argument)) {
- plog(XLOG_FATAL, "unable to free rpc arguments in autofs_program_1");
- going_down(1);
- }
-}
-
-
-static int
-autofs_mount_1_svc(struct mntrequest *mr, struct mntres *result, struct authunix_parms *cred)
-{
- int err = 0;
- am_node *anp, *anp2;
-
- plog(XLOG_INFO, "XXX: autofs_mount_1_svc: %s:%s:%s:%s",
- mr->map, mr->name, mr->opts, mr->path);
-
- /* look for map (eg. "/home") */
- anp = find_ap(mr->path);
- if (!anp) {
- plog(XLOG_ERROR, "map %s not found", mr->path);
- err = ENOENT;
- goto out;
- }
- /* turn on autofs in map flags */
- if (!(anp->am_flags & AMF_AUTOFS)) {
- plog(XLOG_INFO, "turning on AMF_AUTOFS for node %s", mr->path);
- anp->am_flags |= AMF_AUTOFS;
- }
-
- /*
- * Look for (and create if needed) the new node.
- *
- * If an error occurred, return it. If a -1 was returned, that indicates
- * that a mount is in progress, so sleep a while (while the backgrounded
- * mount is happening), and then signal the autofs to retry the mount.
- *
- * There's something I don't understand. I was thinking that this code
- * here is the one which will succeed eventually and will send an RPC
- * reply to the kernel, but apparently that happens somewhere else, not
- * here. It works though, just that I don't know how. Arg. -Erez.
- * */
- err = 0;
- anp2 = autofs_lookuppn(anp, mr->name, &err, VLOOK_CREATE);
- if (!anp2) {
- if (err == -1) { /* then tell autofs to retry */
- sleep(1);
- err = EAGAIN;
- }
- goto out;
- }
-
-out:
- result->status = err;
- return err;
-}
-
-
-static int
-autofs_unmount_1_svc(struct umntrequest *ur, struct umntres *result, struct authunix_parms *cred)
-{
- int err = 0;
-
-#ifdef HAVE_FIELD_UMNTREQUEST_RDEVID
- plog(XLOG_INFO, "XXX: autofs_unmount_1_svc: %d:%lu:%lu:0x%lx",
- ur->isdirect, (unsigned long) ur->devid, (unsigned long) ur->rdevid,
- (unsigned long) ur->next);
-#else /* HAVE_FIELD_UMNTREQUEST_RDEVID */
- plog(XLOG_INFO, "XXX: autofs_unmount_1_svc: %d:%lu:0x%lx",
- ur->isdirect, (unsigned long) ur->devid,
- (unsigned long) ur->next);
-#endif /* HAVE_FIELD_UMNTREQUEST_RDEVID */
-
- err = EINVAL; /* XXX: not implemented yet */
- goto out;
-
-out:
- result->status = err;
- return err;
-}
-
-
-/*
- * Pick a file system to try mounting and
- * do that in the background if necessary
- *
- For each location:
- if it is new -defaults then
- extract and process
- continue;
- fi
- if it is a cut then
- if a location has been tried then
- break;
- fi
- continue;
- fi
- parse mount location
- discard previous mount location if required
- find matching mounted filesystem
- if not applicable then
- this_error = No such file or directory
- continue
- fi
- if the filesystem failed to be mounted then
- this_error = error from filesystem
- elif the filesystem is mounting or unmounting then
- this_error = -1
- elif the fileserver is down then
- this_error = -1
- elif the filesystem is already mounted
- this_error = 0
- break
- fi
- if no error on this mount then
- this_error = initialize mount point
- fi
- if no error on this mount and mount is delayed then
- this_error = -1
- fi
- if this_error < 0 then
- retry = true
- fi
- if no error on this mount then
- make mount point if required
- fi
- if no error on this mount then
- if mount in background then
- run mount in background
- return -1
- else
- this_error = mount in foreground
- fi
- fi
- if an error occurred on this mount then
- update stats
- save error in mount point
- fi
- endfor
- */
-static int
-autofs_bgmount(struct continuation *cp, int mpe)
-{
- mntfs *mf = cp->mp->am_mnt; /* Current mntfs */
- mntfs *mf_retry = 0; /* First mntfs which needed retrying */
- int this_error = -1; /* Per-mount error */
- int hard_error = -1;
- int mp_error = mpe;
-
- /*
- * Try to mount each location.
- * At the end:
- * hard_error == 0 indicates something was mounted.
- * hard_error > 0 indicates everything failed with a hard error
- * hard_error < 0 indicates nothing could be mounted now
- */
- for (; this_error && *cp->ivec; cp->ivec++) {
- am_ops *p;
- am_node *mp = cp->mp;
- char *link_dir;
- int dont_retry;
-
- if (hard_error < 0)
- hard_error = this_error;
-
- this_error = -1;
-
- if (**cp->ivec == '-') {
- /*
- * Pick up new defaults
- */
- 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
- dlog("Setting def_opts to \"%s\"", cp->def_opts);
-#endif /* DEBUG */
- continue;
- }
- /*
- * If a mount has been attempted, and we find
- * a cut then don't try any more locations.
- */
- if (STREQ(*cp->ivec, "/") || STREQ(*cp->ivec, "||")) {
- if (cp->tried) {
-#ifdef DEBUG
- dlog("Cut: not trying any more locations for %s",
- mp->am_path);
-#endif /* DEBUG */
- break;
- }
- continue;
- }
-
- /* match the operators */
- p = ops_match(&cp->fs_opts, *cp->ivec, cp->def_opts, mp->am_path, cp->key, mp->am_parent->am_mnt->mf_info);
-
- /*
- * 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->auto_opts,
- cp->fs_opts.opt_opts,
- cp->fs_opts.opt_remopts);
-
- p = mf->mf_ops;
-#ifdef DEBUG
- dlog("Got a hit with %s", p->fs_type);
-#endif /* DEBUG */
-
- /*
- * Note whether this is a real mount attempt
- */
- if (p == &amfs_error_ops) {
- plog(XLOG_MAP, "Map entry %s for %s did not match", *cp->ivec, mp->am_path);
- if (this_error <= 0)
- this_error = ENOENT;
- continue;
- } else {
- if (cp->fs_opts.fs_mtab) {
- plog(XLOG_MAP, "Trying mount of %s on \"%s\" fstype %s",
- cp->fs_opts.fs_mtab, mp->am_path, p->fs_type);
- }
- cp->tried = TRUE;
- }
-
- this_error = 0;
- dont_retry = FALSE;
-
- if (mp->am_link) {
- XFREE(mp->am_link);
- mp->am_link = 0;
- }
- link_dir = mf->mf_fo->opt_sublink;
-
- if (link_dir && *link_dir) {
- if (*link_dir == '/') {
- mp->am_link = strdup(link_dir);
- } else {
- /*
- * try getting fs option from continuation, not mountpoint!
- * Don't try logging the string from mf, since it may be bad!
- */
- if (cp->fs_opts.opt_fs != mf->mf_fo->opt_fs)
- plog(XLOG_ERROR, "use %s instead of 0x%lx",
- cp->fs_opts.opt_fs, (unsigned long) mf->mf_fo->opt_fs);
-
- mp->am_link = str3cat((char *) 0,
- cp->fs_opts.opt_fs, "/", link_dir);
-
- normalize_slash(mp->am_link);
- }
- }
-
- if (mf->mf_error > 0) {
- this_error = mf->mf_error;
- } else if (mf->mf_flags & (MFF_MOUNTING | MFF_UNMOUNTING)) {
- /*
- * Still mounting - retry later
- */
-#ifdef DEBUG
- dlog("Duplicate pending mount fstype %s", p->fs_type);
-#endif /* DEBUG */
- this_error = -1;
- } else if (FSRV_ISDOWN(mf->mf_server)) {
- /*
- * Would just mount from the same place
- * as a hung mount - so give up
- */
-#ifdef DEBUG
- dlog("%s is already hung - giving up", mf->mf_mount);
-#endif /* DEBUG */
- mp_error = EWOULDBLOCK;
- dont_retry = TRUE;
- this_error = -1;
- } else if (mf->mf_flags & MFF_MOUNTED) {
-#ifdef DEBUG
- dlog("duplicate mount of \"%s\" ...", mf->mf_info);
-#endif /* DEBUG */
-
- /*
- * Just call mounted()
- */
- am_mounted(mp);
-
- this_error = 0;
- break;
- }
-
- /*
- * Will usually need to play around with the mount nodes
- * file attribute structure. This must be done here.
- * Try and get things initialized, even if the fileserver
- * is not known to be up. In the common case this will
- * progress things faster.
- */
- if (!this_error) {
- /*
- * Fill in attribute fields.
- */
- if (mf->mf_ops->fs_flags & FS_DIRECTORY)
- mk_fattr(mp, NFDIR);
- else
- mk_fattr(mp, NFLNK);
-
- 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 /* DEBUG */
- this_error = -1;
- }
-
- if (!this_error && mf->mf_fo->opt_delay) {
- /*
- * If there is a delay timer on the mount
- * then don't try to mount if the timer
- * has not expired.
- */
- int i = atoi(mf->mf_fo->opt_delay);
- if (i > 0 && clocktime() < (cp->start + i)) {
-#ifdef DEBUG
- dlog("Mount of %s delayed by %lds", mf->mf_mount, i - clocktime() + cp->start);
-#endif /* DEBUG */
- this_error = -1;
- }
- }
-
- if (this_error < 0 && !dont_retry) {
- if (!mf_retry)
- mf_retry = dup_mntfs(mf);
- cp->retry = TRUE;
- }
-
- if (!this_error) {
- if (p->fs_flags & FS_MBACKGROUND) {
- mf->mf_flags |= MFF_MOUNTING; /* XXX */
-#ifdef DEBUG
- 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, amfs_auto_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 */
- this_error = try_mount((voidp) mp);
- if (this_error < 0) {
- if (!mf_retry)
- mf_retry = dup_mntfs(mf);
- cp->retry = TRUE;
- }
- }
- }
-
- if (this_error >= 0) {
- if (this_error > 0) {
- amd_stats.d_merr++;
- if (mf != mf_retry) {
- mf->mf_error = this_error;
- mf->mf_flags |= MFF_ERROR;
- }
- }
-
- /*
- * Wakeup anything waiting for this mount
- */
- wakeup((voidp) mf);
- }
- }
-
- if (this_error && cp->retry) {
- free_mntfs(mf);
- mf = cp->mp->am_mnt = mf_retry;
- /*
- * Not retrying again (so far)
- */
- cp->retry = FALSE;
- cp->tried = FALSE;
- /*
- * Start at the beginning.
- * Rewind the location vector and
- * reset the default options.
- */
- cp->ivec = cp->xivec;
- cp->def_opts = strealloc(cp->def_opts, cp->auto_opts);
- /*
- * Arrange that autofs_bgmount is called
- * after anything else happens.
- */
-#ifdef DEBUG
- dlog("Arranging to retry mount of %s", cp->mp->am_path);
-#endif /* DEBUG */
- sched_task(amfs_auto_retry, (voidp) cp, (voidp) mf);
- if (cp->callout)
- untimeout(cp->callout);
- cp->callout = timeout(RETRY_INTERVAL, wakeup, (voidp) mf);
-
- cp->mp->am_ttl = clocktime() + RETRY_INTERVAL;
-
- /*
- * Not done yet - so don't return anything
- */
- 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) {
- if (hard_error)
- plog(XLOG_ERROR, "discarding a retry mntfs for %s", mf_retry->mf_mount);
- free_mntfs(mf_retry);
- }
-
- /*
- * If we get here, then either the mount succeeded or
- * there is no more mount information available.
- */
- if (hard_error < 0 && mp_error)
- hard_error = cp->mp->am_error = mp_error;
- if (hard_error > 0) {
- /*
- * Set a small(ish) timeout on an error node if
- * the error was not a time out.
- */
- switch (hard_error) {
- case ETIMEDOUT:
- case EWOULDBLOCK:
- cp->mp->am_timeo = 17;
- break;
- default:
- cp->mp->am_timeo = 5;
- break;
- }
- new_ttl(cp->mp);
- }
-
- /*
- * Make sure that the error value in the mntfs has a
- * reasonable value.
- */
- if (mf->mf_error < 0) {
- mf->mf_error = hard_error;
- if (hard_error)
- mf->mf_flags |= MFF_ERROR;
- }
-
- /*
- * In any case we don't need the continuation any more
- */
- free_continuation(cp);
-
- return hard_error;
-}
-
-
-/*
- * Automount interface to RPC lookup routine
- * Find the corresponding entry and return
- * the file handle for it.
- */
-am_node *
-autofs_lookuppn(am_node *mp, char *fname, int *error_return, 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 */
- char *auto_opts; /* Automount options */
- int error = 0; /* Error so far */
- char path_name[MAXPATHLEN]; /* General path name buffer */
- char apath[MAXPATHLEN]; /* autofs path (added space) */
- char *pfname; /* Path for database lookup */
- struct continuation *cp; /* Continuation structure if need to mount */
- int in_progress = 0; /* # of (un)mount in progress */
- char *dflts;
- mntfs *mf;
-
-#ifdef DEBUG
- dlog("in autofs_lookuppn");
-#endif /* DEBUG */
-
- /*
- * If the server is shutting down
- * then don't return information
- * about the mount point.
- */
- if (amd_state == Finishing) {
-#ifdef DEBUG
- if ((mf = mp->am_mnt) == 0 || mf->mf_ops == &amfs_direct_ops) {
- dlog("%s mount ignored - going down", fname);
- } else {
- dlog("%s/%s mount ignored - going down", mp->am_path, fname);
- }
-#endif /* DEBUG */
- ereturn(ENOENT);
- }
-
- /*
- * Handle special case of "." and ".."
- */
- if (fname[0] == '.') {
- if (fname[1] == '\0')
- return mp; /* "." is the current node */
- if (fname[1] == '.' && fname[2] == '\0') {
- if (mp->am_parent) {
-#ifdef DEBUG
- dlog(".. in %s gives %s", mp->am_path, mp->am_parent->am_path);
-#endif /* DEBUG */
- return mp->am_parent; /* ".." is the parent node */
- }
- ereturn(ESTALE);
- }
- }
-
- /*
- * Check for valid key name.
- * If it is invalid then pretend it doesn't exist.
- */
- if (!valid_key(fname)) {
- plog(XLOG_WARNING, "Key \"%s\" contains a disallowed character", fname);
- ereturn(ENOENT);
- }
-
- /*
- * Expand key name.
- * fname is now a private copy.
- */
- fname = expand_key(fname);
-
- for (ap_hung = 0, ap = mp->am_child; ap; ap = ap->am_osib) {
- /*
- * Otherwise search children of this node
- */
- if (FSTREQ(ap->am_name, fname)) {
- mf = ap->am_mnt;
- if (ap->am_error) {
- error = ap->am_error;
- continue;
- }
- /*
- * If the error code is undefined then it must be
- * in progress.
- */
- if (mf->mf_error < 0)
- goto in_progrss;
-
- /*
- * Check for a hung node
- */
- if (FSRV_ISDOWN(mf->mf_server)) {
-#ifdef DEBUG
- dlog("server hung");
-#endif /* DEBUG */
- error = ap->am_error;
- ap_hung = ap;
- continue;
- }
- /*
- * If there was a previous error with this node
- * then return that error code.
- */
- if (mf->mf_flags & MFF_ERROR) {
- error = mf->mf_error;
- continue;
- }
- if (!(mf->mf_flags & MFF_MOUNTED) || (mf->mf_flags & MFF_UNMOUNTING)) {
- in_progrss:
- /*
- * If the fs is not mounted or it is unmounting then there
- * is a background (un)mount in progress. In this case
- * we just drop the RPC request (return nil) and
- * wait for a retry, by which time the (un)mount may
- * have completed.
- */
-#ifdef DEBUG
- dlog("ignoring mount of %s in %s -- flags (%x) in progress",
- fname, mf->mf_mount, mf->mf_flags);
-#endif /* DEBUG */
- in_progress++;
- continue;
- }
-
- /*
- * Otherwise we have a hit: return the current mount point.
- */
-#ifdef DEBUG
- dlog("matched %s in %s", fname, ap->am_path);
-#endif /* DEBUG */
- XFREE(fname);
- return ap;
- }
- }
-
- if (in_progress) {
-#ifdef DEBUG
- dlog("Waiting while %d mount(s) in progress", in_progress);
-#endif /* DEBUG */
- XFREE(fname);
- ereturn(-1);
- }
-
- /*
- * If an error occurred then return it.
- */
- if (error) {
-#ifdef DEBUG
- errno = error; /* XXX */
- dlog("Returning error: %m");
-#endif /* DEBUG */
- XFREE(fname);
- ereturn(error);
- }
-
- /*
- * If doing a delete then don't create again!
- */
- switch (op) {
- case VLOOK_DELETE:
- ereturn(ENOENT);
-
- case VLOOK_CREATE:
- break;
-
- default:
- plog(XLOG_FATAL, "Unknown op to autofs_lookuppn: 0x%x", op);
- ereturn(EINVAL);
- }
-
- /*
- * If the server is going down then just return,
- * don't try to mount any more file systems
- */
- if ((int) amd_state >= (int) Finishing) {
-#ifdef DEBUG
- dlog("not found - server going down anyway");
-#endif /* DEBUG */
- XFREE(fname);
- ereturn(ENOENT);
- }
-
- /*
- * If we get there then this is a reference to an,
- * as yet, unknown name so we need to search the mount
- * map for it.
- */
- if (mp->am_pref) {
- sprintf(path_name, "%s%s", mp->am_pref, fname);
- pfname = path_name;
- } else {
- pfname = fname;
- }
-
- mf = mp->am_mnt;
-
-#ifdef DEBUG
- dlog("will search map info in %s to find %s", mf->mf_info, pfname);
-#endif /* DEBUG */
- /*
- * Consult the oracle for some mount information.
- * info is malloc'ed and belongs to this routine.
- * It ends up being free'd in free_continuation().
- *
- * Note that this may return -1 indicating that information
- * is not yet available.
- */
- error = mapc_search((mnt_map *) mf->mf_private, pfname, &info);
- if (error) {
- if (error > 0)
- plog(XLOG_MAP, "No map entry for %s", pfname);
- else
- plog(XLOG_MAP, "Waiting on map entry for %s", pfname);
- XFREE(fname);
- ereturn(error);
- }
-#ifdef DEBUG
- dlog("mount info is %s", info);
-#endif /* DEBUG */
-
- /*
- * Split info into an argument vector.
- * The vector is malloc'ed and belongs to
- * this routine. It is free'd in free_continuation()
- */
- xivec = ivec = strsplit(info, ' ', '\"');
-
- /*
- * Default error code...
- */
- if (ap_hung)
- error = EWOULDBLOCK;
- else
- error = ENOENT;
-
- /*
- * Allocate a new map
- */
- new_mp = exported_ap_alloc();
- if (new_mp == 0) {
- XFREE(xivec);
- XFREE(info);
- XFREE(fname);
- ereturn(ENOSPC);
- }
- if (mf->mf_auto)
- auto_opts = mf->mf_auto;
- else
- auto_opts = "";
-
- auto_opts = strdup(auto_opts);
-
-#ifdef DEBUG
- dlog("searching for /defaults entry");
-#endif /* DEBUG */
- if (mapc_search((mnt_map *) mf->mf_private, "/defaults", &dflts) == 0) {
- char *dfl;
- char **rvec;
-#ifdef DEBUG
- dlog("/defaults gave %s", dflts);
-#endif /* DEBUG */
- if (*dflts == '-')
- dfl = dflts + 1;
- else
- dfl = dflts;
-
- /*
- * Chop the defaults up
- */
- rvec = strsplit(dfl, ' ', '\"');
-
- if (gopt.flags & CFM_SELECTORS_IN_DEFAULTS) {
- /*
- * Pick whichever first entry matched the list of selectors.
- * Strip the selectors from the string, and assign to dfl the
- * rest of the string.
- */
- if (rvec) {
- am_opts ap;
- am_ops *pt;
- char **sp = rvec;
- while (*sp) { /* loop until you find something, if any */
- memset((char *) &ap, 0, sizeof(am_opts));
- pt = ops_match(&ap, *sp, "", mp->am_path, "/defaults",
- mp->am_parent->am_mnt->mf_info);
- free_opts(&ap); /* don't leak */
- if (pt == &amfs_error_ops) {
- plog(XLOG_MAP, "did not match defaults for \"%s\"", *sp);
- } else {
- dfl = strip_selectors(*sp, "/defaults");
- plog(XLOG_MAP, "matched default selectors \"%s\"", dfl);
- break;
- }
- ++sp;
- }
- }
- } else { /* not selectors_in_defaults */
- /*
- * Extract first value
- */
- dfl = rvec[0];
- }
-
- /*
- * If there were any values at all...
- */
- if (dfl) {
- /*
- * Log error if there were other values
- */
- if (!(gopt.flags & CFM_SELECTORS_IN_DEFAULTS) && rvec[1]) {
-# ifdef DEBUG
- dlog("/defaults chopped into %s", dfl);
-# endif /* DEBUG */
- plog(XLOG_USER, "More than a single value for /defaults in %s", mf->mf_info);
- }
-
- /*
- * Prepend to existing defaults if they exist,
- * otherwise just use these defaults.
- */
- if (*auto_opts && *dfl) {
- char *nopts = (char *) xmalloc(strlen(auto_opts) + strlen(dfl) + 2);
- sprintf(nopts, "%s;%s", dfl, auto_opts);
- XFREE(auto_opts);
- auto_opts = nopts;
- } else if (*dfl) {
- auto_opts = strealloc(auto_opts, dfl);
- }
- }
- XFREE(dflts);
- /*
- * Don't need info vector any more
- */
- XFREE(rvec);
- }
-
- /*
- * Fill it in
- */
- init_map(new_mp, fname);
-
- /*
- * Turn on autofs flag if needed.
- */
- if (mp->am_flags & AMF_AUTOFS) {
- new_mp->am_flags |= AMF_AUTOFS;
- }
-
- /*
- * Put it in the table
- */
- insert_am(new_mp, mp);
-
- /*
- * Fill in some other fields,
- * path and mount point.
- *
- * bugfix: do not prepend old am_path if direct map
- * <wls@astro.umd.edu> William Sebok
- */
-
- strcpy(apath, fname);
- strcat(apath, " ");
- new_mp->am_path = str3cat(new_mp->am_path,
- mf->mf_ops == &amfs_direct_ops ? "" : mp->am_path,
- *fname == '/' ? "" : "/",
- apath);
-
-#ifdef DEBUG
- dlog("setting path to \"%s\"", new_mp->am_path);
-#endif /* DEBUG */
-
- /*
- * Take private copy of pfname
- */
- pfname = strdup(pfname);
-
- /*
- * Construct a continuation
- */
- cp = ALLOC(struct continuation);
- cp->callout = 0;
- cp->mp = new_mp;
- cp->xivec = xivec;
- cp->ivec = ivec;
- cp->info = info;
- cp->key = pfname;
- cp->auto_opts = auto_opts;
- cp->retry = FALSE;
- cp->tried = FALSE;
- cp->start = clocktime();
- cp->def_opts = strdup(auto_opts);
- memset((voidp) &cp->fs_opts, 0, sizeof(cp->fs_opts));
-
- /*
- * Try and mount the file system. If this succeeds immediately (possible
- * for a ufs file system) then return the attributes, otherwise just
- * return an error.
- */
- error = autofs_bgmount(cp, error);
- reschedule_timeout_mp();
- if (!error) {
- XFREE(fname);
- return new_mp;
- }
-
- /*
- * Code for quick reply. If nfs_program_2_transp is set, then
- * its the transp that's been passed down from nfs_program_2().
- * If new_mp->am_transp is not already set, set it by copying in
- * nfs_program_2_transp. Once am_transp is set, quick_reply() can
- * use it to send a reply to the client that requested this mount.
- */
- if (nfs_program_2_transp && !new_mp->am_transp) {
- new_mp->am_transp = (SVCXPRT *) xmalloc(sizeof(SVCXPRT));
- *(new_mp->am_transp) = *nfs_program_2_transp;
- }
- if (error && (new_mp->am_mnt->mf_ops == &amfs_error_ops))
- new_mp->am_error = error;
-
- assign_error_mntfs(new_mp);
-
- XFREE(fname);
-
- ereturn(error);
-}
-#endif /* HAVE_FS_AUTOFS */
diff --git a/contrib/amd/amd/ops_cachefs.c b/contrib/amd/amd/ops_cachefs.c
deleted file mode 100644
index d3e303bc2bf9..000000000000
--- a/contrib/amd/amd/ops_cachefs.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_cachefs.c
- *
- */
-
-/*
- * Caching filesystem (Solaris 2.x)
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* forward declarations */
-static char *cachefs_match(am_opts *fo);
-static int cachefs_init(mntfs *mf);
-static int cachefs_mount(am_node *am, mntfs *mf);
-static int cachefs_umount(am_node *am, mntfs *mf);
-
-
-/*
- * Ops structure
- */
-am_ops cachefs_ops =
-{
- "cachefs",
- cachefs_match,
- cachefs_init,
- cachefs_mount,
- cachefs_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* cachefs_readlink */
- 0, /* cachefs_mounted */
- 0, /* cachefs_umounted */
- amfs_generic_find_srvr,
- 0, /* cachefs_get_wchan */
- FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_CACHEFS_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/*
- * Check that f/s has all needed fields.
- * Returns: matched string if found, NULL otherwise.
- */
-static char *
-cachefs_match(am_opts *fo)
-{
- /* sanity check */
- if (!fo->opt_rfs || !fo->opt_fs || !fo->opt_cachedir) {
- plog(XLOG_USER, "cachefs: must specify cachedir, rfs, and fs");
- return NULL;
- }
-
- dlog("CACHEFS: using cache directory \"%s\"", fo->opt_cachedir);
-
- /* determine magic cookie to put in mtab */
- return strdup(fo->opt_cachedir);
-}
-
-
-/*
- * Initialize.
- * Returns: 0 if OK, non-zero (errno) if failed.
- */
-static int
-cachefs_init(mntfs *mf)
-{
- /*
- * Save cache directory name
- */
- if (!mf->mf_private) {
- mf->mf_private = (voidp) strdup(mf->mf_fo->opt_cachedir);
- mf->mf_prfree = (void (*)(voidp)) free;
- }
-
- return 0;
-}
-
-
-/*
- * mntpt is the mount point ($fs) [XXX: was 'dir']
- * backdir is the mounted pathname ($rfs) [XXX: was 'fs_name']
- * cachedir is the cache directory ($cachedir)
- */
-static int
-mount_cachefs(char *mntdir, char *backdir, char *cachedir,
- char *opts, int on_autofs)
-{
- cachefs_args_t ca;
- mntent_t mnt;
- int flags;
- char *cp;
- MTYPE_TYPE type = MOUNT_TYPE_CACHEFS; /* F/S mount type */
-
- memset((voidp) &ca, 0, sizeof(ca)); /* Paranoid */
-
- /*
- * Fill in the mount structure
- */
- memset((voidp) &mnt, 0, sizeof(mnt));
- mnt.mnt_dir = mntdir;
- mnt.mnt_fsname = backdir;
- mnt.mnt_type = MNTTAB_TYPE_CACHEFS;
- mnt.mnt_opts = opts;
-
- flags = compute_mount_flags(&mnt);
-#ifdef HAVE_FS_AUTOFS
- if (on_autofs)
- flags |= autofs_compute_mount_flags(&mnt);
-#endif /* HAVE_FS_AUTOFS */
-
- /* Fill in cachefs mount arguments */
-
- /*
- * XXX: Caveats
- * (1) cache directory is NOT checked for sanity beforehand, nor is it
- * purged. Maybe it should be purged first?
- * (2) cache directory is NOT locked. Should we?
- */
-
- /* mount flags */
- ca.cfs_options.opt_flags = CFS_WRITE_AROUND | CFS_ACCESS_BACKFS;
- /* cache population size */
- ca.cfs_options.opt_popsize = DEF_POP_SIZE; /* default: 64K */
- /* filegrp size */
- ca.cfs_options.opt_fgsize = DEF_FILEGRP_SIZE; /* default: 256 */
-
- /* CFS ID for file system (must be unique) */
- ca.cfs_fsid = cachedir;
-
- /* CFS fscdir name */
- memset(ca.cfs_cacheid, 0, sizeof(ca.cfs_cacheid));
- /*
- * Append cacheid and mountpoint.
- * sizeof(cfs_cacheid) should be C_MAX_MOUNT_FSCDIRNAME as per
- * <sys/fs/cachefs_fs.h> (checked on Solaris 8).
- */
- xsnprintf(ca.cfs_cacheid, sizeof(ca.cfs_cacheid),
- "%s:%s", ca.cfs_fsid, mntdir);
- /* convert '/' to '_' (Solaris does that...) */
- cp = ca.cfs_cacheid;
- while ((cp = strpbrk(cp, "/")) != NULL)
- *cp = '_';
-
- /* path for this cache dir */
- ca.cfs_cachedir = cachedir;
-
- /* back filesystem dir */
- ca.cfs_backfs = backdir;
-
- /* same as nfs values (XXX: need to handle these options) */
- ca.cfs_acregmin = 0;
- ca.cfs_acregmax = 0;
- ca.cfs_acdirmin = 0;
- ca.cfs_acdirmax = 0;
-
- /*
- * Call generic mount routine
- */
- return mount_fs(&mnt, flags, (caddr_t) &ca, 0, type, 0, NULL, mnttab_file_name, on_autofs);
-}
-
-
-static int
-cachefs_mount(am_node *am, mntfs *mf)
-{
- int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
- int error;
-
- error = mount_cachefs(mf->mf_mount,
- mf->mf_fo->opt_rfs,
- mf->mf_fo->opt_cachedir,
- mf->mf_mopts,
- on_autofs);
- if (error) {
- errno = error;
- /* according to Solaris, if errno==ESRCH, "options to not match" */
- if (error == ESRCH)
- plog(XLOG_ERROR, "mount_cachefs: options to no match: %m");
- else
- plog(XLOG_ERROR, "mount_cachefs: %m");
- return error;
- }
-
- return 0;
-}
-
-
-static int
-cachefs_umount(am_node *am, mntfs *mf)
-{
- int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
- int error;
-
- error = UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
-
- /*
- * In the case of cachefs, we must fsck the cache directory. Otherwise,
- * it will remain inconsistent, and the next cachefs mount will fail
- * with the error "no space left on device" (ENOSPC).
- *
- * XXX: this is hacky! use fork/exec/wait instead...
- */
- if (!error) {
- char *cachedir = NULL;
- char cmd[128];
-
- cachedir = (char *) mf->mf_private;
- plog(XLOG_INFO, "running fsck on cache directory \"%s\"", cachedir);
- xsnprintf(cmd, sizeof(cmd), "fsck -F cachefs %s", cachedir);
- system(cmd);
- }
-
- return error;
-}
diff --git a/contrib/amd/amd/ops_cdfs.c b/contrib/amd/amd/ops_cdfs.c
deleted file mode 100644
index 40355ac5c078..000000000000
--- a/contrib/amd/amd/ops_cdfs.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_cdfs.c
- *
- */
-
-/*
- * High Sierra (CD-ROM) file system
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* forward declarations */
-static char *cdfs_match(am_opts *fo);
-static int cdfs_mount(am_node *am, mntfs *mf);
-static int cdfs_umount(am_node *am, mntfs *mf);
-
-/*
- * Ops structure
- */
-am_ops cdfs_ops =
-{
- "cdfs",
- cdfs_match,
- 0, /* cdfs_init */
- cdfs_mount,
- cdfs_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* cdfs_readlink */
- 0, /* cdfs_mounted */
- 0, /* cdfs_umounted */
- amfs_generic_find_srvr,
- 0, /* cdfs_get_wchan */
- FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_CDFS_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/*
- * CDFS needs remote filesystem.
- */
-static char *
-cdfs_match(am_opts *fo)
-{
- if (!fo->opt_dev) {
- plog(XLOG_USER, "cdfs: no source device specified");
- return 0;
- }
- dlog("CDFS: mounting device \"%s\" on \"%s\"",
- fo->opt_dev, fo->opt_fs);
-
- /*
- * Determine magic cookie to put in mtab
- */
- return strdup(fo->opt_dev);
-}
-
-
-static int
-mount_cdfs(char *mntdir, char *fs_name, char *opts, int on_autofs)
-{
- cdfs_args_t cdfs_args;
- mntent_t mnt;
- int genflags, cdfs_flags, retval;
-
- /*
- * Figure out the name of the file system type.
- */
- MTYPE_TYPE type = MOUNT_TYPE_CDFS;
-
- memset((voidp) &cdfs_args, 0, sizeof(cdfs_args)); /* Paranoid */
- cdfs_flags = 0;
-
- /*
- * Fill in the mount structure
- */
- memset((voidp) &mnt, 0, sizeof(mnt));
- mnt.mnt_dir = mntdir;
- mnt.mnt_fsname = fs_name;
- mnt.mnt_type = MNTTAB_TYPE_CDFS;
- mnt.mnt_opts = opts;
-
-#if defined(MNT2_CDFS_OPT_DEFPERM) && defined(MNTTAB_OPT_DEFPERM)
- if (amu_hasmntopt(&mnt, MNTTAB_OPT_DEFPERM))
-# ifdef MNT2_CDFS_OPT_DEFPERM
- cdfs_flags |= MNT2_CDFS_OPT_DEFPERM;
-# else /* not MNT2_CDFS_OPT_DEFPERM */
- cdfs_flags &= ~MNT2_CDFS_OPT_NODEFPERM;
-# endif /* not MNT2_CDFS_OPT_DEFPERM */
-#endif /* defined(MNT2_CDFS_OPT_DEFPERM) && defined(MNTTAB_OPT_DEFPERM) */
-
-#if defined(MNT2_CDFS_OPT_NODEFPERM) && defined(MNTTAB_OPT_NODEFPERM)
- if (amu_hasmntopt(&mnt, MNTTAB_OPT_NODEFPERM))
- cdfs_flags |= MNT2_CDFS_OPT_NODEFPERM;
-#endif /* MNTTAB_OPT_NODEFPERM */
-
-#if defined(MNT2_CDFS_OPT_NOVERSION) && defined(MNTTAB_OPT_NOVERSION)
- if (amu_hasmntopt(&mnt, MNTTAB_OPT_NOVERSION))
- cdfs_flags |= MNT2_CDFS_OPT_NOVERSION;
-#endif /* defined(MNT2_CDFS_OPT_NOVERSION) && defined(MNTTAB_OPT_NOVERSION) */
-
-#if defined(MNT2_CDFS_OPT_RRIP) && defined(MNTTAB_OPT_RRIP)
- if (amu_hasmntopt(&mnt, MNTTAB_OPT_RRIP))
- cdfs_flags |= MNT2_CDFS_OPT_RRIP;
-#endif /* defined(MNT2_CDFS_OPT_RRIP) && defined(MNTTAB_OPT_RRIP) */
-#if defined(MNT2_CDFS_OPT_NORRIP) && defined(MNTTAB_OPT_NORRIP)
- if (amu_hasmntopt(&mnt, MNTTAB_OPT_NORRIP))
- cdfs_flags |= MNT2_CDFS_OPT_NORRIP;
-#endif /* defined(MNT2_CDFS_OPT_NORRIP) && defined(MNTTAB_OPT_NORRIP) */
-
-#if defined(MNT2_CDFS_OPT_GENS) && defined(MNTTAB_OPT_GENS)
- if (amu_hasmntopt(&mnt, MNTTAB_OPT_GENS))
- cdfs_flags |= MNT2_CDFS_OPT_GENS;
-#endif /* defined(MNT2_CDFS_OPT_GENS) && defined(MNTTAB_OPT_GENS) */
-#if defined(MNT2_CDFS_OPT_EXTATT) && defined(MNTTAB_OPT_EXTATT)
- if (amu_hasmntopt(&mnt, MNTTAB_OPT_EXTATT))
- cdfs_flags |= MNT2_CDFS_OPT_EXTATT;
-#endif /* defined(MNT2_CDFS_OPT_EXTATT) && defined(MNTTAB_OPT_EXTATT) */
-
- genflags = compute_mount_flags(&mnt);
-#ifdef HAVE_FS_AUTOFS
- if (on_autofs)
- genflags |= autofs_compute_mount_flags(&mnt);
-#endif /* HAVE_FS_AUTOFS */
-
-#ifdef HAVE_CDFS_ARGS_T_FLAGS
- cdfs_args.flags = cdfs_flags;
-#endif /* HAVE_CDFS_ARGS_T_FLAGS */
-
-#ifdef HAVE_CDFS_ARGS_T_ISO_FLAGS
- cdfs_args.iso_flags = genflags | cdfs_flags;
-#endif /* HAVE_CDFS_ARGS_T_ISO_FLAGS */
-
-#ifdef HAVE_CDFS_ARGS_T_ISO_PGTHRESH
- cdfs_args.iso_pgthresh = hasmntval(&mnt, MNTTAB_OPT_PGTHRESH);
-#endif /* HAVE_CDFS_ARGS_T_ISO_PGTHRESH */
-
-#ifdef HAVE_CDFS_ARGS_T_NORRIP
- /* XXX: need to provide norrip mount opt */
- cdfs_args.norrip = 0; /* use Rock-Ridge Protocol extensions */
-#endif /* HAVE_CDFS_ARGS_T_NORRIP */
-
-#ifdef HAVE_CDFS_ARGS_T_SSECTOR
- /* XXX: need to provide ssector mount option */
- cdfs_args.ssector = 0; /* use 1st session on disk */
-#endif /* HAVE_CDFS_ARGS_T_SSECTOR */
-
-#ifdef HAVE_CDFS_ARGS_T_FSPEC
- cdfs_args.fspec = fs_name;
-#endif /* HAVE_CDFS_ARGS_T_FSPEC */
-
- /*
- * Call generic mount routine
- */
- retval = mount_fs(&mnt, genflags, (caddr_t) &cdfs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs);
-
- return retval;
-}
-
-
-static int
-cdfs_mount(am_node *am, mntfs *mf)
-{
- int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
- int error;
-
- error = mount_cdfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
- if (error) {
- errno = error;
- plog(XLOG_ERROR, "mount_cdfs: %m");
- return error;
- }
- return 0;
-}
-
-
-static int
-cdfs_umount(am_node *am, mntfs *mf)
-{
- int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
-
- return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
-}
diff --git a/contrib/amd/amd/ops_efs.c b/contrib/amd/amd/ops_efs.c
deleted file mode 100644
index 047fe1e4690c..000000000000
--- a/contrib/amd/amd/ops_efs.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_efs.c
- *
- */
-
-/*
- * Irix UN*X file system: EFS (Extent File System)
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* forward declarations */
-static char *efs_match(am_opts *fo);
-static int efs_mount(am_node *am, mntfs *mf);
-static int efs_umount(am_node *am, mntfs *mf);
-
-/*
- * Ops structure
- */
-am_ops efs_ops =
-{
- "efs",
- efs_match,
- 0, /* efs_init */
- efs_mount,
- efs_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* efs_readlink */
- 0, /* efs_mounted */
- 0, /* efs_umounted */
- amfs_generic_find_srvr,
- 0, /* efs_get_wchan */
- FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_EFS_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/*
- * EFS needs local filesystem and device.
- */
-static char *
-efs_match(am_opts *fo)
-{
-
- if (!fo->opt_dev) {
- plog(XLOG_USER, "efs: no device specified");
- return 0;
- }
-
- dlog("EFS: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs);
-
- /*
- * Determine magic cookie to put in mtab
- */
- return strdup(fo->opt_dev);
-}
-
-
-static int
-mount_efs(char *mntdir, char *fs_name, char *opts, int on_autofs)
-{
- efs_args_t efs_args;
- mntent_t mnt;
- int flags;
-
- /*
- * Figure out the name of the file system type.
- */
- MTYPE_TYPE type = MOUNT_TYPE_EFS;
-
- memset((voidp) &efs_args, 0, sizeof(efs_args)); /* Paranoid */
-
- /*
- * Fill in the mount structure
- */
- memset((voidp) &mnt, 0, sizeof(mnt));
- mnt.mnt_dir = mntdir;
- mnt.mnt_fsname = fs_name;
- mnt.mnt_type = MNTTAB_TYPE_EFS;
- mnt.mnt_opts = opts;
-
- flags = compute_mount_flags(&mnt);
-#ifdef HAVE_FS_AUTOFS
- if (on_autofs)
- flags |= autofs_compute_mount_flags(&mnt);
-#endif /* HAVE_FS_AUTOFS */
-
-#ifdef HAVE_EFS_ARGS_T_FLAGS
- efs_args.flags = 0; /* XXX: fix this to correct flags */
-#endif /* HAVE_EFS_ARGS_T_FLAGS */
-#ifdef HAVE_EFS_ARGS_T_FSPEC
- efs_args.fspec = fs_name;
-#endif /* HAVE_EFS_ARGS_T_FSPEC */
-
- /*
- * Call generic mount routine
- */
- return mount_fs(&mnt, flags, (caddr_t) &efs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs);
-}
-
-
-static int
-efs_mount(am_node *am, mntfs *mf)
-{
- int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
- int error;
-
- error = mount_efs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
- if (error) {
- errno = error;
- plog(XLOG_ERROR, "mount_efs: %m");
- return error;
- }
-
- return 0;
-}
-
-
-static int
-efs_umount(am_node *am, mntfs *mf)
-{
- int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
-
- return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
-}
-
diff --git a/contrib/amd/amd/ops_lofs.c b/contrib/amd/amd/ops_lofs.c
deleted file mode 100644
index 26fdc9f9b626..000000000000
--- a/contrib/amd/amd/ops_lofs.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_lofs.c
- *
- */
-
-/*
- * Loopback file system
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* forward definitions */
-static char *lofs_match(am_opts *fo);
-static int lofs_mount(am_node *am, mntfs *mf);
-static int lofs_umount(am_node *am, mntfs *mf);
-
-/*
- * Ops structure
- */
-am_ops lofs_ops =
-{
- "lofs",
- lofs_match,
- 0, /* lofs_init */
- lofs_mount,
- lofs_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* lofs_readlink */
- 0, /* lofs_mounted */
- 0, /* lofs_umounted */
- amfs_generic_find_srvr,
- 0, /* lofs_get_wchan */
- FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_LOFS_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/*
- * LOFS needs remote filesystem.
- */
-static char *
-lofs_match(am_opts *fo)
-{
- if (!fo->opt_rfs) {
- plog(XLOG_USER, "lofs: no source filesystem specified");
- return 0;
- }
- dlog("LOFS: mounting fs \"%s\" on \"%s\"",
- fo->opt_rfs, fo->opt_fs);
-
- /*
- * Determine magic cookie to put in mtab
- */
- return strdup(fo->opt_rfs);
-}
-
-
-int
-mount_lofs(char *mntdir, char *fs_name, char *opts, int on_autofs)
-{
- mntent_t mnt;
- int flags;
-
- /*
- * Figure out the name of the file system type.
- */
- MTYPE_TYPE type = MOUNT_TYPE_LOFS;
-
- /*
- * Fill in the mount structure
- */
- memset((voidp) &mnt, 0, sizeof(mnt));
- mnt.mnt_dir = mntdir;
- mnt.mnt_fsname = fs_name;
- mnt.mnt_type = MNTTAB_TYPE_LOFS;
- mnt.mnt_opts = opts;
-
- flags = compute_mount_flags(&mnt);
-#ifdef HAVE_FS_AUTOFS
- if (on_autofs)
- flags |= autofs_compute_mount_flags(&mnt);
-#endif /* HAVE_FS_AUTOFS */
-
- /*
- * Call generic mount routine
- */
- return mount_fs(&mnt, flags, NULL, 0, type, 0, NULL, mnttab_file_name, on_autofs);
-}
-
-
-static int
-lofs_mount(am_node *am, mntfs *mf)
-{
- int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
- int error;
-
- error = mount_lofs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
- if (error) {
- errno = error;
- plog(XLOG_ERROR, "mount_lofs: %m");
- return error;
- }
- return 0;
-}
-
-
-static int
-lofs_umount(am_node *am, mntfs *mf)
-{
- int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
-
- return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
-}
diff --git a/contrib/amd/amd/ops_mfs.c b/contrib/amd/amd/ops_mfs.c
deleted file mode 100644
index ccaa49c569cd..000000000000
--- a/contrib/amd/amd/ops_mfs.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_mfs.c
- *
- */
-
-/*
- * Memory file system (RAM filesystem)
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* FEEL FREE TO IMPLEMENT THIS... :-) */
diff --git a/contrib/amd/amd/ops_nfs.c b/contrib/amd/amd/ops_nfs.c
deleted file mode 100644
index a6a85858d484..000000000000
--- a/contrib/amd/amd/ops_nfs.c
+++ /dev/null
@@ -1,1042 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_nfs.c
- *
- */
-
-/*
- * Network file system
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/*
- * Convert from nfsstat to UN*X error code
- */
-#define unx_error(e) ((int)(e))
-
-/*
- * FH_TTL is the time a file handle will remain in the cache since
- * last being used. If the file handle becomes invalid, then it
- * will be flushed anyway.
- */
-#define FH_TTL (5 * 60) /* five minutes */
-#define FH_TTL_ERROR (30) /* 30 seconds */
-#define FHID_ALLOC() (++fh_id)
-
-/*
- * The NFS layer maintains a cache of file handles.
- * This is *fundamental* to the implementation and
- * also allows quick remounting when a filesystem
- * is accessed soon after timing out.
- *
- * The NFS server layer knows to flush this cache
- * when a server goes down so avoiding stale handles.
- *
- * Each cache entry keeps a hard reference to
- * the corresponding server. This ensures that
- * the server keepalive information is maintained.
- *
- * The copy of the sockaddr_in here is taken so
- * that the port can be twiddled to talk to mountd
- * instead of portmap or the NFS server as used
- * elsewhere.
- * The port# is flushed if a server goes down.
- * The IP address is never flushed - we assume
- * that the address of a mounted machine never
- * changes. If it does, then you have other
- * problems...
- */
-typedef struct fh_cache fh_cache;
-struct fh_cache {
- qelem fh_q; /* List header */
- wchan_t fh_wchan; /* Wait channel */
- int fh_error; /* Valid data? */
- int fh_id; /* Unique id */
- int fh_cid; /* Callout id */
- u_long fh_nfs_version; /* highest NFS version on host */
- am_nfs_handle_t fh_nfs_handle; /* Handle on filesystem */
- int fh_status; /* Status of last rpc */
- struct sockaddr_in fh_sin; /* Address of mountd */
- fserver *fh_fs; /* Server holding filesystem */
- char *fh_path; /* Filesystem on host */
-};
-
-/* forward definitions */
-static int nfs_init(mntfs *mf);
-static char *nfs_match(am_opts *fo);
-static int nfs_mount(am_node *am, mntfs *mf);
-static int nfs_umount(am_node *am, mntfs *mf);
-static void nfs_umounted(mntfs *mf);
-static int call_mountd(fh_cache *fp, u_long proc, fwd_fun f, wchan_t wchan);
-static int webnfs_lookup(fh_cache *fp, fwd_fun f, wchan_t wchan);
-static int fh_id = 0;
-
-/* globals */
-AUTH *nfs_auth;
-qelem fh_head = {&fh_head, &fh_head};
-
-/*
- * Network file system operations
- */
-am_ops nfs_ops =
-{
- "nfs",
- nfs_match,
- nfs_init,
- nfs_mount,
- nfs_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* nfs_readlink */
- 0, /* nfs_mounted */
- nfs_umounted,
- find_nfs_srvr,
- 0, /* nfs_get_wchan */
- FS_MKMNT | FS_BACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_NFS_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-static fh_cache *
-find_nfs_fhandle_cache(opaque_t arg, int done)
-{
- fh_cache *fp, *fp2 = 0;
- int id = (long) arg; /* for 64-bit archs */
-
- ITER(fp, fh_cache, &fh_head) {
- if (fp->fh_id == id) {
- fp2 = fp;
- break;
- }
- }
-
- if (fp2) {
- dlog("fh cache gives fp %#lx, fs %s", (unsigned long) fp2, fp2->fh_path);
- } else {
- dlog("fh cache search failed");
- }
-
- if (fp2 && !done) {
- fp2->fh_error = ETIMEDOUT;
- return 0;
- }
-
- return fp2;
-}
-
-
-/*
- * Called when a filehandle appears via the mount protocol
- */
-static void
-got_nfs_fh_mount(voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, opaque_t arg, int done)
-{
- fh_cache *fp;
- struct fhstatus res;
-#ifdef HAVE_FS_NFS3
- struct am_mountres3 res3;
-#endif /* HAVE_FS_NFS3 */
-
- fp = find_nfs_fhandle_cache(arg, done);
- if (!fp)
- return;
-
- /*
- * retrieve the correct RPC reply for the file handle, based on the
- * NFS protocol version.
- */
-#ifdef HAVE_FS_NFS3
- if (fp->fh_nfs_version == NFS_VERSION3) {
- memset(&res3, 0, sizeof(res3));
- fp->fh_error = pickup_rpc_reply(pkt, len, (voidp) &res3,
- (XDRPROC_T_TYPE) xdr_am_mountres3);
- fp->fh_status = unx_error(res3.fhs_status);
- memset(&fp->fh_nfs_handle.v3, 0, sizeof(am_nfs_fh3));
- fp->fh_nfs_handle.v3.am_fh3_length = res3.mountres3_u.mountinfo.fhandle.fhandle3_len;
- memmove(fp->fh_nfs_handle.v3.am_fh3_data,
- res3.mountres3_u.mountinfo.fhandle.fhandle3_val,
- fp->fh_nfs_handle.v3.am_fh3_length);
- } else {
-#endif /* HAVE_FS_NFS3 */
- memset(&res, 0, sizeof(res));
- fp->fh_error = pickup_rpc_reply(pkt, len, (voidp) &res,
- (XDRPROC_T_TYPE) xdr_fhstatus);
- fp->fh_status = unx_error(res.fhs_status);
- memmove(&fp->fh_nfs_handle.v2, &res.fhs_fh, NFS_FHSIZE);
-#ifdef HAVE_FS_NFS3
- }
-#endif /* HAVE_FS_NFS3 */
-
- if (!fp->fh_error) {
- dlog("got filehandle for %s:%s", fp->fh_fs->fs_host, fp->fh_path);
- } else {
- plog(XLOG_USER, "filehandle denied for %s:%s", fp->fh_fs->fs_host, fp->fh_path);
- /*
- * Force the error to be EACCES. It's debatable whether it should be
- * ENOENT instead, but the server really doesn't give us any clues, and
- * EACCES is more in line with the "filehandle denied" message.
- */
- fp->fh_error = EACCES;
- }
-
- /*
- * Wakeup anything sleeping on this filehandle
- */
- if (fp->fh_wchan) {
- dlog("Calling wakeup on %#lx", (unsigned long) fp->fh_wchan);
- wakeup(fp->fh_wchan);
- }
-}
-
-
-/*
- * Called when a filehandle appears via WebNFS
- */
-static void
-got_nfs_fh_webnfs(voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, opaque_t arg, int done)
-{
- fh_cache *fp;
- nfsdiropres res;
-#ifdef HAVE_FS_NFS3
- am_LOOKUP3res res3;
-#endif /* HAVE_FS_NFS3 */
-
- fp = find_nfs_fhandle_cache(arg, done);
- if (!fp)
- return;
-
- /*
- * retrieve the correct RPC reply for the file handle, based on the
- * NFS protocol version.
- */
-#ifdef HAVE_FS_NFS3
- if (fp->fh_nfs_version == NFS_VERSION3) {
- memset(&res3, 0, sizeof(res3));
- fp->fh_error = pickup_rpc_reply(pkt, len, (voidp) &res3,
- (XDRPROC_T_TYPE) xdr_am_LOOKUP3res);
- fp->fh_status = unx_error(res3.status);
- memset(&fp->fh_nfs_handle.v3, 0, sizeof(am_nfs_fh3));
- fp->fh_nfs_handle.v3.am_fh3_length = res3.res_u.ok.object.am_fh3_length;
- memmove(fp->fh_nfs_handle.v3.am_fh3_data,
- res3.res_u.ok.object.am_fh3_data,
- fp->fh_nfs_handle.v3.am_fh3_length);
- } else {
-#endif /* HAVE_FS_NFS3 */
- memset(&res, 0, sizeof(res));
- fp->fh_error = pickup_rpc_reply(pkt, len, (voidp) &res,
- (XDRPROC_T_TYPE) xdr_diropres);
- fp->fh_status = unx_error(res.dr_status);
- memmove(&fp->fh_nfs_handle.v2, &res.dr_u.dr_drok_u.drok_fhandle, NFS_FHSIZE);
-#ifdef HAVE_FS_NFS3
- }
-#endif /* HAVE_FS_NFS3 */
-
- if (!fp->fh_error) {
- dlog("got filehandle for %s:%s", fp->fh_fs->fs_host, fp->fh_path);
- } else {
- plog(XLOG_USER, "filehandle denied for %s:%s", fp->fh_fs->fs_host, fp->fh_path);
- /*
- * Force the error to be EACCES. It's debatable whether it should be
- * ENOENT instead, but the server really doesn't give us any clues, and
- * EACCES is more in line with the "filehandle denied" message.
- */
- fp->fh_error = EACCES;
- }
-
- /*
- * Wakeup anything sleeping on this filehandle
- */
- if (fp->fh_wchan) {
- dlog("Calling wakeup on %#lx", (unsigned long) fp->fh_wchan);
- wakeup(fp->fh_wchan);
- }
-}
-
-
-void
-flush_nfs_fhandle_cache(fserver *fs)
-{
- fh_cache *fp;
-
- ITER(fp, fh_cache, &fh_head) {
- if (fp->fh_fs == fs || fs == NULL) {
- /*
- * Only invalidate port info for non-WebNFS servers
- */
- if (!(fp->fh_fs->fs_flags & FSF_WEBNFS))
- fp->fh_sin.sin_port = (u_short) 0;
- fp->fh_error = -1;
- }
- }
-}
-
-
-static void
-discard_fh(opaque_t arg)
-{
- fh_cache *fp = (fh_cache *) arg;
-
- rem_que(&fp->fh_q);
- if (fp->fh_fs) {
- dlog("Discarding filehandle for %s:%s", fp->fh_fs->fs_host, fp->fh_path);
- free_srvr(fp->fh_fs);
- }
- if (fp->fh_path)
- XFREE(fp->fh_path);
- XFREE(fp);
-}
-
-
-/*
- * Determine the file handle for a node
- */
-static int
-prime_nfs_fhandle_cache(char *path, fserver *fs, am_nfs_handle_t *fhbuf, mntfs *mf)
-{
- fh_cache *fp, *fp_save = 0;
- int error;
- int reuse_id = FALSE;
-
- dlog("Searching cache for %s:%s", fs->fs_host, path);
-
- /*
- * First search the cache
- */
- ITER(fp, fh_cache, &fh_head) {
- if (fs != fp->fh_fs || !STREQ(path, fp->fh_path))
- continue; /* skip to next ITER item */
- /* else we got a match */
- switch (fp->fh_error) {
- case 0:
- plog(XLOG_INFO, "prime_nfs_fhandle_cache: NFS version %d", (int) fp->fh_nfs_version);
-
- error = fp->fh_error = fp->fh_status;
-
- if (error == 0) {
- if (mf->mf_flags & MFF_NFS_SCALEDOWN) {
- fp_save = fp;
- /* XXX: why reuse the ID? */
- reuse_id = TRUE;
- break;
- }
-
- if (fhbuf) {
-#ifdef HAVE_FS_NFS3
- if (fp->fh_nfs_version == NFS_VERSION3) {
- memmove((voidp) &(fhbuf->v3), (voidp) &(fp->fh_nfs_handle.v3),
- sizeof(fp->fh_nfs_handle.v3));
- } else
-#endif /* HAVE_FS_NFS3 */
- {
- memmove((voidp) &(fhbuf->v2), (voidp) &(fp->fh_nfs_handle.v2),
- sizeof(fp->fh_nfs_handle.v2));
- }
- }
- if (fp->fh_cid)
- untimeout(fp->fh_cid);
- fp->fh_cid = timeout(FH_TTL, discard_fh, (opaque_t) fp);
- } else if (error == EACCES) {
- /*
- * Now decode the file handle return code.
- */
- plog(XLOG_INFO, "Filehandle denied for \"%s:%s\"",
- fs->fs_host, path);
- } else {
- errno = error; /* XXX */
- plog(XLOG_INFO, "Filehandle error for \"%s:%s\": %m",
- fs->fs_host, path);
- }
-
- /*
- * The error was returned from the remote mount daemon.
- * Policy: this error will be cached for now...
- */
- return error;
-
- case -1:
- /*
- * Still thinking about it, but we can re-use.
- */
- fp_save = fp;
- reuse_id = TRUE;
- break;
-
- default:
- /*
- * Return the error.
- * Policy: make sure we recompute if required again
- * in case this was caused by a network failure.
- * This can thrash mountd's though... If you find
- * your mountd going slowly then:
- * 1. Add a fork() loop to main.
- * 2. Remove the call to innetgr() and don't use
- * netgroups, especially if you don't use YP.
- */
- error = fp->fh_error;
- fp->fh_error = -1;
- return error;
- } /* end of switch statement */
- } /* end of ITER loop */
-
- /*
- * Not in cache
- */
- if (fp_save) {
- fp = fp_save;
- /*
- * Re-use existing slot
- */
- untimeout(fp->fh_cid);
- free_srvr(fp->fh_fs);
- XFREE(fp->fh_path);
- } else {
- fp = ALLOC(struct fh_cache);
- memset((voidp) fp, 0, sizeof(struct fh_cache));
- ins_que(&fp->fh_q, &fh_head);
- }
- if (!reuse_id)
- fp->fh_id = FHID_ALLOC();
- fp->fh_wchan = get_mntfs_wchan(mf);
- fp->fh_error = -1;
- fp->fh_cid = timeout(FH_TTL, discard_fh, (opaque_t) fp);
-
- /*
- * If fs->fs_ip is null, remote server is probably down.
- */
- if (!fs->fs_ip) {
- /* Mark the fileserver down and invalid again */
- fs->fs_flags &= ~FSF_VALID;
- fs->fs_flags |= FSF_DOWN;
- error = AM_ERRNO_HOST_DOWN;
- return error;
- }
-
- /*
- * Either fp has been freshly allocated or the address has changed.
- * Initialize address and nfs version. Don't try to re-use the port
- * information unless using WebNFS where the port is fixed either by
- * the spec or the "port" mount option.
- */
- if (fp->fh_sin.sin_addr.s_addr != fs->fs_ip->sin_addr.s_addr) {
- fp->fh_sin = *fs->fs_ip;
- if (!(mf->mf_flags & MFF_WEBNFS))
- fp->fh_sin.sin_port = 0;
- fp->fh_nfs_version = fs->fs_version;
- }
-
- fp->fh_fs = dup_srvr(fs);
- fp->fh_path = strdup(path);
-
- if (mf->mf_flags & MFF_WEBNFS)
- error = webnfs_lookup(fp, got_nfs_fh_webnfs, get_mntfs_wchan(mf));
- else
- error = call_mountd(fp, MOUNTPROC_MNT, got_nfs_fh_mount, get_mntfs_wchan(mf));
- if (error) {
- /*
- * Local error - cache for a short period
- * just to prevent thrashing.
- */
- untimeout(fp->fh_cid);
- fp->fh_cid = timeout(error < 0 ? 2 * ALLOWED_MOUNT_TIME : FH_TTL_ERROR,
- discard_fh, (opaque_t) fp);
- fp->fh_error = error;
- } else {
- error = fp->fh_error;
- }
-
- return error;
-}
-
-
-int
-make_nfs_auth(void)
-{
- AUTH_CREATE_GIDLIST_TYPE group_wheel = 0;
-
- /* Some NFS mounts (particularly cross-domain) require FQDNs to succeed */
-
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- if (gopt.flags & CFM_FULLY_QUALIFIED_HOSTS) {
- plog(XLOG_INFO, "Using NFS auth for FQHN \"%s\"", hostd);
- nfs_auth = authsys_create(hostd, 0, 0, 1, &group_wheel);
- } else {
- nfs_auth = authsys_create_default();
- }
-#else /* not HAVE_TRANSPORT_TYPE_TLI */
- if (gopt.flags & CFM_FULLY_QUALIFIED_HOSTS) {
- plog(XLOG_INFO, "Using NFS auth for FQHN \"%s\"", hostd);
- nfs_auth = authunix_create(hostd, 0, 0, 1, &group_wheel);
- } else {
- nfs_auth = authunix_create_default();
- }
-#endif /* not HAVE_TRANSPORT_TYPE_TLI */
-
- if (!nfs_auth)
- return ENOBUFS;
-
- return 0;
-}
-
-
-static int
-call_mountd(fh_cache *fp, u_long proc, fwd_fun fun, wchan_t wchan)
-{
- struct rpc_msg mnt_msg;
- int len;
- char iobuf[UDPMSGSIZE];
- int error;
- u_long mnt_version;
-
- if (!nfs_auth) {
- error = make_nfs_auth();
- if (error)
- return error;
- }
-
- if (fp->fh_sin.sin_port == 0) {
- u_short mountd_port;
- error = get_mountd_port(fp->fh_fs, &mountd_port, wchan);
- if (error)
- return error;
- fp->fh_sin.sin_port = mountd_port;
- }
-
- /* find the right version of the mount protocol */
-#ifdef HAVE_FS_NFS3
- if (fp->fh_nfs_version == NFS_VERSION3)
- mnt_version = AM_MOUNTVERS3;
- else
-#endif /* HAVE_FS_NFS3 */
- mnt_version = MOUNTVERS;
- plog(XLOG_INFO, "call_mountd: NFS version %d, mount version %d",
- (int) fp->fh_nfs_version, (int) mnt_version);
-
- rpc_msg_init(&mnt_msg, MOUNTPROG, mnt_version, MOUNTPROC_NULL);
- len = make_rpc_packet(iobuf,
- sizeof(iobuf),
- proc,
- &mnt_msg,
- (voidp) &fp->fh_path,
- (XDRPROC_T_TYPE) xdr_nfspath,
- nfs_auth);
-
- if (len > 0) {
- error = fwd_packet(MK_RPC_XID(RPC_XID_MOUNTD, fp->fh_id),
- iobuf,
- len,
- &fp->fh_sin,
- &fp->fh_sin,
- (opaque_t) ((long) fp->fh_id), /* cast to long needed for 64-bit archs */
- fun);
- } else {
- error = -len;
- }
-
- /*
- * It may be the case that we're sending to the wrong MOUNTD port. This
- * occurs if mountd is restarted on the server after the port has been
- * looked up and stored in the filehandle cache somewhere. The correct
- * solution, if we're going to cache port numbers is to catch the ICMP
- * port unreachable reply from the server and cause the portmap request
- * to be redone. The quick solution here is to invalidate the MOUNTD
- * port.
- */
- fp->fh_sin.sin_port = 0;
-
- return error;
-}
-
-
-static int
-webnfs_lookup(fh_cache *fp, fwd_fun fun, wchan_t wchan)
-{
- struct rpc_msg wnfs_msg;
- int len;
- char iobuf[UDPMSGSIZE];
- int error;
- u_long proc;
- XDRPROC_T_TYPE xdr_fn;
- voidp argp;
- nfsdiropargs args;
-#ifdef HAVE_FS_NFS3
- am_LOOKUP3args args3;
-#endif
- char *wnfs_path;
- size_t l;
-
- if (!nfs_auth) {
- error = make_nfs_auth();
- if (error)
- return error;
- }
-
- if (fp->fh_sin.sin_port == 0) {
- /* FIXME: wrong, don't discard sin_port in the first place for WebNFS. */
- plog(XLOG_WARNING, "webnfs_lookup: port == 0 for nfs on %s, fixed",
- fp->fh_fs->fs_host);
- fp->fh_sin.sin_port = htons(NFS_PORT);
- }
-
- /*
- * Use native path like the rest of amd (cf. RFC 2054, 6.1).
- */
- l = strlen(fp->fh_path) + 2;
- wnfs_path = (char *) xmalloc(l);
- wnfs_path[0] = 0x80;
- xstrlcpy(wnfs_path + 1, fp->fh_path, l - 1);
-
- /* find the right program and lookup procedure */
-#ifdef HAVE_FS_NFS3
- if (fp->fh_nfs_version == NFS_VERSION3) {
- proc = AM_NFSPROC3_LOOKUP;
- xdr_fn = (XDRPROC_T_TYPE) xdr_am_LOOKUP3args;
- argp = &args3;
- /* WebNFS public file handle */
- args3.what.dir.am_fh3_length = 0;
- args3.what.name = wnfs_path;
- } else {
-#endif /* HAVE_FS_NFS3 */
- proc = NFSPROC_LOOKUP;
- xdr_fn = (XDRPROC_T_TYPE) xdr_diropargs;
- argp = &args;
- /* WebNFS public file handle */
- memset(&args.da_fhandle, 0, NFS_FHSIZE);
- args.da_name = wnfs_path;
-#ifdef HAVE_FS_NFS3
- }
-#endif /* HAVE_FS_NFS3 */
-
- plog(XLOG_INFO, "webnfs_lookup: NFS version %d", (int) fp->fh_nfs_version);
-
- rpc_msg_init(&wnfs_msg, NFS_PROGRAM, fp->fh_nfs_version, proc);
- len = make_rpc_packet(iobuf,
- sizeof(iobuf),
- proc,
- &wnfs_msg,
- argp,
- (XDRPROC_T_TYPE) xdr_fn,
- nfs_auth);
-
- if (len > 0) {
- error = fwd_packet(MK_RPC_XID(RPC_XID_WEBNFS, fp->fh_id),
- iobuf,
- len,
- &fp->fh_sin,
- &fp->fh_sin,
- (opaque_t) ((long) fp->fh_id), /* cast to long needed for 64-bit archs */
- fun);
- } else {
- error = -len;
- }
-
- XFREE(wnfs_path);
- return error;
-}
-
-
-/*
- * NFS needs the local filesystem, remote filesystem
- * remote hostname.
- * Local filesystem defaults to remote and vice-versa.
- */
-static char *
-nfs_match(am_opts *fo)
-{
- char *xmtab;
- size_t l;
-
- if (fo->opt_fs && !fo->opt_rfs)
- fo->opt_rfs = fo->opt_fs;
- if (!fo->opt_rfs) {
- plog(XLOG_USER, "nfs: no remote filesystem specified");
- return NULL;
- }
- if (!fo->opt_rhost) {
- plog(XLOG_USER, "nfs: no remote host specified");
- return NULL;
- }
-
- /*
- * Determine magic cookie to put in mtab
- */
- l = strlen(fo->opt_rhost) + strlen(fo->opt_rfs) + 2;
- xmtab = (char *) xmalloc(l);
- xsnprintf(xmtab, l, "%s:%s", fo->opt_rhost, fo->opt_rfs);
- dlog("NFS: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"",
- fo->opt_rhost, fo->opt_rfs, fo->opt_fs);
-
- return xmtab;
-}
-
-
-/*
- * Initialize am structure for nfs
- */
-static int
-nfs_init(mntfs *mf)
-{
- int error;
- am_nfs_handle_t fhs;
- char *colon;
-
- if (mf->mf_private) {
- if (mf->mf_flags & MFF_NFS_SCALEDOWN) {
- fserver *fs;
-
- /* tell remote mountd that we're done with this filehandle */
- mf->mf_ops->umounted(mf);
-
- mf->mf_prfree(mf->mf_private);
- fs = mf->mf_ops->ffserver(mf);
- free_srvr(mf->mf_server);
- mf->mf_server = fs;
- } else
- return 0;
- }
-
- colon = strchr(mf->mf_info, ':');
- if (colon == 0)
- return ENOENT;
-
- error = prime_nfs_fhandle_cache(colon + 1, mf->mf_server, &fhs, mf);
- if (!error) {
- mf->mf_private = (opaque_t) ALLOC(am_nfs_handle_t);
- mf->mf_prfree = (void (*)(opaque_t)) free;
- memmove(mf->mf_private, (voidp) &fhs, sizeof(fhs));
- }
- return error;
-}
-
-
-int
-mount_nfs_fh(am_nfs_handle_t *fhp, char *mntdir, char *fs_name, mntfs *mf)
-{
- MTYPE_TYPE type;
- char *colon;
- char *xopts=NULL, transp_timeo_opts[40], transp_retrans_opts[40];
- char host[MAXHOSTNAMELEN + MAXPATHLEN + 2];
- fserver *fs = mf->mf_server;
- u_long nfs_version = fs->fs_version;
- char *nfs_proto = fs->fs_proto; /* "tcp" or "udp" */
- int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
- int error;
- int genflags;
- int retry;
- int proto = AMU_TYPE_NONE;
- mntent_t mnt;
- nfs_args_t nfs_args;
-
- /*
- * Extract HOST name to give to kernel.
- * Some systems like osf1/aix3/bsd44 variants may need old code
- * for NFS_ARGS_NEEDS_PATH.
- */
- if (!(colon = strchr(fs_name, ':')))
- return ENOENT;
-#ifdef MOUNT_TABLE_ON_FILE
- *colon = '\0';
-#endif /* MOUNT_TABLE_ON_FILE */
- xstrlcpy(host, fs_name, sizeof(host));
-#ifdef MOUNT_TABLE_ON_FILE
- *colon = ':';
-#endif /* MOUNT_TABLE_ON_FILE */
-#ifdef MAXHOSTNAMELEN
- /* most kernels have a name length restriction */
- if (strlen(host) >= MAXHOSTNAMELEN)
- xstrlcpy(host + MAXHOSTNAMELEN - 3, "..",
- sizeof(host) - MAXHOSTNAMELEN + 3);
-#endif /* MAXHOSTNAMELEN */
-
- /*
- * Create option=VAL for udp/tcp specific timeouts and retrans values, but
- * only if these options were specified.
- */
-
- transp_timeo_opts[0] = transp_retrans_opts[0] = '\0'; /* initialize */
- if (STREQ(nfs_proto, "udp"))
- proto = AMU_TYPE_UDP;
- else if (STREQ(nfs_proto, "tcp"))
- proto = AMU_TYPE_TCP;
- if (proto != AMU_TYPE_NONE) {
- if (gopt.amfs_auto_timeo[proto] > 0)
- xsnprintf(transp_timeo_opts, sizeof(transp_timeo_opts), "%s=%d,",
- MNTTAB_OPT_TIMEO, gopt.amfs_auto_timeo[proto]);
- if (gopt.amfs_auto_retrans[proto] > 0)
- xsnprintf(transp_retrans_opts, sizeof(transp_retrans_opts), "%s=%d,",
- MNTTAB_OPT_RETRANS, gopt.amfs_auto_retrans[proto]);
- }
-
- if (mf->mf_remopts && *mf->mf_remopts &&
- !islocalnet(fs->fs_ip->sin_addr.s_addr)) {
- plog(XLOG_INFO, "Using remopts=\"%s\"", mf->mf_remopts);
- /* use transp_opts first, so map-specific opts will override */
- xopts = str3cat(xopts, transp_timeo_opts, transp_retrans_opts, mf->mf_remopts);
- } else {
- /* use transp_opts first, so map-specific opts will override */
- xopts = str3cat(xopts, transp_timeo_opts, transp_retrans_opts, mf->mf_mopts);
- }
-
- memset((voidp) &mnt, 0, sizeof(mnt));
- mnt.mnt_dir = mntdir;
- mnt.mnt_fsname = fs_name;
- mnt.mnt_opts = xopts;
-
- /*
- * Set mount types accordingly
- */
-#ifndef HAVE_FS_NFS3
- type = MOUNT_TYPE_NFS;
- mnt.mnt_type = MNTTAB_TYPE_NFS;
-#else /* HAVE_FS_NFS3 */
- if (nfs_version == NFS_VERSION3) {
- type = MOUNT_TYPE_NFS3;
- /*
- * Systems that include the mount table "vers" option generally do not
- * set the mnttab entry to "nfs3", but to "nfs" and then they set
- * "vers=3". Setting it to "nfs3" works, but it may break some things
- * like "df -t nfs" and the "quota" program (esp. on Solaris and Irix).
- * So on those systems, set it to "nfs".
- * Note: MNTTAB_OPT_VERS is always set for NFS3 (see am_compat.h).
- */
-# if defined(MNTTAB_OPT_VERS) && defined(MOUNT_TABLE_ON_FILE)
- mnt.mnt_type = MNTTAB_TYPE_NFS;
-# else /* defined(MNTTAB_OPT_VERS) && defined(MOUNT_TABLE_ON_FILE) */
- mnt.mnt_type = MNTTAB_TYPE_NFS3;
-# endif /* defined(MNTTAB_OPT_VERS) && defined(MOUNT_TABLE_ON_FILE) */
- } else {
- type = MOUNT_TYPE_NFS;
- mnt.mnt_type = MNTTAB_TYPE_NFS;
- }
-#endif /* HAVE_FS_NFS3 */
- plog(XLOG_INFO, "mount_nfs_fh: NFS version %d", (int) nfs_version);
- plog(XLOG_INFO, "mount_nfs_fh: using NFS transport %s", nfs_proto);
-
- retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
- if (retry <= 0)
- retry = 1; /* XXX */
-
- genflags = compute_mount_flags(&mnt);
-#ifdef HAVE_FS_AUTOFS
- if (on_autofs)
- genflags |= autofs_compute_mount_flags(&mnt);
-#endif /* HAVE_FS_AUTOFS */
-
- /* setup the many fields and flags within nfs_args */
- compute_nfs_args(&nfs_args,
- &mnt,
- genflags,
- NULL, /* struct netconfig *nfsncp */
- fs->fs_ip,
- nfs_version,
- nfs_proto,
- fhp,
- host,
- fs_name);
-
- /* finally call the mounting function */
- if (amuDebug(D_TRACE)) {
- print_nfs_args(&nfs_args, nfs_version);
- plog(XLOG_DEBUG, "Generic mount flags 0x%x used for NFS mount", genflags);
- }
- error = mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type,
- nfs_version, nfs_proto, mnttab_file_name, on_autofs);
- XFREE(xopts);
-
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- free_knetconfig(nfs_args.knconf);
- if (nfs_args.addr)
- XFREE(nfs_args.addr); /* allocated in compute_nfs_args() */
-#endif /* HAVE_TRANSPORT_TYPE_TLI */
-
- return error;
-}
-
-
-static int
-nfs_mount(am_node *am, mntfs *mf)
-{
- int error = 0;
- mntent_t mnt;
-
- if (!mf->mf_private) {
- plog(XLOG_ERROR, "Missing filehandle for %s", mf->mf_info);
- return EINVAL;
- }
-
- mnt.mnt_opts = mf->mf_mopts;
- if (amu_hasmntopt(&mnt, "softlookup") ||
- (amu_hasmntopt(&mnt, "soft") && !amu_hasmntopt(&mnt, "nosoftlookup")))
- am->am_flags |= AMF_SOFTLOOKUP;
-
- error = mount_nfs_fh((am_nfs_handle_t *) mf->mf_private,
- mf->mf_mount,
- mf->mf_info,
- mf);
-
- if (error) {
- errno = error;
- dlog("mount_nfs: %m");
- }
-
- return error;
-}
-
-
-static int
-nfs_umount(am_node *am, mntfs *mf)
-{
- int unmount_flags, new_unmount_flags, error;
-
- unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
- error = UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
-
-#if defined(HAVE_UMOUNT2) && (defined(MNT2_GEN_OPT_FORCE) || defined(MNT2_GEN_OPT_DETACH))
- /*
- * If the attempt to unmount failed with EBUSY, and this fserver was
- * marked for forced unmounts, then use forced/lazy unmounts.
- */
- if (error == EBUSY &&
- gopt.flags & CFM_FORCED_UNMOUNTS &&
- mf->mf_server->fs_flags & FSF_FORCE_UNMOUNT) {
- plog(XLOG_INFO, "EZK: nfs_umount: trying forced/lazy unmounts");
- /*
- * XXX: turning off the FSF_FORCE_UNMOUNT may not be perfectly
- * incorrect. Multiple nodes may need to be timed out and restarted for
- * a single hung fserver.
- */
- mf->mf_server->fs_flags &= ~FSF_FORCE_UNMOUNT;
- new_unmount_flags = unmount_flags | AMU_UMOUNT_FORCE | AMU_UMOUNT_DETACH;
- error = UMOUNT_FS(mf->mf_mount, mnttab_file_name, new_unmount_flags);
- }
-#endif /* HAVE_UMOUNT2 && (MNT2_GEN_OPT_FORCE || MNT2_GEN_OPT_DETACH) */
-
- /*
- * Here is some code to unmount 'restarted' file systems.
- * The restarted file systems are marked as 'nfs', not
- * 'host', so we only have the map information for the
- * the top-level mount. The unmount will fail (EBUSY)
- * if there are anything else from the NFS server mounted
- * below the mount-point. This code checks to see if there
- * is anything mounted with the same prefix as the
- * file system to be unmounted ("/a/b/c" when unmounting "/a/b").
- * If there is, and it is a 'restarted' file system, we unmount
- * it.
- * Added by Mike Mitchell, mcm@unx.sas.com, 09/08/93
- */
- if (error == EBUSY) {
- mntfs *new_mf;
- int len = strlen(mf->mf_mount);
- int didsome = 0;
-
- ITER(new_mf, mntfs, &mfhead) {
- if (new_mf->mf_ops != mf->mf_ops ||
- new_mf->mf_refc > 1 ||
- mf == new_mf ||
- ((new_mf->mf_flags & (MFF_MOUNTED | MFF_UNMOUNTING | MFF_RESTART)) == (MFF_MOUNTED | MFF_RESTART)))
- continue;
-
- if (NSTREQ(mf->mf_mount, new_mf->mf_mount, len) &&
- new_mf->mf_mount[len] == '/') {
- new_unmount_flags =
- (new_mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
- UMOUNT_FS(new_mf->mf_mount, mnttab_file_name, new_unmount_flags);
- didsome = 1;
- }
- }
- if (didsome)
- error = UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
- }
- if (error)
- return error;
-
- return 0;
-}
-
-
-static void
-nfs_umounted(mntfs *mf)
-{
- fserver *fs;
- char *colon, *path;
-
- if (mf->mf_error || mf->mf_refc > 1)
- return;
-
- /*
- * No need to inform mountd when WebNFS is in use.
- */
- if (mf->mf_flags & MFF_WEBNFS)
- return;
-
- /*
- * Call the mount daemon on the server to announce that we are not using
- * the fs any more.
- *
- * XXX: This is *wrong*. The mountd should be called when the fhandle is
- * flushed from the cache, and a reference held to the cached entry while
- * the fs is mounted...
- */
- fs = mf->mf_server;
- colon = path = strchr(mf->mf_info, ':');
- if (fs && colon) {
- fh_cache f;
-
- dlog("calling mountd for %s", mf->mf_info);
- *path++ = '\0';
- f.fh_path = path;
- f.fh_sin = *fs->fs_ip;
- f.fh_sin.sin_port = (u_short) 0;
- f.fh_nfs_version = fs->fs_version;
- f.fh_fs = fs;
- f.fh_id = 0;
- f.fh_error = 0;
- prime_nfs_fhandle_cache(colon + 1, mf->mf_server, (am_nfs_handle_t *) 0, mf);
- call_mountd(&f, MOUNTPROC_UMNT, (fwd_fun *) 0, (wchan_t) 0);
- *colon = ':';
- }
-}
diff --git a/contrib/amd/amd/ops_nfs3.c b/contrib/amd/amd/ops_nfs3.c
deleted file mode 100644
index db3c7f9d265d..000000000000
--- a/contrib/amd/amd/ops_nfs3.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_nfs3.c
- *
- */
-
-/*
- * Network file system version 3.0
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* FEEL FREE TO IMPLEMENT THIS... :-) */
diff --git a/contrib/amd/amd/ops_nullfs.c b/contrib/amd/amd/ops_nullfs.c
deleted file mode 100644
index cf621ec33ff5..000000000000
--- a/contrib/amd/amd/ops_nullfs.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_nullfs.c
- *
- */
-
-/*
- * The null filesystem in BSD-4.4 is similar to the loopback one.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* FEEL FREE TO IMPLEMENT THIS... :-) */
diff --git a/contrib/amd/amd/ops_pcfs.c b/contrib/amd/amd/ops_pcfs.c
deleted file mode 100644
index 527dc926ca77..000000000000
--- a/contrib/amd/amd/ops_pcfs.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_pcfs.c
- *
- */
-
-/*
- * PC (MS-DOS) file system
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* forward definitions */
-static char *pcfs_match(am_opts *fo);
-static int pcfs_mount(am_node *am, mntfs *mf);
-static int pcfs_umount(am_node *am, mntfs *mf);
-
-/*
- * Ops structure
- */
-am_ops pcfs_ops =
-{
- "pcfs",
- pcfs_match,
- 0, /* pcfs_init */
- pcfs_mount,
- pcfs_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* pcfs_readlink */
- 0, /* pcfs_mounted */
- 0, /* pcfs_umounted */
- amfs_generic_find_srvr,
- 0, /* pcfs_get_wchan */
- FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_PCFS_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-
-/*
- * PCFS needs remote filesystem.
- */
-static char *
-pcfs_match(am_opts *fo)
-{
- if (!fo->opt_dev) {
- plog(XLOG_USER, "pcfs: no source device specified");
- return 0;
- }
- dlog("PCFS: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs);
-
- /*
- * Determine magic cookie to put in mtab
- */
- return strdup(fo->opt_dev);
-}
-
-
-static int
-mount_pcfs(char *mntdir, char *fs_name, char *opts, int on_autofs)
-{
- pcfs_args_t pcfs_args;
- mntent_t mnt;
- int flags;
-#if defined(HAVE_PCFS_ARGS_T_MASK) || defined(HAVE_PCFS_ARGS_T_DIRMASK)
- int mask;
-#endif /* defined(HAVE_PCFS_ARGS_T_MASK) || defined(HAVE_PCFS_ARGS_T_DIRMASK) */
-#if defined(HAVE_PCFS_ARGS_T_UID) || defined(HAVE_PCFS_ARGS_T_UID)
- char *str;
-#endif /* defined(HAVE_PCFS_ARGS_T_UID) || defined(HAVE_PCFS_ARGS_T_UID) */
-
- /*
- * Figure out the name of the file system type.
- */
- MTYPE_TYPE type = MOUNT_TYPE_PCFS;
-
- memset((voidp) &pcfs_args, 0, sizeof(pcfs_args)); /* Paranoid */
-
- /*
- * Fill in the mount structure
- */
- memset((voidp) &mnt, 0, sizeof(mnt));
- mnt.mnt_dir = mntdir;
- mnt.mnt_fsname = fs_name;
- mnt.mnt_type = MNTTAB_TYPE_PCFS;
- mnt.mnt_opts = opts;
-
- flags = compute_mount_flags(&mnt);
-#ifdef HAVE_FS_AUTOFS
- if (on_autofs)
- flags |= autofs_compute_mount_flags(&mnt);
-#endif /* HAVE_FS_AUTOFS */
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "mount_pcfs: flags=0x%x", (u_int) flags);
-
-#ifdef HAVE_PCFS_ARGS_T_FSPEC
- pcfs_args.fspec = fs_name;
-#endif /* HAVE_PCFS_ARGS_T_FSPEC */
-
-#ifdef HAVE_PCFS_ARGS_T_MASK
- pcfs_args.mask = 0777; /* this may be the msdos file modes */
- if ((mask = hasmntval(&mnt, MNTTAB_OPT_MASK)) > 0)
- pcfs_args.mask = mask;
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "mount_pcfs: mask=%o (octal)", (u_int) pcfs_args.mask);
-#endif /* HAVE_PCFS_ARGS_T_MASK */
-
-#ifdef HAVE_PCFS_ARGS_T_DIRMASK
- pcfs_args.dirmask = 0777; /* this may be the msdos dir modes */
- if ((mask = hasmntval(&mnt, MNTTAB_OPT_DIRMASK)) > 0)
- pcfs_args.dirmask = mask;
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "mount_pcfs: dirmask=%o (octal)", (u_int) pcfs_args.dirmask);
-#endif /* HAVE_PCFS_ARGS_T_DIRMASK */
-
-#ifdef HAVE_PCFS_ARGS_T_UID
- pcfs_args.uid = 0; /* default to root */
- if ((str = hasmntstr(&mnt, MNTTAB_OPT_USER)) != NULL) {
- struct passwd *pw;
- if ((pw = getpwnam(str)) != NULL)
- pcfs_args.uid = pw->pw_uid;
- else /* maybe used passed a UID number, not user name */
- pcfs_args.uid = atoi(str); /* atoi returns '0' if it failed */
- XFREE(str);
- }
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "mount_pcfs: uid=%d", (int) pcfs_args.uid);
-#endif /* HAVE_PCFS_ARGS_T_UID */
-
-#ifdef HAVE_PCFS_ARGS_T_GID
- pcfs_args.gid = 0; /* default to wheel/root group */
- if ((str = hasmntstr(&mnt, MNTTAB_OPT_GROUP)) != NULL) {
- struct group *gr;
- if ((gr = getgrnam(str)) != NULL)
- pcfs_args.gid = gr->gr_gid;
- else /* maybe used passed a GID number, not group name */
- pcfs_args.gid = atoi(str); /* atoi returns '0' if it failed */
- XFREE(str);
- }
- if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "mount_pcfs: gid=%d", (int) pcfs_args.gid);
-#endif /* HAVE_PCFS_ARGS_T_GID */
-
-#ifdef HAVE_PCFS_ARGS_T_SECONDSWEST
- pcfs_args.secondswest = 0; /* XXX: fill in correct values */
-#endif /* HAVE_PCFS_ARGS_T_SECONDSWEST */
-#ifdef HAVE_PCFS_ARGS_T_DSTTIME
- pcfs_args.dsttime = 0; /* XXX: fill in correct values */
-#endif /* HAVE_PCFS_ARGS_T_DSTTIME */
-
- /*
- * Call generic mount routine
- */
- return mount_fs(&mnt, flags, (caddr_t) & pcfs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs);
-}
-
-
-static int
-pcfs_mount(am_node *am, mntfs *mf)
-{
- int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
- int error;
-
- error = mount_pcfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
- if (error) {
- errno = error;
- plog(XLOG_ERROR, "mount_pcfs: %m");
- return error;
- }
-
- return 0;
-}
-
-
-static int
-pcfs_umount(am_node *am, mntfs *mf)
-{
- int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
-
- return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
-}
diff --git a/contrib/amd/amd/ops_tfs.c b/contrib/amd/amd/ops_tfs.c
deleted file mode 100644
index 142c32022937..000000000000
--- a/contrib/amd/amd/ops_tfs.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_tfs.c
- *
- */
-
-/*
- * Translucent file system
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* FEEL FREE TO IMPLEMENT THIS... :-) */
diff --git a/contrib/amd/amd/ops_tmpfs.c b/contrib/amd/amd/ops_tmpfs.c
deleted file mode 100644
index eddd75569e9e..000000000000
--- a/contrib/amd/amd/ops_tmpfs.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_tmpfs.c
- *
- */
-
-/*
- * TMPFS file system (combines RAM-fs and swap-fs)
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* FEEL FREE TO IMPLEMENT THIS... :-) */
diff --git a/contrib/amd/amd/ops_ufs.c b/contrib/amd/amd/ops_ufs.c
deleted file mode 100644
index fd82a5cd2228..000000000000
--- a/contrib/amd/amd/ops_ufs.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_ufs.c
- *
- */
-
-/*
- * UN*X file system
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* forward declarations */
-static char *ufs_match(am_opts *fo);
-static int ufs_mount(am_node *am, mntfs *mf);
-static int ufs_umount(am_node *am, mntfs *mf);
-
-/*
- * Ops structure
- */
-am_ops ufs_ops =
-{
- "ufs",
- ufs_match,
- 0, /* ufs_init */
- ufs_mount,
- ufs_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* ufs_readlink */
- 0, /* ufs_mounted */
- 0, /* ufs_umounted */
- amfs_generic_find_srvr,
- 0, /* ufs_get_wchan */
- FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_UFS_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/*
- * UFS needs local filesystem and device.
- */
-static char *
-ufs_match(am_opts *fo)
-{
-
- if (!fo->opt_dev) {
- plog(XLOG_USER, "ufs: no device specified");
- return 0;
- }
-
- dlog("UFS: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs);
-
- /*
- * Determine magic cookie to put in mtab
- */
- return strdup(fo->opt_dev);
-}
-
-
-static int
-mount_ufs(char *mntdir, char *fs_name, char *opts, int on_autofs)
-{
- ufs_args_t ufs_args;
- mntent_t mnt;
- int genflags;
-
- /*
- * Figure out the name of the file system type.
- */
- MTYPE_TYPE type = MOUNT_TYPE_UFS;
-
- memset((voidp) &ufs_args, 0, sizeof(ufs_args)); /* Paranoid */
-
- /*
- * Fill in the mount structure
- */
- memset((voidp) &mnt, 0, sizeof(mnt));
- mnt.mnt_dir = mntdir;
- mnt.mnt_fsname = fs_name;
- mnt.mnt_type = MNTTAB_TYPE_UFS;
- mnt.mnt_opts = opts;
-
- genflags = compute_mount_flags(&mnt);
-#ifdef HAVE_FS_AUTOFS
- if (on_autofs)
- genflags |= autofs_compute_mount_flags(&mnt);
-#endif /* HAVE_FS_AUTOFS */
-
-#ifdef HAVE_UFS_ARGS_T_FLAGS
- ufs_args.flags = genflags; /* XXX: is this correct? */
-#endif /* HAVE_UFS_ARGS_T_FLAGS */
-
-#ifdef HAVE_UFS_ARGS_T_UFS_FLAGS
- ufs_args.ufs_flags = genflags;
-#endif /* HAVE_UFS_ARGS_T_UFS_FLAGS */
-
-#ifdef HAVE_UFS_ARGS_T_FSPEC
- ufs_args.fspec = fs_name;
-#endif /* HAVE_UFS_ARGS_T_FSPEC */
-
-#ifdef HAVE_UFS_ARGS_T_UFS_PGTHRESH
- ufs_args.ufs_pgthresh = hasmntval(&mnt, MNTTAB_OPT_PGTHRESH);
-#endif /* HAVE_UFS_ARGS_T_UFS_PGTHRESH */
-
- /*
- * Call generic mount routine
- */
- return mount_fs(&mnt, genflags, (caddr_t) &ufs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs);
-}
-
-
-static int
-ufs_mount(am_node *am, mntfs *mf)
-{
- int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
- int error;
-
- error = mount_ufs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
- if (error) {
- errno = error;
- plog(XLOG_ERROR, "mount_ufs: %m");
- return error;
- }
-
- return 0;
-}
-
-
-static int
-ufs_umount(am_node *am, mntfs *mf)
-{
- int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
-
- return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
-}
diff --git a/contrib/amd/amd/ops_umapfs.c b/contrib/amd/amd/ops_umapfs.c
deleted file mode 100644
index 5ba735e39c61..000000000000
--- a/contrib/amd/amd/ops_umapfs.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_umapfs.c
- *
- */
-
-/*
- * uid/gid mapping filesystem.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* FEEL FREE TO IMPLEMENT THIS... :-) */
diff --git a/contrib/amd/amd/ops_unionfs.c b/contrib/amd/amd/ops_unionfs.c
deleted file mode 100644
index 73f8d6676203..000000000000
--- a/contrib/amd/amd/ops_unionfs.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_unionfs.c
- *
- */
-
-/*
- * Union filesystem (ala BSD-4.4)
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* FEEL FREE TO IMPLEMENT THIS... :-) */
diff --git a/contrib/amd/amd/ops_xfs.c b/contrib/amd/amd/ops_xfs.c
deleted file mode 100644
index e0e740bc0a0e..000000000000
--- a/contrib/amd/amd/ops_xfs.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/ops_xfs.c
- *
- */
-
-/*
- * Irix UN*X file system: XFS (Extended File System)
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* forward declarations */
-static char *xfs_match(am_opts *fo);
-static int xfs_mount(am_node *am, mntfs *mf);
-static int xfs_umount(am_node *am, mntfs *mf);
-
-/*
- * Ops structure
- */
-am_ops xfs_ops =
-{
- "xfs",
- xfs_match,
- 0, /* xfs_init */
- xfs_mount,
- xfs_umount,
- amfs_error_lookup_child,
- amfs_error_mount_child,
- amfs_error_readdir,
- 0, /* xfs_readlink */
- 0, /* xfs_mounted */
- 0, /* xfs_umounted */
- amfs_generic_find_srvr,
- 0, /* xfs_get_wchan */
- FS_MKMNT | FS_NOTIMEOUT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
-#ifdef HAVE_FS_AUTOFS
- AUTOFS_XFS_FS_FLAGS,
-#endif /* HAVE_FS_AUTOFS */
-};
-
-
-/*
- * XFS needs local filesystem and device.
- */
-static char *
-xfs_match(am_opts *fo)
-{
-
- if (!fo->opt_dev) {
- plog(XLOG_USER, "xfs: no device specified");
- return 0;
- }
-
- dlog("XFS: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs);
-
- /*
- * Determine magic cookie to put in mtab
- */
- return strdup(fo->opt_dev);
-}
-
-
-static int
-mount_xfs(char *mntdir, char *fs_name, char *opts, int on_autofs)
-{
- xfs_args_t xfs_args;
- mntent_t mnt;
- int flags;
-
- /*
- * Figure out the name of the file system type.
- */
- MTYPE_TYPE type = MOUNT_TYPE_XFS;
-
- memset((voidp) &xfs_args, 0, sizeof(xfs_args)); /* Paranoid */
-
- /*
- * Fill in the mount structure
- */
- memset((voidp) &mnt, 0, sizeof(mnt));
- mnt.mnt_dir = mntdir;
- mnt.mnt_fsname = fs_name;
- mnt.mnt_type = MNTTAB_TYPE_XFS;
- mnt.mnt_opts = opts;
-
- flags = compute_mount_flags(&mnt);
-#ifdef HAVE_FS_AUTOFS
- if (on_autofs)
- flags |= autofs_compute_mount_flags(&mnt);
-#endif /* HAVE_FS_AUTOFS */
-
-#ifdef HAVE_XFS_ARGS_T_FLAGS
- xfs_args.flags = 0; /* XXX: fix this to correct flags */
-#endif /* HAVE_XFS_ARGS_T_FLAGS */
-#ifdef HAVE_XFS_ARGS_T_FSPEC
- xfs_args.fspec = fs_name;
-#endif /* HAVE_XFS_ARGS_T_FSPEC */
-
- /*
- * Call generic mount routine
- */
- return mount_fs(&mnt, flags, (caddr_t) &xfs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs);
-}
-
-
-static int
-xfs_mount(am_node *am, mntfs *mf)
-{
- int on_autofs = mf->mf_flags & MFF_ON_AUTOFS;
- int error;
-
- error = mount_xfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs);
- if (error) {
- errno = error;
- plog(XLOG_ERROR, "mount_xfs: %m");
- return error;
- }
-
- return 0;
-}
-
-
-static int
-xfs_umount(am_node *am, mntfs *mf)
-{
- int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0;
-
- return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags);
-}
diff --git a/contrib/amd/amd/opts.c b/contrib/amd/amd/opts.c
deleted file mode 100644
index a3d35343adc0..000000000000
--- a/contrib/amd/amd/opts.c
+++ /dev/null
@@ -1,1519 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/opts.c
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/*
- * MACROS:
- */
-#define NLEN 16 /* Length of longest option name (conservative) */
-#define S(x) (x) , (sizeof(x)-1)
-/*
- * The BUFSPACE macros checks that there is enough space
- * left in the expansion buffer. If there isn't then we
- * give up completely. This is done to avoid crashing the
- * automounter itself (which would be a bad thing to do).
- */
-#define BUFSPACE(ep, len) (((ep) + (len)) < expbuf+MAXPATHLEN)
-
-/*
- * TYPEDEFS:
- */
-typedef int (*IntFuncPtr) (char *);
-typedef struct opt_apply opt_apply;
-enum vs_opt { SelEQ, SelNE, VarAss };
-
-/*
- * STRUCTURES
- */
-struct opt {
- char *name; /* Name of the option */
- int nlen; /* Length of option name */
- char **optp; /* Pointer to option value string */
- char **sel_p; /* Pointer to selector value string */
- int (*fxn_p)(char *); /* Pointer to boolean function */
- int case_insensitive; /* How to do selector comparisons */
-};
-
-struct opt_apply {
- char **opt;
- char *val;
-};
-
-struct functable {
- char *name;
- IntFuncPtr func;
-};
-
-/*
- * FORWARD DEFINITION:
- */
-static int f_in_network(char *);
-static int f_xhost(char *);
-static int f_netgrp(char *);
-static int f_netgrpd(char *);
-static int f_exists(char *);
-static int f_false(char *);
-static int f_true(char *);
-static inline char *expand_options(char *key);
-
-/*
- * STATICS:
- */
-static char NullStr[] = "<NULL>";
-static char nullstr[] = "";
-static char *opt_dkey = NullStr;
-static char *opt_host = nullstr; /* XXX: was the global hostname */
-static char *opt_hostd = hostd;
-static char *opt_key = nullstr;
-static char *opt_keyd = nullstr;
-static char *opt_map = nullstr;
-static char *opt_path = nullstr;
-char uid_str[SIZEOF_UID_STR], gid_str[SIZEOF_GID_STR];
-char *opt_uid = uid_str;
-char *opt_gid = gid_str;
-static char *vars[8];
-static char *literal_dollar = "$"; /* ${dollar}: a literal '$' in maps */
-
-/*
- * GLOBALS
- */
-static struct am_opts fs_static; /* copy of the options to play with */
-
-
-/*
- * Options in some order corresponding to frequency of use so that
- * first-match algorithm is sped up.
- */
-static struct opt opt_fields[] = {
- /* Name and length.
- Option str. Selector str. boolean fxn. case sensitive */
- { S("opts"),
- &fs_static.opt_opts, 0, 0, FALSE },
- { S("host"),
- 0, &opt_host, 0, TRUE },
- { S("hostd"),
- 0, &opt_hostd, 0, TRUE },
- { S("type"),
- &fs_static.opt_type, 0, 0, FALSE },
- { S("rhost"),
- &fs_static.opt_rhost, 0, 0, TRUE },
- { S("rfs"),
- &fs_static.opt_rfs, 0, 0, FALSE },
- { S("fs"),
- &fs_static.opt_fs, 0, 0, FALSE },
- { S("key"),
- 0, &opt_key, 0, FALSE },
- { S("map"),
- 0, &opt_map, 0, FALSE },
- { S("sublink"),
- &fs_static.opt_sublink, 0, 0, FALSE },
- { S("arch"),
- 0, &gopt.arch, 0, TRUE },
- { S("dev"),
- &fs_static.opt_dev, 0, 0, FALSE },
- { S("pref"),
- &fs_static.opt_pref, 0, 0, FALSE },
- { S("path"),
- 0, &opt_path, 0, FALSE },
- { S("autodir"),
- 0, &gopt.auto_dir, 0, FALSE },
- { S("delay"),
- &fs_static.opt_delay, 0, 0, FALSE },
- { S("domain"),
- 0, &hostdomain, 0, TRUE },
- { S("karch"),
- 0, &gopt.karch, 0, TRUE },
- { S("cluster"),
- 0, &gopt.cluster, 0, TRUE },
- { S("wire"),
- 0, 0, f_in_network, TRUE },
- { S("network"),
- 0, 0, f_in_network, TRUE },
- { S("netnumber"),
- 0, 0, f_in_network, TRUE },
- { S("byte"),
- 0, &endian, 0, TRUE },
- { S("os"),
- 0, &gopt.op_sys, 0, TRUE },
- { S("osver"),
- 0, &gopt.op_sys_ver, 0, TRUE },
- { S("full_os"),
- 0, &gopt.op_sys_full, 0, TRUE },
- { S("vendor"),
- 0, &gopt.op_sys_vendor, 0, TRUE },
- { S("remopts"),
- &fs_static.opt_remopts, 0, 0, FALSE },
- { S("mount"),
- &fs_static.opt_mount, 0, 0, FALSE },
- { S("unmount"),
- &fs_static.opt_unmount, 0, 0, FALSE },
- { S("umount"),
- &fs_static.opt_umount, 0, 0, FALSE },
- { S("cache"),
- &fs_static.opt_cache, 0, 0, FALSE },
- { S("user"),
- &fs_static.opt_user, 0, 0, FALSE },
- { S("group"),
- &fs_static.opt_group, 0, 0, FALSE },
- { S(".key"),
- 0, &opt_dkey, 0, FALSE },
- { S("key."),
- 0, &opt_keyd, 0, FALSE },
- { S("maptype"),
- &fs_static.opt_maptype, 0, 0, FALSE },
- { S("cachedir"),
- &fs_static.opt_cachedir, 0, 0, FALSE },
- { S("addopts"),
- &fs_static.opt_addopts, 0, 0, FALSE },
- { S("uid"),
- 0, &opt_uid, 0, FALSE },
- { S("gid"),
- 0, &opt_gid, 0, FALSE },
- { S("mount_type"),
- &fs_static.opt_mount_type, 0, 0, FALSE },
- { S("dollar"),
- &literal_dollar, 0, 0, FALSE },
- { S("var0"),
- &vars[0], 0, 0, FALSE },
- { S("var1"),
- &vars[1], 0, 0, FALSE },
- { S("var2"),
- &vars[2], 0, 0, FALSE },
- { S("var3"),
- &vars[3], 0, 0, FALSE },
- { S("var4"),
- &vars[4], 0, 0, FALSE },
- { S("var5"),
- &vars[5], 0, 0, FALSE },
- { S("var6"),
- &vars[6], 0, 0, FALSE },
- { S("var7"),
- &vars[7], 0, 0, FALSE },
- { 0, 0, 0, 0, 0, FALSE },
-};
-
-static struct functable functable[] = {
- { "in_network", f_in_network },
- { "xhost", f_xhost },
- { "netgrp", f_netgrp },
- { "netgrpd", f_netgrpd },
- { "exists", f_exists },
- { "false", f_false },
- { "true", f_true },
- { 0, 0 },
-};
-
-/*
- * Specially expand the remote host name first
- */
-static opt_apply rhost_expansion[] =
-{
- {&fs_static.opt_rhost, "${host}"},
- {0, 0},
-};
-
-/*
- * List of options which need to be expanded
- * Note that the order here _may_ be important.
- */
-static opt_apply expansions[] =
-{
- {&fs_static.opt_sublink, 0},
- {&fs_static.opt_rfs, "${path}"},
- {&fs_static.opt_fs, "${autodir}/${rhost}${rfs}"},
- {&fs_static.opt_opts, "rw"},
- {&fs_static.opt_remopts, "${opts}"},
- {&fs_static.opt_mount, 0},
- {&fs_static.opt_unmount, 0},
- {&fs_static.opt_umount, 0},
- {&fs_static.opt_cachedir, 0},
- {&fs_static.opt_addopts, 0},
- {0, 0},
-};
-
-/*
- * List of options which need to be free'ed before re-use
- */
-static opt_apply to_free[] =
-{
- {&fs_static.fs_glob, 0},
- {&fs_static.fs_local, 0},
- {&fs_static.fs_mtab, 0},
- {&fs_static.opt_sublink, 0},
- {&fs_static.opt_rfs, 0},
- {&fs_static.opt_fs, 0},
- {&fs_static.opt_rhost, 0},
- {&fs_static.opt_opts, 0},
- {&fs_static.opt_remopts, 0},
- {&fs_static.opt_mount, 0},
- {&fs_static.opt_unmount, 0},
- {&fs_static.opt_umount, 0},
- {&fs_static.opt_cachedir, 0},
- {&fs_static.opt_addopts, 0},
- {&vars[0], 0},
- {&vars[1], 0},
- {&vars[2], 0},
- {&vars[3], 0},
- {&vars[4], 0},
- {&vars[5], 0},
- {&vars[6], 0},
- {&vars[7], 0},
- {0, 0},
-};
-
-
-/*
- * expand backslash escape sequences
- * (escaped slash is handled separately in normalize_slash)
- */
-static char
-backslash(char **p)
-{
- char c;
-
- if ((*p)[1] == '\0') {
- plog(XLOG_USER, "Empty backslash escape");
- return **p;
- }
-
- if (**p == '\\') {
- (*p)++;
- switch (**p) {
- case 'g':
- c = '\007'; /* Bell */
- break;
- case 'b':
- c = '\010'; /* Backspace */
- break;
- case 't':
- c = '\011'; /* Horizontal Tab */
- break;
- case 'n':
- c = '\012'; /* New Line */
- break;
- case 'v':
- c = '\013'; /* Vertical Tab */
- break;
- case 'f':
- c = '\014'; /* Form Feed */
- break;
- case 'r':
- c = '\015'; /* Carriage Return */
- break;
- case 'e':
- c = '\033'; /* Escape */
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- {
- int cnt, val, ch;
-
- for (cnt = 0, val = 0; cnt < 3; cnt++) {
- ch = *(*p)++;
- if (ch < '0' || ch > '7') {
- (*p)--;
- break;
- }
- val = (val << 3) | (ch - '0');
- }
-
- if ((val & 0xffffff00) != 0)
- plog(XLOG_USER,
- "Too large character constant %u\n",
- val);
- c = (char) val;
- --(*p);
- }
- break;
-
- default:
- c = **p;
- break;
- }
- } else
- c = **p;
-
- return c;
-}
-
-
-/*
- * Skip to next option in the string
- */
-static char *
-opt(char **p)
-{
- char *cp = *p;
- char *dp = cp;
- char *s = cp;
-
-top:
- while (*cp && *cp != ';') {
- if (*cp == '"') {
- /*
- * Skip past string
- */
- for (cp++; *cp && *cp != '"'; cp++)
- if (*cp == '\\')
- *dp++ = backslash(&cp);
- else
- *dp++ = *cp;
- if (*cp)
- cp++;
- } else {
- *dp++ = *cp++;
- }
- }
-
- /*
- * Skip past any remaining ';'s
- */
- while (*cp == ';')
- cp++;
-
- /*
- * If we have a zero length string
- * and there are more fields, then
- * parse the next one. This allows
- * sequences of empty fields.
- */
- if (*cp && dp == s)
- goto top;
-
- *dp = '\0';
-
- *p = cp;
- return s;
-}
-
-
-/*
- * These routines add a new style of selector; function-style boolean
- * operators. To add new ones, just define functions as in true, false,
- * exists (below) and add them to the functable, above.
- *
- * Usage example: Some people have X11R5 local, some go to a server. I do
- * this:
- *
- * * exists(/usr/pkg/${key});type:=link;fs:=/usr/pkg/${key} || \
- * -type:=nfs;rfs=/usr/pkg/${key} \
- * rhost:=server1 \
- * rhost:=server2
- *
- * -Rens Troost <rens@imsi.com>
- */
-static IntFuncPtr
-functable_lookup(char *key)
-{
- struct functable *fp;
-
- for (fp = functable; fp->name; fp++)
- if (FSTREQ(fp->name, key))
- return (fp->func);
- return (IntFuncPtr) NULL;
-}
-
-
-/*
- * Fill in the global structure fs_static by
- * cracking the string opts. opts may be
- * scribbled on at will. Does NOT evaluate options.
- * Returns 0 on error, 1 if no syntax errors were discovered.
- */
-static int
-split_opts(char *opts, char *mapkey)
-{
- char *o = opts;
- char *f;
-
- /*
- * For each user-specified option
- */
- for (f = opt(&o); *f; f = opt(&o)) {
- struct opt *op;
- char *eq = strchr(f, '=');
- char *opt = NULL;
-
- if (!eq)
- continue;
-
- if (*(eq-1) == '!' ||
- eq[1] == '=' ||
- eq[1] == '!') { /* != or == or =! */
- continue; /* we don't care about selectors */
- }
-
- if (*(eq-1) == ':') { /* := */
- *(eq-1) = '\0';
- } else {
- /* old style assignment */
- eq[0] = '\0';
- }
- opt = eq + 1;
-
- /*
- * For each recognized option
- */
- for (op = opt_fields; op->name; op++) {
- /*
- * Check whether they match
- */
- if (FSTREQ(op->name, f)) {
- if (op->sel_p) {
- plog(XLOG_USER, "key %s: Can't assign to a selector (%s)",
- mapkey, op->name);
- return 0;
- }
- *op->optp = opt; /* actual assignment into fs_static */
- break; /* break out of for loop */
- } /* end of "if (FSTREQ(op->name, f))" statement */
- } /* end of "for (op = opt_fields..." statement */
-
- if (!op->name)
- plog(XLOG_USER, "key %s: Unrecognized key/option \"%s\"", mapkey, f);
- }
-
- return 1;
-}
-
-
-/*
- * Just evaluate selectors, which were split by split_opts.
- * Returns 0 on error or no match, 1 if matched.
- */
-static int
-eval_selectors(char *opts, char *mapkey)
-{
- char *o, *old_o;
- char *f;
- int ret = 0;
-
- o = old_o = strdup(opts);
-
- /*
- * For each user-specified option
- */
- for (f = opt(&o); *f; f = opt(&o)) {
- struct opt *op;
- enum vs_opt vs_opt;
- char *eq = strchr(f, '=');
- char *fx;
- IntFuncPtr func;
- char *opt = NULL;
- char *arg;
-
- if (!eq) {
- /*
- * No value, is it a function call?
- */
- arg = strchr(f, '(');
-
- if (!arg || arg[1] == '\0' || arg == f) {
- /*
- * No, just continue
- */
- plog(XLOG_USER, "key %s: No value component in \"%s\"", mapkey, f);
- continue;
- }
-
- /* null-terminate the argument */
- *arg++ = '\0';
- fx = strchr(arg, ')');
- if (!arg || fx == arg) {
- plog(XLOG_USER, "key %s: Malformed function in \"%s\"", mapkey, f);
- continue;
- }
- *fx = '\0';
-
- if (f[0] == '!') {
- vs_opt = SelNE;
- f++;
- } else {
- vs_opt = SelEQ;
- }
- /*
- * look up f in functable and pass it arg.
- * func must return 0 on failure, and 1 on success.
- */
- if ((func = functable_lookup(f))) {
- int funok;
-
- /* this allocates memory, don't forget to free */
- arg = expand_options(arg);
- funok = func(arg);
- XFREE(arg);
-
- if (vs_opt == SelNE)
- funok = !funok;
- if (!funok)
- goto out;
-
- continue;
- } else {
- plog(XLOG_USER, "key %s: unknown function \"%s\"", mapkey, f);
- goto out;
- }
- } else {
- if (eq[1] == '\0' || eq == f) {
- /* misformed selector */
- plog(XLOG_USER, "key %s: Bad selector \"%s\"", mapkey, f);
- continue;
- }
- }
-
- /*
- * Check what type of operation is happening
- * !=, =! is SelNE
- * == is SelEQ
- * =, := is VarAss
- */
- if (*(eq-1) == '!') { /* != */
- vs_opt = SelNE;
- *(eq-1) = '\0';
- opt = eq + 1;
- } else if (*(eq-1) == ':') { /* := */
- continue;
- } else if (eq[1] == '=') { /* == */
- vs_opt = SelEQ;
- eq[0] = '\0';
- opt = eq + 2;
- } else if (eq[1] == '!') { /* =! */
- vs_opt = SelNE;
- eq[0] = '\0';
- opt = eq + 2;
- } else {
- /* old style assignment */
- continue;
- }
-
- /*
- * For each recognized option
- */
- for (op = opt_fields; op->name; op++) {
- /*
- * Check whether they match
- */
- if (FSTREQ(op->name, f)) {
- opt = expand_options(opt);
-
- if (op->sel_p != NULL) {
- int selok;
- if (op->case_insensitive) {
- selok = STRCEQ(*op->sel_p, opt);
- } else {
- selok = STREQ(*op->sel_p, opt);
- }
- if (vs_opt == SelNE)
- selok = !selok;
- if (!selok) {
- plog(XLOG_MAP, "key %s: map selector %s (=%s) did not %smatch %s",
- mapkey,
- op->name,
- *op->sel_p,
- vs_opt == SelNE ? "mis" : "",
- opt);
- XFREE(opt);
- goto out;
- }
- XFREE(opt);
- }
- /* check if to apply a function */
- if (op->fxn_p) {
- int funok;
-
- funok = op->fxn_p(opt);
- if (vs_opt == SelNE)
- funok = !funok;
- if (!funok) {
- plog(XLOG_MAP, "key %s: map function %s did not %smatch %s",
- mapkey,
- op->name,
- vs_opt == SelNE ? "mis" : "",
- opt);
- XFREE(opt);
- goto out;
- }
- XFREE(opt);
- }
- break; /* break out of for loop */
- }
- }
-
- if (!op->name)
- plog(XLOG_USER, "key %s: Unrecognized key/option \"%s\"", mapkey, f);
- }
-
- /* all is ok */
- ret = 1;
-
- out:
- free(old_o);
- return ret;
-}
-
-
-/*
- * Skip to next option in the string, but don't scribble over the string.
- * However, *p gets repointed to the start of the next string past ';'.
- */
-static char *
-opt_no_scribble(char **p)
-{
- char *cp = *p;
- char *dp = cp;
- char *s = cp;
-
-top:
- while (*cp && *cp != ';') {
- if (*cp == '\"') {
- /*
- * Skip past string
- */
- cp++;
- while (*cp && *cp != '\"')
- *dp++ = *cp++;
- if (*cp)
- cp++;
- } else {
- *dp++ = *cp++;
- }
- }
-
- /*
- * Skip past any remaining ';'s
- */
- while (*cp == ';')
- cp++;
-
- /*
- * If we have a zero length string
- * and there are more fields, then
- * parse the next one. This allows
- * sequences of empty fields.
- */
- if (*cp && dp == s)
- goto top;
-
- *p = cp;
- return s;
-}
-
-
-/*
- * Strip any selectors from a string. Selectors are all assumed to be
- * first in the string. This is used for the new /defaults method which will
- * use selectors as well.
- */
-char *
-strip_selectors(char *opts, char *mapkey)
-{
- /*
- * Fill in the global structure fs_static by
- * cracking the string opts. opts may be
- * scribbled on at will.
- */
- char *o = opts;
- char *oo = opts;
- char *f;
-
- /*
- * Scan options. Note that the opt() function scribbles on the opt string.
- */
- while (*(f = opt_no_scribble(&o))) {
- enum vs_opt vs_opt = VarAss;
- char *eq = strchr(f, '=');
-
- if (!eq || eq[1] == '\0' || eq == f) {
- /*
- * No option or assignment? Return as is.
- */
- plog(XLOG_USER, "key %s: No option or assignment in \"%s\"", mapkey, f);
- return o;
- }
- /*
- * Check what type of operation is happening
- * !=, =! is SelNE
- * == is SelEQ
- * := is VarAss
- */
- if (*(eq-1) == '!') { /* != */
- vs_opt = SelNE;
- } else if (*(eq-1) == ':') { /* := */
- vs_opt = VarAss;
- } else if (eq[1] == '=') { /* == */
- vs_opt = SelEQ;
- } else if (eq[1] == '!') { /* =! */
- vs_opt = SelNE;
- }
- switch (vs_opt) {
- case SelEQ:
- case SelNE:
- /* Skip this selector, maybe there's another one following it */
- plog(XLOG_USER, "skipping selector to \"%s\"", o);
- /* store previous match. it may have been the first assignment */
- oo = o;
- break;
-
- case VarAss:
- /* found the first assignment, return the string starting with it */
- dlog("found first assignment past selectors \"%s\"", o);
- return oo;
- }
- }
-
- /* return the same string by default. should not happen. */
- return oo;
-}
-
-
-/*****************************************************************************
- *** BOOLEAN FUNCTIONS (return 0 if false, 1 if true): ***
- *****************************************************************************/
-
-/* test if arg is any of this host's network names or numbers */
-static int
-f_in_network(char *arg)
-{
- int status;
-
- if (!arg)
- return 0;
-
- status = is_network_member(arg);
- dlog("%s is %son a local network", arg, (status ? "" : "not "));
- return status;
-}
-
-
-/*
- * Test if arg is any of this host's names or aliases (CNAMES).
- * Note: this function compares against the fully expanded host name (hostd).
- * XXX: maybe we also need to compare against the stripped host name?
- */
-static int
-f_xhost(char *arg)
-{
- struct hostent *hp;
- char **cp;
-
- if (!arg)
- return 0;
-
- /* simple test: does it match main host name? */
- if (STREQ(arg, opt_hostd))
- return 1;
-
- /* now find all of the names of "arg" and compare against opt_hostd */
- hp = gethostbyname(arg);
- if (hp == NULL) {
-#ifdef HAVE_HSTRERROR
- plog(XLOG_ERROR, "gethostbyname xhost(%s): %s", arg, hstrerror(h_errno));
-#else /* not HAVE_HSTRERROR */
- plog(XLOG_ERROR, "gethostbyname xhost(%s): h_errno %d", arg, h_errno);
-#endif /* not HAVE_HSTRERROR */
- return 0;
- }
- /* check primary name */
- if (hp->h_name) {
- dlog("xhost: compare %s==%s", hp->h_name, opt_hostd);
- if (STREQ(hp->h_name, opt_hostd)) {
- plog(XLOG_INFO, "xhost(%s): matched h_name %s", arg, hp->h_name);
- return 1;
- }
- }
- /* check all aliases, if any */
- if (hp->h_aliases == NULL) {
- dlog("gethostbyname(%s) has no aliases", arg);
- return 0;
- }
- cp = hp->h_aliases;
- while (*cp) {
- dlog("xhost: compare alias %s==%s", *cp, opt_hostd);
- if (STREQ(*cp, opt_hostd)) {
- plog(XLOG_INFO, "xhost(%s): matched alias %s", arg, *cp);
- return 1;
- }
- cp++;
- }
- /* nothing matched */
- return 0;
-}
-
-
-/* test if this host (short hostname form) is in netgroup (arg) */
-static int
-f_netgrp(char *arg)
-{
- int status;
- char *ptr, *nhost;
-
- if ((ptr = strchr(arg, ',')) != NULL) {
- *ptr = '\0';
- nhost = ptr + 1;
- } else {
- nhost = opt_host;
- }
- status = innetgr(arg, nhost, NULL, NULL);
- dlog("netgrp = %s status = %d host = %s", arg, status, nhost);
- if (ptr)
- *ptr = ',';
- return status;
-}
-
-
-/* test if this host (fully-qualified name) is in netgroup (arg) */
-static int
-f_netgrpd(char *arg)
-{
- int status;
- char *ptr, *nhost;
-
- if ((ptr = strchr(arg, ',')) != NULL) {
- *ptr = '\0';
- nhost = ptr + 1;
- } else {
- nhost = opt_hostd;
- }
- status = innetgr(arg, nhost, NULL, NULL);
- dlog("netgrp = %s status = %d hostd = %s", arg, status, nhost);
- if (ptr)
- *ptr = ',';
- return status;
-}
-
-
-/* test if file (arg) exists via lstat */
-static int
-f_exists(char *arg)
-{
- struct stat buf;
-
- if (lstat(arg, &buf) < 0)
- return (0);
- else
- return (1);
-}
-
-
-/* always false */
-static int
-f_false(char *arg)
-{
- return (0);
-}
-
-
-/* always true */
-static int
-f_true(char *arg)
-{
- return (1);
-}
-
-
-/*
- * Free an option
- */
-static void
-free_op(opt_apply *p, int b)
-{
- if (*p->opt) {
- XFREE(*p->opt);
- }
-}
-
-
-/*
- * Normalize slashes in the string.
- */
-void
-normalize_slash(char *p)
-{
- char *f, *f0;
-
- if (!(gopt.flags & CFM_NORMALIZE_SLASHES))
- return;
-
- f0 = f = strchr(p, '/');
- if (f) {
- char *t = f;
- do {
- /* assert(*f == '/'); */
- if (f == f0 && f[0] == '/' && f[1] == '/') {
- /* copy double slash iff first */
- *t++ = *f++;
- *t++ = *f++;
- } else {
- /* copy a single / across */
- *t++ = *f++;
- }
-
- /* assert(f[-1] == '/'); */
- /* skip past more /'s */
- while (*f == '/')
- f++;
-
- /* assert(*f != '/'); */
- /* keep copying up to next / */
- while (*f && *f != '/') {
- /* support escaped slashes '\/' */
- if (f[0] == '\\' && f[1] == '/')
- f++; /* skip backslash */
- *t++ = *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.
- * If sel_p is true then old expand selectors, otherwise
- * don't expand selectors.
- */
-static char *
-expand_op(char *opt, int sel_p)
-{
-#define EXPAND_ERROR "No space to expand \"%s\""
- char expbuf[MAXPATHLEN + 1];
- char nbuf[NLEN + 1];
- char *ep = expbuf;
- char *cp = opt;
- char *dp;
- struct opt *op;
- char *cp_orig = opt;
-
- while ((dp = strchr(cp, '$'))) {
- char ch;
- /*
- * First copy up to the $
- */
- {
- int len = dp - cp;
-
- if (len > 0) {
- if (BUFSPACE(ep, len)) {
- /*
- * We use strncpy (not xstrlcpy) because 'ep' relies on its
- * semantics. BUFSPACE guarantees that ep can hold len.
- */
- strncpy(ep, cp, len);
- ep += len;
- } else {
- plog(XLOG_ERROR, EXPAND_ERROR, opt);
- goto out;
- }
- }
- }
-
- cp = dp + 1;
- ch = *cp++;
- if (ch == '$') {
- if (BUFSPACE(ep, 1)) {
- *ep++ = '$';
- } else {
- plog(XLOG_ERROR, EXPAND_ERROR, opt);
- goto out;
- }
- } else if (ch == '{') {
- /* Expansion... */
- enum {
- E_All, E_Dir, E_File, E_Domain, E_Host
- } todo;
- /*
- * Find closing brace
- */
- char *br_p = strchr(cp, '}');
- int len;
-
- /*
- * Check we found it
- */
- if (!br_p) {
- /*
- * Just give up
- */
- plog(XLOG_USER, "No closing '}' in \"%s\"", opt);
- goto out;
- }
- len = br_p - cp;
-
- /*
- * Figure out which part of the variable to grab.
- */
- if (*cp == '/') {
- /*
- * Just take the last component
- */
- todo = E_File;
- cp++;
- --len;
- } else if (*(br_p-1) == '/') {
- /*
- * Take all but the last component
- */
- 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
- */
- todo = E_All;
- }
-
- /*
- * Truncate if too long. Since it won't
- * match anyway it doesn't matter that
- * it has been cut short.
- */
- if (len > NLEN)
- len = NLEN;
-
- /*
- * Put the string into another buffer so
- * we can do comparisons.
- *
- * We use strncpy here (not xstrlcpy) because the dest is meant
- * to be truncated and we don't want to log it as an error. The
- * use of the BUFSPACE macro above guarantees the safe use of
- * strncpy with nbuf.
- */
- strncpy(nbuf, cp, len);
- nbuf[len] = '\0';
-
- /*
- * Advance cp
- */
- cp = br_p + 1;
-
- /*
- * Search the option array
- */
- for (op = opt_fields; op->name; op++) {
- /*
- * Check for match
- */
- if (len == op->nlen && STREQ(op->name, nbuf)) {
- char xbuf[NLEN + 3];
- char *val;
- /*
- * Found expansion. Copy
- * the correct value field.
- */
- if (!(!op->sel_p == !sel_p)) {
- /*
- * Copy the string across unexpanded
- */
- xsnprintf(xbuf, sizeof(xbuf), "${%s%s%s}",
- todo == E_File ? "/" :
- todo == E_Domain ? "." : "",
- nbuf,
- todo == E_Dir ? "/" :
- todo == E_Host ? "." : "");
- val = xbuf;
- /*
- * Make sure expansion doesn't
- * munge the value!
- */
- todo = E_All;
- } else if (op->sel_p) {
- val = *op->sel_p;
- } else {
- val = *op->optp;
- }
-
- if (val) {
- /*
- * 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);
- char *vptr = val;
- switch (todo) {
- case E_Dir:
- vptr = strrchr(val, '/');
- if (vptr)
- vlen = vptr - val;
- vptr = val;
- break;
- case E_File:
- vptr = strrchr(val, '/');
- if (vptr) {
- vptr++;
- vlen = strlen(vptr);
- } 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;
- }
-
- if (BUFSPACE(ep, vlen+1)) {
- xstrlcpy(ep, vptr, vlen+1);
- ep += vlen;
- } else {
- plog(XLOG_ERROR, EXPAND_ERROR, opt);
- goto out;
- }
- }
- /*
- * Done with this variable
- */
- break;
- }
- }
-
- /*
- * Check that the search was successful
- */
- if (!op->name) {
- /*
- * If it wasn't then scan the
- * environment for that name
- * and use any value found
- */
- char *env = getenv(nbuf);
-
- if (env) {
- int vlen = strlen(env);
-
- if (BUFSPACE(ep, vlen+1)) {
- xstrlcpy(ep, env, vlen+1);
- ep += vlen;
- } else {
- plog(XLOG_ERROR, EXPAND_ERROR, opt);
- goto out;
- }
- if (amuDebug(D_STR))
- plog(XLOG_DEBUG, "Environment gave \"%s\" -> \"%s\"", nbuf, env);
- } else {
- plog(XLOG_USER, "Unknown sequence \"${%s}\"", nbuf);
- }
- }
- } else {
- /*
- * Error, error
- */
- plog(XLOG_USER, "Unknown $ sequence in \"%s\"", opt);
- }
- }
-
-out:
- /*
- * Handle common case - no expansion
- */
- if (cp == opt) {
- opt = strdup(cp);
- } else {
- /*
- * Finish off the expansion
- */
- int vlen = strlen(cp);
- if (BUFSPACE(ep, vlen+1)) {
- xstrlcpy(ep, cp, vlen+1);
- /* ep += vlen; */
- } else {
- plog(XLOG_ERROR, EXPAND_ERROR, opt);
- }
-
- /*
- * Save the expansion
- */
- opt = strdup(expbuf);
- }
-
- normalize_slash(opt);
-
- if (amuDebug(D_STR)) {
- plog(XLOG_DEBUG, "Expansion of \"%s\"...", cp_orig);
- plog(XLOG_DEBUG, "......... is \"%s\"", opt);
- }
- return opt;
-}
-
-
-/*
- * Wrapper for expand_op
- */
-static void
-expand_opts(opt_apply *p, int sel_p)
-{
- if (*p->opt) {
- *p->opt = expand_op(*p->opt, sel_p);
- } else if (p->val) {
- /*
- * Do double expansion, remembering
- * to free the string from the first
- * expansion...
- */
- char *s = expand_op(p->val, TRUE);
- *p->opt = expand_op(s, sel_p);
- XFREE(s);
- }
-}
-
-
-/*
- * Apply a function to a list of options
- */
-static void
-apply_opts(void (*op) (opt_apply *, int), opt_apply ppp[], int b)
-{
- opt_apply *pp;
-
- for (pp = ppp; pp->opt; pp++)
- (*op) (pp, b);
-}
-
-
-/*
- * Free the option table
- */
-void
-free_opts(am_opts *fo)
-{
- /*
- * Copy in the structure we are playing with
- */
- fs_static = *fo;
-
- /*
- * Free previously allocated memory
- */
- apply_opts(free_op, to_free, FALSE);
-}
-
-
-/*
- * Expand selectors (variables that cannot be assigned to or overridden)
- */
-char *
-expand_selectors(char *key)
-{
- return expand_op(key, TRUE);
-}
-
-
-/*
- * Expand options (i.e. non-selectors, see above for definition)
- */
-static inline char *
-expand_options(char *key)
-{
- return expand_op(key, FALSE);
-}
-
-
-/*
- * Remove trailing /'s from a string
- * unless the string is a single / (Steven Glassman)
- * or unless it is two slashes // (Kevin D. Bond)
- * or unless amd.conf says not to touch slashes.
- */
-void
-deslashify(char *s)
-{
- if (!(gopt.flags & CFM_NORMALIZE_SLASHES))
- return;
-
- if (s && *s) {
- char *sl = s + strlen(s);
-
- while (*--sl == '/' && sl > s)
- *sl = '\0';
- }
-}
-
-
-int
-eval_fs_opts(am_opts *fo, char *opts, char *g_opts, char *path, char *key, char *map)
-{
- int ok = TRUE;
-
- free_opts(fo);
-
- /*
- * Clear out the option table
- */
- memset((voidp) &fs_static, 0, sizeof(fs_static));
- memset((voidp) vars, 0, sizeof(vars));
- memset((voidp) fo, 0, sizeof(*fo));
-
- /* set hostname */
- opt_host = (char *) am_get_hostname();
-
- /*
- * Set key, map & path before expansion
- */
- opt_key = key;
- opt_map = map;
- opt_path = path;
-
- opt_dkey = strchr(key, '.');
- if (!opt_dkey) {
- opt_dkey = NullStr;
- opt_keyd = key;
- } else {
- opt_keyd = strnsave(key, opt_dkey - key);
- opt_dkey++;
- if (*opt_dkey == '\0') /* check for 'host.' */
- opt_dkey = NullStr;
- }
-
- /*
- * Expand global options
- */
- fs_static.fs_glob = expand_selectors(g_opts);
-
- /*
- * Expand local options
- */
- fs_static.fs_local = expand_selectors(opts);
-
- /* break global options into fs_static fields */
- if ((ok = split_opts(fs_static.fs_glob, key))) {
- dlog("global split_opts ok");
- /*
- * evaluate local selectors
- */
- if ((ok = eval_selectors(fs_static.fs_local, key))) {
- dlog("local eval_selectors ok");
- /* if the local selectors matched, then do the local overrides */
- ok = split_opts(fs_static.fs_local, key);
- if (ok)
- dlog("local split_opts ok");
- }
- }
-
- /*
- * Normalize remote host name.
- * 1. Expand variables
- * 2. Normalize relative to host tables
- * 3. Strip local domains from the remote host
- * name before using it in other expansions.
- * This makes mount point names and other things
- * much shorter, while allowing cross domain
- * sharing of mount maps.
- */
- apply_opts(expand_opts, rhost_expansion, FALSE);
- if (ok && fs_static.opt_rhost && *fs_static.opt_rhost)
- host_normalize(&fs_static.opt_rhost);
-
- /*
- * Macro expand the options.
- * Do this regardless of whether we are accepting
- * this mount - otherwise nasty things happen
- * with memory allocation.
- */
- apply_opts(expand_opts, expansions, FALSE);
-
- /*
- * Strip trailing slashes from local pathname...
- */
- deslashify(fs_static.opt_fs);
-
- /*
- * ok... copy the data back out.
- */
- *fo = fs_static;
-
- /*
- * Clear defined options
- */
- if (opt_keyd != key && opt_keyd != nullstr)
- XFREE(opt_keyd);
- opt_keyd = nullstr;
- opt_dkey = NullStr;
- opt_key = opt_map = opt_path = nullstr;
-
- return ok;
-}
diff --git a/contrib/amd/amd/readdir.c b/contrib/amd/amd/readdir.c
deleted file mode 100644
index d025c9118c30..000000000000
--- a/contrib/amd/amd/readdir.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/readdir.c
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-
-/****************************************************************************
- *** MACROS ***
- ****************************************************************************/
-#define DOT_DOT_COOKIE (u_int) 1
-#define MAX_CHAIN 2048
-
-
-/****************************************************************************
- *** FORWARD DEFINITIONS ***
- ****************************************************************************/
-static int key_already_in_chain(char *keyname, const nfsentry *chain);
-static nfsentry *make_entry_chain(am_node *mp, const nfsentry *current_chain, int fully_browsable);
-static int amfs_readdir_browsable(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count, int fully_browsable);
-
-
-/****************************************************************************
- *** FUNCTIONS ***
- ****************************************************************************/
-/*
- * Was: NEW_TOPLVL_READDIR
- * Search a chain for an entry with some name.
- * -Erez Zadok <ezk@cs.columbia.edu>
- */
-static int
-key_already_in_chain(char *keyname, const nfsentry *chain)
-{
- const nfsentry *tmpchain = chain;
-
- while (tmpchain) {
- if (keyname && tmpchain->ne_name && STREQ(keyname, tmpchain->ne_name))
- return 1;
- tmpchain = tmpchain->ne_nextentry;
- }
-
- return 0;
-}
-
-
-/*
- * Create a chain of entries which are not linked.
- * -Erez Zadok <ezk@cs.columbia.edu>
- */
-static nfsentry *
-make_entry_chain(am_node *mp, const nfsentry *current_chain, int fully_browsable)
-{
- static u_int last_cookie = (u_int) 2; /* monotonically increasing */
- static nfsentry chain[MAX_CHAIN];
- static int max_entries = MAX_CHAIN;
- char *key;
- int num_entries = 0, i;
- u_int preflen = 0;
- nfsentry *retval = (nfsentry *) NULL;
- mntfs *mf;
- mnt_map *mmp;
-
- if (!mp) {
- plog(XLOG_DEBUG, "make_entry_chain: mp is (NULL)");
- return retval;
- }
- mf = mp->am_mnt;
- if (!mf) {
- plog(XLOG_DEBUG, "make_entry_chain: mp->am_mnt is (NULL)");
- return retval;
- }
- mmp = (mnt_map *) mf->mf_private;
- if (!mmp) {
- plog(XLOG_DEBUG, "make_entry_chain: mp->am_mnt->mf_private is (NULL)");
- return retval;
- }
-
- if (mp->am_pref)
- preflen = strlen(mp->am_pref);
-
- /* iterate over keys */
- for (i = 0; i < NKVHASH; i++) {
- kv *k;
- for (k = mmp->kvhash[i]; k ; k = k->next) {
-
- /*
- * Skip unwanted entries which are either not real entries or
- * very difficult to interpret (wildcards...) This test needs
- * lots of improvement. Any takers?
- */
- key = k->key;
- if (!key)
- continue;
-
- /* Skip '/defaults' */
- if (STREQ(key, "/defaults"))
- continue;
-
- /* Skip '*' */
- if (!fully_browsable && strchr(key, '*'))
- continue;
-
- /*
- * If the map has a prefix-string then check if the key starts with
- * this string, and if it does, skip over this prefix. If it has a
- * prefix and it doesn't match the start of the key, skip it.
- */
- if (preflen) {
- if (preflen > strlen(key))
- continue;
- if (!NSTREQ(key, mp->am_pref, preflen))
- continue;
- key += preflen;
- }
-
- /* no more '/' are allowed, unless browsable_dirs=full was used */
- if (!fully_browsable && strchr(key, '/'))
- continue;
-
- /* no duplicates allowed */
- if (key_already_in_chain(key, current_chain))
- continue;
-
- /* fill in a cell and link the entry */
- if (num_entries >= max_entries) {
- /* out of space */
- plog(XLOG_DEBUG, "make_entry_chain: no more space in chain");
- if (num_entries > 0) {
- chain[num_entries - 1].ne_nextentry = 0;
- retval = &chain[0];
- }
- return retval;
- }
-
- /* we have space. put entry in next cell */
- ++last_cookie;
- chain[num_entries].ne_fileid = (u_int) last_cookie;
- *(u_int *) chain[num_entries].ne_cookie = (u_int) last_cookie;
- chain[num_entries].ne_name = key;
- if (num_entries < max_entries - 1) { /* link to next one */
- chain[num_entries].ne_nextentry = &chain[num_entries + 1];
- }
- ++num_entries;
- } /* end of "while (k)" */
- } /* end of "for (i ... NKVHASH ..." */
-
- /* terminate chain */
- if (num_entries > 0) {
- chain[num_entries - 1].ne_nextentry = 0;
- retval = &chain[0];
- }
-
- return retval;
-}
-
-
-
-/* This one is called only if map is browsable */
-static int
-amfs_readdir_browsable(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count, int fully_browsable)
-{
- u_int gen = *(u_int *) cookie;
- int chain_length, i;
- static nfsentry *te, *te_next;
- static int j;
-
- dp->dl_eof = FALSE; /* assume readdir not done */
-
- if (amuDebug(D_READDIR))
- plog(XLOG_DEBUG, "amfs_readdir_browsable gen=%u, count=%d",
- gen, count);
-
- if (gen == 0) {
- /*
- * In the default instance (which is used to start a search) we return
- * "." and "..".
- *
- * This assumes that the count is big enough to allow both "." and ".."
- * to be returned in a single packet. If it isn't (which would be
- * fairly unbelievable) then tough.
- */
- dlog("amfs_readdir_browsable: default search");
- /*
- * Check for enough room. This is extremely approximate but is more
- * than enough space. Really need 2 times:
- * 4byte fileid
- * 4byte cookie
- * 4byte name length
- * 4byte name
- * plus the dirlist structure */
- if (count < (2 * (2 * (sizeof(*ep) + sizeof("..") + 4) + sizeof(*dp))))
- return EINVAL;
-
- /*
- * compute # of entries to send in this chain.
- * heuristics: 128 bytes per entry.
- * This is too much probably, but it seems to work better because
- * of the re-entrant nature of nfs_readdir, and esp. on systems
- * like OpenBSD 2.2.
- */
- chain_length = count / 128;
-
- /* reset static state counters */
- te = te_next = NULL;
-
- dp->dl_entries = ep;
-
- /* construct "." */
- ep[0].ne_fileid = mp->am_gen;
- ep[0].ne_name = ".";
- ep[0].ne_nextentry = &ep[1];
- *(u_int *) ep[0].ne_cookie = 0;
-
- /* construct ".." */
- if (mp->am_parent)
- ep[1].ne_fileid = mp->am_parent->am_gen;
- else
- ep[1].ne_fileid = mp->am_gen;
-
- ep[1].ne_name = "..";
- ep[1].ne_nextentry = 0;
- *(u_int *) ep[1].ne_cookie = DOT_DOT_COOKIE;
-
- /*
- * If map is browsable, call a function make_entry_chain() to construct
- * a linked list of unmounted keys, and return it. Then link the chain
- * to the regular list. Get the chain only once, but return
- * chunks of it each time.
- */
- te = make_entry_chain(mp, dp->dl_entries, fully_browsable);
- if (!te)
- return 0;
- if (amuDebug(D_READDIR)) {
- nfsentry *ne;
- for (j = 0, ne = te; ne; ne = ne->ne_nextentry)
- plog(XLOG_DEBUG, "gen1 key %4d \"%s\"", j++, ne->ne_name);
- }
-
- /* return only "chain_length" entries */
- te_next = te;
- for (i=1; i<chain_length; ++i) {
- te_next = te_next->ne_nextentry;
- if (!te_next)
- break;
- }
- if (te_next) {
- nfsentry *te_saved = te_next->ne_nextentry;
- te_next->ne_nextentry = NULL; /* terminate "te" chain */
- te_next = te_saved; /* save rest of "te" for next iteration */
- dp->dl_eof = FALSE; /* tell readdir there's more */
- } else {
- dp->dl_eof = TRUE; /* tell readdir that's it */
- }
- ep[1].ne_nextentry = te; /* append this chunk of "te" chain */
- if (amuDebug(D_READDIR)) {
- nfsentry *ne;
- for (j = 0, ne = te; ne; ne = ne->ne_nextentry)
- plog(XLOG_DEBUG, "gen2 key %4d \"%s\"", j++, ne->ne_name);
- for (j = 0, ne = ep; ne; ne = ne->ne_nextentry)
- plog(XLOG_DEBUG, "gen2+ key %4d \"%s\" fi=%d ck=%d",
- j++, ne->ne_name, ne->ne_fileid, *(u_int *)ne->ne_cookie);
- plog(XLOG_DEBUG, "EOF is %d", dp->dl_eof);
- }
- return 0;
- } /* end of "if (gen == 0)" statement */
-
- dlog("amfs_readdir_browsable: real child");
-
- if (gen == DOT_DOT_COOKIE) {
- dlog("amfs_readdir_browsable: End of readdir in %s", mp->am_path);
- dp->dl_eof = TRUE;
- dp->dl_entries = 0;
- return 0;
- }
-
- /*
- * If browsable directories, then continue serving readdir() with another
- * chunk of entries, starting from where we left off (when gen was equal
- * to 0). Once again, assume last chunk served to readdir.
- */
- dp->dl_eof = TRUE;
- dp->dl_entries = ep;
-
- te = te_next; /* reset 'te' from last saved te_next */
- if (!te) { /* another indicator of end of readdir */
- dp->dl_entries = 0;
- return 0;
- }
- /*
- * compute # of entries to send in this chain.
- * heuristics: 128 bytes per entry.
- */
- chain_length = count / 128;
-
- /* return only "chain_length" entries */
- for (i = 1; i < chain_length; ++i) {
- te_next = te_next->ne_nextentry;
- if (!te_next)
- break;
- }
- if (te_next) {
- nfsentry *te_saved = te_next->ne_nextentry;
- te_next->ne_nextentry = NULL; /* terminate "te" chain */
- te_next = te_saved; /* save rest of "te" for next iteration */
- dp->dl_eof = FALSE; /* tell readdir there's more */
- }
- ep = te; /* send next chunk of "te" chain */
- dp->dl_entries = ep;
- if (amuDebug(D_READDIR)) {
- nfsentry *ne;
- plog(XLOG_DEBUG, "dl_entries=%p, te_next=%p, dl_eof=%d",
- dp->dl_entries, te_next, dp->dl_eof);
- for (ne = te; ne; ne = ne->ne_nextentry)
- plog(XLOG_DEBUG, "gen3 key %4d \"%s\"", j++, ne->ne_name);
- }
- return 0;
-}
-
-
-/*
- * This readdir function which call a special version of it that allows
- * browsing if browsable_dirs=yes was set on the map.
- */
-int
-amfs_generic_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count)
-{
- u_int gen = *(u_int *) cookie;
- am_node *xp;
- mntent_t mnt;
-
- dp->dl_eof = FALSE; /* assume readdir not done */
-
- /* check if map is browsable */
- if (mp->am_mnt && mp->am_mnt->mf_mopts) {
- mnt.mnt_opts = mp->am_mnt->mf_mopts;
- if (amu_hasmntopt(&mnt, "fullybrowsable"))
- return amfs_readdir_browsable(mp, cookie, dp, ep, count, TRUE);
- if (amu_hasmntopt(&mnt, "browsable"))
- return amfs_readdir_browsable(mp, cookie, dp, ep, count, FALSE);
- }
-
- /* when gen is 0, we start reading from the beginning of the directory */
- if (gen == 0) {
- /*
- * In the default instance (which is used to start a search) we return
- * "." and "..".
- *
- * This assumes that the count is big enough to allow both "." and ".."
- * to be returned in a single packet. If it isn't (which would be
- * fairly unbelievable) then tough.
- */
- dlog("amfs_generic_readdir: default search");
- /*
- * Check for enough room. This is extremely approximate but is more
- * than enough space. Really need 2 times:
- * 4byte fileid
- * 4byte cookie
- * 4byte name length
- * 4byte name
- * plus the dirlist structure */
- if (count < (2 * (2 * (sizeof(*ep) + sizeof("..") + 4) + sizeof(*dp))))
- return EINVAL;
-
- xp = next_nonerror_node(mp->am_child);
- dp->dl_entries = ep;
-
- /* construct "." */
- ep[0].ne_fileid = mp->am_gen;
- ep[0].ne_name = ".";
- ep[0].ne_nextentry = &ep[1];
- *(u_int *) ep[0].ne_cookie = 0;
-
- /* construct ".." */
- if (mp->am_parent)
- ep[1].ne_fileid = mp->am_parent->am_gen;
- else
- ep[1].ne_fileid = mp->am_gen;
- ep[1].ne_name = "..";
- ep[1].ne_nextentry = 0;
- *(u_int *) ep[1].ne_cookie = (xp ? xp->am_gen : DOT_DOT_COOKIE);
-
- if (!xp)
- dp->dl_eof = TRUE; /* by default assume readdir done */
-
- if (amuDebug(D_READDIR)) {
- nfsentry *ne;
- int j;
- for (j = 0, ne = ep; ne; ne = ne->ne_nextentry)
- plog(XLOG_DEBUG, "gen1 key %4d \"%s\" fi=%d ck=%d",
- j++, ne->ne_name, ne->ne_fileid, *(u_int *)ne->ne_cookie);
- }
- return 0;
- }
- dlog("amfs_generic_readdir: real child");
-
- if (gen == DOT_DOT_COOKIE) {
- dlog("amfs_generic_readdir: End of readdir in %s", mp->am_path);
- dp->dl_eof = TRUE;
- dp->dl_entries = 0;
- if (amuDebug(D_READDIR))
- plog(XLOG_DEBUG, "end of readdir eof=TRUE, dl_entries=0\n");
- return 0;
- }
-
- /* non-browsable directories code */
- xp = mp->am_child;
- while (xp && xp->am_gen != gen)
- xp = xp->am_osib;
-
- if (xp) {
- int nbytes = count / 2; /* conservative */
- int todo = MAX_READDIR_ENTRIES;
-
- dp->dl_entries = ep;
- do {
- am_node *xp_next = next_nonerror_node(xp->am_osib);
-
- if (xp_next) {
- *(u_int *) ep->ne_cookie = xp_next->am_gen;
- } else {
- *(u_int *) ep->ne_cookie = DOT_DOT_COOKIE;
- dp->dl_eof = TRUE;
- }
-
- ep->ne_fileid = xp->am_gen;
- ep->ne_name = xp->am_name;
- nbytes -= sizeof(*ep) + 1;
- if (xp->am_name)
- nbytes -= strlen(xp->am_name);
-
- xp = xp_next;
-
- if (nbytes > 0 && !dp->dl_eof && todo > 1) {
- ep->ne_nextentry = ep + 1;
- ep++;
- --todo;
- } else {
- todo = 0;
- }
- } while (todo > 0);
-
- ep->ne_nextentry = 0;
-
- if (amuDebug(D_READDIR)) {
- nfsentry *ne;
- int j;
- for (j=0,ne=ep; ne; ne=ne->ne_nextentry)
- plog(XLOG_DEBUG, "gen2 key %4d \"%s\" fi=%d ck=%d",
- j++, ne->ne_name, ne->ne_fileid, *(u_int *)ne->ne_cookie);
- }
- return 0;
- }
- return ESTALE;
-}
diff --git a/contrib/amd/amd/restart.c b/contrib/amd/amd/restart.c
deleted file mode 100644
index 4f71e381e25a..000000000000
--- a/contrib/amd/amd/restart.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/restart.c
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-
-static void
-restart_fake_mntfs(mntent_t *me, am_ops *fs_ops)
-{
- mntfs *mf;
- am_opts mo;
- char *cp;
-
- /*
- * Partially fake up an opts structure
- */
- memset(&mo, 0, sizeof(mo));
- mo.opt_rhost = 0;
- mo.opt_rfs = 0;
- cp = strchr(me->mnt_fsname, ':');
- if (cp) {
- *cp = '\0';
- mo.opt_rhost = strdup(me->mnt_fsname);
- mo.opt_rfs = strdup(cp + 1);
- *cp = ':';
- } else if (STREQ(me->mnt_type, MNTTAB_TYPE_NFS)) {
- /*
- * Hacky workaround for mnttab NFS entries that only list the server
- */
- plog(XLOG_WARNING, "NFS server entry assumed to be %s:/", me->mnt_fsname);
- mo.opt_rhost = strdup(me->mnt_fsname);
- mo.opt_rfs = strdup("/");
- me->mnt_fsname = str3cat(me->mnt_fsname, mo.opt_rhost, ":", "/");
- }
- mo.opt_fs = me->mnt_dir;
- mo.opt_opts = me->mnt_opts;
-
- /*
- * Make a new mounted filesystem
- */
- mf = find_mntfs(fs_ops, &mo, me->mnt_dir,
- me->mnt_fsname, "", me->mnt_opts, "");
- if (mf->mf_refc == 1) {
- mf->mf_flags |= MFF_RESTART | MFF_MOUNTED;
- mf->mf_error = 0; /* Already mounted correctly */
- mf->mf_fo = 0;
- /*
- * Only timeout non-NFS entries
- */
- if (!STREQ(me->mnt_type, MNTTAB_TYPE_NFS))
- mf->mf_flags |= MFF_RSTKEEP;
- if (fs_ops->fs_init) {
- /*
- * Don't care whether this worked since
- * it is checked again when the fs is
- * inherited.
- */
- (void) (*fs_ops->fs_init) (mf);
- }
- plog(XLOG_INFO, "%s restarted fstype %s on %s, flags 0x%x",
- me->mnt_fsname, fs_ops->fs_type, me->mnt_dir, mf->mf_flags);
- } else {
- /* Something strange happened - two mounts at the same place! */
- free_mntfs(mf);
- }
- /*
- * Clean up mo
- */
- if (mo.opt_rhost)
- XFREE(mo.opt_rhost);
- if (mo.opt_rfs)
- XFREE(mo.opt_rfs);
-}
-
-
-/*
- * Handle an amd restart.
- *
- * Scan through the mount list finding all "interesting" mount points.
- * Next hack up partial data structures and add the mounted file
- * system to the list of known filesystems.
- *
- * This module relies on internal details of other components. If
- * you change something else make *sure* restart() still works.
- */
-void
-restart(void)
-{
- mntlist *ml, *mlp;
-
- /*
- * Read the existing mount table. For each entry, find nfs, ufs or auto
- * mounts and create a partial am_node to represent it.
- */
- for (mlp = ml = read_mtab("restart", mnttab_file_name);
- mlp;
- mlp = mlp->mnext) {
- mntent_t *me = mlp->mnt;
- am_ops *fs_ops = 0;
-
- if (STREQ(me->mnt_type, MNTTAB_TYPE_NFS)) {
- /*
- * NFS entry, or possibly an Amd entry...
- * The mnt_fsname for daemon mount points is
- * host:(pidXXX)
- * or (seen on Solaris)
- * host:daemon(pidXXX)
- */
- char *colon = strchr(me->mnt_fsname, ':');
- if (colon && strstr(colon, "(pid"))
- continue;
- }
-
- /* Search for the correct filesystem ops */
- fs_ops = ops_search(me->mnt_type);
-
- /*
- * Catch everything else with symlinks to
- * avoid recursive mounts. This is debatable...
- */
- if (!fs_ops)
- fs_ops = &amfs_link_ops;
-
- restart_fake_mntfs(me, fs_ops);
- }
-
- /*
- * Free the mount list
- */
- free_mntlist(ml);
-}
-
-
-/*
- * Handle an amd restart for amd's own mount points.
- *
- * Scan through the mount list finding all daemon mount points
- * (determined by the presence of a pid inside the mount info).
- * Next hack up partial data structures and add the mounted file
- * system to the list of known filesystems.
- *
- * This module relies on internal details of other components. If
- * you change something else make *sure* restart() still works.
- */
-void
-restart_automounter_nodes(void)
-{
- mntlist *ml, *mlp;
- /* reasonably sized list of restarted nfs ports */
- u_short old_ports[256];
-
- memset((voidp) &old_ports, 0, sizeof(u_short) * 256);
-
- /*
- * Read the existing mount table. For each entry, find nfs, ufs or auto
- * mounts and create a partial am_node to represent it.
- */
- for (mlp = ml = read_mtab("restart", mnttab_file_name);
- mlp;
- mlp = mlp->mnext) {
- mntent_t *me = mlp->mnt;
- am_ops *fs_ops = 0;
- char *colon;
- long pid;
- u_short port;
- int err;
-
- if (!STREQ(me->mnt_type, MNTTAB_TYPE_NFS))
- continue; /* to next mlp */
- /*
- * NFS entry, or possibly an Amd entry...
- * The mnt_fsname for daemon mount points is
- * host:(pidXXX)
- * or (seen on Solaris)
- * host:daemon(pidXXX)
- */
- colon = strchr(me->mnt_fsname, ':');
- if (!colon || !strstr(colon, "(pid"))
- continue;
- /* if got here, then we matched an existing Amd mount point */
- err = 1;
-
- plog(XLOG_WARNING, "%s is an existing automount point", me->mnt_dir);
-
- /* Is the old automounter still alive? */
- if (sscanf(colon, "%*[^(](pid%ld%*[,)]", &pid) != 1) {
- plog(XLOG_WARNING, "Can't parse pid in %s", me->mnt_fsname);
- goto give_up;
- }
- if (kill(pid, 0) != -1 || errno != ESRCH) {
- plog(XLOG_WARNING, "Automounter (pid: %ld) still alive", pid);
- goto give_up;
- }
-
- /*
- * Do we have a map for this mount point? Who cares, we'll restart
- * anyway -- getting ESTALE is way better than hanging.
- */
-
- /* Can we restart it? Only if it tells us what port it was using... */
- if (sscanf(colon, "%*[^,],port%hu)", &port) != 1) {
- plog(XLOG_WARNING, "No port specified for %s", me->mnt_fsname);
- goto give_up;
- }
-
- /* Maybe we already own that port... */
- if (port != nfs_port) {
- int i;
- for (i = 0; i < 256; i++) {
- if (old_ports[i] == port ||
- old_ports[i] == 0)
- break;
- }
- if (i == 256) {
- plog(XLOG_WARNING, "Too many open ports (256)");
- goto give_up;
- }
-
- if (old_ports[i] == 0) {
- int soNFS;
- SVCXPRT *nfsxprt;
- if (create_nfs_service(&soNFS, &port, &nfsxprt, nfs_program_2) != 0) {
- plog(XLOG_WARNING, "Can't bind to port %u", port);
- goto give_up;
- }
- old_ports[i] = nfs_port = port;
- }
- }
- err = 0;
-
- give_up:
- if (err) {
- plog(XLOG_WARNING, "Can't restart %s, leaving it alone", me->mnt_dir);
- fs_ops = &amfs_link_ops;
- } else {
- fs_ops = &amfs_toplvl_ops;
- }
-
- restart_fake_mntfs(me, fs_ops);
- } /* end of "for (mlp" */
-
- /* free the mount list */
- free_mntlist(ml);
-}
diff --git a/contrib/amd/amd/rpc_fwd.c b/contrib/amd/amd/rpc_fwd.c
deleted file mode 100644
index b3c8be4fa3b7..000000000000
--- a/contrib/amd/amd/rpc_fwd.c
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/rpc_fwd.c
- *
- */
-
-/*
- * RPC packet forwarding
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/*
- * Note that the ID field in the external packet is only
- * ever treated as a 32 bit opaque data object, so there
- * is no need to convert to and from network byte ordering.
- */
-
-#define XID_ALLOC() (xid++)
-#define MAX_PACKET_SIZE 8192 /* Maximum UDP packet size */
-
-/*
- * Each pending reply has an rpc_forward structure
- * associated with it. These have a 15 second lifespan.
- * If a new structure is required, then an expired
- * one will be re-allocated if available, otherwise a fresh
- * one is allocated. Whenever a reply is received the
- * structure is discarded.
- */
-typedef struct rpc_forward rpc_forward;
-struct rpc_forward {
- qelem rf_q; /* Linked list */
- time_t rf_ttl; /* Time to live */
- u_int rf_xid; /* Packet id */
- u_int rf_oldid; /* Original packet id */
- fwd_fun *rf_fwd; /* Forwarding function */
- voidp rf_ptr;
- struct sockaddr_in rf_sin;
-};
-
-/*
- * Head of list of pending replies
- */
-qelem rpc_head = {&rpc_head, &rpc_head};
-int fwd_sock;
-static u_int xid;
-
-
-/*
- * Allocate a rely structure
- */
-static rpc_forward *
-fwd_alloc(void)
-{
- time_t now = clocktime(NULL);
- rpc_forward *p = 0, *p2;
-
- /*
- * First search for an existing expired one.
- */
- ITER(p2, rpc_forward, &rpc_head) {
- if (p2->rf_ttl <= now) {
- p = p2;
- break;
- }
- }
-
- /*
- * If one couldn't be found then allocate
- * a new structure and link it at the
- * head of the list.
- */
- if (p) {
- /*
- * Call forwarding function to say that
- * this message was junked.
- */
- dlog("Re-using packet forwarding slot - id %#x", p->rf_xid);
- if (p->rf_fwd)
- (*p->rf_fwd) (0, 0, 0, &p->rf_sin, p->rf_ptr, FALSE);
- rem_que(&p->rf_q);
- } else {
- p = ALLOC(struct rpc_forward);
- }
- ins_que(&p->rf_q, &rpc_head);
-
- /*
- * Set the time to live field
- * Timeout in 43 seconds
- */
- p->rf_ttl = now + 43;
-
- return p;
-}
-
-
-/*
- * Free an allocated reply structure.
- * First unlink it from the list, then
- * discard it.
- */
-static void
-fwd_free(rpc_forward *p)
-{
- rem_que(&p->rf_q);
- XFREE(p);
-}
-
-
-/*
- * Initialize the RPC forwarder
- */
-int
-fwd_init(void)
-{
-#ifdef FIONBIO
- int on = 1;
-#endif /* FIONBIO */
-
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- /*
- * Create ping TLI socket (/dev/tcp and /dev/ticlts did not work)
- * (HPUX-11 does not like using O_NDELAY in flags)
- */
- fwd_sock = t_open("/dev/udp", O_RDWR|O_NONBLOCK, 0);
- if (fwd_sock < 0) {
- plog(XLOG_ERROR, "unable to create RPC forwarding TLI socket: %s",
- t_errlist[t_errno]);
- return errno;
- }
-#else /* not HAVE_TRANSPORT_TYPE_TLI */
- /*
- * Create ping socket
- */
- fwd_sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (fwd_sock < 0) {
- plog(XLOG_ERROR, "unable to create RPC forwarding socket: %m");
- return errno;
- }
-#endif /* not HAVE_TRANSPORT_TYPE_TLI */
-
- /*
- * Some things we talk to require a priv port - so make one here
- */
- if (bind_resv_port(fwd_sock, (u_short *) 0) < 0)
- plog(XLOG_ERROR, "can't bind privileged port (rpc_fwd)");
-
- if (fcntl(fwd_sock, F_SETFL, FNDELAY) < 0
-#ifdef FIONBIO
- && ioctl(fwd_sock, FIONBIO, &on) < 0
-#endif /* FIONBIO */
- ) {
- plog(XLOG_ERROR, "Can't set non-block on forwarding socket: %m");
- return errno;
- }
-
- return 0;
-}
-
-
-/*
- * Locate a packet in the forwarding list
- */
-static rpc_forward *
-fwd_locate(u_int id)
-{
- rpc_forward *p;
-
- ITER(p, rpc_forward, &rpc_head) {
- if (p->rf_xid == id)
- return p;
- }
-
- return 0;
-}
-
-
-/*
- * This is called to forward a packet to another
- * RPC server. The message id is changed and noted
- * so that when a reply appears we can tie it up
- * correctly. Just matching the reply's source address
- * would not work because it might come from a
- * different address.
- */
-int
-fwd_packet(int type_id, char *pkt, int len, struct sockaddr_in *fwdto, struct sockaddr_in *replyto, opaque_t cb_arg, fwd_fun cb)
-{
- rpc_forward *p;
- u_int *pkt_int;
- int error;
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- struct t_unitdata ud;
-#endif /* HAVE_TRANSPORT_TYPE_TLI */
-
- if ((int) amd_state >= (int) Finishing)
- return ENOENT;
-
- /*
- * See if the type_id is fully specified.
- * If so, then discard any old entries
- * for this id.
- * Otherwise make sure the type_id is
- * fully qualified by allocating an id here.
- */
- switch (type_id & RPC_XID_MASK) {
- case RPC_XID_PORTMAP:
- dlog("Sending PORTMAP request %#x", type_id);
- break;
- case RPC_XID_MOUNTD:
- dlog("Sending MOUNTD request %#x", type_id);
- break;
- case RPC_XID_NFSPING:
- dlog("Sending NFS ping %#x", type_id);
- break;
- case RPC_XID_WEBNFS:
- dlog("Sending WebNFS lookup %#x", type_id);
- break;
- default:
- dlog("UNKNOWN RPC XID %#x", type_id);
- break;
- }
-
- if (type_id & ~RPC_XID_MASK) {
- p = fwd_locate(type_id);
- if (p) {
- dlog("Discarding earlier rpc fwd handle");
- fwd_free(p);
- }
- } else {
- dlog("Allocating a new xid...");
- type_id = MK_RPC_XID(type_id, XID_ALLOC());
- }
-
- p = fwd_alloc();
- if (!p)
- return ENOBUFS;
-
- error = 0;
-
- pkt_int = (u_int *) pkt;
-
- /*
- * Get the original packet id
- */
- p->rf_oldid = ntohl(*pkt_int);
-
- /*
- * Replace with newly allocated id
- */
- p->rf_xid = type_id;
- *pkt_int = htonl(type_id);
-
- /*
- * The sendto may fail if, for example, the route
- * to a remote host is lost because an intermediate
- * gateway has gone down. Important to fill in the
- * rest of "p" otherwise nasty things happen later...
- */
-#ifdef DEBUG
- {
- char dq[20];
- if (p && fwdto)
- dlog("Sending packet id %#x to %s:%d",
- p->rf_xid,
- inet_dquad(dq, sizeof(dq), fwdto->sin_addr.s_addr),
- ntohs(fwdto->sin_port));
- }
-#endif /* DEBUG */
-
- /* if NULL, remote server probably down */
- if (!fwdto) {
- error = AM_ERRNO_HOST_DOWN;
- goto out;
- }
-
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- ud.addr.buf = (char *) fwdto;
- if (fwdto) /* if NULL, set sizes to zero */
- ud.addr.maxlen = ud.addr.len = sizeof(struct sockaddr_in);
- else
- ud.addr.maxlen = ud.addr.len = 0;
- ud.opt.buf = (char *) NULL;
- ud.opt.maxlen = ud.opt.len = 0;
- ud.udata.buf = pkt;
- ud.udata.maxlen = ud.udata.len = len;
- if (t_sndudata(fwd_sock, &ud) < 0) {
- plog(XLOG_ERROR,"fwd_packet failed: t_errno=%d, errno=%d",t_errno,errno);
- error = errno;
- }
-#else /* not HAVE_TRANSPORT_TYPE_TLI */
- if (sendto(fwd_sock, (char *) pkt, len, 0,
- (struct sockaddr *) fwdto, sizeof(*fwdto)) < 0)
- error = errno;
-#endif /* not HAVE_TRANSPORT_TYPE_TLI */
-
- /*
- * Save callback function and return address
- */
-out:
- p->rf_fwd = cb;
- if (replyto)
- p->rf_sin = *replyto;
- else
- memset((voidp) &p->rf_sin, 0, sizeof(p->rf_sin));
- p->rf_ptr = cb_arg;
-
- return error;
-}
-
-
-/*
- * Called when some data arrives on the forwarding socket
- */
-void
-fwd_reply(void)
-{
- int len;
- u_int pkt[MAX_PACKET_SIZE / sizeof(u_int) + 1];
- u_int *pkt_int;
- u_int pkt_xid;
- int rc;
- rpc_forward *p;
- struct sockaddr_in src_addr;
- RECVFROM_FROMLEN_TYPE src_addr_len;
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- struct t_unitdata ud;
- int flags = 0;
-#endif /* HAVE_TRANSPORT_TYPE_TLI */
-
- /*
- * Determine the length of the packet
- */
- len = MAX_PACKET_SIZE;
-
- /*
- * Read the packet and check for validity
- */
-again:
- src_addr_len = sizeof(src_addr);
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- ud.addr.buf = (char *) &src_addr;
- ud.addr.maxlen = ud.addr.len = src_addr_len;
- ud.opt.buf = (char *) NULL;
- ud.opt.maxlen = ud.opt.len = 0;
- ud.udata.buf = (char *) pkt;
- ud.udata.maxlen = ud.udata.len = len;
- /* XXX: use flags accordingly such as if T_MORE set */
- rc = t_rcvudata(fwd_sock, &ud, &flags);
- if (rc == 0) /* success, reset rc to length */
- rc = ud.udata.len;
- else {
- plog(XLOG_ERROR,"fwd_reply failed: t_errno=%d, errno=%d, flags=%d",t_errno,errno, flags);
- /*
- * Clear error indication, otherwise the error condition persists and
- * amd gets into an infinite loop.
- */
- if (t_errno == TLOOK)
- t_rcvuderr(fwd_sock, NULL);
- }
-#else /* not HAVE_TRANSPORT_TYPE_TLI */
- rc = recvfrom(fwd_sock,
- (char *) pkt,
- len,
- 0,
- (struct sockaddr *) &src_addr,
- &src_addr_len);
-#endif /* not HAVE_TRANSPORT_TYPE_TLI */
-
- /*
- * XXX: in svr4, if the T_MORE bit of flags is set, what do
- * we then do? -Erez
- */
- if (rc < 0 || src_addr_len != sizeof(src_addr) ||
- src_addr.sin_family != AF_INET) {
- if (rc < 0 && errno == EINTR)
- goto again;
- plog(XLOG_ERROR, "Error reading RPC reply: %m");
- goto out;
- }
-
- /*
- * Do no more work if finishing soon
- */
- if ((int) amd_state >= (int) Finishing)
- goto out;
-
- /*
- * Find packet reference
- */
- pkt_int = (u_int *) pkt;
- pkt_xid = ntohl(*pkt_int);
-
- switch (pkt_xid & RPC_XID_MASK) {
- case RPC_XID_PORTMAP:
- dlog("Receiving PORTMAP reply %#x", pkt_xid);
- break;
- case RPC_XID_MOUNTD:
- dlog("Receiving MOUNTD reply %#x", pkt_xid);
- break;
- case RPC_XID_NFSPING:
- dlog("Receiving NFS ping %#x", pkt_xid);
- break;
- case RPC_XID_WEBNFS:
- dlog("Receiving WebNFS lookup %#x", pkt_xid);
- break;
- default:
- dlog("UNKNOWN RPC XID %#x", pkt_xid);
- break;
- }
-
- p = fwd_locate(pkt_xid);
- if (!p) {
- dlog("Can't forward reply id %#x", pkt_xid);
- goto out;
- }
-
- if (p->rf_fwd) {
- /*
- * Put the original message id back
- * into the packet.
- */
- *pkt_int = htonl(p->rf_oldid);
-
- /*
- * Call forwarding function
- */
- (*p->rf_fwd) ((voidp) pkt, rc, &src_addr, &p->rf_sin, p->rf_ptr, TRUE);
- }
-
- /*
- * Free forwarding info
- */
- fwd_free(p);
-
-out:;
-}
diff --git a/contrib/amd/amd/sched.c b/contrib/amd/amd/sched.c
deleted file mode 100644
index 8efe57a3ab81..000000000000
--- a/contrib/amd/amd/sched.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/sched.c
- *
- */
-
-/*
- * Process scheduler
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-
-typedef struct pjob pjob;
-
-struct pjob {
- qelem hdr; /* Linked list */
- int pid; /* Process ID of job */
- cb_fun *cb_fun; /* Callback function */
- opaque_t cb_arg; /* Argument for callback */
- int w; /* everyone these days uses int, not a "union wait" */
- wchan_t wchan; /* Wait channel */
-};
-
-/* globals */
-qelem proc_list_head = {&proc_list_head, &proc_list_head};
-qelem proc_wait_list = {&proc_wait_list, &proc_wait_list};
-int task_notify_todo;
-
-
-void
-ins_que(qelem *elem, qelem *pred)
-{
- qelem *p = pred->q_forw;
-
- elem->q_back = pred;
- elem->q_forw = p;
- pred->q_forw = elem;
- p->q_back = elem;
-}
-
-
-void
-rem_que(qelem *elem)
-{
- qelem *p = elem->q_forw;
- qelem *p2 = elem->q_back;
-
- p2->q_forw = p;
- p->q_back = p2;
-}
-
-
-static pjob *
-sched_job(cb_fun *cf, opaque_t ca)
-{
- pjob *p = ALLOC(struct pjob);
-
- p->cb_fun = cf;
- p->cb_arg = ca;
-
- /*
- * Now place on wait queue
- */
- ins_que(&p->hdr, &proc_wait_list);
-
- return p;
-}
-
-
-/*
- * tf: The task to execute (ta is its arguments)
- * cf: Continuation function (ca is its arguments)
- */
-void
-run_task(task_fun *tf, opaque_t ta, cb_fun *cf, opaque_t ca)
-{
- pjob *p = sched_job(cf, ca);
-#ifdef HAVE_SIGACTION
- sigset_t new, mask;
-#else /* not HAVE_SIGACTION */
- int mask;
-#endif /* not HAVE_SIGACTION */
-
- p->wchan = (wchan_t) p;
-
-#ifdef HAVE_SIGACTION
- sigemptyset(&new); /* initialize signal set we wish to block */
- sigaddset(&new, SIGCHLD); /* only block on SIGCHLD */
- sigprocmask(SIG_BLOCK, &new, &mask);
-#else /* not HAVE_SIGACTION */
- mask = sigblock(sigmask(SIGCHLD));
-#endif /* not HAVE_SIGACTION */
-
- if ((p->pid = background())) {
-#ifdef HAVE_SIGACTION
- sigprocmask(SIG_SETMASK, &mask, NULL);
-#else /* not HAVE_SIGACTION */
- sigsetmask(mask);
-#endif /* not HAVE_SIGACTION */
- return;
- }
-
- /* child code runs here, parent has returned to caller */
-
- exit((*tf) (ta));
- /* firewall... */
- abort();
-}
-
-
-/*
- * Schedule a task to be run when woken up
- */
-void
-sched_task(cb_fun *cf, opaque_t ca, wchan_t wchan)
-{
- /*
- * Allocate a new task
- */
- pjob *p = sched_job(cf, ca);
-
- dlog("SLEEP on %p", wchan);
- p->wchan = wchan;
- p->pid = 0;
- p->w = 0; /* was memset (when ->w was union) */
-}
-
-
-static void
-wakeupjob(pjob *p)
-{
- rem_que(&p->hdr);
- ins_que(&p->hdr, &proc_list_head);
- task_notify_todo++;
-}
-
-
-void
-wakeup(wchan_t wchan)
-{
- pjob *p, *p2;
-
- if (!foreground)
- return;
-
- /*
- * Can't use ITER() here because
- * wakeupjob() juggles the list.
- */
- for (p = AM_FIRST(pjob, &proc_wait_list);
- p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list);
- p = p2) {
- if (p->wchan == wchan) {
- wakeupjob(p);
- }
- }
-}
-
-
-void
-wakeup_task(int rc, int term, wchan_t wchan)
-{
- wakeup(wchan);
-}
-
-
-wchan_t
-get_mntfs_wchan(mntfs *mf)
-{
- if (mf &&
- mf->mf_ops &&
- mf->mf_ops->get_wchan)
- return mf->mf_ops->get_wchan(mf);
- return mf;
-}
-
-
-/*
- * Run any pending tasks.
- * This must be called with SIGCHLD disabled
- */
-void
-do_task_notify(void)
-{
- /*
- * Keep taking the first item off the list and processing it.
- *
- * Done this way because the callback can, quite reasonably,
- * queue a new task, so no local reference into the list can be
- * held here.
- */
- while (AM_FIRST(pjob, &proc_list_head) != HEAD(pjob, &proc_list_head)) {
- pjob *p = AM_FIRST(pjob, &proc_list_head);
- rem_que(&p->hdr);
- /*
- * This job has completed
- */
- --task_notify_todo;
-
- /*
- * Do callback if it exists
- */
- if (p->cb_fun) {
- /* these two trigraphs will ensure compatibility with strict POSIX.1 */
- p->cb_fun(WIFEXITED(p->w) ? WEXITSTATUS(p->w) : 0,
- WIFSIGNALED(p->w) ? WTERMSIG(p->w) : 0,
- p->cb_arg);
- }
- XFREE(p);
- }
-}
-
-
-RETSIGTYPE
-sigchld(int sig)
-{
- int w; /* everyone these days uses int, not a "union wait" */
- int pid;
-
-#ifdef HAVE_WAITPID
- while ((pid = waitpid((pid_t) -1, &w, WNOHANG)) > 0) {
-#else /* not HAVE_WAITPID */
- while ((pid = wait3( &w, WNOHANG, (struct rusage *) 0)) > 0) {
-#endif /* not HAVE_WAITPID */
- pjob *p, *p2;
-
- if (WIFSIGNALED(w))
- plog(XLOG_ERROR, "Process %d exited with signal %d",
- pid, WTERMSIG(w));
- else
- dlog("Process %d exited with status %d",
- pid, WEXITSTATUS(w));
-
- for (p = AM_FIRST(pjob, &proc_wait_list);
- p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list);
- p = p2) {
- if (p->pid == pid) {
- p->w = w;
- wakeupjob(p);
- break;
- }
- } /* end of for loop */
-
- if (p == HEAD(pjob, &proc_wait_list))
- dlog("can't locate task block for pid %d", pid);
-
- /*
- * Must count down children inside the while loop, otherwise we won't
- * count them all, and NumChildren (and later backoff) will be set
- * incorrectly. SH/RUNIT 940519.
- */
- if (--NumChildren < 0)
- NumChildren = 0;
- } /* end of "while wait..." loop */
-
-#ifdef REINSTALL_SIGNAL_HANDLER
- signal(sig, sigchld);
-#endif /* REINSTALL_SIGNAL_HANDLER */
-
- if (select_intr_valid)
- longjmp(select_intr, sig);
-}
diff --git a/contrib/amd/amd/srvr_amfs_auto.c b/contrib/amd/amd/srvr_amfs_auto.c
deleted file mode 100644
index 4742cf6f750d..000000000000
--- a/contrib/amd/amd/srvr_amfs_auto.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1989 Jan-Simon Pendry
- * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/srvr_amfs_auto.c
- *
- */
-
-/*
- * Automount FS server ("localhost") modeling
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/* globals */
-
-/* statics */
-static qelem amfs_auto_srvr_list = {&amfs_auto_srvr_list, &amfs_auto_srvr_list};
-static fserver *localhost;
-
-
-/*
- * Find an nfs server for the local host
- */
-fserver *
-amfs_generic_find_srvr(mntfs *mf)
-{
- fserver *fs = localhost;
-
- if (!fs) {
- fs = ALLOC(struct fserver);
- fs->fs_refc = 0;
- fs->fs_host = strdup("localhost");
- fs->fs_ip = 0;
- fs->fs_cid = 0;
- fs->fs_pinger = AM_PINGER;
- fs->fs_flags = FSF_VALID | FSF_PING_UNINIT;
- fs->fs_type = "local";
- fs->fs_private = 0;
- fs->fs_prfree = 0;
-
- ins_que(&fs->fs_q, &amfs_auto_srvr_list);
-
- srvrlog(fs, "starts up");
-
- localhost = fs;
- }
- fs->fs_refc++;
-
- return fs;
-}
-
-
-/*****************************************************************************
- *** GENERIC ROUTINES FOLLOW
- *****************************************************************************/
-
-/*
- * Wakeup anything waiting for this server
- */
-void
-wakeup_srvr(fserver *fs)
-{
- fs->fs_flags &= ~FSF_WANT;
- wakeup((voidp) fs);
-}
-
-
-/*
- * Called when final ttl of server has expired
- */
-static void
-timeout_srvr(voidp v)
-{
- fserver *fs = v;
-
- /*
- * If the reference count is still zero then
- * we are free to remove this node
- */
- if (fs->fs_refc == 0) {
- dlog("Deleting file server %s", fs->fs_host);
- if (fs->fs_flags & FSF_WANT)
- wakeup_srvr(fs);
-
- /*
- * Remove from queue.
- */
- rem_que(&fs->fs_q);
- /*
- * (Possibly) call the private free routine.
- */
- if (fs->fs_private && fs->fs_prfree)
- (*fs->fs_prfree) (fs->fs_private);
-
- /*
- * Free the net address
- */
- if (fs->fs_ip)
- XFREE(fs->fs_ip);
-
- /*
- * Free the host name.
- */
- XFREE(fs->fs_host);
-
- /*
- * Discard the fserver object.
- */
- XFREE(fs);
- }
-}
-
-
-/*
- * Free a file server
- */
-void
-free_srvr(fserver *fs)
-{
- if (--fs->fs_refc == 0) {
- /*
- * The reference count is now zero,
- * so arrange for this node to be
- * removed in AM_TTL seconds if no
- * other mntfs is referencing it.
- */
- int ttl = (FSRV_ERROR(fs) || FSRV_ISDOWN(fs)) ? 19 : AM_TTL;
-
- dlog("Last hard reference to file server %s - will timeout in %ds", fs->fs_host, ttl);
- if (fs->fs_cid) {
- untimeout(fs->fs_cid);
- /*
- * Turn off pinging - XXX
- */
- fs->fs_flags &= ~FSF_PINGING;
- }
-
- /*
- * Keep structure lying around for a while
- */
- fs->fs_cid = timeout(ttl, timeout_srvr, (voidp) fs);
-
- /*
- * Mark the fileserver down and invalid again
- */
- fs->fs_flags &= ~FSF_VALID;
- fs->fs_flags |= FSF_DOWN;
- }
-}
-
-
-/*
- * Make a duplicate fserver reference
- */
-fserver *
-dup_srvr(fserver *fs)
-{
- fs->fs_refc++;
- return fs;
-}
-
-
-/*
- * Log state change
- */
-void
-srvrlog(fserver *fs, char *state)
-{
- plog(XLOG_INFO, "file server %s, type %s, state %s", fs->fs_host, fs->fs_type, state);
-}
diff --git a/contrib/amd/amd/srvr_nfs.c b/contrib/amd/amd/srvr_nfs.c
deleted file mode 100644
index 0c74a658e5ee..000000000000
--- a/contrib/amd/amd/srvr_nfs.c
+++ /dev/null
@@ -1,1042 +0,0 @@
-/*
- * Copyright (c) 1997-2006 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- * File: am-utils/amd/srvr_nfs.c
- *
- */
-
-/*
- * NFS server modeling
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/*
- * Number of pings allowed to fail before host is declared down
- * - three-fifths of the allowed mount time...
- */
-#define MAX_ALLOWED_PINGS (3 + /* for luck ... */ 1)
-
-/*
- * How often to ping when starting a new server
- */
-#define FAST_NFS_PING 3
-
-#if (FAST_NFS_PING * MAX_ALLOWED_PINGS) >= ALLOWED_MOUNT_TIME
-# error: sanity check failed in srvr_nfs.c
-/*
- * you cannot do things this way...
- * sufficient fast pings must be given the chance to fail
- * within the allowed mount time
- */
-#endif /* (FAST_NFS_PING * MAX_ALLOWED_PINGS) >= ALLOWED_MOUNT_TIME */
-
-/* structures and typedefs */
-typedef struct nfs_private {
- u_short np_mountd; /* Mount daemon port number */
- char np_mountd_inval; /* Port *may* be invalid */
- int np_ping; /* Number of failed ping attempts */
- time_t np_ttl; /* Time when server is thought dead */
- int np_xid; /* RPC transaction id for pings */
- int np_error; /* Error during portmap request */
-} nfs_private;
-
-/* globals */
-qelem nfs_srvr_list = {&nfs_srvr_list, &nfs_srvr_list};
-
-/* statics */
-static int global_xid; /* For NFS pings */
-#define XID_ALLOC() (++global_xid)
-
-#ifdef HAVE_FS_NFS3
-# define NUM_NFS_VERS 2
-#else /* not HAVE_FS_NFS3 */
-# define NUM_NFS_VERS 1
-#endif /* not HAVE_FS_NFS3 */
-static int ping_len[NUM_NFS_VERS];
-static char ping_buf[NUM_NFS_VERS][sizeof(struct rpc_msg) + 32];
-
-#if defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3)
-/*
- * Protocols we know about, in order of preference.
- *
- * Note that Solaris 8 and newer NetBSD systems are switching to UDP first,
- * so this order may have to be adjusted for Amd in the future once more
- * vendors make that change. -Erez 11/24/2000
- *
- * Or we might simply make this is a platform-specific order. -Ion 09/13/2003
- */
-static char *protocols[] = { "tcp", "udp", NULL };
-#endif /* defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) */
-
-/* forward definitions */
-static void nfs_keepalive(voidp);
-
-
-/*
- * Flush cached data for an fserver (or for all, if fs==NULL)
- */
-void
-flush_srvr_nfs_cache(fserver *fs)
-{
- fserver *fs2 = NULL;
-
- ITER(fs2, fserver, &nfs_srvr_list) {
- if (fs == NULL || fs == fs2) {
- nfs_private *np = (nfs_private *) fs2->fs_private;
- if (np) {
- np->np_mountd_inval = TRUE;
- np->np_error = -1;
- }
- }
- }
-}
-
-
-/*
- * Startup the NFS ping for a particular version.
- */
-static void
-create_ping_payload(u_long nfs_version)
-{
- XDR ping_xdr;
- struct rpc_msg ping_msg;
-
- /*
- * Non nfs mounts like /afs/glue.umd.edu have ended up here.
- */
- if (nfs_version == 0) {
- nfs_version = NFS_VERSION;
- plog(XLOG_WARNING, "create_ping_payload: nfs_version = 0, changed to 2");
- } else
- plog(XLOG_INFO, "create_ping_payload: nfs_version: %d", (int) nfs_version);
-
- rpc_msg_init(&ping_msg, NFS_PROGRAM, nfs_version, NFSPROC_NULL);
-
- /*
- * Create an XDR endpoint
- */
- xdrmem_create(&ping_xdr, ping_buf[nfs_version - NFS_VERSION], sizeof(ping_buf[0]), XDR_ENCODE);
-
- /*
- * Create the NFS ping message
- */
- if (!xdr_callmsg(&ping_xdr, &ping_msg)) {
- plog(XLOG_ERROR, "Couldn't create ping RPC message");
- going_down(3);
- }
- /*
- * Find out how long it is
- */
- ping_len[nfs_version - NFS_VERSION] = xdr_getpos(&ping_xdr);
-
- /*
- * Destroy the XDR endpoint - we don't need it anymore
- */
- xdr_destroy(&ping_xdr);
-}
-
-
-/*
- * Called when a portmap reply arrives
- */
-static void
-got_portmap(voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, voidp idv, int done)
-{
- fserver *fs2 = (fserver *) idv;
- fserver *fs = 0;
-
- /*
- * Find which fileserver we are talking about
- */
- ITER(fs, fserver, &nfs_srvr_list)
- if (fs == fs2)
- break;
-
- if (fs == fs2) {
- u_long port = 0; /* XXX - should be short but protocol is naff */
- int error = done ? pickup_rpc_reply(pkt, len, (voidp) &port, (XDRPROC_T_TYPE) xdr_u_long) : -1;
- nfs_private *np = (nfs_private *) fs->fs_private;
-
- if (!error && port) {
- dlog("got port (%d) for mountd on %s", (int) port, fs->fs_host);
- /*
- * Grab the port number. Portmap sends back
- * an u_long in native ordering, so it
- * needs converting to a u_short in
- * network ordering.
- */
- np->np_mountd = htons((u_short) port);
- np->np_mountd_inval = FALSE;
- np->np_error = 0;
- } else {
- dlog("Error fetching port for mountd on %s", fs->fs_host);
- dlog("\t error=%d, port=%d", error, (int) port);
- /*
- * Almost certainly no mountd running on remote host
- */
- np->np_error = error ? error : ETIMEDOUT;
- }
-
- if (fs->fs_flags & FSF_WANT)
- wakeup_srvr(fs);
- } else if (done) {
- dlog("Got portmap for old port request");
- } else {
- dlog("portmap request timed out");
- }
-}
-
-
-/*
- * Obtain portmap information
- */
-static int
-call_portmap(fserver *fs, AUTH *auth, u_long prog, u_long vers, u_long prot)
-{
- struct rpc_msg pmap_msg;
- int len;
- char iobuf[UDPMSGSIZE];
- int error;
- struct pmap pmap;
-
- rpc_msg_init(&pmap_msg, PMAPPROG, PMAPVERS, PMAPPROC_NULL);
- pmap.pm_prog = prog;
- pmap.pm_vers = vers;
- pmap.pm_prot = prot;
- pmap.pm_port = 0;
- len = make_rpc_packet(iobuf,
- sizeof(iobuf),
- PMAPPROC_GETPORT,
- &pmap_msg,
- (voidp) &pmap,
- (XDRPROC_T_TYPE) xdr_pmap,
- auth);
- if (len > 0) {
- struct sockaddr_in sin;
- memset((voidp) &sin, 0, sizeof(sin));
- sin = *fs->fs_ip;
- sin.sin_port = htons(PMAPPORT);
- error = fwd_packet(RPC_XID_PORTMAP, iobuf, len,
- &sin, &sin, (voidp) fs, got_portmap);
- } else {
- error = -len;
- }
-
- return error;
-}
-
-
-static void
-recompute_portmap(fserver *fs)
-{
- int error;
- u_long mnt_version;
-
- /*
- * No portmap calls for pure WebNFS servers.
- */
- if (fs->fs_flags & FSF_WEBNFS)
- return;
-
- if (nfs_auth)
- error = 0;
- else
- error = make_nfs_auth();
-
- if (error) {
- nfs_private *np = (nfs_private *) fs->fs_private;
- np->np_error = error;
- return;
- }
-
- if (fs->fs_version == 0)
- plog(XLOG_WARNING, "recompute_portmap: nfs_version = 0 fixed");
-
- plog(XLOG_INFO, "recompute_portmap: NFS version %d on %s",
- (int) fs->fs_version, fs->fs_host);
-#ifdef HAVE_FS_NFS3
- if (fs->fs_version == NFS_VERSION3)
- mnt_version = AM_MOUNTVERS3;
- else
-#endif /* HAVE_FS_NFS3 */
- mnt_version = MOUNTVERS;
-
- plog(XLOG_INFO, "Using MOUNT version: %d", (int) mnt_version);
- call_portmap(fs, nfs_auth, MOUNTPROG, mnt_version, (u_long) IPPROTO_UDP);
-}
-
-
-int
-get_mountd_port(fserver *fs, u_short *port, wchan_t wchan)
-{
- int error = -1;
- if (FSRV_ISDOWN(fs))
- return EWOULDBLOCK;
-
- if (FSRV_ISUP(fs)) {
- nfs_private *np = (nfs_private *) fs->fs_private;
- if (np->np_error == 0) {
- *port = np->np_mountd;
- error = 0;
- } else {
- error = np->np_error;
- }
- /*
- * Now go get the port mapping again in case it changed.
- * Note that it is used even if (np_mountd_inval)
- * is True. The flag is used simply as an
- * indication that the mountd may be invalid, not
- * that it is known to be invalid.
- */
- if (np->np_mountd_inval)
- recompute_portmap(fs);
- else
- np->np_mountd_inval = TRUE;
- }
- if (error < 0 && wchan && !(fs->fs_flags & FSF_WANT)) {
- /*
- * If a wait channel is supplied, and no
- * error has yet occurred, then arrange
- * that a wakeup is done on the wait channel,
- * whenever a wakeup is done on this fs node.
- * Wakeup's are done on the fs node whenever
- * it changes state - thus causing control to
- * come back here and new, better things to happen.
- */
- fs->fs_flags |= FSF_WANT;
- sched_task(wakeup_task, wchan, (wchan_t) fs);
- }
- return error;
-}
-
-
-/*
- * This is called when we get a reply to an RPC ping.
- * The value of id was taken from the nfs_private
- * structure when the ping was transmitted.
- */
-static void
-nfs_keepalive_callback(voidp pkt, int len, struct sockaddr_in *sp, struct sockaddr_in *tsp, voidp idv, int done)
-{
- int xid = (long) idv; /* cast needed for 64-bit archs */
- fserver *fs;
- int found_map = 0;
-
- if (!done)
- return;
-
- /*
- * For each node...
- */
- ITER(fs, fserver, &nfs_srvr_list) {
- nfs_private *np = (nfs_private *) fs->fs_private;
- if (np->np_xid == xid && (fs->fs_flags & FSF_PINGING)) {
- /*
- * Reset the ping counter.
- * Update the keepalive timer.
- * Log what happened.
- */
- if (fs->fs_flags & FSF_DOWN) {
- fs->fs_flags &= ~FSF_DOWN;
- if (fs->fs_flags & FSF_VALID) {
- srvrlog(fs, "is up");
- } else {
- if (np->np_ping > 1)
- srvrlog(fs, "ok");
- else
- srvrlog(fs, "starts up");
- fs->fs_flags |= FSF_VALID;
- }
-
- map_flush_srvr(fs);
- } else {
- if (fs->fs_flags & FSF_VALID) {
- dlog("file server %s type nfs is still up", fs->fs_host);
- } else {
- if (np->np_ping > 1)
- srvrlog(fs, "ok");
- fs->fs_flags |= FSF_VALID;
- }
- }
-
- /*
- * Adjust ping interval
- */
- untimeout(fs->fs_cid);
- fs->fs_cid = timeout(fs->fs_pinger, nfs_keepalive, (voidp) fs);
-
- /*
- * Update ttl for this server
- */
- np->np_ttl = clocktime(NULL) +
- (MAX_ALLOWED_PINGS - 1) * FAST_NFS_PING + fs->fs_pinger - 1;
-
- /*
- * New RPC xid...
- */
- np->np_xid = XID_ALLOC();
-
- /*
- * Failed pings is zero...
- */
- np->np_ping = 0;
-
- /*
- * Recompute portmap information if not known
- */
- if (np->np_mountd_inval)
- recompute_portmap(fs);
-
- found_map++;
- break;
- }
- }
-
- if (found_map == 0)
- dlog("Spurious ping packet");
-}
-
-
-static void
-check_fs_addr_change(fserver *fs)
-{
- struct hostent *hp = NULL;
- struct in_addr ia;
- char *old_ipaddr, *new_ipaddr;
-
- hp = gethostbyname(fs->fs_host);
- if (!hp ||
- hp->h_addrtype != AF_INET ||
- !STREQ((char *) hp->h_name, fs->fs_host) ||
- memcmp((voidp) &fs->fs_ip->sin_addr,
- (voidp) hp->h_addr,
- sizeof(fs->fs_ip->sin_addr)) == 0)
- return;
- /* if got here: downed server changed IP address */
- old_ipaddr = strdup(inet_ntoa(fs->fs_ip->sin_addr));
- memmove((voidp) &ia, (voidp) hp->h_addr, sizeof(struct in_addr));
- new_ipaddr = inet_ntoa(ia); /* ntoa uses static buf */
- plog(XLOG_WARNING, "EZK: down fileserver %s changed ip: %s -> %s",
- fs->fs_host, old_ipaddr, new_ipaddr);
- XFREE(old_ipaddr);
- /* copy new IP addr */
- memmove((voidp) &fs->fs_ip->sin_addr,
- (voidp) hp->h_addr,
- sizeof(fs->fs_ip->sin_addr));
- /* XXX: do we need to un/set these flags? */
- fs->fs_flags &= ~FSF_DOWN;
- fs->fs_flags |= FSF_VALID | FSF_WANT;
- map_flush_srvr(fs); /* XXX: a race with flush_srvr_nfs_cache? */
- flush_srvr_nfs_cache(fs);
- fs->fs_flags |= FSF_FORCE_UNMOUNT;
-
-#if 0
- flush_nfs_fhandle_cache(fs); /* done in caller: nfs_keepalive_timeout */
- /* XXX: need to purge nfs_private so that somehow it will get re-initialized? */
-#endif
-}
-
-
-/*
- * Called when no ping-reply received
- */
-static void
-nfs_keepalive_timeout(voidp v)
-{
- fserver *fs = v;
- nfs_private *np = (nfs_private *) fs->fs_private;
-
- /*
- * Another ping has failed
- */
- np->np_ping++;
- if (np->np_ping > 1)
- srvrlog(fs, "not responding");
-
- /*
- * Not known to be up any longer
- */
- if (FSRV_ISUP(fs))
- fs->fs_flags &= ~FSF_VALID;
-
- /*
- * If ttl has expired then guess that it is dead
- */
- if (np->np_ttl < clocktime(NULL)) {
- int oflags = fs->fs_flags;
- dlog("ttl has expired");
- if ((fs->fs_flags & FSF_DOWN) == 0) {
- /*
- * Server was up, but is now down.
- */
- srvrlog(fs, "is down");
- fs->fs_flags |= FSF_DOWN | FSF_VALID;
- /*
- * Since the server is down, the portmap
- * information may now be wrong, so it
- * must be flushed from the local cache
- */
- flush_nfs_fhandle_cache(fs);
- np->np_error = -1;
- check_fs_addr_change(fs); /* check if IP addr of fserver changed */
- } else {
- /*
- * Known to be down
- */
- if ((fs->fs_flags & FSF_VALID) == 0)
- srvrlog(fs, "starts down");
- fs->fs_flags |= FSF_VALID;
- }
- if (oflags != fs->fs_flags && (fs->fs_flags & FSF_WANT))
- wakeup_srvr(fs);
- /*
- * Reset failed ping count
- */
- np->np_ping = 0;
- } else {
- if (np->np_ping > 1)
- dlog("%d pings to %s failed - at most %d allowed", np->np_ping, fs->fs_host, MAX_ALLOWED_PINGS);
- }
-
- /*
- * New RPC xid, so any late responses to the previous ping
- * get ignored...
- */
- np->np_xid = XID_ALLOC();
-
- /*
- * Run keepalive again
- */
- nfs_keepalive(fs);
-}
-
-
-/*
- * Keep track of whether a server is alive
- */
-static void
-nfs_keepalive(voidp v)
-{
- fserver *fs = v;
- int error;
- nfs_private *np = (nfs_private *) fs->fs_private;
- int fstimeo = -1;
-
- /*
- * Send an NFS ping to this node
- */
-
- if (ping_len[fs->fs_version - NFS_VERSION] == 0)
- create_ping_payload(fs->fs_version);
-
- /*
- * Queue the packet...
- */
- error = fwd_packet(MK_RPC_XID(RPC_XID_NFSPING, np->np_xid),
- ping_buf[fs->fs_version - NFS_VERSION],
- ping_len[fs->fs_version - NFS_VERSION],
- fs->fs_ip,
- (struct sockaddr_in *) 0,
- (voidp) ((long) np->np_xid), /* cast needed for 64-bit archs */
- nfs_keepalive_callback);
-
- /*
- * See if a hard error occurred
- */
- switch (error) {
- case ENETDOWN:
- case ENETUNREACH:
- case EHOSTDOWN:
- case EHOSTUNREACH:
- np->np_ping = MAX_ALLOWED_PINGS; /* immediately down */
- np->np_ttl = (time_t) 0;
- /*
- * This causes an immediate call to nfs_keepalive_timeout
- * whenever the server was thought to be up.
- * See +++ below.
- */
- fstimeo = 0;
- break;
-
- case 0:
- dlog("Sent NFS ping to %s", fs->fs_host);
- break;
- }
-
- /*
- * Back off the ping interval if we are not getting replies and
- * the remote system is known to be down.
- */
- switch (fs->fs_flags & (FSF_DOWN | FSF_VALID)) {
- case FSF_VALID: /* Up */
- if (fstimeo < 0) /* +++ see above */
- fstimeo = FAST_NFS_PING;
- break;
-
- case FSF_VALID | FSF_DOWN: /* Down */
- fstimeo = fs->fs_pinger;
- break;
-
- default: /* Unknown */
- fstimeo = FAST_NFS_PING;
- break;
- }
-
- dlog("NFS timeout in %d seconds", fstimeo);
-
- fs->fs_cid = timeout(fstimeo, nfs_keepalive_timeout, (voidp) fs);
-}
-
-
-static void
-start_nfs_pings(fserver *fs, int pingval)
-{
- if (pingval == 0) /* could be because ping mnt option not found */
- pingval = AM_PINGER;
- /* if pings haven't been initalized, then init them for first time */
- if (fs->fs_flags & FSF_PING_UNINIT) {
- fs->fs_flags &= ~FSF_PING_UNINIT;
- plog(XLOG_INFO, "initializing %s's pinger to %d sec", fs->fs_host, pingval);
- goto do_pings;
- }
-
- if ((fs->fs_flags & FSF_PINGING) && fs->fs_pinger == pingval) {
- dlog("already running pings to %s", fs->fs_host);
- return;
- }
-
- /* if got here, then we need to update the ping value */
- plog(XLOG_INFO, "changing %s's ping value from %d%s to %d%s",
- fs->fs_host,
- fs->fs_pinger, (fs->fs_pinger < 0 ? " (off)" : ""),
- pingval, (pingval < 0 ? " (off)" : ""));
- do_pings:
- fs->fs_pinger = pingval;
-
- if (fs->fs_cid)
- untimeout(fs->fs_cid);
- if (pingval < 0) {
- srvrlog(fs, "wired up (pings disabled)");
- fs->fs_flags |= FSF_VALID;
- fs->fs_flags &= ~FSF_DOWN;
- } else {
- fs->fs_flags |= FSF_PINGING;
- nfs_keepalive(fs);
- }
-}
-
-
-/*
- * Find an nfs server for a host.
- */
-fserver *
-find_nfs_srvr(mntfs *mf)
-{
- char *host = mf->mf_fo->opt_rhost;
- fserver *fs;
- int pingval;
- mntent_t mnt;
- nfs_private *np;
- struct hostent *hp = NULL;
- struct sockaddr_in *ip = NULL;
- u_long nfs_version = 0; /* default is no version specified */
- u_long best_nfs_version = 0;
- char *nfs_proto = NULL; /* no IP protocol either */
- int nfs_port = 0;
- int nfs_port_opt = 0;
- int fserver_is_down = 0;
-
- /*
- * Get ping interval from mount options.
- * Current only used to decide whether pings
- * are required or not. < 0 = no pings.
- */
- mnt.mnt_opts = mf->mf_mopts;
- pingval = hasmntval(&mnt, "ping");
-
- if (mf->mf_flags & MFF_NFS_SCALEDOWN) {
- /*
- * the server granted us a filehandle, but we were unable to mount it.
- * therefore, scale down to NFSv2/UDP and try again.
- */
- nfs_version = NFS_VERSION;
- nfs_proto = "udp";
- plog(XLOG_WARNING, "find_nfs_srvr: NFS mount failed, trying again with NFSv2/UDP");
- mf->mf_flags &= ~MFF_NFS_SCALEDOWN;
- } else {
- /*
- * Get the NFS version from the mount options. This is used
- * to decide the highest NFS version to try.
- */
-#ifdef MNTTAB_OPT_VERS
- nfs_version = hasmntval(&mnt, MNTTAB_OPT_VERS);
-#endif /* MNTTAB_OPT_VERS */
-
-#ifdef MNTTAB_OPT_PROTO
- {
- char *proto_opt = hasmnteq(&mnt, MNTTAB_OPT_PROTO);
- if (proto_opt) {
- char **p;
- for (p = protocols; *p; p++)
- if (NSTREQ(proto_opt, *p, strlen(*p))) {
- nfs_proto = *p;
- break;
- }
- if (*p == NULL)
- plog(XLOG_WARNING, "ignoring unknown protocol option for %s:%s",
- host, mf->mf_fo->opt_rfs);
- }
- }
-#endif /* MNTTAB_OPT_PROTO */
-
-#ifdef HAVE_NFS_NFSV2_H
- /* allow overriding if nfsv2 option is specified in mount options */
- if (amu_hasmntopt(&mnt, "nfsv2")) {
- nfs_version = NFS_VERSION;/* nullify any ``vers=X'' statements */
- nfs_proto = "udp"; /* nullify any ``proto=tcp'' statements */
- plog(XLOG_WARNING, "found compatibility option \"nfsv2\": set options vers=2,proto=udp for host %s", host);
- }
-#endif /* HAVE_NFS_NFSV2_H */
-
- /* check if we've globally overridden the NFS version/protocol */
- if (gopt.nfs_vers) {
- nfs_version = gopt.nfs_vers;
- plog(XLOG_INFO, "find_nfs_srvr: force NFS version to %d",
- (int) nfs_version);
- }
- if (gopt.nfs_proto) {
- nfs_proto = gopt.nfs_proto;
- plog(XLOG_INFO, "find_nfs_srvr: force NFS protocol transport to %s", nfs_proto);
- }
- }
-
- /*
- * lookup host address and canonical name
- */
- hp = gethostbyname(host);
-
- /*
- * New code from Bob Harris <harris@basil-rathbone.mit.edu>
- * Use canonical name to keep track of file server
- * information. This way aliases do not generate
- * multiple NFS pingers. (Except when we're normalizing
- * hosts.)
- */
- if (hp && !(gopt.flags & CFM_NORMALIZE_HOSTNAMES))
- host = (char *) hp->h_name;
-
- if (hp) {
- switch (hp->h_addrtype) {
- case AF_INET:
- ip = ALLOC(struct sockaddr_in);
- memset((voidp) ip, 0, sizeof(*ip));
- /* as per POSIX, sin_len need not be set (used internally by kernel) */
- ip->sin_family = AF_INET;
- memmove((voidp) &ip->sin_addr, (voidp) hp->h_addr, sizeof(ip->sin_addr));
- break;
-
- default:
- plog(XLOG_USER, "No IP address for host %s", host);
- goto no_dns;
- }
- } else {
- plog(XLOG_USER, "Unknown host: %s", host);
- goto no_dns;
- }
-
- /*
- * This may not be the best way to do things, but it really doesn't make
- * sense to query a file server which is marked as 'down' for any
- * version/proto combination.
- */
- ITER(fs, fserver, &nfs_srvr_list) {
- if (FSRV_ISDOWN(fs) &&
- STREQ(host, fs->fs_host)) {
- plog(XLOG_WARNING, "fileserver %s is already hung - not running NFS proto/version discovery", host);
- fs->fs_refc++;
- if (ip)
- XFREE(ip);
- return fs;
- }
- }
-
- /*
- * Get the NFS Version, and verify server is up.
- * If the client only supports NFSv2, hardcode it but still try to
- * contact the remote portmapper to see if the service is running.
- */
-#ifndef HAVE_FS_NFS3
- nfs_version = NFS_VERSION;
- nfs_proto = "udp";
- plog(XLOG_INFO, "The client supports only NFS(2,udp)");
-#endif /* not HAVE_FS_NFS3 */
-
-
- if (amu_hasmntopt(&mnt, MNTTAB_OPT_PUBLIC)) {
- /*
- * Use WebNFS to obtain file handles.
- */
- mf->mf_flags |= MFF_WEBNFS;
- plog(XLOG_INFO, "%s option used, NOT contacting the portmapper on %s",
- MNTTAB_OPT_PUBLIC, host);
- /*
- * Prefer NFSv3/tcp if the client supports it (cf. RFC 2054, 7).
- */
- if (!nfs_version) {
-#ifdef HAVE_FS_NFS3
- nfs_version = NFS_VERSION3;
-#else /* not HAVE_FS_NFS3 */
- nfs_version = NFS_VERSION;
-#endif /* not HAVE_FS_NFS3 */
- plog(XLOG_INFO, "No NFS version specified, will use NFSv%d",
- (int) nfs_version);
- }
- if (!nfs_proto) {
-#if defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3)
- nfs_proto = "tcp";
-#else /* not defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) */
- nfs_proto = "udp";
-#endif /* not defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) */
- plog(XLOG_INFO, "No NFS protocol transport specified, will use %s",
- nfs_proto);
- }
- } else {
- /*
- * Find the best combination of NFS version and protocol.
- * When given a choice, use the highest available version,
- * and use TCP over UDP if available.
- */
- if (check_pmap_up(host, ip)) {
- if (nfs_proto) {
- best_nfs_version = get_nfs_version(host, ip, nfs_version, nfs_proto);
- nfs_port = ip->sin_port;
- }
-#ifdef MNTTAB_OPT_PROTO
- else {
- u_int proto_nfs_version;
- char **p;
-
- for (p = protocols; *p; p++) {
- proto_nfs_version = get_nfs_version(host, ip, nfs_version, *p);
-
- if (proto_nfs_version > best_nfs_version) {
- best_nfs_version = proto_nfs_version;
- nfs_proto = *p;
- nfs_port = ip->sin_port;
- }
- }
- }
-#endif /* MNTTAB_OPT_PROTO */
- } else {
- plog(XLOG_INFO, "portmapper service not running on %s", host);
- }
-
- /* use the portmapper results only nfs_version is not set yet */
- if (!best_nfs_version) {
- /*
- * If the NFS server is down or does not support the portmapper call
- * (such as certain Novell NFS servers) we mark it as version 2 and we
- * let the nfs code deal with the case when it is down. If/when the
- * server comes back up and it can support NFSv3 and/or TCP, it will
- * use those.
- */
- if (nfs_version == 0) {
- nfs_version = NFS_VERSION;
- nfs_proto = "udp";
- }
- plog(XLOG_INFO, "NFS service not running on %s", host);
- fserver_is_down = 1;
- } else {
- if (nfs_version == 0)
- nfs_version = best_nfs_version;
- plog(XLOG_INFO, "Using NFS version %d, protocol %s on host %s",
- (int) nfs_version, nfs_proto, host);
- }
- }
-
- /*
- * Determine the NFS port.
- *
- * A valid "port" mount option overrides anything else.
- * If the port has been determined from the portmapper, use that.
- * Default to NFS_PORT otherwise (cf. RFC 2054, 3).
- */
- nfs_port_opt = hasmntval(&mnt, MNTTAB_OPT_PORT);
- if (nfs_port_opt > 0)
- nfs_port = htons(nfs_port_opt);
- if (!nfs_port)
- nfs_port = htons(NFS_PORT);
-
- dlog("find_nfs_srvr: using port %d for nfs on %s",
- (int) ntohs(nfs_port), host);
- ip->sin_port = nfs_port;
-
-no_dns:
- /*
- * Try to find an existing fs server structure for this host.
- * Note that differing versions or protocols have their own structures.
- * XXX: Need to fix the ping mechanism to actually use the NFS protocol
- * chosen here (right now it always uses datagram sockets).
- */
- ITER(fs, fserver, &nfs_srvr_list) {
- if (STREQ(host, fs->fs_host) &&
- nfs_version == fs->fs_version &&
- STREQ(nfs_proto, fs->fs_proto)) {
- /*
- * fill in the IP address -- this is only needed
- * if there is a chance an IP address will change
- * between mounts.
- * Mike Mitchell, mcm@unx.sas.com, 09/08/93
- */
- if (hp && fs->fs_ip &&
- memcmp((voidp) &fs->fs_ip->sin_addr,
- (voidp) hp->h_addr,
- sizeof(fs->fs_ip->sin_addr)) != 0) {
- struct in_addr ia;
- char *old_ipaddr, *new_ipaddr;
- old_ipaddr = strdup(inet_ntoa(fs->fs_ip->sin_addr));
- memmove((voidp) &ia, (voidp) hp->h_addr, sizeof(struct in_addr));
- new_ipaddr = inet_ntoa(ia); /* ntoa uses static buf */
- plog(XLOG_WARNING, "fileserver %s changed ip: %s -> %s",
- fs->fs_host, old_ipaddr, new_ipaddr);
- XFREE(old_ipaddr);
- flush_nfs_fhandle_cache(fs);
- memmove((voidp) &fs->fs_ip->sin_addr, (voidp) hp->h_addr, sizeof(fs->fs_ip->sin_addr));
- }
-
- /*
- * If the new file systems doesn't use WebNFS, the nfs pings may
- * try to contact the portmapper.
- */
- if (!(mf->mf_flags & MFF_WEBNFS))
- fs->fs_flags &= ~FSF_WEBNFS;
-
- /* check if pingval needs to be updated/set/reset */
- start_nfs_pings(fs, pingval);
-
- /*
- * Following if statement from Mike Mitchell <mcm@unx.sas.com>
- * Initialize the ping data if we aren't pinging now. The np_ttl and
- * np_ping fields are especially important.
- */
- if (!(fs->fs_flags & FSF_PINGING)) {
- np = (nfs_private *) fs->fs_private;
- np->np_mountd_inval = TRUE;
- np->np_xid = XID_ALLOC();
- np->np_error = -1;
- np->np_ping = 0;
- /*
- * Initially the server will be deemed dead
- * after MAX_ALLOWED_PINGS of the fast variety
- * have failed.
- */
- np->np_ttl = MAX_ALLOWED_PINGS * FAST_NFS_PING + clocktime(NULL) - 1;
- start_nfs_pings(fs, pingval);
- if (fserver_is_down)
- fs->fs_flags |= FSF_VALID | FSF_DOWN;
- }
-
- fs->fs_refc++;
- if (ip)
- XFREE(ip);
- return fs;
- }
- }
-
- /*
- * Get here if we can't find an entry
- */
-
- /*
- * Allocate a new server
- */
- fs = ALLOC(struct fserver);
- fs->fs_refc = 1;
- fs->fs_host = strdup(hp ? hp->h_name : "unknown_hostname");
- if (gopt.flags & CFM_NORMALIZE_HOSTNAMES)
- host_normalize(&fs->fs_host);
- fs->fs_ip = ip;
- fs->fs_cid = 0;
- if (ip) {
- fs->fs_flags = FSF_DOWN; /* Starts off down */
- } else {
- fs->fs_flags = FSF_ERROR | FSF_VALID;
- mf->mf_flags |= MFF_ERROR;
- mf->mf_error = ENOENT;
- }
- if (mf->mf_flags & MFF_WEBNFS)
- fs->fs_flags |= FSF_WEBNFS;
- fs->fs_version = nfs_version;
- fs->fs_proto = nfs_proto;
- fs->fs_type = MNTTAB_TYPE_NFS;
- fs->fs_pinger = AM_PINGER;
- fs->fs_flags |= FSF_PING_UNINIT; /* pinger hasn't been initialized */
- np = ALLOC(struct nfs_private);
- memset((voidp) np, 0, sizeof(*np));
- np->np_mountd_inval = TRUE;
- np->np_xid = XID_ALLOC();
- np->np_error = -1;
-
- /*
- * Initially the server will be deemed dead after
- * MAX_ALLOWED_PINGS of the fast variety have failed.
- */
- np->np_ttl = clocktime(NULL) + MAX_ALLOWED_PINGS * FAST_NFS_PING - 1;
- fs->fs_private = (voidp) np;
- fs->fs_prfree = (void (*)(voidp)) free;
-
- if (!FSRV_ERROR(fs)) {
- /* start of keepalive timer, first updating pingval */
- start_nfs_pings(fs, pingval);
- if (fserver_is_down)
- fs->fs_flags |= FSF_VALID | FSF_DOWN;
- }
-
- /*
- * Add to list of servers
- */
- ins_que(&fs->fs_q, &nfs_srvr_list);
-
- return fs;
-}