#!/usr/bin/perl
##
## annunci.pl
##
#
# Utilizza il modulo Pg, per l'utilizzo delle librerie LibPQ di
# PostgreSQL.
#
use Pg;
#
# Incorpora la libreria di decodifica dei dati.
#
require ('mini-lib.pl');
#
# &Metodo_non_gestibile ()
#
sub Metodo_non_gestibile
{
    print STDOUT ("Content-type: text/html\n");
    print STDOUT ("\n");
    print STDOUT ("<HTML>\n");
    print STDOUT ("<HEAD>\n");
    print STDOUT ("<TITLE>Errore</TITLE>\n");
    print STDOUT ("</HEAD>\n");
    print STDOUT ("<BODY>\n");
    print STDOUT ("<H1>Metodo $ENV{REQUEST_METHOD} non gestibile.</H1>\n");
    print STDOUT ("</BODY>\n");
    print STDOUT ("</HTML>\n");
}
#
# &Verifica_dati_annuncio ()
#
sub Verifica_dati_annuncio
{
    if ($DATI{rubrica} eq "0")
      {
        return (0);
      }
    if ($DATI{testo} eq "")
      {
        return (0);
      }
    if ($DATI{email} eq "")
      {
        return (0);
      }
    if ($DATI{cognome} eq "")
      {
        return (0);
      }
    if ($DATI{nome} eq "")
      {
        return (0);
      }
    if ($DATI{telefono} eq "")
      {
        return (0);
      }
    return (1);
}
#
# &Verifica_dati_consultazione ()
#
sub Verifica_dati_consultazione
{
    if ($DATI{rubrica} eq "0")
      {
        return (0);
      }
    if ($DATI{modello} eq "")
      {
        $DATI{modello} = "%";
      }
    return (1);
}
#
# &Dati_insufficienti ()
#
sub Dati_insufficienti
{
    print STDOUT ("Content-type: text/html\n");
    print STDOUT ("\n");
    print STDOUT ("<HTML>\n");
    print STDOUT ("<HEAD>\n");
    print STDOUT ("<TITLE>Errore</TITLE>\n");
    print STDOUT ("</HEAD>\n");
    print STDOUT ("<BODY>\n");
    print STDOUT
      ("<H1>I dati inseriti nel modello sono insufficienti.</H1>\n");
    print STDOUT ("Si prega di controllare e aggiungere i dati mancanti.\n");
    print STDOUT ("</BODY>\n");
    print STDOUT ("</HTML>\n");
}
#
# &Modulo_iniziale ()
#
sub Modulo_iniziale
{
    print STDOUT ("Content-type: text/html\n");
    print STDOUT ("\n");
    print STDOUT ("<HTML>\n");
    print STDOUT ("<HEAD>\n");
    print STDOUT ("<TITLE>Annunci on-line</TITLE>\n");
    print STDOUT ("</HEAD>\n");
    print STDOUT ("<BODY>\n");
    print STDOUT ("<H1>Annunci on-line</H1>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("Selezionare una delle due voci seguenti:</P>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("<A href=\"/cgi-bin/annunci.pl?modulo=preannuncio\">");
    print STDOUT ("inserimento di un nuovo annuncio</A></P>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("<A href=\"/cgi-bin/annunci.pl?modulo=prericerca\">");
    print STDOUT ("ricerca tra gli annunci</A></P>\n");
    print STDOUT ("</BODY>\n");
    print STDOUT ("</HTML>\n");
}
#
# &Modulo_nuovo_annuncio ()
#
sub Modulo_nuovo_annuncio
{
    print STDOUT ("Content-type: text/html\n");
    print STDOUT ("\n");
    print STDOUT ("<HTML>\n");
    print STDOUT ("<HEAD>\n");
    print STDOUT ("<TITLE>Annunci on-line: inserimento</TITLE>\n");
    print STDOUT ("</HEAD>\n");
    print STDOUT ("<BODY>\n");
    print STDOUT ("<H1>Inserimento di un annuncio</H1>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("Si prega di inserire tutti i dati richiesti.</P>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("<FORM action=\"/cgi-bin/annunci.pl\" method=\"POST\">\n");
    print STDOUT ("<P>\n");
    print STDOUT ("<INPUT type=\"hidden\" name=\"modulo\" value=\"annuncio\">\n");
    print STDOUT ("Rubrica:&nbsp;<SELECT name=\"rubrica\">\n");
    print STDOUT ("     <OPTION value=\"0\" selected=\"selected\">Nessuna\n");
    print STDOUT ("     <OPTION value=\"1\">Compro\n");
    print STDOUT ("     <OPTION value=\"2\">Vendo\n");
    print STDOUT ("     <OPTION value=\"3\">Messaggi\n");
    print STDOUT ("     <OPTION value=\"4\">Varie\n");
    print STDOUT ("</SELECT></P>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("Testo dell'annuncio:<BR>\n");
    print STDOUT ("     <INPUT name=\"testo\" size=\"80\"></P>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("e-mail:&nbsp;<INPUT name=\"email\" size=\"40\"></P>\n");
    print STDOUT ("\n");
    print STDOUT ("<H2>Dati che non vengono pubblicati</H2>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("Cognome:&nbsp;<INPUT name=\"cognome\" size=\"25\"></P>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("Nome:&nbsp;<INPUT name=\"nome\" size=\"25\"></P>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("Telefono:&nbsp;<INPUT name=\"telefono\" size=\"25\"></P>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("<INPUT type=\"submit\" value=\"Invia l'inserzione\"></P>\n");
    print STDOUT ("</FORM></P>\n");
    print STDOUT ("</BODY>\n");
    print STDOUT ("</HTML>\n");
}
#
# &Modulo_ricerca ()
#
sub Modulo_ricerca
{
    print STDOUT ("Content-type: text/html\n");
    print STDOUT ("\n");
    print STDOUT ("<HTML>\n");
    print STDOUT ("<HEAD>\n");
    print STDOUT ("<TITLE>Annunci on-line: ricerca annunci</TITLE>\n");
    print STDOUT ("</HEAD>\n");
    print STDOUT ("<BODY>\n");
    print STDOUT ("<H1>Ricerca tra gli annunci</H1>\n");
    print STDOUT ("<P>\n");
    print STDOUT
      ("Si deve indicare la rubrica e un modello di ricerca.</P>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("Il modello è sensibile alla differenza tra maiuscole \n");
    print STDOUT ("e minuscole, si può utilizzare il simbolo `%' per \n");
    print STDOUT ("indicare una stringa di caratteri indefinita.\n</P>");
    print STDOUT ("<P>\n");
    print STDOUT ("<FORM action=\"/cgi-bin/annunci.pl\" method=\"GET\">\n");
    print STDOUT ("<P>\n");
    print STDOUT ("<INPUT type=\"hidden\" name=\"modulo\" value=\"ricerca\">\n");
    print STDOUT ("Rubrica:&nbsp;<SELECT name=\"rubrica\">\n");
    print STDOUT ("     <OPTION value=\"0\" selected=\"selected\">Nessuna\n");
    print STDOUT ("     <OPTION value=\"1\">Compro\n");
    print STDOUT ("     <OPTION value=\"2\">Vendo\n");
    print STDOUT ("     <OPTION value=\"3\">Messaggi\n");
    print STDOUT ("     <OPTION value=\"4\">Varie\n");
    print STDOUT ("</SELECT></P>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("Modello di ricerca:&nbsp;");
    print STDOUT ("<INPUT name=\"modello\" size=\"30\" value=\"%\"></P>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("<INPUT type=\"submit\" value=\"Inizia la ricerca\"></P>\n");
    print STDOUT ("</FORM></P>\n");
    print STDOUT ("</BODY>\n");
    print STDOUT ("</HTML>\n");
}
#
# &Ricerca_annunci ()
#
sub Ricerca_annunci
{
    local ($PGquery) = "
        SELECT Annuncio, Email FROM Annunci
                WHERE Rubrica = $DATI{rubrica}
                AND Annuncio LIKE '$DATI{modello}'
                ORDER BY Annuncio
    " ;
    #
    local (@tabella) = ();
    local ($PGconnessione);
    local ($i);
    local ($j);
    #
    # Apre la connessione con il servente PostgreSQL locale,
    # utilizzando la base di dati «pubblico».
    #
    $PGconnessione = Pg::connectdb ("dbname = pubblico");
    #
    # Verifica che la connessione sia avvenuta e quindi esegue
    # l'interrogazione.
    #
    if ($PGconnessione->status == PGRES_CONNECTION_OK)
      {
        #
        # Invia la richiesta utilizzando la funzione Pg::doQuery che
        # fa tutto da sola (non occorre eseguire PQclear).
        #
        Pg::doQuery ($PGconnessione, $PGquery, \@tabella);
      }
    else
      {
        #
        # Per qualche motivo la connessione con la base di dati non
        # funziona e si avvisa l'utente di conseguenza.
        #
        &Database_inaccessibile ();
      }
    #
    print STDOUT ("Content-type: text/html\n");
    print STDOUT ("\n");
    print STDOUT ("<HTML>\n");
    print STDOUT ("<HEAD>\n");
    print STDOUT
      ("<TITLE>Annunci on-line: rubrica n. $DATI{rubrica}</TITLE>\n");
    print STDOUT ("</HEAD>\n");
    print STDOUT ("<BODY>\n");
    print STDOUT ("<H1>Consultazione della rubrica n. $DATI{rubrica}</H1>\n");
    #
    for ($i = 0; $i <= $#tabella; $i++)
      {
        #
        # Emette il testo dell'annuncio.
        #
        print STDOUT ("<P>\n");
        print STDOUT ("$tabella[$i][0]</P>\n");
        #
        # Emette l'indirizzo e-mail dello scrivente.
        #
        print STDOUT ("<P>\n");
        print STDOUT
          ("<A href=\"mailto:$tabella[$i][1]\">$tabella[$i][1]</A></P>\n");
        print STDOUT ("<HR>\n");
      }
    print STDOUT ("\n");
    print STDOUT ("</BODY>\n");
    print STDOUT ("</HTML>\n");
}
#
# &Database_inaccessibile ()
#
sub Modulo_errato {
    print STDOUT ("Content-type: text/html\n");
    print STDOUT ("\n");
    print STDOUT ("<HTML>\n");
    print STDOUT ("<HEAD>\n");
    print STDOUT ("<TITLE>Errore</TITLE>\n");
    print STDOUT ("</HEAD>\n");
    print STDOUT ("<BODY>\n");
    print STDOUT ("<H1>Problemi di accesso alla base di dati.</H1>\n");
    print STDOUT
      ("Per qualche motivo non è possibile accedere alla base di dati ");
    print STDOUT ("degli annunci. Si prega di perdonare l'inconveniente.\n");
    print STDOUT ("</BODY>\n");
    print STDOUT ("</HTML>\n");
}
#
# &Istruzione_errata ()
#
sub Istruzione_errata
{
    local ($errore) = $_[0];
    local ($istruzione) = $_[1];
    #
    print STDOUT ("Content-type: text/html\n");
    print STDOUT ("\n");
    print STDOUT ("<HTML>\n");
    print STDOUT ("<HEAD>\n");
    print STDOUT ("<TITLE>Errore</TITLE>\n");
    print STDOUT ("</HEAD>\n");
    print STDOUT ("<BODY>\n");
    print STDOUT ("<H1>Problemi di accesso alla base di dati.</H1>\n");
    print STDOUT ("<P>\n");
    print STDOUT ("Il comando richiesto ha generato l'errore seguente,</P>");
    print STDOUT ("<P>\n");
    print STDOUT ("<CODE>${errore}</CODE></P>");
    print STDOUT ("<P>\n");
    print STDOUT ("a seguito di questa istruzione SQL:</P>");
    print STDOUT ("<P>\n");
    print STDOUT ("<CODE>${istruzione}</CODE></P>");
    print STDOUT ("Si prega di avvisare l'amministratore del servizio.");
    print STDOUT ("</BODY>\n");
    print STDOUT ("</HTML>\n");
}
#
# &Annuncio_memorizzato ()
#
sub Annuncio_memorizzato
{
    print STDOUT ("Content-type: text/html\n");
    print STDOUT ("\n");
    print STDOUT ("<HTML>\n");
    print STDOUT ("<HEAD>\n");
    print STDOUT ("<TITLE>Annuncio memorizzato</TITLE>\n");
    print STDOUT ("</HEAD>\n");
    print STDOUT ("<BODY>\n");
    print STDOUT ("<H1>Annuncio memorizzato</H1>\n");
    print STDOUT ("L'annuncio è stato memorizzato. Grazie.\n");
    print STDOUT ("</BODY>\n");
    print STDOUT ("</HTML>\n");
}
#
# &Memorizza_annuncio ()
#
sub Memorizza_annuncio
{
    local ($PGconnessione);
    local ($PGrisultato);
    local ($PGistruzione);
    local ($PGstatus);
    local ($data) = time();
    #
    # Apre la connessione con il servente PostgreSQL locale,
    # utilizzando la base di dati «pubblico».
    #
    $PGconnessione = Pg::connectdb ("dbname = pubblico");
    #
    # Verifica che la connessione sia avvenuta.
    #
    if ($PGconnessione->status == PGRES_CONNECTION_OK)
      {
        #
        # La connessione è avvenuta e si procede con l'inserimento
        # dell'annuncio.
        #
        $PGistruzione = "
                INSERT INTO Annunci ( 
                        Data, Cognome, Nome, Telefono, Email,
                        Rubrica, Annuncio
                    )
                    VALUES (
                        ${data}, '$DATI{cognome}',
                        '$DATI{nome}', '$DATI{telefono}',
                        '$DATI{email}', $DATI{rubrica},
                        '$DATI{testo}'
                    ) ";
        #
        $PGrisultato = $PGconnessione->exec ("$PGistruzione");
        #
        # Verifica il risultato dell'esecuzione dell'istruzione.
        #
        $PGstatus = $PGrisultato->resultStatus;
        #
        if (PGRES_COMMAND_OK == $PGstatus )
          {
            &Annuncio_memorizzato();
          }
        else
          {
            &Istruzione_errata( $PGconnessione->errorMessage, $PGistruzione );
          }
      }
    else
      {
        #
        # Per qualche motivo la connessione con la base di dati non
        # funziona e si avvisa l'utente di conseguenza.
        #
        &Database_inaccessibile();
      }
}
##
## Inizio del programma.
##
local (%DATI) = ();
#
# Decodifica i dati in funzione del tipo di metodo della richiesta.
#
if ($ENV{REQUEST_METHOD} eq 'GET')
  {
    %DATI = &Decodifica_GET;
  }
elsif ($ENV{REQUEST_METHOD} eq 'POST')
  {
    %DATI = &Decodifica_POST;
  }
else
  {
    &Metodo_non_gestibile;
  }
#
# Attraverso il dato memorizzato con il nome «modulo» si determina
# l'operazione da compiere.
#
if ($DATI{modulo} eq 'preannuncio')
  {
    &Modulo_nuovo_annuncio ();
  }
elsif ($DATI{modulo} eq 'prericerca')
  {
    &Modulo_ricerca ();
  }
elsif ($DATI{modulo} eq 'annuncio')
  {
    #
    # L'utente ha inviato un annuncio.
    #
    if (&Verifica_dati_annuncio)
      {
        &Memorizza_annuncio ();
      }
    else
      {
        &Dati_insufficienti ();
      }
  }
elsif ($DATI{modulo} eq 'ricerca')
  {
    #
    # L'utente ha eseguito una ricerca tra gli annunci.
    #
    if (&Verifica_dati_consultazione)
      {
        &Ricerca_annunci ();
      }
    else
      {
        &Dati_insufficienti ();
      }
  }
else
  {
    #
    # Si comincia dalla presentazione.
    #
    &Modulo_iniziale ();
  }
#
1;
#
