tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SfxCon.cpp (12251B)


      1 // Main.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "../../../../C/CpuArch.h"
      6 
      7 #include "../../../Common/MyWindows.h"
      8 
      9 #include "../../../Common/MyInitGuid.h"
     10 
     11 #include "../../../Common/CommandLineParser.h"
     12 #include "../../../Common/MyException.h"
     13 
     14 #ifdef _WIN32
     15 #include "../../../Windows/DLL.h"
     16 #include "../../../Windows/FileDir.h"
     17 #endif
     18 #include "../../../Windows/FileName.h"
     19 
     20 #include "../../UI/Common/ExitCode.h"
     21 #include "../../UI/Common/Extract.h"
     22 
     23 #include "../../UI/Console/ExtractCallbackConsole.h"
     24 #include "../../UI/Console/List.h"
     25 #include "../../UI/Console/OpenCallbackConsole.h"
     26 
     27 #include "../../MyVersion.h"
     28 
     29 #include "../../../../C/DllSecur.h"
     30 
     31 using namespace NWindows;
     32 using namespace NFile;
     33 using namespace NDir;
     34 using namespace NCommandLineParser;
     35 
     36 #ifdef _WIN32
     37 HINSTANCE g_hInstance = 0;
     38 #endif
     39 int g_CodePage = -1;
     40 extern CStdOutStream *g_StdStream;
     41 
     42 static const char * const kCopyrightString =
     43 "\n7-Zip SFX " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n";
     44 
     45 static const int kNumSwitches = 6;
     46 
     47 namespace NKey {
     48 enum Enum
     49 {
     50  kHelp1 = 0,
     51  kHelp2,
     52  kDisablePercents,
     53  kYes,
     54  kPassword,
     55  kOutputDir
     56 };
     57 
     58 }
     59 
     60 namespace NRecursedType {
     61 enum EEnum
     62 {
     63  kRecursed,
     64  kWildcardOnlyRecursed,
     65  kNonRecursed
     66 };
     67 }
     68 /*
     69 static const char kRecursedIDChar = 'R';
     70 
     71 namespace NRecursedPostCharIndex {
     72  enum EEnum
     73  {
     74    kWildcardRecursionOnly = 0,
     75    kNoRecursion = 1
     76  };
     77 }
     78 
     79 static const char kFileListID = '@';
     80 static const char kImmediateNameID = '!';
     81 
     82 static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
     83 static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
     84 */
     85 static const CSwitchForm kSwitchForms[kNumSwitches] =
     86 {
     87  { "?",  NSwitchType::kSimple },
     88  { "H",  NSwitchType::kSimple },
     89  { "BD", NSwitchType::kSimple },
     90  { "Y",  NSwitchType::kSimple },
     91  { "P",  NSwitchType::kString, false, 1 },
     92  { "O",  NSwitchType::kString, false, 1 },
     93 };
     94 
     95 static const int kNumCommandForms = 3;
     96 
     97 static const NRecursedType::EEnum kCommandRecursedDefault[kNumCommandForms] =
     98 {
     99  NRecursedType::kRecursed
    100 };
    101 
    102 // static const bool kTestExtractRecursedDefault = true;
    103 // static const bool kAddRecursedDefault = false;
    104 
    105 static const char * const kUniversalWildcard = "*";
    106 static const int kCommandIndex = 0;
    107 
    108 static const char * const kHelpString =
    109    "\nUsage: 7zSFX [<command>] [<switches>...] [<file_name>...]\n"
    110    "\n"
    111    "<Commands>\n"
    112    // "  l: List contents of archive\n"
    113    "  t: Test integrity of archive\n"
    114    "  x: eXtract files with full pathname (default)\n"
    115    "<Switches>\n"
    116    // "  -bd Disable percentage indicator\n"
    117    "  -o{Directory}: set Output directory\n"
    118    "  -p{Password}: set Password\n"
    119    "  -y: assume Yes on all queries\n";
    120 
    121 
    122 // ---------------------------
    123 // exception messages
    124 
    125 static const char * const kUserErrorMessage  = "Incorrect command line"; // NExitCode::kUserError
    126 // static const char * const kIncorrectListFile = "Incorrect wildcard in listfile";
    127 static const char * const kIncorrectWildcardInCommandLine  = "Incorrect wildcard in command line";
    128 
    129 // static const CSysString kFileIsNotArchiveMessageBefore = "File \"";
    130 // static const CSysString kFileIsNotArchiveMessageAfter = "\" is not archive";
    131 
    132 // static const char * const kProcessArchiveMessage = " archive: ";
    133 
    134 static const char * const kCantFindSFX = " cannot find sfx";
    135 
    136 namespace NCommandType
    137 {
    138  enum EEnum
    139  {
    140    kTest = 0,
    141    kFullExtract,
    142    kList
    143  };
    144 }
    145 
    146 static const char *g_Commands = "txl";
    147 
    148 struct CArchiveCommand
    149 {
    150  NCommandType::EEnum CommandType;
    151 
    152  NRecursedType::EEnum DefaultRecursedType() const;
    153 };
    154 
    155 bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command)
    156 {
    157  UString s = commandString;
    158  s.MakeLower_Ascii();
    159  if (s.Len() != 1)
    160    return false;
    161  if (s[0] >= 0x80)
    162    return false;
    163  int index = FindCharPosInString(g_Commands, (char)s[0]);
    164  if (index < 0)
    165    return false;
    166  command.CommandType = (NCommandType::EEnum)index;
    167  return true;
    168 }
    169 
    170 NRecursedType::EEnum CArchiveCommand::DefaultRecursedType() const
    171 {
    172  return kCommandRecursedDefault[CommandType];
    173 }
    174 
    175 void PrintHelp(void)
    176 {
    177  g_StdOut << kHelpString;
    178 }
    179 
    180 static void ShowMessageAndThrowException(const char *message, NExitCode::EEnum code)
    181 {
    182  g_StdOut << message << endl;
    183  throw code;
    184 }
    185 
    186 static void PrintHelpAndExit() // yyy
    187 {
    188  PrintHelp();
    189  ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError);
    190 }
    191 
    192 // ------------------------------------------------------------------
    193 // filenames functions
    194 
    195 static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor,
    196    const UString &name, bool include, NRecursedType::EEnum type)
    197 {
    198  /*
    199  if (!IsWildcardFilePathLegal(name))
    200    return false;
    201  */
    202  bool isWildcard = DoesNameContainWildcard(name);
    203  bool recursed = false;
    204 
    205  switch (type)
    206  {
    207    case NRecursedType::kWildcardOnlyRecursed:
    208      recursed = isWildcard;
    209      break;
    210    case NRecursedType::kRecursed:
    211      recursed = true;
    212      break;
    213    case NRecursedType::kNonRecursed:
    214      recursed = false;
    215      break;
    216  }
    217  wildcardCensor.AddPreItem(include, name, recursed, true);
    218  return true;
    219 }
    220 
    221 void AddCommandLineWildcardToCensor(NWildcard::CCensor &wildcardCensor,
    222    const UString &name, bool include, NRecursedType::EEnum type)
    223 {
    224  if (!AddNameToCensor(wildcardCensor, name, include, type))
    225    ShowMessageAndThrowException(kIncorrectWildcardInCommandLine, NExitCode::kUserError);
    226 }
    227 
    228 
    229 #ifndef _WIN32
    230 static void GetArguments(int numArgs, const char *args[], UStringVector &parts)
    231 {
    232  parts.Clear();
    233  for (int i = 0; i < numArgs; i++)
    234  {
    235    UString s = MultiByteToUnicodeString(args[i]);
    236    parts.Add(s);
    237  }
    238 }
    239 #endif
    240 
    241 int Main2(
    242  #ifndef _WIN32
    243  int numArgs, const char *args[]
    244  #endif
    245 )
    246 {
    247  #ifdef _WIN32
    248  // do we need load Security DLLs for console program?
    249  LoadSecurityDlls();
    250  #endif
    251 
    252  #if defined(_WIN32) && !defined(UNDER_CE)
    253  SetFileApisToOEM();
    254  #endif
    255  
    256  g_StdOut << kCopyrightString;
    257 
    258  UStringVector commandStrings;
    259  #ifdef _WIN32
    260  NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
    261  #else
    262  GetArguments(numArgs, args, commandStrings);
    263  #endif
    264 
    265  #ifdef _WIN32
    266  
    267  FString arcPath;
    268  {
    269    FString path;
    270    NDLL::MyGetModuleFileName(path);
    271    if (!MyGetFullPathName(path, arcPath))
    272    {
    273      g_StdOut << "GetFullPathName Error";
    274      return NExitCode::kFatalError;
    275    }
    276  }
    277 
    278  #else
    279 
    280  UString arcPath = commandStrings.Front();
    281 
    282  #endif
    283 
    284  #ifndef UNDER_CE
    285  if (commandStrings.Size() > 0)
    286    commandStrings.Delete(0);
    287  #endif
    288 
    289  NCommandLineParser::CParser parser;
    290  
    291  try
    292  {
    293    if (!parser.ParseStrings(kSwitchForms, kNumSwitches, commandStrings))
    294    {
    295      g_StdOut << "Command line error:" << endl
    296          << parser.ErrorMessage << endl
    297          << parser.ErrorLine << endl;
    298      return NExitCode::kUserError;
    299    }
    300  }
    301  catch(...)
    302  {
    303    PrintHelpAndExit();
    304  }
    305 
    306  if (parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
    307  {
    308    PrintHelp();
    309    return 0;
    310  }
    311  
    312  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
    313 
    314  unsigned curCommandIndex = 0;
    315 
    316  CArchiveCommand command;
    317  if (nonSwitchStrings.IsEmpty())
    318    command.CommandType = NCommandType::kFullExtract;
    319  else
    320  {
    321    const UString &cmd = nonSwitchStrings[curCommandIndex];
    322    if (!ParseArchiveCommand(cmd, command))
    323    {
    324      g_StdOut << "ERROR: Unknown command:" << endl << cmd << endl;
    325      return NExitCode::kUserError;
    326    }
    327    curCommandIndex = 1;
    328  }
    329 
    330 
    331  NRecursedType::EEnum recursedType;
    332  recursedType = command.DefaultRecursedType();
    333 
    334  NWildcard::CCensor wildcardCensor;
    335  
    336  {
    337    if (nonSwitchStrings.Size() == curCommandIndex)
    338      AddCommandLineWildcardToCensor(wildcardCensor, (UString)kUniversalWildcard, true, recursedType);
    339    for (; curCommandIndex < nonSwitchStrings.Size(); curCommandIndex++)
    340    {
    341      const UString &s = nonSwitchStrings[curCommandIndex];
    342      if (s.IsEmpty())
    343        throw "Empty file path";
    344      AddCommandLineWildcardToCensor(wildcardCensor, s, true, recursedType);
    345    }
    346  }
    347 
    348  bool yesToAll = parser[NKey::kYes].ThereIs;
    349 
    350  // NExtractMode::EEnum extractMode;
    351  // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode);
    352 
    353  bool passwordEnabled = parser[NKey::kPassword].ThereIs;
    354 
    355  UString password;
    356  if (passwordEnabled)
    357    password = parser[NKey::kPassword].PostStrings[0];
    358 
    359  if (!NFind::DoesFileExist(arcPath))
    360    throw kCantFindSFX;
    361  
    362  FString outputDir;
    363  if (parser[NKey::kOutputDir].ThereIs)
    364  {
    365    outputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]);
    366    NName::NormalizeDirPathPrefix(outputDir);
    367  }
    368 
    369 
    370  wildcardCensor.AddPathsToCensor(NWildcard::k_RelatPath);
    371  
    372  {
    373    UStringVector v1, v2;
    374    v1.Add(fs2us(arcPath));
    375    v2.Add(fs2us(arcPath));
    376    const NWildcard::CCensorNode &wildcardCensorHead =
    377      wildcardCensor.Pairs.Front().Head;
    378 
    379    CCodecs *codecs = new CCodecs;
    380    CMyComPtr<
    381      #ifdef EXTERNAL_CODECS
    382      ICompressCodecsInfo
    383      #else
    384      IUnknown
    385      #endif
    386      > compressCodecsInfo = codecs;
    387    {
    388      HRESULT result = codecs->Load();
    389      if (result != S_OK)
    390        throw CSystemException(result);
    391    }
    392 
    393    if (command.CommandType != NCommandType::kList)
    394    {
    395      CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
    396      CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
    397      ecs->Init(g_StdStream, &g_StdErr, g_StdStream);
    398 
    399      #ifndef _NO_CRYPTO
    400      ecs->PasswordIsDefined = passwordEnabled;
    401      ecs->Password = password;
    402      #endif
    403 
    404      /*
    405      COpenCallbackConsole openCallback;
    406      openCallback.Init(g_StdStream, g_StdStream);
    407 
    408      #ifndef _NO_CRYPTO
    409      openCallback.PasswordIsDefined = passwordEnabled;
    410      openCallback.Password = password;
    411      #endif
    412      */
    413 
    414      CExtractOptions eo;
    415      eo.StdOutMode = false;
    416      eo.YesToAll = yesToAll;
    417      eo.TestMode = command.CommandType == NCommandType::kTest;
    418      eo.PathMode = NExtract::NPathMode::kFullPaths;
    419      eo.OverwriteMode = yesToAll ?
    420          NExtract::NOverwriteMode::kOverwrite :
    421          NExtract::NOverwriteMode::kAsk;
    422      eo.OutputDir = outputDir;
    423 
    424      UString errorMessage;
    425      CDecompressStat stat;
    426      HRESULT result = Extract(
    427          codecs, CObjectVector<COpenType>(), CIntVector(),
    428          v1, v2,
    429          wildcardCensorHead,
    430          eo, ecs, ecs,
    431          // NULL, // hash
    432          errorMessage, stat);
    433      if (!errorMessage.IsEmpty())
    434      {
    435        (*g_StdStream) << endl << "Error: " << errorMessage;;
    436        if (result == S_OK)
    437          result = E_FAIL;
    438      }
    439 
    440      if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0)
    441      {
    442        if (ecs->NumArcsWithError != 0)
    443          (*g_StdStream) << endl << "Archive Errors" << endl;
    444        if (ecs->NumFileErrors != 0)
    445          (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl;
    446        return NExitCode::kFatalError;
    447      }
    448      if (result != S_OK)
    449        throw CSystemException(result);
    450    }
    451    else
    452    {
    453      throw CSystemException(E_NOTIMPL);
    454 
    455      /*
    456      UInt64 numErrors = 0;
    457      UInt64 numWarnings = 0;
    458      HRESULT result = ListArchives(
    459          codecs, CObjectVector<COpenType>(), CIntVector(),
    460          false, // stdInMode
    461          v1, v2,
    462          true, // processAltStreams
    463          false, // showAltStreams
    464          wildcardCensorHead,
    465          true, // enableHeaders
    466          false, // techMode
    467          #ifndef _NO_CRYPTO
    468          passwordEnabled, password,
    469          #endif
    470          numErrors, numWarnings);
    471      if (numErrors > 0)
    472      {
    473        g_StdOut << endl << "Errors: " << numErrors;
    474        return NExitCode::kFatalError;
    475      }
    476      if (result != S_OK)
    477        throw CSystemException(result);
    478      */
    479    }
    480  }
    481  return 0;
    482 }