295 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			295 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C++
		
	
	
	
| #include "rar.hpp"
 | |
| 
 | |
| #ifndef GUI
 | |
| #include "log.cpp"
 | |
| #endif
 | |
| 
 | |
| static int KbdAnsi(char *Addr,int Size);
 | |
| 
 | |
| #if !defined(GUI) && !defined(SILENT)
 | |
| static void RawPrint(char *Msg,MESSAGE_TYPE MessageType);
 | |
| static uint 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;
 | |
|   safebuf char Msg[MaxMsgSize];
 | |
|   va_list argptr;
 | |
|   va_start(argptr,fmt);
 | |
|   vsprintf(Msg,fmt,argptr);
 | |
|   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);
 | |
|   vsprintf(Msg,fmt,argptr);
 | |
|   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_32
 | |
|   CharToOem(Msg,Msg);
 | |
| 
 | |
|   char OutMsg[MaxMsgSize],*OutPos=OutMsg;
 | |
|   for (int I=0;Msg[I]!=0;I++)
 | |
|   {
 | |
|     if (Msg[I]=='\n' && (I==0 || Msg[I-1]!='\r'))
 | |
|       *(OutPos++)='\r';
 | |
|     *(OutPos++)=Msg[I];
 | |
|   }
 | |
|   *OutPos=0;
 | |
|   strcpy(Msg,OutMsg);
 | |
| #endif
 | |
| #if defined(_UNIX) || defined(_EMX)
 | |
|   char OutMsg[MaxMsgSize],*OutPos=OutMsg;
 | |
|   for (int I=0;Msg[I]!=0;I++)
 | |
|     if (Msg[I]!='\r')
 | |
|       *(OutPos++)=Msg[I];
 | |
|   *OutPos=0;
 | |
|   strcpy(Msg,OutMsg);
 | |
| #endif
 | |
| 
 | |
|   OutFile.Write(Msg,strlen(Msg));
 | |
| //  OutFile.Flush();
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 
 | |
| #ifndef SILENT
 | |
| void Alarm()
 | |
| {
 | |
| #ifndef SFX_MODULE
 | |
|   if (Sound)
 | |
|     putchar('\007');
 | |
| #endif
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 
 | |
| #ifndef SILENT
 | |
| #ifndef GUI
 | |
| void GetPasswordText(char *Str,int MaxLength)
 | |
| {
 | |
| #ifdef _WIN_32
 | |
|   HANDLE hConIn=GetStdHandle(STD_INPUT_HANDLE);
 | |
|   HANDLE hConOut=GetStdHandle(STD_OUTPUT_HANDLE);
 | |
|   DWORD ConInMode,ConOutMode;
 | |
|   DWORD Read=0;
 | |
|   GetConsoleMode(hConIn,&ConInMode);
 | |
|   GetConsoleMode(hConOut,&ConOutMode);
 | |
|   SetConsoleMode(hConIn,ENABLE_LINE_INPUT);
 | |
|   SetConsoleMode(hConOut,ENABLE_PROCESSED_OUTPUT|ENABLE_WRAP_AT_EOL_OUTPUT);
 | |
|   ReadConsole(hConIn,Str,MaxLength-1,&Read,NULL);
 | |
|   Str[Read]=0;
 | |
|   OemToChar(Str,Str);
 | |
|   SetConsoleMode(hConIn,ConInMode);
 | |
|   SetConsoleMode(hConOut,ConOutMode);
 | |
| #elif defined(_EMX) || defined(_BEOS) || defined(__sparc) || defined(sparc) || defined (__VMS)
 | |
|   fgets(Str,MaxLength-1,stdin);
 | |
| #else
 | |
|   strncpyz(Str,getpass(""),MaxLength);
 | |
| #endif
 | |
|   Str[MaxLength-1]=0;
 | |
|   RemoveLF(Str);
 | |
| }
 | |
| #endif
 | |
| #endif
 | |
| 
 | |
| 
 | |
| #ifndef SILENT
 | |
| bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxLength)
 | |
