summaryrefslogtreecommitdiffabout
path: root/kinsole.cpp
Side-by-side diff
Diffstat (limited to 'kinsole.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--kinsole.cpp4
1 files changed, 2 insertions, 2 deletions
diff --git a/kinsole.cpp b/kinsole.cpp
index 01286f3..7fa3f8b 100644
--- a/kinsole.cpp
+++ b/kinsole.cpp
@@ -1,147 +1,147 @@
#include <stdio.h>
#ifdef _DEBUG
#include <afxwin.h>
#else
#define ASSERT(f) ((void)0)
#define VERIFY(f) ((void)(f))
#define TRACE0(sz)
#define TRACE1(sz, p1)
#define TRACE2(sz, p1, p2)
#define TRACE3(sz, p1, p2, p3)
#endif
#include <winsock.h>
#include "resource.h"
#include "windowsx.h"
#define DAMN_KIN_NAME "KINSole"
-#define DAMN_KIN_VERSION "1.1"
+#define DAMN_KIN_VERSION "1.1.1"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
enum {
WM_USERSOCKET = WM_USER+16,
WM_USERKEY,
WM_USERNOP
};
enum {
tnIAC = 255,
tnSE = 240,
tnNOP = 241,
tnDM = 242,
tnBreak = 243,
tnIP = 244,
tnAO = 245,
tnAYT = 246,
tnEC = 247,
tnEL = 248,
tnGA = 249,
tnSB = 250,
tnWILL = 251,
tnWONT = 252,
tnDO = 253,
tnDONT = 254
};
WSADATA wsaData;
ATOM wsaWC = NULL;
HWND wsaW = NULL;
CHAR remoteHost[256];
CHAR remoteProt[256];
sockaddr_in remoteSIN;
SOCKET telnetSocket;
HANDLE hConsoleInput;
HANDLE hConsoleOutput;
HWND hConsoleWindow;
HANDLE hConsoleThread;
DWORD consoleThreadID;
HANDLE hDispatchThread;
DWORD dispatchThreadID;
BOOL bTelnet,bTermPulled;
enum _cState {
cstateNone = 0, cstateIAC, cstateDO, cstateSB, cstateSBData,
cstateSBDataIAC, cstateWILL, cstateDONT,cstateWONT,
} connState = cstateNone;
BYTE negOption = 0;
BOOL SelectSocket() {
return WSAAsyncSelect(telnetSocket,wsaW,WM_USERSOCKET,FD_READ|FD_OOB|FD_CLOSE)!=SOCKET_ERROR;
}
BOOL ShowWill(BYTE o)
{
TRACE1("We're WILLing to %d\n",(WORD)o);
static
BYTE d[3] = {tnIAC,tnWILL,0};
d[2] = o;
BOOL rv = send(telnetSocket,(char*)d,sizeof(d),0)==sizeof(d);
SelectSocket();
return rv;
}
BOOL ShowUnwill(BYTE o)
{
TRACE1("We're NOT WILLing to %d\n",(WORD)o);
static
BYTE d[3] = {tnIAC,tnWONT,0};
d[2] = o;
BOOL rv = send(telnetSocket,(char*)d,sizeof(d),0)==sizeof(d);
SelectSocket();
return rv;
}
BOOL BegDo(BYTE o)
{
TRACE1("We beg to DO %d\n",(WORD)o);
static
BYTE d[3] = {tnIAC,tnDO,0};
d[2] = o;
BOOL rv = send(telnetSocket,(char*)d,sizeof(d),0)==sizeof(d);
SelectSocket();
return rv;
}
BOOL BegDont(BYTE o)
{
TRACE1("We beg DONT'T %d\n",(WORD)o);
static
BYTE d[3] = {tnIAC,tnDONT,0};
d[2] = o;
BOOL rv = send(telnetSocket,(char*)d,sizeof(d),0)==sizeof(d);
SelectSocket();
return rv;
}
BOOL SubNegotiate(BYTE o,LPBYTE data,UINT size)
{
LPBYTE d = new BYTE[3+size*2+2];
int ds = 0;
d[ds++]=tnIAC; d[ds++]=tnSB; d[ds++]=o;
for(UINT tmp=0;tmp<size;tmp++)
if(data[tmp]!=tnIAC)
d[ds++]=data[tmp];
else{
d[ds++]=tnIAC; d[ds++]=tnIAC;
}
d[ds++]=tnIAC;d[ds++]=tnSE;
BOOL rv = send(telnetSocket,(char*)d,ds,0)==ds;
delete d;
SelectSocket();
return rv;
}
BOOL SendLiteral(CHAR c)
{
BYTE d[2] = {tnIAC,0};
BOOL rv = FALSE;
if(c==tnIAC){
d[1]=c;
rv = send(telnetSocket,(char*)d,2,0)==2;
}else
rv = send(telnetSocket,&c,1,0)==1;
return rv;
@@ -425,257 +425,257 @@ void ProcessNetByte(BYTE c)
break;
case cstateIAC:
ProcessIACByte(c);
break;
case cstateNone:
default:
ASSERT(connState==cstateNone);
if(c==tnIAC)
connState=cstateIAC;
else
TerminalOut(c);
break;
}
}
LRESULT WSMessage(WPARAM wP,LPARAM lP)
{
if(WSAGETSELECTERROR(lP)){
TRACE0("SelectError\n");
PostMessage(wsaW,WM_QUIT,0,0);
return 0;
}
if(WSAGETSELECTEVENT(lP)&FD_READ){
//?? TRACE0("FD_READ\n");
BYTE input[80*12];
int got;
TerminalPreO();
//?? TRACE0("rv\n");
got=recv(telnetSocket,(CHAR*)input,sizeof(input),0);
//?? TRACE1("/rv %d\n",got);
for(int tmp=0;tmp<got;tmp++)
ProcessNetByte(input[tmp]);
TerminalPostO();
//?? TRACE0("/FD_READ\n");
return 0;
}
if(WSAGETSELECTEVENT(lP)&FD_OOB){
TRACE0("OOB\n");
}
if(WSAGETSELECTEVENT(lP)&FD_CLOSE){
TRACE0("CLOSE\n");
PostMessage(wsaW,WM_QUIT,0,0);
return 0;
}
VERIFY(SelectSocket());
return 0;
}
LRESULT CALLBACK WSWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg){
case WM_USERSOCKET:
return WSMessage(wParam,lParam);
case WM_USERKEY:
return ProcessConsoleInput();
default:
TRACE0("DEFWINDOWPROC\n");
return ::DefWindowProc(hWnd,uMsg,wParam,lParam);
}
return 0;
}
BOOL InitializeWinsock()
{
if(WSAStartup(0x101,&wsaData)){
printf("Failed to initialize winsock services\n");
return FALSE;
}
WNDCLASS wc;
memset(&wc,0,sizeof(wc));
wc.lpfnWndProc=WSWndProc; wc.hInstance=::GetModuleHandle(NULL);
wc.lpszClassName = "_WSTFWC_";
wsaWC = RegisterClass(&wc);
if(!wsaWC){
printf("Failed to initialize winsock services - 1\n");
return FALSE;
}
wsaW = ::CreateWindow("_WSTFWC_","KIN Sole Mio",0,0,0,0,0,NULL,NULL,::GetModuleHandle(NULL),NULL);
if(!wsaW){
printf("Failed to initialize winsock services\n");
return FALSE;
}
return TRUE;
}
void DeinitializeWinsock()
{
if(wsaW)
::DestroyWindow(wsaW);
wsaW=NULL;
if(wsaWC)
::UnregisterClass("_WSTFWC_",::GetModuleHandle(NULL));
wsaWC=NULL;
WSACleanup();
}
HWND GetThisConsoleWnd()
{
DWORD pid = GetCurrentProcessId();
CHAR title[512];
CHAR* t = title;
if(!GetConsoleTitle(title,sizeof(title)))
t = NULL;
HWND hrv = FindWindowEx(NULL,NULL,"tty",t);
HWND nopro = NULL;
UINT nopros=0;
do{
DWORD wpid;
if(!GetWindowThreadProcessId(hrv,&wpid))
continue;
if(wpid==pid)
return hrv;
nopro=hrv;
nopros++;
hrv = FindWindowEx(NULL,hrv,"tty",t);
}while(hrv);
if(nopros==1){
ASSERT(nopro);
return nopro;
}
return NULL;
}
main(int argc,char*argv[])
{
if(argc<2){
usagebye:
printf(
- DAMN_KIN_NAME " " DAMN_KIN_VERSION ", Copyright (c) 1998-2004 Klever Group (http://www.klever.net/)\n\n"
+ DAMN_KIN_NAME " " DAMN_KIN_VERSION ", Copyright (c) 1998-2005 Klever Group (http://www.klever.net/)\n\n"
"Usage:\t" DAMN_KIN_NAME " [<options> ]<host-name/ip-address>[ <port>]\n\n"
"Options are:\n"
"-r## or -##\tSet number of rows in console screenbuffer\n"
"-c##\t\tSet number of columns in console screenbuffer\n"
"\tnote: changing console screenbuffer size may not work properly\n"
"\twhen in full-screen mode\n"
"-l<user>\tPass username to remote server in environment\n"
"-e<var>=<val>\tPass environment variable to remote server\n"
"-v<var>=<val>\tPass user environment variable to remote server\n"
"-t<termtype>\tChange preferred terminal type\n"
"\tnote: there are only two different terminal emulations in this\n"
"\trelease - one for dumb terminal and one for vt terminal\n"
);
CleanEnvars();
return 1;
}
if(!InitializeWinsock()){
DeinitializeWinsock();
return 2;
}
CONSOLE_SCREEN_BUFFER_INFO csbi;
int ac = 0;
CHAR *ho = NULL, *po = NULL;
HANDLE hConsole = CreateFile("CONOUT$",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,0,NULL);
ASSERT(hConsole);
// *** GetStdHandle(STD_OUTPUT_HANDLE); // *?*?* Do something about redirections and not only here.
VERIFY(GetConsoleScreenBufferInfo(hConsole,&csbi));
BOOL bSized=FALSE;
bTermPulled=FALSE;
for(int tmp=1;tmp<argc;tmp++){
char* v = argv[tmp];
ASSERT(v && *v);
if((*v)=='/' || (*v)=='-'){
int lines = atoi(&v[1]);
if(lines){
if(lines<csbi.dwSize.Y){
SMALL_RECT wi = {0,0,csbi.dwSize.X-1,lines-1};
VERIFY(SetConsoleWindowInfo(hConsole,TRUE,&wi));
}
COORD ns = {csbi.dwSize.X,lines};
if(SetConsoleScreenBufferSize(hConsole,ns))
bSized=TRUE;
}else if(v[1]=='r'){
int lines = atoi(&v[2]);
if(lines){
if(lines<csbi.dwSize.Y){
SMALL_RECT wi = {0,0,csbi.dwSize.X-1,lines-1};
VERIFY(SetConsoleWindowInfo(hConsole,TRUE,&wi));
}
COORD ns = {csbi.dwSize.X,lines};
if(SetConsoleScreenBufferSize(hConsole,ns))
bSized=TRUE;
}else
goto usagebye;
}else if(v[1]=='c'){
int rows = atoi(&v[2]);
if(rows){
if(rows<csbi.dwSize.X){
SMALL_RECT wi = {0,0,rows-1,csbi.dwSize.Y-1};
VERIFY(SetConsoleWindowInfo(hConsole,TRUE,&wi));
}
COORD ns = {rows,csbi.dwSize.Y};
if(SetConsoleScreenBufferSize(hConsole,ns))
bSized=TRUE;
}else
goto usagebye;
}else if(v[1]=='l'){
CHAR* vv = &v[2];
VERIFY(AddEnvar(nesbVar,"USER",vv));
}else if(v[1]=='e'){ // -e<name>=<value> VAR
CHAR* n = &v[2];
CHAR* vv = strchr(&v[2],'=');
if(!vv)
goto usagebye;
*(vv++)=0;
VERIFY(AddEnvar(nesbVar,n,vv));
}else if(v[1]=='v'){ // -v<name>=<value> USERVAR
CHAR* n = &v[2];
CHAR* vv = strchr(n,'=');
if(!vv)
goto usagebye;
*(vv++)=0;
VERIFY(AddEnvar(nesbUserVar,n,vv));
}else if(v[1]=='t'){ // -t<ttype> -t<tname>=<ttype>
CHAR* n = &v[2];
CHAR* nn = strchr(n,'=');
if(nn){
*(nn++)=0;
if(!*nn)
nn=NULL;
}
if(!TerminalPullType(nn?nn:n,nn?n:NULL)){
printf("Available terminal types are:");
TerminalPrintTypes();
printf("\n");
goto usagebye;
}
bTermPulled=TRUE;
}else if(v[1]=='#'){
int cp = atoi(&v[2]);
#ifdef _DEBUG
TRACE2("SetCP(%d)=%d\n",cp,SetConsoleCP(cp));
TRACE2("SetOutCP(%d)=%d\n",cp,SetConsoleOutputCP(cp));
#else
SetConsoleCP(cp);
SetConsoleOutputCP(cp);
#endif
TRACE2("CP,OCP=%d,%d\n",GetConsoleCP(),GetConsoleOutputCP());
}else
goto usagebye;
}else{
if(ac==0){
ho = v;
ac++;
}else if(ac==1){
po = v;
ac++;
}else
goto usagebye;
}
}
if(!ho)
goto usagebye;
servent* se = getservbyname("telnet","tcp");
UINT port = po?atol(po):(se?ntohs(se->s_port):23);
if(port==23 || (se && port==ntohs(se->s_port)))
bTelnet = TRUE;