/* prototypes */
int testchamp (int numes, char *nomchamp);
/* variables globales au source
(pour éviter des tonnes de passages de paramètres) */
char **listechamp; // mémorise les champs interdits
int sz_listechamp; // nombre de champs mémorisés dans listechamp
char bufChamp [120]; // buffer contenant le champ du mail à tester
int opto, optO; // options de traitement
// chaine de caractère mémorisée pour éviter appels répétitifs à message ()
char mess_analys [50]; // message signalant l'analyse d'un mail
/* programme principal */
int main (int nbarg, char *varg[])
{
char fichliste [szchemin]; // fichier contenant liste des chaines à tester
FILE *fconf; // descripteur du fichier de configuration
FILE *ftrace; // fichier contenant les champs des mail refusés
char *nomchamp; // nom du champ à tester
char *nomfliste; // nom du fichier contenant les chaines à tester
int numes, nbmes; // muméro du mail courant et nombre de mails
char bufw [120]; // buffer d'envoi d'une requête de destruction de mail
char datecour [10]; // date courante (pour le fichier des mails refusés)
int conserves = 0; // nombre de mails conservés
int supprimes = 0; // nombre de mails supprimés
int i, j; // compteurs
// récupération du nom de l'exécutable
memcom (*varg);
// se positionner sur le premier argument de filtrechamp
nbarg --;
varg ++;
// récupération du nom du champ à tester
if (nbarg > 1)
{
nomchamp = varg [0];
nbarg --;
varg ++;
}
// si le programme a été lancé avec des options
while (nbarg >= 2 && **varg == '-')
{
// traitement des options
switch (varg [0][1])
{
// option trace des mails supprimés
case 't' : // 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]);
// option test de la ligne d'entête d'origine (avant conversion)
case 'o' : if (! optO)
opto = 1;
else
// "L'option -O est prioritaire sur l'option -o"
affiche_err ("PRIO_OPT_O");
// aucune autre option n'est reconnue
// "Option %s incorrecte"
default : aff_err_arg ("ERR_OPTION", *varg);
nbarg = 0; // pour rappeller la syntaxe
}
}
// controle du nombre d'arguments restants
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))
{
// détermination du nom du fichier
// contenant les chaines interdites
// cas particulier : chemin d'accès absolu à ce fichier
if (nomfliste && *nomfliste == '/')
strcpy (fichliste, nomfliste);
else
{
// cas général : pas de chemin d'accès absolu au fichier
// récupération du répertoire racine de la messagerie
fgets (fichliste, sizeof (fichliste), fconf);
// on complète ce nom d'un /
strcpy (fichliste + strlen (fichliste) - 1, "/");
// si le nom de ce fichier a été passé en paramètre
if (nomfliste)
// le rajouter au nom du répertoire
strcat (fichliste, nomfliste);
else
{
// sinon, on va générer un nom à partir du nom du champ
strcat (fichliste, ficdir ("FIC_REFUS_"));
i = strlen (fichliste);
j = 0;
do
// le nom du champ est recopié en minuscules
fichliste [i++] = tolower (nomchamp [j]);
while (nomchamp [j++]);
}
}
// charger en mémoire les champs interdits
listechamp = charge_valchamp (fichliste, &sz_listechamp);
// si la liste n'est pas vide
if (sz_listechamp)
{
// récupération du nombre de mails
nbmes = nbmails ();
// Initialisation du message à afficher
// à chaque analyse de mail
// "\rAnalyse du mail n° %d"
strcpy (mess_analys, message ("ANALYSE_MAIL"));
// vérification des différents mails
for (numes = 1; numes <= nbmes; numes++)
{
// si le champ du mail contient une chaine interdite
if (testchamp (numes, nomchamp))
{
// demande de destruction du mail
sprintf (bufw, "DELE %d", numes);
env_pop (bufw);
lire_pop ();
supprimes ++;
// si utilisation d'un fichier trace
if (ftrace)
// mémoriser le champ de ce mail
fprintf (ftrace, "%s%s\n", datecour, bufChamp);
}
else
conserves ++;
}
// 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 nom_champ [-f fich_liste]
// [-(o|O)] [-t fich_trace] fich_configuration"
psyntaxe ("SYNT_FILTRECHAMP");
return (0);
}
/* lit l'entête d'un mail et vérifie si son champ est autorisé */
int testchamp (int numes, char *nomchamp)
{
char bufw [120]; // buffer d'envoi d'une requête
char champbrut [120]; // buffer contenant le champ du mail avant décodage
int debchamp; // position du premier caractère significatif du champ
// "\rAnalyse du mail n° %d"
printf (mess_analys, numes);
fflush (stdout);
// demande de lecture de l'entête du message
sprintf (bufw, "TOP %d 1", numes);
env_pop (bufw);
// lire la première ligne de l'entête du message
lire_pop ();
// terminé pour ce mail si erreur d'envoi coté serveur
if (memcmp (buf_lect, "-ERR ", 5) == 0)
{
// Erreur serveur pour l'accès au mail
aff_err_argnum ("ERREUR_SERVEUR", numes);
return 0;
}
// lecture entête du message et mémorisation de le champ du mail
do
{
// si on a trouvé le champ choisi
if (start (nomchamp))
{
// recherche du premier caractère significatif du champ
debchamp = strlen (nomchamp) + 1;
while (buf_lect [debchamp] == ' ')
debchamp++;
// si option -o ou -O
if (opto || optO)
{
// mémoriser le champ du mail avant conversion en le tronquant
// si nécessaire pour éviter un débordement de tableau
if (strlen (buf_lect + debchamp) >= sizeof (champbrut))
{
memcpy (champbrut, buf_lect + debchamp, sizeof (champbrut));
champbrut [sizeof (champbrut) - 1] = '\0';
}
else
strcpy (champbrut, buf_lect + debchamp);
}
// si on n'utilise pas l'option -O
if (! optO)
{
// convertir les caractères spéciaux de la ligne
majlignentete ();
// tronquer si nécessaire le champ
if (strlen (buf_lect + debchamp) >= sizeof (bufChamp))
buf_lect [debchamp + sizeof (bufChamp) - 1] = '\0';
// lire la ligne suivante de l'entête du message
lire_pop ();
}
// lecture terminée si ligne limitée à un .
while (buf_lect [0] != '.' || buf_lect [1] != '\0');
// vérifier si le mail contient un des champs de la liste interdite
if (optO)
// option -O : test sur le champ brut seulement
return trouve_valchamp (champbrut, listechamp, sz_listechamp);
else if (opto)
{
// option -o (seule) : test sur le champ brut et le champ converti
return (trouve_valchamp (champbrut, listechamp, sz_listechamp)
|| trouve_valchamp (bufChamp, listechamp, sz_listechamp));
}
else
// aucune option : test sur le champ converti seulement
return trouve_valchamp (bufChamp, listechamp, sz_listechamp);
}