/* Vorlesung Verteilte Systeme I
   Sommersemester 1999
   Musterloesung zum Uebungsblatt 3, Aufgabe 3
   Cookie-Server zur Auswahl eines Cookies aus einer Datei
   Joerg Hakenberg 3.5.1999 */


/* ---------- server.c ---------- */
/* Aufruf : server <Server-Port> */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <time.h>

/* Format der cookies.txt : ein Spruch pro Zeile */
#define COOKIE "cookies.txt"

int main(int argc, char* argv[]){

        int list_socket;
        int cli_socket;
        int socklen;
        int ret;
        struct sockaddr_in      servaddr;
        struct sockaddr_in      cliaddr;
        char buffer[128];
        char cookie[128];
        FILE *datei;
        int i, j, lines;

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

        /* den Server-Socket binden */
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(atoi(argv[1]));
        ret = bind(list_socket,
                        (struct sockaddr *) &servaddr, sizeof(servaddr));
        if (ret == -1) {
                perror("bind() error");
                exit(1);
        }

        ret = listen(list_socket, 5);
        if (ret == -1) {
                perror("listen() error");
                exit(1);
        }

        while(1) {
                socklen = sizeof(buffer);
                /* auf einen CLient-Connect warten */
                cli_socket = accept(list_socket,
                                (struct sockaddr *) &cliaddr, &socklen);
                if (ret == -1) {
                        perror("accept() error");
                        exit(1);
                }

                /* Satusmeldung ausgeben : Ip des anfragenden Clients */
                printf("connection from %s, port %d\n",
                                inet_ntoa(cliaddr.sin_addr),
								ntohs(cliaddr.sin_port));

                /* die vom Client gestellte Anfrage lesen und ausgeben*/
                ret = read(cli_socket, (void *) &buffer, sizeof(buffer));
                buffer[ret] = '\0';
                printf("Request: %s\n", buffer);

                /* zufaellig einen Cookie aus der Datei COOKIE auswaehlen */
                datei = fopen(COOKIE, "r");
                lines = 0;
                while (fgets(cookie, 150, datei)) {
                        lines++;
                }
                rewind(datei);
                i = 1 + (int) ((float)lines * rand() / (RAND_MAX + 1.0));
                for (j = 1; j <= i; j++) {
                        fgets(cookie, 150, datei);
                }
                fclose(datei);

                /* den Cookie auf den Socket legen */
                write(cli_socket, cookie, strlen(cookie));

                /* Client-Socket schliessen */
                close(cli_socket);
        }

}

