Apply global flag in substitution

Add loop to move through a path name looking for additional matches if
the global flag is provided for a substitution.  The loop breaks when no
more matches are found for the rule.  Previously, the global flag would
end up advancing to the next rule instead of searching farther into the
path for another match.
diff --git a/tar/subst.c b/tar/subst.c
index fd6f8e2..4710e06 100644
--- a/tar/subst.c
+++ b/tar/subst.c
@@ -236,64 +236,66 @@
 				continue;
 		}
 
-		if (regexec(&rule->re, name, 10, matches, 0))
-			continue;
-
-		got_match = 1;
-		print_match |= rule->print;
-		realloc_strncat(result, name, matches[0].rm_so);
-
-		for (i = 0, j = 0; rule->result[i] != '\0'; ++i) {
-			if (rule->result[i] == '~') {
-				realloc_strncat(result, rule->result + j, i - j);
-				realloc_strncat(result,
-				    name + matches[0].rm_so,
-				    matches[0].rm_eo - matches[0].rm_so);
-				j = i + 1;
-				continue;
-			}
-			if (rule->result[i] != '\\')
-				continue;
-
-			++i;
-			c = rule->result[i];
-			switch (c) {
-			case '~':
-			case '\\':
-				realloc_strncat(result, rule->result + j, i - j - 1);
-				j = i;
+		while (1) {
+			if (regexec(&rule->re, name, 10, matches, 0))
 				break;
-			case '1':
-			case '2':
-			case '3':
-			case '4':
-			case '5':
-			case '6':
-			case '7':
-			case '8':
-			case '9':
-				realloc_strncat(result, rule->result + j, i - j - 1);
-				if ((size_t)(c - '0') > (size_t)(rule->re.re_nsub)) {
-					free(*result);
-					*result = NULL;
-					return -1;
+
+			got_match = 1;
+			print_match |= rule->print;
+			realloc_strncat(result, name, matches[0].rm_so);
+
+			for (i = 0, j = 0; rule->result[i] != '\0'; ++i) {
+				if (rule->result[i] == '~') {
+					realloc_strncat(result, rule->result + j, i - j);
+					realloc_strncat(result,
+					    name + matches[0].rm_so,
+					    matches[0].rm_eo - matches[0].rm_so);
+					j = i + 1;
+					continue;
 				}
-				realloc_strncat(result, name + matches[c - '0'].rm_so, matches[c - '0'].rm_eo - matches[c - '0'].rm_so);
-				j = i + 1;
-				break;
-			default:
-				/* Just continue; */
-				break;
+				if (rule->result[i] != '\\')
+					continue;
+
+				++i;
+				c = rule->result[i];
+				switch (c) {
+				case '~':
+				case '\\':
+					realloc_strncat(result, rule->result + j, i - j - 1);
+					j = i;
+					break;
+				case '1':
+				case '2':
+				case '3':
+				case '4':
+				case '5':
+				case '6':
+				case '7':
+				case '8':
+				case '9':
+					realloc_strncat(result, rule->result + j, i - j - 1);
+					if ((size_t)(c - '0') > (size_t)(rule->re.re_nsub)) {
+						free(*result);
+						*result = NULL;
+						return -1;
+					}
+					realloc_strncat(result, name + matches[c - '0'].rm_so, matches[c - '0'].rm_eo - matches[c - '0'].rm_so);
+					j = i + 1;
+					break;
+				default:
+					/* Just continue; */
+					break;
+				}
+
 			}
 
+			realloc_strcat(result, rule->result + j);
+
+			name += matches[0].rm_eo;
+
+			if (!rule->global)
+				break;
 		}
-
-		realloc_strcat(result, rule->result + j);
-
-		name += matches[0].rm_eo;
-
-		if (!rule->global)
-			break;
 	}
 
 	if (got_match)
diff --git a/tar/test/test_option_s.c b/tar/test/test_option_s.c
index a1f8697..ee8332f 100644
--- a/tar/test/test_option_s.c
+++ b/tar/test/test_option_s.c
@@ -82,9 +82,9 @@
 	 */
 	assertMakeDir("test4", 0755);
 	systemf("%s -cf test4.tar in/d1/foo in/d1/bar",
-	    testprog, testprog);
+	    testprog);
 	systemf("%s -xf test4.tar -s /foo/bar/ -s }bar}baz} -C test4",
-	    testprog, testprog);
+	    testprog);
 	assertFileContents("foo", 3, "test4/in/d1/bar");
 	assertFileContents("bar", 3, "test4/in/d1/baz");
 
@@ -258,4 +258,23 @@
 	assertFileContents("foo", 3, "test13a/in/d1/hardlink2");
 	assertIsHardlink("test13a/in/d1/foo", "test13a/in/d1/hardlink2");
 	/* TODO: See above; expand this test to verify renames at creation. */
+
+	/*
+	 * Test 14: Global substitutions when extracting archive.
+	 */
+    /* Global substitution. */
+	assertMakeDir("test14", 0755);
+	systemf("%s -cf test14.tar in/d1/foo in/d1/bar",
+	    testprog);
+	systemf("%s -xf test14.tar -s /o/z/g -s /bar/baz/ -C test14",
+	    testprog);
+	assertFileContents("foo", 3, "test14/in/d1/fzz");
+	assertFileContents("bar", 3, "test14/in/d1/baz");
+    /* Singular substitution. */
+	systemf("%s -cf test14.tar in/d1/foo in/d1/bar",
+	    testprog);
+	systemf("%s -xf test14.tar -s /o/z/ -s /bar/baz/ -C test14",
+	    testprog);
+	assertFileContents("foo", 3, "test14/in/d1/fzo");
+	assertFileContents("bar", 3, "test14/in/d1/baz");
 }