/* A simple server in the internet domain using TCP
   The port number is passed as an argument */
   /*proxy.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define BUFFER_SIZE 256

void error(const char *msg)
{
    perror(msg);
    exit(1);
}

void sendMessage(const char* msg, const char* address, const char* port){
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

	fprintf(stderr, "sendMessage()1: %s\n", msg);

	portno = atoi(port);
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	fprintf(stderr, "sendMessage()2: %s\n", msg);
	if(sockfd < 0) error("ERRPR opening socket");

	server = gethostbyname(address);
	if(server == NULL){
		fprintf(stderr, "ERROR, no such host\n");
		exit(0);
	}
	fprintf(stderr, "sendMessage()3: %s\n", msg);

	bzero((char *)&serv_addr, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
	serv_addr.sin_port = htons(portno);
	fprintf(stderr, "sendMessage()4: %s  port:%d\n", msg, portno);

	if(connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
		error("ERROR connecting");
	
	n = write(sockfd, msg, strlen(msg));
	if(n < 0) error("ERROR writing to socket");
	close(sockfd);

	fprintf(stderr, "sendMessage()5: %s\n", msg);

	return;
}



void receiveMessage(const char* port, char* buffer){
	int sockfd, newsockfd, portno;
	socklen_t clilen;
	struct sockaddr_in serv_addr, cli_addr;
	int n;
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd < 0) 
		error("ERROR opening socket");
	bzero((char *) &serv_addr, sizeof(serv_addr));
	portno = atoi(port);
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	serv_addr.sin_port = htons(portno);
	if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
		error("ERROR on binding");

	listen(sockfd, 5);
	clilen = sizeof(cli_addr);
	
	newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
	if (newsockfd < 0) 
		error("ERROR on accept");
	bzero(buffer,BUFFER_SIZE);
	n = read(newsockfd,buffer,BUFFER_SIZE - 1);

	if (n < 0) error("ERROR reading from socket");
	printf("Here is the message: %s\n",buffer);
	
	n = write(newsockfd, "I got your message", 18);
	if(n < 0) error("ERROR writing to socket");
	close(newsockfd);
	close(sockfd);
}

int main(int argc, char *argv[])
{
	char buffer[BUFFER_SIZE];
    if (argc < 3) {
       fprintf(stderr,"usage %s portToListenOn addressToForwardTo\n", argv[0]);
       exit(0);
    }
	while(1){
		receiveMessage(argv[1], buffer);
		sendMessage(buffer, argv[3], argv[2]);
	}
	return 0; 
}
