Ian Kent 64001b
diff --git a/lib/master_parse.y b/lib/master_parse.y
Ian Kent 64001b
index f9cba05..ab2895d 100644
Ian Kent 64001b
--- a/lib/master_parse.y
Ian Kent 64001b
+++ b/lib/master_parse.y
Ian Kent 64001b
@@ -45,6 +45,7 @@ extern void master_set_scan_buffer(const char *);
Ian Kent 64001b
 static char *master_strdup(char *);
Ian Kent 64001b
 static void local_init_vars(void);
Ian Kent 64001b
 static void local_free_vars(void);
Ian Kent 64001b
+static void trim_maptype(char *);
Ian Kent 64001b
 static int add_multi_mapstr(void);
Ian Kent 64001b
 
Ian Kent 64001b
 static int master_error(const char *s);
Ian Kent 64001b
@@ -141,21 +142,9 @@ line:
Ian Kent 64001b
 	}
Ian Kent 64001b
 	| PATH MULTITYPE maplist
Ian Kent 64001b
 	{
Ian Kent 64001b
-		char *tmp;
Ian Kent 64001b
-
Ian Kent 64001b
-		tmp = strchr($2, ':');
Ian Kent 64001b
-		if (tmp)
Ian Kent 64001b
-			*tmp = '\0';
Ian Kent 64001b
-		else {
Ian Kent 64001b
-			int len = strlen($2);
Ian Kent 64001b
-			while (len-- && isblank($2[len]))
Ian Kent 64001b
-				$2[len] = '\0';
Ian Kent 64001b
-			if (len < 4) {
Ian Kent 64001b
-				master_notify($2);
Ian Kent 64001b
-				local_free_vars();
Ian Kent 64001b
-				YYABORT;
Ian Kent 64001b
-			}
Ian Kent 64001b
-		}
Ian Kent 64001b
+		char *tmp = NULL;
Ian Kent 64001b
+
Ian Kent 64001b
+		trim_maptype($2);
Ian Kent 64001b
 
Ian Kent 64001b
 		path = master_strdup($1);
Ian Kent 64001b
 		if (!path) {
Ian Kent 64001b
@@ -312,81 +301,93 @@ map:	PATH
Ian Kent 64001b
 			YYABORT;
Ian Kent 64001b
 		}
Ian Kent 64001b
 	}
Ian Kent 64001b
-	| MAPTYPE COLON PATH
Ian Kent 64001b
+	| MAPTYPE PATH
Ian Kent 64001b
 	{
Ian Kent 64001b
 		char *tmp = NULL;
Ian Kent 64001b
 
Ian Kent 64001b
+		trim_maptype($1);
Ian Kent 64001b
+
Ian Kent 64001b
 		if ((tmp = strchr($1, ',')))
Ian Kent 64001b
 			*tmp++ = '\0';
Ian Kent 64001b
 
Ian Kent 64001b
 		type = master_strdup($1);
Ian Kent 64001b
 		if (!type) {
Ian Kent 64001b
+			master_error("memory allocation error");
Ian Kent 64001b
 			local_free_vars();
Ian Kent 64001b
 			YYABORT;
Ian Kent 64001b
 		}
Ian Kent 64001b
 		if (tmp) {
Ian Kent 64001b
 			format = master_strdup(tmp);
Ian Kent 64001b
 			if (!format) {
Ian Kent 64001b
+				master_error("memory allocation error");
Ian Kent 64001b
 				local_free_vars();
Ian Kent 64001b
 				YYABORT;
Ian Kent 64001b
 			}
Ian Kent 64001b
 		}
Ian Kent 64001b
 		tmp_argc++;
Ian Kent 64001b
-		tmp_argv = add_argv(tmp_argc, tmp_argv, $3);
Ian Kent 64001b
+		tmp_argv = add_argv(tmp_argc, tmp_argv, $2);
Ian Kent 64001b
 		if (!tmp_argv) {
Ian Kent 64001b
 			master_error("memory allocation error");
Ian Kent 64001b
 			local_free_vars();
Ian Kent 64001b
 			YYABORT;
Ian Kent 64001b
 		}
Ian Kent 64001b
 	}
