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