--- autofs-4.1.3/modules/parse_sun.c.multi-over	2005-01-17 21:49:30.000000000 +0800
+++ autofs-4.1.3/modules/parse_sun.c	2005-01-17 21:51:06.000000000 +0800
@@ -55,6 +55,13 @@
 	int slashify_colons;	/* Change colons to slashes? */
 };
 
+struct multi_mnt {
+	char *path;
+	char *options;
+	char *location;
+	struct multi_mnt *next;
+};
+
 struct utsname un;
 char processor[65];		/* Not defined on Linux, so we make our own */
 
@@ -609,6 +616,69 @@
 }
 
 /*
+ * Build list of mounts in shortest -> longest order.
+ * Pass in list head and return list head.
+ */
+struct multi_mnt *multi_add_list(struct multi_mnt *list,
+				 char *path, char *options, char *location)
+{
+	struct multi_mnt *mmptr, *new, *old = NULL;
+	int plen;
+
+	if (!path || !options || !location)
+		return NULL;
+
+	new = malloc(sizeof(struct multi_mnt));
+	if (!new)
+		return NULL;
+
+	new->path = path;
+	new->options = options;
+	new->location = location;
+
+	plen = strlen(path);
+	mmptr = list;
+	while (mmptr) {
+		if (plen <= strlen(mmptr->path))
+			break;
+		old = mmptr;
+		mmptr = mmptr->next;
+	}
+
+	if (old)
+		old->next = new;
+	new->next = mmptr;
+
+	return old ? list : new;
+}
+
+void multi_free_list(struct multi_mnt *list)
+{
+	struct multi_mnt *next;
+
+	if (!list)
+		return;
+
+	next = list;
+	while (next) {
+		struct multi_mnt *this = next;
+
+		next = this->next;
+
+		if (this->path)
+			free(this->path);
+
+		if (this->options)
+			free(this->options);
+
+		if (this->location)
+			free(this->location);
+
+		free(this);
+	}
+}
+
+/*
  * syntax is:
  *	[-options] location [location] ...
  *	[-options] [mountpoint [-options] location [location] ... ]...
@@ -661,6 +731,7 @@
 	debug(MODPREFIX "gathered options: %s", options);
 
 	if (*p == '/') {
+		struct multi_mnt *list, *head = NULL, *next;
 		int l;
 		char *multi_root;
 
@@ -679,16 +750,15 @@
 		do {
 			char *myoptions = strdup(options);
 			char *path, *loc;
-			int pathlen, loclen;
 
 			if (myoptions == NULL) {
 				error(MODPREFIX "multi strdup: %m");
 				free(options);
+				multi_free_list(head);
 				return 1;
 			}
 
 			path = dequote(p, l = chunklen(p, 0));
-			pathlen = strlen(path);
 
 			p += l;
 			p = skipspace(p);
@@ -706,6 +776,7 @@
 						    "multi concat_options: %m");
 						free(options);
 						free(path);
+						multi_free_list(head);
 						return 1;
 					}
 					p = skipspace(p);
@@ -721,28 +792,42 @@
 			l = q - p;
 
 			loc = dequote(p, l);
-			loclen = strlen(loc);
-
 			if (loc == NULL || path == NULL) {
 				error(MODPREFIX "out of memory");
 				free(loc);
 				free(path);
 				free(options);
+				free(myoptions);
+				multi_free_list(head);
 				return 1;
 			}
 
 			p += l;
 			p = skipspace(p);
 
+			list = head;
+			head = multi_add_list(list, path, myoptions, loc);
+			if (!head) {
+				free(loc);
+				free(path);
+				free(options);
+				free(myoptions);
+				multi_free_list(list);
+				return 1;
+			}
+		} while (*p == '/');
+
+		next = head;
+		while (next) {
 			debug(MODPREFIX
 			      "multimount: %.*s on %.*s with options %s",
-			      loclen, loc, pathlen, path, myoptions);
+			      strlen(next->location), next->location,
+			      strlen(next->path), next->path, next->options);
 
-			rv = sun_mount(multi_root, path, pathlen, loc, loclen,
-				       myoptions);
-			free(path);
-			free(loc);
-			free(myoptions);
+			rv = sun_mount(multi_root,
+				       next->path, strlen(next->path),
+				       next->location, strlen(next->location),
+				       next->options);
 
 			/* Convert non-strict failure into success */
 			if (rv < 0) {
@@ -751,7 +836,10 @@
 			} else if (rv > 0)
 				break;
 
-		} while (*p == '/');
+			next = next->next;
+		}
+
+		multi_free_list(head);
 
 		free(options);
 		return rv;
