44static bool filesEqual(
const char *fn1,
const char *fn2)
51 if (s1.st_size!=s2.st_size)
55 FILE *f1=fopen(fn1,
"rb");
58 FILE *f2=fopen(fn2,
"rb");
62 static char buf1[16384],buf2[16384];
63 for (
unsigned k=0;k<s1.st_size;)
65 unsigned cur=s1.st_size-k;
68 if (fread(buf1,cur,1,f1)!=1||
69 fread(buf2,cur,1,f2)!=1)
71 if (memcmp(buf1,buf2,cur))
80static int recursiveCull(FILE *batchFile,
81 const char *dir1,
const char *dir2,
87 work=dir1; work+=relDir; work+=
"*.*";
89 long h=_findfirst(work.c_str(),&fd);
94 work=dir2; work+=relDir; work+=
"*.*";
95 h=_findfirst(work.c_str(),&fd);
101 std::vector<std::string> subdir,dupfiles;
105 if (fd.attrib&_A_SUBDIR)
107 if (strcmp(fd.name,
".")&&
108 strcmp(fd.name,
".."))
109 subdir.push_back(fd.name);
113 std::string work1,work2;
114 work1=dir1; work1+=relDir; work1+=fd.name;
115 work2=dir2; work2+=relDir; work2+=fd.name;
116 if (filesEqual(work1.c_str(),work2.c_str()))
117 dupfiles.push_back(fd.name);
119 if (_findnext(h,&fd))
127 for (std::vector<std::string>::iterator i=dupfiles.begin();i!=dupfiles.end();++i)
130 work=dir1; work+=relDir; work+=*i;
131 _chmod(work.c_str(),_S_IREAD|_S_IWRITE);
132 if (_unlink(work.c_str()))
133 fprintf(stderr,
"Error: Can't delete %s\n",work.c_str());
136 fprintf(batchFile,
"attrib -r \"%s\"\n",work.c_str());
137 fprintf(batchFile,
"del -r \"%s\"\n",work.c_str());
141 for (i=subdir.begin();i!=subdir.end();++i)
147 deleted+=recursiveCull(batchFile,dir1,dir2,work.c_str());
154int main(
int argc,
char *argv[])
158 printf(
"Usage: assetcull <dir1> <dir2> <bat-file>\n\n"
160 " All files in <dir1> and <dir2> (and subdirectories) are compared\n"
161 " binary. If an identical file exists it is removed from <dir1>\n"
162 " and a corresponding DEL line is written to the given batch file.\n"
167 FILE *f=fopen(argv[3],
"wt");
170 printf(
"Error: Can't create %s\n",argv[3]);
174 int n=recursiveCull(f,argv[1],argv[2],
"\\.\\");
176 printf(
"assetcull: %i files culled.\n",n);