#include <stdlib.h>
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <fcntl.h>
#include <io.h>
#include <signal.h>
#include "pcdefs.h"
#include "shared.h"
#include "netdef.h"
#include "in.h"
#undef NULL
#include <malloc.h>
#include "net.h"
#include "config.h"

int	delete_segment(u_short);
int	get_real_window(u_long, u_long);
int	get_window(u_char _far *base, u_long size);

extern struct conf Scon;
int configure(char *, struct conf *);
unsigned long Sdomain();
struct tcpport tcpout;
char	buf[1024];
char	inbuf[1024];
void onint();
struct overlay { u_long off; u_short seg; };
u_char	_far *bios;
extern u_short slip_mode;

main()
{
	int	i, j, k;
	int	s;
	int	fd, fd1;
	int	wrote;
	struct sockaddr saddr;
	struct ebuf _far *ep;
#ifdef DOMAIN
	unsigned long ret;
#endif
	char *readfile = "read.txt";
	char *writefile = "write.txt";

	bios = 0;
	((struct overlay *)&bios)->seg = get_real_window(0, 0x1000);
	if (((struct overlay *)&bios)->seg == 0) {
	    printf("Can't get BIOS window\n");
	    exit(1);
	}
	if (configure((char *)0, &Scon) < 0) {
		printf("ERROR: reading config.tel\n");
		exit (-1);
	}
	fd = open(readfile, O_RDONLY|O_TEXT, 0);
	if (fd < 0) {
		perror(readfile);
		exit(1);
	}
	fd1 = open(writefile, O_WRONLY|O_CREAT|O_TRUNC|O_TEXT, S_IREAD|S_IWRITE);
	if (fd1 < 0) {
		perror(writefile);
		exit(1);
	}
	i = Snetinit();
	if (i) {
		printf("Snetinit returns %d\n", i);
		exit (-1);
	}
printf("pkshared=%#x:%#x size=%d\n", FP_SEG(pkshared), FP_OFF(pkshared), sizeof (*pkshared));
	signal(SIGINT, onint);
	printf("slip_mode=%d\n", slip_mode);
	printf("Packet info:\n");
	printf("    version %#x\n", pkshared->p.packet_version);
	printf("    class %#x\n", pkshared->p.packet_class);
	printf("    type %#x\n", pkshared->p.packet_type);
	printf("    ifnumber %#x\n", pkshared->p.packet_ifnumber);
	printf("    name %#lx\n", pkshared->p.packet_name);
	printf("    extended %#x\n", pkshared->p.packet_extended);
	/*
	printf("ip handle = %x\n", ip_handle);
	printf("arp handle = %x\n", arp_handle);
	*/
	ep = pkshared->eb;
	printf("ebaddr 0x%x, len = %d\n", (int)ep->start_addr, (int)ep->count);
#ifdef DOMAIN
	i = Sdominit();
	printf("Sdominit returns %d\n", i);

	ret = Sdomain("vax", 36);
	printf("Sdomain returns %lx\n", ret);
#endif

	s = Socket(SOCK_STREAM, &saddr, 0, (struct port *)&tcpout);
	if (s < 0) {
		printf("send Socket returns %d\n", s);
		Snetshut();
		exit(-1);
	}
#ifdef notdef
	saddr.port = htons(L_CLICKS());
	if (SoBind(s, &saddr) < 0) {
		printf("send SoBind returns errord\n");
		Snetshut();
		exit(-1);
	}
	saddr.addr = 0x010101c0L;
	saddr.port = htons(2000);
	i = SoConnect(s, &saddr);
	if (i < 0) {
		printf("SoConnect returns %d\n", i);
		goto err;
	}
#endif
	saddr.port = htons(4000);
	if (SoBind(s, &saddr) < 0) {
		printf("send SoBind returns errord\n");
		Snetshut();
		exit(-1);
	}
	i = SoListen(s);
	printf("SoListen returns %d\n", i);
	if (i < 0) {
		Snetshut();
		exit(-1);
	}
	printf("Hit any key to abort: ");
	fflush(stdout);
	do {
		netsleep();
		i = SoAccept(s, &saddr);
		if (!i && kbhit()) {
			printf("\n");
			goto err;
		}
	} while (i == 0);
	printf("\nSoAccept returns %d\n", i);
	if (i < 0)
		goto err;
	printf("mss=%d\n", tcpout.outsize);
	printf("connected from 0x%lx port %d\n", saddr.addr, ntohs(saddr.port));
	ep = pkshared->eb;
	while ((i = read(fd, buf, sizeof(buf))) > 0) {
/*		printf("ebaddr 0x%x, len = %d\r", (int)ep->start_addr, (int)ep->count); */
		k = SoRead(s, (u_char *)inbuf, sizeof(inbuf));
		if (k > 0) {
			write(fd1, inbuf, k);
		}
		wrote = 0;
		do {
			netsleep();
			j = SoWrite(s, (u_char *)&buf[wrote], i - wrote);
			if (j < 0)
				goto leave;
			wrote += j;
			k = SoRead(s, (u_char *)inbuf, sizeof(inbuf));
			if (k > 0) {
				write(fd1, inbuf, k);
			}
		} while (wrote < i);
	}
leave:
	printf("test: calling SoClose\n");
	i = SoClose(s);
	printf("test: after leave Soclose returns %d\n", i);
	ep = pkshared->eb;
	printf("ebaddr 0x%x, len = %d\n", (int)ep->start_addr, (int)ep->count);
	ep++;
	printf("ebaddr 0x%x, len = %d\n", (int)ep->start_addr, (int)ep->count);
	ep++;
	printf("ebaddr 0x%x, len = %d\n", (int)ep->start_addr, (int)ep->count);
	while ((k = SoRead(s, (u_char *)inbuf, sizeof(inbuf))) >= 0) {
		netsleep();
		if (k > 0) {
			write(fd1, inbuf, k);
		}
	}
	printf("done writing\n");
err:
	printf("hit any key to continue\n");
	while (!kbhit())
		netsleep();
	close(fd);
	close(fd1);
#ifdef DOMAIN
	Sdomshut();
#endif
	Snetshut();
	ep = pkshared->eb;
	for (i = 0; i < NEBUFS + 1; i++) {
	    if (ep->count)
		printf("eb[%d]: ebaddr %#x, len = %d\n", i, ep->start_addr, ep->count);
	    ep++;
	}
	printf("mbprocess=%#x\n", pkshared->mbprocess);
}

void
onint()
{
	Snetshut();
	exit(1);
}