Ian Kent 64001b
-	| MAPTYPE COLON MAPNAME
Ian Kent 64001b
+	| MAPTYPE MAPNAME
Ian Kent 64001b
 	{
Ian Kent 64001b
 		char *tmp = NULL;
Ian Kent 64001b
 
Ian Kent 64001b
+		trim_maptype($1);
Ian Kent 64001b
+
Ian Kent 64001b
 		if ((tmp = strchr($1, ',')))
Ian Kent 64001b
 			*tmp++ = '\0';
Ian Kent 64001b
 
Ian Kent 64001b
 		type = master_strdup($1);
Ian Kent 64001b
 		if (!type) {
Ian Kent 64001b
+			master_error("memory allocation error");
Ian Kent 64001b
 			local_free_vars();
Ian Kent 64001b
 			YYABORT;
Ian Kent 64001b
 		}
Ian Kent 64001b
 		if (tmp) {
Ian Kent 64001b
 			format = master_strdup(tmp);
Ian Kent 64001b
 			if (!format) {
Ian Kent 64001b
+				master_error("memory allocation error");
Ian Kent 64001b
 				local_free_vars();
Ian Kent 64001b
 				YYABORT;
Ian Kent 64001b
 			}
Ian Kent 64001b
 		}
Ian Kent 64001b
 		tmp_argc++;
Ian Kent 64001b
-		tmp_argv = add_argv(tmp_argc, tmp_argv, $3);
Ian Kent 64001b
+		tmp_argv = add_argv(tmp_argc, tmp_argv, $2);
Ian Kent 64001b
 		if (!tmp_argv) {
Ian Kent 64001b
 			master_error("memory allocation error");
Ian Kent 64001b
 			local_free_vars();
Ian Kent 64001b
 			YYABORT;
Ian Kent 64001b
 		}
Ian Kent 64001b
 	}
