/* files_d iffer.c - determine if two files are identical * Andrew Ho (andrew@zeuscat.com) * * Implements files_differ() which quickly returns false if two files * differ, and true if they are identical. Memory use is capped to * a little over 2*BUFSIZE. * * Build: gcc -Wall -o files_differ files_differ.c * Usage: files_differ file1 file2 */ #include #include #include #ifndef BUFSIZE #define BUFSIZE 1024 #endif /* returns true if file1 and file2 are exactly the same */ int files_differ(const char *file1, const char *file2) { FILE *fh1, *fh2; size_t b1, b2; unsigned char buf1[BUFSIZE+1], buf2[BUFSIZE+1]; fh1 = fopen(file1, "r"); if(!fh1) return 1; fh2 = fopen(file2, "r"); if(!fh2) return 1; memset(buf1, '\0', BUFSIZE+1); memset(buf2, '\0', BUFSIZE+1); while((b1 = fread(buf1, sizeof(char), BUFSIZE, fh1))) { b2 = fread(buf2, sizeof(char), BUFSIZE, fh2); if(feof(fh1) && feof(fh2)) break; else if(feof(fh1) || feof(fh2)) return 1; if(b1 != b2) return 1; if(b1 == 0) break; if(strncmp(buf1, buf2, b1)) return 1; memset(buf1, '\0', BUFSIZE+1); memset(buf2, '\0', BUFSIZE+1); } if(!feof(fh1)) { perror("error reading from file"); return 1; } fclose(fh2); fclose(fh1); return 0; } int main(int argc, char **argv) { if(argc != 3) { fprintf(stderr, "usage: files_differ file1 file2\n"); return 1; } if(files_differ(argv[1], argv[2])) puts("files differ"); else puts("files match"); return 0; }