|
72 | 72 | #include "restore.h"
|
73 | 73 | #include "process_fragments.h"
|
74 | 74 | #include "fnmatch_compat.h"
|
| 75 | +#include "fakerootdb.h" |
75 | 76 |
|
76 | 77 | int delete = FALSE;
|
77 | 78 | int quiet = FALSE;
|
@@ -275,6 +276,9 @@ int no_hardlinks = FALSE;
|
275 | 276 | int one_file_system = FALSE;
|
276 | 277 | dev_t *source_dev;
|
277 | 278 | dev_t cur_dev;
|
| 279 | +/* Override owner/group/permissions/file type from fakeroot(1) database */ |
| 280 | +struct fakerootdb fakerootdb; |
| 281 | +char const *fakerootdb_filename = NULL; |
278 | 282 |
|
279 | 283 | static char *read_from_disk(long long start, unsigned int avail_bytes);
|
280 | 284 | static void add_old_root_entry(char *name, squashfs_inode inode,
|
@@ -308,6 +312,18 @@ static void check_usable_phys_mem(int total_mem);
|
308 | 312 | static void print_summary();
|
309 | 313 | void write_destination(int fd, long long byte, long long bytes, void *buff);
|
310 | 314 |
|
| 315 | +static int lstat_with_fakeroot(const char *path, struct stat *stbuf) |
| 316 | +{ |
| 317 | + int err; |
| 318 | + err = lstat(path, stbuf); |
| 319 | + if (err < 0) |
| 320 | + goto out; |
| 321 | + if (!fakerootdb.db || fakerootdb.count == 0) |
| 322 | + goto out; |
| 323 | + fakeroot_override_stat(stbuf, &fakerootdb); |
| 324 | +out: |
| 325 | + return err; |
| 326 | +} |
311 | 327 |
|
312 | 328 | void prep_exit()
|
313 | 329 | {
|
@@ -3350,7 +3366,7 @@ static squashfs_inode scan_single(char *pathname, int progress)
|
3350 | 3366 | * it to the root directory dir_info structure */
|
3351 | 3367 | dir_ent = create_dir_entry("", NULL, pathname, scan1_opendir("", "", 0));
|
3352 | 3368 |
|
3353 |
| - if(lstat(pathname, &buf) == -1) |
| 3369 | + if(lstat_with_fakeroot(pathname, &buf) == -1) |
3354 | 3370 | /* source directory has disappeared? */
|
3355 | 3371 | BAD_ERROR("Cannot stat source directory %s because %s\n",
|
3356 | 3372 | pathname, strerror(errno));
|
@@ -3392,6 +3408,7 @@ static squashfs_inode scan_encomp(int progress)
|
3392 | 3408 | buf.st_mtime = time(NULL);
|
3393 | 3409 | buf.st_dev = 0;
|
3394 | 3410 | buf.st_ino = 0;
|
| 3411 | + fakeroot_override_stat(&buf, &fakerootdb); |
3395 | 3412 | dir_ent->inode = lookup_inode(&buf);
|
3396 | 3413 | dir_ent->inode->dummy_root_dir = TRUE;
|
3397 | 3414 | dir_ent->dir = root_dir;
|
@@ -3593,7 +3610,7 @@ static struct dir_info *dir_scan1(char *filename, char *subpath,
|
3593 | 3610 | continue;
|
3594 | 3611 | }
|
3595 | 3612 |
|
3596 |
| - if(lstat(filename, &buf) == -1) { |
| 3613 | + if(lstat_with_fakeroot(filename, &buf) == -1) { |
3597 | 3614 | ERROR_START("Cannot stat dir/file %s because %s",
|
3598 | 3615 | filename, strerror(errno));
|
3599 | 3616 | ERROR_EXIT(", ignoring\n");
|
@@ -4361,7 +4378,7 @@ static struct dir_info *add_source(struct dir_info *sdir, char *source,
|
4361 | 4378 | goto failed_early;
|
4362 | 4379 | }
|
4363 | 4380 |
|
4364 |
| - res = lstat(file, &buf); |
| 4381 | + res = lstat_with_fakeroot(file, &buf); |
4365 | 4382 | if (res == -1) {
|
4366 | 4383 | ERROR("Error: Can't stat %s because %s\n", file, strerror(errno));
|
4367 | 4384 | goto failed_early;
|
@@ -4708,13 +4725,14 @@ static squashfs_inode process_source(int progress)
|
4708 | 4725 | buf.st_uid = getuid();
|
4709 | 4726 | buf.st_gid = getgid();
|
4710 | 4727 | buf.st_mtime = time(NULL);
|
| 4728 | + fakeroot_override_stat(&buf, &fakerootdb); |
4711 | 4729 | entry = create_dir_entry("", NULL, "", new);
|
4712 | 4730 | entry->inode = lookup_inode(&buf);
|
4713 | 4731 | entry->inode->dummy_root_dir = TRUE;
|
4714 | 4732 | } else {
|
4715 | 4733 | char *pathname = absolute ? "/" : ".";
|
4716 | 4734 |
|
4717 |
| - if(lstat(pathname, &buf) == -1) |
| 4735 | + if(lstat_with_fakeroot(pathname, &buf) == -1) |
4718 | 4736 | BAD_ERROR("Cannot stat %s because %s\n",
|
4719 | 4737 | pathname, strerror(errno));
|
4720 | 4738 |
|
@@ -6576,6 +6594,12 @@ int main(int argc, char *argv[])
|
6576 | 6594 | exit(1);
|
6577 | 6595 | }
|
6578 | 6596 | }
|
| 6597 | + } else if(strcmp(argv[i], "-fakerootdb") == 0) { |
| 6598 | + if(++i == argc) { |
| 6599 | + ERROR("%s: -fakerootdb: missing filename\n", argv[0]); |
| 6600 | + exit(1); |
| 6601 | + } |
| 6602 | + fakerootdb_filename = argv[i]; |
6579 | 6603 | } else if(strcmp(argv[i], "-noI") == 0 ||
|
6580 | 6604 | strcmp(argv[i], "-noInodeCompression") == 0)
|
6581 | 6605 | noI = TRUE;
|
@@ -6807,6 +6831,24 @@ int main(int argc, char *argv[])
|
6807 | 6831 | strcmp(argv[i], "-log") == 0)
|
6808 | 6832 | i++;
|
6809 | 6833 |
|
| 6834 | + if (fakerootdb_filename) { |
| 6835 | + int err; |
| 6836 | + FILE *fakedata = NULL; |
| 6837 | + fakedata = fopen(fakerootdb_filename, "r"); |
| 6838 | + if (!fakedata) { |
| 6839 | + ERROR("%s: -fakerootdb: failed to open fakeroot database %s\n", |
| 6840 | + argv[0], fakerootdb_filename); |
| 6841 | + EXIT_MKSQUASHFS(); |
| 6842 | + } |
| 6843 | + err = fakeroot_read_db(fakedata, &fakerootdb); |
| 6844 | + fclose(fakedata); |
| 6845 | + if (err) { |
| 6846 | + ERROR("%s: -fakerootdb: failed to read fakeroot database %s\n", |
| 6847 | + argv[0], fakerootdb_filename); |
| 6848 | + EXIT_MKSQUASHFS(); |
| 6849 | + } |
| 6850 | + } |
| 6851 | + |
6810 | 6852 | if(!delete) {
|
6811 | 6853 | comp = read_super(fd, &sBlk, destination_file);
|
6812 | 6854 | if(comp == NULL) {
|
|
0 commit comments