| {
 | |
|   Alarm();
 | |
|   while (true)
 | |
|   {
 | |
|     char PromptStr[NM+256];
 | |
| #if defined(_EMX) || defined(_BEOS)
 | |
|     strcpy(PromptStr,St(MAskPswEcho));
 | |
| #else
 | |
|     strcpy(PromptStr,St(MAskPsw));
 | |
| #endif
 | |
|     if (Type!=PASSWORD_GLOBAL)
 | |
|     {
 | |
|       strcat(PromptStr,St(MFor));
 | |
|       char *NameOnly=PointToName(FileName);
 | |
|       if (strlen(PromptStr)+strlen(NameOnly)<ASIZE(PromptStr))
 | |
|         strcat(PromptStr,NameOnly);
 | |
|     }
 | |
|     eprintf("\n%s: ",PromptStr);
 | |
|     GetPasswordText(Password,MaxLength);
 | |
|     if (*Password==0 && Type==PASSWORD_GLOBAL)
 | |
|       return(false);
 | |
|     if (Type==PASSWORD_GLOBAL)
 | |
|     {
 | |
|       eprintf(St(MReAskPsw));
 | |
|       char CmpStr[MAXPASSWORD];
 | |
|       GetPasswordText(CmpStr,ASIZE(CmpStr));
 | |
|       if (*CmpStr==0 || strcmp(Password,CmpStr)!=0)
 | |
|       {
 | |
|         eprintf(St(MNotMatchPsw));
 | |
|         memset(Password,0,MaxLength);
 | |
|         memset(CmpStr,0,sizeof(CmpStr));
 | |
|         continue;
 | |
|       }
 | |
|       memset(CmpStr,0,sizeof(CmpStr));
 | |
|     }
 | |
|     break;
 | |
|   }
 | |
|   return(true);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 
 | |
| #if !defined(GUI) && !defined(SILENT)
 | |
| uint 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(USER_BREAK);
 | |
|   }
 | |
|   return(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;I<NumItems && !Found;I++)
 | |
|         if (loctoupper(Item[I][ItemKeyPos[I]])==loctoupper(CurKey))
 | |
|           Found=true;
 | |
|       if (!Found && CurKey!=' ')
 | |
|         break;
 | |
|       KeyPos++;
 | |
|     }
 | |
|     ItemKeyPos[NumItems]=KeyPos;
 | |
|     NumItems++;
 | |
|   }
 | |
| 
 | |
|   for (int I=0;I<NumItems;I++)
 | |
|   {
 | |
|     eprintf(I==0 ? (NumItems>4 ? "\n":" "):", ");
 | |
|     int KeyPos=ItemKeyPos[I];
 | |
|     for (int J=0;J<KeyPos;J++)
 | |
|       eprintf("%c",Item[I][J]);
 | |
|     eprintf("[%c]%s",Item[I][KeyPos],&Item[I][KeyPos+1]);
 | |
|   }
 | |
|   eprintf(" ");
 | |
|   int Ch=GetKey();
 | |
| #if defined(_WIN_32)
 | |
|   OemToCharBuff((LPCSTR)&Ch,(LPTSTR)&Ch,1);
 | |
| #endif
 | |
|   Ch=loctoupper(Ch);
 | |
|   for (int I=0;I<NumItems;I++)
 | |
|     if (Ch==Item[I][ItemKeyPos[I]])
 | |
|       return(I+1);
 | |
|   return(0);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 
 | |
| int KbdAnsi(char *Addr,size_t Size)
 | |
| {
 | |
|   int RetCode=0;
 | |
| #ifndef GUI
 | |
|   for (size_t I=0;I<Size;I++)
 | |
|     if (Addr[I]==27 && Addr[I+1]=='[')
 | |
|     {
 | |
|       for (size_t J=I+2;J<Size;J++)
 | |
|       {
 | |
|         if (Addr[J]=='\"')
 | |
|           return(2);
 | |
|         if (!IsDigit(Addr[J]) && Addr[J]!=';')
 | |
|           break;
 | |
|       }
 | |
|       RetCode=1;
 | |
|     }
 | |
| #endif
 | |
|   return(RetCode);
 | |
| }
 | |
| 
 | |
| 
 | |
| void OutComment(char *Comment,size_t Size)
 | |
| {
 | |
| #ifndef GUI
 | |
|   if (KbdAnsi(Comment,Size)==2)
 | |
|     return;
 | |
|   const size_t MaxOutSize=0x400;
 | |
|   for (size_t I=0;I<Size;I+=MaxOutSize)
 | |
|   {
 | |
|     char Msg[MaxOutSize+1];
 | |
|     size_t CopySize=Min(MaxOutSize,Size-I);
 | |
|     strncpy(Msg,Comment+I,CopySize);
 | |
|     Msg[CopySize]=0;
 | |
|     mprintf("%s",Msg);
 | |
|   }
 | |
|   mprintf("\n");
 | |
| #endif
 | |
| }
 |