File 0122-restore-Add-regex-matching-of-paths-and-files-to-be-.patch of Package btrfsprogs

From 2f0c2a29ab13b17ae1cc21effcf532f2447b7c8c Mon Sep 17 00:00:00 2001
From: Peter Stuge <peter@stuge.se>
Date: Fri, 25 Nov 2011 01:03:58 +0100
Subject: [PATCH 23/35] restore: Add regex matching of paths and files to be
 restored

The option -m is used to specify the regex string. -c is used to
specify case insensitive matching. -i was already taken.

In order to restore only a single folder somewhere in the btrfs
tree, it is unfortunately neccessary to construct a slightly
nontrivial regex, e.g.:

restore -m '^/(|home(|/username(|/Desktop(|/.*))))$' /dev/sdb2 /output

This is needed in order to match each directory along the way to the
Desktop directory, as well as all contents below the Desktop directory.

Signed-off-by: Peter Stuge <peter@stuge.se>
Signed-off-by: Josef Bacik <josef@redhat.com>
---
 restore.c |   40 ++++++++++++++++++++++++++++++++++------
 1 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/restore.c b/restore.c
index 0b92ed5..e65746a 100644
--- a/restore.c
+++ b/restore.c
@@ -25,6 +25,8 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <zlib.h>
+#include <sys/types.h>
+#include <regex.h>
 #include "kerncompat.h"
 #include "ctree.h"
 #include "disk-io.h"
@@ -451,7 +453,8 @@ set_size:
 }
 
 static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
-		      const char *output_rootdir, const char *dir)
+		      const char *output_rootdir, const char *dir,
+		      const regex_t *mreg)
 {
 	struct btrfs_path *path;
 	struct extent_buffer *leaf;
@@ -558,6 +561,9 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
 		/* full path from root of btrfs being restored */
 		snprintf(fs_name, 4096, "%s/%s", dir, filename);
 
+		if (REG_NOMATCH == regexec(mreg, fs_name, 0, NULL, 0))
+			goto next;
+
 		/* full path from system root */
 		snprintf(path_name, 4096, "%s%s", output_rootdir, fs_name);
 
@@ -669,7 +675,7 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
 			}
 			loops = 0;
 			ret = search_dir(search_root, &location,
-					 output_rootdir, dir);
+					 output_rootdir, dir, mreg);
 			free(dir);
 			if (ret) {
 				if (ignore_errors)
@@ -690,8 +696,8 @@ next:
 
 static void usage()
 {
-	fprintf(stderr, "Usage: restore [-svio] [-t disk offset] <device> "
-		"<directory>\n");
+	fprintf(stderr, "Usage: restore [-svioc] [-t disk offset] "
+		"[-m regex] <device> <directory>\n");
 }
 
 static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_mirror)
@@ -784,8 +790,12 @@ int main(int argc, char **argv)
 	int opt;
 	int super_mirror = 0;
 	int find_dir = 0;
+	const char *match_regstr = NULL;
+	int match_cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
+	regex_t match_reg, *mreg = NULL;
+	char reg_err[256];
 
-	while ((opt = getopt(argc, argv, "sviot:u:df:r:")) != -1) {
+	while ((opt = getopt(argc, argv, "sviot:u:df:r:cm:")) != -1) {
 		switch (opt) {
 			case 's':
 				get_snaps = 1;
@@ -836,6 +846,12 @@ int main(int argc, char **argv)
 					exit(1);
 				}
 				break;
+			case 'c':
+				match_cflags |= REG_ICASE;
+				break;
+			case 'm':
+				match_regstr = optarg;
+				break;
 			default:
 				usage();
 				exit(1);
@@ -906,9 +922,21 @@ int main(int argc, char **argv)
 		key.objectid = BTRFS_FIRST_FREE_OBJECTID;
 	}
 
-	ret = search_dir(root, &key, dir_name, "");
+	if (match_regstr) {
+		ret = regcomp(&match_reg, match_regstr, match_cflags);
+		if (ret) {
+			regerror(ret, &match_reg, reg_err, sizeof(reg_err));
+			fprintf(stderr, "Regex compile failed: %s\n", reg_err);
+			goto out;
+		}
+		mreg = &match_reg;
+	}
+
+	ret = search_dir(root, &key, dir_name, "", mreg);
 
 out:
+	if (mreg)
+		regfree(mreg);
 	close_ctree(root);
 	return ret;
 }
-- 
1.7.6.233.gd79bc

openSUSE Build Service is sponsored by