/*
Fichier chargemail.c
Auteur Bernard Chardonneau
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 télécharge les mail en attente sur un serveur.
Un fichier de configuration est utilisé pour se connecter à la
boite aux lettres et pour fixer le répertoire racine du système
de messagerie.
Les mail entrants sont stockés dans le sous répertoire "entree"
de ce répertoire racine et se distinguent par leur numéro.
On peut choisir de télécharger :
- tous les mails (option par défaut)
- un mail particulier identifié par son numéro
*/
#define appli // pour la déclaration de variables globales à l'application
/* constantes pour indiquer si l'on efface le(s) mail(s) téléchargé(s) */
#define OPTDEFAUT 0
#define EFFACE 1
#define CONSERVE 2
/* prototype */
void chargemail (int numes, long numail, int effacement);
/* variable globale au source
(pour éviter des tonnes de passages de paramètres) */
char dirmails [szchemin]; // répertoire de destination des messages
// chaine de caractères mémorisée pour éviter un appel répétitif à message ()
char mess_telech [50]; // message signalant le téléchargement d'un mail
/* 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
long numail; // numéro du mail dans le fichier téléchargé
int option; // option : détermine si on conserve les mails récupérés
// récupération du nom de l'exécutable
memcom (*varg);
// se positionner sur le premier argument de chargemail
varg ++;
// récupération de l'option de fonctionnement éventuelle
if (--nbarg > 1 && **varg == '-')
{
if (varg [0][1] == 'd')
option = EFFACE;
else if (varg [0][1] == 'k')
option = CONSERVE;
else
{
// "Option %s incorrecte"
aff_err_arg ("ERR_OPTION", *varg);
nbarg = 0; // pour afficher la syntaxe de la commande
}
// décompter l'argument traité
varg ++;
nbarg --;
}
else
// option de fonctionnement par défaut
option = OPTDEFAUT;
// récupérer le numéro du mail à télécharger s'il a été spécifié
if (nbarg && atoi (*varg) > 0)
{
numes = atoi (*varg);
// décompter l'argument traité
nbarg --;
varg ++;
}
else
numes = 0; // on téléchargera tous les mails
// controle du nombre d'arguments restant
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é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)
{
// 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 du message à
// afficher à chaque téléchargement
// "\rTéléchargement du mail n° %d"
strcpy (mess_telech, message ("TELECH_MAIL"));
// si demande de téléchargement d'un mail particulier
if (numes)
{
// si un mail existe avec ce numéro
if (numes <= nbmes)
{
// par défaut, lorsqu'on récupère un mail
// unique, on le laisse sur le serveur
if (option == OPTDEFAUT)
option = CONSERVE;
// téléchargement du mail demandé
chargemail (numes, ++numail, option);
}
// sinon, afficher un message d'erreur
else
// "Numéro de mail trop grand"
affiche_err ("NUMAIL_TROP_GRAND");
}
// sinon, on téléchargera tous les mails
else
{
// par défaut, lorsqu'on récupère tous les mails,
// on les supprime du serveur
if (option == OPTDEFAUT)
option = EFFACE;
// téléchargement de tous les mails
for (numes = 1; numes <= nbmes; numes++)
chargemail (numes, ++numail, option);
}
// pour l'affichage
putchar ('\n');
// 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)] [numéro_mail] fichier_configuration"
psyntaxe ("SYNT_CHARGEMAIL");
// pour faire plaisir à gcc qui veut une fonction main de type int
return (0);
}
/* télécharge le message 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);
}