add netbsd nl(1)
[rofl0r-hardcore-utils.git] / bdiff.c
blobc198a04e88d42e3d02c0df14a65e50d086737adb
1 #include <inttypes.h>
2 #include <stddef.h>
3 #include <string.h>
4 #include <assert.h>
5 #include <unistd.h>
6 #include <sys/stat.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <fcntl.h>
10 #ifdef USE_LIBULZ
11 #include <ulz/stdio-repl.h>
12 #endif
14 static int fetch(FILE *f, off_t *cnt) {
15 int c = fgetc(f);
16 if(c >= 0) *cnt = *cnt + 1;
17 return c;
20 static int diff(FILE *f1, FILE* f2) {
21 off_t min;
22 size_t diffs = 0;
23 struct stat st1, st2;
24 if(fstat(fileno(f1), &st1)) return 1;
25 if(fstat(fileno(f2), &st2)) return 1;
26 min = st1.st_size;
27 off_t p1, p2, l, diffbytes = 0;
28 if (st2.st_size != min) {
29 printf("sizes differ! %llu, %llu\n",
30 (long long) st1.st_size, (long long) st2.st_size);
31 if (st2.st_size < min) min = st2.st_size;
33 p1 = 0;
34 p2 = 0;
35 while(p1 < min) {
36 l = 0;
37 while(p1 < min && fetch(f1, &p1) != fetch(f2, &p2)) l++;
38 if(l) {
39 printf("difference at offset %llu of size %llu\n",
40 (long long) p1-l-1, (long long) l);
41 diffs++;
42 diffbytes += l;
45 printf("%zu differences in %llu out of %llu bytes detected.\n",
46 diffs, (long long) diffbytes, (long long) min);
47 return diffs != 0;
51 static void syntax(void) {
52 printf("syntax: filename1 filename2\nlist differences in binaries\n");
53 exit(1);
56 static int canread(char* fn) {
57 return access(fn, R_OK) != -1;
60 int main(int argc, char** argv) {
61 if(argc < 3) syntax();
62 if(!canread(argv[1]) || !canread(argv[2])) {
63 perror("can not read");
64 return 1;
66 return diff(fopen(argv[1], "r"), fopen(argv[2], "r"));