diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp index 7fe18fbc1..ae26ed1d7 100644 --- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp @@ -120,6 +120,15 @@ static bool StringToUInt32(const wchar_t *s, UInt32 &v) return *end == 0; } +static bool StringToInt32(const wchar_t *s, Int32 &v) +{ + if (*s == 0) + return false; + const wchar_t *end; + v = ConvertStringToInt32(s, &end); + return *end == 0; +} + namespace NKey { enum Enum @@ -209,6 +218,7 @@ enum Enum #ifndef Z7_NO_CRYPTO , kPassword + , kPasswordFd #endif }; @@ -360,6 +370,7 @@ static const CSwitchForm kSwitchForms[] = #ifndef Z7_NO_CRYPTO , { "p", SWFRM_STRING } + , { "pfd", SWFRM_STRING } #endif }; @@ -1460,6 +1471,22 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) options.PasswordEnabled = parser[NKey::kPassword].ThereIs; if (options.PasswordEnabled) options.Password = parser[NKey::kPassword].PostStrings[0]; + + options.PasswordFd = 0; + + if (parser[NKey::kPasswordFd].ThereIs) + { + const UString &s = parser[NKey::kPasswordFd].PostStrings[0]; + if (s.IsEmpty()) + throw CArcCmdLineException("No file descriptor given to -pfd", s); + else + { + Int32 v; + if (!StringToInt32(s, v)) + throw CArcCmdLineException("A file descriptor is required for -pfd", s); + options.PasswordFd = (int)v; + } + } #endif options.ShowDialog = parser[NKey::kShowDialog].ThereIs; diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h index d17ec5a3c..bf7aa92a2 100644 --- a/CPP/7zip/UI/Common/ArchiveCommandLine.h +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.h @@ -89,6 +89,7 @@ struct CArcCmdLineOptions #ifndef Z7_NO_CRYPTO bool PasswordEnabled; UString Password; + int PasswordFd; #endif UStringVector HashMethods; diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp index 874caef3c..8b346d1e9 100644 --- a/CPP/7zip/UI/Console/List.cpp +++ b/CPP/7zip/UI/Console/List.cpp @@ -1081,7 +1081,7 @@ HRESULT ListArchives( const NWildcard::CCensorNode &wildcardCensor, bool enableHeaders, bool techMode, #ifndef Z7_NO_CRYPTO - bool &passwordEnabled, UString &password, + bool &passwordEnabled, UString &password, int &passwordFd, #endif #ifndef Z7_SFX const CObjectVector *props, @@ -1161,6 +1161,7 @@ HRESULT ListArchives( openCallback.PasswordIsDefined = passwordEnabled; openCallback.Password = password; + openCallback.PasswordFd = passwordFd; #endif diff --git a/CPP/7zip/UI/Console/List.h b/CPP/7zip/UI/Console/List.h index d87f512b6..ab43731c4 100644 --- a/CPP/7zip/UI/Console/List.h +++ b/CPP/7zip/UI/Console/List.h @@ -31,7 +31,7 @@ HRESULT ListArchives( const NWildcard::CCensorNode &wildcardCensor, bool enableHeaders, bool techMode, #ifndef Z7_NO_CRYPTO - bool &passwordEnabled, UString &password, + bool &passwordEnabled, UString &password, int &passwordFd, #endif #ifndef Z7_SFX const CObjectVector *props, diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp index 90e00a495..86f7e42c7 100644 --- a/CPP/7zip/UI/Console/Main.cpp +++ b/CPP/7zip/UI/Console/Main.cpp @@ -163,6 +163,7 @@ static const char * const kHelpString = " -o{Directory} : set Output directory\n" #ifndef Z7_NO_CRYPTO " -p{Password} : set Password\n" + " -pfd{N} : read Password from fd\n" #endif " -r[-|0] : Recurse subdirectories for name search\n" " -sa{a|e|s} : set Archive name mode\n" @@ -1333,6 +1334,7 @@ int Main2( #ifndef Z7_NO_CRYPTO ecs->PasswordIsDefined = options.PasswordEnabled; ecs->Password = options.Password; + ecs->PasswordFd = options.PasswordFd; #endif ecs->Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents); @@ -1517,6 +1519,7 @@ int Main2( #ifndef Z7_NO_CRYPTO options.PasswordEnabled, options.Password, + options.PasswordFd, #endif &options.Properties, numErrors, numWarnings); @@ -1551,6 +1554,7 @@ int Main2( (options.PasswordEnabled && !options.Password.IsEmpty()); openCallback.PasswordIsDefined = passwordIsDefined; openCallback.Password = options.Password; + openCallback.PasswordFd = options.PasswordFd; #endif CUpdateCallbackConsole callback; @@ -1564,6 +1568,7 @@ int Main2( callback.PasswordIsDefined = passwordIsDefined; callback.AskPassword = (options.PasswordEnabled && options.Password.IsEmpty()); callback.Password = options.Password; + callback.PasswordFd = options.PasswordFd; #endif callback.StdOutMode = uo.StdOutMode; diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp index 1e7adf5d4..58b53b32a 100644 --- a/CPP/7zip/UI/Console/OpenCallbackConsole.cpp +++ b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp @@ -87,6 +87,15 @@ HRESULT COpenCallbackConsole::Open_CryptoGetTextPassword(BSTR *password) if (!PasswordIsDefined) { ClosePercents(); + if (PasswordFd) { + FILE *_file = fdopen(PasswordFd, "r"); + + if (!_file) + return S_FALSE; + + g_StdIn = CStdInStream(_file); + } + RINOK(GetPassword_HRESULT(_so, Password)) PasswordIsDefined = true; } diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.h b/CPP/7zip/UI/Console/OpenCallbackConsole.h index 5e7c19cc0..9f8bdf6e1 100644 --- a/CPP/7zip/UI/Console/OpenCallbackConsole.h +++ b/CPP/7zip/UI/Console/OpenCallbackConsole.h @@ -67,6 +67,7 @@ class COpenCallbackConsole: public IOpenCallbackUI bool PasswordIsDefined; // bool PasswordWasAsked; UString Password; + int PasswordFd; #endif }; diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp index 5185d5cc8..16006f5a0 100644 --- a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp +++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp @@ -828,6 +828,16 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, if (!PasswordIsDefined) { + if (PasswordFd) { + FILE *_file = fdopen(PasswordFd, "r"); + + if (!_file) + return S_FALSE; + + g_StdIn = CStdInStream(_file); + } + + if (AskPassword) { RINOK(GetPassword_HRESULT(_so, Password)) @@ -857,6 +867,15 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password) if (!PasswordIsDefined) { { + if (PasswordFd) { + FILE *_file = fdopen(PasswordFd, "r"); + + if (!_file) + return S_FALSE; + + g_StdIn = CStdInStream(_file); + } + RINOK(GetPassword_HRESULT(_so, Password)) PasswordIsDefined = true; } diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.h b/CPP/7zip/UI/Console/UpdateCallbackConsole.h index a3863711c..2a4d9a54e 100644 --- a/CPP/7zip/UI/Console/UpdateCallbackConsole.h +++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.h @@ -122,6 +122,7 @@ class CUpdateCallbackConsole Z7_final: bool PasswordIsDefined; bool AskPassword; UString Password; + int PasswordFd; #endif CUpdateCallbackConsole(): diff --git a/CPP/7zip/UI/Console/UserInputUtils.h b/CPP/7zip/UI/Console/UserInputUtils.h index 695a3e66d..d8ffd1c2c 100644 --- a/CPP/7zip/UI/Console/UserInputUtils.h +++ b/CPP/7zip/UI/Console/UserInputUtils.h @@ -3,6 +3,7 @@ #ifndef ZIP7_INC_USER_INPUT_UTILS_H #define ZIP7_INC_USER_INPUT_UTILS_H +#include "../../../Common/StdInStream.h" #include "../../../Common/StdOutStream.h" namespace NUserAnswerMode {