/*
Fichier simulsmtp.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
Bibliothèque de fonctions permettant
la simulation d'envoi de mails au serveur smtp
Fonctionne même sans connexion au réseau
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "buflect.h"
#include "smtp.h"
#include "base64.h"
#define defaut_port_smtp 25 // port utilisé par défaut par les serveurs smtp
#define octet unsigned char
/* Connexion au serveur smtp (même fonction qu'en mode normal) */
int connect_smtp (char *infoserveur)
{
octet *carinfo; // caractère de infoserveur
char serv_smtp [120]; // nom du serveur smtp utilisé
int port; // numéro du port smtp utilisé
FILE *fich_auth; // descripteur du fichier d'authentification smtp
char bufin [120]; // buffer pour lire le fichier d'authentification
char bufw [120]; // buffer d'envoi d'une ligne ou requête smtp
int caract; // caractère du fichier d'authentification smtp
int retour; // code de retour de la fonction
// initialisation du numéro de port par défaut
port = defaut_port_smtp;
// si la ligne smtp de fichier de configuration fait
// référence à un fichier d'authentification smtp
if (*infoserveur == '>')
{
// se positionner sur le nom de ce fichier
carinfo = infoserveur + 1;
while (*carinfo == ' ' || *carinfo == '\t')
carinfo ++;
fich_auth = fopen (carinfo, "r");
if (fich_auth)
{
// recupérer le nom du serveur smtp
fgets (serv_smtp, 120, fich_auth);
serv_smtp [strlen (serv_smtp) - 1] = '\0';
// mémoriser les autres lignes particulières du fichier
// d'authentification smtp (on s'arrête sur une ligne vide)
while (fgets (bufin, 120, fich_auth) && *bufin != '\n')
{
bufin [strlen (bufin) - 1] = '\0';
// numéro de port spécifié ?
if (startligne (bufin, "port"))
{
// récupérer le numéro du port
carinfo = bufin + 4;
while (*carinfo == ' ' || *carinfo == '\t')
carinfo++;
port = atoi (carinfo);
// le vérifier sommairement
if (!port)
{
// "Numéro de port smtp invalide"
affiche_err ("PORT_SMTP_INVALIDE");
retour = 0;
}
}
}
// tentative de connexion au serveur smtp
if (port)
retour = connect_serv_smtp (serv_smtp, port);
// si la connexion s'est bien déroulée
if (retour)
{
// se positionner sur la première ligne
// du dialogue d'authentification
while (fgets (bufin, 120, fich_auth) && *bufin == '\n')
;
// dialogue d'authentification
do
{
// mise en forme de la ligne lue
bufin [strlen (bufin) - 1] = '\0';
// si ligne à encoder base 64
if (startligne (bufin, "b64"))
{
// l'encoder avant de l'envoyer
encode64 (bufin + 4, bufw, strlen (bufin + 4));
puts (bufin);
envoie_smtp (bufw);
}
// sinon, envoyer directement la ligne
else
envoie_smtp (bufin);
// et lire la réponse du serveur
lire_smtp ();
}
// passage à la ligne suivante
while (fgets (bufin, 120, fich_auth));
}
// libérer le fichier d'authentification smtp
fclose (fich_auth);
}
else
{
// message d'erreur
// "Fichier %s non trouvé"
aff_err_arg ("FICH_ABSENT", carinfo);
retour = 0;
}
}
// sinon simple connexion à un serveur smtp sans authentification
else
{
// parcourir le nom du serveur smtp
carinfo = infoserveur;
while (*carinfo > ' ')
carinfo ++;
// si le nom du serveur smtp est suivi d'autres informations
if (*carinfo)
{
// terminer le nom du serveur smtp
*carinfo = '\0';
// se positionner sur le numéro de port éventuel
do
carinfo++;
while (*carinfo == ' ' || *carinfo == '\t');
}
// si un numéro de port semble présent
if (*carinfo)
// le récupérer
port = atoi (carinfo);
// si numéro de port trouvé ou si on a conservé le port par défaut
if (port)
// établir la connexion smtp avec le port choisi
retour = connect_serv_smtp (infoserveur, port);
// sinon message d'erreur
else
{
// "Numéro de port smtp invalide"
affiche_err ("PORT_SMTP_INVALIDE");
retour = 0;
}
// si la connexion smtp s'est bien déroulée
if (retour)
{
// générer le message helo nom_de_calculateur
strcpy (bufw, "HELO ");
gethostname (bufw + 5, sizeof (bufw) - 5);
// identification de l'ordinateur connecté
envoie_smtp (bufw);
lire_smtp ();
}
}
// renvoyer le code de retour de la fonction
return (retour);
}
/* Simulation de connexion réussie au serveur smtp sans authentification */
int connect_serv_smtp (char *serveur, int port_smtp)
{
char bufw [120]; // buffer d'envoi d'une ligne ou requête smtp
printf ("Connexion au serveur %s sur le port %d\n", serveur, port_smtp);
// simulation de la réponse du serveur smtp
lire_smtp ();
return (1);
}
/* teste si la ligne passée en paramètre commence par un mot clé particulier */
int startligne (char *ligne, char *motcle)
{
int i;
i = 0;
// on teste caractère par caractère en ignorant la casse
while (motcle [i] && tolower (ligne [i]) == tolower (motcle [i]))
i++;
// le mot clé doit être suivi d'un blanc dans la ligne lue
return (ligne [i] == ' ');
}
/* Simulation écriture de données */
void envoie_smtp (char *buffer)
{
puts (buffer);
}
/* Simulation lecture d'une ligne de données */
void lire_smtp ()
{
strcpy (buf_lect, "250 OK");
}
/* Simulation déconnexion propre du serveur smtp */
void deconnect_smtp ()
{
// envoi du message de deconnexion
envoie_smtp ("QUIT");
// lecture de l'acquittement
lire_smtp ();
}