diff options
author | Jan Schmidt <swdev@jan-o-sch.net> | 2012-10-24 10:43:35 +0200 |
---|---|---|
committer | Jan Schmidt <swdev@jan-o-sch.net> | 2012-10-24 10:43:35 +0200 |
commit | 5283cb810965c8b2fca021fc8374215bfb653534 (patch) | |
tree | 2c299c3a06b65ccd381c74f4c4611f513dbecee2 | |
parent | fe8612be99b8012aa66bf320d37feb475d8d019b (diff) | |
download | far-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.c | 47 |
1 files changed, 30 insertions, 17 deletions
@@ -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': |