#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <sysexits.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <signal.h>

enum {
	EX_SUCCESS = 0,
	EX_FAILURE = 1,
};

static char *progname;

static void
error(int exit_code, int error_code, char const *fmt, ...)
{
	va_list ap;

	fprintf(stderr, "%s: ", progname);
	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	va_end(ap);
	if (error_code)
		fprintf(stderr, ": %s", strerror(error_code));
	fputc('\n', stderr);
	if (exit_code)
		exit(exit_code);
}

int
usage(void)
{
	printf("usage: %s HOST PORT\n", progname);
	exit(EX_USAGE);
}

void
sighan(int sig)
{
	error(EX_FAILURE, 0, "time out");
}

int
main(int argc, char **argv)
{
	FILE *fp;
	int fd;
	int rc;
	struct addrinfo hints;
	struct addrinfo *ap;
	char buf[80];
	
	progname = argv[0];
	if (argc != 3)
		usage();

	memset(&hints, 0, sizeof(hints));
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = 0;
	hints.ai_family = AF_INET;

	rc = getaddrinfo(argv[1], argv[2], &hints, &ap);
	switch (rc) {
	case 0:
		break;
	case EAI_SYSTEM:
	case EAI_MEMORY:
		error(EX_OSERR, errno, "getaddrinfo");

	default:
		error(EX_OSERR, 0, "getaddrinfo: %s", gai_strerror(rc));
		return 1;
	}

	signal(SIGALRM, sighan);
	alarm(30);
	       
	fd = socket(ap->ai_addr->sa_family, SOCK_STREAM, 0);
	if (fd == -1)
		error(EX_OSERR, errno, "socket");

	if (connect(fd, ap->ai_addr, ap->ai_addrlen))
		error(EX_FAILURE, errno, "connect");

	fp = fdopen(fd, "w+");
	if (!fp)
		error(EX_OSERR, errno, "fdopen");

	if (!fgets(buf, sizeof(buf), fp)) 
		error(EX_FAILURE, errno, "can't read reply");

	if (!((strncmp(buf, "220", 3) == 0 &&
	       (buf[3] == '0' || buf[3] == ' ' || buf[3] == '-'))))
		error(EX_FAILURE, 0, "unexpected SMTP greeting line: %s", buf);

	return EX_SUCCESS;
}

	
	
