From e0aa90e0f3321dab0f66ab7c96a77dea7e69ebda Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 23 Jan 2016 12:27:41 +0100 Subject: [PATCH 1/4] Changed: Use CBigFile to unpack BNP in CPatchManager --- code/ryzom/client/src/login_patch.cpp | 150 +++----------------------- code/ryzom/client/src/login_patch.h | 9 +- 2 files changed, 15 insertions(+), 144 deletions(-) diff --git a/code/ryzom/client/src/login_patch.cpp b/code/ryzom/client/src/login_patch.cpp index 0529f6b41..c942071d0 100644 --- a/code/ryzom/client/src/login_patch.cpp +++ b/code/ryzom/client/src/login_patch.cpp @@ -1745,92 +1745,6 @@ void CPatchManager::getPatchFromDesc(SFileToPatch &ftpOut, const CBNPFile &fIn, } // end of else local BNP file exists } -// **************************************************************************** -bool CPatchManager::readBNPHeader(const string &SourceName, vector &Files) -{ - /* ***** - If the BNP Header format change, please modify 'EmptyBnpFileSize' as needed - ***** */ - FILE *f = fopen (SourceName.c_str(), "rb"); - if (f == NULL) return false; - - nlfseek64 (f, 0, SEEK_END); - uint32 nFileSize = NLMISC::CFile::getFileSize (SourceName); - nlfseek64 (f, nFileSize-sizeof(uint32), SEEK_SET); - - uint32 nOffsetFromBeginning; - if (fread (&nOffsetFromBeginning, sizeof(uint32), 1, f) != 1) - { - fclose(f); - return false; - } - -#ifdef NL_BIG_ENDIAN - NLMISC_BSWAP32(nOffsetFromBeginning); -#endif - - if (nlfseek64 (f, nOffsetFromBeginning, SEEK_SET) != 0) - { - fclose(f); - return false; - } - - uint32 nNbFile; - if (fread (&nNbFile, sizeof(uint32), 1, f) != 1) - { - fclose(f); - return false; - } - -#ifdef NL_BIG_ENDIAN - NLMISC_BSWAP32(nNbFile); -#endif - - for (uint32 i = 0; i < nNbFile; ++i) - { - uint8 nStringSize; - if (fread (&nStringSize, 1, 1, f) != 1) - { - fclose(f); - return false; - } - - char sName[256]; - if (fread (sName, 1, nStringSize, f) != nStringSize) - { - fclose(f); - return false; - } - sName[nStringSize] = 0; - - SBNPFile tmpBNPFile; - tmpBNPFile.Name = sName; - if (fread (&tmpBNPFile.Size, sizeof(uint32), 1, f) != 1) - { - fclose(f); - return false; - } - -#ifdef NL_BIG_ENDIAN - NLMISC_BSWAP32(tmpBNPFile.Size); -#endif - - if (fread (&tmpBNPFile.Pos, sizeof(uint32), 1, f) != 1) - { - fclose(f); - return false; - } - -#ifdef NL_BIG_ENDIAN - NLMISC_BSWAP32(tmpBNPFile.Pos); -#endif - - Files.push_back (tmpBNPFile); - } - fclose (f); - return true; -} - // **************************************************************************** bool CPatchManager::bnpUnpack(const string &srcBigfile, const string &dstPath, vector &vFilenames) { @@ -1856,8 +1770,10 @@ bool CPatchManager::bnpUnpack(const string &srcBigfile, const string &dstPath, v setState(true,s); // Read Header of the BNP File - vector Files; - if (!readBNPHeader(SourceName, Files)) + CBigFile::BNP bnpFile; + bnpFile.BigFileName = SourceName; + + if (!bnpFile.readHeader()) { ucstring s = CI18N::get("uiUnpackErrHead") + " " + SourceName; setState(true,s); @@ -1865,54 +1781,14 @@ bool CPatchManager::bnpUnpack(const string &srcBigfile, const string &dstPath, v } // Unpack - { - FILE *bnp = fopen (SourceName.c_str(), "rb"); - FILE *out; - if (bnp == NULL) - return false; - - for (uint32 i = 0; i < Files.size(); ++i) - { - CPatchManager::SBNPFile &rBNPFile = Files[i]; - string filename = DestPath + rBNPFile.Name; - out = fopen (filename.c_str(), "wb"); - if (out != NULL) - { - nlfseek64 (bnp, rBNPFile.Pos, SEEK_SET); - uint8 *ptr = new uint8[rBNPFile.Size]; - - if (fread (ptr, rBNPFile.Size, 1, bnp) != 1) - { - fclose(out); - return false; - } - - bool writeError = fwrite (ptr, rBNPFile.Size, 1, out) != 1; - if (writeError) - { - nlwarning("errno = %d", errno); - } - bool diskFull = ferror(out) && errno == 28 /* ENOSPC*/; - fclose (out); - delete [] ptr; - if (diskFull) - { - throw NLMISC::EDiskFullError(filename); - } - if (writeError) - { - throw NLMISC::EWriteError(filename); - } - } - } - fclose (bnp); - } + if (!bnpFile.unpack(DestPath)) + return false; // Return names { vFilenames.clear(); - for (uint32 i = 0; i < Files.size(); ++i) - vFilenames.push_back(Files[i].Name); + for (uint32 i = 0; i < bnpFile.SFiles.size(); ++i) + vFilenames.push_back(bnpFile.SFiles[i].Name); } return true; @@ -2332,16 +2208,18 @@ void CCheckThread::run () sTranslate = CI18N::get("uiCheckInBNP") + " " + rCat.getFile(j); pPM->setState(true, sTranslate); - vector vFiles; - if (pPM->readBNPHeader(sBNPFilename, vFiles)) + CBigFile::BNP bnpFile; + bnpFile.BigFileName = sBNPFilename; + + if (bnpFile.readHeader()) { // read the file inside the bnp and calculate the sha1 FILE *bnp = fopen (sBNPFilename.c_str(), "rb"); if (bnp != NULL) { - for (uint32 k = 0; k < vFiles.size(); ++k) + for (uint32 k = 0; k < bnpFile.SFiles.size(); ++k) { - CPatchManager::SBNPFile &rBNPFile = vFiles[k]; + const CBigFile::SBNPFile &rBNPFile = bnpFile.SFiles[k]; // Is the real file exists ? string sRealFilename = rCat.getUnpackTo() + rBNPFile.Name; if (NLMISC::CFile::fileExists(sRealFilename)) diff --git a/code/ryzom/client/src/login_patch.h b/code/ryzom/client/src/login_patch.h index 509a74f9a..9fdf907e8 100644 --- a/code/ryzom/client/src/login_patch.h +++ b/code/ryzom/client/src/login_patch.h @@ -102,13 +102,6 @@ public: uint32 SZFileSize; // Size of the SZ file }; - struct SBNPFile - { - std::string Name; - uint32 Size; - uint32 Pos; - }; - struct SPatchInfo { struct SCat @@ -326,7 +319,6 @@ private: void getPatchFromDesc(SFileToPatch &ftpOut, const CBNPFile &fIn, bool forceCheckSumTest); - bool readBNPHeader(const std::string &Filename, std::vector &FilesOut); bool bnpUnpack(const std::string &srcBigfile, const std::string &dstPath, std::vector &vFilenames); // stop the threads (called when knowing the thread ended) @@ -471,6 +463,7 @@ private: // The date to apply when file is buggy: use default of year 2001, just to have a coherent date enum {DefaultResetDate= 31 * 366 * 24 * 3600}; // The file size of a an empty BNP + // If the BNP Header format change, please modify 'EmptyBnpFileSize' as needed enum {EmptyBnpFileSize= 8}; // Use an external downloader: (BitTorrent) IAsyncDownloader* _AsyncDownloader; From 61b6ea07235b8cf964b2db9261f642e97bf961b3 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 23 Jan 2016 12:28:22 +0100 Subject: [PATCH 2/4] Fixed: Return true if a required argument is found --- code/nel/src/misc/cmd_args.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/misc/cmd_args.cpp b/code/nel/src/misc/cmd_args.cpp index f44bc15b1..9140778b8 100644 --- a/code/nel/src/misc/cmd_args.cpp +++ b/code/nel/src/misc/cmd_args.cpp @@ -157,7 +157,7 @@ bool CCmdArgs::haveAdditionalArg() const // they don't have any short or long name, but need a name in help if (arg.shortName.empty() && arg.longName.empty() && !arg.helpName.empty() && arg.found) - return false; + return true; } return false; From 0ff951d94ca39cf8db45745e62d07b9f3e78a08c Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 23 Jan 2016 12:28:40 +0100 Subject: [PATCH 3/4] Changed: Replace tabs by spaces --- code/nel/tools/3d/tga_2_dds/tga2dds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/tools/3d/tga_2_dds/tga2dds.cpp b/code/nel/tools/3d/tga_2_dds/tga2dds.cpp index 17ce786bc..f962f99b8 100644 --- a/code/nel/tools/3d/tga_2_dds/tga2dds.cpp +++ b/code/nel/tools/3d/tga_2_dds/tga2dds.cpp @@ -297,7 +297,7 @@ int main(int argc, char **argv) " default : DXTC1 if 24 bits, DXTC5 if 32 bits." ); args.addArg("m", "mipmap", "", "Create MipMap"); - args.addArg("r", "reduce", "FACTOR", "Reduce the bitmap size before compressing\n\t\t\tFACTOR is 0, 1, 2, 3, 4, 5, 6, 7 or 8"); + args.addArg("r", "reduce", "FACTOR", "Reduce the bitmap size before compressing\n FACTOR is 0, 1, 2, 3, 4, 5, 6, 7 or 8"); args.addAdditionalArg("input", "PNG or TGA files to convert", false); if (!args.parse(argc, argv)) return 1; From 3446cb4038f1bc32ec6f4bf44e0282ec16133760 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 23 Jan 2016 12:30:01 +0100 Subject: [PATCH 4/4] Changed: Use CBigFile to manage BNP and CCmdArgs for command-line in bnp_make --- code/nel/tools/misc/bnp_make/main.cpp | 537 +++++--------------------- 1 file changed, 95 insertions(+), 442 deletions(-) diff --git a/code/nel/tools/misc/bnp_make/main.cpp b/code/nel/tools/misc/bnp_make/main.cpp index a3f34a6a4..edab782b0 100644 --- a/code/nel/tools/misc/bnp_make/main.cpp +++ b/code/nel/tools/misc/bnp_make/main.cpp @@ -32,6 +32,8 @@ #include "nel/misc/path.h" #include "nel/misc/algo.h" #include "nel/misc/common.h" +#include "nel/misc/big_file.h" +#include "nel/misc/cmd_args.h" using namespace std; @@ -49,7 +51,7 @@ std::vector WildCards; // --------------------------------------------------------------------------- -bool keepFile (const char *fileName) +bool keepFile (const std::string &fileName) { uint i; bool ifPresent = false; @@ -60,13 +62,13 @@ bool keepFile (const char *fileName) if (WildCards[i].Not) { // One ifnot condition met and the file is not added - if (testWildCard(file.c_str(), WildCards[i].Expression.c_str())) + if (testWildCard(file, WildCards[i].Expression)) return false; } else { ifPresent = true; - ifTrue |= testWildCard(file.c_str(), WildCards[i].Expression.c_str()); + ifTrue |= testWildCard(file, WildCards[i].Expression); } } @@ -75,199 +77,7 @@ bool keepFile (const char *fileName) // --------------------------------------------------------------------------- -struct BNPFile -{ - string Name; - uint32 Size; - uint32 Pos; -}; - -struct BNPHeader -{ - vector Files; - uint32 OffsetFromBeginning; - - // Append the header to the big file - bool append (const string &filename) - { - FILE *f = fopen (filename.c_str(), "ab"); - if (f == NULL) return false; - - uint32 nNbFile = (uint32)Files.size(); - - // value to be serialized - uint32 nNbFile2 = nNbFile; - -#ifdef NL_BIG_ENDIAN - NLMISC_BSWAP32(nNbFile2); -#endif - - if (fwrite (&nNbFile2, sizeof(uint32), 1, f) != 1) - { - fclose(f); - return false; - } - - for (uint32 i = 0; i < nNbFile; ++i) - { - uint8 nStringSize = (uint8)Files[i].Name.size(); - if (fwrite (&nStringSize, 1, 1, f) != 1) - { - fclose(f); - return false; - } - - if (fwrite (Files[i].Name.c_str(), 1, nStringSize, f) != nStringSize) - { - fclose(f); - return false; - } - - uint32 nFileSize = Files[i].Size; - -#ifdef NL_BIG_ENDIAN - NLMISC_BSWAP32(nFileSize); -#endif - - if (fwrite (&nFileSize, sizeof(uint32), 1, f) != 1) - { - fclose(f); - return false; - } - - uint32 nFilePos = Files[i].Pos; - -#ifdef NL_BIG_ENDIAN - NLMISC_BSWAP32(nFilePos); -#endif - - if (fwrite (&nFilePos, sizeof(uint32), 1, f) != 1) - { - fclose(f); - return false; - } - } - - uint32 nOffsetFromBeginning = OffsetFromBeginning; - -#ifdef NL_BIG_ENDIAN - NLMISC_BSWAP32(nOffsetFromBeginning); -#endif - - if (fwrite (&nOffsetFromBeginning, sizeof(uint32), 1, f) != 1) - { - fclose(f); - return false; - } - - fclose (f); - return true; - } - - // Read the header from a big file - bool read (const string &filename) - { - FILE *f = fopen (filename.c_str(), "rb"); - if (f == NULL) return false; - - nlfseek64 (f, 0, SEEK_END); - uint32 nFileSize=CFile::getFileSize (filename); - nlfseek64 (f, nFileSize-sizeof(uint32), SEEK_SET); - - uint32 nOffsetFromBeginning; - if (fread (&nOffsetFromBeginning, sizeof(uint32), 1, f) != 1) - { - fclose (f); - return false; - } - -#ifdef NL_BIG_ENDIAN - NLMISC_BSWAP32(nOffsetFromBeginning); -#endif - - if (nlfseek64 (f, nOffsetFromBeginning, SEEK_SET) != 0) - { - fclose (f); - return false; - } - - uint32 nNbFile; - if (fread (&nNbFile, sizeof(uint32), 1, f) != 1) - { - fclose (f); - return false; - } - -#ifdef NL_BIG_ENDIAN - NLMISC_BSWAP32(nNbFile); -#endif - - for (uint32 i = 0; i < nNbFile; ++i) - { - uint8 nStringSize; - char sName[256]; - if (fread (&nStringSize, 1, 1, f) != 1) - { - fclose (f); - return false; - } - if (fread (sName, 1, nStringSize, f) != nStringSize) - { - fclose (f); - return false; - } - sName[nStringSize] = 0; - BNPFile tmpBNPFile; - tmpBNPFile.Name = sName; - if (fread (&tmpBNPFile.Size, sizeof(uint32), 1, f) != 1) - { - fclose (f); - return false; - } - -#ifdef NL_BIG_ENDIAN - NLMISC_BSWAP32(tmpBNPFile.Size); -#endif - - if (fread (&tmpBNPFile.Pos, sizeof(uint32), 1, f) != 1) - { - fclose (f); - return false; - } - -#ifdef NL_BIG_ENDIAN - NLMISC_BSWAP32(tmpBNPFile.Pos); -#endif - - Files.push_back (tmpBNPFile); - } - - fclose (f); - return true; - } -}; - -string gDestBNPFile; -BNPHeader gBNPHeader; - -// --------------------------------------------------------------------------- -void append(const string &filename1, const string &filename2, uint32 sizeToRead) -{ - FILE *f1 = fopen(filename1.c_str(), "ab"); - FILE *f2 = fopen(filename2.c_str(), "rb"); - if (f1 == NULL) return; - if (f2 == NULL) { fclose(f1); return; } - - uint8 *ptr = new uint8[sizeToRead]; - if (fread (ptr, sizeToRead, 1, f2) != 1) - nlwarning("%s read error", filename2.c_str()); - if (fwrite (ptr, sizeToRead, 1, f1) != 1) - nlwarning("%s write error", filename1.c_str()); - delete [] ptr; - - fclose(f2); - fclose(f1); -} +NLMISC::CBigFile::BNP gBNPHeader; // --------------------------------------------------------------------------- bool i_comp(const string &s0, const string &s1) @@ -275,35 +85,24 @@ bool i_comp(const string &s0, const string &s1) return nlstricmp (CFile::getFilename(s0).c_str(), CFile::getFilename(s1).c_str()) < 0; } -void packSubRecurse () +void packSubRecurse(const std::string &srcDirectory) { vector pathContent; - string cp = CPath::getCurrentPath(); - printf ("Treating directory : %s\n", cp.c_str()); - CPath::getPathContent(cp, true, false, true, pathContent); + printf ("Treating directory: %s\n", srcDirectory.c_str()); + CPath::getPathContent(srcDirectory, true, false, true, pathContent); + + // TODO: remove duplicate files // Sort filename sort (pathContent.begin(), pathContent.end(), i_comp); - uint i; - for (i=0; i [] [] [option] ... [option]\n"); - printf (" option : \n"); - printf (" -if wildcard : add the file if it matches the wilcard (at least one 'if' conditions must be met for a file to be adding)\n"); - printf (" -ifnot wildcard : add the file if it doesn't match the wilcard (all the 'ifnot' conditions must be met for a file to be adding)\n"); - printf (" Pack the directory to a bnp file\n"); - printf (" bnp_make /u \n"); - printf (" Unpack the bnp file to a directory\n"); - printf (" bnp_make /l \n"); - printf (" List the files contained in the bnp file\n"); -} - -// --------------------------------------------------------------------------- - -uint readOptions (int nNbArg, char **ppArgs) -{ - uint i; - uint optionCount = 0; - for (i=0; i<(uint)nNbArg; i++) - { - // If ? - if ((strcmp (ppArgs[i], "-if") == 0) && ((i+1)<(uint)nNbArg)) - { - CWildCard card; - card.Expression = toLower(string(ppArgs[i+1])); - card.Not = false; - WildCards.push_back (card); - optionCount += 2; - } - // If not ? - if ((strcmp (ppArgs[i], "-ifnot") == 0) && ((i+1)<(uint)nNbArg)) - { - CWildCard card; - card.Expression = toLower(string(ppArgs[i+1])); - card.Not = true; - WildCards.push_back (card); - optionCount += 2; - } - } - return optionCount; -} - -// --------------------------------------------------------------------------- -int main (int nNbArg, char **ppArgs) +int main(int argc, char **argv) { NLMISC::CApplicationContext myApplicationContext; - if (nNbArg < 3) + NLMISC::CCmdArgs args; + + args.addArg("p", "pack", "", "Pack the directory to a BNP file"); + args.addArg("u", "unpack", "", "Unpack the BNP file to a directory"); + args.addArg("l", "list", "", "List the files contained in the BNP file"); + args.addArg("o", "output", "destination", "Output directory or file"); + args.addArg("i", "if", "wildcard", "Add the file if it matches the wilcard (at least one 'if' conditions must be met for a file to be adding)"); + args.addArg("n", "ifnot", "wildcard", "Add the file if it doesn't match the wilcard (all the 'ifnot' conditions must be met for a file to be adding)"); + args.addAdditionalArg("input", "Input directory or BNP file depending on command"); + + if (!args.parse(argc, argv)) return 1; + + if (args.haveArg("p")) { - usage(); - return -1; - } + std::vector filters; + + // If ? + filters = args.getLongArg("if"); - if ((strcmp(ppArgs[1], "/p") == 0) || (strcmp(ppArgs[1], "/P") == 0) || - (strcmp(ppArgs[1], "-p") == 0) || (strcmp(ppArgs[1], "-P") == 0)) - { - // Pack a directory - uint count = readOptions (nNbArg, ppArgs); - nNbArg -= count; - - // Read options - - string sCurDir; - - if (nNbArg >= 4) + for (uint i = 0; i < filters.size(); ++i) { - // store current path - sCurDir = CPath::getCurrentPath(); + CWildCard card; + card.Expression = toLower(filters[i]); + card.Not = false; + WildCards.push_back(card); + } - // go to the dest path - string sDestDir; - if (CPath::setCurrentPath(ppArgs[3])) + // If not ? + filters = args.getLongArg("ifnot"); + + for (uint i = 0; i < filters.size(); ++i) + { + CWildCard card; + card.Expression = toLower(filters[i]); + card.Not = true; + WildCards.push_back(card); + } + + // Pack a directory + std::string srcDirectory = args.getAdditionalArg("input").front(); + + if (!CFile::isDirectory(srcDirectory) || !CFile::isExists(srcDirectory)) + { + nlwarning("Error: %s doesn't exist or is not a directory!", srcDirectory.c_str()); + } + + // Output directory or filename + if (args.haveArg("o")) + { + gBNPHeader.BigFileName = args.getArg("o").front(); + + if (CFile::isDirectory(gBNPHeader.BigFileName)) { - sDestDir = CPath::getCurrentPath(); - - bool tmp = CPath::setCurrentPath(sCurDir.c_str()); - // restore current path, should not failed - nlassert (tmp); // removed in release - - // go to the source dir - if (CPath::setCurrentPath(ppArgs[2])) - { - sCurDir = CPath::getCurrentPath(); - - gDestBNPFile = CPath::standardizePath(sDestDir); - - if(nNbArg == 5) - { - gDestBNPFile += ppArgs[4]; - // add ext if necessary - if (string(ppArgs[4]).find(".") == string::npos) - gDestBNPFile += string(".bnp"); - } - else - { - const char *pos = strrchr (sCurDir.c_str(), '/'); - if (pos != NULL) - { - gDestBNPFile += string(pos+1); - } - // get the dest file name - gDestBNPFile += string(".bnp"); - } - } - else - { - nlwarning ("ERROR (bnp_make) : can't set current directory to %s", ppArgs[2]); - return -1; - } - } - else - { - nlwarning ("ERROR (bnp_make) : can't set current directory to %s", ppArgs[3]); - return -1; + gBNPHeader.BigFileName = CPath::standardizePath(gBNPHeader.BigFileName) + CFile::getFilename(srcDirectory); } } else { - if (chdir (ppArgs[2]) == -1) - { - nlwarning ("ERROR (bnp_make) : can't set current directory to %s", ppArgs[2]); - return -1; - } - //getcwd (sCurDir, MAX_PATH); - gDestBNPFile = CPath::getCurrentPath() + string(".bnp"); + gBNPHeader.BigFileName = CFile::getFilename(srcDirectory); } - - remove (gDestBNPFile.c_str()); - gBNPHeader.OffsetFromBeginning = 0; - packSubRecurse(); - gBNPHeader.append (gDestBNPFile); - return 0; + + if (CFile::getExtension(gBNPHeader.BigFileName) != "bnp") + gBNPHeader.BigFileName += ".bnp"; + + CFile::deleteFile(gBNPHeader.BigFileName); + + packSubRecurse(srcDirectory); + return gBNPHeader.appendHeader() ? 0:-1; } - if ((strcmp(ppArgs[1], "/u") == 0) || (strcmp(ppArgs[1], "/U") == 0) || - (strcmp(ppArgs[1], "-u") == 0) || (strcmp(ppArgs[1], "-U") == 0)) + if (args.haveArg("u")) { - string::size_type i; - string path; - gDestBNPFile = ppArgs[2]; - if ((gDestBNPFile.rfind('/') != string::npos) || (gDestBNPFile.rfind('/') != string::npos)) - { - string::size_type pos = gDestBNPFile.rfind('/'); - if (pos == string::npos) - pos = gDestBNPFile.rfind('/'); - for (i = 0; i <= pos; ++i) - path += gDestBNPFile[i]; - string wholeName = gDestBNPFile; - gDestBNPFile = ""; - for (; i < wholeName.size(); ++i) - gDestBNPFile += wholeName[i]; - if (CPath::setCurrentPath(path.c_str())) - { - path = CPath::getCurrentPath(); - } - else - { - nlwarning ("ERROR (bnp_make) : can't set current directory to %s", path.c_str()); - return -1; - } - } - if (stricmp (gDestBNPFile.c_str()+gDestBNPFile.size()-4, ".bnp") != 0) - { - gDestBNPFile += ".bnp"; - } - string dirName; - for (i = 0; i < gDestBNPFile.size()-4; ++i) - dirName += gDestBNPFile[i]; - // Unpack a bnp file - if (!gBNPHeader.read (gDestBNPFile)) - return -1; + gBNPHeader.BigFileName = args.getAdditionalArg("input").front(); - //mkdir (dirName.c_str()); - CFile::createDirectory(dirName); + std::string dirName; - unpack (dirName); - - return 0; - } - - if ((strcmp(ppArgs[1], "/l") == 0) || (strcmp(ppArgs[1], "/L") == 0) || - (strcmp(ppArgs[1], "-l") == 0) || (strcmp(ppArgs[1], "-L") == 0)) - { - string::size_type i; - string path; - gDestBNPFile = ppArgs[2]; - if ((gDestBNPFile.rfind('/') != string::npos) || (gDestBNPFile.rfind('/') != string::npos)) + // Output directory or filename + if (args.haveArg("o")) { - string::size_type pos = gDestBNPFile.rfind('/'); - if (pos == string::npos) - pos = gDestBNPFile.rfind('/'); - for (i = 0; i <= pos; ++i) - path += gDestBNPFile[i]; - string wholeName = gDestBNPFile; - gDestBNPFile = ""; - for (; i < wholeName.size(); ++i) - gDestBNPFile += wholeName[i]; - if (CPath::setCurrentPath(path.c_str())) - { - path = CPath::getCurrentPath(); - } - else - { - nlwarning ("ERROR (bnp_make) : can't set current directory to %s", path.c_str()); - return -1; - } + dirName = args.getArg("o").front(); } - if (stricmp (gDestBNPFile.c_str()+gDestBNPFile.size()-4, ".bnp") != 0) + else { - gDestBNPFile += ".bnp"; + dirName = CFile::getFilenameWithoutExtension(gBNPHeader.BigFileName); } - string dirName; - for (i = 0; i < gDestBNPFile.size()-4; ++i) - dirName += gDestBNPFile[i]; // Unpack a bnp file - if (!gBNPHeader.read (gDestBNPFile)) - return -1; + return gBNPHeader.unpack(dirName) ? 0:-1; + } - for (i = 0; i < gBNPHeader.Files.size(); ++i) - printf ("%s\n", gBNPHeader.Files[i].Name.c_str()); + if (args.haveArg("l")) + { + gBNPHeader.BigFileName = args.getAdditionalArg("input").front(); + + // Read header of BNP file + if (!gBNPHeader.readHeader()) return -1; + + for (uint i = 0; i < gBNPHeader.SFiles.size(); ++i) + { + printf("%s\n", gBNPHeader.SFiles[i].Name.c_str()); + } return 0; } - usage (); + args.displayHelp(); return -1; }