summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Schmidt <swdev@jan-o-sch.net>2012-10-24 10:43:35 +0200
committerJan Schmidt <swdev@jan-o-sch.net>2012-10-24 10:43:35 +0200
commit5283cb810965c8b2fca021fc8374215bfb653534 (patch)
tree2c299c3a06b65ccd381c74f4c4611f513dbecee2
parentfe8612be99b8012aa66bf320d37feb475d8d019b (diff)
downloadfar-progs-5283cb810965c8b2fca021fc8374215bfb653534.tar.gz
fssum: added option -e
The default behaviour is to exit on open errors. With -e instead, the errno of a failed open is added to the checksum. Signed-off-by: Jan Schmidt <swdev@jan-o-sch.net>
-rw-r--r--fssum.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/fssum.c b/fssum.c
index 864c592..6190021 100644
--- a/fssum.c
+++ b/fssum.c
@@ -61,13 +61,14 @@ enum _flags {
FLAG_MTIME,
FLAG_CTIME,
FLAG_DATA,
+ FLAG_OPEN_ERROR,
NUM_FLAGS
};
-const char flchar[] = "ugoamcd";
+const char flchar[] = "ugoamcde";
char line[65536];
-int flags[NUM_FLAGS] = { 1, 1, 1, 1, 1, 0, 1 };
+int flags[NUM_FLAGS] = { 1, 1, 1, 1, 1, 0, 1, 0 };
char *
getln(char *buf, int size, FILE *fp)
@@ -130,11 +131,12 @@ usage(void)
fprintf(stderr, " a : include atime\n");
fprintf(stderr, " c : include ctime\n");
fprintf(stderr, " d : include file data\n");
- fprintf(stderr, " -[UGOAMCD] : exclude respective field from calculation\n");
+ fprintf(stderr, " e : include open errors (aborts otherwise)\n");
+ fprintf(stderr, " -[UGOAMCDE] : exclude respective field from calculation\n");
fprintf(stderr, " -n : reset all flags\n");
fprintf(stderr, " -N : set all flags\n");
fprintf(stderr, " -h : this help\n\n");
- fprintf(stderr, "The default field mask is ugoamCd. If the checksum/manifest is read from a\n");
+ fprintf(stderr, "The default field mask is ugoamCdE. If the checksum/manifest is read from a\n");
fprintf(stderr, "file, the mask is taken from there and the values given on the command line\n");
fprintf(stderr, "are ignored.\n");
exit(-1);
@@ -432,32 +434,41 @@ sum(int dirfd, int level, sum_t *dircs, char *path_in)
sum_add_time(&meta, st.st_ctime);
if (S_ISDIR(st.st_mode)) {
fd = openat(dirfd, namelist[i], 0);
- if (fd == -1) {
+ if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
+ sum_add_u64(&meta, errno);
+ } else if (fd == -1) {
fprintf(stderr, "open failed for %s: %s\n",
path, strerror(errno));
exit(-1);
+ } else {
+ sum(fd, level + 1, &cs, path);
+ close(fd);
}
- sum(fd, level + 1, &cs, path);
- close(fd);
} else if (S_ISREG(st.st_mode)) {
sum_add_u64(&meta, st.st_size);
if (flags[FLAG_DATA]) {
fd = openat(dirfd, namelist[i], 0);
- if (fd == -1) {
+ if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
+ sum_add_u64(&meta, errno);
+ } else if (fd == -1) {
fprintf(stderr,
"open failed for %s: %s\n",
path, strerror(errno));
exit(-1);
}
- while((ret = read(fd, buf, sizeof(buf))) > 0)
- sum_add(&cs, buf, ret);
- if (ret < 0) {
- fprintf(stderr,
- "read failed for %s: %s\n",
- path, strerror(errno));
- exit(-1);
+ if (fd != -1) {
+ while ((ret =
+ read(fd, buf, sizeof(buf))) > 0)
+ sum_add(&cs, buf, ret);
+ if (ret < 0) {
+ fprintf(stderr,
+ "read failed for "
+ "%s: %s\n", path,
+ strerror(errno));
+ exit(-1);
+ }
+ close(fd);
}
- close(fd);
}
} else if (S_ISLNK(st.st_mode)) {
ret = readlink(namelist[i], buf, sizeof(buf));
@@ -510,7 +521,7 @@ main(int argc, char *argv[])
int i;
out_fp = stdout;
- while ((c = getopt(argc, argv, "hfuUgGoOaAmMcCdDnNw:r:")) != EOF) {
+ while ((c = getopt(argc, argv, "heEfuUgGoOaAmMcCdDnNw:r:")) != EOF) {
switch(c) {
case 'f':
gen_manifest = 1;
@@ -529,6 +540,8 @@ main(int argc, char *argv[])
case 'C':
case 'd':
case 'D':
+ case 'e':
+ case 'E':
parse_flag(c);
break;
case 'n':