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

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