/* * 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 */