/* A simple server using TCP with port number is passed as an argument */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

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


#define MAXREQ  256
#define MAXQUEUE 5

int main(int argc, char *argv[])
{
  int sockfd, newsockfd, portno;
  char reqbuf[MAXREQ];
  struct sockaddr_in serv_addr;
  struct sockaddr_in cli_addr;
  int n;
  uint clilen = sizeof(cli_addr);

  if (argc < 2) {
    fprintf(stderr,"ERROR, no port provided\n");
    exit(1);
  }
  portno = atoi(argv[1]);


  /* Create Socket to receive requests*/
  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0) 
    error("ERROR opening socket");

  /* Bind socket to port */
  memset((char *) &serv_addr,0,sizeof(serv_addr));
  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");

  printf("%s listening on port %d\n",argv[0],portno);
  while (1) {

    /* Listen for incoming connections */
    listen(sockfd,MAXQUEUE);

    /* Accept incoming connection, obtaining a new socket for it */
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
    if (newsockfd < 0) 
      error("ERROR on accept");

    /* Read request from the socket */
    memset(reqbuf,0, MAXREQ);
    n = read(newsockfd,reqbuf,MAXREQ-1);
    if (n < 0) error("ERROR reading from socket");

    /* Print request on server stdout */
    printf("Req: %s\n",reqbuf);

    n = write(newsockfd,reqbuf,strlen(reqbuf));
    if (n < 0) error("ERROR writing to socket");

    close(newsockfd);
  }
  
  printf("Server exiting\n");
  close(sockfd);
  return 0; 
}