#!/bin/ash

# Distribuito sotto licenza GPL versione 2 o successiva
# Autore: Alessandro Selli http://alessandro.route-add.net

VERSIONE='2.1'
DATA='08 novembre 2005'
# In caso sia rilevato un errore, esci?
NIENTEERRORI='si'
LOGORROICO='no'
#set -o errexit
# Questo ora è controllato dal parametro "--errexit" sulla
# riga di comando

# Directory predeterminata dove cercare i messaggi Usenet da spostare nel sito Gopher:
USENETDIR="/var/spool/cyrus/mail/user/$USER/Usenet"
# Directory predeterminata di base dell'archivio Usenet disponibile via Gopher:
GOPHERDIR=~gopher/Utenti/Alessandro/Usenet
# Espressione regolare predeterminata che individua i nomi dei file degli articoli Usenet:
USENETFILES='[0-9]*.'
# Variabile che indica se si deve permettere la creazione di un nuovo file che sia identico
# ad uno già esistente (nuovo dalla versione 1.9)
DOPPIONI='no'

Uso () {
cat <<EOF

Istruzioni per l'uso di "$(basename $0)":
  [--usenet|-u directory] [--gopher|-g directory] [--file|-f regexp]
  [--doppioni|-d no|si] [--errexit|-e] [--noerror|-n] [--help|--aiuto|-h|-?]
  [--version|--versione|-V] [--verbose|-v]

  La directory specificata con "--usenet" (valore presente:
"$USENETDIR")
contiene i file da aggiungere all'albero di directory per gruppo di
discussione sito nella directory specificata con "--gopher" (valore
presente: "$GOPHERDIR").
  "--file" deve essere seguito dall'espressione regolare che indica il
nome generico dei file presenti nella directory Usenet (valore presente:
"$USENETFILES").
  "--doppioni" causa la creazione di un file e di un indice nel file
gophermap che siano uguali ad un altro file/indice già presenti, che
altrimenti non verrebbero creati.
  "--errexit" causa l'impostazione della flag "errexit" della shell che
termina l'esecuzione per ogni errore incontrato.
  "--noerror" causa il proseguimento dell'elaborazione anche in caso di
errori non gravi.

EOF
}

## Analisi parametri sulla riga di comando
if test $# -ne 0
then INDICE=1
     VOLTE=$#
     while test $INDICE -le $VOLTE
     do case "$1" in
             '-u'|'--usenet')
                  if test ! -d "$2"
                  then echo "ERRORE: la directory \"$2\" non esiste" >&2
                       exit 20
                  else USENETDIR="$2"
                       INDICE=$(($INDICE+1))
                       shift
                  fi ;;
             '-g'|'--gopher')
                  if test ! -d "$2"
                  then echo "ERRORE: la directory \"$2\" non esiste" >&2
                       exit 21
                  else GOPHERDIR="$2"
                       INDICE=$(($INDICE+1))
                       shift
                  fi ;;
              '-f'|'--file')
                  if test -n "$2"
                  then USENETFILES="$2"
                       INDICE=$(($INDICE+1))
                       shift
                  else 'ERRORE: il parametro "--file" deve essere seguito da un'\''espressione regolare' >&2
                       exit 25
                  fi ;;
              '-d'|'--doppioni')
                  RISPOSTA=$(echo "$2" | tr 'SINO' 'sino')
                  if test "$RISPOSTA" = 'si'
                  then DOPPIONI='si'
                  else if test "$RISPOSTA" = 'no'
                       then DOPPIONI='no'
                       else echo 'ERRORE: il parametro "--doppioni" deve essere seguito da "si" oppure "no"' >&2
                            exit 26
                       fi
                  fi
                  INDICE=$(($INDICE+1))
                  shift ;;
             '-e'|'--errexit')
                  set -o errexit
                  ;;
             '-n'|'--noerror')
                  NIENTEERRORI='no'
                  ;;
             '-?'|'-h'|'--help'|'--aiuto')
                  Uso ; exit
                  ;;
             '-V'|'--version'|'--versione')
                  echo "Versione: $VERSIONE del: $DATA" ; exit
                  ;;
             '-v'|'--verbose')
                  LOGORROICO='si'
                  ;;
             *) echo "ERRORE: parametro sconosciuto: \"$1\"" >&2
                Uso
                exit 29 ;;
       esac
        INDICE=$(($INDICE+1))
        shift
     done
fi

# Vediamo se adesso abbiamo dei valori buoni per le directory sorgente e destinazione:
if test ! -d "$USENETDIR" -o ! -r "$USENETDIR"
then echo "ERRORE: la directory \"$USENETDIR\" non esiste oppure non è leggibile" >&2
     exit 30
