unbin.c (1911B)
1#include <stdlib.h> 2#include <stdio.h> 3#include <string.h> 4#include <stdarg.h> 5 6#define ISFLAG(str, fshort, flong) (!strcmp(str, fshort) || !strcmp(str, flong)) 7 8const char *usage = "USAGE: unbin [-r] [-s SKIP] [-n COUNT] [FILE]\n"; 9 10void 11die(const char *fmtstr, ...) 12{ 13 va_list ap; 14 15 va_start(ap, fmtstr); 16 vfprintf(stderr, fmtstr, ap); 17 va_end(ap); 18 19 exit(EXIT_FAILURE); 20} 21 22int 23main(int argc, const char **argv) 24{ 25 unsigned char byte, bit; 26 size_t skip, cnt, pos; 27 const char *filepath; 28 int i, revbyte, cntset; 29 char *end; 30 FILE *f; 31 32 filepath = NULL; 33 cnt = skip = 0; 34 revbyte = cntset = 0; 35 36 for (i = 1; i < argc; i++) { 37 if (ISFLAG(argv[i], "-s", "--skip")) { 38 if (i++ == argc - 1) goto missing_arg; 39 skip = strtoul(argv[i], &end, 0); 40 if (end && *end) goto bad_arg; 41 } else if (ISFLAG(argv[i], "-n", "--count")) { 42 if (i++ == argc - 1) goto missing_arg; 43 cnt = strtoul(argv[i], &end, 0); 44 cntset = 1; 45 if (end && *end) goto bad_arg; 46 } else if (ISFLAG(argv[i], "-r", "--revb")) { 47 revbyte = 1; 48 } else if (ISFLAG(argv[i], "-h", "--help")) { 49 die(usage); 50 } else if (*argv[i] == '-') { 51 die("Unknown flag: %s\n", argv[i]); 52 } else if (filepath) { 53 die("Too many files specified\n"); 54 } else { 55 filepath = argv[i]; 56 } 57 } 58 59 if (!filepath) 60 f = stdin; 61 else if (!(f = fopen(filepath, "r"))) 62 die("Failed to open file\n"); 63 64 pos = 0; 65 while (!cntset || pos < cnt + skip) { 66 if (pos % 8 == 0) byte = 0; 67 bit = fgetc(f); 68 if (feof(f)) break; 69 if (bit != '1' && bit != '0') 70 continue; 71 bit = (bit == '1'); 72 if (pos >= 0) { 73 if (revbyte) 74 byte |= bit << (pos % 8); 75 else 76 byte |= bit << (7 - pos % 8); 77 if (pos % 8 == 7) 78 putchar(byte); 79 } 80 pos += 1; 81 } 82 if (pos % 8 != 0) 83 putchar(byte); 84 85 fclose(f); 86 87 return EXIT_SUCCESS; 88 89missing_arg: 90 die("Flag %s expects an argument\n", argv[i]); 91 92bad_arg: 93 die("Argument has unexpected value: %s\n", argv[i]); 94}