From e5fd101c57ad356e7e758c4dc87bcbc33fee9b18 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pawe=C5=82=20Sikora?= Date: Sat, 29 Aug 2009 13:16:27 +0000 Subject: [PATCH] - import latest patchset. Changed files: autofs-5.0.4-add-lsb-init-script-parameter-block.patch -> 1.1 autofs-5.0.4-add-missing-changelog-entries.patch -> 1.1 autofs-5.0.4-add-nfs-mount-proto-default-conf-option.patch -> 1.1 autofs-5.0.4-allow-automount-daemon-to-dump-core.patch -> 1.1 autofs-5.0.4-always-read-file-maps-fix.patch -> 1.1 autofs-5.0.4-always-read-file-maps-key-lookup-fixes.patch -> 1.1 autofs-5.0.4-always-read-file-maps-multi-map-fix.patch -> 1.1 autofs-5.0.4-always-read-file-maps.patch -> 1.1 autofs-5.0.4-another-easy-alloca-replacements-fix.patch -> 1.1 autofs-5.0.4-clear-rpc-client-on-lookup-fail.patch -> 1.1 autofs-5.0.4-code-analysis-corrections.patch -> 1.1 autofs-5.0.4-configure-libtirpc-fix.patch -> 1.1 autofs-5.0.4-configure-libtirpc.patch -> 1.1 autofs-5.0.4-dont-fail-on-ipv6-address-adding-host.patch -> 1.1 autofs-5.0.4-dont-umount-existing-direct-mount-on-reread.patch -> 1.1 autofs-5.0.4-easy-alloca-replacements-fix.patch -> 1.1 autofs-5.0.4-easy-alloca-replacements.patch -> 1.1 autofs-5.0.4-expire-specific-submount-only.patch -> 1.1 autofs-5.0.4-fix-bad-token-declare.patch -> 1.1 autofs-5.0.4-fix-double-free-in-do_sasl_bind.patch -> 1.1 autofs-5.0.4-fix-double-free-in-expire_proc.patch -> 1.1 autofs-5.0.4-fix-dumb-libxml2-check.patch -> 1.1 autofs-5.0.4-fix-hosts-map-use-after-free.patch -> 1.1 autofs-5.0.4-fix-incorrect-dclist-free.patch -> 1.1 autofs-5.0.4-fix-kernel-includes.patch -> 1.1 autofs-5.0.4-fix-ldap-detection.patch -> 1.1 autofs-5.0.4-fix-lsb-init-script-header.patch -> 1.1 autofs-5.0.4-fix-map-type-info-parse-error-update.patch -> 1.1 autofs-5.0.4-fix-map-type-info-parse-error.patch -> 1.1 autofs-5.0.4-fix-memory-leak-reading-ldap-master.patch -> 1.1 autofs-5.0.4-fix-negative-cache-non-existent-key.patch -> 1.1 autofs-5.0.4-fix-notify-mount-message-path.patch -> 1.1 autofs-5.0.4-fix-pthread-push-order-in-expire_proc_direct.patch -> 1.1 autofs-5.0.4-fix-quoted-mess.patch -> 1.1 autofs-5.0.4-fix-restorecon.patch -> 1.1 autofs-5.0.4-fix-return-start-status-on-fail.patch -> 1.1 autofs-5.0.4-fix-rpc-fd-leak.patch -> 1.1 autofs-5.0.4-fix-select-fd-limit.patch -> 1.1 autofs-5.0.4-fix-st_remove_tasks-locking.patch -> 1.1 autofs-5.0.4-force-unlink-umount.patch -> 1.1 autofs-5.0.4-improve-manual-umount-recovery.patch -> 1.1 autofs-5.0.4-ipv6-name-and-address-support.patch -> 1.1 autofs-5.0.4-ipv6-parse.patch -> 1.1 autofs-5.0.4-library-reload-fix-update-fix-2.patch -> 1.1 autofs-5.0.4-library-reload-fix-update-fix.patch -> 1.1 autofs-5.0.4-library-reload-fix-update.patch -> 1.1 autofs-5.0.4-libxml2-workaround-fix.patch -> 1.1 autofs-5.0.4-make-MAX_ERR_BUF-and-PARSE_MAX_BUF-use-easier-to-audit.patch -> 1.1 autofs-5.0.4-make-hash-table-scale-to-thousands-of-entries.patch -> 1.1 autofs-5.0.4-manual-umount-recovery-fixes.patch -> 1.1 autofs-5.0.4-remount-we-created-mount-point-fix.patch -> 1.1 autofs-5.0.4-renew-sasl-creds-upon-reconnect-fail.patch -> 1.1 autofs-5.0.4-reset-flex-scanner-when-setting-buffer.patch -> 1.1 autofs-5.0.4-srv-lookup-handle-endian.patch -> 1.1 autofs-5.0.4-uris-list-locking-fix.patch -> 1.1 autofs-5.0.4-use-CLOEXEC-flag-setmntent-include-fix.patch -> 1.1 autofs-5.0.4-use-CLOEXEC-flag-setmntent.patch -> 1.1 autofs-5.0.4-use-CLOEXEC-flag.patch -> 1.1 autofs-5.0.4-use-intr-as-hosts-mount-default.patch -> 1.1 autofs-5.0.4-use-misc-device.patch -> 1.1 autofs-5.0.4-use-percent-hack-for-master.patch -> 1.1 autofs-5.0.4-use-srv-query-for-domain-dn.patch -> 1.1 autofs-5.0.4-zero-s_magic-is-valid.patch -> 1.1 --- ...-add-lsb-init-script-parameter-block.patch | 69 + ...-5.0.4-add-missing-changelog-entries.patch | 27 + ...-nfs-mount-proto-default-conf-option.patch | 181 + ...-allow-automount-daemon-to-dump-core.patch | 83 + autofs-5.0.4-always-read-file-maps-fix.patch | 61 + ...ways-read-file-maps-key-lookup-fixes.patch | 65 + ...-always-read-file-maps-multi-map-fix.patch | 132 + autofs-5.0.4-always-read-file-maps.patch | 226 + ...another-easy-alloca-replacements-fix.patch | 36 + ....0.4-clear-rpc-client-on-lookup-fail.patch | 47 + autofs-5.0.4-code-analysis-corrections.patch | 552 ++ autofs-5.0.4-configure-libtirpc-fix.patch | 5422 +++++++++++++++++ autofs-5.0.4-configure-libtirpc.patch | 1835 ++++++ ...ont-fail-on-ipv6-address-adding-host.patch | 68 + ...ount-existing-direct-mount-on-reread.patch | 368 ++ ...s-5.0.4-easy-alloca-replacements-fix.patch | 191 + autofs-5.0.4-easy-alloca-replacements.patch | 1156 ++++ ...-5.0.4-expire-specific-submount-only.patch | 94 + autofs-5.0.4-fix-bad-token-declare.patch | 39 + ....0.4-fix-double-free-in-do_sasl_bind.patch | 42 + ...5.0.4-fix-double-free-in-expire_proc.patch | 38 + autofs-5.0.4-fix-dumb-libxml2-check.patch | 87 + ...s-5.0.4-fix-hosts-map-use-after-free.patch | 52 + autofs-5.0.4-fix-incorrect-dclist-free.patch | 39 + autofs-5.0.4-fix-kernel-includes.patch | 103 + autofs-5.0.4-fix-ldap-detection.patch | 115 + autofs-5.0.4-fix-lsb-init-script-header.patch | 57 + ...fix-map-type-info-parse-error-update.patch | 165 + ...-5.0.4-fix-map-type-info-parse-error.patch | 51 + ...-fix-memory-leak-reading-ldap-master.patch | 38 + ...-fix-negative-cache-non-existent-key.patch | 331 + ...-5.0.4-fix-notify-mount-message-path.patch | 61 + ...ead-push-order-in-expire_proc_direct.patch | 40 + autofs-5.0.4-fix-quoted-mess.patch | 38 + autofs-5.0.4-fix-restorecon.patch | 51 + ....0.4-fix-return-start-status-on-fail.patch | 157 + autofs-5.0.4-fix-rpc-fd-leak.patch | 47 + autofs-5.0.4-fix-select-fd-limit.patch | 275 + ...fs-5.0.4-fix-st_remove_tasks-locking.patch | 60 + autofs-5.0.4-force-unlink-umount.patch | 235 + ...5.0.4-improve-manual-umount-recovery.patch | 161 + ...-5.0.4-ipv6-name-and-address-support.patch | 1016 +++ autofs-5.0.4-ipv6-parse.patch | 467 ++ ....0.4-library-reload-fix-update-fix-2.patch | 53 + ...-5.0.4-library-reload-fix-update-fix.patch | 82 + autofs-5.0.4-library-reload-fix-update.patch | 352 ++ autofs-5.0.4-libxml2-workaround-fix.patch | 38 + ...nd-PARSE_MAX_BUF-use-easier-to-audit.patch | 222 + ...-table-scale-to-thousands-of-entries.patch | 294 + ...s-5.0.4-manual-umount-recovery-fixes.patch | 100 + ...4-remount-we-created-mount-point-fix.patch | 55 + ...renew-sasl-creds-upon-reconnect-fail.patch | 61 + ...set-flex-scanner-when-setting-buffer.patch | 59 + autofs-5.0.4-srv-lookup-handle-endian.patch | 37 + autofs-5.0.4-uris-list-locking-fix.patch | 224 + ...e-CLOEXEC-flag-setmntent-include-fix.patch | 49 + autofs-5.0.4-use-CLOEXEC-flag-setmntent.patch | 96 + autofs-5.0.4-use-CLOEXEC-flag.patch | 1191 ++++ ....0.4-use-intr-as-hosts-mount-default.patch | 82 + autofs-5.0.4-use-misc-device.patch | 52 + ...fs-5.0.4-use-percent-hack-for-master.patch | 136 + ...fs-5.0.4-use-srv-query-for-domain-dn.patch | 1097 ++++ autofs-5.0.4-zero-s_magic-is-valid.patch | 47 + 63 files changed, 18705 insertions(+) create mode 100644 autofs-5.0.4-add-lsb-init-script-parameter-block.patch create mode 100644 autofs-5.0.4-add-missing-changelog-entries.patch create mode 100644 autofs-5.0.4-add-nfs-mount-proto-default-conf-option.patch create mode 100644 autofs-5.0.4-allow-automount-daemon-to-dump-core.patch create mode 100644 autofs-5.0.4-always-read-file-maps-fix.patch create mode 100644 autofs-5.0.4-always-read-file-maps-key-lookup-fixes.patch create mode 100644 autofs-5.0.4-always-read-file-maps-multi-map-fix.patch create mode 100644 autofs-5.0.4-always-read-file-maps.patch create mode 100644 autofs-5.0.4-another-easy-alloca-replacements-fix.patch create mode 100644 autofs-5.0.4-clear-rpc-client-on-lookup-fail.patch create mode 100644 autofs-5.0.4-code-analysis-corrections.patch create mode 100644 autofs-5.0.4-configure-libtirpc-fix.patch create mode 100644 autofs-5.0.4-configure-libtirpc.patch create mode 100644 autofs-5.0.4-dont-fail-on-ipv6-address-adding-host.patch create mode 100644 autofs-5.0.4-dont-umount-existing-direct-mount-on-reread.patch create mode 100644 autofs-5.0.4-easy-alloca-replacements-fix.patch create mode 100644 autofs-5.0.4-easy-alloca-replacements.patch create mode 100644 autofs-5.0.4-expire-specific-submount-only.patch create mode 100644 autofs-5.0.4-fix-bad-token-declare.patch create mode 100644 autofs-5.0.4-fix-double-free-in-do_sasl_bind.patch create mode 100644 autofs-5.0.4-fix-double-free-in-expire_proc.patch create mode 100644 autofs-5.0.4-fix-dumb-libxml2-check.patch create mode 100644 autofs-5.0.4-fix-hosts-map-use-after-free.patch create mode 100644 autofs-5.0.4-fix-incorrect-dclist-free.patch create mode 100644 autofs-5.0.4-fix-kernel-includes.patch create mode 100644 autofs-5.0.4-fix-ldap-detection.patch create mode 100644 autofs-5.0.4-fix-lsb-init-script-header.patch create mode 100644 autofs-5.0.4-fix-map-type-info-parse-error-update.patch create mode 100644 autofs-5.0.4-fix-map-type-info-parse-error.patch create mode 100644 autofs-5.0.4-fix-memory-leak-reading-ldap-master.patch create mode 100644 autofs-5.0.4-fix-negative-cache-non-existent-key.patch create mode 100644 autofs-5.0.4-fix-notify-mount-message-path.patch create mode 100644 autofs-5.0.4-fix-pthread-push-order-in-expire_proc_direct.patch create mode 100644 autofs-5.0.4-fix-quoted-mess.patch create mode 100644 autofs-5.0.4-fix-restorecon.patch create mode 100644 autofs-5.0.4-fix-return-start-status-on-fail.patch create mode 100644 autofs-5.0.4-fix-rpc-fd-leak.patch create mode 100644 autofs-5.0.4-fix-select-fd-limit.patch create mode 100644 autofs-5.0.4-fix-st_remove_tasks-locking.patch create mode 100644 autofs-5.0.4-force-unlink-umount.patch create mode 100644 autofs-5.0.4-improve-manual-umount-recovery.patch create mode 100644 autofs-5.0.4-ipv6-name-and-address-support.patch create mode 100644 autofs-5.0.4-ipv6-parse.patch create mode 100644 autofs-5.0.4-library-reload-fix-update-fix-2.patch create mode 100644 autofs-5.0.4-library-reload-fix-update-fix.patch create mode 100644 autofs-5.0.4-library-reload-fix-update.patch create mode 100644 autofs-5.0.4-libxml2-workaround-fix.patch create mode 100644 autofs-5.0.4-make-MAX_ERR_BUF-and-PARSE_MAX_BUF-use-easier-to-audit.patch create mode 100644 autofs-5.0.4-make-hash-table-scale-to-thousands-of-entries.patch create mode 100644 autofs-5.0.4-manual-umount-recovery-fixes.patch create mode 100644 autofs-5.0.4-remount-we-created-mount-point-fix.patch create mode 100644 autofs-5.0.4-renew-sasl-creds-upon-reconnect-fail.patch create mode 100644 autofs-5.0.4-reset-flex-scanner-when-setting-buffer.patch create mode 100644 autofs-5.0.4-srv-lookup-handle-endian.patch create mode 100644 autofs-5.0.4-uris-list-locking-fix.patch create mode 100644 autofs-5.0.4-use-CLOEXEC-flag-setmntent-include-fix.patch create mode 100644 autofs-5.0.4-use-CLOEXEC-flag-setmntent.patch create mode 100644 autofs-5.0.4-use-CLOEXEC-flag.patch create mode 100644 autofs-5.0.4-use-intr-as-hosts-mount-default.patch create mode 100644 autofs-5.0.4-use-misc-device.patch create mode 100644 autofs-5.0.4-use-percent-hack-for-master.patch create mode 100644 autofs-5.0.4-use-srv-query-for-domain-dn.patch create mode 100644 autofs-5.0.4-zero-s_magic-is-valid.patch diff --git a/autofs-5.0.4-add-lsb-init-script-parameter-block.patch b/autofs-5.0.4-add-lsb-init-script-parameter-block.patch new file mode 100644 index 0000000..7b7aa0e --- /dev/null +++ b/autofs-5.0.4-add-lsb-init-script-parameter-block.patch @@ -0,0 +1,69 @@ +autofs-5.0.4 - add lsb init script parameter block + +From: Ian Kent + + +--- + + CHANGELOG | 1 + + redhat/autofs.init.in | 11 ++++++++++- + samples/rc.autofs.in | 11 ++++++++++- + 3 files changed, 21 insertions(+), 2 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 4df6a60..aab3209 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -30,6 +30,7 @@ + - fix return start status on fail. + - fix double free in expire_proc(). + - another easy alloca replacements fix. ++- add LSB init script parameter block. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in +index 471667e..0fd1777 100644 +--- a/redhat/autofs.init.in ++++ b/redhat/autofs.init.in +@@ -6,7 +6,16 @@ + # processname: /usr/sbin/automount + # config: /etc/auto.master + # description: Automounts filesystems on demand +- ++# ++### BEGIN INIT INFO ++# Provides: $autofs ++# Should-Start: $network $ypbind ++# Should-Stop: $network $ypbind ++# Default-Start: 3 4 5 ++# Default-Stop: 0 1 2 6 ++# Short-Description: Automounts filesystems on demand ++# Description: Automounts filesystems on demand ++### END INIT INFO + # + # Location of the automount daemon and the init directory + # +diff --git a/samples/rc.autofs.in b/samples/rc.autofs.in +index 2877fe2..63a0c5d 100644 +--- a/samples/rc.autofs.in ++++ b/samples/rc.autofs.in +@@ -5,7 +5,16 @@ + # On most distributions, this file should be called: + # /etc/rc.d/init.d/autofs or /etc/init.d/autofs or /etc/rc.d/rc.autofs + # +- ++# ++### BEGIN INIT INFO ++# Provides: $autofs ++# Should-Start: $network $ypbind ++# Should-Stop: $network $ypbind ++# Default-Start: 3 4 5 ++# Default-Stop: 0 1 2 6 ++# Short-Description: Automounts filesystems on demand ++# Description: Automounts filesystems on demand ++### END INIT INFO + # + # Location of the automount daemon and the init directory + # diff --git a/autofs-5.0.4-add-missing-changelog-entries.patch b/autofs-5.0.4-add-missing-changelog-entries.patch new file mode 100644 index 0000000..545358a --- /dev/null +++ b/autofs-5.0.4-add-missing-changelog-entries.patch @@ -0,0 +1,27 @@ +autofs-5.0.4 - add missing changelog entries + +From: Ian Kent + +Add changelog entries inadvertantly missed in last commit. +--- + + CHANGELOG | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 417a001..3ff3daa 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -16,6 +16,11 @@ + use of 5.0.3 strartup behavior if required. + - always read entire file map into cache to speed lookups. + - make MAX_ERR_BUF and PARSE_MAX_BUF use easier to audit. ++- make some easy alloca replacements (Valerie Aurora Henson). ++- update to configure libtirpc if present. ++- update to provide ipv6 name and address support. ++- update to provide ipv6 address parsing. ++ + + 4/11/2008 autofs-5.0.4 + ----------------------- diff --git a/autofs-5.0.4-add-nfs-mount-proto-default-conf-option.patch b/autofs-5.0.4-add-nfs-mount-proto-default-conf-option.patch new file mode 100644 index 0000000..3a5d46c --- /dev/null +++ b/autofs-5.0.4-add-nfs-mount-proto-default-conf-option.patch @@ -0,0 +1,181 @@ +autofs-5.0.4 - add nfs mount protocol default configuration option + +From: Ian Kent + +Add configuration option MOUNT_NFS_DEFAULT_PROTOCOL with default of 3. +Since the default mount protocol used by mount.nfs(8) will change to +NFS version 4 at some point, and because we can't identify the default +automatically, we need to be able to set it in our configuration. +This will only make a difference for replicated map entries as +availability probing isn't used for single host map entries. +--- + + CHANGELOG | 1 + + include/defaults.h | 2 ++ + lib/defaults.c | 15 ++++++++++++++- + man/auto.master.5.in | 6 ++++++ + modules/mount_nfs.c | 8 +++++--- + redhat/autofs.sysconfig.in | 10 ++++++++++ + samples/autofs.conf.default.in | 10 ++++++++++ + 7 files changed, 48 insertions(+), 4 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index ad74b7d..0ce2a56 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -25,6 +25,7 @@ + - add check for alternate libtirpc library for libtirpc tsd workaround. + - cleanup configure defines for libtirpc. + - add WITH_LIBTIRPC to -V status report. ++- add nfs mount protocol default configuration option. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/include/defaults.h b/include/defaults.h +index 9a2430f..9bf16e5 100644 +--- a/include/defaults.h ++++ b/include/defaults.h +@@ -37,6 +37,7 @@ + #define DEFAULT_ENTRY_ATTR "cn" + #define DEFAULT_VALUE_ATTR "nisMapEntry" + ++#define DEFAULT_NFS_MOUNT_PROTOCOL 3 + #define DEFAULT_APPEND_OPTIONS 1 + #define DEFAULT_AUTH_CONF_FILE AUTOFS_MAP_DIR "/autofs_ldap_auth.conf" + +@@ -61,6 +62,7 @@ struct ldap_schema *defaults_get_default_schema(void); + struct ldap_schema *defaults_get_schema(void); + struct ldap_searchdn *defaults_get_searchdns(void); + void defaults_free_searchdns(struct ldap_searchdn *); ++unsigned int defaults_get_mount_nfs_default_proto(void); + unsigned int defaults_get_append_options(void); + unsigned int defaults_get_umount_wait(void); + const char *defaults_get_auth_conf_file(void); +diff --git a/lib/defaults.c b/lib/defaults.c +index e507a59..17164bd 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -45,6 +45,7 @@ + #define ENV_NAME_ENTRY_ATTR "ENTRY_ATTRIBUTE" + #define ENV_NAME_VALUE_ATTR "VALUE_ATTRIBUTE" + ++#define ENV_MOUNT_NFS_DEFAULT_PROTOCOL "MOUNT_NFS_DEFAULT_PROTOCOL" + #define ENV_APPEND_OPTIONS "APPEND_OPTIONS" + #define ENV_UMOUNT_WAIT "UMOUNT_WAIT" + #define ENV_AUTH_CONF_FILE "AUTH_CONF_FILE" +@@ -326,7 +327,8 @@ unsigned int defaults_read_config(unsigned int to_syslog) + check_set_config_value(key, ENV_APPEND_OPTIONS, value, to_syslog) || + check_set_config_value(key, ENV_UMOUNT_WAIT, value, to_syslog) || + check_set_config_value(key, ENV_AUTH_CONF_FILE, value, to_syslog) || +- check_set_config_value(key, ENV_MAP_HASH_TABLE_SIZE, value, to_syslog)) ++ check_set_config_value(key, ENV_MAP_HASH_TABLE_SIZE, value, to_syslog) || ++ check_set_config_value(key, ENV_MOUNT_NFS_DEFAULT_PROTOCOL, value, to_syslog)) + ; + } + +@@ -643,6 +645,17 @@ struct ldap_schema *defaults_get_schema(void) + return schema; + } + ++unsigned int defaults_get_mount_nfs_default_proto(void) ++{ ++ long proto; ++ ++ proto = get_env_number(ENV_MOUNT_NFS_DEFAULT_PROTOCOL); ++ if (proto < 2 || proto > 4) ++ proto = DEFAULT_NFS_MOUNT_PROTOCOL; ++ ++ return (unsigned int) proto; ++} ++ + unsigned int defaults_get_append_options(void) + { + int res; +diff --git a/man/auto.master.5.in b/man/auto.master.5.in +index 9cc5f02..aaa6324 100644 +--- a/man/auto.master.5.in ++++ b/man/auto.master.5.in +@@ -183,6 +183,12 @@ but it is the best we can do. + .B BROWSE_MODE + Maps are browsable by default (program default "yes"). + .TP ++.B MOUNT_NFS_DEFAULT_PROTOCOL ++Specify the default protocol used by mount.nfs(8) (program default 3). Since ++we can't identify this default automatically we need to set it in the autofs ++configuration. This option will only make a difference for replicated map ++entries as availability probing isn't used for single host map entries. ++.TP + .B APPEND_OPTIONS + Determine whether global options, given on the command line or per mount + in the master map, are appended to map entry options or if the map entry +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 4f3f514..14d3850 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -61,7 +61,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + char fullpath[PATH_MAX]; + char buf[MAX_ERR_BUF]; + struct host *this, *hosts = NULL; +- unsigned int vers; ++ unsigned int mount_default_proto, vers; + char *nfsoptions = NULL; + unsigned int random_selection = ap->flags & MOUNT_FLAG_RANDOM_SELECT; + int len, status, err, existed = 1; +@@ -130,10 +130,12 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + nfsoptions, nosymlink, ro); + } + ++ mount_default_proto = defaults_get_mount_nfs_default_proto(); ++ vers = NFS_VERS_MASK | NFS_PROTO_MASK; + if (strcmp(fstype, "nfs4") == 0) + vers = NFS4_VERS_MASK | TCP_SUPPORTED; +- else +- vers = NFS_VERS_MASK | NFS_PROTO_MASK; ++ else if (mount_default_proto == 4) ++ vers = vers | NFS4_VERS_MASK; + + if (!parse_location(ap->logopt, &hosts, what)) { + info(ap->logopt, MODPREFIX "no hosts available"); +diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in +index fe36f45..04e521c 100644 +--- a/redhat/autofs.sysconfig.in ++++ b/redhat/autofs.sysconfig.in +@@ -22,6 +22,16 @@ TIMEOUT=300 + # + BROWSE_MODE="no" + # ++# MOUNT_NFS_DEFAULT_PROTOCOL - specify the default protocol used by ++# mount.nfs(8). Since we can't identify ++# the default automatically we need to ++# set it in our configuration. This will ++# only make a difference for replicated ++# map entries as availability probing isn't ++# used for single host map entries. ++# ++#MOUNT_NFS_DEFAULT_PROTOCOL=3 ++# + # APPEND_OPTIONS - append to global options instead of replace. + # + #APPEND_OPTIONS="yes" +diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in +index 4496738..52d18ec 100644 +--- a/samples/autofs.conf.default.in ++++ b/samples/autofs.conf.default.in +@@ -22,6 +22,16 @@ TIMEOUT=300 + # + BROWSE_MODE="no" + # ++# MOUNT_NFS_DEFAULT_PROTOCOL - specify the default protocol used by ++# mount.nfs(8). Since we can't identify ++# the default automatically we need to ++# set it in our configuration. This will ++# only make a difference for replicated ++# map entries as availability probing isn't ++# used for single host map entries. ++# ++#MOUNT_NFS_DEFAULT_PROTOCOL=3 ++# + # APPEND_OPTIONS - append to global options instead of replace. + # + #APPEND_OPTIONS="yes" diff --git a/autofs-5.0.4-allow-automount-daemon-to-dump-core.patch b/autofs-5.0.4-allow-automount-daemon-to-dump-core.patch new file mode 100644 index 0000000..2542621 --- /dev/null +++ b/autofs-5.0.4-allow-automount-daemon-to-dump-core.patch @@ -0,0 +1,83 @@ +autofs-5.0.4 - allow the automount daemon to dump core + +From: Jeff Moyer + +Right now, the automount daemon blocks all signals. We should at least +unblock those that will cause us to dump core. Otherwise, I think the +behaviour could be, umm, interesting. + +I tested this by sending SIGBUS and SIGSEGV to the automount daemon. + +edit - raven +- I changed this a little so that the change to the signals is + done in one place and added SIGABRT and SIGTRAP to the list + of signals that aren't blocked. + +Signed-off-by: Jeff Moyer +--- + + CHANGELOG | 1 + + daemon/automount.c | 16 ++++++++++++---- + 2 files changed, 13 insertions(+), 4 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 7f27f5e..4b85649 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -57,6 +57,7 @@ + - mannual umount recovery fixes. + - fix map type info parse error. + - fix an RPC fd leak. ++- don't block signals we expect to dump core. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/automount.c b/daemon/automount.c +index 44dcdd6..e7f801b 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -64,6 +64,8 @@ static int st_stat = 1; + static int *pst_stat = &st_stat; + static pthread_t state_mach_thid; + ++static sigset_t block_sigs; ++ + /* Pre-calculated kernel packet length */ + static size_t kpkt_len; + +@@ -1321,7 +1323,7 @@ static void *statemachine(void *arg) + sigset_t signalset; + int sig; + +- sigfillset(&signalset); ++ memcpy(&signalset, &block_sigs, sizeof(signalset)); + sigdelset(&signalset, SIGCHLD); + sigdelset(&signalset, SIGCONT); + +@@ -1817,7 +1819,6 @@ int main(int argc, char *argv[]) + unsigned foreground, have_global_options; + time_t timeout; + time_t age = time(NULL); +- sigset_t allsigs; + struct rlimit rlim; + static const struct option long_options[] = { + {"help", 0, 0, 'h'}, +@@ -1837,8 +1838,15 @@ int main(int argc, char *argv[]) + {0, 0, 0, 0} + }; + +- sigfillset(&allsigs); +- sigprocmask(SIG_BLOCK, &allsigs, NULL); ++ sigfillset(&block_sigs); ++ /* allow for the dropping of core files */ ++ sigdelset(&block_sigs, SIGABRT); ++ sigdelset(&block_sigs, SIGBUS); ++ sigdelset(&block_sigs, SIGSEGV); ++ sigdelset(&block_sigs, SIGILL); ++ sigdelset(&block_sigs, SIGFPE); ++ sigdelset(&block_sigs, SIGTRAP); ++ sigprocmask(SIG_BLOCK, &block_sigs, NULL); + + program = argv[0]; + diff --git a/autofs-5.0.4-always-read-file-maps-fix.patch b/autofs-5.0.4-always-read-file-maps-fix.patch new file mode 100644 index 0000000..5706d94 --- /dev/null +++ b/autofs-5.0.4-always-read-file-maps-fix.patch @@ -0,0 +1,61 @@ +autofs-5.0.4 - always read file maps fix + +From: Ian Kent + +If map instances are present for a map source then either we have +plus included entries or we are looking through a list of nsswitch +sources. In either case we cannot avoid reading through the map +because we must preserve the key lookup order over multiple sources. +But also, we can't know if a source instance has been changed since +the last time we checked it until we preform a lookup against it. +So, in this case a lookup within the internal cache cannot be relied +upon to find the key we're looking for. At least, when we get to the +file source instance itself, the lookup for the key will be done from +the cache. +--- + + CHANGELOG | 1 + + modules/lookup_file.c | 17 ++++++++++++++--- + 2 files changed, 15 insertions(+), 3 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index aab3209..da7ecbf 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -31,6 +31,7 @@ + - fix double free in expire_proc(). + - another easy alloca replacements fix. + - add LSB init script parameter block. ++- fix file map lookup when reading included or nsswitch sources. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index ec78090..bd30bc5 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -998,9 +998,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + cache_readlock(mc); + me = cache_lookup_first(mc); +- if (me && st.st_mtime <= me->age) +- goto do_cache_lookup; +- else ++ if (me && st.st_mtime <= me->age) { ++ /* ++ * If any map instances are present for this source ++ * then either we have plus included entries or we ++ * are looking through the list of nsswitch sources. ++ * In either case we cannot avoid reading through the ++ * map because we must preserve the key order over ++ * multiple sources. But also, we can't know, at this ++ * point, if a source instance has been changed since ++ * the last time we checked it. ++ */ ++ if (!source->instance) ++ goto do_cache_lookup; ++ } else + source->stale = 1; + + me = cache_lookup_distinct(mc, key); diff --git a/autofs-5.0.4-always-read-file-maps-key-lookup-fixes.patch b/autofs-5.0.4-always-read-file-maps-key-lookup-fixes.patch new file mode 100644 index 0000000..17db1dc --- /dev/null +++ b/autofs-5.0.4-always-read-file-maps-key-lookup-fixes.patch @@ -0,0 +1,65 @@ +autofs-5.0.4 - always read file maps key lookup fixes + +From: Ian Kent + +Since we always read file maps at start we need to ensure that +we return a not found if the key isn't found in the cache. Also, +if we're looking through a "multi" map we can't use the cache +lookup optimisation because, in this case, there is a single map +source shared by the "multi" maps so we may not get correct results +from the lookup if a map later in the search has been modified. +--- + + CHANGELOG | 1 + + modules/lookup_file.c | 17 +++++++++++------ + 2 files changed, 12 insertions(+), 6 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 972ef63..5000f0c 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -48,6 +48,7 @@ + - improve manual umount recovery. + - dont fail on ipv6 address when adding host. + - always read file maps multi map fix. ++- always read file maps key lookup fixes. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index bd30bc5..a4ca39d 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -1003,13 +1003,15 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + * If any map instances are present for this source + * then either we have plus included entries or we + * are looking through the list of nsswitch sources. +- * In either case we cannot avoid reading through the +- * map because we must preserve the key order over +- * multiple sources. But also, we can't know, at this +- * point, if a source instance has been changed since +- * the last time we checked it. ++ * In either case, or if it's a "multi" source, we ++ * cannot avoid reading through the map because we ++ * must preserve the key order over multiple sources ++ * or maps. But also, we can't know, at this point, ++ * if a source instance has been changed since the ++ * last time we checked it. + */ +- if (!source->instance) ++ if (!source->instance && ++ source->type && strcmp(source->type, "multi")) + goto do_cache_lookup; + } else + source->stale = 1; +@@ -1055,6 +1057,9 @@ do_cache_lookup: + } + cache_unlock(mc); + ++ if (!me) ++ return NSS_STATUS_NOTFOUND; ++ + if (!mapent) + return NSS_STATUS_TRYAGAIN; + diff --git a/autofs-5.0.4-always-read-file-maps-multi-map-fix.patch b/autofs-5.0.4-always-read-file-maps-multi-map-fix.patch new file mode 100644 index 0000000..bfa8b8b --- /dev/null +++ b/autofs-5.0.4-always-read-file-maps-multi-map-fix.patch @@ -0,0 +1,132 @@ +autofs-5.0.4 - always read file maps multi map fix + +From: Ian Kent + +Since "multi" map entries may contain file maps themselves and we +always want to read file maps we need to move the chack of whether +to read the map from lookup_nss_read_map() into the individual +map type lookup modules. +--- + + CHANGELOG | 1 + + daemon/lookup.c | 14 -------------- + modules/lookup_hosts.c | 8 ++++++++ + modules/lookup_ldap.c | 8 ++++++++ + modules/lookup_nisplus.c | 8 ++++++++ + modules/lookup_yp.c | 8 ++++++++ + 6 files changed, 33 insertions(+), 14 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 7e1012f..972ef63 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -47,6 +47,7 @@ + - fix incorrect shutdown introduced by library relaod fixes. + - improve manual umount recovery. + - dont fail on ipv6 address when adding host. ++- always read file maps multi map fix. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/lookup.c b/daemon/lookup.c +index bc94655..9d5a5c8 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -278,20 +278,6 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a + map->lookup = lookup; + master_source_unlock(ap->entry); + +- /* If we don't need to create directories then there's no use +- * reading the map. We just need to test that the map is valid +- * for the fail cases to function correctly and to cache the +- * lookup handle. +- * +- * We always need to read the whole map for direct mounts in +- * order to mount the triggers. We also want to read the whole +- * map if it's a file map to avoid potentially lengthy linear +- * file scanning. +- */ +- if (strcmp(map->type, "file") && +- !(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) +- return NSS_STATUS_SUCCESS; +- + if (!map->stale) + return NSS_STATUS_SUCCESS; + +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index d3ae0e2..a213780 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -89,6 +89,14 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + ap->entry->current = NULL; + master_source_current_signal(ap->entry); + ++ /* ++ * If we don't need to create directories then there's no use ++ * reading the map. We always need to read the whole map for ++ * direct mounts in order to mount the triggers. ++ */ ++ if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) ++ return NSS_STATUS_SUCCESS; ++ + mc = source->mc; + + status = pthread_mutex_lock(&hostent_mutex); +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 8c6a8f2..a847622 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -2236,6 +2236,14 @@ static int read_one_map(struct autofs_point *ap, + ap->entry->current = NULL; + master_source_current_signal(ap->entry); + ++ /* ++ * If we don't need to create directories then there's no use ++ * reading the map. We always need to read the whole map for ++ * direct mounts in order to mount the triggers. ++ */ ++ if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) ++ return NSS_STATUS_SUCCESS; ++ + sp.ap = ap; + sp.age = age; + +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index 0c75905..ae53481 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -180,6 +180,14 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + ap->entry->current = NULL; + master_source_current_signal(ap->entry); + ++ /* ++ * If we don't need to create directories then there's no use ++ * reading the map. We always need to read the whole map for ++ * direct mounts in order to mount the triggers. ++ */ ++ if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) ++ return NSS_STATUS_SUCCESS; ++ + mc = source->mc; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index ce438e8..208f95e 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -322,6 +322,14 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + ap->entry->current = NULL; + master_source_current_signal(ap->entry); + ++ /* ++ * If we don't need to create directories then there's no use ++ * reading the map. We always need to read the whole map for ++ * direct mounts in order to mount the triggers. ++ */ ++ if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) ++ return NSS_STATUS_SUCCESS; ++ + ypcb_data.ap = ap; + ypcb_data.source = source; + ypcb_data.logopt = logopt; diff --git a/autofs-5.0.4-always-read-file-maps.patch b/autofs-5.0.4-always-read-file-maps.patch new file mode 100644 index 0000000..651fb76 --- /dev/null +++ b/autofs-5.0.4-always-read-file-maps.patch @@ -0,0 +1,226 @@ +autofs-5.0.4 - always read file maps + +From: Ian Kent + +autofs tries to not load an entire map into the internal cache unless it +has to. For maps that do get loaded into the cache it relies on checks to +work out if a map is up to date in order to trigger a map read. This is +fine for maps that can do direct key lookups but file maps need to do a +linear search through the file when locating an entry for a key. For large +maps this can be a huge overhead. This patch make autofs always load file +based maps at start and makes use of the map file mtime to discover if the +cache needs to be refreshed. +--- + + CHANGELOG | 1 + + daemon/lookup.c | 9 +++++-- + modules/lookup_file.c | 65 ++++++++++++++++--------------------------------- + 3 files changed, 28 insertions(+), 47 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index d4dd70b..afd1335 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -14,6 +14,7 @@ + - check for stale SASL credentials upon connect fail. + - add "forcestart" and "forcerestart" init script options to allow + use of 5.0.3 strartup behavior if required. ++- always read entire file map into cache to speed lookups. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 741d846..e034348 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -283,10 +283,13 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a + * for the fail cases to function correctly and to cache the + * lookup handle. + * +- * We always need to whole map for direct mounts in order to +- * mount the triggers. ++ * We always need to read the whole map for direct mounts in ++ * order to mount the triggers. We also want to read the whole ++ * map if it's a file map to avoid potentially lengthy linear ++ * file scanning. + */ +- if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) ++ if (strcmp(map->type, "file") && ++ !(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) + return NSS_STATUS_SUCCESS; + + if (!map->stale) +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index 95b9f6f..aafeb8b 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -44,7 +44,6 @@ typedef enum { esc_none, esc_char, esc_val, esc_all } ESCAPES; + + struct lookup_context { + const char *mapname; +- time_t mtime; + struct parse_mod *parse; + }; + +@@ -54,7 +53,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +- struct stat st; + + *context = NULL; + +@@ -87,15 +85,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 1; + } + +- if (stat(ctxt->mapname, &st)) { +- free(ctxt); +- logmsg(MODPREFIX "file map %s, could not stat", +- argv[0]); +- return 1; +- } +- +- ctxt->mtime = st.st_mtime; +- + if (!mapfmt) + mapfmt = MAPFMT_DEFAULT; + +@@ -391,9 +380,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + int blen; + char *path; + char *ent; +- struct stat st; + FILE *f; +- int fd; + unsigned int path_len, ent_len; + int entry, cur_state; + +@@ -428,8 +415,6 @@ int lookup_read_master(struct master *master, time_t age, void *context) + return NSS_STATUS_UNAVAIL; + } + +- fd = fileno(f); +- + while(1) { + entry = read_one(logopt, f, path, &path_len, ent, &ent_len); + if (!entry) { +@@ -504,13 +489,6 @@ int lookup_read_master(struct master *master, time_t age, void *context) + break; + } + +- if (fstat(fd, &st)) { +- crit(logopt, MODPREFIX "file map %s, could not stat", +- ctxt->mapname); +- return NSS_STATUS_UNAVAIL; +- } +- ctxt->mtime = st.st_mtime; +- + fclose(f); + + return NSS_STATUS_SUCCESS; +@@ -642,9 +620,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + struct mapent_cache *mc; + char *key; + char *mapent; +- struct stat st; + FILE *f; +- int fd; + unsigned int k_len, m_len; + int entry; + +@@ -684,8 +660,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + return NSS_STATUS_UNAVAIL; + } + +- fd = fileno(f); +- + while(1) { + entry = read_one(ap->logopt, f, key, &k_len, mapent, &m_len); + if (!entry) { +@@ -748,13 +722,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + break; + } + +- if (fstat(fd, &st)) { +- crit(ap->logopt, +- MODPREFIX "file map %s, could not stat", +- ctxt->mapname); +- return NSS_STATUS_UNAVAIL; +- } +- ctxt->mtime = st.st_mtime; + source->age = age; + + fclose(f); +@@ -951,9 +918,6 @@ static int check_map_indirect(struct autofs_point *ap, + if (ret == CHE_FAIL) + return NSS_STATUS_NOTFOUND; + +- if (ret & CHE_UPDATED) +- source->stale = 1; +- + pthread_cleanup_push(cache_lock_cleanup, mc); + cache_writelock(mc); + exists = cache_lookup_distinct(mc, key); +@@ -963,7 +927,6 @@ static int check_map_indirect(struct autofs_point *ap, + free(exists->mapent); + exists->mapent = NULL; + exists->status = 0; +- source->stale = 1; + } + } + pthread_cleanup_pop(1); +@@ -985,14 +948,8 @@ static int check_map_indirect(struct autofs_point *ap, + we = cache_lookup_distinct(mc, "*"); + if (we) { + /* Wildcard entry existed and is now gone */ +- if (we->source == source && (wild & CHE_MISSING)) { ++ if (we->source == source && (wild & CHE_MISSING)) + cache_delete(mc, "*"); +- source->stale = 1; +- } +- } else { +- /* Wildcard not in map but now is */ +- if (wild & (CHE_OK | CHE_UPDATED)) +- source->stale = 1; + } + pthread_cleanup_pop(1); + +@@ -1062,9 +1019,28 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + * we never know about it. + */ + if (ap->type == LKP_INDIRECT && *key != '/') { ++ struct stat st; + char *lkp_key; + ++ /* ++ * We can skip the map lookup and cache update altogether ++ * if we know the map hasn't been modified since it was ++ * last read. If it has then we can mark the map stale ++ * so a re-read is triggered following the lookup. ++ */ ++ if (stat(ctxt->mapname, &st)) { ++ error(ap->logopt, MODPREFIX ++ "file map %s, could not stat", ctxt->mapname); ++ return NSS_STATUS_UNAVAIL; ++ } ++ + cache_readlock(mc); ++ me = cache_lookup_first(mc); ++ if (me && st.st_mtime <= me->age) ++ goto do_cache_lookup; ++ else ++ source->stale = 1; ++ + me = cache_lookup_distinct(mc, key); + if (me && me->multi) + lkp_key = strdup(me->multi->key); +@@ -1088,6 +1064,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + } + + cache_readlock(mc); ++do_cache_lookup: + me = cache_lookup(mc, key); + /* Stale mapent => check for entry in alternate source or wildcard */ + if (me && !me->mapent) { diff --git a/autofs-5.0.4-another-easy-alloca-replacements-fix.patch b/autofs-5.0.4-another-easy-alloca-replacements-fix.patch new file mode 100644 index 0000000..fb0e57b --- /dev/null +++ b/autofs-5.0.4-another-easy-alloca-replacements-fix.patch @@ -0,0 +1,36 @@ +autofs-5.0.4 - another easy alloca replacements fix + +From: Ian Kent + +Fix array out of bounds access in modules/lookup_ldap.c:get_query_dn(). +--- + + CHANGELOG | 1 + + modules/lookup_ldap.c | 1 - + 2 files changed, 1 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 8860b2c..4df6a60 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -29,6 +29,7 @@ + - fix bad token declaration in master map parser. + - fix return start status on fail. + - fix double free in expire_proc(). ++- another easy alloca replacements fix. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 547ca01..5a54b5f 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -323,7 +323,6 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt + } + scope = LDAP_SCOPE_SUBTREE; + } +- query[l] = '\0'; + + if (!ctxt->base) { + sdns = defaults_get_searchdns(); diff --git a/autofs-5.0.4-clear-rpc-client-on-lookup-fail.patch b/autofs-5.0.4-clear-rpc-client-on-lookup-fail.patch new file mode 100644 index 0000000..bdb9394 --- /dev/null +++ b/autofs-5.0.4-clear-rpc-client-on-lookup-fail.patch @@ -0,0 +1,47 @@ +autofs-5.0.4 - clear rpc client on lookup fail + +From: Ian Kent + +If a name lookup failure occurs in create_tcp_client() or create_udp_client() +the client is destoryed and the file descriptor is closed at exit but the rpc +client isn't set to NULL. This leads to a subsequent SEGV when attempting to +use the invalid client. +--- + + CHANGELOG | 1 + + lib/rpc_subs.c | 2 ++ + 2 files changed, 3 insertions(+), 0 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 00b455e..91edd14 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -34,6 +34,7 @@ + - fix file map lookup when reading included or nsswitch sources. + - use misc device ioctl interface by default, if available. + - fix call restorecon when misc device file doesn't exist. ++- clear rpc client on lookup fail. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index a822f1f..d034b29 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -346,6 +346,7 @@ static CLIENT *create_udp_client(struct conn_info *info) + if (ret) { + error(LOGOPT_ANY, + "hostname lookup failed: %s", gai_strerror(ret)); ++ info->client = NULL; + goto out_close; + } + +@@ -470,6 +471,7 @@ static CLIENT *create_tcp_client(struct conn_info *info) + if (ret) { + error(LOGOPT_ANY, + "hostname lookup failed: %s", gai_strerror(ret)); ++ info->client = NULL; + goto out_close; + } + diff --git a/autofs-5.0.4-code-analysis-corrections.patch b/autofs-5.0.4-code-analysis-corrections.patch new file mode 100644 index 0000000..b0601fd --- /dev/null +++ b/autofs-5.0.4-code-analysis-corrections.patch @@ -0,0 +1,552 @@ +autofs-5.0.4 - code analysis corrections + +From: Ian Kent + +Several mistakes have been reported by Paul Wankadia : +- a malloc(3) allocation return was not being checked in make_fullpath(). +- a double free and a use after free was identified in lookup_prune_cache(). +- off-by-one buffer overflow in lib/macros.c:macro_parse_globalvar(). +- several potential buffer overflows in modules/parse_hesiod.c. +- double free in daemon/indirect.c:do_mount_autofs_indirect(). +- bogus struct name used for sizeof in lib/cache.c:cache_init() and + lib/cache.c:cache_init_null_cache(). +- in daemon/direct.c:handle_packet_expire_direct master_unlock_mutex() not + needed and mutexes not unlocked for file descriptor fail case. +- in modules/lookup_multi.c:lookup_init() struct module_info array not + checked before free for allocation failure case. +- in modules/lookup_program.c:lookup_mount() mapent not freed on cache update failure. +- in modules/mount_nfs.c allocation of mount location not checked. +- in modules/parse_sun.c:parse_mapent() mount location not freed on syntax error. +- in modules/parse_sun.c:parse_mount() mount location not freed on syntax error. +- in modules/parse_sun.c:parse_init() a malloc is not checked and the + handling of the fail case is poor. +- in lib/mounts.c:tree_make_mnt_tree() variable ent is not freed on ent->path + alloc fail. +- in modules/replicated.c:add_host() NULL pointer dereference. +- add missing pthread_attr_destroy() in lib/alarm.c:alarm_start_handler(). +- add missing pthread_attr_destroy() in daemon/state.c:st_start_handler(). +- add missing fclose() in lib/defaults.c:*defaults_get_searchdns(). +- add missing close()es in modules/mount_changer.c:swapCD(). +--- + + daemon/direct.c | 6 ++- + daemon/indirect.c | 3 +- + daemon/lookup.c | 20 +++++------- + daemon/state.c | 6 ++- + lib/alarm.c | 6 ++- + lib/cache.c | 4 +- + lib/defaults.c | 1 + + lib/macros.c | 2 + + lib/mounts.c | 5 ++- + modules/lookup_multi.c | 15 +++++---- + modules/lookup_program.c | 4 ++ + modules/mount_changer.c | 2 + + modules/mount_nfs.c | 5 +++ + modules/parse_hesiod.c | 79 ++++++++++++++++++++++++++++++++++++++++------ + modules/parse_sun.c | 18 ++++++---- + modules/replicated.c | 2 + + 16 files changed, 123 insertions(+), 55 deletions(-) + + +diff --git a/daemon/direct.c b/daemon/direct.c +index 2d979f1..fc3c969 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -1088,7 +1088,6 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di + crit(ap->logopt, "can't find map entry for (%lu,%lu)", + (unsigned long) pkt->dev, (unsigned long) pkt->ino); + master_source_unlock(ap->entry); +- master_mutex_unlock(); + pthread_setcancelstate(state, NULL); + return 1; + } +@@ -1098,8 +1097,9 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di + int ioctlfd; + ops->open(ap->logopt, &ioctlfd, me->dev, me->key); + if (ioctlfd == -1) { +- crit(ap->logopt, "can't open ioctlfd for %s", +- me->key); ++ crit(ap->logopt, "can't open ioctlfd for %s", me->key); ++ cache_unlock(mc); ++ master_source_unlock(ap->entry); + pthread_setcancelstate(state, NULL); + return 1; + } +diff --git a/daemon/indirect.c b/daemon/indirect.c +index 2ccbc53..f40c393 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -159,6 +159,7 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) + } + + free(options); ++ options = NULL; + + ret = stat(root, &st); + if (ret == -1) { +@@ -167,8 +168,6 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) + goto out_umount; + } + +- options = NULL; +- + if (ops->open(ap->logopt, &ap->ioctlfd, st.st_dev, root)) { + crit(ap->logopt, + "failed to create ioctl fd for autofs path %s", ap->path); +diff --git a/daemon/lookup.c b/daemon/lookup.c +index e034348..fd2ce55 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -1001,12 +1001,16 @@ static char *make_fullpath(const char *root, const char *key) + if (l > KEY_MAX_LEN) + return NULL; + path = malloc(l); ++ if (!path) ++ return NULL; + strcpy(path, key); + } else { + l = strlen(key) + 1 + strlen(root) + 1; + if (l > KEY_MAX_LEN) + return NULL; + path = malloc(l); ++ if (!path) ++ return NULL; + sprintf(path, "%s/%s", root, key); + } + return path; +@@ -1076,10 +1080,6 @@ int lookup_prune_cache(struct autofs_point *ap, time_t age) + this = cache_lookup_distinct(mc, key); + if (!this) { + cache_unlock(mc); +- free(key); +- if (next_key) +- free(next_key); +- free(path); + goto next; + } + +@@ -1097,18 +1097,14 @@ int lookup_prune_cache(struct autofs_point *ap, time_t age) + } + cache_unlock(mc); + +- if (!next_key) { +- free(key); +- free(path); +- cache_readlock(mc); +- continue; +- } + next: + cache_readlock(mc); +- me = cache_lookup_distinct(mc, next_key); ++ if (next_key) { ++ me = cache_lookup_distinct(mc, next_key); ++ free(next_key); ++ } + free(key); + free(path); +- free(next_key); + } + pthread_cleanup_pop(1); + map->stale = 0; +diff --git a/daemon/state.c b/daemon/state.c +index cd63be1..606743b 100644 +--- a/daemon/state.c ++++ b/daemon/state.c +@@ -1140,9 +1140,9 @@ int st_start_handler(void) + } + + status = pthread_create(&thid, pattrs, st_queue_handler, NULL); +- if (status) +- return 0; + +- return 1; ++ pthread_attr_destroy(pattrs); ++ ++ return !status; + } + +diff --git a/lib/alarm.c b/lib/alarm.c +index 1e32291..46df38a 100755 +--- a/lib/alarm.c ++++ b/lib/alarm.c +@@ -238,9 +238,9 @@ int alarm_start_handler(void) + } + + status = pthread_create(&thid, pattrs, alarm_handler, NULL); +- if (status) +- return 0; + +- return 1; ++ pthread_attr_destroy(pattrs); ++ ++ return !status; + } + +diff --git a/lib/cache.c b/lib/cache.c +index edb3192..4cb4582 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -192,7 +192,7 @@ struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map) + + mc->size = defaults_get_map_hash_table_size(); + +- mc->hash = malloc(mc->size * sizeof(struct entry *)); ++ mc->hash = malloc(mc->size * sizeof(struct mapent *)); + if (!mc->hash) { + free(mc); + return NULL; +@@ -243,7 +243,7 @@ struct mapent_cache *cache_init_null_cache(struct master *master) + + mc->size = NULL_MAP_HASHSIZE; + +- mc->hash = malloc(mc->size * sizeof(struct entry *)); ++ mc->hash = malloc(mc->size * sizeof(struct mapent *)); + if (!mc->hash) { + free(mc); + return NULL; +diff --git a/lib/defaults.c b/lib/defaults.c +index 0d39716..e507a59 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -565,6 +565,7 @@ struct ldap_searchdn *defaults_get_searchdns(void) + + if (!new) { + defaults_free_searchdns(sdn); ++ fclose(f); + return NULL; + } + +diff --git a/lib/macros.c b/lib/macros.c +index 85f9cd3..32b70bf 100644 +--- a/lib/macros.c ++++ b/lib/macros.c +@@ -165,7 +165,7 @@ int macro_parse_globalvar(const char *define) + char buf[MAX_MACRO_STRING]; + char *pbuf, *value; + +- if (strlen(define) > MAX_MACRO_STRING) ++ if (strlen(define) >= MAX_MACRO_STRING) + return 0; + + strcpy(buf, define); +diff --git a/lib/mounts.c b/lib/mounts.c +index b98e1a4..08ca4e3 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -257,10 +257,10 @@ struct mnt_list *get_mnt_list(const char *table, const char *path, int include) + + if (mptr == list) + list = ent; ++ else ++ last->next = ent; + + ent->next = mptr; +- if (last) +- last->next = ent; + + ent->path = malloc(len + 1); + if (!ent->path) { +@@ -705,6 +705,7 @@ struct mnt_list *tree_make_mnt_tree(const char *table, const char *path) + ent->path = malloc(len + 1); + if (!ent->path) { + endmntent(tab); ++ free(ent); + tree_free_mnt_tree(tree); + return NULL; + } +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index 1bf2e0a..6ec8434 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -212,14 +212,15 @@ nomem: + logerr(MODPREFIX "error: %s", estr); + error_out: + if (ctxt) { +- for (i = 0; i < ctxt->n; i++) { +- if (ctxt->m[i].mod) +- close_lookup(ctxt->m[i].mod); +- if (ctxt->m[i].argv) +- free_argv(ctxt->m[i].argc, ctxt->m[i].argv); +- } +- if (ctxt->m) ++ if (ctxt->m) { ++ for (i = 0; i < ctxt->n; i++) { ++ if (ctxt->m[i].mod) ++ close_lookup(ctxt->m[i].mod); ++ if (ctxt->m[i].argv) ++ free_argv(ctxt->m[i].argc, ctxt->m[i].argv); ++ } + free(ctxt->m); ++ } + if (ctxt->argl) + free(ctxt->argl); + free(ctxt); +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index 9878936..5b295a5 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -396,8 +396,10 @@ next: + cache_writelock(mc); + ret = cache_update(mc, source, name, mapent, time(NULL)); + cache_unlock(mc); +- if (ret == CHE_FAIL) ++ if (ret == CHE_FAIL) { ++ free(mapent); + return NSS_STATUS_UNAVAIL; ++ } + + debug(ap->logopt, MODPREFIX "%s -> %s", name, mapent); + +diff --git a/modules/mount_changer.c b/modules/mount_changer.c +index 92bb72b..c30190d 100644 +--- a/modules/mount_changer.c ++++ b/modules/mount_changer.c +@@ -162,6 +162,7 @@ int swapCD(const char *device, const char *slotName) + logerr(MODPREFIX + "Device %s is not an ATAPI compliant CD changer.", + device); ++ close(fd); + return 1; + } + +@@ -169,6 +170,7 @@ int swapCD(const char *device, const char *slotName) + slot = ioctl(fd, CDROM_SELECT_DISC, slot); + if (slot < 0) { + logerr(MODPREFIX "CDROM_SELECT_DISC failed"); ++ close(fd); + return 1; + } + +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 20732f8..6f54f47 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -221,6 +221,11 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + /* Not a local host - do an NFS mount */ + + loc = malloc(strlen(this->name) + 1 + strlen(this->path) + 1); ++ if (!loc) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, "malloc: %s", estr); ++ return 1; ++ } + strcpy(loc, this->name); + strcat(loc, ":"); + strcat(loc, this->path); +diff --git a/modules/parse_hesiod.c b/modules/parse_hesiod.c +index d5bb0f4..7a6a57d 100644 +--- a/modules/parse_hesiod.c ++++ b/modules/parse_hesiod.c +@@ -46,6 +46,12 @@ static int parse_afs(struct autofs_point *ap, + + /* Isolate the source for this AFS fs. */ + for (i = 0; (!isspace(p[i]) && i < source_len); i++) { ++ if (!p[i]) { ++ error(ap->logopt, MODPREFIX ++ "unexpeced end of input looking for AFS " ++ "source: %s", p); ++ return 1; ++ } + source[i] = p[i]; + } + +@@ -56,8 +62,14 @@ static int parse_afs(struct autofs_point *ap, + while ((*p) && (isspace(*p))) + p++; + +- /* Isolate the source for this AFS fs. */ ++ /* Isolate the options for this AFS fs. */ + for (i = 0; (!isspace(p[i]) && i < options_len); i++) { ++ if (!p[i]) { ++ error(ap->logopt, MODPREFIX ++ "unexpeced end of input looking for AFS " ++ "options: %s", p); ++ return 1; ++ } + options[i] = p[i]; + } + options[i] = 0; +@@ -106,6 +118,12 @@ static int parse_nfs(struct autofs_point *ap, + + /* Isolate the remote mountpoint for this NFS fs. */ + for (i = 0; (!isspace(p[i]) && i < (int) sizeof(mount)); i++) { ++ if (!p[i]) { ++ error(ap->logopt, MODPREFIX ++ "unexpeced end of input looking for NFS " ++ "mountpoint: %s", p); ++ return 1; ++ } + mount[i] = p[i]; + } + +@@ -118,15 +136,26 @@ static int parse_nfs(struct autofs_point *ap, + + /* Isolate the remote host. */ + for (i = 0; (!isspace(p[i]) && i < source_len); i++) { ++ if (!p[i]) { ++ error(ap->logopt, MODPREFIX ++ "unexpeced end of input looking for NFS " ++ "host: %s", p); ++ return 1; ++ } + source[i] = p[i]; + } + + source[i] = 0; + p += i; + ++ if (strlen(source) + strlen(mount) + 2 > source_len) { ++ error(ap->logopt, MODPREFIX "entry too log for mount source"); ++ return 1; ++ } ++ + /* Append ":mountpoint" to the source to get "host:mountpoint". */ +- strncat(source, ":", source_len); +- strncat(source, mount, source_len); ++ strcat(source, ":"); ++ strcat(source, mount); + + /* Skip whitespace. */ + while ((*p) && (isspace(*p))) +@@ -134,6 +163,12 @@ static int parse_nfs(struct autofs_point *ap, + + /* Isolate the mount options. */ + for (i = 0; (!isspace(p[i]) && i < options_len); i++) { ++ if (!p[i]) { ++ error(ap->logopt, MODPREFIX ++ "unexpeced end of input looking for NFS " ++ "mount options: %s", p); ++ return 1; ++ } + options[i] = p[i]; + } + options[i] = 0; +@@ -178,6 +213,12 @@ static int parse_generic(struct autofs_point *ap, + + /* Isolate the source for this fs. */ + for (i = 0; (!isspace(p[i]) && i < source_len); i++) { ++ if (!p[i]) { ++ error(ap->logopt, MODPREFIX ++ "unexpeced end of input looking for generic " ++ "mount source: %s", p); ++ return 1; ++ } + source[i] = p[i]; + } + +@@ -190,6 +231,12 @@ static int parse_generic(struct autofs_point *ap, + + /* Isolate the mount options. */ + for (i = 0; (!isspace(p[i]) && i < options_len); i++) { ++ if (!p[i]) { ++ error(ap->logopt, MODPREFIX ++ "unexpeced end of input looking for generic " ++ "mount options: %s", p); ++ return 1; ++ } + options[i] = p[i]; + } + options[i] = 0; +@@ -227,6 +274,7 @@ int parse_mount(struct autofs_point *ap, const char *name, + char options[HESIOD_LEN + 1]; + char *q; + const char *p; ++ int ret; + + ap->entry->current = NULL; + master_source_current_signal(ap->entry); +@@ -250,19 +298,28 @@ int parse_mount(struct autofs_point *ap, const char *name, + return 1; + /* If it's an AFS fs... */ + } else if (!strcasecmp(fstype, "afs")) +- parse_afs(ap, mapent, name, name_len, +- source, sizeof(source), options, sizeof(options)); ++ ret = parse_afs(ap, mapent, name, name_len, ++ source, sizeof(source), options, ++ sizeof(options)); + /* If it's NFS... */ + else if (!strcasecmp(fstype, "nfs")) +- parse_nfs(ap, mapent, name, name_len, +- source, sizeof(source), options, sizeof(options)); ++ ret = parse_nfs(ap, mapent, name, name_len, ++ source, sizeof(source), options, ++ sizeof(options)); + /* Punt. */ + else +- parse_generic(ap, mapent, name, name_len, source, sizeof(source), +- options, sizeof(options)); ++ ret = parse_generic(ap, mapent, name, name_len, ++ source, sizeof(source), options, ++ sizeof(options)); + +- debug(ap->logopt, +- MODPREFIX "mount %s is type %s from %s", name, fstype, source); ++ if (ret) { ++ error(ap->logopt, MODPREFIX "failed to parse entry"); ++ return 1; ++ } else { ++ debug(ap->logopt, ++ MODPREFIX "mount %s is type %s from %s", ++ name, fstype, source); ++ } + + return do_mount(ap, ap->path, name, name_len, source, fstype, options); + } +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 72e51e2..ed73e46 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -379,15 +379,17 @@ int parse_init(int argc, const char *const *argv, void **context) + if (ctxt->optstr) { + noptstr = + (char *) realloc(ctxt->optstr, optlen + len + 2); +- if (!noptstr) +- break; +- noptstr[optlen] = ','; +- strcpy(noptstr + optlen + 1, argv[i] + offset); +- optlen += len + 1; ++ if (noptstr) { ++ noptstr[optlen] = ','; ++ strcpy(noptstr + optlen + 1, argv[i] + offset); ++ optlen += len + 1; ++ } + } else { + noptstr = (char *) malloc(len + 1); +- strcpy(noptstr, argv[i] + offset); +- optlen = len; ++ if (noptstr) { ++ strcpy(noptstr, argv[i] + offset); ++ optlen = len; ++ } + } + if (!noptstr) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +@@ -895,6 +897,7 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char * + if (*p == '/') { + warn(logopt, MODPREFIX "error location begins with \"/\""); + free(myoptions); ++ free(loc); + return 0; + } + +@@ -1636,6 +1639,7 @@ int parse_mount(struct autofs_point *ap, const char *name, + /* Location can't begin with a '/' */ + if (*p == '/') { + free(options); ++ free(loc); + warn(ap->logopt, + MODPREFIX "error location begins with \"/\""); + return 1; +diff --git a/modules/replicated.c b/modules/replicated.c +index 63829a2..835af97 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -304,7 +304,7 @@ static int add_host(struct host **list, struct host *host) + { + struct host *this, *last; + +- if (!list) { ++ if (!*list) { + *list = host; + return 1; + } diff --git a/autofs-5.0.4-configure-libtirpc-fix.patch b/autofs-5.0.4-configure-libtirpc-fix.patch new file mode 100644 index 0000000..a7e9da0 --- /dev/null +++ b/autofs-5.0.4-configure-libtirpc-fix.patch @@ -0,0 +1,5422 @@ +autofs-5.0.4 - configure libtirpc fix + +From: Ian Kent + +Cleanup configure defines for libtirpc. +Add WITH_LIBTIRPC to the -V status report. +Add a check for libtirpc.so.1 for the libtirpc workaround in case libtirpc.so +is not present. +--- + + CHANGELOG | 3 + aclocal.m4 | 3 + configure | 2769 ++++++++++++++++++++++++++++----------------------- + daemon/automount.c | 12 + include/config.h.in | 5 + 5 files changed, 1539 insertions(+), 1253 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index b8ad22e..ad74b7d 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -22,6 +22,9 @@ + - update to provide ipv6 address parsing. + - easy alloca replacements fix. + - add check for alternate libxml2 library for libxml2 tsd workaround. ++- add check for alternate libtirpc library for libtirpc tsd workaround. ++- cleanup configure defines for libtirpc. ++- add WITH_LIBTIRPC to -V status report. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/aclocal.m4 b/aclocal.m4 +index 5777fcd..e7f1a30 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -364,7 +364,8 @@ AC_TRY_LINK( + [ AC_MSG_RESULT(no) ]) + + if test "$af_have_libtirpc" = "yes"; then +- AC_DEFINE(TIRPC_WORKAROUND,1, [Use libtirpc tsd usage workaround]) ++ AC_DEFINE(WITH_LIBTIRPC,1, [Define to 1 if you have the libtirpc library installed]) ++ AC_DEFINE(TIRPC_WORKAROUND,1, [Define to 1 to use the libtirpc tsd usage workaround]) + TIRPCLIB="-ltirpc" + fi + +diff --git a/configure b/configure +index 8a6d944..995a472 100755 +--- a/configure ++++ b/configure +@@ -1,9 +1,9 @@ + #! /bin/sh + # Guess values for system-dependent variables and create Makefiles. +-# Generated by GNU Autoconf 2.61. ++# Generated by GNU Autoconf 2.63. + # + # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +-# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. ++# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + # This configure script is free software; the Free Software Foundation + # gives unlimited permission to copy, distribute and modify it. + ## --------------------- ## +@@ -15,7 +15,7 @@ DUALCASE=1; export DUALCASE # for MKS sh + if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which ++ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +@@ -37,17 +37,45 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS + as_cr_digits='0123456789' + as_cr_alnum=$as_cr_Letters$as_cr_digits + +-# The user is always right. +-if test "${PATH_SEPARATOR+set}" != set; then +- echo "#! /bin/sh" >conf$$.sh +- echo "exit 0" >>conf$$.sh +- chmod +x conf$$.sh +- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then +- PATH_SEPARATOR=';' ++as_nl=' ++' ++export as_nl ++# Printing a long string crashes Solaris 7 /usr/bin/printf. ++as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo ++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo ++if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then ++ as_echo='printf %s\n' ++ as_echo_n='printf %s' ++else ++ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then ++ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' ++ as_echo_n='/usr/ucb/echo -n' + else +- PATH_SEPARATOR=: ++ as_echo_body='eval expr "X$1" : "X\\(.*\\)"' ++ as_echo_n_body='eval ++ arg=$1; ++ case $arg in ++ *"$as_nl"*) ++ expr "X$arg" : "X\\(.*\\)$as_nl"; ++ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; ++ esac; ++ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ++ ' ++ export as_echo_n_body ++ as_echo_n='sh -c $as_echo_n_body as_echo' + fi +- rm -f conf$$.sh ++ export as_echo_body ++ as_echo='sh -c $as_echo_body as_echo' ++fi ++ ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ PATH_SEPARATOR=: ++ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { ++ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || ++ PATH_SEPARATOR=';' ++ } + fi + + # Support unset when possible. +@@ -63,8 +91,6 @@ fi + # there to prevent editors from complaining about space-tab. + # (If _AS_PATH_WALK were called with IFS unset, it would disable word + # splitting by setting IFS to empty value.) +-as_nl=' +-' + IFS=" "" $as_nl" + + # Find who we are. Look in the path if we contain no directory separator. +@@ -87,7 +113,7 @@ if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then +- echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 ++ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } + fi + +@@ -100,17 +126,10 @@ PS2='> ' + PS4='+ ' + + # NLS nuisances. +-for as_var in \ +- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ +- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ +- LC_TELEPHONE LC_TIME +-do +- if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then +- eval $as_var=C; export $as_var +- else +- ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +- fi +-done ++LC_ALL=C ++export LC_ALL ++LANGUAGE=C ++export LANGUAGE + + # Required to use basename. + if expr a : '\(a\)' >/dev/null 2>&1 && +@@ -132,7 +151,7 @@ as_me=`$as_basename -- "$0" || + $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +-echo X/"$0" | ++$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q +@@ -158,7 +177,7 @@ else + as_have_required=no + fi + +- if test $as_have_required = yes && (eval ": ++ if test $as_have_required = yes && (eval ": + (as_func_return () { + (exit \$1) + } +@@ -240,7 +259,7 @@ IFS=$as_save_IFS + if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which ++ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +@@ -261,7 +280,7 @@ _ASEOF + if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which ++ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +@@ -341,10 +360,10 @@ fi + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV +- do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +- done +- export CONFIG_SHELL +- exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} ++ do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var ++ done ++ export CONFIG_SHELL ++ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} + fi + + +@@ -413,9 +432,10 @@ fi + + test \$exitcode = 0") || { + echo No shell found that supports shell functions. +- echo Please tell autoconf@gnu.org about your system, +- echo including any error possibly output before this +- echo message ++ echo Please tell bug-autoconf@gnu.org about your system, ++ echo including any error possibly output before this message. ++ echo This can help us improve future autoconf versions. ++ echo Configuration will now proceed without shell functions. + } + + +@@ -451,7 +471,7 @@ test \$exitcode = 0") || { + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || +- { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 ++ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems +@@ -479,7 +499,6 @@ case `echo -n x` in + *) + ECHO_N='-n';; + esac +- + if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +@@ -492,19 +511,22 @@ if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file + else + rm -f conf$$.dir +- mkdir conf$$.dir +-fi +-echo >conf$$.file +-if ln -s conf$$.file conf$$ 2>/dev/null; then +- as_ln_s='ln -s' +- # ... but there are two gotchas: +- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. +- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. +- # In both cases, we have to default to `cp -p'. +- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || ++ mkdir conf$$.dir 2>/dev/null ++fi ++if (echo >conf$$.file) 2>/dev/null; then ++ if ln -s conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s='ln -s' ++ # ... but there are two gotchas: ++ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. ++ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. ++ # In both cases, we have to default to `cp -p'. ++ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || ++ as_ln_s='cp -p' ++ elif ln conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s=ln ++ else + as_ln_s='cp -p' +-elif ln conf$$.file conf$$ 2>/dev/null; then +- as_ln_s=ln ++ fi + else + as_ln_s='cp -p' + fi +@@ -529,10 +551,10 @@ else + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then +- test -d "$1/."; ++ test -d "$1/."; + else + case $1 in +- -*)set "./$1";; ++ -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi +@@ -614,98 +636,115 @@ ac_includes_default="\ + # include + #endif" + +-ac_subst_vars='SHELL +-PATH_SEPARATOR +-PACKAGE_NAME +-PACKAGE_TARNAME +-PACKAGE_VERSION +-PACKAGE_STRING +-PACKAGE_BUGREPORT +-exec_prefix +-prefix +-program_transform_name +-bindir +-sbindir +-libexecdir +-datarootdir +-datadir +-sysconfdir +-sharedstatedir +-localstatedir +-includedir +-oldincludedir +-docdir +-infodir +-htmldir +-dvidir +-pdfdir +-psdir +-libdir +-localedir +-mandir +-DEFS +-ECHO_C +-ECHO_N +-ECHO_T +-LIBS +-build_alias +-host_alias +-target_alias +-initdir +-confdir +-mapdir +-fifodir +-flagdir +-CC +-CFLAGS +-LDFLAGS +-CPPFLAGS +-ac_ct_CC +-EXEEXT +-OBJEXT +-TIRPCLIB +-DMALLOCLIB +-MOUNT +-HAVE_MOUNT +-UMOUNT +-HAVE_UMOUNT +-E2FSCK +-HAVE_E2FSCK +-E3FSCK +-HAVE_E3FSCK +-MODPROBE +-HAVE_MODPROBE +-LEX +-PATH_LEX +-YACC +-PATH_YACC +-RANLIB +-PATH_RANLIB +-RPCGEN +-PATH_RPCGEN +-XML_CONFIG +-LIBNSL +-LIBRESOLV +-HAVE_HESIOD +-LIBHESIOD +-HESIOD_FLAGS +-CPP +-GREP +-EGREP +-HAVE_NISPLUS +-LDAP_FLAGS +-HAVE_LDAP +-LIBLDAP +-XML_FLAGS +-XML_LIBS +-SASL_FLAGS +-HAVE_SASL +-LIBSASL +-DAEMON_CFLAGS +-DAEMON_LDFLAGS ++ac_subst_vars='LTLIBOBJS + LIBOBJS +-LTLIBOBJS' ++DAEMON_LDFLAGS ++DAEMON_CFLAGS ++LIBSASL ++HAVE_SASL ++SASL_FLAGS ++XML_LIBS ++XML_FLAGS ++LIBLDAP ++HAVE_LDAP ++LDAP_FLAGS ++HAVE_NISPLUS ++EGREP ++GREP ++CPP ++HESIOD_FLAGS ++LIBHESIOD ++HAVE_HESIOD ++LIBRESOLV ++LIBNSL ++XML_CONFIG ++PATH_RPCGEN ++RPCGEN ++PATH_RANLIB ++RANLIB ++PATH_YACC ++YACC ++PATH_LEX ++LEX ++HAVE_MODPROBE ++MODPROBE ++HAVE_E3FSCK ++E3FSCK ++HAVE_E2FSCK ++E2FSCK ++HAVE_UMOUNT ++UMOUNT ++HAVE_MOUNT ++MOUNT ++DMALLOCLIB ++TIRPCLIB ++OBJEXT ++EXEEXT ++ac_ct_CC ++CPPFLAGS ++LDFLAGS ++CFLAGS ++CC ++flagdir ++fifodir ++mapdir ++confdir ++initdir ++target_alias ++host_alias ++build_alias ++LIBS ++ECHO_T ++ECHO_N ++ECHO_C ++DEFS ++mandir ++localedir ++libdir ++psdir ++pdfdir ++dvidir ++htmldir ++infodir ++docdir ++oldincludedir ++includedir ++localstatedir ++sharedstatedir ++sysconfdir ++datadir ++datarootdir ++libexecdir ++sbindir ++bindir ++program_transform_name ++prefix ++exec_prefix ++PACKAGE_BUGREPORT ++PACKAGE_STRING ++PACKAGE_VERSION ++PACKAGE_TARNAME ++PACKAGE_NAME ++PATH_SEPARATOR ++SHELL' + ac_subst_files='' ++ac_user_opts=' ++enable_option_checking ++with_path ++with_confdir ++with_mapdir ++with_fifodir ++with_flagdir ++with_libtirpc ++with_dmalloc ++with_hesiod ++with_openldap ++with_sasl ++enable_ext_env ++enable_mount_locking ++enable_forced_shutdown ++enable_ignore_busy ++' + ac_precious_vars='build_alias + host_alias + target_alias +@@ -720,6 +759,8 @@ CPP' + # Initialize some variables set by options. + ac_init_help= + ac_init_version=false ++ac_unrecognized_opts= ++ac_unrecognized_sep= + # The variables have the same names as the options, with + # dashes changed to underlines. + cache_file=/dev/null +@@ -818,13 +859,21 @@ do + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) +- ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` ++ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. +- expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && +- { echo "$as_me: error: invalid feature name: $ac_feature" >&2 ++ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && ++ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } +- ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` +- eval enable_$ac_feature=no ;; ++ ac_useropt_orig=$ac_useropt ++ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` ++ case $ac_user_opts in ++ *" ++"enable_$ac_useropt" ++"*) ;; ++ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ++ ac_unrecognized_sep=', ';; ++ esac ++ eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; +@@ -837,13 +886,21 @@ do + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) +- ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` ++ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. +- expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && +- { echo "$as_me: error: invalid feature name: $ac_feature" >&2 ++ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && ++ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } +- ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` +- eval enable_$ac_feature=\$ac_optarg ;; ++ ac_useropt_orig=$ac_useropt ++ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` ++ case $ac_user_opts in ++ *" ++"enable_$ac_useropt" ++"*) ;; ++ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ++ ac_unrecognized_sep=', ';; ++ esac ++ eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ +@@ -1034,22 +1091,38 @@ do + ac_init_version=: ;; + + -with-* | --with-*) +- ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` ++ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. +- expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && +- { echo "$as_me: error: invalid package name: $ac_package" >&2 ++ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && ++ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } +- ac_package=`echo $ac_package | sed 's/[-.]/_/g'` +- eval with_$ac_package=\$ac_optarg ;; ++ ac_useropt_orig=$ac_useropt ++ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` ++ case $ac_user_opts in ++ *" ++"with_$ac_useropt" ++"*) ;; ++ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ++ ac_unrecognized_sep=', ';; ++ esac ++ eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) +- ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` ++ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. +- expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && +- { echo "$as_me: error: invalid package name: $ac_package" >&2 ++ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && ++ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } +- ac_package=`echo $ac_package | sed 's/[-.]/_/g'` +- eval with_$ac_package=no ;; ++ ac_useropt_orig=$ac_useropt ++ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` ++ case $ac_user_opts in ++ *" ++"with_$ac_useropt" ++"*) ;; ++ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ++ ac_unrecognized_sep=', ';; ++ esac ++ eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. +@@ -1069,7 +1142,7 @@ do + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + +- -*) { echo "$as_me: error: unrecognized option: $ac_option ++ -*) { $as_echo "$as_me: error: unrecognized option: $ac_option + Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; +@@ -1078,16 +1151,16 @@ Try \`$0 --help' for more information." >&2 + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && +- { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 ++ { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. +- echo "$as_me: WARNING: you should use --build, --host, --target" >&2 ++ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && +- echo "$as_me: WARNING: invalid host type: $ac_option" >&2 ++ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + +@@ -1096,22 +1169,38 @@ done + + if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` +- { echo "$as_me: error: missing argument to $ac_option" >&2 ++ { $as_echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } + fi + +-# Be sure to have absolute directory names. ++if test -n "$ac_unrecognized_opts"; then ++ case $enable_option_checking in ++ no) ;; ++ fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 ++ { (exit 1); exit 1; }; } ;; ++ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; ++ esac ++fi ++ ++# Check all directory arguments for consistency. + for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir + do + eval ac_val=\$$ac_var ++ # Remove trailing slashes. ++ case $ac_val in ++ */ ) ++ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` ++ eval $ac_var=\$ac_val;; ++ esac ++ # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac +- { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 ++ { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } + done + +@@ -1126,7 +1215,7 @@ target=$target_alias + if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe +- echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. ++ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes +@@ -1142,10 +1231,10 @@ test "$silent" = yes && exec 6>/dev/null + ac_pwd=`pwd` && test -n "$ac_pwd" && + ac_ls_di=`ls -di .` && + ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || +- { echo "$as_me: error: Working directory cannot be determined" >&2 ++ { $as_echo "$as_me: error: working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } + test "X$ac_ls_di" = "X$ac_pwd_ls_di" || +- { echo "$as_me: error: pwd does not report name of working directory" >&2 ++ { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +@@ -1153,12 +1242,12 @@ test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. +- ac_confdir=`$as_dirname -- "$0" || +-$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$0" : 'X\(//\)[^/]' \| \ +- X"$0" : 'X\(//\)$' \| \ +- X"$0" : 'X\(/\)' \| . 2>/dev/null || +-echo X"$0" | ++ ac_confdir=`$as_dirname -- "$as_myself" || ++$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$as_myself" : 'X\(//\)[^/]' \| \ ++ X"$as_myself" : 'X\(//\)$' \| \ ++ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q +@@ -1185,12 +1274,12 @@ else + fi + if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." +- { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 ++ { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi + ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" + ac_abs_confdir=`( +- cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 ++ cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` + # When building in place, set srcdir=. +@@ -1239,9 +1328,9 @@ Configuration: + + Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX +- [$ac_default_prefix] ++ [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX +- [PREFIX] ++ [PREFIX] + + By default, \`make install' will install all the files in + \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +@@ -1251,25 +1340,25 @@ for instance \`--prefix=\$HOME'. + For better control, use the options below. + + Fine tuning of the installation directories: +- --bindir=DIR user executables [EPREFIX/bin] +- --sbindir=DIR system admin executables [EPREFIX/sbin] +- --libexecdir=DIR program executables [EPREFIX/libexec] +- --sysconfdir=DIR read-only single-machine data [PREFIX/etc] +- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] +- --localstatedir=DIR modifiable single-machine data [PREFIX/var] +- --libdir=DIR object code libraries [EPREFIX/lib] +- --includedir=DIR C header files [PREFIX/include] +- --oldincludedir=DIR C header files for non-gcc [/usr/include] +- --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] +- --datadir=DIR read-only architecture-independent data [DATAROOTDIR] +- --infodir=DIR info documentation [DATAROOTDIR/info] +- --localedir=DIR locale-dependent data [DATAROOTDIR/locale] +- --mandir=DIR man documentation [DATAROOTDIR/man] +- --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] +- --htmldir=DIR html documentation [DOCDIR] +- --dvidir=DIR dvi documentation [DOCDIR] +- --pdfdir=DIR pdf documentation [DOCDIR] +- --psdir=DIR ps documentation [DOCDIR] ++ --bindir=DIR user executables [EPREFIX/bin] ++ --sbindir=DIR system admin executables [EPREFIX/sbin] ++ --libexecdir=DIR program executables [EPREFIX/libexec] ++ --sysconfdir=DIR read-only single-machine data [PREFIX/etc] ++ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] ++ --localstatedir=DIR modifiable single-machine data [PREFIX/var] ++ --libdir=DIR object code libraries [EPREFIX/lib] ++ --includedir=DIR C header files [PREFIX/include] ++ --oldincludedir=DIR C header files for non-gcc [/usr/include] ++ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] ++ --datadir=DIR read-only architecture-independent data [DATAROOTDIR] ++ --infodir=DIR info documentation [DATAROOTDIR/info] ++ --localedir=DIR locale-dependent data [DATAROOTDIR/locale] ++ --mandir=DIR man documentation [DATAROOTDIR/man] ++ --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] ++ --htmldir=DIR html documentation [DOCDIR] ++ --dvidir=DIR dvi documentation [DOCDIR] ++ --pdfdir=DIR pdf documentation [DOCDIR] ++ --psdir=DIR ps documentation [DOCDIR] + _ACEOF + + cat <<\_ACEOF +@@ -1281,6 +1370,7 @@ if test -n "$ac_init_help"; then + cat <<\_ACEOF + + Optional Features: ++ --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-ext-env disable search in environment for substitution variable +@@ -1325,15 +1415,17 @@ fi + if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue +- test -d "$ac_dir" || continue ++ test -d "$ac_dir" || ++ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || ++ continue + ac_builddir=. + + case "$ac_dir" in + .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) +- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` ++ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. +- ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` ++ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; +@@ -1369,7 +1461,7 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else +- echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 ++ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +@@ -1379,10 +1471,10 @@ test -n "$ac_init_help" && exit $ac_status + if $ac_init_version; then + cat <<\_ACEOF + configure +-generated by GNU Autoconf 2.61 ++generated by GNU Autoconf 2.63 + + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +-2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. ++2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + This configure script is free software; the Free Software Foundation + gives unlimited permission to copy, distribute and modify it. + _ACEOF +@@ -1393,7 +1485,7 @@ This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. + + It was created by $as_me, which was +-generated by GNU Autoconf 2.61. Invocation command line was ++generated by GNU Autoconf 2.63. Invocation command line was + + $ $0 $@ + +@@ -1429,7 +1521,7 @@ for as_dir in $PATH + do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. +- echo "PATH: $as_dir" ++ $as_echo "PATH: $as_dir" + done + IFS=$as_save_IFS + +@@ -1464,7 +1556,7 @@ do + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) +- ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; ++ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; +@@ -1516,11 +1608,12 @@ _ASBOX + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( +- *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; ++ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 ++$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( ++ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac +@@ -1550,9 +1643,9 @@ _ASBOX + do + eval ac_val=\$$ac_var + case $ac_val in +- *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; ++ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac +- echo "$ac_var='\''$ac_val'\''" ++ $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + +@@ -1567,9 +1660,9 @@ _ASBOX + do + eval ac_val=\$$ac_var + case $ac_val in +- *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; ++ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac +- echo "$ac_var='\''$ac_val'\''" ++ $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi +@@ -1585,8 +1678,8 @@ _ASBOX + echo + fi + test "$ac_signal" != 0 && +- echo "$as_me: caught signal $ac_signal" +- echo "$as_me: exit $exit_status" ++ $as_echo "$as_me: caught signal $ac_signal" ++ $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && +@@ -1628,21 +1721,24 @@ _ACEOF + + + # Let the site file select an alternate cache file if it wants to. +-# Prefer explicitly selected file to automatically selected ones. ++# Prefer an explicitly selected file to automatically selected ones. ++ac_site_file1=NONE ++ac_site_file2=NONE + if test -n "$CONFIG_SITE"; then +- set x "$CONFIG_SITE" ++ ac_site_file1=$CONFIG_SITE + elif test "x$prefix" != xNONE; then +- set x "$prefix/share/config.site" "$prefix/etc/config.site" ++ ac_site_file1=$prefix/share/config.site ++ ac_site_file2=$prefix/etc/config.site + else +- set x "$ac_default_prefix/share/config.site" \ +- "$ac_default_prefix/etc/config.site" ++ ac_site_file1=$ac_default_prefix/share/config.site ++ ac_site_file2=$ac_default_prefix/etc/config.site + fi +-shift +-for ac_site_file ++for ac_site_file in "$ac_site_file1" "$ac_site_file2" + do ++ test "x$ac_site_file" = xNONE && continue + if test -r "$ac_site_file"; then +- { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +-echo "$as_me: loading site script $ac_site_file" >&6;} ++ { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 ++$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +@@ -1659,29 +1755,38 @@ for ac_var in $ac_precious_vars; do + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) +- { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +-echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ++ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 ++$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) +- { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +-echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ++ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 ++$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then +- { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +-echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} +- { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +-echo "$as_me: former value: $ac_old_val" >&2;} +- { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +-echo "$as_me: current value: $ac_new_val" >&2;} +- ac_cache_corrupted=: ++ # differences in whitespace do not lead to failure. ++ ac_old_val_w=`echo x $ac_old_val` ++ ac_new_val_w=`echo x $ac_new_val` ++ if test "$ac_old_val_w" != "$ac_new_val_w"; then ++ { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 ++$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ++ ac_cache_corrupted=: ++ else ++ { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 ++$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} ++ eval $ac_var=\$ac_old_val ++ fi ++ { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5 ++$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} ++ { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5 ++$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in +- *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; ++ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in +@@ -1691,10 +1796,12 @@ echo "$as_me: current value: $ac_new_val" >&2;} + fi + done + if $ac_cache_corrupted; then +- { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +-echo "$as_me: error: changes in the environment can compromise the build" >&2;} +- { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +-echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} ++ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++ { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 ++$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} ++ { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 ++$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } + fi + +@@ -1744,24 +1851,24 @@ if test "${with_path+set}" = set; then + fi + + +-{ echo "$as_me:$LINENO: checking for binaries in" >&5 +-echo $ECHO_N "checking for binaries in... $ECHO_C" >&6; } +-{ echo "$as_me:$LINENO: result: $searchpath" >&5 +-echo "${ECHO_T}$searchpath" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for binaries in" >&5 ++$as_echo_n "checking for binaries in... " >&6; } ++{ $as_echo "$as_me:$LINENO: result: $searchpath" >&5 ++$as_echo "$searchpath" >&6; } + + # + # Make sure we have "/proc" + # +-{ echo "$as_me:$LINENO: checking for Linux proc filesystem" >&5 +-echo $ECHO_N "checking for Linux proc filesystem... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for Linux proc filesystem" >&5 ++$as_echo_n "checking for Linux proc filesystem... " >&6; } + if test "x`cat /proc/sys/kernel/ostype 2>&-`" = "xLinux" + then + linux_procfs=yes + else + linux_procfs=no + fi +-{ echo "$as_me:$LINENO: result: $linux_procfs" >&5 +-echo "${ECHO_T}$linux_procfs" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $linux_procfs" >&5 ++$as_echo "$linux_procfs" >&6; } + if test $linux_procfs = yes + then + +@@ -1775,14 +1882,14 @@ fi + # Location of init.d directory? + # + if test -z "$initdir"; then +- { echo "$as_me:$LINENO: checking location of the init.d directory" >&5 +-echo $ECHO_N "checking location of the init.d directory... $ECHO_C" >&6; } ++ { $as_echo "$as_me:$LINENO: checking location of the init.d directory" >&5 ++$as_echo_n "checking location of the init.d directory... " >&6; } + for init_d in /etc/init.d /etc/rc.d/init.d; do + if test -z "$initdir"; then + if test -d "$init_d"; then + initdir="$init_d" +- { echo "$as_me:$LINENO: result: $initdir" >&5 +-echo "${ECHO_T}$initdir" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $initdir" >&5 ++$as_echo "$initdir" >&6; } + fi + fi + done +@@ -1813,10 +1920,10 @@ if test "${with_confdir+set}" = set; then + + fi + +-{ echo "$as_me:$LINENO: checking for autofs configuration file directory" >&5 +-echo $ECHO_N "checking for autofs configuration file directory... $ECHO_C" >&6; } +-{ echo "$as_me:$LINENO: result: $confdir" >&5 +-echo "${ECHO_T}$confdir" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for autofs configuration file directory" >&5 ++$as_echo_n "checking for autofs configuration file directory... " >&6; } ++{ $as_echo "$as_me:$LINENO: result: $confdir" >&5 ++$as_echo "$confdir" >&6; } + + + # +@@ -1843,10 +1950,10 @@ if test "${with_mapdir+set}" = set; then + + fi + +-{ echo "$as_me:$LINENO: checking for autofs maps directory" >&5 +-echo $ECHO_N "checking for autofs maps directory... $ECHO_C" >&6; } +-{ echo "$as_me:$LINENO: result: $mapdir" >&5 +-echo "${ECHO_T}$mapdir" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for autofs maps directory" >&5 ++$as_echo_n "checking for autofs maps directory... " >&6; } ++{ $as_echo "$as_me:$LINENO: result: $mapdir" >&5 ++$as_echo "$mapdir" >&6; } + + + # +@@ -1873,10 +1980,10 @@ if test "${with_fifodir+set}" = set; then + + fi + +-{ echo "$as_me:$LINENO: checking for autofs fifos directory" >&5 +-echo $ECHO_N "checking for autofs fifos directory... $ECHO_C" >&6; } +-{ echo "$as_me:$LINENO: result: $fifodir" >&5 +-echo "${ECHO_T}$fifodir" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for autofs fifos directory" >&5 ++$as_echo_n "checking for autofs fifos directory... " >&6; } ++{ $as_echo "$as_me:$LINENO: result: $fifodir" >&5 ++$as_echo "$fifodir" >&6; } + + + # +@@ -1903,10 +2010,10 @@ if test "${with_flagdir+set}" = set; then + + fi + +-{ echo "$as_me:$LINENO: checking for autofs flag file directory" >&5 +-echo $ECHO_N "checking for autofs flag file directory... $ECHO_C" >&6; } +-{ echo "$as_me:$LINENO: result: $flagdir" >&5 +-echo "${ECHO_T}$flagdir" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for autofs flag file directory" >&5 ++$as_echo_n "checking for autofs flag file directory... " >&6; } ++{ $as_echo "$as_me:$LINENO: result: $flagdir" >&5 ++$as_echo "$flagdir" >&6; } + + + # +@@ -1920,10 +2027,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. + set dummy ${ac_tool_prefix}gcc; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_prog_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +@@ -1936,7 +2043,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -1947,11 +2054,11 @@ fi + fi + CC=$ac_cv_prog_CC + if test -n "$CC"; then +- { echo "$as_me:$LINENO: result: $CC" >&5 +-echo "${ECHO_T}$CC" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $CC" >&5 ++$as_echo "$CC" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -1960,10 +2067,10 @@ if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. + set dummy gcc; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_prog_ac_ct_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +@@ -1976,7 +2083,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -1987,11 +2094,11 @@ fi + fi + ac_ct_CC=$ac_cv_prog_ac_ct_CC + if test -n "$ac_ct_CC"; then +- { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +-echo "${ECHO_T}$ac_ct_CC" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 ++$as_echo "$ac_ct_CC" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + if test "x$ac_ct_CC" = x; then +@@ -1999,12 +2106,8 @@ fi + else + case $cross_compiling:$ac_tool_warned in + yes:) +-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +-whose name does not start with the host triplet. If you think this +-configuration is useful to you, please write to autoconf@gnu.org." >&5 +-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +-whose name does not start with the host triplet. If you think this +-configuration is useful to you, please write to autoconf@gnu.org." >&2;} ++{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} + ac_tool_warned=yes ;; + esac + CC=$ac_ct_CC +@@ -2017,10 +2120,10 @@ if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. + set dummy ${ac_tool_prefix}cc; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_prog_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +@@ -2033,7 +2136,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -2044,11 +2147,11 @@ fi + fi + CC=$ac_cv_prog_CC + if test -n "$CC"; then +- { echo "$as_me:$LINENO: result: $CC" >&5 +-echo "${ECHO_T}$CC" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $CC" >&5 ++$as_echo "$CC" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -2057,10 +2160,10 @@ fi + if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. + set dummy cc; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_prog_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +@@ -2078,7 +2181,7 @@ do + continue + fi + ac_cv_prog_CC="cc" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -2101,11 +2204,11 @@ fi + fi + CC=$ac_cv_prog_CC + if test -n "$CC"; then +- { echo "$as_me:$LINENO: result: $CC" >&5 +-echo "${ECHO_T}$CC" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $CC" >&5 ++$as_echo "$CC" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -2116,10 +2219,10 @@ if test -z "$CC"; then + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. + set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_prog_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +@@ -2132,7 +2235,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -2143,11 +2246,11 @@ fi + fi + CC=$ac_cv_prog_CC + if test -n "$CC"; then +- { echo "$as_me:$LINENO: result: $CC" >&5 +-echo "${ECHO_T}$CC" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $CC" >&5 ++$as_echo "$CC" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -2160,10 +2263,10 @@ if test -z "$CC"; then + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_prog_ac_ct_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +@@ -2176,7 +2279,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -2187,11 +2290,11 @@ fi + fi + ac_ct_CC=$ac_cv_prog_ac_ct_CC + if test -n "$ac_ct_CC"; then +- { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +-echo "${ECHO_T}$ac_ct_CC" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 ++$as_echo "$ac_ct_CC" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -2203,12 +2306,8 @@ done + else + case $cross_compiling:$ac_tool_warned in + yes:) +-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +-whose name does not start with the host triplet. If you think this +-configuration is useful to you, please write to autoconf@gnu.org." >&5 +-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +-whose name does not start with the host triplet. If you think this +-configuration is useful to you, please write to autoconf@gnu.org." >&2;} ++{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} + ac_tool_warned=yes ;; + esac + CC=$ac_ct_CC +@@ -2218,44 +2317,50 @@ fi + fi + + +-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH ++test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH + See \`config.log' for more details." >&5 +-echo "$as_me: error: no acceptable C compiler found in \$PATH ++$as_echo "$as_me: error: no acceptable C compiler found in \$PATH + See \`config.log' for more details." >&2;} +- { (exit 1); exit 1; }; } ++ { (exit 1); exit 1; }; }; } + + # Provide some information about the compiler. +-echo "$as_me:$LINENO: checking for C compiler version" >&5 +-ac_compiler=`set X $ac_compile; echo $2` ++$as_echo "$as_me:$LINENO: checking for C compiler version" >&5 ++set X $ac_compile ++ac_compiler=$2 + { (ac_try="$ac_compiler --version >&5" + case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + { (ac_try="$ac_compiler -v >&5" + case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + { (ac_try="$ac_compiler -V >&5" + case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + + cat >conftest.$ac_ext <<_ACEOF +@@ -2274,27 +2379,22 @@ main () + } + _ACEOF + ac_clean_files_save=$ac_clean_files +-ac_clean_files="$ac_clean_files a.out a.exe b.out" ++ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" + # Try to create an executable without -o first, disregard a.out. + # It will help us diagnose broken compilers, and finding out an intuition + # of exeext. +-{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +-# +-# List of possible output files, starting from the most likely. +-# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +-# only as a last resort. b.out is created by i960 compilers. +-ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +-# +-# The IRIX 6 linker writes into existing files which may not be +-# executable, retaining their permissions. Remove them first so a +-# subsequent execution test works. ++{ $as_echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 ++$as_echo_n "checking for C compiler default output file name... " >&6; } ++ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` ++ ++# The possible output files: ++ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ++ + ac_rmfiles= + for ac_file in $ac_files + do + case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac + done +@@ -2305,10 +2405,11 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. + # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +@@ -2319,7 +2420,7 @@ for ac_file in $ac_files '' + do + test -f "$ac_file" || continue + case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most +@@ -2346,25 +2447,27 @@ else + ac_file='' + fi + +-{ echo "$as_me:$LINENO: result: $ac_file" >&5 +-echo "${ECHO_T}$ac_file" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5 ++$as_echo "$ac_file" >&6; } + if test -z "$ac_file"; then +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + +-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables ++{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++{ { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables + See \`config.log' for more details." >&5 +-echo "$as_me: error: C compiler cannot create executables ++$as_echo "$as_me: error: C compiler cannot create executables + See \`config.log' for more details." >&2;} +- { (exit 77); exit 77; }; } ++ { (exit 77); exit 77; }; }; } + fi + + ac_exeext=$ac_cv_exeext + + # Check that the compiler produces executables we can run. If not, either + # the compiler is broken, or we cross compile. +-{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5 ++$as_echo_n "checking whether the C compiler works... " >&6; } + # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 + # If not cross compiling, check that we can run a simple program. + if test "$cross_compiling" != yes; then +@@ -2373,49 +2476,53 @@ if test "$cross_compiling" != yes; then + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else +- { { echo "$as_me:$LINENO: error: cannot run C compiled programs. ++ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++{ { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. + If you meant to cross compile, use \`--host'. + See \`config.log' for more details." >&5 +-echo "$as_me: error: cannot run C compiled programs. ++$as_echo "$as_me: error: cannot run C compiled programs. + If you meant to cross compile, use \`--host'. + See \`config.log' for more details." >&2;} +- { (exit 1); exit 1; }; } ++ { (exit 1); exit 1; }; }; } + fi + fi + fi +-{ echo "$as_me:$LINENO: result: yes" >&5 +-echo "${ECHO_T}yes" >&6; } ++{ $as_echo "$as_me:$LINENO: result: yes" >&5 ++$as_echo "yes" >&6; } + +-rm -f a.out a.exe conftest$ac_cv_exeext b.out ++rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out + ac_clean_files=$ac_clean_files_save + # Check that the compiler produces executables we can run. If not, either + # the compiler is broken, or we cross compile. +-{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +-{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +-echo "${ECHO_T}$cross_compiling" >&6; } ++{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 ++$as_echo_n "checking whether we are cross compiling... " >&6; } ++{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 ++$as_echo "$cross_compiling" >&6; } + +-{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5 ++$as_echo_n "checking for suffix of executables... " >&6; } + if { (ac_try="$ac_link" + case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) + # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +@@ -2424,31 +2531,33 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac + done + else +- { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link ++ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link + See \`config.log' for more details." >&5 +-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link ++$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link + See \`config.log' for more details." >&2;} +- { (exit 1); exit 1; }; } ++ { (exit 1); exit 1; }; }; } + fi + + rm -f conftest$ac_cv_exeext +-{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +-echo "${ECHO_T}$ac_cv_exeext" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 ++$as_echo "$ac_cv_exeext" >&6; } + + rm -f conftest.$ac_ext + EXEEXT=$ac_cv_exeext + ac_exeext=$EXEEXT +-{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 ++$as_echo_n "checking for suffix of object files... " >&6; } + if test "${ac_cv_objext+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ +@@ -2471,40 +2580,43 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac + done + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + +-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile ++{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile + See \`config.log' for more details." >&5 +-echo "$as_me: error: cannot compute suffix of object files: cannot compile ++$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile + See \`config.log' for more details." >&2;} +- { (exit 1); exit 1; }; } ++ { (exit 1); exit 1; }; }; } + fi + + rm -f conftest.$ac_cv_objext conftest.$ac_ext + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +-echo "${ECHO_T}$ac_cv_objext" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 ++$as_echo "$ac_cv_objext" >&6; } + OBJEXT=$ac_cv_objext + ac_objext=$OBJEXT +-{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 ++$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } + if test "${ac_cv_c_compiler_gnu+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ +@@ -2530,20 +2642,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +@@ -2553,15 +2666,19 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_c_compiler_gnu=$ac_compiler_gnu + + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +-GCC=`test $ac_compiler_gnu = yes && echo yes` ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 ++$as_echo "$ac_cv_c_compiler_gnu" >&6; } ++if test $ac_compiler_gnu = yes; then ++ GCC=yes ++else ++ GCC= ++fi + ac_test_CFLAGS=${CFLAGS+set} + ac_save_CFLAGS=$CFLAGS +-{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 ++$as_echo_n "checking whether $CC accepts -g... " >&6; } + if test "${ac_cv_prog_cc_g+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes +@@ -2588,20 +2705,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" +@@ -2626,20 +2744,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag +@@ -2665,20 +2784,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + +@@ -2693,8 +2813,8 @@ fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 ++$as_echo "$ac_cv_prog_cc_g" >&6; } + if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS + elif test $ac_cv_prog_cc_g = yes; then +@@ -2710,10 +2830,10 @@ else + CFLAGS= + fi + fi +-{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +-echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 ++$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } + if test "${ac_cv_prog_cc_c89+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + ac_cv_prog_cc_c89=no + ac_save_CC=$CC +@@ -2784,20 +2904,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + +@@ -2813,15 +2934,15 @@ fi + # AC_CACHE_VAL + case "x$ac_cv_prog_cc_c89" in + x) +- { echo "$as_me:$LINENO: result: none needed" >&5 +-echo "${ECHO_T}none needed" >&6; } ;; ++ { $as_echo "$as_me:$LINENO: result: none needed" >&5 ++$as_echo "none needed" >&6; } ;; + xno) +- { echo "$as_me:$LINENO: result: unsupported" >&5 +-echo "${ECHO_T}unsupported" >&6; } ;; ++ { $as_echo "$as_me:$LINENO: result: unsupported" >&5 ++$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" +- { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +-echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; ++ { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 ++$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; + esac + + +@@ -2832,8 +2953,8 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ + ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +-{ echo "$as_me:$LINENO: checking if libtirpc is requested and available" >&5 +-echo $ECHO_N "checking if libtirpc is requested and available... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking if libtirpc is requested and available" >&5 ++$as_echo_n "checking if libtirpc is requested and available... " >&6; } + + # Check whether --with-libtirpc was given. + if test "${with_libtirpc+set}" = set; then +@@ -2870,35 +2991,44 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err +- } && test -s conftest$ac_exeext && +- $as_test_x conftest$ac_exeext; then ++ } && test -s conftest$ac_exeext && { ++ test "$cross_compiling" = yes || ++ $as_test_x conftest$ac_exeext ++ }; then + af_have_libtirpc=yes +- { echo "$as_me:$LINENO: result: yes" >&5 +-echo "${ECHO_T}yes" >&6; } ++ { $as_echo "$as_me:$LINENO: result: yes" >&5 ++$as_echo "yes" >&6; } + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + ++rm -rf conftest.dSYM + rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + + if test "$af_have_libtirpc" = "yes"; then + + cat >>confdefs.h <<\_ACEOF ++#define WITH_LIBTIRPC 1 ++_ACEOF ++ ++ ++cat >>confdefs.h <<\_ACEOF + #define TIRPC_WORKAROUND 1 + _ACEOF + +@@ -2909,8 +3039,8 @@ fi + CFLAGS="$af_check_libtirpc_save_cflags" + LDFLAGS="$af_check_libtirpc_save_ldflags" + +- { echo "$as_me:$LINENO: checking if libtirpc has IPv6 support" >&5 +-echo $ECHO_N "checking if libtirpc has IPv6 support... $ECHO_C" >&6; } ++ { $as_echo "$as_me:$LINENO: checking if libtirpc has IPv6 support" >&5 ++$as_echo_n "checking if libtirpc has IPv6 support... " >&6; } + + # save current flags + af_check_libtirpc_ipv6_save_cflags="$CFLAGS" +@@ -2944,29 +3074,33 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err +- } && test -s conftest$ac_exeext && +- $as_test_x conftest$ac_exeext; then ++ } && test -s conftest$ac_exeext && { ++ test "$cross_compiling" = yes || ++ $as_test_x conftest$ac_exeext ++ }; then + af_have_libtirpc_ipv6=yes +- { echo "$as_me:$LINENO: result: yes" >&5 +-echo "${ECHO_T}yes" >&6; } ++ { $as_echo "$as_me:$LINENO: result: yes" >&5 ++$as_echo "yes" >&6; } + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + ++rm -rf conftest.dSYM + rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + +@@ -2983,12 +3117,12 @@ CFLAGS="$af_check_libtirpc_ipv6_save_cflags" + LDFLAGS="$af_check_libtirpc_ipv6_save_ldflags" + + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -2997,14 +3131,14 @@ fi + # + # Optional include dmalloc + # +-{ echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5 +-echo $ECHO_N "checking if malloc debugging is wanted... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5 ++$as_echo_n "checking if malloc debugging is wanted... " >&6; } + + # Check whether --with-dmalloc was given. + if test "${with_dmalloc+set}" = set; then + withval=$with_dmalloc; if test "$withval" = yes; then +- { echo "$as_me:$LINENO: result: yes" >&5 +-echo "${ECHO_T}yes" >&6; } ++ { $as_echo "$as_me:$LINENO: result: yes" >&5 ++$as_echo "yes" >&6; } + + cat >>confdefs.h <<\_ACEOF + #define WITH_DMALLOC 1 +@@ -3013,12 +3147,12 @@ _ACEOF + DMALLOCLIB="-ldmallocth" + LDFLAGS="$LDFLAGS -g" + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -3031,10 +3165,10 @@ for ac_prog in mount + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_path_MOUNT+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + case $MOUNT in + [\\/]* | ?:[\\/]*) +@@ -3049,7 +3183,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_MOUNT="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -3061,11 +3195,11 @@ esac + fi + MOUNT=$ac_cv_path_MOUNT + if test -n "$MOUNT"; then +- { echo "$as_me:$LINENO: result: $MOUNT" >&5 +-echo "${ECHO_T}$MOUNT" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $MOUNT" >&5 ++$as_echo "$MOUNT" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -3093,10 +3227,10 @@ for ac_prog in umount + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_path_UMOUNT+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + case $UMOUNT in + [\\/]* | ?:[\\/]*) +@@ -3111,7 +3245,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_UMOUNT="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -3123,11 +3257,11 @@ esac + fi + UMOUNT=$ac_cv_path_UMOUNT + if test -n "$UMOUNT"; then +- { echo "$as_me:$LINENO: result: $UMOUNT" >&5 +-echo "${ECHO_T}$UMOUNT" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $UMOUNT" >&5 ++$as_echo "$UMOUNT" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -3155,10 +3289,10 @@ for ac_prog in fsck.ext2 e2fsck + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_path_E2FSCK+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + case $E2FSCK in + [\\/]* | ?:[\\/]*) +@@ -3173,7 +3307,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_E2FSCK="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -3185,11 +3319,11 @@ esac + fi + E2FSCK=$ac_cv_path_E2FSCK + if test -n "$E2FSCK"; then +- { echo "$as_me:$LINENO: result: $E2FSCK" >&5 +-echo "${ECHO_T}$E2FSCK" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $E2FSCK" >&5 ++$as_echo "$E2FSCK" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -3216,10 +3350,10 @@ for ac_prog in fsck.ext3 e3fsck + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_path_E3FSCK+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + case $E3FSCK in + [\\/]* | ?:[\\/]*) +@@ -3234,7 +3368,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_E3FSCK="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -3246,11 +3380,11 @@ esac + fi + E3FSCK=$ac_cv_path_E3FSCK + if test -n "$E3FSCK"; then +- { echo "$as_me:$LINENO: result: $E3FSCK" >&5 +-echo "${ECHO_T}$E3FSCK" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $E3FSCK" >&5 ++$as_echo "$E3FSCK" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -3277,10 +3411,10 @@ for ac_prog in modprobe + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_path_MODPROBE+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + case $MODPROBE in + [\\/]* | ?:[\\/]*) +@@ -3295,7 +3429,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_MODPROBE="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -3307,11 +3441,11 @@ esac + fi + MODPROBE=$ac_cv_path_MODPROBE + if test -n "$MODPROBE"; then +- { echo "$as_me:$LINENO: result: $MODPROBE" >&5 +-echo "${ECHO_T}$MODPROBE" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $MODPROBE" >&5 ++$as_echo "$MODPROBE" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -3339,10 +3473,10 @@ for ac_prog in flex lex + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_path_LEX+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + case $LEX in + [\\/]* | ?:[\\/]*) +@@ -3357,7 +3491,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_LEX="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -3369,11 +3503,11 @@ esac + fi + LEX=$ac_cv_path_LEX + if test -n "$LEX"; then +- { echo "$as_me:$LINENO: result: $LEX" >&5 +-echo "${ECHO_T}$LEX" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $LEX" >&5 ++$as_echo "$LEX" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -3388,8 +3522,8 @@ _ACEOF + + PATH_LEX="$LEX" + else +- { { echo "$as_me:$LINENO: error: required program LEX not found" >&5 +-echo "$as_me: error: required program LEX not found" >&2;} ++ { { $as_echo "$as_me:$LINENO: error: required program LEX not found" >&5 ++$as_echo "$as_me: error: required program LEX not found" >&2;} + { (exit 1); exit 1; }; } + fi + +@@ -3397,10 +3531,10 @@ for ac_prog in bison + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_path_YACC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + case $YACC in + [\\/]* | ?:[\\/]*) +@@ -3415,7 +3549,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_YACC="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -3427,11 +3561,11 @@ esac + fi + YACC=$ac_cv_path_YACC + if test -n "$YACC"; then +- { echo "$as_me:$LINENO: result: $YACC" >&5 +-echo "${ECHO_T}$YACC" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $YACC" >&5 ++$as_echo "$YACC" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -3446,8 +3580,8 @@ _ACEOF + + PATH_YACC="$YACC" + else +- { { echo "$as_me:$LINENO: error: required program YACC not found" >&5 +-echo "$as_me: error: required program YACC not found" >&2;} ++ { { $as_echo "$as_me:$LINENO: error: required program YACC not found" >&5 ++$as_echo "$as_me: error: required program YACC not found" >&2;} + { (exit 1); exit 1; }; } + fi + +@@ -3455,10 +3589,10 @@ for ac_prog in ranlib + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_path_RANLIB+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + case $RANLIB in + [\\/]* | ?:[\\/]*) +@@ -3473,7 +3607,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_RANLIB="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -3485,11 +3619,11 @@ esac + fi + RANLIB=$ac_cv_path_RANLIB + if test -n "$RANLIB"; then +- { echo "$as_me:$LINENO: result: $RANLIB" >&5 +-echo "${ECHO_T}$RANLIB" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $RANLIB" >&5 ++$as_echo "$RANLIB" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -3504,8 +3638,8 @@ _ACEOF + + PATH_RANLIB="$RANLIB" + else +- { { echo "$as_me:$LINENO: error: required program RANLIB not found" >&5 +-echo "$as_me: error: required program RANLIB not found" >&2;} ++ { { $as_echo "$as_me:$LINENO: error: required program RANLIB not found" >&5 ++$as_echo "$as_me: error: required program RANLIB not found" >&2;} + { (exit 1); exit 1; }; } + fi + +@@ -3513,10 +3647,10 @@ for ac_prog in rpcgen + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_path_RPCGEN+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + case $RPCGEN in + [\\/]* | ?:[\\/]*) +@@ -3531,7 +3665,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_RPCGEN="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -3543,11 +3677,11 @@ esac + fi + RPCGEN=$ac_cv_path_RPCGEN + if test -n "$RPCGEN"; then +- { echo "$as_me:$LINENO: result: $RPCGEN" >&5 +-echo "${ECHO_T}$RPCGEN" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $RPCGEN" >&5 ++$as_echo "$RPCGEN" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -3562,8 +3696,8 @@ _ACEOF + + PATH_RPCGEN="$RPCGEN" + else +- { { echo "$as_me:$LINENO: error: required program RPCGEN not found" >&5 +-echo "$as_me: error: required program RPCGEN not found" >&2;} ++ { { $as_echo "$as_me:$LINENO: error: required program RPCGEN not found" >&5 ++$as_echo "$as_me: error: required program RPCGEN not found" >&2;} + { (exit 1); exit 1; }; } + fi + +@@ -3573,19 +3707,19 @@ fi + # good for portability + # + if test -n "$MOUNT" ; then +- { echo "$as_me:$LINENO: checking if mount accepts the -s option" >&5 +-echo $ECHO_N "checking if mount accepts the -s option... $ECHO_C" >&6; } ++ { $as_echo "$as_me:$LINENO: checking if mount accepts the -s option" >&5 ++$as_echo_n "checking if mount accepts the -s option... " >&6; } + if "$MOUNT" -s > /dev/null 2>&1 ; then + + cat >>confdefs.h <<\_ACEOF + #define HAVE_SLOPPY_MOUNT 1 + _ACEOF + +- { echo "$as_me:$LINENO: result: yes" >&5 +-echo "${ECHO_T}yes" >&6; } ++ { $as_echo "$as_me:$LINENO: result: yes" >&5 ++$as_echo "yes" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + fi + +@@ -3594,10 +3728,10 @@ for ac_prog in xml2-config + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_path_XML_CONFIG+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + case $XML_CONFIG in + [\\/]* | ?:[\\/]*) +@@ -3612,7 +3746,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_XML_CONFIG="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -3624,11 +3758,11 @@ esac + fi + XML_CONFIG=$ac_cv_path_XML_CONFIG + if test -n "$XML_CONFIG"; then +- { echo "$as_me:$LINENO: result: $XML_CONFIG" >&5 +-echo "${ECHO_T}$XML_CONFIG" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $XML_CONFIG" >&5 ++$as_echo "$XML_CONFIG" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -3636,16 +3770,16 @@ fi + done + test -n "$XML_CONFIG" || XML_CONFIG="no" + +-{ echo "$as_me:$LINENO: checking for libxml2" >&5 +-echo $ECHO_N "checking for libxml2... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for libxml2" >&5 ++$as_echo_n "checking for libxml2... " >&6; } + if test "$XML_CONFIG" = "no" + then +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + HAVE_LIBXML=0 + else +- { echo "$as_me:$LINENO: result: yes" >&5 +-echo "${ECHO_T}yes" >&6; } ++ { $as_echo "$as_me:$LINENO: result: yes" >&5 ++$as_echo "yes" >&6; } + HAVE_LIBXML=1 + XML_LIBS=`$XML_CONFIG --libs` + XML_FLAGS=`$XML_CONFIG --cflags` +@@ -3671,10 +3805,10 @@ fi + # + # glibc/libc 6 new libraries + # +-{ echo "$as_me:$LINENO: checking for yp_match in -lnsl" >&5 +-echo $ECHO_N "checking for yp_match in -lnsl... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for yp_match in -lnsl" >&5 ++$as_echo_n "checking for yp_match in -lnsl... " >&6; } + if test "${ac_cv_lib_nsl_yp_match+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + ac_check_lib_save_LIBS=$LIBS + LIBS="-lnsl $LIBS" +@@ -3706,42 +3840,46 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err +- } && test -s conftest$ac_exeext && +- $as_test_x conftest$ac_exeext; then ++ } && test -s conftest$ac_exeext && { ++ test "$cross_compiling" = yes || ++ $as_test_x conftest$ac_exeext ++ }; then + ac_cv_lib_nsl_yp_match=yes + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_nsl_yp_match=no + fi + ++rm -rf conftest.dSYM + rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_check_lib_save_LIBS + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_yp_match" >&5 +-echo "${ECHO_T}$ac_cv_lib_nsl_yp_match" >&6; } +-if test $ac_cv_lib_nsl_yp_match = yes; then ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_yp_match" >&5 ++$as_echo "$ac_cv_lib_nsl_yp_match" >&6; } ++if test "x$ac_cv_lib_nsl_yp_match" = x""yes; then + LIBNSL="-lnsl" + fi + + + +-{ echo "$as_me:$LINENO: checking for res_query in -lresolv" >&5 +-echo $ECHO_N "checking for res_query in -lresolv... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for res_query in -lresolv" >&5 ++$as_echo_n "checking for res_query in -lresolv... " >&6; } + if test "${ac_cv_lib_resolv_res_query+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + ac_check_lib_save_LIBS=$LIBS + LIBS="-lresolv $LIBS" +@@ -3773,33 +3911,37 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err +- } && test -s conftest$ac_exeext && +- $as_test_x conftest$ac_exeext; then ++ } && test -s conftest$ac_exeext && { ++ test "$cross_compiling" = yes || ++ $as_test_x conftest$ac_exeext ++ }; then + ac_cv_lib_resolv_res_query=yes + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_resolv_res_query=no + fi + ++rm -rf conftest.dSYM + rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_check_lib_save_LIBS + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_res_query" >&5 +-echo "${ECHO_T}$ac_cv_lib_resolv_res_query" >&6; } +-if test $ac_cv_lib_resolv_res_query = yes; then ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_res_query" >&5 ++$as_echo "$ac_cv_lib_resolv_res_query" >&6; } ++if test "x$ac_cv_lib_resolv_res_query" = x""yes; then + LIBRESOLV="-lresolv" + fi + +@@ -3833,8 +3975,8 @@ fi + if test -z "$HAVE_HESIOD" -o "$HAVE_HESIOD" != "0" + then + HAVE_HESIOD=0 +- { echo "$as_me:$LINENO: checking for libhesiod" >&5 +-echo $ECHO_N "checking for libhesiod... $ECHO_C" >&6; } ++ { $as_echo "$as_me:$LINENO: checking for libhesiod" >&5 ++$as_echo_n "checking for libhesiod... " >&6; } + + # save current ldflags + af_check_hesiod_save_ldflags="$LDFLAGS" +@@ -3861,30 +4003,34 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err +- } && test -s conftest$ac_exeext && +- $as_test_x conftest$ac_exeext; then ++ } && test -s conftest$ac_exeext && { ++ test "$cross_compiling" = yes || ++ $as_test_x conftest$ac_exeext ++ }; then + HAVE_HESIOD=1 + LIBHESIOD="$LIBHESIOD -lhesiod -lresolv" +- { echo "$as_me:$LINENO: result: yes" >&5 +-echo "${ECHO_T}yes" >&6; } ++ { $as_echo "$as_me:$LINENO: result: yes" >&5 ++$as_echo "yes" >&6; } + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + ++rm -rf conftest.dSYM + rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + +@@ -3911,15 +4057,15 @@ ac_cpp='$CPP $CPPFLAGS' + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' + ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' + ac_compiler_gnu=$ac_cv_c_compiler_gnu +-{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 ++$as_echo_n "checking how to run the C preprocessor... " >&6; } + # On Suns, sometimes $CPP names a directory. + if test -n "$CPP" && test -d "$CPP"; then + CPP= + fi + if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" +@@ -3951,20 +4097,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +@@ -3988,13 +4135,14 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err +@@ -4002,7 +4150,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + # Broken: success on invalid input. + continue + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +@@ -4027,8 +4175,8 @@ fi + else + ac_cv_prog_CPP=$CPP + fi +-{ echo "$as_me:$LINENO: result: $CPP" >&5 +-echo "${ECHO_T}$CPP" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $CPP" >&5 ++$as_echo "$CPP" >&6; } + ac_preproc_ok=false + for ac_c_preproc_warn_flag in '' yes + do +@@ -4056,20 +4204,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +@@ -4093,13 +4242,14 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err +@@ -4107,7 +4257,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + # Broken: success on invalid input. + continue + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +@@ -4123,11 +4273,13 @@ rm -f conftest.err conftest.$ac_ext + if $ac_preproc_ok; then + : + else +- { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check ++ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++{ { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check + See \`config.log' for more details." >&5 +-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check ++$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check + See \`config.log' for more details." >&2;} +- { (exit 1); exit 1; }; } ++ { (exit 1); exit 1; }; }; } + fi + + ac_ext=c +@@ -4137,42 +4289,37 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ + ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +-{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +-echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +-if test "${ac_cv_path_GREP+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- # Extract the first word of "grep ggrep" to use in msg output +-if test -z "$GREP"; then +-set dummy grep ggrep; ac_prog_name=$2 ++{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 ++$as_echo_n "checking for grep that handles long lines and -e... " >&6; } + if test "${ac_cv_path_GREP+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else ++ if test -z "$GREP"; then + ac_path_GREP_found=false +-# Loop through the user's path and test for each of PROGNAME-LIST +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin + do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do +- for ac_exec_ext in '' $ac_executable_extensions; do +- ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" +- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +- # Check for GNU ac_path_GREP and select it if it is found. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" ++ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue ++# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP + case `"$ac_path_GREP" --version 2>&1` in + *GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; + *) + ac_count=0 +- echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" ++ $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" +- echo 'GREP' >> "conftest.nl" ++ $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` +@@ -4187,74 +4334,60 @@ case `"$ac_path_GREP" --version 2>&1` in + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; + esac + +- +- $ac_path_GREP_found && break 3 ++ $ac_path_GREP_found && break 3 ++ done + done + done +- +-done + IFS=$as_save_IFS +- +- +-fi +- +-GREP="$ac_cv_path_GREP" +-if test -z "$GREP"; then +- { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} ++ if test -z "$ac_cv_path_GREP"; then ++ { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 ++$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +-fi +- ++ fi + else + ac_cv_path_GREP=$GREP + fi + +- + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +-echo "${ECHO_T}$ac_cv_path_GREP" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 ++$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +-{ echo "$as_me:$LINENO: checking for egrep" >&5 +-echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for egrep" >&5 ++$as_echo_n "checking for egrep... " >&6; } + if test "${ac_cv_path_EGREP+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else +- # Extract the first word of "egrep" to use in msg output +-if test -z "$EGREP"; then +-set dummy egrep; ac_prog_name=$2 +-if test "${ac_cv_path_EGREP+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else ++ if test -z "$EGREP"; then + ac_path_EGREP_found=false +-# Loop through the user's path and test for each of PROGNAME-LIST +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin + do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do +- for ac_exec_ext in '' $ac_executable_extensions; do +- ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" +- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +- # Check for GNU ac_path_EGREP and select it if it is found. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" ++ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue ++# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP + case `"$ac_path_EGREP" --version 2>&1` in + *GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; + *) + ac_count=0 +- echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" ++ $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" +- echo 'EGREP' >> "conftest.nl" ++ $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` +@@ -4269,40 +4402,31 @@ case `"$ac_path_EGREP" --version 2>&1` in + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; + esac + +- +- $ac_path_EGREP_found && break 3 ++ $ac_path_EGREP_found && break 3 ++ done + done + done +- +-done + IFS=$as_save_IFS +- +- +-fi +- +-EGREP="$ac_cv_path_EGREP" +-if test -z "$EGREP"; then +- { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} ++ if test -z "$ac_cv_path_EGREP"; then ++ { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 ++$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +-fi +- ++ fi + else + ac_cv_path_EGREP=$EGREP + fi + +- + fi + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +-echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 ++$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +-{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 ++$as_echo_n "checking for ANSI C header files... " >&6; } + if test "${ac_cv_header_stdc+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ +@@ -4329,20 +4453,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +@@ -4434,37 +4559,40 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : + else +- echo "$as_me: program exited with status $ac_status" >&5 +-echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: program exited with status $ac_status" >&5 ++$as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + ( exit $ac_status ) + ac_cv_header_stdc=no + fi ++rm -rf conftest.dSYM + rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext + fi + + + fi + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +-echo "${ECHO_T}$ac_cv_header_stdc" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 ++$as_echo "$ac_cv_header_stdc" >&6; } + if test $ac_cv_header_stdc = yes; then + + cat >>confdefs.h <<\_ACEOF +@@ -4486,11 +4614,11 @@ fi + for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h + do +-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +-{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } ++as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ++{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 ++$as_echo_n "checking for $ac_header... " >&6; } + if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ +@@ -4508,20 +4636,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +@@ -4529,12 +4658,15 @@ fi + + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi +-ac_res=`eval echo '${'$as_ac_Header'}'` +- { echo "$as_me:$LINENO: result: $ac_res" >&5 +-echo "${ECHO_T}$ac_res" >&6; } +-if test `eval echo '${'$as_ac_Header'}'` = yes; then ++ac_res=`eval 'as_val=${'$as_ac_Header'} ++ $as_echo "$as_val"'` ++ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++as_val=`eval 'as_val=${'$as_ac_Header'} ++ $as_echo "$as_val"'` ++ if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 ++#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 + _ACEOF + + fi +@@ -4543,17 +4675,17 @@ done + + + if test "${ac_cv_header_rpcsvc_nis_h+set}" = set; then +- { echo "$as_me:$LINENO: checking for rpcsvc/nis.h" >&5 +-echo $ECHO_N "checking for rpcsvc/nis.h... $ECHO_C" >&6; } ++ { $as_echo "$as_me:$LINENO: checking for rpcsvc/nis.h" >&5 ++$as_echo_n "checking for rpcsvc/nis.h... " >&6; } + if test "${ac_cv_header_rpcsvc_nis_h+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_header_rpcsvc_nis_h" >&5 +-echo "${ECHO_T}$ac_cv_header_rpcsvc_nis_h" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_rpcsvc_nis_h" >&5 ++$as_echo "$ac_cv_header_rpcsvc_nis_h" >&6; } + else + # Is the header compilable? +-{ echo "$as_me:$LINENO: checking rpcsvc/nis.h usability" >&5 +-echo $ECHO_N "checking rpcsvc/nis.h usability... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking rpcsvc/nis.h usability" >&5 ++$as_echo_n "checking rpcsvc/nis.h usability... " >&6; } + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ + _ACEOF +@@ -4569,32 +4701,33 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no + fi + + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +-echo "${ECHO_T}$ac_header_compiler" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 ++$as_echo "$ac_header_compiler" >&6; } + + # Is the header present? +-{ echo "$as_me:$LINENO: checking rpcsvc/nis.h presence" >&5 +-echo $ECHO_N "checking rpcsvc/nis.h presence... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking rpcsvc/nis.h presence" >&5 ++$as_echo_n "checking rpcsvc/nis.h presence... " >&6; } + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ + _ACEOF +@@ -4608,66 +4741,67 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no + fi + + rm -f conftest.err conftest.$ac_ext +-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +-echo "${ECHO_T}$ac_header_preproc" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 ++$as_echo "$ac_header_preproc" >&6; } + + # So? What about this header? + case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) +- { echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: accepted by the compiler, rejected by the preprocessor!" >&5 +-echo "$as_me: WARNING: rpcsvc/nis.h: accepted by the compiler, rejected by the preprocessor!" >&2;} +- { echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: proceeding with the compiler's result" >&5 +-echo "$as_me: WARNING: rpcsvc/nis.h: proceeding with the compiler's result" >&2;} ++ { $as_echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: accepted by the compiler, rejected by the preprocessor!" >&5 ++$as_echo "$as_me: WARNING: rpcsvc/nis.h: accepted by the compiler, rejected by the preprocessor!" >&2;} ++ { $as_echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: proceeding with the compiler's result" >&5 ++$as_echo "$as_me: WARNING: rpcsvc/nis.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) +- { echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: present but cannot be compiled" >&5 +-echo "$as_me: WARNING: rpcsvc/nis.h: present but cannot be compiled" >&2;} +- { echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: check for missing prerequisite headers?" >&5 +-echo "$as_me: WARNING: rpcsvc/nis.h: check for missing prerequisite headers?" >&2;} +- { echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: see the Autoconf documentation" >&5 +-echo "$as_me: WARNING: rpcsvc/nis.h: see the Autoconf documentation" >&2;} +- { echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: section \"Present But Cannot Be Compiled\"" >&5 +-echo "$as_me: WARNING: rpcsvc/nis.h: section \"Present But Cannot Be Compiled\"" >&2;} +- { echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: proceeding with the preprocessor's result" >&5 +-echo "$as_me: WARNING: rpcsvc/nis.h: proceeding with the preprocessor's result" >&2;} +- { echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: in the future, the compiler will take precedence" >&5 +-echo "$as_me: WARNING: rpcsvc/nis.h: in the future, the compiler will take precedence" >&2;} ++ { $as_echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: present but cannot be compiled" >&5 ++$as_echo "$as_me: WARNING: rpcsvc/nis.h: present but cannot be compiled" >&2;} ++ { $as_echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: check for missing prerequisite headers?" >&5 ++$as_echo "$as_me: WARNING: rpcsvc/nis.h: check for missing prerequisite headers?" >&2;} ++ { $as_echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: see the Autoconf documentation" >&5 ++$as_echo "$as_me: WARNING: rpcsvc/nis.h: see the Autoconf documentation" >&2;} ++ { $as_echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: section \"Present But Cannot Be Compiled\"" >&5 ++$as_echo "$as_me: WARNING: rpcsvc/nis.h: section \"Present But Cannot Be Compiled\"" >&2;} ++ { $as_echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: proceeding with the preprocessor's result" >&5 ++$as_echo "$as_me: WARNING: rpcsvc/nis.h: proceeding with the preprocessor's result" >&2;} ++ { $as_echo "$as_me:$LINENO: WARNING: rpcsvc/nis.h: in the future, the compiler will take precedence" >&5 ++$as_echo "$as_me: WARNING: rpcsvc/nis.h: in the future, the compiler will take precedence" >&2;} + + ;; + esac +-{ echo "$as_me:$LINENO: checking for rpcsvc/nis.h" >&5 +-echo $ECHO_N "checking for rpcsvc/nis.h... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for rpcsvc/nis.h" >&5 ++$as_echo_n "checking for rpcsvc/nis.h... " >&6; } + if test "${ac_cv_header_rpcsvc_nis_h+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + ac_cv_header_rpcsvc_nis_h=$ac_header_preproc + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_header_rpcsvc_nis_h" >&5 +-echo "${ECHO_T}$ac_cv_header_rpcsvc_nis_h" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_rpcsvc_nis_h" >&5 ++$as_echo "$ac_cv_header_rpcsvc_nis_h" >&6; } + + fi +-if test $ac_cv_header_rpcsvc_nis_h = yes; then ++if test "x$ac_cv_header_rpcsvc_nis_h" = x""yes; then + HAVE_NISPLUS=1 + fi + +@@ -4700,10 +4834,10 @@ fi + if test -z "$HAVE_LDAP" -o "$HAVE_LDAP" != "0"; then + HAVE_LDAP=0 + LDAP_FLAGS="$LDAP_FLAGS -DLDAP_DEPRECATED=1" +- { echo "$as_me:$LINENO: checking for ldap_initialize in -lldap" >&5 +-echo $ECHO_N "checking for ldap_initialize in -lldap... $ECHO_C" >&6; } ++ { $as_echo "$as_me:$LINENO: checking for ldap_initialize in -lldap" >&5 ++$as_echo_n "checking for ldap_initialize in -lldap... " >&6; } + if test "${ac_cv_lib_ldap_ldap_initialize+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + ac_check_lib_save_LIBS=$LIBS + LIBS="-lldap -llber -lresolv $LIBS $LIBS" +@@ -4735,33 +4869,37 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err +- } && test -s conftest$ac_exeext && +- $as_test_x conftest$ac_exeext; then ++ } && test -s conftest$ac_exeext && { ++ test "$cross_compiling" = yes || ++ $as_test_x conftest$ac_exeext ++ }; then + ac_cv_lib_ldap_ldap_initialize=yes + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_ldap_ldap_initialize=no + fi + ++rm -rf conftest.dSYM + rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_check_lib_save_LIBS + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_initialize" >&5 +-echo "${ECHO_T}$ac_cv_lib_ldap_ldap_initialize" >&6; } +-if test $ac_cv_lib_ldap_ldap_initialize = yes; then ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_initialize" >&5 ++$as_echo "$ac_cv_lib_ldap_ldap_initialize" >&6; } ++if test "x$ac_cv_lib_ldap_ldap_initialize" = x""yes; then + HAVE_LDAP=1 LIBLDAP="$LIBLDAP -lldap -llber -lresolv" + fi + +@@ -4772,8 +4910,8 @@ cat >>confdefs.h <<\_ACEOF + _ACEOF + + fi +- { echo "$as_me:$LINENO: checking for ldap_create_page_control in -lldap" >&5 +-echo $ECHO_N "checking for ldap_create_page_control in -lldap... $ECHO_C" >&6; } ++ { $as_echo "$as_me:$LINENO: checking for ldap_create_page_control in -lldap" >&5 ++$as_echo_n "checking for ldap_create_page_control in -lldap... " >&6; } + + # save current libs + af_check_ldap_create_page_control_save_libs="$LIBS" +@@ -4805,29 +4943,33 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err +- } && test -s conftest$ac_exeext && +- $as_test_x conftest$ac_exeext; then ++ } && test -s conftest$ac_exeext && { ++ test "$cross_compiling" = yes || ++ $as_test_x conftest$ac_exeext ++ }; then + af_have_ldap_create_page_control=yes +- { echo "$as_me:$LINENO: result: yes" >&5 +-echo "${ECHO_T}yes" >&6; } ++ { $as_echo "$as_me:$LINENO: result: yes" >&5 ++$as_echo "yes" >&6; } + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + ++rm -rf conftest.dSYM + rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + +@@ -4842,8 +4984,8 @@ fi + # restore libs + LIBS="$af_check_ldap_create_page_control_save_libs" + +- { echo "$as_me:$LINENO: checking for ldap_parse_page_control in -lldap" >&5 +-echo $ECHO_N "checking for ldap_parse_page_control in -lldap... $ECHO_C" >&6; } ++ { $as_echo "$as_me:$LINENO: checking for ldap_parse_page_control in -lldap" >&5 ++$as_echo_n "checking for ldap_parse_page_control in -lldap... " >&6; } + + # save current libs + af_check_ldap_parse_page_control_save_libs="$LIBS" +@@ -4875,29 +5017,33 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err +- } && test -s conftest$ac_exeext && +- $as_test_x conftest$ac_exeext; then ++ } && test -s conftest$ac_exeext && { ++ test "$cross_compiling" = yes || ++ $as_test_x conftest$ac_exeext ++ }; then + af_have_ldap_parse_page_control=yes +- { echo "$as_me:$LINENO: result: yes" >&5 +-echo "${ECHO_T}yes" >&6; } ++ { $as_echo "$as_me:$LINENO: result: yes" >&5 ++$as_echo "yes" >&6; } + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + ++rm -rf conftest.dSYM + rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + +@@ -4949,10 +5095,10 @@ fi + if test -z "$HAVE_SASL" -o "$HAVE_SASL" != "0" -a "$HAVE_LIBXML" == "1" + then + HAVE_SASL=0 +- { echo "$as_me:$LINENO: checking for sasl_client_start in -lsasl2" >&5 +-echo $ECHO_N "checking for sasl_client_start in -lsasl2... $ECHO_C" >&6; } ++ { $as_echo "$as_me:$LINENO: checking for sasl_client_start in -lsasl2" >&5 ++$as_echo_n "checking for sasl_client_start in -lsasl2... " >&6; } + if test "${ac_cv_lib_sasl2_sasl_client_start+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + ac_check_lib_save_LIBS=$LIBS + LIBS="-lsasl2 -lsasl2 $LIBS $LIBS" +@@ -4984,33 +5130,37 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err +- } && test -s conftest$ac_exeext && +- $as_test_x conftest$ac_exeext; then ++ } && test -s conftest$ac_exeext && { ++ test "$cross_compiling" = yes || ++ $as_test_x conftest$ac_exeext ++ }; then + ac_cv_lib_sasl2_sasl_client_start=yes + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_sasl2_sasl_client_start=no + fi + ++rm -rf conftest.dSYM + rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_check_lib_save_LIBS + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_lib_sasl2_sasl_client_start" >&5 +-echo "${ECHO_T}$ac_cv_lib_sasl2_sasl_client_start" >&6; } +-if test $ac_cv_lib_sasl2_sasl_client_start = yes; then ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_sasl2_sasl_client_start" >&5 ++$as_echo "$ac_cv_lib_sasl2_sasl_client_start" >&6; } ++if test "x$ac_cv_lib_sasl2_sasl_client_start" = x""yes; then + HAVE_SASL=1 LIBSASL="$LIBSASL -lsasl2" + fi + +@@ -5041,10 +5191,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. + set dummy ${ac_tool_prefix}gcc; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_prog_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +@@ -5057,7 +5207,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -5068,11 +5218,11 @@ fi + fi + CC=$ac_cv_prog_CC + if test -n "$CC"; then +- { echo "$as_me:$LINENO: result: $CC" >&5 +-echo "${ECHO_T}$CC" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $CC" >&5 ++$as_echo "$CC" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -5081,10 +5231,10 @@ if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. + set dummy gcc; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_prog_ac_ct_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +@@ -5097,7 +5247,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -5108,11 +5258,11 @@ fi + fi + ac_ct_CC=$ac_cv_prog_ac_ct_CC + if test -n "$ac_ct_CC"; then +- { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +-echo "${ECHO_T}$ac_ct_CC" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 ++$as_echo "$ac_ct_CC" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + if test "x$ac_ct_CC" = x; then +@@ -5120,12 +5270,8 @@ fi + else + case $cross_compiling:$ac_tool_warned in + yes:) +-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +-whose name does not start with the host triplet. If you think this +-configuration is useful to you, please write to autoconf@gnu.org." >&5 +-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +-whose name does not start with the host triplet. If you think this +-configuration is useful to you, please write to autoconf@gnu.org." >&2;} ++{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} + ac_tool_warned=yes ;; + esac + CC=$ac_ct_CC +@@ -5138,10 +5284,10 @@ if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. + set dummy ${ac_tool_prefix}cc; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_prog_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +@@ -5154,7 +5300,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -5165,11 +5311,11 @@ fi + fi + CC=$ac_cv_prog_CC + if test -n "$CC"; then +- { echo "$as_me:$LINENO: result: $CC" >&5 +-echo "${ECHO_T}$CC" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $CC" >&5 ++$as_echo "$CC" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -5178,10 +5324,10 @@ fi + if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. + set dummy cc; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_prog_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +@@ -5199,7 +5345,7 @@ do + continue + fi + ac_cv_prog_CC="cc" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -5222,11 +5368,11 @@ fi + fi + CC=$ac_cv_prog_CC + if test -n "$CC"; then +- { echo "$as_me:$LINENO: result: $CC" >&5 +-echo "${ECHO_T}$CC" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $CC" >&5 ++$as_echo "$CC" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -5237,10 +5383,10 @@ if test -z "$CC"; then + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. + set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_prog_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +@@ -5253,7 +5399,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -5264,11 +5410,11 @@ fi + fi + CC=$ac_cv_prog_CC + if test -n "$CC"; then +- { echo "$as_me:$LINENO: result: $CC" >&5 +-echo "${ECHO_T}$CC" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $CC" >&5 ++$as_echo "$CC" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -5281,10 +5427,10 @@ if test -z "$CC"; then + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 ++$as_echo_n "checking for $ac_word... " >&6; } + if test "${ac_cv_prog_ac_ct_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +@@ -5297,7 +5443,7 @@ do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi + done +@@ -5308,11 +5454,11 @@ fi + fi + ac_ct_CC=$ac_cv_prog_ac_ct_CC + if test -n "$ac_ct_CC"; then +- { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +-echo "${ECHO_T}$ac_ct_CC" >&6; } ++ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 ++$as_echo "$ac_ct_CC" >&6; } + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { $as_echo "$as_me:$LINENO: result: no" >&5 ++$as_echo "no" >&6; } + fi + + +@@ -5324,12 +5470,8 @@ done + else + case $cross_compiling:$ac_tool_warned in + yes:) +-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +-whose name does not start with the host triplet. If you think this +-configuration is useful to you, please write to autoconf@gnu.org." >&5 +-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +-whose name does not start with the host triplet. If you think this +-configuration is useful to you, please write to autoconf@gnu.org." >&2;} ++{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 ++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} + ac_tool_warned=yes ;; + esac + CC=$ac_ct_CC +@@ -5339,50 +5481,56 @@ fi + fi + + +-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH ++test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH + See \`config.log' for more details." >&5 +-echo "$as_me: error: no acceptable C compiler found in \$PATH ++$as_echo "$as_me: error: no acceptable C compiler found in \$PATH + See \`config.log' for more details." >&2;} +- { (exit 1); exit 1; }; } ++ { (exit 1); exit 1; }; }; } + + # Provide some information about the compiler. +-echo "$as_me:$LINENO: checking for C compiler version" >&5 +-ac_compiler=`set X $ac_compile; echo $2` ++$as_echo "$as_me:$LINENO: checking for C compiler version" >&5 ++set X $ac_compile ++ac_compiler=$2 + { (ac_try="$ac_compiler --version >&5" + case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + { (ac_try="$ac_compiler -v >&5" + case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + { (ac_try="$ac_compiler -V >&5" + case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +-{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 ++$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } + if test "${ac_cv_c_compiler_gnu+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ +@@ -5408,20 +5556,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +@@ -5431,15 +5580,19 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_c_compiler_gnu=$ac_compiler_gnu + + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +-GCC=`test $ac_compiler_gnu = yes && echo yes` ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 ++$as_echo "$ac_cv_c_compiler_gnu" >&6; } ++if test $ac_compiler_gnu = yes; then ++ GCC=yes ++else ++ GCC= ++fi + ac_test_CFLAGS=${CFLAGS+set} + ac_save_CFLAGS=$CFLAGS +-{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 ++$as_echo_n "checking whether $CC accepts -g... " >&6; } + if test "${ac_cv_prog_cc_g+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes +@@ -5466,20 +5619,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" +@@ -5504,20 +5658,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag +@@ -5543,20 +5698,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + +@@ -5571,8 +5727,8 @@ fi + rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag + fi +-{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 ++$as_echo "$ac_cv_prog_cc_g" >&6; } + if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS + elif test $ac_cv_prog_cc_g = yes; then +@@ -5588,10 +5744,10 @@ else + CFLAGS= + fi + fi +-{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +-echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 ++$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } + if test "${ac_cv_prog_cc_c89+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++ $as_echo_n "(cached) " >&6 + else + ac_cv_prog_cc_c89=no + ac_save_CC=$CC +@@ -5662,20 +5818,21 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg + else +- echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + +@@ -5691,15 +5848,15 @@ fi + # AC_CACHE_VAL + case "x$ac_cv_prog_cc_c89" in + x) +- { echo "$as_me:$LINENO: result: none needed" >&5 +-echo "${ECHO_T}none needed" >&6; } ;; ++ { $as_echo "$as_me:$LINENO: result: none needed" >&5 ++$as_echo "none needed" >&6; } ;; + xno) +- { echo "$as_me:$LINENO: result: unsupported" >&5 +-echo "${ECHO_T}unsupported" >&6; } ;; ++ { $as_echo "$as_me:$LINENO: result: unsupported" >&5 ++$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" +- { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +-echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; ++ { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 ++$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; + esac + + +@@ -5716,14 +5873,16 @@ CFLAGS=-fPIE + LDFLAGS=-pie + DAEMON_CFLAGS= + DAEMON_LDFLAGS= +-{ echo "$as_me:$LINENO: checking whether gcc -fPIE works" >&5 +-echo $ECHO_N "checking whether gcc -fPIE works... $ECHO_C" >&6; } ++{ $as_echo "$as_me:$LINENO: checking whether gcc -fPIE works" >&5 ++$as_echo_n "checking whether gcc -fPIE works... " >&6; } + if test "$cross_compiling" = yes; then +- { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling ++ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++{ { $as_echo "$as_me:$LINENO: error: cannot run test program while cross compiling + See \`config.log' for more details." >&5 +-echo "$as_me: error: cannot run test program while cross compiling ++$as_echo "$as_me: error: cannot run test program while cross compiling + See \`config.log' for more details." >&2;} +- { (exit 1); exit 1; }; } ++ { (exit 1); exit 1; }; }; } + else + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ +@@ -5746,35 +5905,38 @@ case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; + esac +-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" ++$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + gcc_supports_pie=yes + else +- echo "$as_me: program exited with status $ac_status" >&5 +-echo "$as_me: failed program was:" >&5 ++ $as_echo "$as_me: program exited with status $ac_status" >&5 ++$as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + + ( exit $ac_status ) + gcc_supports_pie=no + fi ++rm -rf conftest.dSYM + rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext + fi + + +-{ echo "$as_me:$LINENO: result: $gcc_supports_pie" >&5 +-echo "${ECHO_T}$gcc_supports_pie" >&6; } ++{ $as_echo "$as_me:$LINENO: result: $gcc_supports_pie" >&5 ++$as_echo "$gcc_supports_pie" >&6; } + if test $gcc_supports_pie = yes ; then + DAEMON_CFLAGS="-fPIE" + DAEMON_LDFLAGS="-pie" +@@ -5875,7 +6037,7 @@ ac_ltlibobjs= + for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' +- ac_i=`echo "$ac_i" | sed "$ac_script"` ++ ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" +@@ -5888,11 +6050,12 @@ LTLIBOBJS=$ac_ltlibobjs + + + : ${CONFIG_STATUS=./config.status} ++ac_write_fail=0 + ac_clean_files_save=$ac_clean_files + ac_clean_files="$ac_clean_files $CONFIG_STATUS" +-{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +-echo "$as_me: creating $CONFIG_STATUS" >&6;} +-cat >$CONFIG_STATUS <<_ACEOF ++{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 ++$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} ++cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + #! $SHELL + # Generated by $as_me. + # Run this file to recreate the current configuration. +@@ -5905,7 +6068,7 @@ ac_cs_silent=false + SHELL=\${CONFIG_SHELL-$SHELL} + _ACEOF + +-cat >>$CONFIG_STATUS <<\_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + ## --------------------- ## + ## M4sh Initialization. ## + ## --------------------- ## +@@ -5915,7 +6078,7 @@ DUALCASE=1; export DUALCASE # for MKS sh + if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which ++ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +@@ -5937,17 +6100,45 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS + as_cr_digits='0123456789' + as_cr_alnum=$as_cr_Letters$as_cr_digits + +-# The user is always right. +-if test "${PATH_SEPARATOR+set}" != set; then +- echo "#! /bin/sh" >conf$$.sh +- echo "exit 0" >>conf$$.sh +- chmod +x conf$$.sh +- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then +- PATH_SEPARATOR=';' ++as_nl=' ++' ++export as_nl ++# Printing a long string crashes Solaris 7 /usr/bin/printf. ++as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo ++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo ++if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then ++ as_echo='printf %s\n' ++ as_echo_n='printf %s' ++else ++ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then ++ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' ++ as_echo_n='/usr/ucb/echo -n' + else +- PATH_SEPARATOR=: ++ as_echo_body='eval expr "X$1" : "X\\(.*\\)"' ++ as_echo_n_body='eval ++ arg=$1; ++ case $arg in ++ *"$as_nl"*) ++ expr "X$arg" : "X\\(.*\\)$as_nl"; ++ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; ++ esac; ++ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ++ ' ++ export as_echo_n_body ++ as_echo_n='sh -c $as_echo_n_body as_echo' + fi +- rm -f conf$$.sh ++ export as_echo_body ++ as_echo='sh -c $as_echo_body as_echo' ++fi ++ ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ PATH_SEPARATOR=: ++ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { ++ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || ++ PATH_SEPARATOR=';' ++ } + fi + + # Support unset when possible. +@@ -5963,8 +6154,6 @@ fi + # there to prevent editors from complaining about space-tab. + # (If _AS_PATH_WALK were called with IFS unset, it would disable word + # splitting by setting IFS to empty value.) +-as_nl=' +-' + IFS=" "" $as_nl" + + # Find who we are. Look in the path if we contain no directory separator. +@@ -5987,7 +6176,7 @@ if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then +- echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 ++ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } + fi + +@@ -6000,17 +6189,10 @@ PS2='> ' + PS4='+ ' + + # NLS nuisances. +-for as_var in \ +- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ +- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ +- LC_TELEPHONE LC_TIME +-do +- if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then +- eval $as_var=C; export $as_var +- else +- ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +- fi +-done ++LC_ALL=C ++export LC_ALL ++LANGUAGE=C ++export LANGUAGE + + # Required to use basename. + if expr a : '\(a\)' >/dev/null 2>&1 && +@@ -6032,7 +6214,7 @@ as_me=`$as_basename -- "$0" || + $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +-echo X/"$0" | ++$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q +@@ -6083,7 +6265,7 @@ $as_unset CDPATH + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || +- { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 ++ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems +@@ -6111,7 +6293,6 @@ case `echo -n x` in + *) + ECHO_N='-n';; + esac +- + if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +@@ -6124,19 +6305,22 @@ if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file + else + rm -f conf$$.dir +- mkdir conf$$.dir +-fi +-echo >conf$$.file +-if ln -s conf$$.file conf$$ 2>/dev/null; then +- as_ln_s='ln -s' +- # ... but there are two gotchas: +- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. +- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. +- # In both cases, we have to default to `cp -p'. +- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || ++ mkdir conf$$.dir 2>/dev/null ++fi ++if (echo >conf$$.file) 2>/dev/null; then ++ if ln -s conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s='ln -s' ++ # ... but there are two gotchas: ++ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. ++ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. ++ # In both cases, we have to default to `cp -p'. ++ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || ++ as_ln_s='cp -p' ++ elif ln conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s=ln ++ else + as_ln_s='cp -p' +-elif ln conf$$.file conf$$ 2>/dev/null; then +- as_ln_s=ln ++ fi + else + as_ln_s='cp -p' + fi +@@ -6161,10 +6345,10 @@ else + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then +- test -d "$1/."; ++ test -d "$1/."; + else + case $1 in +- -*)set "./$1";; ++ -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi +@@ -6187,7 +6371,7 @@ exec 6>&1 + # values after options handling. + ac_log=" + This file was extended by $as_me, which was +-generated by GNU Autoconf 2.61. Invocation command line was ++generated by GNU Autoconf 2.63. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS +@@ -6200,29 +6384,39 @@ on `(hostname || uname -n) 2>/dev/null | sed 1q` + + _ACEOF + +-cat >>$CONFIG_STATUS <<_ACEOF ++case $ac_config_files in *" ++"*) set x $ac_config_files; shift; ac_config_files=$*;; ++esac ++ ++case $ac_config_headers in *" ++"*) set x $ac_config_headers; shift; ac_config_headers=$*;; ++esac ++ ++ ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + # Files that config.status was made for. + config_files="$ac_config_files" + config_headers="$ac_config_headers" + + _ACEOF + +-cat >>$CONFIG_STATUS <<\_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + ac_cs_usage="\ + \`$as_me' instantiates files from templates according to the + current configuration. + +-Usage: $0 [OPTIONS] [FILE]... ++Usage: $0 [OPTION]... [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit +- -q, --quiet do not print progress messages ++ -q, --quiet, --silent ++ do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions +- --file=FILE[:TEMPLATE] +- instantiate the configuration file FILE +- --header=FILE[:TEMPLATE] +- instantiate the configuration header FILE ++ --file=FILE[:TEMPLATE] ++ instantiate the configuration file FILE ++ --header=FILE[:TEMPLATE] ++ instantiate the configuration header FILE + + Configuration files: + $config_files +@@ -6233,23 +6427,23 @@ $config_headers + Report bugs to ." + + _ACEOF +-cat >>$CONFIG_STATUS <<_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_cs_version="\\ + config.status +-configured by $0, generated by GNU Autoconf 2.61, +- with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" ++configured by $0, generated by GNU Autoconf 2.63, ++ with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +-Copyright (C) 2006 Free Software Foundation, Inc. ++Copyright (C) 2008 Free Software Foundation, Inc. + This config.status script is free software; the Free Software Foundation + gives unlimited permission to copy, distribute and modify it." + + ac_pwd='$ac_pwd' + srcdir='$srcdir' ++test -n "\$AWK" || AWK=awk + _ACEOF + +-cat >>$CONFIG_STATUS <<\_ACEOF +-# If no file are specified by the user, then we need to provide default +-# value. By we need to know if files were specified by the user. ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++# The default lists apply if the user does not specify any file. + ac_need_defaults=: + while test $# != 0 + do +@@ -6271,30 +6465,36 @@ do + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) +- echo "$ac_cs_version"; exit ;; ++ $as_echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift +- CONFIG_FILES="$CONFIG_FILES $ac_optarg" ++ case $ac_optarg in ++ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; ++ esac ++ CONFIG_FILES="$CONFIG_FILES '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift +- CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ++ case $ac_optarg in ++ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; ++ esac ++ CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header +- { echo "$as_me: error: ambiguous option: $1 ++ { $as_echo "$as_me: error: ambiguous option: $1 + Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) +- echo "$ac_cs_usage"; exit ;; ++ $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. +- -*) { echo "$as_me: error: unrecognized option: $1 ++ -*) { $as_echo "$as_me: error: unrecognized option: $1 + Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + +@@ -6313,30 +6513,32 @@ if $ac_cs_silent; then + fi + + _ACEOF +-cat >>$CONFIG_STATUS <<_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + if \$ac_cs_recheck; then +- echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 +- CONFIG_SHELL=$SHELL ++ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion ++ shift ++ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 ++ CONFIG_SHELL='$SHELL' + export CONFIG_SHELL +- exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion ++ exec "\$@" + fi + + _ACEOF +-cat >>$CONFIG_STATUS <<\_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + exec 5>>config.log + { + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX + ## Running $as_me. ## + _ASBOX +- echo "$ac_log" ++ $as_echo "$ac_log" + } >&5 + + _ACEOF +-cat >>$CONFIG_STATUS <<_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + _ACEOF + +-cat >>$CONFIG_STATUS <<\_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + + # Handling of arguments. + for ac_config_target in $ac_config_targets +@@ -6345,8 +6547,8 @@ do + "include/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/config.h" ;; + "Makefile.conf") CONFIG_FILES="$CONFIG_FILES Makefile.conf" ;; + +- *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +-echo "$as_me: error: invalid argument: $ac_config_target" >&2;} ++ *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 ++$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac + done +@@ -6386,156 +6588,144 @@ $debug || + (umask 077 && mkdir "$tmp") + } || + { +- echo "$me: cannot create a temporary directory in ." >&2 ++ $as_echo "$as_me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } + } + +-# +-# Set up the sed scripts for CONFIG_FILES section. +-# +- +-# No need to generate the scripts if there are no CONFIG_FILES. +-# This happens for instance when ./config.status config.h ++# Set up the scripts for CONFIG_FILES section. ++# No need to generate them if there are no CONFIG_FILES. ++# This happens for instance with `./config.status config.h'. + if test -n "$CONFIG_FILES"; then + +-_ACEOF + ++ac_cr=' +' ++ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` ++if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ++ ac_cs_awk_cr='\\r' ++else ++ ac_cs_awk_cr=$ac_cr ++fi ++ ++echo 'BEGIN {' >"$tmp/subs1.awk" && ++_ACEOF + + ++{ ++ echo "cat >conf$$subs.awk <<_ACEOF" && ++ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && ++ echo "_ACEOF" ++} >conf$$subs.sh || ++ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 ++$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} ++ { (exit 1); exit 1; }; } ++ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` + ac_delim='%!_!# ' + for ac_last_try in false false false false false :; do +- cat >conf$$subs.sed <<_ACEOF +-SHELL!$SHELL$ac_delim +-PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +-PACKAGE_NAME!$PACKAGE_NAME$ac_delim +-PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +-PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +-PACKAGE_STRING!$PACKAGE_STRING$ac_delim +-PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +-exec_prefix!$exec_prefix$ac_delim +-prefix!$prefix$ac_delim +-program_transform_name!$program_transform_name$ac_delim +-bindir!$bindir$ac_delim +-sbindir!$sbindir$ac_delim +-libexecdir!$libexecdir$ac_delim +-datarootdir!$datarootdir$ac_delim +-datadir!$datadir$ac_delim +-sysconfdir!$sysconfdir$ac_delim +-sharedstatedir!$sharedstatedir$ac_delim +-localstatedir!$localstatedir$ac_delim +-includedir!$includedir$ac_delim +-oldincludedir!$oldincludedir$ac_delim +-docdir!$docdir$ac_delim +-infodir!$infodir$ac_delim +-htmldir!$htmldir$ac_delim +-dvidir!$dvidir$ac_delim +-pdfdir!$pdfdir$ac_delim +-psdir!$psdir$ac_delim +-libdir!$libdir$ac_delim +-localedir!$localedir$ac_delim +-mandir!$mandir$ac_delim +-DEFS!$DEFS$ac_delim +-ECHO_C!$ECHO_C$ac_delim +-ECHO_N!$ECHO_N$ac_delim +-ECHO_T!$ECHO_T$ac_delim +-LIBS!$LIBS$ac_delim +-build_alias!$build_alias$ac_delim +-host_alias!$host_alias$ac_delim +-target_alias!$target_alias$ac_delim +-initdir!$initdir$ac_delim +-confdir!$confdir$ac_delim +-mapdir!$mapdir$ac_delim +-fifodir!$fifodir$ac_delim +-flagdir!$flagdir$ac_delim +-CC!$CC$ac_delim +-CFLAGS!$CFLAGS$ac_delim +-LDFLAGS!$LDFLAGS$ac_delim +-CPPFLAGS!$CPPFLAGS$ac_delim +-ac_ct_CC!$ac_ct_CC$ac_delim +-EXEEXT!$EXEEXT$ac_delim +-OBJEXT!$OBJEXT$ac_delim +-TIRPCLIB!$TIRPCLIB$ac_delim +-DMALLOCLIB!$DMALLOCLIB$ac_delim +-MOUNT!$MOUNT$ac_delim +-HAVE_MOUNT!$HAVE_MOUNT$ac_delim +-UMOUNT!$UMOUNT$ac_delim +-HAVE_UMOUNT!$HAVE_UMOUNT$ac_delim +-E2FSCK!$E2FSCK$ac_delim +-HAVE_E2FSCK!$HAVE_E2FSCK$ac_delim +-E3FSCK!$E3FSCK$ac_delim +-HAVE_E3FSCK!$HAVE_E3FSCK$ac_delim +-MODPROBE!$MODPROBE$ac_delim +-HAVE_MODPROBE!$HAVE_MODPROBE$ac_delim +-LEX!$LEX$ac_delim +-PATH_LEX!$PATH_LEX$ac_delim +-YACC!$YACC$ac_delim +-PATH_YACC!$PATH_YACC$ac_delim +-RANLIB!$RANLIB$ac_delim +-PATH_RANLIB!$PATH_RANLIB$ac_delim +-RPCGEN!$RPCGEN$ac_delim +-PATH_RPCGEN!$PATH_RPCGEN$ac_delim +-XML_CONFIG!$XML_CONFIG$ac_delim +-LIBNSL!$LIBNSL$ac_delim +-LIBRESOLV!$LIBRESOLV$ac_delim +-HAVE_HESIOD!$HAVE_HESIOD$ac_delim +-LIBHESIOD!$LIBHESIOD$ac_delim +-HESIOD_FLAGS!$HESIOD_FLAGS$ac_delim +-CPP!$CPP$ac_delim +-GREP!$GREP$ac_delim +-EGREP!$EGREP$ac_delim +-HAVE_NISPLUS!$HAVE_NISPLUS$ac_delim +-LDAP_FLAGS!$LDAP_FLAGS$ac_delim +-HAVE_LDAP!$HAVE_LDAP$ac_delim +-LIBLDAP!$LIBLDAP$ac_delim +-XML_FLAGS!$XML_FLAGS$ac_delim +-XML_LIBS!$XML_LIBS$ac_delim +-SASL_FLAGS!$SASL_FLAGS$ac_delim +-HAVE_SASL!$HAVE_SASL$ac_delim +-LIBSASL!$LIBSASL$ac_delim +-DAEMON_CFLAGS!$DAEMON_CFLAGS$ac_delim +-DAEMON_LDFLAGS!$DAEMON_LDFLAGS$ac_delim +-LIBOBJS!$LIBOBJS$ac_delim +-LTLIBOBJS!$LTLIBOBJS$ac_delim +-_ACEOF +- +- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 91; then ++ . ./conf$$subs.sh || ++ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 ++$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} ++ { (exit 1); exit 1; }; } ++ ++ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` ++ if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then +- { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +-echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} ++ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 ++$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi + done ++rm -f conf$$subs.sh ++ ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++cat >>"\$tmp/subs1.awk" <<\\_ACAWK && ++_ACEOF ++sed -n ' ++h ++s/^/S["/; s/!.*/"]=/ ++p ++g ++s/^[^!]*!// ++:repl ++t repl ++s/'"$ac_delim"'$// ++t delim ++:nl ++h ++s/\(.\{148\}\).*/\1/ ++t more1 ++s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ ++p ++n ++b repl ++:more1 ++s/["\\]/\\&/g; s/^/"/; s/$/"\\/ ++p ++g ++s/.\{148\}// ++t nl ++:delim ++h ++s/\(.\{148\}\).*/\1/ ++t more2 ++s/["\\]/\\&/g; s/^/"/; s/$/"/ ++p ++b ++:more2 ++s/["\\]/\\&/g; s/^/"/; s/$/"\\/ ++p ++g ++s/.\{148\}// ++t delim ++' >$CONFIG_STATUS || ac_write_fail=1 ++rm -f conf$$subs.awk ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++_ACAWK ++cat >>"\$tmp/subs1.awk" <<_ACAWK && ++ for (key in S) S_is_set[key] = 1 ++ FS = "" + +-ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +-if test -n "$ac_eof"; then +- ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` +- ac_eof=`expr $ac_eof + 1` +-fi ++} ++{ ++ line = $ 0 ++ nfields = split(line, field, "@") ++ substed = 0 ++ len = length(field[1]) ++ for (i = 2; i < nfields; i++) { ++ key = field[i] ++ keylen = length(key) ++ if (S_is_set[key]) { ++ value = S[key] ++ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) ++ len += length(value) + length(field[++i]) ++ substed = 1 ++ } else ++ len += 1 + keylen ++ } ++ ++ print line ++} + +-cat >>$CONFIG_STATUS <<_ACEOF +-cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end ++_ACAWK + _ACEOF +-sed ' +-s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +-s/^/s,@/; s/!/@,|#_!!_#|/ +-:n +-t n +-s/'"$ac_delim"'$/,g/; t +-s/$/\\/; p +-N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +-' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +-:end +-s/|#_!!_#|//g +-CEOF$ac_eof ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then ++ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" ++else ++ cat ++fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ ++ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 ++$as_echo "$as_me: error: could not setup config files machinery" >&2;} ++ { (exit 1); exit 1; }; } + _ACEOF + +- + # VPATH may cause trouble with some makes, so we remove $(srcdir), + # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and + # trailing colons and then remove the whole line if VPATH becomes empty +@@ -6551,19 +6741,133 @@ s/^[^=]*=[ ]*$// + }' + fi + +-cat >>$CONFIG_STATUS <<\_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + fi # test -n "$CONFIG_FILES" + ++# Set up the scripts for CONFIG_HEADERS section. ++# No need to generate them if there are no CONFIG_HEADERS. ++# This happens for instance with `./config.status Makefile'. ++if test -n "$CONFIG_HEADERS"; then ++cat >"$tmp/defines.awk" <<\_ACAWK || ++BEGIN { ++_ACEOF ++ ++# Transform confdefs.h into an awk script `defines.awk', embedded as ++# here-document in config.status, that substitutes the proper values into ++# config.h.in to produce config.h. + +-for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS ++# Create a delimiter string that does not exist in confdefs.h, to ease ++# handling of long lines. ++ac_delim='%!_!# ' ++for ac_last_try in false false :; do ++ ac_t=`sed -n "/$ac_delim/p" confdefs.h` ++ if test -z "$ac_t"; then ++ break ++ elif $ac_last_try; then ++ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 ++$as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} ++ { (exit 1); exit 1; }; } ++ else ++ ac_delim="$ac_delim!$ac_delim _$ac_delim!! " ++ fi ++done ++ ++# For the awk script, D is an array of macro values keyed by name, ++# likewise P contains macro parameters if any. Preserve backslash ++# newline sequences. ++ ++ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* ++sed -n ' ++s/.\{148\}/&'"$ac_delim"'/g ++t rset ++:rset ++s/^[ ]*#[ ]*define[ ][ ]*/ / ++t def ++d ++:def ++s/\\$// ++t bsnl ++s/["\\]/\\&/g ++s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ ++D["\1"]=" \3"/p ++s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p ++d ++:bsnl ++s/["\\]/\\&/g ++s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ ++D["\1"]=" \3\\\\\\n"\\/p ++t cont ++s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p ++t cont ++d ++:cont ++n ++s/.\{148\}/&'"$ac_delim"'/g ++t clear ++:clear ++s/\\$// ++t bsnlc ++s/["\\]/\\&/g; s/^/"/; s/$/"/p ++d ++:bsnlc ++s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p ++b cont ++' >$CONFIG_STATUS || ac_write_fail=1 ++ ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++ for (key in D) D_is_set[key] = 1 ++ FS = "" ++} ++/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { ++ line = \$ 0 ++ split(line, arg, " ") ++ if (arg[1] == "#") { ++ defundef = arg[2] ++ mac1 = arg[3] ++ } else { ++ defundef = substr(arg[1], 2) ++ mac1 = arg[2] ++ } ++ split(mac1, mac2, "(") #) ++ macro = mac2[1] ++ prefix = substr(line, 1, index(line, defundef) - 1) ++ if (D_is_set[macro]) { ++ # Preserve the white space surrounding the "#". ++ print prefix "define", macro P[macro] D[macro] ++ next ++ } else { ++ # Replace #undef with comments. This is necessary, for example, ++ # in the case of _POSIX_SOURCE, which is predefined and required ++ # on some systems where configure will not decide to define it. ++ if (defundef == "undef") { ++ print "/*", prefix defundef, macro, "*/" ++ next ++ } ++ } ++} ++{ print } ++_ACAWK ++_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ++ { { $as_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 ++$as_echo "$as_me: error: could not setup config headers machinery" >&2;} ++ { (exit 1); exit 1; }; } ++fi # test -n "$CONFIG_HEADERS" ++ ++ ++eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " ++shift ++for ac_tag + do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; +- :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +-echo "$as_me: error: Invalid tag $ac_tag." >&2;} ++ :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 ++$as_echo "$as_me: error: invalid tag $ac_tag" >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; +@@ -6592,26 +6896,38 @@ echo "$as_me: error: Invalid tag $ac_tag." >&2;} + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || +- { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +-echo "$as_me: error: cannot find input file: $ac_f" >&2;} ++ { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 ++$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac +- ac_file_inputs="$ac_file_inputs $ac_f" ++ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ++ ac_file_inputs="$ac_file_inputs '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ +- configure_input="Generated from "`IFS=: +- echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." ++ configure_input='Generated from '` ++ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' ++ `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" +- { echo "$as_me:$LINENO: creating $ac_file" >&5 +-echo "$as_me: creating $ac_file" >&6;} ++ { $as_echo "$as_me:$LINENO: creating $ac_file" >&5 ++$as_echo "$as_me: creating $ac_file" >&6;} + fi ++ # Neutralize special characters interpreted by sed in replacement strings. ++ case $configure_input in #( ++ *\&* | *\|* | *\\* ) ++ ac_sed_conf_input=`$as_echo "$configure_input" | ++ sed 's/[\\\\&|]/\\\\&/g'`;; #( ++ *) ac_sed_conf_input=$configure_input;; ++ esac + + case $ac_tag in +- *:-:* | *:-) cat >"$tmp/stdin";; ++ *:-:* | *:-) cat >"$tmp/stdin" \ ++ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 ++$as_echo "$as_me: error: could not create $ac_file" >&2;} ++ { (exit 1); exit 1; }; } ;; + esac + ;; + esac +@@ -6621,7 +6937,7 @@ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +-echo X"$ac_file" | ++$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q +@@ -6647,7 +6963,7 @@ echo X"$ac_file" | + as_dirs= + while :; do + case $as_dir in #( +- *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( ++ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" +@@ -6656,7 +6972,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +-echo X"$as_dir" | ++$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q +@@ -6677,17 +6993,17 @@ echo X"$as_dir" | + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" +- } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +-echo "$as_me: error: cannot create directory $as_dir" >&2;} ++ } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 ++$as_echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + + case "$ac_dir" in + .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) +- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` ++ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. +- ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` ++ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; +@@ -6723,12 +7039,13 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + _ACEOF + +-cat >>$CONFIG_STATUS <<\_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + # If the template does not know about datarootdir, expand it. + # FIXME: This hack should be removed a few years after 2.60. + ac_datarootdir_hack=; ac_datarootdir_seen= + +-case `sed -n '/datarootdir/ { ++ac_sed_dataroot=' ++/datarootdir/ { + p + q + } +@@ -6737,13 +7054,14 @@ case `sed -n '/datarootdir/ { + /@infodir@/p + /@localedir@/p + /@mandir@/p +-' $ac_file_inputs` in ++' ++case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in + *datarootdir*) ac_datarootdir_seen=yes;; + *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) +- { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +-echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} ++ { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 ++$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} + _ACEOF +-cat >>$CONFIG_STATUS <<_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g +@@ -6757,15 +7075,16 @@ _ACEOF + # Neutralize VPATH when `$srcdir' = `.'. + # Shell code in configure.ac might set extrasub. + # FIXME: do we really want to maintain this feature? +-cat >>$CONFIG_STATUS <<_ACEOF +- sed "$ac_vpsub ++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ++ac_sed_extra="$ac_vpsub + $extrasub + _ACEOF +-cat >>$CONFIG_STATUS <<\_ACEOF ++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + :t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b +-s&@configure_input@&$configure_input&;t t ++s|@configure_input@|$ac_sed_conf_input|;t t + s&@top_builddir@&$ac_top_builddir_sub&;t t ++s&@top_build_prefix@&$ac_top_build_prefix&;t t + s&@srcdir@&$ac_srcdir&;t t + s&@abs_srcdir@&$ac_abs_srcdir&;t t + s&@top_srcdir@&$ac_top_srcdir&;t t +@@ -6774,119 +7093,58 @@ s&@builddir@&$ac_builddir&;t t + s&@abs_builddir@&$ac_abs_builddir&;t t + s&@abs_top_builddir@&$ac_abs_top_builddir&;t t + $ac_datarootdir_hack +-" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out ++" ++eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ ++ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 ++$as_echo "$as_me: error: could not create $ac_file" >&2;} ++ { (exit 1); exit 1; }; } + + test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && +- { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' ++ { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' + which seems to be undefined. Please make sure it is defined." >&5 +-echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' ++$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' + which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in +- -) cat "$tmp/out"; rm -f "$tmp/out";; +- *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; +- esac ++ -) cat "$tmp/out" && rm -f "$tmp/out";; ++ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; ++ esac \ ++ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 ++$as_echo "$as_me: error: could not create $ac_file" >&2;} ++ { (exit 1); exit 1; }; } + ;; + :H) + # + # CONFIG_HEADER + # +-_ACEOF +- +-# Transform confdefs.h into a sed script `conftest.defines', that +-# substitutes the proper values into config.h.in to produce config.h. +-rm -f conftest.defines conftest.tail +-# First, append a space to every undef/define line, to ease matching. +-echo 's/$/ /' >conftest.defines +-# Then, protect against being on the right side of a sed subst, or in +-# an unquoted here document, in config.status. If some macros were +-# called several times there might be several #defines for the same +-# symbol, which is useless. But do not sort them, since the last +-# AC_DEFINE must be honored. +-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +-# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +-# NAME is the cpp macro being defined, VALUE is the value it is being given. +-# PARAMS is the parameter list in the macro definition--in most cases, it's +-# just an empty string. +-ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +-ac_dB='\\)[ (].*,\\1define\\2' +-ac_dC=' ' +-ac_dD=' ,' +- +-uniq confdefs.h | +- sed -n ' +- t rset +- :rset +- s/^[ ]*#[ ]*define[ ][ ]*// +- t ok +- d +- :ok +- s/[\\&,]/\\&/g +- s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p +- s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p +- ' >>conftest.defines +- +-# Remove the space that was appended to ease matching. +-# Then replace #undef with comments. This is necessary, for +-# example, in the case of _POSIX_SOURCE, which is predefined and required +-# on some systems where configure will not decide to define it. +-# (The regexp can be short, since the line contains either #define or #undef.) +-echo 's/ $// +-s,^[ #]*u.*,/* & */,' >>conftest.defines +- +-# Break up conftest.defines: +-ac_max_sed_lines=50 +- +-# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +-# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +-# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +-# et cetera. +-ac_in='$ac_file_inputs' +-ac_out='"$tmp/out1"' +-ac_nxt='"$tmp/out2"' +- +-while : +-do +- # Write a here document: +- cat >>$CONFIG_STATUS <<_ACEOF +- # First, check the format of the line: +- cat >"\$tmp/defines.sed" <<\\CEOF +-/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +-/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +-b +-:def +-_ACEOF +- sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS +- echo 'CEOF +- sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS +- ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in +- sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail +- grep . conftest.tail >/dev/null || break +- rm -f conftest.defines +- mv conftest.tail conftest.defines +-done +-rm -f conftest.defines conftest.tail +- +-echo "ac_result=$ac_in" >>$CONFIG_STATUS +-cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then +- echo "/* $configure_input */" >"$tmp/config.h" +- cat "$ac_result" >>"$tmp/config.h" +- if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then +- { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +-echo "$as_me: $ac_file is unchanged" >&6;} ++ { ++ $as_echo "/* $configure_input */" \ ++ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" ++ } >"$tmp/config.h" \ ++ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 ++$as_echo "$as_me: error: could not create $ac_file" >&2;} ++ { (exit 1); exit 1; }; } ++ if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then ++ { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5 ++$as_echo "$as_me: $ac_file is unchanged" >&6;} + else +- rm -f $ac_file +- mv "$tmp/config.h" $ac_file ++ rm -f "$ac_file" ++ mv "$tmp/config.h" "$ac_file" \ ++ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 ++$as_echo "$as_me: error: could not create $ac_file" >&2;} ++ { (exit 1); exit 1; }; } + fi + else +- echo "/* $configure_input */" +- cat "$ac_result" ++ $as_echo "/* $configure_input */" \ ++ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ ++ || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 ++$as_echo "$as_me: error: could not create -" >&2;} ++ { (exit 1); exit 1; }; } + fi +- rm -f "$tmp/out12" + ;; + + +@@ -6900,6 +7158,11 @@ _ACEOF + chmod +x $CONFIG_STATUS + ac_clean_files=$ac_clean_files_save + ++test $ac_write_fail = 0 || ++ { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 ++$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} ++ { (exit 1); exit 1; }; } ++ + + # configure is writing to config.log, and then calls config.status. + # config.status does its own redirection, appending to config.log. +@@ -6921,6 +7184,10 @@ if test "$no_create" != yes; then + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } + fi ++if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then ++ { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 ++$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} ++fi + + + # +diff --git a/daemon/automount.c b/daemon/automount.c +index a664277..776c92c 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -1730,6 +1730,16 @@ static void show_build_info(void) + #ifdef LIBXML2_WORKAROUND + printf("LIBXML2_WORKAROUND "); + count = count + 19; ++ ++ if (count > 60) { ++ printf("\n "); ++ count = 0; ++ } ++#endif ++ ++#ifdef WITH_LIBTIRPC ++ printf("WITH_LIBTIRPC "); ++ count = count + 14; + #endif + + printf("\n\n"); +@@ -2063,6 +2073,8 @@ int main(int argc, char *argv[]) + #endif + #ifdef TIRPC_WORKAROUND + void *dh_tirpc = dlopen("libitirpc.so", RTLD_NOW); ++ if (!dh_tirpc) ++ dh_tirpc = dlopen("libitirpc.so.1", RTLD_NOW); + #endif + + if (!master_read_master(master_list, age, 0)) { +diff --git a/include/config.h.in b/include/config.h.in +index 31b0d75..39cfa4b 100644 +--- a/include/config.h.in ++++ b/include/config.h.in +@@ -117,7 +117,7 @@ + /* Define to 1 if you have the ANSI C header files. */ + #undef STDC_HEADERS + +-/* Use libtirpc tsd usage workaround */ ++/* Define to 1 to use the libtirpc tsd usage workaround */ + #undef TIRPC_WORKAROUND + + /* Define if using the dmalloc debugging malloc package */ +@@ -129,5 +129,8 @@ + /* Define if using LDAP as a source of automount maps */ + #undef WITH_LDAP + ++/* Define to 1 if you have the libtirpc library installed */ ++#undef WITH_LIBTIRPC ++ + /* Define if using SASL authentication with the LDAP module */ + #undef WITH_SASL diff --git a/autofs-5.0.4-configure-libtirpc.patch b/autofs-5.0.4-configure-libtirpc.patch new file mode 100644 index 0000000..b1e9af2 --- /dev/null +++ b/autofs-5.0.4-configure-libtirpc.patch @@ -0,0 +1,1835 @@ +autofs-5.0.4 - configure libtirpc + +From: Ian Kent + +With NFS over ipv6 on the way we need to update autofs to use the +libtirpc library as it provides ipv6 functionality. This change adds +configure checks to look for libtirpc (if it has been requested with +--with-libtirpc) and checks whether it has been built with ipv6 +support and uses it if so. +--- + + Makefile.conf.in | 3 + Makefile.rules | 5 + aclocal.m4 | 81 +++ + autofs.spec | 2 + configure | 1548 ++++++++++++++++++++++++++++----------------------- + configure.in | 6 + daemon/automount.c | 13 + include/config.h.in | 6 + 8 files changed, 970 insertions(+), 694 deletions(-) + + +diff --git a/Makefile.conf.in b/Makefile.conf.in +index ffda2a0..f0287c3 100644 +--- a/Makefile.conf.in ++++ b/Makefile.conf.in +@@ -49,6 +49,9 @@ YACC = @PATH_YACC@ + RPCGEN = @PATH_RPCGEN@ + RANLIB = @PATH_RANLIB@ + ++# Use libtirpc if requested and available ++TIRPCLIB = @TIRPCLIB@ ++ + # Use dmalloc for memory debuging + DMALLOCLIB = @DMALLOCLIB@ + +diff --git a/Makefile.rules b/Makefile.rules +index 30716dc..f2ba386 100644 +--- a/Makefile.rules ++++ b/Makefile.rules +@@ -47,6 +47,11 @@ SOLDFLAGS = -shared + CFLAGS += -D_REENTRANT -D_FILE_OFFSET_BITS=64 + LDFLAGS += -lpthread + ++ifdef TIRPCLIB ++CFLAGS += -I/usr/include/tirpc ++LDFLAGS += $(TIRPCLIB) ++endif ++ + ifdef DMALLOCLIB + LDFLAGS += $(DMALLOCLIB) + endif +diff --git a/aclocal.m4 b/aclocal.m4 +index ab11112..5777fcd 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -304,3 +304,84 @@ fi + LIBS="$af_check_ldap_parse_page_control_save_libs" + ]) + ++dnl -------------------------------------------------------------------------- ++dnl AF_CHECK_LIBTIRPC_IPV6 ++dnl ++dnl Use libtirpc for rpc transport ++dnl -------------------------------------------------------------------------- ++AC_DEFUN([AF_CHECK_LIBTIRPC_IPV6], ++[AC_MSG_CHECKING(if libtirpc has IPv6 support) ++ ++# save current flags ++af_check_libtirpc_ipv6_save_cflags="$CFLAGS" ++af_check_libtirpc_ipv6_save_ldflags="$LDFLAGS" ++CFLAGS="$CFLAGS -I/usr/include/tirpc" ++LDFLAGS="$LDFLAGS -ltirpc" ++ ++AC_TRY_LINK( ++ [ #define INET6 ++ #include ], ++ [ CLIENT *cl; ++ struct sockaddr_in addr; ++ int fd; ++ unsigned long ul; struct timeval t; unsigned int ui; ++ cl = clntudp6_bufcreate(&addr,ul,ul,t,&fd,ui,ui); ], ++ [ af_have_libtirpc_ipv6=yes ++ AC_MSG_RESULT(yes) ], ++ [ AC_MSG_RESULT(no) ]) ++ ++if test "$af_have_libtirpc_ipv6" = "yes"; then ++ AC_DEFINE(INET6,1, [Use IPv6 with libtirpc]) ++fi ++ ++# restore flags ++CFLAGS="$af_check_libtirpc_ipv6_save_cflags" ++LDFLAGS="$af_check_libtirpc_ipv6_save_ldflags" ++]) ++ ++dnl -------------------------------------------------------------------------- ++dnl AF_CHECK_LIBTIRPC ++dnl ++dnl Use libtirpc for rpc transport ++dnl -------------------------------------------------------------------------- ++AC_DEFUN([AF_CHECK_LIBTIRPC], ++[ ++# save current flags ++af_check_libtirpc_save_cflags="$CFLAGS" ++af_check_libtirpc_save_ldflags="$LDFLAGS" ++CFLAGS="$CFLAGS -I/usr/include/tirpc" ++LDFLAGS="$LDFLAGS -ltirpc" ++ ++AC_TRY_LINK( ++ [ #include ], ++ [ CLIENT *cl; ++ struct sockaddr_in addr; ++ int fd; ++ unsigned long ul; struct timeval t; unsigned int ui; ++ cl = clntudp_bufcreate(&addr,ul,ul,t,&fd,ui,ui); ], ++ [ af_have_libtirpc=yes ++ AC_MSG_RESULT(yes) ], ++ [ AC_MSG_RESULT(no) ]) ++ ++if test "$af_have_libtirpc" = "yes"; then ++ AC_DEFINE(TIRPC_WORKAROUND,1, [Use libtirpc tsd usage workaround]) ++ TIRPCLIB="-ltirpc" ++fi ++ ++# restore flags ++CFLAGS="$af_check_libtirpc_save_cflags" ++LDFLAGS="$af_check_libtirpc_save_ldflags" ++]) ++ ++AC_DEFUN([AM_WITH_LIBTIRPC], ++[AC_MSG_CHECKING([if libtirpc is requested and available]) ++AC_ARG_WITH(libtirpc, ++[ --with-libtirpc use libtirpc if available], ++[if test "$withval" = yes; then ++ AF_CHECK_LIBTIRPC() ++ AF_CHECK_LIBTIRPC_IPV6() ++else ++ AC_MSG_RESULT(no) ++fi], [AC_MSG_RESULT(no)]) ++]) ++ +diff --git a/autofs.spec b/autofs.spec +index 9fec583..f4b096e 100644 +--- a/autofs.spec ++++ b/autofs.spec +@@ -57,7 +57,7 @@ inkludera n + echo %{version}-%{release} > .version + + %build +-CFLAGS="$RPM_OPT_FLAGS -Wall" ./configure --libdir=%{_libdir} --disable-mount-locking --enable-ignore-busy ++CFLAGS="$RPM_OPT_FLAGS -Wall" ./configure --libdir=%{_libdir} --disable-mount-locking --enable-ignore-busy --with-libtirpc + CFLAGS="$RPM_OPT_FLAGS -Wall" make initdir=/etc/rc.d/init.d DONTSTRIP=1 + + %install +diff --git a/configure b/configure +index afa692c..8a6d944 100755 +--- a/configure ++++ b/configure +@@ -656,6 +656,14 @@ confdir + mapdir + fifodir + flagdir ++CC ++CFLAGS ++LDFLAGS ++CPPFLAGS ++ac_ct_CC ++EXEEXT ++OBJEXT ++TIRPCLIB + DMALLOCLIB + MOUNT + HAVE_MOUNT +@@ -676,13 +684,6 @@ PATH_RANLIB + RPCGEN + PATH_RPCGEN + XML_CONFIG +-CC +-CFLAGS +-LDFLAGS +-CPPFLAGS +-ac_ct_CC +-EXEEXT +-OBJEXT + LIBNSL + LIBRESOLV + HAVE_HESIOD +@@ -1297,6 +1298,7 @@ Optional Packages: + --with-mapdir=PATH look in PATH for mount maps used by the automounter + --with-fifodir=PATH use PATH as the directory for fifos used by the automounter + --with-flagdir=PATH use PATH as the directory for the flag file used by the automounter ++ --with-libtirpc use libtirpc if available + --with-dmalloc use dmalloc, as in + http://www.dmalloc.com/dmalloc.tar.gz + --with-hesiod=DIR enable Hesiod support (libs and includes in DIR) +@@ -1908,681 +1910,7 @@ echo "${ECHO_T}$flagdir" >&6; } + + + # +-# Optional include dmalloc +-# +-{ echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5 +-echo $ECHO_N "checking if malloc debugging is wanted... $ECHO_C" >&6; } +- +-# Check whether --with-dmalloc was given. +-if test "${with_dmalloc+set}" = set; then +- withval=$with_dmalloc; if test "$withval" = yes; then +- { echo "$as_me:$LINENO: result: yes" >&5 +-echo "${ECHO_T}yes" >&6; } +- +-cat >>confdefs.h <<\_ACEOF +-#define WITH_DMALLOC 1 +-_ACEOF +- +- DMALLOCLIB="-ldmallocth" +- LDFLAGS="$LDFLAGS -g" +-else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +-fi +-else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +-fi +- +- +- +- +-# +-# Programs needed for various system functions or modules +-# +-for ac_prog in mount +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +-if test "${ac_cv_path_MOUNT+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- case $MOUNT in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_MOUNT="$MOUNT" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $searchpath +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then +- ac_cv_path_MOUNT="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +-done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-MOUNT=$ac_cv_path_MOUNT +-if test -n "$MOUNT"; then +- { echo "$as_me:$LINENO: result: $MOUNT" >&5 +-echo "${ECHO_T}$MOUNT" >&6; } +-else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +-fi +- +- +- test -n "$MOUNT" && break +-done +-test -n "$MOUNT" || MOUNT="/bin/mount" +- +-if test -n "$MOUNT"; then +- +-cat >>confdefs.h <<\_ACEOF +-#define HAVE_MOUNT 1 +-_ACEOF +- +- +-cat >>confdefs.h <<_ACEOF +-#define PATH_MOUNT "$MOUNT" +-_ACEOF +- +- HAVE_MOUNT=1 +-else +- HAVE_MOUNT=0 +-fi +- +-for ac_prog in umount +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +-if test "${ac_cv_path_UMOUNT+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- case $UMOUNT in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_UMOUNT="$UMOUNT" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $searchpath +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then +- ac_cv_path_UMOUNT="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +-done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-UMOUNT=$ac_cv_path_UMOUNT +-if test -n "$UMOUNT"; then +- { echo "$as_me:$LINENO: result: $UMOUNT" >&5 +-echo "${ECHO_T}$UMOUNT" >&6; } +-else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +-fi +- +- +- test -n "$UMOUNT" && break +-done +-test -n "$UMOUNT" || UMOUNT="/bin/umount" +- +-if test -n "$UMOUNT"; then +- +-cat >>confdefs.h <<\_ACEOF +-#define HAVE_UMOUNT 1 +-_ACEOF +- +- +-cat >>confdefs.h <<_ACEOF +-#define PATH_UMOUNT "$UMOUNT" +-_ACEOF +- +- HAVE_UMOUNT=1 +-else +- HAVE_UMOUNT=0 +-fi +- +-for ac_prog in fsck.ext2 e2fsck +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +-if test "${ac_cv_path_E2FSCK+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- case $E2FSCK in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_E2FSCK="$E2FSCK" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $searchpath +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then +- ac_cv_path_E2FSCK="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +-done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-E2FSCK=$ac_cv_path_E2FSCK +-if test -n "$E2FSCK"; then +- { echo "$as_me:$LINENO: result: $E2FSCK" >&5 +-echo "${ECHO_T}$E2FSCK" >&6; } +-else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +-fi +- +- +- test -n "$E2FSCK" && break +-done +- +-if test -n "$E2FSCK"; then +- +-cat >>confdefs.h <<\_ACEOF +-#define HAVE_E2FSCK 1 +-_ACEOF +- +- +-cat >>confdefs.h <<_ACEOF +-#define PATH_E2FSCK "$E2FSCK" +-_ACEOF +- +- HAVE_E2FSCK=1 +-else +- HAVE_E2FSCK=0 +-fi +- +-for ac_prog in fsck.ext3 e3fsck +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +-if test "${ac_cv_path_E3FSCK+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- case $E3FSCK in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_E3FSCK="$E3FSCK" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $searchpath +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then +- ac_cv_path_E3FSCK="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +-done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-E3FSCK=$ac_cv_path_E3FSCK +-if test -n "$E3FSCK"; then +- { echo "$as_me:$LINENO: result: $E3FSCK" >&5 +-echo "${ECHO_T}$E3FSCK" >&6; } +-else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +-fi +- +- +- test -n "$E3FSCK" && break +-done +- +-if test -n "$E3FSCK"; then +- +-cat >>confdefs.h <<\_ACEOF +-#define HAVE_E3FSCK 1 +-_ACEOF +- +- +-cat >>confdefs.h <<_ACEOF +-#define PATH_E3FSCK "$E3FSCK" +-_ACEOF +- +- HAVE_E3FSCK=1 +-else +- HAVE_E3FSCK=0 +-fi +- +-for ac_prog in modprobe +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +-if test "${ac_cv_path_MODPROBE+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- case $MODPROBE in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_MODPROBE="$MODPROBE" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $searchpath +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then +- ac_cv_path_MODPROBE="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +-done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-MODPROBE=$ac_cv_path_MODPROBE +-if test -n "$MODPROBE"; then +- { echo "$as_me:$LINENO: result: $MODPROBE" >&5 +-echo "${ECHO_T}$MODPROBE" >&6; } +-else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +-fi +- +- +- test -n "$MODPROBE" && break +-done +- +-if test -n "$MODPROBE"; then +- +-cat >>confdefs.h <<\_ACEOF +-#define HAVE_MODPROBE 1 +-_ACEOF +- +- +-cat >>confdefs.h <<_ACEOF +-#define PATH_MODPROBE "$MODPROBE" +-_ACEOF +- +- HAVE_MODPROBE=1 +-else +- HAVE_MODPROBE=0 +-fi +- +- +-for ac_prog in flex lex +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +-if test "${ac_cv_path_LEX+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- case $LEX in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_LEX="$LEX" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $searchpath +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then +- ac_cv_path_LEX="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +-done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-LEX=$ac_cv_path_LEX +-if test -n "$LEX"; then +- { echo "$as_me:$LINENO: result: $LEX" >&5 +-echo "${ECHO_T}$LEX" >&6; } +-else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +-fi +- +- +- test -n "$LEX" && break +-done +- +-if test -n "$LEX"; then +- +-cat >>confdefs.h <<_ACEOF +-#define PATH_LEX "$LEX" +-_ACEOF +- +- PATH_LEX="$LEX" +-else +- { { echo "$as_me:$LINENO: error: required program LEX not found" >&5 +-echo "$as_me: error: required program LEX not found" >&2;} +- { (exit 1); exit 1; }; } +-fi +- +-for ac_prog in bison +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +-if test "${ac_cv_path_YACC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- case $YACC in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_YACC="$YACC" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $searchpath +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then +- ac_cv_path_YACC="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +-done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-YACC=$ac_cv_path_YACC +-if test -n "$YACC"; then +- { echo "$as_me:$LINENO: result: $YACC" >&5 +-echo "${ECHO_T}$YACC" >&6; } +-else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +-fi +- +- +- test -n "$YACC" && break +-done +- +-if test -n "$YACC"; then +- +-cat >>confdefs.h <<_ACEOF +-#define PATH_YACC "$YACC" +-_ACEOF +- +- PATH_YACC="$YACC" +-else +- { { echo "$as_me:$LINENO: error: required program YACC not found" >&5 +-echo "$as_me: error: required program YACC not found" >&2;} +- { (exit 1); exit 1; }; } +-fi +- +-for ac_prog in ranlib +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +-if test "${ac_cv_path_RANLIB+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- case $RANLIB in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_RANLIB="$RANLIB" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $searchpath +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then +- ac_cv_path_RANLIB="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +-done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-RANLIB=$ac_cv_path_RANLIB +-if test -n "$RANLIB"; then +- { echo "$as_me:$LINENO: result: $RANLIB" >&5 +-echo "${ECHO_T}$RANLIB" >&6; } +-else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +-fi +- +- +- test -n "$RANLIB" && break +-done +- +-if test -n "$RANLIB"; then +- +-cat >>confdefs.h <<_ACEOF +-#define PATH_RANLIB "$RANLIB" +-_ACEOF +- +- PATH_RANLIB="$RANLIB" +-else +- { { echo "$as_me:$LINENO: error: required program RANLIB not found" >&5 +-echo "$as_me: error: required program RANLIB not found" >&2;} +- { (exit 1); exit 1; }; } +-fi +- +-for ac_prog in rpcgen +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +-if test "${ac_cv_path_RPCGEN+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- case $RPCGEN in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_RPCGEN="$RPCGEN" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $searchpath +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then +- ac_cv_path_RPCGEN="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +-done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-RPCGEN=$ac_cv_path_RPCGEN +-if test -n "$RPCGEN"; then +- { echo "$as_me:$LINENO: result: $RPCGEN" >&5 +-echo "${ECHO_T}$RPCGEN" >&6; } +-else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +-fi +- +- +- test -n "$RPCGEN" && break +-done +- +-if test -n "$RPCGEN"; then +- +-cat >>confdefs.h <<_ACEOF +-#define PATH_RPCGEN "$RPCGEN" +-_ACEOF +- +- PATH_RPCGEN="$RPCGEN" +-else +- { { echo "$as_me:$LINENO: error: required program RPCGEN not found" >&5 +-echo "$as_me: error: required program RPCGEN not found" >&2;} +- { (exit 1); exit 1; }; } +-fi +- +- +-# +-# Newer mounts have the -s (sloppy) option to ignore unknown options, +-# good for portability +-# +-if test -n "$MOUNT" ; then +- { echo "$as_me:$LINENO: checking if mount accepts the -s option" >&5 +-echo $ECHO_N "checking if mount accepts the -s option... $ECHO_C" >&6; } +- if "$MOUNT" -s > /dev/null 2>&1 ; then +- +-cat >>confdefs.h <<\_ACEOF +-#define HAVE_SLOPPY_MOUNT 1 +-_ACEOF +- +- { echo "$as_me:$LINENO: result: yes" >&5 +-echo "${ECHO_T}yes" >&6; } +- else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +- fi +-fi +- +-# LDAP SASL auth need libxml +-for ac_prog in xml2-config +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +-if test "${ac_cv_path_XML_CONFIG+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- case $XML_CONFIG in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_XML_CONFIG="$XML_CONFIG" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then +- ac_cv_path_XML_CONFIG="$as_dir/$ac_word$ac_exec_ext" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +-done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-XML_CONFIG=$ac_cv_path_XML_CONFIG +-if test -n "$XML_CONFIG"; then +- { echo "$as_me:$LINENO: result: $XML_CONFIG" >&5 +-echo "${ECHO_T}$XML_CONFIG" >&6; } +-else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +-fi +- +- +- test -n "$XML_CONFIG" && break +-done +-test -n "$XML_CONFIG" || XML_CONFIG="no" +- +-{ echo "$as_me:$LINENO: checking for libxml2" >&5 +-echo $ECHO_N "checking for libxml2... $ECHO_C" >&6; } +-if test "$XML_CONFIG" = "no" +-then +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +- HAVE_LIBXML=0 +-else +- { echo "$as_me:$LINENO: result: yes" >&5 +-echo "${ECHO_T}yes" >&6; } +- HAVE_LIBXML=1 +- XML_LIBS=`$XML_CONFIG --libs` +- XML_FLAGS=`$XML_CONFIG --cflags` +- XML_VER=`$XML_CONFIG --version` +- XML_MAJOR=`echo $XML_VER|cut -d\. -f1` +- if test $XML_MAJOR -le 99 +- then +- XML_MINOR=`echo $XML_VER|cut -d\. -f2` +- if test $XML_MINOR -le 99 +- then +- XML_REV=`echo $XML_VER|cut -d\. -f3` +- if test $XML_REV -le 99; then +- +-cat >>confdefs.h <<\_ACEOF +-#define LIBXML2_WORKAROUND 1 +-_ACEOF +- +- fi +- fi +- fi +-fi +- +-# +-# glibc/libc 6 new libraries ++# Use libtirpc + # + ac_ext=c + ac_cpp='$CPP $CPPFLAGS' +@@ -3504,6 +2832,845 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ + ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ++{ echo "$as_me:$LINENO: checking if libtirpc is requested and available" >&5 ++echo $ECHO_N "checking if libtirpc is requested and available... $ECHO_C" >&6; } ++ ++# Check whether --with-libtirpc was given. ++if test "${with_libtirpc+set}" = set; then ++ withval=$with_libtirpc; if test "$withval" = yes; then ++ ++# save current flags ++af_check_libtirpc_save_cflags="$CFLAGS" ++af_check_libtirpc_save_ldflags="$LDFLAGS" ++CFLAGS="$CFLAGS -I/usr/include/tirpc" ++LDFLAGS="$LDFLAGS -ltirpc" ++ ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ #include ++int ++main () ++{ ++ CLIENT *cl; ++ struct sockaddr_in addr; ++ int fd; ++ unsigned long ul; struct timeval t; unsigned int ui; ++ cl = clntudp_bufcreate(&addr,ul,ul,t,&fd,ui,ui); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++ (eval "$ac_link") 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && { ++ test -z "$ac_c_werror_flag" || ++ test ! -s conftest.err ++ } && test -s conftest$ac_exeext && ++ $as_test_x conftest$ac_exeext; then ++ af_have_libtirpc=yes ++ { echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6; } ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ ++ conftest$ac_exeext conftest.$ac_ext ++ ++if test "$af_have_libtirpc" = "yes"; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define TIRPC_WORKAROUND 1 ++_ACEOF ++ ++ TIRPCLIB="-ltirpc" ++fi ++ ++# restore flags ++CFLAGS="$af_check_libtirpc_save_cflags" ++LDFLAGS="$af_check_libtirpc_save_ldflags" ++ ++ { echo "$as_me:$LINENO: checking if libtirpc has IPv6 support" >&5 ++echo $ECHO_N "checking if libtirpc has IPv6 support... $ECHO_C" >&6; } ++ ++# save current flags ++af_check_libtirpc_ipv6_save_cflags="$CFLAGS" ++af_check_libtirpc_ipv6_save_ldflags="$LDFLAGS" ++CFLAGS="$CFLAGS -I/usr/include/tirpc" ++LDFLAGS="$LDFLAGS -ltirpc" ++ ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ #define INET6 ++ #include ++int ++main () ++{ ++ CLIENT *cl; ++ struct sockaddr_in addr; ++ int fd; ++ unsigned long ul; struct timeval t; unsigned int ui; ++ cl = clntudp6_bufcreate(&addr,ul,ul,t,&fd,ui,ui); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++ (eval "$ac_link") 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && { ++ test -z "$ac_c_werror_flag" || ++ test ! -s conftest.err ++ } && test -s conftest$ac_exeext && ++ $as_test_x conftest$ac_exeext; then ++ af_have_libtirpc_ipv6=yes ++ { echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6; } ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ ++ conftest$ac_exeext conftest.$ac_ext ++ ++if test "$af_have_libtirpc_ipv6" = "yes"; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define INET6 1 ++_ACEOF ++ ++fi ++ ++# restore flags ++CFLAGS="$af_check_libtirpc_ipv6_save_cflags" ++LDFLAGS="$af_check_libtirpc_ipv6_save_ldflags" ++ ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++ ++ ++ ++# ++# Optional include dmalloc ++# ++{ echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5 ++echo $ECHO_N "checking if malloc debugging is wanted... $ECHO_C" >&6; } ++ ++# Check whether --with-dmalloc was given. ++if test "${with_dmalloc+set}" = set; then ++ withval=$with_dmalloc; if test "$withval" = yes; then ++ { echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6; } ++ ++cat >>confdefs.h <<\_ACEOF ++#define WITH_DMALLOC 1 ++_ACEOF ++ ++ DMALLOCLIB="-ldmallocth" ++ LDFLAGS="$LDFLAGS -g" ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++ ++ ++ ++# ++# Programs needed for various system functions or modules ++# ++for ac_prog in mount ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++if test "${ac_cv_path_MOUNT+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $MOUNT in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_MOUNT="$MOUNT" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $searchpath ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_path_MOUNT="$as_dir/$ac_word$ac_exec_ext" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++MOUNT=$ac_cv_path_MOUNT ++if test -n "$MOUNT"; then ++ { echo "$as_me:$LINENO: result: $MOUNT" >&5 ++echo "${ECHO_T}$MOUNT" >&6; } ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++ ++ test -n "$MOUNT" && break ++done ++test -n "$MOUNT" || MOUNT="/bin/mount" ++ ++if test -n "$MOUNT"; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define HAVE_MOUNT 1 ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PATH_MOUNT "$MOUNT" ++_ACEOF ++ ++ HAVE_MOUNT=1 ++else ++ HAVE_MOUNT=0 ++fi ++ ++for ac_prog in umount ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++if test "${ac_cv_path_UMOUNT+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $UMOUNT in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_UMOUNT="$UMOUNT" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $searchpath ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_path_UMOUNT="$as_dir/$ac_word$ac_exec_ext" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++UMOUNT=$ac_cv_path_UMOUNT ++if test -n "$UMOUNT"; then ++ { echo "$as_me:$LINENO: result: $UMOUNT" >&5 ++echo "${ECHO_T}$UMOUNT" >&6; } ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++ ++ test -n "$UMOUNT" && break ++done ++test -n "$UMOUNT" || UMOUNT="/bin/umount" ++ ++if test -n "$UMOUNT"; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define HAVE_UMOUNT 1 ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PATH_UMOUNT "$UMOUNT" ++_ACEOF ++ ++ HAVE_UMOUNT=1 ++else ++ HAVE_UMOUNT=0 ++fi ++ ++for ac_prog in fsck.ext2 e2fsck ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++if test "${ac_cv_path_E2FSCK+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $E2FSCK in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_E2FSCK="$E2FSCK" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $searchpath ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_path_E2FSCK="$as_dir/$ac_word$ac_exec_ext" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++E2FSCK=$ac_cv_path_E2FSCK ++if test -n "$E2FSCK"; then ++ { echo "$as_me:$LINENO: result: $E2FSCK" >&5 ++echo "${ECHO_T}$E2FSCK" >&6; } ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++ ++ test -n "$E2FSCK" && break ++done ++ ++if test -n "$E2FSCK"; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define HAVE_E2FSCK 1 ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PATH_E2FSCK "$E2FSCK" ++_ACEOF ++ ++ HAVE_E2FSCK=1 ++else ++ HAVE_E2FSCK=0 ++fi ++ ++for ac_prog in fsck.ext3 e3fsck ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++if test "${ac_cv_path_E3FSCK+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $E3FSCK in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_E3FSCK="$E3FSCK" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $searchpath ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_path_E3FSCK="$as_dir/$ac_word$ac_exec_ext" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++E3FSCK=$ac_cv_path_E3FSCK ++if test -n "$E3FSCK"; then ++ { echo "$as_me:$LINENO: result: $E3FSCK" >&5 ++echo "${ECHO_T}$E3FSCK" >&6; } ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++ ++ test -n "$E3FSCK" && break ++done ++ ++if test -n "$E3FSCK"; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define HAVE_E3FSCK 1 ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PATH_E3FSCK "$E3FSCK" ++_ACEOF ++ ++ HAVE_E3FSCK=1 ++else ++ HAVE_E3FSCK=0 ++fi ++ ++for ac_prog in modprobe ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++if test "${ac_cv_path_MODPROBE+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $MODPROBE in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_MODPROBE="$MODPROBE" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $searchpath ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_path_MODPROBE="$as_dir/$ac_word$ac_exec_ext" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++MODPROBE=$ac_cv_path_MODPROBE ++if test -n "$MODPROBE"; then ++ { echo "$as_me:$LINENO: result: $MODPROBE" >&5 ++echo "${ECHO_T}$MODPROBE" >&6; } ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++ ++ test -n "$MODPROBE" && break ++done ++ ++if test -n "$MODPROBE"; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define HAVE_MODPROBE 1 ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PATH_MODPROBE "$MODPROBE" ++_ACEOF ++ ++ HAVE_MODPROBE=1 ++else ++ HAVE_MODPROBE=0 ++fi ++ ++ ++for ac_prog in flex lex ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++if test "${ac_cv_path_LEX+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $LEX in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_LEX="$LEX" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $searchpath ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_path_LEX="$as_dir/$ac_word$ac_exec_ext" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++LEX=$ac_cv_path_LEX ++if test -n "$LEX"; then ++ { echo "$as_me:$LINENO: result: $LEX" >&5 ++echo "${ECHO_T}$LEX" >&6; } ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++ ++ test -n "$LEX" && break ++done ++ ++if test -n "$LEX"; then ++ ++cat >>confdefs.h <<_ACEOF ++#define PATH_LEX "$LEX" ++_ACEOF ++ ++ PATH_LEX="$LEX" ++else ++ { { echo "$as_me:$LINENO: error: required program LEX not found" >&5 ++echo "$as_me: error: required program LEX not found" >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++for ac_prog in bison ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++if test "${ac_cv_path_YACC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $YACC in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_YACC="$YACC" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $searchpath ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_path_YACC="$as_dir/$ac_word$ac_exec_ext" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++YACC=$ac_cv_path_YACC ++if test -n "$YACC"; then ++ { echo "$as_me:$LINENO: result: $YACC" >&5 ++echo "${ECHO_T}$YACC" >&6; } ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++ ++ test -n "$YACC" && break ++done ++ ++if test -n "$YACC"; then ++ ++cat >>confdefs.h <<_ACEOF ++#define PATH_YACC "$YACC" ++_ACEOF ++ ++ PATH_YACC="$YACC" ++else ++ { { echo "$as_me:$LINENO: error: required program YACC not found" >&5 ++echo "$as_me: error: required program YACC not found" >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++for ac_prog in ranlib ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++if test "${ac_cv_path_RANLIB+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $RANLIB in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_RANLIB="$RANLIB" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $searchpath ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_path_RANLIB="$as_dir/$ac_word$ac_exec_ext" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++RANLIB=$ac_cv_path_RANLIB ++if test -n "$RANLIB"; then ++ { echo "$as_me:$LINENO: result: $RANLIB" >&5 ++echo "${ECHO_T}$RANLIB" >&6; } ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++ ++ test -n "$RANLIB" && break ++done ++ ++if test -n "$RANLIB"; then ++ ++cat >>confdefs.h <<_ACEOF ++#define PATH_RANLIB "$RANLIB" ++_ACEOF ++ ++ PATH_RANLIB="$RANLIB" ++else ++ { { echo "$as_me:$LINENO: error: required program RANLIB not found" >&5 ++echo "$as_me: error: required program RANLIB not found" >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++for ac_prog in rpcgen ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++if test "${ac_cv_path_RPCGEN+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $RPCGEN in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_RPCGEN="$RPCGEN" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $searchpath ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_path_RPCGEN="$as_dir/$ac_word$ac_exec_ext" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++RPCGEN=$ac_cv_path_RPCGEN ++if test -n "$RPCGEN"; then ++ { echo "$as_me:$LINENO: result: $RPCGEN" >&5 ++echo "${ECHO_T}$RPCGEN" >&6; } ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++ ++ test -n "$RPCGEN" && break ++done ++ ++if test -n "$RPCGEN"; then ++ ++cat >>confdefs.h <<_ACEOF ++#define PATH_RPCGEN "$RPCGEN" ++_ACEOF ++ ++ PATH_RPCGEN="$RPCGEN" ++else ++ { { echo "$as_me:$LINENO: error: required program RPCGEN not found" >&5 ++echo "$as_me: error: required program RPCGEN not found" >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++ ++# ++# Newer mounts have the -s (sloppy) option to ignore unknown options, ++# good for portability ++# ++if test -n "$MOUNT" ; then ++ { echo "$as_me:$LINENO: checking if mount accepts the -s option" >&5 ++echo $ECHO_N "checking if mount accepts the -s option... $ECHO_C" >&6; } ++ if "$MOUNT" -s > /dev/null 2>&1 ; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define HAVE_SLOPPY_MOUNT 1 ++_ACEOF ++ ++ { echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6; } ++ else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++ fi ++fi ++ ++# LDAP SASL auth need libxml ++for ac_prog in xml2-config ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++{ echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } ++if test "${ac_cv_path_XML_CONFIG+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $XML_CONFIG in ++ [\\/]* | ?:[\\/]*) ++ ac_cv_path_XML_CONFIG="$XML_CONFIG" # Let the user override the test with a path. ++ ;; ++ *) ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ ac_cv_path_XML_CONFIG="$as_dir/$ac_word$ac_exec_ext" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++IFS=$as_save_IFS ++ ++ ;; ++esac ++fi ++XML_CONFIG=$ac_cv_path_XML_CONFIG ++if test -n "$XML_CONFIG"; then ++ { echo "$as_me:$LINENO: result: $XML_CONFIG" >&5 ++echo "${ECHO_T}$XML_CONFIG" >&6; } ++else ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi ++ ++ ++ test -n "$XML_CONFIG" && break ++done ++test -n "$XML_CONFIG" || XML_CONFIG="no" ++ ++{ echo "$as_me:$LINENO: checking for libxml2" >&5 ++echo $ECHO_N "checking for libxml2... $ECHO_C" >&6; } ++if test "$XML_CONFIG" = "no" ++then ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++ HAVE_LIBXML=0 ++else ++ { echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6; } ++ HAVE_LIBXML=1 ++ XML_LIBS=`$XML_CONFIG --libs` ++ XML_FLAGS=`$XML_CONFIG --cflags` ++ XML_VER=`$XML_CONFIG --version` ++ XML_MAJOR=`echo $XML_VER|cut -d\. -f1` ++ if test $XML_MAJOR -le 99 ++ then ++ XML_MINOR=`echo $XML_VER|cut -d\. -f2` ++ if test $XML_MINOR -le 99 ++ then ++ XML_REV=`echo $XML_VER|cut -d\. -f3` ++ if test $XML_REV -le 99; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define LIBXML2_WORKAROUND 1 ++_ACEOF ++ ++ fi ++ fi ++ fi ++fi ++ ++# ++# glibc/libc 6 new libraries ++# + { echo "$as_me:$LINENO: checking for yp_match in -lnsl" >&5 + echo $ECHO_N "checking for yp_match in -lnsl... $ECHO_C" >&6; } + if test "${ac_cv_lib_nsl_yp_match+set}" = set; then +@@ -6280,6 +6447,14 @@ confdir!$confdir$ac_delim + mapdir!$mapdir$ac_delim + fifodir!$fifodir$ac_delim + flagdir!$flagdir$ac_delim ++CC!$CC$ac_delim ++CFLAGS!$CFLAGS$ac_delim ++LDFLAGS!$LDFLAGS$ac_delim ++CPPFLAGS!$CPPFLAGS$ac_delim ++ac_ct_CC!$ac_ct_CC$ac_delim ++EXEEXT!$EXEEXT$ac_delim ++OBJEXT!$OBJEXT$ac_delim ++TIRPCLIB!$TIRPCLIB$ac_delim + DMALLOCLIB!$DMALLOCLIB$ac_delim + MOUNT!$MOUNT$ac_delim + HAVE_MOUNT!$HAVE_MOUNT$ac_delim +@@ -6300,13 +6475,6 @@ PATH_RANLIB!$PATH_RANLIB$ac_delim + RPCGEN!$RPCGEN$ac_delim + PATH_RPCGEN!$PATH_RPCGEN$ac_delim + XML_CONFIG!$XML_CONFIG$ac_delim +-CC!$CC$ac_delim +-CFLAGS!$CFLAGS$ac_delim +-LDFLAGS!$LDFLAGS$ac_delim +-CPPFLAGS!$CPPFLAGS$ac_delim +-ac_ct_CC!$ac_ct_CC$ac_delim +-EXEEXT!$EXEEXT$ac_delim +-OBJEXT!$OBJEXT$ac_delim + LIBNSL!$LIBNSL$ac_delim + LIBRESOLV!$LIBRESOLV$ac_delim + HAVE_HESIOD!$HAVE_HESIOD$ac_delim +@@ -6330,7 +6498,7 @@ LIBOBJS!$LIBOBJS$ac_delim + LTLIBOBJS!$LTLIBOBJS$ac_delim + _ACEOF + +- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 90; then ++ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 91; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +diff --git a/configure.in b/configure.in +index 423f213..d09a2b6 100644 +--- a/configure.in ++++ b/configure.in +@@ -113,6 +113,12 @@ AC_MSG_RESULT([$flagdir]) + AC_SUBST(flagdir) + + # ++# Use libtirpc ++# ++AM_WITH_LIBTIRPC() ++AC_SUBST(TIRPCLIB) ++ ++# + # Optional include dmalloc + # + AM_WITH_DMALLOC() +diff --git a/daemon/automount.c b/daemon/automount.c +index 269fc5b..1ec686b 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -2057,7 +2057,10 @@ int main(int argc, char *argv[]) + } + + #ifdef LIBXML2_WORKAROUND +- void *dh = dlopen("libxml2.so", RTLD_NOW); ++ void *dh_xml2 = dlopen("libxml2.so", RTLD_NOW); ++#endif ++#ifdef TIRPC_WORKAROUND ++ void *dh_tirpc = dlopen("libitirpc.so", RTLD_NOW); + #endif + + if (!master_read_master(master_list, age, 0)) { +@@ -2090,9 +2093,13 @@ int main(int argc, char *argv[]) + closelog(); + release_flag_file(); + ++#ifdef TIRPC_WORKAROUND ++ if (dh_tirpc) ++ dlclose(dh_tirpc); ++#endif + #ifdef LIBXML2_WORKAROUND +- if (dh) +- dlclose(dh); ++ if (dh_xml2) ++ dlclose(dh_xml2); + #endif + close_ioctl_ctl(); + +diff --git a/include/config.h.in b/include/config.h.in +index d8f1747..31b0d75 100644 +--- a/include/config.h.in ++++ b/include/config.h.in +@@ -66,6 +66,9 @@ + /* Define to 1 if you have the header file. */ + #undef HAVE_UNISTD_H + ++/* Use IPv6 with libtirpc */ ++#undef INET6 ++ + /* Use libxml2 tsd usage workaround */ + #undef LIBXML2_WORKAROUND + +@@ -114,6 +117,9 @@ + /* Define to 1 if you have the ANSI C header files. */ + #undef STDC_HEADERS + ++/* Use libtirpc tsd usage workaround */ ++#undef TIRPC_WORKAROUND ++ + /* Define if using the dmalloc debugging malloc package */ + #undef WITH_DMALLOC + diff --git a/autofs-5.0.4-dont-fail-on-ipv6-address-adding-host.patch b/autofs-5.0.4-dont-fail-on-ipv6-address-adding-host.patch new file mode 100644 index 0000000..89f4790 --- /dev/null +++ b/autofs-5.0.4-dont-fail-on-ipv6-address-adding-host.patch @@ -0,0 +1,68 @@ +autofs-5.0.4 - dont fail on ipv6 address adding host + +From: Ian Kent + +We don't have IPv6 support enabled in libtirpc yet. When we +perform name (or address) lookup and we get a mixture of IPv4 +and IPv6 addresses the lack of IPv6 support can cause the +parse_location() function to fail to add any valid hosts when +in fact it should. +--- + + CHANGELOG | 1 + + include/replicated.h | 1 + + modules/replicated.c | 9 ++++++++- + 3 files changed, 10 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 89aaa99..7e1012f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -46,6 +46,7 @@ + - dont umount existing direct mount on master re-read. + - fix incorrect shutdown introduced by library relaod fixes. + - improve manual umount recovery. ++- dont fail on ipv6 address when adding host. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/include/replicated.h b/include/replicated.h +index e0133ff..fd87c08 100644 +--- a/include/replicated.h ++++ b/include/replicated.h +@@ -21,6 +21,7 @@ + #define PROXIMITY_SUBNET 0x0002 + #define PROXIMITY_NET 0x0004 + #define PROXIMITY_OTHER 0x0008 ++#define PROXIMITY_UNSUPPORTED 0x0010 + + #define NFS2_SUPPORTED 0x0010 + #define NFS3_SUPPORTED 0x0020 +diff --git a/modules/replicated.c b/modules/replicated.c +index 79845d0..a66de9f 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -181,7 +181,7 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + + case AF_INET6: + #ifndef INET6 +- return PROXIMITY_ERROR; ++ return PROXIMITY_UNSUPPORTED; + #else + addr6 = (struct sockaddr_in6 *) host_addr; + hst6_addr = (struct in6_addr *) &addr6->sin6_addr; +@@ -1048,6 +1048,13 @@ static int add_new_host(struct host **list, + int addr_len; + + prx = get_proximity(host_addr->ai_addr); ++ /* ++ * If we tried to add an IPv6 address and we don't have IPv6 ++ * support return success in the hope of getting an IPv4 ++ * address later. ++ */ ++ if (prx == PROXIMITY_UNSUPPORTED) ++ return 1; + if (prx == PROXIMITY_ERROR) + return 0; + diff --git a/autofs-5.0.4-dont-umount-existing-direct-mount-on-reread.patch b/autofs-5.0.4-dont-umount-existing-direct-mount-on-reread.patch new file mode 100644 index 0000000..6f76087 --- /dev/null +++ b/autofs-5.0.4-dont-umount-existing-direct-mount-on-reread.patch @@ -0,0 +1,368 @@ +autofs-5.0.4 - dont umount existing direct mount on master re-read + +From: Ian Kent + +Since direct mounts can have multiple entries in the master map they each +have an instance associated with them. If one entry changes, such as the +mount options, the instance comparison test fails and a new instance is +added. This causes autofs to get confused because there are now two +entries that contain the same mount information in different internal +caches. There are several consequences of this, most of which are just +noise in the log, but it also causes confuion for the expiration of mounts +since, for an active mount, the old cache entry can't be pruned until it's +umounted. Also, the map caches were not being properly pruned. +--- + + CHANGELOG | 1 + daemon/lookup.c | 160 ++++++++++++++++++++++++++++----------------------- + daemon/state.c | 90 +++++++++++++++++++++-------- + include/automount.h | 1 + 4 files changed, 156 insertions(+), 96 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 387af5e..7ca45fd 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -43,6 +43,7 @@ + - use percent hack for master map keys. + - use intr option as hosts mount default. + - fix kernel includes. ++- dont umount existing direct mount on master re-read. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/lookup.c b/daemon/lookup.c +index fd2ce55..bc94655 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -1016,96 +1016,114 @@ static char *make_fullpath(const char *root, const char *key) + return path; + } + +-int lookup_prune_cache(struct autofs_point *ap, time_t age) ++void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, time_t age) + { +- struct master_mapent *entry = ap->entry; +- struct map_source *map; +- struct mapent_cache *mc; + struct mapent *me, *this; + char *path; + int status = CHE_FAIL; + +- pthread_cleanup_push(master_source_lock_cleanup, entry); +- master_source_readlock(entry); ++ me = cache_enumerate(mc, NULL); ++ while (me) { ++ struct mapent *valid; ++ char *key = NULL, *next_key = NULL; + +- map = entry->maps; +- while (map) { +- /* Is the map stale */ +- if (!map->stale) { +- map = map->next; ++ if (me->age >= age) { ++ me = cache_enumerate(mc, me); + continue; + } +- mc = map->mc; +- pthread_cleanup_push(cache_lock_cleanup, mc); +- cache_readlock(mc); +- me = cache_enumerate(mc, NULL); +- while (me) { +- char *key = NULL, *next_key = NULL; + +- if (me->age >= age) { +- me = cache_enumerate(mc, me); +- continue; +- } ++ key = strdup(me->key); ++ me = cache_enumerate(mc, me); ++ if (!key || *key == '*') { ++ if (key) ++ free(key); ++ continue; ++ } + +- key = strdup(me->key); +- me = cache_enumerate(mc, me); +- if (!key || *key == '*') { +- if (key) +- free(key); +- continue; +- } ++ path = make_fullpath(ap->path, key); ++ if (!path) { ++ warn(ap->logopt, "can't malloc storage for path"); ++ free(key); ++ continue; ++ } + +- path = make_fullpath(ap->path, key); +- if (!path) { +- warn(ap->logopt, +- "can't malloc storage for path"); +- free(key); +- continue; +- } ++ /* ++ * If this key has another valid entry we want to prune it, ++ * even if it's a mount, as the valid entry will take the ++ * mount if it is a direct mount or it's just a stale indirect ++ * cache entry. ++ */ ++ valid = lookup_source_valid_mapent(ap, key, LKP_DISTINCT); ++ if (!valid && ++ is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { ++ debug(ap->logopt, ++ "prune check posponed, %s mounted", path); ++ free(key); ++ free(path); ++ continue; ++ } ++ if (valid) ++ cache_unlock(valid->mc); + +- if (is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { +- debug(ap->logopt, +- "prune check posponed, %s mounted", path); +- free(key); +- free(path); +- continue; +- } ++ if (me) ++ next_key = strdup(me->key); + +- if (me) +- next_key = strdup(me->key); ++ cache_unlock(mc); + ++ cache_writelock(mc); ++ this = cache_lookup_distinct(mc, key); ++ if (!this) { + cache_unlock(mc); ++ goto next; ++ } + +- cache_writelock(mc); +- this = cache_lookup_distinct(mc, key); +- if (!this) { +- cache_unlock(mc); +- goto next; +- } +- +- if (!is_mounted(_PROC_MOUNTS, path, MNTS_AUTOFS)) { +- status = CHE_FAIL; +- if (this->ioctlfd == -1) +- status = cache_delete(mc, key); +- if (status != CHE_FAIL) { +- if (ap->type == LKP_INDIRECT) { +- if (ap->flags & MOUNT_FLAG_GHOST) +- rmdir_path(ap, path, ap->dev); +- } else +- rmdir_path(ap, path, this->dev); +- } ++ if (valid) ++ cache_delete(mc, key); ++ else if (!is_mounted(_PROC_MOUNTS, path, MNTS_AUTOFS)) { ++ status = CHE_FAIL; ++ if (this->ioctlfd == -1) ++ status = cache_delete(mc, key); ++ if (status != CHE_FAIL) { ++ if (ap->type == LKP_INDIRECT) { ++ if (ap->flags & MOUNT_FLAG_GHOST) ++ rmdir_path(ap, path, ap->dev); ++ } else ++ rmdir_path(ap, path, this->dev); + } +- cache_unlock(mc); ++ } ++ cache_unlock(mc); + + next: +- cache_readlock(mc); +- if (next_key) { +- me = cache_lookup_distinct(mc, next_key); +- free(next_key); +- } +- free(key); +- free(path); ++ cache_readlock(mc); ++ if (next_key) { ++ me = cache_lookup_distinct(mc, next_key); ++ free(next_key); + } ++ free(key); ++ free(path); ++ } ++ ++ return; ++} ++ ++int lookup_prune_cache(struct autofs_point *ap, time_t age) ++{ ++ struct master_mapent *entry = ap->entry; ++ struct map_source *map; ++ ++ pthread_cleanup_push(master_source_lock_cleanup, entry); ++ master_source_readlock(entry); ++ ++ map = entry->maps; ++ while (map) { ++ /* Is the map stale */ ++ if (!map->stale) { ++ map = map->next; ++ continue; ++ } ++ pthread_cleanup_push(cache_lock_cleanup, map->mc); ++ cache_readlock(map->mc); ++ lookup_prune_one_cache(ap, map->mc, age); + pthread_cleanup_pop(1); + map->stale = 0; + map = map->next; +@@ -1124,7 +1142,6 @@ struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *k + struct mapent_cache *mc; + struct mapent *me = NULL; + +- master_source_readlock(entry); + map = entry->maps; + while (map) { + /* +@@ -1147,7 +1164,6 @@ struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *k + cache_unlock(mc); + map = map->next; + } +- master_source_unlock(entry); + + return me; + } +diff --git a/daemon/state.c b/daemon/state.c +index 533e241..84ccba3 100644 +--- a/daemon/state.c ++++ b/daemon/state.c +@@ -352,6 +352,68 @@ static void tree_mnts_cleanup(void *arg) + return; + } + ++static void do_readmap_mount(struct autofs_point *ap, struct mnt_list *mnts, ++ struct map_source *map, struct mapent *me, time_t now) ++{ ++ struct mapent_cache *nc; ++ struct mapent *ne, *nested, *valid; ++ ++ nc = ap->entry->master->nc; ++ ++ ne = cache_lookup_distinct(nc, me->key); ++ if (!ne) { ++ nested = cache_partial_match(nc, me->key); ++ if (nested) { ++ error(ap->logopt, ++ "removing invalid nested null entry %s", ++ nested->key); ++ nested = cache_partial_match(nc, me->key); ++ if (nested) ++ cache_delete(nc, nested->key); ++ } ++ } ++ ++ if (me->age < now || (ne && map->master_line > ne->age)) { ++ /* ++ * The map instance may have changed, such as the map name or ++ * the mount options, but the direct map entry may still exist ++ * in one of the other maps. If so then update the new cache ++ * entry device and inode so we can find it at lookup. Later, ++ * the mount for the new cache entry will just update the ++ * timeout. ++ * ++ * TODO: how do we recognise these orphaned map instances. We ++ * can't just delete these instances when the cache becomes ++ * empty because that is a valid state for a master map entry. ++ * This is becuase of the requirement to continue running with ++ * an empty cache awaiting a map re-load. ++ */ ++ valid = lookup_source_valid_mapent(ap, me->key, LKP_DISTINCT); ++ if (valid) { ++ struct mapent_cache *vmc = valid->mc; ++ cache_unlock(vmc); ++ debug(ap->logopt, ++ "updating cache entry for valid direct trigger %s", ++ me->key); ++ cache_writelock(vmc); ++ valid = cache_lookup_distinct(vmc, me->key); ++ /* Take over the mount if there is one */ ++ valid->ioctlfd = me->ioctlfd; ++ me->ioctlfd = -1; ++ /* Set device and inode number of the new mapent */ ++ cache_set_ino_index(vmc, me->key, me->dev, me->ino); ++ cache_unlock(vmc); ++ } else if (!tree_is_mounted(mnts, me->key, MNTS_REAL)) ++ do_umount_autofs_direct(ap, mnts, me); ++ else ++ debug(ap->logopt, ++ "%s is mounted", me->key); ++ } else ++ do_mount_autofs_direct(ap, mnts, me); ++ ++ return; ++} ++ + static void *do_readmap(void *arg) + { + struct autofs_point *ap; +@@ -398,7 +460,8 @@ static void *do_readmap(void *arg) + lookup_prune_cache(ap, now); + status = lookup_ghost(ap, ap->path); + } else { +- struct mapent *me, *ne, *nested; ++ struct mapent *me; ++ + mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/"); + pthread_cleanup_push(tree_mnts_cleanup, mnts); + pthread_cleanup_push(master_source_lock_cleanup, ap->entry); +@@ -418,31 +481,10 @@ static void *do_readmap(void *arg) + cache_readlock(mc); + me = cache_enumerate(mc, NULL); + while (me) { +- ne = cache_lookup_distinct(nc, me->key); +- if (!ne) { +- nested = cache_partial_match(nc, me->key); +- if (nested) { +- error(ap->logopt, +- "removing invalid nested null entry %s", +- nested->key); +- nested = cache_partial_match(nc, me->key); +- if (nested) +- cache_delete(nc, nested->key); +- } +- } +- +- /* TODO: check return of do_... */ +- if (me->age < now || (ne && map->master_line > ne->age)) { +- if (!tree_is_mounted(mnts, me->key, MNTS_REAL)) +- do_umount_autofs_direct(ap, mnts, me); +- else +- debug(ap->logopt, +- "%s is mounted", me->key); +- } else +- do_mount_autofs_direct(ap, mnts, me); +- ++ do_readmap_mount(ap, mnts, map, me, now); + me = cache_enumerate(mc, me); + } ++ lookup_prune_one_cache(ap, map->mc, now); + pthread_cleanup_pop(1); + map->stale = 0; + map = map->next; +diff --git a/include/automount.h b/include/automount.h +index d4675bd..ae517a7 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -238,6 +238,7 @@ int lookup_enumerate(struct autofs_point *ap, + int lookup_ghost(struct autofs_point *ap, const char *root); + int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const char *name, int name_len); + void lookup_close_lookup(struct autofs_point *ap); ++void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, time_t age); + int lookup_prune_cache(struct autofs_point *ap, time_t age); + struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *key, unsigned int type); + struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key, unsigned int type); diff --git a/autofs-5.0.4-easy-alloca-replacements-fix.patch b/autofs-5.0.4-easy-alloca-replacements-fix.patch new file mode 100644 index 0000000..1d17e72 --- /dev/null +++ b/autofs-5.0.4-easy-alloca-replacements-fix.patch @@ -0,0 +1,191 @@ +autofs-5.0.4 - easy alloca replacements fix + +From: Ian Kent + +Fix array out of bounds accesses and remove alloca(3) calls from +modules/mount_autofs.c and modules/mount_nfs.c as well. +--- + + CHANGELOG | 2 +- + modules/lookup_ldap.c | 3 --- + modules/mount_autofs.c | 9 ++------- + modules/mount_bind.c | 6 +++++- + modules/mount_changer.c | 6 +++++- + modules/mount_ext2.c | 6 +++++- + modules/mount_generic.c | 6 +++++- + modules/mount_nfs.c | 12 +++++++----- + 8 files changed, 30 insertions(+), 20 deletions(-) + + +--- autofs-5.0.4.orig/CHANGELOG ++++ autofs-5.0.4/CHANGELOG +@@ -20,7 +20,7 @@ + - update to configure libtirpc if present. + - update to provide ipv6 name and address support. + - update to provide ipv6 address parsing. +- ++- easy alloca replacements fix. + + 4/11/2008 autofs-5.0.4 + ----------------------- +--- autofs-5.0.4.orig/modules/lookup_ldap.c ++++ autofs-5.0.4/modules/lookup_ldap.c +@@ -1474,7 +1474,6 @@ int lookup_read_master(struct master *ma + free(query); + return NSS_STATUS_UNAVAIL; + } +- query[l] = '\0'; + + /* Initialize the LDAP context. */ + ldap = do_reconnect(logopt, ctxt); +@@ -2213,7 +2212,6 @@ static int read_one_map(struct autofs_po + free(sp.query); + return NSS_STATUS_UNAVAIL; + } +- sp.query[l] = '\0'; + + /* Initialize the LDAP context. */ + sp.ldap = do_reconnect(ap->logopt, ctxt); +@@ -2404,7 +2402,6 @@ static int lookup_one(struct autofs_poin + free(query); + return CHE_FAIL; + } +- query[ql] = '\0'; + + /* Initialize the LDAP context. */ + ldap = do_reconnect(ap->logopt, ctxt); +--- autofs-5.0.4.orig/modules/mount_autofs.c ++++ autofs-5.0.4/modules/mount_autofs.c +@@ -45,7 +45,8 @@ int mount_mount(struct autofs_point *ap, + { + struct startup_cond suc; + pthread_t thid; +- char *realpath, *mountpoint; ++ char realpath[PATH_MAX]; ++ char mountpoint[PATH_MAX]; + const char **argv; + int argc, status, ghost = ap->flags & MOUNT_FLAG_GHOST; + time_t timeout = ap->exp_timeout; +@@ -62,8 +63,6 @@ int mount_mount(struct autofs_point *ap, + /* Root offset of multi-mount */ + len = strlen(root); + if (root[len - 1] == '/') { +- realpath = alloca(strlen(ap->path) + name_len + 2); +- mountpoint = alloca(len + 1); + strcpy(realpath, ap->path); + strcat(realpath, "/"); + strcat(realpath, name); +@@ -71,8 +70,6 @@ int mount_mount(struct autofs_point *ap, + strncpy(mountpoint, root, len); + mountpoint[len] = '\0'; + } else if (*name == '/') { +- realpath = alloca(name_len + 1); +- mountpoint = alloca(len + 1); + if (ap->flags & MOUNT_FLAG_REMOUNT) { + strcpy(mountpoint, name); + strcpy(realpath, name); +@@ -81,8 +78,6 @@ int mount_mount(struct autofs_point *ap, + strcpy(realpath, name); + } + } else { +- realpath = alloca(len + name_len + 2); +- mountpoint = alloca(len + name_len + 2); + strcpy(mountpoint, root); + strcat(mountpoint, "/"); + strcpy(realpath, mountpoint); +--- autofs-5.0.4.orig/modules/mount_bind.c ++++ autofs-5.0.4/modules/mount_bind.c +@@ -81,8 +81,12 @@ int mount_mount(struct autofs_point *ap, + len = strlen(root); + if (root[len - 1] == '/') { + len = snprintf(fullpath, len, "%s", root); +- /* Direct mount name is absolute path so don't use root */ + } else if (*name == '/') { ++ /* ++ * Direct or offset mount, name is absolute path so ++ * don't use root (but with move mount changes root ++ * is now the same as name). ++ */ + len = sprintf(fullpath, "%s", root); + } else { + len = sprintf(fullpath, "%s/%s", root, name); +--- autofs-5.0.4.orig/modules/mount_changer.c ++++ autofs-5.0.4/modules/mount_changer.c +@@ -58,8 +58,12 @@ int mount_mount(struct autofs_point *ap, + len = strlen(root); + if (root[len - 1] == '/') { + len = snprintf(fullpath, len, "%s", root); +- /* Direct mount name is absolute path so don't use root */ + } else if (*name == '/') { ++ /* ++ * Direct or offset mount, name is absolute path so ++ * don't use root (but with move mount changes root ++ * is now the same as name). ++ */ + len = sprintf(fullpath, "%s", root); + } else { + len = sprintf(fullpath, "%s/%s", root, name); +--- autofs-5.0.4.orig/modules/mount_ext2.c ++++ autofs-5.0.4/modules/mount_ext2.c +@@ -50,8 +50,12 @@ int mount_mount(struct autofs_point *ap, + len = strlen(root); + if (root[len - 1] == '/') { + len = snprintf(fullpath, len, "%s", root); +- /* Direct mount name is absolute path so don't use root */ + } else if (*name == '/') { ++ /* ++ * Direct or offset mount, name is absolute path so ++ * don't use root (but with move mount changes root ++ * is now the same as name). ++ */ + len = sprintf(fullpath, "%s", root); + } else { + len = sprintf(fullpath, "%s/%s", root, name); +--- autofs-5.0.4.orig/modules/mount_generic.c ++++ autofs-5.0.4/modules/mount_generic.c +@@ -49,8 +49,12 @@ int mount_mount(struct autofs_point *ap, + len = strlen(root); + if (root[len - 1] == '/') { + len = snprintf(fullpath, len, "%s", root); +- /* Direct mount name is absolute path so don't use root */ + } else if (*name == '/') { ++ /* ++ * Direct or offset mount, name is absolute path so ++ * don't use root (but with move mount changes root ++ * is now the same as name). ++ */ + len = sprintf(fullpath, "%s", root); + } else { + len = sprintf(fullpath, "%s/%s", root, name); +--- autofs-5.0.4.orig/modules/mount_nfs.c ++++ autofs-5.0.4/modules/mount_nfs.c +@@ -58,7 +58,8 @@ int mount_mount(struct autofs_point *ap, + const char *what, const char *fstype, const char *options, + void *context) + { +- char *fullpath, buf[MAX_ERR_BUF]; ++ char fullpath[PATH_MAX]; ++ char buf[MAX_ERR_BUF]; + struct host *this, *hosts = NULL; + unsigned int vers; + char *nfsoptions = NULL; +@@ -150,14 +151,15 @@ int mount_mount(struct autofs_point *ap, + /* Root offset of multi-mount */ + len = strlen(root); + if (root[len - 1] == '/') { +- fullpath = alloca(len); + len = snprintf(fullpath, len, "%s", root); +- /* Direct mount name is absolute path so don't use root */ + } else if (*name == '/') { +- fullpath = alloca(len + 1); ++ /* ++ * Direct or offset mount, name is absolute path so ++ * don't use root (but with move mount changes root ++ * is now the same as name). ++ */ + len = sprintf(fullpath, "%s", root); + } else { +- fullpath = alloca(len + name_len + 2); + len = sprintf(fullpath, "%s/%s", root, name); + } + fullpath[len] = '\0'; diff --git a/autofs-5.0.4-easy-alloca-replacements.patch b/autofs-5.0.4-easy-alloca-replacements.patch new file mode 100644 index 0000000..3441fb7 --- /dev/null +++ b/autofs-5.0.4-easy-alloca-replacements.patch @@ -0,0 +1,1156 @@ +autofs-5.0.4 - easy alloca replacements + +From: Valerie Aurora Henson + +alloca() is compiler-dependent, non-standard, and has undefined +behavior when it fails (IOW, the program crashes). Replace with +normal C stack variables where possible and malloc() where not. +--- + + daemon/automount.c | 29 ++++++-------- + daemon/direct.c | 12 ++---- + daemon/flag.c | 13 +++--- + daemon/indirect.c | 12 ++---- + daemon/module.c | 45 +++++++--------------- + lib/cache.c | 31 +++++---------- + lib/cat_path.c | 1 + modules/lookup_file.c | 82 +++++++++++++---------------------------- + modules/lookup_ldap.c | 93 +++++++++++++++++++++++++++++----------------- + modules/lookup_nisplus.c | 71 ++++++++++++++++++++--------------- + modules/mount_autofs.c | 1 + modules/mount_bind.c | 7 +-- + modules/mount_changer.c | 5 -- + modules/mount_ext2.c | 5 -- + modules/mount_generic.c | 5 -- + 15 files changed, 184 insertions(+), 228 deletions(-) + + +diff --git a/daemon/automount.c b/daemon/automount.c +index e20e7c9..269fc5b 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -127,8 +127,8 @@ static int do_mkdir(const char *parent, const char *path, mode_t mode) + + int mkdir_path(const char *path, mode_t mode) + { +- char *buf = alloca(strlen(path) + 1); +- char *parent = alloca(strlen(path) + 1); ++ char buf[PATH_MAX]; ++ char parent[PATH_MAX]; + const char *cp = path, *lcp = path; + char *bp = buf, *pp = parent; + +@@ -163,7 +163,7 @@ int mkdir_path(const char *path, mode_t mode) + int rmdir_path(struct autofs_point *ap, const char *path, dev_t dev) + { + int len = strlen(path); +- char *buf = alloca(len + 1); ++ char buf[PATH_MAX]; + char *cp; + int first = 1; + struct stat st; +@@ -468,20 +468,17 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + pthread_cleanup_push(cache_lock_cleanup, mc); + + if (me->multi) { +- char *root, *base; +- size_t ap_len; ++ char root[PATH_MAX]; ++ char *base; + int cur_state; + +- ap_len = strlen(ap->path); +- +- if (!strchr(me->multi->key, '/')) { ++ if (!strchr(me->multi->key, '/')) + /* Indirect multi-mount root */ +- root = alloca(ap_len + strlen(me->multi->key) + 2); +- strcpy(root, ap->path); +- strcat(root, "/"); +- strcat(root, me->multi->key); +- } else +- root = me->multi->key; ++ /* sprintf okay - if it's mounted, it's ++ * PATH_MAX or less bytes */ ++ sprintf(root, "%s/%s", ap->path, me->multi->key); ++ else ++ strcpy(root, me->multi->key); + + if (is_mm_root) + base = NULL; +@@ -929,14 +926,14 @@ static int get_pkt(struct autofs_point *ap, union autofs_v5_packet_union *pkt) + + int do_expire(struct autofs_point *ap, const char *name, int namelen) + { +- char buf[PATH_MAX + 1]; ++ char buf[PATH_MAX]; + int len, ret; + + if (*name != '/') { + len = ncat_path(buf, sizeof(buf), ap->path, name, namelen); + } else { + len = snprintf(buf, PATH_MAX, "%s", name); +- if (len > PATH_MAX) ++ if (len >= PATH_MAX) + len = 0; + } + +diff --git a/daemon/direct.c b/daemon/direct.c +index fc3c969..4f4ff20 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -637,7 +637,9 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char * + time_t timeout = ap->exp_timeout; + struct stat st; + int ioctlfd, status, ret; +- const char *type, *map_name = NULL; ++ const char *hosts_map_name = "-hosts"; ++ const char *map_name = hosts_map_name; ++ const char *type; + char mountpoint[PATH_MAX]; + + if (ops->version && ap->flags & MOUNT_FLAG_REMOUNT) { +@@ -740,13 +742,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char * + mp->options, mountpoint); + + type = ap->entry->maps->type; +- if (type && !strcmp(ap->entry->maps->type, "hosts")) { +- char *tmp = alloca(7); +- if (tmp) { +- strcpy(tmp, "-hosts"); +- map_name = (const char *) tmp; +- } +- } else ++ if (!type || strcmp(ap->entry->maps->type, "hosts")) + map_name = me->mc->map->argv[0]; + + ret = mount(map_name, mountpoint, "autofs", MS_MGC_VAL, mp->options); +diff --git a/daemon/flag.c b/daemon/flag.c +index e43cece..f8fe163 100644 +--- a/daemon/flag.c ++++ b/daemon/flag.c +@@ -23,10 +23,10 @@ + #include + #include + #include +-#include + #include + #include + #include ++#include + + #include "automount.h" + +@@ -113,12 +113,13 @@ void release_flag_file(void) + /* * Try to create flag file */ + int aquire_flag_file(void) + { +- char *linkf; +- int len; ++ char linkf[PATH_MAX]; ++ size_t len; + +- len = strlen(FLAG_FILE) + MAX_PIDSIZE; +- linkf = alloca(len + 1); +- snprintf(linkf, len, "%s.%d", FLAG_FILE, getpid()); ++ len = snprintf(linkf, sizeof(linkf), "%s.%d", FLAG_FILE, getpid()); ++ if (len >= sizeof(linkf)) ++ /* Didn't acquire it */ ++ return 0; + + /* + * Repeat until it was us who made the link or we find the +diff --git a/daemon/indirect.c b/daemon/indirect.c +index f40c393..2539282 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -90,7 +90,9 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) + struct ioctl_ops *ops = get_ioctl_ops(); + time_t timeout = ap->exp_timeout; + char *options = NULL; +- const char *type, *map_name = NULL; ++ const char *hosts_map_name = "-hosts"; ++ const char *map_name = hosts_map_name; ++ const char *type; + struct stat st; + struct mnt_list *mnts; + int ret; +@@ -142,13 +144,7 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) + } + + type = ap->entry->maps->type; +- if (type && !strcmp(ap->entry->maps->type, "hosts")) { +- char *tmp = alloca(7); +- if (tmp) { +- strcpy(tmp, "-hosts"); +- map_name = (const char *) tmp; +- } +- } else ++ if (!type || strcmp(ap->entry->maps->type, "hosts")) + map_name = ap->entry->maps->argv[0]; + + ret = mount(map_name, root, "autofs", MS_MGC_VAL, options); +diff --git a/daemon/module.c b/daemon/module.c +index e593d75..466d8d7 100644 +--- a/daemon/module.c ++++ b/daemon/module.c +@@ -58,15 +58,11 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + { + struct lookup_mod *mod; + char buf[MAX_ERR_BUF]; +- char *fnbuf; +- size_t size_name; +- size_t size_fnbuf; ++ char fnbuf[PATH_MAX]; ++ size_t size; + void *dh; + int *ver; + +- size_name = _strlen(name, PATH_MAX + 1); +- if (!size_name) +- return NULL; + + mod = malloc(sizeof(struct lookup_mod)); + if (!mod) { +@@ -77,9 +73,9 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + return NULL; + } + +- size_fnbuf = size_name + strlen(AUTOFS_LIB_DIR) + 13; +- fnbuf = alloca(size_fnbuf); +- if (!fnbuf) { ++ size = snprintf(fnbuf, sizeof(fnbuf), ++ "%s/lookup_%s.so", AUTOFS_LIB_DIR, name); ++ if (size >= sizeof(fnbuf)) { + free(mod); + if (err_prefix) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +@@ -87,7 +83,6 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + } + return NULL; + } +- snprintf(fnbuf, size_fnbuf, "%s/lookup_%s.so", AUTOFS_LIB_DIR, name); + + if (!(dh = dlopen(fnbuf, RTLD_NOW))) { + if (err_prefix) +@@ -141,15 +136,11 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix, + { + struct parse_mod *mod; + char buf[MAX_ERR_BUF]; +- char *fnbuf; +- size_t size_name; +- size_t size_fnbuf; ++ char fnbuf[PATH_MAX]; ++ size_t size; + void *dh; + int *ver; + +- size_name = _strlen(name, PATH_MAX + 1); +- if (!size_name) +- return NULL; + + mod = malloc(sizeof(struct parse_mod)); + if (!mod) { +@@ -160,9 +151,9 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix, + return NULL; + } + +- size_fnbuf = size_name + strlen(AUTOFS_LIB_DIR) + 13; +- fnbuf = alloca(size_fnbuf); +- if (!fnbuf) { ++ size = snprintf(fnbuf, sizeof(fnbuf), ++ "%s/parse_%s.so", AUTOFS_LIB_DIR, name); ++ if (size >= sizeof(fnbuf)) { + free(mod); + if (err_prefix) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +@@ -170,7 +161,6 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix, + } + return NULL; + } +- snprintf(fnbuf, size_fnbuf, "%s/parse_%s.so", AUTOFS_LIB_DIR, name); + + if (!(dh = dlopen(fnbuf, RTLD_NOW))) { + if (err_prefix) +@@ -222,15 +212,11 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix) + { + struct mount_mod *mod; + char buf[MAX_ERR_BUF]; +- char *fnbuf; +- size_t size_name; +- size_t size_fnbuf; ++ char fnbuf[PATH_MAX]; ++ size_t size; + void *dh; + int *ver; + +- size_name = _strlen(name, PATH_MAX + 1); +- if (!size_name) +- return NULL; + + mod = malloc(sizeof(struct mount_mod)); + if (!mod) { +@@ -241,9 +227,9 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix) + return NULL; + } + +- size_fnbuf = size_name + strlen(AUTOFS_LIB_DIR) + 13; +- fnbuf = alloca(size_fnbuf); +- if (!fnbuf) { ++ size = snprintf(fnbuf, sizeof(fnbuf), ++ "%s/mount_%s.so", AUTOFS_LIB_DIR, name); ++ if (size >= sizeof(fnbuf)) { + free(mod); + if (err_prefix) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +@@ -251,7 +237,6 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix) + } + return NULL; + } +- snprintf(fnbuf, size_fnbuf, "%s/mount_%s.so", AUTOFS_LIB_DIR, name); + + if (!(dh = dlopen(fnbuf, RTLD_NOW))) { + if (err_prefix) +diff --git a/lib/cache.c b/lib/cache.c +index 4cb4582..cd62ac2 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -482,27 +482,23 @@ struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int s + { + struct list_head *p; + struct mapent *this; +- int plen = strlen(prefix); +- char *o_key; ++ /* Keys for direct maps may be as long as a path name */ ++ char o_key[PATH_MAX]; ++ /* Avoid "//" at the beginning of paths */ ++ const char *path_prefix = strlen(prefix) > 1 ? prefix : ""; ++ size_t size; + + /* root offset duplicates "/" */ +- if (plen > 1) { +- o_key = alloca(plen + strlen(offset) + 1); +- strcpy(o_key, prefix); +- strcat(o_key, offset); +- } else { +- o_key = alloca(strlen(offset) + 1); +- strcpy(o_key, offset); +- } ++ size = snprintf(o_key, sizeof(o_key), "%s%s", path_prefix, offset); ++ if (size >= sizeof(o_key)) ++ return NULL; + + list_for_each(p, head) { + this = list_entry(p, struct mapent, multi_list); + if (!strcmp(&this->key[start], o_key)) +- goto done; ++ return this; + } +- this = NULL; +-done: +- return this; ++ return NULL; + } + + /* cache must be read locked by caller */ +@@ -759,13 +755,8 @@ int cache_delete(struct mapent_cache *mc, const char *key) + struct mapent *me = NULL, *pred; + u_int32_t hashval = hash(key, mc->size); + int status, ret = CHE_OK; +- char *this; ++ char this[PATH_MAX]; + +- this = alloca(strlen(key) + 1); +- if (!this) { +- ret = CHE_FAIL; +- goto done; +- } + strcpy(this, key); + + me = mc->hash[hashval]; +diff --git a/lib/cat_path.c b/lib/cat_path.c +index 576b424..60669db 100644 +--- a/lib/cat_path.c ++++ b/lib/cat_path.c +@@ -12,7 +12,6 @@ + * + * ----------------------------------------------------------------------- */ + +-#include + #include + #include + #include +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index aafeb8b..ba80f2a 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -378,8 +378,8 @@ int lookup_read_master(struct master *master, time_t age, void *context) + unsigned int logopt = master->logopt; + char *buffer; + int blen; +- char *path; +- char *ent; ++ char path[KEY_MAX_LEN + 1]; ++ char ent[MAPENT_MAX_LEN + 1]; + FILE *f; + unsigned int path_len, ent_len; + int entry, cur_state; +@@ -393,20 +393,6 @@ int lookup_read_master(struct master *master, time_t age, void *context) + return NSS_STATUS_UNAVAIL; + } + +- path = alloca(KEY_MAX_LEN + 1); +- if (!path) { +- error(logopt, +- MODPREFIX "could not malloc storage for path"); +- return NSS_STATUS_UNAVAIL; +- } +- +- ent = alloca(MAPENT_MAX_LEN + 1); +- if (!ent) { +- error(logopt, +- MODPREFIX "could not malloc storage for mapent"); +- return NSS_STATUS_UNAVAIL; +- } +- + f = open_fopen_r(ctxt->mapname); + if (!f) { + error(logopt, +@@ -618,8 +604,8 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + struct lookup_context *ctxt = (struct lookup_context *) context; + struct map_source *source; + struct mapent_cache *mc; +- char *key; +- char *mapent; ++ char key[KEY_MAX_LEN + 1]; ++ char mapent[MAPENT_MAX_LEN + 1]; + FILE *f; + unsigned int k_len, m_len; + int entry; +@@ -639,20 +625,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + return NSS_STATUS_UNAVAIL; + } + +- key = alloca(KEY_MAX_LEN + 1); +- if (!key) { +- error(ap->logopt, +- MODPREFIX "could not malloc storage for key"); +- return NSS_STATUS_UNAVAIL; +- } +- +- mapent = alloca(MAPENT_MAX_LEN + 1); +- if (!mapent) { +- error(ap->logopt, +- MODPREFIX "could not malloc storage for mapent"); +- return NSS_STATUS_UNAVAIL; +- } +- + f = open_fopen_r(ctxt->mapname); + if (!f) { + error(ap->logopt, +@@ -972,7 +944,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + char key[KEY_MAX_LEN + 1]; + int key_len; + char *mapent = NULL; +- int mapent_len; ++ char mapent_buf[MAPENT_MAX_LEN + 1]; + int status = 0; + int ret = 1; + +@@ -1076,38 +1048,36 @@ do_cache_lookup: + } + if (me && (me->source == source || *me->key == '/')) { + pthread_cleanup_push(cache_lock_cleanup, mc); +- mapent_len = strlen(me->mapent); +- mapent = alloca(mapent_len + 1); +- strcpy(mapent, me->mapent); ++ strcpy(mapent_buf, me->mapent); ++ mapent = mapent_buf; + pthread_cleanup_pop(0); + } + cache_unlock(mc); + +- if (mapent) { +- master_source_current_wait(ap->entry); +- ap->entry->current = source; ++ if (!mapent) ++ return NSS_STATUS_TRYAGAIN; + +- debug(ap->logopt, MODPREFIX "%s -> %s", key, mapent); +- ret = ctxt->parse->parse_mount(ap, key, key_len, +- mapent, ctxt->parse->context); +- if (ret) { +- time_t now = time(NULL); +- int rv = CHE_OK; ++ master_source_current_wait(ap->entry); ++ ap->entry->current = source; + +- cache_writelock(mc); ++ debug(ap->logopt, MODPREFIX "%s -> %s", key, mapent); ++ ret = ctxt->parse->parse_mount(ap, key, key_len, ++ mapent, ctxt->parse->context); ++ if (ret) { ++ time_t now = time(NULL); ++ int rv = CHE_OK; ++ ++ cache_writelock(mc); ++ me = cache_lookup_distinct(mc, key); ++ if (!me) ++ rv = cache_update(mc, source, key, NULL, now); ++ if (rv != CHE_FAIL) { + me = cache_lookup_distinct(mc, key); +- if (!me) +- rv = cache_update(mc, source, key, NULL, now); +- if (rv != CHE_FAIL) { +- me = cache_lookup_distinct(mc, key); +- me->status = now + ap->negative_timeout; +- } +- cache_unlock(mc); ++ me->status = now + ap->negative_timeout; + } +- } +- +- if (ret) ++ cache_unlock(mc); + return NSS_STATUS_TRYAGAIN; ++ } + + return NSS_STATUS_SUCCESS; + } +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index d8a60d3..094cbdc 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -294,10 +294,10 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt + if (ctxt->mapname) + l += strlen(key) + strlen(ctxt->mapname) + strlen("(&(=))"); + +- query = alloca(l); ++ query = malloc(l); + if (query == NULL) { + char *estr = strerror_r(errno, buf, sizeof(buf)); +- crit(logopt, MODPREFIX "alloca: %s", estr); ++ crit(logopt, MODPREFIX "malloc: %s", estr); + return NSS_STATUS_UNAVAIL; + } + +@@ -310,6 +310,7 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt + key, (int) strlen(ctxt->mapname), ctxt->mapname) >= l) { + debug(logopt, + MODPREFIX "error forming query string"); ++ free(query); + return 0; + } + scope = LDAP_SCOPE_SUBTREE; +@@ -317,6 +318,7 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt + if (sprintf(query, "(objectclass=%s)", class) >= l) { + debug(logopt, + MODPREFIX "error forming query string"); ++ free(query); + return 0; + } + scope = LDAP_SCOPE_SUBTREE; +@@ -340,6 +342,7 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt + error(logopt, + MODPREFIX "query failed for %s: %s", + query, ldap_err2string(rv)); ++ free(query); + return 0; + } + +@@ -353,6 +356,7 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt + MODPREFIX "query succeeded, no matches for %s", + query); + ldap_msgfree(result); ++ free(query); + return 0; + } + } else { +@@ -395,10 +399,12 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt + ldap_msgfree(result); + error(logopt, + MODPREFIX "failed to find query dn under search base dns"); ++ free(query); + return 0; + } + } + ++ free(query); + qdn = strdup(dn); + ldap_memfree(dn); + ldap_msgfree(result); +@@ -1181,7 +1187,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c + else { + char *estr; + estr = strerror_r(errno, buf, sizeof(buf)); +- logerr(MODPREFIX "malloc: %s", estr); ++ logerr(MODPREFIX "strdup: %s", estr); + if (ctxt->server) + free(ctxt->server); + return 0; +@@ -1441,23 +1447,26 @@ int lookup_read_master(struct master *master, time_t age, void *context) + + l = strlen("(objectclass=)") + strlen(class) + 1; + +- query = alloca(l); ++ query = malloc(l); + if (query == NULL) { + char *estr = strerror_r(errno, buf, sizeof(buf)); +- logerr(MODPREFIX "alloca: %s", estr); ++ logerr(MODPREFIX "malloc: %s", estr); + return NSS_STATUS_UNAVAIL; + } + + if (sprintf(query, "(objectclass=%s)", class) >= l) { + error(logopt, MODPREFIX "error forming query string"); ++ free(query); + return NSS_STATUS_UNAVAIL; + } + query[l] = '\0'; + + /* Initialize the LDAP context. */ + ldap = do_reconnect(logopt, ctxt); +- if (!ldap) ++ if (!ldap) { ++ free(query); + return NSS_STATUS_UNAVAIL; ++ } + + /* Look around. */ + debug(logopt, +@@ -1469,6 +1478,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + error(logopt, MODPREFIX "query failed for %s: %s", + query, ldap_err2string(rv)); + unbind_ldap_connection(logging, ldap, ctxt); ++ free(query); + return NSS_STATUS_NOTFOUND; + } + +@@ -1479,6 +1489,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + query); + ldap_msgfree(result); + unbind_ldap_connection(logging, ldap, ctxt); ++ free(query); + return NSS_STATUS_NOTFOUND; + } else + debug(logopt, MODPREFIX "examining entries"); +@@ -1548,6 +1559,7 @@ next: + /* Clean up. */ + ldap_msgfree(result); + unbind_ldap_connection(logopt, ldap, ctxt); ++ free(query); + + return NSS_STATUS_SUCCESS; + } +@@ -2174,7 +2186,7 @@ static int read_one_map(struct autofs_point *ap, + /* Build a query string. */ + l = strlen("(objectclass=)") + strlen(class) + 1; + +- sp.query = alloca(l); ++ sp.query = malloc(l); + if (sp.query == NULL) { + char *estr = strerror_r(errno, buf, sizeof(buf)); + logerr(MODPREFIX "malloc: %s", estr); +@@ -2183,14 +2195,17 @@ static int read_one_map(struct autofs_point *ap, + + if (sprintf(sp.query, "(objectclass=%s)", class) >= l) { + error(ap->logopt, MODPREFIX "error forming query string"); ++ free(sp.query); + return NSS_STATUS_UNAVAIL; + } + sp.query[l] = '\0'; + + /* Initialize the LDAP context. */ + sp.ldap = do_reconnect(ap->logopt, ctxt); +- if (!sp.ldap) ++ if (!sp.ldap) { ++ free(sp.query); + return NSS_STATUS_UNAVAIL; ++ } + + /* Look around. */ + debug(ap->logopt, +@@ -2215,6 +2230,7 @@ static int read_one_map(struct autofs_point *ap, + if (rv != LDAP_SUCCESS || !sp.result) { + unbind_ldap_connection(ap->logopt, sp.ldap, ctxt); + *result_ldap = rv; ++ free(sp.query); + return NSS_STATUS_UNAVAIL; + } + +@@ -2223,6 +2239,7 @@ static int read_one_map(struct autofs_point *ap, + ldap_msgfree(sp.result); + unbind_ldap_connection(ap->logopt, sp.ldap, ctxt); + *result_ldap = rv; ++ free(sp.query); + return NSS_STATUS_NOTFOUND; + } + ldap_msgfree(sp.result); +@@ -2233,6 +2250,7 @@ static int read_one_map(struct autofs_point *ap, + unbind_ldap_connection(ap->logopt, sp.ldap, ctxt); + + source->age = age; ++ free(sp.query); + + return NSS_STATUS_SUCCESS; + } +@@ -2328,7 +2346,7 @@ static int lookup_one(struct autofs_point *ap, + if (enc_len1) + l += 2*strlen(entry) + enc_len1 + enc_len2 + 6; + +- query = alloca(l); ++ query = malloc(l); + if (query == NULL) { + char *estr = strerror_r(errno, buf, sizeof(buf)); + crit(ap->logopt, MODPREFIX "malloc: %s", estr); +@@ -2336,6 +2354,7 @@ static int lookup_one(struct autofs_point *ap, + free(enc_key1); + free(enc_key2); + } ++ free(query); + return CHE_FAIL; + } + +@@ -2367,14 +2386,17 @@ static int lookup_one(struct autofs_point *ap, + if (ql >= l) { + error(ap->logopt, + MODPREFIX "error forming query string"); ++ free(query); + return CHE_FAIL; + } + query[ql] = '\0'; + + /* Initialize the LDAP context. */ + ldap = do_reconnect(ap->logopt, ctxt); +- if (!ldap) ++ if (!ldap) { ++ free(query); + return CHE_UNAVAIL; ++ } + + debug(ap->logopt, + MODPREFIX "searching for \"%s\" under \"%s\"", query, ctxt->qdn); +@@ -2384,6 +2406,7 @@ static int lookup_one(struct autofs_point *ap, + if ((rv != LDAP_SUCCESS) || !result) { + crit(ap->logopt, MODPREFIX "query failed for %s", query); + unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ free(query); + return CHE_FAIL; + } + +@@ -2396,6 +2419,7 @@ static int lookup_one(struct autofs_point *ap, + MODPREFIX "got answer, but no entry for %s", query); + ldap_msgfree(result); + unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ free(query); + return CHE_MISSING; + } + +@@ -2610,6 +2634,7 @@ next: + } + } + pthread_cleanup_pop(1); ++ free(query); + + return ret; + } +@@ -2696,7 +2721,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + char key[KEY_MAX_LEN + 1]; + int key_len; + char *mapent = NULL; +- int mapent_len; ++ char mapent_buf[MAPENT_MAX_LEN + 1]; + int status = 0; + int ret = 1; + +@@ -2766,38 +2791,36 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + me = cache_lookup_distinct(mc, "*"); + } + if (me && (me->source == source || *me->key == '/')) { +- mapent_len = strlen(me->mapent); +- mapent = alloca(mapent_len + 1); +- strcpy(mapent, me->mapent); ++ strcpy(mapent_buf, me->mapent); ++ mapent = mapent_buf; + } + cache_unlock(mc); + +- if (mapent) { +- master_source_current_wait(ap->entry); +- ap->entry->current = source; ++ if (!mapent) ++ return NSS_STATUS_TRYAGAIN; + +- debug(ap->logopt, MODPREFIX "%s -> %s", key, mapent); +- ret = ctxt->parse->parse_mount(ap, key, key_len, +- mapent, ctxt->parse->context); +- if (ret) { +- time_t now = time(NULL); +- int rv = CHE_OK; ++ master_source_current_wait(ap->entry); ++ ap->entry->current = source; + +- /* Record the the mount fail in the cache */ +- cache_writelock(mc); ++ debug(ap->logopt, MODPREFIX "%s -> %s", key, mapent); ++ ret = ctxt->parse->parse_mount(ap, key, key_len, ++ mapent, ctxt->parse->context); ++ if (ret) { ++ time_t now = time(NULL); ++ int rv = CHE_OK; ++ ++ /* Record the the mount fail in the cache */ ++ cache_writelock(mc); ++ me = cache_lookup_distinct(mc, key); ++ if (!me) ++ rv = cache_update(mc, source, key, NULL, now); ++ if (rv != CHE_FAIL) { + me = cache_lookup_distinct(mc, key); +- if (!me) +- rv = cache_update(mc, source, key, NULL, now); +- if (rv != CHE_FAIL) { +- me = cache_lookup_distinct(mc, key); +- me->status = now + ap->negative_timeout; +- } +- cache_unlock(mc); ++ me->status = now + ap->negative_timeout; + } +- } +- +- if (ret) ++ cache_unlock(mc); + return NSS_STATUS_TRYAGAIN; ++ } + + return NSS_STATUS_SUCCESS; + } +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index 4c3ce60..0c75905 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -92,10 +92,10 @@ int lookup_read_master(struct master *master, time_t age, void *context) + int cur_state, len; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- tablename = alloca(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20); ++ tablename = malloc(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20); + if (!tablename) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "alloca: %s", estr); ++ logerr(MODPREFIX "malloc: %s", estr); + pthread_setcancelstate(cur_state, NULL); + return NSS_STATUS_UNAVAIL; + } +@@ -107,6 +107,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + nis_freeresult(result); + crit(logopt, + MODPREFIX "couldn't locate nis+ table %s", ctxt->mapname); ++ free(tablename); + pthread_setcancelstate(cur_state, NULL); + return NSS_STATUS_NOTFOUND; + } +@@ -118,6 +119,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + nis_freeresult(result); + crit(logopt, + MODPREFIX "couldn't enumrate nis+ map %s", ctxt->mapname); ++ free(tablename); + pthread_setcancelstate(cur_state, NULL); + return NSS_STATUS_UNAVAIL; + } +@@ -155,6 +157,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + } + + nis_freeresult(result); ++ free(tablename); + pthread_setcancelstate(cur_state, NULL); + + return NSS_STATUS_SUCCESS; +@@ -180,10 +183,10 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + mc = source->mc; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- tablename = alloca(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20); ++ tablename = malloc(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20); + if (!tablename) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "alloca: %s", estr); ++ logerr(MODPREFIX "malloc: %s", estr); + pthread_setcancelstate(cur_state, NULL); + return NSS_STATUS_UNAVAIL; + } +@@ -195,6 +198,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + nis_freeresult(result); + crit(ap->logopt, + MODPREFIX "couldn't locate nis+ table %s", ctxt->mapname); ++ free(tablename); + pthread_setcancelstate(cur_state, NULL); + return NSS_STATUS_NOTFOUND; + } +@@ -206,6 +210,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + nis_freeresult(result); + crit(ap->logopt, + MODPREFIX "couldn't enumrate nis+ map %s", ctxt->mapname); ++ free(tablename); + pthread_setcancelstate(cur_state, NULL); + return NSS_STATUS_UNAVAIL; + } +@@ -245,6 +250,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + + source->age = age; + ++ free(tablename); + pthread_setcancelstate(cur_state, NULL); + + return NSS_STATUS_SUCCESS; +@@ -271,11 +277,11 @@ static int lookup_one(struct autofs_point *ap, + mc = source->mc; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- tablename = alloca(strlen(key) + +- strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20); ++ tablename = malloc(strlen(key) + strlen(ctxt->mapname) + ++ strlen(ctxt->domainname) + 20); + if (!tablename) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "alloca: %s", estr); ++ logerr(MODPREFIX "malloc: %s", estr); + pthread_setcancelstate(cur_state, NULL); + return -1; + } +@@ -286,6 +292,7 @@ static int lookup_one(struct autofs_point *ap, + if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) { + nis_error rs = result->status; + nis_freeresult(result); ++ free(tablename); + pthread_setcancelstate(cur_state, NULL); + if (rs == NIS_NOTFOUND || + rs == NIS_S_NOTFOUND || +@@ -303,6 +310,7 @@ static int lookup_one(struct autofs_point *ap, + cache_unlock(mc); + + nis_freeresult(result); ++ free(tablename); + pthread_setcancelstate(cur_state, NULL); + + return ret; +@@ -327,10 +335,10 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt) + mc = source->mc; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- tablename = alloca(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20); ++ tablename = malloc(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20); + if (!tablename) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "alloca: %s", estr); ++ logerr(MODPREFIX "malloc: %s", estr); + pthread_setcancelstate(cur_state, NULL); + return -1; + } +@@ -341,6 +349,7 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt) + if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) { + nis_error rs = result->status; + nis_freeresult(result); ++ free(tablename); + pthread_setcancelstate(cur_state, NULL); + if (rs == NIS_NOTFOUND || + rs == NIS_S_NOTFOUND || +@@ -357,6 +366,7 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt) + cache_unlock(mc); + + nis_freeresult(result); ++ free(tablename); + pthread_setcancelstate(cur_state, NULL); + + return ret; +@@ -546,36 +556,37 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + } + if (me && (me->source == source || *me->key == '/')) { + mapent_len = strlen(me->mapent); +- mapent = alloca(mapent_len + 1); ++ mapent = malloc(mapent_len + 1); + strcpy(mapent, me->mapent); + } + cache_unlock(mc); + +- if (mapent) { +- master_source_current_wait(ap->entry); +- ap->entry->current = source; ++ if (!mapent) ++ return NSS_STATUS_TRYAGAIN; + +- debug(ap->logopt, MODPREFIX "%s -> %s", key, mapent); +- ret = ctxt->parse->parse_mount(ap, key, key_len, +- mapent, ctxt->parse->context); +- if (ret) { +- time_t now = time(NULL); +- int rv = CHE_OK; ++ master_source_current_wait(ap->entry); ++ ap->entry->current = source; ++ ++ debug(ap->logopt, MODPREFIX "%s -> %s", key, mapent); ++ ret = ctxt->parse->parse_mount(ap, key, key_len, ++ mapent, ctxt->parse->context); ++ if (ret) { ++ time_t now = time(NULL); ++ int rv = CHE_OK; + +- cache_writelock(mc); ++ cache_writelock(mc); ++ me = cache_lookup_distinct(mc, key); ++ if (!me) ++ rv = cache_update(mc, source, key, NULL, now); ++ if (rv != CHE_FAIL) { + me = cache_lookup_distinct(mc, key); +- if (!me) +- rv = cache_update(mc, source, key, NULL, now); +- if (rv != CHE_FAIL) { +- me = cache_lookup_distinct(mc, key); +- me->status = time(NULL) + ap->negative_timeout; +- } +- cache_unlock(mc); ++ me->status = time(NULL) + ap->negative_timeout; + } +- } +- +- if (ret) ++ cache_unlock(mc); ++ free(mapent); + return NSS_STATUS_TRYAGAIN; ++ } ++ free(mapent); + + return NSS_STATUS_SUCCESS; + } +diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c +index 44fc043..fab2906 100644 +--- a/modules/mount_autofs.c ++++ b/modules/mount_autofs.c +@@ -18,7 +18,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/modules/mount_bind.c b/modules/mount_bind.c +index 361f0c2..b8ef581 100644 +--- a/modules/mount_bind.c ++++ b/modules/mount_bind.c +@@ -69,7 +69,7 @@ out: + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, void *context) + { +- char *fullpath; ++ char fullpath[PATH_MAX]; + char buf[MAX_ERR_BUF]; + int err; + int i, len; +@@ -80,14 +80,11 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + /* Root offset of multi-mount */ + len = strlen(root); + if (root[len - 1] == '/') { +- fullpath = alloca(len); + len = snprintf(fullpath, len, "%s", root); + /* Direct mount name is absolute path so don't use root */ + } else if (*name == '/') { +- fullpath = alloca(len + 1); + len = sprintf(fullpath, "%s", root); + } else { +- fullpath = alloca(len + name_len + 2); + len = sprintf(fullpath, "%s/%s", root, name); + } + fullpath[len] = '\0'; +@@ -141,7 +138,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + } + } else { + char *cp; +- char *basepath = alloca(strlen(fullpath) + 1); ++ char basepath[PATH_MAX]; + int status; + struct stat st; + +diff --git a/modules/mount_changer.c b/modules/mount_changer.c +index c30190d..856cf6a 100644 +--- a/modules/mount_changer.c ++++ b/modules/mount_changer.c +@@ -44,7 +44,7 @@ int mount_init(void **context) + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, void *context) + { +- char *fullpath; ++ char fullpath[PATH_MAX]; + char buf[MAX_ERR_BUF]; + int err; + int len, status, existed = 1; +@@ -57,14 +57,11 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + /* Root offset of multi-mount */ + len = strlen(root); + if (root[len - 1] == '/') { +- fullpath = alloca(len); + len = snprintf(fullpath, len, "%s", root); + /* Direct mount name is absolute path so don't use root */ + } else if (*name == '/') { +- fullpath = alloca(len + 1); + len = sprintf(fullpath, "%s", root); + } else { +- fullpath = alloca(len + name_len + 2); + len = sprintf(fullpath, "%s/%s", root, name); + } + fullpath[len] = '\0'; +diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c +index 192ec04..85329ab 100644 +--- a/modules/mount_ext2.c ++++ b/modules/mount_ext2.c +@@ -36,7 +36,7 @@ int mount_init(void **context) + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, void *context) + { +- char *fullpath; ++ char fullpath[PATH_MAX]; + char buf[MAX_ERR_BUF]; + const char *p, *p1; + int err, ro = 0; +@@ -49,14 +49,11 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + /* Root offset of multi-mount */ + len = strlen(root); + if (root[len - 1] == '/') { +- fullpath = alloca(len); + len = snprintf(fullpath, len, "%s", root); + /* Direct mount name is absolute path so don't use root */ + } else if (*name == '/') { +- fullpath = alloca(len + 1); + len = sprintf(fullpath, "%s", root); + } else { +- fullpath = alloca(len + name_len + 2); + len = sprintf(fullpath, "%s/%s", root, name); + } + fullpath[len] = '\0'; +diff --git a/modules/mount_generic.c b/modules/mount_generic.c +index 6d7b4b3..1dc1bfd 100644 +--- a/modules/mount_generic.c ++++ b/modules/mount_generic.c +@@ -37,7 +37,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + const char *what, const char *fstype, const char *options, + void *context) + { +- char *fullpath; ++ char fullpath[PATH_MAX]; + char buf[MAX_ERR_BUF]; + int err; + int len, status, existed = 1; +@@ -48,14 +48,11 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + /* Root offset of multi-mount */ + len = strlen(root); + if (root[len - 1] == '/') { +- fullpath = alloca(len); + len = snprintf(fullpath, len, "%s", root); + /* Direct mount name is absolute path so don't use root */ + } else if (*name == '/') { +- fullpath = alloca(len + 1); + len = sprintf(fullpath, "%s", root); + } else { +- fullpath = alloca(len + name_len + 2); + len = sprintf(fullpath, "%s/%s", root, name); + } + fullpath[len] = '\0'; diff --git a/autofs-5.0.4-expire-specific-submount-only.patch b/autofs-5.0.4-expire-specific-submount-only.patch new file mode 100644 index 0000000..0a6a804 --- /dev/null +++ b/autofs-5.0.4-expire-specific-submount-only.patch @@ -0,0 +1,94 @@ +autofs-5.0.4 - expire specific submount only + +From: Ian Kent + +The submount shutdown at expire assumes that certain locks are not +held but when notifying submounts containing nested submounts not +all locks were being released. This leads to occassional deadlock +when child submounts attempt to shutdown. +--- + + CHANGELOG | 1 + + lib/master.c | 33 ++++++++------------------------- + 2 files changed, 9 insertions(+), 25 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 4e8209e..88ca579 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,6 +1,7 @@ + ??/??/2009 autofs-5.0.5 + ----------------------- + - fix dumb libxml2 check ++- fix nested submount expire deadlock. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/lib/master.c b/lib/master.c +index a243e6a..e1cc062 100644 +--- a/lib/master.c ++++ b/lib/master.c +@@ -834,7 +834,6 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state + { + struct list_head *head, *p; + struct autofs_point *this = NULL; +- size_t plen = strlen(path); + int ret = 1; + + mounts_mutex_lock(ap); +@@ -842,37 +841,19 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state + head = &ap->submounts; + p = head->prev; + while (p != head) { +- size_t len; +- + this = list_entry(p, struct autofs_point, mounts); + p = p->prev; + + if (!master_submount_list_empty(this)) { +- if (!master_notify_submount(this, path, state)) { +- ret = 0; +- break; +- } ++ mounts_mutex_unlock(ap); ++ return master_notify_submount(this, path, state); + } + +- len = strlen(this->path); +- +- /* Initial path not the same */ +- if (strncmp(this->path, path, len)) ++ /* path not the same */ ++ if (strcmp(this->path, path)) + continue; + +- /* +- * Part of submount tree? +- * We must wait till we get to submount itself. +- * If it is tell caller by returning true. +- */ +- if (plen > len) { +- /* Not part of this directory tree */ +- if (path[len] != '/') +- continue; +- break; +- } +- +- /* Now we have a submount to expire */ ++ /* Now we have found the submount we want to expire */ + + st_mutex_lock(); + +@@ -901,8 +882,10 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state + struct timespec t = { 0, 300000000 }; + struct timespec r; + +- if (this->state != ST_SHUTDOWN) ++ if (this->state != ST_SHUTDOWN) { ++ ret = 0; + break; ++ } + + st_mutex_unlock(); + mounts_mutex_unlock(ap); diff --git a/autofs-5.0.4-fix-bad-token-declare.patch b/autofs-5.0.4-fix-bad-token-declare.patch new file mode 100644 index 0000000..3787ddc --- /dev/null +++ b/autofs-5.0.4-fix-bad-token-declare.patch @@ -0,0 +1,39 @@ +autofs-5.0.4 - fix bad token declaration + +From: Ian Kent + +Fix an incorrect %token declaration in the master map parser. +In some rare cases this can cause the timeout sent from the tokenizer +to the parser to always be zero. +--- + + CHANGELOG | 1 + + lib/master_parse.y | 2 +- + 2 files changed, 2 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 0ce2a56..fdde400 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -26,6 +26,7 @@ + - cleanup configure defines for libtirpc. + - add WITH_LIBTIRPC to -V status report. + - add nfs mount protocol default configuration option. ++- fix bad token declaration in master map parser. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/lib/master_parse.y b/lib/master_parse.y +index 3e598d9..454a2ed 100644 +--- a/lib/master_parse.y ++++ b/lib/master_parse.y +@@ -122,7 +122,7 @@ static int master_fprintf(FILE *, char *, ...); + %token MAPNULL + %token MAPXFN + %token MAPNAME +-%token NUMBER ++%token NUMBER + %token OPTION + + %start file diff --git a/autofs-5.0.4-fix-double-free-in-do_sasl_bind.patch b/autofs-5.0.4-fix-double-free-in-do_sasl_bind.patch new file mode 100644 index 0000000..a9e28a6 --- /dev/null +++ b/autofs-5.0.4-fix-double-free-in-do_sasl_bind.patch @@ -0,0 +1,42 @@ +autofs-5.0.4 - fix double free in do_sasl_bind() + +From: Ian Kent + +In do_sasl_bind() the connection negotiation loop can exit with the +local variable server_cred non-null after it has been freed, leading +to a double free. +--- + + CHANGELOG | 1 + + modules/cyrus-sasl.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index e138ca3..f0d0e58 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -53,6 +53,7 @@ + - fix not releasing resources when using submounts. + - fix notify mount message path. + - remount we created mount point fix. ++- fix double free in sasl_bind(). + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c +index ec2ab0c..04001d0 100644 +--- a/modules/cyrus-sasl.c ++++ b/modules/cyrus-sasl.c +@@ -348,8 +348,10 @@ do_sasl_bind(unsigned logopt, LDAP *ld, sasl_conn_t *conn, const char **clientou + } + } + +- if (server_cred && server_cred->bv_len > 0) ++ if (server_cred && server_cred->bv_len > 0) { + ber_bvfree(server_cred); ++ server_cred = NULL; ++ } + + } while ((bind_result == LDAP_SASL_BIND_IN_PROGRESS) || + (sasl_result == SASL_CONTINUE)); diff --git a/autofs-5.0.4-fix-double-free-in-expire_proc.patch b/autofs-5.0.4-fix-double-free-in-expire_proc.patch new file mode 100644 index 0000000..d307330 --- /dev/null +++ b/autofs-5.0.4-fix-double-free-in-expire_proc.patch @@ -0,0 +1,38 @@ +autofs-5.0.4 - fix double free in expire_proc() + +From: Ian Kent + +In state.c:expire_proc() the function expire_proc_cleanup() is called +which frees the parameter structure but automount frees this again in +the following line. +--- + + CHANGELOG | 1 + + daemon/state.c | 1 - + 2 files changed, 1 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 2cb35dc..8860b2c 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -28,6 +28,7 @@ + - add nfs mount protocol default configuration option. + - fix bad token declaration in master map parser. + - fix return start status on fail. ++- fix double free in expire_proc(). + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/state.c b/daemon/state.c +index 606743b..417fde1 100644 +--- a/daemon/state.c ++++ b/daemon/state.c +@@ -298,7 +298,6 @@ static enum expire expire_proc(struct autofs_point *ap, int now) + error(ap->logopt, + "expire thread create for %s failed", ap->path); + expire_proc_cleanup((void *) ea); +- free(ea); + return EXP_ERROR; + } + ap->exp_thread = thid; diff --git a/autofs-5.0.4-fix-dumb-libxml2-check.patch b/autofs-5.0.4-fix-dumb-libxml2-check.patch new file mode 100644 index 0000000..acff7b3 --- /dev/null +++ b/autofs-5.0.4-fix-dumb-libxml2-check.patch @@ -0,0 +1,87 @@ +autofs-5.0.4 - fix dumb libxml2 check + +From: Ian Kent + +The workaround for libxml2 not deleting its thread specific data +key at library unload has become broken. It was foolish of me to +think that the libxml2 folks would fix this in any reasonable time. +This patch changes the version check to 99 for the major and minor +revisions, the same as the check for the revision to ensure that +the workaround is always used and adds the setting to the build +information produced by the -V option. +--- + + CHANGELOG | 4 ++++ + aclocal.m4 | 4 ++-- + configure | 4 ++-- + daemon/automount.c | 10 ++++++++++ + 4 files changed, 18 insertions(+), 4 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index a618d7e..4e8209e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,3 +1,7 @@ ++??/??/2009 autofs-5.0.5 ++----------------------- ++- fix dumb libxml2 check ++ + 4/11/2008 autofs-5.0.4 + ----------------------- + - correct configure test for ldapr page control functions. +diff --git a/aclocal.m4 b/aclocal.m4 +index 52a1e47..bb0ab21 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -201,10 +201,10 @@ else + XML_FLAGS=`$XML_CONFIG --cflags` + XML_VER=`$XML_CONFIG --version` + XML_MAJOR=`echo $XML_VER|cut -d\. -f1` +- if test $XML_MAJOR -le 2 ++ if test $XML_MAJOR -le 99 + then + XML_MINOR=`echo $XML_VER|cut -d\. -f2` +- if test $XML_MINOR -le 6 ++ if test $XML_MINOR -le 99 + then + XML_REV=`echo $XML_VER|cut -d\. -f3` + if test $XML_REV -le 99; then +diff --git a/configure b/configure +index b8cc62f..ed17660 100755 +--- a/configure ++++ b/configure +@@ -2564,10 +2564,10 @@ echo "${ECHO_T}yes" >&6; } + XML_FLAGS=`$XML_CONFIG --cflags` + XML_VER=`$XML_CONFIG --version` + XML_MAJOR=`echo $XML_VER|cut -d\. -f1` +- if test $XML_MAJOR -le 2 ++ if test $XML_MAJOR -le 99 + then + XML_MINOR=`echo $XML_VER|cut -d\. -f2` +- if test $XML_MINOR -le 6 ++ if test $XML_MINOR -le 99 + then + XML_REV=`echo $XML_VER|cut -d\. -f3` + if test $XML_REV -le 99; then +diff --git a/daemon/automount.c b/daemon/automount.c +index 863aac5..6f078c1 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -1743,6 +1743,16 @@ static void show_build_info(void) + #ifdef WITH_DMALLOC + printf("WITH_DMALLOC "); + count = count + 13; ++ ++ if (count > 60) { ++ printf("\n "); ++ count = 0; ++ } ++#endif ++ ++#ifdef LIBXML2_WORKAROUND ++ printf("LIBXML2_WORKAROUND "); ++ count = count + 19; + #endif + + printf("\n\n"); diff --git a/autofs-5.0.4-fix-hosts-map-use-after-free.patch b/autofs-5.0.4-fix-hosts-map-use-after-free.patch new file mode 100644 index 0000000..82ff524 --- /dev/null +++ b/autofs-5.0.4-fix-hosts-map-use-after-free.patch @@ -0,0 +1,52 @@ +autofs-5.0.4 - fix hosts map use after free + +From: Ian Kent + +This patch fixed use a map entry after it has been freed in the +hosts map lookup module. +--- + + CHANGELOG | 1 + + modules/lookup_hosts.c | 8 +++++--- + 2 files changed, 6 insertions(+), 3 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index eb4a189..3199e4d 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -9,6 +9,7 @@ + Valerie Aurora Henson). + - clear the quoted flag after each character from program map input. + - use CLOEXEC flag for setmntent also. ++- fix hosts map use after free. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index 93b975a..d3ae0e2 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -138,17 +138,19 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, name, LKP_DISTINCT); + if (me) { ++ struct mapent_cache *fmc = me->mc; ++ + if (me->status >= time(NULL)) { +- cache_unlock(me->mc); ++ cache_unlock(fmc); + return NSS_STATUS_NOTFOUND; + } + + if (!me->mapent) { +- cache_delete(me->mc, name); ++ cache_delete(fmc, name); + me = NULL; + } + +- cache_unlock(me->mc); ++ cache_unlock(fmc); + } + + cache_readlock(mc); diff --git a/autofs-5.0.4-fix-incorrect-dclist-free.patch b/autofs-5.0.4-fix-incorrect-dclist-free.patch new file mode 100644 index 0000000..0a0ee68 --- /dev/null +++ b/autofs-5.0.4-fix-incorrect-dclist-free.patch @@ -0,0 +1,39 @@ +autofs-5.0.4 - fix incorrect dclist free + +From: Ian Kent + +We incorrectly try to free dclist in modules/lookup_ldap.c:find_server(). +--- + + modules/lookup_ldap.c | 10 ++++++++-- + 1 files changed, 8 insertions(+), 2 deletions(-) + + +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index f6b3f42..8f352d6 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -688,6 +688,10 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) + } + } + if (!uri) { ++ if (dclist) { ++ free_dclist(dclist); ++ dclist = NULL; ++ } + p = p->next; + continue; + } +@@ -700,8 +704,10 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) + } + free(uri); + uri = NULL; +- free_dclist(dclist); +- dclist = NULL; ++ if (dclist) { ++ free_dclist(dclist); ++ dclist = NULL; ++ } + p = p->next; + } + diff --git a/autofs-5.0.4-fix-kernel-includes.patch b/autofs-5.0.4-fix-kernel-includes.patch new file mode 100644 index 0000000..5df38a8 --- /dev/null +++ b/autofs-5.0.4-fix-kernel-includes.patch @@ -0,0 +1,103 @@ +autofs-5.0.4 - fix kernel includes + +From: Valerie Aurora Henson + +autofs_dev-ioctl.h is included by both the kernel module and autofs, +and it includes two kernel header files. The compile worked if the +kernel headers were installed but failed otherwise. + +imk: there are a couple of other instances were we include kernel +headers. I've tried to fix that up too. +--- + + CHANGELOG | 1 + + include/automount.h | 3 +-- + include/dev-ioctl-lib.h | 3 +-- + include/linux/auto_dev-ioctl.h | 7 ++++++- + include/linux/auto_fs.h | 6 ++++-- + 5 files changed, 13 insertions(+), 7 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index a42dd14..387af5e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -42,6 +42,7 @@ + - zero s_magic is valid. + - use percent hack for master map keys. + - use intr option as hosts mount default. ++- fix kernel includes. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/include/automount.h b/include/automount.h +index 615e07d..d4675bd 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -8,12 +8,11 @@ + #ifndef AUTOMOUNT_H + #define AUTOMOUNT_H + +-#include + #include + #include + #include + #include +-#include ++#include + #include + #include + #include +diff --git a/include/dev-ioctl-lib.h b/include/dev-ioctl-lib.h +index b7b8211..6d35da2 100644 +--- a/include/dev-ioctl-lib.h ++++ b/include/dev-ioctl-lib.h +@@ -21,8 +21,7 @@ + #ifndef AUTOFS_DEV_IOCTL_LIB_H + #define AUTOFS_DEV_IOCTL_LIB_H + +-#include +-#include "linux/auto_dev-ioctl.h" ++#include + + #define CONTROL_DEVICE "/dev/autofs" + +diff --git a/include/linux/auto_dev-ioctl.h b/include/linux/auto_dev-ioctl.h +index 91a7739..850f39b 100644 +--- a/include/linux/auto_dev-ioctl.h ++++ b/include/linux/auto_dev-ioctl.h +@@ -10,8 +10,13 @@ + #ifndef _LINUX_AUTO_DEV_IOCTL_H + #define _LINUX_AUTO_DEV_IOCTL_H + ++#include ++ ++#ifdef __KERNEL__ + #include +-#include ++#else ++#include ++#endif /* __KERNEL__ */ + + #define AUTOFS_DEVICE_NAME "autofs" + +diff --git a/include/linux/auto_fs.h b/include/linux/auto_fs.h +index bd39f09..91d414f 100644 +--- a/include/linux/auto_fs.h ++++ b/include/linux/auto_fs.h +@@ -17,11 +17,13 @@ + #ifdef __KERNEL__ + #include + #include ++#include ++#include ++#else + #include ++#include + #endif /* __KERNEL__ */ + +-#include +- + /* This file describes autofs v3 */ + #define AUTOFS_PROTO_VERSION 3 + diff --git a/autofs-5.0.4-fix-ldap-detection.patch b/autofs-5.0.4-fix-ldap-detection.patch new file mode 100644 index 0000000..b5b97ac --- /dev/null +++ b/autofs-5.0.4-fix-ldap-detection.patch @@ -0,0 +1,115 @@ +autofs-5.0.4 - fix ldap detection + +From: Guillaume Rousse + +The test for LDAP library wrongly use LDFLAGS to add -lldap to the gcc +call. However, when strict linker ordering is in effect, it doesn't work +correctly. As described in autoconf documentation, additional libs +should be added through LIBS variable instead. +--- + + aclocal.m4 | 20 ++++++++++---------- + configure | 20 ++++++++++---------- + 2 files changed, 20 insertions(+), 20 deletions(-) + + +diff --git a/aclocal.m4 b/aclocal.m4 +index bb0ab21..ab11112 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -246,9 +246,9 @@ dnl -------------------------------------------------------------------------- + AC_DEFUN([AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL], + [AC_MSG_CHECKING(for ldap_create_page_control in -lldap) + +-# save current ldflags +-af_check_ldap_create_page_control_save_ldflags="$LDFLAGS" +-LDFLAGS="$LDFLAGS -lldap" ++# save current libs ++af_check_ldap_create_page_control_save_libs="$LIBS" ++LIBS="$LIBS -lldap" + + AC_TRY_LINK( + [ #include ], +@@ -267,8 +267,8 @@ if test "$af_have_ldap_create_page_control" = "yes"; then + [Define to 1 if you have the `ldap_create_page_control' function.]) + fi + +-# restore ldflags +-LDFLAGS="$af_check_ldap_create_page_control_save_ldflags" ++# restore libs ++LIBS="$af_check_ldap_create_page_control_save_libs" + ]) + + dnl -------------------------------------------------------------------------- +@@ -279,9 +279,9 @@ dnl -------------------------------------------------------------------------- + AC_DEFUN([AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL], + [AC_MSG_CHECKING(for ldap_parse_page_control in -lldap) + +-# save current ldflags +-af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS" +-LDFLAGS="$LDFLAGS -lldap" ++# save current libs ++af_check_ldap_parse_page_control_save_libs="$LIBS" ++LIBS="$LIBS -lldap" + + AC_TRY_LINK( + [ #include ], +@@ -300,7 +300,7 @@ if test "$af_have_ldap_create_page_control" = "yes"; then + [Define to 1 if you have the `ldap_parse_page_control' function.]) + fi + +-# restore ldflags +-LDFLAGS="$af_check_ldap_parse_page_control_save_ldflags" ++# restore libs ++LIBS="$af_check_ldap_parse_page_control_save_libs" + ]) + +diff --git a/configure b/configure +index ed17660..afa692c 100755 +--- a/configure ++++ b/configure +@@ -4608,9 +4608,9 @@ _ACEOF + { echo "$as_me:$LINENO: checking for ldap_create_page_control in -lldap" >&5 + echo $ECHO_N "checking for ldap_create_page_control in -lldap... $ECHO_C" >&6; } + +-# save current ldflags +-af_check_ldap_create_page_control_save_ldflags="$LDFLAGS" +-LDFLAGS="$LDFLAGS -lldap" ++# save current libs ++af_check_ldap_create_page_control_save_libs="$LIBS" ++LIBS="$LIBS -lldap" + + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ +@@ -4672,15 +4672,15 @@ _ACEOF + + fi + +-# restore ldflags +-LDFLAGS="$af_check_ldap_create_page_control_save_ldflags" ++# restore libs ++LIBS="$af_check_ldap_create_page_control_save_libs" + + { echo "$as_me:$LINENO: checking for ldap_parse_page_control in -lldap" >&5 + echo $ECHO_N "checking for ldap_parse_page_control in -lldap... $ECHO_C" >&6; } + +-# save current ldflags +-af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS" +-LDFLAGS="$LDFLAGS -lldap" ++# save current libs ++af_check_ldap_parse_page_control_save_libs="$LIBS" ++LIBS="$LIBS -lldap" + + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ +@@ -4742,8 +4742,8 @@ _ACEOF + + fi + +-# restore ldflags +-LDFLAGS="$af_check_ldap_parse_page_control_save_ldflags" ++# restore libs ++LIBS="$af_check_ldap_parse_page_control_save_libs" + + fi + diff --git a/autofs-5.0.4-fix-lsb-init-script-header.patch b/autofs-5.0.4-fix-lsb-init-script-header.patch new file mode 100644 index 0000000..82b9018 --- /dev/null +++ b/autofs-5.0.4-fix-lsb-init-script-header.patch @@ -0,0 +1,57 @@ +autofs-5.0.4 - fix lsb init script header + +From: Ian Kent + +It truns out that "Should-Start:" is not sufficient to enforce +the required ordering of services and a "Required-Start:" is +needed instead. +--- + + CHANGELOG | 1 + + redhat/autofs.init.in | 4 ++-- + samples/rc.autofs.in | 4 ++-- + 3 files changed, 5 insertions(+), 4 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 91edd14..2be7683 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -35,6 +35,7 @@ + - use misc device ioctl interface by default, if available. + - fix call restorecon when misc device file doesn't exist. + - clear rpc client on lookup fail. ++- fix lsb init script header. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in +index a9a33c8..fded1d8 100644 +--- a/redhat/autofs.init.in ++++ b/redhat/autofs.init.in +@@ -9,8 +9,8 @@ + # + ### BEGIN INIT INFO + # Provides: $autofs +-# Should-Start: $network $ypbind +-# Should-Stop: $network $ypbind ++# Required-Start: $network $ypbind ++# Required-Stop: $network $ypbind + # Default-Start: 3 4 5 + # Default-Stop: 0 1 2 6 + # Short-Description: Automounts filesystems on demand +diff --git a/samples/rc.autofs.in b/samples/rc.autofs.in +index 78cbec2..b193a4e 100644 +--- a/samples/rc.autofs.in ++++ b/samples/rc.autofs.in +@@ -8,8 +8,8 @@ + # + ### BEGIN INIT INFO + # Provides: $autofs +-# Should-Start: $network $ypbind +-# Should-Stop: $network $ypbind ++# Required-Start: $network $ypbind ++# Required-Stop: $network $ypbind + # Default-Start: 3 4 5 + # Default-Stop: 0 1 2 6 + # Short-Description: Automounts filesystems on demand diff --git a/autofs-5.0.4-fix-map-type-info-parse-error-update.patch b/autofs-5.0.4-fix-map-type-info-parse-error-update.patch new file mode 100644 index 0000000..bbb1531 --- /dev/null +++ b/autofs-5.0.4-fix-map-type-info-parse-error-update.patch @@ -0,0 +1,165 @@ +autofs-5.0.4 - fix map type info parse error update + +From: Ian Kent + +Make parsing map type info more robust. +--- + + lib/parse_subs.c | 123 +++++++++++++++++++++++++++++++++++++++++++++--------- + 1 files changed, 102 insertions(+), 21 deletions(-) + + +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index 0608cb7..2326838 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -20,6 +20,30 @@ + #include + #include "automount.h" + ++struct types { ++ char *type; ++ unsigned int len; ++}; ++ ++static struct types map_type[] = { ++ { "file", 4 }, ++ { "program", 7 }, ++ { "yp", 2 }, ++ { "nis", 3 }, ++ { "nisplus", 7 }, ++ { "ldap", 4 }, ++ { "ldaps", 5 }, ++ { "hesiod", 6 }, ++ { "userdir", 7 }, ++}; ++static unsigned int map_type_count = sizeof(map_type)/sizeof(struct types); ++ ++static struct types format_type[] = { ++ { "sun", 3 }, ++ { "hesiod", 6 }, ++}; ++static unsigned int format_type_count = sizeof(format_type)/sizeof(struct types); ++ + /* + * Skip whitespace in a string; if we hit a #, consider the rest of the + * entry a comment. +@@ -315,7 +339,7 @@ struct map_type_info *parse_map_type_info(const char *str) + { + struct map_type_info *info; + char *buf, *type, *fmt, *map, *tmp; +- int seen_colon = 0; ++ char *pos; + + buf = strdup(str); + if (!buf) +@@ -328,32 +352,89 @@ struct map_type_info *parse_map_type_info(const char *str) + } + memset(info, 0, sizeof(struct map_type_info)); + +- type = fmt = NULL; ++ type = fmt = map = NULL; ++ ++ tmp = strchr(buf, ':'); ++ if (!tmp) { ++ pos = buf; ++ while (*pos == ' ') ++ *pos++ = '\0'; ++ map = pos; ++ } else { ++ int i, j; ++ ++ for (i = 0; i < map_type_count; i++) { ++ char *m_type = map_type[i].type; ++ unsigned int m_len = map_type[i].len; ++ ++ pos = buf; ++ ++ if (strncmp(m_type, pos, m_len)) ++ continue; ++ ++ type = pos; ++ pos += m_len; ++ ++ if (*pos == ' ' || *pos == ':') { ++ while (*pos == ' ') ++ *pos++ = '\0'; ++ if (*pos != ':') { ++ free(buf); ++ free(info); ++ return NULL; ++ } else { ++ *pos++ = '\0'; ++ while (*pos == ' ') ++ *pos++ = '\0'; ++ map = pos; ++ break; ++ } ++ } ++ ++ if (*pos == ',') { ++ *pos++ = '\0'; ++ for (j = 0; j < format_type_count; j++) { ++ char *f_type = format_type[j].type; ++ unsigned int f_len = format_type[j].len; ++ ++ if (strncmp(f_type, pos, f_len)) ++ continue; ++ ++ fmt = pos; ++ pos += f_len; ++ ++ if (*pos == ' ' || *pos == ':') { ++ while (*pos == ' ') ++ *pos++ = '\0'; ++ if (*pos != ':') { ++ free(buf); ++ free(info); ++ return NULL; ++ } else { ++ *pos++ = '\0'; ++ while (*pos == ' ') ++ *pos++ = '\0'; ++ map = pos; ++ break; ++ } ++ } ++ } ++ } ++ } ++ ++ if (!type) { ++ pos = buf; ++ while (*pos == ' ') ++ *pos++ = '\0'; ++ map = pos; ++ } ++ } + + /* Look for space terminator - ignore local options */ +- map = buf; + for (tmp = buf; *tmp; tmp++) { + if (*tmp == ' ') { + *tmp = '\0'; + break; +- } else if (!seen_colon && *tmp == ',') { +- type = buf; +- *tmp++ = '\0'; +- fmt = tmp; +- } else if (*tmp == ':') { +- seen_colon = 1; +- if (!fmt) +- type = buf; +- *tmp++ = '\0'; +- map = tmp; +- } else if (*tmp == '[') { +- /* +- * Unescaped '[' is a syntax error here as only +- * an ldap map with a type specified should contain +- * them. +- */ +- free(buf); +- return 0; + } + if (*tmp == '\\') + tmp++; diff --git a/autofs-5.0.4-fix-map-type-info-parse-error.patch b/autofs-5.0.4-fix-map-type-info-parse-error.patch new file mode 100644 index 0000000..537eab7 --- /dev/null +++ b/autofs-5.0.4-fix-map-type-info-parse-error.patch @@ -0,0 +1,51 @@ +autofs-5.0.4 - fix map type info parse error + +From: Ian Kent + +Fix a mistake in map type info parsing introduced by the IPv6 parse +changes. +--- + + CHANGELOG | 1 + + lib/parse_subs.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 05e0206..3fd97d3 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -55,6 +55,7 @@ + - remount we created mount point fix. + - fix double free in sasl_bind(). + - mannual umount recovery fixes. ++- fix map type info parse error. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index 0cba95a..0608cb7 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -315,6 +315,7 @@ struct map_type_info *parse_map_type_info(const char *str) + { + struct map_type_info *info; + char *buf, *type, *fmt, *map, *tmp; ++ int seen_colon = 0; + + buf = strdup(str); + if (!buf) +@@ -335,11 +336,12 @@ struct map_type_info *parse_map_type_info(const char *str) + if (*tmp == ' ') { + *tmp = '\0'; + break; +- } else if (*tmp == ',') { ++ } else if (!seen_colon && *tmp == ',') { + type = buf; + *tmp++ = '\0'; + fmt = tmp; + } else if (*tmp == ':') { ++ seen_colon = 1; + if (!fmt) + type = buf; + *tmp++ = '\0'; diff --git a/autofs-5.0.4-fix-memory-leak-reading-ldap-master.patch b/autofs-5.0.4-fix-memory-leak-reading-ldap-master.patch new file mode 100644 index 0000000..d278429 --- /dev/null +++ b/autofs-5.0.4-fix-memory-leak-reading-ldap-master.patch @@ -0,0 +1,38 @@ +autofs-5.0.4 - fix memory leak reading ldap master map + +From: Ian Kent + +When reading the master map the storage allocated by getting the location +value is not freed after use. +--- + + CHANGELOG | 1 + + modules/lookup_ldap.c | 2 ++ + 2 files changed, 3 insertions(+), 0 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 2be7683..a143294 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -36,6 +36,7 @@ + - fix call restorecon when misc device file doesn't exist. + - clear rpc client on lookup fail. + - fix lsb init script header. ++- fix memory leak reading master map. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 5a54b5f..9b1180c 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -1563,6 +1563,8 @@ int lookup_read_master(struct master *master, time_t age, void *context) + ldap_value_free(values); + goto next; + } ++ ldap_value_free(values); ++ + master_parse_entry(parse_buf, timeout, logging, age); + next: + ldap_value_free(keyValue); diff --git a/autofs-5.0.4-fix-negative-cache-non-existent-key.patch b/autofs-5.0.4-fix-negative-cache-non-existent-key.patch new file mode 100644 index 0000000..a17ffab --- /dev/null +++ b/autofs-5.0.4-fix-negative-cache-non-existent-key.patch @@ -0,0 +1,331 @@ +autofs-5.0.4 - fix negative cache non-existent key + +From: Ian Kent + +autofs was not recording map entries that don't exist for negative +caching. This was causing unwanted network map lookups. +--- + + CHANGELOG | 1 + + daemon/lookup.c | 48 ++++++++++++++++++++++++++++++++++++++++++++-- + modules/lookup_file.c | 20 ++++++++++++------- + modules/lookup_hosts.c | 21 ++++++++++++++++---- + modules/lookup_ldap.c | 20 ++++++++++++------- + modules/lookup_nisplus.c | 19 ++++++++++++------ + modules/lookup_program.c | 35 ++++++++++++++++++++++++++-------- + modules/lookup_yp.c | 19 ++++++++++++------ + 8 files changed, 143 insertions(+), 40 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 88ca579..bd35b00 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -2,6 +2,7 @@ + ----------------------- + - fix dumb libxml2 check + - fix nested submount expire deadlock. ++- fix negative caching for non-existent map keys. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 803df4f..0cf6e3f 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -804,6 +804,45 @@ static enum nsswitch_status lookup_map_name(struct nss_source *this, + return result; + } + ++static void update_negative_cache(struct autofs_point *ap, struct map_source *source, const char *name) ++{ ++ struct master_mapent *entry = ap->entry; ++ struct map_source *map; ++ struct mapent *me; ++ ++ /* Have we recorded the lookup fail for negative caching? */ ++ me = lookup_source_mapent(ap, name, LKP_DISTINCT); ++ if (me) ++ /* ++ * Already exists in the cache, the mount fail updates ++ * will update negative timeout status. ++ */ ++ cache_unlock(me->mc); ++ else { ++ /* Notify only once after fail */ ++ error(ap->logopt, "key \"%s\" not found in map.", name); ++ ++ /* Doesn't exist in any source, just add it somewhere */ ++ if (source) ++ map = source; ++ else ++ map = entry->maps; ++ if (map) { ++ time_t now = time(NULL); ++ int rv = CHE_FAIL; ++ ++ cache_writelock(map->mc); ++ rv = cache_update(map->mc, map, name, NULL, now); ++ if (rv != CHE_FAIL) { ++ me = cache_lookup_distinct(map->mc, name); ++ me->status = now + ap->negative_timeout; ++ } ++ cache_unlock(map->mc); ++ } ++ } ++ return; ++} ++ + int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const char *name, int name_len) + { + struct master_mapent *entry = ap->entry; +@@ -907,8 +946,13 @@ int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const c + send_map_update_request(ap); + pthread_cleanup_pop(1); + +- if (result == NSS_STATUS_NOTFOUND) +- error(ap->logopt, "key \"%s\" not found in map.", name); ++ /* ++ * The last source lookup will return NSS_STATUS_NOTFOUND if the ++ * map exits and the key has not been found but the map may also ++ * not exist in which case the key is also not found. ++ */ ++ if (result == NSS_STATUS_NOTFOUND || result == NSS_STATUS_UNAVAIL) ++ update_negative_cache(ap, source, name); + + return !result; + } +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index 807ceab..9e34b72 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -1069,14 +1069,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (key_len > KEY_MAX_LEN) + return NSS_STATUS_NOTFOUND; + +- /* Check if we recorded a mount fail for this key */ +- cache_readlock(mc); +- me = cache_lookup_distinct(mc, key); +- if (me && me->status >= time(NULL)) { +- cache_unlock(mc); +- return NSS_STATUS_UNAVAIL; ++ /* Check if we recorded a mount fail for this key anywhere */ ++ me = lookup_source_mapent(ap, key, LKP_DISTINCT); ++ if (me) { ++ if (me->status >= time(NULL)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ /* Negative timeout expired for non-existent entry. */ ++ if (!me->mapent) ++ cache_delete(me->mc, key); ++ ++ cache_unlock(me->mc); + } +- cache_unlock(mc); + + /* + * We can't check the direct mount map as if it's not in +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index bf24d7f..f8d4269 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -136,12 +136,25 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + mc = source->mc; + ++ /* Check if we recorded a mount fail for this key anywhere */ ++ me = lookup_source_mapent(ap, name, LKP_DISTINCT); ++ if (me) { ++ if (me->status >= time(NULL)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ if (!me->mapent) { ++ cache_delete(me->mc, name); ++ me = NULL; ++ } ++ ++ cache_unlock(me->mc); ++ } ++ + cache_readlock(mc); + me = cache_lookup_distinct(mc, name); +- if (me && me->status >= time(NULL)) { +- cache_unlock(mc); +- return NSS_STATUS_NOTFOUND; +- } else if (!me) { ++ if (!me) { + cache_unlock(mc); + /* + * We haven't read the list of hosts into the +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 31c2c13..42c3235 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -2709,14 +2709,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (key_len > KEY_MAX_LEN) + return NSS_STATUS_NOTFOUND; + +- /* Check if we recorded a mount fail for this key */ +- cache_readlock(mc); +- me = cache_lookup_distinct(mc, key); +- if (me && me->status >= time(NULL)) { +- cache_unlock(mc); +- return NSS_STATUS_NOTFOUND; ++ /* Check if we recorded a mount fail for this key anywhere */ ++ me = lookup_source_mapent(ap, key, LKP_DISTINCT); ++ if (me) { ++ if (me->status >= time(NULL)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ /* Negative timeout expired for non-existent entry. */ ++ if (!me->mapent) ++ cache_delete(me->mc, key); ++ ++ cache_unlock(me->mc); + } +- cache_unlock(mc); + + /* + * We can't check the direct mount map as if it's not in +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index 755556d..f15465f 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -493,13 +493,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (key_len > KEY_MAX_LEN) + return NSS_STATUS_NOTFOUND; + +- cache_readlock(mc); +- me = cache_lookup_distinct(mc, key); +- if (me && me->status >= time(NULL)) { +- cache_unlock(mc); +- return NSS_STATUS_NOTFOUND; ++ /* Check if we recorded a mount fail for this key anywhere */ ++ me = lookup_source_mapent(ap, key, LKP_DISTINCT); ++ if (me) { ++ if (me->status >= time(NULL)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ /* Negative timeout expired for non-existent entry. */ ++ if (!me->mapent) ++ cache_delete(me->mc, key); ++ ++ cache_unlock(me->mc); + } +- cache_unlock(mc); + + /* + * We can't check the direct mount map as if it's not in +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index daf874d..bf32d3b 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -131,13 +131,25 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + mc = source->mc; + ++ /* Check if we recorded a mount fail for this key anywhere */ ++ me = lookup_source_mapent(ap, name, LKP_DISTINCT); ++ if (me) { ++ if (me->status >= time(NULL)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ /* Negative timeout expired for non-existent entry. */ ++ if (!me->mapent) ++ cache_delete(me->mc, name); ++ ++ cache_unlock(me->mc); ++ } ++ + /* Catch installed direct offset triggers */ +- cache_readlock(mc); ++ cache_writelock(mc); + me = cache_lookup_distinct(mc, name); +- if (me && me->status >= time(NULL)) { +- cache_unlock(mc); +- return NSS_STATUS_NOTFOUND; +- } else if (!me) { ++ if (!me) { + cache_unlock(mc); + /* + * If there's a '/' in the name and the offset is not in +@@ -149,8 +161,6 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + return NSS_STATUS_NOTFOUND; + } + } else { +- cache_unlock(mc); +- + /* Otherwise we found a valid offset so try mount it */ + debug(ap->logopt, MODPREFIX "%s -> %s", name, me->mapent); + +@@ -163,19 +173,28 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + */ + if (strchr(name, '/') || + me->age + ap->negative_timeout > time(NULL)) { ++ char *ent = NULL; ++ ++ if (me->mapent) { ++ ent = alloca(strlen(me->mapent) + 1); ++ strcpy(ent, me->mapent); ++ } ++ cache_unlock(mc); + master_source_current_wait(ap->entry); + ap->entry->current = source; + ret = ctxt->parse->parse_mount(ap, name, +- name_len, me->mapent, ctxt->parse->context); ++ name_len, ent, ctxt->parse->context); + goto out_free; + } else { + if (me->multi) { ++ cache_unlock(mc); + warn(ap->logopt, MODPREFIX + "unexpected lookup for active multi-mount" + " key %s, returning fail", name); + return NSS_STATUS_UNAVAIL; + } + cache_delete(mc, name); ++ cache_unlock(mc); + } + } + +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index 8b6408b..1b62f57 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -603,13 +603,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (key_len > KEY_MAX_LEN) + return NSS_STATUS_NOTFOUND; + +- cache_readlock(mc); +- me = cache_lookup_distinct(mc, key); +- if (me && me->status >= time(NULL)) { +- cache_unlock(mc); +- return NSS_STATUS_NOTFOUND; ++ /* Check if we recorded a mount fail for this key anywhere */ ++ me = lookup_source_mapent(ap, key, LKP_DISTINCT); ++ if (me) { ++ if (me->status >= time(NULL)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ /* Negative timeout expired for non-existent entry. */ ++ if (!me->mapent) ++ cache_delete(me->mc, key); ++ ++ cache_unlock(me->mc); + } +- cache_unlock(mc); + + /* + * We can't check the direct mount map as if it's not in diff --git a/autofs-5.0.4-fix-notify-mount-message-path.patch b/autofs-5.0.4-fix-notify-mount-message-path.patch new file mode 100644 index 0000000..38b9777 --- /dev/null +++ b/autofs-5.0.4-fix-notify-mount-message-path.patch @@ -0,0 +1,61 @@ +autofs-5.0.4 - fix notify mount message path + +From: Ian Kent + +If logging is set to verbose we want to log the actual path rather +than the false root. Hoevever, when logging is set to debug we do +need to show the false root to give us the true picture in relation +to accompanying log messages. +--- + + CHANGELOG | 1 + + daemon/direct.c | 5 ++++- + daemon/indirect.c | 5 ++++- + 3 files changed, 9 insertions(+), 2 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index d1cc113..0a0519f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -51,6 +51,7 @@ + - always read file maps key lookup fixes. + - use srv query for domain dn. + - fix not releasing resources when using submounts. ++- fix notify mount message path. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/direct.c b/daemon/direct.c +index 1ed2b15..74a9acc 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -767,8 +767,11 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char * + } + + ops->timeout(ap->logopt, ioctlfd, &timeout); +- notify_mount_result(ap, mountpoint, str_offset); + cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino); ++ if (ap->logopt & LOGOPT_DEBUG) ++ notify_mount_result(ap, mountpoint, str_offset); ++ else ++ notify_mount_result(ap, me->key, str_offset); + ops->close(ap->logopt, ioctlfd); + + debug(ap->logopt, "mounted trigger %s at %s", me->key, mountpoint); +diff --git a/daemon/indirect.c b/daemon/indirect.c +index bc39e63..463b39c 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -174,7 +174,10 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) + ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + + ops->timeout(ap->logopt, ap->ioctlfd, &timeout); +- notify_mount_result(ap, root, str_indirect); ++ if (ap->logopt & LOGOPT_DEBUG) ++ notify_mount_result(ap, root, str_indirect); ++ else ++ notify_mount_result(ap, ap->path, str_indirect); + + return 0; + diff --git a/autofs-5.0.4-fix-pthread-push-order-in-expire_proc_direct.patch b/autofs-5.0.4-fix-pthread-push-order-in-expire_proc_direct.patch new file mode 100644 index 0000000..ea37cc4 --- /dev/null +++ b/autofs-5.0.4-fix-pthread-push-order-in-expire_proc_direct.patch @@ -0,0 +1,40 @@ +autofs-5.0.4 - fix pthread push order in expire_proc_direct() + +From: Ian Kent + +Apparently the pthread_cleanup_push() has the quite stupid semantic +of not working properly if the value of the pointer passed to it +changes after it has been called. +--- + + CHANGELOG | 1 + + daemon/direct.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 4b85649..4491449 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -58,6 +58,7 @@ + - fix map type info parse error. + - fix an RPC fd leak. + - don't block signals we expect to dump core. ++- fix pthread push order in expire_proc_direct(). + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/direct.c b/daemon/direct.c +index 7b02c7a..0f33d03 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -823,8 +823,8 @@ void *expire_proc_direct(void *arg) + + left = 0; + +- pthread_cleanup_push(mnts_cleanup, mnts); + mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/"); ++ pthread_cleanup_push(mnts_cleanup, mnts); + + /* Get a list of mounts select real ones and expire them if possible */ + INIT_LIST_HEAD(&list); diff --git a/autofs-5.0.4-fix-quoted-mess.patch b/autofs-5.0.4-fix-quoted-mess.patch new file mode 100644 index 0000000..fa5b9de --- /dev/null +++ b/autofs-5.0.4-fix-quoted-mess.patch @@ -0,0 +1,38 @@ +autofs-5.0.4 - clear the quoted flag after each character + +From: Jeff Moyer + +This regression was introduced by autofs-5.0.4-fix-select-fd-limit.patch. +The fix is to clear the quoted flag after processing each character from +program map input. +--- + + CHANGELOG | 1 + + modules/lookup_program.c | 1 + + 2 files changed, 2 insertions(+), 0 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 912c088..af77b55 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -7,6 +7,7 @@ + - fix select(2) fd limit. + - make hash table scale to thousands of entries (Paul Wankadia, + Valerie Aurora Henson). ++- clear the quoted flag after each character from program map input. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index f62d3ef..9878936 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -341,6 +341,7 @@ cont: + /* Eat characters till there's no more output */ + break; + } ++ quoted = 0; + goto cont; + } + quoted = 0; diff --git a/autofs-5.0.4-fix-restorecon.patch b/autofs-5.0.4-fix-restorecon.patch new file mode 100644 index 0000000..a651300 --- /dev/null +++ b/autofs-5.0.4-fix-restorecon.patch @@ -0,0 +1,51 @@ +autofs-5.0.4 - fix restorecon + +From: Ian Kent + +If the misc device node doesn't exist don't try to run restorecon on it. +--- + + CHANGELOG | 1 + + redhat/autofs.init.in | 2 +- + samples/rc.autofs.in | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 96a4617..00b455e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -33,6 +33,7 @@ + - add LSB init script parameter block. + - fix file map lookup when reading included or nsswitch sources. + - use misc device ioctl interface by default, if available. ++- fix call restorecon when misc device file doesn't exist. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in +index 0fd1777..a9a33c8 100644 +--- a/redhat/autofs.init.in ++++ b/redhat/autofs.init.in +@@ -76,7 +76,7 @@ function start() { + mknod -m 0600 /dev/$DEVICE c 10 $MINOR + fi + fi +- if [ -x /sbin/restorecon ]; then ++ if [ -x /sbin/restorecon -a -c /dev/$DEVICE ]; then + /sbin/restorecon /dev/$DEVICE + fi + else +diff --git a/samples/rc.autofs.in b/samples/rc.autofs.in +index 63a0c5d..78cbec2 100644 +--- a/samples/rc.autofs.in ++++ b/samples/rc.autofs.in +@@ -66,7 +66,7 @@ function start() { + mknod -m 0600 /dev/$DEVICE c 10 $MINOR + fi + fi +- if [ -x /sbin/restorecon ]; then ++ if [ -x /sbin/restorecon -a -c /dev/$DEVICE ]; then + /sbin/restorecon /dev/$DEVICE + fi + else diff --git a/autofs-5.0.4-fix-return-start-status-on-fail.patch b/autofs-5.0.4-fix-return-start-status-on-fail.patch new file mode 100644 index 0000000..29e40cc --- /dev/null +++ b/autofs-5.0.4-fix-return-start-status-on-fail.patch @@ -0,0 +1,157 @@ +autofs-5.0.4 - fix return start status on fail + +From: Ian Kent + +We're not returning the status to the parent when automount(8) is waiting +for the daemon to finish its startup. +--- + + CHANGELOG | 1 + + daemon/automount.c | 27 +++++++++++++++++++++------ + 2 files changed, 22 insertions(+), 6 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index fdde400..2cb35dc 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -27,6 +27,7 @@ + - add WITH_LIBTIRPC to -V status report. + - add nfs mount protocol default configuration option. + - fix bad token declaration in master map parser. ++- fix return start status on fail. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/automount.c b/daemon/automount.c +index 776c92c..80691fa 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -60,7 +60,7 @@ long global_negative_timeout = -1; + int do_force_unlink = 0; /* Forceably unlink mount tree at startup */ + + static int start_pipefd[2]; +-static int st_stat = 0; ++static int st_stat = 1; + static int *pst_stat = &st_stat; + static pthread_t state_mach_thid; + +@@ -1046,6 +1046,7 @@ static void become_daemon(unsigned foreground, unsigned daemon_check) + { + FILE *pidfp; + char buf[MAX_ERR_BUF]; ++ int res; + pid_t pid; + + /* Don't BUSY any directories unnecessarily */ +@@ -1072,10 +1073,9 @@ static void become_daemon(unsigned foreground, unsigned daemon_check) + } else { + pid = fork(); + if (pid > 0) { +- int r; + close(start_pipefd[1]); +- r = read(start_pipefd[0], pst_stat, sizeof(*pst_stat)); +- if (r < 0) ++ res = read(start_pipefd[0], pst_stat, sizeof(*pst_stat)); ++ if (res < 0) + exit(1); + exit(*pst_stat); + } else if (pid < 0) { +@@ -1088,8 +1088,13 @@ static void become_daemon(unsigned foreground, unsigned daemon_check) + if (daemon_check && !aquire_flag_file()) { + fprintf(stderr, "%s: program is already running.\n", + program); ++ /* Return success if already running */ ++ st_stat = 0; ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ if (res < 0) ++ exit(1); + close(start_pipefd[1]); +- exit(1); ++ exit(*pst_stat); + } + + /* +@@ -1099,8 +1104,9 @@ static void become_daemon(unsigned foreground, unsigned daemon_check) + if (setsid() == -1) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + fprintf(stderr, "setsid: %s", estr); ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); +- exit(1); ++ exit(*pst_stat); + } + log_to_syslog(); + } +@@ -1991,6 +1997,7 @@ int main(int argc, char *argv[]) + if (!master_list) { + logerr("%s: can't create master map %s", + program, argv[0]); ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); + exit(1); +@@ -1999,6 +2006,7 @@ int main(int argc, char *argv[]) + if (pthread_attr_init(&th_attr)) { + logerr("%s: failed to init thread attribute struct!", + program); ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); + exit(1); +@@ -2007,6 +2015,7 @@ int main(int argc, char *argv[]) + if (pthread_attr_init(&th_attr_detached)) { + logerr("%s: failed to init thread attribute struct!", + program); ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); + exit(1); +@@ -2016,6 +2025,7 @@ int main(int argc, char *argv[]) + &th_attr_detached, PTHREAD_CREATE_DETACHED)) { + logerr("%s: failed to set detached thread attribute!", + program); ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); + exit(1); +@@ -2026,6 +2036,7 @@ int main(int argc, char *argv[]) + &th_attr_detached, PTHREAD_STACK_MIN*64)) { + logerr("%s: failed to set stack size thread attribute!", + program); ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); + exit(1); +@@ -2043,6 +2054,7 @@ int main(int argc, char *argv[]) + logerr("%s: failed to create thread data key for std env vars!", + program); + master_kill(master_list); ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); + exit(1); +@@ -2053,6 +2065,7 @@ int main(int argc, char *argv[]) + if (!alarm_start_handler()) { + logerr("%s: failed to create alarm handler thread!", program); + master_kill(master_list); ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); + exit(1); +@@ -2061,6 +2074,7 @@ int main(int argc, char *argv[]) + if (!st_start_handler()) { + logerr("%s: failed to create FSM handler thread!", program); + master_kill(master_list); ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); + exit(1); +@@ -2092,6 +2106,7 @@ int main(int argc, char *argv[]) + */ + do_force_unlink = 0; + ++ st_stat = 0; + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + diff --git a/autofs-5.0.4-fix-rpc-fd-leak.patch b/autofs-5.0.4-fix-rpc-fd-leak.patch new file mode 100644 index 0000000..d05d67a --- /dev/null +++ b/autofs-5.0.4-fix-rpc-fd-leak.patch @@ -0,0 +1,47 @@ +autofs-5.0.4 - fix rpc fd leak + +From: Ian Kent + +Recent changes which introduced the ability to handle to cope with +IPv6 addresses causes a file descriptor leak in the RPC library. +--- + + CHANGELOG | 1 + + lib/rpc_subs.c | 11 ----------- + 2 files changed, 1 insertions(+), 11 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 3fd97d3..7f27f5e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -56,6 +56,7 @@ + - fix double free in sasl_bind(). + - mannual umount recovery fixes. + - fix map type info parse error. ++- fix an RPC fd leak. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index d034b29..cafc775 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -253,17 +253,6 @@ static CLIENT *rpc_do_create_client(struct sockaddr *addr, struct conn_info *inf + return NULL; + } + +- if (!info->client) { +- *fd = open_sock(addr->sa_family, type, proto); +- if (*fd < 0) +- return NULL; +- +- if (bind(*fd, laddr, slen) < 0) { +- close(*fd); +- return NULL; +- } +- } +- + switch (info->proto->p_proto) { + case IPPROTO_UDP: + if (!info->client) { diff --git a/autofs-5.0.4-fix-select-fd-limit.patch b/autofs-5.0.4-fix-select-fd-limit.patch new file mode 100644 index 0000000..c12a59f --- /dev/null +++ b/autofs-5.0.4-fix-select-fd-limit.patch @@ -0,0 +1,275 @@ +autofs-5.0.4 - fix select fd limit + +From: Ian Kent + +Using a large number of direct mounts causes autofs to hang. This is +because select(2) is limited to 1024 file handles (usually). To resolve +this we need to convert calls to select(2) to use poll(2). +--- + + CHANGELOG | 1 + + daemon/spawn.c | 19 ++++++------ + lib/rpc_subs.c | 32 ++++++++++++++------ + modules/lookup_program.c | 74 +++++++++++++++++++++++++++------------------- + 4 files changed, 78 insertions(+), 48 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 43f3205..0fb7db5 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -4,6 +4,7 @@ + - fix nested submount expire deadlock. + - fix negative caching for non-existent map keys. + - use CLOEXEC flag. ++- fix select(2) fd limit. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/spawn.c b/daemon/spawn.c +index 4ddf46f..e02d926 100644 +--- a/daemon/spawn.c ++++ b/daemon/spawn.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -89,21 +90,21 @@ void reset_signals(void) + + static int timed_read(int pipe, char *buf, size_t len, int time) + { +- struct timeval timeout = { 0, 0 }; +- struct timeval *tout = NULL; +- fd_set wset, rset; ++ struct pollfd pfd[1]; ++ int timeout = time; + int ret; + +- FD_ZERO(&rset); +- FD_SET(pipe, &rset); +- wset = rset; ++ pfd[0].fd = pipe; ++ pfd[0].events = POLLIN; + + if (time != -1) { +- timeout.tv_sec = time; +- tout = &timeout; ++ if (time >= (INT_MAX - 1)/1000) ++ timeout = INT_MAX - 1; ++ else ++ timeout = time * 1000; + } + +- ret = select(pipe + 1, &rset, &wset, NULL, tout); ++ ret = poll(pfd, 1, timeout); + if (ret <= 0) { + if (ret == 0) + ret = -ETIMEDOUT; +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 9ac3657..7b347a7 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include "mount.h" + #include "rpc_subs.h" +@@ -197,14 +198,15 @@ void rpc_destroy_udp_client(struct conn_info *info) + /* + * Perform a non-blocking connect on the socket fd. + * +- * tout contains the timeout. It will be modified to contain the time +- * remaining (i.e. time provided - time elasped). ++ * The input struct timeval always has tv_nsec set to zero, ++ * we only ever use tv_sec for timeouts. + */ + static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout) + { ++ struct pollfd pfd[1]; ++ int timeout = tout->tv_sec; + int flags, ret; + socklen_t len; +- fd_set wset, rset; + + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) +@@ -229,12 +231,10 @@ static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout) + if (ret == 0) + goto done; + +- /* now wait */ +- FD_ZERO(&rset); +- FD_SET(fd, &rset); +- wset = rset; ++ pfd[0].fd = fd; ++ pfd[0].events = POLLOUT; + +- ret = select(fd + 1, &rset, &wset, NULL, tout); ++ ret = poll(pfd, 1, timeout); + if (ret <= 0) { + if (ret == 0) + ret = -ETIMEDOUT; +@@ -243,13 +243,27 @@ static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout) + goto done; + } + +- if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) { ++ if (pfd[0].revents) { + int status; + + len = sizeof(ret); + status = getsockopt(fd, SOL_SOCKET, SO_ERROR, &ret, &len); + if (status < 0) { ++ char buf[MAX_ERR_BUF + 1]; ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ ++ /* ++ * We assume getsockopt amounts to a read on the ++ * descriptor and gives us the errno we need for ++ * the POLLERR revent case. ++ */ + ret = -errno; ++ ++ /* Unexpected case, log it so we know we got caught */ ++ if (pfd[0].revents & POLLNVAL) ++ logerr("unexpected poll(2) error on connect:" ++ " %s", estr); ++ + goto done; + } + +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index 6f4e2a3..f62d3ef 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #define MODULE_LOOKUP + #include "automount.h" +@@ -113,14 +114,12 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + char errbuf[1024], *errp; + char ch; + int pipefd[2], epipefd[2]; ++ struct pollfd pfd[2]; + pid_t f; +- int files_left; + int status; +- fd_set readfds, ourfds; + enum state { st_space, st_map, st_done } state; + int quoted = 0; + int ret = 1; +- int max_fd; + int distance; + int alloci = 1; + +@@ -253,30 +252,39 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + errp = errbuf; + state = st_space; + +- FD_ZERO(&ourfds); +- FD_SET(pipefd[0], &ourfds); +- FD_SET(epipefd[0], &ourfds); ++ pfd[0].fd = pipefd[0]; ++ pfd[0].events = POLLIN; ++ pfd[1].fd = epipefd[0]; ++ pfd[1].events = POLLIN; + +- max_fd = pipefd[0] > epipefd[0] ? pipefd[0] : epipefd[0]; ++ while (1) { ++ int bytes; + +- files_left = 2; ++ if (poll(pfd, 2, -1) < 0 && errno != EINTR) ++ break; ++ ++ if (pfd[0].fd == -1 && pfd[1].fd == -1) ++ break; + +- while (files_left != 0) { +- readfds = ourfds; +- if (select(max_fd + 1, &readfds, NULL, NULL, NULL) < 0 && errno != EINTR) ++ if ((pfd[0].revents & (POLLIN|POLLHUP)) == POLLHUP && ++ (pfd[1].revents & (POLLIN|POLLHUP)) == POLLHUP) + break; + + /* Parse maps from stdout */ +- if (FD_ISSET(pipefd[0], &readfds)) { +- if (read(pipefd[0], &ch, 1) < 1) { +- FD_CLR(pipefd[0], &ourfds); +- files_left--; ++ if (pfd[0].revents) { ++cont: ++ bytes = read(pipefd[0], &ch, 1); ++ if (bytes == 0) ++ goto next; ++ else if (bytes < 0) { ++ pfd[0].fd = -1; + state = st_done; ++ goto next; + } + + if (!quoted && ch == '\\') { + quoted = 1; +- continue; ++ goto cont; + } + + switch (state) { +@@ -333,26 +341,32 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + /* Eat characters till there's no more output */ + break; + } ++ goto cont; + } + quoted = 0; +- ++next: + /* Deal with stderr */ +- if (FD_ISSET(epipefd[0], &readfds)) { +- if (read(epipefd[0], &ch, 1) < 1) { +- FD_CLR(epipefd[0], &ourfds); +- files_left--; +- } else if (ch == '\n') { +- *errp = '\0'; +- if (errbuf[0]) +- logmsg(">> %s", errbuf); +- errp = errbuf; +- } else { +- if (errp >= &errbuf[1023]) { ++ if (pfd[1].revents) { ++ while (1) { ++ bytes = read(epipefd[0], &ch, 1); ++ if (bytes == 0) ++ break; ++ else if (bytes < 0) { ++ pfd[1].fd = -1; ++ break; ++ } else if (ch == '\n') { + *errp = '\0'; +- logmsg(">> %s", errbuf); ++ if (errbuf[0]) ++ logmsg(">> %s", errbuf); + errp = errbuf; ++ } else { ++ if (errp >= &errbuf[1023]) { ++ *errp = '\0'; ++ logmsg(">> %s", errbuf); ++ errp = errbuf; ++ } ++ *(errp++) = ch; + } +- *(errp++) = ch; + } + } + } diff --git a/autofs-5.0.4-fix-st_remove_tasks-locking.patch b/autofs-5.0.4-fix-st_remove_tasks-locking.patch new file mode 100644 index 0000000..cb0f618 --- /dev/null +++ b/autofs-5.0.4-fix-st_remove_tasks-locking.patch @@ -0,0 +1,60 @@ +autofs-5.0.4 - fix st_remove_tasks() locking + +From: Ian Kent + +The autofs serialization of state changing during task (mount, umount etc.) +execution was being done twice, with the state queue manager and by using +a pipe to communicate state changes to the handle_mounts() thread. This +required the use of two mutexes which was unnecessary and problematic. So +the pipe was removed and the state queue alone now handles this. When this +was done most of the state queue locking was moved into the state queue +manager functions, however, the locking was inadvertantly left out of the +st_remove_tasks() function. +--- + + CHANGELOG | 1 + + daemon/state.c | 8 +++++++- + 2 files changed, 8 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index a143294..c8b88e4 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -37,6 +37,7 @@ + - clear rpc client on lookup fail. + - fix lsb init script header. + - fix memory leak reading master map. ++- fix st_remove_tasks() locking. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/state.c b/daemon/state.c +index 417fde1..533e241 100644 +--- a/daemon/state.c ++++ b/daemon/state.c +@@ -783,10 +783,14 @@ void st_remove_tasks(struct autofs_point *ap) + struct state_queue *task, *waiting; + int status; + ++ st_mutex_lock(); ++ + head = &state_queue; + +- if (list_empty(head)) ++ if (list_empty(head)) { ++ st_mutex_unlock(); + return; ++ } + + p = head->next; + while (p != head) { +@@ -823,6 +827,8 @@ void st_remove_tasks(struct autofs_point *ap) + if (status) + fatal(status); + ++ st_mutex_unlock(); ++ + return; + } + diff --git a/autofs-5.0.4-force-unlink-umount.patch b/autofs-5.0.4-force-unlink-umount.patch new file mode 100644 index 0000000..3b49747 --- /dev/null +++ b/autofs-5.0.4-force-unlink-umount.patch @@ -0,0 +1,235 @@ +autofs-5.0.4 - force unlink umount at startup + +From: Ian Kent + +Version 5.0.3 autofs would unlink existing mounts at startup. This +functioned OK most of the time but caused processes whose working +directory was within unlinked automounted directories to not get a +correct pwd reported by the system. + +There can be situations where the unlink umounting is desirable, such +as when the daemon is forceably killed and we want to get rid of any +existing mounts at startup. This change provides a way to force this +old behavior by passing the "--force" option to the daemon. This can +also be done by using the "forcestart" and "forcerestart" actions to +the init script. + +Note that the old behavior will always be used if the kernel does not +include the iotcl re-implementation which provides the ability to +re-connect to existing mounts. +--- + + CHANGELOG | 2 ++ + daemon/automount.c | 14 +++++++++++++- + daemon/direct.c | 2 +- + daemon/indirect.c | 2 +- + include/automount.h | 3 +++ + man/automount.8 | 13 +++++++++++++ + redhat/autofs.init.in | 10 +++++++++- + samples/rc.autofs.in | 10 +++++++++- + 8 files changed, 51 insertions(+), 5 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 7dee674..d4dd70b 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -12,6 +12,8 @@ + - fix hosts map use after free. + - fix uri list locking (again). + - check for stale SASL credentials upon connect fail. ++- add "forcestart" and "forcerestart" init script options to allow ++ use of 5.0.3 strartup behavior if required. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/automount.c b/daemon/automount.c +index f04273f..e20e7c9 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -57,6 +57,7 @@ static char *pid_file = NULL; /* File in which to keep pid */ + unsigned int global_random_selection; /* use random policy when selecting + * which multi-mount host to mount */ + long global_negative_timeout = -1; ++int do_force_unlink = 0; /* Forceably unlink mount tree at startup */ + + static int start_pipefd[2]; + static int st_stat = 0; +@@ -1798,6 +1799,7 @@ int main(int argc, char *argv[]) + {"version", 0, 0, 'V'}, + {"set-log-priority", 1, 0, 'l'}, + {"dont-check-daemon", 0, 0, 'C'}, ++ {"force", 0, 0, 'F'}, + {0, 0, 0, 0} + }; + +@@ -1819,7 +1821,7 @@ int main(int argc, char *argv[]) + daemon_check = 1; + + opterr = 0; +- while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:n:C", long_options, NULL)) != EOF) { ++ while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:n:CF", long_options, NULL)) != EOF) { + switch (opt) { + case 'h': + usage(); +@@ -1892,6 +1894,10 @@ int main(int argc, char *argv[]) + daemon_check = 0; + break; + ++ case 'F': ++ do_force_unlink = 1; ++ break; ++ + case '?': + case ':': + printf("%s: Ambiguous or unknown options\n", program); +@@ -2066,6 +2072,12 @@ int main(int argc, char *argv[]) + exit(3); + } + ++ /* ++ * Mmm ... reset force unlink umount so we don't also do this ++ * in future when we receive a HUP signal. ++ */ ++ do_force_unlink = 0; ++ + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + +diff --git a/daemon/direct.c b/daemon/direct.c +index d9dda3d..2d979f1 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -335,7 +335,7 @@ int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struc + /* Calculate the timeouts */ + ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + +- if (ops->version) { ++ if (ops->version && !do_force_unlink) { + ap->flags |= MOUNT_FLAG_REMOUNT; + ret = try_remount(ap, me, t_direct); + ap->flags &= ~MOUNT_FLAG_REMOUNT; +diff --git a/daemon/indirect.c b/daemon/indirect.c +index 0721707..2ccbc53 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -97,7 +97,7 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) + + ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + +- if (ops->version) { ++ if (ops->version && !do_force_unlink) { + ap->flags |= MOUNT_FLAG_REMOUNT; + ret = try_remount(ap, NULL, t_indirect); + ap->flags &= ~MOUNT_FLAG_REMOUNT; +diff --git a/include/automount.h b/include/automount.h +index 46cb6c6..1f14d5b 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -428,6 +428,9 @@ struct autofs_point { + struct list_head submounts; /* List of child submounts */ + }; + ++/* Foreably unlink existing mounts at startup. */ ++extern int do_force_unlink; ++ + /* Standard functions used by daemon or modules */ + + #define MOUNT_OFFSET_OK 0 +diff --git a/man/automount.8 b/man/automount.8 +index d9285bf..9fcaaf4 100644 +--- a/man/automount.8 ++++ b/man/automount.8 +@@ -84,6 +84,11 @@ path name as specified in the master map. + .TP + .I "\-C, \-\-dont-check-daemon" + Don't check if the daemon is currently running (see NOTES). ++.TP ++.I "\-F, \-\-force" ++Force an unlink umount of existing mounts under autofs managed mount points ++during startup. This can cause problems for processes with working directories ++within these mounts (see NOTES). + .SH ARGUMENTS + \fBautomount\fP takes one optional argument, the name of the master map to + use. +@@ -132,6 +137,14 @@ for certain types of automount maps. The mounts of the seperate daemons + might interfere with one another. The implications of running multiple + daemon instances needs to be checked and tested before we can say this + is supported. ++.P ++If the option to force an unlink of mounts at startup is used then processes ++whose working directory is within unlinked automounted directories will not ++get the correct pwd from the system. This is because, after the mount is ++unlinked from the mount tree, anything that needs to walk back up the mount ++tree to construct a path, such as getcwd(2) and the proc filesystem ++/proc//cwd, cannot work because the point from which the path is ++constructed has been detached from the mount tree. + .SH "SEE ALSO" + .BR autofs (5), + .BR autofs (8), +diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in +index 65c786e..471667e 100644 +--- a/redhat/autofs.init.in ++++ b/redhat/autofs.init.in +@@ -137,6 +137,10 @@ case "$1" in + start) + start + ;; ++ forcestart) ++ OPTIONS="$OPTIONS --force" ++ start ++ ;; + stop) + stop + ;; +@@ -146,6 +150,10 @@ case "$1" in + restart) + restart + ;; ++ forcerestart) ++ OPTIONS="$OPTIONS --force" ++ restart ++ ;; + reload) + reload + ;; +@@ -155,7 +163,7 @@ case "$1" in + fi + ;; + *) +- echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}" ++ echo $"Usage: $0 {start|forcestart|stop|status|restart|orcerestart|reload|condrestart}" + exit 1; + ;; + esac +diff --git a/samples/rc.autofs.in b/samples/rc.autofs.in +index 51f5b02..2877fe2 100644 +--- a/samples/rc.autofs.in ++++ b/samples/rc.autofs.in +@@ -117,17 +117,25 @@ case "$1" in + start) + start + ;; ++ forcestart) ++ OPTIONS="$OPTIONS --force" ++ start ++ ;; + stop) + stop + ;; + restart) + restart + ;; ++ forcerestart) ++ OPTIONS="$OPTIONS --force" ++ restart ++ ;; + reload) + reload + ;; + *) +- echo $"Usage: $0 {start|stop|restart|reload}" ++ echo $"Usage: $0 {start|forcestart|stop|restart|forcerestart|reload}" + exit 1; + ;; + esac diff --git a/autofs-5.0.4-improve-manual-umount-recovery.patch b/autofs-5.0.4-improve-manual-umount-recovery.patch new file mode 100644 index 0000000..8a055d3 --- /dev/null +++ b/autofs-5.0.4-improve-manual-umount-recovery.patch @@ -0,0 +1,161 @@ +autofs-5.0.4 - improve manual umount recovery + +From: Ian Kent + +The check for manually umounted mounts in the expire of direct mounts is +racy and the check itself is inadequate in that it can incorrectly clear +the descriptor of an active mount. Also, we do a similar test following +the expire which is a waste since we can catch this on the next expire. +So these two tests have been combined and the check done only prior to +the expire. In the indirect expire we don't have a check at all so we +add one. +--- + + CHANGELOG | 1 + + daemon/direct.c | 28 ++++++++++------------------ + daemon/indirect.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- + 3 files changed, 57 insertions(+), 19 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 5e01812..89aaa99 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -45,6 +45,7 @@ + - fix kernel includes. + - dont umount existing direct mount on master re-read. + - fix incorrect shutdown introduced by library relaod fixes. ++- improve manual umount recovery. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/direct.c b/daemon/direct.c +index 4f4ff20..1ed2b15 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -881,13 +881,14 @@ void *expire_proc_direct(void *arg) + * avoid maintaining a file handle for control + * functions as once it's mounted all opens are + * directed to the mount not the trigger. +- * But first expire possible rootless offsets first. + */ + +- /* Offsets always have a real mount at their base */ ++ /* Check for manual umount */ + cache_writelock(me->mc); +- if (strstr(next->opts, "offset")) { +- ops->close(ap->logopt, me->ioctlfd); ++ if (me->ioctlfd != -1 && ++ fstat(ioctlfd, &st) != -1 && ++ !count_mounts(ap->logopt, next->path, st.st_dev)) { ++ ops->close(ap->logopt, ioctlfd); + me->ioctlfd = -1; + cache_unlock(me->mc); + pthread_setcancelstate(cur_state, NULL); +@@ -904,15 +905,6 @@ void *expire_proc_direct(void *arg) + continue; + } + +- cache_writelock(me->mc); +- if (me->ioctlfd != -1 && +- fstat(ioctlfd, &st) != -1 && +- !count_mounts(ap->logopt, next->path, st.st_dev)) { +- ops->close(ap->logopt, ioctlfd); +- me->ioctlfd = -1; +- } +- cache_unlock(me->mc); +- + pthread_setcancelstate(cur_state, NULL); + continue; + } +@@ -1068,7 +1060,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di + map = ap->entry->maps; + while (map) { + mc = map->mc; +- cache_readlock(mc); ++ cache_writelock(mc); + me = cache_lookup_ino(mc, pkt->dev, pkt->ino); + if (me) + break; +@@ -1345,7 +1337,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + } + + mc = map->mc; +- cache_readlock(mc); ++ cache_writelock(mc); + me = cache_lookup_ino(mc, pkt->dev, pkt->ino); + if (me) + break; +@@ -1367,10 +1359,10 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + + if (me->ioctlfd != -1) { + /* Maybe someone did a manual umount, clean up ! */ +- ioctlfd = me->ioctlfd; ++ close(me->ioctlfd); + me->ioctlfd = -1; +- } else +- ops->open(ap->logopt, &ioctlfd, me->dev, me->key); ++ } ++ ops->open(ap->logopt, &ioctlfd, me->dev, me->key); + + if (ioctlfd == -1) { + cache_unlock(mc); +diff --git a/daemon/indirect.c b/daemon/indirect.c +index 2539282..bc39e63 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -428,8 +428,53 @@ void *expire_proc_indirect(void *arg) + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + if (strstr(next->opts, "indirect")) + master_notify_submount(ap, next->path, ap->state); +- pthread_setcancelstate(cur_state, NULL); ++ else if (strstr(next->opts, "offset")) { ++ struct map_source *map; ++ struct mapent_cache *mc = NULL; ++ struct mapent *me = NULL; ++ struct stat st; ++ ++ master_source_readlock(ap->entry); ++ ++ map = ap->entry->maps; ++ while (map) { ++ mc = map->mc; ++ cache_writelock(mc); ++ me = cache_lookup_distinct(mc, next->path); ++ if (me) ++ break; ++ cache_unlock(mc); ++ map = map->next; ++ } + ++ if (!mc || !me) { ++ master_source_unlock(ap->entry); ++ pthread_setcancelstate(cur_state, NULL); ++ continue; ++ } ++ ++ /* Check for manual umount */ ++ if (me->ioctlfd != -1 && ++ (fstat(me->ioctlfd, &st) == -1 || ++ !count_mounts(ap->logopt, me->key, st.st_dev))) { ++ if (is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL)) { ++ error(ap->logopt, ++ "error: possible mtab mismatch %s", ++ me->key); ++ cache_unlock(mc); ++ master_source_unlock(ap->entry); ++ pthread_setcancelstate(cur_state, NULL); ++ continue; ++ } ++ close(me->ioctlfd); ++ me->ioctlfd = -1; ++ } ++ ++ cache_unlock(mc); ++ master_source_unlock(ap->entry); ++ } ++ ++ pthread_setcancelstate(cur_state, NULL); + continue; + } + diff --git a/autofs-5.0.4-ipv6-name-and-address-support.patch b/autofs-5.0.4-ipv6-name-and-address-support.patch new file mode 100644 index 0000000..5c176cd --- /dev/null +++ b/autofs-5.0.4-ipv6-name-and-address-support.patch @@ -0,0 +1,1016 @@ +autofs-5.0.4 - ipv6 name and address support + +From: Ian Kent + +For ipv6 we need to convert all ipv4 specific function calls to ipv6 +compatible function calls and update the rpc code to deal with ipv6 +addresses. The host proximity calculation also needes to be updated. + +I'm sure this isn't completely correct yet and it will need more work +as I become more familiar with how ipv6 and subneting with it is used. +The changes so far function correctly for the current autofs +connectathon test suite maps so I hope there aren't any regressions +with current map configurations. +--- + + include/replicated.h | 2 + include/rpc_subs.h | 4 + lib/rpc_subs.c | 484 ++++++++++++++++++++++++++++++++------------------ + modules/cyrus-sasl.c | 17 +- + modules/replicated.c | 235 +++++++++++++++++------- + 5 files changed, 499 insertions(+), 243 deletions(-) + + +diff --git a/include/replicated.h b/include/replicated.h +index 88cd08a..e0133ff 100644 +--- a/include/replicated.h ++++ b/include/replicated.h +@@ -51,7 +51,7 @@ + + struct host { + char *name; +- char *addr; ++ struct sockaddr *addr; + size_t addr_len; + char *path; + unsigned int version; +diff --git a/include/rpc_subs.h b/include/rpc_subs.h +index e20a89d..87fd568 100644 +--- a/include/rpc_subs.h ++++ b/include/rpc_subs.h +@@ -46,7 +46,7 @@ + + struct conn_info { + const char *host; +- const char *addr; ++ struct sockaddr *addr; + size_t addr_len; + unsigned short port; + unsigned long program; +@@ -63,7 +63,7 @@ int rpc_udp_getclient(struct conn_info *, unsigned int, unsigned int); + void rpc_destroy_udp_client(struct conn_info *); + int rpc_tcp_getclient(struct conn_info *, unsigned int, unsigned int); + void rpc_destroy_tcp_client(struct conn_info *); +-int rpc_portmap_getclient(struct conn_info *, const char *, const char *, size_t, const char *, unsigned int); ++int rpc_portmap_getclient(struct conn_info *, const char *, struct sockaddr *, size_t, const char *, unsigned int); + unsigned short rpc_portmap_getport(struct conn_info *, struct pmap *); + int rpc_ping_proto(struct conn_info *); + int rpc_ping(const char *, long, long, unsigned int); +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 7b347a7..a822f1f 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -17,10 +17,11 @@ + #define _GNU_SOURCE + #endif + ++#include "config.h" ++ + #include + #include + #include +- + #include + #include + #include +@@ -54,145 +55,76 @@ + + inline void dump_core(void); + +-/* +- * Create a UDP RPC client +- */ +-static CLIENT *create_udp_client(struct conn_info *info) ++static CLIENT *rpc_clntudp_create(struct sockaddr *addr, struct conn_info *info, int *fd) + { +- int fd, ret, ghn_errno; +- CLIENT *client; +- struct sockaddr_in laddr, raddr; +- struct hostent hp; +- struct hostent *php = &hp; +- struct hostent *result; +- char buf[HOST_ENT_BUF_SIZE]; +- size_t len; +- +- if (info->proto->p_proto != IPPROTO_UDP) +- return NULL; +- +- if (info->client) { +- if (!clnt_control(info->client, CLGET_FD, (char *) &fd)) { +- fd = -1; +- clnt_destroy(info->client); +- info->client = NULL; +- } else { +- clnt_control(info->client, CLSET_FD_NCLOSE, NULL); +- clnt_destroy(info->client); +- } +- } +- +- memset(&laddr, 0, sizeof(laddr)); +- memset(&raddr, 0, sizeof(raddr)); +- +- raddr.sin_family = AF_INET; +- if (info->addr) { +- memcpy(&raddr.sin_addr.s_addr, info->addr, info->addr_len); +- goto got_addr; +- } +- +- if (inet_aton(info->host, &raddr.sin_addr)) +- goto got_addr; +- +- memset(&hp, 0, sizeof(struct hostent)); +- +- ret = gethostbyname_r(info->host, php, +- buf, HOST_ENT_BUF_SIZE, &result, &ghn_errno); +- if (ret || !result) { +- int err = ghn_errno == -1 ? errno : ghn_errno; +- char *estr = strerror_r(err, buf, HOST_ENT_BUF_SIZE); +- logerr("hostname lookup failed: %s", estr); +- goto out_close; +- } +- memcpy(&raddr.sin_addr.s_addr, php->h_addr, php->h_length); +- +-got_addr: +- raddr.sin_port = htons(info->port); +- +- if (!info->client) { +- /* +- * bind to any unused port. If we left this up to the rpc +- * layer, it would bind to a reserved port, which has been shown +- * to exhaust the reserved port range in some situations. +- */ +- fd = open_sock(PF_INET, SOCK_DGRAM, IPPROTO_UDP); +- if (fd < 0) +- return NULL; +- +- laddr.sin_family = AF_INET; +- laddr.sin_port = 0; +- laddr.sin_addr.s_addr = htonl(INADDR_ANY); +- +- len = sizeof(struct sockaddr_in); +- if (bind(fd, (struct sockaddr *)&laddr, len) < 0) { +- close(fd); +- fd = RPC_ANYSOCK; +- /* FALLTHROUGH */ +- } +- } +- +- client = clntudp_bufcreate(&raddr, +- info->program, info->version, +- info->timeout, &fd, +- info->send_sz, info->recv_sz); ++ struct sockaddr_in *in4_raddr; ++ struct sockaddr_in6 *in6_raddr; ++ CLIENT *client = NULL; ++ ++ switch (addr->sa_family) { ++ case AF_INET: ++ in4_raddr = (struct sockaddr_in *) addr; ++ in4_raddr->sin_port = htons(info->port); ++ client = clntudp_bufcreate(in4_raddr, ++ info->program, info->version, ++ info->timeout, fd, ++ info->send_sz, info->recv_sz); ++ break; + +- if (!client) { +- info->client = NULL; +- goto out_close; +- } ++ case AF_INET6: ++#ifndef INET6 ++ /* Quiet compile warning */ ++ in6_raddr = NULL; ++#else ++ in6_raddr = (struct sockaddr_in6 *) addr; ++ in6_raddr->sin6_port = htons(info->port); ++ client = clntudp6_bufcreate(in6_raddr, ++ info->program, info->version, ++ info->timeout, fd, ++ info->send_sz, info->recv_sz); ++#endif ++ break; + +- /* Close socket fd on destroy, as is default for rpcowned fds */ +- if (!clnt_control(client, CLSET_FD_CLOSE, NULL)) { +- clnt_destroy(client); +- info->client = NULL; +- goto out_close; ++ default: ++ break; + } + + return client; +- +-out_close: +- if (fd != -1) +- close(fd); +- return NULL; + } + +-int rpc_udp_getclient(struct conn_info *info, +- unsigned int program, unsigned int version) ++static CLIENT *rpc_clnttcp_create(struct sockaddr *addr, struct conn_info *info, int *fd) + { +- struct protoent *pe_proto; +- CLIENT *client; ++ struct sockaddr_in *in4_raddr; ++ struct sockaddr_in6 *in6_raddr; ++ CLIENT *client = NULL; ++ ++ switch (addr->sa_family) { ++ case AF_INET: ++ in4_raddr = (struct sockaddr_in *) addr; ++ in4_raddr->sin_port = htons(info->port); ++ client = clnttcp_create(in4_raddr, ++ info->program, info->version, fd, ++ info->send_sz, info->recv_sz); ++ break; + +- if (!info->client) { +- pe_proto = getprotobyname("udp"); +- if (!pe_proto) +- return 0; ++ case AF_INET6: ++#ifndef INET6 ++ /* Quiet compile warning */ ++ in6_raddr = NULL; ++#else ++ in6_raddr = (struct sockaddr_in6 *) addr; ++ in6_raddr->sin6_port = htons(info->port); ++ client = clnttcp6_create(in6_raddr, ++ info->program, info->version, fd, ++ info->send_sz, info->recv_sz); ++#endif ++ break; + +- info->proto = pe_proto; +- info->send_sz = UDPMSGSIZE; +- info->recv_sz = UDPMSGSIZE; ++ default: ++ break; + } + +- info->program = program; +- info->version = version; +- +- client = create_udp_client(info); +- +- if (!client) +- return 0; +- +- info->client = client; +- +- return 1; +-} +- +-void rpc_destroy_udp_client(struct conn_info *info) +-{ +- if (!info->client) +- return; +- +- clnt_destroy(info->client); +- info->client = NULL; +- return; ++ return client; + } + + /* +@@ -201,12 +133,11 @@ void rpc_destroy_udp_client(struct conn_info *info) + * The input struct timeval always has tv_nsec set to zero, + * we only ever use tv_sec for timeouts. + */ +-static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout) ++static int connect_nb(int fd, struct sockaddr *addr, socklen_t len, struct timeval *tout) + { + struct pollfd pfd[1]; + int timeout = tout->tv_sec; + int flags, ret; +- socklen_t len; + + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) +@@ -221,8 +152,7 @@ static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout) + * we set ret = -errno to capture it in case we decide to + * use it later. + */ +- len = sizeof(struct sockaddr); +- ret = connect(fd, (struct sockaddr *)addr, len); ++ ret = connect(fd, addr, len); + if (ret < 0 && errno != EINPROGRESS) { + ret = -errno; + goto done; +@@ -277,26 +207,241 @@ done: + return ret; + } + ++static CLIENT *rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, int *fd) ++{ ++ CLIENT *client = NULL; ++ struct sockaddr *laddr; ++ struct sockaddr_in in4_laddr; ++ struct sockaddr_in6 in6_laddr; ++ int type, proto; ++ socklen_t slen; ++ ++ proto = info->proto->p_proto; ++ if (proto == IPPROTO_UDP) ++ type = SOCK_DGRAM; ++ else ++ type = SOCK_STREAM; ++ ++ /* ++ * bind to any unused port. If we left this up to the rpc ++ * layer, it would bind to a reserved port, which has been shown ++ * to exhaust the reserved port range in some situations. ++ */ ++ switch (addr->sa_family) { ++ case AF_INET: ++ in4_laddr.sin_family = AF_INET; ++ in4_laddr.sin_port = htons(0); ++ in4_laddr.sin_addr.s_addr = htonl(INADDR_ANY); ++ slen = sizeof(struct sockaddr_in); ++ laddr = (struct sockaddr *) &in4_laddr; ++ break; ++ ++ case AF_INET6: ++#ifndef INET6 ++ /* Quiet compiler */ ++ in6_laddr.sin6_family = AF_INET6; ++ return NULL; ++#else ++ in6_laddr.sin6_family = AF_INET6; ++ in6_laddr.sin6_port = htons(0); ++ in6_laddr.sin6_addr = in6addr_any; ++ slen = sizeof(struct sockaddr_in6); ++ laddr = (struct sockaddr *) &in6_laddr; ++ break; ++#endif ++ default: ++ return NULL; ++ } ++ ++ if (!info->client) { ++ *fd = open_sock(addr->sa_family, type, proto); ++ if (*fd < 0) ++ return NULL; ++ ++ if (bind(*fd, laddr, slen) < 0) { ++ close(*fd); ++ return NULL; ++ } ++ } ++ ++ switch (info->proto->p_proto) { ++ case IPPROTO_UDP: ++ if (!info->client) { ++ *fd = open_sock(addr->sa_family, type, proto); ++ if (*fd < 0) ++ return NULL; ++ ++ if (bind(*fd, laddr, slen) < 0) { ++ close(*fd); ++ return NULL; ++ } ++ } ++ client = rpc_clntudp_create(addr, info, fd); ++ break; ++ ++ case IPPROTO_TCP: ++ if (!info->client) { ++ *fd = open_sock(addr->sa_family, type, proto); ++ if (*fd < 0) ++ return NULL; ++ ++ if (connect_nb(*fd, laddr, slen, &info->timeout) < 0) { ++ close(*fd); ++ return NULL; ++ } ++ } ++ client = rpc_clnttcp_create(addr, info, fd); ++ break; ++ ++ default: ++ break; ++ } ++ ++ return client; ++} ++ ++/* ++ * Create a UDP RPC client ++ */ ++static CLIENT *create_udp_client(struct conn_info *info) ++{ ++ CLIENT *client = NULL; ++ struct addrinfo *ai, *haddr; ++ struct addrinfo hints; ++ int fd, ret; ++ ++ if (info->proto->p_proto != IPPROTO_UDP) ++ return NULL; ++ ++ fd = RPC_ANYSOCK; ++ ++ if (info->client) { ++ if (!clnt_control(info->client, CLGET_FD, (char *) &fd)) { ++ fd = RPC_ANYSOCK; ++ clnt_destroy(info->client); ++ info->client = NULL; ++ } else { ++ clnt_control(info->client, CLSET_FD_NCLOSE, NULL); ++ clnt_destroy(info->client); ++ } ++ } ++ ++ if (info->addr) { ++ client = rpc_do_create_client(info->addr, info, &fd); ++ if (client) ++ goto done; ++ ++ if (!info->client) { ++ close(fd); ++ fd = RPC_ANYSOCK; ++ } ++ } ++ ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_flags = AI_ADDRCONFIG; ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_DGRAM; ++ ++ ret = getaddrinfo(info->host, NULL, &hints, &ai); ++ if (ret) { ++ error(LOGOPT_ANY, ++ "hostname lookup failed: %s", gai_strerror(ret)); ++ goto out_close; ++ } ++ ++ haddr = ai; ++ while (haddr) { ++ client = rpc_do_create_client(haddr->ai_addr, info, &fd); ++ if (client) ++ break; ++ ++ if (!info->client) { ++ close(fd); ++ fd = RPC_ANYSOCK; ++ } ++ ++ haddr = haddr->ai_next; ++ } ++ ++ freeaddrinfo(ai); ++ ++ if (!client) { ++ info->client = NULL; ++ goto out_close; ++ } ++done: ++ /* Close socket fd on destroy, as is default for rpcowned fds */ ++ if (!clnt_control(client, CLSET_FD_CLOSE, NULL)) { ++ clnt_destroy(client); ++ info->client = NULL; ++ goto out_close; ++ } ++ ++ return client; ++ ++out_close: ++ if (fd != -1) ++ close(fd); ++ return NULL; ++} ++ ++int rpc_udp_getclient(struct conn_info *info, ++ unsigned int program, unsigned int version) ++{ ++ struct protoent *pe_proto; ++ CLIENT *client; ++ ++ if (!info->client) { ++ pe_proto = getprotobyname("udp"); ++ if (!pe_proto) ++ return 0; ++ ++ info->proto = pe_proto; ++ info->send_sz = UDPMSGSIZE; ++ info->recv_sz = UDPMSGSIZE; ++ } ++ ++ info->program = program; ++ info->version = version; ++ ++ client = create_udp_client(info); ++ ++ if (!client) ++ return 0; ++ ++ info->client = client; ++ ++ return 1; ++} ++ ++void rpc_destroy_udp_client(struct conn_info *info) ++{ ++ if (!info->client) ++ return; ++ ++ clnt_destroy(info->client); ++ info->client = NULL; ++ return; ++} ++ + /* + * Create a TCP RPC client using non-blocking connect + */ + static CLIENT *create_tcp_client(struct conn_info *info) + { +- int fd, ghn_errno; +- CLIENT *client; +- struct sockaddr_in addr; +- struct hostent hp; +- struct hostent *php = &hp; +- struct hostent *result; +- char buf[HOST_ENT_BUF_SIZE]; +- int ret; ++ CLIENT *client = NULL; ++ struct addrinfo *ai, *haddr; ++ struct addrinfo hints; ++ int fd, ret; + + if (info->proto->p_proto != IPPROTO_TCP) + return NULL; + ++ fd = RPC_ANYSOCK; ++ + if (info->client) { + if (!clnt_control(info->client, CLGET_FD, (char *) &fd)) { +- fd = -1; ++ fd = RPC_ANYSOCK; + clnt_destroy(info->client); + info->client = NULL; + } else { +@@ -305,51 +450,50 @@ static CLIENT *create_tcp_client(struct conn_info *info) + } + } + +- memset(&addr, 0, sizeof(addr)); +- +- addr.sin_family = AF_INET; + if (info->addr) { +- memcpy(&addr.sin_addr.s_addr, info->addr, info->addr_len); +- goto got_addr; +- } ++ client = rpc_do_create_client(info->addr, info, &fd); ++ if (client) ++ goto done; + +- if (inet_aton(info->host, &addr.sin_addr)) +- goto got_addr; ++ if (!info->client) { ++ close(fd); ++ fd = RPC_ANYSOCK; ++ } ++ } + +- memset(&hp, 0, sizeof(struct hostent)); ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_flags = AI_ADDRCONFIG; ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_STREAM; + +- ret = gethostbyname_r(info->host, php, +- buf, HOST_ENT_BUF_SIZE, &result, &ghn_errno); +- if (ret || !result) { +- int err = ghn_errno == -1 ? errno : ghn_errno; +- char *estr = strerror_r(err, buf, HOST_ENT_BUF_SIZE); +- logerr("hostname lookup failed: %s", estr); ++ ret = getaddrinfo(info->host, NULL, &hints, &ai); ++ if (ret) { ++ error(LOGOPT_ANY, ++ "hostname lookup failed: %s", gai_strerror(ret)); + goto out_close; + } +- memcpy(&addr.sin_addr.s_addr, php->h_addr, php->h_length); + +-got_addr: +- addr.sin_port = htons(info->port); ++ haddr = ai; ++ while (haddr) { ++ client = rpc_do_create_client(haddr->ai_addr, info, &fd); ++ if (client) ++ break; + +- if (!info->client) { +- fd = open_sock(PF_INET, SOCK_STREAM, info->proto->p_proto); +- if (fd < 0) +- return NULL; ++ if (!info->client) { ++ close(fd); ++ fd = RPC_ANYSOCK; ++ } + +- ret = connect_nb(fd, &addr, &info->timeout); +- if (ret < 0) +- goto out_close; ++ haddr = haddr->ai_next; + } + +- client = clnttcp_create(&addr, +- info->program, info->version, &fd, +- info->send_sz, info->recv_sz); ++ freeaddrinfo(ai); + + if (!client) { + info->client = NULL; + goto out_close; + } +- ++done: + /* Close socket fd on destroy, as is default for rpcowned fds */ + if (!clnt_control(client, CLSET_FD_CLOSE, NULL)) { + clnt_destroy(client); +@@ -420,7 +564,7 @@ void rpc_destroy_tcp_client(struct conn_info *info) + } + + int rpc_portmap_getclient(struct conn_info *info, +- const char *host, const char *addr, size_t addr_len, ++ const char *host, struct sockaddr *addr, size_t addr_len, + const char *proto, unsigned int option) + { + struct protoent *pe_proto; +diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c +index 286af15..ec2ab0c 100644 +--- a/modules/cyrus-sasl.c ++++ b/modules/cyrus-sasl.c +@@ -732,16 +732,25 @@ sasl_bind_mech(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const c + debug(logopt, "Attempting sasl bind with mechanism %s", mech); + + result = ldap_get_option(ldap, LDAP_OPT_HOST_NAME, &host); +- if (result != LDAP_SUCCESS || !host) { ++ if (result != LDAP_OPT_SUCCESS || !host) { + debug(logopt, "failed to get hostname for connection"); + return NULL; + } + +- if ((tmp = strchr(host, ':'))) +- *tmp = '\0'; ++ if ((tmp = strrchr(host, ':'))) { ++ if (*(tmp - 1) != ']') { ++ *tmp = '\0'; ++ tmp = host; ++ } else { ++ *(tmp - 1) = '\0'; ++ tmp = host; ++ if (*tmp == '[') ++ tmp++; ++ } ++ } + + /* Create a new authentication context for the service. */ +- result = sasl_client_new("ldap", host, NULL, NULL, NULL, 0, &conn); ++ result = sasl_client_new("ldap", tmp, NULL, NULL, NULL, 0, &conn); + if (result != SASL_OK) { + error(logopt, "sasl_client_new failed with error %d", + result); +diff --git a/modules/replicated.c b/modules/replicated.c +index 835af97..9e85c00 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -45,7 +45,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +@@ -75,6 +75,20 @@ static int volatile ifc_last_len = 0; + #define max(x, y) (x >= y ? x : y) + #define mmax(x, y, z) (max(x, y) == x ? max(x, z) : max(y, z)) + ++unsigned int ipv6_mask_cmp(uint32_t *host, uint32_t *iface, uint32_t *mask) ++{ ++ unsigned int ret = 1; ++ unsigned int i; ++ ++ for (i = 0; i < 4; i++) { ++ if ((host[i] & mask[i]) != (iface[i] & mask[i])) { ++ ret = 0; ++ break; ++ } ++ } ++ return ret; ++} ++ + void seed_random(void) + { + int fd; +@@ -136,20 +150,49 @@ static int alloc_ifreq(struct ifconf *ifc, int sock) + return 1; + } + +-static unsigned int get_proximity(const char *host_addr, int addr_len) ++static unsigned int get_proximity(struct sockaddr *host_addr) + { +- struct sockaddr_in *msk_addr, *if_addr; ++ struct sockaddr_in *addr, *msk_addr, *if_addr; ++ struct sockaddr_in6 *addr6, *msk6_addr, *if6_addr; + struct in_addr *hst_addr; +- char tmp[20], buf[MAX_ERR_BUF], *ptr; ++ struct in6_addr *hst6_addr; ++ int addr_len; ++ char buf[MAX_ERR_BUF], *ptr; + struct ifconf ifc; + struct ifreq *ifr, nmptr; + int sock, ret, i; +- uint32_t mask, ha, ia; ++ uint32_t mask, ha, ia, *mask6, *ha6, *ia6; ++ ++ addr = NULL; ++ addr6 = NULL; ++ hst_addr = NULL; ++ hst6_addr = NULL; ++ mask6 = NULL; ++ ha6 = NULL; ++ ia6 = NULL; ++ ++ switch (host_addr->sa_family) { ++ case AF_INET: ++ addr = (struct sockaddr_in *) host_addr; ++ hst_addr = (struct in_addr *) &addr->sin_addr; ++ ha = ntohl((uint32_t) hst_addr->s_addr); ++ addr_len = sizeof(hst_addr); ++ break; + +- memcpy(tmp, host_addr, addr_len); +- hst_addr = (struct in_addr *) tmp; ++ case AF_INET6: ++#ifndef INET6 ++ return PROXIMITY_ERROR; ++#else ++ addr6 = (struct sockaddr_in6 *) host_addr; ++ hst6_addr = (struct in6_addr *) &addr6->sin6_addr; ++ ha6 = &hst6_addr->s6_addr32[0]; ++ addr_len = sizeof(hst6_addr); ++ break; ++#endif + +- ha = ntohl((uint32_t) hst_addr->s_addr); ++ default: ++ return PROXIMITY_ERROR; ++ } + + sock = open_sock(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { +@@ -174,6 +217,10 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) + + switch (ifr->ifr_addr.sa_family) { + case AF_INET: ++#ifndef INET6 ++ if (host_addr->sa_family == AF_INET6) ++ break; ++#endif + if_addr = (struct sockaddr_in *) &ifr->ifr_addr; + ret = memcmp(&if_addr->sin_addr, hst_addr, addr_len); + if (!ret) { +@@ -183,6 +230,20 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) + } + break; + ++ case AF_INET6: ++#ifndef INET6 ++ if (host_addr->sa_family == AF_INET) ++ break; ++ ++ if6_addr = (struct sockaddr_in6 *) &ifr->ifr_addr; ++ ret = memcmp(&if6_addr->sin6_addr, hst6_addr, addr_len); ++ if (!ret) { ++ close(sock); ++ free(ifc.ifc_req); ++ return PROXIMITY_LOCAL; ++ } ++#endif ++ + default: + break; + } +@@ -197,23 +258,27 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) + while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) { + ifr = (struct ifreq *) ptr; + ++ nmptr = *ifr; ++ ret = ioctl(sock, SIOCGIFNETMASK, &nmptr); ++ if (ret == -1) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr("ioctl: %s", estr); ++ close(sock); ++ free(ifc.ifc_req); ++ return PROXIMITY_ERROR; ++ } ++ + switch (ifr->ifr_addr.sa_family) { + case AF_INET: ++#ifndef INET6 ++ if (host_addr->sa_family == AF_INET6) ++ break; ++#endif + if_addr = (struct sockaddr_in *) &ifr->ifr_addr; + ia = ntohl((uint32_t) if_addr->sin_addr.s_addr); + + /* Is the address within a localiy attached subnet */ + +- nmptr = *ifr; +- ret = ioctl(sock, SIOCGIFNETMASK, &nmptr); +- if (ret == -1) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr("ioctl: %s", estr); +- close(sock); +- free(ifc.ifc_req); +- return PROXIMITY_ERROR; +- } +- + msk_addr = (struct sockaddr_in *) &nmptr.ifr_netmask; + mask = ntohl((uint32_t) msk_addr->sin_addr.s_addr); + +@@ -247,6 +312,29 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) + } + break; + ++ case AF_INET6: ++#ifndef INET6 ++ if (host_addr->sa_family == AF_INET) ++ break; ++ ++ if6_addr = (struct sockaddr_in6 *) &ifr->ifr_addr; ++ ia6 = &if6_addr->sin6_addr.s6_addr32[0]; ++ ++ /* Is the address within the network of the interface */ ++ ++ msk6_addr = (struct sockaddr_in6 *) &nmptr.ifr_netmask; ++ mask6 = &msk6_addr->sin6_addr.s6_addr32[0]; ++ ++ if (ipv6_mask_cmp(ha6, ia6, mask6)) { ++ close(sock); ++ free(ifc.ifc_req); ++ return PROXIMITY_SUBNET; ++ } ++ ++ /* How do we define "local network" in ipv6? */ ++#endif ++ break; ++ + default: + break; + } +@@ -262,11 +350,12 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) + } + + static struct host *new_host(const char *name, +- const char *addr, size_t addr_len, ++ struct sockaddr *addr, size_t addr_len, + unsigned int proximity, unsigned int weight) + { + struct host *new; +- char *tmp1, *tmp2; ++ struct sockaddr *tmp2; ++ char *tmp1; + + if (!name || !addr) + return NULL; +@@ -950,65 +1039,78 @@ int prune_host_list(unsigned logopt, struct host **list, + return 1; + } + +-static int add_host_addrs(struct host **list, const char *host, unsigned int weight) ++static int add_new_host(struct host **list, ++ const char *host, unsigned int weight, ++ struct addrinfo *host_addr) + { +- struct hostent he; +- struct hostent *phe = &he; +- struct hostent *result; +- struct sockaddr_in saddr; +- char buf[MAX_IFC_BUF], **haddr; +- int ghn_errno, ret; + struct host *new; + unsigned int prx; ++ int addr_len; + +- saddr.sin_family = AF_INET; +- if (inet_aton(host, &saddr.sin_addr)) { +- const char *thost = (const char *) &saddr.sin_addr; +- +- prx = get_proximity(thost, sizeof(saddr.sin_addr)); +- if (prx == PROXIMITY_ERROR) +- return 0; +- +- if (!(new = new_host(host, thost, sizeof(saddr.sin_addr), prx, weight))) +- return 0; +- +- if (!add_host(list, new)) +- free_host(new); +- +- return 1; +- } ++ prx = get_proximity(host_addr->ai_addr); ++ if (prx == PROXIMITY_ERROR) ++ return 0; + +- memset(buf, 0, MAX_IFC_BUF); +- memset(&he, 0, sizeof(struct hostent)); ++ addr_len = sizeof(struct sockaddr); ++ new = new_host(host, host_addr->ai_addr, addr_len, prx, weight); ++ if (!new) ++ return 0; + +- ret = gethostbyname_r(host, phe, +- buf, MAX_IFC_BUF, &result, &ghn_errno); +- if (ret || !result) { +- if (ghn_errno == -1) +- logmsg("host %s: lookup failure %d", host, errno); +- else +- logmsg("host %s: lookup failure %d", host, ghn_errno); ++ if (!add_host(list, new)) { ++ free_host(new); + return 0; + } + +- for (haddr = phe->h_addr_list; *haddr; haddr++) { +- struct in_addr tt; ++ return 1; ++} + +- prx = get_proximity(*haddr, phe->h_length); +- if (prx == PROXIMITY_ERROR) +- return 0; ++static int add_host_addrs(struct host **list, const char *host, unsigned int weight) ++{ ++ struct addrinfo hints, *ni, *this; ++ int ret; + +- memcpy(&tt, *haddr, sizeof(struct in_addr)); +- if (!(new = new_host(host, *haddr, phe->h_length, prx, weight))) +- return 0; ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_flags = AI_NUMERICHOST; ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_DGRAM; + +- if (!add_host(list, new)) { +- free_host(new); +- continue; +- } ++ ret = getaddrinfo(host, NULL, &hints, &ni); ++ if (ret) ++ goto try_name; ++ ++ this = ni; ++ while (this) { ++ ret = add_new_host(list, host, weight, this); ++ if (!ret) ++ break; ++ this = this->ai_next; ++ } ++ freeaddrinfo(ni); ++ goto done; ++ ++try_name: ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_flags = AI_ADDRCONFIG; ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_DGRAM; ++ ++ ret = getaddrinfo(host, NULL, &hints, &ni); ++ if (ret) { ++ error(LOGOPT_ANY, "hostname lookup failed: %s", ++ gai_strerror(ret)); ++ return 0; + } + +- return 1; ++ this = ni; ++ while (this) { ++ ret = add_new_host(list, host, weight, this); ++ if (!ret) ++ break; ++ this = this->ai_next; ++ } ++ freeaddrinfo(ni); ++done: ++ return ret; + } + + static int add_path(struct host *hosts, const char *path, int len) +@@ -1057,7 +1159,8 @@ static int add_local_path(struct host **hosts, const char *path) + new->path = tmp; + new->proximity = PROXIMITY_LOCAL; + new->version = NFS_VERS_MASK; +- new->name = new->addr = NULL; ++ new->name = NULL; ++ new->addr = NULL; + new->weight = new->cost = 0; + + add_host(hosts, new); diff --git a/autofs-5.0.4-ipv6-parse.patch b/autofs-5.0.4-ipv6-parse.patch new file mode 100644 index 0000000..cd60ce9 --- /dev/null +++ b/autofs-5.0.4-ipv6-parse.patch @@ -0,0 +1,467 @@ +autofs-5.0.4 - ipv6 parse + +From: Ian Kent + +Since ipv6 addresses use a colon separator and we use the colon quite a +bit as a delimiting character we need to distinguish between when the +colon is the delimeter we are looking for and when it is part of an ipv6 +address. Since there is widespread use of "[" and "]" to provide the +ability to separate a port specification from an ipv6 address this +convention has also been used in autofs. +--- + + include/parse_subs.h | 8 ++++ + lib/master_tok.l | 10 +++-- + lib/parse_subs.c | 99 +++++++++++++++++++++++++++++++++++++++++++++--- + modules/lookup_file.c | 40 +++++++------------ + modules/lookup_ldap.c | 21 +++++++++- + modules/mount_autofs.c | 29 ++++++-------- + modules/parse_sun.c | 16 +++++--- + modules/replicated.c | 26 ++++++++++++- + 8 files changed, 186 insertions(+), 63 deletions(-) + + +diff --git a/include/parse_subs.h b/include/parse_subs.h +index 643ad68..ecc712d 100644 +--- a/include/parse_subs.h ++++ b/include/parse_subs.h +@@ -20,6 +20,12 @@ + + struct mapent; + ++struct map_type_info { ++ char *type; ++ char *format; ++ char *map; ++}; ++ + const char *skipspace(const char *); + int check_colon(const char *); + int chunklen(const char *, int); +@@ -27,5 +33,7 @@ int strmcmp(const char *, const char *, int); + char *dequote(const char *, int, unsigned int); + int span_space(const char *, unsigned int); + char *sanitize_path(const char *, int, unsigned int, unsigned int); ++void free_map_type_info(struct map_type_info *); ++struct map_type_info *parse_map_type_info(const char *); + + #endif +diff --git a/lib/master_tok.l b/lib/master_tok.l +index 801aa6f..b6cc8be 100644 +--- a/lib/master_tok.l ++++ b/lib/master_tok.l +@@ -96,10 +96,12 @@ SLASHIFYSTR (--(no-)?slashify-colons) + NUMBER [0-9]+ + + DNSERVSTR1 ([[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?:) +-DNSERVSTR2 (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/) +-DNSERVSTR3 (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:) +-DNSERVSTR4 (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/) +-DNSERVERSTR ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4}) ++DNSERVSTR2 (\[([[:xdigit:]]:.)+\](:[0-9]+)?:) ++DNSERVSTR3 (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/) ++DNSERVSTR4 (\/\/\[([[:xdigit:]]:.)+\](:[0-9]+)?\/) ++DNSERVSTR5 (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:) ++DNSERVSTR6 (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/) ++DNSERVERSTR ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4}|{DNSERVSTR5}|{DNSERVSTR6}) + + AT_CN ([cC][[nN]) + AT_NMN ([nN][iI][sS][Mm][aA][pP][Nn][aA][mM][eE]) +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index 8a032e8..0cba95a 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -56,14 +56,13 @@ int check_colon(const char *str) + char *ptr = (char *) str; + + /* Colon escape */ +- if (*ptr == ':') ++ if (!strncmp(ptr, ":/", 2)) + return 1; + +- while (*ptr && *ptr != ':' && *ptr != '/') { ++ while (*ptr && strncmp(ptr, ":/", 2)) + ptr++; +- } + +- if (!*ptr || *ptr == '/') ++ if (!*ptr) + return 0; + + return 1; +@@ -93,12 +92,12 @@ int chunklen(const char *whence, int expect_colon) + n++; + if (*str == '"') + break; +- if (*str == ':') ++ if (!strncmp(str, ":/", 2)) + expect_colon = 0; + } + break; + case ':': +- if (expect_colon) ++ if (expect_colon && !strncmp(str, ":/", 2)) + expect_colon = 0; + continue; + case ' ': +@@ -300,3 +299,91 @@ char *sanitize_path(const char *path, int origlen, unsigned int type, unsigned i + return s_path; + } + ++void free_map_type_info(struct map_type_info *info) ++{ ++ if (info->type) ++ free(info->type); ++ if (info->format) ++ free(info->format); ++ if (info->map) ++ free(info->map); ++ free(info); ++ return; ++} ++ ++struct map_type_info *parse_map_type_info(const char *str) ++{ ++ struct map_type_info *info; ++ char *buf, *type, *fmt, *map, *tmp; ++ ++ buf = strdup(str); ++ if (!buf) ++ return NULL; ++ ++ info = malloc(sizeof(struct map_type_info)); ++ if (!info) { ++ free(buf); ++ return NULL; ++ } ++ memset(info, 0, sizeof(struct map_type_info)); ++ ++ type = fmt = NULL; ++ ++ /* Look for space terminator - ignore local options */ ++ map = buf; ++ for (tmp = buf; *tmp; tmp++) { ++ if (*tmp == ' ') { ++ *tmp = '\0'; ++ break; ++ } else if (*tmp == ',') { ++ type = buf; ++ *tmp++ = '\0'; ++ fmt = tmp; ++ } else if (*tmp == ':') { ++ if (!fmt) ++ type = buf; ++ *tmp++ = '\0'; ++ map = tmp; ++ } else if (*tmp == '[') { ++ /* ++ * Unescaped '[' is a syntax error here as only ++ * an ldap map with a type specified should contain ++ * them. ++ */ ++ free(buf); ++ return 0; ++ } ++ if (*tmp == '\\') ++ tmp++; ++ } ++ ++ if (type) { ++ info->type = strdup(type); ++ if (!info->type) { ++ free(buf); ++ free_map_type_info(info); ++ return NULL; ++ } ++ } ++ ++ if (fmt) { ++ info->format = strdup(fmt); ++ if (!info->format) { ++ free(buf); ++ free_map_type_info(info); ++ return NULL; ++ } ++ } ++ ++ info->map = strdup(map); ++ if (!info->map) { ++ free(buf); ++ free_map_type_info(info); ++ return NULL; ++ } ++ ++ free(buf); ++ ++ return info; ++} ++ +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index ba80f2a..ec78090 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -523,10 +523,10 @@ prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned in + { + struct map_source *current; + struct map_source *source; +- char *type, *map, *fmt; ++ struct map_type_info *info; + const char *argv[2]; + int argc; +- char *buf, *tmp; ++ char *buf; + + current = ap->entry->current; + ap->entry->current = NULL; +@@ -548,33 +548,19 @@ prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned in + return NULL; + } + +- type = fmt = NULL; +- +- /* Look for space terminator - ignore local options */ +- map = buf; +- for (tmp = buf; *tmp; tmp++) { +- if (*tmp == ' ') { +- *tmp = '\0'; +- break; +- } else if (*tmp == ',') { +- type = buf; +- *tmp++ = '\0'; +- fmt = tmp; +- } else if (*tmp == ':') { +- if (!fmt) +- type = buf; +- *tmp++ = '\0'; +- map = tmp; +- } +- if (*tmp == '\\') +- tmp++; ++ if (!(info = parse_map_type_info(buf))) { ++ error(ap->logopt, MODPREFIX "failed to parse map info"); ++ free(buf); ++ return NULL; + } + + argc = 1; +- argv[0] = map; ++ argv[0] = info->map; + argv[1] = NULL; + +- source = master_find_source_instance(current, type, fmt, argc, argv); ++ source = master_find_source_instance(current, ++ info->type, info->format, ++ argc, argv); + if (source) + /* + * Make sure included map age is in sync with its owner +@@ -582,8 +568,11 @@ prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned in + */ + source->age = age; + else { +- source = master_add_source_instance(current, type, fmt, age, argc, argv); ++ source = master_add_source_instance(current, ++ info->type, info->format, ++ age, argc, argv); + if (!source) { ++ free_map_type_info(info); + free(buf); + error(ap->logopt, "failed to add included map instance"); + return NULL; +@@ -594,6 +583,7 @@ prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned in + if (inc) + source->recurse = 1; + ++ free_map_type_info(info); + free(buf); + + return source; +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 094cbdc..7845bcf 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -1119,11 +1119,26 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c + memcpy(ctxt->server, s, l); + */ + } +- } else if (strchr(ptr, ':') != NULL) { +- char *q = NULL; ++ } else if (strchr(ptr, ':') != NULL || *ptr == '[') { ++ const char *q = NULL; + + /* Isolate the server. Include the port spec */ +- q = strchr(ptr, ':'); ++ if (*ptr != '[') ++ q = strchr(ptr, ':'); ++ else { ++ q = ++ptr; ++ while (*q == ':' || isxdigit(*q)) ++ q++; ++ if (*q != ']') { ++ crit(logopt, MODPREFIX ++ "invalid LDAP map syntax %s", ptr); ++ return 0; ++ } ++ q++; ++ if (*q == ':') ++ q++; ++ } ++ + if (isdigit(*q)) + while (isdigit(*q)) + q++; +diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c +index fab2906..14d6307 100644 +--- a/modules/mount_autofs.c ++++ b/modules/mount_autofs.c +@@ -50,7 +50,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + int argc, status, ghost = ap->flags & MOUNT_FLAG_GHOST; + time_t timeout = ap->exp_timeout; + unsigned logopt = ap->logopt; +- char *type, *format, *tmp, *tmp2; ++ struct map_type_info *info; + struct master *master; + struct master_mapent *entry; + struct map_source *source; +@@ -174,21 +174,12 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + + argc = 1; + +- type = NULL; +- format = NULL; +- +- tmp = strchr(what, ':'); +- if (tmp) { +- *tmp++ = '\0'; +- tmp2 = strchr(what, ','); +- if (tmp2) { +- *tmp2++ = '\0'; +- format = tmp2; +- } +- type = (char *) what; +- argv[0] = tmp; +- } else +- argv[0] = (char *) what; ++ if (!(info = parse_map_type_info(what))) { ++ error(ap->logopt, MODPREFIX "failed to parse map info"); ++ master_free_mapent(entry); ++ return 1; ++ } ++ argv[0] = info->map; + + if (options) { + p = options; +@@ -202,13 +193,17 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + } + argv[argc] = NULL; + +- source = master_add_map_source(entry, type, format, time(NULL), argc, argv); ++ source = master_add_map_source(entry, ++ info->type, info->format, ++ time(NULL), argc, argv); + if (!source) { + error(ap->logopt, + MODPREFIX "failed to add map source to entry"); + master_free_mapent(entry); ++ free_map_type_info(info); + return 1; + } ++ free_map_type_info(info); + + source->mc = cache_init(entry->ap, source); + if (!source->mc) { +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index ed73e46..65417e1 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -245,7 +245,9 @@ int expandsunent(const char *src, char *dst, const char *key, + *(dst++) = + (seen_colons && slashify_colons) ? '/' : ':'; + len++; +- seen_colons = 1; ++ /* Were looking for the colon preceeding a path */ ++ if (*src == '/') ++ seen_colons = 1; + break; + + default: +@@ -814,21 +816,23 @@ static int validate_location(char *loc) + return 1; + + /* +- * If a ':' is present now it must be a host name, except ++ * If a ':/' is present now it must be a host name, except + * for those special file systems like sshfs which use "#" +- * and "@" in the host name part. ++ * and "@" in the host name part and ipv6 addresses that ++ * have ":", "[" and "]". + */ + if (check_colon(ptr)) { +- while (*ptr && *ptr != ':') { ++ while (*ptr && strncmp(ptr, ":/", 2)) { + if (!(isalnum(*ptr) || + *ptr == '-' || *ptr == '.' || *ptr == '_' || + *ptr == ',' || *ptr == '(' || *ptr == ')' || +- *ptr == '#' || *ptr == '@')) ++ *ptr == '#' || *ptr == '@' || *ptr == ':' || ++ *ptr == '[' || *ptr == ']')) + return 0; + ptr++; + } + +- if (*ptr && *ptr == ':') ++ if (*ptr && !strncmp(ptr, ":/", 2)) + ptr++; + } + +diff --git a/modules/replicated.c b/modules/replicated.c +index 9e85c00..79845d0 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -1168,6 +1168,28 @@ static int add_local_path(struct host **hosts, const char *path) + return 1; + } + ++static char *seek_delim(const char *s) ++{ ++ const char *p = s; ++ char *delim; ++ ++ delim = strpbrk(p, "(, \t:"); ++ if (delim && *delim != ':') ++ return delim; ++ ++ while (*p) { ++ if (*p != ':') { ++ p++; ++ continue; ++ } ++ if (!strncmp(p, ":/", 2)) ++ return (char *) p; ++ p++; ++ } ++ ++ return NULL; ++} ++ + int parse_location(unsigned logopt, struct host **hosts, const char *list) + { + char *str, *p, *delim; +@@ -1187,7 +1209,7 @@ int parse_location(unsigned logopt, struct host **hosts, const char *list) + int weight = 0; + + p += strspn(p, " \t,"); +- delim = strpbrk(p, "(, \t:"); ++ delim = seek_delim(p); + + if (delim) { + if (*delim == '(') { +@@ -1211,7 +1233,7 @@ int parse_location(unsigned logopt, struct host **hosts, const char *list) + + /* Oh boy - might have spaces in the path */ + next = path; +- while (*next && *next != ':') ++ while (*next && strncmp(next, ":/", 2)) + next++; + + /* No spaces in host names at least */ diff --git a/autofs-5.0.4-library-reload-fix-update-fix-2.patch b/autofs-5.0.4-library-reload-fix-update-fix-2.patch new file mode 100644 index 0000000..3075ccf --- /dev/null +++ b/autofs-5.0.4-library-reload-fix-update-fix-2.patch @@ -0,0 +1,53 @@ +autofs-5.0.4 - library reload fix update fix 2 + +From: Ian Kent + +The library reload fixes introduced a bug which causes autofs to +not release mount thread resources when using submounts. +--- + + CHANGELOG | 1 + + daemon/automount.c | 11 +++++++++-- + 2 files changed, 10 insertions(+), 2 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index f49784a..d1cc113 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -50,6 +50,7 @@ + - always read file maps multi map fix. + - always read file maps key lookup fixes. + - use srv query for domain dn. ++- fix not releasing resources when using submounts. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/automount.c b/daemon/automount.c +index 3a0fe0b..44dcdd6 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -1460,14 +1460,21 @@ static void handle_mounts_cleanup(void *arg) + master_remove_mapent(ap->entry); + master_source_unlock(ap->entry); + ++ destroy_logpri_fifo(ap); ++ ++ /* ++ * Submounts are detached threads and don't belong to the ++ * master map entry list so we need to free their resources ++ * here. ++ */ + if (submount) { + mounts_mutex_unlock(ap->parent); + master_source_unlock(ap->parent->entry); ++ master_free_mapent_sources(ap->entry, 1); ++ master_free_mapent(ap->entry); + } + master_mutex_unlock(); + +- destroy_logpri_fifo(ap); +- + if (clean) { + if (rmdir(path) == -1) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); diff --git a/autofs-5.0.4-library-reload-fix-update-fix.patch b/autofs-5.0.4-library-reload-fix-update-fix.patch new file mode 100644 index 0000000..566c1e5 --- /dev/null +++ b/autofs-5.0.4-library-reload-fix-update-fix.patch @@ -0,0 +1,82 @@ +autofs-5.0.4 - library reload fix update fix + +From: Ian Kent + +The library reload fixes introduced a bug which causes autofs to +incorrectly shutdown. Previously the signal handling thread only +recieved signals either when they were explicity sent or it was +time to shutdown so continuing on to call the signal handling +routine was the correct thing to do. Now we need to join with +the mount handling thread at exit but, in this case, we don't +want to continue on to the signal handling routine as that will +incorrectly cause the signal to be passed on to other mount +handling threads. +--- + + CHANGELOG | 1 + + daemon/automount.c | 18 ++++++++++++++++-- + lib/master.c | 2 -- + 3 files changed, 17 insertions(+), 4 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 7ca45fd..5e01812 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -44,6 +44,7 @@ + - use intr option as hosts mount default. + - fix kernel includes. + - dont umount existing direct mount on master re-read. ++- fix incorrect shutdown introduced by library relaod fixes. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/automount.c b/daemon/automount.c +index 80691fa..3a0fe0b 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -1332,8 +1332,22 @@ static void *statemachine(void *arg) + case SIGTERM: + case SIGINT: + case SIGUSR2: +- if (master_done(master_list)) +- return NULL; ++ master_mutex_lock(); ++ if (list_empty(&master_list->completed)) { ++ if (list_empty(&master_list->mounts)) { ++ master_mutex_unlock(); ++ return NULL; ++ } ++ } else { ++ if (master_done(master_list)) { ++ master_mutex_unlock(); ++ return NULL; ++ } ++ master_mutex_unlock(); ++ break; ++ } ++ master_mutex_unlock(); ++ + case SIGUSR1: + do_signals(master_list, sig); + break; +diff --git a/lib/master.c b/lib/master.c +index 762094f..e43f835 100644 +--- a/lib/master.c ++++ b/lib/master.c +@@ -1182,7 +1182,6 @@ int master_done(struct master *master) + struct master_mapent *entry; + int res = 0; + +- master_mutex_lock(); + head = &master->completed; + p = head->next; + while (p != head) { +@@ -1195,7 +1194,6 @@ int master_done(struct master *master) + } + if (list_empty(&master->mounts)) + res = 1; +- master_mutex_unlock(); + + return res; + } diff --git a/autofs-5.0.4-library-reload-fix-update.patch b/autofs-5.0.4-library-reload-fix-update.patch new file mode 100644 index 0000000..cb8df60 --- /dev/null +++ b/autofs-5.0.4-library-reload-fix-update.patch @@ -0,0 +1,352 @@ +autofs-5.0.4 - library reload fix update + +From: Ian Kent + +We still have a problem with libxml2 being unloaded before its thread +specific data destructor is called. This is due to the main thread +exiting (closing the handle we hold open to prevent this) before all +the mount handling threads have actually completed. This patch makes +the mount handling threads joinable (and joins with them as they exit) +to ensure that the mount handling threads have completed before allowing +the main thread to complete. +--- + + daemon/automount.c | 35 +++++++++++++++++++++++------------ + daemon/direct.c | 7 ++++--- + daemon/indirect.c | 7 ++++--- + daemon/state.c | 7 ++++--- + include/master.h | 3 +++ + lib/master.c | 38 ++++++++++++++++++++++++++++++++++---- + modules/mount_autofs.c | 4 ++-- + 7 files changed, 74 insertions(+), 27 deletions(-) + + +diff --git a/daemon/automount.c b/daemon/automount.c +index e120f50..f04273f 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -69,8 +69,9 @@ static size_t kpkt_len; + /* Does kernel know about SOCK_CLOEXEC and friends */ + static int cloexec_works = 0; + +-/* Attribute to create detached thread */ +-pthread_attr_t thread_attr; ++/* Attributes for creating detached and joinable threads */ ++pthread_attr_t th_attr; ++pthread_attr_t th_attr_detached; + + struct master_readmap_cond mrc = { + PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, NULL, 0, 0, 0, 0}; +@@ -1192,7 +1193,7 @@ static pthread_t do_signals(struct master *master, int sig) + if (status) + fatal(status); + +- status = pthread_create(&thid, &thread_attr, do_notify_state, &r_sig); ++ status = pthread_create(&thid, &th_attr_detached, do_notify_state, &r_sig); + if (status) { + error(master->logopt, + "mount state notify thread create failed"); +@@ -1281,7 +1282,7 @@ static int do_hup_signal(struct master *master, time_t age) + + master->reading = 1; + +- status = pthread_create(&thid, &thread_attr, do_read_master, NULL); ++ status = pthread_create(&thid, &th_attr_detached, do_read_master, NULL); + if (status) { + error(logopt, + "master read map thread create failed"); +@@ -1327,7 +1328,7 @@ static void *statemachine(void *arg) + case SIGTERM: + case SIGINT: + case SIGUSR2: +- if (master_list_empty(master_list)) ++ if (master_done(master_list)) + return NULL; + case SIGUSR1: + do_signals(master_list, sig); +@@ -1448,8 +1449,6 @@ static void handle_mounts_cleanup(void *arg) + master_mutex_unlock(); + + destroy_logpri_fifo(ap); +- master_free_mapent_sources(ap->entry, 1); +- master_free_mapent(ap->entry); + + if (clean) { + if (rmdir(path) == -1) { +@@ -1461,8 +1460,12 @@ static void handle_mounts_cleanup(void *arg) + + info(logopt, "shut down path %s", path); + +- /* If we are the last tell the state machine to shutdown */ +- if (!submount && master_list_empty(master_list)) ++ /* ++ * If we are not a submount send a signal to the signal handler ++ * so it can join with any completed handle_mounts() threads and ++ * perform final cleanup. ++ */ ++ if (!submount) + pthread_kill(state_mach_thid, SIGTERM); + + return; +@@ -1980,7 +1983,15 @@ int main(int argc, char *argv[]) + exit(1); + } + +- if (pthread_attr_init(&thread_attr)) { ++ if (pthread_attr_init(&th_attr)) { ++ logerr("%s: failed to init thread attribute struct!", ++ program); ++ close(start_pipefd[1]); ++ release_flag_file(); ++ exit(1); ++ } ++ ++ if (pthread_attr_init(&th_attr_detached)) { + logerr("%s: failed to init thread attribute struct!", + program); + close(start_pipefd[1]); +@@ -1989,7 +2000,7 @@ int main(int argc, char *argv[]) + } + + if (pthread_attr_setdetachstate( +- &thread_attr, PTHREAD_CREATE_DETACHED)) { ++ &th_attr_detached, PTHREAD_CREATE_DETACHED)) { + logerr("%s: failed to set detached thread attribute!", + program); + close(start_pipefd[1]); +@@ -1999,7 +2010,7 @@ int main(int argc, char *argv[]) + + #ifdef _POSIX_THREAD_ATTR_STACKSIZE + if (pthread_attr_setstacksize( +- &thread_attr, PTHREAD_STACK_MIN*64)) { ++ &th_attr_detached, PTHREAD_STACK_MIN*64)) { + logerr("%s: failed to set stack size thread attribute!", + program); + close(start_pipefd[1]); +diff --git a/daemon/direct.c b/daemon/direct.c +index c0243c4..d9dda3d 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -37,7 +37,8 @@ + + #include "automount.h" + +-extern pthread_attr_t thread_attr; ++/* Attribute to create detached thread */ ++extern pthread_attr_t th_attr_detached; + + struct mnt_params { + char *options; +@@ -1142,7 +1143,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di + debug(ap->logopt, "token %ld, name %s", + (unsigned long) pkt->wait_queue_token, mt->name); + +- status = pthread_create(&thid, &thread_attr, do_expire_direct, mt); ++ status = pthread_create(&thid, &th_attr_detached, do_expire_direct, mt); + if (status) { + error(ap->logopt, "expire thread create failed"); + ops->send_fail(ap->logopt, +@@ -1451,7 +1452,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + mt->gid = pkt->gid; + mt->wait_queue_token = pkt->wait_queue_token; + +- status = pthread_create(&thid, &thread_attr, do_mount_direct, mt); ++ status = pthread_create(&thid, &th_attr_detached, do_mount_direct, mt); + if (status) { + error(ap->logopt, "missing mount thread create failed"); + ops->send_fail(ap->logopt, +diff --git a/daemon/indirect.c b/daemon/indirect.c +index 9d3745c..0721707 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -36,7 +36,8 @@ + + #include "automount.h" + +-extern pthread_attr_t thread_attr; ++/* Attribute to create detached thread */ ++extern pthread_attr_t th_attr_detached; + + static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER; + +@@ -647,7 +648,7 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_ + mt->len = pkt->len; + mt->wait_queue_token = pkt->wait_queue_token; + +- status = pthread_create(&thid, &thread_attr, do_expire_indirect, mt); ++ status = pthread_create(&thid, &th_attr_detached, do_expire_indirect, mt); + if (status) { + error(ap->logopt, "expire thread create failed"); + ops->send_fail(ap->logopt, +@@ -835,7 +836,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin + mt->gid = pkt->gid; + mt->wait_queue_token = pkt->wait_queue_token; + +- status = pthread_create(&thid, &thread_attr, do_mount_indirect, mt); ++ status = pthread_create(&thid, &th_attr_detached, do_mount_indirect, mt); + if (status) { + error(ap->logopt, "expire thread create failed"); + ops->send_fail(ap->logopt, +diff --git a/daemon/state.c b/daemon/state.c +index 87c16a6..cd63be1 100644 +--- a/daemon/state.c ++++ b/daemon/state.c +@@ -16,7 +16,8 @@ + + #include "automount.h" + +-extern pthread_attr_t thread_attr; ++/* Attribute to create detached thread */ ++extern pthread_attr_t th_attr_detached; + + struct state_queue { + pthread_t thid; +@@ -292,7 +293,7 @@ static enum expire expire_proc(struct autofs_point *ap, int now) + else + expire = expire_proc_direct; + +- status = pthread_create(&thid, &thread_attr, expire, ea); ++ status = pthread_create(&thid, &th_attr_detached, expire, ea); + if (status) { + error(ap->logopt, + "expire thread create for %s failed", ap->path); +@@ -519,7 +520,7 @@ static unsigned int st_readmap(struct autofs_point *ap) + ra->ap = ap; + ra->now = now; + +- status = pthread_create(&thid, &thread_attr, do_readmap, ra); ++ status = pthread_create(&thid, &th_attr_detached, do_readmap, ra); + if (status) { + error(ap->logopt, "read map thread create failed"); + st_readmap_cleanup(ra); +diff --git a/include/master.h b/include/master.h +index 6d801a9..c519e97 100644 +--- a/include/master.h ++++ b/include/master.h +@@ -48,6 +48,7 @@ struct master_mapent { + struct map_source *maps; + struct autofs_point *ap; + struct list_head list; ++ struct list_head join; + }; + + struct master { +@@ -61,6 +62,7 @@ struct master { + unsigned int logopt; + struct mapent_cache *nc; + struct list_head mounts; ++ struct list_head completed; + }; + + /* From the yacc master map parser */ +@@ -109,6 +111,7 @@ void master_notify_state_change(struct master *, int); + int master_mount_mounts(struct master *, time_t, int); + extern inline unsigned int master_get_logopt(void); + int master_list_empty(struct master *); ++int master_done(struct master *); + int master_kill(struct master *); + + #endif +diff --git a/lib/master.c b/lib/master.c +index e1cc062..762094f 100644 +--- a/lib/master.c ++++ b/lib/master.c +@@ -32,8 +32,8 @@ struct master *master_list = NULL; + + extern long global_negative_timeout; + +-/* Attribute to create detached thread */ +-extern pthread_attr_t thread_attr; ++/* Attribute to create a joinable thread */ ++extern pthread_attr_t th_attr; + + extern struct startup_cond suc; + +@@ -704,11 +704,16 @@ void master_add_mapent(struct master *master, struct master_mapent *entry) + + void master_remove_mapent(struct master_mapent *entry) + { ++ struct master *master = entry->master; ++ + if (entry->ap->submount) + return; + +- if (!list_empty(&entry->list)) ++ if (!list_empty(&entry->list)) { + list_del_init(&entry->list); ++ list_add(&entry->join, &master->completed); ++ } ++ + return; + } + +@@ -786,6 +791,7 @@ struct master *master_new(const char *name, unsigned int timeout, unsigned int g + master->logopt = master->default_logging; + + INIT_LIST_HEAD(&master->mounts); ++ INIT_LIST_HEAD(&master->completed); + + return master; + } +@@ -993,7 +999,7 @@ static int master_do_mount(struct master_mapent *entry) + + debug(ap->logopt, "mounting %s", entry->path); + +- status = pthread_create(&thid, &thread_attr, handle_mounts, &suc); ++ status = pthread_create(&thid, &th_attr, handle_mounts, &suc); + if (status) { + crit(ap->logopt, + "failed to create mount handler thread for %s", +@@ -1170,6 +1176,30 @@ int master_list_empty(struct master *master) + return res; + } + ++int master_done(struct master *master) ++{ ++ struct list_head *head, *p; ++ struct master_mapent *entry; ++ int res = 0; ++ ++ master_mutex_lock(); ++ head = &master->completed; ++ p = head->next; ++ while (p != head) { ++ entry = list_entry(p, struct master_mapent, join); ++ p = p->next; ++ list_del(&entry->join); ++ pthread_join(entry->thid, NULL); ++ master_free_mapent_sources(entry, 1); ++ master_free_mapent(entry); ++ } ++ if (list_empty(&master->mounts)) ++ res = 1; ++ master_mutex_unlock(); ++ ++ return res; ++} ++ + inline unsigned int master_get_logopt(void) + { + return master_list ? master_list->logopt : LOGOPT_NONE; +diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c +index 82a5ef3..44fc043 100644 +--- a/modules/mount_autofs.c ++++ b/modules/mount_autofs.c +@@ -30,7 +30,7 @@ + #define MODPREFIX "mount(autofs): " + + /* Attribute to create detached thread */ +-extern pthread_attr_t thread_attr; ++extern pthread_attr_t th_attr_detached; + extern struct startup_cond suc; + + int mount_version = AUTOFS_MOUNT_VERSION; /* Required by protocol */ +@@ -235,7 +235,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + suc.done = 0; + suc.status = 0; + +- if (pthread_create(&thid, &thread_attr, handle_mounts, &suc)) { ++ if (pthread_create(&thid, &th_attr_detached, handle_mounts, &suc)) { + crit(ap->logopt, + MODPREFIX + "failed to create mount handler thread for %s", diff --git a/autofs-5.0.4-libxml2-workaround-fix.patch b/autofs-5.0.4-libxml2-workaround-fix.patch new file mode 100644 index 0000000..1ff6af2 --- /dev/null +++ b/autofs-5.0.4-libxml2-workaround-fix.patch @@ -0,0 +1,38 @@ +autofs-5.0.4 - libxml2 workaround fix + +From: Ian Kent + +Add a check for libxml2.so.2 for the libxml2 workaround in case libxml2.so +is not present. +--- + + CHANGELOG | 1 + + daemon/automount.c | 2 ++ + 2 files changed, 3 insertions(+), 0 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 1cb56fe..b8ad22e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -21,6 +21,7 @@ + - update to provide ipv6 name and address support. + - update to provide ipv6 address parsing. + - easy alloca replacements fix. ++- add check for alternate libxml2 library for libxml2 tsd workaround. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/automount.c b/daemon/automount.c +index 1ec686b..a664277 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -2058,6 +2058,8 @@ int main(int argc, char *argv[]) + + #ifdef LIBXML2_WORKAROUND + void *dh_xml2 = dlopen("libxml2.so", RTLD_NOW); ++ if (!dh_xml2) ++ dh_xml2 = dlopen("libxml2.so.2", RTLD_NOW); + #endif + #ifdef TIRPC_WORKAROUND + void *dh_tirpc = dlopen("libitirpc.so", RTLD_NOW); diff --git a/autofs-5.0.4-make-MAX_ERR_BUF-and-PARSE_MAX_BUF-use-easier-to-audit.patch b/autofs-5.0.4-make-MAX_ERR_BUF-and-PARSE_MAX_BUF-use-easier-to-audit.patch new file mode 100644 index 0000000..9deaf26 --- /dev/null +++ b/autofs-5.0.4-make-MAX_ERR_BUF-and-PARSE_MAX_BUF-use-easier-to-audit.patch @@ -0,0 +1,222 @@ +autofs-5.0.4 - make MAX_ERR_BUF and PARSE_MAX_BUF use easier to audit + +From: Valerie Aurora Henson + +Non-critical changes to make auditing buffer lengths easier. + +* Some buffers were the wrong (too big) size, some were used twice for + different purposes. +* Use sizeof(buf) instead of repeating the *MAX* define in functions + that need to know the size of a statically allocated buffer. +* Fix a compiler warning about discarding the const on a string. +--- + + CHANGELOG | 1 + + modules/lookup_ldap.c | 51 ++++++++++++++++++++++--------------------------- + 2 files changed, 24 insertions(+), 28 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index afd1335..417a001 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -15,6 +15,7 @@ + - add "forcestart" and "forcerestart" init script options to allow + use of 5.0.3 strartup behavior if required. + - always read entire file map into cache to speed lookups. ++- make MAX_ERR_BUF and PARSE_MAX_BUF use easier to audit. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index bee97ae..d8a60d3 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -272,7 +272,7 @@ LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_conte + + static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key) + { +- char buf[PARSE_MAX_BUF]; ++ char buf[MAX_ERR_BUF]; + char *query, *dn, *qdn; + LDAPMessage *result, *e; + struct ldap_searchdn *sdns = NULL; +@@ -296,7 +296,7 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt + + query = alloca(l); + if (query == NULL) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ char *estr = strerror_r(errno, buf, sizeof(buf)); + crit(logopt, MODPREFIX "alloca: %s", estr); + return NSS_STATUS_UNAVAIL; + } +@@ -1082,7 +1082,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c + } + if (!tmp) { + char *estr; +- estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ estr = strerror_r(errno, buf, sizeof(buf)); + logerr(MODPREFIX "malloc: %s", estr); + return 0; + } +@@ -1104,7 +1104,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c + tmp = malloc(l + 1); + if (!tmp) { + char *estr; +- estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ estr = strerror_r(errno, buf, sizeof(buf)); + crit(logopt, MODPREFIX "malloc: %s", estr); + return 0; + } +@@ -1139,7 +1139,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c + /* Isolate the server's name. */ + if (!tmp) { + char *estr; +- estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ estr = strerror_r(errno, buf, sizeof(buf)); + logerr(MODPREFIX "malloc: %s", estr); + return 0; + } +@@ -1180,7 +1180,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c + ctxt->mapname = map; + else { + char *estr; +- estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ estr = strerror_r(errno, buf, sizeof(buf)); + logerr(MODPREFIX "malloc: %s", estr); + if (ctxt->server) + free(ctxt->server); +@@ -1191,7 +1191,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c + base = malloc(l + 1); + if (!base) { + char *estr; +- estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ estr = strerror_r(errno, buf, sizeof(buf)); + logerr(MODPREFIX "malloc: %s", estr); + if (ctxt->server) + free(ctxt->server); +@@ -1205,7 +1205,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c + char *map = malloc(l + 1); + if (!map) { + char *estr; +- estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ estr = strerror_r(errno, buf, sizeof(buf)); + logerr(MODPREFIX "malloc: %s", estr); + if (ctxt->server) + free(ctxt->server); +@@ -1318,7 +1318,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + /* If we can't build a context, bail. */ + ctxt = malloc(sizeof(struct lookup_context)); + if (!ctxt) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ char *estr = strerror_r(errno, buf, sizeof(buf)); + logerr(MODPREFIX "malloc: %s", estr); + return 1; + } +@@ -1419,8 +1419,9 @@ int lookup_read_master(struct master *master, time_t age, void *context) + unsigned int timeout = master->default_timeout; + unsigned int logging = master->default_logging; + unsigned int logopt = master->logopt; +- int rv, l, count, blen; +- char buf[PARSE_MAX_BUF]; ++ int rv, l, count; ++ char buf[MAX_ERR_BUF]; ++ char parse_buf[PARSE_MAX_BUF]; + char *query; + LDAPMessage *result, *e; + char *class, *info, *entry; +@@ -1442,7 +1443,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + + query = alloca(l); + if (query == NULL) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ char *estr = strerror_r(errno, buf, sizeof(buf)); + logerr(MODPREFIX "alloca: %s", estr); + return NSS_STATUS_UNAVAIL; + } +@@ -1532,19 +1533,13 @@ int lookup_read_master(struct master *master, time_t age, void *context) + goto next; + } + +- blen = strlen(*keyValue) + 1 + strlen(*values) + 2; +- if (blen > PARSE_MAX_BUF) { ++ if (snprintf(parse_buf, sizeof(parse_buf), "%s %s", ++ *keyValue, *values) >= sizeof(parse_buf)) { + error(logopt, MODPREFIX "map entry too long"); + ldap_value_free(values); + goto next; + } +- memset(buf, 0, PARSE_MAX_BUF); +- +- strcpy(buf, *keyValue); +- strcat(buf, " "); +- strcat(buf, *values); +- +- master_parse_entry(buf, timeout, logging, age); ++ master_parse_entry(parse_buf, timeout, logging, age); + next: + ldap_value_free(keyValue); + e = ldap_next_entry(ldap, e); +@@ -1561,7 +1556,7 @@ static int get_percent_decoded_len(const char *name) + { + int escapes = 0; + int escaped = 0; +- char *tmp = name; ++ const char *tmp = name; + int look_for_close = 0; + + while (*tmp) { +@@ -2060,7 +2055,7 @@ static int do_get_entries(struct ldap_search_params *sp, struct map_source *sour + mapent = malloc(v_len + 1); + if (!mapent) { + char *estr; +- estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ estr = strerror_r(errno, buf, sizeof(buf)); + logerr(MODPREFIX "malloc: %s", estr); + ldap_value_free_len(bvValues); + goto next; +@@ -2080,7 +2075,7 @@ static int do_get_entries(struct ldap_search_params *sp, struct map_source *sour + mapent_len = new_size; + } else { + char *estr; +- estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ estr = strerror_r(errno, buf, sizeof(buf)); + logerr(MODPREFIX "realloc: %s", estr); + } + } +@@ -2181,7 +2176,7 @@ static int read_one_map(struct autofs_point *ap, + + sp.query = alloca(l); + if (sp.query == NULL) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ char *estr = strerror_r(errno, buf, sizeof(buf)); + logerr(MODPREFIX "malloc: %s", estr); + return NSS_STATUS_UNAVAIL; + } +@@ -2335,7 +2330,7 @@ static int lookup_one(struct autofs_point *ap, + + query = alloca(l); + if (query == NULL) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ char *estr = strerror_r(errno, buf, sizeof(buf)); + crit(ap->logopt, MODPREFIX "malloc: %s", estr); + if (enc_len1) { + free(enc_key1); +@@ -2507,7 +2502,7 @@ static int lookup_one(struct autofs_point *ap, + mapent = malloc(v_len + 1); + if (!mapent) { + char *estr; +- estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ estr = strerror_r(errno, buf, sizeof(buf)); + logerr(MODPREFIX "malloc: %s", estr); + ldap_value_free_len(bvValues); + goto next; +@@ -2527,7 +2522,7 @@ static int lookup_one(struct autofs_point *ap, + mapent_len = new_size; + } else { + char *estr; +- estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ estr = strerror_r(errno, buf, sizeof(buf)); + logerr(MODPREFIX "realloc: %s", estr); + } + } diff --git a/autofs-5.0.4-make-hash-table-scale-to-thousands-of-entries.patch b/autofs-5.0.4-make-hash-table-scale-to-thousands-of-entries.patch new file mode 100644 index 0000000..c5f53b2 --- /dev/null +++ b/autofs-5.0.4-make-hash-table-scale-to-thousands-of-entries.patch @@ -0,0 +1,294 @@ +autofs-5.0.4 - make hash table scale to thousands of entries + +From: Valerie Aurora Henson + +Originally written by Paul Wankadia . + +The autofs cache lookup performs poorly for large maps. + +The additive hashing algorithm used by autofs results in a clustering +of hash values around the average hash chain size. It is biased toward +a small range of hash indexes which becomes worse as the hash table size +increases. + +Simple testing shows that the "One-at-a-time" hash function (implemented +by this patch) gives a much better distribution of hash indexes as table +size increases. + +The only change made to the original patch is to make the hash table size +configurable with a default somewhat larger than it is currently. +--- + + CHANGELOG | 2 ++ + include/automount.h | 2 +- + include/defaults.h | 3 +++ + lib/cache.c | 47 +++++++++++++++++++++++----------------- + lib/defaults.c | 16 +++++++++++++- + redhat/autofs.sysconfig.in | 6 +++++ + samples/autofs.conf.default.in | 6 +++++ + 7 files changed, 60 insertions(+), 22 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 0fb7db5..912c088 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -5,6 +5,8 @@ + - fix negative caching for non-existent map keys. + - use CLOEXEC flag. + - fix select(2) fd limit. ++- make hash table scale to thousands of entries (Paul Wankadia, ++ Valerie Aurora Henson). + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/include/automount.h b/include/automount.h +index a55ddbc..fa24885 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -128,7 +128,7 @@ struct autofs_point; + #define CHE_DUPLICATE 0x0020 + #define CHE_UNAVAIL 0x0040 + +-#define HASHSIZE 77 ++#define NULL_MAP_HASHSIZE 64 + #define NEGATIVE_TIMEOUT 10 + #define UMOUNT_RETRIES 8 + #define EXPIRE_RETRIES 3 +diff --git a/include/defaults.h b/include/defaults.h +index 12534ec..9a2430f 100644 +--- a/include/defaults.h ++++ b/include/defaults.h +@@ -40,6 +40,8 @@ + #define DEFAULT_APPEND_OPTIONS 1 + #define DEFAULT_AUTH_CONF_FILE AUTOFS_MAP_DIR "/autofs_ldap_auth.conf" + ++#define DEFAULT_MAP_HASH_TABLE_SIZE 1024 ++ + struct ldap_schema; + struct ldap_searchdn; + +@@ -62,6 +64,7 @@ void defaults_free_searchdns(struct ldap_searchdn *); + unsigned int defaults_get_append_options(void); + unsigned int defaults_get_umount_wait(void); + const char *defaults_get_auth_conf_file(void); ++unsigned int defaults_get_map_hash_table_size(void); + + #endif + +diff --git a/lib/cache.c b/lib/cache.c +index 4a00367..edb3192 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -190,7 +190,7 @@ struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map) + if (!mc) + return NULL; + +- mc->size = HASHSIZE; ++ mc->size = defaults_get_map_hash_table_size(); + + mc->hash = malloc(mc->size * sizeof(struct entry *)); + if (!mc->hash) { +@@ -241,7 +241,7 @@ struct mapent_cache *cache_init_null_cache(struct master *master) + if (!mc) + return NULL; + +- mc->size = HASHSIZE; ++ mc->size = NULL_MAP_HASHSIZE; + + mc->hash = malloc(mc->size * sizeof(struct entry *)); + if (!mc->hash) { +@@ -279,29 +279,36 @@ struct mapent_cache *cache_init_null_cache(struct master *master) + return mc; + } + +-static unsigned int hash(const char *key) ++static u_int32_t hash(const char *key, unsigned int size) + { +- unsigned long hashval; ++ u_int32_t hashval; + char *s = (char *) key; + +- for (hashval = 0; *s != '\0';) +- hashval += *s++; ++ for (hashval = 0; *s != '\0';) { ++ hashval += (unsigned char) *s++; ++ hashval += (hashval << 10); ++ hashval ^= (hashval >> 6); ++ } ++ ++ hashval += (hashval << 3); ++ hashval ^= (hashval >> 11); ++ hashval += (hashval << 15); + +- return hashval % HASHSIZE; ++ return hashval % size; + } + +-static unsigned int ino_hash(dev_t dev, ino_t ino) ++static u_int32_t ino_hash(dev_t dev, ino_t ino, unsigned int size) + { +- unsigned long hashval; ++ u_int32_t hashval; + + hashval = dev + ino; + +- return hashval % HASHSIZE; ++ return hashval % size; + } + + int cache_set_ino_index(struct mapent_cache *mc, const char *key, dev_t dev, ino_t ino) + { +- unsigned int ino_index = ino_hash(dev, ino); ++ u_int32_t ino_index = ino_hash(dev, ino, mc->size); + struct mapent *me; + + me = cache_lookup_distinct(mc, key); +@@ -323,10 +330,10 @@ struct mapent *cache_lookup_ino(struct mapent_cache *mc, dev_t dev, ino_t ino) + { + struct mapent *me = NULL; + struct list_head *head, *p; +- unsigned int ino_index; ++ u_int32_t ino_index; + + ino_index_lock(mc); +- ino_index = ino_hash(dev, ino); ++ ino_index = ino_hash(dev, ino, mc->size); + head = &mc->ino_index[ino_index]; + + list_for_each(p, head) { +@@ -369,7 +376,7 @@ struct mapent *cache_lookup_first(struct mapent_cache *mc) + struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me) + { + struct mapent *this; +- unsigned long hashval; ++ u_int32_t hashval; + unsigned int i; + + if (!me) +@@ -385,7 +392,7 @@ struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me) + return this; + } + +- hashval = hash(me->key) + 1; ++ hashval = hash(me->key, mc->size) + 1; + if (hashval < mc->size) { + for (i = (unsigned int) hashval; i < mc->size; i++) { + this = mc->hash[i]; +@@ -433,7 +440,7 @@ struct mapent *cache_lookup(struct mapent_cache *mc, const char *key) + if (!key) + return NULL; + +- for (me = mc->hash[hash(key)]; me != NULL; me = me->next) { ++ for (me = mc->hash[hash(key, mc->size)]; me != NULL; me = me->next) { + if (strcmp(key, me->key) == 0) + goto done; + } +@@ -446,7 +453,7 @@ struct mapent *cache_lookup(struct mapent_cache *mc, const char *key) + goto done; + } + +- for (me = mc->hash[hash("*")]; me != NULL; me = me->next) ++ for (me = mc->hash[hash("*", mc->size)]; me != NULL; me = me->next) + if (strcmp("*", me->key) == 0) + goto done; + } +@@ -462,7 +469,7 @@ struct mapent *cache_lookup_distinct(struct mapent_cache *mc, const char *key) + if (!key) + return NULL; + +- for (me = mc->hash[hash(key)]; me != NULL; me = me->next) { ++ for (me = mc->hash[hash(key, mc->size)]; me != NULL; me = me->next) { + if (strcmp(key, me->key) == 0) + return me; + } +@@ -530,7 +537,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c + { + struct mapent *me, *existing = NULL; + char *pkey, *pent; +- unsigned int hashval = hash(key); ++ u_int32_t hashval = hash(key, mc->size); + int status; + + me = (struct mapent *) malloc(sizeof(struct mapent)); +@@ -750,7 +757,7 @@ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key + int cache_delete(struct mapent_cache *mc, const char *key) + { + struct mapent *me = NULL, *pred; +- unsigned int hashval = hash(key); ++ u_int32_t hashval = hash(key, mc->size); + int status, ret = CHE_OK; + char *this; + +diff --git a/lib/defaults.c b/lib/defaults.c +index ff653e3..0d39716 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -49,6 +49,8 @@ + #define ENV_UMOUNT_WAIT "UMOUNT_WAIT" + #define ENV_AUTH_CONF_FILE "AUTH_CONF_FILE" + ++#define ENV_MAP_HASH_TABLE_SIZE "MAP_HASH_TABLE_SIZE" ++ + static const char *default_master_map_name = DEFAULT_MASTER_MAP_NAME; + static const char *default_auth_conf_file = DEFAULT_AUTH_CONF_FILE; + +@@ -323,7 +325,8 @@ unsigned int defaults_read_config(unsigned int to_syslog) + check_set_config_value(key, ENV_NAME_VALUE_ATTR, value, to_syslog) || + check_set_config_value(key, ENV_APPEND_OPTIONS, value, to_syslog) || + check_set_config_value(key, ENV_UMOUNT_WAIT, value, to_syslog) || +- check_set_config_value(key, ENV_AUTH_CONF_FILE, value, to_syslog)) ++ check_set_config_value(key, ENV_AUTH_CONF_FILE, value, to_syslog) || ++ check_set_config_value(key, ENV_MAP_HASH_TABLE_SIZE, value, to_syslog)) + ; + } + +@@ -672,3 +675,14 @@ const char *defaults_get_auth_conf_file(void) + return (const char *) cf; + } + ++unsigned int defaults_get_map_hash_table_size(void) ++{ ++ long size; ++ ++ size = get_env_number(ENV_MAP_HASH_TABLE_SIZE); ++ if (size < 0) ++ size = DEFAULT_MAP_HASH_TABLE_SIZE; ++ ++ return (unsigned int) size; ++} ++ +diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in +index 8256888..fe36f45 100644 +--- a/redhat/autofs.sysconfig.in ++++ b/redhat/autofs.sysconfig.in +@@ -89,6 +89,12 @@ BROWSE_MODE="no" + # + #AUTH_CONF_FILE="@@autofsmapdir@@/autofs_ldap_auth.conf" + # ++# MAP_HASH_TABLE_SIZE - set the map cache hash table size. ++# Should be a power of 2 with a ratio roughly ++# between 1:10 and 1:20 for each map. ++# ++#MAP_HASH_TABLE_SIZE=1024 ++# + # General global options + # + # If the kernel supports using the autofs miscellanous device +diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in +index 844a6f3..4496738 100644 +--- a/samples/autofs.conf.default.in ++++ b/samples/autofs.conf.default.in +@@ -89,6 +89,12 @@ BROWSE_MODE="no" + # + #AUTH_CONF_FILE="@@autofsmapdir@@/autofs_ldap_auth.conf" + # ++# MAP_HASH_TABLE_SIZE - set the map cache hash table size. ++# Should be a power of 2 with a ratio roughly ++# between 1:10 and 1:20 for each map. ++# ++#MAP_HASH_TABLE_SIZE=1024 ++# + # General global options + # + # If the kernel supports using the autofs miscellanous device diff --git a/autofs-5.0.4-manual-umount-recovery-fixes.patch b/autofs-5.0.4-manual-umount-recovery-fixes.patch new file mode 100644 index 0000000..509ed80 --- /dev/null +++ b/autofs-5.0.4-manual-umount-recovery-fixes.patch @@ -0,0 +1,100 @@ +autofs-5.0.4 - mannual umount recovery fixes + +From: Ian Kent + +Check for the absence of a mount before doing the manual umount +checks and check ioctlfd is valid seperately. Take a write lock +on the map entry mutex to ensure any mount request is complete +before checking. +--- + + CHANGELOG | 1 + + daemon/direct.c | 4 ++-- + daemon/indirect.c | 37 +++++++++++++++++++++++-------------- + 3 files changed, 26 insertions(+), 16 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index f0d0e58..05e0206 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -54,6 +54,7 @@ + - fix notify mount message path. + - remount we created mount point fix. + - fix double free in sasl_bind(). ++- mannual umount recovery fixes. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/direct.c b/daemon/direct.c +index 74a9acc..7b02c7a 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -889,9 +889,9 @@ void *expire_proc_direct(void *arg) + /* Check for manual umount */ + cache_writelock(me->mc); + if (me->ioctlfd != -1 && +- fstat(ioctlfd, &st) != -1 && ++ fstat(me->ioctlfd, &st) != -1 && + !count_mounts(ap->logopt, next->path, st.st_dev)) { +- ops->close(ap->logopt, ioctlfd); ++ ops->close(ap->logopt, me->ioctlfd); + me->ioctlfd = -1; + cache_unlock(me->mc); + pthread_setcancelstate(cur_state, NULL); +diff --git a/daemon/indirect.c b/daemon/indirect.c +index 463b39c..8025ee4 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -437,7 +437,19 @@ void *expire_proc_indirect(void *arg) + struct mapent *me = NULL; + struct stat st; + +- master_source_readlock(ap->entry); ++ /* It's got a mount, deal with in the outer loop */ ++ if (is_mounted(_PATH_MOUNTED, next->path, MNTS_REAL)) { ++ pthread_setcancelstate(cur_state, NULL); ++ continue; ++ } ++ ++ /* Don't touch submounts */ ++ if (master_find_submount(ap, next->path)) { ++ pthread_setcancelstate(cur_state, NULL); ++ continue; ++ } ++ ++ master_source_writelock(ap->entry); + + map = ap->entry->maps; + while (map) { +@@ -456,20 +468,17 @@ void *expire_proc_indirect(void *arg) + continue; + } + ++ if (me->ioctlfd == -1) { ++ cache_unlock(mc); ++ master_source_unlock(ap->entry); ++ pthread_setcancelstate(cur_state, NULL); ++ continue; ++ } ++ + /* Check for manual umount */ +- if (me->ioctlfd != -1 && +- (fstat(me->ioctlfd, &st) == -1 || +- !count_mounts(ap->logopt, me->key, st.st_dev))) { +- if (is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL)) { +- error(ap->logopt, +- "error: possible mtab mismatch %s", +- me->key); +- cache_unlock(mc); +- master_source_unlock(ap->entry); +- pthread_setcancelstate(cur_state, NULL); +- continue; +- } +- close(me->ioctlfd); ++ if (fstat(me->ioctlfd, &st) == -1 || ++ !count_mounts(ap->logopt, me->key, st.st_dev)) { ++ ops->close(ap->logopt, me->ioctlfd); + me->ioctlfd = -1; + } + diff --git a/autofs-5.0.4-remount-we-created-mount-point-fix.patch b/autofs-5.0.4-remount-we-created-mount-point-fix.patch new file mode 100644 index 0000000..6ac9aa7 --- /dev/null +++ b/autofs-5.0.4-remount-we-created-mount-point-fix.patch @@ -0,0 +1,55 @@ +autofs-5.0.4 - remount we created mount point fix + +From: Ian Kent + +During remount determine if autofs created the mount point directory, +as best we can. +--- + + CHANGELOG | 1 + + lib/mounts.c | 15 +++++++-------- + 2 files changed, 8 insertions(+), 8 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 0a0519f..e138ca3 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -52,6 +52,7 @@ + - use srv query for domain dn. + - fix not releasing resources when using submounts. + - fix notify mount message path. ++- remount we created mount point fix. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/lib/mounts.c b/lib/mounts.c +index 4787bb6..4c44982 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1359,18 +1359,17 @@ int try_remount(struct autofs_point *ap, struct mapent *me, unsigned int type) + /* + * The directory must exist since we found a device + * number for the mount but we can't know if we created +- * it or not. However, if we're mounted on an autofs fs +- * then we need to cleanup the path anyway. ++ * it or not. However, if this is an indirect mount with ++ * the nobrowse option we need to remove the mount point ++ * directory at umount anyway. + */ + if (type == t_indirect) { +- ap->flags &= ~MOUNT_FLAG_DIR_CREATED; +- if (ret == DEV_IOCTL_IS_AUTOFS) ++ if (ap->flags & MOUNT_FLAG_GHOST) ++ ap->flags &= ~MOUNT_FLAG_DIR_CREATED; ++ else + ap->flags |= MOUNT_FLAG_DIR_CREATED; +- } else { ++ } else + me->flags &= ~MOUNT_FLAG_DIR_CREATED; +- if (ret == DEV_IOCTL_IS_AUTOFS) +- me->flags |= MOUNT_FLAG_DIR_CREATED; +- } + + /* + * Either we opened the mount or we're re-reading the map. diff --git a/autofs-5.0.4-renew-sasl-creds-upon-reconnect-fail.patch b/autofs-5.0.4-renew-sasl-creds-upon-reconnect-fail.patch new file mode 100644 index 0000000..08e4a37 --- /dev/null +++ b/autofs-5.0.4-renew-sasl-creds-upon-reconnect-fail.patch @@ -0,0 +1,61 @@ +autofs-5.0.4 - renew sasl creds upon reconnect fail + +From: Ian Kent + +If a server re-connect fails it could be due to the authentication +credentail having timed out. So we need to dispose of this and retry +the connection including refreshing re-authenticating. +--- + + CHANGELOG | 1 + + modules/lookup_ldap.c | 17 +++++++++++++++++ + 2 files changed, 18 insertions(+), 0 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index b093451..7dee674 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -11,6 +11,7 @@ + - use CLOEXEC flag for setmntent also. + - fix hosts map use after free. + - fix uri list locking (again). ++- check for stale SASL credentials upon connect fail. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index b6784e1..bee97ae 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -675,6 +675,13 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) + + if (ctxt->server || !ctxt->uris) { + ldap = do_connect(logopt, ctxt->server, ctxt); ++#ifdef WITH_SASL ++ /* Dispose of the sasl authentication connection and try again. */ ++ if (!ldap) { ++ autofs_sasl_dispose(ctxt); ++ ldap = connect_to_server(logopt, ctxt->server, ctxt); ++ } ++#endif + return ldap; + } + +@@ -682,6 +689,16 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) + this = ctxt->uri; + uris_mutex_unlock(ctxt); + ldap = do_connect(logopt, this->uri, ctxt); ++#ifdef WITH_SASL ++ /* ++ * Dispose of the sasl authentication connection and try the ++ * current server again before trying other servers in the list. ++ */ ++ if (!ldap) { ++ autofs_sasl_dispose(ctxt); ++ ldap = connect_to_server(logopt, this->uri, ctxt); ++ } ++#endif + if (ldap) + return ldap; + diff --git a/autofs-5.0.4-reset-flex-scanner-when-setting-buffer.patch b/autofs-5.0.4-reset-flex-scanner-when-setting-buffer.patch new file mode 100644 index 0000000..6d1f73e --- /dev/null +++ b/autofs-5.0.4-reset-flex-scanner-when-setting-buffer.patch @@ -0,0 +1,59 @@ +autofs-5.0.4 - reset flex scanner when setting buffer + +From: Ian Kent + +We still have problems resetting the flex scan buffer after an error +is detected. This appears to fix the problem. +--- + + CHANGELOG | 1 + + lib/master_tok.l | 9 ++++++++- + 2 files changed, 9 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index c8b88e4..5f1cf7f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -38,6 +38,7 @@ + - fix lsb init script header. + - fix memory leak reading master map. + - fix st_remove_tasks() locking. ++- reset flex scanner when setting buffer. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/lib/master_tok.l b/lib/master_tok.l +index b6cc8be..373248b 100644 +--- a/lib/master_tok.l ++++ b/lib/master_tok.l +@@ -130,7 +130,6 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo + \x00 { + if (optr != buff) { + *optr = '\0'; +- optr = buff; + strcpy(master_lval.strtype, buff); + return NILL; + } +@@ -139,6 +138,11 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo + #.* { return COMMENT; } + + "/" { ++ if (optr != buff) { ++ *optr = '\0'; ++ strcpy(master_lval.strtype, buff); ++ return NILL; ++ } + BEGIN(PATHSTR); + bptr = buff; + yyless(0); +@@ -410,6 +414,9 @@ static void master_echo(void) + + void master_set_scan_buffer(const char *buffer) + { ++ master_lex_destroy(); ++ optr = buff; ++ + line = buffer; + line_pos = &line[0]; + /* diff --git a/autofs-5.0.4-srv-lookup-handle-endian.patch b/autofs-5.0.4-srv-lookup-handle-endian.patch new file mode 100644 index 0000000..093ecc8 --- /dev/null +++ b/autofs-5.0.4-srv-lookup-handle-endian.patch @@ -0,0 +1,37 @@ +autofs-5.0.4 - srv lookup handle endianness + +From: Ian Kent + + +--- + + modules/dclist.c | 6 ++++++ + 1 files changed, 6 insertions(+), 0 deletions(-) + + +diff --git a/modules/dclist.c b/modules/dclist.c +index 5b0e577..967581c 100644 +--- a/modules/dclist.c ++++ b/modules/dclist.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + #include "automount.h" + #include "dclist.h" +@@ -72,8 +73,13 @@ + #define SVAL(buf, pos) (*(const uint16_t *)((const char *)(buf) + (pos))) + #define IVAL(buf, pos) (*(const uint32_t *)((const char *)(buf) + (pos))) + ++#if __BYTE_ORDER == __LITTLE_ENDIAN + #define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) + #define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16))) ++#else ++#define SREV(x) (x) ++#define IREV(x) (x) ++#endif + + #define RSVAL(buf, pos) SREV(SVAL(buf, pos)) + #define RIVAL(buf, pos) IREV(IVAL(buf, pos)) diff --git a/autofs-5.0.4-uris-list-locking-fix.patch b/autofs-5.0.4-uris-list-locking-fix.patch new file mode 100644 index 0000000..ed01f3d --- /dev/null +++ b/autofs-5.0.4-uris-list-locking-fix.patch @@ -0,0 +1,224 @@ +autofs-5.0.4 - uris list locking fix + +From: Ian Kent + +The ldap uris list doesn't need to change we just need to keep +track of current server uri in the list and try to connect in +a round robin order. Also it's possible multiple concurrent +connection attempts may not be able to use the full list of +servers (if one is present). +--- + + CHANGELOG | 1 + + include/lookup_ldap.h | 3 +- + modules/lookup_ldap.c | 68 ++++++++++++++++++++++--------------------------- + 3 files changed, 33 insertions(+), 39 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 3199e4d..b093451 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -10,6 +10,7 @@ + - clear the quoted flag after each character from program map input. + - use CLOEXEC flag for setmntent also. + - fix hosts map use after free. ++- fix uri list locking (again). + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h +index f9ed778..b47bf5d 100644 +--- a/include/lookup_ldap.h ++++ b/include/lookup_ldap.h +@@ -55,7 +55,8 @@ struct lookup_context { + * given in configuration. + */ + pthread_mutex_t uris_mutex; +- struct list_head *uri; ++ struct list_head *uris; ++ struct ldap_uri *uri; + char *cur_host; + struct ldap_searchdn *sdns; + +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 6ba80eb..b6784e1 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -137,7 +137,7 @@ static void uris_mutex_unlock(struct lookup_context *ctxt) + return; + } + +-int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) ++int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt) + { + int rv; + +@@ -147,16 +147,14 @@ int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt + rv = ldap_simple_bind_s(ldap, NULL, NULL); + + if (rv != LDAP_SUCCESS) { +- if (!ctxt->uri) { ++ if (!ctxt->uris) { + crit(logopt, MODPREFIX + "Unable to bind to the LDAP server: " + "%s, error %s", ctxt->server ? "" : "(default)", + ldap_err2string(rv)); + } else { +- struct ldap_uri *uri; +- uri = list_entry(ctxt->uri->next, struct ldap_uri, list); + info(logopt, MODPREFIX "Unable to bind to the LDAP server: " +- "%s, error %s", uri->uri, ldap_err2string(rv)); ++ "%s, error %s", uri, ldap_err2string(rv)); + } + return -1; + } +@@ -498,7 +496,7 @@ static int find_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctx + return 0; + } + +-static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) ++static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt) + { + char *host = NULL, *nhost; + int rv, need_base = 1; +@@ -511,11 +509,11 @@ static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) + rv = autofs_sasl_bind(logopt, ldap, ctxt); + debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv); + } else { +- rv = bind_ldap_anonymous(logopt, ldap, ctxt); ++ rv = bind_ldap_anonymous(logopt, ldap, uri, ctxt); + debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv); + } + #else +- rv = bind_ldap_anonymous(logopt, ldap, ctxt); ++ rv = bind_ldap_anonymous(logopt, ldap, uri, ctxt); + debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv); + #endif + +@@ -584,7 +582,7 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context + if (!ldap) + return NULL; + +- if (!do_bind(logopt, ldap, ctxt)) { ++ if (!do_bind(logopt, ldap, uri, ctxt)) { + unbind_ldap_connection(logopt, ldap, ctxt); + return NULL; + } +@@ -612,7 +610,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c + return NULL; + } + +- if (!do_bind(logopt, ldap, ctxt)) { ++ if (!do_bind(logopt, ldap, uri, ctxt)) { + unbind_ldap_connection(logopt, ldap, ctxt); + autofs_sasl_dispose(ctxt); + error(logopt, MODPREFIX "cannot bind to server"); +@@ -638,36 +636,34 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) + { + LDAP *ldap = NULL; + struct ldap_uri *this; +- struct list_head *p; +- LIST_HEAD(tmp); ++ struct list_head *p, *first; + + /* Try each uri in list, add connect fails to tmp list */ + uris_mutex_lock(ctxt); +- p = ctxt->uri->next; +- while(p != ctxt->uri) { ++ if (!ctxt->uri) ++ first = ctxt->uris; ++ else ++ first = &ctxt->uri->list; ++ uris_mutex_unlock(ctxt); ++ p = first->next; ++ while(p != first) { ++ /* Skip list head */ ++ if (p == ctxt->uris) { ++ p = p->next; ++ continue; ++ } + this = list_entry(p, struct ldap_uri, list); +- uris_mutex_unlock(ctxt); + debug(logopt, "trying server %s", this->uri); + ldap = connect_to_server(logopt, this->uri, ctxt); + if (ldap) { + info(logopt, "connected to uri %s", this->uri); + uris_mutex_lock(ctxt); ++ ctxt->uri = this; ++ uris_mutex_unlock(ctxt); + break; + } +- uris_mutex_lock(ctxt); + p = p->next; +- list_del_init(&this->list); +- list_add_tail(&this->list, &tmp); + } +- /* +- * Successfuly connected uri (head of list) and untried uris are +- * in ctxt->uri list. Make list of remainder and failed uris with +- * failed uris at end and assign back to ctxt-uri. +- */ +- list_splice(ctxt->uri, &tmp); +- INIT_LIST_HEAD(ctxt->uri); +- list_splice(&tmp, ctxt->uri); +- uris_mutex_unlock(ctxt); + + return ldap; + } +@@ -677,23 +673,19 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) + struct ldap_uri *this; + LDAP *ldap; + +- if (ctxt->server || !ctxt->uri) { ++ if (ctxt->server || !ctxt->uris) { + ldap = do_connect(logopt, ctxt->server, ctxt); + return ldap; + } + + uris_mutex_lock(ctxt); +- this = list_entry(ctxt->uri->next, struct ldap_uri, list); ++ this = ctxt->uri; + uris_mutex_unlock(ctxt); + ldap = do_connect(logopt, this->uri, ctxt); + if (ldap) + return ldap; + +- /* Failed to connect, put at end of list */ +- uris_mutex_lock(ctxt); +- list_del_init(&this->list); +- list_add_tail(&this->list, ctxt->uri); +- uris_mutex_unlock(ctxt); ++ /* Failed to connect, try to find a new server */ + + #ifdef WITH_SASL + autofs_sasl_dispose(ctxt); +@@ -1259,8 +1251,8 @@ static void free_context(struct lookup_context *ctxt) + free(ctxt->cur_host); + if (ctxt->base) + free(ctxt->base); +- if (ctxt->uri) +- defaults_free_uris(ctxt->uri); ++ if (ctxt->uris) ++ defaults_free_uris(ctxt->uris); + ret = pthread_mutex_destroy(&ctxt->uris_mutex); + if (ret) + fatal(ret); +@@ -1344,7 +1336,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + if (uris) { + validate_uris(uris); + if (!list_empty(uris)) +- ctxt->uri = uris; ++ ctxt->uris = uris; + else { + error(LOGOPT_ANY, + "no valid uris found in config list" +@@ -1375,7 +1367,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + } + #endif + +- if (ctxt->server || !ctxt->uri) { ++ if (ctxt->server || !ctxt->uris) { + ldap = connect_to_server(LOGOPT_NONE, ctxt->server, ctxt); + if (!ldap) { + free_context(ctxt); diff --git a/autofs-5.0.4-use-CLOEXEC-flag-setmntent-include-fix.patch b/autofs-5.0.4-use-CLOEXEC-flag-setmntent-include-fix.patch new file mode 100644 index 0000000..231fbf2 --- /dev/null +++ b/autofs-5.0.4-use-CLOEXEC-flag-setmntent-include-fix.patch @@ -0,0 +1,49 @@ +autofs-5.0.4 - use CLOEXEC flag setmntent include fix + +From: Ian Kent + +Fix mntent.h not included before use of setmntent_r() in automount.h. +--- + + include/automount.h | 1 + + lib/dev-ioctl-lib.c | 1 - + lib/mounts.c | 1 - + 3 files changed, 1 insertions(+), 2 deletions(-) + + +diff --git a/include/automount.h b/include/automount.h +index 1f14d5b..615e07d 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include "config.h" + #include "list.h" + +diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c +index 056a0a9..7c8c433 100644 +--- a/lib/dev-ioctl-lib.c ++++ b/lib/dev-ioctl-lib.c +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + #include + + #include "automount.h" +diff --git a/lib/mounts.c b/lib/mounts.c +index 08ca4e3..4787bb6 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -14,7 +14,6 @@ + + #include + #include +-#include + #include + #include + #include diff --git a/autofs-5.0.4-use-CLOEXEC-flag-setmntent.patch b/autofs-5.0.4-use-CLOEXEC-flag-setmntent.patch new file mode 100644 index 0000000..f92b828 --- /dev/null +++ b/autofs-5.0.4-use-CLOEXEC-flag-setmntent.patch @@ -0,0 +1,96 @@ +autofs-5.0.4 - use CLOEXEC flag for setmntent + +From: Ian Kent + +Update use of CLOEXEC functionality to cover setmntent(3) +calls as well. +--- + + CHANGELOG | 1 + + include/automount.h | 20 ++++++++++++++++++++ + lib/mounts.c | 8 ++++---- + 3 files changed, 25 insertions(+), 4 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index af77b55..eb4a189 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -8,6 +8,7 @@ + - make hash table scale to thousands of entries (Paul Wankadia, + Valerie Aurora Henson). + - clear the quoted flag after each character from program map input. ++- use CLOEXEC flag for setmntent also. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/include/automount.h b/include/automount.h +index 005d209..46cb6c6 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -581,5 +581,25 @@ static inline FILE *open_fopen_r(const char *path) + return f; + } + ++static inline FILE *open_setmntent_r(const char *table) ++{ ++ FILE *tab; ++ ++#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) ++ if (cloexec_works != -1) { ++ tab = setmntent(table, "re"); ++ if (tab != NULL) { ++ check_cloexec(fileno(tab)); ++ return tab; ++ } ++ } ++#endif ++ tab = fopen(table, "r"); ++ if (tab == NULL) ++ return NULL; ++ check_cloexec(fileno(tab)); ++ return tab; ++} ++ + #endif + +diff --git a/lib/mounts.c b/lib/mounts.c +index ce4691b..b98e1a4 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -218,7 +218,7 @@ struct mnt_list *get_mnt_list(const char *table, const char *path, int include) + if (!path || !pathlen || pathlen > PATH_MAX) + return NULL; + +- tab = setmntent(table, "r"); ++ tab = open_setmntent_r(table); + if (!tab) { + char *estr = strerror_r(errno, buf, PATH_MAX - 1); + logerr("setmntent: %s", estr); +@@ -415,7 +415,7 @@ static int table_is_mounted(const char *table, const char *path, unsigned int ty + if (!path || !pathlen || pathlen >= PATH_MAX) + return 0; + +- tab = setmntent(table, "r"); ++ tab = open_setmntent_r(table); + if (!tab) { + char *estr = strerror_r(errno, buf, PATH_MAX - 1); + logerr("setmntent: %s", estr); +@@ -489,7 +489,7 @@ int has_fstab_option(const char *opt) + if (!opt) + return 0; + +- tab = setmntent(_PATH_MNTTAB, "r"); ++ tab = open_setmntent_r(_PATH_MNTTAB); + if (!tab) { + char *estr = strerror_r(errno, buf, PATH_MAX - 1); + logerr("setmntent: %s", estr); +@@ -668,7 +668,7 @@ struct mnt_list *tree_make_mnt_tree(const char *table, const char *path) + size_t plen; + int eq; + +- tab = setmntent(table, "r"); ++ tab = open_setmntent_r(table); + if (!tab) { + char *estr = strerror_r(errno, buf, PATH_MAX - 1); + logerr("setmntent: %s", estr); diff --git a/autofs-5.0.4-use-CLOEXEC-flag.patch b/autofs-5.0.4-use-CLOEXEC-flag.patch new file mode 100644 index 0000000..73f5251 --- /dev/null +++ b/autofs-5.0.4-use-CLOEXEC-flag.patch @@ -0,0 +1,1191 @@ +autofs-5.0.4 - use CLOEXEC flag + +From: Ian Kent + +Update autofs to use the new CLOEXEC flag if present. +This allows us to set close on exec atomically flag when opening files, +hopefully avoiding selinux complaining about leaked file handles. +--- + + CHANGELOG | 1 + daemon/automount.c | 42 ++++-------------- + daemon/direct.c | 2 - + daemon/flag.c | 8 ++- + daemon/indirect.c | 2 - + daemon/lookup.c | 1 + daemon/module.c | 2 - + daemon/spawn.c | 11 +---- + include/automount.h | 106 +++++++++++++++++++++++++++++++++++++++++++++ + include/state.h | 1 + lib/cache.c | 2 - + lib/defaults.c | 7 ++- + lib/dev-ioctl-lib.c | 17 +------ + lib/log.c | 2 - + lib/macros.c | 1 + lib/mounts.c | 2 - + lib/nss_parse.y | 13 +----- + lib/parse_subs.c | 1 + lib/rpc_subs.c | 21 ++------- + modules/cyrus-sasl.c | 1 + modules/lookup_file.c | 40 +++-------------- + modules/lookup_hesiod.c | 1 + modules/lookup_hosts.c | 1 + modules/lookup_ldap.c | 1 + modules/lookup_multi.c | 1 + modules/lookup_nisplus.c | 1 + modules/lookup_program.c | 5 +- + modules/lookup_userhome.c | 1 + modules/lookup_yp.c | 1 + modules/mount_afs.c | 2 - + modules/mount_autofs.c | 2 - + modules/mount_bind.c | 2 - + modules/mount_changer.c | 10 ---- + modules/mount_ext2.c | 2 - + modules/mount_generic.c | 2 - + modules/mount_nfs.c | 2 - + modules/parse_hesiod.c | 1 + modules/parse_sun.c | 2 - + modules/replicated.c | 13 +----- + 39 files changed, 149 insertions(+), 184 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index bd35b00..43f3205 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -3,6 +3,7 @@ + - fix dumb libxml2 check + - fix nested submount expire deadlock. + - fix negative caching for non-existent map keys. ++- use CLOEXEC flag. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/automount.c b/daemon/automount.c +index 6f078c1..e120f50 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -20,13 +20,11 @@ + * ----------------------------------------------------------------------- */ + + #include +-#include + #include + #include + #include + #include + #include +-#include + #include + #include + #include +@@ -68,6 +66,9 @@ static pthread_t state_mach_thid; + /* Pre-calculated kernel packet length */ + static size_t kpkt_len; + ++/* Does kernel know about SOCK_CLOEXEC and friends */ ++static int cloexec_works = 0; ++ + /* Attribute to create detached thread */ + pthread_attr_t thread_attr; + +@@ -671,7 +672,7 @@ static char *automount_path_to_fifo(unsigned logopt, const char *path) + static int create_logpri_fifo(struct autofs_point *ap) + { + int ret = -1; +- int fd, cl_flags; ++ int fd; + char *fifo_name; + char buf[MAX_ERR_BUF]; + +@@ -697,7 +698,7 @@ static int create_logpri_fifo(struct autofs_point *ap) + goto out_free; + } + +- fd = open(fifo_name, O_RDWR|O_NONBLOCK); ++ fd = open_fd(fifo_name, O_RDWR|O_NONBLOCK); + if (fd < 0) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + crit(ap->logopt, +@@ -707,11 +708,6 @@ static int create_logpri_fifo(struct autofs_point *ap) + goto out_free; + } + +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + ap->logpri_fifo = fd; + + out_free: +@@ -963,7 +959,7 @@ int do_expire(struct autofs_point *ap, const char *name, int namelen) + + static int autofs_init_ap(struct autofs_point *ap) + { +- int pipefd[2], cl_flags; ++ int pipefd[2]; + + if ((ap->state != ST_INIT)) { + /* This can happen if an autofs process is already running*/ +@@ -974,7 +970,7 @@ static int autofs_init_ap(struct autofs_point *ap) + ap->pipefd = ap->kpipefd = ap->ioctlfd = -1; + + /* Pipe for kernel communications */ +- if (pipe(pipefd) < 0) { ++ if (open_pipe(pipefd) < 0) { + crit(ap->logopt, + "failed to create commumication pipe for autofs path %s", + ap->path); +@@ -984,18 +980,8 @@ static int autofs_init_ap(struct autofs_point *ap) + ap->pipefd = pipefd[0]; + ap->kpipefd = pipefd[1]; + +- if ((cl_flags = fcntl(ap->pipefd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(ap->pipefd, F_SETFD, cl_flags); +- } +- +- if ((cl_flags = fcntl(ap->kpipefd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(ap->kpipefd, F_SETFD, cl_flags); +- } +- + /* Pipe state changes from signal handler to main loop */ +- if (pipe(ap->state_pipe) < 0) { ++ if (open_pipe(ap->state_pipe) < 0) { + crit(ap->logopt, + "failed create state pipe for autofs path %s", ap->path); + close(ap->pipefd); +@@ -1003,16 +989,6 @@ static int autofs_init_ap(struct autofs_point *ap) + return -1; + } + +- if ((cl_flags = fcntl(ap->state_pipe[0], F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(ap->state_pipe[0], F_SETFD, cl_flags); +- } +- +- if ((cl_flags = fcntl(ap->state_pipe[1], F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(ap->state_pipe[1], F_SETFD, cl_flags); +- } +- + if (create_logpri_fifo(ap) < 0) { + logmsg("could not create FIFO for path %s\n", ap->path); + logmsg("dynamic log level changes not available for %s", ap->path); +@@ -1080,7 +1056,7 @@ static void become_daemon(unsigned foreground, unsigned daemon_check) + exit(0); + } + +- if (pipe(start_pipefd) < 0) { ++ if (open_pipe(start_pipefd) < 0) { + fprintf(stderr, "%s: failed to create start_pipefd.\n", + program); + exit(0); +diff --git a/daemon/direct.c b/daemon/direct.c +index 98fcc07..c0243c4 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -21,12 +21,10 @@ + + #include + #include +-#include + #include + #include + #include + #include +-#include + #include + #include + #include +diff --git a/daemon/flag.c b/daemon/flag.c +index d8ca61b..e43cece 100644 +--- a/daemon/flag.c ++++ b/daemon/flag.c +@@ -21,15 +21,15 @@ + #include + #include + #include +-#include + #include +-#include + #include + #include + #include + #include + #include + ++#include "automount.h" ++ + #define MAX_PIDSIZE 20 + #define FLAG_FILE AUTOFS_FLAG_DIR "/autofs-running" + +@@ -129,7 +129,7 @@ int aquire_flag_file(void) + while (!we_created_flagfile) { + int errsv, i, j; + +- i = open(linkf, O_WRONLY|O_CREAT, 0); ++ i = open_fd_mode(linkf, O_WRONLY|O_CREAT, 0); + if (i < 0) { + release_flag_file(); + return 0; +@@ -146,7 +146,7 @@ int aquire_flag_file(void) + return 0; + } + +- fd = open(FLAG_FILE, O_RDWR); ++ fd = open_fd(FLAG_FILE, O_RDWR); + if (fd < 0) { + /* Maybe the file was just deleted? */ + if (errno == ENOENT) +diff --git a/daemon/indirect.c b/daemon/indirect.c +index 1232810..9d3745c 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -21,12 +21,10 @@ + + #include + #include +-#include + #include + #include + #include + #include +-#include + #include + #include + #include +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 0cf6e3f..741d846 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + #include "automount.h" + #include "nsswitch.h" + +diff --git a/daemon/module.c b/daemon/module.c +index 36eca00..e593d75 100644 +--- a/daemon/module.c ++++ b/daemon/module.c +@@ -31,7 +31,7 @@ int load_autofs4_module(void) + * is an older version we will catch it at mount + * time. + */ +- fp = fopen("/proc/filesystems", "r"); ++ fp = open_fopen_r("/proc/filesystems"); + if (!fp) { + logerr("cannot open /proc/filesystems\n"); + return 0; +diff --git a/daemon/spawn.c b/daemon/spawn.c +index 17f92f4..4ddf46f 100644 +--- a/daemon/spawn.c ++++ b/daemon/spawn.c +@@ -13,7 +13,6 @@ + * + * ----------------------------------------------------------------------- */ + +-#include + #include + #include + #include +@@ -21,7 +20,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -125,7 +123,7 @@ static int do_spawn(unsigned logopt, unsigned int wait, + int ret, status, pipefd[2]; + char errbuf[ERRBUFSIZ + 1], *p, *sp; + int errp, errn; +- int flags, cancel_state; ++ int cancel_state; + unsigned int use_lock = options & SPAWN_OPT_LOCK; + unsigned int use_access = options & SPAWN_OPT_ACCESS; + sigset_t allsigs, tmpsig, oldsig; +@@ -133,7 +131,7 @@ static int do_spawn(unsigned logopt, unsigned int wait, + pid_t euid = 0; + gid_t egid = 0; + +- if (pipe(pipefd)) ++ if (open_pipe(pipefd)) + return -1; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state); +@@ -213,11 +211,6 @@ static int do_spawn(unsigned logopt, unsigned int wait, + return -1; + } + +- if ((flags = fcntl(pipefd[0], F_GETFD, 0)) != -1) { +- flags |= FD_CLOEXEC; +- fcntl(pipefd[0], F_SETFD, flags); +- } +- + errp = 0; + do { + errn = timed_read(pipefd[0], +diff --git a/include/automount.h b/include/automount.h +index 1ba0d3c..a55ddbc 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -17,6 +17,8 @@ + #include + #include + #include ++#include ++#include + #include "config.h" + #include "list.h" + +@@ -475,5 +477,109 @@ int alarm_start_handler(void); + int alarm_add(struct autofs_point *ap, time_t seconds); + void alarm_delete(struct autofs_point *ap); + ++/* ++ * Use CLOEXEC flag for open(), pipe(), fopen() (read-only case) and ++ * socket() if possible. ++ */ ++static int cloexec_works; ++ ++static inline void check_cloexec(int fd) ++{ ++ if (cloexec_works == 0) { ++ int fl = fcntl(fd, F_GETFD); ++ cloexec_works = (fl & FD_CLOEXEC) ? 1 : -1; ++ } ++ if (cloexec_works > 0) ++ return; ++ fcntl(fd, F_SETFD, FD_CLOEXEC); ++ return; ++} ++ ++static inline int open_fd(const char *path, int flags) ++{ ++ int fd; ++ ++#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) ++ if (cloexec_works != -1) ++ flags |= O_CLOEXEC; ++#endif ++ fd = open(path, flags); ++ if (fd == -1) ++ return -1; ++ check_cloexec(fd); ++ return fd; ++} ++ ++static inline int open_fd_mode(const char *path, int flags, int mode) ++{ ++ int fd; ++ ++#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) ++ if (cloexec_works != -1) ++ flags |= O_CLOEXEC; ++#endif ++ fd = open(path, flags, mode); ++ if (fd == -1) ++ return -1; ++ check_cloexec(fd); ++ return fd; ++} ++ ++static inline int open_pipe(int pipefd[2]) ++{ ++ int ret; ++ ++#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) && defined(__have_pipe2) ++ if (cloexec_works != -1) { ++ ret = pipe2(pipefd, O_CLOEXEC); ++ if (ret != -1) ++ return 0; ++ if (errno != EINVAL) ++ return -1; ++ } ++#endif ++ ret = pipe(pipefd); ++ if (ret == -1) ++ return -1; ++ check_cloexec(pipefd[0]); ++ check_cloexec(pipefd[1]); ++ return 0; ++} ++ ++static inline int open_sock(int domain, int type, int protocol) ++{ ++ int fd; ++ ++#ifdef SOCK_CLOEXEC ++ if (cloexec_works != -1) ++ type |= SOCK_CLOEXEC; ++#endif ++ fd = socket(domain, type, protocol); ++ if (fd == -1) ++ return -1; ++ check_cloexec(fd); ++ return fd; ++} ++ ++static inline FILE *open_fopen_r(const char *path) ++{ ++ FILE *f; ++ ++#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) ++ if (cloexec_works != -1) { ++ f = fopen(path, "re"); ++ if (f != NULL) { ++ check_cloexec(fileno(f)); ++ return f; ++ } ++ } ++#endif ++ f = fopen(path, "r"); ++ if (f == NULL) ++ return NULL; ++ check_cloexec(fileno(f)); ++ return f; ++} ++ + #endif + +diff --git a/include/state.h b/include/state.h +index d7349d9..b44a353 100644 +--- a/include/state.h ++++ b/include/state.h +@@ -20,7 +20,6 @@ + #ifndef STATE_H + #define STATE_H + +-#include + #include + #include + #include +diff --git a/lib/cache.c b/lib/cache.c +index ce47e04..4a00367 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -17,10 +17,8 @@ + #include + #include + #include +-#include + #include + #include +-#include + #include + #include + #include +diff --git a/lib/defaults.c b/lib/defaults.c +index 21d76d2..ff653e3 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -21,6 +21,7 @@ + #include "defaults.h" + #include "lookup_ldap.h" + #include "log.h" ++#include "automount.h" + + #define DEFAULTS_CONFIG_FILE AUTOFS_CONF_DIR "/autofs" + #define MAX_LINE_LEN 256 +@@ -255,7 +256,7 @@ struct list_head *defaults_get_uris(void) + char *res; + struct list_head *list; + +- f = fopen(DEFAULTS_CONFIG_FILE, "r"); ++ f = open_fopen_r(DEFAULTS_CONFIG_FILE); + if (!f) + return NULL; + +@@ -298,7 +299,7 @@ unsigned int defaults_read_config(unsigned int to_syslog) + char buf[MAX_LINE_LEN]; + char *res; + +- f = fopen(DEFAULTS_CONFIG_FILE, "r"); ++ f = open_fopen_r(DEFAULTS_CONFIG_FILE); + if (!f) + return 0; + +@@ -544,7 +545,7 @@ struct ldap_searchdn *defaults_get_searchdns(void) + char *res; + struct ldap_searchdn *sdn, *last; + +- f = fopen(DEFAULTS_CONFIG_FILE, "r"); ++ f = open_fopen_r(DEFAULTS_CONFIG_FILE); + if (!f) + return NULL; + +diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c +index 57af785..056a0a9 100644 +--- a/lib/dev-ioctl-lib.c ++++ b/lib/dev-ioctl-lib.c +@@ -121,17 +121,12 @@ void init_ioctl_ctl(void) + if (ctl.ops) + return; + +- devfd = open(CONTROL_DEVICE, O_RDONLY); ++ devfd = open_fd(CONTROL_DEVICE, O_RDONLY); + if (devfd == -1) + ctl.ops = &ioctl_ops; + else { + struct autofs_dev_ioctl param; + +- int cl_flags = fcntl(devfd, F_GETFD, 0); +- if (cl_flags != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(devfd, F_SETFD, cl_flags); +- } + /* + * Check compile version against kernel. + * Selinux may allow us to open the device but not +@@ -378,20 +373,14 @@ static int ioctl_open(unsigned int logopt, + int *ioctlfd, dev_t devid, const char *path) + { + struct statfs sfs; +- int save_errno, fd, cl_flags; ++ int save_errno, fd; + + *ioctlfd = -1; + +- fd = open(path, O_RDONLY); ++ fd = open_fd(path, O_RDONLY); + if (fd == -1) + return -1; + +- cl_flags = fcntl(fd, F_GETFD, 0); +- if (cl_flags != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + if (fstatfs(fd, &sfs) == -1) { + save_errno = errno; + goto err; +diff --git a/lib/log.c b/lib/log.c +index 65e8ad2..46220fd 100644 +--- a/lib/log.c ++++ b/lib/log.c +@@ -20,8 +20,6 @@ + + #include + #include +-#include +-#include + #include + #include + +diff --git a/lib/macros.c b/lib/macros.c +index fa6db8e..85f9cd3 100644 +--- a/lib/macros.c ++++ b/lib/macros.c +@@ -14,7 +14,6 @@ + * ----------------------------------------------------------------------- */ + + #include +-#include + #include + #include + #include +diff --git a/lib/mounts.c b/lib/mounts.c +index 6d0a69c..ce4691b 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -14,13 +14,11 @@ + + #include + #include +-#include + #include + #include + #include + #include + #include +-#include + #include + #include + #include +diff --git a/lib/nss_parse.y b/lib/nss_parse.y +index fa6958a..3bda6b3 100644 +--- a/lib/nss_parse.y ++++ b/lib/nss_parse.y +@@ -22,8 +22,6 @@ + #include + #include + #include +-#include +-#include + #include + + #include "automount.h" +@@ -164,9 +162,9 @@ static void parse_close_nsswitch(void *arg) + int nsswitch_parse(struct list_head *list) + { + FILE *nsswitch; +- int fd, cl_flags, status; ++ int status; + +- nsswitch = fopen(NSSWITCH_FILE, "r"); ++ nsswitch = open_fopen_r(NSSWITCH_FILE); + if (!nsswitch) { + logerr("couldn't open %s\n", NSSWITCH_FILE); + return 1; +@@ -174,13 +172,6 @@ int nsswitch_parse(struct list_head *list) + + pthread_cleanup_push(parse_close_nsswitch, nsswitch); + +- fd = fileno(nsswitch); +- +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + parse_mutex_lock(); + pthread_cleanup_push(parse_mutex_unlock, NULL); + +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index 3a04dd6..8a032e8 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -18,7 +18,6 @@ + #include + #include + #include +-#include + #include "automount.h" + + /* +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 6be86c6..9ac3657 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -21,13 +21,11 @@ + #include + #include + +-#include + #include + #include + #include + #include + #include +-#include + #include + #include + #include +@@ -36,6 +34,7 @@ + + #include "mount.h" + #include "rpc_subs.h" ++#include "automount.h" + + /* #define STANDALONE */ + #ifdef STANDALONE +@@ -59,7 +58,7 @@ inline void dump_core(void); + */ + static CLIENT *create_udp_client(struct conn_info *info) + { +- int fd, cl_flags, ret, ghn_errno; ++ int fd, ret, ghn_errno; + CLIENT *client; + struct sockaddr_in laddr, raddr; + struct hostent hp; +@@ -115,15 +114,10 @@ got_addr: + * layer, it would bind to a reserved port, which has been shown + * to exhaust the reserved port range in some situations. + */ +- fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); ++ fd = open_sock(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (fd < 0) + return NULL; + +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + laddr.sin_family = AF_INET; + laddr.sin_port = 0; + laddr.sin_addr.s_addr = htonl(INADDR_ANY); +@@ -274,7 +268,7 @@ done: + */ + static CLIENT *create_tcp_client(struct conn_info *info) + { +- int fd, cl_flags, ghn_errno; ++ int fd, ghn_errno; + CLIENT *client; + struct sockaddr_in addr; + struct hostent hp; +@@ -324,15 +318,10 @@ got_addr: + addr.sin_port = htons(info->port); + + if (!info->client) { +- fd = socket(PF_INET, SOCK_STREAM, info->proto->p_proto); ++ fd = open_sock(PF_INET, SOCK_STREAM, info->proto->p_proto); + if (fd < 0) + return NULL; + +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + ret = connect_nb(fd, &addr, &info->timeout); + if (ret < 0) + goto out_close; +diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c +index 902d9aa..286af15 100644 +--- a/modules/cyrus-sasl.c ++++ b/modules/cyrus-sasl.c +@@ -51,7 +51,6 @@ + #include + #include + #include +-#include + #include + #include + +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index 9e34b72..95b9f6f 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -17,8 +17,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include +@@ -395,7 +393,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + char *ent; + struct stat st; + FILE *f; +- int fd, cl_flags; ++ int fd; + unsigned int path_len, ent_len; + int entry, cur_state; + +@@ -422,7 +420,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + return NSS_STATUS_UNAVAIL; + } + +- f = fopen(ctxt->mapname, "r"); ++ f = open_fopen_r(ctxt->mapname); + if (!f) { + error(logopt, + MODPREFIX "could not open master map file %s", +@@ -432,11 +430,6 @@ int lookup_read_master(struct master *master, time_t age, void *context) + + fd = fileno(f); + +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + while(1) { + entry = read_one(logopt, f, path, &path_len, ent, &ent_len); + if (!entry) { +@@ -651,7 +644,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + char *mapent; + struct stat st; + FILE *f; +- int fd, cl_flags; ++ int fd; + unsigned int k_len, m_len; + int entry; + +@@ -684,7 +677,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + return NSS_STATUS_UNAVAIL; + } + +- f = fopen(ctxt->mapname, "r"); ++ f = open_fopen_r(ctxt->mapname); + if (!f) { + error(ap->logopt, + MODPREFIX "could not open map file %s", ctxt->mapname); +@@ -693,11 +686,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + + fd = fileno(f); + +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + while(1) { + entry = read_one(ap->logopt, f, key, &k_len, mapent, &m_len); + if (!entry) { +@@ -784,7 +772,6 @@ static int lookup_one(struct autofs_point *ap, + char mapent[MAPENT_MAX_LEN + 1]; + time_t age = time(NULL); + FILE *f; +- int fd, cl_flags; + unsigned int k_len, m_len; + int entry, ret; + +@@ -794,20 +781,13 @@ static int lookup_one(struct autofs_point *ap, + + mc = source->mc; + +- f = fopen(ctxt->mapname, "r"); ++ f = open_fopen_r(ctxt->mapname); + if (!f) { + error(ap->logopt, + MODPREFIX "could not open map file %s", ctxt->mapname); + return CHE_FAIL; + } + +- fd = fileno(f); +- +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + while(1) { + entry = read_one(ap->logopt, f, mkey, &k_len, mapent, &m_len); + if (entry) { +@@ -897,7 +877,6 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt) + char mapent[MAPENT_MAX_LEN + 1]; + time_t age = time(NULL); + FILE *f; +- int fd, cl_flags; + unsigned int k_len, m_len; + int entry, ret; + +@@ -907,20 +886,13 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt) + + mc = source->mc; + +- f = fopen(ctxt->mapname, "r"); ++ f = open_fopen_r(ctxt->mapname); + if (!f) { + error(ap->logopt, + MODPREFIX "could not open map file %s", ctxt->mapname); + return CHE_FAIL; + } + +- fd = fileno(f); +- +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + while(1) { + entry = read_one(ap->logopt, f, mkey, &k_len, mapent, &m_len); + if (entry) { +diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c +index 737a47e..0a2ee44 100644 +--- a/modules/lookup_hesiod.c ++++ b/modules/lookup_hesiod.c +@@ -10,7 +10,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index f8d4269..93b975a 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -15,7 +15,6 @@ + + #include + #include +-#include + #include + #include + #include +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 42c3235..6ba80eb 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -21,7 +21,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index 601d48e..1bf2e0a 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -18,7 +18,6 @@ + #include + #include + #include +-#include + #include + + #define MODULE_LOOKUP +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index f15465f..4c3ce60 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -6,7 +6,6 @@ + + #include + #include +-#include + #include + #include + #include +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index bf32d3b..6f4e2a3 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -18,7 +18,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -212,12 +211,12 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + * want to send stderr to the syslog, and we don't use spawnl() + * because we need the pipe hooks + */ +- if (pipe(pipefd)) { ++ if (open_pipe(pipefd)) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr(MODPREFIX "pipe: %s", estr); + goto out_free; + } +- if (pipe(epipefd)) { ++ if (open_pipe(epipefd)) { + close(pipefd[0]); + close(pipefd[1]); + goto out_free; +diff --git a/modules/lookup_userhome.c b/modules/lookup_userhome.c +index 680ddaf..fb3caaa 100644 +--- a/modules/lookup_userhome.c ++++ b/modules/lookup_userhome.c +@@ -16,7 +16,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index 1b62f57..ce438e8 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -16,7 +16,6 @@ + + #include + #include +-#include + #include + #include + #include +diff --git a/modules/mount_afs.c b/modules/mount_afs.c +index 96a1367..50628ce 100644 +--- a/modules/mount_afs.c ++++ b/modules/mount_afs.c +@@ -9,8 +9,6 @@ + + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c +index eb63d8e..82a5ef3 100644 +--- a/modules/mount_autofs.c ++++ b/modules/mount_autofs.c +@@ -16,8 +16,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/mount_bind.c b/modules/mount_bind.c +index 022d183..361f0c2 100644 +--- a/modules/mount_bind.c ++++ b/modules/mount_bind.c +@@ -15,8 +15,6 @@ + + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/mount_changer.c b/modules/mount_changer.c +index 43b8355..92bb72b 100644 +--- a/modules/mount_changer.c ++++ b/modules/mount_changer.c +@@ -19,8 +19,6 @@ + + #include + #include +-#include +-#include + #include + #include + #include +@@ -145,25 +143,19 @@ int swapCD(const char *device, const char *slotName) + { + int fd; /* file descriptor for CD-ROM device */ + int status; /* return status for system calls */ +- int cl_flags; + int slot = -1; + int total_slots_available; + + slot = atoi(slotName) - 1; + + /* open device */ +- fd = open(device, O_RDONLY | O_NONBLOCK); ++ fd = open_fd(device, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + logerr(MODPREFIX "Opening device %s failed : %s", + device, strerror(errno)); + return 1; + } + +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + /* Check CD player status */ + total_slots_available = ioctl(fd, CDROM_CHANGER_NSLOTS); + if (total_slots_available <= 1) { +diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c +index 4c5b271..192ec04 100644 +--- a/modules/mount_ext2.c ++++ b/modules/mount_ext2.c +@@ -15,8 +15,6 @@ + + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/mount_generic.c b/modules/mount_generic.c +index f094d07..6d7b4b3 100644 +--- a/modules/mount_generic.c ++++ b/modules/mount_generic.c +@@ -15,8 +15,6 @@ + + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index c747078..20732f8 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -17,8 +17,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/parse_hesiod.c b/modules/parse_hesiod.c +index ff1f0a5..d5bb0f4 100644 +--- a/modules/parse_hesiod.c ++++ b/modules/parse_hesiod.c +@@ -7,7 +7,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 2c4f8b2..72e51e2 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -18,8 +18,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/replicated.c b/modules/replicated.c +index b435f4b..63829a2 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -52,8 +52,6 @@ + #include + #include + #include +-#include +-#include + + #include "rpc_subs.h" + #include "replicated.h" +@@ -82,7 +80,7 @@ void seed_random(void) + int fd; + unsigned int seed; + +- fd = open("/dev/urandom", O_RDONLY); ++ fd = open_fd("/dev/urandom", O_RDONLY); + if (fd < 0) { + srandom(time(NULL)); + return; +@@ -145,7 +143,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) + char tmp[20], buf[MAX_ERR_BUF], *ptr; + struct ifconf ifc; + struct ifreq *ifr, nmptr; +- int sock, cl_flags, ret, i; ++ int sock, ret, i; + uint32_t mask, ha, ia; + + memcpy(tmp, host_addr, addr_len); +@@ -153,18 +151,13 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) + + ha = ntohl((uint32_t) hst_addr->s_addr); + +- sock = socket(AF_INET, SOCK_DGRAM, 0); ++ sock = open_sock(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr("socket creation failed: %s", estr); + return PROXIMITY_ERROR; + } + +- if ((cl_flags = fcntl(sock, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(sock, F_SETFD, cl_flags); +- } +- + if (!alloc_ifreq(&ifc, sock)) { + close(sock); + return PROXIMITY_ERROR; diff --git a/autofs-5.0.4-use-intr-as-hosts-mount-default.patch b/autofs-5.0.4-use-intr-as-hosts-mount-default.patch new file mode 100644 index 0000000..94ae5cc --- /dev/null +++ b/autofs-5.0.4-use-intr-as-hosts-mount-default.patch @@ -0,0 +1,82 @@ +autofs-5.0.4 - use intr option as hosts mount default + +From: Ian Kent + +Use the "intr" option as default mount option for the hosts map +unless explicily overridden. +--- + + CHANGELOG | 1 + + man/auto.master.5.in | 5 +++-- + modules/parse_sun.c | 11 +++++++---- + 3 files changed, 11 insertions(+), 6 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 8258e00..a42dd14 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -41,6 +41,7 @@ + - reset flex scanner when setting buffer. + - zero s_magic is valid. + - use percent hack for master map keys. ++- use intr option as hosts mount default. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/man/auto.master.5.in b/man/auto.master.5.in +index aaa6324..7b7004f 100644 +--- a/man/auto.master.5.in ++++ b/man/auto.master.5.in +@@ -208,8 +208,9 @@ For example, with an entry in the master map of + accessing /net/myserver will mount exports from myserver on directories below + /net/myserver. + .P +-NOTE: mounts done from a hosts map will be mounted with the "nosuid" and "nodev" options +-unless the options "suid" and "dev" are explicitly given in the master map entry. ++NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev,intr" options ++unless overridden by explicily specifying the "suid", "dev" or "nointr" options in the ++master map entry. + .SH LDAP MAPS + If the map type \fBldap\fP is specified the mapname is of the form + \fB[//servername/]dn\fP, where the optional \fBservername\fP is +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 65417e1..db36ae2 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -607,9 +607,10 @@ static int sun_mount(struct autofs_point *ap, const char *root, + int len = strlen(options); + int suid = strstr(options, "suid") ? 0 : 7; + int dev = strstr(options, "dev") ? 0 : 6; ++ int nointr = strstr(options, "nointr") ? 0 : 5; + +- if (suid || dev) { +- char *tmp = alloca(len + suid + dev + 1); ++ if (suid || dev || nointr) { ++ char *tmp = alloca(len + suid + dev + nointr + 1); + if (!tmp) { + error(ap->logopt, MODPREFIX + "alloca failed for options"); +@@ -623,10 +624,12 @@ static int sun_mount(struct autofs_point *ap, const char *root, + strcat(tmp, ",nosuid"); + if (dev) + strcat(tmp, ",nodev"); ++ if (nointr) ++ strcat(tmp, ",intr"); + options = tmp; + } + } else { +- char *tmp = alloca(13); ++ char *tmp = alloca(18); + if (!tmp) { + error(ap->logopt, + MODPREFIX "alloca failed for options"); +@@ -634,7 +637,7 @@ static int sun_mount(struct autofs_point *ap, const char *root, + return -1; + return 1; + } +- strcpy(tmp, "nosuid,nodev"); ++ strcpy(tmp, "nosuid,nodev,intr"); + options = tmp; + } + } diff --git a/autofs-5.0.4-use-misc-device.patch b/autofs-5.0.4-use-misc-device.patch new file mode 100644 index 0000000..1a1655b --- /dev/null +++ b/autofs-5.0.4-use-misc-device.patch @@ -0,0 +1,52 @@ +autofs-5.0.4 - use misc device + +From: Ian Kent + +Change default installed configuration to use the misc device ioctl +interface if available. +--- + + CHANGELOG | 1 + + redhat/autofs.sysconfig.in | 2 +- + samples/autofs.conf.default.in | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index da7ecbf..96a4617 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -32,6 +32,7 @@ + - another easy alloca replacements fix. + - add LSB init script parameter block. + - fix file map lookup when reading included or nsswitch sources. ++- use misc device ioctl interface by default, if available. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in +index 04e521c..97e20fe 100644 +--- a/redhat/autofs.sysconfig.in ++++ b/redhat/autofs.sysconfig.in +@@ -110,7 +110,7 @@ BROWSE_MODE="no" + # If the kernel supports using the autofs miscellanous device + # and you wish to use it you must set this configuration option + # to "yes" otherwise it will not be used. +-#USE_MISC_DEVICE="no" ++USE_MISC_DEVICE="yes" + # + #OPTIONS="" + # +diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in +index 52d18ec..62084c2 100644 +--- a/samples/autofs.conf.default.in ++++ b/samples/autofs.conf.default.in +@@ -110,7 +110,7 @@ BROWSE_MODE="no" + # If the kernel supports using the autofs miscellanous device + # and you wish to use it you must set this configuration option + # to "yes" otherwise it will not be used. +-#USE_MISC_DEVICE="no" ++USE_MISC_DEVICE="yes" + # + #OPTIONS="" + # diff --git a/autofs-5.0.4-use-percent-hack-for-master.patch b/autofs-5.0.4-use-percent-hack-for-master.patch new file mode 100644 index 0000000..73fbf6c --- /dev/null +++ b/autofs-5.0.4-use-percent-hack-for-master.patch @@ -0,0 +1,136 @@ +autofs-5.0.4 - use percent hack for master map keys + +From: Ian Kent + +The percent hack translation has been done for map keys but it +isn't used for master map keys. +--- + + CHANGELOG | 1 + + modules/lookup_ldap.c | 66 +++++++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 59 insertions(+), 8 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 4ed80e0..8258e00 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -40,6 +40,7 @@ + - fix st_remove_tasks() locking. + - reset flex scanner when setting buffer. + - zero s_magic is valid. ++- use percent hack for master map keys. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 9b1180c..8c6a8f2 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -60,6 +60,7 @@ struct ldap_search_params { + }; + + static LDAP *auth_init(unsigned logopt, const char *, struct lookup_context *); ++static int decode_percent_hack(const char *, char **); + + #ifndef HAVE_LDAP_CREATE_PAGE_CONTROL + int ldap_create_page_control(LDAP *ldap, ber_int_t pagesize, +@@ -1508,6 +1509,9 @@ int lookup_read_master(struct master *master, time_t age, void *context) + debug(logopt, MODPREFIX "examining entries"); + + while (e) { ++ char *key = NULL; ++ int dec_len, i; ++ + keyValue = ldap_get_values(ldap, e, entry); + + if (!keyValue || !*keyValue) { +@@ -1519,19 +1523,63 @@ int lookup_read_master(struct master *master, time_t age, void *context) + * By definition keys must be unique within + * each map entry + */ +- if (ldap_count_values(keyValue) > 1) { +- error(logopt, +- MODPREFIX +- "key %s has duplicate entries - ignoring", +- *keyValue); +- goto next; ++ count = ldap_count_values(keyValue); ++ if (strcasecmp(class, "nisObject")) { ++ if (count > 1) { ++ error(logopt, MODPREFIX ++ "key %s has duplicates - ignoring", ++ *keyValue); ++ goto next; ++ } ++ key = strdup(keyValue[0]); ++ if (!key) { ++ error(logopt, MODPREFIX ++ "failed to dup map key %s - ignoring", ++ *keyValue); ++ goto next; ++ } ++ } else if (count == 1) { ++ dec_len = decode_percent_hack(keyValue[0], &key); ++ if (dec_len < 0) { ++ error(logopt, MODPREFIX ++ "invalid map key %s - ignoring", ++ *keyValue); ++ goto next; ++ } ++ } else { ++ dec_len = decode_percent_hack(keyValue[0], &key); ++ if (dec_len < 0) { ++ error(logopt, MODPREFIX ++ "invalid map key %s - ignoring", ++ *keyValue); ++ goto next; ++ } ++ ++ for (i = 1; i < count; i++) { ++ char *k; ++ dec_len = decode_percent_hack(keyValue[i], &k); ++ if (dec_len < 0) { ++ error(logopt, MODPREFIX ++ "invalid map key %s - ignoring", ++ *keyValue); ++ goto next; ++ } ++ if (strcmp(key, k)) { ++ error(logopt, MODPREFIX ++ "key entry mismatch %s - ignoring", ++ *keyValue); ++ free(k); ++ goto next; ++ } ++ free(k); ++ } + } + + /* + * Ignore keys beginning with '+' as plus map + * inclusion is only valid in file maps. + */ +- if (**keyValue == '+') { ++ if (*key == '+') { + warn(logopt, + MODPREFIX + "ignoreing '+' map entry - not in file map"); +@@ -1558,7 +1606,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + } + + if (snprintf(parse_buf, sizeof(parse_buf), "%s %s", +- *keyValue, *values) >= sizeof(parse_buf)) { ++ key, *values) >= sizeof(parse_buf)) { + error(logopt, MODPREFIX "map entry too long"); + ldap_value_free(values); + goto next; +@@ -1568,6 +1616,8 @@ int lookup_read_master(struct master *master, time_t age, void *context) + master_parse_entry(parse_buf, timeout, logging, age); + next: + ldap_value_free(keyValue); ++ if (key) ++ free(key); + e = ldap_next_entry(ldap, e); + } + diff --git a/autofs-5.0.4-use-srv-query-for-domain-dn.patch b/autofs-5.0.4-use-srv-query-for-domain-dn.patch new file mode 100644 index 0000000..6ab088e --- /dev/null +++ b/autofs-5.0.4-use-srv-query-for-domain-dn.patch @@ -0,0 +1,1097 @@ +autofs-5.0.4 - use srv query for domain dn + +From: Ian Kent + +Add the ability to use a domain dn in the LDAP_URI configuration +entry. If a domain dn is encountered in the LDAP_URI the list of +servers will be queried and used for the LDAP connection. The list +won't be queried again until the minimum ttl found in the SRV RR +records is reached or, if ttl isn't given in any SRV RR records, +after 1 hour. +--- + + CHANGELOG | 1 + include/dclist.h | 14 + + include/lookup_ldap.h | 3 + man/auto.master.5.in | 8 + modules/Makefile | 5 + modules/dclist.c | 785 ++++++++++++++++++++++++++++++++++++++++ + modules/lookup_ldap.c | 86 ++++ + redhat/autofs.sysconfig.in | 11 + + samples/autofs.conf.default.in | 11 + + 9 files changed, 911 insertions(+), 13 deletions(-) + create mode 100644 include/dclist.h + create mode 100644 modules/dclist.c + + +diff --git a/CHANGELOG b/CHANGELOG +index 5000f0c..f49784a 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -49,6 +49,7 @@ + - dont fail on ipv6 address when adding host. + - always read file maps multi map fix. + - always read file maps key lookup fixes. ++- use srv query for domain dn. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/include/dclist.h b/include/dclist.h +new file mode 100644 +index 0000000..ed89f97 +--- /dev/null ++++ b/include/dclist.h +@@ -0,0 +1,14 @@ ++#ifndef __DCLIST_H ++#define __DCLIST_H ++ ++#include ++ ++struct dclist { ++ time_t expire; ++ const char *uri; ++}; ++ ++struct dclist *get_dc_list(unsigned int logopt, const char *uri); ++void free_dclist(struct dclist *dclist); ++ ++#endif +diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h +index b47bf5d..dcae220 100644 +--- a/include/lookup_ldap.h ++++ b/include/lookup_ldap.h +@@ -10,6 +10,8 @@ + #include + #endif + ++#include "dclist.h" ++ + struct ldap_schema { + char *map_class; + char *map_attr; +@@ -57,6 +59,7 @@ struct lookup_context { + pthread_mutex_t uris_mutex; + struct list_head *uris; + struct ldap_uri *uri; ++ struct dclist *dclist; + char *cur_host; + struct ldap_searchdn *sdns; + +diff --git a/man/auto.master.5.in b/man/auto.master.5.in +index 7b7004f..71c4402 100644 +--- a/man/auto.master.5.in ++++ b/man/auto.master.5.in +@@ -271,6 +271,14 @@ Map entries that include a server name override this option and it is then + not used. Default is an empty list in which case either the server given + in a map entry or the LDAP configured default is used. This uri list is read at + startup and whenever the daemon receives a HUP signal. ++.P ++This configuration option can also be used to request autofs lookup SRV RRs ++for a domain of the form :///[]. Note that a trailing ++"/" is not allowed when using this form. If the domain dn is not specified ++the dns domain name (if any) is used to construct the domain dn for the ++SRV RR lookup. The server list returned from an SRV RR lookup is refreshed ++according to the minimum ttl found in the SRV RR records or after one hour, ++whichever is less. + .TP + .B SEARCH_BASE + The base dn to use when searching for amap base dn. This entry may be +diff --git a/modules/Makefile b/modules/Makefile +index 0d12f01..13b3bd8 100644 +--- a/modules/Makefile ++++ b/modules/Makefile +@@ -86,9 +86,10 @@ lookup_hesiod.so: lookup_hesiod.c + cyrus-sasl.o: cyrus-sasl.c + $(CC) $(CFLAGS) $(LDAP_FLAGS) -c $< + +-lookup_ldap.so: lookup_ldap.c $(SASL_OBJ) ++lookup_ldap.so: lookup_ldap.c dclist.o $(SASL_OBJ) + $(CC) $(SOLDFLAGS) $(CFLAGS) $(LDAP_FLAGS) -o lookup_ldap.so \ +- lookup_ldap.c $(SASL_OBJ) $(AUTOFS_LIB) $(LIBLDAP) ++ lookup_ldap.c dclist.o $(SASL_OBJ) \ ++ $(AUTOFS_LIB) $(LIBLDAP) $(LIBRESOLV) + $(STRIP) lookup_ldap.so + + mount_nfs.so: mount_nfs.c replicated.o +diff --git a/modules/dclist.c b/modules/dclist.c +new file mode 100644 +index 0000000..5b0e577 +--- /dev/null ++++ b/modules/dclist.c +@@ -0,0 +1,785 @@ ++/* ++ * Copyright 2009 Ian Kent ++ * Copyright 2009 Red Hat, Inc. ++ * ++ * This module was apapted from code contained in the Samba distribution ++ * file source/libads/dns.c which contained the following copyright ++ * information: ++ * ++ * Unix SMB/CIFS implementation. ++ * DNS utility library ++ * Copyright (C) Gerald (Jerry) Carter 2006. ++ * Copyright (C) Jeremy Allison 2007. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "automount.h" ++#include "dclist.h" ++ ++#define MAX_DNS_PACKET_SIZE 0xffff ++#define MAX_DNS_NAME_LENGTH MAXHOSTNAMELEN ++/* The longest time we will cache dns srv records */ ++#define MAX_TTL (60*60*1) /* 1 hours */ ++ ++#ifdef NS_HFIXEDSZ /* Bind 8/9 interface */ ++#if !defined(C_IN) /* AIX 5.3 already defines C_IN */ ++# define C_IN ns_c_in ++#endif ++#if !defined(T_A) /* AIX 5.3 already defines T_A */ ++# define T_A ns_t_a ++#endif ++ ++# define T_SRV ns_t_srv ++#if !defined(T_NS) /* AIX 5.3 already defines T_NS */ ++# define T_NS ns_t_ns ++#endif ++#else ++# ifdef HFIXEDSZ ++# define NS_HFIXEDSZ HFIXEDSZ ++# else ++# define NS_HFIXEDSZ sizeof(HEADER) ++# endif /* HFIXEDSZ */ ++# ifdef PACKETSZ ++# define NS_PACKETSZ PACKETSZ ++# else /* 512 is usually the default */ ++# define NS_PACKETSZ 512 ++# endif /* PACKETSZ */ ++# define T_SRV 33 ++#endif ++ ++#define SVAL(buf, pos) (*(const uint16_t *)((const char *)(buf) + (pos))) ++#define IVAL(buf, pos) (*(const uint32_t *)((const char *)(buf) + (pos))) ++ ++#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) ++#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16))) ++ ++#define RSVAL(buf, pos) SREV(SVAL(buf, pos)) ++#define RIVAL(buf, pos) IREV(IVAL(buf, pos)) ++ ++#define QSORT_CAST (int (*)(const void *, const void *)) ++ ++/* DNS query section in replies */ ++ ++struct dns_query { ++ const char *hostname; ++ uint16_t type; ++ uint16_t in_class; ++}; ++ ++/* DNS RR record in reply */ ++ ++struct dns_rr { ++ const char *hostname; ++ uint16_t type; ++ uint16_t in_class; ++ uint32_t ttl; ++ uint16_t rdatalen; ++ uint8_t *rdata; ++}; ++ ++/* SRV records */ ++ ++struct dns_rr_srv { ++ const char *hostname; ++ uint16_t priority; ++ uint16_t weight; ++ uint16_t port; ++ uint32_t ttl; ++}; ++ ++static pthread_mutex_t dclist_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++static void dclist_mutex_lock(void) ++{ ++ int status = pthread_mutex_lock(&dclist_mutex); ++ if (status) ++ fatal(status); ++ return; ++} ++ ++static void dclist_mutex_unlock(void) ++{ ++ int status = pthread_mutex_unlock(&dclist_mutex); ++ if (status) ++ fatal(status); ++ return; ++} ++ ++static int dns_parse_query(unsigned int logopt, ++ uint8_t *start, uint8_t *end, ++ uint8_t **ptr, struct dns_query *q) ++{ ++ uint8_t *p = *ptr; ++ char hostname[MAX_DNS_NAME_LENGTH]; ++ char buf[MAX_ERR_BUF]; ++ int namelen; ++ ++ if (!start || !end || !q || !*ptr) ++ return 0; ++ ++ memset(q, 0, sizeof(*q)); ++ ++ /* See RFC 1035 for details. If this fails, then return. */ ++ ++ namelen = dn_expand(start, end, p, hostname, sizeof(hostname)); ++ if (namelen < 0) { ++ error(logopt, "failed to expand query hostname"); ++ return 0; ++ } ++ ++ p += namelen; ++ q->hostname = strdup(hostname); ++ if (!q) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "strdup: %s", estr); ++ return 0; ++ } ++ ++ /* check that we have space remaining */ ++ ++ if (p + 4 > end) { ++ error(logopt, "insufficient buffer space for result"); ++ free((void *) q->hostname); ++ return 0; ++ } ++ ++ q->type = RSVAL(p, 0); ++ q->in_class = RSVAL(p, 2); ++ p += 4; ++ ++ *ptr = p; ++ ++ return 1; ++} ++ ++static int dns_parse_rr(unsigned int logopt, ++ uint8_t *start, uint8_t *end, ++ uint8_t **ptr, struct dns_rr *rr) ++{ ++ uint8_t *p = *ptr; ++ char hostname[MAX_DNS_NAME_LENGTH]; ++ char buf[MAX_ERR_BUF]; ++ int namelen; ++ ++ if (!start || !end || !rr || !*ptr) ++ return 0; ++ ++ memset(rr, 0, sizeof(*rr)); ++ ++ /* pull the name from the answer */ ++ ++ namelen = dn_expand(start, end, p, hostname, sizeof(hostname)); ++ if (namelen < 0) { ++ error(logopt, "failed to expand query hostname"); ++ return 0; ++ } ++ p += namelen; ++ rr->hostname = strdup(hostname); ++ if (!rr->hostname) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "strdup: %s", estr); ++ return 0; ++ } ++ ++ /* check that we have space remaining */ ++ ++ if (p + 10 > end) { ++ error(logopt, "insufficient buffer space for result"); ++ free((void *) rr->hostname); ++ return 0; ++ } ++ ++ /* pull some values and then skip onto the string */ ++ ++ rr->type = RSVAL(p, 0); ++ rr->in_class = RSVAL(p, 2); ++ rr->ttl = RIVAL(p, 4); ++ rr->rdatalen = RSVAL(p, 8); ++ ++ p += 10; ++ ++ /* sanity check the available space */ ++ ++ if (p + rr->rdatalen > end) { ++ error(logopt, "insufficient buffer space for data"); ++ free((void *) rr->hostname); ++ return 0; ++ } ++ ++ /* save a point to the rdata for this section */ ++ ++ rr->rdata = p; ++ p += rr->rdatalen; ++ ++ *ptr = p; ++ ++ return 1; ++} ++ ++static int dns_parse_rr_srv(unsigned int logopt, ++ uint8_t *start, uint8_t *end, ++ uint8_t **ptr, struct dns_rr_srv *srv) ++{ ++ struct dns_rr rr; ++ uint8_t *p; ++ char dcname[MAX_DNS_NAME_LENGTH]; ++ char buf[MAX_ERR_BUF]; ++ int namelen; ++ ++ if (!start || !end || !srv || !*ptr) ++ return 0; ++ ++ /* Parse the RR entry. Coming out of the this, ptr is at the beginning ++ of the next record */ ++ ++ if (!dns_parse_rr(logopt, start, end, ptr, &rr)) { ++ error(logopt, "Failed to parse RR record"); ++ return 0; ++ } ++ ++ if (rr.type != T_SRV) { ++ error(logopt, "Bad answer type (%d)", rr.type); ++ return 0; ++ } ++ ++ p = rr.rdata; ++ ++ srv->priority = RSVAL(p, 0); ++ srv->weight = RSVAL(p, 2); ++ srv->port = RSVAL(p, 4); ++ srv->ttl = rr.ttl; ++ ++ p += 6; ++ ++ namelen = dn_expand(start, end, p, dcname, sizeof(dcname)); ++ if (namelen < 0) { ++ error(logopt, "Failed to expand dcname"); ++ return 0; ++ } ++ ++ srv->hostname = strdup(dcname); ++ if (!srv->hostname) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "strdup: %s", estr); ++ return 0; ++ } ++ ++ debug(logopt, "Parsed %s [%u, %u, %u]", ++ srv->hostname, srv->priority, srv->weight, srv->port); ++ ++ return 1; ++} ++ ++/********************************************************************* ++ Sort SRV record list based on weight and priority. See RFC 2782. ++*********************************************************************/ ++ ++static int dnssrvcmp(struct dns_rr_srv *a, struct dns_rr_srv *b) ++{ ++ if (a->priority == b->priority) { ++ /* randomize entries with an equal weight and priority */ ++ if (a->weight == b->weight) ++ return 0; ++ ++ /* higher weights should be sorted lower */ ++ if (a->weight > b->weight) ++ return -1; ++ else ++ return 1; ++ } ++ ++ if (a->priority < b->priority) ++ return -1; ++ ++ return 1; ++} ++ ++#define DNS_FAILED_WAITTIME 30 ++ ++static int dns_send_req(unsigned int logopt, ++ const char *name, int q_type, uint8_t **rbuf, ++ int *resp_length) ++{ ++ uint8_t *buffer = NULL; ++ size_t buf_len = 0; ++ int resp_len = NS_PACKETSZ; ++ static time_t last_dns_check = 0; ++ static unsigned int last_dns_status = 0; ++ time_t now = time(NULL); ++ char buf[MAX_ERR_BUF]; ++ ++ /* Try to prevent bursts of DNS lookups if the server is down */ ++ ++ /* Protect against large clock changes */ ++ ++ if (last_dns_check > now) ++ last_dns_check = 0; ++ ++ /* IF we had a DNS timeout or a bad server and we are still ++ in the 30 second cache window, just return the previous ++ status and save the network timeout. */ ++ ++ if ((last_dns_status == ETIMEDOUT || ++ last_dns_status == ECONNREFUSED) && ++ ((last_dns_check + DNS_FAILED_WAITTIME) > now)) { ++ char *estr = strerror_r(last_dns_status, buf, MAX_ERR_BUF); ++ debug(logopt, "Returning cached status (%s)", estr); ++ return last_dns_status; ++ } ++ ++ /* Send the Query */ ++ do { ++ if (buffer) ++ free(buffer); ++ ++ buf_len = resp_len * sizeof(uint8_t); ++ ++ if (buf_len) { ++ buffer = malloc(buf_len); ++ if (!buffer) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "malloc: %s", estr); ++ last_dns_status = ENOMEM; ++ last_dns_check = time(NULL); ++ return last_dns_status; ++ } ++ } ++ ++ resp_len = res_query(name, C_IN, q_type, buffer, buf_len); ++ if (resp_len < 0) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "Failed to resolve %s (%s)", name, estr); ++ free(buffer); ++ last_dns_status = ENOENT; ++ last_dns_check = time(NULL); ++ return last_dns_status; ++ } ++ ++ /* On AIX, Solaris, and possibly some older glibc systems (e.g. SLES8) ++ truncated replies never give back a resp_len > buflen ++ which ends up causing DNS resolve failures on large tcp DNS replies */ ++ ++ if (buf_len == resp_len) { ++ if (resp_len == MAX_DNS_PACKET_SIZE) { ++ error(logopt, ++ "DNS reply too large when resolving %s", ++ name); ++ free(buffer); ++ last_dns_status = EMSGSIZE; ++ last_dns_check = time(NULL); ++ return last_dns_status; ++ } ++ ++ resp_len = MIN(resp_len * 2, MAX_DNS_PACKET_SIZE); ++ } ++ } while (buf_len < resp_len && resp_len <= MAX_DNS_PACKET_SIZE); ++ ++ *rbuf = buffer; ++ *resp_length = resp_len; ++ ++ last_dns_check = time(NULL); ++ last_dns_status = 0; ++ ++ return 0; ++} ++ ++static int dns_lookup_srv(unsigned int logopt, const char *name, ++ struct dns_rr_srv **dclist, int *numdcs) ++{ ++ uint8_t *buffer = NULL; ++ int resp_len = 0; ++ struct dns_rr_srv *dcs = NULL; ++ int query_count, answer_count; ++ uint8_t *p = buffer; ++ int rrnum; ++ int idx = 0; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ if (!name || !dclist) ++ return -EINVAL; ++ ++ /* Send the request. May have to loop several times in case ++ of large replies */ ++ ++ ret = dns_send_req(logopt, name, T_SRV, &buffer, &resp_len); ++ if (ret) { ++ error(logopt, "Failed to send DNS query"); ++ return ret; ++ } ++ p = buffer; ++ ++ /* For some insane reason, the ns_initparse() et. al. routines are only ++ available in libresolv.a, and not the shared lib. Who knows why.... ++ So we have to parse the DNS reply ourselves */ ++ ++ /* Pull the answer RR's count from the header. ++ * Use the NMB ordering macros */ ++ ++ query_count = RSVAL(p, 4); ++ answer_count = RSVAL(p, 6); ++ ++ debug(logopt, ++ "%d records returned in the answer section.", ++ answer_count); ++ ++ if (answer_count) { ++ dcs = malloc(sizeof(struct dns_rr_srv) * answer_count); ++ if (!dcs) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "malloc: %s", estr); ++ free(buffer); ++ return ENOMEM; ++ } ++ } ++ ++ /* now skip the header */ ++ ++ p += NS_HFIXEDSZ; ++ ++ /* parse the query section */ ++ ++ for (rrnum = 0; rrnum < query_count; rrnum++) { ++ struct dns_query q; ++ ++ ret = dns_parse_query(logopt, buffer, buffer+resp_len, &p, &q); ++ if (!ret) { ++ error(logopt, ++ "Failed to parse query record [%d]", rrnum); ++ free(buffer); ++ free(dcs); ++ return EBADMSG; ++ } ++ } ++ ++ /* now we are at the answer section */ ++ ++ for (rrnum = 0; rrnum < answer_count; rrnum++) { ++ ret = dns_parse_rr_srv(logopt, ++ buffer, buffer+resp_len, ++ &p, &dcs[rrnum]); ++ if (!ret) { ++ error(logopt, ++ "Failed to parse answer record [%d]", rrnum); ++ free(buffer); ++ free(dcs); ++ return EBADMSG; ++ } ++ } ++ idx = rrnum; ++ ++ qsort(dcs, idx, sizeof(struct dns_rr_srv), QSORT_CAST dnssrvcmp); ++ ++ *dclist = dcs; ++ *numdcs = idx; ++ ++ return 0; ++} ++ ++static char *escape_dn_commas(const char *uri) ++{ ++ size_t len = strlen(uri); ++ char *new, *tmp, *ptr; ++ ++ ptr = (char *) uri; ++ while (*ptr) { ++ if (*ptr == '\\') ++ ptr += 2; ++ if (*ptr == ',') ++ len += 2; ++ ptr++; ++ } ++ ++ new = malloc(len + 1); ++ if (!new) ++ return NULL; ++ memset(new, 0, len + 1); ++ ++ ptr = (char *) uri; ++ tmp = new; ++ while (*ptr) { ++ if (*ptr == '\\') { ++ ptr++; ++ *tmp++ = *ptr++; ++ continue; ++ } ++ if (*ptr == ',') { ++ strcpy(tmp, "%2c"); ++ ptr++; ++ tmp += 3; ++ continue; ++ } ++ *tmp++ = *ptr++; ++ } ++ ++ return new; ++} ++ ++void free_dclist(struct dclist *dclist) ++{ ++ if (dclist->uri) ++ free((void *) dclist->uri); ++ free(dclist); ++} ++ ++static char *getdnsdomainname(unsigned int logopt) ++{ ++ struct addrinfo hints, *ni; ++ char name[MAX_DNS_NAME_LENGTH + 1]; ++ char buf[MAX_ERR_BUF]; ++ char *dnsdomain = NULL; ++ char *ptr; ++ int ret; ++ ++ memset(name, 0, sizeof(name)); ++ if (gethostname(name, MAX_DNS_NAME_LENGTH) == -1) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "gethostname: %s", estr); ++ return NULL; ++ } ++ ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_flags = AI_CANONNAME; ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_DGRAM; ++ ++ ret = getaddrinfo(name, NULL, &hints, &ni); ++ if (ret) { ++ error(logopt, "hostname lookup failed: %s", gai_strerror(ret)); ++ return NULL; ++ } ++ ++ ptr = ni->ai_canonname; ++ while (*ptr && *ptr != '.') ++ ptr++; ++ ++ if (*++ptr) ++ dnsdomain = strdup(ptr); ++ ++ freeaddrinfo(ni); ++ ++ return dnsdomain; ++} ++ ++struct dclist *get_dc_list(unsigned int logopt, const char *uri) ++{ ++ LDAPURLDesc *ludlist = NULL; ++ LDAPURLDesc **ludp; ++ struct dns_rr_srv *dcs; ++ unsigned int min_ttl = MAX_TTL; ++ struct dclist *dclist = NULL;; ++ char buf[MAX_ERR_BUF]; ++ char *dn_uri, *esc_uri; ++ char *domain; ++ char *list; ++ int numdcs; ++ int ret; ++ ++ if (strcmp(uri, "ldap:///") && strcmp(uri, "ldaps:///")) { ++ dn_uri = strdup(uri); ++ if (!dn_uri) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "strdup: %s", estr); ++ return NULL; ++ } ++ } else { ++ char *dnsdomain; ++ char *hdn; ++ ++ dnsdomain = getdnsdomainname(logopt); ++ if (!dnsdomain) { ++ error(logopt, "failed to get dns domainname"); ++ return NULL; ++ } ++ ++ if (ldap_domain2dn(dnsdomain, &hdn) || hdn == NULL) { ++ error(logopt, ++ "Could not turn domain \"%s\" into a dn\n", ++ dnsdomain); ++ free(dnsdomain); ++ return NULL; ++ } ++ free(dnsdomain); ++ ++ dn_uri = malloc(strlen(uri) + strlen(hdn) + 1); ++ if (!dn_uri) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "malloc: %s", estr); ++ ber_memfree(hdn); ++ return NULL; ++ } ++ ++ strcpy(dn_uri, uri); ++ strcat(dn_uri, hdn); ++ ber_memfree(hdn); ++ } ++ ++ esc_uri = escape_dn_commas(dn_uri); ++ if (!esc_uri) { ++ error(logopt, "Could not escape commas in uri %s", dn_uri); ++ free(dn_uri); ++ return NULL; ++ } ++ ++ ret = ldap_url_parse(esc_uri, &ludlist); ++ if (ret != LDAP_URL_SUCCESS) { ++ error(logopt, "Could not parse uri %s (%d)", dn_uri, ret); ++ free(esc_uri); ++ free(dn_uri); ++ return NULL; ++ } ++ ++ free(esc_uri); ++ ++ if (!ludlist) { ++ error(logopt, "No dn found in uri %s", dn_uri); ++ free(dn_uri); ++ return NULL; ++ } ++ ++ free(dn_uri); ++ ++ dclist = malloc(sizeof(struct dclist)); ++ if (!dclist) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "malloc: %s", estr); ++ ldap_free_urldesc(ludlist); ++ return NULL; ++ } ++ memset(dclist, 0, sizeof(struct dclist)); ++ ++ list = NULL; ++ for (ludp = &ludlist; *ludp != NULL;) { ++ LDAPURLDesc *lud = *ludp; ++ size_t req_len, len; ++ char *request = NULL; ++ char *tmp; ++ int i; ++ ++ if (!lud->lud_dn && !lud->lud_dn[0] && ++ (!lud->lud_host || !lud->lud_host[0])) { ++ *ludp = lud->lud_next; ++ continue; ++ } ++ ++ domain = NULL; ++ if (ldap_dn2domain(lud->lud_dn, &domain) || domain == NULL) { ++ error(logopt, ++ "Could not turn dn \"%s\" into a domain", ++ lud->lud_dn); ++ *ludp = lud->lud_next; ++ continue; ++ } ++ ++ debug(logopt, "doing lookup of SRV RRs for domain %s", domain); ++ ++ req_len = sizeof("_ldap._tcp.") + strlen(domain); ++ request = malloc(req_len); ++ if (!request) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "malloc: %s", estr); ++ goto out_error; ++ } ++ ++ ret = snprintf(request, req_len, "_ldap._tcp.%s", domain); ++ if (ret >= req_len) { ++ free(request); ++ goto out_error; ++ } ++ ++ dclist_mutex_lock(); ++ if (dns_lookup_srv(logopt, request, &dcs, &numdcs)) { ++ error(logopt, ++ "DNS SRV query failed for domain %s", domain); ++ dclist_mutex_unlock(); ++ free(request); ++ goto out_error; ++ } ++ dclist_mutex_unlock(); ++ free(request); ++ ++ len = strlen(lud->lud_scheme); ++ len += sizeof("://"); ++ len *= numdcs; ++ ++ for (i = 0; i < numdcs; i++) { ++ if (dcs[i].ttl > 0 && dcs[i].ttl < min_ttl) ++ min_ttl = dcs[i].ttl; ++ len += strlen(dcs[i].hostname); ++ if (dcs[i].port > 0) ++ len += sizeof(":65535"); ++ } ++ ++ tmp = realloc(list, len); ++ if (!tmp) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "realloc: %s", estr); ++ goto out_error; ++ } ++ ++ if (!list) ++ memset(tmp, 0, len); ++ else ++ strcat(tmp, " "); ++ ++ for (i = 0; i < numdcs; i++) { ++ if (i > 0) ++ strcat(tmp, " "); ++ strcat(tmp, lud->lud_scheme); ++ strcat(tmp, "://"); ++ strcat(tmp, dcs[i].hostname); ++ if (dcs[i].port > 0) { ++ char port[7]; ++ ret = snprintf(port, 7, ":%d", dcs[i].port); ++ if (ret > 6) { ++ error(logopt, ++ "invalid port: %u", dcs[i].port); ++ goto out_error; ++ } ++ strcat(tmp, port); ++ } ++ } ++ list = tmp; ++ ++ *ludp = lud->lud_next; ++ ber_memfree(domain); ++ } ++ ++ ldap_free_urldesc(ludlist); ++ ++ dclist->expire = time(NULL) + min_ttl; ++ dclist->uri = list; ++ ++ return dclist; ++ ++out_error: ++ if (list) ++ free(list); ++ if (domain) ++ ber_memfree(domain); ++ ldap_free_urldesc(ludlist); ++ free_dclist(dclist); ++ return NULL; ++} +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index a847622..f6b3f42 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -643,14 +643,26 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) + LDAP *ldap = NULL; + struct ldap_uri *this; + struct list_head *p, *first; ++ struct dclist *dclist = NULL; ++ char *uri = NULL; + +- /* Try each uri in list, add connect fails to tmp list */ + uris_mutex_lock(ctxt); ++ if (ctxt->dclist) { ++ dclist = ctxt->dclist; ++ if (ctxt->dclist->expire < time(NULL)) { ++ free_dclist(ctxt->dclist); ++ ctxt->dclist = NULL; ++ dclist = NULL; ++ } ++ } + if (!ctxt->uri) + first = ctxt->uris; + else + first = &ctxt->uri->list; + uris_mutex_unlock(ctxt); ++ ++ ++ /* Try each uri, save point in server list upon success */ + p = first->next; + while(p != first) { + /* Skip list head */ +@@ -659,25 +671,62 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt) + continue; + } + this = list_entry(p, struct ldap_uri, list); +- debug(logopt, "trying server %s", this->uri); +- ldap = connect_to_server(logopt, this->uri, ctxt); ++ if (!strstr(this->uri, ":///")) ++ uri = strdup(this->uri); ++ else { ++ if (dclist) ++ uri = strdup(dclist->uri); ++ else { ++ struct dclist *tmp; ++ tmp = get_dc_list(logopt, this->uri); ++ if (!tmp) { ++ p = p->next; ++ continue; ++ } ++ dclist = tmp; ++ uri = strdup(dclist->uri); ++ } ++ } ++ if (!uri) { ++ p = p->next; ++ continue; ++ } ++ debug(logopt, "trying server uri %s", uri); ++ ldap = connect_to_server(logopt, uri, ctxt); + if (ldap) { +- info(logopt, "connected to uri %s", this->uri); +- uris_mutex_lock(ctxt); +- ctxt->uri = this; +- uris_mutex_unlock(ctxt); ++ info(logopt, "connected to uri %s", uri); ++ free(uri); + break; + } ++ free(uri); ++ uri = NULL; ++ free_dclist(dclist); ++ dclist = NULL; + p = p->next; + } + ++ uris_mutex_lock(ctxt); ++ if (ldap) ++ ctxt->uri = this; ++ if (dclist) { ++ if (!ctxt->dclist) ++ ctxt->dclist = dclist; ++ else { ++ if (ctxt->dclist != dclist) { ++ free_dclist(ctxt->dclist); ++ ctxt->dclist = dclist; ++ } ++ } ++ } ++ uris_mutex_unlock(ctxt); ++ + return ldap; + } + + static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) + { +- struct ldap_uri *this; + LDAP *ldap; ++ char *uri; + + if (ctxt->server || !ctxt->uris) { + ldap = do_connect(logopt, ctxt->server, ctxt); +@@ -692,9 +741,20 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) + } + + uris_mutex_lock(ctxt); +- this = ctxt->uri; ++ if (ctxt->dclist) ++ uri = strdup(ctxt->dclist->uri); ++ else ++ uri = strdup(ctxt->uri->uri); + uris_mutex_unlock(ctxt); +- ldap = do_connect(logopt, this->uri, ctxt); ++ ++ if (!uri) { ++ char buf[MAX_ERR_BUF]; ++ char *estr = strerror_r(errno, buf, sizeof(buf)); ++ crit(logopt, MODPREFIX "strdup: %s", estr); ++ return NULL; ++ } ++ ++ ldap = do_connect(logopt, uri, ctxt); + #ifdef WITH_SASL + /* + * Dispose of the sasl authentication connection and try the +@@ -702,9 +762,11 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt) + */ + if (!ldap) { + autofs_sasl_dispose(ctxt); +- ldap = connect_to_server(logopt, this->uri, ctxt); ++ ldap = connect_to_server(logopt, uri, ctxt); + } + #endif ++ free(uri); ++ + if (ldap) + return ldap; + +@@ -1296,6 +1358,8 @@ static void free_context(struct lookup_context *ctxt) + fatal(ret); + if (ctxt->sdns) + defaults_free_searchdns(ctxt->sdns); ++ if (ctxt->dclist) ++ free_dclist(ctxt->dclist); + free(ctxt); + + return; +diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in +index 97e20fe..37448ea 100644 +--- a/redhat/autofs.sysconfig.in ++++ b/redhat/autofs.sysconfig.in +@@ -50,6 +50,17 @@ BROWSE_MODE="no" + # Map entries that include a server name override + # this option. + # ++# This configuration option can also be used to ++# request autofs lookup SRV RRs for a domain of ++# the form :///[]. Note that a ++# trailing "/" is not allowed when using this form. ++# If the domain dn is not specified the dns domain ++# name (if any) is used to construct the domain dn ++# for the SRV RR lookup. The server list returned ++# from an SRV RR lookup is refreshed according to ++# the minimum ttl found in the SRV RR records or ++# after one hour, whichever is less. ++# + #LDAP_URI="" + # + # LDAP__TIMEOUT - timeout value for the synchronous API calls +diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in +index 62084c2..7dee5fd 100644 +--- a/samples/autofs.conf.default.in ++++ b/samples/autofs.conf.default.in +@@ -48,6 +48,17 @@ BROWSE_MODE="no" + # Map entries that include a server name override + # this option. + # ++# This configuration option can also be used to ++# request autofs lookup SRV RRs for a domain of ++# the form :///[]. Note that a ++# trailing "/" is not allowed when using this form. ++# If the domain dn is not specified the dns domain ++# name (if any) is used to construct the domain dn ++# for the SRV RR lookup. The server list returned ++# from an SRV RR lookup is refreshed according to ++# the minimum ttl found in the SRV RR records or ++# after one hour, whichever is less. ++# + #LDAP_URI="" + # + # LDAP__TIMEOUT - timeout value for the synchronous API calls diff --git a/autofs-5.0.4-zero-s_magic-is-valid.patch b/autofs-5.0.4-zero-s_magic-is-valid.patch new file mode 100644 index 0000000..a85724e --- /dev/null +++ b/autofs-5.0.4-zero-s_magic-is-valid.patch @@ -0,0 +1,47 @@ +autofs-5.0.4 - zero s_magic is valid + +From: Ian Kent + +When checking the super magic using the mount control ioctl +re-implementation an incorrect assumption is made that s_magic +field in the super block will not be zero. +--- + + CHANGELOG | 1 + + lib/dev-ioctl-lib.c | 10 ++++------ + 2 files changed, 5 insertions(+), 6 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 5f1cf7f..4ed80e0 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -39,6 +39,7 @@ + - fix memory leak reading master map. + - fix st_remove_tasks() locking. + - reset flex scanner when setting buffer. ++- zero s_magic is valid. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c +index 7c8c433..a034a3d 100644 +--- a/lib/dev-ioctl-lib.c ++++ b/lib/dev-ioctl-lib.c +@@ -764,12 +764,10 @@ static int dev_ioctl_ismountpoint(unsigned int logopt, + if (err) { + *mountpoint = DEV_IOCTL_IS_MOUNTED; + +- if (param->ismountpoint.out.magic) { +- if (param->ismountpoint.out.magic == AUTOFS_SUPER_MAGIC) +- *mountpoint |= DEV_IOCTL_IS_AUTOFS; +- else +- *mountpoint |= DEV_IOCTL_IS_OTHER; +- } ++ if (param->ismountpoint.out.magic == AUTOFS_SUPER_MAGIC) ++ *mountpoint |= DEV_IOCTL_IS_AUTOFS; ++ else ++ *mountpoint |= DEV_IOCTL_IS_OTHER; + } + + free_dev_ioctl_path(param); -- 2.44.0