Ian Kent 64001b
-	| MAPTYPE COLON dn
Ian Kent 64001b
+	| MAPTYPE dn
Ian Kent 64001b
 	{
Ian Kent 64001b
 		char *tmp = NULL;
Ian Kent 64001b
 
Ian Kent 64001b
+		trim_maptype($1);
Ian Kent 64001b
+
Ian Kent 64001b
 		if ((tmp = strchr($1, ',')))
Ian Kent 64001b
 			*tmp++ = '\0';
Ian Kent 64001b
 
Ian Kent 64001b
 		type = master_strdup($1);
Ian Kent 64001b
 		if (!type) {
Ian Kent 64001b
+			master_error("memory allocation error");
Ian Kent 64001b
 			local_free_vars();
Ian Kent 64001b
 			YYABORT;
Ian Kent 64001b
 		}
Ian Kent 64001b
 		if (tmp) {
Ian Kent 64001b
 			format = master_strdup(tmp);
Ian Kent 64001b
 			if (!format) {
Ian Kent 64001b
+				master_error("memory allocation error");
Ian Kent 64001b
 				local_free_vars();
Ian Kent 64001b
 				YYABORT;
Ian Kent 64001b
 			}
Ian Kent 64001b
 		}
Ian Kent 64001b
 		tmp_argc++;
Ian Kent 64001b
-		tmp_argv = add_argv(tmp_argc, tmp_argv, $3);
Ian Kent 64001b
+		tmp_argv = add_argv(tmp_argc, tmp_argv, $2);
Ian Kent 64001b
 		if (!tmp_argv) {
Ian Kent 64001b
 			master_error("memory allocation error");
Ian Kent 64001b
 			local_free_vars();
Ian Kent 64001b
@@ -396,6 +397,7 @@ map:	PATH
Ian Kent 64001b
 		if (*tmp_argv[0]) {
Ian Kent 64001b
 			tmp = malloc(strlen(type) + strlen(tmp_argv[0]) + 2);
Ian Kent 64001b
 			if (!tmp) {
Ian Kent 64001b
+				master_error("memory allocation error");
Ian Kent 64001b
 				local_free_vars();
Ian Kent 64001b
 				YYABORT;
Ian Kent 64001b
 			}
Ian Kent 64001b
@@ -628,33 +630,47 @@ static void local_free_vars(void)
Ian Kent 64001b
 	}
Ian Kent 64001b
 }
Ian Kent 64001b
 
Ian Kent 64001b
-static int add_multi_mapstr(void)
Ian Kent 64001b
+static void trim_maptype(char *type)
Ian Kent 64001b
 {
Ian Kent 64001b
-	/* We need the individual map types for a multi map */
Ian Kent 64001b
-	if (!type) {
Ian Kent 64001b
-		if (tmp_argc > 0 && *tmp_argv[0] == '/')
Ian Kent 64001b
-			type = strdup("file");
Ian Kent 64001b
-		else
Ian Kent 64001b
-			return 0;
Ian Kent 64001b
+	char *tmp;
Ian Kent 64001b
+
Ian Kent 64001b
+	tmp = strchr(type, ':');
Ian Kent 64001b
+	if (tmp)
Ian Kent 64001b
+		*tmp = '\0';
Ian Kent 64001b
+	else {
Ian Kent 64001b
+		int len = strlen(type);
Ian Kent 64001b
+		while (len-- && isblank(type[len]))
Ian Kent 64001b
+			type[len] = '\0';
Ian Kent 64001b
 	}
Ian Kent 64001b
+	return;
Ian Kent 64001b
+}
Ian Kent 64001b
+
Ian Kent 64001b
+static int add_multi_mapstr(void)
Ian Kent 64001b
+{
Ian Kent 64001b
+	if (type) {
Ian Kent 64001b
+		/* If type given and format is non-null add it back */
Ian Kent 64001b
+		if (format) {
Ian Kent 64001b
+			int len = strlen(type) + strlen(format) + 2;
Ian Kent 64001b
+			char *tmp = realloc(type, len);
Ian Kent 64001b
+			if (!tmp)
Ian Kent 64001b
+				return 0;
Ian Kent 64001b
+			type = tmp;
Ian Kent 64001b
+			strcat(type, ",");
Ian Kent 64001b
+			strcat(type, format);
Ian Kent 64001b
+			free(format);
Ian Kent 64001b
+			format = NULL;
Ian Kent 64001b
+		}
Ian Kent 64001b
 
Ian Kent 64001b
-	if (format) {
Ian Kent 64001b
-		char *tmp = realloc(type, strlen(type) + strlen(format) + 2);
Ian Kent 64001b
-		if (!tmp)
Ian Kent 64001b
+		local_argc++;
Ian Kent 64001b
+		local_argv = add_argv(local_argc, local_argv, type);
Ian Kent 64001b
+		if (!local_argv) {
Ian Kent 64001b
+			free(type);
Ian Kent 64001b
+			type = NULL;
Ian Kent 64001b
 			return 0;
Ian Kent 64001b
-		type = tmp;
Ian Kent 64001b
-		strcat(type, ",");
Ian Kent 64001b
-		strcat(type, format);
Ian Kent 64001b
-		free(format);
Ian Kent 64001b
-		format = NULL;
Ian Kent 64001b
-	}
Ian Kent 64001b
+		}
Ian Kent 64001b
 
Ian Kent 64001b
-	local_argc++;
Ian Kent 64001b
-	local_argv = add_argv(local_argc, local_argv, type);
Ian Kent 64001b
-	if (!local_argv) {
Ian Kent 64001b
 		free(type);
Ian Kent 64001b
 		type = NULL;
Ian Kent 64001b
-		return 0;
Ian Kent 64001b
 	}
Ian Kent 64001b
 
Ian Kent 64001b
 	local_argv = append_argv(local_argc, local_argv, tmp_argc, tmp_argv);
Ian Kent 64001b
@@ -667,8 +683,6 @@ static int add_multi_mapstr(void)
Ian Kent 64001b
 
Ian Kent 64001b
 	tmp_argc = 0;
Ian Kent 64001b
 	tmp_argv = NULL;
Ian Kent 64001b
-	free(type);
Ian Kent 64001b
-	type = NULL;
Ian Kent 64001b
 
Ian Kent 64001b
 	return 1;
Ian Kent 64001b
 }
Ian Kent 64001b
diff --git a/lib/master_tok.l b/lib/master_tok.l
Ian Kent 64001b
index 0548de1..9bfeefa 100644
Ian Kent 64001b
--- a/lib/master_tok.l
Ian Kent 64001b
+++ b/lib/master_tok.l
Ian Kent 64001b
@@ -111,9 +111,9 @@ DNATTRSTR	{AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C}
Ian Kent 64001b
 DNNAMESTR	([[:alnum:]_.\-]+)
Ian Kent 64001b
 
Ian Kent 64001b
 INTMAP		(-hosts|-null)
Ian Kent 64001b
-MULTI		((multi)(,(sun|hesiod))?[\:]?{OPTWS})
Ian Kent 64001b
+MULTI		((multi)(,(sun|hesiod))?(:{OPTWS}|{WS}))
Ian Kent 64001b
 MULTISEP	([\-]{2}[[:blank:]]+)
Ian Kent 64001b
-MTYPE		((file|program|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?)
Ian Kent 64001b
+MTYPE		((file|program|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?(:{OPTWS}|{WS}))
Ian Kent 64001b
 
Ian Kent 64001b
 
Ian Kent 64001b
 OPTTOUT		(-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
Ian Kent 64001b
@@ -192,7 +192,7 @@ OPTTOUT		(-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
Ian Kent 64001b
 		return(MULTITYPE);
Ian Kent 64001b
 	}
Ian Kent 64001b
 
Ian Kent 64001b
-	{MTYPE}/":" {
Ian Kent 64001b
+	{MTYPE} {
Ian Kent 64001b
 		strcpy(master_lval.strtype, master_text);
Ian Kent 64001b
 		return(MAPTYPE);
Ian Kent 64001b
 	}
Ian Kent d18ed0
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
Ian Kent d18ed0
index 0e36a6f..98afaa9 100644
Ian Kent d18ed0
--- a/man/auto.master.5.in
Ian Kent d18ed0
+++ b/man/auto.master.5.in
Ian Kent d18ed0
@@ -103,6 +103,10 @@ entries are used for maps.
Ian Kent d18ed0
 .B ldap \fPor\fB ldaps
Ian Kent d18ed0
 The map is stored in an LDAP directory. If \fBldaps\fP is used the
Ian Kent d18ed0
 appropriate certificate must be configured in the LDAP client.
Ian Kent d18ed0
+.TP
Ian Kent d18ed0
+.B multi
Ian Kent d18ed0
+This map type allows the specification of multiple maps separated
Ian Kent d18ed0
+by "--". These maps are searched in order to resolve key lookups.
Ian Kent d18ed0
 .RE
Ian Kent d18ed0
 .TP
Ian Kent d18ed0
 \fBformat\fP
Ian Kent 64001b
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
Ian Kent 64001b
index 38ca36c..8fa94ae 100644
Ian Kent 64001b
--- a/modules/lookup_multi.c
Ian Kent 64001b
+++ b/modules/lookup_multi.c
Ian Kent 64001b
@@ -19,6 +19,7 @@
Ian Kent 64001b
 #include <stdio.h>
Ian Kent 64001b
 #include <string.h>
Ian Kent 64001b
 #include <unistd.h>
Ian Kent 64001b
+#include <sys/stat.h>
Ian Kent 64001b
 
Ian Kent 64001b
 #define MODULE_LOOKUP
Ian Kent 64001b
 #include "automount.h"
Ian Kent 64001b
@@ -28,7 +29,7 @@
Ian Kent 64001b
 
Ian Kent 64001b
 struct module_info {
Ian Kent 64001b
 	int argc;
Ian Kent 64001b
-	const char *const *argv;
Ian Kent 64001b
+	const char **argv;
Ian Kent 64001b
 	struct lookup_mod *mod;
Ian Kent 64001b
 };
Ian Kent 64001b
 
Ian Kent 64001b
@@ -40,11 +41,105 @@ struct lookup_context {
Ian Kent 64001b
 
Ian Kent 64001b
 int lookup_version = AUTOFS_LOOKUP_VERSION;	/* Required by protocol */
Ian Kent 64001b
 
Ian Kent 64001b
+static struct lookup_mod *nss_open_lookup(const char *format, int argc, const char **argv)
Ian Kent 64001b
+{
Ian Kent 64001b
+	struct list_head nsslist;
Ian Kent 64001b
+	struct list_head *head, *p;
Ian Kent 64001b
+	struct lookup_mod *mod;
Ian Kent 64001b
+	char buf[MAX_ERR_BUF], *estr;
Ian Kent 64001b
+
Ian Kent 64001b
+	if (!argv || !argv[0])
Ian Kent 64001b
+		return NULL;
Ian Kent 64001b
+
Ian Kent 64001b
+	if (*argv[0] == '/')
Ian Kent 64001b
+		return open_lookup("file", MODPREFIX, format, argc, argv);
Ian Kent 64001b
+
Ian Kent 64001b
+	if (!strncmp(argv[0], "file", 4) ||
Ian Kent 64001b
+	    !strncmp(argv[0], "yp", 2) ||
Ian Kent 64001b
+	    !strncmp(argv[0], "nisplus", 7) ||
Ian Kent 64001b
+	    !strncmp(argv[0], "nis", 3) ||
Ian Kent 64001b
+	    !strncmp(argv[0], "ldaps", 5) ||
Ian Kent 64001b
+	    !strncmp(argv[0], "ldap", 4)) {
Ian Kent 64001b
+		const char *fmt = strchr(argv[0], ',');
Ian Kent 64001b
+		if (fmt)
Ian Kent 64001b
+			fmt++;
Ian Kent 64001b
+		else
Ian Kent 64001b
+			fmt = format;
Ian Kent 64001b
+		return open_lookup(argv[0], MODPREFIX, fmt, argc -1, argv + 1);
Ian Kent 64001b
+	}
Ian Kent 64001b
+
Ian Kent 64001b
+	INIT_LIST_HEAD(&nsslist);
Ian Kent 64001b
+
Ian Kent 64001b
+	if (nsswitch_parse(&nsslist)) {
Ian Kent 64001b
+		if (!list_empty(&nsslist))
Ian Kent 64001b
+			free_sources(&nsslist);
Ian Kent 64001b
+		error(LOGOPT_ANY, "can't to read name service switch config.");
Ian Kent 64001b
+		return NULL;
Ian Kent 64001b
+	}
Ian Kent 64001b
+
Ian Kent 64001b
+	head = &nsslist;
Ian Kent 64001b
+	list_for_each(p, head) {
Ian Kent 64001b
+		struct nss_source *this;
Ian Kent 64001b
+
Ian Kent 64001b
+		this = list_entry(p, struct nss_source, list);
Ian Kent 64001b
+
Ian Kent 64001b
+		if (!strcmp(this->source, "files")) {
Ian Kent 64001b
+			char src_file[] = "file";
Ian Kent 64001b
+			char src_prog[] = "program";
Ian Kent 64001b
+			struct stat st;
Ian Kent 64001b
+			char *type, *path, *save_argv0;
Ian Kent 64001b
+
Ian Kent 64001b
+			path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(argv[0]) + 2);
Ian Kent 64001b
+			if (!path) {
Ian Kent 64001b
+				estr = strerror_r(errno, buf, MAX_ERR_BUF);
Ian Kent 64001b
+				crit(LOGOPT_ANY, MODPREFIX "error: %s", estr);
Ian Kent 64001b
+				free_sources(&nsslist);
Ian Kent 64001b
+				return NULL;
Ian Kent 64001b
+			}
Ian Kent 64001b
+			strcpy(path, AUTOFS_MAP_DIR);
Ian Kent 64001b
+			strcat(path, "/");
Ian Kent 64001b
+			strcat(path, argv[0]);
Ian Kent 64001b
+
Ian Kent 64001b
+			if (stat(path, &st) == -1 || !S_ISREG(st.st_mode)) {
Ian Kent 64001b
+				free(path);
Ian Kent 64001b
+				continue;
Ian Kent 64001b
+			}
Ian Kent 64001b
+
Ian Kent 64001b
+			if (st.st_mode & __S_IEXEC)
Ian Kent 64001b
+				type = src_prog;
Ian Kent 64001b
+			else
Ian Kent 64001b
+				type = src_file;
Ian Kent 64001b
+
Ian Kent 64001b
+			save_argv0 = (char *) argv[0];
Ian Kent 64001b
+			argv[0] = path;
Ian Kent 64001b
+
Ian Kent 64001b
+			mod = open_lookup(type, MODPREFIX, format, argc, argv);
Ian Kent 64001b
+			if (mod) {
Ian Kent 64001b
+				free_sources(&nsslist);
Ian Kent 64001b
+				free(save_argv0);
Ian Kent 64001b
+				return mod;
Ian Kent 64001b
+			}
Ian Kent 64001b
+
Ian Kent 64001b
+			argv[0] = save_argv0;
Ian Kent 64001b
+			free(path);
Ian Kent 64001b
+		}
Ian Kent 64001b
+
Ian Kent 64001b
+		mod = open_lookup(this->source, MODPREFIX, format, argc, argv);
Ian Kent 64001b
+		if (mod) {
Ian Kent 64001b
+			free_sources(&nsslist);
Ian Kent 64001b
+			return mod;
Ian Kent 64001b
+		}
Ian Kent 64001b
+	}
Ian Kent 64001b
+	free_sources(&nsslist);
Ian Kent 64001b
+
Ian Kent 64001b
+	return NULL;
Ian Kent 64001b
+}
Ian Kent 64001b
+
Ian Kent 64001b
 int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void **context)
Ian Kent 64001b
 {
Ian Kent 64001b
 	struct lookup_context *ctxt;
Ian Kent 64001b
 	char buf[MAX_ERR_BUF];
Ian Kent 64001b
-	char *map, *mapfmt;
Ian Kent 64001b
+	char **args;
Ian Kent 64001b
 	int i, an;
Ian Kent 64001b
 	char *estr;
Ian Kent 64001b
 
Ian Kent 64001b
@@ -73,39 +168,42 @@ int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void *
Ian Kent 64001b
 
Ian Kent 64001b
 	memcpy(ctxt->argl, argv, (argc + 1) * sizeof(const char *));
Ian Kent 64001b
 
Ian Kent 64001b
+	args = NULL;
Ian Kent 64001b
 	for (i = an = 0; ctxt->argl[an]; an++) {
Ian Kent 64001b
 		if (ctxt->m[i].argc == 0) {
Ian Kent 64001b
-			ctxt->m[i].argv = &ctxt->argl[an];
Ian Kent 64001b
+			args = (char **) &ctxt->argl[an];
Ian Kent 64001b
 		}
Ian Kent 64001b
 		if (!strcmp(ctxt->argl[an], "--")) {
Ian Kent 64001b
 			ctxt->argl[an] = NULL;
Ian Kent 64001b
+			if (!args) {
Ian Kent 64001b
+				crit(LOGOPT_ANY,
Ian Kent 64001b
+				     MODPREFIX "error assigning map args");
Ian Kent 64001b
+				goto error_out;
Ian Kent 64001b
+			}
Ian Kent 64001b
+			ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args);
Ian Kent 64001b
+			if (!ctxt->m[i].argv)
Ian Kent 64001b
+				goto nomem;
Ian Kent 64001b
+			args = NULL;
Ian Kent 64001b
 			i++;
Ian Kent 64001b
 		} else {
Ian Kent 64001b
 			ctxt->m[i].argc++;
Ian Kent 64001b
 		}
Ian Kent 64001b
 	}
Ian Kent 64001b
 
Ian Kent 64001b
-	for (i = 0; i < ctxt->n; i++) {
Ian Kent 64001b
-		if (!ctxt->m[i].argv[0]) {
Ian Kent 64001b
-			crit(LOGOPT_ANY, MODPREFIX "missing module name");
Ian Kent 64001b
-			goto error_out;
Ian Kent 64001b
-		}
Ian Kent 64001b
-		map = strdup(ctxt->m[i].argv[0]);
Ian Kent 64001b
-		if (!map)
Ian Kent 64001b
+	/* catch the last one */
Ian Kent 64001b
+	if (args) {
Ian Kent 64001b
+		ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args);
Ian Kent 64001b
+		if (!ctxt->m[i].argv)
Ian Kent 64001b
 			goto nomem;
Ian Kent 64001b
+	}
Ian Kent 64001b
 
Ian Kent 64001b
-		if ((mapfmt = strchr(map, ',')))
Ian Kent 64001b
-			*(mapfmt++) = '\0';
Ian Kent 64001b
-
Ian Kent 64001b
-		if (!(ctxt->m[i].mod = open_lookup(map, MODPREFIX,
Ian Kent 64001b
-						   mapfmt ? mapfmt : my_mapfmt,
Ian Kent 64001b
-						   ctxt->m[i].argc - 1,
Ian Kent 64001b
-						   ctxt->m[i].argv + 1))) {
Ian Kent 64001b
+	for (i = 0; i < ctxt->n; i++) {
Ian Kent 64001b
+		ctxt->m[i].mod = nss_open_lookup(my_mapfmt,
Ian Kent 64001b
+				 ctxt->m[i].argc, ctxt->m[i].argv);
Ian Kent 64001b
+		if (!ctxt->m[i].mod) {
Ian Kent 64001b
 			error(LOGOPT_ANY, MODPREFIX "error opening module");
Ian Kent 64001b
-			free(map);
Ian Kent 64001b
 			goto error_out;
Ian Kent 64001b
 		}
Ian Kent 64001b
-		free(map);
Ian Kent 64001b
 	}
Ian Kent 64001b
 
Ian Kent 64001b
 	*context = ctxt;
Ian Kent 64001b
@@ -116,9 +214,12 @@ nomem:
Ian Kent 64001b
 	crit(LOGOPT_ANY, MODPREFIX "error: %s", estr);
Ian Kent 64001b
 error_out:
Ian Kent 64001b
 	if (ctxt) {
Ian Kent 64001b
-		for (i = 0; i < ctxt->n; i++)
Ian Kent 64001b
+		for (i = 0; i < ctxt->n; i++) {
Ian Kent 64001b
 			if (ctxt->m[i].mod)
Ian Kent 64001b
 				close_lookup(ctxt->m[i].mod);
Ian Kent 64001b
+			if (ctxt->m[i].argv)
Ian Kent 64001b
+				free_argv(ctxt->m[i].argc, ctxt->m[i].argv);
Ian Kent 64001b
+		}
Ian Kent 64001b
 		if (ctxt->m)
Ian Kent 64001b
 			free(ctxt->m);
Ian Kent 64001b
 		if (ctxt->argl)
Ian Kent 64001b
@@ -188,6 +289,8 @@ int lookup_done(void *context)
Ian Kent 64001b
 	for (i = 0; i < ctxt->n; i++) {
Ian Kent 64001b
 		if (ctxt->m[i].mod)
Ian Kent 64001b
 			rv = rv || close_lookup(ctxt->m[i].mod);
Ian Kent 64001b
+		if (ctxt->m[i].argv)
Ian Kent 64001b
+			free_argv(ctxt->m[i].argc, ctxt->m[i].argv);
Ian Kent 64001b
 	}
Ian Kent 64001b
 	free(ctxt->argl);
Ian Kent 64001b
 	free(ctxt->m);