/*  Dictionary Client.
 *
 * Released: June 30th, 2005
 *
 * This was actaully written back in 2003 at some point.. never really finished, the code
 * isn't all that special. I just figured I'd post it for the hell of it.
 * 
 * Usage: ./dict -s word server
 * Usage: ./dict -s crasis dict.die.net
 *
 * Compile With:
 * Linux: gcc -o dict_c dict_c.c
 * Solaris: gcc -o dict_c dict_c.c -lsocket -lnsl
 *

                                    ZZZZZZZZZZZZZZZZZZZ
                                    Z:::::::::::::::::Z
                  nnnn  nnnnnnnn    Z:::::::::::::::::Z   ooooooooooo
                  n:::nn::::::::nn  Z:::ZZZZZZZ::::::Z  oo:::::::::::oo
     eeeeeeeeeee  n::::::::::::::nn ZZZZZ  * Z::::::Z  o:::::::::::::::o
   ee:::::::::::eenn:::::::::::::::n      5 Z:::::Z    o:::::ooooo:::::o
  e:::::::::::::::een:::::nnnn:::::n     0 Z:::::Z     o::::o     o::::o
 e::::::eeeee::::::en::::n    n::::n    0 Z:::::Z      o::::o     o::::o
 e:::::e     e:::::en::::n    n::::n   2 Z:::::Z       o::::o     o::::o
 e::::::eeeee::::::en::::n    n::::n  * Z:::::Z        o::::o     o::::o
 e::::::::::::::::e n::::n    n::::n   Z:::::Z         o:::::ooooo:::::o
 e:::::eeeeeeeeeee  n::::n    n::::nZZZ:::::Z     ZZZZZo:::::::::::::::o
 e::::::e           n::::n    n::::nZ::::::ZZZZZZZZ:::Z oo:::::::::::oo
 e:::::::e          nnnnnn    nnnnnnZ:::::::::::::::::Z   ooooooooooo
  e:::::::eeeeeeeeee                Z:::::::::::::::::Z
   ee::::::::::::::e                ZZZZZZZZZZZZZZZZZZZ
    ee:::::::::::::e             \... www.enZotech.net .../
     eeeeeeeeeeeeee
                 

                                                                                                                                              



#define VER 1.1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netdb.h>
#include <getopt.h>
#include <unistd.h>
#include <errno.h>

int request(char *ip, int port, char *string);
void usage(char *argv0);
void checkport(int port);

int main(int argc, char *argv[])
{

	int errorflag = 0;
	int port = 2628;
	int c;
	char *string = "blah";

	if ((argc < 2) || (argc > 5))
		usage(argv[0]);

	while ((c=getopt(argc, argv, "vp:hs:")) != EOF) {
		switch(c) {
			case 'p':
				port = strtol(optarg, NULL, 10);
				checkport(port);
				fprintf(stderr, "Using port: %s\n", optarg);
				break;
			case 'h':
				usage(argv[0]);
				break;
			case 's':
				if (strlen(optarg) >= 101) {
				fprintf(stderr, "Use a filename 100 characters or less\n");
				exit(1); } 
				string = optarg;
				break;
			case 'v':
				fprintf(stderr, "Copyright 2003 enZo.\n");
				exit(0);
			case '?':
				fprintf(stderr, "Unrecognized option: -%c\n", optopt);
				errorflag++;
		}
	}

				

	if (errorflag) {
		usage(argv[0]);
	}


	request(argv[argc-1], port, string);
	return 0;
}

void usage(char* argv0)
{
	fprintf(stderr, "\n\e[0;1mdict program\e[0m\n\n");
	fprintf(stderr, "Copyright 2003 enZo\n");
	fprintf(stderr, "Usage: %s [options] IP\n\n", argv0);
	fprintf(stderr,
			"-h \tPrint a summary of the options\n"
			"-v \tPrint Version information\n"
			"-p \tPort To use\n"
			"-s \tWord to request (Default: blah)\n");
			exit(1);
			
}


int request(char *ip, int port, char *string)
{

	int s, r, j;
	int x = 1;
	int c = 0;
	char *d = NULL;
	char response_string[600];
	char reqstring[117];
	char *p = NULL;

	struct sockaddr_in addr;
	struct hostent *hp;
	memset((char *) &addr, '\0', sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(ip);
	addr.sin_port= htons(port);


	/* build request string */
    	snprintf(reqstring, (sizeof(reqstring)-1), "DEFINE * %s \r\n", string);


        if ((hp = gethostbyname(ip)) == NULL) {
		fprintf(stderr, "Unknown host: %s\n", ip);
		exit(1);
        }

        if ((hp = gethostbyname(ip)) != NULL) {
                if (hp->h_length > sizeof(addr.sin_addr)) {
                        hp->h_length = sizeof(addr.sin_addr); }

                 memcpy((char *) &addr.sin_addr, hp->h_addr, hp->h_length);
        }
        else {
                if ((addr.sin_addr.s_addr = inet_addr(ip)) < 0) {
                        return(0);
                 }
        }

        s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if (s == -1) {
		perror("socket() failed");
		return 2; }

        r = connect(s, (struct sockaddr *) &addr, sizeof(addr));

	if (r == -1) {
		perror("connect() failed");
		return 2; }

	write(s, reqstring, strlen(reqstring));
	c = 0;
	memset(response_string, '\0', sizeof(response_string));


while (recv(s, response_string, sizeof(response_string), 0) > 0) {

	if (strstr(response_string, "") != NULL) {
	fprintf(stdout, response_string);
	}
write(s, "QUIT\n", 5);
}

close(s);


	    return 0;
}

void checkport(int port)
{
	if(port > 65535) {
		fprintf(stderr, "Invalid port\n");
		exit(1); 
	}
}
