/*****************************************************************************/
/* Simple TCP server                                                         */
/*                                                                           */
/* The server get no input as external parameters                            */
/*                                                                           */
/*                                                                           */
/*                                                                           */
/* Process:                                                                  */
/*   The server binds the requested port                                     */
/*   Listen to conenction requests from clients (multiple clientsi supported)*/
/*   Accepts conneciton from client                                          */
/*                                                                           */
/* Termination:                                                              */
/*   Close the connection as needed                                          */
/*                                                                           */
/*                                                                           */
/*                                                                           */
/* The source is taken from Beej's Guide to Network Programming              */
/*                                                                           */
/* (c) Eddie Aronovich, Nov 2001                                             */
/*                                                                           */
/*****************************************************************************/


void signal_term(int signo);
void signal_int(int signo);
void signal_kill(int signo);
void signal_hup(int signo);
void signal_other(int signo);

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <string.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h> 
#include <sys/wait.h> 
#include <signal.h> 

#define MYPORT 3490			/* the port users will be connecting to */
#define BACKLOG 10			/* how many pending connections queue will hold */
#define _GNU_SOURCE
#define MAXDATASIZE 100     		/* max number of bytes we can get at once */
 
 

main()
    {
        int sockfd, new_fd, numbytes;		/* listen on sock_fd, new connection on new_fd */
	struct sockaddr_in my_addr;	/* my address information */
	struct sockaddr_in their_addr;	/* connector's address information */
	int sin_size;
	char buf[MAXDATASIZE];		/*The string to be passed               */  

	signal (SIGHUP, signal_hup); /*When signal SIGHUP (1) is issued */
	signal (SIGINT, signal_int); /*When signal SIGINT (2) is issued */
	signal (3, signal_other);
	signal (4, signal_other);
	signal (5, signal_other);
	signal (6, signal_other);
	signal (7, signal_other);
	signal (8, signal_other);
	signal (SIGKILL, signal_kill); /*When signal SIGKILL is issued - can't be caught !  */
	signal (10, signal_other);
	signal (11, signal_other);
	signal (12, signal_other);
	signal (13, signal_other);
	signal (14, signal_other);
	signal (SIGTERM, signal_term); /*When signal SIGTERM is issued */
	signal (16, signal_other);
	signal (17, signal_other);
	signal (18, signal_other);
	signal (19, signal_other);
	signal (20, signal_other);
	signal (21, signal_other);
	signal (22, signal_other);
	signal (23, signal_other);
	signal (24, signal_other);
	signal (25, signal_other);
	signal (26, signal_other);
	signal (27, signal_other);
	signal (28, signal_other);
	signal (29, signal_other);
	signal (30, signal_other);
	signal (31, signal_other);
	signal (32, signal_other);

	
        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
            perror("socket");
            exit(1);
        }

        my_addr.sin_family = AF_INET;         /* host byte order */
	my_addr.sin_port = htons(MYPORT);     /* short, network byte order */
	my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */
	bzero(&(my_addr.sin_zero), 8);        /* zero the rest of the struct */

	/*Binding the requested port */ 
	if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) \
                                                                      == -1) {
            perror("bind");
            exit(1);
        }

	/*Listent to the incoming conenction request from the client */
	if (listen(sockfd, BACKLOG) == -1) {
            perror("listen");
            exit(1);
        }

        while(1) {  /* main accept() loop */
	    sin_size = sizeof(struct sockaddr_in);
            if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, \
                                                          &sin_size)) == -1) {
                perror("accept");
                continue;
            }
            printf("server: got connection from %s\n", \
                                               inet_ntoa(their_addr.sin_addr));
	/********************************************************************************/
	/*Important : The server recieves multiple connection in the same program 	*/
	/*but only answere is forked 							*/
	/********************************************************************************/
	if (!fork()) { /* this is the child process */
	   while(1) {
		if (send(new_fd, "Hello, world!\n", 14, 0) == -1){
                	perror("send");
               		exit(0);
		}
		if ((numbytes=recv(new_fd, buf, MAXDATASIZE, 0)) == -1) {/*Recieve infor from the server*/
            		perror("recv");
            		exit(1);
	  	}
	   }
		buf[numbytes]='\0';
		printf("String=%s\n",buf);
		shutdown (new_fd,2);
               	close(new_fd);
        	return;
       	}
            	close(new_fd);  /* parent doesn't need this */
	/*	while(waitpid(-1,NULL,WNOHANG) > 0); /* clean up child processes */ 
	
    }
}

void signal_child(int signo)
{
	#include <unistd.h> 

	pid_t	pid;
	int	stat;

	pid=wait(&stat);
	printf("Child %d terminated \n",pid);
	return;
}

void signal_int(int signo)
{

	printf("INTERUPT signal - ^c (break)\n");
	return;
}

void signal_kill(int signo)
{

	printf("Signal Terminate was issued {kill -9} \n"); 
	return;
}

void signal_term(int signo)
{

	printf("Signall kill was issued - kill {pid}\n");
	return;
}


void signal_hup(int signo)
{

	printf("Signall HUP was issued - kill -HUP {pid}\n");
	return;
}

void signal_other(int signo)
{

	printf("Signall %d was issued, which means: %s  \n",signo, strsignal(signo));
	return;
}