⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 archivecommandline.cpp

📁 由7-zip提供的压缩、解压缩程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ArchiveCommandLine.cpp#include "StdAfx.h"#include <io.h>#include <stdio.h>#include "Common/ListFileUtils.h"#include "Common/StringConvert.h"#include "Common/StringToInt.h"#include "Windows/FileName.h"#include "Windows/FileDir.h"#ifdef _WIN32#include "Windows/FileMapping.h"#include "Windows/Synchronization.h"#endif#include "ArchiveCommandLine.h"#include "UpdateAction.h"#include "Update.h"#include "ArchiverInfo.h"#include "SortUtils.h"#include "EnumDirItems.h"#ifdef HAVE_LSTATextern int global_use_lstat;#endifusing namespace NCommandLineParser;using namespace NWindows;using namespace NFile;static const int kNumSwitches = 27;namespace NKey {enum Enum{  kHelp1 = 0,  kHelp2,  kHelp3,  kDisableHeaders,  kDisablePercents,  kArchiveType,  kYes,  kPassword,  kProperty,  kOutputDir,  kWorkingDir,  kInclude,  kExclude,  kArInclude,  kArExclude,  kNoArName,  kUpdate,  kVolume,  kRecursed,  kSfx,  kStdIn,  kStdOut,  kOverwrite,  kEmail,  kShowDialog,  kUseLStat,  kTechMode};}static const wchar_t kRecursedIDChar = 'R';static const wchar_t *kRecursedPostCharSet = L"0-";static const wchar_t *kDefaultArchiveType = L"7z";static const wchar_t *kSFXExtension =  #ifdef _WIN32    L"exe";  #else    L"";  #endifnamespace NRecursedPostCharIndex {  enum EEnum   {    kWildCardRecursionOnly = 0,     kNoRecursion = 1  };}static const char kImmediateNameID = '!';static const char kMapNameID = '#';static const char kFileListID = '@';static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must bestatic const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must bestatic const wchar_t *kOverwritePostCharSet = L"asut";NExtract::NOverwriteMode::EEnum k_OverwriteModes[] ={  NExtract::NOverwriteMode::kWithoutPrompt,  NExtract::NOverwriteMode::kSkipExisting,  NExtract::NOverwriteMode::kAutoRename,  NExtract::NOverwriteMode::kAutoRenameExisting};static const CSwitchForm kSwitchForms[kNumSwitches] =   {    { L"?",  NSwitchType::kSimple, false },    { L"H",  NSwitchType::kSimple, false },    { L"-HELP",  NSwitchType::kSimple, false },    { L"BA", NSwitchType::kSimple, false },    { L"BD", NSwitchType::kSimple, false },    { L"T",  NSwitchType::kUnLimitedPostString, false, 1 },    { L"Y",  NSwitchType::kSimple, false },    { L"P",  NSwitchType::kUnLimitedPostString, false, 0 },    { L"M", NSwitchType::kUnLimitedPostString, true, 1 },    { L"O",  NSwitchType::kUnLimitedPostString, false, 1 },    { L"W",  NSwitchType::kUnLimitedPostString, false, 0 },    { L"I",  NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},    { L"X",  NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},    { L"AI",  NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},    { L"AX",  NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},    { L"AN", NSwitchType::kSimple, false },    { L"U",  NSwitchType::kUnLimitedPostString, true, 1},    { L"V",  NSwitchType::kUnLimitedPostString, true, 1},    { L"R",  NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet },    { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 },    { L"SI",  NSwitchType::kUnLimitedPostString, false, 0 },    { L"SO",  NSwitchType::kSimple, false, 0 },    { L"AO",  NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet},    { L"SEML", NSwitchType::kUnLimitedPostString, false, 0},    { L"AD",  NSwitchType::kSimple, false },    { L"L",  NSwitchType::kSimple, false },    { L"SLT", NSwitchType::kSimple, false }  };static const int kNumCommandForms = 7;static const CCommandForm g_CommandForms[kNumCommandForms] = {  { L"A", false },  { L"U", false },  { L"D", false },  { L"T", false },  { L"E", false },  { L"X", false },  { L"L", false }};static const int kMaxCmdLineSize = 1000;static const wchar_t *kUniversalWildcard = L"*";static const int kMinNonSwitchWords = 1;static const int kCommandIndex = 0;// ---------------------------// exception messagesstatic const char *kUserErrorMessage  = "Incorrect command line";static const char *kIncorrectListFile = "Incorrect wildcard in listfile";static const char *kIncorrectWildCardInListFile = "Incorrect wildcard in listfile";static const char *kIncorrectWildCardInCommandLine  = "Incorrect wildcard in command line";static const char *kTerminalOutError = "I won't write compressed data to a terminal";// ---------------------------bool CArchiveCommand::IsFromExtractGroup() const{  switch(CommandType)  {    case NCommandType::kTest:    case NCommandType::kExtract:    case NCommandType::kFullExtract:      return true;    default:      return false;  }}NExtract::NPathMode::EEnum CArchiveCommand::GetPathMode() const{  switch(CommandType)  {    case NCommandType::kTest:    case NCommandType::kFullExtract:      return NExtract::NPathMode::kFullPathnames;    default:      return NExtract::NPathMode::kNoPathnames;  }}bool CArchiveCommand::IsFromUpdateGroup() const{  return (CommandType == NCommandType::kAdd ||     CommandType == NCommandType::kUpdate ||    CommandType == NCommandType::kDelete);}static NRecursedType::EEnum GetRecursedTypeFromIndex(int index){  switch (index)  {    case NRecursedPostCharIndex::kWildCardRecursionOnly:       return NRecursedType::kWildCardOnlyRecursed;    case NRecursedPostCharIndex::kNoRecursion:       return NRecursedType::kNonRecursed;    default:      return NRecursedType::kRecursed;  }}static bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command){  UString commandStringUpper = commandString;  commandStringUpper.MakeUpper();  UString postString;  int commandIndex = ParseCommand(kNumCommandForms, g_CommandForms, commandStringUpper,       postString) ;  if (commandIndex < 0)    return false;  command.CommandType = (NCommandType::EEnum)commandIndex;  return true;}// ------------------------------------------------------------------// filenames functionsstatic bool AddNameToCensor(NWildcard::CCensor &wildcardCensor,     const UString &name, bool include, NRecursedType::EEnum type){  bool isWildCard = DoesNameContainWildCard(name);  bool recursed;  switch (type)  {    case NRecursedType::kWildCardOnlyRecursed:      recursed = isWildCard;      break;    case NRecursedType::kRecursed:      recursed = true;      break;    case NRecursedType::kNonRecursed:      recursed = false;      break;  }  wildcardCensor.AddItem(include, name, recursed);  return true;}static inline UINT GetCurrentCodePage() { return AreFileApisANSI() ? CP_ACP : CP_OEMCP; } static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor,     LPCWSTR fileName, bool include, NRecursedType::EEnum type, UINT codePage){  UStringVector names;  if (!ReadNamesFromListFile(GetSystemString(fileName, GetCurrentCodePage()), names, codePage))    throw kIncorrectListFile;  for (int i = 0; i < names.Size(); i++)    if (!AddNameToCensor(wildcardCensor, names[i], include, type))      throw kIncorrectWildCardInListFile;}static void AddCommandLineWildCardToCensr(NWildcard::CCensor &wildcardCensor,     const UString &name, bool include, NRecursedType::EEnum recursedType){  if (!AddNameToCensor(wildcardCensor, name, include, recursedType))    throw kIncorrectWildCardInCommandLine;}static void AddToCensorFromNonSwitchesStrings(    int startIndex,    NWildcard::CCensor &wildcardCensor,     const UStringVector &nonSwitchStrings, NRecursedType::EEnum type,     bool thereAreSwitchIncludes, UINT codePage){  if(nonSwitchStrings.Size() == startIndex && (!thereAreSwitchIncludes))     AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type);  for(int i = startIndex; i < nonSwitchStrings.Size(); i++)  {    const UString &s = nonSwitchStrings[i];    if (s[0] == kFileListID)      AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage);    else      AddCommandLineWildCardToCensr(wildcardCensor, s, true, type);  }}#ifdef _WIN32static void ParseMapWithPaths(NWildcard::CCensor &wildcardCensor,     const UString &switchParam, bool include,     NRecursedType::EEnum commonRecursedType){  int splitPos = switchParam.Find(L':');  if (splitPos < 0)    throw kUserErrorMessage;  UString mappingName = switchParam.Left(splitPos);    UString switchParam2 = switchParam.Mid(splitPos + 1);  splitPos = switchParam2.Find(L':');  if (splitPos < 0)    throw kUserErrorMessage;    UString mappingSize = switchParam2.Left(splitPos);  UString eventName = switchParam2.Mid(splitPos + 1);    UInt64 dataSize64 = ConvertStringToUInt64(mappingSize, NULL);  UInt32 dataSize = (UInt32)dataSize64;  {    CFileMapping fileMapping;    if (!fileMapping.Open(FILE_MAP_READ, false, GetSystemString(mappingName)))      throw L"Can not open mapping";    LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_READ, 0, dataSize);    if (data == NULL)      throw L"MapViewOfFile error";    try    {      const wchar_t *curData = (const wchar_t *)data;      if (*curData != 0)        throw L"Incorrect mapping data";      UInt32 numChars = dataSize / sizeof(wchar_t);      UString name;      for (UInt32 i = 1; i < numChars; i++)      {        wchar_t c = curData[i];        if (c == L'\0')        {          AddCommandLineWildCardToCensr(wildcardCensor,               name, include, commonRecursedType);          name.Empty();        }        else          name += c;      }      if (!name.IsEmpty())        throw L"data error";    }    catch(...)    {      UnmapViewOfFile(data);      throw;    }    UnmapViewOfFile(data);  }    {    NSynchronization::CEvent event;    event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName));    event.Set();  }}#endifstatic void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,     const UStringVector &strings, bool include,     NRecursedType::EEnum commonRecursedType, UINT codePage){  for(int i = 0; i < strings.Size(); i++)  {    const UString &name = strings[i];    NRecursedType::EEnum recursedType;    int pos = 0;    if (name.Length() < kSomeCludePostStringMinSize)      throw kUserErrorMessage;    if (::MyCharUpper(name[pos]) == kRecursedIDChar)    {      pos++;      int index = UString(kRecursedPostCharSet).Find(name[pos]);      recursedType = GetRecursedTypeFromIndex(index);      if (index >= 0)        pos++;    }    else      recursedType = commonRecursedType;    if (name.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize)      throw kUserErrorMessage;    UString tail = name.Mid(pos + 1);    if (name[pos] == kImmediateNameID)      AddCommandLineWildCardToCensr(wildcardCensor, tail, include, recursedType);    else if (name[pos] == kFileListID)      AddToCensorFromListFile(wildcardCensor, tail, include, recursedType, codePage);    #ifdef _WIN32    else if (name[pos] == kMapNameID)      ParseMapWithPaths(wildcardCensor, tail, include, recursedType);    #endif    else      throw kUserErrorMessage;  }}#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::CFileInfoW fileInfo;  if (NFind::FindFile(prefix + name, fileInfo))    name = fileInfo.Name;}static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items){  for (int i = 0; i < items.Size(); i++)  {    NWildcard::CItem &item = items[i];    if (item.Recursive || item.PathParts.Size() != 1)      continue;    ConvertToLongName(prefix, item.PathParts.Front());  }}static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node){  ConvertToLongNames(prefix, node.IncludeItems);  ConvertToLongNames(prefix, node.ExcludeItems);  int i;  for (i = 0; i < node.SubNodes.Size(); i++)    ConvertToLongName(prefix, node.SubNodes[i].Name);  // mix folders with same name  for (i = 0; i < node.SubNodes.Size(); i++)  {    NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];    for (int j = i + 1; j < node.SubNodes.Size();)    {      const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];      if (nextNode1.Name.CompareNoCase(nextNode2.Name) == 0)      {        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_t(NFile::NName::kDirDelimiter), nextNode);   }}static void ConvertToLongNames(NWildcard::CCensor &censor){  for (int i = 0; i < censor.Pairs.Size(); i++)  {    NWildcard::CPair &pair = censor.Pairs[i];    ConvertToLongNames(pair.Prefix, pair.Head);  }}#endifstatic NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i){  switch(i)  {    case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore;    case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy;    case NUpdateArchive::NPairAction::kCompress: return NUpdateArchive::NPairAction::kCompress;    case NUpdateArchive::NPairAction::kCompressAsAnti: return NUpdateArchive::NPairAction::kCompressAsAnti;  }  throw 98111603;}const UString kUpdatePairStateIDSet = L"PQRXYZW";const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress, Create Anticonst wchar_t *kUpdateIgnoreItselfPostStringID = L"-"; const wchar_t kUpdateNewArchivePostCharID = '!'; static bool ParseUpdateCommandString2(const UString &command,     NUpdateArchive::CActionSet &actionSet, UString &postString)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -