@@ -502,6 +502,162 @@ malformed:
excess_file(fn);
}
+void
+sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in);
+
+void
+sum_one(int dirfd, int level, sum_t *dircs, char *path_prefix,
+ char *path_in, char *name) {
+ sum_t cs;
+ sum_t meta;
+ int fd;
+ int ret;
+ int excl;
+ char* path;
+ struct stat64 st;
+ sum_file_data_t sum_file_data = flags[FLAG_STRUCTURE] ?
+ sum_file_data_strict : sum_file_data_permissive;
+
+ sum_init(&cs);
+ sum_init(&meta);
+ path = alloc(strlen(path_in) + strlen(name) + 3);
+ sprintf(path, "%s/%s", path_in, name);
+ for (excl = 0; excl < n_excludes; ++excl) {
+ if (strncmp(excludes[excl].path, path,
+ excludes[excl].len) == 0)
+ goto out;
+ }
+
+ ret = fchdir(dirfd);
+ if (ret == -1) {
+ perror("fchdir");
+ exit(-1);
+ }
+ ret = lstat64(name, &st);
+ if (ret) {
+ fprintf(stderr, "stat failed for %s/%s: %s\n",
+ path_prefix, path, strerror(errno));
+ exit(-1);
+ }
+
+ sum_add_u64(&meta, level);
+ sum_add(&meta, name, strlen(name));
+ if (!S_ISDIR(st.st_mode))
+ sum_add_u64(&meta, st.st_nlink);
+ if (flags[FLAG_UID])
+ sum_add_u64(&meta, st.st_uid);
+ if (flags[FLAG_GID])
+ sum_add_u64(&meta, st.st_gid);
+ if (flags[FLAG_MODE])
+ sum_add_u64(&meta, st.st_mode);
+ if (flags[FLAG_ATIME])
+ sum_add_time(&meta, st.st_atime);
+ if (flags[FLAG_MTIME])
+ sum_add_time(&meta, st.st_mtime);
+ if (flags[FLAG_CTIME])
+ sum_add_time(&meta, st.st_ctime);
+ if (flags[FLAG_XATTRS] &&
+ (S_ISDIR(st.st_mode) || S_ISREG(st.st_mode))) {
+ fd = openat(dirfd, name, 0);
+ if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
+ sum_add_u64(&meta, errno);
+ } else if (fd == -1) {
+ fprintf(stderr, "open failed for %s/%s: %s\n",
+ path_prefix, path, strerror(errno));
+ exit(-1);
+ } else {
+ ret = sum_xattrs(fd, &meta);
+ close(fd);
+ if (ret < 0) {
+ fprintf(stderr,
+ "failed to read xattrs from "
+ "%s/%s: %s\n",
+ path_prefix, path,
+ strerror(-ret));
+ exit(-1);
+ }
+ }
+ }
+ if (S_ISDIR(st.st_mode)) {
+ fd = openat(dirfd, name, 0);
+ if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
+ sum_add_u64(&meta, errno);
+ } else if (fd == -1) {
+ fprintf(stderr, "open failed for %s/%s: %s\n",
+ path_prefix, path, strerror(errno));
+ exit(-1);
+ } else {
+ sum(fd, level + 1, &cs, path_prefix, path);
+ close(fd);
+ }
+ } else if (S_ISREG(st.st_mode)) {
+ sum_add_u64(&meta, st.st_size);
+ if (flags[FLAG_DATA]) {
+ if (verbose)
+ fprintf(stderr, "file %s\n",
+ name);
+ fd = openat(dirfd, name, 0);
+ if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
+ sum_add_u64(&meta, errno);
+ } else if (fd == -1) {
+ fprintf(stderr,
+ "open failed for %s/%s: %s\n",
+ path_prefix, path,
+ strerror(errno));
+ exit(-1);
+ }
+ if (fd != -1) {
+ ret = sum_file_data(fd, &cs);
+ if (ret < 0) {
+ fprintf(stderr,
+ "read failed for "
+ "%s/%s: %s\n",
+ path_prefix, path,
+ strerror(errno));
+ exit(-1);
+ }
+ close(fd);
+ }
+ }
+ } else if (S_ISLNK(st.st_mode)) {
+ ret = readlink(name, buf, sizeof(buf));
+ if (ret == -1) {
+ perror("readlink");
+ exit(-1);
+ }
+ sum_add(&cs, buf, ret);
+ } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
+ sum_add_u64(&cs, major(st.st_rdev));
+ sum_add_u64(&cs, minor(st.st_rdev));
+ }
+ sum_fini(&cs);
+ sum_fini(&meta);
+ if (gen_manifest || in_manifest) {
+ char *fn;
+ char *m;
+ char *c;
+
+ if (S_ISDIR(st.st_mode))
+ strcat(path, "/");
+ fn = escape(path);
+ m = sum_to_string(&meta);
+ c = sum_to_string(&cs);
+
+ if (gen_manifest)
+ fprintf(out_fp, "%s %s %s\n", fn, m, c);
+ if (in_manifest)
+ check_manifest(fn, m, c, 0);
+ free(c);
+ free(m);
+ free(fn);
+ }
+ sum_add_sum(dircs, &cs);
+ sum_add_sum(dircs, &meta);
+
+out:
+ free(path);
+}
+
void
sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
{
@@ -512,10 +668,6 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
int entries = 0;
int i;
int ret;
- int fd;
- int excl;
- sum_file_data_t sum_file_data = flags[FLAG_STRUCTURE] ?
- sum_file_data_strict : sum_file_data_permissive;
struct stat64 dir_st;
if (fstat64(dirfd, &dir_st)) {
@@ -550,19 +702,6 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
qsort(namelist, entries, sizeof(*namelist), namecmp);
for (i = 0; i < entries; ++i) {
struct stat64 st;
- sum_t cs;
- sum_t meta;
- char *path;
-
- sum_init(&cs);
- sum_init(&meta);
- path = alloc(strlen(path_in) + strlen(namelist[i]) + 3);
- sprintf(path, "%s/%s", path_in, namelist[i]);
- for (excl = 0; excl < n_excludes; ++excl) {
- if (strncmp(excludes[excl].path, path,
- excludes[excl].len) == 0)
- goto next;
- }
ret = fchdir(dirfd);
if (ret == -1) {
@@ -571,130 +710,17 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
}
ret = lstat64(namelist[i], &st);
if (ret) {
- fprintf(stderr, "stat failed for %s/%s: %s\n",
- path_prefix, path, strerror(errno));
+ fprintf(stderr, "stat failed for %s/%s/%s: %s\n",
+ path_prefix, path_in, namelist[i],
+ strerror(errno));
exit(-1);
}
/* We are crossing into a different subvol, skip this subtree. */
if (st.st_dev != dir_st.st_dev)
- goto next;
-
- sum_add_u64(&meta, level);
- sum_add(&meta, namelist[i], strlen(namelist[i]));
- if (!S_ISDIR(st.st_mode))
- sum_add_u64(&meta, st.st_nlink);
- if (flags[FLAG_UID])
- sum_add_u64(&meta, st.st_uid);
- if (flags[FLAG_GID])
- sum_add_u64(&meta, st.st_gid);
- if (flags[FLAG_MODE])
- sum_add_u64(&meta, st.st_mode);
- if (flags[FLAG_ATIME])
- sum_add_time(&meta, st.st_atime);
- if (flags[FLAG_MTIME])
- sum_add_time(&meta, st.st_mtime);
- if (flags[FLAG_CTIME])
- sum_add_time(&meta, st.st_ctime);
- if (flags[FLAG_XATTRS] &&
- (S_ISDIR(st.st_mode) || S_ISREG(st.st_mode))) {
- fd = openat(dirfd, namelist[i], 0);
- if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
- sum_add_u64(&meta, errno);
- } else if (fd == -1) {
- fprintf(stderr, "open failed for %s/%s: %s\n",
- path_prefix, path, strerror(errno));
- exit(-1);
- } else {
- ret = sum_xattrs(fd, &meta);
- close(fd);
- if (ret < 0) {
- fprintf(stderr,
- "failed to read xattrs from "
- "%s/%s: %s\n",
- path_prefix, path,
- strerror(-ret));
- exit(-1);
- }
- }
- }
- if (S_ISDIR(st.st_mode)) {
- fd = openat(dirfd, namelist[i], 0);
- if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
- sum_add_u64(&meta, errno);
- } else if (fd == -1) {
- fprintf(stderr, "open failed for %s/%s: %s\n",
- path_prefix, path, strerror(errno));
- exit(-1);
- } else {
- sum(fd, level + 1, &cs, path_prefix, path);
- close(fd);
- }
- } else if (S_ISREG(st.st_mode)) {
- sum_add_u64(&meta, st.st_size);
- if (flags[FLAG_DATA]) {
- if (verbose)
- fprintf(stderr, "file %s\n",
- namelist[i]);
- fd = openat(dirfd, namelist[i], 0);
- if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
- sum_add_u64(&meta, errno);
- } else if (fd == -1) {
- fprintf(stderr,
- "open failed for %s/%s: %s\n",
- path_prefix, path,
- strerror(errno));
- exit(-1);
- }
- if (fd != -1) {
- ret = sum_file_data(fd, &cs);
- if (ret < 0) {
- fprintf(stderr,
- "read failed for "
- "%s/%s: %s\n",
- path_prefix, path,
- strerror(errno));
- exit(-1);
- }
- close(fd);
- }
- }
- } else if (S_ISLNK(st.st_mode)) {
- ret = readlink(namelist[i], buf, sizeof(buf));
- if (ret == -1) {
- perror("readlink");
- exit(-1);
- }
- sum_add(&cs, buf, ret);
- } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
- sum_add_u64(&cs, major(st.st_rdev));
- sum_add_u64(&cs, minor(st.st_rdev));
- }
- sum_fini(&cs);
- sum_fini(&meta);
- if (gen_manifest || in_manifest) {
- char *fn;
- char *m;
- char *c;
-
- if (S_ISDIR(st.st_mode))
- strcat(path, "/");
- fn = escape(path);
- m = sum_to_string(&meta);
- c = sum_to_string(&cs);
-
- if (gen_manifest)
- fprintf(out_fp, "%s %s %s\n", fn, m, c);
- if (in_manifest)
- check_manifest(fn, m, c, 0);
- free(c);
- free(m);
- free(fn);
- }
- sum_add_sum(dircs, &cs);
- sum_add_sum(dircs, &meta);
-next:
- free(path);
+ continue;
+
+ sum_one(dirfd, level, dircs, path_prefix, path_in, namelist[i]);
}
}