Blame SOURCES/autofs-5.0.7-teach-dumpmaps-to-output-simple-key-value-pairs.patch

304803
autofs-5.0.7 - teach dumpmaps to output simple key value pairs
304803
304803
From: Ian Kent <raven@themaw.net>
304803
304803
The dumpmaps option doesn't allow maps to be output in <key, value>
304803
pairs suitable for use as a file map.
304803
304803
This could be useful to save current maps as a backup for emergency
304803
use.
304803
304803
If the dumpmaps option is given and is followed by two parameters,
304803
"<map type> <map name>" then simple <key, value> pairs that would
304803
be read in by a map read are printed to stdout if the given map type
304803
and map name are found in the map configuration.
304803
304803
If the map is an LDAP map and there is more than one map of same name
304803
in different base dns only the first map encountered by autofs will
304803
be listed.
304803
304803
If the map type is an old style multi-map and any one of the map
304803
names in the multi-map entry matches the given map name the entries
304803
that would be used by autofs for the whole multi-map will be listed.
304803
---
304803
 CHANGELOG          |    1 
304803
 daemon/automount.c |   56 ++++++++++++---
304803
 include/master.h   |    1 
304803
 lib/master.c       |  187 +++++++++++++++++++++++++++++++++++++++++++++++++++++
304803
 man/automount.8    |   20 +++++
304803
 5 files changed, 250 insertions(+), 15 deletions(-)
304803
304803
--- autofs-5.0.7.orig/CHANGELOG
304803
+++ autofs-5.0.7/CHANGELOG
304803
@@ -60,6 +60,7 @@
304803
 - fix fix wildcard multi map regression.
304803
 - fix dumpmaps multi output.
304803
 - try and cleanup after dumpmaps.
304803
+- teach dumpmaps to output simple key value pairs.
304803
 
304803
 25/07/2012 autofs-5.0.7
304803
 =======================
304803
--- autofs-5.0.7.orig/daemon/automount.c
304803
+++ autofs-5.0.7/daemon/automount.c
304803
@@ -1725,7 +1725,8 @@ static void usage(void)
304803
 		"	-f --foreground do not fork into background\n"
304803
 		"	-r --random-multimount-selection\n"
304803
 		"			use ramdom replicated server selection\n"
304803
-		"	-m --dumpmaps	dump automounter maps and exit\n"
304803
+		"	-m --dumpmaps [<map type> <map name>]\n"
304803
+		"			dump automounter maps and exit\n"
304803
 		"	-n --negative-timeout n\n"
304803
 		"			set the timeout for failed key lookups.\n"
304803
 		"	-O --global-options\n"
304803
@@ -2125,22 +2126,33 @@ int main(int argc, char *argv[])
304803
 			program);
304803
 #endif
304803
 
304803
-	if (argc == 0)
304803
-		master_list = master_new(NULL, timeout, ghost);
304803
-	else
304803
-		master_list = master_new(argv[0], timeout, ghost);
304803
-
304803
-	if (!master_list) {
304803
-		printf("%s: can't create master map %s", program, argv[0]);
304803
-		exit(1);
304803
-	}
304803
-
304803
 	if (dumpmaps) {
304803
 		struct master_mapent *entry;
304803
 		struct list_head *head, *p;
304803
 		struct mapent_cache *nc;
304803
+		const char *type = NULL;
304803
+		const char *name = NULL;
304803
+		const char *master = NULL;
304803
+
304803
+		if (argc > 0) {
304803
+			if (argc >= 2) {
304803
+				type = argv[0];
304803
+				name = argv[1];
304803
+			}
304803
+			if (argc == 3)
304803
+				master = argv[2];
304803
+		}
304803
 
304803
-		open_log();
304803
+		if (master)
304803
+			master_list = master_new(NULL, timeout, ghost);
304803
+		else
304803
+			master_list = master_new(master, timeout, ghost);
304803
+		if (!master_list) {
304803
+			printf("%s: can't create master map", program);
304803
+			exit(1);
304803
+		}
304803
+
304803
+		log_to_stderr();
304803
 
304803
 		master_init_scan();
304803
 
304803
@@ -2153,7 +2165,15 @@ int main(int argc, char *argv[])
304803
 		master_list->nc = nc;
304803
 
304803
 		lookup_nss_read_master(master_list, 0);
304803
-		master_show_mounts(master_list);
304803
+		if (type) {
304803
+			const char *map = basename(name);
304803
+			if (!map)
304803
+				printf("%s: invalid map name %s\n",
304803
+					program, name);
304803
+			else
304803
+				dump_map(master_list, type, map);
304803
+		} else
304803
+			master_show_mounts(master_list);
304803
 
304803
 		head = &master_list->mounts;
304803
 		p = head->next;
304803
@@ -2168,6 +2188,16 @@ int main(int argc, char *argv[])
304803
 		exit(0);
304803
 	}
