/*--  First line of WVSock.c ------------------------------------ */
#include <winsock.h>
#include "wvglob.h"
#include "winvn.h"
//#include <errno.h>
#include <stdlib.h>
#include <stdio.h> // for sprintf

#include <memory.h>
#include <dos.h>

#define MAXSENDLEN 32767
#define COMMBUFSIZE  1600

char CommBuff[COMMBUFSIZE];
int CommBuffIdx = COMMBUFSIZE + 1;
int CharsInCommBuff = 0;

struct sockaddr addr;
struct sockaddr from;
struct sockaddr_in sa_in;

SOCKET NNTPSock;

WSADATA winsock_data;

int DebugSock = 0;
char mymesbuf[80];

unsigned long taddr_n, taddr_h;
short tport_n, tport_h;

/*-- function SetupSock --------------------------------------------
 *
 *   Setups up BSD-style socket to the NNTP server.
 *
 *   Returns 1 upon success, else 0.
 */
int SetupSock ()
{
	struct hostent far *hostentry;
	unsigned long ip_address;


	if ((ip_address=inet_addr (NNTPHost)) != INADDR_NONE) {
		sa_in.sin_addr.s_addr = ip_address;
	}
	else {
		if ((hostentry = gethostbyname( NNTPHost )) == NULL) {
			MessageBox (hWndConf, "Can't resolve hostname.", "WinVn", MB_OK);
			exit (1);
		}
		sa_in.sin_addr.s_addr = *(long far *)hostentry->h_addr;
        }

	if ((NNTPSock = socket( AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET) {
		MessageBox (hWndConf, "Have you loaded the network?", "socket() failed", MB_OK);
		exit (1);
	}

	sa_in.sin_family = AF_INET;
	sa_in.sin_port = htons (NNTPPort);

	if (connect( NNTPSock, (struct sockaddr *)&sa_in, sizeof(struct sockaddr_in))==SOCKET_ERROR) {
		MessageBox( hWndConf, "Could not connect to News Server", "WinVn", MB_OK);
		closesocket( NNTPSock );
		exit (0);
	}

	return (1);
}

/* MRRReadComm PutCommLine MRRInitComm MRRCloseComm */

/*-- function MRRReadComm ---------------------------------------
 *
 *  Reads characters from either a serial line or TCP socket.
 */
int MRRReadComm()
{
	int bytesread;
	int myerr;
	u_long lIoctlarg;

	myerr = 0;

	if (CommBuffIdx >= CharsInCommBuff) {
		ioctlsocket( NNTPSock, FIONREAD, &lIoctlarg );

		if (lIoctlarg == 0)
			bytesread = 0;
		else
			bytesread = recv( NNTPSock, CommBuff, COMMBUFSIZE, 0 );

		if (bytesread == SOCKET_ERROR)
			myerr = WSAGetLastError();

		if (!bytesread || (myerr == WSAEWOULDBLOCK) || (myerr == WSAEINPROGRESS)) {
			return (-1);
		}
		else if (bytesread > 0) {
			CharsInCommBuff = bytesread;
			CommBuffIdx = 0;
		}

		else {
			sprintf (mymesbuf, "NNTPSock=%d  bytesread=%d  neterrno=%d", NNTPSock, bytesread, WSAGetLastError());
			MessageBox (hWndConf, mymesbuf, "Unexpected error in MRRReadComm", MB_OK);
			return (-1);
		}
	}
	return (0xff & CommBuff[CommBuffIdx++]);
}


/*-- function PutCommLine ----------------------------------------------
 *
 *  Entry   line   points to a buffer of characters.
 *          nchars is the number of characters to output.
 */
void
putline_internal (char * line, unsigned int nchars)
{
  int num_sent;

  while (nchars > 0) {
  	num_sent = send (NNTPSock, line, nchars, 0);
	if (num_sent == SOCKET_ERROR)
  	  MessageBox (hWndConf, "Error in send ()", "WinVN", MB_OK);
	else {
	  nchars -= num_sent;
	  line += num_sent;
	}
  }
}

void
PutCommLine (line, nchars)
     char *line;
     unsigned int nchars;
{
  putline_internal (line, nchars);
  putline_internal ("\n", 1);
}


/*-- function MRRCloseComm -----------------------------------------
 *
 *  Close the communications port, serial or TCP.
 */
void MRRCloseComm ()
{
  closesocket( NNTPSock );
  WSACleanup();
}

MRRInitComm()
{
  int retcode;

  retcode = WSAStartup (1, &winsock_data);

  switch (retcode) {
   case 0:
	// successful
	break;
   case WSASYSNOTREADY:
	MessageBox (hWndConf, "Network Not Initialized", "WinVN", MB_ICONHAND || MB_OK);
	return (-1);
	break;
   case WSAVERNOTSUPPORTED:
   case WSAEINVAL:
	MessageBox (hWndConf, "WINSOCK Version not supported.", "WinVN", MB_ICONHAND || MB_OK);
	return (-1);
	break;
  }

  retcode = SetupSock();

  if (!retcode) {
    MessageBox (hWndConf, "Can't set up socket", "Initialization error", MB_OK | MB_ICONHAND);
  }

  IgnoreCommCh = '\r';
  EOLCommCh = '\n';

  CommLinePtr = CommLineIn;
  CommState = ST_ESTABLISH_COMM;
  CommBusy = FALSE;
  return (0);
}
