#include <windows.h>

#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>

#pragma comment(lib, "wsock32.lib")

/*
 * Intrface.c
 *
 *  To compile type cl intrface.c
 */


/* Handles for interface with GS Telnet Server */
HANDLE g_hRlsIEvent = NULL;
HANDLE g_hGetIEvent = NULL;
HANDLE g_hRlsOEvent = NULL;
HANDLE g_hGetOEvent = NULL;
HANDLE g_hAckEvent = NULL;


BOOL appInitEvents(void);
void appUninitEvents(void);


void main(void)
{
    WSADATA Data;
    int nStatus;
    SOCKET hSocket;
    char *szHSocket;
    char ch;
    char szBuf[MAX_PATH];

    __try
    {
        /* Get socket handle from environment */
        szHSocket = getenv("GWTN_HSOCKET");
        if (szHSocket == NULL)
        {
            printf("Environment not set");
            __leave;
        }
        hSocket = (SOCKET)atoi(szHSocket);

        /* Initialize WINSOCK */
        nStatus = WSAStartup(MAKEWORD(1, 1), &Data);
        if (nStatus != 0)
        {
            printf("\nAttempt to run socket app without tcp/ip support");
            __leave;
        }

        /* Initialize interface events */
        if (!appInitEvents())
        {
            printf("\nCould not open events");
            __leave;
        }

        /*
         *   Take over input from socket and wait for acknowledgement
         *   from server
         */
        SetEvent(g_hGetIEvent);
        if (WaitForSingleObject(g_hAckEvent, INFINITE) != WAIT_OBJECT_0)
            __leave;

        /*
         *  Take over output to socket and wait for acknowledgement
         *  from server
         */
        SetEvent(g_hGetOEvent);
        if (WaitForSingleObject(g_hAckEvent, INFINITE) != WAIT_OBJECT_0)
            __leave;

        /*
         *  Wait for chars and echo them until 'q' pressed
         */
        send(hSocket, "\n\rEnter text (I will echo):\n\r", 29, 0);
        while (recv(hSocket, &ch, 1, 0) == 1)
        {
            send(hSocket, &ch, 1, 0);
            if (ch == 'q')
                break;
        }
    }
    __finally
    {
        /* Release control to GS Telnet Server */
        SetEvent(g_hRlsIEvent);
        WaitForSingleObject(g_hAckEvent, INFINITE);
        SetEvent(g_hRlsOEvent);
        WaitForSingleObject(g_hAckEvent, INFINITE);

        /* Clean up event handles */
        appUninitEvents();

        /* Close Winsock, do not close the socket !!!!!! */
        WSACleanup();
    }
}


BOOL appInitEvents(void)
{
    if ((g_hRlsIEvent = OpenEvent(EVENT_ALL_ACCESS,
                                  FALSE,
                                  getenv("GWTN_RLS_I"))) == NULL)
        return FALSE;
    if ((g_hRlsOEvent = OpenEvent(EVENT_ALL_ACCESS,
                                  FALSE,
                                  getenv("GWTN_RLS_O"))) == NULL)
        return FALSE;
    if ((g_hGetIEvent = OpenEvent(EVENT_ALL_ACCESS,
                                  FALSE,
                                  getenv("GWTN_GET_I"))) == NULL)
        return FALSE;
    if ((g_hGetOEvent = OpenEvent(EVENT_ALL_ACCESS,
                                  FALSE,
                                  getenv("GWTN_GET_O"))) == NULL)
        return FALSE;
    if ((g_hAckEvent = OpenEvent(EVENT_ALL_ACCESS,
                                 FALSE,
                                 getenv("GWTN_ACK"))) == NULL)
        return FALSE;
                        

    return TRUE;
}


void appUninitEvents(void)
{
    if (g_hRlsIEvent != NULL)
        CloseHandle(g_hRlsIEvent);
    if (g_hGetIEvent != NULL)
        CloseHandle(g_hGetIEvent);
    if (g_hRlsOEvent != NULL)
        CloseHandle(g_hRlsOEvent);
    if (g_hGetOEvent != NULL)
        CloseHandle(g_hGetOEvent);
    if (g_hAckEvent != NULL)
        CloseHandle(g_hAckEvent);
}
