/* cet include peut être mis en commentaire si
on n'utilise pas les mots de passe cryptés */
#include "clecrypt.h"
// #define DEBUG
#define defaut_port_pop 110 // port utilisé par défaut par les serveurs pop
#define timeout_connect 5 // attente maximum en secondes à la connexion
/* variables globales au source
(pour éviter des tonnes de passages de paramètres) */
static int sockfd = -1; // descripteur pour dialoguer avec le serveur
/* mémorise si les nom d'utilisateur et mot de passe ont déjà été saisis
au clavier
utile pour éviter de reposer la question avec l'outil chargepartaille
cette variable peut devenir interne à connect_pop (en restant statique)
si on supprime la fonction init_cmdpop */
static int memcmd [2] = { 0, 0 };
/* connexion au serveur pop et identification de la boite aux lettres */
int connect_pop (FILE *fconf)
{
char nom_serv_pop [120]; // nom du serveur pop
char *carnom; // caractère de nom_serv_pop
int port; // numéro du port pop utilisé
struct hostent *HostEnt; // description du host serveur
struct sockaddr_in serv_addr; // addresse du serveur
struct timeval st_timeout; // structure pour fixer timeout à la connexion
time_t avant, apres; // pour détection sortie sur timeout
char bufw [120]; // buffer pour message au serveur pop
static char cmdpop [2][120]; // mémorisation nom utilisateur et mot passe
int i, j; // compteurs;
// récupération du nom du serveur pop
fgets (nom_serv_pop, sizeof (nom_serv_pop), fconf);
nom_serv_pop [strlen (nom_serv_pop) - 1] = '\0';
// initialisation du numéro de port par défaut
port = defaut_port_pop;
// positionnement à la fin du nom du serveur
carnom = nom_serv_pop;
while (*carnom > ' ')
carnom ++;
// si le nom du serveur pop est suivi d'autres informations
if (*carnom)
{
// terminer le nom du serveur pop
*carnom = '\0';
// se positionner sur le numéro de port éventuel
do
carnom++;
while (*carnom == ' ' || *carnom == '\t');
// si un numéro de port semble présent
if (*carnom)
{
// le récupérer
port = atoi (carnom);
// vérifier sommairement qu'il peut convenir
if (!port)
{
// "Numéro de port pop invalide"
affiche_err ("PORT_POP_INVALIDE");
return (0);
}
}
}
// cette partie système est repompée d'un source peu commenté
memset (&serv_addr, 0, sizeof (serv_addr)); // init serv_addr
HostEnt = gethostbyname (nom_serv_pop);
if (HostEnt == NULL)
{
// "Serveur pop non trouvé"
affiche_err ("SERV_POP_ABSENT");
return (0);
}
serv_addr.sin_port = htons (port); // host to network port
serv_addr.sin_family = AF_INET; // AF_*** : INET=internet
// création de la socket
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
{
// "Problème création socket client"
affiche_err ("CREAT_SOCKET_POP");
return (0);
}
// on fixe un temps de réponse maximum à la connexion
st_timeout.tv_sec = timeout_connect;
st_timeout.tv_usec = 0;
if (setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO,
&st_timeout, sizeof (st_timeout)) < 0)
{
// "Problème pour fixer un timeout à la connexion : attente bloquante"
affiche_err ("PB_FIX_TIMEOUT");
}
// on va mesurer le temps nécessaire pour se connecter
time (&avant);
// requête de connexion
if (connect (sockfd, (struct sockaddr*) &serv_addr, sizeof (serv_addr)) < 0)
{
time (&apres);
// afficher un message adapté
if (apres - avant >= timeout_connect)
// "Problème demande de connexion : délai dépassé"
affiche_err ("PB_TIMEOUT_SERVEUR");
else
{
// "Problème demande de connexion"
// "peut être due à une connexion Internet par proxy"
affiche_err ("PB_ACCES_SERV-1");
affiche_err ("PB_ACCES_SERV-2");
}
return (0);
}
// attente réponse serveur pop
lire_pop ();
// envoi du nom d'utilisateur et du mot de passe
for (i = 0; i < 2; i++)
{
// lecture d'une ligne du fichier de configuration
fgets (bufw, sizeof (bufw), fconf);
bufw [strlen (bufw) - 1] = '\0';
// si l'information doit être saisie au clavier
if (*bufw == '?')
{
// et qu'elle n'a pas déjà été demandée
if (! memcmd [i])
{
// mise en forme de la première partie de la commande pop
for (j = 0; j < 4; j++)
bufw [j] = bufw [j + 1];
bufw [j] = ' ';
// saisie au clavier et mémorisation du login ou du mot de passe
printf ("%s? ", bufw);
// sans afficher les mots de passe
if (i == 1)
system ("stty -echo");
fgets (bufw + 5, sizeof (bufw) - 5, stdin);
// on réautorise l'affichage
if (i == 1)
{
system ("stty echo");
putchar ('\n');
}
// on termine la chaine lue
bufw [strlen (bufw) - 1] = '\0';
// mémorisation de la commande pop obtenue
// pour ne pas reposer la question plus tard
strcpy (cmdpop [i], bufw);
// pour éviter de redemander la même chose
memcmd [i] = 1;
}
else
// sinon récupérer la commande pop déjà mémorisée
strcpy (bufw, cmdpop [i]);
}
#ifdef cryptepass
// sinon si mot de passe crypté
else if (*bufw == '%' && i == 1)
{
// suppression du % qui précède la commande pop
for (j = 0; bufw [j]; j++)
bufw [j] = bufw [j + 1];
// décryptage du mot de passe
for (j = 5; bufw [j]; j++)
bufw [j] = bufw [j] ^ (clecrypt [(j - 5) & 0x0F] & 0x1F);
}
#endif
// envoyer la commande pop et lire la réponse
env_pop (bufw);
lire_pop ();
// test sommaire de la réponse du serveur pop
if (buf_lect [1] != 'O' || buf_lect [2] != 'K')
{
// "Erreur d'identification de la boite aux lettres"
affiche_err ("PB_ACCES_BAL");
deconnect_pop ();
return 0;
}
}
// identification réussie
return 1;
}
/* Cette fonction permet de ressaisir au clavier un nom d'utilisateur ou un mot
de passe, alors que cela a déjà été fait auparavant dans connect_pop (...)
Elle n'est pas utilisée par libremail, mais est quand même fournie pour info
*/