1 // Purely user interface function. Gets and returns user input.
uiAskReplace(wchar * Name,size_t MaxNameSize,int64 FileSize,RarTime * FileTime,uint Flags)2 UIASKREP_RESULT uiAskReplace(wchar *Name,size_t MaxNameSize,int64 FileSize,RarTime *FileTime,uint Flags)
3 {
4   wchar SizeText1[20],DateStr1[50],SizeText2[20],DateStr2[50];
5 
6   FindData ExistingFD;
7   memset(&ExistingFD,0,sizeof(ExistingFD)); // In case find fails.
8   FindFile::FastFind(Name,&ExistingFD);
9   itoa(ExistingFD.Size,SizeText1,ASIZE(SizeText1));
10   ExistingFD.mtime.GetText(DateStr1,ASIZE(DateStr1),false);
11 
12   if (FileSize==INT64NDF || FileTime==NULL)
13   {
14     eprintf(L"\n");
15     eprintf(St(MAskOverwrite),Name);
16   }
17   else
18   {
19     itoa(FileSize,SizeText2,ASIZE(SizeText2));
20     FileTime->GetText(DateStr2,ASIZE(DateStr2),false);
21     if ((Flags & UIASKREP_F_EXCHSRCDEST)==0)
22       eprintf(St(MAskReplace),Name,SizeText1,DateStr1,SizeText2,DateStr2);
23     else
24       eprintf(St(MAskReplace),Name,SizeText2,DateStr2,SizeText1,DateStr1);
25   }
26 
27   bool AllowRename=(Flags & UIASKREP_F_NORENAME)==0;
28   int Choice=0;
29   do
30   {
31     Choice=Ask(St(AllowRename ? MYesNoAllRenQ : MYesNoAllQ));
32   } while (Choice==0); // 0 means invalid input.
33   switch(Choice)
34   {
35     case 1:
36       return UIASKREP_R_REPLACE;
37     case 2:
38       return UIASKREP_R_SKIP;
39     case 3:
40       return UIASKREP_R_REPLACEALL;
41     case 4:
42       return UIASKREP_R_SKIPALL;
43   }
44   if (AllowRename && Choice==5)
45   {
46     mprintf(St(MAskNewName));
47     if (getwstr(Name,MaxNameSize))
48       return UIASKREP_R_RENAME;
49     else
50       return UIASKREP_R_SKIP; // Process fwgets failure as if user answered 'No'.
51   }
52   return UIASKREP_R_CANCEL;
53 }
54 
55 
56 
57 
uiStartArchiveExtract(bool Extract,const wchar * ArcName)58 void uiStartArchiveExtract(bool Extract,const wchar *ArcName)
59 {
60   mprintf(St(Extract ? MExtracting : MExtrTest), ArcName);
61 }
62 
63 
uiStartFileExtract(const wchar * FileName,bool Extract,bool Test,bool Skip)64 bool uiStartFileExtract(const wchar *FileName,bool Extract,bool Test,bool Skip)
65 {
66   return true;
67 }
68 
69 
uiExtractProgress(int64 CurFileSize,int64 TotalFileSize,int64 CurSize,int64 TotalSize)70 void uiExtractProgress(int64 CurFileSize,int64 TotalFileSize,int64 CurSize,int64 TotalSize)
71 {
72   int CurPercent=ToPercent(CurSize,TotalSize);
73   mprintf(L"\b\b\b\b%3d%%",CurPercent);
74 }
75 
76 
uiProcessProgress(const char * Command,int64 CurSize,int64 TotalSize)77 void uiProcessProgress(const char *Command,int64 CurSize,int64 TotalSize)
78 {
79   int CurPercent=ToPercent(CurSize,TotalSize);
80   mprintf(L"\b\b\b\b%3d%%",CurPercent);
81 }
82 
83 
Msg()84 void uiMsgStore::Msg()
85 {
86   switch(Code)
87   {
88     case UIERROR_SYSERRMSG:
89     case UIERROR_GENERALERRMSG:
90       Log(NULL,L"\n%ls",Str[0]);
91       break;
92     case UIERROR_CHECKSUM:
93       Log(Str[0],St(MCRCFailed),Str[1]);
94       break;
95     case UIERROR_CHECKSUMENC:
96       Log(Str[0],St(MEncrBadCRC),Str[1]);
97       break;
98     case UIERROR_CHECKSUMPACKED:
99       Log(Str[0],St(MDataBadCRC),Str[1],Str[0]);
100       break;
101     case UIERROR_BADPSW:
102       Log(Str[0],St(MWrongFilePassword),Str[1]);
103       break;
104     case UIWAIT_BADPSW:
105       Log(Str[0],St(MWrongPassword));
106       break;
107     case UIERROR_MEMORY:
108       mprintf(L"\n");
109       Log(NULL,St(MErrOutMem));
110       break;
111     case UIERROR_FILEOPEN:
112       Log(Str[0],St(MCannotOpen),Str[1]);
113       break;
114     case UIERROR_FILECREATE:
115       Log(Str[0],St(MCannotCreate),Str[1]);
116       break;
117     case UIERROR_FILECLOSE:
118       Log(NULL,St(MErrFClose),Str[0]);
119       break;
120     case UIERROR_FILESEEK:
121       Log(NULL,St(MErrSeek),Str[0]);
122       break;
123     case UIERROR_FILEREAD:
124       Log(Str[0],St(MErrRead),Str[1]);
125       break;
126     case UIERROR_FILEWRITE:
127       Log(Str[0],St(MErrWrite),Str[1]);
128       break;
129 #ifndef SFX_MODULE
130     case UIERROR_FILEDELETE:
131       Log(Str[0],St(MCannotDelete),Str[1]);
132       break;
133     case UIERROR_RECYCLEFAILED:
134       Log(Str[0],St(MRecycleFailed));
135       break;
136     case UIERROR_FILERENAME:
137       Log(Str[0],St(MErrRename),Str[1],Str[2]);
138       break;
139 #endif
140     case UIERROR_FILEATTR:
141       Log(Str[0],St(MErrChangeAttr),Str[1]);
142       break;
143     case UIERROR_FILECOPY:
144       Log(Str[0],St(MCopyError),Str[1],Str[2]);
145       break;
146     case UIERROR_FILECOPYHINT:
147       Log(Str[0],St(MCopyErrorHint));
148       mprintf(L"     "); // For progress percent.
149       break;
150     case UIERROR_DIRCREATE:
151       Log(Str[0],St(MExtrErrMkDir),Str[1]);
152       break;
153     case UIERROR_SLINKCREATE:
154       Log(Str[0],St(MErrCreateLnkS),Str[1]);
155       break;
156     case UIERROR_HLINKCREATE:
157       Log(NULL,St(MErrCreateLnkH),Str[0]);
158       break;
159     case UIERROR_NOLINKTARGET:
160       Log(NULL,St(MErrLnkTarget));
161       mprintf(L"     "); // For progress percent.
162       break;
163     case UIERROR_NEEDADMIN:
164       Log(NULL,St(MNeedAdmin));
165       break;
166     case UIERROR_ARCBROKEN:
167       Log(Str[0],St(MErrBrokenArc));
168       break;
169     case UIERROR_HEADERBROKEN:
170       Log(Str[0],St(MHeaderBroken));
171       break;
172     case UIERROR_MHEADERBROKEN:
173       Log(Str[0],St(MMainHeaderBroken));
174       break;
175     case UIERROR_FHEADERBROKEN:
176       Log(Str[0],St(MLogFileHead),Str[1]);
177       break;
178     case UIERROR_SUBHEADERBROKEN:
179       Log(Str[0],St(MSubHeadCorrupt));
180       break;
181     case UIERROR_SUBHEADERUNKNOWN:
182       Log(Str[0],St(MSubHeadUnknown));
183       break;
184     case UIERROR_SUBHEADERDATABROKEN:
185       Log(Str[0],St(MSubHeadDataCRC),Str[1]);
186       break;
187     case UIERROR_RRDAMAGED:
188       Log(Str[0],St(MRRDamaged));
189       break;
190     case UIERROR_UNKNOWNMETHOD:
191       Log(Str[0],St(MUnknownMeth),Str[1]);
192       break;
193     case UIERROR_UNKNOWNENCMETHOD:
194       {
195         wchar Msg[256];
196         swprintf(Msg,ASIZE(Msg),St(MUnkEncMethod),Str[1]);
197         Log(Str[0],L"%s: %s",Msg,Str[2]);
198       }
199       break;
200 #ifndef SFX_MODULE
201    case UIERROR_RENAMING:
202       Log(Str[0],St(MRenaming),Str[1],Str[2]);
203       break;
204     case UIERROR_NEWERRAR:
205       Log(Str[0],St(MNewerRAR));
206       break;
207 #endif
208     case UIERROR_RECVOLDIFFSETS:
209       Log(NULL,St(MRecVolDiffSets),Str[0],Str[1]);
210       break;
211     case UIERROR_RECVOLALLEXIST:
212       mprintf(St(MRecVolAllExist));
213       break;
214     case UIERROR_RECONSTRUCTING:
215       mprintf(St(MReconstructing));
216       break;
217     case UIERROR_RECVOLCANNOTFIX:
218       mprintf(St(MRecVolCannotFix));
219       break;
220     case UIERROR_UNEXPEOF:
221       Log(Str[0],St(MLogUnexpEOF));
222       break;
223     case UIERROR_BADARCHIVE:
224       Log(Str[0],St(MBadArc),Str[0]);
225       break;
226     case UIERROR_CMTBROKEN:
227       Log(Str[0],St(MLogCommBrk));
228       break;
229     case UIERROR_INVALIDNAME:
230       Log(Str[0],St(MInvalidName),Str[1]);
231       mprintf(L"\n"); // Needed when called from CmdExtract::ExtractCurrentFile.
232       break;
233 #ifndef SFX_MODULE
234     case UIERROR_NEWRARFORMAT:
235       Log(Str[0],St(MNewRarFormat));
236       break;
237 #endif
238     case UIERROR_NOFILESTOEXTRACT:
239       mprintf(St(MExtrNoFiles));
240       break;
241     case UIERROR_MISSINGVOL:
242       Log(Str[0],St(MAbsNextVol),Str[0]);
243       break;
244 #ifndef SFX_MODULE
245     case UIERROR_NEEDPREVVOL:
246       Log(Str[0],St(MUnpCannotMerge),Str[1]);
247       break;
248     case UIERROR_UNKNOWNEXTRA:
249       Log(Str[0],St(MUnknownExtra),Str[1]);
250       break;
251     case UIERROR_CORRUPTEXTRA:
252       Log(Str[0],St(MCorruptExtra),Str[1],Str[2]);
253       break;
254 #endif
255 #if !defined(SFX_MODULE) && defined(_WIN_ALL)
256     case UIERROR_NTFSREQUIRED:
257       Log(NULL,St(MNTFSRequired),Str[0]);
258       break;
259 #endif
260 #if !defined(SFX_MODULE) && defined(_WIN_ALL)
261     case UIERROR_ACLBROKEN:
262       Log(Str[0],St(MACLBroken),Str[1]);
263       break;
264     case UIERROR_ACLUNKNOWN:
265       Log(Str[0],St(MACLUnknown),Str[1]);
266       break;
267     case UIERROR_ACLSET:
268       Log(Str[0],St(MACLSetError),Str[1]);
269       break;
270     case UIERROR_STREAMBROKEN:
271       Log(Str[0],St(MStreamBroken),Str[1]);
272       break;
273     case UIERROR_STREAMUNKNOWN:
274       Log(Str[0],St(MStreamUnknown),Str[1]);
275       break;
276 #endif
277     case UIERROR_INCOMPATSWITCH:
278       mprintf(St(MIncompatSwitch),Str[0],Num[0]);
279       break;
280     case UIERROR_PATHTOOLONG:
281       Log(NULL,L"\n%ls%ls%ls",Str[0],Str[1],Str[2]);
282       Log(NULL,St(MPathTooLong));
283       break;
284 #ifndef SFX_MODULE
285     case UIERROR_DIRSCAN:
286       Log(NULL,St(MScanError),Str[0]);
287       break;
288 #endif
289     case UIERROR_UOWNERBROKEN:
290       Log(Str[0],St(MOwnersBroken),Str[1]);
291       break;
292     case UIERROR_UOWNERGETOWNERID:
293       Log(Str[0],St(MErrGetOwnerID),Str[1]);
294       break;
295     case UIERROR_UOWNERGETGROUPID:
296       Log(Str[0],St(MErrGetGroupID),Str[1]);
297       break;
298     case UIERROR_UOWNERSET:
299       Log(Str[0],St(MSetOwnersError),Str[1]);
300       break;
301     case UIERROR_ULINKREAD:
302       Log(NULL,St(MErrLnkRead),Str[0]);
303       break;
304     case UIERROR_ULINKEXIST:
305       Log(NULL,St(MSymLinkExists),Str[0]);
306       break;
307 
308 
309 #ifndef SFX_MODULE
310     case UIMSG_STRING:
311       mprintf(L"\n%s",Str[0]);
312       break;
313 #endif
314     case UIMSG_CORRECTINGNAME:
315       Log(Str[0],St(MCorrectingName));
316       break;
317     case UIMSG_BADARCHIVE:
318       mprintf(St(MBadArc),Str[0]);
319       break;
320     case UIMSG_CREATING:
321       mprintf(St(MCreating),Str[0]);
322       break;
323     case UIMSG_RENAMING:
324       mprintf(St(MRenaming),Str[0],Str[1]);
325       break;
326     case UIMSG_RECVOLCALCCHECKSUM:
327       mprintf(St(MCalcCRCAllVol));
328       break;
329     case UIMSG_RECVOLFOUND:
330       mprintf(St(MRecVolFound),Num[0]);
331       break;
332     case UIMSG_RECVOLMISSING:
333       mprintf(St(MRecVolMissing),Num[0]);
334       break;
335     case UIMSG_MISSINGVOL:
336       mprintf(St(MAbsNextVol),Str[0]);
337       break;
338     case UIMSG_RECONSTRUCTING:
339       mprintf(St(MReconstructing));
340       break;
341     case UIMSG_CHECKSUM:
342       mprintf(St(MCRCFailed),Str[0]);
343       break;
344     case UIMSG_FAT32SIZE:
345       mprintf(St(MFAT32Size));
346       mprintf(L"     "); // For progress percent.
347       break;
348 
349 
350 
351     case UIEVENT_RRTESTINGSTART:
352       mprintf(L"%s      ",St(MTestingRR));
353       break;
354   }
355 }
356 
357 
uiGetPassword(UIPASSWORD_TYPE Type,const wchar * FileName,SecPassword * Password)358 bool uiGetPassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *Password)
359 {
360   // Unlike GUI we cannot provide Cancel button here, so we use the empty
361   // password to abort. Otherwise user not knowing a password would need to
362   // press Ctrl+C multiple times to quit from infinite password request loop.
363   return GetConsolePassword(Type,FileName,Password) && Password->IsSet();
364 }
365 
366 
uiIsGlobalPasswordSet()367 bool uiIsGlobalPasswordSet()
368 {
369   return false;
370 }
371 
372 
uiAlarm(UIALARM_TYPE Type)373 void uiAlarm(UIALARM_TYPE Type)
374 {
375   if (uiSoundNotify==SOUND_NOTIFY_ON)
376   {
377     static clock_t LastTime=-10; // Negative to always beep first time.
378     if ((MonoClock()-LastTime)/CLOCKS_PER_SEC>5)
379     {
380 #ifdef _WIN_ALL
381       MessageBeep(-1);
382 #else
383       putwchar('\007');
384 #endif
385       LastTime=MonoClock();
386     }
387   }
388 }
389 
390 
391 
392 
uiAskNextVolume(wchar * VolName,size_t MaxSize)393 bool uiAskNextVolume(wchar *VolName,size_t MaxSize)
394 {
395   eprintf(St(MAskNextVol),VolName);
396   return Ask(St(MContinueQuit))!=2;
397 }
398 
399 
uiAskRepeatRead(const wchar * FileName)400 bool uiAskRepeatRead(const wchar *FileName)
401 {
402   mprintf(L"\n");
403   Log(NULL,St(MErrRead),FileName);
404   return Ask(St(MRetryAbort))==1;
405 }
406 
407 
uiAskRepeatWrite(const wchar * FileName,bool DiskFull)408 bool uiAskRepeatWrite(const wchar *FileName,bool DiskFull)
409 {
410   mprintf(L"\n");
411   Log(NULL,St(DiskFull ? MNotEnoughDisk:MErrWrite),FileName);
412   return Ask(St(MRetryAbort))==1;
413 }
414 
415 
416 #ifndef SFX_MODULE
uiGetMonthName(int Month)417 const wchar *uiGetMonthName(int Month)
418 {
419   static MSGID MonthID[12]={
420          MMonthJan,MMonthFeb,MMonthMar,MMonthApr,MMonthMay,MMonthJun,
421          MMonthJul,MMonthAug,MMonthSep,MMonthOct,MMonthNov,MMonthDec
422   };
423   return St(MonthID[Month]);
424 }
425 #endif
426