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     SysErrMsg();
70     mprintf("\n");
71     Log(NULL,St(MErrRead),FileName);
72     return(Ask(St(MRetryAbort))==1);
73   }
74 #endif
75   return(false);
76 }
77 
78 
WriteError(const char * ArcName,const char * FileName)79 void ErrorHandler::WriteError(const char *ArcName,const char *FileName)
80 {
81 #ifndef SILENT
82   WriteErrorMsg(ArcName,FileName);
83 #endif
84 #if !defined(SILENT) || defined(RARDLL)
85   Throw(WRITE_ERROR);
86 #endif
87 }
88 
89 
90 #ifdef _WIN_32
WriteErrorFAT(const char * FileName)91 void ErrorHandler::WriteErrorFAT(const char *FileName)
92 {
93 #if !defined(SILENT) && !defined(SFX_MODULE)
94   SysErrMsg();
95   ErrMsg(NULL,St(MNTFSRequired),FileName);
96 #endif
97 #if !defined(SILENT) && !defined(SFX_MODULE) || defined(RARDLL)
98   Throw(WRITE_ERROR);
99 #endif
100 }
101 #endif
102 
103 
AskRepeatWrite(const char * FileName,bool DiskFull)104 bool ErrorHandler::AskRepeatWrite(const char *FileName,bool DiskFull)
105 {
106 #if !defined(SILENT) && !defined(_WIN_CE)
107   if (!Silent)
108   {
109     SysErrMsg();
110     mprintf("\n");
111     Log(NULL,St(DiskFull ? MNotEnoughDisk:MErrWrite),FileName);
112     return(Ask(St(MRetryAbort))==1);
113   }
114 #endif
115   return(false);
116 }
117 
118 
SeekError(const char * FileName)119 void ErrorHandler::SeekError(const char *FileName)
120 {
121 #ifndef SILENT
122   if (!UserBreak)
123   {
124     ErrMsg(NULL,St(MErrSeek),FileName);
125     SysErrMsg();
126   }
127 #endif
128 #if !defined(SILENT) || defined(RARDLL)
129   Throw(FATAL_ERROR);
130 #endif
131 }
132 
133 
GeneralErrMsg(const char * Msg)134 void ErrorHandler::GeneralErrMsg(const char *Msg)
135 {
136 #ifndef SILENT
137   Log(NULL,"%s",Msg);
138   SysErrMsg();
139 #endif
140 }
141 
142 
MemoryErrorMsg()143 void ErrorHandler::MemoryErrorMsg()
144 {
145 #ifndef SILENT
146   ErrMsg(NULL,St(MErrOutMem));
147 #endif
148 }
149 
150 
OpenErrorMsg(const char * FileName)151 void ErrorHandler::OpenErrorMsg(const char *FileName)
152 {
153   OpenErrorMsg(NULL,FileName);
154 }
155 
156 
OpenErrorMsg(const char * ArcName,const char * FileName)157 void ErrorHandler::OpenErrorMsg(const char *ArcName,const char *FileName)
158 {
159 #ifndef SILENT
160   Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotOpen),FileName);
161   Alarm();
162   SysErrMsg();
163 #endif
164 }
165 
166 
CreateErrorMsg(const char * FileName)167 void ErrorHandler::CreateErrorMsg(const char *FileName)
168 {
169   CreateErrorMsg(NULL,FileName);
170 }
171 
172 
CreateErrorMsg(const char * ArcName,const char * FileName)173 void ErrorHandler::CreateErrorMsg(const char *ArcName,const char *FileName)
174 {
175 #ifndef SILENT
176   Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotCreate),FileName);
177   Alarm();
178 #if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) && defined(MAX_PATH)
179   if (GetLastError()==ERROR_PATH_NOT_FOUND)
180   {
181     size_t NameLength=strlen(FileName);
182     if (!IsFullPath(FileName))
183     {
184       char CurDir[NM];
185       GetCurrentDirectory(sizeof(CurDir),CurDir);
186       NameLength+=strlen(CurDir)+1;
187     }
188     if (NameLength>MAX_PATH)
189     {
190       Log(ArcName && *ArcName ? ArcName:NULL,St(MMaxPathLimit),MAX_PATH);
191     }
192   }
193 #endif
194   SysErrMsg();
195 #endif
196 }
197 
198 
ReadErrorMsg(const char * ArcName,const char * FileName)199 void ErrorHandler::ReadErrorMsg(const char *ArcName,const char *FileName)
200 {
201 #ifndef SILENT
202   ErrMsg(ArcName,St(MErrRead),FileName);
203   SysErrMsg();
204 #endif
205 }
206 
207 
WriteErrorMsg(const char * ArcName,const char * FileName)208 void ErrorHandler::WriteErrorMsg(const char *ArcName,const char *FileName)
209 {
210 #ifndef SILENT
211   ErrMsg(ArcName,St(MErrWrite),FileName);
212   SysErrMsg();
213 #endif
214 }
215 
216 
Exit(int ExitCode)217 void ErrorHandler::Exit(int ExitCode)
218 {
219 #ifndef SFX_MODULE
220   Alarm();
221 #endif
222   Throw(ExitCode);
223 }
224 
225 
226 #ifndef GUI
ErrMsg(const char * ArcName,const char * fmt,...)227 void ErrorHandler::ErrMsg(const char *ArcName,const char *fmt,...)
228 {
229   safebuf char Msg[NM+1024];
230   va_list argptr;
231   va_start(argptr,fmt);
232   vsprintf(Msg,fmt,argptr);
233   va_end(argptr);
234 #ifdef _WIN_32
235   if (UserBreak)
236     Sleep(5000);
237 #endif
238   Alarm();
239   if (*Msg)
240   {
241     Log(ArcName,"\n%s",Msg);
242     mprintf("\n%s\n",St(MProgAborted));
243   }
244 }
245 #endif
246 
247 
SetErrorCode(int Code)248 void ErrorHandler::SetErrorCode(int Code)
249 {
250   switch(Code)
251   {
252     case WARNING:
253     case USER_BREAK:
254       if (ExitCode==SUCCESS)
255         ExitCode=Code;
256       break;
257     case FATAL_ERROR:
258       if (ExitCode==SUCCESS || ExitCode==WARNING)
259         ExitCode=FATAL_ERROR;
260       break;
261     default:
262       ExitCode=Code;
263       break;
264   }
265   ErrCount++;
266 }
267 
268 
269 #if !defined(GUI) && !defined(_SFX_RTL_)
270 #ifdef _WIN_32
ProcessSignal(DWORD SigType)271 BOOL __stdcall ProcessSignal(DWORD SigType)
272 #else
273 #if defined(__sun)
274 extern "C"
275 #endif
276 void _stdfunction ProcessSignal(int SigType)
277 #endif
278 {
279 #ifdef _WIN_32
280   if (SigType==CTRL_LOGOFF_EVENT)
281     return(TRUE);
282 #endif
283   UserBreak=true;
284   mprintf(St(MBreak));
285   for (int I=0;!File::RemoveCreated() && I<3;I++)
286   {
287 #ifdef _WIN_32
288     Sleep(100);
289 #endif
290   }
291 #if defined(USE_RC) && !defined(SFX_MODULE) && !defined(_WIN_CE) && !defined(RARDLL)
292   ExtRes.UnloadDLL();
293 #endif
294   exit(USER_BREAK);
295 #if defined(_WIN_32) && !defined(_MSC_VER)
296   // never reached, just to avoid a compiler warning
297   return(TRUE);
298 #endif
299 }
300 #endif
301 
302 
SetSignalHandlers(bool Enable)303 void ErrorHandler::SetSignalHandlers(bool Enable)
304 {
305   EnableBreak=Enable;
306 #if !defined(GUI) && !defined(_SFX_RTL_)
307 #ifdef _WIN_32
308   SetConsoleCtrlHandler(Enable ? ProcessSignal:NULL,TRUE);
309 //  signal(SIGBREAK,Enable ? ProcessSignal:SIG_IGN);
310 #else
311   signal(SIGINT,Enable ? ProcessSignal:SIG_IGN);
312   signal(SIGTERM,Enable ? ProcessSignal:SIG_IGN);
313 #endif
314 #endif
315 }
316 
317 
Throw(int Code)318 void ErrorHandler::Throw(int Code)
319 {
320   if (Code==USER_BREAK && !EnableBreak)
321     return;
322   ErrHandler.SetErrorCode(Code);
323 #ifdef ALLOW_EXCEPTIONS
324   throw Code;
325 #else
326   File::RemoveCreated();
327   exit(Code);
328 #endif
329 }
330 
331 
SysErrMsg()332 void ErrorHandler::SysErrMsg()
333 {
334 #if !defined(SFX_MODULE) && !defined(SILENT)
335 #ifdef _WIN_32
336     #define STRCHR strchr
337     #define ERRCHAR char
338   ERRCHAR  *lpMsgBuf=NULL;
339   int ErrType=GetLastError();
340   if (ErrType!=0 && FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
341               NULL,ErrType,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
342               (LPTSTR)&lpMsgBuf,0,NULL))
343   {
344     ERRCHAR  *CurMsg=lpMsgBuf;
345     while (CurMsg!=NULL)
346     {
347       while (*CurMsg=='\r' || *CurMsg=='\n')
348         CurMsg++;
349       if (*CurMsg==0)
350         break;
351       ERRCHAR *EndMsg=STRCHR(CurMsg,'\r');
352       if (EndMsg==NULL)
353         EndMsg=STRCHR(CurMsg,'\n');
354       if (EndMsg!=NULL)
355       {
356         *EndMsg=0;
357         EndMsg++;
358       }
359       Log(NULL,"\n%s",CurMsg);
360       CurMsg=EndMsg;
361     }
362   }
363   LocalFree( lpMsgBuf );
364 #endif
365 
366 #if defined(_UNIX) || defined(_EMX)
367   char *err=strerror(errno);
368   if (err!=NULL)
369     Log(NULL,"\n%s",err);
370 #endif
371 
372 #endif
373 }
374 
375 
376 
377 
378