/*
    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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include "messages.h"
#include "buflect.h"
#include "ficonf.h"
#include "pop.h"
#include "numail.h"
#include "szchemin.h"


/* 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);
}