304803
 
304803
+	if (argc == 0)
304803
+		master_list = master_new(NULL, timeout, ghost);
304803
+	else
304803
+		master_list = master_new(argv[0], timeout, ghost);
304803
+
304803
+	if (!master_list) {
304803
+		printf("%s: can't create master map %s", program, argv[0]);
304803
+		exit(1);
304803
+	}
304803
+
304803
 	become_daemon(foreground, daemon_check);
304803
 
304803
 	if (pthread_attr_init(&th_attr)) {
304803
--- autofs-5.0.7.orig/include/master.h
304803
+++ autofs-5.0.7/include/master.h
304803
@@ -112,6 +112,7 @@ int master_submount_list_empty(struct au
304803
 int master_notify_submount(struct autofs_point *, const char *path, enum states);
304803
 void master_notify_state_change(struct master *, int);
304803
 int master_mount_mounts(struct master *, time_t, int);
304803
+int dump_map(struct master *, const char *, const char *);
304803
 int master_show_mounts(struct master *);
304803
 extern inline unsigned int master_get_logopt(void);
304803
 int master_list_empty(struct master *);
304803
--- autofs-5.0.7.orig/lib/master.c
304803
+++ autofs-5.0.7/lib/master.c
304803
@@ -1329,6 +1329,193 @@ static void print_map_info(struct map_so
304803
 	return;
304803
 }
304803
 
304803
+static int match_type(const char *source, const char *type)
304803
+{
304803
+	if (!strcmp(source, type))
304803
+		return 1;
304803
+	/* Sources file and files are synonymous */
304803
+	if (!strncmp(source, type, 4) && (strlen(source) <= 5))
304803
+		return 1;
304803
+	return 0;
304803
+}
304803
+
304803
+static char *get_map_name(const char *string)
304803
+{
304803
+	char *name, *tmp;
304803
+	char *start, *end, *base;
304803
+
304803
+	tmp = strdup(string);
304803
+	if (!tmp) {
304803
+		printf("error: allocation failure: %s\n", strerror(errno));
304803
+		return NULL;
304803
+	}
304803
+
304803
+	base = basename(tmp);
304803
+	end = strchr(base, ',');
304803
+	if (end)
304803
+		*end = '\0';
304803
+	start = strchr(tmp, '=');
304803
+	if (start)
304803
+		start++;
304803
+	else {
304803
+		char *colon = strrchr(base, ':');
304803
+		if (colon)
304803
+			start = ++colon;
304803
+		else
304803
+			start = base;
304803
+	}
304803
+
304803
+	name = strdup(start);
304803
+	if (!name)
304803
+		printf("error: allocation failure: %s\n", strerror(errno));
304803
+	free(tmp);
304803
+
304803
+	return name;
304803
+}
304803
+
304803
+static int match_name(struct map_source *source, const char *name)
304803
+{
304803
+	int argc = source->argc;
304803
+	int ret = 0;
304803
+	int i;
304803
+
304803
+	/*
304803
+	 * This can't work for old style "multi" type sources since
304803
+	 * there's no way to know from which map the cache entry came
304803
+	 * from and duplicate entries are ignored at map read time.
304803
+	 * All we can really do is list all the entries for the given
304803
+	 * multi map if one of its map names matches.
304803
+	 */
304803
+	for (i = 0; i < argc; i++) {
304803
+		if (i == 0 || !strcmp(source->argv[i], "--")) {
304803
+			if (i != 0) {
304803
+				i++;
304803
+				if (i >= argc)
304803
+					break;
304803
+			}
304803
+
304803
+			if (source->argv[i] && *source->argv[i] != '-') {
304803
+				char *map = get_map_name(source->argv[i]);
304803
+				if (!map)
304803
+					break;
304803
+				if (!strcmp(map, name)) {
304803
+					ret = 1;
304803
+					free(map);
304803
+					break;
304803
+				}
304803
+				free(map);
304803
+			}
304803
+		}
304803
+	}
304803
+
304803
+	return ret;
304803
+}
304803
+
304803
+int dump_map(struct master *master, const char *type, const char *name)
304803
+{
304803
+	struct list_head *p, *head;
304803
+
304803
+	if (list_empty(&master->mounts)) {
304803
+		printf("no master map entries found\n");
304803
+		return 1;
304803
+	}
304803
+
304803
+	head = &master->mounts;
304803
+	p = head->next;
304803
+	while (p != head) {
304803
+		struct map_source *source;
304803
+		struct master_mapent *this;
304803
+		struct autofs_point *ap;
304803
+		time_t now = time(NULL);
304803
+
304803
+		this = list_entry(p, struct master_mapent, list);
304803
+		p = p->next;
304803
+
304803
+		ap = this->ap;
304803
+
304803
+		/*
304803
+		 * Ensure we actually read indirect map entries so we can
304803
+		 * list them. The map reads won't read any indirect map
304803
+		 * entries (other than those in a file map) unless the
304803
+		 * browse option is set.
304803
+		 */
304803
+		if (ap->type == LKP_INDIRECT)
304803
+			ap->flags |= MOUNT_FLAG_GHOST;
304803
+
304803
+		/* Read the map content into the cache */
304803
+		if (lookup_nss_read_map(ap, NULL, now))
304803
+			lookup_prune_cache(ap, now);
304803
+		else {
304803
+			printf("failed to read map\n");
304803
+			lookup_close_lookup(ap);
304803
+			continue;
304803
+		}
304803
+
304803
+		if (!this->maps) {
304803
+			printf("no map sources found for %s\n", ap->path);
304803
+			lookup_close_lookup(ap);
304803
+			continue;
304803
+		}
304803
+
304803
+		source = this->maps;
304803
+		while (source) {
304803
+			struct map_source *instance;
304803
+			struct mapent *me;
304803
+
304803
+			instance = NULL;
304803
+			if (source->type) {
304803
+				if (!match_type(source->type, type)) {
304803
+					source = source->next;
304803
+					continue;
304803
+				}
304803
+				if (!match_name(source, name)) {
304803
+					source = source->next;
304803
+					continue;
304803
+				}
304803
+				instance = source;
304803
+			} else {
304803
+				struct map_source *map;
304803
+
304803
+				map = source->instance;
304803
+				while (map) {
304803
+					if (!match_type(map->type, type)) {
304803
+						map = map->next;
304803
+						continue;
304803
+					}
304803
+					if (!match_name(map, name)) {
304803
+						map = map->next;
304803
+						continue;
304803
+					}
304803
+					instance = map;
304803
+					break;
304803
+				}
304803
+			}
304803
+
304803
+			if (!instance) {
304803
+				source = source->next;
304803
+				lookup_close_lookup(ap);
304803
+				continue;
304803
+			}
304803
+
304803
+			me = cache_lookup_first(source->mc);
304803
+			if (!me)
304803
+				printf("no keys found in map\n");
304803
+			else {
304803
+				do {
304803
+					if (me->source == instance)
304803
+						printf("%s\t%s\n", me->key, me->mapent);
304803
+				} while ((me = cache_lookup_next(source->mc, me)));
304803
+			}
304803
+
304803
+			lookup_close_lookup(ap);
304803
+			return 1;
304803
+		}
304803
+		lookup_close_lookup(ap);
304803
+	}
304803
+
304803
+	return 0;
304803
+}
304803
+
304803
 int master_show_mounts(struct master *master)
304803
 {
304803
 	struct list_head *p, *head;
304803
--- autofs-5.0.7.orig/man/automount.8
304803
+++ autofs-5.0.7/man/automount.8
304803
@@ -57,8 +57,24 @@ Run the daemon in the foreground and log
304803
 Enables the use of ramdom selection when choosing a host from a
304803
 list of replicated servers.
304803
 .TP
304803
-.I "\-m, \-\-dumpmaps"
304803
-Dump configured automounter maps, then exit.
304803
+.I "\-m, \-\-dumpmaps [<map type> <map name>]"
304803
+With no parameters, list information about the configured automounter
304803
+maps, then exit.
304803
+
304803
+If the dumpmaps option is given and is followed by two parameters,
304803
+"<map type> <map name>" then simple "<key, value>" pairs that would
304803
+be read in by a map read are printed to stdout if the given map type
304803
+and map name are found in the map configuration.
304803
+
304803
+If the map is an LDAP map and there is more than one map of same name
304803
+in different base dns only the first map encountered by autofs will
304803
+be listed. Similarly, if the map is a file map and there is more than
304803
+one map of the same name in different directories, only the first map
304803
+encountered will be listed.
304803
+
304803
+If the map type is an old style multi-map and any one of the map
304803
+names in the multi-map entry matches the given map name the entries
304803
+that would be used by autofs for the whole multi-map will be listed.
304803
 .TP
304803
 .I "\-O, \-\-global-options"
304803
 Allows the specification of global mount options used for all master