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