@@ -16,7 +16,6 @@
* Boston, MA 021110-1307, USA.
*/
-
#include "kerncompat.h"
#include <ctype.h>
@@ -33,6 +32,7 @@
#include <getopt.h>
#include <sys/types.h>
#include <sys/xattr.h>
+#include <sys/mman.h>
#include "ctree.h"
#include "disk-io.h"
@@ -932,7 +932,9 @@ out:
static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
const char *output_rootdir, const char *in_dir,
- const regex_t *mreg)
+ const regex_t *mreg,
+ const char *mfile,
+ const int msize)
{
struct btrfs_path *path;
struct extent_buffer *leaf;
@@ -1040,6 +1042,9 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
if (mreg && REG_NOMATCH == regexec(mreg, fs_name, 0, NULL, 0))
goto next;
+ if (mfile && NULL == memmem(mfile, msize, fs_name, strlen(fs_name)))
+ goto next;
+
/* full path from system root */
snprintf(path_name, PATH_MAX, "%s%s", output_rootdir, fs_name);
@@ -1142,7 +1147,7 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
}
loops = 0;
ret = search_dir(search_root, &location,
- output_rootdir, dir, mreg);
+ output_rootdir, dir, mreg, mfile, msize);
free(dir);
if (ret) {
fprintf(stderr, "Error searching %s\n",
@@ -1402,6 +1407,9 @@ const char * const cmd_restore_usage[] = {
" you have to use following syntax (possibly quoted):",
" ^/(|home(|/username(|/Desktop(|/.*))))$",
"-c ignore case (--path-regex only)",
+ "--path-from-file <file>",
+ " restore only filenames from file,",
+ " one file per line, case sensitive",
NULL
};
@@ -1422,11 +1430,17 @@ int cmd_restore(int argc, char **argv)
int match_cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
regex_t match_reg, *mreg = NULL;
char reg_err[256];
+ char *mfile = NULL;
+ int msize = 0;
+ const char *match_filename = NULL;
+ struct stat match_filestat;
+ int match_fd = 0;
while (1) {
int opt;
static const struct option long_options[] = {
{ "path-regex", required_argument, NULL, 256},
+ { "path-from-file", required_argument, NULL, 255},
{ "dry-run", no_argument, NULL, 'D'},
{ "metadata", no_argument, NULL, 'm'},
{ "symlinks", no_argument, NULL, 'S'},
@@ -1503,6 +1517,9 @@ int cmd_restore(int argc, char **argv)
case 256:
match_regstr = optarg;
break;
+ case 255:
+ match_filename = optarg;
+ break;
case 'x':
get_xattrs = 1;
break;
@@ -1599,14 +1616,37 @@ int cmd_restore(int argc, char **argv)
mreg = &match_reg;
}
+ if (match_filename) {
+ if ((match_fd = open(match_filename, O_RDONLY)) == -1) {
+ fprintf(stderr, "Failed to open file: %s\n", match_filename);
+ goto out;
+ }
+ if ((fstat (match_fd, &match_filestat)) == -1) {
+ fprintf(stderr, "Failed to stat file: %s\n", match_filename);
+ goto out;
+ }
+ msize = match_filestat.st_size;
+ if ((mfile = mmap(0, match_filestat.st_size, PROT_READ, MAP_PRIVATE, match_fd, 0)) == (char*) -1) {
+ fprintf(stderr, "Failed to map file: %s\n", match_filename);
+ mfile = NULL;
+ goto out;
+ }
+ if (close(match_fd) == -1) {
+ fprintf(stderr, "Failed to close file: %s\n", match_filename);
+ goto out;
+ }
+ }
+
if (dry_run)
printf("This is a dry-run, no files are going to be restored\n");
- ret = search_dir(root, &key, dir_name, "", mreg);
+ ret = search_dir(root, &key, dir_name, "", mreg, mfile, msize);
out:
if (mreg)
regfree(mreg);
+ if (mfile)
+ munmap(mfile, match_filestat.st_size);
close_ctree(root);
return !!ret;
}