/*
Fichier voirfmail.c
Auteur Bernard Chardonneau
Logiciel libre, droits d'utilisation précisés en français
dans le fichier : licence.fr
Traductions des droits d'utilisation dans les fichiers :
licence.de , licence.en , licence.es , licence.it
licence.nl , licence.pt , licence.eo , licence.eo-utf
Ce programme affiche le contenu d'un fichier mail passé en paramètre
Le chemin d'accès au fichier peut être absolu ou relatif
*/
#define appli // pour la déclaration de variables globales à l'application
#include <stdio.h>
#include <string.h>
#include "messages.h"
#include "buflect.h"
#include "fmail.h"
#include "trtentete.h"
#include "trtligne.h"
#include "trtbordure.h"
#include "trtsection.h"
/* prototypes */
void aff_entete ();
void affchamp (long pos_deblig, int conversion);
void aff_mail ();
void aff_texte ();
void genligne (char *chaine);
/* variable globale au source
(pour éviter des tonnes de passages de paramètres) */
int opth; // option affichage de la section text/html au lieu de text/plain
/* programme principal */
int main (int nbarg, char *varg[])
{
// récupération du nom de l'exécutable
memcom (*varg);
// si commande lancée avec l'option -h ou -H
if (--nbarg > 1 && varg [1][0] == '-' && (varg [1][1] | 0x20) == 'h')
{
// mémoriser cette option
if (varg [1][1] == 'h')
opth = 1;
else
opth = 2;
// un argument traité
nbarg --;
varg ++;
}
else
// sinon pas d'option -h ni -H
opth = 0;
// controle du nombre d'arguments
if (nbarg == 1)
{
// ouvrir le fichier mail
fmail = fopen (varg [1], "r");
// si le fichier a pu être ouvert
if (fmail)
{
// afficher l'entête du mail puis son contenu
aff_entete ();
// et fermer le fichier mail
fclose (fmail);
}
else
// "Fichier %s non trouvé"
aff_err_arg ("FICH_ABSENT", varg [1]);
}
else
// "Syntaxe : %s [-(h|H)] nom_fichier_mail"
psyntaxe ("SYNT_VOIRFMAIL");
// pour faire plaisir à gcc qui veut une fonction main de type int
return (0);
}
/* lit le message choisi et l'affiche
cette fonction traite essentiellement l'entête du mail
puis appelle aff_mail pour l'affichage du corps du mail */
void aff_entete ()
{
long pos_deblig; // position dans le fichier en début de ligne
// position dans le fichier mail des principaux champs de l'entête
long posDate, posFrom, posTo, posCc, posReply, posSubject, posContent;
// initialisation
posDate = -1;
posFrom = -1;
posTo = -1;
posCc = -1;
posReply = -1;
posSubject = -1;
posContent = -1;
// lecture de l'entête et mémorisation de la position des champs importants
do
{
// récupérer la position en début de ligne
pos_deblig = ftell (fmail);
// lire une ligne de l'entête du message
lire_fmail ();
// repérage des champs importants et mémorisation de leur position
if (start ("X-Mailer") || start ("User-Agent")) // pour le fun
puts (buf_lect); // le mailer est affiché directement
else if (start ("Date"))
posDate = pos_deblig;
else if (start ("From"))
posFrom = pos_deblig;
else if (start ("To"))
posTo = pos_deblig;
else if (start ("Cc"))
posCc = pos_deblig;
else if (start ("Reply-To"))
posReply = pos_deblig;
else if (start ("Subject"))
posSubject = pos_deblig;
else if (start ("Content-Type"))
posContent = pos_deblig;
else if (start ("Content-Transfer-Encoding"))
mem_encodage ();
}
while (buf_lect [0] != '\0'); // lecture entête terminée si ligne vide
// affichage ordonné des champs principaux de l'entête
if (posDate >= 0)
affchamp (posDate, 0);
if (posFrom >= 0)
affchamp (posFrom, 1);
if (posTo >= 0)
affchamp (posTo, 1);
if (posCc >= 0)
affchamp (posCc, 1);
if (posReply >= 0)
affchamp (posReply, 1);
if (posSubject >= 0)
affchamp (posSubject, 1);
// récupérer le type principal du message et ses caractéristiques
typeorig (posContent);
// revenir au début du corps du message
fseek (fmail, pos_deblig, SEEK_SET);
lire_fmail ();
// affichage du contenu du mail
if (ctypeorig & Multipart)
// il faudra analyser les sections
aff_mail ();
else
// un affichage simple suffit
aff_texte ();
}
/* affiche un champ de l'entête d'une ou plusieurs lignes
repéré à partir de sa position dans le fichier mail */
void affchamp (long pos_deblig, int conversion)
{
// se positionner sur la ligne contenant le champ
fseek (fmail, pos_deblig, SEEK_SET);
// lire cette ligne
lire_fmail ();
// répéter
do
{
// interpréter si nécessaire les caractères spéciaux
if (conversion)
majlignentete ();
// et afficher la ligne
printf ("%s", buf_lect);
// en tenant compte d'un éventuel \n dans le buffer
if (buf_lect [strlen (buf_lect) - 1] != '\n')
putchar ('\n');
// lire la ligne suivante
lire_fmail ();
}
// jusqu'à ce qu'on ait traité tout le champ
while (*buf_lect == ' ' || *buf_lect == '\t');
}
/* affichage du contenu d'un mail en mode multipart */
void aff_mail ()
{
// si mode multipart/mixed ou multipart/related, mémoriser
// le type et la bordure éventuelle de la section suivante
if ((ctypeorig == MultipMixed) || (ctypeorig == MultipRel))
mem_soustype ();
// se positionner sur la section texte (ou text/html si option -h)
// du mail (si l'on n'y est pas)
if (opth)
posit_texthtm ();
else
posit_texte ();
// message d'avertissement éventuel
test_encode ();
// générer une ligne de séparation avec l'entête
putchar ('\n');
// si structure du mail non conforme, message d'erreur
if (! lire_fmail ())
{
if (opth)
// "Pas de zone texte html dans ce mail !!!"
affiche_msg ("MANQUE_ZONE_HTML");
else
// "Pas de zone texte dans ce mail !!!"
affiche_msg ("MANQUE_ZONE_TEXTE");
}
// lecture et affichage du corps du message
do
{
// mise en forme de la dernière ligne lue
majligne ();
// si traitement des balises html
if (opth == 2)
{
// supprimer les balises html
sup_balhtm ();
// et convertir les caractère sous la forme &...;
conv_carhtm (0);
}
// et affichage de la dernière ligne lue
printf ("%s", buf_lect);
// et lecture de la suivante
if (! lire_fmail ())
return; // on sort en fin de fichier
// si mode multipart/report, on saute les entêtes de section
if (ctypeorig == MultipRep && nbordures && surbordure ())
{
do
lire_fmail ();
while (*buf_lect);
}
}
// on s'arrête en fin de fichier, ou sur la prochaine bordure
while (nbordures == 0 || ! surbordure ());
// si mode multipart mixed on va lister les pièces jointes
if (ctypeorig == MultipMixed)
liste_pj ();
}
/* lecture et affichage d'un mail de type text/plain */
void aff_texte ()
{
// si le mail est au format test/plain
if (ctypeorig == TextPlain)
// on ne traitera pas les balises html
opth = 0;
// message d'avertissement éventuel
test_encode ();
// répéter
do
{
// mise en forme de la dernière ligne lue
majligne ();
// si traitement des balises html
if (opth == 2)
{
// supprimer les balises html
sup_balhtm ();
// et convertir les caractère sous la forme &...;
conv_carhtm (0);
}
// et affichage de la dernière ligne lue
printf ("%s", buf_lect);
// et lecture de la suivante
}
// on s'arrête en fin de fichier
while (lire_fmail ());
}
/* pour compatibilité avec la bibliothèque trtsection */
void genligne (char *chaine)
{
printf ("%s", chaine);
}