|
78 | 78 | #include "restore.h" |
79 | 79 | #include "process_fragments.h" |
80 | 80 | #include "fnmatch_compat.h" |
| 81 | +#include "fakerootdb.h" |
81 | 82 |
|
82 | 83 | int delete = FALSE; |
83 | 84 | int quiet = FALSE; |
@@ -269,6 +270,10 @@ int keep_as_directory = FALSE; |
269 | 270 | /* Should Mksquashfs detect hardlinked files? */ |
270 | 271 | int no_hardlinks = FALSE; |
271 | 272 |
|
| 273 | +/* Override owner/group/permissions/file type from fakeroot(1) database */ |
| 274 | +struct fakerootdb fakerootdb; |
| 275 | +char const *fakerootdb_filename = NULL; |
| 276 | + |
272 | 277 | static char *read_from_disk(long long start, unsigned int avail_bytes); |
273 | 278 | static void add_old_root_entry(char *name, squashfs_inode inode, int inode_number, |
274 | 279 | int type); |
@@ -298,6 +303,18 @@ static void write_filesystem_tables(struct squashfs_super_block *sBlk, int nopad |
298 | 303 | unsigned short get_checksum_mem(char *buff, int bytes); |
299 | 304 | static void check_usable_phys_mem(int total_mem); |
300 | 305 |
|
| 306 | +static int lstat_with_fakeroot(const char *path, struct stat *stbuf) |
| 307 | +{ |
| 308 | + int err; |
| 309 | + err = lstat(path, stbuf); |
| 310 | + if (err < 0) |
| 311 | + goto out; |
| 312 | + if (!fakerootdb.db || fakerootdb.count == 0) |
| 313 | + goto out; |
| 314 | + fakeroot_override_stat(stbuf, &fakerootdb); |
| 315 | +out: |
| 316 | + return err; |
| 317 | +} |
301 | 318 |
|
302 | 319 | void prep_exit() |
303 | 320 | { |
@@ -3029,7 +3046,7 @@ static squashfs_inode scan_single(char *pathname, int progress) |
3029 | 3046 | * it to the root directory dir_info structure */ |
3030 | 3047 | dir_ent = create_dir_entry("", NULL, pathname, scan1_opendir("", "", 0)); |
3031 | 3048 |
|
3032 | | - if(lstat(pathname, &buf) == -1) |
| 3049 | + if(lstat_with_fakeroot(pathname, &buf) == -1) |
3033 | 3050 | /* source directory has disappeared? */ |
3034 | 3051 | BAD_ERROR("Cannot stat source directory %s because %s\n", |
3035 | 3052 | pathname, strerror(errno)); |
@@ -3071,6 +3088,7 @@ static squashfs_inode scan_encomp(int progress) |
3071 | 3088 | buf.st_mtime = time(NULL); |
3072 | 3089 | buf.st_dev = 0; |
3073 | 3090 | buf.st_ino = 0; |
| 3091 | + fakeroot_override_stat(&buf, &fakerootdb); |
3074 | 3092 | dir_ent->inode = lookup_inode2(&buf, PSEUDO_FILE_OTHER, 0); |
3075 | 3093 | dir_ent->dir = root_dir; |
3076 | 3094 | root_dir->dir_ent = dir_ent; |
@@ -3267,7 +3285,7 @@ static struct dir_info *dir_scan1(char *filename, char *subpath, |
3267 | 3285 | continue; |
3268 | 3286 | } |
3269 | 3287 |
|
3270 | | - if(lstat(filename, &buf) == -1) { |
| 3288 | + if(lstat_with_fakeroot(filename, &buf) == -1) { |
3271 | 3289 | ERROR_START("Cannot stat dir/file %s because %s", |
3272 | 3290 | filename, strerror(errno)); |
3273 | 3291 | ERROR_EXIT(", ignoring\n"); |
@@ -4012,7 +4030,7 @@ static struct dir_info *add_source(struct dir_info *sdir, char *source, |
4012 | 4030 | goto failed_early; |
4013 | 4031 | } |
4014 | 4032 |
|
4015 | | - res = lstat(file, &buf); |
| 4033 | + res = lstat_with_fakeroot(file, &buf); |
4016 | 4034 | if (res == -1) { |
4017 | 4035 | ERROR("Error: Can't stat %s because %s", file, strerror(errno)); |
4018 | 4036 | goto failed_early; |
@@ -4263,12 +4281,13 @@ static squashfs_inode process_source(int progress) |
4263 | 4281 | buf.st_uid = getuid(); |
4264 | 4282 | buf.st_gid = getgid(); |
4265 | 4283 | buf.st_mtime = time(NULL); |
| 4284 | + fakeroot_override_stat(&buf, &fakerootdb); |
4266 | 4285 | entry = create_dir_entry("", NULL, "", new); |
4267 | 4286 | entry->inode = lookup_inode2(&buf, PSEUDO_FILE_OTHER, 0); |
4268 | 4287 | } else { |
4269 | 4288 | char *pathname = absolute ? "/" : "."; |
4270 | 4289 |
|
4271 | | - if(lstat(pathname, &buf) == -1) |
| 4290 | + if(lstat_with_fakeroot(pathname, &buf) == -1) |
4272 | 4291 | BAD_ERROR("Cannot stat %s because %s\n", |
4273 | 4292 | pathname, strerror(errno)); |
4274 | 4293 |
|
@@ -6016,6 +6035,12 @@ int main(int argc, char *argv[]) |
6016 | 6035 | exit(1); |
6017 | 6036 | } |
6018 | 6037 | } |
| 6038 | + } else if(strcmp(argv[i], "-fakerootdb") == 0) { |
| 6039 | + if(++i == argc) { |
| 6040 | + ERROR("%s: -fakerootdb: missing filename\n", argv[0]); |
| 6041 | + exit(1); |
| 6042 | + } |
| 6043 | + fakerootdb_filename = argv[i]; |
6019 | 6044 | } else if(strcmp(argv[i], "-noI") == 0 || |
6020 | 6045 | strcmp(argv[i], "-noInodeCompression") == 0) |
6021 | 6046 | noI = TRUE; |
@@ -6213,6 +6238,24 @@ int main(int argc, char *argv[]) |
6213 | 6238 | strcmp(argv[i], "-log") == 0) |
6214 | 6239 | i++; |
6215 | 6240 |
|
| 6241 | + if (fakerootdb_filename) { |
| 6242 | + int err; |
| 6243 | + FILE *fakedata = NULL; |
| 6244 | + fakedata = fopen(fakerootdb_filename, "r"); |
| 6245 | + if (!fakedata) { |
| 6246 | + ERROR("%s: -fakerootdb: failed to open fakeroot database %s\n", |
| 6247 | + argv[0], fakerootdb_filename); |
| 6248 | + EXIT_MKSQUASHFS(); |
| 6249 | + } |
| 6250 | + err = fakeroot_read_db(fakedata, &fakerootdb); |
| 6251 | + fclose(fakedata); |
| 6252 | + if (err) { |
| 6253 | + ERROR("%s: -fakerootdb: failed to read fakeroot database %s\n", |
| 6254 | + argv[0], fakerootdb_filename); |
| 6255 | + EXIT_MKSQUASHFS(); |
| 6256 | + } |
| 6257 | + } |
| 6258 | + |
6216 | 6259 | if(!delete) { |
6217 | 6260 | comp = read_super(fd, &sBlk, argv[source + 1]); |
6218 | 6261 | if(comp == NULL) { |
|
0 commit comments