From b5803897df7792d3137e8050ef3c3fb96288d24a Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Mon, 21 Aug 2017 17:57:54 +0200 Subject: initial commit of holes --- holes.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 holes.c (limited to 'holes.c') diff --git a/holes.c b/holes.c new file mode 100644 index 0000000..865ea50 --- /dev/null +++ b/holes.c @@ -0,0 +1,89 @@ +/* holes - find holes (= runs of zero bytes) in input files */ + +#include +#include +#include +#include +#include + +ssize_t minlen = 64; +int ret; +char *argv0; + +void +holes(FILE *input, char *filename) +{ + off_t offset = 0; + off_t run = 0; + int ch; + + while ((ch = getc_unlocked(input)) != EOF) { + if (ch == 0) { + run++; + } else { + if (run >= minlen) { + if (filename) + printf("%s: ", filename); + printf("%08lx %ld\n", offset - run, run); + } + run = 0; + } + offset++; + } + if (ferror(input)) { + fprintf(stderr, "%s: can't read '%s': %s\n", + argv0, filename ? filename : "-", strerror(errno)); + ret = 1; + return; + } + + if (offset == 0 || // empty file + run >= minlen) { + if (filename) + printf("%s: ", filename); + printf("%08lx %ld\n", offset - run, run); + } +} + +int +main(int argc, char *argv[]) +{ + int c, i; + + argv0 = argv[0]; + + while ((c = getopt(argc, argv, "n:")) != -1) + switch(c) { + case 'n': + minlen = atoll(optarg); + break; + default: + fprintf(stderr, + "Usage: %s [-n MINLEN] [FILES...]\n", argv0); + exit(2); + } + + if (minlen < 1) { + fprintf(stderr, "%s: MINLEN must not be smaller than 1.\n", + argv0); + exit(2); + } + + if (optind == argc) + holes(stdin, 0); + else + for (i = optind; i < argc; i++) { + FILE *input = (strcmp(argv[i], "-") == 0) ? + stdin : fopen(argv[i], "rb"); + + if (!input) { + fprintf(stderr, "%s: can't open file '%s': %s\n", + argv0, argv[i], strerror(errno)); + ret = 1; + } else { + holes(input, argc - optind > 1 ? argv[i] : 0); + } + } + + return ret; +} -- cgit 1.4.1