// 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
aff_entete ();
// afficher son contenu
aff_corpsmail ();
// et fermer le fichier mail
fclose (fmail);
}
else
// "Fichier %s non trouvé"
aff_err_arg ("FICH_ABSENT", varg [1]);
}
else
// "Syntaxe : %s [-(h|H)] [-T] nom_fichier_mail"
psyntaxe ("SYNT_VOIRFMAIL");
// pour faire plaisir à gcc qui veut une fonction main de type int
return (0);
}
/* lit l'entête du message choisi et l'affiche */
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, posXorig, posTo, posCc, posReply, posSubject,
posContent;
char *varenv_xorig; // variable d'environnement libremail_xorig
char xorig; // information utile de libremail_xorig
// récupérer la partie significative de la variable libremail_xorig
varenv_xorig = getenv ("libremail_xorig");
if (varenv_xorig)
xorig = tolower (*varenv_xorig);
else
xorig = '\0';
// 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
// Le premier champ est un peu pour le fun
if ((start ("X-Mailer") || start ("User-Agent")) && ! optT)
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 ("X-Original-From") && xorig != 'n')
posXorig = 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
// si mode de fonctionnement standard
if (! optT)
{
// affichage ordonné des champs principaux de l'entête
if (posDate >= 0)
affchamp (posDate, 0);
if (posFrom >= 0 && (posXorig < 0 || xorig == '2'))
affchamp (posFrom, 1);
if (posXorig >= 0)
affchamp (posXorig, 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);
}
// sinon affichage réduit au sujet sans le nom de ce champ
else if (posSubject >= 0)
affchamp (posSubject + 8, 1);
// revenir au début du corps du message
fseek (fmail, pos_deblig, SEEK_SET);
// récupérer le type principal du message et ses caractéristiques
recup_typeorig (posContent);
}
/* 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');
}
/* lit le corps du message choisi et l'affiche */
void aff_corpsmail ()
{
// sauter la ligne blanche entre l'entête et le corps du mail
lire_fmail ();
// affichage du contenu du mail
if (ctypeorig & Multipart)
// il faudra analyser les sections
aff_mail ();
else
// un affichage simple suffit
aff_texte ();
}
/* suppression des balises html et affichage du reste */
void filtre_balhtm ()
{
// supprimer les balises html
sup_balhtm ();
// réduit à un les blancs multiples et les supprime en fin de ligne
sup_multiblancs ();
// et convertir les caractère sous la forme &...;
conv_carhtm ();
// si la dernière ligne lue n'est pas vide
if (*buf_lect && *buf_lect != '\n')
{
// l'afficher
printf ("%s", buf_lect);
// et mémoriser le fait qu'elle n'est pas vide
lig_nonvide = 1;
}
// sinon si la précédente n'était pas vide ou pas d'option -H
else if (lig_nonvide)
{
// l'afficher
putchar ('\n');
// et mémoriser le fait qu'elle est vide
lig_nonvide = 0;
}
}
/* affichage du contenu d'un mail en mode multipart */
// mémoriser tous les modes multipart imbriqués
do
{
switch (ctype)
{
case MultipMixed : multipmixed = 1;
break;
case MultipAlter : multipalter = 1;
break;
case MultipRep : multiprep = 1;
break;
case MultipRel : multiprel = 1;
}
// passer à la section suivante
prochaine_section ();
// récupérer ses caractéristiques
recup_infos_section ();
}
while ((ctype & Multipart) && lire_fmail ());
// indiquer si le mail peut contenir des pièces jointes
if (multipmixed)
// "Pièce(s) jointes(s) probable(s)"
affiche_msg ("PJ_PROBABLE");
// si une section multipart/alternative a été trouvée, se positionner
// (si l'on n'y est pas) sur la section text/plain ou text/html du mail
if (multipalter)
{
if (opthb)
posit_texthtm ();
else
posit_texte ();
}
// 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 (opthb)
// "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");
}
// si on doit supprimer la partie html avant <body
if (opthb & 4)
// le mémoriser
avantbody = 1;
// lecture et affichage du corps du message
do
{
// mise en forme de la dernière ligne lue
majligne ();
// si on est dans l'entête html qu'on doit supprimer
if (avantbody)
// le faire
supavantbody ();
// si option de suppression des balises html
if (opthb & 2)
// les supprimer
filtre_balhtm ();
// sinon afficher simplement la ligne
else
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 (multiprep && nbordures && surbordure ())
{
// aller à la prochaine ligne vide
while (lire_fmail () && *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 text/plain
if (ctypeorig == TextPlain)
// on ne traitera pas les balises html
opthb = 0;
// si texte encodé base 64
if (encodage_texte == Base64)
// générer une ligne de séparation avec l'entête
putchar ('\n');
// si on doit supprimer la partie html avant <body
if (opthb & 4)
// le mémoriser
avantbody = 1;
// répéter
do
{
// mise en forme de la dernière ligne lue
majligne ();
// si on est dans l'entête html qu'on doit supprimer
if (avantbody)
// le faire
supavantbody ();
// si option de suppression des balises html
if (opthb & 2)
// les supprimer
filtre_balhtm ();
// sinon afficher simplement la ligne
else
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 */