|
|
/*
* Copyright (c) Microsoft Corporation * * Module Name : * main.c * * This is the main file containing the client code. * * * Sadagopan Rajaram -- Oct 14, 1999 * */
// Can kill this program on a normal NT console using the
// Alt - X Key combination. Just a shortcut, that is all.
// Serves no useful purpose.
#include "tcclnt.h"
#include "tcsrvc.h"
WSABUF ReceiveBuffer; CHAR RecvBuf[MAX_BUFFER_SIZE]; IO_STATUS_BLOCK IoStatus; HANDLE InputHandle; DWORD bytesRecvd; WSAOVERLAPPED junk; SOCKET cli_sock; DWORD flags;
#if _MSC_FULL_VER >= 13008827
#pragma warning(push)
#pragma warning(disable:4715) // Not all control paths return (due to infinite loop)
#endif
DWORD inputUpdate( PVOID dummy ) { // Runs in a single thread getting all the inputs
// from the keyboard.
ULONG result; // gets a multibyte string for every character
// pressed on the keyboard.
CHAR r[MB_CUR_MAX + 1];
while(1){ r[0] = _T('\0'); inchar(r); // BUGBUG - Performance issues in sending a single character
// at a time across the n/w
if(strlen(r)){ // may send a single byte or two bytes.
send(cli_sock,r,strlen(r),0); } } return 1;
}
#if _MSC_FULL_VER >= 13008827
#pragma warning(pop)
#endif
VOID sendUpdate( IN DWORD dwError, IN DWORD cbTransferred, IN LPWSAOVERLAPPED lpOverLapped, IN DWORD dwFlags ) { int error,i; // Receives a packet and sends it through the stream parser
// BUGBUG - For effeciency it can be made inline.
// I am not sure of the performance increase, but it should
// be substantial as we will be sending a lot of data.
if(dwError != 0){ exit(1); } for(i=0;i < (int)cbTransferred;i++){ PrintChar(ReceiveBuffer.buf[i]); } // Repost the receive on the socket.
error = WSARecv(cli_sock, &ReceiveBuffer, 1, &bytesRecvd, &flags, &junk, sendUpdate ); if((error == SOCKET_ERROR) &&(WSAGetLastError()!=WSA_IO_PENDING)){ // Implies something wrong with the socket.
exit(1); } return;
}
int __cdecl main( IN int argc, char *argv[] ) /*++
Opens a single port, binds to the tcserver and passes information back and forth. --*/ { struct sockaddr_in srv_addr,cli_addr; LPHOSTENT host_info; CLIENT_INFO SendInfo; int status; WSADATA data; #ifdef UNICODE
// BUGBUG - Trying to write a code that works for
// both Unicode and ASCII. Gets multi byte sequences
// Confusion when the tcclnt and tcclnt are in different
// modes.
ANSI_STRING Src; UNICODE_STRING Dest; #endif
NTSTATUS Status; HANDLE Thread; DWORD ThreadId; COORD coord; SMALL_RECT rect; int RetVal; struct hostent *ht; ULONG r; TCHAR Buffer[80];
if((argc<2) || (argc >4)){ // Error in running the program
printf("Usage - tcclnt COMPORTNAME [ipaddress]\n"); exit(0); }
ThreadId = GetEnvironmentVariable(_T("TERM"),Buffer , 80); // We need to know if we have a vt100 screen or an ANSI screen.
AttributeFunction = ProcessTextAttributes; if(ThreadId >0){ // Terminal type exists in the environment.
// Use it
if((_tcsncmp(Buffer, _T("VT100"), 5) == 0)|| _tcsncmp(Buffer, _T("vt100"),5) ==0 ) AttributeFunction = vt100Attributes; }
hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE); coord.X = MAX_TERMINAL_WIDTH; coord.Y = MAX_TERMINAL_HEIGHT; rect.Left = rect.Top = 0; rect.Right = MAX_TERMINAL_WIDTH -1; rect.Bottom = MAX_TERMINAL_HEIGHT -1;
if(hConsoleOutput == NULL){ printf("Could not get current console handle %d\n", GetLastError()); return 1; }
RetVal = SetConsoleScreenBufferSize(hConsoleOutput, coord );
RetVal = SetConsoleWindowInfo(hConsoleOutput, TRUE, &rect ); if (RetVal == FALSE) { printf("Could not set window size %d\n", GetLastError()); return 1; } RetVal = SetConsoleMode(hConsoleOutput,ENABLE_PROCESSED_OUTPUT); if(RetVal == FALSE){ printf("Could not console mode %d\n", GetLastError()); return 1; }
/* Set up client socket */ InputHandle = GetStdHandle(STD_INPUT_HANDLE); if(InputHandle == NULL) return 1; SetConsoleMode(InputHandle, 0); status=WSAStartup(514,&data);
if(status){ printf("Cannot start up %d\n",status); return(1); }
cli_sock=WSASocket(PF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
if (cli_sock==INVALID_SOCKET){ printf("Windows Sockets error %d: Couldn't create socket.", WSAGetLastError()); return(1); }
cli_addr.sin_family=AF_INET; cli_addr.sin_addr.s_addr=INADDR_ANY; cli_addr.sin_port=0; /* no specific port req'd */
/* Bind client socket to any local interface and port */
if (bind(cli_sock,(LPSOCKADDR)&cli_addr,sizeof(cli_addr))==SOCKET_ERROR){ printf("Windows Sockets error %d: Couldn't bind socket.", WSAGetLastError()); return(1); }
srv_addr.sin_family = AF_INET; if(argc == 3){ srv_addr.sin_addr.s_addr = inet_addr(argv[2]); if (srv_addr.sin_addr.s_addr == INADDR_NONE) { ht = gethostbyname(argv[2]); if(!ht || !ht->h_addr){ // cannot resolve the name
printf("Cannot resolve %s", argv[2]); exit(1); } memcpy((&(srv_addr.sin_addr.s_addr)),ht->h_addr, ht->h_length); } } else{ srv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); } srv_addr.sin_port=htons(SERVICE_PORT);
/* Connect to FTP server at address SERVER */
if (connect(cli_sock,(LPSOCKADDR)&srv_addr,sizeof(srv_addr))==SOCKET_ERROR){ printf("Windows Sockets error %d: Couldn't connect socket.\n", WSAGetLastError()); return(1); }
SendInfo.len = sizeof(CLIENT_INFO);
#ifdef UNICODE
Src.Buffer = argv[1]; Src.Length = (USHORT)strlen(argv[1]); Dest.Buffer = SendInfo.device; Dest.MaximumLength = MAX_BUFFER_SIZE; Status = RtlAnsiStringToUnicodeString(&Dest, &Src, FALSE); if (!NT_SUCCESS(Status)) { printf("RtlAnsiStringToUnicodeString failed, ec = 0x%08x\n",Status); exit(1); } send(cli_sock, (PCHAR) &SendInfo, sizeof(CLIENT_INFO), 0); #else
// We are sending to an ANSI String
strcpy(SendInfo.device, argv[1]); send(cli_sock, (PCHAR) &SendInfo, sizeof(CLIENT_INFO), 0); #endif
ReceiveBuffer.len = MAX_BUFFER_SIZE; ReceiveBuffer.buf = RecvBuf; status=WSARecv(cli_sock, &ReceiveBuffer, 1, &bytesRecvd, &flags, &junk, sendUpdate ); if((status == SOCKET_ERROR) &&(WSAGetLastError() != WSA_IO_PENDING)){ printf("Error in recv %d\n",WSAGetLastError()); exit(1); } // Create a thread that gets input from the console
// to send to the bridge.
Thread = CreateThread(NULL, 0, inputUpdate, NULL, 0, &ThreadId ); if (Thread== NULL) { exit(1); } CloseHandle(Thread);
while(1){ // Put this thread in an alertable
// state so that the receive calls can
// asynchronously terminate within the
// context of this thread.
status=SleepEx(INFINITE,TRUE); } // We never return here.
closesocket(cli_sock); return 0; }
|