diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp')
-rw-r--r-- | 3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp | 1017 |
1 files changed, 678 insertions, 339 deletions
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp index 832ec66d9c5..2bdbc418243 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp @@ -8,27 +8,53 @@ #ifndef UNDER_CE #include <io.h> #endif +#else +// for isatty() +#include <unistd.h> #endif + #include <stdio.h> +#ifdef Z7_LARGE_PAGES +#include "../../../../C/Alloc.h" +#endif + +#include "../../../Common/IntToString.h" #include "../../../Common/ListFileUtils.h" #include "../../../Common/StringConvert.h" #include "../../../Common/StringToInt.h" +#include "../../../Windows/ErrorMsg.h" #include "../../../Windows/FileDir.h" #include "../../../Windows/FileName.h" +#include "../../../Windows/System.h" #ifdef _WIN32 #include "../../../Windows/FileMapping.h" +#include "../../../Windows/MemoryLock.h" #include "../../../Windows/Synchronization.h" #endif #include "ArchiveCommandLine.h" #include "EnumDirItems.h" -#include "SortUtils.h" #include "Update.h" #include "UpdateAction.h" extern bool g_CaseSensitive; +extern bool g_PathTrailReplaceMode; + +#ifdef Z7_LARGE_PAGES +extern +bool g_LargePagesMode; +bool g_LargePagesMode = false; +#endif + +/* +#ifdef ENV_HAVE_LSTAT +EXTERN_C_BEGIN +extern int global_use_lstat; +EXTERN_C_END +#endif +*/ #ifdef UNDER_CE @@ -36,13 +62,18 @@ extern bool g_CaseSensitive; #else -#if _MSC_VER >= 1400 -#define MY_isatty_fileno(x) _isatty(_fileno(x)) -#else -#define MY_isatty_fileno(x) isatty(fileno(x)) -#endif - -#define MY_IS_TERMINAL(x) (MY_isatty_fileno(x) != 0); +// #define MY_isatty_fileno(x) (isatty(fileno(x))) +// #define MY_IS_TERMINAL(x) (MY_isatty_fileno(x) != 0); +static inline bool MY_IS_TERMINAL(FILE *x) +{ + return ( + #if defined(_MSC_VER) && (_MSC_VER >= 1400) + _isatty(_fileno(x)) + #else + isatty(fileno(x)) + #endif + != 0); +} #endif @@ -59,17 +90,6 @@ static bool StringToUInt32(const wchar_t *s, UInt32 &v) return *end == 0; } -CArcCmdLineException::CArcCmdLineException(const char *a, const wchar_t *u) -{ - (*this) += MultiByteToUnicodeString(a); - if (u) - { - this->Add_LF(); - (*this) += u; - } -} - -int g_CodePage = -1; namespace NKey { enum Enum @@ -113,6 +133,8 @@ enum Enum kSfx, kEmail, kHash, + // kHashGenFile, + kHashDir, kStdIn, kStdOut, @@ -121,26 +143,38 @@ enum Enum kListfileCharSet, kConsoleCharSet, kTechMode, + kListFields, + kPreserveATime, kShareForWrite, + kStopAfterOpenError, kCaseSensitive, kArcNameMode, + kUseSlashMark, kDisableWildcardParsing, kElimDup, kFullPathMode, kHardLinks, + kSymLinks_AllowDangerous, kSymLinks, kNtSecurity, + + kStoreOwnerId, + kStoreOwnerName, + + kZoneFile, kAltStreams, kReplaceColonForAltStream, kWriteToAltStreamIfColon, + kNameTrailReplace, + kDeleteAfterCompressing, kSetArcMTime - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO , kPassword #endif }; @@ -149,13 +183,13 @@ enum Enum static const wchar_t kRecursedIDChar = 'r'; -static const char *kRecursedPostCharSet = "0-"; +static const char * const kRecursedPostCharSet = "0-"; -static const char *k_ArcNameMode_PostCharSet = "sea"; +static const char * const k_ArcNameMode_PostCharSet = "sea"; -static const char *k_Stream_PostCharSet = "012"; +static const char * const k_Stream_PostCharSet = "012"; -static inline const EArcNameMode ParseArcNameMode(int postCharIndex) +static inline EArcNameMode ParseArcNameMode(int postCharIndex) { switch (postCharIndex) { @@ -173,14 +207,17 @@ namespace NRecursedPostCharIndex { }; } -static const char kImmediateNameID = '!'; -static const char kMapNameID = '#'; -static const char kFileListID = '@'; +// static const char +#define kImmediateNameID '!' +#ifdef _WIN32 +#define kMapNameID '#' +#endif +#define kFileListID '@' -static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be -static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be +static const Byte kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be +static const Byte kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be -static const char *kOverwritePostCharSet = "asut"; +static const char * const kOverwritePostCharSet = "asut"; static const NExtract::NOverwriteMode::EEnum k_OverwriteModes[] = { @@ -190,125 +227,154 @@ static const NExtract::NOverwriteMode::EEnum k_OverwriteModes[] = NExtract::NOverwriteMode::kRenameExisting }; + + +#define SWFRM_3(t, mu, mi) t, mu, mi, NULL + +#define SWFRM_1(t) SWFRM_3(t, false, 0) +#define SWFRM_SIMPLE SWFRM_1(NSwitchType::kSimple) +#define SWFRM_MINUS SWFRM_1(NSwitchType::kMinus) +#define SWFRM_STRING SWFRM_1(NSwitchType::kString) + +#define SWFRM_STRING_SINGL(mi) SWFRM_3(NSwitchType::kString, false, mi) +#define SWFRM_STRING_MULT(mi) SWFRM_3(NSwitchType::kString, true, mi) + + static const CSwitchForm kSwitchForms[] = { - { "?" }, - { "h" }, - { "-help" }, + { "?", SWFRM_SIMPLE }, + { "h", SWFRM_SIMPLE }, + { "-help", SWFRM_SIMPLE }, - { "ba" }, - { "bd" }, - { "bt" }, - { "bb", NSwitchType::kString, false, 0 }, + { "ba", SWFRM_SIMPLE }, + { "bd", SWFRM_SIMPLE }, + { "bt", SWFRM_SIMPLE }, + { "bb", SWFRM_STRING_SINGL(0) }, { "bso", NSwitchType::kChar, false, 1, k_Stream_PostCharSet }, { "bse", NSwitchType::kChar, false, 1, k_Stream_PostCharSet }, { "bsp", NSwitchType::kChar, false, 1, k_Stream_PostCharSet }, - { "y" }, + { "y", SWFRM_SIMPLE }, - { "ad" }, + { "ad", SWFRM_SIMPLE }, { "ao", NSwitchType::kChar, false, 1, kOverwritePostCharSet}, - { "t", NSwitchType::kString, false, 1 }, - { "stx", NSwitchType::kString, true, 1 }, + { "t", SWFRM_STRING_SINGL(1) }, + { "stx", SWFRM_STRING_MULT(1) }, - { "m", NSwitchType::kString, true, 1 }, - { "o", NSwitchType::kString, false, 1 }, - { "w", NSwitchType::kString }, - - { "i", NSwitchType::kString, true, kSomeCludePostStringMinSize}, - { "x", NSwitchType::kString, true, kSomeCludePostStringMinSize}, - { "ai", NSwitchType::kString, true, kSomeCludePostStringMinSize}, - { "ax", NSwitchType::kString, true, kSomeCludePostStringMinSize}, - { "an" }, + { "m", SWFRM_STRING_MULT(1) }, + { "o", SWFRM_STRING_SINGL(1) }, + { "w", SWFRM_STRING }, + + { "i", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) }, + { "x", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) }, + { "ai", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) }, + { "ax", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) }, + { "an", SWFRM_SIMPLE }, - { "u", NSwitchType::kString, true, 1}, - { "v", NSwitchType::kString, true, 1}, + { "u", SWFRM_STRING_MULT(1) }, + { "v", SWFRM_STRING_MULT(1) }, { "r", NSwitchType::kChar, false, 0, kRecursedPostCharSet }, - { "stm", NSwitchType::kString }, - { "sfx", NSwitchType::kString }, - { "seml", NSwitchType::kString, false, 0}, - { "scrc", NSwitchType::kString, true, 0 }, + { "stm", SWFRM_STRING }, + { "sfx", SWFRM_STRING }, + { "seml", SWFRM_STRING_SINGL(0) }, + { "scrc", SWFRM_STRING_MULT(0) }, + // { "scrf", SWFRM_STRING_SINGL(1) }, + { "shd", SWFRM_STRING_SINGL(1) }, - { "si", NSwitchType::kString }, - { "so" }, - - { "slp", NSwitchType::kMinus }, - { "scs", NSwitchType::kString }, - { "scc", NSwitchType::kString }, - { "slt" }, - - { "ssw" }, - { "ssc", NSwitchType::kMinus }, + { "si", SWFRM_STRING }, + { "so", SWFRM_SIMPLE }, + + { "slp", SWFRM_STRING }, + { "scs", SWFRM_STRING }, + { "scc", SWFRM_STRING }, + { "slt", SWFRM_SIMPLE }, + { "slf", SWFRM_STRING_SINGL(1) }, + + { "ssp", SWFRM_SIMPLE }, + { "ssw", SWFRM_SIMPLE }, + { "sse", SWFRM_SIMPLE }, + { "ssc", SWFRM_MINUS }, { "sa", NSwitchType::kChar, false, 1, k_ArcNameMode_PostCharSet }, - { "spd" }, - { "spe", NSwitchType::kMinus }, - { "spf", NSwitchType::kString, false, 0 }, + { "spm", SWFRM_STRING_SINGL(0) }, + { "spd", SWFRM_SIMPLE }, + { "spe", SWFRM_MINUS }, + { "spf", SWFRM_STRING_SINGL(0) }, - { "snh", NSwitchType::kMinus }, - { "snl", NSwitchType::kMinus }, - { "sni" }, - { "sns", NSwitchType::kMinus }, - { "snr" }, - { "snc" }, + { "snh", SWFRM_MINUS }, + { "snld", SWFRM_MINUS }, + { "snl", SWFRM_MINUS }, + { "sni", SWFRM_SIMPLE }, + + { "snoi", SWFRM_MINUS }, + { "snon", SWFRM_MINUS }, - { "sdel" }, - { "stl" } + { "snz", SWFRM_STRING_SINGL(0) }, + { "sns", SWFRM_MINUS }, + { "snr", SWFRM_SIMPLE }, + { "snc", SWFRM_SIMPLE }, + + { "snt", SWFRM_MINUS }, + + { "sdel", SWFRM_SIMPLE }, + { "stl", SWFRM_SIMPLE } - #ifndef _NO_CRYPTO - , { "p", NSwitchType::kString } + #ifndef Z7_NO_CRYPTO + , { "p", SWFRM_STRING } #endif }; -static const wchar_t *kUniversalWildcard = L"*"; +static const char * const kUniversalWildcard = "*"; static const unsigned kMinNonSwitchWords = 1; static const unsigned kCommandIndex = 0; -// static const char *kUserErrorMessage = "Incorrect command line"; -static const char *kCannotFindListFile = "Cannot find listfile"; -static const char *kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch."; -static const char *kTerminalOutError = "I won't write compressed data to a terminal"; -static const char *kSameTerminalError = "I won't write data and program's messages to same stream"; -static const char *kEmptyFilePath = "Empty file path"; -static const char *kCannotFindArchive = "Cannot find archive"; +// static const char * const kUserErrorMessage = "Incorrect command line"; +// static const char * const kCannotFindListFile = "Cannot find listfile"; +static const char * const kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch."; +static const char * const kTerminalOutError = "I won't write compressed data to a terminal"; +static const char * const kSameTerminalError = "I won't write data and program's messages to same stream"; +static const char * const kEmptyFilePath = "Empty file path"; bool CArcCommand::IsFromExtractGroup() const { - switch (CommandType) + switch ((int)CommandType) { case NCommandType::kTest: case NCommandType::kExtract: case NCommandType::kExtractFull: return true; + default: + return false; } - return false; } NExtract::NPathMode::EEnum CArcCommand::GetPathMode() const { - switch (CommandType) + switch ((int)CommandType) { case NCommandType::kTest: case NCommandType::kExtractFull: return NExtract::NPathMode::kFullPaths; + default: + return NExtract::NPathMode::kNoPaths; } - return NExtract::NPathMode::kNoPaths; } bool CArcCommand::IsFromUpdateGroup() const { - switch (CommandType) + switch ((int)CommandType) { case NCommandType::kAdd: case NCommandType::kUpdate: case NCommandType::kDelete: case NCommandType::kRename: return true; + default: + return false; } - return false; } static NRecursedType::EEnum GetRecursedTypeFromIndex(int index) @@ -328,7 +394,7 @@ static const char *g_Commands = "audtexlbih"; static bool ParseArchiveCommand(const UString &commandString, CArcCommand &command) { - UString s = commandString; + UString s (commandString); s.MakeLower_Ascii(); if (s.Len() == 1) { @@ -351,12 +417,28 @@ static bool ParseArchiveCommand(const UString &commandString, CArcCommand &comma // ------------------------------------------------------------------ // filenames functions +struct CNameOption +{ + bool Include; + bool WildcardMatching; + Byte MarkMode; + NRecursedType::EEnum RecursedType; + + CNameOption(): + Include(true), + WildcardMatching(true), + MarkMode(NWildcard::kMark_FileOrDir), + RecursedType(NRecursedType::kNonRecursed) + {} +}; + + static void AddNameToCensor(NWildcard::CCensor &censor, - const UString &name, bool include, NRecursedType::EEnum type, bool wildcardMatching) + const CNameOption &nop, const UString &name) { bool recursed = false; - switch (type) + switch ((int)nop.RecursedType) { case NRecursedType::kWildcardOnlyRecursed: recursed = DoesNameContainWildcard(name); @@ -364,8 +446,15 @@ static void AddNameToCensor(NWildcard::CCensor &censor, case NRecursedType::kRecursed: recursed = true; break; + default: + break; } - censor.AddPreItem(include, name, recursed, wildcardMatching); + + NWildcard::CCensorPathProps props; + props.Recursive = recursed; + props.WildcardMatching = nop.WildcardMatching; + props.MarkMode = nop.MarkMode; + censor.AddPreItem(nop.Include, name, props); } static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs, @@ -386,9 +475,9 @@ static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs, val += pair.NewName; val.Add_LF(); if (type == NRecursedType::kRecursed) - val.AddAscii("-r"); + val += "-r"; else if (type == NRecursedType::kWildcardOnlyRecursed) - val.AddAscii("-r0"); + val += "-r0"; throw CArcCmdLineException("Unsupported rename command:", val); } } @@ -396,13 +485,26 @@ static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs, static void AddToCensorFromListFile( CObjectVector<CRenamePair> *renamePairs, NWildcard::CCensor &censor, - LPCWSTR fileName, bool include, NRecursedType::EEnum type, bool wildcardMatching, Int32 codePage) + const CNameOption &nop, LPCWSTR fileName, UInt32 codePage) { UStringVector names; - if (!NFind::DoesFileExist(us2fs(fileName))) + /* + if (!NFind::DoesFileExist_FollowLink(us2fs(fileName))) throw CArcCmdLineException(kCannotFindListFile, fileName); - if (!ReadNamesFromListFile(us2fs(fileName), names, codePage)) + */ + DWORD lastError = 0; + if (!ReadNamesFromListFile2(us2fs(fileName), names, codePage, lastError)) + { + if (lastError != 0) + { + UString m; + m = "The file operation error for listfile"; + m.Add_LF(); + m += NError::MyFormatMessage(lastError); + throw CArcCmdLineException(m, fileName); + } throw CArcCmdLineException(kIncorrectListFile, fileName); + } if (renamePairs) { if ((names.Size() & 1) != 0) @@ -410,55 +512,73 @@ static void AddToCensorFromListFile( for (unsigned i = 0; i < names.Size(); i += 2) { // change type !!!! - AddRenamePair(renamePairs, names[i], names[i + 1], type, wildcardMatching); + AddRenamePair(renamePairs, names[i], names[i + 1], nop.RecursedType, nop.WildcardMatching); } } else FOR_VECTOR (i, names) - AddNameToCensor(censor, names[i], include, type, wildcardMatching); + AddNameToCensor(censor, nop, names[i]); } static void AddToCensorFromNonSwitchesStrings( CObjectVector<CRenamePair> *renamePairs, unsigned startIndex, NWildcard::CCensor &censor, - const UStringVector &nonSwitchStrings, NRecursedType::EEnum type, - bool wildcardMatching, - bool thereAreSwitchIncludes, Int32 codePage) + const UStringVector &nonSwitchStrings, + int stopSwitchIndex, + const CNameOption &nop, + bool thereAreSwitchIncludes, UInt32 codePage) { + // another default if ((renamePairs || nonSwitchStrings.Size() == startIndex) && !thereAreSwitchIncludes) - AddNameToCensor(censor, kUniversalWildcard, true, type, - true // wildcardMatching - ); + { + /* for rename command: -i switch sets the mask for archive item reading. + if (thereAreSwitchIncludes), { we don't use UniversalWildcard. } + also for non-rename command: we set UniversalWildcard, only if there are no nonSwitches. */ + // we use default fileds in (CNameOption) for UniversalWildcard. + CNameOption nop2; + // recursive mode is not important for UniversalWildcard (*) + // nop2.RecursedType = nop.RecursedType; // we don't need it + /* + nop2.RecursedType = NRecursedType::kNonRecursed; + nop2.Include = true; + nop2.WildcardMatching = true; + nop2.MarkMode = NWildcard::kMark_FileOrDir; + */ + AddNameToCensor(censor, nop2, UString(kUniversalWildcard)); + } int oldIndex = -1; + if (stopSwitchIndex < 0) + stopSwitchIndex = (int)nonSwitchStrings.Size(); + for (unsigned i = startIndex; i < nonSwitchStrings.Size(); i++) { const UString &s = nonSwitchStrings[i]; if (s.IsEmpty()) throw CArcCmdLineException(kEmptyFilePath); - if (s[0] == kFileListID) - AddToCensorFromListFile(renamePairs, censor, s.Ptr(1), true, type, wildcardMatching, codePage); + if (i < (unsigned)stopSwitchIndex && s[0] == kFileListID) + AddToCensorFromListFile(renamePairs, censor, nop, s.Ptr(1), codePage); else if (renamePairs) { if (oldIndex == -1) - oldIndex = i; + oldIndex = (int)i; else { // NRecursedType::EEnum type is used for global wildcard (-i! switches) - AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, NRecursedType::kNonRecursed, wildcardMatching); + AddRenamePair(renamePairs, nonSwitchStrings[(unsigned)oldIndex], s, NRecursedType::kNonRecursed, nop.WildcardMatching); // AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, type); oldIndex = -1; } } else - AddNameToCensor(censor, s, true, type, wildcardMatching); + AddNameToCensor(censor, nop, s); } if (oldIndex != -1) { - throw CArcCmdLineException("There is no second file name for rename pair:", nonSwitchStrings[oldIndex]); + throw CArcCmdLineException("There is no second file name for rename pair:", nonSwitchStrings[(unsigned)oldIndex]); } } @@ -477,35 +597,34 @@ struct CEventSetEnd } }; -const char *k_IncorrectMapCommand = "Incorrect Map command"; +static const char * const k_IncorrectMapCommand = "Incorrect Map command"; static const char *ParseMapWithPaths( NWildcard::CCensor &censor, - const UString &s2, bool include, - NRecursedType::EEnum commonRecursedType, - bool wildcardMatching) + const UString &s2, + const CNameOption &nop) { - UString s = s2; + UString s (s2); int pos = s.Find(L':'); if (pos < 0) return k_IncorrectMapCommand; - int pos2 = s.Find(L':', pos + 1); + int pos2 = s.Find(L':', (unsigned)(pos + 1)); if (pos2 < 0) return k_IncorrectMapCommand; - CEventSetEnd eventSetEnd((const wchar_t *)s + ((unsigned)pos2 + 1)); - s.DeleteFrom(pos2); + CEventSetEnd eventSetEnd((const wchar_t *)s + (unsigned)(pos2 + 1)); + s.DeleteFrom((unsigned)pos2); UInt32 size; - if (!StringToUInt32(s.Ptr(pos + 1), size) + if (!StringToUInt32(s.Ptr((unsigned)(pos + 1)), size) || size < sizeof(wchar_t) || size > ((UInt32)1 << 31) || size % sizeof(wchar_t) != 0) return "Unsupported Map data size"; - s.DeleteFrom(pos); + s.DeleteFrom((unsigned)pos); CFileMapping map; if (map.Open(FILE_MAP_READ, GetSystemString(s)) != 0) - return "Can not open mapping"; + return "Cannot open mapping"; LPVOID data = map.Map(FILE_MAP_READ, 0, size); if (!data) return "MapViewOfFile error"; @@ -522,7 +641,7 @@ static const char *ParseMapWithPaths( if (c == 0) { // MessageBoxW(0, name, L"7-Zip", 0); - AddNameToCensor(censor, name, include, commonRecursedType, wildcardMatching); + AddNameToCensor(censor, nop, name); name.Empty(); } else @@ -538,17 +657,15 @@ static const char *ParseMapWithPaths( static void AddSwitchWildcardsToCensor( NWildcard::CCensor &censor, - const UStringVector &strings, bool include, - NRecursedType::EEnum commonRecursedType, - bool wildcardMatching, - Int32 codePage) + const UStringVector &strings, + const CNameOption &nop, + UInt32 codePage) { const char *errorMessage = NULL; unsigned i; for (i = 0; i < strings.Size(); i++) { const UString &name = strings[i]; - NRecursedType::EEnum recursedType; unsigned pos = 0; if (name.Len() < kSomeCludePostStringMinSize) @@ -556,37 +673,118 @@ static void AddSwitchWildcardsToCensor( errorMessage = "Too short switch"; break; } - - if (::MyCharLower_Ascii(name[pos]) == kRecursedIDChar) + + if (!nop.Include) { - pos++; - wchar_t c = name[pos]; - int index = -1; - if (c <= 0x7F) - index = FindCharPosInString(kRecursedPostCharSet, (char)c); - recursedType = GetRecursedTypeFromIndex(index); - if (index >= 0) + if (name.IsEqualTo_Ascii_NoCase("td")) + { + censor.ExcludeDirItems = true; + continue; + } + if (name.IsEqualTo_Ascii_NoCase("tf")) + { + censor.ExcludeFileItems = true; + continue; + } + } + + CNameOption nop2 = nop; + + bool type_WasUsed = false; + bool recursed_WasUsed = false; + bool matching_WasUsed = false; + bool error = false; + + for (;;) + { + wchar_t c = ::MyCharLower_Ascii(name[pos]); + if (c == kRecursedIDChar) + { + if (recursed_WasUsed) + { + error = true; + break; + } + recursed_WasUsed = true; + pos++; + c = name[pos]; + int index = -1; + if (c <= 0x7F) + index = FindCharPosInString(kRecursedPostCharSet, (char)c); + nop2.RecursedType = GetRecursedTypeFromIndex(index); + if (index >= 0) + { + pos++; + continue; + } + } + + if (c == 'w') + { + if (matching_WasUsed) + { + error = true; + break; + } + matching_WasUsed = true; + nop2.WildcardMatching = true; pos++; + if (name[pos] == '-') + { + nop2.WildcardMatching = false; + pos++; + } + } + else if (c == 'm') + { + if (type_WasUsed) + { + error = true; + break; + } + type_WasUsed = true; + pos++; + nop2.MarkMode = NWildcard::kMark_StrictFile; + c = name[pos]; + if (c == '-') + { + nop2.MarkMode = NWildcard::kMark_FileOrDir; + pos++; + } + else if (c == '2') + { + nop2.MarkMode = NWildcard::kMark_StrictFile_IfWildcard; + pos++; + } + } + else + break; } - else - recursedType = commonRecursedType; + if (error) + { + errorMessage = "inorrect switch"; + break; + } + if (name.Len() < pos + kSomeCludeAfterRecursedPostStringMinSize) { errorMessage = "Too short switch"; break; } - UString tail = name.Ptr(pos + 1); - - if (name[pos] == kImmediateNameID) - AddNameToCensor(censor, tail, include, recursedType, wildcardMatching); - else if (name[pos] == kFileListID) - AddToCensorFromListFile(NULL, censor, tail, include, recursedType, wildcardMatching, codePage); + const UString tail = name.Ptr(pos + 1); + + const wchar_t c = name[pos]; + + if (c == kImmediateNameID) + AddNameToCensor(censor, nop2, tail); + else if (c == kFileListID) + AddToCensorFromListFile(NULL, censor, nop2, tail, codePage); #ifdef _WIN32 - else if (name[pos] == kMapNameID) + else if (c == kMapNameID) { - errorMessage = ParseMapWithPaths(censor, tail, include, recursedType, wildcardMatching); + errorMessage = ParseMapWithPaths(censor, tail, nop2); if (errorMessage) break; } @@ -597,88 +795,11 @@ static void AddSwitchWildcardsToCensor( break; } } + if (i != strings.Size()) throw CArcCmdLineException(errorMessage, strings[i]); } -#ifdef _WIN32 - -// This code converts all short file names to long file names. - -static void ConvertToLongName(const UString &prefix, UString &name) -{ - if (name.IsEmpty() || DoesNameContainWildcard(name)) - return; - NFind::CFileInfo fi; - const FString path = us2fs(prefix + name); - #ifndef UNDER_CE - if (NFile::NName::IsDevicePath(path)) - return; - #endif - if (fi.Find(path)) - name = fs2us(fi.Name); -} - -static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items) -{ - FOR_VECTOR (i, items) - { - NWildcard::CItem &item = items[i]; - if (item.Recursive || item.PathParts.Size() != 1) - continue; - if (prefix.IsEmpty() && item.IsDriveItem()) - continue; - ConvertToLongName(prefix, item.PathParts.Front()); - } -} - -static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node) -{ - ConvertToLongNames(prefix, node.IncludeItems); - ConvertToLongNames(prefix, node.ExcludeItems); - unsigned i; - for (i = 0; i < node.SubNodes.Size(); i++) - { - UString &name = node.SubNodes[i].Name; - if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name)) - continue; - ConvertToLongName(prefix, name); - } - // mix folders with same name - for (i = 0; i < node.SubNodes.Size(); i++) - { - NWildcard::CCensorNode &nextNode1 = node.SubNodes[i]; - for (unsigned j = i + 1; j < node.SubNodes.Size();) - { - const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j]; - if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name)) - { - nextNode1.IncludeItems += nextNode2.IncludeItems; - nextNode1.ExcludeItems += nextNode2.ExcludeItems; - node.SubNodes.Delete(j); - } - else - j++; - } - } - for (i = 0; i < node.SubNodes.Size(); i++) - { - NWildcard::CCensorNode &nextNode = node.SubNodes[i]; - ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode); - } -} - -void ConvertToLongNames(NWildcard::CCensor &censor) -{ - FOR_VECTOR (i, censor.Pairs) - { - NWildcard::CPair &pair = censor.Pairs[i]; - ConvertToLongNames(pair.Prefix, pair.Head); - } -} - -#endif - /* static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i) { @@ -693,11 +814,11 @@ static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i) } */ -static const wchar_t *kUpdatePairStateIDSet = L"pqrxyzw"; +static const char * const kUpdatePairStateIDSet = "pqrxyzw"; static const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1}; static const unsigned kNumUpdatePairActions = 4; -static const char *kUpdateIgnoreItselfPostStringID = "-"; +static const char * const kUpdateIgnoreItselfPostStringID = "-"; static const wchar_t kUpdateNewArchivePostCharID = '!'; @@ -707,8 +828,8 @@ static bool ParseUpdateCommandString2(const UString &command, for (unsigned i = 0; i < command.Len();) { wchar_t c = MyCharLower_Ascii(command[i]); - int statePos = FindCharPosInString(kUpdatePairStateIDSet, c); - if (statePos < 0) + int statePos = FindCharPosInString(kUpdatePairStateIDSet, (char)c); + if (c > 0x7F || statePos < 0) { postString = command.Ptr(i); return true; @@ -717,9 +838,9 @@ static bool ParseUpdateCommandString2(const UString &command, if (i >= command.Len()) return false; c = command[i]; - if (c < '0' || c >= '0' + kNumUpdatePairActions) + if (c < '0' || c >= (wchar_t)('0' + kNumUpdatePairActions)) return false; - unsigned actionPos = c - '0'; + unsigned actionPos = (unsigned)(c - '0'); actionSet.StateActions[(unsigned)statePos] = (NUpdateArchive::NPairAction::EEnum)(actionPos); if (kUpdatePairStateNotSupportedActions[(unsigned)statePos] == (int)actionPos) return false; @@ -784,7 +905,7 @@ static void SetAddCommandOptions( CUpdateOptions &options) { NUpdateArchive::CActionSet defaultActionSet; - switch (commandType) + switch ((int)commandType) { case NCommandType::kAdd: defaultActionSet = NUpdateArchive::k_ActionSet_Add; @@ -823,8 +944,10 @@ static void SetAddCommandOptions( FOR_VECTOR (i, sv) { UInt64 size; - if (!ParseComplexSize(sv[i], size) || size == 0) + if (!ParseComplexSize(sv[i], size)) throw CArcCmdLineException("Incorrect volume size:", sv[i]); + if (i == sv.Size() - 1 && size == 0) + throw CArcCmdLineException("zero size last volume is not allowed"); options.VolumesSizes.Add(size); } } @@ -841,26 +964,37 @@ static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &pr int index = prop.Name.Find(L'='); if (index >= 0) { - prop.Value = prop.Name.Ptr(index + 1); - prop.Name.DeleteFrom(index); + prop.Value = prop.Name.Ptr((unsigned)(index + 1)); + prop.Name.DeleteFrom((unsigned)index); } properties.Add(prop); } } } -CArcCmdLineParser::CArcCmdLineParser(): parser(ARRAY_SIZE(kSwitchForms)) {} static inline void SetStreamMode(const CSwitchResult &sw, unsigned &res) { if (sw.ThereIs) - res = sw.PostCharIndex; + res = (unsigned)sw.PostCharIndex; } + +#if defined(_WIN32) && !defined(UNDER_CE) +static void PrintHex(UString &s, UInt64 v) +{ + char temp[32]; + ConvertUInt64ToHex(v, temp); + s += temp; +} +#endif + + void CArcCmdLineParser::Parse1(const UStringVector &commandStrings, CArcCmdLineOptions &options) { - if (!parser.ParseStrings(kSwitchForms, commandStrings)) + Parse1Log.Empty(); + if (!parser.ParseStrings(kSwitchForms, Z7_ARRAY_SIZE(kSwitchForms), commandStrings)) throw CArcCmdLineException(parser.ErrorMessage, parser.ErrorLine); options.IsInTerminal = MY_IS_TERMINAL(stdin); @@ -872,6 +1006,11 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings, options.StdInMode = parser[NKey::kStdIn].ThereIs; options.StdOutMode = parser[NKey::kStdOut].ThereIs; options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs; + if (parser[NKey::kListFields].ThereIs) + { + const UString &s = parser[NKey::kListFields].PostStrings[0]; + options.ListFields = GetAnsiString(s); + } options.TechMode = parser[NKey::kTechMode].ThereIs; options.ShowTime = parser[NKey::kShowTime].ThereIs; @@ -903,14 +1042,52 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings, if (parser[NKey::kCaseSensitive].ThereIs) { + options.CaseSensitive = g_CaseSensitive = !parser[NKey::kCaseSensitive].WithMinus; - options.CaseSensitiveChange = true; - options.CaseSensitive = g_CaseSensitive; + options.CaseSensitive_Change = true; } - options.LargePages = false; + + #if defined(_WIN32) && !defined(UNDER_CE) + NSecurity::EnablePrivilege_SymLink(); + #endif + + // options.LargePages = false; + if (parser[NKey::kLargePages].ThereIs) - options.LargePages = !parser[NKey::kLargePages].WithMinus; + { + UInt32 slp = 0; + const UString &s = parser[NKey::kLargePages].PostStrings[0]; + if (s.IsEmpty()) + slp = 1; + else if (s != L"-") + { + if (!StringToUInt32(s, slp)) + throw CArcCmdLineException("Unsupported switch postfix for -slp", s); + } + + #ifdef Z7_LARGE_PAGES + if (slp > + #if defined(_WIN32) && !defined(UNDER_CE) + (unsigned)NSecurity::Get_LargePages_RiskLevel() + #else + 0 + #endif + ) + { + #ifdef _WIN32 // change it ! + SetLargePageSize(); + #endif + // note: this process also can inherit that Privilege from parent process + g_LargePagesMode = + #if defined(_WIN32) && !defined(UNDER_CE) + NSecurity::EnablePrivilege_LockMemory(); + #else + true; + #endif + } + #endif + } #ifndef UNDER_CE @@ -920,32 +1097,83 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings, const UString &s = parser[NKey::kAffinity].PostStrings[0]; if (!s.IsEmpty()) { - UInt32 v = 0; AString a; a.SetFromWStr_if_Ascii(s); - if (!a.IsEmpty()) + Parse1Log += "Set process affinity mask: "; + + #ifdef _WIN32 + + UInt64 v = 0; { const char *end; - v = ConvertHexStringToUInt32(a, &end); + v = ConvertHexStringToUInt64(a, &end); if (*end != 0) a.Empty(); } if (a.IsEmpty()) throw CArcCmdLineException("Unsupported switch postfix -stm", s); + + { + #ifndef _WIN64 + if (v >= ((UInt64)1 << 32)) + throw CArcCmdLineException("unsupported value -stm", s); + #endif + { + PrintHex(Parse1Log, v); + if (!SetProcessAffinityMask(GetCurrentProcess(), (DWORD_PTR)v)) + { + DWORD lastError = GetLastError(); + Parse1Log += " : ERROR : "; + Parse1Log += NError::MyFormatMessage(lastError); + } + } + } - #ifdef _WIN32 - SetProcessAffinityMask(GetCurrentProcess(), v); - #endif + #else // _WIN32 + + { + Parse1Log += a; + NSystem::CProcessAffinity aff; + aff.CpuZero(); + for (unsigned i = 0; i < a.Len(); i++) + { + char c = a[i]; + unsigned v; + if (c >= '0' && c <= '9') v = (unsigned)(c - '0'); + else if (c >= 'A' && c <= 'F') v = 10 + (unsigned)(c - 'A'); + else if (c >= 'a' && c <= 'f') v = 10 + (unsigned)(c - 'a'); + else + throw CArcCmdLineException("Unsupported switch postfix -stm", s); + for (unsigned k = 0; k < 4; k++) + { + const unsigned cpu = (a.Len() - 1 - i) * 4 + k; + if (v & ((unsigned)1 << k)) + aff.CpuSet(cpu); + } + } + + if (!aff.SetProcAffinity()) + { + DWORD lastError = GetLastError(); + Parse1Log += " : ERROR : "; + Parse1Log += NError::MyFormatMessage(lastError); + } + } + #endif // _WIN32 + + Parse1Log.Add_LF(); } } #endif } + + struct CCodePagePair { const char *Name; - Int32 CodePage; + UInt32 CodePage; }; static const unsigned kNumByteOnlyCodePages = 3; @@ -955,8 +1183,8 @@ static const CCodePagePair g_CodePagePairs[] = { "utf-8", CP_UTF8 }, { "win", CP_ACP }, { "dos", CP_OEMCP }, - { "utf-16le", MY__CP_UTF16 }, - { "utf-16be", MY__CP_UTF16BE } + { "utf-16le", Z7_WIN_CP_UTF16 }, + { "utf-16be", Z7_WIN_CP_UTF16BE } }; static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned keyIndex, @@ -965,81 +1193,23 @@ static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned key if (!parser[keyIndex].ThereIs) return defaultVal; - UString name = parser[keyIndex].PostStrings.Back(); + UString name (parser[keyIndex].PostStrings.Back()); UInt32 v; if (StringToUInt32(name, v)) if (v < ((UInt32)1 << 16)) return (Int32)v; name.MakeLower_Ascii(); - unsigned num = byteOnlyCodePages ? kNumByteOnlyCodePages : ARRAY_SIZE(g_CodePagePairs); + const unsigned num = byteOnlyCodePages ? kNumByteOnlyCodePages : Z7_ARRAY_SIZE(g_CodePagePairs); for (unsigned i = 0;; i++) { if (i == num) // to disable warnings from different compilers throw CArcCmdLineException("Unsupported charset:", name); const CCodePagePair &pair = g_CodePagePairs[i]; if (name.IsEqualTo(pair.Name)) - return pair.CodePage; + return (Int32)pair.CodePage; } } -HRESULT EnumerateDirItemsAndSort( - NWildcard::CCensor &censor, - NWildcard::ECensorPathMode censorPathMode, - const UString &addPathPrefix, - UStringVector &sortedPaths, - UStringVector &sortedFullPaths, - CDirItemsStat &st, - IDirItemsCallback *callback) -{ - FStringVector paths; - - { - CDirItems dirItems; - dirItems.Callback = callback; - { - HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems); - st = dirItems.Stat; - RINOK(res); - } - - FOR_VECTOR (i, dirItems.Items) - { - const CDirItem &dirItem = dirItems.Items[i]; - if (!dirItem.IsDir()) - paths.Add(dirItems.GetPhyPath(i)); - } - } - - if (paths.Size() == 0) - throw CArcCmdLineException(kCannotFindArchive); - - UStringVector fullPaths; - - unsigned i; - - for (i = 0; i < paths.Size(); i++) - { - FString fullPath; - NFile::NDir::MyGetFullPathName(paths[i], fullPath); - fullPaths.Add(fs2us(fullPath)); - } - - CUIntVector indices; - SortFileNames(fullPaths, indices); - sortedPaths.ClearAndReserve(indices.Size()); - sortedFullPaths.ClearAndReserve(indices.Size()); - - for (i = 0; i < indices.Size(); i++) - { - unsigned index = indices[i]; - sortedPaths.AddInReserved(fs2us(paths[index])); - sortedFullPaths.AddInReserved(fullPaths[index]); - if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0) - throw CArcCmdLineException("Duplicate archive path:", sortedFullPaths[i]); - } - - return S_OK; -} static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, CBoolPair &bp) { @@ -1051,7 +1221,7 @@ static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) { const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; - unsigned numNonSwitchStrings = nonSwitchStrings.Size(); + const unsigned numNonSwitchStrings = nonSwitchStrings.Size(); if (numNonSwitchStrings < kMinNonSwitchWords) throw CArcCmdLineException("The command must be specified"); @@ -1060,6 +1230,27 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) if (parser[NKey::kHash].ThereIs) options.HashMethods = parser[NKey::kHash].PostStrings; + + /* + if (parser[NKey::kHashGenFile].ThereIs) + { + const UString &s = parser[NKey::kHashGenFile].PostStrings[0]; + for (unsigned i = 0 ; i < s.Len();) + { + const wchar_t c = s[i++]; + if (!options.HashOptions.ParseFlagCharOption(c, true)) + { + if (c != '=') + throw CArcCmdLineException("Unsupported hash mode switch:", s); + options.HashOptions.HashFilePath = s.Ptr(i); + break; + } + } + } + */ + + if (parser[NKey::kHashDir].ThereIs) + options.ExtractOptions.HashDir = parser[NKey::kHashDir].PostStrings[0]; if (parser[NKey::kElimDup].ThereIs) { @@ -1082,31 +1273,51 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) } } - NRecursedType::EEnum recursedType; + if (parser[NKey::kNameTrailReplace].ThereIs) + g_PathTrailReplaceMode = !parser[NKey::kNameTrailReplace].WithMinus; + + CNameOption nop; + if (parser[NKey::kRecursed].ThereIs) - recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex); - else - recursedType = NRecursedType::kNonRecursed; + nop.RecursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex); - bool wildcardMatching = true; if (parser[NKey::kDisableWildcardParsing].ThereIs) - wildcardMatching = false; + nop.WildcardMatching = false; + + if (parser[NKey::kUseSlashMark].ThereIs) + { + const UString &s = parser[NKey::kUseSlashMark].PostStrings[0]; + if (s.IsEmpty()) + nop.MarkMode = NWildcard::kMark_StrictFile; + else if (s.IsEqualTo_Ascii_NoCase("-")) + nop.MarkMode = NWildcard::kMark_FileOrDir; + else if (s.IsEqualTo_Ascii_NoCase("2")) + nop.MarkMode = NWildcard::kMark_StrictFile_IfWildcard; + else + throw CArcCmdLineException("Unsupported -spm:", s); + } - g_CodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1); - Int32 codePage = FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8); + + options.ConsoleCodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1); + + UInt32 codePage = (UInt32)FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8); bool thereAreSwitchIncludes = false; - + if (parser[NKey::kInclude].ThereIs) { thereAreSwitchIncludes = true; + nop.Include = true; AddSwitchWildcardsToCensor(options.Censor, - parser[NKey::kInclude].PostStrings, true, recursedType, wildcardMatching, codePage); + parser[NKey::kInclude].PostStrings, nop, codePage); } if (parser[NKey::kExclude].ThereIs) + { + nop.Include = false; AddSwitchWildcardsToCensor(options.Censor, - parser[NKey::kExclude].PostStrings, false, recursedType, wildcardMatching, codePage); + parser[NKey::kExclude].PostStrings, nop, codePage); + } unsigned curCommandIndex = kCommandIndex + 1; bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs && @@ -1114,9 +1325,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) options.Command.CommandType != NCommandType::kInfo && options.Command.CommandType != NCommandType::kHash; - bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); - bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList; - bool isRename = options.Command.CommandType == NCommandType::kRename; + const bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + const bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList; + const bool isRename = options.Command.CommandType == NCommandType::kRename; if ((isExtractOrList || isRename) && options.StdInMode) thereIsArchiveName = false; @@ -1136,15 +1347,17 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) #endif } + nop.Include = true; AddToCensorFromNonSwitchesStrings(isRename ? &options.UpdateOptions.RenamePairs : NULL, curCommandIndex, options.Censor, - nonSwitchStrings, recursedType, wildcardMatching, + nonSwitchStrings, parser.StopSwitchIndex, + nop, thereAreSwitchIncludes, codePage); options.YesToAll = parser[NKey::kYes].ThereIs; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO options.PasswordEnabled = parser[NKey::kPassword].ThereIs; if (options.PasswordEnabled) options.Password = parser[NKey::kPassword].PostStrings[0]; @@ -1164,11 +1377,41 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) SetBoolPair(parser, NKey::kAltStreams, options.AltStreams); SetBoolPair(parser, NKey::kHardLinks, options.HardLinks); SetBoolPair(parser, NKey::kSymLinks, options.SymLinks); + + SetBoolPair(parser, NKey::kStoreOwnerId, options.StoreOwnerId); + SetBoolPair(parser, NKey::kStoreOwnerName, options.StoreOwnerName); + + CBoolPair symLinks_AllowDangerous; + SetBoolPair(parser, NKey::kSymLinks_AllowDangerous, symLinks_AllowDangerous); + + + /* + bool supportSymLink = options.SymLinks.Val; + + if (!options.SymLinks.Def) + { + if (isExtractOrList) + supportSymLink = true; + else + supportSymLink = false; + } + + #ifdef ENV_HAVE_LSTAT + if (supportSymLink) + global_use_lstat = 1; + else + global_use_lstat = 0; + #endif + */ + if (isExtractOrList) { CExtractOptionsBase &eo = options.ExtractOptions; + eo.ExcludeDirItems = options.Censor.ExcludeDirItems; + eo.ExcludeFileItems = options.Censor.ExcludeFileItems; + { CExtractNtOptions &nt = eo.NtOptions; nt.NtSecurity = options.NtSecurity; @@ -1185,10 +1428,33 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) if (!options.SymLinks.Def) nt.SymLinks.Val = true; + nt.SymLinks_AllowDangerous = symLinks_AllowDangerous; + nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs; nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs; + + nt.ExtractOwner = options.StoreOwnerId.Val; // StoreOwnerName + + if (parser[NKey::kPreserveATime].ThereIs) + nt.PreserveATime = true; + if (parser[NKey::kShareForWrite].ThereIs) + nt.OpenShareForWrite = true; } - + + if (parser[NKey::kZoneFile].ThereIs) + { + eo.ZoneMode = NExtract::NZoneIdMode::kAll; + const UString &s = parser[NKey::kZoneFile].PostStrings[0]; + if (!s.IsEmpty()) + { + if (s == L"0") eo.ZoneMode = NExtract::NZoneIdMode::kNone; + else if (s == L"1") eo.ZoneMode = NExtract::NZoneIdMode::kAll; + else if (s == L"2") eo.ZoneMode = NExtract::NZoneIdMode::kOffice; + else + throw CArcCmdLineException("Unsupported -snz:", s); + } + } + options.Censor.AddPathsToCensor(NWildcard::k_AbsPath); options.Censor.ExtendExclude(); @@ -1198,13 +1464,28 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) NWildcard::CCensor &arcCensor = options.arcCensor; + CNameOption nopArc; + // nopArc.RecursedType = NRecursedType::kNonRecursed; // default: we don't want recursing for archives, if -r specified + // is it OK, external switches can disable WildcardMatching and MarcMode for arc. + nopArc.WildcardMatching = nop.WildcardMatching; + nopArc.MarkMode = nop.MarkMode; + if (parser[NKey::kArInclude].ThereIs) - AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, wildcardMatching, codePage); + { + nopArc.Include = true; + AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArInclude].PostStrings, nopArc, codePage); + } if (parser[NKey::kArExclude].ThereIs) - AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, wildcardMatching, codePage); + { + nopArc.Include = false; + AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, nopArc, codePage); + } if (thereIsArchiveName) - AddNameToCensor(arcCensor, options.ArchiveName, true, NRecursedType::kNonRecursed, wildcardMatching); + { + nopArc.Include = true; + AddNameToCensor(arcCensor, nopArc, options.ArchiveName); + } arcCensor.AddPathsToCensor(NWildcard::k_RelatPath); @@ -1242,6 +1523,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) if (parser[NKey::kOutputDir].ThereIs) { eo.OutputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]); + #ifdef _WIN32 + NFile::NName::NormalizeDirSeparators(eo.OutputDir); + #endif NFile::NName::NormalizeDirPathPrefix(eo.OutputDir); } @@ -1281,8 +1565,12 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) updateOptions.MethodMode.Properties = options.Properties; + if (parser[NKey::kPreserveATime].ThereIs) + updateOptions.PreserveATime = true; if (parser[NKey::kShareForWrite].ThereIs) updateOptions.OpenShareForWrite = true; + if (parser[NKey::kStopAfterOpenError].ThereIs) + updateOptions.StopAfterOpenError = true; updateOptions.PathMode = censorPathMode; @@ -1290,6 +1578,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) updateOptions.NtSecurity = options.NtSecurity; updateOptions.HardLinks = options.HardLinks; updateOptions.SymLinks = options.SymLinks; + + updateOptions.StoreOwnerId = options.StoreOwnerId; + updateOptions.StoreOwnerName = options.StoreOwnerName; updateOptions.EMailMode = parser[NKey::kEmail].ThereIs; if (updateOptions.EMailMode) @@ -1333,11 +1624,13 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) else if (options.Command.CommandType == NCommandType::kBenchmark) { options.NumIterations = 1; + options.NumIterations_Defined = false; if (curCommandIndex < numNonSwitchStrings) { if (!StringToUInt32(nonSwitchStrings[curCommandIndex], options.NumIterations)) - throw CArcCmdLineException("Incorrect Number of benmchmark iterations", nonSwitchStrings[curCommandIndex]); + throw CArcCmdLineException("Incorrect number of benchmark iterations", nonSwitchStrings[curCommandIndex]); curCommandIndex++; + options.NumIterations_Defined = true; } } else if (options.Command.CommandType == NCommandType::kHash) @@ -1348,10 +1641,14 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) CHashOptions &hashOptions = options.HashOptions; hashOptions.PathMode = censorPathMode; hashOptions.Methods = options.HashMethods; + // hashOptions.HashFilePath = options.HashFilePath; + if (parser[NKey::kPreserveATime].ThereIs) + hashOptions.PreserveATime = true; if (parser[NKey::kShareForWrite].ThereIs) hashOptions.OpenShareForWrite = true; hashOptions.StdInMode = options.StdInMode; hashOptions.AltStreamsMode = options.AltStreams.Val; + hashOptions.SymLinks = options.SymLinks; } else if (options.Command.CommandType == NCommandType::kInfo) { @@ -1359,3 +1656,45 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) else throw 20150919; } + + + +#ifndef _WIN32 + +static AString g_ModuleDirPrefix; + +void Set_ModuleDirPrefix_From_ProgArg0(const char *s); +void Set_ModuleDirPrefix_From_ProgArg0(const char *s) +{ + AString a (s); + int sep = a.ReverseFind_PathSepar(); + a.DeleteFrom((unsigned)(sep + 1)); + g_ModuleDirPrefix = a; +} + +namespace NWindows { +namespace NDLL { + +FString GetModuleDirPrefix(); +FString GetModuleDirPrefix() +{ + FString s; + + s = fas2fs(g_ModuleDirPrefix); + if (s.IsEmpty()) + s = FTEXT(".") FSTRING_PATH_SEPARATOR; + return s; + /* + setenv("_7ZIP_HOME_DIR", "/test/", 0); + const char *home = getenv("_7ZIP_HOME_DIR"); + if (home) + s = home; + else + s = FTEXT(".") FSTRING_PATH_SEPARATOR; + return s; + */ +} + +}} + +#endif // ! _WIN32 |