1// Main.cpp 2 3#include "StdAfx.h" 4 5#include "../../../Common/MyWindows.h" 6 7#ifdef _WIN32 8 9#ifndef Z7_OLD_WIN_SDK 10 11#if defined(__MINGW32__) || defined(__MINGW64__) 12#include <psapi.h> 13#else 14#include <Psapi.h> 15#endif 16 17#else // Z7_OLD_WIN_SDK 18 19typedef struct _PROCESS_MEMORY_COUNTERS { 20 DWORD cb; 21 DWORD PageFaultCount; 22 SIZE_T PeakWorkingSetSize; 23 SIZE_T WorkingSetSize; 24 SIZE_T QuotaPeakPagedPoolUsage; 25 SIZE_T QuotaPagedPoolUsage; 26 SIZE_T QuotaPeakNonPagedPoolUsage; 27 SIZE_T QuotaNonPagedPoolUsage; 28 SIZE_T PagefileUsage; 29 SIZE_T PeakPagefileUsage; 30} PROCESS_MEMORY_COUNTERS; 31typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS; 32 33#endif // Z7_OLD_WIN_SDK 34 35#else // _WIN32 36#include <unistd.h> 37#include <sys/ioctl.h> 38#include <sys/time.h> 39#include <sys/times.h> 40#endif // _WIN32 41 42#include "../../../../C/CpuArch.h" 43 44#include "../../../Common/MyInitGuid.h" 45 46#include "../../../Common/CommandLineParser.h" 47#include "../../../Common/IntToString.h" 48#include "../../../Common/MyException.h" 49#include "../../../Common/StdInStream.h" 50#include "../../../Common/StdOutStream.h" 51#include "../../../Common/StringConvert.h" 52#include "../../../Common/StringToInt.h" 53#include "../../../Common/UTFConvert.h" 54 55#include "../../../Windows/ErrorMsg.h" 56#include "../../../Windows/TimeUtils.h" 57#include "../../../Windows/FileDir.h" 58 59#include "../Common/ArchiveCommandLine.h" 60#include "../Common/Bench.h" 61#include "../Common/ExitCode.h" 62#include "../Common/Extract.h" 63 64#ifdef Z7_EXTERNAL_CODECS 65#include "../Common/LoadCodecs.h" 66#endif 67 68#include "../../Common/RegisterCodec.h" 69 70#include "BenchCon.h" 71#include "ConsoleClose.h" 72#include "ExtractCallbackConsole.h" 73#include "HashCon.h" 74#include "List.h" 75#include "OpenCallbackConsole.h" 76#include "UpdateCallbackConsole.h" 77 78#ifdef Z7_PROG_VARIANT_R 79#include "../../../../C/7zVersion.h" 80#else 81#include "../../MyVersion.h" 82#endif 83 84using namespace NWindows; 85using namespace NFile; 86using namespace NCommandLineParser; 87 88#ifdef _WIN32 89extern 90HINSTANCE g_hInstance; 91HINSTANCE g_hInstance = NULL; 92#endif 93 94extern CStdOutStream *g_StdStream; 95extern CStdOutStream *g_ErrStream; 96 97extern unsigned g_NumCodecs; 98extern const CCodecInfo *g_Codecs[]; 99 100extern unsigned g_NumHashers; 101extern const CHasherInfo *g_Hashers[]; 102 103#ifdef Z7_EXTERNAL_CODECS 104extern 105const CExternalCodecs *g_ExternalCodecs_Ptr; 106const CExternalCodecs *g_ExternalCodecs_Ptr; 107#endif 108 109DECLARE_AND_SET_CLIENT_VERSION_VAR 110 111#if defined(Z7_PROG_VARIANT_Z) 112 #define PROG_POSTFIX "z" 113 #define PROG_POSTFIX_2 " (z)" 114#elif defined(Z7_PROG_VARIANT_R) 115 #define PROG_POSTFIX "r" 116 #define PROG_POSTFIX_2 " (r)" 117#elif !defined(Z7_EXTERNAL_CODECS) 118 #define PROG_POSTFIX "a" 119 #define PROG_POSTFIX_2 " (a)" 120#else 121 #define PROG_POSTFIX "" 122 #define PROG_POSTFIX_2 "" 123#endif 124 125 126static const char * const kCopyrightString = "\n7-Zip" 127 PROG_POSTFIX_2 128 " " MY_VERSION_CPU 129 " : " MY_COPYRIGHT_DATE "\n"; 130 131static const char * const kHelpString = 132 "Usage: 7z" 133 PROG_POSTFIX 134 " <command> [<switches>...] <archive_name> [<file_names>...] [@listfile]\n" 135 "\n" 136 "<Commands>\n" 137 " a : Add files to archive\n" 138 " b : Benchmark\n" 139 " d : Delete files from archive\n" 140 " e : Extract files from archive (without using directory names)\n" 141 " h : Calculate hash values for files\n" 142 " i : Show information about supported formats\n" 143 " l : List contents of archive\n" 144 " rn : Rename files in archive\n" 145 " t : Test integrity of archive\n" 146 " u : Update files to archive\n" 147 " x : eXtract files with full paths\n" 148 "\n" 149 "<Switches>\n" 150 " -- : Stop switches and @listfile parsing\n" 151 " -ai[r[-|0]]{@listfile|!wildcard} : Include archives\n" 152 " -ax[r[-|0]]{@listfile|!wildcard} : eXclude archives\n" 153 " -ao{a|s|t|u} : set Overwrite mode\n" 154 " -an : disable archive_name field\n" 155 " -bb[0-3] : set output log level\n" 156 " -bd : disable progress indicator\n" 157 " -bs{o|e|p}{0|1|2} : set output stream for output/error/progress line\n" 158 " -bt : show execution time statistics\n" 159 " -i[r[-|0]]{@listfile|!wildcard} : Include filenames\n" 160 " -m{Parameters} : set compression Method\n" 161 " -mmt[N] : set number of CPU threads\n" 162 " -mx[N] : set compression level: -mx1 (fastest) ... -mx9 (ultra)\n" 163 " -o{Directory} : set Output directory\n" 164 #ifndef Z7_NO_CRYPTO 165 " -p{Password} : set Password\n" 166 #endif 167 " -r[-|0] : Recurse subdirectories for name search\n" 168 " -sa{a|e|s} : set Archive name mode\n" 169 " -scc{UTF-8|WIN|DOS} : set charset for console input/output\n" 170 " -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files\n" 171 " -scrc[CRC32|CRC64|SHA1|SHA256|*] : set hash function for x, e, h commands\n" 172 " -sdel : delete files after compression\n" 173 " -seml[.] : send archive by email\n" 174 " -sfx[{name}] : Create SFX archive\n" 175 " -si[{name}] : read data from stdin\n" 176 " -slp : set Large Pages mode\n" 177 " -slt : show technical information for l (List) command\n" 178 " -snh : store hard links as links\n" 179 " -snl : store symbolic links as links\n" 180 " -sni : store NT security information\n" 181 " -sns[-] : store NTFS alternate streams\n" 182 " -so : write data to stdout\n" 183 " -spd : disable wildcard matching for file names\n" 184 " -spe : eliminate duplication of root folder for extract command\n" 185 " -spf[2] : use fully qualified file paths\n" 186 " -ssc[-] : set sensitive case mode\n" 187 " -sse : stop archive creating, if it can't open some input file\n" 188 " -ssp : do not change Last Access Time of source files while archiving\n" 189 " -ssw : compress shared files\n" 190 " -stl : set archive timestamp from the most recently modified file\n" 191 " -stm{HexMask} : set CPU thread affinity mask (hexadecimal number)\n" 192 " -stx{Type} : exclude archive type\n" 193 " -t{Type} : Set type of archive\n" 194 " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options\n" 195 " -v{Size}[b|k|m|g] : Create volumes\n" 196 " -w[{path}] : assign Work directory. Empty path means a temporary directory\n" 197 " -x[r[-|0]]{@listfile|!wildcard} : eXclude filenames\n" 198 " -y : assume Yes on all queries\n"; 199 200// --------------------------- 201// exception messages 202 203static const char * const kEverythingIsOk = "Everything is Ok"; 204static const char * const kUserErrorMessage = "Incorrect command line"; 205static const char * const kNoFormats = "7-Zip cannot find the code that works with archives."; 206static const char * const kUnsupportedArcTypeMessage = "Unsupported archive type"; 207// static const char * const kUnsupportedUpdateArcType = "Can't create archive for that type"; 208 209#define kDefaultSfxModule "7zCon.sfx" 210 211Z7_ATTR_NORETURN 212static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code) 213{ 214 if (g_ErrStream) 215 *g_ErrStream << endl << "ERROR: " << message << endl; 216 throw code; 217} 218 219 220#ifdef _WIN32 221#define ShowProgInfo(so) 222#else 223static void ShowProgInfo(CStdOutStream *so) 224{ 225 if (!so) 226 return; 227 228 *so 229 230 /* 231 #ifdef __DATE__ 232 << " " << __DATE__ 233 #endif 234 #ifdef __TIME__ 235 << " " << __TIME__ 236 #endif 237 */ 238 239 << " " << (unsigned)(sizeof(void *)) * 8 << "-bit" 240 241 #ifdef __ILP32__ 242 << " ILP32" 243 #endif 244 245 #ifdef __ARM_ARCH 246 << " arm_v:" << __ARM_ARCH 247 #ifdef __ARM_ARCH_ISA_THUMB 248 << " thumb:" << __ARM_ARCH_ISA_THUMB 249 #endif 250 #endif 251 ; 252 253 254 255 #ifdef ENV_HAVE_LOCALE 256 *so << " locale=" << GetLocale(); 257 #endif 258 #ifndef _WIN32 259 { 260 const bool is_IsNativeUTF8 = IsNativeUTF8(); 261 if (!is_IsNativeUTF8) 262 *so << " UTF8=" << (is_IsNativeUTF8 ? "+" : "-"); 263 } 264 if (!g_ForceToUTF8) 265 *so << " use-UTF8=" << (g_ForceToUTF8 ? "+" : "-"); 266 { 267 const unsigned wchar_t_size = (unsigned)sizeof(wchar_t); 268 if (wchar_t_size != 4) 269 *so << " wchar_t=" << wchar_t_size * 8 << "-bit"; 270 } 271 { 272 const unsigned off_t_size = (unsigned)sizeof(off_t); 273 if (off_t_size != 8) 274 *so << " Files=" << off_t_size * 8 << "-bit"; 275 } 276 #endif 277 278 { 279 const UInt32 numCpus = NWindows::NSystem::GetNumberOfProcessors(); 280 *so << " Threads:" << numCpus; 281 const UInt64 openMAX= NWindows::NSystem::Get_File_OPEN_MAX(); 282 *so << " OPEN_MAX:" << openMAX; 283 { 284 FString temp; 285 NDir::MyGetTempPath(temp); 286 if (!temp.IsEqualTo(STRING_PATH_SEPARATOR "tmp" STRING_PATH_SEPARATOR)) 287 *so << " temp_path:" << temp; 288 } 289 } 290 291 #ifdef Z7_7ZIP_ASM 292 *so << ", ASM"; 293 #endif 294 295 /* 296 { 297 AString s; 298 GetCpuName(s); 299 s.Trim(); 300 *so << ", " << s; 301 } 302 303 #ifdef __ARM_FEATURE_CRC32 304 << " CRC32" 305 #endif 306 307 308 #if (defined MY_CPU_X86_OR_AMD64 || defined(MY_CPU_ARM_OR_ARM64)) 309 if (CPU_IsSupported_AES()) *so << ",AES"; 310 #endif 311 312 #ifdef MY_CPU_ARM_OR_ARM64 313 if (CPU_IsSupported_CRC32()) *so << ",CRC32"; 314 #if defined(_WIN32) 315 if (CPU_IsSupported_CRYPTO()) *so << ",CRYPTO"; 316 #else 317 if (CPU_IsSupported_SHA1()) *so << ",SHA1"; 318 if (CPU_IsSupported_SHA2()) *so << ",SHA2"; 319 #endif 320 #endif 321 */ 322 323 *so << endl; 324} 325#endif 326 327static void ShowCopyrightAndHelp(CStdOutStream *so, bool needHelp) 328{ 329 if (!so) 330 return; 331 *so << kCopyrightString; 332 // *so << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << endl; 333 ShowProgInfo(so); 334 *so << endl; 335 if (needHelp) 336 *so << kHelpString; 337} 338 339 340static void PrintStringRight(CStdOutStream &so, const char *s, unsigned size) 341{ 342 unsigned len = MyStringLen(s); 343 for (unsigned i = len; i < size; i++) 344 so << ' '; 345 so << s; 346} 347 348static void PrintUInt32(CStdOutStream &so, UInt32 val, unsigned size) 349{ 350 char s[16]; 351 ConvertUInt32ToString(val, s); 352 PrintStringRight(so, s, size); 353} 354 355#ifdef Z7_EXTERNAL_CODECS 356static void PrintNumber(CStdOutStream &so, UInt32 val, unsigned numDigits) 357{ 358 AString s; 359 s.Add_UInt32(val); 360 while (s.Len() < numDigits) 361 s.InsertAtFront('0'); 362 so << s; 363} 364#endif 365 366static void PrintLibIndex(CStdOutStream &so, int libIndex) 367{ 368 if (libIndex >= 0) 369 PrintUInt32(so, (UInt32)libIndex, 2); 370 else 371 so << " "; 372 so << ' '; 373} 374 375static void PrintString(CStdOutStream &so, const UString &s, unsigned size) 376{ 377 unsigned len = s.Len(); 378 so << s; 379 for (unsigned i = len; i < size; i++) 380 so << ' '; 381} 382 383static inline char GetHex(unsigned val) 384{ 385 return (char)((val < 10) ? ('0' + val) : ('A' + (val - 10))); 386} 387 388static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so) 389{ 390 FOR_VECTOR(i, pc.Paths) 391 { 392 so.NormalizePrint_UString(fs2us(pc.Paths[i])); 393 so << " : "; 394 so << NError::MyFormatMessage(pc.Codes[i]) << endl; 395 } 396 so << "----------------" << endl; 397} 398 399static int WarningsCheck(HRESULT result, const CCallbackConsoleBase &callback, 400 const CUpdateErrorInfo &errorInfo, 401 CStdOutStream *so, 402 CStdOutStream *se, 403 bool showHeaders) 404{ 405 int exitCode = NExitCode::kSuccess; 406 407 if (callback.ScanErrors.Paths.Size() != 0) 408 { 409 if (se) 410 { 411 *se << endl; 412 *se << "Scan WARNINGS for files and folders:" << endl << endl; 413 PrintWarningsPaths(callback.ScanErrors, *se); 414 *se << "Scan WARNINGS: " << callback.ScanErrors.Paths.Size(); 415 *se << endl; 416 } 417 exitCode = NExitCode::kWarning; 418 } 419 420 if (result != S_OK || errorInfo.ThereIsError()) 421 { 422 if (se) 423 { 424 UString message; 425 if (!errorInfo.Message.IsEmpty()) 426 { 427 message += errorInfo.Message.Ptr(); 428 message.Add_LF(); 429 } 430 { 431 FOR_VECTOR(i, errorInfo.FileNames) 432 { 433 message += fs2us(errorInfo.FileNames[i]); 434 message.Add_LF(); 435 } 436 } 437 if (errorInfo.SystemError != 0) 438 { 439 message += NError::MyFormatMessage(errorInfo.SystemError); 440 message.Add_LF(); 441 } 442 if (!message.IsEmpty()) 443 *se << L"\nError:\n" << message; 444 } 445 446 // we will work with (result) later 447 // throw CSystemException(result); 448 return NExitCode::kFatalError; 449 } 450 451 unsigned numErrors = callback.FailedFiles.Paths.Size(); 452 if (numErrors == 0) 453 { 454 if (showHeaders) 455 if (callback.ScanErrors.Paths.Size() == 0) 456 if (so) 457 { 458 if (se) 459 se->Flush(); 460 *so << kEverythingIsOk << endl; 461 } 462 } 463 else 464 { 465 if (se) 466 { 467 *se << endl; 468 *se << "WARNINGS for files:" << endl << endl; 469 PrintWarningsPaths(callback.FailedFiles, *se); 470 *se << "WARNING: Cannot open " << numErrors << " file"; 471 if (numErrors > 1) 472 *se << 's'; 473 *se << endl; 474 } 475 exitCode = NExitCode::kWarning; 476 } 477 478 return exitCode; 479} 480 481static void ThrowException_if_Error(HRESULT res) 482{ 483 if (res != S_OK) 484 throw CSystemException(res); 485} 486 487static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ') 488{ 489 char temp[64]; 490 char *p = temp + 32; 491 ConvertUInt64ToString(val, p); 492 unsigned len = MyStringLen(p); 493 for (; len < numDigits; len++) 494 *--p = c; 495 *g_StdStream << p; 496} 497 498#ifdef _WIN32 499 500static void PrintTime(const char *s, UInt64 val, UInt64 total) 501{ 502 *g_StdStream << endl << s << " Time ="; 503 const UInt32 kFreq = 10000000; 504 UInt64 sec = val / kFreq; 505 PrintNum(sec, 6); 506 *g_StdStream << '.'; 507 UInt32 ms = (UInt32)(val - (sec * kFreq)) / (kFreq / 1000); 508 PrintNum(ms, 3, '0'); 509 510 while (val > ((UInt64)1 << 56)) 511 { 512 val >>= 1; 513 total >>= 1; 514 } 515 516 UInt64 percent = 0; 517 if (total != 0) 518 percent = val * 100 / total; 519 *g_StdStream << " ="; 520 PrintNum(percent, 5); 521 *g_StdStream << '%'; 522} 523 524#ifndef UNDER_CE 525 526#define SHIFT_SIZE_VALUE(x, num) (((x) + (1 << (num)) - 1) >> (num)) 527 528static void PrintMemUsage(const char *s, UInt64 val) 529{ 530 *g_StdStream << " " << s << " Memory ="; 531 PrintNum(SHIFT_SIZE_VALUE(val, 20), 7); 532 *g_StdStream << " MB"; 533 /* 534 *g_StdStream << " ="; 535 PrintNum(SHIFT_SIZE_VALUE(val, 10), 9); 536 *g_StdStream << " KB"; 537 */ 538 #ifdef Z7_LARGE_PAGES 539 AString lp; 540 Add_LargePages_String(lp); 541 if (!lp.IsEmpty()) 542 *g_StdStream << lp; 543 #endif 544} 545 546EXTERN_C_BEGIN 547typedef BOOL (WINAPI *Func_GetProcessMemoryInfo)(HANDLE Process, 548 PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb); 549typedef BOOL (WINAPI *Func_QueryProcessCycleTime)(HANDLE Process, PULONG64 CycleTime); 550EXTERN_C_END 551 552#endif 553 554static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; } 555 556static void PrintStat() 557{ 558 FILETIME creationTimeFT, exitTimeFT, kernelTimeFT, userTimeFT; 559 if (! 560 #ifdef UNDER_CE 561 ::GetThreadTimes(::GetCurrentThread() 562 #else 563 // NT 3.5 564 ::GetProcessTimes(::GetCurrentProcess() 565 #endif 566 , &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT)) 567 return; 568 FILETIME curTimeFT; 569 NTime::GetCurUtc_FiTime(curTimeFT); 570 571 #ifndef UNDER_CE 572 573 PROCESS_MEMORY_COUNTERS m; 574 memset(&m, 0, sizeof(m)); 575 BOOL memDefined = FALSE; 576 BOOL cycleDefined = FALSE; 577 ULONG64 cycleTime = 0; 578 { 579 /* NT 4.0: GetProcessMemoryInfo() in Psapi.dll 580 Win7: new function K32GetProcessMemoryInfo() in kernel32.dll 581 It's faster to call kernel32.dll code than Psapi.dll code 582 GetProcessMemoryInfo() requires Psapi.lib 583 Psapi.lib in SDK7+ can link to K32GetProcessMemoryInfo in kernel32.dll 584 The program with K32GetProcessMemoryInfo will not work on systems before Win7 585 // memDefined = GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); 586 */ 587 const HMODULE kern = ::GetModuleHandleW(L"kernel32.dll"); 588 Func_GetProcessMemoryInfo 589 my_GetProcessMemoryInfo = Z7_GET_PROC_ADDRESS( 590 Func_GetProcessMemoryInfo, kern, 591 "K32GetProcessMemoryInfo"); 592 if (!my_GetProcessMemoryInfo) 593 { 594 const HMODULE lib = LoadLibraryW(L"Psapi.dll"); 595 if (lib) 596 my_GetProcessMemoryInfo = Z7_GET_PROC_ADDRESS( 597 Func_GetProcessMemoryInfo, lib, 598 "GetProcessMemoryInfo"); 599 } 600 if (my_GetProcessMemoryInfo) 601 memDefined = my_GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); 602 // FreeLibrary(lib); 603 const 604 Func_QueryProcessCycleTime 605 my_QueryProcessCycleTime = Z7_GET_PROC_ADDRESS( 606 Func_QueryProcessCycleTime, kern, 607 "QueryProcessCycleTime"); 608 if (my_QueryProcessCycleTime) 609 cycleDefined = my_QueryProcessCycleTime(GetCurrentProcess(), &cycleTime); 610 } 611 612 #endif 613 614 UInt64 curTime = GetTime64(curTimeFT); 615 UInt64 creationTime = GetTime64(creationTimeFT); 616 UInt64 kernelTime = GetTime64(kernelTimeFT); 617 UInt64 userTime = GetTime64(userTimeFT); 618 619 UInt64 totalTime = curTime - creationTime; 620 621 PrintTime("Kernel ", kernelTime, totalTime); 622 623 const UInt64 processTime = kernelTime + userTime; 624 625 #ifndef UNDER_CE 626 if (cycleDefined) 627 { 628 *g_StdStream << " Cnt:"; 629 PrintNum(cycleTime / 1000000, 15); 630 *g_StdStream << " MCycles"; 631 } 632 #endif 633 634 PrintTime("User ", userTime, totalTime); 635 636 #ifndef UNDER_CE 637 if (cycleDefined) 638 { 639 *g_StdStream << " Freq (cnt/ptime):"; 640 UInt64 us = processTime / 10; 641 if (us == 0) 642 us = 1; 643 PrintNum(cycleTime / us, 6); 644 *g_StdStream << " MHz"; 645 } 646 #endif 647 648 PrintTime("Process", processTime, totalTime); 649 #ifndef UNDER_CE 650 if (memDefined) PrintMemUsage("Virtual ", m.PeakPagefileUsage); 651 #endif 652 653 PrintTime("Global ", totalTime, totalTime); 654 #ifndef UNDER_CE 655 if (memDefined) PrintMemUsage("Physical", m.PeakWorkingSetSize); 656 #endif 657 *g_StdStream << endl; 658} 659 660 661#else // ! _WIN32 662 663static UInt64 Get_timeofday_us() 664{ 665 struct timeval now; 666 if (gettimeofday(&now, NULL) == 0) 667 return (UInt64)now.tv_sec * 1000000 + (UInt64)now.tv_usec; 668 return 0; 669} 670 671static void PrintTime(const char *s, UInt64 val, UInt64 total_us, UInt64 kFreq) 672{ 673 *g_StdStream << endl << s << " Time ="; 674 675 { 676 UInt64 sec, ms; 677 678 if (kFreq == 0) 679 { 680 sec = val / 1000000; 681 ms = val % 1000000 / 1000; 682 } 683 else 684 { 685 sec = val / kFreq; 686 ms = (UInt32)((val - (sec * kFreq)) * 1000 / kFreq); 687 } 688 689 PrintNum(sec, 6); 690 *g_StdStream << '.'; 691 PrintNum(ms, 3, '0'); 692 } 693 694 if (total_us == 0) 695 return; 696 697 UInt64 percent = 0; 698 if (kFreq == 0) 699 percent = val * 100 / total_us; 700 else 701 { 702 const UInt64 kMaxVal = (UInt64)(Int64)-1; 703 UInt32 m = 100000000; 704 for (;;) 705 { 706 if (m == 0 || kFreq == 0) 707 break; 708 if (kMaxVal / m > val && 709 kMaxVal / kFreq > total_us) 710 break; 711 if (val > m) 712 val >>= 1; 713 else 714 m >>= 1; 715 if (kFreq > total_us) 716 kFreq >>= 1; 717 else 718 total_us >>= 1; 719 } 720 const UInt64 total = kFreq * total_us; 721 if (total != 0) 722 percent = val * m / total; 723 } 724 *g_StdStream << " ="; 725 PrintNum(percent, 5); 726 *g_StdStream << '%'; 727} 728 729static void PrintStat(const UInt64 startTime) 730{ 731 tms t; 732 /* clock_t res = */ times(&t); 733 const UInt64 totalTime = Get_timeofday_us() - startTime; 734 const UInt64 kFreq = (UInt64)sysconf(_SC_CLK_TCK); 735 PrintTime("Kernel ", (UInt64)t.tms_stime, totalTime, kFreq); 736 PrintTime("User ", (UInt64)t.tms_utime, totalTime, kFreq); 737 PrintTime("Process", (UInt64)t.tms_utime + (UInt64)t.tms_stime, totalTime, kFreq); 738 PrintTime("Global ", totalTime, totalTime, 0); 739 *g_StdStream << endl; 740} 741 742#endif // ! _WIN32 743 744 745 746 747 748static void PrintHexId(CStdOutStream &so, UInt64 id) 749{ 750 char s[32]; 751 ConvertUInt64ToHex(id, s); 752 PrintStringRight(so, s, 8); 753} 754 755#ifndef _WIN32 756void Set_ModuleDirPrefix_From_ProgArg0(const char *s); 757#endif 758 759int Main2( 760 #ifndef _WIN32 761 int numArgs, char *args[] 762 #endif 763); 764int Main2( 765 #ifndef _WIN32 766 int numArgs, char *args[] 767 #endif 768) 769{ 770 #if defined(MY_CPU_SIZEOF_POINTER) 771 { unsigned k = sizeof(void *); if (k != MY_CPU_SIZEOF_POINTER) throw "incorrect MY_CPU_PTR_SIZE"; } 772 #endif 773 774 #if defined(_WIN32) && !defined(UNDER_CE) 775 SetFileApisToOEM(); 776 #endif 777 778 #ifdef ENV_HAVE_LOCALE 779 // printf("\nBefore SetLocale() : %s\n", IsNativeUtf8() ? "NATIVE UTF-8" : "IS NOT NATIVE UTF-8"); 780 MY_SetLocale(); 781 // printf("\nAfter SetLocale() : %s\n", IsNativeUtf8() ? "NATIVE UTF-8" : "IS NOT NATIVE UTF-8"); 782 #endif 783 784 #ifndef _WIN32 785 const UInt64 startTime = Get_timeofday_us(); 786 #endif 787 788 /* 789 { 790 g_StdOut << "DWORD:" << (unsigned)sizeof(DWORD); 791 g_StdOut << " LONG:" << (unsigned)sizeof(LONG); 792 g_StdOut << " long:" << (unsigned)sizeof(long); 793 #ifdef _WIN64 794 // g_StdOut << " long long:" << (unsigned)sizeof(long long); 795 #endif 796 g_StdOut << " int:" << (unsigned)sizeof(int); 797 g_StdOut << " void*:" << (unsigned)sizeof(void *); 798 g_StdOut << endl; 799 } 800 */ 801 802 UStringVector commandStrings; 803 804 #ifdef _WIN32 805 NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); 806 #else 807 { 808 if (numArgs > 0) 809 Set_ModuleDirPrefix_From_ProgArg0(args[0]); 810 811 for (int i = 0; i < numArgs; i++) 812 { 813 AString a (args[i]); 814 /* 815 printf("\n%d %s :", i, a.Ptr()); 816 for (unsigned k = 0; k < a.Len(); k++) 817 printf(" %2x", (unsigned)(Byte)a[k]); 818 */ 819 const UString s = MultiByteToUnicodeString(a); 820 commandStrings.Add(s); 821 } 822 // printf("\n"); 823 } 824 825 #endif 826 827 #ifndef UNDER_CE 828 if (commandStrings.Size() > 0) 829 commandStrings.Delete(0); 830 #endif 831 832 if (commandStrings.Size() == 0) 833 { 834 ShowCopyrightAndHelp(g_StdStream, true); 835 return 0; 836 } 837 838 CArcCmdLineOptions options; 839 840 CArcCmdLineParser parser; 841 842 parser.Parse1(commandStrings, options); 843 844 g_StdOut.IsTerminalMode = options.IsStdOutTerminal; 845 g_StdErr.IsTerminalMode = options.IsStdErrTerminal; 846 847 if (options.Number_for_Out != k_OutStream_stdout) 848 g_StdStream = (options.Number_for_Out == k_OutStream_stderr ? &g_StdErr : NULL); 849 850 if (options.Number_for_Errors != k_OutStream_stderr) 851 g_ErrStream = (options.Number_for_Errors == k_OutStream_stdout ? &g_StdOut : NULL); 852 853 CStdOutStream *percentsStream = NULL; 854 if (options.Number_for_Percents != k_OutStream_disabled) 855 percentsStream = (options.Number_for_Percents == k_OutStream_stderr) ? &g_StdErr : &g_StdOut; 856 857 if (options.HelpMode) 858 { 859 ShowCopyrightAndHelp(g_StdStream, true); 860 return 0; 861 } 862 863 if (options.EnableHeaders) 864 { 865 ShowCopyrightAndHelp(g_StdStream, false); 866 if (!parser.Parse1Log.IsEmpty()) 867 *g_StdStream << parser.Parse1Log; 868 } 869 870 parser.Parse2(options); 871 872 { 873 int cp = options.ConsoleCodePage; 874 875 int stdout_cp = cp; 876 int stderr_cp = cp; 877 int stdin_cp = cp; 878 879 /* 880 // these cases are complicated. 881 // maybe we must use CRT functions instead of console WIN32. 882 // different Windows/CRT versions also can work different ways. 883 // so the following code was not enabled: 884 if (cp == -1) 885 { 886 // we set CodePage only if stream is attached to terminal 887 // maybe we should set CodePage even if is not terminal? 888 #ifdef _WIN32 889 { 890 UINT ccp = GetConsoleOutputCP(); 891 if (ccp != 0) 892 { 893 if (options.IsStdOutTerminal) stdout_cp = ccp; 894 if (options.IsStdErrTerminal) stderr_cp = ccp; 895 } 896 } 897 if (options.IsInTerminal) 898 { 899 UINT ccp = GetConsoleCP(); 900 if (ccp != 0) stdin_cp = ccp; 901 } 902 #endif 903 } 904 */ 905 906 if (stdout_cp != -1) g_StdOut.CodePage = stdout_cp; 907 if (stderr_cp != -1) g_StdErr.CodePage = stderr_cp; 908 if (stdin_cp != -1) g_StdIn.CodePage = stdin_cp; 909 } 910 911 unsigned percentsNameLevel = 1; 912 if (options.LogLevel == 0 || options.Number_for_Percents != options.Number_for_Out) 913 percentsNameLevel = 2; 914 915 unsigned consoleWidth = 80; 916 917 if (percentsStream) 918 { 919 #ifdef _WIN32 920 921 #if !defined(UNDER_CE) 922 CONSOLE_SCREEN_BUFFER_INFO consoleInfo; 923 if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo)) 924 consoleWidth = (unsigned)(unsigned short)consoleInfo.dwSize.X; 925 #endif 926 927 #else 928 929 struct winsize w; 930 if (ioctl(0, TIOCGWINSZ, &w) == 0) 931 consoleWidth = w.ws_col; 932 933 #endif 934 } 935 936 CREATE_CODECS_OBJECT 937 938 codecs->CaseSensitive_Change = options.CaseSensitive_Change; 939 codecs->CaseSensitive = options.CaseSensitive; 940 ThrowException_if_Error(codecs->Load()); 941 Codecs_AddHashArcHandler(codecs); 942 943 #ifdef Z7_EXTERNAL_CODECS 944 { 945 g_ExternalCodecs_Ptr = &_externalCodecs; 946 UString s; 947 codecs->GetCodecsErrorMessage(s); 948 if (!s.IsEmpty()) 949 { 950 CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); 951 so << endl << s << endl; 952 } 953 } 954 #endif 955 956 const bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); 957 958 if (codecs->Formats.Size() == 0 && 959 (isExtractGroupCommand 960 || options.Command.CommandType == NCommandType::kList 961 || options.Command.IsFromUpdateGroup())) 962 { 963 #ifdef Z7_EXTERNAL_CODECS 964 if (!codecs->MainDll_ErrorPath.IsEmpty()) 965 { 966 UString s ("Can't load module: "); 967 s += fs2us(codecs->MainDll_ErrorPath); 968 throw s; 969 } 970 #endif 971 throw kNoFormats; 972 } 973 974 CObjectVector<COpenType> types; 975 if (!ParseOpenTypes(*codecs, options.ArcType, types)) 976 { 977 throw kUnsupportedArcTypeMessage; 978 } 979 980 981 CIntVector excludedFormats; 982 FOR_VECTOR (k, options.ExcludedArcTypes) 983 { 984 CIntVector tempIndices; 985 if (!codecs->FindFormatForArchiveType(options.ExcludedArcTypes[k], tempIndices) 986 || tempIndices.Size() != 1) 987 throw kUnsupportedArcTypeMessage; 988 989 990 991 excludedFormats.AddToUniqueSorted(tempIndices[0]); 992 // excludedFormats.Sort(); 993 } 994 995 #ifdef Z7_EXTERNAL_CODECS 996 if (isExtractGroupCommand 997 || options.Command.IsFromUpdateGroup() 998 || options.Command.CommandType == NCommandType::kHash 999 || options.Command.CommandType == NCommandType::kBenchmark) 1000 ThrowException_if_Error(_externalCodecs.Load()); 1001 #endif 1002 1003 int retCode = NExitCode::kSuccess; 1004 HRESULT hresultMain = S_OK; 1005 1006 // bool showStat = options.ShowTime; 1007 1008 /* 1009 if (!options.EnableHeaders || 1010 options.TechMode) 1011 showStat = false; 1012 */ 1013 1014 1015 if (options.Command.CommandType == NCommandType::kInfo) 1016 { 1017 CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); 1018 unsigned i; 1019 1020 #ifdef Z7_EXTERNAL_CODECS 1021 so << endl << "Libs:" << endl; 1022 for (i = 0; i < codecs->Libs.Size(); i++) 1023 { 1024 PrintLibIndex(so, (int)i); 1025 const CCodecLib &lib = codecs->Libs[i]; 1026 // if (lib.Version != 0) 1027 so << ": " << (lib.Version >> 16) << "."; 1028 PrintNumber(so, lib.Version & 0xffff, 2); 1029 so << " : " << lib.Path << endl; 1030 } 1031 #endif 1032 1033 so << endl << "Formats:" << endl; 1034 1035 const char * const kArcFlags = "KSNFMGOPBELHXCc+a+m+r+"; 1036 const char * const kArcTimeFlags = "wudn"; 1037 const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags); 1038 const unsigned kNumArcTimeFlags = (unsigned)strlen(kArcTimeFlags); 1039 1040 for (i = 0; i < codecs->Formats.Size(); i++) 1041 { 1042 const CArcInfoEx &arc = codecs->Formats[i]; 1043 1044 #ifdef Z7_EXTERNAL_CODECS 1045 PrintLibIndex(so, arc.LibIndex); 1046 #else 1047 so << " "; 1048 #endif 1049 1050 so << (char)(arc.UpdateEnabled ? 'C' : ' '); 1051 1052 { 1053 unsigned b; 1054 for (b = 0; b < kNumArcFlags; b++) 1055 so << (char)((arc.Flags & ((UInt32)1 << b)) != 0 ? kArcFlags[b] : '.'); 1056 so << ' '; 1057 } 1058 1059 if (arc.TimeFlags != 0) 1060 { 1061 unsigned b; 1062 for (b = 0; b < kNumArcTimeFlags; b++) 1063 so << (char)((arc.TimeFlags & ((UInt32)1 << b)) != 0 ? kArcTimeFlags[b] : '.'); 1064 so << arc.Get_DefaultTimePrec(); 1065 so << ' '; 1066 } 1067 1068 so << ' '; 1069 PrintString(so, arc.Name, 8); 1070 so << ' '; 1071 UString s; 1072 1073 FOR_VECTOR (t, arc.Exts) 1074 { 1075 if (t != 0) 1076 s.Add_Space(); 1077 const CArcExtInfo &ext = arc.Exts[t]; 1078 s += ext.Ext; 1079 if (!ext.AddExt.IsEmpty()) 1080 { 1081 s += " ("; 1082 s += ext.AddExt; 1083 s += ')'; 1084 } 1085 } 1086 1087 PrintString(so, s, 13); 1088 so << ' '; 1089 1090 if (arc.SignatureOffset != 0) 1091 so << "offset=" << arc.SignatureOffset << ' '; 1092 1093 // so << "numSignatures = " << arc.Signatures.Size() << " "; 1094 1095 FOR_VECTOR(si, arc.Signatures) 1096 { 1097 if (si != 0) 1098 so << " || "; 1099 1100 const CByteBuffer &sig = arc.Signatures[si]; 1101 1102 for (size_t j = 0; j < sig.Size(); j++) 1103 { 1104 if (j != 0) 1105 so << ' '; 1106 Byte b = sig[j]; 1107 if (b > 0x20 && b < 0x80) 1108 { 1109 so << (char)b; 1110 } 1111 else 1112 { 1113 so << GetHex((b >> 4) & 0xF); 1114 so << GetHex(b & 0xF); 1115 } 1116 } 1117 } 1118 so << endl; 1119 } 1120 1121 so << endl << "Codecs:" << endl; // << "Lib ID Name" << endl; 1122 1123 for (i = 0; i < g_NumCodecs; i++) 1124 { 1125 const CCodecInfo &cod = *g_Codecs[i]; 1126 1127 PrintLibIndex(so, -1); 1128 1129 if (cod.NumStreams == 1) 1130 so << ' '; 1131 else 1132 so << cod.NumStreams; 1133 1134 so << (char)(cod.CreateEncoder ? 'E' : ' '); 1135 so << (char)(cod.CreateDecoder ? 'D' : ' '); 1136 so << (char)(cod.IsFilter ? 'F' : ' '); 1137 1138 so << ' '; 1139 PrintHexId(so, cod.Id); 1140 so << ' ' << cod.Name << endl; 1141 } 1142 1143 1144 #ifdef Z7_EXTERNAL_CODECS 1145 1146 UInt32 numMethods; 1147 if (_externalCodecs.GetCodecs->GetNumMethods(&numMethods) == S_OK) 1148 for (UInt32 j = 0; j < numMethods; j++) 1149 { 1150 PrintLibIndex(so, codecs->GetCodec_LibIndex(j)); 1151 1152 UInt32 numStreams = codecs->GetCodec_NumStreams(j); 1153 if (numStreams == 1) 1154 so << ' '; 1155 else 1156 so << numStreams; 1157 1158 so << (char)(codecs->GetCodec_EncoderIsAssigned(j) ? 'E' : ' '); 1159 so << (char)(codecs->GetCodec_DecoderIsAssigned(j) ? 'D' : ' '); 1160 { 1161 bool isFilter_Assigned; 1162 const bool isFilter = codecs->GetCodec_IsFilter(j, isFilter_Assigned); 1163 so << (char)(isFilter ? 'F' : isFilter_Assigned ? ' ' : '*'); 1164 } 1165 1166 1167 so << ' '; 1168 UInt64 id; 1169 HRESULT res = codecs->GetCodec_Id(j, id); 1170 if (res != S_OK) 1171 id = (UInt64)(Int64)-1; 1172 PrintHexId(so, id); 1173 so << ' ' << codecs->GetCodec_Name(j) << endl; 1174 } 1175 1176 #endif 1177 1178 1179 so << endl << "Hashers:" << endl; // << " L Size ID Name" << endl; 1180 1181 for (i = 0; i < g_NumHashers; i++) 1182 { 1183 const CHasherInfo &codec = *g_Hashers[i]; 1184 PrintLibIndex(so, -1); 1185 PrintUInt32(so, codec.DigestSize, 4); 1186 so << ' '; 1187 PrintHexId(so, codec.Id); 1188 so << ' ' << codec.Name << endl; 1189 } 1190 1191 #ifdef Z7_EXTERNAL_CODECS 1192 1193 numMethods = _externalCodecs.GetHashers->GetNumHashers(); 1194 for (UInt32 j = 0; j < numMethods; j++) 1195 { 1196 PrintLibIndex(so, codecs->GetHasherLibIndex(j)); 1197 PrintUInt32(so, codecs->GetHasherDigestSize(j), 4); 1198 so << ' '; 1199 PrintHexId(so, codecs->GetHasherId(j)); 1200 so << ' ' << codecs->GetHasherName(j) << endl; 1201 } 1202 1203 #endif 1204 1205 } 1206 else if (options.Command.CommandType == NCommandType::kBenchmark) 1207 { 1208 CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); 1209 hresultMain = BenchCon(EXTERNAL_CODECS_VARS_L 1210 options.Properties, options.NumIterations, (FILE *)so); 1211 if (hresultMain == S_FALSE) 1212 { 1213 so << endl; 1214 if (g_ErrStream) 1215 *g_ErrStream << "\nDecoding ERROR\n"; 1216 retCode = NExitCode::kFatalError; 1217 hresultMain = S_OK; 1218 } 1219 } 1220 else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList) 1221 { 1222 UStringVector ArchivePathsSorted; 1223 UStringVector ArchivePathsFullSorted; 1224 1225 if (options.StdInMode) 1226 { 1227 ArchivePathsSorted.Add(options.ArcName_for_StdInMode); 1228 ArchivePathsFullSorted.Add(options.ArcName_for_StdInMode); 1229 } 1230 else 1231 { 1232 CExtractScanConsole scan; 1233 1234 scan.Init(options.EnableHeaders ? g_StdStream : NULL, g_ErrStream, percentsStream); 1235 scan.SetWindowWidth(consoleWidth); 1236 1237 if (g_StdStream && options.EnableHeaders) 1238 *g_StdStream << "Scanning the drive for archives:" << endl; 1239 1240 CDirItemsStat st; 1241 1242 scan.StartScanning(); 1243 1244 hresultMain = EnumerateDirItemsAndSort( 1245 options.arcCensor, 1246 NWildcard::k_RelatPath, 1247 UString(), // addPathPrefix 1248 ArchivePathsSorted, 1249 ArchivePathsFullSorted, 1250 st, 1251 &scan); 1252 1253 scan.CloseScanning(); 1254 1255 if (hresultMain == S_OK) 1256 { 1257 if (options.EnableHeaders) 1258 scan.PrintStat(st); 1259 } 1260 else 1261 { 1262 /* 1263 if (res != E_ABORT) 1264 { 1265 throw CSystemException(res); 1266 // errorInfo.Message = "Scanning error"; 1267 } 1268 return res; 1269 */ 1270 } 1271 } 1272 1273 if (hresultMain == S_OK) { 1274 if (isExtractGroupCommand) 1275 { 1276 CExtractCallbackConsole *ecs = new CExtractCallbackConsole; 1277 CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; 1278 1279 #ifndef Z7_NO_CRYPTO 1280 ecs->PasswordIsDefined = options.PasswordEnabled; 1281 ecs->Password = options.Password; 1282 #endif 1283 1284 ecs->Init(g_StdStream, g_ErrStream, percentsStream); 1285 ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1); 1286 1287 ecs->LogLevel = options.LogLevel; 1288 ecs->PercentsNameLevel = percentsNameLevel; 1289 1290 if (percentsStream) 1291 ecs->SetWindowWidth(consoleWidth); 1292 1293 /* 1294 COpenCallbackConsole openCallback; 1295 openCallback.Init(g_StdStream, g_ErrStream); 1296 1297 #ifndef Z7_NO_CRYPTO 1298 openCallback.PasswordIsDefined = options.PasswordEnabled; 1299 openCallback.Password = options.Password; 1300 #endif 1301 */ 1302 1303 CExtractOptions eo; 1304 (CExtractOptionsBase &)eo = options.ExtractOptions; 1305 1306 eo.StdInMode = options.StdInMode; 1307 eo.StdOutMode = options.StdOutMode; 1308 eo.YesToAll = options.YesToAll; 1309 eo.TestMode = options.Command.IsTestCommand(); 1310 1311 #ifndef Z7_SFX 1312 eo.Properties = options.Properties; 1313 #endif 1314 1315 UString errorMessage; 1316 CDecompressStat stat; 1317 CHashBundle hb; 1318 IHashCalc *hashCalc = NULL; 1319 1320 if (!options.HashMethods.IsEmpty()) 1321 { 1322 hashCalc = &hb; 1323 ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS_L options.HashMethods)); 1324 // hb.Init(); 1325 } 1326 1327 hresultMain = Extract( 1328 // EXTERNAL_CODECS_VARS_L 1329 codecs, 1330 types, 1331 excludedFormats, 1332 ArchivePathsSorted, 1333 ArchivePathsFullSorted, 1334 options.Censor.Pairs.Front().Head, 1335 eo, 1336 ecs, ecs, ecs, 1337 hashCalc, errorMessage, stat); 1338 1339 ecs->ClosePercents(); 1340 1341 if (!errorMessage.IsEmpty()) 1342 { 1343 if (g_ErrStream) 1344 *g_ErrStream << endl << "ERROR:" << endl << errorMessage << endl; 1345 if (hresultMain == S_OK) 1346 hresultMain = E_FAIL; 1347 } 1348 1349 CStdOutStream *so = g_StdStream; 1350 1351 bool isError = false; 1352 1353 if (so) 1354 { 1355 *so << endl; 1356 1357 if (ecs->NumTryArcs > 1) 1358 { 1359 *so << "Archives: " << ecs->NumTryArcs << endl; 1360 *so << "OK archives: " << ecs->NumOkArcs << endl; 1361 } 1362 } 1363 1364 if (ecs->NumCantOpenArcs != 0) 1365 { 1366 isError = true; 1367 if (so) 1368 *so << "Can't open as archive: " << ecs->NumCantOpenArcs << endl; 1369 } 1370 1371 if (ecs->NumArcsWithError != 0) 1372 { 1373 isError = true; 1374 if (so) 1375 *so << "Archives with Errors: " << ecs->NumArcsWithError << endl; 1376 } 1377 1378 if (so) 1379 { 1380 if (ecs->NumArcsWithWarnings != 0) 1381 *so << "Archives with Warnings: " << ecs->NumArcsWithWarnings << endl; 1382 1383 if (ecs->NumOpenArcWarnings != 0) 1384 { 1385 *so << endl; 1386 if (ecs->NumOpenArcWarnings != 0) 1387 *so << "Warnings: " << ecs->NumOpenArcWarnings << endl; 1388 } 1389 } 1390 1391 if (ecs->NumOpenArcErrors != 0) 1392 { 1393 isError = true; 1394 if (so) 1395 { 1396 *so << endl; 1397 if (ecs->NumOpenArcErrors != 0) 1398 *so << "Open Errors: " << ecs->NumOpenArcErrors << endl; 1399 } 1400 } 1401 1402 if (isError) 1403 retCode = NExitCode::kFatalError; 1404 1405 if (so) { 1406 if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0) 1407 { 1408 // if (ecs->NumArchives > 1) 1409 { 1410 *so << endl; 1411 if (ecs->NumFileErrors != 0) 1412 *so << "Sub items Errors: " << ecs->NumFileErrors << endl; 1413 } 1414 } 1415 else if (hresultMain == S_OK) 1416 { 1417 if (stat.NumFolders != 0) 1418 *so << "Folders: " << stat.NumFolders << endl; 1419 if (stat.NumFiles != 1 || stat.NumFolders != 0 || stat.NumAltStreams != 0) 1420 *so << "Files: " << stat.NumFiles << endl; 1421 if (stat.NumAltStreams != 0) 1422 { 1423 *so << "Alternate Streams: " << stat.NumAltStreams << endl; 1424 *so << "Alternate Streams Size: " << stat.AltStreams_UnpackSize << endl; 1425 } 1426 1427 *so 1428 << "Size: " << stat.UnpackSize << endl 1429 << "Compressed: " << stat.PackSize << endl; 1430 if (hashCalc) 1431 { 1432 *so << endl; 1433 PrintHashStat(*so, hb); 1434 } 1435 } 1436 } // if (so) 1437 } 1438 else // if_(!isExtractGroupCommand) 1439 { 1440 UInt64 numErrors = 0; 1441 UInt64 numWarnings = 0; 1442 1443 // options.ExtractNtOptions.StoreAltStreams = true, if -sns[-] is not definmed 1444 1445 CListOptions lo; 1446 lo.ExcludeDirItems = options.Censor.ExcludeDirItems; 1447 lo.ExcludeFileItems = options.Censor.ExcludeFileItems; 1448 1449 hresultMain = ListArchives( 1450 lo, 1451 codecs, 1452 types, 1453 excludedFormats, 1454 options.StdInMode, 1455 ArchivePathsSorted, 1456 ArchivePathsFullSorted, 1457 options.ExtractOptions.NtOptions.AltStreams.Val, 1458 options.AltStreams.Val, // we don't want to show AltStreams by default 1459 options.Censor.Pairs.Front().Head, 1460 options.EnableHeaders, 1461 options.TechMode, 1462 #ifndef Z7_NO_CRYPTO 1463 options.PasswordEnabled, 1464 options.Password, 1465 #endif 1466 &options.Properties, 1467 numErrors, numWarnings); 1468 1469 if (options.EnableHeaders) 1470 if (numWarnings > 0) 1471 g_StdOut << endl << "Warnings: " << numWarnings << endl; 1472 1473 if (numErrors > 0) 1474 { 1475 if (options.EnableHeaders) 1476 g_StdOut << endl << "Errors: " << numErrors << endl; 1477 retCode = NExitCode::kFatalError; 1478 } 1479 } // if_(isExtractGroupCommand) 1480 } // if_(hresultMain == S_OK) 1481 } 1482 else if (options.Command.IsFromUpdateGroup()) 1483 { 1484 CUpdateOptions &uo = options.UpdateOptions; 1485 if (uo.SfxMode && uo.SfxModule.IsEmpty()) 1486 uo.SfxModule = kDefaultSfxModule; 1487 1488 COpenCallbackConsole openCallback; 1489 openCallback.Init(g_StdStream, g_ErrStream, percentsStream); 1490 1491 #ifndef Z7_NO_CRYPTO 1492 bool passwordIsDefined = 1493 (options.PasswordEnabled && !options.Password.IsEmpty()); 1494 openCallback.PasswordIsDefined = passwordIsDefined; 1495 openCallback.Password = options.Password; 1496 #endif 1497 1498 CUpdateCallbackConsole callback; 1499 callback.LogLevel = options.LogLevel; 1500 callback.PercentsNameLevel = percentsNameLevel; 1501 1502 if (percentsStream) 1503 callback.SetWindowWidth(consoleWidth); 1504 1505 #ifndef Z7_NO_CRYPTO 1506 callback.PasswordIsDefined = passwordIsDefined; 1507 callback.AskPassword = (options.PasswordEnabled && options.Password.IsEmpty()); 1508 callback.Password = options.Password; 1509 #endif 1510 1511 callback.StdOutMode = uo.StdOutMode; 1512 callback.Init( 1513 // NULL, 1514 g_StdStream, g_ErrStream, percentsStream); 1515 1516 CUpdateErrorInfo errorInfo; 1517 1518 /* 1519 if (!uo.Init(codecs, types, options.ArchiveName)) 1520 throw kUnsupportedUpdateArcType; 1521 */ 1522 hresultMain = UpdateArchive(codecs, 1523 types, 1524 options.ArchiveName, 1525 options.Censor, 1526 uo, 1527 errorInfo, &openCallback, &callback, true); 1528 1529 callback.ClosePercents2(); 1530 1531 CStdOutStream *se = g_StdStream; 1532 if (!se) 1533 se = g_ErrStream; 1534 1535 retCode = WarningsCheck(hresultMain, callback, errorInfo, 1536 g_StdStream, se, 1537 true // options.EnableHeaders 1538 ); 1539 } 1540 else if (options.Command.CommandType == NCommandType::kHash) 1541 { 1542 const CHashOptions &uo = options.HashOptions; 1543 1544 CHashCallbackConsole callback; 1545 if (percentsStream) 1546 callback.SetWindowWidth(consoleWidth); 1547 1548 callback.Init(g_StdStream, g_ErrStream, percentsStream); 1549 callback.PrintHeaders = options.EnableHeaders; 1550 callback.PrintFields = options.ListFields; 1551 1552 AString errorInfoString; 1553 hresultMain = HashCalc(EXTERNAL_CODECS_VARS_L 1554 options.Censor, uo, 1555 errorInfoString, &callback); 1556 CUpdateErrorInfo errorInfo; 1557 errorInfo.Message = errorInfoString; 1558 CStdOutStream *se = g_StdStream; 1559 if (!se) 1560 se = g_ErrStream; 1561 retCode = WarningsCheck(hresultMain, callback, errorInfo, g_StdStream, se, options.EnableHeaders); 1562 } 1563 else 1564 ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError); 1565 1566 if (options.ShowTime && g_StdStream) 1567 PrintStat( 1568 #ifndef _WIN32 1569 startTime 1570 #endif 1571 ); 1572 1573 ThrowException_if_Error(hresultMain); 1574 1575 return retCode; 1576} 1577