/*
 * foobook v0.3 / 27.08.2000 
 */

#include <stdio.h>
#include <time.h>

/*
 * In 'foobook.h' muss gegebenenfalls die symbolische Konstante
 * 'FOOBOOK_CGI_URL' angepasst werden. Der Standardwert verweist
 * auf '/cgi-bin/foobook'. Dieser Wert ist von den lokalen
 * Gegebenheiten abhaengig.
 */
#include "foobook.h"
#include "cgi_lib.h"
#include "lock_file.h"
#include "char_vector.h"

int main (void)
{
        cgi_lib *cgi;

        char_vector *foobook_html;
        lock_file   *foobook_lock;
        FILE        *foobook_db;
        int          foobook_in;

        /* 'cgi_lib' Modul initialisieren. */
        cgi = cgi_lib_new (cgi);
        if (cgi == NULL)
        {       /* Es trat ein Fehler auf. Welcher? */
                switch (cgi_lib_errno)
                {
                        case CGI_LIB_ALREADY_IN_USE:
                        {
                                cgi_lib_send_HTML (cgi, "cgi_lib: already in use\n");
                                break;
                        }

                        case CGI_LIB_OUT_OF_MEMORY:
                        {
                                cgi_lib_send_HTML (cgi, "cgi_lib: out of memory\n");
                                break;
                        }

                        case CGI_LIB_METHOD_UNKNOWN:
                        {
                                cgi_lib_send_HTML (cgi, "cgi_lib: method unknown\n");
                                break;
                        }
                }

                return cgi_lib_errno;
        }

        /*
         * Wir erstellen ein 'advisory lockfile' ('FOOBOOK_LOCK'). Dadurch
         * wird verhindert dass mehrere Instanzen dieses CGI Prozesses zur
         * selben Zeit in unsere Gaestebuchdatei ('FOOBOOK_DB') schreiben.
         */
        foobook_lock = lock_file_new (foobook_lock, FOOBOOK_LOCK);
        if (foobook_lock == NULL)
        {       /* Es trat ein Fehler auf. */
                cgi_lib_send_HTML (cgi, "lock_file: out of memory\n");
                cgi_lib_del (cgi);

                return FOOBOOK_OUT_OF_MEMORY;
        }

        /*
         * Soll ein neuer Eintrag ins Gaestebuch aufgenommen werden?
         */
        if (cgi_lib_get_param_item (cgi, "add") != NULL)
        {
                /*
                 * Das Gaestebuchformular enthaelt ein verstecktes ('hidden')
                 * Formularelement ('<INPUT NAME="add" TYPE="hidden" VALUE="ok">').
                 * Ist dieses vorhanden so soll ein neuer Eintrag eingefuegt werden.
                 * Ist dieses nicht vorhanden so wird das Gaestebuch mit allen
                 * Eintraegen ausgegeben. Dies ist immer dann der Fall wenn das
                 * Gaestebuch normal aufgerufen wird.
                 */

                char *foo;
                char date_str[21];

                /* Datum abfragen und in ein bestimmtes Format umwandel. */
                time_t date = time (&date);
                strftime (date_str, 20, "%d-%m-%Y %H:%M:%S", localtime (&date));

                /* Die Gaestebuchdatei ('FOOBOOK_DB') zum Anhaengen oeffnen. */
                foobook_db = fopen (FOOBOOK_DB, "a");
                if (foobook_db == NULL)
                {       /* Es trat ein Fehler auf. */
                        cgi_lib_send_HTML (cgi, "foobook: file not found\n");
                        cgi_lib_del (cgi);

                        return FOOBOOK_FILE_NOT_FOUND;
                }

                /*
                 * Neuer Gaestebucheintrag abspeichern.
                 *
                 * Als naechstes werden die beim Request uebermittelten
                 * Formularinhalte ausgelesen. Dazu wird 'cgi_lib_get_
                 * param_item' verwendet. 'name', 'mail', 'http' und
                 * 'note' sind die Namen der Formularfelder.
                 */
                fprintf (foobook_db, FOOBOOK_HTML_ENTRY,
                ((foo = cgi_lib_get_param_item (cgi, "name")) == NULL ? "" : foo),
                ((foo = cgi_lib_get_param_item (cgi, "mail")) == NULL ? "" : foo),
                ((foo = cgi_lib_get_param_item (cgi, "mail")) == NULL ? "" : foo),
                ((foo = cgi_lib_get_param_item (cgi, "http")) == NULL ? "" : foo),
                ((foo = cgi_lib_get_param_item (cgi, "http")) == NULL ? "" : foo),
                ((foo = cgi_lib_get_param_item (cgi, "note")) == NULL ? "" : foo),
                date_str);

                fclose (foobook_db);
        }

        /*
         * Wir erzeugenen einen neuen 'char_vector'. In diesen 'char_vector'
         * werden spaeter die Gaestebucheintraege eingelesen. Die Anfangs-
         * groesse wird auf '2000 * sizeof (char)' gesetzt. Der 'char_vector'
         * passt seine Groesse automatisch an.
         */
        foobook_html = char_vector_new (foobook_html, 2000);
        if (foobook_html == NULL)
        {       /* Es trat ein Fehler auf. */
                cgi_lib_send_HTML (cgi, "char_vector: out of memory\n");
                cgi_lib_del (cgi);

                return FOOBOOK_OUT_OF_MEMORY;
        }

        /*
         * Die Gaestebuchdatei ('FOOBOOK_DB') wird nun zum Lesen geoeffnet.
         * Dabei kann kein Fehler auftreten. Ist die Datei nicht vorhanden
         * so gibt es noch keinerlei Eintraege im Gaestebuch.
         */
        foobook_db = fopen (FOOBOOK_DB, "r");
        if (foobook_db != NULL)
        {       /*
                 * Die einzelnen Gaestebucheintraege werden in
                 * den zuvor erzeugten 'char_vector' kopiert.
                 */
                while ((foobook_in = fgetc (foobook_db)) != EOF)
                {
                        char_vector_add (foobook_html, foobook_in);
                }
                fclose (foobook_db);
        }

        /*
         * Das zuvor erzeugte 'advisory lockfile' ('FOOBOOK_LOCK') kann
         * wieder entfernt werden. Der naechste Prozess kann nun auf die
         * Gaestebuchdatei ('FOOBOOK_DB') zugreifen.
         */
        if (lock_file_del (foobook_lock) != LOCK_FILE_OK)
        {
                char_vector_del (foobook_html);

                cgi_lib_send_HTML (cgi, "lock_file: lockfile error\n");
                cgi_lib_del (cgi);

                return FOOBOOK_LOCK_FILE_ERROR;
        }

        /*
         * Die HTML Seite ist jetzt fertig und kann an den Browser
         * ausgegeben werden. Dazu wird die Funktion 'cgi_lib_send
         * HTML' verwendet.
         */
        cgi_lib_send_HTML (cgi, "%s %s %s %s", FOOBOOK_HTML_HEAD,
                                               FOOBOOK_HTML_FORM,
                                               foobook_html->vector,
                                               FOOBOOK_HTML_FOOTER);

        /*
         * Fertig. Zum Schluss kann das 'char_vector' Modul und
         * das 'cgi_lib' Modul wieder aus dem Speicher entfernen.
         */
        char_vector_del (foobook_html);
        cgi_lib_del (cgi);

        return FOOBOOK_OK;
}