1 #include "rar.hpp"
2
3
4 static bool UserBreak;
5
ErrorHandler()6 ErrorHandler::ErrorHandler()
7 {
8 Clean();
9 }
10
11
Clean()12 void ErrorHandler::Clean()
13 {
14 ExitCode=SUCCESS;
15 ErrCount=0;
16 EnableBreak=true;
17 Silent=false;
18 DoShutdown=false;
19 }
20
21
MemoryError()22 void ErrorHandler::MemoryError()
23 {
24 MemoryErrorMsg();
25 Throw(MEMORY_ERROR);
26 }
27
28
OpenError(const char * FileName)29 void ErrorHandler::OpenError(const char *FileName)
30 {
31 #ifndef SILENT
32 OpenErrorMsg(FileName);
33 Throw(OPEN_ERROR);
34 #endif
35 }
36
37
CloseError(const char * FileName)38 void ErrorHandler::CloseError(const char *FileName)
39 {
40 #ifndef SILENT
41 if (!UserBreak)
42 {
43 ErrMsg(NULL,St(MErrFClose),FileName);
44 SysErrMsg();
45 }
46 #endif
47 #if !defined(SILENT) || defined(RARDLL)
48 Throw(FATAL_ERROR);
49 #endif
50 }
51
52
ReadError(const char * FileName)53 void ErrorHandler::ReadError(const char *FileName)
54 {
55 #ifndef SILENT
56 ReadErrorMsg(NULL,FileName);
57 #endif
58 #if !defined(SILENT) || defined(RARDLL)
59 Throw(FATAL_ERROR);
60 #endif
61 }
62
63
AskRepeatRead(const char * FileName)64 bool ErrorHandler::AskRepeatRead(const char *FileName)
65 {
66 #if !defined(SILENT) && !defined(SFX_MODULE) && !defined(_WIN_CE)
67 if (!Silent)
68 {
69 mprintf("\n");
70 Log(NULL,St(MErrRead),FileName);
71 return(Ask(St(MRetryAbort))==1);
72 }
73 #endif
74 return(false);
75 }
76
77
WriteError(const char * ArcName,const char * FileName)78 void ErrorHandler::WriteError(const char *ArcName,const char *FileName)
79 {
80 #ifndef SILENT
81 WriteErrorMsg(ArcName,FileName);
82 #endif
83 #if !defined(SILENT) || defined(RARDLL)
84 Throw(WRITE_ERROR);
85 #endif
86 }
87
88
89 #ifdef _WIN_32
WriteErrorFAT(const char * FileName)90 void ErrorHandler::WriteErrorFAT(const char *FileName)
91 {
92 #if !defined(SILENT) && !defined(SFX_MODULE)
93 SysErrMsg();
94 ErrMsg(NULL,St(MNTFSRequired),FileName);
95 #endif
96 #if !defined(SILENT) && !defined(SFX_MODULE) || defined(RARDLL)
97 Throw(WRITE_ERROR);
98 #endif
99 }
100 #endif
101
102
AskRepeatWrite(const char * FileName)103 bool ErrorHandler::AskRepeatWrite(const char *FileName)
104 {
105 #if !defined(SILENT) && !defined(_WIN_CE)
106 if (!Silent)
107 {
108 mprintf("\n");
109 Log(NULL,St(MErrWrite),FileName);
110 return(Ask(St(MRetryAbort))==1);
111 }
112 #endif
113 return(false);
114 }
115
116
SeekError(const char * FileName)117 void ErrorHandler::SeekError(const char *FileName)
118 {
119 #ifndef SILENT
120 if (!UserBreak)
121 {
122 ErrMsg(NULL,St(MErrSeek),FileName);
123 SysErrMsg();
124 }
125 #endif
126 #if !defined(SILENT) || defined(RARDLL)
127 Throw(FATAL_ERROR);
128 #endif
129 }
130
131
MemoryErrorMsg()132 void ErrorHandler::MemoryErrorMsg()
133 {
134 #ifndef SILENT
135 ErrMsg(NULL,St(MErrOutMem));
136 #endif
137 }
138
139
OpenErrorMsg(const char * FileName)140 void ErrorHandler::OpenErrorMsg(const char *FileName)
141 {
142 OpenErrorMsg(NULL,FileName);
143 }
144
145
OpenErrorMsg(const char * ArcName,const char * FileName)146 void ErrorHandler::OpenErrorMsg(const char *ArcName,const char *FileName)
147 {
148 #ifndef SILENT
149 Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotOpen),FileName);
150 Alarm();
151 SysErrMsg();
152 #endif
153 }
154
155
CreateErrorMsg(const char * FileName)156 void ErrorHandler::CreateErrorMsg(const char *FileName)
157 {
158 CreateErrorMsg(NULL,FileName);
159 }
160
161
CreateErrorMsg(const char * ArcName,const char * FileName)162 void ErrorHandler::CreateErrorMsg(const char *ArcName,const char *FileName)
163 {
164 #ifndef SILENT
165 Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotCreate),FileName);
166 Alarm();
167 #if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) && defined(MAXPATH)
168 if (GetLastError()==ERROR_PATH_NOT_FOUND)
169 {
170 int NameLength=strlen(FileName);
171 if (!IsFullPath(FileName))
172 {
173 char CurDir[NM];
174 GetCurrentDirectory(sizeof(CurDir),CurDir);
175 NameLength+=strlen(CurDir)+1;
176 }
177 if (NameLength>MAXPATH)
178 {
179 Log(ArcName && *ArcName ? ArcName:NULL,St(MMaxPathLimit),MAXPATH);
180 }
181 }
182 #endif
183 SysErrMsg();
184 #endif
185 }
186
187
ReadErrorMsg(const char * ArcName,const char * FileName)188 void ErrorHandler::ReadErrorMsg(const char *ArcName,const char *FileName)
189 {
190 #ifndef SILENT
191 ErrMsg(ArcName,St(MErrRead),FileName);
192 SysErrMsg();
193 #endif
194 }
195
196
WriteErrorMsg(const char * ArcName,const char * FileName)197 void ErrorHandler::WriteErrorMsg(const char *ArcName,const char *FileName)
198 {
199 #ifndef SILENT
200 ErrMsg(ArcName,St(MErrWrite),FileName);
201 SysErrMsg();
202 #endif
203 }
204
205
Exit(int ExitCode)206 void ErrorHandler::Exit(int ExitCode)
207 {
208 #ifndef SFX_MODULE
209 Alarm();
210 #endif
211 Throw(ExitCode);
212 }
213
214
215 #ifndef GUI
ErrMsg(const char * ArcName,const char * fmt,...)216 void ErrorHandler::ErrMsg(const char *ArcName,const char *fmt,...)
217 {
218 safebuf char Msg[NM+1024];
219 va_list argptr;
220 va_start(argptr,fmt);
221 vsprintf(Msg,fmt,argptr);
222 va_end(argptr);
223 #ifdef _WIN_32
224 if (UserBreak)
225 Sleep(5000);
226 #endif
227 Alarm();
228 if (*Msg)
229 {
230 Log(ArcName,"\n%s",Msg);
231 mprintf("\n%s\n",St(MProgAborted));
232 }
233 }
234 #endif
235
236
SetErrorCode(int Code)237 void ErrorHandler::SetErrorCode(int Code)
238 {
239 switch(Code)
240 {
241 case WARNING:
242 case USER_BREAK:
243 if (ExitCode==SUCCESS)
244 ExitCode=Code;
245 break;
246 case FATAL_ERROR:
247 if (ExitCode==SUCCESS || ExitCode==WARNING)
248 ExitCode=FATAL_ERROR;
249 break;
250 default:
251 ExitCode=Code;
252 break;
253 }
254 ErrCount++;
255 }
256
257
258 #if !defined(GUI) && !defined(_SFX_RTL_)
259 #ifdef _WIN_32
ProcessSignal(DWORD SigType)260 BOOL __stdcall ProcessSignal(DWORD SigType)
261 #else
262 #if defined(__sun)
263 extern "C"
264 #endif
265 void _stdfunction ProcessSignal(int SigType)
266 #endif
267 {
268 #ifdef _WIN_32
269 if (SigType==CTRL_LOGOFF_EVENT)
270 return(TRUE);
271 #endif
272 UserBreak=true;
273 mprintf(St(MBreak));
274 for (int I=0;!File::RemoveCreated() && I<3;I++)
275 {
276 #ifdef _WIN_32
277 Sleep(100);
278 #endif
279 }
280 #if defined(USE_RC) && !defined(SFX_MODULE) && !defined(_WIN_CE)
281 ExtRes.UnloadDLL();
282 #endif
283 exit(USER_BREAK);
284 #ifdef _WIN_32
285 return(TRUE);
286 #endif
287 }
288 #endif
289
290
SetSignalHandlers(bool Enable)291 void ErrorHandler::SetSignalHandlers(bool Enable)
292 {
293 EnableBreak=Enable;
294 #if !defined(GUI) && !defined(_SFX_RTL_)
295 #ifdef _WIN_32
296 SetConsoleCtrlHandler(Enable ? ProcessSignal:NULL,TRUE);
297 // signal(SIGBREAK,Enable ? ProcessSignal:SIG_IGN);
298 #else
299 signal(SIGINT,Enable ? ProcessSignal:SIG_IGN);
300 signal(SIGTERM,Enable ? ProcessSignal:SIG_IGN);
301 #endif
302 #endif
303 }
304
305
Throw(int Code)306 void ErrorHandler::Throw(int Code)
307 {
308 if (Code==USER_BREAK && !EnableBreak)
309 return;
310 ErrHandler.SetErrorCode(Code);
311 #ifdef ALLOW_EXCEPTIONS
312 throw Code;
313 #else
314 File::RemoveCreated();
315 exit(Code);
316 #endif
317 }
318
319
SysErrMsg()320 void ErrorHandler::SysErrMsg()
321 {
322 #if defined(_WIN_32) && !defined(SFX_MODULE) && !defined(SILENT)
323 #define STRCHR strchr
324 #define ERRCHAR char
325 ERRCHAR *lpMsgBuf=NULL;
326 int ErrType=GetLastError();
327 if (ErrType!=0 && FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
328 NULL,ErrType,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
329 (LPTSTR)&lpMsgBuf,0,NULL))
330 {
331 ERRCHAR *CurMsg=lpMsgBuf;
332 while (CurMsg!=NULL)
333 {
334 while (*CurMsg=='\r' || *CurMsg=='\n')
335 CurMsg++;
336 if (*CurMsg==0)
337 break;
338 ERRCHAR *EndMsg=STRCHR(CurMsg,'\r');
339 if (EndMsg==NULL)
340 EndMsg=STRCHR(CurMsg,'\n');
341 if (EndMsg!=NULL)
342 {
343 *EndMsg=0;
344 EndMsg++;
345 }
346 Log(NULL,"\n%s",CurMsg);
347 CurMsg=EndMsg;
348 }
349 }
350 LocalFree( lpMsgBuf );
351 #endif
352 }
353