/*
  FakeServer.cpp



  Fake server

    Console app which listens on a port and when something connects you can talk to it.

  Simply waits for one connection and then goes into an infinite loop pumping data between the socket and the console.



  TODOs
  -
    . Make it allow multiple connections and pop up a different console
    . Recording of the conversations to file
    . Playback of conversations


*/


#include "stdafx.h"


#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#include <winsock.h>
#include <stdio.h>
#include <conio.h>




//---- Default listen port

int LISTEN_PORT = 8080;



//---- Data

WSADATA wi;
unsigned long thrid_sock;
unsigned long thrid_console;
sockaddr_in myaddr;
SOCKET sock;

SOCKET talk;



//---- run_sock

unsigned long __stdcall run_sock(void*)
{
  char buffer[256];
  int read;
  DWORD writ;

  int i;

  //  Read from socket and write to screen

  while( 0 < (read = recv( talk, buffer, 256, 0 )))
  {
    for( i=0; i<read; i++ ) printf("%c", buffer[i] );
  }

  return 0;
}



//---- run_console

unsigned long __stdcall run_console(void*)
{
  char buffer[256];
  DWORD read;
  DWORD writ;
  char c;

  while( c = getch() )
  {
    printf( "%c", c );
    send( talk, &c, 1, 0 );
  }

  return 0;
}



//---- main

int main( int argc, char* argv[] )
{
  //- Get command line argument (port to listen on)

  if( argc > 1 )
  {
    sscanf( argv[1], "%d", &LISTEN_PORT );
  }

  // Startup Winsock

  int err = WSAStartup(0x0101,&wi);

  printf("FakeServer v0.2\nStarted on port %d\n\n--\n", LISTEN_PORT );

  // Create a Socket and bind to a local port

  sock = socket(AF_INET,SOCK_STREAM,0);

  myaddr.sin_family = AF_INET;
  myaddr.sin_port = htons( LISTEN_PORT );
  myaddr.sin_addr.s_addr = INADDR_ANY;

  if( bind(sock,(sockaddr*)&myaddr,sizeof(sockaddr)))
  {
    printf( "ERROR: Could not bind to local port\r\n" );
    return 1;
  }

  // Listen for an incomming connection...

  int a = listen( sock, 1 );

  //  Wait for an incoming connection

  SOCKADDR_IN sa;
  talk = accept( sock, (LPSOCKADDR)&sa, NULL );

  //  Thread 1 - Reads from stdin, writes to dest socket

  CreateThread( NULL, 0, run_sock, NULL, 0, &thrid_sock );

  //  Thread 2 - Reads from remote socket, writes to stdout

  CreateThread( NULL, 0, run_console, NULL, 0, &thrid_console );

  //  infinte loop

  while( true )
  {
    Sleep( 1000 );
  }

  //  Cleanup the socket layer

  WSACleanup();

  return 0;
}


