220 lines
6.2 KiB
C++
220 lines
6.2 KiB
C++
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#include <nel/misc/path.h>
|
|
#include <nel/misc/debug.h>
|
|
#include <nel/misc/file.h>
|
|
|
|
#include <nel/misc/sha1.h>
|
|
|
|
using namespace std;
|
|
using namespace NLMISC;
|
|
|
|
|
|
//-----------------------------------------------
|
|
// main
|
|
//
|
|
//-----------------------------------------------
|
|
int main( int argc, char ** argv )
|
|
{
|
|
if( argc < 3 || argc > 4 )
|
|
{
|
|
printf("Build a listing of the diff of two path contents and copy new files in <dest_path>\n");
|
|
printf("usage: path_content <ref_path> <new_path> [<dest_path>]\n");
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
string DestPath;
|
|
if( argc == 4 )
|
|
{
|
|
DestPath = CPath::standardizeDosPath(argv[3]);
|
|
if(CFile::isExists(DestPath))
|
|
{
|
|
if(!CFile::isDirectory(DestPath))
|
|
{
|
|
printf("'%s' is not a directory\n", DestPath.c_str());
|
|
return EXIT_FAILURE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!CFile::createDirectory(DestPath))
|
|
{
|
|
printf("Can't create directory: '%s'\n", DestPath.c_str());
|
|
return EXIT_FAILURE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// content of new path
|
|
string newPath(argv[2]);
|
|
vector<string> newPathContent;
|
|
CPath::getPathContent(newPath, true, false, true, newPathContent);
|
|
|
|
string outputFileName = CFile::findNewFile("path_content_diff.txt");
|
|
FILE *output = fopen (outputFileName.c_str(), "wt");
|
|
if( output == NULL )
|
|
{
|
|
nlwarning("Can't open output file %s",outputFileName.c_str());
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// add ref path in search paths
|
|
string refPath(argv[1]);
|
|
CPath::addSearchPath(refPath, true, false);
|
|
|
|
map<string,CHashKey> refSHAMap;
|
|
CIFile refSHAFile;
|
|
if( refSHAFile.open(refPath +".sha1key") )
|
|
{
|
|
// load the map of SHA hash key for the ref files
|
|
refSHAFile.serialCont( refSHAMap );
|
|
refSHAFile.close();
|
|
}
|
|
else
|
|
{
|
|
// build the map of SHA hash key for the ref files
|
|
string extension;
|
|
vector<string> refPathContent;
|
|
CPath::getFileList(extension, refPathContent);
|
|
vector<string>::const_iterator itFile;
|
|
for( itFile = refPathContent.begin(); itFile != refPathContent.end(); ++itFile )
|
|
{
|
|
refSHAMap.insert( make_pair(*itFile,getSHA1(*itFile)) );
|
|
}
|
|
COFile refSHAFile(refPath + ".sha1key");
|
|
refSHAFile.serialCont( refSHAMap );
|
|
}
|
|
|
|
|
|
// build the map of SHA hash key for new files
|
|
map<string,CHashKey> newSHAMap;
|
|
vector<string>::const_iterator itFile;
|
|
for( itFile = newPathContent.begin(); itFile != newPathContent.end(); ++itFile )
|
|
{
|
|
newSHAMap.insert( make_pair(*itFile,getSHA1(*itFile)) );
|
|
}
|
|
|
|
// display (debug)
|
|
map<string,CHashKey>::iterator itSHA;
|
|
/*
|
|
for( itSHA = refSHAMap.begin(); itSHA != refSHAMap.end(); ++itSHA )
|
|
{
|
|
nlinfo("(ref) %s : %s",(*itSHA).first.c_str(),(*itSHA).second.toString().c_str());
|
|
}
|
|
for( itSHA = newSHAMap.begin(); itSHA != newSHAMap.end(); ++itSHA )
|
|
{
|
|
nlinfo("(new) %s : %s",(*itSHA).first.c_str(),(*itSHA).second.toString().c_str());
|
|
}
|
|
*/
|
|
//
|
|
|
|
uint32 LastDisplay = 0, curFile = 0;
|
|
|
|
// get the list of new or modified files
|
|
vector<string> differentFiles;
|
|
for( itFile = newPathContent.begin(); itFile != newPathContent.end(); ++itFile )
|
|
{
|
|
string newFileName = *itFile;
|
|
string newFileNameShort = CFile::getFilename(newFileName);
|
|
|
|
curFile++;
|
|
|
|
if (CTime::getSecondsSince1970() > LastDisplay + 5)
|
|
{
|
|
printf("%d on %d files, %d left\n", curFile, newPathContent.size(), newPathContent.size() - curFile);
|
|
LastDisplay = CTime::getSecondsSince1970();
|
|
}
|
|
|
|
if( CFile::getExtension(newFileNameShort) == "bnp" )
|
|
{
|
|
nlwarning ("BNP PROBLEM: %s is a big file, content of big files is not managed", newFileName.c_str());
|
|
nlwarning ("The <new_path> must *not* contains .bnp files");
|
|
}
|
|
|
|
bool keepIt = false;
|
|
|
|
string refFileName = CPath::lookup(strlwr(newFileNameShort), false, false, false);
|
|
if( refFileName.empty() )
|
|
{
|
|
keepIt = true;
|
|
nlinfo ("new file : %s",newFileNameShort.c_str());
|
|
}
|
|
else
|
|
{
|
|
itSHA = refSHAMap.find( newFileNameShort );
|
|
CHashKey refSHA;
|
|
if( itSHA != refSHAMap.end() )
|
|
{
|
|
refSHA = (*itSHA).second;
|
|
}
|
|
|
|
itSHA = newSHAMap.find( newFileName );
|
|
CHashKey newSHA;
|
|
if( itSHA != newSHAMap.end() )
|
|
{
|
|
newSHA = (*itSHA).second;
|
|
}
|
|
|
|
if( !(refSHA==newSHA) )
|
|
{
|
|
keepIt = true;
|
|
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));
|
|
}
|
|
|
|
/*
|
|
uint32 refModificationDate = CFile::getFileModificationDate( refFileName );
|
|
uint32 newModificationDate = CFile::getFileModificationDate( newFileName );
|
|
|
|
if( newModificationDate > refModificationDate )
|
|
{
|
|
keepIt = true;
|
|
nlinfo ("DATE CHANGED: %s", newFileName.c_str());
|
|
}
|
|
else
|
|
{
|
|
// same date, must be same size
|
|
uint32 refSize = CFile::getFileSize( refFileName );
|
|
uint32 newSize = CFile::getFileSize( newFileName );
|
|
if( refSize != newSize )
|
|
{
|
|
nlwarning ("DATE PROBLEM: file '%s' have the same date but not the same size than '%s'", newFileName.c_str(), refFileName.c_str());
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
if( keepIt )
|
|
{
|
|
differentFiles.push_back( newFileName );
|
|
|
|
//uint32 newCreationDate = CFile::getFileCreationDate( newFileName );
|
|
//string outputLine = newFileName + "\t\t"+toString(newSize) + "\t" + toString(newModificationDate) + "\t" + toString(newCreationDate) + "\n";
|
|
string outputLine = newFileName + "\n";
|
|
fprintf (output, outputLine.c_str());
|
|
|
|
if( !DestPath.empty() )
|
|
{
|
|
string systemStr = "copy /Y " + CPath::standardizeDosPath(newFileName) + " " + DestPath;
|
|
//nlinfo("System call '%s'",systemStr.c_str());
|
|
system( systemStr.c_str() );
|
|
}
|
|
}
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|