
#pragma once

#include "stream.h"
#include "Socket.h"

extern struct hostent *gethostbyname(char *);
extern struct servent *getservbyname(char *, char *);
extern        int      socket(int, int, int);

Socket::Socket(char* hostname, char* portname)
{
	struct sockaddr_in	sname;
	struct hostent		*hp;
	struct servent		*sp;
	struct in_addr		sa;

	int portnum;

	/*
	 * resolve hostname
	 */

	if (isdigit(*hostname)) {
		if ((sa.s_addr = inet_addr(hostname)) == -1)
			hp = gethostbyname(hostname);
		else
			hp = gethostbyaddr(&sa, sizeof(sa), AF_INET);
	} else
		hp = gethostbyname(hostname);		

	if (hp == NULL)
		printf("Locally unknown host: [%s]\n", hostname);

	/*
	 * resolve portname
	 */

	if (isdigit(*portname))
		portnum = htons(atoi(portname));
	else {
		sp = getservbyname(portname, "tcp");
		if (sp == NULL) {
			cerr << "unknown port " << portname << "\n";
			return;
		}
		portnum = sp->s_port;
		portname = sp->s_name;
	}


	/*
	 * build server socket name
	 */

	bzero(&sname, sizeof(sname));
	sname.sin_family = AF_INET;
	if (hp)
		bcopy(hp->h_addr, &sname.sin_addr, hp->h_length);
	else
		bcopy(&sa.s_addr, &sname.sin_addr, sizeof(sa.s_addr));
	sname.sin_port = portnum;


	/*
	 * create a network socket
	 */

	sock = socket(PF_INET, SOCK_STREAM, 0);
	if (sock < 0) {
		perror("socket");
		return;
	}

	/*
	 * make a connection to the specified server on the socket
	 */

	if (connect(sock, &sname, sizeof(sname)) < 0) {
	  perror("connect");
	  return;
	}

	if (debug) {
	  cout << "debug> Connected to " << hp ? hp->hname : hostname << ", port " << portname << " (" << ntohs(portnum) << ").\n";
	  fflush(stdout);
	}
}
