#include "nel/misc/types_nl.h" #include "nel/misc/app_context.h" #include "nel/misc/path.h" #include "nel/misc/common.h" #include "nel/misc/sstring.h" #include "nel/misc/algo.h" using namespace std; using namespace NLMISC; enum TAction { pack, unpack, undefined }; const string DefaultExt("xml_pack"); const uint32 MaxLineSize = 16*1024; const string ExcludeFiles(".#*;*.log;*.bin"); const string ExcludeDirs("CVS"); bool isExcludedFile(const std::string &fileName) { static vector excludeFileVect; static bool init = false; if (!init) { explode(ExcludeFiles, ";", excludeFileVect, true); init = true; } bool excluded = false; for (uint i=0; i excludeDirVect; static bool init = false; if (!init) { explode(ExcludeDirs, ";", excludeDirVect, true); } bool excluded = false; for (uint i=0; i 0 && (path[pos] == '\\' || path[pos] == '/')) --pos; while(pos > 0 && path[pos] != '\\' && path[pos] != '/' ) dirName = path[pos--] + dirName; return dirName; } int main(int argc, char *argv[]) { printf("XML Packer/Unpacker V0.1\n(C) Nevrax 2006\n"); CApplicationContext appContext; TAction action = undefined; bool recursive = false; // compute the current folder name string currentPath = CPath::getCurrentPath(); string dirName = getLastDirName(currentPath);; string filename = dirName + "."+DefaultExt; // check the params to choose action for (uint i=0; i]\n", argv[0]); printf(" -p : pack the current folder\n"); printf(" -u : unpack the current folder\n"); printf(" -r : pack or unpack subdirectories recursively\n"); // printf(" -f : use the specified filename instead of current directory name\n"); return -1; } vector dirStack; printf("Current patch is '%s'\n", CPath::getCurrentPath().c_str()); // push the current directory to start the loop dirStack.push_back(CPath::getCurrentPath()); while(!dirStack.empty()) { string dirName = dirStack.back(); dirStack.pop_back(); string filename = dirName+"/"+getLastDirName(dirName) + "."+DefaultExt; switch (action) { case pack: { printf("Packing directory '%s'...\n", dirName.c_str()); // string packFileName = dirName+"/tmp."+DefaultExt; string packFileName = filename; // get the current directory content vector files; CPath::getPathContent(dirName, false, false, true, files); vector validFiles; // first loop to build the list of valid file for (uint i=0; i= packDate) // no more to check break; } // all files are older than the pack file ! no repack needed needRepack = false; } if (needRepack) { // open the pack file // FILE *fp = nlfopen(filename, "wt"); FILE *fp = nlfopen(packFileName, "wt"); fprintf(fp, "\n"); for (uint i=0; i\n", CFile::getFilename(subFileName).c_str()); FILE *subFp = nlfopen(subFileName, "rt"); nlassert(subFp != NULL); char buffer[MaxLineSize]; char *result; bool needFinalReturn = false; result = fgets(buffer, MaxLineSize, subFp); needFinalReturn = result != NULL ? buffer[strlen(buffer)-1] != '\n' : true; while(result != 0) { fputs(buffer, fp); result = fgets(buffer, MaxLineSize, subFp); needFinalReturn = result != NULL ? buffer[strlen(buffer)-1] != '\n' : needFinalReturn; } if (needFinalReturn) { char *finalReturn = "\n"; fputs(finalReturn, fp); } fclose(subFp); fprintf(fp, " \n"); } fprintf(fp, "\n"); fclose(fp); } else { printf("Directory %s is up to date, no repack\n", dirName.c_str()); } } break; case unpack: { printf("Unpacking directory '%s'...\n", dirName.c_str()); // open the pack file // FILE *fp = nlfopen(dirName+"/tmp."+DefaultExt, "rt"); FILE *fp = nlfopen(filename, "rt"); nlassert(fp != NULL); uint linecount = 0; // read the first line char buffer[MaxLineSize]; fgets(buffer, MaxLineSize, fp); linecount++; if (strcmp(buffer, "\n") != 0) { printf ("Error : invalid pack file '%s'\n", filename.c_str()); exit(-1); } char *result = NULL; do { // read a file line fgets(buffer, MaxLineSize, fp); CSString parser(buffer); linecount++; if (parser.find(" ") == 0) { // end of pack file fclose(fp); break; } printf ("Error : invalid pack file '%s' at line %u", filename.c_str(), linecount); exit(-1); } CSString subFileName = parser.leftCrop(sizeof(" \n") != 0) { fputs(result, output); // read next line result = fgets(buffer, MaxLineSize, fp); linecount++; } fclose(output); } while(result != NULL); } // break; } if (recursive) { vector subDirs; CPath::getPathContent(dirName, false, true, false, subDirs); // filter the directories for (uint i=subDirs.size(); i>0; --i) { if (!isExcludedDir(subDirs[i-1])) dirStack.push_back(subDirs[i-1]); } } } return 0; }