QuietUnrar/libunrar/errhnd.cpp

378 lines
6.6 KiB
C++

#include "rar.hpp"
static bool UserBreak;
ErrorHandler::ErrorHandler()
{
Clean();
}
void ErrorHandler::Clean()
{
ExitCode=SUCCESS;
ErrCount=0;
EnableBreak=true;
Silent=false;
DoShutdown=false;
}
void ErrorHandler::MemoryError()
{
MemoryErrorMsg();
Throw(MEMORY_ERROR);
}
void ErrorHandler::OpenError(const char *FileName)
{
#ifndef SILENT
OpenErrorMsg(FileName);
Throw(OPEN_ERROR);
#endif
}
void ErrorHandler::CloseError(const char *FileName)
{
#ifndef SILENT
if (!UserBreak)
{
ErrMsg(NULL,St(MErrFClose),FileName);
SysErrMsg();
}
#endif
#if !defined(SILENT) || defined(RARDLL)
Throw(FATAL_ERROR);
#endif
}
void ErrorHandler::ReadError(const char *FileName)
{
#ifndef SILENT
ReadErrorMsg(NULL,FileName);
#endif
#if !defined(SILENT) || defined(RARDLL)
Throw(FATAL_ERROR);
#endif
}
bool ErrorHandler::AskRepeatRead(const char *FileName)
{
#if !defined(SILENT) && !defined(SFX_MODULE) && !defined(_WIN_CE)
if (!Silent)
{
SysErrMsg();
mprintf("\n");
Log(NULL,St(MErrRead),FileName);
return(Ask(St(MRetryAbort))==1);
}
#endif
return(false);
}
void ErrorHandler::WriteError(const char *ArcName,const char *FileName)
{
#ifndef SILENT
WriteErrorMsg(ArcName,FileName);
#endif
#if !defined(SILENT) || defined(RARDLL)
Throw(WRITE_ERROR);
#endif
}
#ifdef _WIN_32
void ErrorHandler::WriteErrorFAT(const char *FileName)
{
#if !defined(SILENT) && !defined(SFX_MODULE)
SysErrMsg();
ErrMsg(NULL,St(MNTFSRequired),FileName);
#endif
#if !defined(SILENT) && !defined(SFX_MODULE) || defined(RARDLL)
Throw(WRITE_ERROR);
#endif
}
#endif
bool ErrorHandler::AskRepeatWrite(const char *FileName,bool DiskFull)
{
#if !defined(SILENT) && !defined(_WIN_CE)
if (!Silent)
{
SysErrMsg();
mprintf("\n");
Log(NULL,St(DiskFull ? MNotEnoughDisk:MErrWrite),FileName);
return(Ask(St(MRetryAbort))==1);
}
#endif
return(false);
}
void ErrorHandler::SeekError(const char *FileName)
{
#ifndef SILENT
if (!UserBreak)
{
ErrMsg(NULL,St(MErrSeek),FileName);
SysErrMsg();
}
#endif
#if !defined(SILENT) || defined(RARDLL)
Throw(FATAL_ERROR);
#endif
}
void ErrorHandler::GeneralErrMsg(const char *Msg)
{
#ifndef SILENT
Log(NULL,"%s",Msg);
SysErrMsg();
#endif
}
void ErrorHandler::MemoryErrorMsg()
{
#ifndef SILENT
ErrMsg(NULL,St(MErrOutMem));
#endif
}
void ErrorHandler::OpenErrorMsg(const char *FileName)
{
OpenErrorMsg(NULL,FileName);
}
void ErrorHandler::OpenErrorMsg(const char *ArcName,const char *FileName)
{
#ifndef SILENT
Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotOpen),FileName);
Alarm();
SysErrMsg();
#endif
}
void ErrorHandler::CreateErrorMsg(const char *FileName)
{
CreateErrorMsg(NULL,FileName);
}
void ErrorHandler::CreateErrorMsg(const char *ArcName,const char *FileName)
{
#ifndef SILENT
Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotCreate),FileName);
Alarm();
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) && defined(MAX_PATH)
if (GetLastError()==ERROR_PATH_NOT_FOUND)
{
size_t NameLength=strlen(FileName);
if (!IsFullPath(FileName))
{
char CurDir[NM];
GetCurrentDirectory(sizeof(CurDir),CurDir);
NameLength+=strlen(CurDir)+1;
}
if (NameLength>MAX_PATH)
{
Log(ArcName && *ArcName ? ArcName:NULL,St(MMaxPathLimit),MAX_PATH);
}
}
#endif
SysErrMsg();
#endif
}
void ErrorHandler::ReadErrorMsg(const char *ArcName,const char *FileName)
{
#ifndef SILENT
ErrMsg(ArcName,St(MErrRead),FileName);
SysErrMsg();
#endif
}
void ErrorHandler::WriteErrorMsg(const char *ArcName,const char *FileName)
{
#ifndef SILENT
ErrMsg(ArcName,St(MErrWrite),FileName);
SysErrMsg();
#endif
}
void ErrorHandler::Exit(int ExitCode)
{
#ifndef SFX_MODULE
Alarm();
#endif
Throw(ExitCode);
}
#ifndef GUI
void ErrorHandler::ErrMsg(const char *ArcName,const char *fmt,...)
{
safebuf char Msg[NM+1024];
va_list argptr;
va_start(argptr,fmt);
vsprintf(Msg,fmt,argptr);
va_end(argptr);
#ifdef _WIN_32
if (UserBreak)
Sleep(5000);
#endif
Alarm();
if (*Msg)
{
Log(ArcName,"\n%s",Msg);
mprintf("\n%s\n",St(MProgAborted));
}
}
#endif
void ErrorHandler::SetErrorCode(int Code)
{
switch(Code)
{
case WARNING:
case USER_BREAK:
if (ExitCode==SUCCESS)
ExitCode=Code;
break;
case FATAL_ERROR:
if (ExitCode==SUCCESS || ExitCode==WARNING)
ExitCode=FATAL_ERROR;
break;
default:
ExitCode=Code;
break;
}
ErrCount++;
}
#if !defined(GUI) && !defined(_SFX_RTL_)
#ifdef _WIN_32
BOOL __stdcall ProcessSignal(DWORD SigType)
#else
#if defined(__sun)
extern "C"
#endif
void _stdfunction ProcessSignal(int SigType)
#endif
{
#ifdef _WIN_32
if (SigType==CTRL_LOGOFF_EVENT)
return(TRUE);
#endif
UserBreak=true;
mprintf(St(MBreak));
for (int I=0;!File::RemoveCreated() && I<3;I++)
{
#ifdef _WIN_32
Sleep(100);
#endif
}
#if defined(USE_RC) && !defined(SFX_MODULE) && !defined(_WIN_CE)
ExtRes.UnloadDLL();
#endif
exit(USER_BREAK);
#if defined(_WIN_32) && !defined(_MSC_VER)
// never reached, just to avoid a compiler warning
return(TRUE);
#endif
}
#endif
void ErrorHandler::SetSignalHandlers(bool Enable)
{
EnableBreak=Enable;
#if !defined(GUI) && !defined(_SFX_RTL_)
#ifdef _WIN_32
SetConsoleCtrlHandler(Enable ? ProcessSignal:NULL,TRUE);
// signal(SIGBREAK,Enable ? ProcessSignal:SIG_IGN);
#else
signal(SIGINT,Enable ? ProcessSignal:SIG_IGN);
signal(SIGTERM,Enable ? ProcessSignal:SIG_IGN);
#endif
#endif
}
void ErrorHandler::Throw(int Code)
{
if (Code==USER_BREAK && !EnableBreak)
return;
ErrHandler.SetErrorCode(Code);
#ifdef ALLOW_EXCEPTIONS
throw Code;
#else
File::RemoveCreated();
exit(Code);
#endif
}
void ErrorHandler::SysErrMsg()
{
#if !defined(SFX_MODULE) && !defined(SILENT)
#ifdef _WIN_32
#define STRCHR strchr
#define ERRCHAR char
ERRCHAR *lpMsgBuf=NULL;
int ErrType=GetLastError();
if (ErrType!=0 && FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL,ErrType,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,0,NULL))
{
ERRCHAR *CurMsg=lpMsgBuf;
while (CurMsg!=NULL)
{
while (*CurMsg=='\r' || *CurMsg=='\n')
CurMsg++;
if (*CurMsg==0)
break;
ERRCHAR *EndMsg=STRCHR(CurMsg,'\r');
if (EndMsg==NULL)
EndMsg=STRCHR(CurMsg,'\n');
if (EndMsg!=NULL)
{
*EndMsg=0;
EndMsg++;
}
Log(NULL,"\n%s",CurMsg);
CurMsg=EndMsg;
}
}
LocalFree( lpMsgBuf );
#endif
#if defined(_UNIX) || defined(_EMX)
char *err=strerror(errno);
if (err!=NULL)
Log(NULL,"\n%s",err);
#endif
#endif
}