From c5187b0dbfcad4e8228685555d9b6578a0ec2a6d Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Feb 16 2009 04:01:39 +0000 Subject: - 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. - 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. - update to configure libtirpc if present. - update to provide ipv6 name and address support. - update to provide ipv6 address parsing. --- 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-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.patch b/autofs-5.0.4-configure-libtirpc.patch new file mode 100644 index 0000000..3473e04 --- /dev/null +++ b/autofs-5.0.4-configure-libtirpc.patch @@ -0,0 +1,3262 @@ +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. +--- + + CHANGELOG | 1 + Makefile.conf.in | 3 + Makefile.rules | 5 + aclocal.m4 | 81 + + autofs.spec | 2 + configure | 2584 +++++++++++++++++++++++++++------------------------- + configure.in | 6 + daemon/automount.c | 13 + include/config.h.in | 6 + 9 files changed, 1489 insertions(+), 1212 deletions(-) + + +--- autofs-5.0.4.orig/Makefile.conf.in ++++ autofs-5.0.4/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@ + +--- autofs-5.0.4.orig/Makefile.rules ++++ autofs-5.0.4/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 +--- autofs-5.0.4.orig/aclocal.m4 ++++ autofs-5.0.4/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)]) ++]) ++ +--- autofs-5.0.4.orig/autofs.spec ++++ autofs-5.0.4/autofs.spec +@@ -57,7 +57,7 @@ inkludera n�tfilsystem, CD-ROM, floppydi + 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 +--- autofs-5.0.4.orig/configure ++++ autofs-5.0.4/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,60 +1910,32 @@ 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 ++# Use libtirpc + # +-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 ++ac_ext=c ++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 ++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; } +-if test "${ac_cv_path_MOUNT+set}" = set; then ++if test "${ac_cv_prog_CC+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 ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++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_MOUNT="$as_dir/$ac_word$ac_exec_ext" ++ ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +@@ -1969,61 +1943,39 @@ 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; } ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { echo "$as_me:$LINENO: result: $CC" >&5 ++echo "${ECHO_T}$CC" >&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 ++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; } +-if test "${ac_cv_path_UMOUNT+set}" = set; then ++if test "${ac_cv_prog_ac_ct_CC+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 ++ if test -n "$ac_ct_CC"; then ++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. ++else ++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_UMOUNT="$as_dir/$ac_word$ac_exec_ext" ++ ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +@@ -2031,61 +1983,56 @@ 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; } ++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; } + 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 ++ if test "x$ac_ct_CC" = x; then ++ CC="" ++ 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;} ++ac_tool_warned=yes ;; ++esac ++ CC=$ac_ct_CC ++ fi + else +- HAVE_UMOUNT=0 ++ CC="$ac_cv_prog_CC" + 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 ++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; } +-if test "${ac_cv_path_E2FSCK+set}" = set; then ++if test "${ac_cv_prog_CC+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 ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++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_E2FSCK="$as_dir/$ac_word$ac_exec_ext" ++ ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +@@ -2093,60 +2040,44 @@ 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; } ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { echo "$as_me:$LINENO: result: $CC" >&5 ++echo "${ECHO_T}$CC" >&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 + 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 ++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; } +-if test "${ac_cv_path_E3FSCK+set}" = set; then ++if test "${ac_cv_prog_CC+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 ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++ ac_prog_rejected=no ++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_E3FSCK="$as_dir/$ac_word$ac_exec_ext" ++ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ++ ac_prog_rejected=yes ++ continue ++ fi ++ ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +@@ -2154,60 +2085,53 @@ done + done + IFS=$as_save_IFS + +- ;; +-esac ++if test $ac_prog_rejected = yes; then ++ # We found a bogon in the path, so make sure we never use it. ++ set dummy $ac_cv_prog_CC ++ shift ++ if test $# != 0; then ++ # We chose a different compiler from the bogus one. ++ # However, it has the same basename, so the bogon will be chosen ++ # first if we set CC to just the basename; use the full file name. ++ shift ++ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" ++ fi + fi +-E3FSCK=$ac_cv_path_E3FSCK +-if test -n "$E3FSCK"; then +- { echo "$as_me:$LINENO: result: $E3FSCK" >&5 +-echo "${ECHO_T}$E3FSCK" >&6; } ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { echo "$as_me:$LINENO: result: $CC" >&5 ++echo "${ECHO_T}$CC" >&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 ++if test -z "$CC"; then ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in cl.exe ++ 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; } +-if test "${ac_cv_path_MODPROBE+set}" = set; then ++if test "${ac_cv_prog_CC+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 ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++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_MODPROBE="$as_dir/$ac_word$ac_exec_ext" ++ ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +@@ -2215,61 +2139,43 @@ 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; } ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ { echo "$as_me:$LINENO: result: $CC" >&5 ++echo "${ECHO_T}$CC" >&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 ++ test -n "$CC" && break ++ done + fi +- +- +-for ac_prog in flex lex ++if test -z "$CC"; then ++ ac_ct_CC=$CC ++ for ac_prog in cl.exe + 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 ++if test "${ac_cv_prog_ac_ct_CC+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 ++ if test -n "$ac_ct_CC"; then ++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. ++else ++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_LEX="$as_dir/$ac_word$ac_exec_ext" ++ ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +@@ -2277,434 +2183,872 @@ 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; } ++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; } + 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 ++ test -n "$ac_ct_CC" && break + done +-IFS=$as_save_IFS + +- ;; ++ if test "x$ac_ct_CC" = x; then ++ CC="" ++ 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;} ++ac_tool_warned=yes ;; + esac ++ CC=$ac_ct_CC ++ fi + 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 ++test -z "$CC" && { { 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 ++See \`config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } + +-if test -n "$YACC"; then ++# Provide some information about the compiler. ++echo "$as_me:$LINENO: checking for C compiler version" >&5 ++ac_compiler=`set X $ac_compile; echo $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_compiler --version >&5") 2>&5 ++ ac_status=$? ++ 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_compiler -v >&5") 2>&5 ++ ac_status=$? ++ 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_compiler -V >&5") 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } + +-cat >>confdefs.h <<_ACEOF +-#define PATH_YACC "$YACC" ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ + _ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ + +- 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 ++int ++main () ++{ + +-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 ++ ; ++ return 0; ++} ++_ACEOF ++ac_clean_files_save=$ac_clean_files ++ac_clean_files="$ac_clean_files a.out 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. ++ac_rmfiles= ++for ac_file in $ac_files + 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 ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; ++ * ) ac_rmfiles="$ac_rmfiles $ac_file";; ++ esac + done +-IFS=$as_save_IFS ++rm -f $ac_rmfiles + +- ;; ++if { (ac_try="$ac_link_default" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; + esac +-fi +-RANLIB=$ac_cv_path_RANLIB +-if test -n "$RANLIB"; then +- { echo "$as_me:$LINENO: result: $RANLIB" >&5 +-echo "${ECHO_T}$RANLIB" >&6; } ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++ (eval "$ac_link_default") 2>&5 ++ ac_status=$? ++ 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' ++# in a Makefile. We should not override ac_cv_exeext if it was cached, ++# so that the user can short-circuit this test for compilers unknown to ++# Autoconf. ++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 ) ++ ;; ++ [ab].out ) ++ # We found the default executable, but exeext='' is most ++ # certainly right. ++ break;; ++ *.* ) ++ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; ++ then :; else ++ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` ++ fi ++ # We set ac_cv_exeext here because the later test for it is not ++ # safe: cross compilers may not add the suffix if given an `-o' ++ # argument, so we may need to know it at that point already. ++ # Even if this section looks crufty: it has the advantage of ++ # actually working. ++ break;; ++ * ) ++ break;; ++ esac ++done ++test "$ac_cv_exeext" = no && ac_cv_exeext= ++ + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ ac_file='' + fi + ++{ echo "$as_me:$LINENO: result: $ac_file" >&5 ++echo "${ECHO_T}$ac_file" >&6; } ++if test -z "$ac_file"; then ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 + +- test -n "$RANLIB" && break +-done +- +-if test -n "$RANLIB"; then ++{ { 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 ++See \`config.log' for more details." >&2;} ++ { (exit 77); exit 77; }; } ++fi + +-cat >>confdefs.h <<_ACEOF +-#define PATH_RANLIB "$RANLIB" +-_ACEOF ++ac_exeext=$ac_cv_exeext + +- 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;} ++# 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; } ++# 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 ++ if { ac_try='./$ac_file' ++ { (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") 2>&5 ++ ac_status=$? ++ 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. ++If you meant to cross compile, use \`--host'. ++See \`config.log' for more details." >&5 ++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; }; } ++ fi ++ fi + fi ++{ echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6; } + +-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 ++rm -f a.out 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; } + +- ;; ++{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 ++echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } ++if { (ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; + esac +-fi +-RPCGEN=$ac_cv_path_RPCGEN +-if test -n "$RPCGEN"; then +- { echo "$as_me:$LINENO: result: $RPCGEN" >&5 +-echo "${ECHO_T}$RPCGEN" >&6; } ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++ (eval "$ac_link") 2>&5 ++ ac_status=$? ++ 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 ++# work properly (i.e., refer to `conftest.exe'), while it won't with ++# `rm'. ++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_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` ++ break;; ++ * ) break;; ++ esac ++done + else +- { echo "$as_me:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } ++ { { 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 ++See \`config.log' for more details." >&2;} ++ { (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; } + +- test -n "$RPCGEN" && break +-done ++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; } ++if test "${ac_cv_objext+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ + +-if test -n "$RPCGEN"; then ++int ++main () ++{ + +-cat >>confdefs.h <<_ACEOF +-#define PATH_RPCGEN "$RPCGEN" ++ ; ++ return 0; ++} + _ACEOF +- +- PATH_RPCGEN="$RPCGEN" ++rm -f conftest.o conftest.obj ++if { (ac_try="$ac_compile" ++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_compile") 2>&5 ++ ac_status=$? ++ 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_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` ++ break;; ++ esac ++done + else +- { { echo "$as_me:$LINENO: error: required program RPCGEN not found" >&5 +-echo "$as_me: error: required program RPCGEN not found" >&2;} ++ 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 ++See \`config.log' for more details." >&5 ++echo "$as_me: error: cannot compute suffix of object files: cannot compile ++See \`config.log' for more details." >&2;} + { (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; } ++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; } ++if test "${ac_cv_c_compiler_gnu+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ + +-# +-# 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 ++int ++main () ++{ ++#ifndef __GNUC__ ++ choke me ++#endif + +-cat >>confdefs.h <<\_ACEOF +-#define HAVE_SLOPPY_MOUNT 1 ++ ; ++ return 0; ++} + _ACEOF ++rm -f conftest.$ac_objext ++if { (ac_try="$ac_compile" ++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_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 ++ (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 ++sed 's/^/| /' conftest.$ac_ext >&5 + +- { 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 ++ ac_compiler_gnu=no + 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 ++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` ++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; } ++if test "${ac_cv_prog_cc_g+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 ++ ac_save_c_werror_flag=$ac_c_werror_flag ++ ac_c_werror_flag=yes ++ ac_cv_prog_cc_g=no ++ CFLAGS="-g" ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ + +- ;; ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (ac_try="$ac_compile" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; + 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; } ++eval "echo \"\$as_me:$LINENO: $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 ++ (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:$LINENO: result: no" >&5 +-echo "${ECHO_T}no" >&6; } +-fi ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 + ++ CFLAGS="" ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ + +- test -n "$XML_CONFIG" && break +-done +-test -n "$XML_CONFIG" || XML_CONFIG="no" ++int ++main () ++{ + +-{ 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 ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (ac_try="$ac_compile" ++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_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 ++ (exit $ac_status); } && { ++ test -z "$ac_c_werror_flag" || ++ test ! -s conftest.err ++ } && test -s conftest.$ac_objext; then ++ : + 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 ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 + +-cat >>confdefs.h <<\_ACEOF +-#define LIBXML2_WORKAROUND 1 ++ ac_c_werror_flag=$ac_save_c_werror_flag ++ CFLAGS="-g" ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ + _ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (ac_try="$ac_compile" ++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_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 ++ (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 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ++fi ++ ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++ ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++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; } ++if test "$ac_test_CFLAGS" = set; then ++ CFLAGS=$ac_save_CFLAGS ++elif test $ac_cv_prog_cc_g = yes; then ++ if test "$GCC" = yes; then ++ CFLAGS="-g -O2" ++ else ++ CFLAGS="-g" ++ fi ++else ++ if test "$GCC" = yes; then ++ CFLAGS="-O2" ++ 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; } ++if test "${ac_cv_prog_cc_c89+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_cv_prog_cc_c89=no ++ac_save_CC=$CC ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++#include ++#include ++#include ++/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ ++struct buf { int x; }; ++FILE * (*rcsopen) (struct buf *, struct stat *, int); ++static char *e (p, i) ++ char **p; ++ int i; ++{ ++ return p[i]; ++} ++static char *f (char * (*g) (char **, int), char **p, ...) ++{ ++ char *s; ++ va_list v; ++ va_start (v,p); ++ s = g (p, va_arg (v,int)); ++ va_end (v); ++ return s; ++} ++ ++/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has ++ function prototypes and stuff, but not '\xHH' hex character constants. ++ These don't provoke an error unfortunately, instead are silently treated ++ as 'x'. The following induces an error, until -std is added to get ++ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an ++ array size at least. It's necessary to write '\x00'==0 to get something ++ that's true only with -std. */ ++int osf4_cc_array ['\x00' == 0 ? 1 : -1]; ++ ++/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters ++ inside strings and character constants. */ ++#define FOO(x) 'x' ++int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; ++ ++int test (int i, double x); ++struct s1 {int (*f) (int a);}; ++struct s2 {int (*f) (double a);}; ++int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); ++int argc; ++char **argv; ++int ++main () ++{ ++return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ++ ; ++ return 0; ++} ++_ACEOF ++for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ ++ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" ++do ++ CC="$ac_save_CC $ac_arg" ++ rm -f conftest.$ac_objext ++if { (ac_try="$ac_compile" ++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_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 ++ (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 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ++fi ++ ++rm -f core conftest.err conftest.$ac_objext ++ test "x$ac_cv_prog_cc_c89" != "xno" && break ++done ++rm -f conftest.$ac_ext ++CC=$ac_save_CC ++ ++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; } ;; ++ xno) ++ { echo "$as_me:$LINENO: result: unsupported" >&5 ++echo "${ECHO_T}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; } ;; ++esac + +- fi +- fi +- fi +-fi + +-# +-# glibc/libc 6 new libraries +-# + ac_ext=c + 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 +-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; } +-if test "${ac_cv_prog_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. ++ ++ ++{ 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 +-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_prog_CC="${ac_tool_prefix}gcc" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +-done +-IFS=$as_save_IFS ++ 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 +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { echo "$as_me:$LINENO: result: $CC" >&5 +-echo "${ECHO_T}$CC" >&6; } ++ ++# 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:$LINENO: result: no" >&5 ++ 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 + +-fi +-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; } +-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- if test -n "$ac_ct_CC"; then +- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +-else +-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_prog_ac_ct_CC="gcc" +- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +-done +-IFS=$as_save_IFS ++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 +-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; } + else + { echo "$as_me:$LINENO: result: no" >&5 + echo "${ECHO_T}no" >&6; } + fi + +- if test "x$ac_ct_CC" = x; then +- CC="" +- 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;} +-ac_tool_warned=yes ;; +-esac +- CC=$ac_ct_CC +- 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 +- CC="$ac_cv_prog_CC" ++ { 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 + +-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 ++ ++ ++ ++# ++# 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_prog_CC+set}" = set; then ++if test "${ac_cv_path_MOUNT+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 + else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH ++ 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_prog_CC="${ac_tool_prefix}cc" ++ 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 +@@ -2712,44 +3056,61 @@ done + done + IFS=$as_save_IFS + ++ ;; ++esac + fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { echo "$as_me:$LINENO: result: $CC" >&5 +-echo "${ECHO_T}$CC" >&6; } ++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 + + +- 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 +-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 ++ ++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_prog_CC+set}" = set; then ++if test "${ac_cv_path_UMOUNT+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 + else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +- ac_prog_rejected=no +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH ++ 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 +- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then +- ac_prog_rejected=yes +- continue +- fi +- ac_cv_prog_CC="cc" ++ 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 +@@ -2757,53 +3118,61 @@ done + done + IFS=$as_save_IFS + +-if test $ac_prog_rejected = yes; then +- # We found a bogon in the path, so make sure we never use it. +- set dummy $ac_cv_prog_CC +- shift +- if test $# != 0; then +- # We chose a different compiler from the bogus one. +- # However, it has the same basename, so the bogon will be chosen +- # first if we set CC to just the basename; use the full file name. +- shift +- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" +- fi +-fi +-fi ++ ;; ++esac + fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { echo "$as_me:$LINENO: result: $CC" >&5 +-echo "${ECHO_T}$CC" >&6; } ++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 +-if test -z "$CC"; then +- if test -n "$ac_tool_prefix"; then +- for ac_prog in cl.exe +- 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 ++ ++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_prog_CC+set}" = set; then ++if test "${ac_cv_path_E2FSCK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 + else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH ++ 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_prog_CC="$ac_tool_prefix$ac_prog" ++ 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 +@@ -2811,43 +3180,60 @@ done + done + IFS=$as_save_IFS + ++ ;; ++esac + fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { echo "$as_me:$LINENO: result: $CC" >&5 +-echo "${ECHO_T}$CC" >&6; } ++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 "$CC" && break +- done ++ 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 +-if test -z "$CC"; then +- ac_ct_CC=$CC +- for ac_prog in cl.exe ++ ++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_prog_ac_ct_CC+set}" = set; then ++if test "${ac_cv_path_E3FSCK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 + else +- if test -n "$ac_ct_CC"; then +- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH ++ 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_prog_ac_ct_CC="$ac_prog" ++ 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 +@@ -2855,655 +3241,436 @@ done + done + IFS=$as_save_IFS + ++ ;; ++esac + 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; } ++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 "$ac_ct_CC" && break ++ test -n "$E3FSCK" && break + done + +- if test "x$ac_ct_CC" = x; then +- CC="" +- 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;} +-ac_tool_warned=yes ;; +-esac +- CC=$ac_ct_CC +- fi +-fi +- +-fi +- +- +-test -z "$CC" && { { 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 +-See \`config.log' for more details." >&2;} +- { (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` +-{ (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_compiler --version >&5") 2>&5 +- ac_status=$? +- 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_compiler -v >&5") 2>&5 +- ac_status=$? +- 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_compiler -V >&5") 2>&5 +- ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 +- (exit $ac_status); } ++if test -n "$E3FSCK"; then + +-cat >conftest.$ac_ext <<_ACEOF +-/* confdefs.h. */ ++cat >>confdefs.h <<\_ACEOF ++#define HAVE_E3FSCK 1 + _ACEOF +-cat confdefs.h >>conftest.$ac_ext +-cat >>conftest.$ac_ext <<_ACEOF +-/* end confdefs.h. */ + +-int +-main () +-{ + +- ; +- return 0; +-} ++cat >>confdefs.h <<_ACEOF ++#define PATH_E3FSCK "$E3FSCK" + _ACEOF +-ac_clean_files_save=$ac_clean_files +-ac_clean_files="$ac_clean_files a.out 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. +-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_rmfiles="$ac_rmfiles $ac_file";; +- esac +-done +-rm -f $ac_rmfiles + +-if { (ac_try="$ac_link_default" +-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_default") 2>&5 +- ac_status=$? +- 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' +-# in a Makefile. We should not override ac_cv_exeext if it was cached, +-# so that the user can short-circuit this test for compilers unknown to +-# Autoconf. +-for ac_file in $ac_files '' ++ HAVE_E3FSCK=1 ++else ++ HAVE_E3FSCK=0 ++fi ++ ++for ac_prog in modprobe + do +- test -f "$ac_file" || continue +- case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) +- ;; +- [ab].out ) +- # We found the default executable, but exeext='' is most +- # certainly right. +- break;; +- *.* ) +- if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; +- then :; else +- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` +- fi +- # We set ac_cv_exeext here because the later test for it is not +- # safe: cross compilers may not add the suffix if given an `-o' +- # argument, so we may need to know it at that point already. +- # Even if this section looks crufty: it has the advantage of +- # actually working. +- break;; +- * ) +- break;; +- esac ++ # 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 +-test "$ac_cv_exeext" = no && ac_cv_exeext= ++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 +- ac_file='' ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } + fi + +-{ echo "$as_me:$LINENO: result: $ac_file" >&5 +-echo "${ECHO_T}$ac_file" >&6; } +-if test -z "$ac_file"; then +- echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 + +-{ { 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 +-See \`config.log' for more details." >&2;} +- { (exit 77); exit 77; }; } +-fi ++ test -n "$MODPROBE" && break ++done + +-ac_exeext=$ac_cv_exeext ++if test -n "$MODPROBE"; then + +-# 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; } +-# 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 +- if { ac_try='./$ac_file' +- { (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") 2>&5 +- ac_status=$? +- 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. +-If you meant to cross compile, use \`--host'. +-See \`config.log' for more details." >&5 +-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; }; } +- fi +- fi +-fi +-{ echo "$as_me:$LINENO: result: yes" >&5 +-echo "${ECHO_T}yes" >&6; } ++cat >>confdefs.h <<\_ACEOF ++#define HAVE_MODPROBE 1 ++_ACEOF + +-rm -f a.out 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; } + +-{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&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_link") 2>&5 +- ac_status=$? +- 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 +-# work properly (i.e., refer to `conftest.exe'), while it won't with +-# `rm'. +-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_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` +- break;; +- * ) break;; +- esac +-done ++cat >>confdefs.h <<_ACEOF ++#define PATH_MODPROBE "$MODPROBE" ++_ACEOF ++ ++ HAVE_MODPROBE=1 + else +- { { 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 +-See \`config.log' for more details." >&2;} +- { (exit 1); exit 1; }; } ++ HAVE_MODPROBE=0 + fi + +-rm -f conftest$ac_cv_exeext +-{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +-echo "${ECHO_T}$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; } +-if test "${ac_cv_objext+set}" = set; then ++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 +- cat >conftest.$ac_ext <<_ACEOF +-/* confdefs.h. */ +-_ACEOF +-cat confdefs.h >>conftest.$ac_ext +-cat >>conftest.$ac_ext <<_ACEOF +-/* end confdefs.h. */ +- +-int +-main () +-{ ++ 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 + +- ; +- return 0; +-} +-_ACEOF +-rm -f conftest.o conftest.obj +-if { (ac_try="$ac_compile" +-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_compile") 2>&5 +- ac_status=$? +- 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_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` +- break;; +- esac +-done ++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: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi + +-{ { 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 +-See \`config.log' for more details." >&2;} ++ ++ 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 + +-rm -f conftest.$ac_cv_objext conftest.$ac_ext ++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 +-{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +-echo "${ECHO_T}$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; } +-if test "${ac_cv_c_compiler_gnu+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 ++YACC=$ac_cv_path_YACC ++if test -n "$YACC"; then ++ { echo "$as_me:$LINENO: result: $YACC" >&5 ++echo "${ECHO_T}$YACC" >&6; } + else +- cat >conftest.$ac_ext <<_ACEOF +-/* confdefs.h. */ +-_ACEOF +-cat confdefs.h >>conftest.$ac_ext +-cat >>conftest.$ac_ext <<_ACEOF +-/* end confdefs.h. */ ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi + +-int +-main () +-{ +-#ifndef __GNUC__ +- choke me +-#endif + +- ; +- return 0; +-} +-_ACEOF +-rm -f conftest.$ac_objext +-if { (ac_try="$ac_compile" +-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_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 +- (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 +-sed 's/^/| /' conftest.$ac_ext >&5 ++ test -n "$YACC" && break ++done + +- ac_compiler_gnu=no +-fi ++if test -n "$YACC"; then + +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-ac_cv_c_compiler_gnu=$ac_compiler_gnu ++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 +-{ 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` +-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; } +-if test "${ac_cv_prog_cc_g+set}" = set; then ++ ++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 +- ac_save_c_werror_flag=$ac_c_werror_flag +- ac_c_werror_flag=yes +- ac_cv_prog_cc_g=no +- CFLAGS="-g" +- cat >conftest.$ac_ext <<_ACEOF +-/* confdefs.h. */ +-_ACEOF +-cat confdefs.h >>conftest.$ac_ext +-cat >>conftest.$ac_ext <<_ACEOF +-/* end confdefs.h. */ +- +-int +-main () +-{ ++ 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 + +- ; +- return 0; +-} +-_ACEOF +-rm -f conftest.$ac_objext +-if { (ac_try="$ac_compile" +-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_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 +- (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 ++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: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi + +- CFLAGS="" +- cat >conftest.$ac_ext <<_ACEOF +-/* confdefs.h. */ +-_ACEOF +-cat confdefs.h >>conftest.$ac_ext +-cat >>conftest.$ac_ext <<_ACEOF +-/* end confdefs.h. */ + +-int +-main () +-{ ++ test -n "$RANLIB" && break ++done + +- ; +- return 0; +-} +-_ACEOF +-rm -f conftest.$ac_objext +-if { (ac_try="$ac_compile" +-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_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 +- (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 +-sed 's/^/| /' conftest.$ac_ext >&5 ++if test -n "$RANLIB"; then + +- ac_c_werror_flag=$ac_save_c_werror_flag +- CFLAGS="-g" +- cat >conftest.$ac_ext <<_ACEOF +-/* confdefs.h. */ ++cat >>confdefs.h <<_ACEOF ++#define PATH_RANLIB "$RANLIB" + _ACEOF +-cat confdefs.h >>conftest.$ac_ext +-cat >>conftest.$ac_ext <<_ACEOF +-/* end confdefs.h. */ + +-int +-main () +-{ ++ 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 + +- ; +- return 0; +-} +-_ACEOF +-rm -f conftest.$ac_objext +-if { (ac_try="$ac_compile" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; ++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 +-eval "echo \"\$as_me:$LINENO: $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 +- (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 ++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: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 ++ { echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6; } ++fi + + +-fi ++ test -n "$RPCGEN" && break ++done + +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi ++if test -n "$RPCGEN"; then + +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi ++cat >>confdefs.h <<_ACEOF ++#define PATH_RPCGEN "$RPCGEN" ++_ACEOF + +-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; } +-if test "$ac_test_CFLAGS" = set; then +- CFLAGS=$ac_save_CFLAGS +-elif test $ac_cv_prog_cc_g = yes; then +- if test "$GCC" = yes; then +- CFLAGS="-g -O2" +- else +- CFLAGS="-g" +- fi ++ PATH_RPCGEN="$RPCGEN" + else +- if test "$GCC" = yes; then +- CFLAGS="-O2" +- else +- CFLAGS= +- fi ++ { { 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 +-{ 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; } +-if test "${ac_cv_prog_cc_c89+set}" = set; then +- echo $ECHO_N "(cached) $ECHO_C" >&6 +-else +- ac_cv_prog_cc_c89=no +-ac_save_CC=$CC +-cat >conftest.$ac_ext <<_ACEOF +-/* confdefs.h. */ +-_ACEOF +-cat confdefs.h >>conftest.$ac_ext +-cat >>conftest.$ac_ext <<_ACEOF +-/* end confdefs.h. */ +-#include +-#include +-#include +-#include +-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +-struct buf { int x; }; +-FILE * (*rcsopen) (struct buf *, struct stat *, int); +-static char *e (p, i) +- char **p; +- int i; +-{ +- return p[i]; +-} +-static char *f (char * (*g) (char **, int), char **p, ...) +-{ +- char *s; +- va_list v; +- va_start (v,p); +- s = g (p, va_arg (v,int)); +- va_end (v); +- return s; +-} + +-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has +- function prototypes and stuff, but not '\xHH' hex character constants. +- These don't provoke an error unfortunately, instead are silently treated +- as 'x'. The following induces an error, until -std is added to get +- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an +- array size at least. It's necessary to write '\x00'==0 to get something +- that's true only with -std. */ +-int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters +- inside strings and character constants. */ +-#define FOO(x) 'x' +-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; ++# ++# 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 + +-int test (int i, double x); +-struct s1 {int (*f) (int a);}; +-struct s2 {int (*f) (double a);}; +-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +-int argc; +-char **argv; +-int +-main () +-{ +-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; +- ; +- return 0; +-} ++cat >>confdefs.h <<\_ACEOF ++#define HAVE_SLOPPY_MOUNT 1 + _ACEOF +-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ +- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +-do +- CC="$ac_save_CC $ac_arg" +- rm -f conftest.$ac_objext +-if { (ac_try="$ac_compile" +-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_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 +- (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 +-sed 's/^/| /' conftest.$ac_ext >&5 +- + ++ { 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 + +-rm -f core conftest.err conftest.$ac_objext +- test "x$ac_cv_prog_cc_c89" != "xno" && break ++# 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 +-rm -f conftest.$ac_ext +-CC=$ac_save_CC ++done ++IFS=$as_save_IFS + +-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; } ;; +- xno) +- { echo "$as_me:$LINENO: result: unsupported" >&5 +-echo "${ECHO_T}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; } ;; ++ ;; + 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 + + +-ac_ext=c +-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 ++ 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 +--- autofs-5.0.4.orig/configure.in ++++ autofs-5.0.4/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() +--- autofs-5.0.4.orig/daemon/automount.c ++++ autofs-5.0.4/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(); + +--- autofs-5.0.4.orig/include/config.h.in ++++ autofs-5.0.4/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 + +--- autofs-5.0.4.orig/CHANGELOG ++++ autofs-5.0.4/CHANGELOG +@@ -17,6 +17,7 @@ + - 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. + + 4/11/2008 autofs-5.0.4 + ----------------------- 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..ba97db1 --- /dev/null +++ b/autofs-5.0.4-easy-alloca-replacements.patch @@ -0,0 +1,1137 @@ +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. +--- + + CHANGELOG | 1 + 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 -- + 16 files changed, 185 insertions(+), 228 deletions(-) + + +--- autofs-5.0.4.orig/daemon/automount.c ++++ autofs-5.0.4/daemon/automount.c +@@ -127,8 +127,8 @@ static int do_mkdir(const char *parent, + + 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 + 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 + 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 * + + 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; + } + +--- autofs-5.0.4.orig/daemon/direct.c ++++ autofs-5.0.4/daemon/direct.c +@@ -637,7 +637,9 @@ int mount_autofs_offset(struct autofs_po + 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_po + 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); +--- autofs-5.0.4.orig/daemon/flag.c ++++ autofs-5.0.4/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 +--- autofs-5.0.4.orig/daemon/indirect.c ++++ autofs-5.0.4/daemon/indirect.c +@@ -90,7 +90,9 @@ static int do_mount_autofs_indirect(stru + 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(stru + } + + 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); +--- autofs-5.0.4.orig/daemon/module.c ++++ autofs-5.0.4/daemon/module.c +@@ -58,15 +58,11 @@ struct lookup_mod *open_lookup(const cha + { + 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 cha + 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 cha + } + 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 + { + 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 + 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 + } + 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 + { + 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 + 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 + } + return NULL; + } +- snprintf(fnbuf, size_fnbuf, "%s/mount_%s.so", AUTOFS_LIB_DIR, name); + + if (!(dh = dlopen(fnbuf, RTLD_NOW))) { + if (err_prefix) +--- autofs-5.0.4.orig/lib/cache.c ++++ autofs-5.0.4/lib/cache.c +@@ -482,27 +482,23 @@ struct mapent *cache_lookup_offset(const + { + 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 + 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]; +--- autofs-5.0.4.orig/lib/cat_path.c ++++ autofs-5.0.4/lib/cat_path.c +@@ -12,7 +12,6 @@ + * + * ----------------------------------------------------------------------- */ + +-#include + #include + #include + #include +--- autofs-5.0.4.orig/modules/lookup_file.c ++++ autofs-5.0.4/modules/lookup_file.c +@@ -378,8 +378,8 @@ int lookup_read_master(struct master *ma + 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 *ma + 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 + 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 + 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 + 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; + } +--- autofs-5.0.4.orig/modules/lookup_ldap.c ++++ autofs-5.0.4/modules/lookup_ldap.c +@@ -294,10 +294,10 @@ static int get_query_dn(unsigned logopt, + 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, + 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, + 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, + 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, + 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_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 + 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 *ma + + 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 *ma + 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 *ma + 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_po + /* 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_po + + 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_po + 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_po + 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_po + 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_poin + 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_poin + free(enc_key1); + free(enc_key2); + } ++ free(query); + return CHE_FAIL; + } + +@@ -2367,14 +2386,17 @@ static int lookup_one(struct autofs_poin + 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_poin + 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_poin + 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 + 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 + 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; + } +--- autofs-5.0.4.orig/modules/lookup_nisplus.c ++++ autofs-5.0.4/modules/lookup_nisplus.c +@@ -92,10 +92,10 @@ int lookup_read_master(struct master *ma + 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 *ma + 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 *ma + 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 *ma + } + + 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 + 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 + 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 + 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 + + source->age = age; + ++ free(tablename); + pthread_setcancelstate(cur_state, NULL); + + return NSS_STATUS_SUCCESS; +@@ -271,11 +277,11 @@ static int lookup_one(struct autofs_poin + 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_poin + 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_poin + 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_poi + 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_poi + 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_poi + 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 + } + 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; + } +--- autofs-5.0.4.orig/modules/mount_autofs.c ++++ autofs-5.0.4/modules/mount_autofs.c +@@ -18,7 +18,6 @@ + #include + #include + #include +-#include + #include + #include + #include +--- autofs-5.0.4.orig/modules/mount_bind.c ++++ autofs-5.0.4/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, + /* 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, + } + } else { + char *cp; +- char *basepath = alloca(strlen(fullpath) + 1); ++ char basepath[PATH_MAX]; + int status; + struct stat st; + +--- autofs-5.0.4.orig/modules/mount_changer.c ++++ autofs-5.0.4/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, + /* 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'; +--- autofs-5.0.4.orig/modules/mount_ext2.c ++++ autofs-5.0.4/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, + /* 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'; +--- autofs-5.0.4.orig/modules/mount_generic.c ++++ autofs-5.0.4/modules/mount_generic.c +@@ -37,7 +37,7 @@ int mount_mount(struct autofs_point *ap, + 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, + /* 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'; +--- autofs-5.0.4.orig/CHANGELOG ++++ autofs-5.0.4/CHANGELOG +@@ -16,6 +16,7 @@ + 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). + + 4/11/2008 autofs-5.0.4 + ----------------------- 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-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-ipv6-name-and-address-support.patch b/autofs-5.0.4-ipv6-name-and-address-support.patch new file mode 100644 index 0000000..397b6c9 --- /dev/null +++ b/autofs-5.0.4-ipv6-name-and-address-support.patch @@ -0,0 +1,1018 @@ +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. +--- + + CHANGELOG | 1 + include/replicated.h | 2 + include/rpc_subs.h | 4 + lib/rpc_subs.c | 486 +++++++++++++++++++++++++++++++++------------------ + modules/cyrus-sasl.c | 17 + + modules/replicated.c | 235 +++++++++++++++++------- + 6 files changed, 501 insertions(+), 244 deletions(-) + + +--- autofs-5.0.4.orig/include/replicated.h ++++ autofs-5.0.4/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; +--- autofs-5.0.4.orig/include/rpc_subs.h ++++ autofs-5.0.4/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 * + 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); +--- autofs-5.0.4.orig/lib/rpc_subs.c ++++ autofs-5.0.4/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_ + * 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 soc + * 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,117 @@ 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 TCP RPC client using non-blocking connect ++ * Create a UDP RPC client + */ +-static CLIENT *create_tcp_client(struct conn_info *info) ++static CLIENT *create_udp_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) ++ 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 = -1; ++ fd = RPC_ANYSOCK; + clnt_destroy(info->client); + info->client = NULL; + } else { +@@ -305,51 +326,174 @@ static CLIENT *create_tcp_client(struct + } + } + +- 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 (!info->client) { ++ close(fd); ++ fd = RPC_ANYSOCK; ++ } + } + +- if (inet_aton(info->host, &addr.sin_addr)) +- goto got_addr; ++ 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; ++ } + +- memset(&hp, 0, sizeof(struct hostent)); ++ freeaddrinfo(ai); + +- 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); ++ 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; + } +- memcpy(&addr.sin_addr.s_addr, php->h_addr, php->h_length); + +-got_addr: +- addr.sin_port = htons(info->port); ++ 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) { +- fd = open_sock(PF_INET, SOCK_STREAM, info->proto->p_proto); +- if (fd < 0) +- return NULL; ++ 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) ++{ ++ 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 = 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; + +- ret = connect_nb(fd, &addr, &info->timeout); +- if (ret < 0) +- goto out_close; ++ 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_STREAM; ++ ++ 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; + } + +- 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_ + } + + 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; +--- autofs-5.0.4.orig/modules/cyrus-sasl.c ++++ autofs-5.0.4/modules/cyrus-sasl.c +@@ -732,16 +732,25 @@ sasl_bind_mech(unsigned logopt, LDAP *ld + 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); +--- autofs-5.0.4.orig/modules/replicated.c ++++ autofs-5.0.4/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 *if + 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; + +- memcpy(tmp, host_addr, addr_len); +- hst_addr = (struct in_addr *) tmp; ++ 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; + +- ha = ntohl((uint32_t) hst_addr->s_addr); ++ 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 ++ ++ 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 + + 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 + } + 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 + 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 + } + 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 + } + + 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, str + 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; ++ ++ ret = getaddrinfo(host, NULL, &hints, &ni); ++ if (ret) ++ goto try_name; + +- if (!add_host(list, new)) { +- free_host(new); +- continue; +- } ++ this = ni; ++ while (this) { ++ ret = add_new_host(list, host, weight, this); ++ if (!ret) ++ break; ++ this = this->ai_next; + } ++ freeaddrinfo(ni); ++ goto done; + +- return 1; ++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; ++ } ++ ++ 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 ** + 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); +--- autofs-5.0.4.orig/CHANGELOG ++++ autofs-5.0.4/CHANGELOG +@@ -18,6 +18,7 @@ + - 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. + + 4/11/2008 autofs-5.0.4 + ----------------------- diff --git a/autofs-5.0.4-ipv6-parse.patch b/autofs-5.0.4-ipv6-parse.patch new file mode 100644 index 0000000..f0530a2 --- /dev/null +++ b/autofs-5.0.4-ipv6-parse.patch @@ -0,0 +1,462 @@ +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. +--- + + CHANGELOG | 1 + 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 +++++++++++- + 9 files changed, 187 insertions(+), 63 deletions(-) + + +--- autofs-5.0.4.orig/include/parse_subs.h ++++ autofs-5.0.4/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 *, + 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 +--- autofs-5.0.4.orig/lib/master_tok.l ++++ autofs-5.0.4/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]) +--- autofs-5.0.4.orig/lib/parse_subs.c ++++ autofs-5.0.4/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 exp + 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, in + 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; ++} ++ +--- autofs-5.0.4.orig/modules/lookup_file.c ++++ autofs-5.0.4/modules/lookup_file.c +@@ -523,10 +523,10 @@ prepare_plus_include(struct autofs_point + { + 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 + 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 + */ + 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 + if (inc) + source->recurse = 1; + ++ free_map_type_info(info); + free(buf); + + return source; +--- autofs-5.0.4.orig/modules/lookup_ldap.c ++++ autofs-5.0.4/modules/lookup_ldap.c +@@ -1119,11 +1119,26 @@ static int parse_server_string(unsigned + 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++; +--- autofs-5.0.4.orig/modules/mount_autofs.c ++++ autofs-5.0.4/modules/mount_autofs.c +@@ -50,7 +50,7 @@ int mount_mount(struct autofs_point *ap, + 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, + + 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, + } + 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) { +--- autofs-5.0.4.orig/modules/parse_sun.c ++++ autofs-5.0.4/modules/parse_sun.c +@@ -245,7 +245,9 @@ int expandsunent(const char *src, char * + *(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++; + } + +--- autofs-5.0.4.orig/modules/replicated.c ++++ autofs-5.0.4/modules/replicated.c +@@ -1168,6 +1168,28 @@ static int add_local_path(struct host ** + 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, stru + 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, stru + + /* 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 */ +--- autofs-5.0.4.orig/CHANGELOG ++++ autofs-5.0.4/CHANGELOG +@@ -19,6 +19,7 @@ + - 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-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-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-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-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.spec b/autofs.spec index 56d86f2..ccb1ae1 100644 --- a/autofs.spec +++ b/autofs.spec @@ -4,7 +4,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.0.4 -Release: 8 +Release: 9 Epoch: 1 License: GPLv2+ Group: System Environment/Daemons @@ -19,6 +19,18 @@ Patch6: autofs-5.0.4-fix-select-fd-limit.patch Patch7: autofs-5.0.4-make-hash-table-scale-to-thousands-of-entries.patch Patch8: autofs-5.0.4-fix-quoted-mess.patch Patch9: autofs-5.0.4-use-CLOEXEC-flag-setmntent.patch +Patch10: autofs-5.0.4-fix-hosts-map-use-after-free.patch +Patch11: autofs-5.0.4-uris-list-locking-fix.patch +Patch12: autofs-5.0.4-renew-sasl-creds-upon-reconnect-fail.patch +Patch13: autofs-5.0.4-library-reload-fix-update.patch +Patch14: autofs-5.0.4-force-unlink-umount.patch +Patch15: autofs-5.0.4-always-read-file-maps.patch +Patch16: autofs-5.0.4-code-analysis-corrections.patch +Patch17: autofs-5.0.4-make-MAX_ERR_BUF-and-PARSE_MAX_BUF-use-easier-to-audit.patch +Patch18: autofs-5.0.4-easy-alloca-replacements.patch +Patch19: autofs-5.0.4-configure-libtirpc.patch +Patch20: autofs-5.0.4-ipv6-name-and-address-support.patch +Patch21: autofs-5.0.4-ipv6-parse.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs Requires: kernel >= 2.6.17 @@ -69,10 +81,22 @@ echo %{version}-%{release} > .version %patch7 -p1 %patch8 -p1 %patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 %build #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir} -%configure --disable-mount-locking --enable-ignore-busy +%configure --disable-mount-locking --enable-ignore-busy --with-libtirpc make initdir=%{_initrddir} DONTSTRIP=1 %install @@ -121,6 +145,19 @@ fi %{_libdir}/autofs/ %changelog +* Mon Feb 16 2009 Ian Kent - 5.0.4-9 +- 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. +- 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. +- update to configure libtirpc if present. +- update to provide ipv6 name and address support. +- update to provide ipv6 address parsing. + * Thu Feb 5 2009 Ian Kent - 5.0.4-8 - rename program map parsing bug fix patch. - use CLOEXEC flag functionality for setmntent also, if present.