/*
**	Joerg Czeranski
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

static char sccsid[] = "@(#)up.c	1.5 8/27/97";


#define N_TRIES 5
#define TIMEOUT 2000 /* ms */

static char *me;


static void fatal()
{
	perror(me);
	exit(2);
}


int main(argc, argv)
int argc;
char **argv;
{
	char *host;
	struct hostent *h_ent;
	int s;
	struct sockaddr_in a;
	fd_set rfds;
	struct timeval t;
	int i;
	unsigned long h;

	(me = strrchr(argv[0], '/')) ? me++ : (me = argv[0]);

	if (argc != 2)
	{
		fprintf(stderr, "usage: %s host\n", me);
		return 1;
	}

	host = argv[1];

	memset(&a, 0, sizeof a);
	a.sin_family = AF_INET;
	a.sin_port = htons(65000 + rand() % 535);

	if (((h = inet_addr(host)) & 0xffffffff) != 0xffffffff)
		a.sin_addr.s_addr = h;
	else if ((h_ent = gethostbyname(host)) != NULL)
		memcpy(&a.sin_addr, h_ent->h_addr, sizeof a.sin_addr);
	else
	{
		fprintf(stderr, "%s: unknown host %s\n", me, host);
		return 3;
	}

	if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
		fatal();

	srand(time(NULL) + getpid());

	if (connect(s, (struct sockaddr *)&a, sizeof a))
		fatal();

	if (send(s, "", 0, 0) < 0)
		fatal();

	FD_ZERO(&rfds);
	FD_SET(s, &rfds);

	for (i = 0; i < N_TRIES; i++)
	{
		t.tv_sec = TIMEOUT / 1000;
		t.tv_usec = TIMEOUT % 1000 * 1000;
		switch (select(s + 1, &rfds, NULL, NULL, &t))
		{
		case -1:
			fatal();

		case 0:
			continue;

		default:
			printf("%s is alive\n", host);
			return 0;
		}
	}

	printf("no answer from %s\n", host);
	return 10;
}
