/* constantes pour indiquer si l'on efface le(s) mail(s) téléchargé(s) */
#define OPTDEFAUT 0
#define EFFACE 1
#define CONSERVE 2
/* prototypes */
int testexped (int numes);
void chargemail (int numes, long numail, int effacement);
/* variable globale au source
(pour éviter des tonnes de passages de paramètres) */
char **listexped; // mémorise les destinataires autorisés
int sz_listexped; // nombre de destinataires mémorisés dans listexped
char dirmails [szchemin]; // répertoire de destination des messages
// chaines de caractères mémorisées pour éviter appels répétitifs à message ()
char mess_analys [50]; // message signalant l'analyse d'un mail
char mess_telech [50]; // message signalant le téléchargement d'un mail
/* programme principal */
int main (int nbarg, char *varg[])
{
char ficonf [120]; // fichier de configuration du système de mail
FILE *fconf; // descripteur du fichier de configuration
char fichliste [szchemin]; // fichier contenant liste des chaines à tester
int numes, nbmes; // numéro du mail courant et nombre de mails
int nbrecup = 0; // nombre de mails téléchargés
long numail; // numéro du mail dans le fichier téléchargé
int option; // détermine si on conserve sur le serveur les mails récupérés
// récupération du nom de l'exécutable
memcom (*varg);
// se positionner sur le premier argument de chargexpedok
varg ++;
nbarg --;
// options de fonctionnement par défaut
option = OPTDEFAUT;
// récupération de l'option de fonctionnement éventuelle
while (nbarg > 0 && **varg == '-')
{
switch (varg [0][1])
{
// option effacement du serveur des mails récupérés
case 'd': if (option == CONSERVE)
{
// "Options -d et -k incompatibles"
affiche_err ("COMPAT_OPT_DK");
return (-1);
}
else
option = EFFACE;
break;
// option conservation sur le serveur des mails récupérés
case 'k': if (option == EFFACE)
{
// "Options -d et -k incompatibles"
affiche_err ("COMPAT_OPT_DK");
return (-1);
}
else
option = CONSERVE;
break;
// "Option %s incorrecte"
default : aff_err_arg ("ERR_OPTION", *varg);
nbarg = 0; // pour afficher la syntaxe de la commande
}
// controle du nombre d'arguments
if (nbarg == 1)
{
// ouvrir le fichier de configuration
fconf = ouvre_ficonf (varg [0]);
if (fconf)
{
// connexion sur le compte mail du serveur pop
if (connect_pop (fconf))
{
// récupérer le répertoire racine de la messagerie
fgets (dirmails, sizeof (dirmails) - 7, fconf);
dirmails [strlen (dirmails) - 1] = '\0';
// si ce répertoire existe
if (access (dirmails, 0) == 0)
{
// chercher le nom du fichier contenant
// les expéditeurs autorisés
sprintf (fichliste, "%s/%s", dirmails,
ficdir ("FIC_ACCEPT_ADR"));
// charger en mémoire les expéditeurs autorisés
listexped = charge_valchamp (fichliste, &sz_listexped);
// si la liste n'est pas vide
if (sz_listexped)
{
// créer si nécessaire le sous repertoire d'entrée
strcat (dirmails, "/");
strcat (dirmails, ficdir ("DIR_ENTREE"));
mkdir (dirmails, 0755);
// récupération du nombre de mails
nbmes = nbmails ();
// si des mails peuvent être récupérés
if (nbmes)
{
// récupération du numéro du dernier fichier mail
numail = num_dermail (dirmails);
// Initialisation des messages à afficher à chaque
// analyse ou téléchargement de mail
// "\rAnalyse du mail n° %d "
strcpy (mess_analys, message ("ANALYSE_MAIL_BL"));
// "\rTéléchargement du mail n° %d"
strcpy (mess_telech, message ("TELECH_MAIL"));
// pour chaque fichier mail du serveur
for (numes = 1; numes <= nbmes; numes++)
{
// si l'expéditeur du mail est autorisé
if (testexped (numes))
{
// télécharger le mail correspondant
chargemail (numes, ++numail, option);
// on compte les mails téléchargés
nbrecup ++;
}
}
// édition d'un récapitulatif
// "\n%d mails téléchargés sur %d\n"
printf (message ("TOTAL_TELECH"), nbrecup, nbmes);
// sauvegarde du numéro du dernier fichier mail
sauv_num_dermail (dirmails, numail);
}
}
}
else
// "répertoire de messagerie %s inexistant"
aff_err_arg ("REP_RACINE_ABSENT", dirmails);
// se déconnecter proprement du serveur pop
deconnect_pop ();
}
// on n'a plus besoin du fichier de configuration
fclose (fconf);
}
}
else
// "Syntaxe : %s [-(k|d)] fichier_configuration"
psyntaxe ("SYNT_CHARGEXPEDOK");
// pour faire plaisir à gcc qui veut une fonction main de type int
return (0);
}
/* lit l'entête d'un mail et vérifie si son expéditeur est autorisé */
int testexped (int numes)
{
char bufw [120]; // buffer d'envoi d'une requête
char bufFrom [120]; // buffer contenant l'expéditeur du mail
int i; // simple compteur
// message de suivi de déroulement
// "\rAnalyse du mail n° %d "
printf (mess_analys, numes);
fflush (stdout);
// initialisation
bufFrom [0] = '\0';
// 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 l'expediteur du mail
do
{
// si on a trouvé le champ expediteur
if (start ("From"))
{
// convertir les caractères spéciaux de la ligne
majlignentete ();
// initialisation
i = 5;
// recherche du début de l'expediteur
while (buf_lect [i] == ' ')
i++;
// tronquer si nécessaire l'expediteur (pour éviter un plantage)
if (strlen (buf_lect + i) > sizeof (bufFrom))
buf_lect [i + sizeof (bufFrom) - 1] = '\0';
// mémorisation de l'expediteur
strcpy (bufFrom, buf_lect + i);
}
// 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 l'expéditeur du mail est autorisé
return trouve_valchamp (bufFrom, listexped, sz_listexped);
}
/* télécharge le mail choisi et l'enlève du serveur si c'est demandé */
void chargemail (int numes, long numail, int effacement)
{
char bufw [120]; // buffer d'envoi d'une requête
char ficmail [sizeof (dirmails) + 9];
FILE *fmail;
// création du fichier mail
sprintf (ficmail, "%s/r%07ld.n", dirmails, numail);
fmail = fopen (ficmail, "w");
if (fmail)
{
// message de suivi du déroulement
// "\rTéléchargement du mail n° %d"
printf (mess_telech, numes);
fflush (stdout);
// demande de lecture du message et réception de l'acquittement
sprintf (bufw, "RETR %d", numes);
env_pop (bufw);
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);
fclose (fmail);
unlink (ficmail);
return;
}
// lire la première ligne de l'entête du mail
lire_pop ();
// lecture et copie du message jusqu'à une ligne limitée a un .
while (buf_lect [0] != '.' || buf_lect [1] != '\0')
{
// copie de la ligne lue dans le fichier mail
fputs (buf_lect, fmail);
fputc ('\n', fmail); // nécessaire car supprimé de buf_lect
// et lecture de la suivante
lire_pop ();
}
// fermer le fichier contenant le mail
fclose (fmail);
// et supprimer si nécessaire le mail du serveur
if (effacement != CONSERVE)
{
sprintf (bufw, "DELE %d", numes);
env_pop (bufw);
lire_pop ();
}
}
else
// "Impossible d'écrire dans le fichier %s"
aff_err_arg ("IMPOS_ECR_FICH", ficmail);
}