#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>

#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#define DEF_TCP_PORT 2222

int get_sock_fd(char* host_name, char* port)
{
	struct in_addr host_ip;
	struct hostent *hostent;
	int sock = -1;
	struct sockaddr_in serv_addr;
	short int prt = DEF_TCP_PORT;
	int r;

	r = inet_aton(host_name, &host_ip);
	if (r) 
		goto __have_ip;

	/* 'host_name' is not dotted decimal IPv4 address */
	printf("Resolving '%s' ... ", host_name);
	fflush(stdout);
	hostent = gethostbyname(host_name);
	if (!hostent) {
		fprintf(stderr, "Can't resolve %s: %s\n", host_name, hstrerror(h_errno));
		goto __exit;
	}
	host_ip = *(struct in_addr *)hostent->h_addr;
	printf("Ok\n");

      __have_ip:

	if (port) {
		r = sscanf(port, "%hd", &prt);
		if (r != 1)
			printf("Invalid port '%s', will use default %d\n", port, prt);
	}

	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sock) {
		perror("socket()");
		goto __exit;
	};

	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(prt);
	serv_addr.sin_addr = host_ip;

	printf("Connecting to %s:%d... ", host_name, prt); fflush(stdout);
	r = connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
	if (-1 == r) {
		perror("Failed: ");
		close(sock);
		sock = -1;
		goto __exit;
	}
	printf("Ok\n");

      __exit:
	return sock;
}

char buf[256];

void gds_ask(int fd, char *cmd)
{
	int r;
	char c;
	int k;

	printf("SENT: %s", cmd); 
	r = write(fd, cmd, strlen(cmd));
	if (-1 == r) {
		perror("write()");
		exit(1);
	};

	memset(buf, 0, sizeof(buf));
	k = 0;

	do {
		r = read(fd, &c, 1);
		if (-1 == r) {
			perror("read()");
			break;
		};
		buf[k++] = c;

		if (k == sizeof(buf))
			break;

	} while ( c != '\n' );

	printf("RECEIVED: %s", buf); 
}

int main(int argc, char *argv[])
{
	int fd;
	
	if (1 == argc) {
		printf("Usage: %s host [port]\n", argv[0]);
		exit(0);
	};

	/* argv[1] - host, argv[2] - port */
	fd = get_sock_fd(argv[1], argv[2]);
	if (-1 == fd)
		exit(1);

	gds_ask(fd, "*idn?\n");

	close(fd);
	exit(0);
}