Code:
/*
* copyright David J. Binette
* ALL RIGHTS RESERVED
*/
/* ------------------------------------------------------------------------ */
#include "dos.h"
/* ------------------------------------------------------------------------ */
#define TRAPCONTROLC 0
/* ------------------------------------------------------------------------ */
#if TRAPCONTROLC
static SESSION * GlobalSessionHook = NULL;
#endif
/* ------------------------------------------------------------------------ */
static void clearToEndOfScreen(SESSION *sess)
{
int num_chars;
DWORD written;
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(sess->o ,&info);
num_chars = info.dwSize.X-info.dwCursorPosition.X + info.dwSize.X*(info.dwSize.Y-info.dwCursorPosition.Y-1);
FillConsoleOutputCharacter(sess->o ,' ',num_chars ,info.dwCursorPosition ,&written);
FillConsoleOutputAttribute(sess->o ,info.wAttributes ,num_chars ,info.dwCursorPosition ,&written);
}
/* ------------------------------------------------------------------------ */
void ClearScreen(SESSION *sess)
{
if(sess->ansi)
fprintf(sess->o ,"\033[H\033[2J");
else
{ COORD coord = {0 ,0};
/* home */
SetConsoleCursorPosition(sess->o ,coord);
/* erase to end of screen */
clearToEndOfScreen(sess);
}
}
/* ------------------------------------------------------------------------ */
char *Ask(SESSION *sess ,const char *prompt ,char *buf ,int n ,short hide)
{
char *p;
DWORD omode=0;
DWORD b;
/* save cursor position */
if(sess->ansi) fprintf(sess->o ,"\033[s");
fprintf(sess->o ,"%s" ,prompt);
if(hide)
{ GetConsoleMode(sess->i ,&omode);
SetConsoleMode(sess->i ,omode &~ ENABLE_ECHO_INPUT);
}
ReadFile( sess->i ,buf ,n ,&b ,0 );
if(hide)
SetConsoleMode(sess->i ,omode);
if(hide>1)
fprintf(sess->o ,"\n");
buf[b] = EOS;
p=strchr(buf ,'\r'); if(p) *p = EOS;
p=strchr(buf ,'\n'); if(p) *p = EOS;
/* restore cursor position */
if(sess->ansi)
{ fprintf(sess->o ,"\033[u");
clearToEndOfScreen(sess);
}
return buf;
}
/* ------------------------------------------------------------------------ */
BOOL KeybDataAvailable(SESSION *sess)
{
INPUT_RECORD inrec;
DWORD num_keys;
if(GetNumberOfConsoleInputEvents(sess->i ,&num_keys)
&& num_keys
&& ReadConsoleInput(sess->i ,&inrec ,1UL ,&num_keys)
&& num_keys
&& (inrec.EventType == KEY_EVENT)
&& inrec.Event.KeyEvent.bKeyDown
)
{ switch(inrec.Event.KeyEvent.wVirtualScanCode) {
case VK_RETURN : FlushConsoleInputBuffer(sess->i);
case VK_NUMLOCK :
case VK_CAPITAL :
case VK_SHIFT :
case VK_CONTROL :
case VK_MENU :
case VK_LWIN :
case VK_RWIN :
case VK_APPS :
break;
default:
return TRUE;
}
}
return FALSE;
}
/* ------------------------------------------------------------------------ */
/* DOS version of a signal handler
* traps ^C
* return TRUE to continue
* return FALSE for default signal handling
*/
#if TRAPCONTROLC
static BOOL WINAPI control_c_handler(DWORD whathappened)
{
BOOL r = FALSE;
if(whathappened == CTRL_C_EVENT)
{ if(GlobalSessionHook->sock != INVALID_SOCKET)
{ closesocket(GlobalSessionHook->sock);
GlobalSessionHook->sock = INVALID_SOCKET;
GlobalSessionHook->quit = 1;
}
r = TRUE;
}
return r;
}
#endif /*TRAPCONTROLC*/
/* ------------------------------------------------------------------------ */
int SessionHook(SESSION *sess ,short state ,short argc ,void* args)
{
int r = TRUE;
switch(state) {
/* the program has started */
/* user data has not yet been entered */
case SHOOK_PROG:
sess->i = GetStdHandle(STD_INPUT_HANDLE);
sess->o = GetStdHandle(STD_OUTPUT_HANDLE);
#if TRAPCONTROLC
GlobalSessionHook = sess;
#endif /*TRAPCONTROLC*/
break;
/* user data is complete */
/* prepare to start networking */
/* login follows this */
case SHOOK_NET: /* validation complete ,ready to start networking */
SetConsoleTitle("Yahmini");
{ WSADATA wsaData;
if(WSAStartup(0x101 ,&wsaData))
{ fprintf(sess->o ,"WSAStartup failed\n");
r = FALSE; /* fail */
}
}
break;
/* login was successful */
/* next is login to chat */
case SHOOK_CHAT:
break;
/* connected to chat */
/* ready to start receiving data */
case SHOOK_RECV:
{ char tmp[CHATNAMESIZE+CHATROOMSIZE+32];
sprintf(tmp ,"%s: %s" ,"Yahmini",sess->user);
SetConsoleTitle(tmp);
fprintf(sess->o ,"waiting for yahoo greeting\n");
#if TRAPCONTROLC
SetConsoleCtrlHandler(control_c_handler ,TRUE);
#endif /*TRAPCONTROLC*/
}
break;
/* yahoo data packet has arrived */
case SHOOK_DATA:
/* on a login packet ,do a room join */
if(sess->yin.type == 0x01)
{ char tmp[CHATNAMESIZE+CHATROOMSIZE+32];
sprintf(tmp ,"%s: %s: %s" ,"Yahmini",sess->user ,sess->room);
SetConsoleTitle(tmp);
fprintf(sess->o ,"Chat started, type /help for help\n");
YahooTextCommand(sess ,"join " ,sess->room);
/* set the return value for the program */
sess->rval = 0;
}
break;
/* an optional hook fron the parser/decoder
* return TRUE if we displayed it here
* return FALSE for the default display handler
*/
case SHOOK_DECODE:
r = FALSE;
break;
/* the user has entered chat text
* args points to the NULL delimited string
* if you return FALSE it wont be sent
* this would be a good place to make macro
* substitutions etc.
*/
case SHOOK_INPUT:
break;
/* all sockets closed */
/* end all networking */
case SHOOK_NETEND:
#if TRAPCONTROLC
SetConsoleCtrlHandler(control_c_handler ,FALSE);
#endif /*TRAPCONTROLC*/
WSACleanup();
break;
/* program is exiting */
case SHOOK_EXIT:
SetConsoleTitle("Yahmini");
fprintf(sess->o ,"done\n");
r = sess->rval;
break;
}
return r;
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(args);
}
/* ------------------------------------------------------------------------ */
/* end */