#include "rar.hpp" #ifndef GUI #include "log.cpp" #endif #ifdef __BIONIC__ #include #endif static int KbdAnsi(char *Addr,int Size); #if !defined(GUI) && !defined(SILENT) static void RawPrint(char *Msg,MESSAGE_TYPE MessageType); static byte GetKey(); #endif static MESSAGE_TYPE MsgStream=MSG_STDOUT; static bool Sound=false; const int MaxMsgSize=2*NM+2048; void InitConsoleOptions(MESSAGE_TYPE MsgStream,bool Sound) { ::MsgStream=MsgStream; ::Sound=Sound; } #if !defined(GUI) && !defined(SILENT) void mprintf(const char *fmt,...) { if (MsgStream==MSG_NULL || MsgStream==MSG_ERRONLY) return; char Msg[MaxMsgSize]; va_list argptr; va_start(argptr,fmt); vsnprintf(Msg,ASIZE(Msg),fmt,argptr); // Different vsnprintf implementation can return either -1 or >=MaxMsgSize // if string is truncated. So we do not check exit code and always zero // terminate the string for safety. It is faster than check for error. Msg[ASIZE(Msg)-1] = 0; RawPrint(Msg,MsgStream); va_end(argptr); } #endif #if !defined(GUI) && !defined(SILENT) void eprintf(const char *fmt,...) { if (MsgStream==MSG_NULL) return; safebuf char Msg[MaxMsgSize]; va_list argptr; va_start(argptr,fmt); vsnprintf(Msg,ASIZE(Msg),fmt,argptr); // Different vsnprintf implementation can return either -1 or >=MaxMsgSize // if string is truncated. So we do not check exit code and always zero // terminate the string for safety. It is faster than check for error. Msg[ASIZE(Msg)-1] = 0; RawPrint(Msg,MSG_STDERR); va_end(argptr); } #endif #if !defined(GUI) && !defined(SILENT) void RawPrint(char *Msg,MESSAGE_TYPE MessageType) { File OutFile; switch(MessageType) { case MSG_STDOUT: OutFile.SetHandleType(FILE_HANDLESTD); break; case MSG_STDERR: case MSG_ERRONLY: OutFile.SetHandleType(FILE_HANDLEERR); break; default: return; } #ifdef _WIN_ALL CharToOemA(Msg,Msg); char OutMsg[MaxMsgSize]; size_t OutPos=0; for (size_t I=0;Msg[I]!=0;I++) { if (Msg[I]=='\n' && (I==0 || Msg[I-1]!='\r') && OutPosSet(PlainPsw); cleandata(PlainPsw,sizeof(PlainPsw)); break; } return(true); } #endif #if !defined(GUI) && !defined(SILENT) byte GetKey() { char Str[80]; bool EndOfFile; #if defined(__GNUC__) || defined(sun) EndOfFile=(fgets(Str,sizeof(Str),stdin)==NULL); #else File SrcFile; SrcFile.SetHandleType(FILE_HANDLESTD); EndOfFile=(SrcFile.Read(Str,sizeof(Str))==0); #endif if (EndOfFile) { // Looks like stdin is a null device. We can enter to infinite loop // calling Ask(), so let's better exit. ErrHandler.Exit(RARX_USERBREAK); } return (byte)Str[0]; } #endif #if !defined(GUI) && !defined(SILENT) int Ask(const char *AskStr) { const int MaxItems=10; char Item[MaxItems][40]; int ItemKeyPos[MaxItems],NumItems=0; for (const char *NextItem=AskStr;NextItem!=NULL;NextItem=strchr(NextItem+1,'_')) { char *CurItem=Item[NumItems]; strncpyz(CurItem,NextItem+1,ASIZE(Item[0])); char *EndItem=strchr(CurItem,'_'); if (EndItem!=NULL) *EndItem=0; int KeyPos=0,CurKey; while ((CurKey=CurItem[KeyPos])!=0) { bool Found=false; for (int I=0;I4 ? "\n":" "):", "); int KeyPos=ItemKeyPos[I]; for (int J=0;J