else if test ! -d "$GOPHERDIR" -o ! -r "$GOPHERDIR"
     then echo "ERRORE: la directory \"$GOPHERDIR\" non esiste oppure non è leggibile" >&2
          exit 31
     fi
fi

# Controlla la disponibilità dei comandi "munpack" e "dos2unix"
for COMANDO in munpack dos2unix
do which "$COMANDO" >/dev/null 2>&1
   if test $? -ne 0
   then echo "ERRORE: il comando \"$COMANDO\" non è disponibile" >&2
        exit 1
   fi
done

TMPDIRA="/tmp/$(basename $0)_$$"
TMPDIR="$TMPDIRA"
until test ! -e "$TMPDIR"
do TMPDIR="${TMPDIRA}_$RANDOM"
done

# File temporaneo creato dal comando munpack
FILETEMP="$TMPDIR/tempdesc.txt"

Esci () {
/bin/rm -rf "$TMPDIR"
trap - INT TERM QUIT HUP ABRT USR1 USR2
exit $(($1+0))
}

# D'ora in poi, per uscire forzatamente usa la funzione "Esci", che pulisce
# il filesystem dai file e dalle directory temporanei creati.
# Procediamo adesso ad isolare il nome del gruppo di discussione del quale
# ci serve di individuare o di creare la corrispondente sottodirectory nell'
# area Gopher.  Nel caso si trovino piu` di un gruppo, si deve fare l'opera-
# zione associata una volta per ciascun gruppo.  Ad esempio, potremmo trovare:
# Newsgroups: it.cultura.orientale,it.cultura.religioni.buddhismo

# Se ricevo uno dei segnali che seguono, pulisco tutto ed esco
trap "Esci 99" INT TERM QUIT HUP ABRT USR1 USR2

mkdir "$TMPDIR"

for USENETFILE in "$USENETDIR"/$USENETFILES
do if test -f "$USENETFILE" -a -r "$USENETFILE"
   then # Si, e` un file regolare leggibile, andiamo avanti
        test "$LOGORROICO" = 'si' && echo "Sto per elaborare il file \"$USENETFILE\""
        LAVORANDO="$TMPDIR"/$(basename "$USENETFILE")
        cat "$USENETFILE" | dos2unix > "$LAVORANDO"
        munpack -C "$TMPDIR" "$LAVORANDO" >/dev/null 2>&1
        if test $? -ne 0
        then echo "ERRORE: eccezione durante la creazione del file temporaneo \"$FILETEMP\"" >&2
             test "$NIENTEERRORI" = 'si' && Esci 10
        else # munpack ha creato in "$TMPDIR" il file "tempdesc.txt", a meno che
             # il file non sia di tipo: "Content-Transfer-Encoding: 8bit" (altro?).
             # In questo caso, copiamo l'intero file senza modifiche:
             if test ! -f "$FILETEMP"
             then cp "$LAVORANDO" "$FILETEMP"
             else # Munpack puo` scrivere: "Did not find anything to unpack from
                  # standard input" se il file non e` "Content-Transfer-Encoding:
                  # quoted-printable" ma, ad esempio: "Content-Transfer-Encoding:
                  # 8bit"  Il file "tempdesc.txt" è privo di intestazioni.
                  # Aggiungiamogliele:            
                  awk '{if ($1 !~ /^$/) print ; else exit}' "$LAVORANDO" > "$FILETEMP".awk
                  echo >> "$FILETEMP".awk
                  cat "$FILETEMP" >> "$FILETEMP".awk
                  mv "$FILETEMP".awk "$FILETEMP"
             fi
             # D'ora innanzi LAVORANDO non serve piu`, si fara` tutto con il
             # solo FILETEMP
             /bin/rm -f "$LAVORANDO"
             GRUPPI=$(awk '{if ($1 !~ /^$/) { if ($1 == "Newsgroups:") {gsub(",", " ", $2) ; print $2}} else exit}' "$FILETEMP")
             if test -n "$GRUPPI"
             then # La stringa "Newsgroups: " e` stata trovata in inizio di riga
                  # Il comando che definisce la variabile GRUPPI isola, dalla sola
                  # riga delle intestazioni e non dal corpo del messaggio, il campo
                  # che segue la stringa "Newsgroups: " ad inizio riga.
                  for GRUPPO in $GRUPPI
                  do if test ! -d "$GOPHERDIR/$GRUPPO"
                     then # La directory manca, creala, se puoi
                          mkdir "$GOPHERDIR/$GRUPPO"
                          if test $? -ne 0
                          then echo "ERRORE: non posso creare la directory \"$GOPHERDIR/$GRUPPO\"" >&2
                               Esci 2
                          fi
                     fi # La directory dove mettere gli articoli esiste
                     GOPHERMAP="$GOPHERDIR/$GRUPPO/gophermap"
                     if test -f "$GOPHERMAP" -a ! -w "$GOPHERMAP"
                     then echo "AVVERTENZA: non posso scrivere il file \"$GOPHERMAP\"" >&2
                          if test "$NIENTEERRORI" = 'si'
                          then echo 'Esco.' >&2
                               Esci 3
                          else GOPHERMAP='/dev/null'
                          fi
                     fi
                     if test ! -e "$GOPHERMAP"
                     then # crea un nuovo file gophermap
                          cat <<EOF> "$GOPHERMAP"
