sendmail.sh (4042 octets)


#!/bin/sh

#
# sendmail.sh - programme appelle par le MUA comme suit :
#     cat message | sendmail.sh
#
# sendmail.sh doit donc lire sur l'entree standard le mel, et faire, pour
# chaque destinataire, un envoi au serveur concerne
#
# Ligne a modifier si besoin
#
#

cd `dirname $0`

. ./commun-smtpd

rm -rf $Tmp

#
# Premiere partie : analyse du mel pour en extraire les adresses de
# l'expediteur (champ From:), des destinataires (champ To:, Cc: ou Bcc:).
# L'adresse de l'expediteur va nous servir par la suite pour envoyer un
# mel d'erreur a l'expediteur si une adresses du (des) destinataire(s)
# est non valide.
# L'adresse des destinataires va bien evidemment servir a contacter les
# serveurs de mels en charge de leur(s) domaine(s)
#

while read ligne
do
    echo "$ligne" >> $Tmp
    set -- $ligne
    Cmd=`echo $1 | tr [a-z] [A-Z]`
    case "$Cmd" in 
        "FROM:") while [ -n "$2" ]
                 do
                     if echo "$2" | grep "@" > /dev/null
                     then
                         From=`echo $2 | sed -e "s/.*<//g" -e "s/>.*//g"`
                         break
                     else
                         shift
                     fi
                 done
                 ;;
        "TO:"|"CC:"|"BCC:")
                 while [ -n "$2" ]
                 do
                     if echo "$2" | grep "@" > /dev/null
                     then
                         NewTo=`echo $2 | sed -e "s/.*<//g" \
                                              -e "s/>.*//g" \
                                              -e "s/,//g"`
                         To=`echo $To $NewTo`
                     fi
                     shift
                 done
                 ;;
    esac
done

#
# Deuxieme partie : pour chaque destinataire, trouver quel serveur
# contacter, envoyer un mel d'erreur a l'expediteur si on ne trouve
# pas de serveur, et envoyer le mel via une connexion SMTP
#

for dest in $To
do

#
# Quel serveur (MX) contacter ?
#

    Mx=""

#
# Quel est le nom de domaine du destinataire (partie a droite du '@'
# dans l'adresse). Par exemple, mdecore@chez.moi a pour nom de domaine
# chez.moi
#

    Dest=`echo $dest | sed "s/.*@//"`

#
# Ce domaine a t-il des serveurs de mels (MX) definits par le DNS ?
# Par exemple, le domaine chez.moi a pour MX tarsier.chez.moi
#

    ListeMx=`host -t mx $Dest 2> /dev/null | sort -n | cut -d" " -f7`

#
# Si oui, ces serveurs sont-ils interrogables (ie. on peut etablire une
# connexion sur le port SMTP) -> envoi d'une trame ICMP pour tester. On
# repete l'operation pour tous les serveurs, classes precedemment par ordre
# de preference, jusqu'a ce qu'il y en ai un qui reponde.
# Si aucun serveur MX n'est definit, on prend le nom de domaine de l'adresse
# du destinataire (en esperant qu'elle corresponde a une machine)
#

    for serveur in $ListeMx $Dest
    do
        nc -w 5 -z $serveur $PORT > /dev/null 2>&1 && sleep 1 \
        && Mx=$serveur && break || continue
    done

    echo >> $FicLog
    echo "$dest -> $Mx:$PORT" >> $FicLog

#
# Le serveur de mels du destinataire est-il definit (ie. il a un nom
# valide est peut etre contacte) ?
#

    if [ -n "$Mx" ]
    then

#
# Si oui, on envoie le mel au destinataire
#

        (cat << EOF
helo $Fqdn
mail from: $From
rcpt to: $dest
data
EOF
        cat $Tmp | sed -e "/Bcc:/d"
        echo "."
        echo "quit"
        ) | nc $Mx $PORT > /dev/null 2>&1

    else

#
# Sinon, on envoie un mel d'erreur a l'expediteur
#

        if ChercheLoop
        then
            echo "Domaine inconnu : $dest" >> $FicLog
            (cat << EOF
From: $DemonMailer@$Domaine
To: $From
Date: `date`
Subject: Unvalid domain
X-Loop: $DemonMailer@$Domain

EOF
            (sed -e "s/TO/$dest/" \
                 -e "s/DOMAINE/`echo $dest | sed "s/.*@//"`/") \
            < format/domaine-non-valide
            cat $Tmp | while read ligne
            do
                echo "> $ligne"
            done 
            ) > $Queue/$Fic
        fi
    fi
    sleep 1
done

rm -rf $Tmp

exit 0