1 #include "../include/filelist.h"
2 #include "../include/filelib.h"
3 #include "../include/logger.h"
7 static int stringptr_endswithchar(stringptr
* s
, int ch
) {
8 if(stringptr_getsize(s
) == 0) return 0;
9 return stringptr_get(s
)[stringptr_getsize(s
)-1] == ch
;
12 static int compare_files(stringptr
* fn1
, stringptr
* fn2
) {
13 FILE *f1
= fopen(stringptr_get(fn1
), "r");
14 FILE *f2
= fopen(stringptr_get(fn2
), "r");
18 unsigned char buf1
[16*1024];
19 unsigned char buf2
[16*1024];
20 n
= fread(buf1
, 1, sizeof buf1
, f1
);
21 if(n
== 0) { ret
= 0; break; }
22 if(n
!= fread(buf2
, 1, sizeof buf2
, f2
)) break;
23 if(memcmp(buf1
, buf2
, n
)) break;
30 static int mode
= 0; /* 0: identical, 1: not identical */
32 static int process_path(stringptr
* dir1
, stringptr
* dir2
) {
35 ret
= filelist_search(&fl1
, dir1
, SPL("*"), FLF_EXCLUDE_PATH
|FLF_INCLUDE_HIDDEN
);
37 ret
= filelist_search(&fl2
, dir2
, SPL("*"), FLF_EXCLUDE_PATH
|FLF_INCLUDE_HIDDEN
);
40 for(i
=0; i
< stringptrlist_getsize(fl1
.files
); ++i
) {
41 stringptr
*f1
= stringptrlist_get(fl1
.files
, i
);
42 if(!stringptrlist_contains(fl2
.files
, f1
)) continue;
43 stringptr
* full1
= stringptr_concat(dir1
, stringptr_endswithchar(dir1
, '/') ? SPL("") : SPL("/"), f1
, NULL
);
44 stringptr
* full2
= stringptr_concat(dir2
, stringptr_endswithchar(dir1
, '/') ? SPL("") : SPL("/"), f1
, NULL
);
45 if(stringptr_endswithchar(f1
, '/')) {
46 ret
= process_path(full1
, full2
);
50 if(getfilesize(stringptr_get(full1
)) != getfilesize(stringptr_get(full2
)))
53 if(compare_files(full1
, full2
) == mode
) {
59 stringptr_free(full1
);
60 stringptr_free(full2
);
68 "usage: PROG MODE DIR1 DIR2\n"
69 "MODE: i - identical or n - not identical\n"
70 "finds all (not) identical files in DIR1/2 and its subdirs.\n"
71 "prints filenames of DIR1 that match MODE.\n"
72 "files that exist only in DIR1 or DIR2 are excluded.\n"
77 int main(int argc
, char** argv
) {
78 if(argc
!= 4) return usage();
79 mode
= argv
[1][0] == 'i' ? 0 : 1;
80 SPDECLAREC(dir1
, argv
[2]);
81 SPDECLAREC(dir2
, argv
[3]);
82 int ret
= process_path(dir1
, dir2
);