123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- static bool AnyMessageDisplayed=false; // For console -idn switch.
- // Purely user interface function. Gets and returns user input.
- UIASKREP_RESULT uiAskReplace(wchar *Name,size_t MaxNameSize,int64 FileSize,RarTime *FileTime,uint Flags)
- {
- wchar SizeText1[20],DateStr1[50],SizeText2[20],DateStr2[50];
- FindData ExistingFD;
- memset(&ExistingFD,0,sizeof(ExistingFD)); // In case find fails.
- FindFile::FastFind(Name,&ExistingFD);
- itoa(ExistingFD.Size,SizeText1,ASIZE(SizeText1));
- ExistingFD.mtime.GetText(DateStr1,ASIZE(DateStr1),false);
- if (FileSize==INT64NDF || FileTime==NULL)
- {
- eprintf(L"\n");
- eprintf(St(MAskOverwrite),Name);
- }
- else
- {
- itoa(FileSize,SizeText2,ASIZE(SizeText2));
- FileTime->GetText(DateStr2,ASIZE(DateStr2),false);
- if ((Flags & UIASKREP_F_EXCHSRCDEST)==0)
- eprintf(St(MAskReplace),Name,SizeText1,DateStr1,SizeText2,DateStr2);
- else
- eprintf(St(MAskReplace),Name,SizeText2,DateStr2,SizeText1,DateStr1);
- }
- bool AllowRename=(Flags & UIASKREP_F_NORENAME)==0;
- int Choice=0;
- do
- {
- Choice=Ask(St(AllowRename ? MYesNoAllRenQ : MYesNoAllQ));
- } while (Choice==0); // 0 means invalid input.
- switch(Choice)
- {
- case 1:
- return UIASKREP_R_REPLACE;
- case 2:
- return UIASKREP_R_SKIP;
- case 3:
- return UIASKREP_R_REPLACEALL;
- case 4:
- return UIASKREP_R_SKIPALL;
- }
- if (AllowRename && Choice==5)
- {
- mprintf(St(MAskNewName));
- if (getwstr(Name,MaxNameSize))
- return UIASKREP_R_RENAME;
- else
- return UIASKREP_R_SKIP; // Process fwgets failure as if user answered 'No'.
- }
- return UIASKREP_R_CANCEL;
- }
- void uiStartArchiveExtract(bool Extract,const wchar *ArcName)
- {
- mprintf(St(Extract ? MExtracting : MExtrTest), ArcName);
- }
- bool uiStartFileExtract(const wchar *FileName,bool Extract,bool Test,bool Skip)
- {
- return true;
- }
- void uiExtractProgress(int64 CurFileSize,int64 TotalFileSize,int64 CurSize,int64 TotalSize)
- {
- // We set the total size to 0 to update only the current progress and keep
- // the total progress intact in WinRAR. Unlike WinRAR, console RAR has only
- // the total progress and updates it with current values in such case.
- int CurPercent=TotalSize!=0 ? ToPercent(CurSize,TotalSize) : ToPercent(CurFileSize,TotalFileSize);
- mprintf(L"\b\b\b\b%3d%%",CurPercent);
- }
- void uiProcessProgress(const char *Command,int64 CurSize,int64 TotalSize)
- {
- int CurPercent=ToPercent(CurSize,TotalSize);
- mprintf(L"\b\b\b\b%3d%%",CurPercent);
- }
- void uiMsgStore::Msg()
- {
- // When creating volumes, AnyMessageDisplayed must be reset for UIEVENT_NEWARCHIVE,
- // so it ignores this and all earlier messages like UIEVENT_PROTECTEND
- // and UIEVENT_PROTECTEND, because they precede "Creating archive" message
- // and do not interfere with -idn and file names. If we do not ignore them,
- // uiEolAfterMsg() in uiStartFileAddit() can cause unneeded carriage return
- // in archiving percent after creating a new volume with -v -idn (and -rr
- // for UIEVENT_PROTECT*) switches. AnyMessageDisplayed is set for messages
- // after UIEVENT_NEWARCHIVE, so archiving percent with -idn is moved to
- // next line and does not delete their last characters.
- // Similarly we ignore UIEVENT_RRTESTINGEND for volumes, because it is issued
- // before "Testing archive" and would add an excessive \n otherwise.
- AnyMessageDisplayed=(Code!=UIEVENT_NEWARCHIVE && Code!=UIEVENT_RRTESTINGEND);
- switch(Code)
- {
- case UIERROR_SYSERRMSG:
- case UIERROR_GENERALERRMSG:
- Log(NULL,L"\n%ls",Str[0]);
- break;
- case UIERROR_CHECKSUM:
- Log(Str[0],St(MCRCFailed),Str[1]);
- break;
- case UIERROR_CHECKSUMENC:
- Log(Str[0],St(MEncrBadCRC),Str[1]);
- break;
- case UIERROR_CHECKSUMPACKED:
- Log(Str[0],St(MDataBadCRC),Str[1],Str[0]);
- break;
- case UIERROR_BADPSW:
- Log(Str[0],St(MWrongFilePassword),Str[1]);
- break;
- case UIWAIT_BADPSW:
- Log(Str[0],St(MWrongPassword));
- break;
- case UIERROR_MEMORY:
- mprintf(L"\n");
- Log(NULL,St(MErrOutMem));
- break;
- case UIERROR_FILEOPEN:
- Log(Str[0],St(MCannotOpen),Str[1]);
- break;
- case UIERROR_FILECREATE:
- Log(Str[0],St(MCannotCreate),Str[1]);
- break;
- case UIERROR_FILECLOSE:
- Log(NULL,St(MErrFClose),Str[0]);
- break;
- case UIERROR_FILESEEK:
- Log(NULL,St(MErrSeek),Str[0]);
- break;
- case UIERROR_FILEREAD:
- mprintf(L"\n");
- Log(Str[0],St(MErrRead),Str[1]);
- break;
- case UIERROR_FILEWRITE:
- Log(Str[0],St(MErrWrite),Str[1]);
- break;
- #ifndef SFX_MODULE
- case UIERROR_FILEDELETE:
- Log(Str[0],St(MCannotDelete),Str[1]);
- break;
- case UIERROR_RECYCLEFAILED:
- Log(Str[0],St(MRecycleFailed));
- break;
- case UIERROR_FILERENAME:
- Log(Str[0],St(MErrRename),Str[1],Str[2]);
- break;
- #endif
- case UIERROR_FILEATTR:
- Log(Str[0],St(MErrChangeAttr),Str[1]);
- break;
- case UIERROR_FILECOPY:
- Log(Str[0],St(MCopyError),Str[1],Str[2]);
- break;
- case UIERROR_FILECOPYHINT:
- Log(Str[0],St(MCopyErrorHint));
- mprintf(L" "); // For progress percent.
- break;
- case UIERROR_DIRCREATE:
- Log(Str[0],St(MExtrErrMkDir),Str[1]);
- break;
- case UIERROR_SLINKCREATE:
- Log(Str[0],St(MErrCreateLnkS),Str[1]);
- break;
- case UIERROR_HLINKCREATE:
- Log(NULL,St(MErrCreateLnkH),Str[0]);
- break;
- case UIERROR_NOLINKTARGET:
- Log(NULL,St(MErrLnkTarget));
- mprintf(L" "); // For progress percent.
- break;
- case UIERROR_NEEDADMIN:
- Log(NULL,St(MNeedAdmin));
- break;
- case UIERROR_ARCBROKEN:
- Log(Str[0],St(MErrBrokenArc));
- break;
- case UIERROR_HEADERBROKEN:
- Log(Str[0],St(MHeaderBroken));
- break;
- case UIERROR_MHEADERBROKEN:
- Log(Str[0],St(MMainHeaderBroken));
- break;
- case UIERROR_FHEADERBROKEN:
- Log(Str[0],St(MLogFileHead),Str[1]);
- break;
- case UIERROR_SUBHEADERBROKEN:
- Log(Str[0],St(MSubHeadCorrupt));
- break;
- case UIERROR_SUBHEADERUNKNOWN:
- Log(Str[0],St(MSubHeadUnknown));
- break;
- case UIERROR_SUBHEADERDATABROKEN:
- Log(Str[0],St(MSubHeadDataCRC),Str[1]);
- break;
- case UIERROR_RRDAMAGED:
- Log(Str[0],St(MRRDamaged));
- break;
- case UIERROR_UNKNOWNMETHOD:
- Log(Str[0],St(MUnknownMeth),Str[1]);
- break;
- case UIERROR_UNKNOWNENCMETHOD:
- {
- wchar Msg[256];
- swprintf(Msg,ASIZE(Msg),St(MUnkEncMethod),Str[1]);
- Log(Str[0],L"%s: %s",Msg,Str[2]);
- }
- break;
- #ifndef SFX_MODULE
- case UIERROR_RENAMING:
- Log(Str[0],St(MRenaming),Str[1],Str[2]);
- break;
- case UIERROR_NEWERRAR:
- Log(Str[0],St(MNewerRAR));
- break;
- #endif
- case UIERROR_RECVOLDIFFSETS:
- Log(NULL,St(MRecVolDiffSets),Str[0],Str[1]);
- break;
- case UIERROR_RECVOLALLEXIST:
- mprintf(St(MRecVolAllExist));
- break;
- case UIERROR_RECONSTRUCTING:
- mprintf(St(MReconstructing));
- break;
- case UIERROR_RECVOLCANNOTFIX:
- mprintf(St(MRecVolCannotFix));
- break;
- case UIERROR_UNEXPEOF:
- Log(Str[0],St(MLogUnexpEOF));
- break;
- case UIERROR_BADARCHIVE:
- Log(Str[0],St(MBadArc),Str[0]);
- break;
- case UIERROR_CMTBROKEN:
- Log(Str[0],St(MLogCommBrk));
- break;
- case UIERROR_INVALIDNAME:
- Log(Str[0],St(MInvalidName),Str[1]);
- mprintf(L"\n"); // Needed when called from CmdExtract::ExtractCurrentFile.
- break;
- #ifndef SFX_MODULE
- case UIERROR_OPFAILED:
- Log(NULL,St(MOpFailed));
- break;
- case UIERROR_NEWRARFORMAT:
- Log(Str[0],St(MNewRarFormat));
- break;
- #endif
- case UIERROR_NOFILESTOEXTRACT:
- mprintf(St(MExtrNoFiles));
- break;
- case UIERROR_MISSINGVOL:
- Log(Str[0],St(MAbsNextVol),Str[0]);
- break;
- #ifndef SFX_MODULE
- case UIERROR_NEEDPREVVOL:
- Log(Str[0],St(MUnpCannotMerge),Str[1]);
- break;
- case UIERROR_UNKNOWNEXTRA:
- Log(Str[0],St(MUnknownExtra),Str[1]);
- break;
- case UIERROR_CORRUPTEXTRA:
- Log(Str[0],St(MCorruptExtra),Str[1],Str[2]);
- break;
- #endif
- #if !defined(SFX_MODULE) && defined(_WIN_ALL)
- case UIERROR_NTFSREQUIRED:
- Log(NULL,St(MNTFSRequired),Str[0]);
- break;
- #endif
- #if !defined(SFX_MODULE) && defined(_WIN_ALL)
- case UIERROR_ACLBROKEN:
- Log(Str[0],St(MACLBroken),Str[1]);
- break;
- case UIERROR_ACLUNKNOWN:
- Log(Str[0],St(MACLUnknown),Str[1]);
- break;
- case UIERROR_ACLSET:
- Log(Str[0],St(MACLSetError),Str[1]);
- break;
- case UIERROR_STREAMBROKEN:
- Log(Str[0],St(MStreamBroken),Str[1]);
- break;
- case UIERROR_STREAMUNKNOWN:
- Log(Str[0],St(MStreamUnknown),Str[1]);
- break;
- #endif
- case UIERROR_INCOMPATSWITCH:
- mprintf(St(MIncompatSwitch),Str[0],Num[0]);
- break;
- case UIERROR_PATHTOOLONG:
- Log(NULL,L"\n%ls%ls%ls",Str[0],Str[1],Str[2]);
- Log(NULL,St(MPathTooLong));
- break;
- #ifndef SFX_MODULE
- case UIERROR_DIRSCAN:
- Log(NULL,St(MScanError),Str[0]);
- break;
- #endif
- case UIERROR_UOWNERBROKEN:
- Log(Str[0],St(MOwnersBroken),Str[1]);
- break;
- case UIERROR_UOWNERGETOWNERID:
- Log(Str[0],St(MErrGetOwnerID),Str[1]);
- break;
- case UIERROR_UOWNERGETGROUPID:
- Log(Str[0],St(MErrGetGroupID),Str[1]);
- break;
- case UIERROR_UOWNERSET:
- Log(Str[0],St(MSetOwnersError),Str[1]);
- break;
- case UIERROR_ULINKREAD:
- Log(NULL,St(MErrLnkRead),Str[0]);
- break;
- case UIERROR_ULINKEXIST:
- Log(NULL,St(MSymLinkExists),Str[0]);
- break;
- case UIERROR_READERRTRUNCATED:
- Log(NULL,St(MErrReadTrunc),Str[0]);
- break;
- case UIERROR_READERRCOUNT:
- Log(NULL,St(MErrReadCount),Num[0]);
- break;
- case UIERROR_DIRNAMEEXISTS:
- Log(NULL,St(MDirNameExists));
- break;
- case UIERROR_TRUNCPSW:
- eprintf(St(MTruncPsw),Num[0]);
- eprintf(L"\n");
- break;
- case UIERROR_ADJUSTVALUE:
- Log(NULL,St(MAdjustValue),Str[0],Str[1]);
- break;
- #ifndef SFX_MODULE
- case UIMSG_STRING:
- mprintf(L"\n%s",Str[0]);
- break;
- #endif
- case UIMSG_CORRECTINGNAME:
- Log(Str[0],St(MCorrectingName));
- break;
- case UIMSG_BADARCHIVE:
- mprintf(St(MBadArc),Str[0]);
- break;
- case UIMSG_CREATING:
- mprintf(St(MCreating),Str[0]);
- break;
- case UIMSG_RENAMING:
- mprintf(St(MRenaming),Str[0],Str[1]);
- break;
- case UIMSG_RECVOLCALCCHECKSUM:
- mprintf(St(MCalcCRCAllVol));
- break;
- case UIMSG_RECVOLFOUND:
- mprintf(St(MRecVolFound),Num[0]);
- break;
- case UIMSG_RECVOLMISSING:
- mprintf(St(MRecVolMissing),Num[0]);
- break;
- case UIMSG_MISSINGVOL:
- mprintf(St(MAbsNextVol),Str[0]);
- break;
- case UIMSG_RECONSTRUCTING:
- mprintf(St(MReconstructing));
- break;
- case UIMSG_CHECKSUM:
- mprintf(St(MCRCFailed),Str[0]);
- break;
- case UIMSG_FAT32SIZE:
- mprintf(St(MFAT32Size));
- mprintf(L" "); // For progress percent.
- break;
- case UIMSG_SKIPENCARC:
- Log(NULL,St(MSkipEncArc),Str[0]);
- break;
- case UIEVENT_RRTESTINGSTART:
- mprintf(L"%s ",St(MTestingRR));
- break;
- }
- }
- bool uiGetPassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *Password)
- {
- // Unlike GUI we cannot provide Cancel button here, so we use the empty
- // password to abort. Otherwise user not knowing a password would need to
- // press Ctrl+C multiple times to quit from infinite password request loop.
- return GetConsolePassword(Type,FileName,Password) && Password->IsSet();
- }
- bool uiIsGlobalPasswordSet()
- {
- return false;
- }
- void uiAlarm(UIALARM_TYPE Type)
- {
- if (uiSoundNotify==SOUND_NOTIFY_ON)
- {
- static clock_t LastTime=-10; // Negative to always beep first time.
- if ((MonoClock()-LastTime)/CLOCKS_PER_SEC>5)
- {
- #ifdef _WIN_ALL
- MessageBeep(-1);
- #else
- putwchar('\007');
- #endif
- LastTime=MonoClock();
- }
- }
- }
- bool uiAskNextVolume(wchar *VolName,size_t MaxSize)
- {
- eprintf(St(MAskNextVol),VolName);
- return Ask(St(MContinueQuit))!=2;
- }
- void uiAskRepeatRead(const wchar *FileName,bool &Ignore,bool &All,bool &Retry,bool &Quit)
- {
- eprintf(St(MErrReadInfo));
- int Code=Ask(St(MIgnoreAllRetryQuit));
- Ignore=(Code==1);
- All=(Code==2);
- Quit=(Code==4);
- Retry=!Ignore && !All && !Quit; // Default also for invalid input, not just for 'Retry'.
- }
- bool uiAskRepeatWrite(const wchar *FileName,bool DiskFull)
- {
- mprintf(L"\n");
- Log(NULL,St(DiskFull ? MNotEnoughDisk:MErrWrite),FileName);
- return Ask(St(MRetryAbort))==1;
- }
- #ifndef SFX_MODULE
- const wchar *uiGetMonthName(int Month)
- {
- static MSGID MonthID[12]={
- MMonthJan,MMonthFeb,MMonthMar,MMonthApr,MMonthMay,MMonthJun,
- MMonthJul,MMonthAug,MMonthSep,MMonthOct,MMonthNov,MMonthDec
- };
- return St(MonthID[Month]);
- }
- #endif
- void uiEolAfterMsg()
- {
- if (AnyMessageDisplayed)
- {
- // Avoid deleting several last characters of any previous error message
- // with percentage indicator in -idn mode.
- AnyMessageDisplayed=false;
- mprintf(L"\n");
- }
- }
|