#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>


void HandleForked(int sock) {
	int r;
	char buf[128];

	printf("Process %i recv()ing on %i\n",GetCurrentProcessId(),sock);
	r = recv(sock,buf,sizeof(buf),0);
	printf("recv return: %i, error %i\n",r,GetLastError());
	exit(0);
}

int main(int argc, char *argv[])
{
	int sock,sock2,sock3;
	struct sockaddr_in a;
	DWORD as;
	char cmd[128];
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	WSADATA wsaData;

	if (WSAStartup(MAKEWORD(2,0), &wsaData) != 0) {
		printf("WSAStartup() failed: %i\n",GetLastError());
		exit(1);
	}

	if (argc != 1)
		HandleForked(atoi(argv[1]));

	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock == INVALID_SOCKET) {
		printf("socket() failed: %i\n",GetLastError());
		exit(1);
	}

	a.sin_family = AF_INET;
	a.sin_addr.s_addr = INADDR_ANY;
	a.sin_port = htons(999);

	if (bind(sock, (struct sockaddr *)&a, sizeof(a))) {
		printf("bind() falied: %i\n",GetLastError());
		exit(1);
	}

	if (listen(sock,2)) {
		printf("listen() failed: %i\n",GetLastError());
		exit(1);
	}

	printf("%i now accept()ing...\n",GetCurrentProcessId());
	as = sizeof(a);
	ZeroMemory(&a,sizeof(a));
	sock2 = accept(sock, &a, &as);
	if (sock2 == INVALID_SOCKET) {
		printf("accept() failed: %i\n",GetLastError());
		exit(1);
	}
	printf("%i accept()ed %i\n",GetCurrentProcessId(),sock2);

	if (!DuplicateHandle(GetCurrentProcess(),
						 (HANDLE)sock2,
						 GetCurrentProcess(),
						 (HANDLE*)&sock3,
						 0,
						 TRUE,
						 DUPLICATE_SAME_ACCESS))
	{
		printf("Failed to duplicate handle: %i\n",GetLastError());
		exit(1);
	}

	printf("%i now execing...\n",GetCurrentProcessId());

	wsprintf(cmd,"sockt.exe %i",sock3);
	ZeroMemory(&si,sizeof(si));
	ZeroMemory(&pi,sizeof(pi));
	si.cb =sizeof(si);
	if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
		printf("CreateProcess() failed: %i\n",GetLastError());
		exit(1);
	}

	Sleep(2000);
	printf("Master exiting\n");
	exit(0);
}

