#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <memory.h>
#include <string.h>
#include <errno.h>
#include <sys/errno.h>
 
 
const int MAXSTR=9024;      // Maximum String length
const long PORTNUM=8070;   // The "Well-known" port number
 
void handleRequest(int);    // Function to handle clients' request(s)
using namespace::std;
main( int argc, char *argv[])
{
    int portNumber;
    //char executableName[MAXSTR];
    //struct sigaction action;
 
    // Validate and read from the command line
    if ( (argc != 3) && (argc != 1) )
    {  
        cerr << "Invalid command line.\n";
        exit(1);
    }
    if ( argc == 1 )
    {
        portNumber = PORTNUM;                                                                                                                                  
    }
    else                                                                                                                                                       
    {  
        if (!strcmp(argv[1],"-p"))
        {  
            portNumber = atoi(argv[2]);
        }
        else
        {  
            cerr << "Invalid command line.\n";
            exit(1);
        }
    }
 

    int sockfd,newsockfd,clilen,childpid;
    struct sockaddr_in serv_addr,cli_addr;
 
    // Create a new TCP socket...
    if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
    {  
        cerr << "Cant open stream socket.\n";
        exit(0);
    }
 
    bzero((char *)&serv_addr,sizeof(serv_addr)) ;
 
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(portNumber);
    serv_addr.sin_port = htons(portNumber);                                                                                                                    
 
    // Bind the socket to the server's ( this process ) address.
    if (bind(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
    {  
        cerr << "Cant bind local address.\n";
        exit(1);
    }
 
    // Listen for connections in this socket
    listen(sockfd,5);
    int status;
    cerr <<  " Connected to port : " << portNumber << "\n";
 
    char buf[MAXSTR],ack[MAXSTR];
 
    // repeat forever..
    while (1)
    {  
        clilen = sizeof(cli_addr);
        // Accept a client's request, and get the client's address info into the local variable cli_addr.
        newsockfd = accept(sockfd,(struct sockaddr *)&cli_addr,(socklen_t *)&clilen);
        // After accepting the connection, all transaction with this client would happen with the new socket descriptor - newsockfd.
 
        if ((newsockfd < 0) &&  (errno != EINTR))
            cerr << " server : accept error.\n";
        else if (newsockfd > 0)
        {  
            handleRequest(newsockfd);
            close(newsockfd);
        }
        newsockfd = NULL;
    }
 
}
void handleRequest(int newsockfd)
{
    char buf[MAXSTR],execName[MAXSTR],ack[MAXSTR];
    char data[MAXSTR];
    static int count = 1;
    int check_read = 0;
 
    // Read from the socket, for the password and the requested command.
    check_read = read(newsockfd,buf,strlen(buf));
    sscanf(buf,"%s",execName);
    write(newsockfd,buf,strlen(buf));
                                                                                                                              
    cout << "====================================================" << endl;
    cout << "\e[1;36mcounts:\e[31m " << count++ << "\e[m" << endl;
    cout << "\e[1;36mCheck Read:\e[31m " << check_read << "\e[m" << endl << endl;
    cout << "\e[1;36mstrlen(execName):\e[31m " << strlen(execName) << "\e[m" << endl;
    cout << "\e[1;36mexecName:\e[31m " << execName << "\e[m" << endl;
    cout << "\e[1;36mstrlen(buf):\e[31m " << strlen(buf) << "\e[m" << endl;
    cout << "\e[1;36mbuf:\e[31m " << buf << "\e[m" << endl;
    cout << "====================================================" << endl;

}