123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- #include "rar.hpp"
- #include "log.cpp"
- static MESSAGE_TYPE MsgStream=MSG_STDOUT;
- static RAR_CHARSET RedirectCharset=RCH_DEFAULT;
- static bool ProhibitInput=false;
- const int MaxMsgSize=2*NM+2048;
- static bool StdoutRedirected=false,StderrRedirected=false,StdinRedirected=false;
- #ifdef _WIN_ALL
- static bool IsRedirected(DWORD nStdHandle)
- {
- HANDLE hStd=GetStdHandle(nStdHandle);
- DWORD Mode;
- return GetFileType(hStd)!=FILE_TYPE_CHAR || GetConsoleMode(hStd,&Mode)==0;
- }
- #endif
- void InitConsole()
- {
- #ifdef _WIN_ALL
-
-
-
- setbuf(stdout,NULL);
- setbuf(stderr,NULL);
-
-
-
-
-
- StdoutRedirected=IsRedirected(STD_OUTPUT_HANDLE);
- StderrRedirected=IsRedirected(STD_ERROR_HANDLE);
- StdinRedirected=IsRedirected(STD_INPUT_HANDLE);
- #ifdef _MSC_VER
- if (!StdoutRedirected)
- _setmode(_fileno(stdout), _O_U16TEXT);
- if (!StderrRedirected)
- _setmode(_fileno(stderr), _O_U16TEXT);
- #endif
- #elif defined(_UNIX)
- StdoutRedirected=!isatty(fileno(stdout));
- StderrRedirected=!isatty(fileno(stderr));
- StdinRedirected=!isatty(fileno(stdin));
- #endif
- }
- void SetConsoleMsgStream(MESSAGE_TYPE MsgStream)
- {
- ::MsgStream=MsgStream;
- }
- void SetConsoleRedirectCharset(RAR_CHARSET RedirectCharset)
- {
- ::RedirectCharset=RedirectCharset;
- }
- void ProhibitConsoleInput()
- {
- ProhibitInput=true;
- }
- #ifndef SILENT
- static void cvt_wprintf(FILE *dest,const wchar *fmt,va_list arglist)
- {
-
-
- wchar fmtw[1024];
- PrintfPrepareFmt(fmt,fmtw,ASIZE(fmtw));
- #ifdef _WIN_ALL
- safebuf wchar Msg[MaxMsgSize];
- if (dest==stdout && StdoutRedirected || dest==stderr && StderrRedirected)
- {
- HANDLE hOut=GetStdHandle(dest==stdout ? STD_OUTPUT_HANDLE:STD_ERROR_HANDLE);
- vswprintf(Msg,ASIZE(Msg),fmtw,arglist);
- DWORD Written;
- if (RedirectCharset==RCH_UNICODE)
- WriteFile(hOut,Msg,(DWORD)wcslen(Msg)*sizeof(*Msg),&Written,NULL);
- else
- {
-
- safebuf char MsgA[MaxMsgSize];
- if (RedirectCharset==RCH_UTF8)
- WideToUtf(Msg,MsgA,ASIZE(MsgA));
- else
- WideToChar(Msg,MsgA,ASIZE(MsgA));
- if (RedirectCharset==RCH_DEFAULT || RedirectCharset==RCH_OEM)
- CharToOemA(MsgA,MsgA);
-
-
- WriteFile(hOut,MsgA,(DWORD)strlen(MsgA),&Written,NULL);
- }
- return;
- }
-
-
- vswprintf(Msg,ASIZE(Msg),fmtw,arglist);
- HANDLE hOut=GetStdHandle(dest==stderr ? STD_ERROR_HANDLE:STD_OUTPUT_HANDLE);
- DWORD Written;
- WriteConsole(hOut,Msg,(DWORD)wcslen(Msg),&Written,NULL);
- #else
- vfwprintf(dest,fmtw,arglist);
-
- fflush(dest);
- #endif
- }
- void mprintf(const wchar *fmt,...)
- {
- if (MsgStream==MSG_NULL || MsgStream==MSG_ERRONLY)
- return;
- fflush(stderr);
- va_list arglist;
- va_start(arglist,fmt);
- FILE *dest=MsgStream==MSG_STDERR ? stderr:stdout;
- cvt_wprintf(dest,fmt,arglist);
- va_end(arglist);
- }
- #endif
- #ifndef SILENT
- void eprintf(const wchar *fmt,...)
- {
- if (MsgStream==MSG_NULL)
- return;
- fflush(stdout);
- va_list arglist;
- va_start(arglist,fmt);
- cvt_wprintf(stderr,fmt,arglist);
- va_end(arglist);
- }
- #endif
- #ifndef SILENT
- static void QuitIfInputProhibited()
- {
-
-
- if (ProhibitInput)
- {
- mprintf(St(MStdinNoInput));
- ErrHandler.Exit(RARX_FATAL);
- }
- }
- static void GetPasswordText(wchar *Str,uint MaxLength)
- {
- if (MaxLength==0)
- return;
- QuitIfInputProhibited();
- if (StdinRedirected)
- getwstr(Str,MaxLength);
- else
- {
- #ifdef _WIN_ALL
- HANDLE hConIn=GetStdHandle(STD_INPUT_HANDLE);
- DWORD ConInMode;
- GetConsoleMode(hConIn,&ConInMode);
- SetConsoleMode(hConIn,ENABLE_LINE_INPUT);
-
- DWORD Read=0;
- ReadConsole(hConIn,Str,MaxLength-1,&Read,NULL);
- Str[Read]=0;
- SetConsoleMode(hConIn,ConInMode);
-
-
-
-
-
- if (wcschr(Str,'\r')==NULL)
- while (true)
- {
- wchar Trail[64];
- DWORD TrailRead=0;
-
- ReadConsole(hConIn,Trail,ASIZE(Trail)-1,&TrailRead,NULL);
- Trail[TrailRead]=0;
- if (TrailRead==0 || wcschr(Trail,'\r')!=NULL)
- break;
- }
- #else
- char StrA[MAXPASSWORD*4];
- #if defined(_EMX) || defined (__VMS)
- fgets(StrA,ASIZE(StrA)-1,stdin);
- #elif defined(__sun)
- strncpyz(StrA,getpassphrase(""),ASIZE(StrA));
- #else
- strncpyz(StrA,getpass(""),ASIZE(StrA));
- #endif
- CharToWide(StrA,Str,MaxLength);
- cleandata(StrA,sizeof(StrA));
- #endif
- }
- Str[MaxLength-1]=0;
- RemoveLF(Str);
- }
- #endif
- #ifndef SILENT
- bool GetConsolePassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *Password)
- {
- if (!StdinRedirected)
- uiAlarm(UIALARM_QUESTION);
-
- while (true)
- {
- if (Type==UIPASSWORD_GLOBAL)
- eprintf(L"\n%s: ",St(MAskPsw));
- else
- eprintf(St(MAskPswFor),FileName);
- wchar PlainPsw[MAXPASSWORD+1];
- GetPasswordText(PlainPsw,ASIZE(PlainPsw));
- if (*PlainPsw==0 && Type==UIPASSWORD_GLOBAL)
- return false;
- if (wcslen(PlainPsw)>=MAXPASSWORD)
- {
- PlainPsw[MAXPASSWORD-1]=0;
- uiMsg(UIERROR_TRUNCPSW,MAXPASSWORD-1);
- }
- if (!StdinRedirected && Type==UIPASSWORD_GLOBAL)
- {
- eprintf(St(MReAskPsw));
- wchar CmpStr[MAXPASSWORD];
- GetPasswordText(CmpStr,ASIZE(CmpStr));
- if (*CmpStr==0 || wcscmp(PlainPsw,CmpStr)!=0)
- {
- eprintf(St(MNotMatchPsw));
- cleandata(PlainPsw,sizeof(PlainPsw));
- cleandata(CmpStr,sizeof(CmpStr));
- continue;
- }
- cleandata(CmpStr,sizeof(CmpStr));
- }
- Password->Set(PlainPsw);
- cleandata(PlainPsw,sizeof(PlainPsw));
- break;
- }
- return true;
- }
- #endif
- #ifndef SILENT
- bool getwstr(wchar *str,size_t n)
- {
-
- fflush(stderr);
- QuitIfInputProhibited();
- *str=0;
- #if defined(_WIN_ALL)
-
-
- if (StdinRedirected)
- {
-
-
- Array<char> StrA(n*4);
- File SrcFile;
- SrcFile.SetHandleType(FILE_HANDLESTD);
- SrcFile.SetLineInputMode(true);
- int ReadSize=SrcFile.Read(&StrA[0],StrA.Size()-1);
- if (ReadSize<=0)
- {
-
-
- ErrHandler.Exit(RARX_USERBREAK);
- }
- StrA[ReadSize]=0;
-
-
-
-
-
- CharToWide(&StrA[0],str,n);
- cleandata(&StrA[0],StrA.Size());
- }
- else
- {
- DWORD ReadSize=0;
- if (ReadConsole(GetStdHandle(STD_INPUT_HANDLE),str,DWORD(n-1),&ReadSize,NULL)==0)
- return false;
- str[ReadSize]=0;
- }
- #else
- if (fgetws(str,n,stdin)==NULL)
- ErrHandler.Exit(RARX_USERBREAK);
- #endif
- RemoveLF(str);
- return true;
- }
- #endif
- #ifndef SILENT
- int Ask(const wchar *AskStr)
- {
- uiAlarm(UIALARM_QUESTION);
- const int MaxItems=10;
- wchar Item[MaxItems][40];
- int ItemKeyPos[MaxItems],NumItems=0;
- for (const wchar *NextItem=AskStr;NextItem!=NULL;NextItem=wcschr(NextItem+1,'_'))
- {
- wchar *CurItem=Item[NumItems];
- wcsncpyz(CurItem,NextItem+1,ASIZE(Item[0]));
- wchar *EndItem=wcschr(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 (toupperw(Item[I][ItemKeyPos[I]])==toupperw(CurKey))
- Found=true;
- if (!Found && CurKey!=' ')
- break;
- KeyPos++;
- }
- ItemKeyPos[NumItems]=KeyPos;
- NumItems++;
- }
- for (int I=0;I<NumItems;I++)
- {
- eprintf(I==0 ? (NumItems>3 ? L"\n":L" "):L", ");
- int KeyPos=ItemKeyPos[I];
- for (int J=0;J<KeyPos;J++)
- eprintf(L"%c",Item[I][J]);
- eprintf(L"[%c]%ls",Item[I][KeyPos],&Item[I][KeyPos+1]);
- }
- eprintf(L" ");
- wchar Str[50];
- getwstr(Str,ASIZE(Str));
- wchar Ch=toupperw(Str[0]);
- for (int I=0;I<NumItems;I++)
- if (Ch==Item[I][ItemKeyPos[I]])
- return I+1;
- return 0;
- }
- #endif
- static bool IsCommentUnsafe(const wchar *Data,size_t Size)
- {
- for (size_t I=0;I<Size;I++)
- if (Data[I]==27 && Data[I+1]=='[')
- for (size_t J=I+2;J<Size;J++)
- {
-
-
- if (Data[J]=='\"')
- return true;
- if (!IsDigit(Data[J]) && Data[J]!=';')
- break;
- }
- return false;
- }
- void OutComment(const wchar *Comment,size_t Size)
- {
- if (IsCommentUnsafe(Comment,Size))
- return;
- const size_t MaxOutSize=0x400;
- for (size_t I=0;I<Size;I+=MaxOutSize)
- {
- wchar Msg[MaxOutSize+1];
- size_t CopySize=Min(MaxOutSize,Size-I);
- wcsncpy(Msg,Comment+I,CopySize);
- Msg[CopySize]=0;
- mprintf(L"%s",Msg);
- }
- mprintf(L"\n");
- }
|