#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>


/* Port fuer die Requests */
#define PORT 7777

/* Puffergroesse */
#define BUFSIZE 16384

void do_dialog (int sock);
void err_exit(char *message);

int main(int argc, char *argv[])
  {
  int sockfd, newsockfd, c_len, status;
  struct sockaddr_in serv_addr, c_addr;
  pid_t pid;
  
  /* Socket erzeugen */
  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0) 
    err_exit("ERROR opening socket");

  /* Socket-Struktur initialisieren */
  memset( &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(PORT);
 
  /* Port an die Host-Adresse binden */
  if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
    err_exit("ERROR on binding");

  /* Auf Verbindungsanfragen warten */
  listen(sockfd,5);
  c_len = sizeof(c_addr);
  for(;;) 
    {
    printf("Server bereit ...\n");
    /* Verbindung akzeptieren */
    newsockfd = accept(sockfd, (struct sockaddr *) &c_addr, (socklen_t *)&c_len);
    if (newsockfd < 0)
      err_exit("ERROR on accept");

    /* Verbindung steht */
    printf("Connect von: %s\n", inet_ntoa(c_addr.sin_addr));

    /* Kindprocess erzeugen (erbt die akt. Verbindung) */
    pid = fork();
    if (pid < 0)
      err_exit("ERROR on fork");
    else if (pid == 0)  
      {
      /* Das ist der Kindprozess */
      close(sockfd); /* Eltern-Socket schliessen */
      /* Kommunizieren */
      do_dialog(newsockfd);
      exit(0);
      }
    else
      {
      /* Dies ist der Elternprozess */
      close(newsockfd); /* Kind-Socket schliessen */
      printf("Parent PID =  %d, Child PID = %d\n", getpid(), pid);
      waitpid(pid, &status, WNOHANG);
      printf("Kindprozess-Exitstatus: %d\n", status);
      }
    } /* end of while */
  }

/* Kommunikation ueber den Socket durchfuehren */
void do_dialog (int sock)
  {
  int n;
  char buffer[BUFSIZE];
  bzero(buffer,BUFSIZE);

  n = read(sock,buffer,BUFSIZE);
  if (n < 0)
    err_exit("ERROR reading from socket");
  printf("Message: %s\n",buffer);
  n = write(sock,"OK\n",3);
  if (n < 0) 
    err_exit("ERROR writing to socket");
  }

/* Fehlermeldung ausgeben und exit */
void err_exit(char *message)
  {
  perror(message);
  exit(1);
  }

