+2005-04-16 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * scripts/amd.conf.5, doc/am-utils.texi (normalize_slashes
+ Parameter), scripts/amd.conf-sample: document new
+ normalize_slashes global configuration parameter.
+
+ * amd/opts.c (deslashify, normalize_slash): don't touch trailing
+ slashes, even if multiples of them, if user said
+ normalize_slashes=no in amd.conf.
+
+ * amd/conf.c (gopt_normalize_slashes): new function to record if
+ to normalize slashes or not.
+
+ * amd/amd.h (CFM_NORMALIZE_SLASHES): new flag to decide if to
+ normalize double-slashes or not ("yes" by default).
+
+ * amd/autil.c (am_mounted): pass TRUE when calling mf_mounted.
+ 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.
+
+ * amd/autil.c (mf_mounted): Be careful when calling free_ops and
+ XFREE here. Some pseudo file systems like nfsx call this
+ function, 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).
+
+ * amd/amd.h: pass flag to mf_mounted, to free or not to free the
+ am_opts.
+
+ * amd/amfs_nfsx.c (amfs_nfsx_cont): call mf_mounted with FALSE to
+ tell it not to free the am_opts, to avoid double free.
+
+ * include/am_defs.h: include limits.h if found.
+
+ * configure.in: check for limits.h. Check for certain Linux
+ headers such as auto_fs.h after checking for limits.h, and include
+ the latter if it exists, because some Linux headers depend on
+ limits.h. This prevents warnings during configure time.
+
+2005-04-12 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * amd/amfs_toplvl.c (amfs_toplvl_mount): do NOT set retrans/timeo
+ values from default global UDP settings, because it can cause
+ unexpected timeouts in Amd on slow systems. The default that each
+ OS provides for these toplvl NFS mounts should be OK, or else you
+ can use the map_options entry.
+
2005-04-09 Daniel P. Ottavio <dottavio@ic.sunysb.edu>
* amd/nfs_subr.c (mp_to_fh): Replace xstrlcpy with memcpy because the
* libamu/util.c (xstrlcpy): Return immediately if len is 0 to
avoid unnecessary work. Log an error and return if len is less
than 0.
-
+
2005-04-07 Erez Zadok <ezk@cs.sunysb.edu>
* include/am_utils.h (XFREE): XFREE() should nullify the pointer
*** Notes specific to am-utils version 6.1-rc2
+New amd.conf global parameter: normalize_slashes (default to "yes"). If set
+to "no," then Amd will not condense repeated slashes or remove trailing ones
+from strings representing pathnames. This is sometimes useful with SMB
+mounts, which often require multiple slash characters in pathnames.
+
Using a custom version of strlcpy instead of strncpy (but only where
it makes sense), to minimize string overlow changes. Audited all use
of strncpy/strlcpy to ensure safety.
- bugs fixed:
* pawd handles all file systems
+ * fix double-free in type:=nfsx
*** Notes specific to am-utils version 6.1-rc1
* SUCH DAMAGE.
*
*
- * $Id: amd.h,v 1.63 2005/03/08 06:05:33 ezk Exp $
+ * $Id: amd.h,v 1.64 2005/04/17 03:05:54 ezk Exp $
*
*/
#define CFM_AUTOFS_USE_LOFS 0x1000
#define CFM_NFS_INSECURE_PORT 0x2000
#define CFM_DOMAIN_STRIP 0x4000
+#define CFM_NORMALIZE_SLASHES 0x8000 /* normalize slashes? */
/* 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)
+#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.
extern am_node *next_nonerror_node(am_node *xp);
extern void flush_srvr_nfs_cache(void);
extern void am_mounted(am_node *);
-extern void mf_mounted(mntfs *mf);
+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);
* SUCH DAMAGE.
*
*
- * $Id: amfs_nfsx.c,v 1.22 2005/01/03 20:56:45 ezk Exp $
+ * $Id: amfs_nfsx.c,v 1.23 2005/04/17 03:05:54 ezk Exp $
*
*/
/*
* The mount worked.
*/
- mf_mounted(n->n_mnt);
+ mf_mounted(n->n_mnt, FALSE); /* FALSE => don't free the n_mnt->am_opts */
n->n_error = 0;
}
break;
if (m->mf_flags & MFF_MOUNTED) {
- mf_mounted(m);
+ mf_mounted(m, FALSE); /* FALSE => don't free the m->am_opts */
n->n_error = glob_error = 0;
continue;
}
* SUCH DAMAGE.
*
*
- * $Id: amfs_toplvl.c,v 1.37 2005/02/17 21:32:05 ezk Exp $
+ * $Id: amfs_toplvl.c,v 1.38 2005/04/17 03:05:54 ezk Exp $
*
*/
strcat(preopts, MNTTAB_OPT_IGNORE);
strcat(preopts, ",");
#endif /* MNTTAB_OPT_IGNORE */
+#ifdef WANT_TIMEO_AND_RETRANS_ON_TOPLVL
sprintf(opts, "%s%s,%s=%d,%s=%d,%s=%d,%s,map=%s",
+#else /* WANT_TIMEO_AND_RETRANS_ON_TOPLVL */
+ sprintf(opts, "%s%s,%s=%d,%s,map=%s",
+#endif /* WANT_TIMEO_AND_RETRANS_ON_TOPLVL */
preopts,
MNTTAB_OPT_RW,
MNTTAB_OPT_PORT, nfs_port,
+#ifdef WANT_TIMEO_AND_RETRANS_ON_TOPLVL
/* note: TIMEO+RETRANS for toplvl are only "udp" currently */
MNTTAB_OPT_TIMEO, gopt.amfs_auto_timeo[AMU_TYPE_UDP],
MNTTAB_OPT_RETRANS, gopt.amfs_auto_retrans[AMU_TYPE_UDP],
+#endif /* WANT_TIMEO_AND_RETRANS_ON_TOPLVL */
mf->mf_ops->fs_type, mf->mf_info);
#ifdef MNTTAB_OPT_NOAC
if (gopt.auto_attrcache == 0) {
* SUCH DAMAGE.
*
*
- * $Id: autil.c,v 1.50 2005/03/05 07:09:17 ezk Exp $
+ * $Id: autil.c,v 1.51 2005/04/17 03:05:54 ezk Exp $
*
*/
void
-mf_mounted(mntfs *mf)
+mf_mounted(mntfs *mf, bool_t call_free_opts)
{
int quoted;
int wasmounted = mf->mf_flags & MFF_MOUNTED;
if (mf->mf_ops->mounted)
mf->mf_ops->mounted(mf);
- free_opts(mf->mf_fo);
- XFREE(mf->mf_fo);
+ /*
+ * 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) {
int notimeout = 0; /* assume normal timeouts initially */
mntfs *mf = mp->am_mnt;
- mf_mounted(mf);
+ /*
+ * 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)
* SUCH DAMAGE.
*
*
- * $Id: conf.c,v 1.31 2005/03/08 06:05:33 ezk Exp $
+ * $Id: conf.c,v 1.32 2005/04/17 03:05:54 ezk Exp $
*
*/
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);
{"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},
}
+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)
{
* SUCH DAMAGE.
*
*
- * $Id: opts.c,v 1.38 2005/04/09 18:15:35 ottavio Exp $
+ * $Id: opts.c,v 1.39 2005/04/17 03:05:54 ezk Exp $
*
*/
void
normalize_slash(char *p)
{
- char *f = strchr(p, '/');
- char *f0 = f;
+ char *f, *f0;
+ if (!(gopt.flags & CFM_NORMALIZE_SLASHES))
+ return;
+
+ f0 = f = strchr(p, '/');
if (f) {
char *t = f;
do {
* 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);
dnl
dnl AC_CONFIG_AUX_DIR(m4)
AC_PREREQ(2.52)
-AC_REVISION($Revision: 1.83 $)
+AC_REVISION($Revision: 1.84 $)
AC_COPYRIGHT([Copyright (c) 1997-2005 Erez Zadok])
dnl find out system type
AC_MSG_NOTICE(*** SYSTEM TYPES ***)
gdbm/ndbm.h \
hsfs/hsfs.h \
isofs/cd9660/cd9660_mount.h \
- linux/auto_fs.h \
- linux/auto_fs4.h \
+ limits.h \
linux/fs.h \
linux/kdev_t.h \
linux/list.h \
- linux/loop.h \
linux/nfs.h \
- linux/nfs_mount.h \
linux/posix_types.h \
machine/endian.h \
msdosfs/msdosfsmount.h \
lber.h \
ldap.h \
libgen.h \
+ limits.h \
malloc.h \
memory.h \
mntent.h \
varargs.h \
unistd.h \
)
-dnl ======================================================================
+dnl headers which depend on others, else you get an configure error
+AC_CHECK_HEADERS([ \
+ linux/auto_fs.h \
+ linux/auto_fs4.h \
+ linux/loop.h \
+ linux/nfs_mount.h \
+], [], [],
+[
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif /* HAVE_SYS_SOCKET_H */
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif /* HAVE_LIMITS_H */
+#ifdef HAVE_LINUX_POSIX_TYPES_H
+# include <linux/posix_types.h>
+#endif /* HAVE_LINUX_POSIX_TYPES_H */
+/* next dev_t lines needed due to changes in kernel code */
+#undef dev_t
+#define dev_t unsigned short /* compatible with Red Hat and SuSE */
+])
dnl ======================================================================
dnl db/ndbm/gdbm: This is serious autoconf-fu...
@c
@c %W% (Berkeley) %G%
@c
-@c $Id: am-utils.texi,v 1.100 2005/03/08 06:05:33 ezk Exp $
+@c $Id: am-utils.texi,v 1.101 2005/04/17 03:05:54 ezk Exp $
@c
@setfilename am-utils.info
* nfs_vers Parameter::
* nis_domain Parameter::
* normalize_hostnames Parameter::
+* normalize_slashes Parameter::
* os Parameter::
* osver Parameter::
* pid_file Parameter::
This option is ignored if NIS support is not available.
@c ----------------------------------------------------------------
-@node normalize_hostnames Parameter, os Parameter, nis_domain Parameter, Global Parameters
+@node normalize_hostnames Parameter, normalize_slashes Parameter, nis_domain Parameter, Global Parameters
@comment node-name, next, previous, up
@subsection @t{normalize_hostnames} Parameter
@cindex normalize_hostnames Parameter
translate aliases into ``official'' names.
@c ----------------------------------------------------------------
-@node os Parameter, osver Parameter, normalize_hostnames Parameter, Global Parameters
+@node normalize_slashes Parameter, os Parameter, normalize_hostnames Parameter, Global Parameters
+@comment node-name, next, previous, up
+@subsection @t{normalize_slashes} Parameter
+@cindex normalize_slashes Parameter
+
+(type=boolean, default=@samp{yes}). If @samp{yes} then amd will
+condense all multiple @code{/} (slash) characters into one and remove
+all trailing slashes. If @samp{no}, then amd will not touch strings
+that may contain repeated or trailing slashes. The latter is
+sometimes useful with SMB mounts, which often require multiple slash
+characters in pathnames.
+
+@c ----------------------------------------------------------------
+@node os Parameter, osver Parameter, normalize_slashes Parameter, Global Parameters
@comment node-name, next, previous, up
@subsection @t{os} Parameter
@cindex os Parameter
* SUCH DAMAGE.
*
*
- * $Id: am_defs.h,v 1.55 2005/04/07 03:50:41 ezk Exp $
+ * $Id: am_defs.h,v 1.56 2005/04/17 03:05:54 ezk Exp $
*
*/
# include <sys/types.h>
#endif /* HAVE_SYS_TYPES_H */
+/*
+ * Actions to take if HAVE_LIMITS_H is defined.
+ */
+#if HAVE_LIMITS_H_H
+# include <limits.h>
+#endif /* HAVE_LIMITS_H */
+
/*
* Actions to take if HAVE_UNISTD_H is defined.
*/
localhost_address = foo.example.com | 192.168.1.2
# number of seconds to timeout before map returns output
exec_map_timeout = 10
+# normalize multiple/trailing slashes or not?
+normalize_slashes = yes | no
##############################################################################
# DEFINE AN AMD MOUNT POINT
.\"
.\" %W% (Berkeley) %G%
.\"
-.\" $Id: amd.conf.5,v 1.36 2005/03/08 06:05:33 ezk Exp $
+.\" $Id: amd.conf.5,v 1.37 2005/04/17 03:05:54 ezk Exp $
.\"
.TH AMD.CONF 5 "7 August 1997"
.SH NAME
normalized relative to the host database before being used. The effect is
to translate aliases into ``official'' names.
+.TP
+.BR normalize_slashes " (boolean, default=yes)"
+
+If "yes," then amd will condense all multiple ``/'' (slash) characters into
+one and remove all trailing slashes. If "no," then amd will not touch
+strings that may contain repeated or trailing slashes. The latter is
+sometimes useful with SMB mounts, which often require multiple slash
+characters in pathnames.
+
.TP
.BR os " (string, default to compiled in value)"
Same as the