
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "winsock.h"
#include <time.h>

char *server_ip = "127.0.0.1";
char *server_name = "tftpd32.exe";
int delay = 1;
int port = 21;
char *myname;
WSADATA Data;

void usage(char *str);
unsigned long GetAddr (LPSTR szHost);

main(int argc, char **argv)
{
	char *p;
	myname = *argv;

	if ((p = strrchr(myname,'\\')) != NULL)
		myname = ++p;

	while(--argc)
	{
		p = *++argv;
		if (*p == '-')
		{
			switch(*++p)
			{
				case 'p': port = atoi(++p); if (port < 1) usage(NULL); break;
				case 'd': delay = atoi(++p); break;
				case 'i': server_ip = ++p; break;
				case 's': server_name = ++p; break;
				default:
					usage(*argv);
			}
		}
		else
			usage(NULL);
	}

	if (WSAStartup(MAKEWORD(1, 1), &Data) != 0)
	{
		fprintf(stderr,"%s: Failed to initialize winsock\n", myname);
	}

	for(;;)
	{
		SOCKET sc;
		time_t mt = time(NULL);
		struct tm *tm = localtime(&mt);
		char tbuf[64];
		strftime(tbuf,sizeof(tbuf),"[%x %X]", tm);

		printf("%s %s Trying server --> ", myname, tbuf);
		
		if ((sc = socket(PF_INET,SOCK_STREAM,0)) == INVALID_SOCKET)
		{
			printf("%s: Failed to create socket");
			exit(-1);
		}
	
		// Connect to server
		SOCKADDR_IN sin;
		sin.sin_family = AF_INET;
		sin.sin_port = htons(port);
		sin.sin_addr.S_un.S_addr = GetAddr(server_ip);
	
		// Retry 10 times, each with a 2 second delay to make sure the server is down...
		for(int i = 0; i < 10; i++)
		{
			if (connect(sc,(LPSOCKADDR)&sin,sizeof(sin)))
			{
				int err = WSAGetLastError();
				printf(".");
			}
			else
			{
				printf(" Connected OK\n");
				goto connected_ok;
			}
			Sleep(2000);
		}

		// Start server
		printf(" Failed! Restrarting server.\n");
		system(server_name);

connected_ok:
		closesocket(sc);

		Sleep((DWORD)(delay * (1000 * 60)));
	}

	return 0; // Just to make the compiler happy...
}

void usage(char *str)
{
	if (str)
		fprintf(stderr,"%s: Unknown paramater\n", str);

	fprintf(stderr,"Usage %s [-pPort] [-dDelayInSeconds] [-iServerIP] [-sServerName]\n", myname);
	fprintf(stderr,"Default values:\n\tPort=21\n\tDelay=1 (minute)\n\tServerIP=127.0.0.1\n\tServerName=tftpd32.exe\n\n");
	exit(-1);
}

// The following code is borrowed from the sample code at http://www.sockets.com
/*-----------------------------------------------------------
 * Function: GetAddr()
 *
 * Description: Given a string, it will return an IP address.
 *   - first it tries to convert the string directly
 *   - if that fails, it tries o resolve it as a hostname
 *
 * WARNING: gethostbyname() is a blocking function
 */
unsigned long GetAddr (LPSTR szHost) 
{
  LPHOSTENT lpstHost;
  u_long lAddr = INADDR_ANY;
  
  /* check that we have a string */
  if (*szHost) {
  
    /* check for a dotted-IP address string */
    lAddr = inet_addr (szHost);
  
    /* If not an address, then try to resolve it as a hostname */
    if ((lAddr == INADDR_NONE) &&
        (strcmp(szHost, "255.255.255.255"))) {
      
      lpstHost = gethostbyname(szHost);
      if (lpstHost) {  /* success */
        lAddr = *((u_long FAR *) (lpstHost->h_addr));
      } else {  
        lAddr = INADDR_ANY;   /* failure */
      }
    }
  }
  return (lAddr); 
} /* end GetAddr() */