Combine IP{,6}T_LIB_DIR into XTABLES_LIBDIR
diff --git a/xtables.c b/xtables.c
index 89863d7..b26b416 100644
--- a/xtables.c
+++ b/xtables.c
@@ -305,12 +305,58 @@
 	}
 }
 
+static void *load_extension(const char *search_path, const char *prefix,
+    const char *name, bool is_target)
+{
+	const char *dir = search_path, *next;
+	void *ptr = NULL;
+	struct stat sb;
+	char path[256];
+
+	do {
+		next = strchr(dir, ':');
+		if (next == NULL)
+			next = dir + strlen(dir);
+		snprintf(path, sizeof(path), "%.*s/libxt_%s.so",
+		         next - dir, dir, name);
+
+		if (dlopen(path, RTLD_NOW) != NULL) {
+			/* Found library.  If it didn't register itself,
+			   maybe they specified target as match. */
+			if (is_target)
+				ptr = find_target(name, DONT_LOAD);
+			else
+				ptr = find_match(name, DONT_LOAD, NULL);
+		} else if (stat(path, &sb) == 0) {
+			fprintf(stderr, "%s: %s\n", path, dlerror());
+		}
+
+		if (ptr != NULL)
+			return ptr;
+
+		snprintf(path, sizeof(path), "%.*s/%s%s.so",
+		         next - dir, dir, prefix, name);
+		if (dlopen(path, RTLD_NOW) != NULL) {
+			if (is_target)
+				ptr = find_target(name, DONT_LOAD);
+			else
+				ptr = find_match(name, DONT_LOAD, NULL);
+		} else if (stat(path, &sb) == 0) {
+			fprintf(stderr, "%s: %s\n", path, dlerror());
+		}
+
+		if (ptr != NULL)
+			return ptr;
+
+		dir = next + 1;
+	} while (*next != '\0');
+
+	return NULL;
+}
+
 struct xtables_match *find_match(const char *name, enum xt_tryload tryload,
 				 struct xtables_rule_match **matches)
 {
-#ifndef NO_SHARED_LIBS
-	struct stat sb;
-#endif
 	struct xtables_match *ptr;
 	const char *icmp6 = "icmp6";
 
@@ -343,25 +389,7 @@
 
 #ifndef NO_SHARED_LIBS
 	if (!ptr && tryload != DONT_LOAD && tryload != DURING_LOAD) {
-		char path[strlen(lib_dir) + sizeof("/.so")
-			  + strlen(afinfo.libprefix) + strlen(name)];
-
-		sprintf(path, "%s/libxt_%s.so", lib_dir, name);
-		if (dlopen(path, RTLD_NOW) != NULL)
-			/* Found library.  If it didn't register itself,
-			   maybe they specified target as match. */
-			ptr = find_match(name, DONT_LOAD, NULL);
-		else if (stat(path, &sb) == 0)
-			fprintf(stderr, "%s: %s\n", path, dlerror());
-
-		if (ptr == NULL) {
-			sprintf(path, "%s/%s%s.so", lib_dir, afinfo.libprefix,
-				name);
-			if (dlopen(path, RTLD_NOW) != NULL)
-				ptr = find_match(name, DONT_LOAD, NULL);
-			else if (stat(path, &sb) == 0)
-				fprintf(stderr, "%s: %s\n", path, dlerror());
-		}
+		ptr = load_extension(lib_dir, afinfo.libprefix, name, false);
 
 		if (ptr == NULL && tryload == LOAD_MUST_SUCCEED)
 			exit_error(PARAMETER_PROBLEM,
@@ -403,9 +431,6 @@
 
 struct xtables_target *find_target(const char *name, enum xt_tryload tryload)
 {
-#ifndef NO_SHARED_LIBS
-	struct stat sb;
-#endif
 	struct xtables_target *ptr;
 
 	/* Standard target? */
@@ -423,25 +448,8 @@
 
 #ifndef NO_SHARED_LIBS
 	if (!ptr && tryload != DONT_LOAD && tryload != DURING_LOAD) {
-		char path[strlen(lib_dir) + sizeof("/.so")
-			  + strlen(afinfo.libprefix) + strlen(name)];
+		ptr = load_extension(lib_dir, afinfo.libprefix, name, true);
 
-		sprintf(path, "%s/libxt_%s.so", lib_dir, name);
-		if (dlopen(path, RTLD_NOW) != NULL)
-			/* Found library.  If it didn't register itself,
-			   maybe they specified match as a target. */
-			ptr = find_target(name, DONT_LOAD);
-		else if (stat(path, &sb) == 0)
-			fprintf(stderr, "%s: %s\n", path, dlerror());
-
-		if (ptr == NULL) {
-			sprintf(path, "%s/%s%s.so", lib_dir, afinfo.libprefix,
-				name);
-			if (dlopen(path, RTLD_NOW) != NULL)
-				ptr = find_target(name, DONT_LOAD);
-			else if (stat(path, &sb) == 0)
-				fprintf(stderr, "%s: %s\n", path, dlerror());
-		}
 		if (ptr == NULL && tryload == LOAD_MUST_SUCCEED)
 			exit_error(PARAMETER_PROBLEM,
 				   "Couldn't load target `%s':%s\n",