Articoli archiviati dal gruppo di discussione: $GRUPPO

EOF
                     fi

                     # Per isolare certi campi dalle intestazioni, uso uno scriptino
                     # AWK, perché così posso limitare la ricerca alle sole
                     # righe dell'intestazione, scartando le righe del corpo del
                     # messaggio
                     #grep ^Subject:\  "$FILETEMP" | sed 's/^Subject: //'
                     #grep ^Date:\  "$FILETEMP" | sed 's/^Date: //'
                     SUBJECT=$(awk '{if ($1 !~ /^$/) { if ($1 == "Subject:") {sub( /^Subject: /, "") ; print} } else exit}' "$FILETEMP")
                     DATE=$(awk '{if ($1 !~ /^$/) { if ($1 == "Date:") {sub( /^Date: /, "") ; print} } else exit}' "$FILETEMP")
                     if test -z "$DATE"
                     then DATE=$(date +%D:%T) # Data:ora di adesso
                     fi
                     FILENUOVO="$GOPHERDIR/$GRUPPO/$(printf %010d $(echo $SUBJECT $DATE | cksum | sed 's/ .*//'))"
                     NUOVOFILE="$FILENUOVO"
                     INDICE=1
                     until test ! -e "$NUOVOFILE"
                     do # NUOVOFILE esiste già; controllo che siano ammessi i doppioni
                        if test "$DOPPIONI" = 'si'
                        then # I doppioni sono ammessi: crea un nuovo nome file senza altri controlli
                             NUOVOFILE="${FILENUOVO}_$INDICE"
                             INDICE=$(($INDICE + 1))
                        else # I doppioni non sono ammessi: devo controllare che non sia proprio lo stesso file
                             if test "$(cksum "$FILETEMP" | sed 's/ .*//')" = "$(cksum "$NUOVOFILE" | sed 's/ .*//')"
                             then # Si, sono proprio file uguali: esci da questo until ... do ... done
                                  # e fai in modo che sia il nuovo file che le modifiche al Gophermap siano
                                  # scartati in /dev/null
                                  test "$LOGORROICO" = 'si' && echo " Scartato file duplicato \"$NUOVOFILE\""
                                  NUOVOFILE='/dev/null'
                                  GOPHERMAP='/dev/null'
                                  break
                             else # No, in realtà sono diversi: crea un nuovo nome file
                                  NUOVOFILE="${FILENUOVO}_$INDICE"
                                  INDICE=$(($INDICE + 1))
                             fi
                        fi
                     done
                     cp "$FILETEMP" "$NUOVOFILE"
                     if test $? -ne 0
                     then echo "ERRORE: non ho potuto creare il file \"$NUOVOFILE\"" >&2
                          test "$NIENTEERRORI" = 'si' && Esci 4
                     else # Aggiorna il Gophermap
                          # Formato di una riga gophermap:
                          # 1Descrizione<TAB>nome_directory
                          # 0Descrizione<TAB>nome_file
                          echo "0$SUBJECT\t$(basename "$NUOVOFILE")" >> "$GOPHERMAP"
                     fi
                  done # for GRUPPO in $GRUPPI
             else echo "Non ho trovato gruppi definiti nel file \"$FILETEMP\""
             fi # if test -n "$GRUPPI"
             /bin/rm -f "$FILETEMP"
        fi
        test "$LOGORROICO" = 'si' && echo "Ho finito di elaborare il file \"$USENETFILE\""
   else echo "ERRORE: il file \"$USENETFILE\" non è un file regolare leggibile" >&2
        test "$NIENTEERRORI" = 'si' && Esci 5
   fi # if test -f "$USENETFILE" -a -r "$USENETFILE"
done # for USENETFILE in $USENETDIR/$USENETFILES
Esci 0

