Logiciel libre, droits d'utilisation précisés en français
dans le fichier : licence-fr.txt
Traductions des droits d'utilisation dans les fichiers :
licence-de.txt , licence-en.txt , licence-es.txt ,
licence-it.txt , licence-nl.txt , licence-pt.txt ,
licence-eo.txt , licence-eo-utf.txt
Droits d'utilisation également sur la page web :
http://libremail.tuxfamily.org/voir.php?page=droits
Ce programme détruit les mails écrits en HTML pur.
Ce format de mail très rarement utilisé par des particuliers
est par contre beaucoup plus fréquent dans les spams.
Un message est généré à l'intention de l'expéditeur du mail
non récupéré.
Un fichier de configuration est utilisé pour se connecter à la
boite aux lettres et pour sélectionner le serveur SMTP servant
à l'envoi des messages.
*/
#define appli // pour la déclaration de variables globales à l'application
/* variables globales au source
(pour éviter des tonnes de passages de paramètres) */
char adr_mail [120]; // adresse mail de l'utilisateur
char pref_adr [120]; // préfixe vraie adresse mail pour la masquer aux
// robots qui traitent les réponses aux spams
FILE *ftrace; // Fichier contenant les adresses d'expéditeurs refusés
char datecour [10]; // Date courante (pour le fichier d'expéditeurs refusés)
int opte; // Option -e (mails refusés non signalés à adresse Reply-To)
int opts; // Option -s (mails refusés non signalés aux expéditeurs)
int etat_smtp = 0; // état de la connexion smtp
char serv_smtp [120]; // nom du serveur smtp utilisé
char *ficmailrep; // fichier comptenant un mail pour réponse spécifique
/* compteurs */
int conserves = 0;
int supprimes = 0;
int avertis = 0;
int non_avertis = 0;
/* programme principal */
int main (int nbarg, char *varg[])
{
FILE *fconf; // descripteur du fichier de configuration
int numes, nbmes; // numéro du mail courant et nombre de mails
// récupération du nom de l'exécutable
memcom (*varg);
// se positionner sur le premier argument de suphtm
nbarg --;
varg ++;
// prise en compte des options de suphtm
while (nbarg > 1 && **varg == '-')
{
// option -m (utilisation d'un mail de réponse spécifique)
if (varg [0][1] == 'm')
{
// mémoriser le nom du fichier contenant le mail de réponse
ficmailrep = varg [1];
// si ce fichier n'existe pas
if (access (ficmailrep, 0) != 0)
errfatale ("MANQUE_FICMAILREP", ficmailrep);
// option -e (pas de mail d'avertissement à l'adresse du champ
// Reply-To en plus de l'adresse de l'expéditeur)
else if (strcmp (*varg, "-e") == 0)
{
opte = 1;
// sauter l'argument traité
nbarg --;
varg ++;
}
// option -s (pas de mail d'avertissement lorsque mail HTML détruit)
else if (strcmp (*varg, "-s") == 0)
{
opts = 1;
// sauter l'argument traité
nbarg --;
varg ++;
}
// option -t (utilisation d'un fichier trace)
else if (strcmp (*varg, "-t") == 0)
{
// ouvrir le fichier trace en écriture fin de fichier
ftrace = fopen (varg [1], "a");
// si nom de fichier correct
if (ftrace)
// initialiser la date courante
initdatecour (datecour);
else
// sinon, avertir l'utilisateur
// "Impossible d'écrire dans le fichier %s"
aff_err_arg ("IMPOS_ECR_FICH", varg [1]);
// sauter les arguments traités
nbarg -= 2;
varg += 2;
}
// option incorrecte
else
{
// "Option %s incorrecte"
aff_err_arg ("ERR_OPTION", *varg);
nbarg = 0; // on terminera en affichant la syntaxe de la commande
}
}
// aucun traitement si option -e et -s utilisées simultanément
if (opte && opts)
// "Option -e et -s incompatibles"
affiche_err ("COMPAT_OPT_ES");
// aucun traitement si option -m et -s utilisées simultanément
else if (ficmailrep && opts)
// "Option -m et -s incompatibles"
affiche_err ("COMPAT_OPT_MS");
// idem si option -p et -s utilisées simultanément
else if (*pref_adr && opts)
// "Option -p et -s incompatibles"
affiche_err ("COMPAT_OPT_PS");
// sinon, controle du nombre d'arguments restants
else if (nbarg == 1)
{
// ouvrir le fichier de configuration
fconf = ouvre_ficonf (*varg);
if (fconf)
{
// connexion sur le compte mail du serveur pop
if (connect_pop (fconf))
{
// récupération du nombre de mails
nbmes = nbmails ();
// on saute la ligne contenant le répertoire des mails
while (fgetc (fconf) != '\n')
;
if (supprimes && (opts == 0))
// "%d expéditeurs avertis, %d non avertis\n"
printf (message ("BILAN_AVERTIS"), avertis,
non_avertis);
// fermeture de la connexion smtp si elle a été ouverte
if (etat_smtp)
deconnect_smtp ();
}
// se déconnecter proprement du serveur pop
deconnect_pop ();
// si des mails ont été supprimés
if (supprimes)
// attendre pour enregistrement correct des suppressions
// (évite problème si autre filtre appelé juste après)
sleep (2);
}
// on n'a plus besoin du fichier de configuration
fclose (fconf);
}
}
else
{
// "Syntaxe : %s [-pd|-p préfixe] [-e|-s] [-m fichier_mail_réponse]"
// [-t fichier_adresses] fichier_configuration"
psyntaxe2 ("SYNT_SUPHTM1", "SYNT_SUPHTM2");
}
// pour faire plaisir à gcc qui veut une fonction main de type int
return (0);
}
/* vérifie si le message choisi est en HTML pur, et
le détruit dans ce cas en avertissant l'expéditeur */
void filtremail (int numes)
{
char bufw [120]; // buffer d'envoi d'une requête
int posbuf; // simple compteur
// message de suivi de déroulement
// "\rAnalyse du mail n° %d "
printf (message ("ANALYSE_MAIL"), numes);
fflush (stdout);
/* demande de lecture de l'entête du message
On demande 5 lignes du corps du message pour trouver le
2ème Content-type si le premier est multipart/mixed */
sprintf (bufw, "TOP %d 5", numes);
env_pop (bufw);
// lecture et mémorisation des caractéristiques du message
do
{
// lire une ligne de l'entête du message
lire_pop ();
// convertir les caractères spéciaux
majlignentete ();
// mémorisation des caractéristiques importantes
if (start ("Date"))
membuf (bufDate);
else if (start ("From"))
membuf (bufFrom);
else if (start ("To"))
membuf (bufTo);
else if (start ("Cc"))
membuf (bufCc);
else if (start ("Reply-To"))
membuf (bufReply);
else if (start ("Subject"))
membuf (bufSubject);
else if (start ("Content-Type"))
membuf (bufContent);
else if (start ("Return-Path"))
membuf (bufRetPath);
}
// lecture terminée si ligne limitée à un .
while (buf_lect [0] != '.' || buf_lect [1] != '\0');
// si le mail contenait une ligne Content-Type
if (*bufContent)
{
// positionnement sur le 2ème attribut de Content_type
// nécessaire pour bonne détection s'il y à 0 ou plus
// d'un blanc après le : du Content-Type
posbuf = 17;
while (bufContent [posbuf] != '/')
posbuf++;
}
// si le mail est en HTML pur
if (*bufContent && tolower (bufContent [posbuf+1]) == 'h'
&& tolower (bufContent [posbuf+2]) == 't')
{
// demande de destruction du message
sprintf (bufw, "DELE %d", numes);
env_pop (bufw);
lire_pop ();
supprimes ++;
// si utilisation d'un fichier trace
if (ftrace)
// mémoriser l'adresse de l'expéditeur dans ce fichier
fprintf (ftrace, "%s%s\n", datecour, bufFrom + 5);
// envoyer un mail à l'expéditeur, sauf si option -s
if (! opts && (bufFrom [0] || bufRetPath [0]))
{
// si la connexion smtp n'a pas encore été ouverte
if (! etat_smtp)
{
// ouvrir cette connexion et mémoriser son ouverture
if (connect_smtp (serv_smtp))
etat_smtp = 1;
else
etat_smtp = -1;
}
// avertir si possible l'expéditeur et mémorise l'avertissement
if ((etat_smtp > 0) && avertir ())
avertis ++;
else
non_avertis ++;
}
}
else
conserves ++;
}
/* avertit l'expéditeur d'un mail en HTML pur que son message est refusé */
int avertir ()
{
char bufw [120]; // buffer d'envoi d'une ligne ou d'une requête smtp
// l'envoi du mail d'avertissement suppose l'accès à un fichier de données
if (! acces_mailrep (NULL, "suphtm"))
return (0);
// destinataire du message
strcpy (bufw, "RCPT TO: <");
// si pas d'option -e, on envoie en priorité à l'adresse du Return_Path
if (!opte && bufRetPath [0])
ajout_adr (bufw, bufRetPath + 12);
// sinon on envoie à l'expéditeur déclaré
else
ajout_adr (bufw, bufFrom + 5);
// si destinataire refusé, on le signale
if (buf_lect [0] != '2')
{
// Affichage de l'adresse à problème
// "Destinataire %s refusé\n"
putchar ('\n');
printf (message ("REFUS_DEST"), bufw + 9);
puts (buf_lect);
// on n'envoie pas de mail
envoie_smtp ("RSET");
lire_smtp ();
return 0; // mail non envoyé
}
// préparation de l'envoi du message
envoie_smtp ("DATA");
lire_smtp ();
// génération de l'entête du message
// Champ date
gen_champ_date (bufw);
envoie_smtp (bufw);
// si préfixe, l'adresse expéditeur est modifiée dans
// l'entête du message pour tromper les robots de spam
if (*pref_adr)
sprintf (bufw, "From: <%s-%s>", pref_adr, adr_mail);
else
sprintf (bufw, "From: <%s>", adr_mail);
// chercher le @
while (source [orig] != '@' && source [orig])
orig ++;
// remonter au debut de l'adresse
while (orig > 0 && source [orig] != ' ' && source [orig] != '<')
orig--;
// l'adresse commence sur un caractère significatif
if (source [orig] == '<' || source [orig] == ' ')
debut = orig + 1;
else
debut = orig;
// copie de l'adresse
posdest = strlen (dest);
// on s'arrête si l'on rencontre un > , un blanc ou une fin de chaine
while (source [debut] != '>' && source [debut] & 0xDF)
dest [posdest++] = source [debut++];
// terminer l'expression de l'adresse
dest [posdest] = '\0';
}
/* copie dans le mail à envoyer d'une ligne du mail reçu */
void transf_ligne (char *message)
{
char bufw [82]; // buffer contenant la ligne à envoyer