Fix
[ryzomcore.git] / tool / path_content_diff / path_content_diff.cpp
blobb40a4e75ff842687e41944bf0275a48a42ce16cb
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include <nel/misc/common.h>
18 #include <nel/misc/path.h>
19 #include <nel/misc/debug.h>
20 #include <nel/misc/file.h>
22 #include <nel/misc/sha1.h>
24 using namespace std;
25 using namespace NLMISC;
28 //-----------------------------------------------
29 // main
31 //-----------------------------------------------
32 int main( int argc, char ** argv )
34 if( argc < 3 || argc > 4 )
36 printf("Build a listing of the diff of two path contents and copy new files in <dest_path>\n");
37 printf("usage: path_content <ref_path> <new_path> [<dest_path>]\n");
38 return EXIT_FAILURE;
41 string DestPath;
42 if( argc == 4 )
44 DestPath = CPath::standardizeDosPath(argv[3]);
45 if(CFile::isExists(DestPath))
47 if(!CFile::isDirectory(DestPath))
49 printf("'%s' is not a directory\n", DestPath.c_str());
50 return EXIT_FAILURE;
53 else
55 if (!CFile::createDirectory(DestPath))
57 printf("Can't create directory: '%s'\n", DestPath.c_str());
58 return EXIT_FAILURE;
63 // content of new path
64 string newPath(argv[2]);
65 vector<string> newPathContent;
66 CPath::getPathContent(newPath, true, false, true, newPathContent);
68 string outputFileName = CFile::findNewFile("path_content_diff.txt");
69 FILE *output = nlfopen(outputFileName, "wt");
70 if( output == NULL )
72 nlwarning("Can't open output file %s",outputFileName.c_str());
73 return EXIT_FAILURE;
76 // add ref path in search paths
77 string refPath(argv[1]);
78 CPath::addSearchPath(refPath, true, false);
80 map<string,CHashKey> refSHAMap;
81 CIFile refSHAFile;
82 if( refSHAFile.open(refPath +".sha1key") )
84 // load the map of SHA hash key for the ref files
85 refSHAFile.serialCont( refSHAMap );
86 refSHAFile.close();
88 else
90 // build the map of SHA hash key for the ref files
91 string extension;
92 vector<string> refPathContent;
93 CPath::getFileList(extension, refPathContent);
94 vector<string>::const_iterator itFile;
95 for( itFile = refPathContent.begin(); itFile != refPathContent.end(); ++itFile )
97 refSHAMap.insert( make_pair(*itFile,getSHA1(*itFile)) );
99 COFile refSHAFile(refPath + ".sha1key");
100 refSHAFile.serialCont( refSHAMap );
104 // build the map of SHA hash key for new files
105 map<string,CHashKey> newSHAMap;
106 vector<string>::const_iterator itFile;
107 for( itFile = newPathContent.begin(); itFile != newPathContent.end(); ++itFile )
109 newSHAMap.insert( make_pair(*itFile,getSHA1(*itFile)) );
112 // display (debug)
113 map<string,CHashKey>::iterator itSHA;
115 for( itSHA = refSHAMap.begin(); itSHA != refSHAMap.end(); ++itSHA )
117 nlinfo("(ref) %s : %s",(*itSHA).first.c_str(),(*itSHA).second.toString().c_str());
119 for( itSHA = newSHAMap.begin(); itSHA != newSHAMap.end(); ++itSHA )
121 nlinfo("(new) %s : %s",(*itSHA).first.c_str(),(*itSHA).second.toString().c_str());
126 uint32 LastDisplay = 0, curFile = 0;
128 // get the list of new or modified files
129 vector<string> differentFiles;
130 for( itFile = newPathContent.begin(); itFile != newPathContent.end(); ++itFile )
132 string newFileName = *itFile;
133 string newFileNameShort = CFile::getFilename(newFileName);
135 curFile++;
137 if (CTime::getSecondsSince1970() > LastDisplay + 5)
139 printf("%d on %d files, %d left\n", curFile, newPathContent.size(), newPathContent.size() - curFile);
140 LastDisplay = CTime::getSecondsSince1970();
143 if( CFile::getExtension(newFileNameShort) == "bnp" )
145 nlwarning ("BNP PROBLEM: %s is a big file, content of big files is not managed", newFileName.c_str());
146 nlwarning ("The <new_path> must *not* contains .bnp files");
149 bool keepIt = false;
151 string refFileName = CPath::lookup(strlwr(newFileNameShort), false, false, false);
152 if( refFileName.empty() )
154 keepIt = true;
155 nlinfo ("new file : %s",newFileNameShort.c_str());
157 else
159 itSHA = refSHAMap.find( newFileNameShort );
160 CHashKey refSHA;
161 if( itSHA != refSHAMap.end() )
163 refSHA = (*itSHA).second;
166 itSHA = newSHAMap.find( newFileName );
167 CHashKey newSHA;
168 if( itSHA != newSHAMap.end() )
170 newSHA = (*itSHA).second;
173 if( !(refSHA==newSHA) )
175 keepIt = true;
176 nlinfo("file : %s , key : %s(%s), size : %d(%d)",newFileNameShort.c_str(), newSHA.toString().c_str(),refSHA.toString().c_str(),CFile::getFileSize(newFileName),CFile::getFileSize(refFileName));
180 uint32 refModificationDate = CFile::getFileModificationDate( refFileName );
181 uint32 newModificationDate = CFile::getFileModificationDate( newFileName );
183 if( newModificationDate > refModificationDate )
185 keepIt = true;
186 nlinfo ("DATE CHANGED: %s", newFileName.c_str());
188 else
190 // same date, must be same size
191 uint32 refSize = CFile::getFileSize( refFileName );
192 uint32 newSize = CFile::getFileSize( newFileName );
193 if( refSize != newSize )
195 nlwarning ("DATE PROBLEM: file '%s' have the same date but not the same size than '%s'", newFileName.c_str(), refFileName.c_str());
201 if( keepIt )
203 differentFiles.push_back( newFileName );
205 //uint32 newCreationDate = CFile::getFileCreationDate( newFileName );
206 //string outputLine = newFileName + "\t\t"+toString(newSize) + "\t" + toString(newModificationDate) + "\t" + toString(newCreationDate) + "\n";
207 string outputLine = newFileName + "\n";
208 fprintf (output, outputLine.c_str());
210 if( !DestPath.empty() )
212 string systemStr = "copy /Y " + CPath::standardizeDosPath(newFileName) + " " + DestPath;
213 //nlinfo("System call '%s'",systemStr.c_str());
214 system( systemStr.c_str() );
219 return EXIT_SUCCESS;