From 0bb70d21ffc963b9aaacea2cd464803d6ac5f106 Mon Sep 17 00:00:00 2001 From: Anders Blomdell <anders.blomdell@control.lth.se> Date: Thu, 1 Jun 2017 18:15:42 +0200 Subject: [PATCH] Make nul terminated lines an option --- md5toc.c | 59 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/md5toc.c b/md5toc.c index 3de756b..1eaf676 100644 --- a/md5toc.c +++ b/md5toc.c @@ -31,16 +31,17 @@ #include <inttypes.h> #include <time.h> #include <sys/types.h> -#include <attr/xattr.h> +#include <sys/xattr.h> #include <fcntl.h> /* Definition of AT_* constants */ #define XATTR_MD5SUM "trusted.md5sum.control.lth.se" -#define FLAGS_READ_XATTR 0x01 -#define FLAGS_WRITE_XATTR 0x02 -#define FLAGS_CLEAR_XATTR 0x04 -#define FLAGS_MAX_AGE 0x08 -#define FLAGS_VERBOSE 0x10 +#define FLAGS_READ_XATTR 0x01 +#define FLAGS_WRITE_XATTR 0x02 +#define FLAGS_CLEAR_XATTR 0x04 +#define FLAGS_MAX_AGE 0x08 +#define FLAGS_VERBOSE 0x10 +#define FLAGS_NUL_TERMINATED 0x20 struct options { int flags; @@ -60,7 +61,8 @@ void usage() " -w, --write-xattr write MD5 extended attribute\n" " -c, --clear-xattr remove MD5 extended attribute\n" " -m, --max-age SECONDS max age of MD5 extended attribute\n" - " -v, --verbose be verbose\n"); + " -v, --verbose be verbose\n" + " --print0 nul terminated lines\n"); exit(1); } @@ -115,17 +117,20 @@ void trim(char *s) { void printentry(long long size, int mtime, int uid, int gid, int mode, - char *md5, char kind, char *name) + char *md5, char kind, char *name, + struct options *options) { trim(name); if (name[0]) { /* Don't print empty filenames */ if (kind != 'D') { - printf("%Ld:%d:%d:%d:%o:%s:%c:%s\n", - size, mtime, uid, gid, mode & ~S_IFMT, md5, kind, name); + printf("%Ld:%d:%d:%d:%o:%s:%c:%s%c", + size, mtime, uid, gid, mode & ~S_IFMT, md5, kind, name, + (options->flags & FLAGS_NUL_TERMINATED) ? '\0' : '\n'); } else { - printf("::%d:%d:%o:%s:%c:%s\n", - uid, gid, mode & ~S_IFMT, md5, kind, name); + printf("::%d:%d:%o:%s:%c:%s%c", + uid, gid, mode & ~S_IFMT, md5, kind, name, + (options->flags & FLAGS_NUL_TERMINATED) ? '\0' : '\n'); } } } @@ -214,7 +219,7 @@ void md5sum_file(char *filename, const struct stat64 buf, if (options->flags & FLAGS_CLEAR_XATTR) { if (removexattr(filename, XATTR_MD5SUM) != 0) { - if (errno != ENOATTR) { + if (errno != ENODATA) { fprintf(stderr, "Failed to remove xattr '%s'\n", filename); } } else if (options->flags & FLAGS_VERBOSE) { @@ -240,7 +245,7 @@ void md5sum_file(char *filename, const struct stat64 buf, recalc = 0; } else { if (removexattr(filename, XATTR_MD5SUM) != 0) { - if (errno != ENOATTR) { + if (errno != ENODATA) { fprintf(stderr, "Failed to remove xattr '%s' (mtime)\n", filename); } } else if (options->flags & FLAGS_VERBOSE) { @@ -258,7 +263,7 @@ void md5sum_file(char *filename, const struct stat64 buf, if (options->flags & (FLAGS_READ_XATTR|FLAGS_WRITE_XATTR)) { /* Only remove md5sum for unreadble file if we are root */ if (removexattr(filename, XATTR_MD5SUM) != 0) { - if (errno != ENOATTR) { + if (errno != ENODATA) { fprintf(stderr, "Failed to remove xattr '%s' (unreadable)\n", filename); } @@ -294,7 +299,7 @@ void md5sum_file(char *filename, const struct stat64 buf, } printentry(buf.st_size, buf.st_mtime, buf.st_uid, buf.st_gid, buf.st_mode, - md5, 'F', filename); + md5, 'F', filename, options); out: ; } @@ -316,13 +321,14 @@ void dofile(char *filename, dev_t *dev, struct options *options) fprintf(stderr, "Failed to lstat '%s'\n", filename); } else if (*dev != buf.st_dev) { fprintf(stderr, "skipping mountpoint '%s'\n", filename); - } else if (filenameislegal(filename)) { + } else if (options->flags & FLAGS_NUL_TERMINATED || + filenameislegal(filename)) { if (S_ISREG(buf.st_mode)) { md5sum_file(filename, buf, options); } else if (S_ISDIR(buf.st_mode)) { if (! (options->flags & FLAGS_CLEAR_XATTR)) { printentry(0, 0, buf.st_uid, buf.st_gid, buf.st_mode, - "", 'D', filename); + "", 'D', filename, options); } if (filename[0] == 0) { filename = "."; } dodir(filename, dev, options); @@ -344,7 +350,7 @@ void dofile(char *filename, dev_t *dev, struct options *options) } printentry(buf.st_size, buf.st_mtime, buf.st_uid, buf.st_gid, buf.st_mode, - md5, 'L', filename); + md5, 'L', filename, options); } free(link); } else { @@ -359,7 +365,7 @@ void dofile(char *filename, dev_t *dev, struct options *options) } printentry(buf.st_size, buf.st_mtime, buf.st_uid, buf.st_gid, buf.st_mode, - "", kind, filename); + "", kind, filename, options); } } out: @@ -382,6 +388,7 @@ int main(int argc, char *argv[]) {"clear-xattr", no_argument, NULL, 'c' }, {"max-age", required_argument, NULL, 'm' }, {"verbose", no_argument, NULL, 'v' }, + {"print0", no_argument, NULL, 'z' }, {0, 0, NULL, 0 } }; @@ -415,6 +422,9 @@ int main(int argc, char *argv[]) case 'v': { options.flags |= FLAGS_VERBOSE; } break; + case 'z': { + options.flags |= FLAGS_NUL_TERMINATED; + } break; } } if (options.flags & (FLAGS_READ_XATTR | FLAGS_WRITE_XATTR | @@ -426,11 +436,14 @@ int main(int argc, char *argv[]) } } - printf("#fields: size:mtime:uid:gid:mode:md5:kind:name\n"); + printf("#fields: size:mtime:uid:gid:mode:md5:kind:name%c", + (options.flags & FLAGS_NUL_TERMINATED) ? '\0' : '\n'); for (i = optind ; i < argc ; i++) { - printf("#path: %s\n", argv[i]); + printf("#path: %s%c", argv[i], + (options.flags & FLAGS_NUL_TERMINATED) ? '\0' : '\n'); dofile(argv[i], 0, &options); } - printf("#endTOC\n"); + printf("#endTOC%c", + (options.flags & FLAGS_NUL_TERMINATED) ? '\0' : '\n'); return 0; } -- GitLab