1370b324cSopenharmony_ci// ArchiveCommandLine.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci#undef printf
5370b324cSopenharmony_ci#undef sprintf
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#ifdef _WIN32
8370b324cSopenharmony_ci#ifndef UNDER_CE
9370b324cSopenharmony_ci#include <io.h>
10370b324cSopenharmony_ci#endif
11370b324cSopenharmony_ci#else
12370b324cSopenharmony_ci// for isatty()
13370b324cSopenharmony_ci#include <unistd.h>
14370b324cSopenharmony_ci#endif
15370b324cSopenharmony_ci
16370b324cSopenharmony_ci#include <stdio.h>
17370b324cSopenharmony_ci
18370b324cSopenharmony_ci#ifdef Z7_LARGE_PAGES
19370b324cSopenharmony_ci#include "../../../../C/Alloc.h"
20370b324cSopenharmony_ci#endif
21370b324cSopenharmony_ci
22370b324cSopenharmony_ci#include "../../../Common/IntToString.h"
23370b324cSopenharmony_ci#include "../../../Common/ListFileUtils.h"
24370b324cSopenharmony_ci#include "../../../Common/StringConvert.h"
25370b324cSopenharmony_ci#include "../../../Common/StringToInt.h"
26370b324cSopenharmony_ci
27370b324cSopenharmony_ci#include "../../../Windows/ErrorMsg.h"
28370b324cSopenharmony_ci#include "../../../Windows/FileDir.h"
29370b324cSopenharmony_ci#include "../../../Windows/FileName.h"
30370b324cSopenharmony_ci#include "../../../Windows/System.h"
31370b324cSopenharmony_ci#ifdef _WIN32
32370b324cSopenharmony_ci#include "../../../Windows/FileMapping.h"
33370b324cSopenharmony_ci#include "../../../Windows/MemoryLock.h"
34370b324cSopenharmony_ci#include "../../../Windows/Synchronization.h"
35370b324cSopenharmony_ci#endif
36370b324cSopenharmony_ci
37370b324cSopenharmony_ci#include "ArchiveCommandLine.h"
38370b324cSopenharmony_ci#include "EnumDirItems.h"
39370b324cSopenharmony_ci#include "Update.h"
40370b324cSopenharmony_ci#include "UpdateAction.h"
41370b324cSopenharmony_ci
42370b324cSopenharmony_ciextern bool g_CaseSensitive;
43370b324cSopenharmony_ciextern bool g_PathTrailReplaceMode;
44370b324cSopenharmony_ci
45370b324cSopenharmony_ci#ifdef Z7_LARGE_PAGES
46370b324cSopenharmony_ciextern
47370b324cSopenharmony_cibool g_LargePagesMode;
48370b324cSopenharmony_cibool g_LargePagesMode = false;
49370b324cSopenharmony_ci#endif
50370b324cSopenharmony_ci
51370b324cSopenharmony_ci/*
52370b324cSopenharmony_ci#ifdef ENV_HAVE_LSTAT
53370b324cSopenharmony_ciEXTERN_C_BEGIN
54370b324cSopenharmony_ciextern int global_use_lstat;
55370b324cSopenharmony_ciEXTERN_C_END
56370b324cSopenharmony_ci#endif
57370b324cSopenharmony_ci*/
58370b324cSopenharmony_ci
59370b324cSopenharmony_ci#ifdef UNDER_CE
60370b324cSopenharmony_ci
61370b324cSopenharmony_ci#define MY_IS_TERMINAL(x) false;
62370b324cSopenharmony_ci
63370b324cSopenharmony_ci#else
64370b324cSopenharmony_ci
65370b324cSopenharmony_ci// #define MY_isatty_fileno(x) (isatty(fileno(x)))
66370b324cSopenharmony_ci// #define MY_IS_TERMINAL(x) (MY_isatty_fileno(x) != 0);
67370b324cSopenharmony_cistatic inline bool MY_IS_TERMINAL(FILE *x)
68370b324cSopenharmony_ci{
69370b324cSopenharmony_ci  return (
70370b324cSopenharmony_ci    #if defined(_MSC_VER) && (_MSC_VER >= 1400)
71370b324cSopenharmony_ci      _isatty(_fileno(x))
72370b324cSopenharmony_ci    #else
73370b324cSopenharmony_ci      isatty(fileno(x))
74370b324cSopenharmony_ci    #endif
75370b324cSopenharmony_ci      != 0);
76370b324cSopenharmony_ci}
77370b324cSopenharmony_ci
78370b324cSopenharmony_ci#endif
79370b324cSopenharmony_ci
80370b324cSopenharmony_ciusing namespace NCommandLineParser;
81370b324cSopenharmony_ciusing namespace NWindows;
82370b324cSopenharmony_ciusing namespace NFile;
83370b324cSopenharmony_ci
84370b324cSopenharmony_cistatic bool StringToUInt32(const wchar_t *s, UInt32 &v)
85370b324cSopenharmony_ci{
86370b324cSopenharmony_ci  if (*s == 0)
87370b324cSopenharmony_ci    return false;
88370b324cSopenharmony_ci  const wchar_t *end;
89370b324cSopenharmony_ci  v = ConvertStringToUInt32(s, &end);
90370b324cSopenharmony_ci  return *end == 0;
91370b324cSopenharmony_ci}
92370b324cSopenharmony_ci
93370b324cSopenharmony_ci
94370b324cSopenharmony_cinamespace NKey {
95370b324cSopenharmony_cienum Enum
96370b324cSopenharmony_ci{
97370b324cSopenharmony_ci  kHelp1 = 0,
98370b324cSopenharmony_ci  kHelp2,
99370b324cSopenharmony_ci  kHelp3,
100370b324cSopenharmony_ci
101370b324cSopenharmony_ci  kDisableHeaders,
102370b324cSopenharmony_ci  kDisablePercents,
103370b324cSopenharmony_ci  kShowTime,
104370b324cSopenharmony_ci  kLogLevel,
105370b324cSopenharmony_ci
106370b324cSopenharmony_ci  kOutStream,
107370b324cSopenharmony_ci  kErrStream,
108370b324cSopenharmony_ci  kPercentStream,
109370b324cSopenharmony_ci
110370b324cSopenharmony_ci  kYes,
111370b324cSopenharmony_ci
112370b324cSopenharmony_ci  kShowDialog,
113370b324cSopenharmony_ci  kOverwrite,
114370b324cSopenharmony_ci
115370b324cSopenharmony_ci  kArchiveType,
116370b324cSopenharmony_ci  kExcludedArcType,
117370b324cSopenharmony_ci
118370b324cSopenharmony_ci  kProperty,
119370b324cSopenharmony_ci  kOutputDir,
120370b324cSopenharmony_ci  kWorkingDir,
121370b324cSopenharmony_ci
122370b324cSopenharmony_ci  kInclude,
123370b324cSopenharmony_ci  kExclude,
124370b324cSopenharmony_ci  kArInclude,
125370b324cSopenharmony_ci  kArExclude,
126370b324cSopenharmony_ci  kNoArName,
127370b324cSopenharmony_ci
128370b324cSopenharmony_ci  kUpdate,
129370b324cSopenharmony_ci  kVolume,
130370b324cSopenharmony_ci  kRecursed,
131370b324cSopenharmony_ci
132370b324cSopenharmony_ci  kAffinity,
133370b324cSopenharmony_ci  kSfx,
134370b324cSopenharmony_ci  kEmail,
135370b324cSopenharmony_ci  kHash,
136370b324cSopenharmony_ci  // kHashGenFile,
137370b324cSopenharmony_ci  kHashDir,
138370b324cSopenharmony_ci
139370b324cSopenharmony_ci  kStdIn,
140370b324cSopenharmony_ci  kStdOut,
141370b324cSopenharmony_ci
142370b324cSopenharmony_ci  kLargePages,
143370b324cSopenharmony_ci  kListfileCharSet,
144370b324cSopenharmony_ci  kConsoleCharSet,
145370b324cSopenharmony_ci  kTechMode,
146370b324cSopenharmony_ci  kListFields,
147370b324cSopenharmony_ci
148370b324cSopenharmony_ci  kPreserveATime,
149370b324cSopenharmony_ci  kShareForWrite,
150370b324cSopenharmony_ci  kStopAfterOpenError,
151370b324cSopenharmony_ci  kCaseSensitive,
152370b324cSopenharmony_ci  kArcNameMode,
153370b324cSopenharmony_ci
154370b324cSopenharmony_ci  kUseSlashMark,
155370b324cSopenharmony_ci  kDisableWildcardParsing,
156370b324cSopenharmony_ci  kElimDup,
157370b324cSopenharmony_ci  kFullPathMode,
158370b324cSopenharmony_ci
159370b324cSopenharmony_ci  kHardLinks,
160370b324cSopenharmony_ci  kSymLinks_AllowDangerous,
161370b324cSopenharmony_ci  kSymLinks,
162370b324cSopenharmony_ci  kNtSecurity,
163370b324cSopenharmony_ci
164370b324cSopenharmony_ci  kStoreOwnerId,
165370b324cSopenharmony_ci  kStoreOwnerName,
166370b324cSopenharmony_ci
167370b324cSopenharmony_ci  kZoneFile,
168370b324cSopenharmony_ci  kAltStreams,
169370b324cSopenharmony_ci  kReplaceColonForAltStream,
170370b324cSopenharmony_ci  kWriteToAltStreamIfColon,
171370b324cSopenharmony_ci
172370b324cSopenharmony_ci  kNameTrailReplace,
173370b324cSopenharmony_ci
174370b324cSopenharmony_ci  kDeleteAfterCompressing,
175370b324cSopenharmony_ci  kSetArcMTime
176370b324cSopenharmony_ci
177370b324cSopenharmony_ci  #ifndef Z7_NO_CRYPTO
178370b324cSopenharmony_ci  , kPassword
179370b324cSopenharmony_ci  #endif
180370b324cSopenharmony_ci};
181370b324cSopenharmony_ci
182370b324cSopenharmony_ci}
183370b324cSopenharmony_ci
184370b324cSopenharmony_ci
185370b324cSopenharmony_cistatic const wchar_t kRecursedIDChar = 'r';
186370b324cSopenharmony_cistatic const char * const kRecursedPostCharSet = "0-";
187370b324cSopenharmony_ci
188370b324cSopenharmony_cistatic const char * const k_ArcNameMode_PostCharSet = "sea";
189370b324cSopenharmony_ci
190370b324cSopenharmony_cistatic const char * const k_Stream_PostCharSet = "012";
191370b324cSopenharmony_ci
192370b324cSopenharmony_cistatic inline EArcNameMode ParseArcNameMode(int postCharIndex)
193370b324cSopenharmony_ci{
194370b324cSopenharmony_ci  switch (postCharIndex)
195370b324cSopenharmony_ci  {
196370b324cSopenharmony_ci    case 1: return k_ArcNameMode_Exact;
197370b324cSopenharmony_ci    case 2: return k_ArcNameMode_Add;
198370b324cSopenharmony_ci    default: return k_ArcNameMode_Smart;
199370b324cSopenharmony_ci  }
200370b324cSopenharmony_ci}
201370b324cSopenharmony_ci
202370b324cSopenharmony_cinamespace NRecursedPostCharIndex {
203370b324cSopenharmony_ci  enum EEnum
204370b324cSopenharmony_ci  {
205370b324cSopenharmony_ci    kWildcardRecursionOnly = 0,
206370b324cSopenharmony_ci    kNoRecursion = 1
207370b324cSopenharmony_ci  };
208370b324cSopenharmony_ci}
209370b324cSopenharmony_ci
210370b324cSopenharmony_ci// static const char
211370b324cSopenharmony_ci#define kImmediateNameID '!'
212370b324cSopenharmony_ci#ifdef _WIN32
213370b324cSopenharmony_ci#define kMapNameID '#'
214370b324cSopenharmony_ci#endif
215370b324cSopenharmony_ci#define kFileListID '@'
216370b324cSopenharmony_ci
217370b324cSopenharmony_cistatic const Byte kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
218370b324cSopenharmony_cistatic const Byte kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
219370b324cSopenharmony_ci
220370b324cSopenharmony_cistatic const char * const kOverwritePostCharSet = "asut";
221370b324cSopenharmony_ci
222370b324cSopenharmony_cistatic const NExtract::NOverwriteMode::EEnum k_OverwriteModes[] =
223370b324cSopenharmony_ci{
224370b324cSopenharmony_ci  NExtract::NOverwriteMode::kOverwrite,
225370b324cSopenharmony_ci  NExtract::NOverwriteMode::kSkip,
226370b324cSopenharmony_ci  NExtract::NOverwriteMode::kRename,
227370b324cSopenharmony_ci  NExtract::NOverwriteMode::kRenameExisting
228370b324cSopenharmony_ci};
229370b324cSopenharmony_ci
230370b324cSopenharmony_ci
231370b324cSopenharmony_ci
232370b324cSopenharmony_ci#define SWFRM_3(t, mu, mi) t, mu, mi, NULL
233370b324cSopenharmony_ci
234370b324cSopenharmony_ci#define SWFRM_1(t) SWFRM_3(t, false, 0)
235370b324cSopenharmony_ci#define SWFRM_SIMPLE SWFRM_1(NSwitchType::kSimple)
236370b324cSopenharmony_ci#define SWFRM_MINUS  SWFRM_1(NSwitchType::kMinus)
237370b324cSopenharmony_ci#define SWFRM_STRING SWFRM_1(NSwitchType::kString)
238370b324cSopenharmony_ci
239370b324cSopenharmony_ci#define SWFRM_STRING_SINGL(mi) SWFRM_3(NSwitchType::kString, false, mi)
240370b324cSopenharmony_ci#define SWFRM_STRING_MULT(mi)  SWFRM_3(NSwitchType::kString, true, mi)
241370b324cSopenharmony_ci
242370b324cSopenharmony_ci
243370b324cSopenharmony_cistatic const CSwitchForm kSwitchForms[] =
244370b324cSopenharmony_ci{
245370b324cSopenharmony_ci  { "?", SWFRM_SIMPLE },
246370b324cSopenharmony_ci  { "h", SWFRM_SIMPLE },
247370b324cSopenharmony_ci  { "-help", SWFRM_SIMPLE },
248370b324cSopenharmony_ci
249370b324cSopenharmony_ci  { "ba", SWFRM_SIMPLE },
250370b324cSopenharmony_ci  { "bd", SWFRM_SIMPLE },
251370b324cSopenharmony_ci  { "bt", SWFRM_SIMPLE },
252370b324cSopenharmony_ci  { "bb", SWFRM_STRING_SINGL(0) },
253370b324cSopenharmony_ci
254370b324cSopenharmony_ci  { "bso", NSwitchType::kChar, false, 1, k_Stream_PostCharSet },
255370b324cSopenharmony_ci  { "bse", NSwitchType::kChar, false, 1, k_Stream_PostCharSet },
256370b324cSopenharmony_ci  { "bsp", NSwitchType::kChar, false, 1, k_Stream_PostCharSet },
257370b324cSopenharmony_ci
258370b324cSopenharmony_ci  { "y", SWFRM_SIMPLE },
259370b324cSopenharmony_ci
260370b324cSopenharmony_ci  { "ad", SWFRM_SIMPLE },
261370b324cSopenharmony_ci  { "ao", NSwitchType::kChar, false, 1, kOverwritePostCharSet},
262370b324cSopenharmony_ci
263370b324cSopenharmony_ci  { "t",  SWFRM_STRING_SINGL(1) },
264370b324cSopenharmony_ci  { "stx", SWFRM_STRING_MULT(1) },
265370b324cSopenharmony_ci
266370b324cSopenharmony_ci  { "m",  SWFRM_STRING_MULT(1) },
267370b324cSopenharmony_ci  { "o",  SWFRM_STRING_SINGL(1) },
268370b324cSopenharmony_ci  { "w",  SWFRM_STRING },
269370b324cSopenharmony_ci
270370b324cSopenharmony_ci  { "i",  SWFRM_STRING_MULT(kSomeCludePostStringMinSize) },
271370b324cSopenharmony_ci  { "x",  SWFRM_STRING_MULT(kSomeCludePostStringMinSize) },
272370b324cSopenharmony_ci  { "ai", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) },
273370b324cSopenharmony_ci  { "ax", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) },
274370b324cSopenharmony_ci  { "an", SWFRM_SIMPLE },
275370b324cSopenharmony_ci
276370b324cSopenharmony_ci  { "u",  SWFRM_STRING_MULT(1) },
277370b324cSopenharmony_ci  { "v",  SWFRM_STRING_MULT(1) },
278370b324cSopenharmony_ci  { "r",  NSwitchType::kChar, false, 0, kRecursedPostCharSet },
279370b324cSopenharmony_ci
280370b324cSopenharmony_ci  { "stm", SWFRM_STRING },
281370b324cSopenharmony_ci  { "sfx", SWFRM_STRING },
282370b324cSopenharmony_ci  { "seml", SWFRM_STRING_SINGL(0) },
283370b324cSopenharmony_ci  { "scrc", SWFRM_STRING_MULT(0) },
284370b324cSopenharmony_ci  // { "scrf", SWFRM_STRING_SINGL(1) },
285370b324cSopenharmony_ci  { "shd", SWFRM_STRING_SINGL(1) },
286370b324cSopenharmony_ci
287370b324cSopenharmony_ci  { "si", SWFRM_STRING },
288370b324cSopenharmony_ci  { "so", SWFRM_SIMPLE },
289370b324cSopenharmony_ci
290370b324cSopenharmony_ci  { "slp", SWFRM_STRING },
291370b324cSopenharmony_ci  { "scs", SWFRM_STRING },
292370b324cSopenharmony_ci  { "scc", SWFRM_STRING },
293370b324cSopenharmony_ci  { "slt", SWFRM_SIMPLE },
294370b324cSopenharmony_ci  { "slf", SWFRM_STRING_SINGL(1) },
295370b324cSopenharmony_ci
296370b324cSopenharmony_ci  { "ssp", SWFRM_SIMPLE },
297370b324cSopenharmony_ci  { "ssw", SWFRM_SIMPLE },
298370b324cSopenharmony_ci  { "sse", SWFRM_SIMPLE },
299370b324cSopenharmony_ci  { "ssc", SWFRM_MINUS },
300370b324cSopenharmony_ci  { "sa",  NSwitchType::kChar, false, 1, k_ArcNameMode_PostCharSet },
301370b324cSopenharmony_ci
302370b324cSopenharmony_ci  { "spm", SWFRM_STRING_SINGL(0) },
303370b324cSopenharmony_ci  { "spd", SWFRM_SIMPLE },
304370b324cSopenharmony_ci  { "spe", SWFRM_MINUS },
305370b324cSopenharmony_ci  { "spf", SWFRM_STRING_SINGL(0) },
306370b324cSopenharmony_ci
307370b324cSopenharmony_ci  { "snh", SWFRM_MINUS },
308370b324cSopenharmony_ci  { "snld", SWFRM_MINUS },
309370b324cSopenharmony_ci  { "snl", SWFRM_MINUS },
310370b324cSopenharmony_ci  { "sni", SWFRM_SIMPLE },
311370b324cSopenharmony_ci
312370b324cSopenharmony_ci  { "snoi", SWFRM_MINUS },
313370b324cSopenharmony_ci  { "snon", SWFRM_MINUS },
314370b324cSopenharmony_ci
315370b324cSopenharmony_ci  { "snz", SWFRM_STRING_SINGL(0) },
316370b324cSopenharmony_ci  { "sns", SWFRM_MINUS },
317370b324cSopenharmony_ci  { "snr", SWFRM_SIMPLE },
318370b324cSopenharmony_ci  { "snc", SWFRM_SIMPLE },
319370b324cSopenharmony_ci
320370b324cSopenharmony_ci  { "snt", SWFRM_MINUS },
321370b324cSopenharmony_ci
322370b324cSopenharmony_ci  { "sdel", SWFRM_SIMPLE },
323370b324cSopenharmony_ci  { "stl", SWFRM_SIMPLE }
324370b324cSopenharmony_ci
325370b324cSopenharmony_ci  #ifndef Z7_NO_CRYPTO
326370b324cSopenharmony_ci  , { "p", SWFRM_STRING }
327370b324cSopenharmony_ci  #endif
328370b324cSopenharmony_ci};
329370b324cSopenharmony_ci
330370b324cSopenharmony_cistatic const char * const kUniversalWildcard = "*";
331370b324cSopenharmony_cistatic const unsigned kMinNonSwitchWords = 1;
332370b324cSopenharmony_cistatic const unsigned kCommandIndex = 0;
333370b324cSopenharmony_ci
334370b324cSopenharmony_ci// static const char * const kUserErrorMessage  = "Incorrect command line";
335370b324cSopenharmony_ci// static const char * const kCannotFindListFile = "Cannot find listfile";
336370b324cSopenharmony_cistatic const char * const kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch.";
337370b324cSopenharmony_cistatic const char * const kTerminalOutError = "I won't write compressed data to a terminal";
338370b324cSopenharmony_cistatic const char * const kSameTerminalError = "I won't write data and program's messages to same stream";
339370b324cSopenharmony_cistatic const char * const kEmptyFilePath = "Empty file path";
340370b324cSopenharmony_ci
341370b324cSopenharmony_cibool CArcCommand::IsFromExtractGroup() const
342370b324cSopenharmony_ci{
343370b324cSopenharmony_ci  switch ((int)CommandType)
344370b324cSopenharmony_ci  {
345370b324cSopenharmony_ci    case NCommandType::kTest:
346370b324cSopenharmony_ci    case NCommandType::kExtract:
347370b324cSopenharmony_ci    case NCommandType::kExtractFull:
348370b324cSopenharmony_ci      return true;
349370b324cSopenharmony_ci    default:
350370b324cSopenharmony_ci      return false;
351370b324cSopenharmony_ci  }
352370b324cSopenharmony_ci}
353370b324cSopenharmony_ci
354370b324cSopenharmony_ciNExtract::NPathMode::EEnum CArcCommand::GetPathMode() const
355370b324cSopenharmony_ci{
356370b324cSopenharmony_ci  switch ((int)CommandType)
357370b324cSopenharmony_ci  {
358370b324cSopenharmony_ci    case NCommandType::kTest:
359370b324cSopenharmony_ci    case NCommandType::kExtractFull:
360370b324cSopenharmony_ci      return NExtract::NPathMode::kFullPaths;
361370b324cSopenharmony_ci    default:
362370b324cSopenharmony_ci      return NExtract::NPathMode::kNoPaths;
363370b324cSopenharmony_ci  }
364370b324cSopenharmony_ci}
365370b324cSopenharmony_ci
366370b324cSopenharmony_cibool CArcCommand::IsFromUpdateGroup() const
367370b324cSopenharmony_ci{
368370b324cSopenharmony_ci  switch ((int)CommandType)
369370b324cSopenharmony_ci  {
370370b324cSopenharmony_ci    case NCommandType::kAdd:
371370b324cSopenharmony_ci    case NCommandType::kUpdate:
372370b324cSopenharmony_ci    case NCommandType::kDelete:
373370b324cSopenharmony_ci    case NCommandType::kRename:
374370b324cSopenharmony_ci      return true;
375370b324cSopenharmony_ci    default:
376370b324cSopenharmony_ci      return false;
377370b324cSopenharmony_ci  }
378370b324cSopenharmony_ci}
379370b324cSopenharmony_ci
380370b324cSopenharmony_cistatic NRecursedType::EEnum GetRecursedTypeFromIndex(int index)
381370b324cSopenharmony_ci{
382370b324cSopenharmony_ci  switch (index)
383370b324cSopenharmony_ci  {
384370b324cSopenharmony_ci    case NRecursedPostCharIndex::kWildcardRecursionOnly:
385370b324cSopenharmony_ci      return NRecursedType::kWildcardOnlyRecursed;
386370b324cSopenharmony_ci    case NRecursedPostCharIndex::kNoRecursion:
387370b324cSopenharmony_ci      return NRecursedType::kNonRecursed;
388370b324cSopenharmony_ci    default:
389370b324cSopenharmony_ci      return NRecursedType::kRecursed;
390370b324cSopenharmony_ci  }
391370b324cSopenharmony_ci}
392370b324cSopenharmony_ci
393370b324cSopenharmony_cistatic const char *g_Commands = "audtexlbih";
394370b324cSopenharmony_ci
395370b324cSopenharmony_cistatic bool ParseArchiveCommand(const UString &commandString, CArcCommand &command)
396370b324cSopenharmony_ci{
397370b324cSopenharmony_ci  UString s (commandString);
398370b324cSopenharmony_ci  s.MakeLower_Ascii();
399370b324cSopenharmony_ci  if (s.Len() == 1)
400370b324cSopenharmony_ci  {
401370b324cSopenharmony_ci    if (s[0] > 0x7F)
402370b324cSopenharmony_ci      return false;
403370b324cSopenharmony_ci    int index = FindCharPosInString(g_Commands, (char)s[0]);
404370b324cSopenharmony_ci    if (index < 0)
405370b324cSopenharmony_ci      return false;
406370b324cSopenharmony_ci    command.CommandType = (NCommandType::EEnum)index;
407370b324cSopenharmony_ci    return true;
408370b324cSopenharmony_ci  }
409370b324cSopenharmony_ci  if (s.Len() == 2 && s[0] == 'r' && s[1] == 'n')
410370b324cSopenharmony_ci  {
411370b324cSopenharmony_ci    command.CommandType = (NCommandType::kRename);
412370b324cSopenharmony_ci    return true;
413370b324cSopenharmony_ci  }
414370b324cSopenharmony_ci  return false;
415370b324cSopenharmony_ci}
416370b324cSopenharmony_ci
417370b324cSopenharmony_ci// ------------------------------------------------------------------
418370b324cSopenharmony_ci// filenames functions
419370b324cSopenharmony_ci
420370b324cSopenharmony_cistruct CNameOption
421370b324cSopenharmony_ci{
422370b324cSopenharmony_ci  bool Include;
423370b324cSopenharmony_ci  bool WildcardMatching;
424370b324cSopenharmony_ci  Byte MarkMode;
425370b324cSopenharmony_ci  NRecursedType::EEnum RecursedType;
426370b324cSopenharmony_ci
427370b324cSopenharmony_ci  CNameOption():
428370b324cSopenharmony_ci      Include(true),
429370b324cSopenharmony_ci      WildcardMatching(true),
430370b324cSopenharmony_ci      MarkMode(NWildcard::kMark_FileOrDir),
431370b324cSopenharmony_ci      RecursedType(NRecursedType::kNonRecursed)
432370b324cSopenharmony_ci      {}
433370b324cSopenharmony_ci};
434370b324cSopenharmony_ci
435370b324cSopenharmony_ci
436370b324cSopenharmony_cistatic void AddNameToCensor(NWildcard::CCensor &censor,
437370b324cSopenharmony_ci    const CNameOption &nop, const UString &name)
438370b324cSopenharmony_ci{
439370b324cSopenharmony_ci  bool recursed = false;
440370b324cSopenharmony_ci
441370b324cSopenharmony_ci  switch ((int)nop.RecursedType)
442370b324cSopenharmony_ci  {
443370b324cSopenharmony_ci    case NRecursedType::kWildcardOnlyRecursed:
444370b324cSopenharmony_ci      recursed = DoesNameContainWildcard(name);
445370b324cSopenharmony_ci      break;
446370b324cSopenharmony_ci    case NRecursedType::kRecursed:
447370b324cSopenharmony_ci      recursed = true;
448370b324cSopenharmony_ci      break;
449370b324cSopenharmony_ci    default:
450370b324cSopenharmony_ci      break;
451370b324cSopenharmony_ci  }
452370b324cSopenharmony_ci
453370b324cSopenharmony_ci  NWildcard::CCensorPathProps props;
454370b324cSopenharmony_ci  props.Recursive = recursed;
455370b324cSopenharmony_ci  props.WildcardMatching = nop.WildcardMatching;
456370b324cSopenharmony_ci  props.MarkMode = nop.MarkMode;
457370b324cSopenharmony_ci  censor.AddPreItem(nop.Include, name, props);
458370b324cSopenharmony_ci}
459370b324cSopenharmony_ci
460370b324cSopenharmony_cistatic void AddRenamePair(CObjectVector<CRenamePair> *renamePairs,
461370b324cSopenharmony_ci    const UString &oldName, const UString &newName, NRecursedType::EEnum type,
462370b324cSopenharmony_ci    bool wildcardMatching)
463370b324cSopenharmony_ci{
464370b324cSopenharmony_ci  CRenamePair &pair = renamePairs->AddNew();
465370b324cSopenharmony_ci  pair.OldName = oldName;
466370b324cSopenharmony_ci  pair.NewName = newName;
467370b324cSopenharmony_ci  pair.RecursedType = type;
468370b324cSopenharmony_ci  pair.WildcardParsing = wildcardMatching;
469370b324cSopenharmony_ci
470370b324cSopenharmony_ci  if (!pair.Prepare())
471370b324cSopenharmony_ci  {
472370b324cSopenharmony_ci    UString val;
473370b324cSopenharmony_ci    val += pair.OldName;
474370b324cSopenharmony_ci    val.Add_LF();
475370b324cSopenharmony_ci    val += pair.NewName;
476370b324cSopenharmony_ci    val.Add_LF();
477370b324cSopenharmony_ci    if (type == NRecursedType::kRecursed)
478370b324cSopenharmony_ci      val += "-r";
479370b324cSopenharmony_ci    else if (type == NRecursedType::kWildcardOnlyRecursed)
480370b324cSopenharmony_ci      val += "-r0";
481370b324cSopenharmony_ci    throw CArcCmdLineException("Unsupported rename command:", val);
482370b324cSopenharmony_ci  }
483370b324cSopenharmony_ci}
484370b324cSopenharmony_ci
485370b324cSopenharmony_cistatic void AddToCensorFromListFile(
486370b324cSopenharmony_ci    CObjectVector<CRenamePair> *renamePairs,
487370b324cSopenharmony_ci    NWildcard::CCensor &censor,
488370b324cSopenharmony_ci    const CNameOption &nop, LPCWSTR fileName, UInt32 codePage)
489370b324cSopenharmony_ci{
490370b324cSopenharmony_ci  UStringVector names;
491370b324cSopenharmony_ci  /*
492370b324cSopenharmony_ci  if (!NFind::DoesFileExist_FollowLink(us2fs(fileName)))
493370b324cSopenharmony_ci    throw CArcCmdLineException(kCannotFindListFile, fileName);
494370b324cSopenharmony_ci  */
495370b324cSopenharmony_ci  DWORD lastError = 0;
496370b324cSopenharmony_ci  if (!ReadNamesFromListFile2(us2fs(fileName), names, codePage, lastError))
497370b324cSopenharmony_ci  {
498370b324cSopenharmony_ci    if (lastError != 0)
499370b324cSopenharmony_ci    {
500370b324cSopenharmony_ci      UString m;
501370b324cSopenharmony_ci      m = "The file operation error for listfile";
502370b324cSopenharmony_ci      m.Add_LF();
503370b324cSopenharmony_ci      m += NError::MyFormatMessage(lastError);
504370b324cSopenharmony_ci      throw CArcCmdLineException(m, fileName);
505370b324cSopenharmony_ci    }
506370b324cSopenharmony_ci    throw CArcCmdLineException(kIncorrectListFile, fileName);
507370b324cSopenharmony_ci  }
508370b324cSopenharmony_ci  if (renamePairs)
509370b324cSopenharmony_ci  {
510370b324cSopenharmony_ci    if ((names.Size() & 1) != 0)
511370b324cSopenharmony_ci      throw CArcCmdLineException(kIncorrectListFile, fileName);
512370b324cSopenharmony_ci    for (unsigned i = 0; i < names.Size(); i += 2)
513370b324cSopenharmony_ci    {
514370b324cSopenharmony_ci      // change type !!!!
515370b324cSopenharmony_ci      AddRenamePair(renamePairs, names[i], names[i + 1], nop.RecursedType, nop.WildcardMatching);
516370b324cSopenharmony_ci    }
517370b324cSopenharmony_ci  }
518370b324cSopenharmony_ci  else
519370b324cSopenharmony_ci    FOR_VECTOR (i, names)
520370b324cSopenharmony_ci      AddNameToCensor(censor, nop, names[i]);
521370b324cSopenharmony_ci}
522370b324cSopenharmony_ci
523370b324cSopenharmony_cistatic void AddToCensorFromNonSwitchesStrings(
524370b324cSopenharmony_ci    CObjectVector<CRenamePair> *renamePairs,
525370b324cSopenharmony_ci    unsigned startIndex,
526370b324cSopenharmony_ci    NWildcard::CCensor &censor,
527370b324cSopenharmony_ci    const UStringVector &nonSwitchStrings,
528370b324cSopenharmony_ci    int stopSwitchIndex,
529370b324cSopenharmony_ci    const CNameOption &nop,
530370b324cSopenharmony_ci    bool thereAreSwitchIncludes, UInt32 codePage)
531370b324cSopenharmony_ci{
532370b324cSopenharmony_ci  // another default
533370b324cSopenharmony_ci  if ((renamePairs || nonSwitchStrings.Size() == startIndex) && !thereAreSwitchIncludes)
534370b324cSopenharmony_ci  {
535370b324cSopenharmony_ci    /* for rename command: -i switch sets the mask for archive item reading.
536370b324cSopenharmony_ci       if (thereAreSwitchIncludes), { we don't use UniversalWildcard. }
537370b324cSopenharmony_ci       also for non-rename command: we set UniversalWildcard, only if there are no nonSwitches. */
538370b324cSopenharmony_ci    // we use default fileds in (CNameOption) for UniversalWildcard.
539370b324cSopenharmony_ci    CNameOption nop2;
540370b324cSopenharmony_ci    // recursive mode is not important for UniversalWildcard (*)
541370b324cSopenharmony_ci    // nop2.RecursedType = nop.RecursedType; // we don't need it
542370b324cSopenharmony_ci    /*
543370b324cSopenharmony_ci    nop2.RecursedType = NRecursedType::kNonRecursed;
544370b324cSopenharmony_ci    nop2.Include = true;
545370b324cSopenharmony_ci    nop2.WildcardMatching = true;
546370b324cSopenharmony_ci    nop2.MarkMode = NWildcard::kMark_FileOrDir;
547370b324cSopenharmony_ci    */
548370b324cSopenharmony_ci    AddNameToCensor(censor, nop2, UString(kUniversalWildcard));
549370b324cSopenharmony_ci  }
550370b324cSopenharmony_ci
551370b324cSopenharmony_ci  int oldIndex = -1;
552370b324cSopenharmony_ci
553370b324cSopenharmony_ci  if (stopSwitchIndex < 0)
554370b324cSopenharmony_ci    stopSwitchIndex = (int)nonSwitchStrings.Size();
555370b324cSopenharmony_ci
556370b324cSopenharmony_ci  for (unsigned i = startIndex; i < nonSwitchStrings.Size(); i++)
557370b324cSopenharmony_ci  {
558370b324cSopenharmony_ci    const UString &s = nonSwitchStrings[i];
559370b324cSopenharmony_ci    if (s.IsEmpty())
560370b324cSopenharmony_ci      throw CArcCmdLineException(kEmptyFilePath);
561370b324cSopenharmony_ci    if (i < (unsigned)stopSwitchIndex && s[0] == kFileListID)
562370b324cSopenharmony_ci      AddToCensorFromListFile(renamePairs, censor, nop, s.Ptr(1), codePage);
563370b324cSopenharmony_ci    else if (renamePairs)
564370b324cSopenharmony_ci    {
565370b324cSopenharmony_ci      if (oldIndex == -1)
566370b324cSopenharmony_ci        oldIndex = (int)i;
567370b324cSopenharmony_ci      else
568370b324cSopenharmony_ci      {
569370b324cSopenharmony_ci        // NRecursedType::EEnum type is used for global wildcard (-i! switches)
570370b324cSopenharmony_ci        AddRenamePair(renamePairs, nonSwitchStrings[(unsigned)oldIndex], s, NRecursedType::kNonRecursed, nop.WildcardMatching);
571370b324cSopenharmony_ci        // AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, type);
572370b324cSopenharmony_ci        oldIndex = -1;
573370b324cSopenharmony_ci      }
574370b324cSopenharmony_ci    }
575370b324cSopenharmony_ci    else
576370b324cSopenharmony_ci      AddNameToCensor(censor, nop, s);
577370b324cSopenharmony_ci  }
578370b324cSopenharmony_ci
579370b324cSopenharmony_ci  if (oldIndex != -1)
580370b324cSopenharmony_ci  {
581370b324cSopenharmony_ci    throw CArcCmdLineException("There is no second file name for rename pair:", nonSwitchStrings[(unsigned)oldIndex]);
582370b324cSopenharmony_ci  }
583370b324cSopenharmony_ci}
584370b324cSopenharmony_ci
585370b324cSopenharmony_ci#ifdef _WIN32
586370b324cSopenharmony_ci
587370b324cSopenharmony_cistruct CEventSetEnd
588370b324cSopenharmony_ci{
589370b324cSopenharmony_ci  UString Name;
590370b324cSopenharmony_ci
591370b324cSopenharmony_ci  CEventSetEnd(const wchar_t *name): Name(name) {}
592370b324cSopenharmony_ci  ~CEventSetEnd()
593370b324cSopenharmony_ci  {
594370b324cSopenharmony_ci    NSynchronization::CManualResetEvent event;
595370b324cSopenharmony_ci    if (event.Open(EVENT_MODIFY_STATE, false, GetSystemString(Name)) == 0)
596370b324cSopenharmony_ci      event.Set();
597370b324cSopenharmony_ci  }
598370b324cSopenharmony_ci};
599370b324cSopenharmony_ci
600370b324cSopenharmony_cistatic const char * const k_IncorrectMapCommand = "Incorrect Map command";
601370b324cSopenharmony_ci
602370b324cSopenharmony_cistatic const char *ParseMapWithPaths(
603370b324cSopenharmony_ci    NWildcard::CCensor &censor,
604370b324cSopenharmony_ci    const UString &s2,
605370b324cSopenharmony_ci    const CNameOption &nop)
606370b324cSopenharmony_ci{
607370b324cSopenharmony_ci  UString s (s2);
608370b324cSopenharmony_ci  int pos = s.Find(L':');
609370b324cSopenharmony_ci  if (pos < 0)
610370b324cSopenharmony_ci    return k_IncorrectMapCommand;
611370b324cSopenharmony_ci  int pos2 = s.Find(L':', (unsigned)(pos + 1));
612370b324cSopenharmony_ci  if (pos2 < 0)
613370b324cSopenharmony_ci    return k_IncorrectMapCommand;
614370b324cSopenharmony_ci
615370b324cSopenharmony_ci  CEventSetEnd eventSetEnd((const wchar_t *)s + (unsigned)(pos2 + 1));
616370b324cSopenharmony_ci  s.DeleteFrom((unsigned)pos2);
617370b324cSopenharmony_ci  UInt32 size;
618370b324cSopenharmony_ci  if (!StringToUInt32(s.Ptr((unsigned)(pos + 1)), size)
619370b324cSopenharmony_ci      || size < sizeof(wchar_t)
620370b324cSopenharmony_ci      || size > ((UInt32)1 << 31)
621370b324cSopenharmony_ci      || size % sizeof(wchar_t) != 0)
622370b324cSopenharmony_ci    return "Unsupported Map data size";
623370b324cSopenharmony_ci
624370b324cSopenharmony_ci  s.DeleteFrom((unsigned)pos);
625370b324cSopenharmony_ci  CFileMapping map;
626370b324cSopenharmony_ci  if (map.Open(FILE_MAP_READ, GetSystemString(s)) != 0)
627370b324cSopenharmony_ci    return "Cannot open mapping";
628370b324cSopenharmony_ci  LPVOID data = map.Map(FILE_MAP_READ, 0, size);
629370b324cSopenharmony_ci  if (!data)
630370b324cSopenharmony_ci    return "MapViewOfFile error";
631370b324cSopenharmony_ci  CFileUnmapper unmapper(data);
632370b324cSopenharmony_ci
633370b324cSopenharmony_ci  UString name;
634370b324cSopenharmony_ci  const wchar_t *p = (const wchar_t *)data;
635370b324cSopenharmony_ci  if (*p != 0) // data format marker
636370b324cSopenharmony_ci    return "Unsupported Map data";
637370b324cSopenharmony_ci  UInt32 numChars = size / sizeof(wchar_t);
638370b324cSopenharmony_ci  for (UInt32 i = 1; i < numChars; i++)
639370b324cSopenharmony_ci  {
640370b324cSopenharmony_ci    wchar_t c = p[i];
641370b324cSopenharmony_ci    if (c == 0)
642370b324cSopenharmony_ci    {
643370b324cSopenharmony_ci      // MessageBoxW(0, name, L"7-Zip", 0);
644370b324cSopenharmony_ci      AddNameToCensor(censor, nop, name);
645370b324cSopenharmony_ci      name.Empty();
646370b324cSopenharmony_ci    }
647370b324cSopenharmony_ci    else
648370b324cSopenharmony_ci      name += c;
649370b324cSopenharmony_ci  }
650370b324cSopenharmony_ci  if (!name.IsEmpty())
651370b324cSopenharmony_ci    return "Map data error";
652370b324cSopenharmony_ci
653370b324cSopenharmony_ci  return NULL;
654370b324cSopenharmony_ci}
655370b324cSopenharmony_ci
656370b324cSopenharmony_ci#endif
657370b324cSopenharmony_ci
658370b324cSopenharmony_cistatic void AddSwitchWildcardsToCensor(
659370b324cSopenharmony_ci    NWildcard::CCensor &censor,
660370b324cSopenharmony_ci    const UStringVector &strings,
661370b324cSopenharmony_ci    const CNameOption &nop,
662370b324cSopenharmony_ci    UInt32 codePage)
663370b324cSopenharmony_ci{
664370b324cSopenharmony_ci  const char *errorMessage = NULL;
665370b324cSopenharmony_ci  unsigned i;
666370b324cSopenharmony_ci  for (i = 0; i < strings.Size(); i++)
667370b324cSopenharmony_ci  {
668370b324cSopenharmony_ci    const UString &name = strings[i];
669370b324cSopenharmony_ci    unsigned pos = 0;
670370b324cSopenharmony_ci
671370b324cSopenharmony_ci    if (name.Len() < kSomeCludePostStringMinSize)
672370b324cSopenharmony_ci    {
673370b324cSopenharmony_ci      errorMessage = "Too short switch";
674370b324cSopenharmony_ci      break;
675370b324cSopenharmony_ci    }
676370b324cSopenharmony_ci
677370b324cSopenharmony_ci    if (!nop.Include)
678370b324cSopenharmony_ci    {
679370b324cSopenharmony_ci      if (name.IsEqualTo_Ascii_NoCase("td"))
680370b324cSopenharmony_ci      {
681370b324cSopenharmony_ci        censor.ExcludeDirItems = true;
682370b324cSopenharmony_ci        continue;
683370b324cSopenharmony_ci      }
684370b324cSopenharmony_ci      if (name.IsEqualTo_Ascii_NoCase("tf"))
685370b324cSopenharmony_ci      {
686370b324cSopenharmony_ci        censor.ExcludeFileItems = true;
687370b324cSopenharmony_ci        continue;
688370b324cSopenharmony_ci      }
689370b324cSopenharmony_ci    }
690370b324cSopenharmony_ci
691370b324cSopenharmony_ci    CNameOption nop2 = nop;
692370b324cSopenharmony_ci
693370b324cSopenharmony_ci    bool type_WasUsed = false;
694370b324cSopenharmony_ci    bool recursed_WasUsed = false;
695370b324cSopenharmony_ci    bool matching_WasUsed = false;
696370b324cSopenharmony_ci    bool error = false;
697370b324cSopenharmony_ci
698370b324cSopenharmony_ci    for (;;)
699370b324cSopenharmony_ci    {
700370b324cSopenharmony_ci      wchar_t c = ::MyCharLower_Ascii(name[pos]);
701370b324cSopenharmony_ci      if (c == kRecursedIDChar)
702370b324cSopenharmony_ci      {
703370b324cSopenharmony_ci        if (recursed_WasUsed)
704370b324cSopenharmony_ci        {
705370b324cSopenharmony_ci          error = true;
706370b324cSopenharmony_ci          break;
707370b324cSopenharmony_ci        }
708370b324cSopenharmony_ci        recursed_WasUsed = true;
709370b324cSopenharmony_ci        pos++;
710370b324cSopenharmony_ci        c = name[pos];
711370b324cSopenharmony_ci        int index = -1;
712370b324cSopenharmony_ci        if (c <= 0x7F)
713370b324cSopenharmony_ci          index = FindCharPosInString(kRecursedPostCharSet, (char)c);
714370b324cSopenharmony_ci        nop2.RecursedType = GetRecursedTypeFromIndex(index);
715370b324cSopenharmony_ci        if (index >= 0)
716370b324cSopenharmony_ci        {
717370b324cSopenharmony_ci          pos++;
718370b324cSopenharmony_ci          continue;
719370b324cSopenharmony_ci        }
720370b324cSopenharmony_ci      }
721370b324cSopenharmony_ci
722370b324cSopenharmony_ci      if (c == 'w')
723370b324cSopenharmony_ci      {
724370b324cSopenharmony_ci        if (matching_WasUsed)
725370b324cSopenharmony_ci        {
726370b324cSopenharmony_ci          error = true;
727370b324cSopenharmony_ci          break;
728370b324cSopenharmony_ci        }
729370b324cSopenharmony_ci        matching_WasUsed = true;
730370b324cSopenharmony_ci        nop2.WildcardMatching = true;
731370b324cSopenharmony_ci        pos++;
732370b324cSopenharmony_ci        if (name[pos] == '-')
733370b324cSopenharmony_ci        {
734370b324cSopenharmony_ci          nop2.WildcardMatching = false;
735370b324cSopenharmony_ci          pos++;
736370b324cSopenharmony_ci        }
737370b324cSopenharmony_ci      }
738370b324cSopenharmony_ci      else if (c == 'm')
739370b324cSopenharmony_ci      {
740370b324cSopenharmony_ci        if (type_WasUsed)
741370b324cSopenharmony_ci        {
742370b324cSopenharmony_ci          error = true;
743370b324cSopenharmony_ci          break;
744370b324cSopenharmony_ci        }
745370b324cSopenharmony_ci        type_WasUsed = true;
746370b324cSopenharmony_ci        pos++;
747370b324cSopenharmony_ci        nop2.MarkMode = NWildcard::kMark_StrictFile;
748370b324cSopenharmony_ci        c = name[pos];
749370b324cSopenharmony_ci        if (c == '-')
750370b324cSopenharmony_ci        {
751370b324cSopenharmony_ci          nop2.MarkMode = NWildcard::kMark_FileOrDir;
752370b324cSopenharmony_ci          pos++;
753370b324cSopenharmony_ci        }
754370b324cSopenharmony_ci        else if (c == '2')
755370b324cSopenharmony_ci        {
756370b324cSopenharmony_ci          nop2.MarkMode = NWildcard::kMark_StrictFile_IfWildcard;
757370b324cSopenharmony_ci          pos++;
758370b324cSopenharmony_ci        }
759370b324cSopenharmony_ci      }
760370b324cSopenharmony_ci      else
761370b324cSopenharmony_ci        break;
762370b324cSopenharmony_ci    }
763370b324cSopenharmony_ci
764370b324cSopenharmony_ci    if (error)
765370b324cSopenharmony_ci    {
766370b324cSopenharmony_ci      errorMessage = "inorrect switch";
767370b324cSopenharmony_ci      break;
768370b324cSopenharmony_ci    }
769370b324cSopenharmony_ci
770370b324cSopenharmony_ci    if (name.Len() < pos + kSomeCludeAfterRecursedPostStringMinSize)
771370b324cSopenharmony_ci    {
772370b324cSopenharmony_ci      errorMessage = "Too short switch";
773370b324cSopenharmony_ci      break;
774370b324cSopenharmony_ci    }
775370b324cSopenharmony_ci
776370b324cSopenharmony_ci    const UString tail = name.Ptr(pos + 1);
777370b324cSopenharmony_ci
778370b324cSopenharmony_ci    const wchar_t c = name[pos];
779370b324cSopenharmony_ci
780370b324cSopenharmony_ci    if (c == kImmediateNameID)
781370b324cSopenharmony_ci      AddNameToCensor(censor, nop2, tail);
782370b324cSopenharmony_ci    else if (c == kFileListID)
783370b324cSopenharmony_ci      AddToCensorFromListFile(NULL, censor, nop2, tail, codePage);
784370b324cSopenharmony_ci    #ifdef _WIN32
785370b324cSopenharmony_ci    else if (c == kMapNameID)
786370b324cSopenharmony_ci    {
787370b324cSopenharmony_ci      errorMessage = ParseMapWithPaths(censor, tail, nop2);
788370b324cSopenharmony_ci      if (errorMessage)
789370b324cSopenharmony_ci        break;
790370b324cSopenharmony_ci    }
791370b324cSopenharmony_ci    #endif
792370b324cSopenharmony_ci    else
793370b324cSopenharmony_ci    {
794370b324cSopenharmony_ci      errorMessage = "Incorrect wildcard type marker";
795370b324cSopenharmony_ci      break;
796370b324cSopenharmony_ci    }
797370b324cSopenharmony_ci  }
798370b324cSopenharmony_ci
799370b324cSopenharmony_ci  if (i != strings.Size())
800370b324cSopenharmony_ci    throw CArcCmdLineException(errorMessage, strings[i]);
801370b324cSopenharmony_ci}
802370b324cSopenharmony_ci
803370b324cSopenharmony_ci/*
804370b324cSopenharmony_cistatic NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
805370b324cSopenharmony_ci{
806370b324cSopenharmony_ci  switch (i)
807370b324cSopenharmony_ci  {
808370b324cSopenharmony_ci    case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore;
809370b324cSopenharmony_ci    case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy;
810370b324cSopenharmony_ci    case NUpdateArchive::NPairAction::kCompress: return NUpdateArchive::NPairAction::kCompress;
811370b324cSopenharmony_ci    case NUpdateArchive::NPairAction::kCompressAsAnti: return NUpdateArchive::NPairAction::kCompressAsAnti;
812370b324cSopenharmony_ci  }
813370b324cSopenharmony_ci  throw 98111603;
814370b324cSopenharmony_ci}
815370b324cSopenharmony_ci*/
816370b324cSopenharmony_ci
817370b324cSopenharmony_cistatic const char * const kUpdatePairStateIDSet = "pqrxyzw";
818370b324cSopenharmony_cistatic const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};
819370b324cSopenharmony_ci
820370b324cSopenharmony_cistatic const unsigned kNumUpdatePairActions = 4;
821370b324cSopenharmony_cistatic const char * const kUpdateIgnoreItselfPostStringID = "-";
822370b324cSopenharmony_cistatic const wchar_t kUpdateNewArchivePostCharID = '!';
823370b324cSopenharmony_ci
824370b324cSopenharmony_ci
825370b324cSopenharmony_cistatic bool ParseUpdateCommandString2(const UString &command,
826370b324cSopenharmony_ci    NUpdateArchive::CActionSet &actionSet, UString &postString)
827370b324cSopenharmony_ci{
828370b324cSopenharmony_ci  for (unsigned i = 0; i < command.Len();)
829370b324cSopenharmony_ci  {
830370b324cSopenharmony_ci    wchar_t c = MyCharLower_Ascii(command[i]);
831370b324cSopenharmony_ci    int statePos = FindCharPosInString(kUpdatePairStateIDSet, (char)c);
832370b324cSopenharmony_ci    if (c > 0x7F || statePos < 0)
833370b324cSopenharmony_ci    {
834370b324cSopenharmony_ci      postString = command.Ptr(i);
835370b324cSopenharmony_ci      return true;
836370b324cSopenharmony_ci    }
837370b324cSopenharmony_ci    i++;
838370b324cSopenharmony_ci    if (i >= command.Len())
839370b324cSopenharmony_ci      return false;
840370b324cSopenharmony_ci    c = command[i];
841370b324cSopenharmony_ci    if (c < '0' || c >= (wchar_t)('0' + kNumUpdatePairActions))
842370b324cSopenharmony_ci      return false;
843370b324cSopenharmony_ci    unsigned actionPos = (unsigned)(c - '0');
844370b324cSopenharmony_ci    actionSet.StateActions[(unsigned)statePos] = (NUpdateArchive::NPairAction::EEnum)(actionPos);
845370b324cSopenharmony_ci    if (kUpdatePairStateNotSupportedActions[(unsigned)statePos] == (int)actionPos)
846370b324cSopenharmony_ci      return false;
847370b324cSopenharmony_ci    i++;
848370b324cSopenharmony_ci  }
849370b324cSopenharmony_ci  postString.Empty();
850370b324cSopenharmony_ci  return true;
851370b324cSopenharmony_ci}
852370b324cSopenharmony_ci
853370b324cSopenharmony_cistatic void ParseUpdateCommandString(CUpdateOptions &options,
854370b324cSopenharmony_ci    const UStringVector &updatePostStrings,
855370b324cSopenharmony_ci    const NUpdateArchive::CActionSet &defaultActionSet)
856370b324cSopenharmony_ci{
857370b324cSopenharmony_ci  const char *errorMessage = "incorrect update switch command";
858370b324cSopenharmony_ci  unsigned i;
859370b324cSopenharmony_ci  for (i = 0; i < updatePostStrings.Size(); i++)
860370b324cSopenharmony_ci  {
861370b324cSopenharmony_ci    const UString &updateString = updatePostStrings[i];
862370b324cSopenharmony_ci    if (updateString.IsEqualTo(kUpdateIgnoreItselfPostStringID))
863370b324cSopenharmony_ci    {
864370b324cSopenharmony_ci      if (options.UpdateArchiveItself)
865370b324cSopenharmony_ci      {
866370b324cSopenharmony_ci        options.UpdateArchiveItself = false;
867370b324cSopenharmony_ci        options.Commands.Delete(0);
868370b324cSopenharmony_ci      }
869370b324cSopenharmony_ci    }
870370b324cSopenharmony_ci    else
871370b324cSopenharmony_ci    {
872370b324cSopenharmony_ci      NUpdateArchive::CActionSet actionSet = defaultActionSet;
873370b324cSopenharmony_ci
874370b324cSopenharmony_ci      UString postString;
875370b324cSopenharmony_ci      if (!ParseUpdateCommandString2(updateString, actionSet, postString))
876370b324cSopenharmony_ci        break;
877370b324cSopenharmony_ci      if (postString.IsEmpty())
878370b324cSopenharmony_ci      {
879370b324cSopenharmony_ci        if (options.UpdateArchiveItself)
880370b324cSopenharmony_ci          options.Commands[0].ActionSet = actionSet;
881370b324cSopenharmony_ci      }
882370b324cSopenharmony_ci      else
883370b324cSopenharmony_ci      {
884370b324cSopenharmony_ci        if (postString[0] != kUpdateNewArchivePostCharID)
885370b324cSopenharmony_ci          break;
886370b324cSopenharmony_ci        CUpdateArchiveCommand uc;
887370b324cSopenharmony_ci        UString archivePath = postString.Ptr(1);
888370b324cSopenharmony_ci        if (archivePath.IsEmpty())
889370b324cSopenharmony_ci          break;
890370b324cSopenharmony_ci        uc.UserArchivePath = archivePath;
891370b324cSopenharmony_ci        uc.ActionSet = actionSet;
892370b324cSopenharmony_ci        options.Commands.Add(uc);
893370b324cSopenharmony_ci      }
894370b324cSopenharmony_ci    }
895370b324cSopenharmony_ci  }
896370b324cSopenharmony_ci  if (i != updatePostStrings.Size())
897370b324cSopenharmony_ci    throw CArcCmdLineException(errorMessage, updatePostStrings[i]);
898370b324cSopenharmony_ci}
899370b324cSopenharmony_ci
900370b324cSopenharmony_cibool ParseComplexSize(const wchar_t *s, UInt64 &result);
901370b324cSopenharmony_ci
902370b324cSopenharmony_cistatic void SetAddCommandOptions(
903370b324cSopenharmony_ci    NCommandType::EEnum commandType,
904370b324cSopenharmony_ci    const CParser &parser,
905370b324cSopenharmony_ci    CUpdateOptions &options)
906370b324cSopenharmony_ci{
907370b324cSopenharmony_ci  NUpdateArchive::CActionSet defaultActionSet;
908370b324cSopenharmony_ci  switch ((int)commandType)
909370b324cSopenharmony_ci  {
910370b324cSopenharmony_ci    case NCommandType::kAdd:
911370b324cSopenharmony_ci      defaultActionSet = NUpdateArchive::k_ActionSet_Add;
912370b324cSopenharmony_ci      break;
913370b324cSopenharmony_ci    case NCommandType::kDelete:
914370b324cSopenharmony_ci      defaultActionSet = NUpdateArchive::k_ActionSet_Delete;
915370b324cSopenharmony_ci      break;
916370b324cSopenharmony_ci    default:
917370b324cSopenharmony_ci      defaultActionSet = NUpdateArchive::k_ActionSet_Update;
918370b324cSopenharmony_ci  }
919370b324cSopenharmony_ci
920370b324cSopenharmony_ci  options.UpdateArchiveItself = true;
921370b324cSopenharmony_ci
922370b324cSopenharmony_ci  options.Commands.Clear();
923370b324cSopenharmony_ci  CUpdateArchiveCommand updateMainCommand;
924370b324cSopenharmony_ci  updateMainCommand.ActionSet = defaultActionSet;
925370b324cSopenharmony_ci  options.Commands.Add(updateMainCommand);
926370b324cSopenharmony_ci  if (parser[NKey::kUpdate].ThereIs)
927370b324cSopenharmony_ci    ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings,
928370b324cSopenharmony_ci        defaultActionSet);
929370b324cSopenharmony_ci  if (parser[NKey::kWorkingDir].ThereIs)
930370b324cSopenharmony_ci  {
931370b324cSopenharmony_ci    const UString &postString = parser[NKey::kWorkingDir].PostStrings[0];
932370b324cSopenharmony_ci    if (postString.IsEmpty())
933370b324cSopenharmony_ci      NDir::MyGetTempPath(options.WorkingDir);
934370b324cSopenharmony_ci    else
935370b324cSopenharmony_ci      options.WorkingDir = us2fs(postString);
936370b324cSopenharmony_ci  }
937370b324cSopenharmony_ci  options.SfxMode = parser[NKey::kSfx].ThereIs;
938370b324cSopenharmony_ci  if (options.SfxMode)
939370b324cSopenharmony_ci    options.SfxModule = us2fs(parser[NKey::kSfx].PostStrings[0]);
940370b324cSopenharmony_ci
941370b324cSopenharmony_ci  if (parser[NKey::kVolume].ThereIs)
942370b324cSopenharmony_ci  {
943370b324cSopenharmony_ci    const UStringVector &sv = parser[NKey::kVolume].PostStrings;
944370b324cSopenharmony_ci    FOR_VECTOR (i, sv)
945370b324cSopenharmony_ci    {
946370b324cSopenharmony_ci      UInt64 size;
947370b324cSopenharmony_ci      if (!ParseComplexSize(sv[i], size))
948370b324cSopenharmony_ci        throw CArcCmdLineException("Incorrect volume size:", sv[i]);
949370b324cSopenharmony_ci      if (i == sv.Size() - 1 && size == 0)
950370b324cSopenharmony_ci        throw CArcCmdLineException("zero size last volume is not allowed");
951370b324cSopenharmony_ci      options.VolumesSizes.Add(size);
952370b324cSopenharmony_ci    }
953370b324cSopenharmony_ci  }
954370b324cSopenharmony_ci}
955370b324cSopenharmony_ci
956370b324cSopenharmony_cistatic void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &properties)
957370b324cSopenharmony_ci{
958370b324cSopenharmony_ci  if (parser[NKey::kProperty].ThereIs)
959370b324cSopenharmony_ci  {
960370b324cSopenharmony_ci    FOR_VECTOR (i, parser[NKey::kProperty].PostStrings)
961370b324cSopenharmony_ci    {
962370b324cSopenharmony_ci      CProperty prop;
963370b324cSopenharmony_ci      prop.Name = parser[NKey::kProperty].PostStrings[i];
964370b324cSopenharmony_ci      int index = prop.Name.Find(L'=');
965370b324cSopenharmony_ci      if (index >= 0)
966370b324cSopenharmony_ci      {
967370b324cSopenharmony_ci        prop.Value = prop.Name.Ptr((unsigned)(index + 1));
968370b324cSopenharmony_ci        prop.Name.DeleteFrom((unsigned)index);
969370b324cSopenharmony_ci      }
970370b324cSopenharmony_ci      properties.Add(prop);
971370b324cSopenharmony_ci    }
972370b324cSopenharmony_ci  }
973370b324cSopenharmony_ci}
974370b324cSopenharmony_ci
975370b324cSopenharmony_ci
976370b324cSopenharmony_cistatic inline void SetStreamMode(const CSwitchResult &sw, unsigned &res)
977370b324cSopenharmony_ci{
978370b324cSopenharmony_ci  if (sw.ThereIs)
979370b324cSopenharmony_ci    res = (unsigned)sw.PostCharIndex;
980370b324cSopenharmony_ci}
981370b324cSopenharmony_ci
982370b324cSopenharmony_ci
983370b324cSopenharmony_ci#if defined(_WIN32) && !defined(UNDER_CE)
984370b324cSopenharmony_cistatic void PrintHex(UString &s, UInt64 v)
985370b324cSopenharmony_ci{
986370b324cSopenharmony_ci  char temp[32];
987370b324cSopenharmony_ci  ConvertUInt64ToHex(v, temp);
988370b324cSopenharmony_ci  s += temp;
989370b324cSopenharmony_ci}
990370b324cSopenharmony_ci#endif
991370b324cSopenharmony_ci
992370b324cSopenharmony_ci
993370b324cSopenharmony_civoid CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
994370b324cSopenharmony_ci    CArcCmdLineOptions &options)
995370b324cSopenharmony_ci{
996370b324cSopenharmony_ci  Parse1Log.Empty();
997370b324cSopenharmony_ci  if (!parser.ParseStrings(kSwitchForms, Z7_ARRAY_SIZE(kSwitchForms), commandStrings))
998370b324cSopenharmony_ci    throw CArcCmdLineException(parser.ErrorMessage, parser.ErrorLine);
999370b324cSopenharmony_ci
1000370b324cSopenharmony_ci  options.IsInTerminal = MY_IS_TERMINAL(stdin);
1001370b324cSopenharmony_ci  options.IsStdOutTerminal = MY_IS_TERMINAL(stdout);
1002370b324cSopenharmony_ci  options.IsStdErrTerminal = MY_IS_TERMINAL(stderr);
1003370b324cSopenharmony_ci
1004370b324cSopenharmony_ci  options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs  || parser[NKey::kHelp3].ThereIs;
1005370b324cSopenharmony_ci
1006370b324cSopenharmony_ci  options.StdInMode = parser[NKey::kStdIn].ThereIs;
1007370b324cSopenharmony_ci  options.StdOutMode = parser[NKey::kStdOut].ThereIs;
1008370b324cSopenharmony_ci  options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs;
1009370b324cSopenharmony_ci  if (parser[NKey::kListFields].ThereIs)
1010370b324cSopenharmony_ci  {
1011370b324cSopenharmony_ci    const UString &s = parser[NKey::kListFields].PostStrings[0];
1012370b324cSopenharmony_ci    options.ListFields = GetAnsiString(s);
1013370b324cSopenharmony_ci  }
1014370b324cSopenharmony_ci  options.TechMode = parser[NKey::kTechMode].ThereIs;
1015370b324cSopenharmony_ci  options.ShowTime = parser[NKey::kShowTime].ThereIs;
1016370b324cSopenharmony_ci
1017370b324cSopenharmony_ci  if (parser[NKey::kDisablePercents].ThereIs
1018370b324cSopenharmony_ci      || options.StdOutMode
1019370b324cSopenharmony_ci      || !options.IsStdOutTerminal)
1020370b324cSopenharmony_ci    options.Number_for_Percents = k_OutStream_disabled;
1021370b324cSopenharmony_ci
1022370b324cSopenharmony_ci  if (options.StdOutMode)
1023370b324cSopenharmony_ci    options.Number_for_Out = k_OutStream_disabled;
1024370b324cSopenharmony_ci
1025370b324cSopenharmony_ci  SetStreamMode(parser[NKey::kOutStream], options.Number_for_Out);
1026370b324cSopenharmony_ci  SetStreamMode(parser[NKey::kErrStream], options.Number_for_Errors);
1027370b324cSopenharmony_ci  SetStreamMode(parser[NKey::kPercentStream], options.Number_for_Percents);
1028370b324cSopenharmony_ci
1029370b324cSopenharmony_ci  if (parser[NKey::kLogLevel].ThereIs)
1030370b324cSopenharmony_ci  {
1031370b324cSopenharmony_ci    const UString &s = parser[NKey::kLogLevel].PostStrings[0];
1032370b324cSopenharmony_ci    if (s.IsEmpty())
1033370b324cSopenharmony_ci      options.LogLevel = 1;
1034370b324cSopenharmony_ci    else
1035370b324cSopenharmony_ci    {
1036370b324cSopenharmony_ci      UInt32 v;
1037370b324cSopenharmony_ci      if (!StringToUInt32(s, v))
1038370b324cSopenharmony_ci        throw CArcCmdLineException("Unsupported switch postfix -bb", s);
1039370b324cSopenharmony_ci      options.LogLevel = (unsigned)v;
1040370b324cSopenharmony_ci    }
1041370b324cSopenharmony_ci  }
1042370b324cSopenharmony_ci
1043370b324cSopenharmony_ci  if (parser[NKey::kCaseSensitive].ThereIs)
1044370b324cSopenharmony_ci  {
1045370b324cSopenharmony_ci    options.CaseSensitive =
1046370b324cSopenharmony_ci    g_CaseSensitive = !parser[NKey::kCaseSensitive].WithMinus;
1047370b324cSopenharmony_ci    options.CaseSensitive_Change = true;
1048370b324cSopenharmony_ci  }
1049370b324cSopenharmony_ci
1050370b324cSopenharmony_ci
1051370b324cSopenharmony_ci  #if defined(_WIN32) && !defined(UNDER_CE)
1052370b324cSopenharmony_ci  NSecurity::EnablePrivilege_SymLink();
1053370b324cSopenharmony_ci  #endif
1054370b324cSopenharmony_ci
1055370b324cSopenharmony_ci  // options.LargePages = false;
1056370b324cSopenharmony_ci
1057370b324cSopenharmony_ci  if (parser[NKey::kLargePages].ThereIs)
1058370b324cSopenharmony_ci  {
1059370b324cSopenharmony_ci    UInt32 slp = 0;
1060370b324cSopenharmony_ci    const UString &s = parser[NKey::kLargePages].PostStrings[0];
1061370b324cSopenharmony_ci    if (s.IsEmpty())
1062370b324cSopenharmony_ci      slp = 1;
1063370b324cSopenharmony_ci    else if (s != L"-")
1064370b324cSopenharmony_ci    {
1065370b324cSopenharmony_ci      if (!StringToUInt32(s, slp))
1066370b324cSopenharmony_ci        throw CArcCmdLineException("Unsupported switch postfix for -slp", s);
1067370b324cSopenharmony_ci    }
1068370b324cSopenharmony_ci
1069370b324cSopenharmony_ci    #ifdef Z7_LARGE_PAGES
1070370b324cSopenharmony_ci    if (slp >
1071370b324cSopenharmony_ci          #if defined(_WIN32) && !defined(UNDER_CE)
1072370b324cSopenharmony_ci            (unsigned)NSecurity::Get_LargePages_RiskLevel()
1073370b324cSopenharmony_ci          #else
1074370b324cSopenharmony_ci            0
1075370b324cSopenharmony_ci          #endif
1076370b324cSopenharmony_ci        )
1077370b324cSopenharmony_ci    {
1078370b324cSopenharmony_ci      #ifdef _WIN32 // change it !
1079370b324cSopenharmony_ci      SetLargePageSize();
1080370b324cSopenharmony_ci      #endif
1081370b324cSopenharmony_ci      // note: this process also can inherit that Privilege from parent process
1082370b324cSopenharmony_ci      g_LargePagesMode =
1083370b324cSopenharmony_ci      #if defined(_WIN32) && !defined(UNDER_CE)
1084370b324cSopenharmony_ci        NSecurity::EnablePrivilege_LockMemory();
1085370b324cSopenharmony_ci      #else
1086370b324cSopenharmony_ci        true;
1087370b324cSopenharmony_ci      #endif
1088370b324cSopenharmony_ci    }
1089370b324cSopenharmony_ci    #endif
1090370b324cSopenharmony_ci  }
1091370b324cSopenharmony_ci
1092370b324cSopenharmony_ci
1093370b324cSopenharmony_ci  #ifndef UNDER_CE
1094370b324cSopenharmony_ci
1095370b324cSopenharmony_ci  if (parser[NKey::kAffinity].ThereIs)
1096370b324cSopenharmony_ci  {
1097370b324cSopenharmony_ci    const UString &s = parser[NKey::kAffinity].PostStrings[0];
1098370b324cSopenharmony_ci    if (!s.IsEmpty())
1099370b324cSopenharmony_ci    {
1100370b324cSopenharmony_ci      AString a;
1101370b324cSopenharmony_ci      a.SetFromWStr_if_Ascii(s);
1102370b324cSopenharmony_ci      Parse1Log += "Set process affinity mask: ";
1103370b324cSopenharmony_ci
1104370b324cSopenharmony_ci      #ifdef _WIN32
1105370b324cSopenharmony_ci
1106370b324cSopenharmony_ci      UInt64 v = 0;
1107370b324cSopenharmony_ci      {
1108370b324cSopenharmony_ci        const char *end;
1109370b324cSopenharmony_ci        v = ConvertHexStringToUInt64(a, &end);
1110370b324cSopenharmony_ci        if (*end != 0)
1111370b324cSopenharmony_ci          a.Empty();
1112370b324cSopenharmony_ci      }
1113370b324cSopenharmony_ci      if (a.IsEmpty())
1114370b324cSopenharmony_ci        throw CArcCmdLineException("Unsupported switch postfix -stm", s);
1115370b324cSopenharmony_ci
1116370b324cSopenharmony_ci      {
1117370b324cSopenharmony_ci        #ifndef _WIN64
1118370b324cSopenharmony_ci        if (v >= ((UInt64)1 << 32))
1119370b324cSopenharmony_ci          throw CArcCmdLineException("unsupported value -stm", s);
1120370b324cSopenharmony_ci        #endif
1121370b324cSopenharmony_ci        {
1122370b324cSopenharmony_ci          PrintHex(Parse1Log, v);
1123370b324cSopenharmony_ci          if (!SetProcessAffinityMask(GetCurrentProcess(), (DWORD_PTR)v))
1124370b324cSopenharmony_ci          {
1125370b324cSopenharmony_ci            DWORD lastError = GetLastError();
1126370b324cSopenharmony_ci            Parse1Log += " : ERROR : ";
1127370b324cSopenharmony_ci            Parse1Log += NError::MyFormatMessage(lastError);
1128370b324cSopenharmony_ci          }
1129370b324cSopenharmony_ci        }
1130370b324cSopenharmony_ci      }
1131370b324cSopenharmony_ci
1132370b324cSopenharmony_ci      #else // _WIN32
1133370b324cSopenharmony_ci
1134370b324cSopenharmony_ci      {
1135370b324cSopenharmony_ci        Parse1Log += a;
1136370b324cSopenharmony_ci        NSystem::CProcessAffinity aff;
1137370b324cSopenharmony_ci        aff.CpuZero();
1138370b324cSopenharmony_ci        for (unsigned i = 0; i < a.Len(); i++)
1139370b324cSopenharmony_ci        {
1140370b324cSopenharmony_ci          char c = a[i];
1141370b324cSopenharmony_ci          unsigned v;
1142370b324cSopenharmony_ci               if (c >= '0' && c <= '9') v =      (unsigned)(c - '0');
1143370b324cSopenharmony_ci          else if (c >= 'A' && c <= 'F') v = 10 + (unsigned)(c - 'A');
1144370b324cSopenharmony_ci          else if (c >= 'a' && c <= 'f') v = 10 + (unsigned)(c - 'a');
1145370b324cSopenharmony_ci          else
1146370b324cSopenharmony_ci            throw CArcCmdLineException("Unsupported switch postfix -stm", s);
1147370b324cSopenharmony_ci          for (unsigned k = 0; k < 4; k++)
1148370b324cSopenharmony_ci          {
1149370b324cSopenharmony_ci            const unsigned cpu = (a.Len() - 1 - i) * 4 + k;
1150370b324cSopenharmony_ci            if (v & ((unsigned)1 << k))
1151370b324cSopenharmony_ci              aff.CpuSet(cpu);
1152370b324cSopenharmony_ci          }
1153370b324cSopenharmony_ci        }
1154370b324cSopenharmony_ci
1155370b324cSopenharmony_ci        if (!aff.SetProcAffinity())
1156370b324cSopenharmony_ci        {
1157370b324cSopenharmony_ci          DWORD lastError = GetLastError();
1158370b324cSopenharmony_ci          Parse1Log += " : ERROR : ";
1159370b324cSopenharmony_ci          Parse1Log += NError::MyFormatMessage(lastError);
1160370b324cSopenharmony_ci        }
1161370b324cSopenharmony_ci      }
1162370b324cSopenharmony_ci      #endif // _WIN32
1163370b324cSopenharmony_ci
1164370b324cSopenharmony_ci      Parse1Log.Add_LF();
1165370b324cSopenharmony_ci    }
1166370b324cSopenharmony_ci  }
1167370b324cSopenharmony_ci
1168370b324cSopenharmony_ci  #endif
1169370b324cSopenharmony_ci}
1170370b324cSopenharmony_ci
1171370b324cSopenharmony_ci
1172370b324cSopenharmony_ci
1173370b324cSopenharmony_cistruct CCodePagePair
1174370b324cSopenharmony_ci{
1175370b324cSopenharmony_ci  const char *Name;
1176370b324cSopenharmony_ci  UInt32 CodePage;
1177370b324cSopenharmony_ci};
1178370b324cSopenharmony_ci
1179370b324cSopenharmony_cistatic const unsigned kNumByteOnlyCodePages = 3;
1180370b324cSopenharmony_ci
1181370b324cSopenharmony_cistatic const CCodePagePair g_CodePagePairs[] =
1182370b324cSopenharmony_ci{
1183370b324cSopenharmony_ci  { "utf-8", CP_UTF8 },
1184370b324cSopenharmony_ci  { "win", CP_ACP },
1185370b324cSopenharmony_ci  { "dos", CP_OEMCP },
1186370b324cSopenharmony_ci  { "utf-16le", Z7_WIN_CP_UTF16 },
1187370b324cSopenharmony_ci  { "utf-16be", Z7_WIN_CP_UTF16BE }
1188370b324cSopenharmony_ci};
1189370b324cSopenharmony_ci
1190370b324cSopenharmony_cistatic Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned keyIndex,
1191370b324cSopenharmony_ci    bool byteOnlyCodePages, Int32 defaultVal)
1192370b324cSopenharmony_ci{
1193370b324cSopenharmony_ci  if (!parser[keyIndex].ThereIs)
1194370b324cSopenharmony_ci    return defaultVal;
1195370b324cSopenharmony_ci
1196370b324cSopenharmony_ci  UString name (parser[keyIndex].PostStrings.Back());
1197370b324cSopenharmony_ci  UInt32 v;
1198370b324cSopenharmony_ci  if (StringToUInt32(name, v))
1199370b324cSopenharmony_ci    if (v < ((UInt32)1 << 16))
1200370b324cSopenharmony_ci      return (Int32)v;
1201370b324cSopenharmony_ci  name.MakeLower_Ascii();
1202370b324cSopenharmony_ci  const unsigned num = byteOnlyCodePages ? kNumByteOnlyCodePages : Z7_ARRAY_SIZE(g_CodePagePairs);
1203370b324cSopenharmony_ci  for (unsigned i = 0;; i++)
1204370b324cSopenharmony_ci  {
1205370b324cSopenharmony_ci    if (i == num) // to disable warnings from different compilers
1206370b324cSopenharmony_ci      throw CArcCmdLineException("Unsupported charset:", name);
1207370b324cSopenharmony_ci    const CCodePagePair &pair = g_CodePagePairs[i];
1208370b324cSopenharmony_ci    if (name.IsEqualTo(pair.Name))
1209370b324cSopenharmony_ci      return (Int32)pair.CodePage;
1210370b324cSopenharmony_ci  }
1211370b324cSopenharmony_ci}
1212370b324cSopenharmony_ci
1213370b324cSopenharmony_ci
1214370b324cSopenharmony_cistatic void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, CBoolPair &bp)
1215370b324cSopenharmony_ci{
1216370b324cSopenharmony_ci  bp.Def = parser[switchID].ThereIs;
1217370b324cSopenharmony_ci  if (bp.Def)
1218370b324cSopenharmony_ci    bp.Val = !parser[switchID].WithMinus;
1219370b324cSopenharmony_ci}
1220370b324cSopenharmony_ci
1221370b324cSopenharmony_civoid CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
1222370b324cSopenharmony_ci{
1223370b324cSopenharmony_ci  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
1224370b324cSopenharmony_ci  const unsigned numNonSwitchStrings = nonSwitchStrings.Size();
1225370b324cSopenharmony_ci  if (numNonSwitchStrings < kMinNonSwitchWords)
1226370b324cSopenharmony_ci    throw CArcCmdLineException("The command must be specified");
1227370b324cSopenharmony_ci
1228370b324cSopenharmony_ci  if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command))
1229370b324cSopenharmony_ci    throw CArcCmdLineException("Unsupported command:", nonSwitchStrings[kCommandIndex]);
1230370b324cSopenharmony_ci
1231370b324cSopenharmony_ci  if (parser[NKey::kHash].ThereIs)
1232370b324cSopenharmony_ci    options.HashMethods = parser[NKey::kHash].PostStrings;
1233370b324cSopenharmony_ci
1234370b324cSopenharmony_ci  /*
1235370b324cSopenharmony_ci  if (parser[NKey::kHashGenFile].ThereIs)
1236370b324cSopenharmony_ci  {
1237370b324cSopenharmony_ci    const UString &s = parser[NKey::kHashGenFile].PostStrings[0];
1238370b324cSopenharmony_ci    for (unsigned i = 0 ; i < s.Len();)
1239370b324cSopenharmony_ci    {
1240370b324cSopenharmony_ci      const wchar_t c = s[i++];
1241370b324cSopenharmony_ci      if (!options.HashOptions.ParseFlagCharOption(c, true))
1242370b324cSopenharmony_ci      {
1243370b324cSopenharmony_ci        if (c != '=')
1244370b324cSopenharmony_ci          throw CArcCmdLineException("Unsupported hash mode switch:", s);
1245370b324cSopenharmony_ci        options.HashOptions.HashFilePath = s.Ptr(i);
1246370b324cSopenharmony_ci        break;
1247370b324cSopenharmony_ci      }
1248370b324cSopenharmony_ci    }
1249370b324cSopenharmony_ci  }
1250370b324cSopenharmony_ci  */
1251370b324cSopenharmony_ci
1252370b324cSopenharmony_ci  if (parser[NKey::kHashDir].ThereIs)
1253370b324cSopenharmony_ci    options.ExtractOptions.HashDir = parser[NKey::kHashDir].PostStrings[0];
1254370b324cSopenharmony_ci
1255370b324cSopenharmony_ci  if (parser[NKey::kElimDup].ThereIs)
1256370b324cSopenharmony_ci  {
1257370b324cSopenharmony_ci    options.ExtractOptions.ElimDup.Def = true;
1258370b324cSopenharmony_ci    options.ExtractOptions.ElimDup.Val = !parser[NKey::kElimDup].WithMinus;
1259370b324cSopenharmony_ci  }
1260370b324cSopenharmony_ci
1261370b324cSopenharmony_ci  NWildcard::ECensorPathMode censorPathMode = NWildcard::k_RelatPath;
1262370b324cSopenharmony_ci  bool fullPathMode = parser[NKey::kFullPathMode].ThereIs;
1263370b324cSopenharmony_ci  if (fullPathMode)
1264370b324cSopenharmony_ci  {
1265370b324cSopenharmony_ci    censorPathMode = NWildcard::k_AbsPath;
1266370b324cSopenharmony_ci    const UString &s = parser[NKey::kFullPathMode].PostStrings[0];
1267370b324cSopenharmony_ci    if (!s.IsEmpty())
1268370b324cSopenharmony_ci    {
1269370b324cSopenharmony_ci      if (s == L"2")
1270370b324cSopenharmony_ci        censorPathMode = NWildcard::k_FullPath;
1271370b324cSopenharmony_ci      else
1272370b324cSopenharmony_ci        throw CArcCmdLineException("Unsupported -spf:", s);
1273370b324cSopenharmony_ci    }
1274370b324cSopenharmony_ci  }
1275370b324cSopenharmony_ci
1276370b324cSopenharmony_ci  if (parser[NKey::kNameTrailReplace].ThereIs)
1277370b324cSopenharmony_ci    g_PathTrailReplaceMode = !parser[NKey::kNameTrailReplace].WithMinus;
1278370b324cSopenharmony_ci
1279370b324cSopenharmony_ci  CNameOption nop;
1280370b324cSopenharmony_ci
1281370b324cSopenharmony_ci  if (parser[NKey::kRecursed].ThereIs)
1282370b324cSopenharmony_ci    nop.RecursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
1283370b324cSopenharmony_ci
1284370b324cSopenharmony_ci  if (parser[NKey::kDisableWildcardParsing].ThereIs)
1285370b324cSopenharmony_ci    nop.WildcardMatching = false;
1286370b324cSopenharmony_ci
1287370b324cSopenharmony_ci  if (parser[NKey::kUseSlashMark].ThereIs)
1288370b324cSopenharmony_ci  {
1289370b324cSopenharmony_ci    const UString &s = parser[NKey::kUseSlashMark].PostStrings[0];
1290370b324cSopenharmony_ci    if (s.IsEmpty())
1291370b324cSopenharmony_ci      nop.MarkMode = NWildcard::kMark_StrictFile;
1292370b324cSopenharmony_ci    else if (s.IsEqualTo_Ascii_NoCase("-"))
1293370b324cSopenharmony_ci      nop.MarkMode = NWildcard::kMark_FileOrDir;
1294370b324cSopenharmony_ci    else if (s.IsEqualTo_Ascii_NoCase("2"))
1295370b324cSopenharmony_ci      nop.MarkMode = NWildcard::kMark_StrictFile_IfWildcard;
1296370b324cSopenharmony_ci    else
1297370b324cSopenharmony_ci      throw CArcCmdLineException("Unsupported -spm:", s);
1298370b324cSopenharmony_ci  }
1299370b324cSopenharmony_ci
1300370b324cSopenharmony_ci
1301370b324cSopenharmony_ci  options.ConsoleCodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1);
1302370b324cSopenharmony_ci
1303370b324cSopenharmony_ci  UInt32 codePage = (UInt32)FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8);
1304370b324cSopenharmony_ci
1305370b324cSopenharmony_ci  bool thereAreSwitchIncludes = false;
1306370b324cSopenharmony_ci
1307370b324cSopenharmony_ci  if (parser[NKey::kInclude].ThereIs)
1308370b324cSopenharmony_ci  {
1309370b324cSopenharmony_ci    thereAreSwitchIncludes = true;
1310370b324cSopenharmony_ci    nop.Include = true;
1311370b324cSopenharmony_ci    AddSwitchWildcardsToCensor(options.Censor,
1312370b324cSopenharmony_ci        parser[NKey::kInclude].PostStrings, nop, codePage);
1313370b324cSopenharmony_ci  }
1314370b324cSopenharmony_ci
1315370b324cSopenharmony_ci  if (parser[NKey::kExclude].ThereIs)
1316370b324cSopenharmony_ci  {
1317370b324cSopenharmony_ci    nop.Include = false;
1318370b324cSopenharmony_ci    AddSwitchWildcardsToCensor(options.Censor,
1319370b324cSopenharmony_ci        parser[NKey::kExclude].PostStrings, nop, codePage);
1320370b324cSopenharmony_ci  }
1321370b324cSopenharmony_ci
1322370b324cSopenharmony_ci  unsigned curCommandIndex = kCommandIndex + 1;
1323370b324cSopenharmony_ci  bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs &&
1324370b324cSopenharmony_ci      options.Command.CommandType != NCommandType::kBenchmark &&
1325370b324cSopenharmony_ci      options.Command.CommandType != NCommandType::kInfo &&
1326370b324cSopenharmony_ci      options.Command.CommandType != NCommandType::kHash;
1327370b324cSopenharmony_ci
1328370b324cSopenharmony_ci  const bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
1329370b324cSopenharmony_ci  const bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList;
1330370b324cSopenharmony_ci  const bool isRename = options.Command.CommandType == NCommandType::kRename;
1331370b324cSopenharmony_ci
1332370b324cSopenharmony_ci  if ((isExtractOrList || isRename) && options.StdInMode)
1333370b324cSopenharmony_ci    thereIsArchiveName = false;
1334370b324cSopenharmony_ci
1335370b324cSopenharmony_ci  if (parser[NKey::kArcNameMode].ThereIs)
1336370b324cSopenharmony_ci    options.UpdateOptions.ArcNameMode = ParseArcNameMode(parser[NKey::kArcNameMode].PostCharIndex);
1337370b324cSopenharmony_ci
1338370b324cSopenharmony_ci  if (thereIsArchiveName)
1339370b324cSopenharmony_ci  {
1340370b324cSopenharmony_ci    if (curCommandIndex >= numNonSwitchStrings)
1341370b324cSopenharmony_ci      throw CArcCmdLineException("Cannot find archive name");
1342370b324cSopenharmony_ci    options.ArchiveName = nonSwitchStrings[curCommandIndex++];
1343370b324cSopenharmony_ci    if (options.ArchiveName.IsEmpty())
1344370b324cSopenharmony_ci      throw CArcCmdLineException("Archive name cannot by empty");
1345370b324cSopenharmony_ci    #ifdef _WIN32
1346370b324cSopenharmony_ci    // options.ArchiveName.Replace(L'/', WCHAR_PATH_SEPARATOR);
1347370b324cSopenharmony_ci    #endif
1348370b324cSopenharmony_ci  }
1349370b324cSopenharmony_ci
1350370b324cSopenharmony_ci  nop.Include = true;
1351370b324cSopenharmony_ci  AddToCensorFromNonSwitchesStrings(isRename ? &options.UpdateOptions.RenamePairs : NULL,
1352370b324cSopenharmony_ci      curCommandIndex, options.Censor,
1353370b324cSopenharmony_ci      nonSwitchStrings, parser.StopSwitchIndex,
1354370b324cSopenharmony_ci      nop,
1355370b324cSopenharmony_ci      thereAreSwitchIncludes, codePage);
1356370b324cSopenharmony_ci
1357370b324cSopenharmony_ci  options.YesToAll = parser[NKey::kYes].ThereIs;
1358370b324cSopenharmony_ci
1359370b324cSopenharmony_ci
1360370b324cSopenharmony_ci  #ifndef Z7_NO_CRYPTO
1361370b324cSopenharmony_ci  options.PasswordEnabled = parser[NKey::kPassword].ThereIs;
1362370b324cSopenharmony_ci  if (options.PasswordEnabled)
1363370b324cSopenharmony_ci    options.Password = parser[NKey::kPassword].PostStrings[0];
1364370b324cSopenharmony_ci  #endif
1365370b324cSopenharmony_ci
1366370b324cSopenharmony_ci  options.ShowDialog = parser[NKey::kShowDialog].ThereIs;
1367370b324cSopenharmony_ci
1368370b324cSopenharmony_ci  if (parser[NKey::kArchiveType].ThereIs)
1369370b324cSopenharmony_ci    options.ArcType = parser[NKey::kArchiveType].PostStrings[0];
1370370b324cSopenharmony_ci
1371370b324cSopenharmony_ci  options.ExcludedArcTypes = parser[NKey::kExcludedArcType].PostStrings;
1372370b324cSopenharmony_ci
1373370b324cSopenharmony_ci  SetMethodOptions(parser, options.Properties);
1374370b324cSopenharmony_ci
1375370b324cSopenharmony_ci  if (parser[NKey::kNtSecurity].ThereIs) options.NtSecurity.SetTrueTrue();
1376370b324cSopenharmony_ci
1377370b324cSopenharmony_ci  SetBoolPair(parser, NKey::kAltStreams, options.AltStreams);
1378370b324cSopenharmony_ci  SetBoolPair(parser, NKey::kHardLinks, options.HardLinks);
1379370b324cSopenharmony_ci  SetBoolPair(parser, NKey::kSymLinks, options.SymLinks);
1380370b324cSopenharmony_ci
1381370b324cSopenharmony_ci  SetBoolPair(parser, NKey::kStoreOwnerId, options.StoreOwnerId);
1382370b324cSopenharmony_ci  SetBoolPair(parser, NKey::kStoreOwnerName, options.StoreOwnerName);
1383370b324cSopenharmony_ci
1384370b324cSopenharmony_ci  CBoolPair symLinks_AllowDangerous;
1385370b324cSopenharmony_ci  SetBoolPair(parser, NKey::kSymLinks_AllowDangerous, symLinks_AllowDangerous);
1386370b324cSopenharmony_ci
1387370b324cSopenharmony_ci
1388370b324cSopenharmony_ci  /*
1389370b324cSopenharmony_ci  bool supportSymLink = options.SymLinks.Val;
1390370b324cSopenharmony_ci
1391370b324cSopenharmony_ci  if (!options.SymLinks.Def)
1392370b324cSopenharmony_ci  {
1393370b324cSopenharmony_ci    if (isExtractOrList)
1394370b324cSopenharmony_ci      supportSymLink = true;
1395370b324cSopenharmony_ci    else
1396370b324cSopenharmony_ci      supportSymLink = false;
1397370b324cSopenharmony_ci  }
1398370b324cSopenharmony_ci
1399370b324cSopenharmony_ci  #ifdef ENV_HAVE_LSTAT
1400370b324cSopenharmony_ci  if (supportSymLink)
1401370b324cSopenharmony_ci    global_use_lstat = 1;
1402370b324cSopenharmony_ci  else
1403370b324cSopenharmony_ci    global_use_lstat = 0;
1404370b324cSopenharmony_ci  #endif
1405370b324cSopenharmony_ci  */
1406370b324cSopenharmony_ci
1407370b324cSopenharmony_ci
1408370b324cSopenharmony_ci  if (isExtractOrList)
1409370b324cSopenharmony_ci  {
1410370b324cSopenharmony_ci    CExtractOptionsBase &eo = options.ExtractOptions;
1411370b324cSopenharmony_ci
1412370b324cSopenharmony_ci    eo.ExcludeDirItems = options.Censor.ExcludeDirItems;
1413370b324cSopenharmony_ci    eo.ExcludeFileItems = options.Censor.ExcludeFileItems;
1414370b324cSopenharmony_ci
1415370b324cSopenharmony_ci    {
1416370b324cSopenharmony_ci      CExtractNtOptions &nt = eo.NtOptions;
1417370b324cSopenharmony_ci      nt.NtSecurity = options.NtSecurity;
1418370b324cSopenharmony_ci
1419370b324cSopenharmony_ci      nt.AltStreams = options.AltStreams;
1420370b324cSopenharmony_ci      if (!options.AltStreams.Def)
1421370b324cSopenharmony_ci        nt.AltStreams.Val = true;
1422370b324cSopenharmony_ci
1423370b324cSopenharmony_ci      nt.HardLinks = options.HardLinks;
1424370b324cSopenharmony_ci      if (!options.HardLinks.Def)
1425370b324cSopenharmony_ci        nt.HardLinks.Val = true;
1426370b324cSopenharmony_ci
1427370b324cSopenharmony_ci      nt.SymLinks = options.SymLinks;
1428370b324cSopenharmony_ci      if (!options.SymLinks.Def)
1429370b324cSopenharmony_ci        nt.SymLinks.Val = true;
1430370b324cSopenharmony_ci
1431370b324cSopenharmony_ci      nt.SymLinks_AllowDangerous = symLinks_AllowDangerous;
1432370b324cSopenharmony_ci
1433370b324cSopenharmony_ci      nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs;
1434370b324cSopenharmony_ci      nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs;
1435370b324cSopenharmony_ci
1436370b324cSopenharmony_ci      nt.ExtractOwner = options.StoreOwnerId.Val; // StoreOwnerName
1437370b324cSopenharmony_ci
1438370b324cSopenharmony_ci      if (parser[NKey::kPreserveATime].ThereIs)
1439370b324cSopenharmony_ci        nt.PreserveATime = true;
1440370b324cSopenharmony_ci      if (parser[NKey::kShareForWrite].ThereIs)
1441370b324cSopenharmony_ci        nt.OpenShareForWrite = true;
1442370b324cSopenharmony_ci    }
1443370b324cSopenharmony_ci
1444370b324cSopenharmony_ci    if (parser[NKey::kZoneFile].ThereIs)
1445370b324cSopenharmony_ci    {
1446370b324cSopenharmony_ci      eo.ZoneMode = NExtract::NZoneIdMode::kAll;
1447370b324cSopenharmony_ci      const UString &s = parser[NKey::kZoneFile].PostStrings[0];
1448370b324cSopenharmony_ci      if (!s.IsEmpty())
1449370b324cSopenharmony_ci      {
1450370b324cSopenharmony_ci             if (s == L"0") eo.ZoneMode = NExtract::NZoneIdMode::kNone;
1451370b324cSopenharmony_ci        else if (s == L"1") eo.ZoneMode = NExtract::NZoneIdMode::kAll;
1452370b324cSopenharmony_ci        else if (s == L"2") eo.ZoneMode = NExtract::NZoneIdMode::kOffice;
1453370b324cSopenharmony_ci        else
1454370b324cSopenharmony_ci          throw CArcCmdLineException("Unsupported -snz:", s);
1455370b324cSopenharmony_ci      }
1456370b324cSopenharmony_ci    }
1457370b324cSopenharmony_ci
1458370b324cSopenharmony_ci    options.Censor.AddPathsToCensor(NWildcard::k_AbsPath);
1459370b324cSopenharmony_ci    options.Censor.ExtendExclude();
1460370b324cSopenharmony_ci
1461370b324cSopenharmony_ci    // are there paths that look as non-relative (!Prefix.IsEmpty())
1462370b324cSopenharmony_ci    if (!options.Censor.AllAreRelative())
1463370b324cSopenharmony_ci      throw CArcCmdLineException("Cannot use absolute pathnames for this command");
1464370b324cSopenharmony_ci
1465370b324cSopenharmony_ci    NWildcard::CCensor &arcCensor = options.arcCensor;
1466370b324cSopenharmony_ci
1467370b324cSopenharmony_ci    CNameOption nopArc;
1468370b324cSopenharmony_ci    // nopArc.RecursedType = NRecursedType::kNonRecursed; // default:  we don't want recursing for archives, if -r specified
1469370b324cSopenharmony_ci    // is it OK, external switches can disable WildcardMatching and MarcMode for arc.
1470370b324cSopenharmony_ci    nopArc.WildcardMatching = nop.WildcardMatching;
1471370b324cSopenharmony_ci    nopArc.MarkMode = nop.MarkMode;
1472370b324cSopenharmony_ci
1473370b324cSopenharmony_ci    if (parser[NKey::kArInclude].ThereIs)
1474370b324cSopenharmony_ci    {
1475370b324cSopenharmony_ci      nopArc.Include = true;
1476370b324cSopenharmony_ci      AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArInclude].PostStrings, nopArc, codePage);
1477370b324cSopenharmony_ci    }
1478370b324cSopenharmony_ci    if (parser[NKey::kArExclude].ThereIs)
1479370b324cSopenharmony_ci    {
1480370b324cSopenharmony_ci      nopArc.Include = false;
1481370b324cSopenharmony_ci      AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, nopArc, codePage);
1482370b324cSopenharmony_ci    }
1483370b324cSopenharmony_ci
1484370b324cSopenharmony_ci    if (thereIsArchiveName)
1485370b324cSopenharmony_ci    {
1486370b324cSopenharmony_ci      nopArc.Include = true;
1487370b324cSopenharmony_ci      AddNameToCensor(arcCensor, nopArc, options.ArchiveName);
1488370b324cSopenharmony_ci    }
1489370b324cSopenharmony_ci
1490370b324cSopenharmony_ci    arcCensor.AddPathsToCensor(NWildcard::k_RelatPath);
1491370b324cSopenharmony_ci
1492370b324cSopenharmony_ci    #ifdef _WIN32
1493370b324cSopenharmony_ci    ConvertToLongNames(arcCensor);
1494370b324cSopenharmony_ci    #endif
1495370b324cSopenharmony_ci
1496370b324cSopenharmony_ci    arcCensor.ExtendExclude();
1497370b324cSopenharmony_ci
1498370b324cSopenharmony_ci    if (options.StdInMode)
1499370b324cSopenharmony_ci      options.ArcName_for_StdInMode = parser[NKey::kStdIn].PostStrings.Front();
1500370b324cSopenharmony_ci
1501370b324cSopenharmony_ci    if (isExtractGroupCommand)
1502370b324cSopenharmony_ci    {
1503370b324cSopenharmony_ci      if (options.StdOutMode)
1504370b324cSopenharmony_ci      {
1505370b324cSopenharmony_ci        if (
1506370b324cSopenharmony_ci                  options.Number_for_Percents == k_OutStream_stdout
1507370b324cSopenharmony_ci            // || options.Number_for_Out      == k_OutStream_stdout
1508370b324cSopenharmony_ci            // || options.Number_for_Errors   == k_OutStream_stdout
1509370b324cSopenharmony_ci            ||
1510370b324cSopenharmony_ci            (
1511370b324cSopenharmony_ci              (options.IsStdOutTerminal && options.IsStdErrTerminal)
1512370b324cSopenharmony_ci              &&
1513370b324cSopenharmony_ci              (
1514370b324cSopenharmony_ci                      options.Number_for_Percents != k_OutStream_disabled
1515370b324cSopenharmony_ci                // || options.Number_for_Out      != k_OutStream_disabled
1516370b324cSopenharmony_ci                // || options.Number_for_Errors   != k_OutStream_disabled
1517370b324cSopenharmony_ci              )
1518370b324cSopenharmony_ci            )
1519370b324cSopenharmony_ci           )
1520370b324cSopenharmony_ci          throw CArcCmdLineException(kSameTerminalError);
1521370b324cSopenharmony_ci      }
1522370b324cSopenharmony_ci
1523370b324cSopenharmony_ci      if (parser[NKey::kOutputDir].ThereIs)
1524370b324cSopenharmony_ci      {
1525370b324cSopenharmony_ci        eo.OutputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]);
1526370b324cSopenharmony_ci        #ifdef _WIN32
1527370b324cSopenharmony_ci          NFile::NName::NormalizeDirSeparators(eo.OutputDir);
1528370b324cSopenharmony_ci        #endif
1529370b324cSopenharmony_ci        NFile::NName::NormalizeDirPathPrefix(eo.OutputDir);
1530370b324cSopenharmony_ci      }
1531370b324cSopenharmony_ci
1532370b324cSopenharmony_ci      eo.OverwriteMode = NExtract::NOverwriteMode::kAsk;
1533370b324cSopenharmony_ci      if (parser[NKey::kOverwrite].ThereIs)
1534370b324cSopenharmony_ci      {
1535370b324cSopenharmony_ci        eo.OverwriteMode = k_OverwriteModes[(unsigned)parser[NKey::kOverwrite].PostCharIndex];
1536370b324cSopenharmony_ci        eo.OverwriteMode_Force = true;
1537370b324cSopenharmony_ci      }
1538370b324cSopenharmony_ci      else if (options.YesToAll)
1539370b324cSopenharmony_ci      {
1540370b324cSopenharmony_ci        eo.OverwriteMode = NExtract::NOverwriteMode::kOverwrite;
1541370b324cSopenharmony_ci        eo.OverwriteMode_Force = true;
1542370b324cSopenharmony_ci      }
1543370b324cSopenharmony_ci    }
1544370b324cSopenharmony_ci
1545370b324cSopenharmony_ci    eo.PathMode = options.Command.GetPathMode();
1546370b324cSopenharmony_ci    if (censorPathMode == NWildcard::k_AbsPath)
1547370b324cSopenharmony_ci    {
1548370b324cSopenharmony_ci      eo.PathMode = NExtract::NPathMode::kAbsPaths;
1549370b324cSopenharmony_ci      eo.PathMode_Force = true;
1550370b324cSopenharmony_ci    }
1551370b324cSopenharmony_ci    else if (censorPathMode == NWildcard::k_FullPath)
1552370b324cSopenharmony_ci    {
1553370b324cSopenharmony_ci      eo.PathMode = NExtract::NPathMode::kFullPaths;
1554370b324cSopenharmony_ci      eo.PathMode_Force = true;
1555370b324cSopenharmony_ci    }
1556370b324cSopenharmony_ci  }
1557370b324cSopenharmony_ci  else if (options.Command.IsFromUpdateGroup())
1558370b324cSopenharmony_ci  {
1559370b324cSopenharmony_ci    if (parser[NKey::kArInclude].ThereIs)
1560370b324cSopenharmony_ci      throw CArcCmdLineException("-ai switch is not supported for this command");
1561370b324cSopenharmony_ci
1562370b324cSopenharmony_ci    CUpdateOptions &updateOptions = options.UpdateOptions;
1563370b324cSopenharmony_ci
1564370b324cSopenharmony_ci    SetAddCommandOptions(options.Command.CommandType, parser, updateOptions);
1565370b324cSopenharmony_ci
1566370b324cSopenharmony_ci    updateOptions.MethodMode.Properties = options.Properties;
1567370b324cSopenharmony_ci
1568370b324cSopenharmony_ci    if (parser[NKey::kPreserveATime].ThereIs)
1569370b324cSopenharmony_ci      updateOptions.PreserveATime = true;
1570370b324cSopenharmony_ci    if (parser[NKey::kShareForWrite].ThereIs)
1571370b324cSopenharmony_ci      updateOptions.OpenShareForWrite = true;
1572370b324cSopenharmony_ci    if (parser[NKey::kStopAfterOpenError].ThereIs)
1573370b324cSopenharmony_ci      updateOptions.StopAfterOpenError = true;
1574370b324cSopenharmony_ci
1575370b324cSopenharmony_ci    updateOptions.PathMode = censorPathMode;
1576370b324cSopenharmony_ci
1577370b324cSopenharmony_ci    updateOptions.AltStreams = options.AltStreams;
1578370b324cSopenharmony_ci    updateOptions.NtSecurity = options.NtSecurity;
1579370b324cSopenharmony_ci    updateOptions.HardLinks = options.HardLinks;
1580370b324cSopenharmony_ci    updateOptions.SymLinks = options.SymLinks;
1581370b324cSopenharmony_ci
1582370b324cSopenharmony_ci    updateOptions.StoreOwnerId = options.StoreOwnerId;
1583370b324cSopenharmony_ci    updateOptions.StoreOwnerName = options.StoreOwnerName;
1584370b324cSopenharmony_ci
1585370b324cSopenharmony_ci    updateOptions.EMailMode = parser[NKey::kEmail].ThereIs;
1586370b324cSopenharmony_ci    if (updateOptions.EMailMode)
1587370b324cSopenharmony_ci    {
1588370b324cSopenharmony_ci      updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front();
1589370b324cSopenharmony_ci      if (updateOptions.EMailAddress.Len() > 0)
1590370b324cSopenharmony_ci        if (updateOptions.EMailAddress[0] == L'.')
1591370b324cSopenharmony_ci        {
1592370b324cSopenharmony_ci          updateOptions.EMailRemoveAfter = true;
1593370b324cSopenharmony_ci          updateOptions.EMailAddress.Delete(0);
1594370b324cSopenharmony_ci        }
1595370b324cSopenharmony_ci    }
1596370b324cSopenharmony_ci
1597370b324cSopenharmony_ci    updateOptions.StdOutMode = options.StdOutMode;
1598370b324cSopenharmony_ci    updateOptions.StdInMode = options.StdInMode;
1599370b324cSopenharmony_ci
1600370b324cSopenharmony_ci    updateOptions.DeleteAfterCompressing = parser[NKey::kDeleteAfterCompressing].ThereIs;
1601370b324cSopenharmony_ci    updateOptions.SetArcMTime = parser[NKey::kSetArcMTime].ThereIs;
1602370b324cSopenharmony_ci
1603370b324cSopenharmony_ci    if (updateOptions.StdOutMode && updateOptions.EMailMode)
1604370b324cSopenharmony_ci      throw CArcCmdLineException("stdout mode and email mode cannot be combined");
1605370b324cSopenharmony_ci
1606370b324cSopenharmony_ci    if (updateOptions.StdOutMode)
1607370b324cSopenharmony_ci    {
1608370b324cSopenharmony_ci      if (options.IsStdOutTerminal)
1609370b324cSopenharmony_ci        throw CArcCmdLineException(kTerminalOutError);
1610370b324cSopenharmony_ci
1611370b324cSopenharmony_ci      if (options.Number_for_Percents == k_OutStream_stdout
1612370b324cSopenharmony_ci          || options.Number_for_Out == k_OutStream_stdout
1613370b324cSopenharmony_ci          || options.Number_for_Errors == k_OutStream_stdout)
1614370b324cSopenharmony_ci        throw CArcCmdLineException(kSameTerminalError);
1615370b324cSopenharmony_ci    }
1616370b324cSopenharmony_ci
1617370b324cSopenharmony_ci    if (updateOptions.StdInMode)
1618370b324cSopenharmony_ci      updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front();
1619370b324cSopenharmony_ci
1620370b324cSopenharmony_ci    if (options.Command.CommandType == NCommandType::kRename)
1621370b324cSopenharmony_ci      if (updateOptions.Commands.Size() != 1)
1622370b324cSopenharmony_ci        throw CArcCmdLineException("Only one archive can be created with rename command");
1623370b324cSopenharmony_ci  }
1624370b324cSopenharmony_ci  else if (options.Command.CommandType == NCommandType::kBenchmark)
1625370b324cSopenharmony_ci  {
1626370b324cSopenharmony_ci    options.NumIterations = 1;
1627370b324cSopenharmony_ci    options.NumIterations_Defined = false;
1628370b324cSopenharmony_ci    if (curCommandIndex < numNonSwitchStrings)
1629370b324cSopenharmony_ci    {
1630370b324cSopenharmony_ci      if (!StringToUInt32(nonSwitchStrings[curCommandIndex], options.NumIterations))
1631370b324cSopenharmony_ci        throw CArcCmdLineException("Incorrect number of benchmark iterations", nonSwitchStrings[curCommandIndex]);
1632370b324cSopenharmony_ci      curCommandIndex++;
1633370b324cSopenharmony_ci      options.NumIterations_Defined = true;
1634370b324cSopenharmony_ci    }
1635370b324cSopenharmony_ci  }
1636370b324cSopenharmony_ci  else if (options.Command.CommandType == NCommandType::kHash)
1637370b324cSopenharmony_ci  {
1638370b324cSopenharmony_ci    options.Censor.AddPathsToCensor(censorPathMode);
1639370b324cSopenharmony_ci    options.Censor.ExtendExclude();
1640370b324cSopenharmony_ci
1641370b324cSopenharmony_ci    CHashOptions &hashOptions = options.HashOptions;
1642370b324cSopenharmony_ci    hashOptions.PathMode = censorPathMode;
1643370b324cSopenharmony_ci    hashOptions.Methods = options.HashMethods;
1644370b324cSopenharmony_ci    // hashOptions.HashFilePath = options.HashFilePath;
1645370b324cSopenharmony_ci    if (parser[NKey::kPreserveATime].ThereIs)
1646370b324cSopenharmony_ci      hashOptions.PreserveATime = true;
1647370b324cSopenharmony_ci    if (parser[NKey::kShareForWrite].ThereIs)
1648370b324cSopenharmony_ci      hashOptions.OpenShareForWrite = true;
1649370b324cSopenharmony_ci    hashOptions.StdInMode = options.StdInMode;
1650370b324cSopenharmony_ci    hashOptions.AltStreamsMode = options.AltStreams.Val;
1651370b324cSopenharmony_ci    hashOptions.SymLinks = options.SymLinks;
1652370b324cSopenharmony_ci  }
1653370b324cSopenharmony_ci  else if (options.Command.CommandType == NCommandType::kInfo)
1654370b324cSopenharmony_ci  {
1655370b324cSopenharmony_ci  }
1656370b324cSopenharmony_ci  else
1657370b324cSopenharmony_ci    throw 20150919;
1658370b324cSopenharmony_ci}
1659370b324cSopenharmony_ci
1660370b324cSopenharmony_ci
1661370b324cSopenharmony_ci
1662370b324cSopenharmony_ci#ifndef _WIN32
1663370b324cSopenharmony_ci
1664370b324cSopenharmony_cistatic AString g_ModuleDirPrefix;
1665370b324cSopenharmony_ci
1666370b324cSopenharmony_civoid Set_ModuleDirPrefix_From_ProgArg0(const char *s);
1667370b324cSopenharmony_civoid Set_ModuleDirPrefix_From_ProgArg0(const char *s)
1668370b324cSopenharmony_ci{
1669370b324cSopenharmony_ci  AString a (s);
1670370b324cSopenharmony_ci  int sep = a.ReverseFind_PathSepar();
1671370b324cSopenharmony_ci  a.DeleteFrom((unsigned)(sep + 1));
1672370b324cSopenharmony_ci  g_ModuleDirPrefix = a;
1673370b324cSopenharmony_ci}
1674370b324cSopenharmony_ci
1675370b324cSopenharmony_cinamespace NWindows {
1676370b324cSopenharmony_cinamespace NDLL {
1677370b324cSopenharmony_ci
1678370b324cSopenharmony_ciFString GetModuleDirPrefix();
1679370b324cSopenharmony_ciFString GetModuleDirPrefix()
1680370b324cSopenharmony_ci{
1681370b324cSopenharmony_ci  FString s;
1682370b324cSopenharmony_ci
1683370b324cSopenharmony_ci  s = fas2fs(g_ModuleDirPrefix);
1684370b324cSopenharmony_ci  if (s.IsEmpty())
1685370b324cSopenharmony_ci    s = FTEXT(".") FSTRING_PATH_SEPARATOR;
1686370b324cSopenharmony_ci  return s;
1687370b324cSopenharmony_ci  /*
1688370b324cSopenharmony_ci  setenv("_7ZIP_HOME_DIR", "/test/", 0);
1689370b324cSopenharmony_ci  const char *home = getenv("_7ZIP_HOME_DIR");
1690370b324cSopenharmony_ci  if (home)
1691370b324cSopenharmony_ci    s = home;
1692370b324cSopenharmony_ci  else
1693370b324cSopenharmony_ci    s = FTEXT(".") FSTRING_PATH_SEPARATOR;
1694370b324cSopenharmony_ci  return s;
1695370b324cSopenharmony_ci  */
1696370b324cSopenharmony_ci}
1697370b324cSopenharmony_ci
1698370b324cSopenharmony_ci}}
1699370b324cSopenharmony_ci
1700370b324cSopenharmony_ci#endif // ! _WIN32
1701