I. Moniteur POP3 de emails en C



Documents pareils
Programmation système de commandes en C

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Java Licence Professionnelle CISII,

Cours 6 : Tubes anonymes et nommés

Programmation système en C/C++

3IS - Système d'exploitation linux - Programmation système

Introduction au langage C

Les structures de données. Rajae El Ouazzani

Programmation système I Les entrées/sorties

Simulation d un système de paiement par carte bancaire

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles florence.henry@obspm.fr

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Le prototype de la fonction main()

MISE A NIVEAU INFORMATIQUE LANGAGE C - EXEMPLES DE PROGRAMMES. Université Paris Dauphine IUP Génie Mathématique et Informatique 2 ème année

Programmation Classique en langage C

OS Réseaux et Programmation Système - C5

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Bases de programmation. Cours 5. Structurer les données

Communication par sockets

Programmation C++ (débutant)/instructions for, while et do...while

Les arbres binaires de recherche

Compression de Données - Algorithme de Huffman Document de Conception

Le système de gestion des fichiers, les entrées/sorties.

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

STS SE. FreeRTOS. Programmation réseau WIFI. Programmation réseau. Socket Tcp. FlyPort smart Wi-Fi module

Le traitement du temps

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

Cours de Programmation Impérative: Zones de mémoires et pointeurs

Programmation en langage C


TRAVAUX PRATIQUES Programmation Système Langage C / Système UNIX. 2 e année Génie Informatique

Cours Programmation Système

Programmation impérative

Gestion distribuée (par sockets) de banque en Java

Algorithmique et Programmation, IMA

Conventions d écriture et outils de mise au point

Cours de C. Petits secrets du C & programmation avancée. Sébastien Paumier

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Chapitre 1 : La gestion dynamique de la mémoire

Programmation client-serveur sockets - RPC

#include <stdio.h> #include <stdlib.h> struct cell { int clef; struct cell *suiv; };

Cours d initiation à la programmation en C++ Johann Cuenin

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

TD3: tableaux avancées, première classe et chaînes

DNS Server RPC Interface buffer overflow. Céline COLLUMEAU Nicolas BODIN

Les fichiers. Chapitre 4

Dans le chapitre 1, nous associions aux fichiers ouverts des descripteurs de fichiers par lesquels nous accédions aux fichiers.

Plan du cours. Historique du langage Nouveautés de Java 7

COMPARAISONDESLANGAGESC, C++, JAVA ET

Cours de Systèmes d Exploitation

Initiation. àl algorithmique et à la programmation. en C

LEs processus coopèrent souvent pour traiter un même problème. Ces

Playing with ptrace() for fun and profit

Initiation à LabView : Les exemples d applications :

Langage C. Patrick Corde. 22 juin Patrick Corde ( Patrick.Corde@idris.fr ) Langage C 22 juin / 289

1 Lecture de fichiers

Plan global. Programmation système II. Socket du domaine UNIX. Plan. Socket UNIX, Terminaux, Async IO, Mémoire, ELF.

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Introduction à MATLAB R

Travaux Dirigés n 1 : chaînes de caractères

INTRODUCTION AUX SYSTEMES D EXPLOITATION. TD2 Exclusion mutuelle / Sémaphores

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

Programmer en JAVA. par Tama

Arguments d un programme

Exercice sur les Dockers

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Réalisation de SMSMail

TP2 : tableaux dynamiques et listes chaînées

Développement d un logiciel de messagerie instantanée avec Dotnet (version simplifiée)

Projet d informatique M1BI : Compression et décompression de texte. 1 Généralités sur la compression/décompression de texte

Programmation Internet en Java

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

UE Programmation Impérative Licence 2ème Année

Programmation C. Apprendre à développer des programmes simples dans le langage C

Cours d Algorithmique et de Langage C v 3.0

PHP et mysql. Code: php_mysql. Olivier Clavel - Daniel K. Schneider - Patrick Jermann - Vivian Synteta Version: 0.9 (modifié le 13/3/01 par VS)

Cahier des charges. driver WIFI pour chipset Ralink RT2571W. sur hardware ARM7

INITIATION A LA PROGRAMMATION

Le langage C. Séance n 4

Pensez à vous inscrire... si ce n est pas encore fait

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

INSTALLATION DE WINDOWS 2000 SERVER POUR BCDI3. par. G.Haberer, A.Peuch, P.Saadé

Contrôle d accès UTIL TP N 1 découverte

Programmation en langage C d un µcontrôleur PIC à l aide du compilateur C-CCS Sommaire

Les chaînes de caractères

Pour plus de détails concernant le protocole TCP conférez vous à la présentation des protocoles Internet enseignée pendant.

UE C avancé cours 1: introduction et révisions

SNT4U16 - Initiation à la programmation TD - Dynamique de POP III - Fichiers sources

Applications client/serveur TCP/IP - Sockets Rappels. C.Crochepeyre Applications CS 1

Solutions du chapitre 4

INF 104 (SELC) Introduction au langage C

Notions fondamentales du langage C# Version 1.0

Licence Sciences et Technologies Examen janvier 2010

Processus! programme. DIMA, Systèmes Centralisés (Ph. Mauran) " Processus = suite d'actions = suite d'états obtenus = trace

PROGRAMMATION PAR OBJETS

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Transcription:

Année universitaire 2014/2015 Site : Luminy St-Charles St-Jérôme Cht-Gombert Aix-Montperrin Aubagne-SATIS Sujet de : 1 er semestre 2ème semestre Session 2 Examen de : L3 Code du module : SIN5U3 Calculatrices autorisées : NON Nom du diplôme : Licence d Informatique Durée de l épreuve : 2h Libellé du module : Réseau et Communication Documents autorisés : OUI, notes de Cours/TD/TP Vous pouvez appeler sans les recopier les fonctions de la boîte à outil réseau vues en TD. I. Moniteur POP3 de emails en C On se propose de réaliser un programme C monipop3.c qui affiche régulièrement le nombre de messages et leur taille totale présents dans un compte email via le protocole POP3. On rappelle que POP3 est un protocole ASCII 7 bits sur TCP/IP à base de question/réponses. Voici un exemple de session réalisé avec netcat (ici on se trompe volontairement de mot de passe pour montrer l effet); le résultat est qu il ya3messages pouruntotal de 9251 octets. $ netcat serveur 110 PASS mauvais mdp STAT QUIT $ POP3 ready -ERR Invalid login or pw -ERR Invalid command Mailbox ready 3 9251 On se donne le type Etat pour coder l état correspondant aux différentes phases du dialogue : typedef enum DEMARRER_CONN, ATTENDRE_CONN_OK, ENVOYER_USER, ATTENDRE_USER_OK, ENVOYER_PASS, ATTENDRE_PASS_OK, ENVOYER_STAT, ATTENDRE_STAT_OK, ENVOYER_QUIT, ATTENDRE_QUIT_OK, TERMINER_CONN Etat; On définit le type Moniteur pour mémoriser tous les paramètres de notre programme : Les champs user et pass servent à l identification; mess contient le message en émission ou en réception (selon etat), pos est la position d émission ou d insertion dans mess; delai est le délai en secondes au bout duquel on réinterroge le serveur POP3; pop3_ok est vrai si le dialogue en POP3 s est déroulé sans erreur (c est-à-dire si aucun message commançant par "-ERR" n a été reçu). #define MESS_SIZE 1024 typedef struct int soc; char *serveur_nom; struct sockaddr_in client_adr, serveur_adr; int serveur_port; char *user, *pass; Etat etat; char mess[mess_size]; int pos, delai, pop3_ok; Moniteur; 1) Écrire la fonction void changer_etat (Moniteur *mon, Etat etat) qui reçoit en paramètre un nouvel etat. La fonction le mémorise dans mon, puis initialise le champ pos à 0 (signifiant que dans ce nouvel etat, aucun octet n a encore été envoyé ou reçu). Si etat est ENVOYER_USER ou ENVOYER_PASS, le champ mess est affecté à "\n" ou à "PASS pass\n", respectivement, en remplaçant user ou pass par leur valeur; si etat est ENVOYER_STAT ou ENVOYER_QUIT, le champ mess est affecté à "STAT\n" ou "QUIT\n", respectivement; pour toutes les autres valeurs de etat, le champ mess est affecté à la chaîne vide. Par la suite, tous les changements d état seront faits en appelant cette fonction. Réseau et Communication, UE SIN5U3, Edouard Thiel CC BY-NC http://pageperso.lif.univ-mrs.fr/~edouard.thiel/ens/rezo/ 1

2) Écrire la fonction int connecter_pop3 (Moniteur *mon), qui passe le champ etat à DEMARRER_CONN, puis crée une socket TCP/IP qui sera mémorisée dans le champ soc; elle affiche l adresse IPv4 du serveur POP3 mémorisée dans le champ serveur_adr (on suppose que la résolution d adresse est faite dans le main), puis s y connecte. En cas d erreur, la fonction renvoie -1; en cas de succès elle passe etat à ATTENDRE_CONN_OK, pop3_ok à 1, puis renvoie 0. 3) Écrire la fonction int envoyer_message (Moniteur *mon), dans laquelle on suppose que la socket soc est connectée au serveur POP3 et que le champ etat est dans la catégorie ENVOYER_*, ce qui signifie que le champ mess contient la chaîne à envoyer. La fonction écrit dans la socket le message mess à partir de la position pos en une seule opération. En cas d erreur elle renvoie -1, sinon elle met à jour pos, puis teste si la chaîne complète a été envoyée; si tel est le cas, etat est incrémenté. Enfin, la fonction renvoie le nombre de caractères qu elle a écrit lors de cet envoi. 4) Écrire la fonction void afficher_stats_mails (char *reponse) qui reçoit en paramètre la reponse positive du serveur pour la commande STAT. La fonction en extrait le nombre de mails et leur taille totale en octets, puis les affiche dans une phrase dans la sortie standard si l extraction a réussi, sinon affiche un message d erreur de format dans la sortie d erreur. 5) Écrire la fonction int lire_et_traiter_reponse (Moniteur *mon), dans laquelle on suppose que la socket soc est connectée au serveur POP3 et que le champ etat est dans la catégorie ATTENDRE_*_OK, ce qui signifie que le champ mess contient la réponse partiellement lue. La fonction lit dans la socket la (suite de la) réponse et la stocke dans mess à partir de la position d insertion pos, en une seule opération. En cas d erreur ou de fin de fichier elle renvoie -1 ou 0, sinon elle met à jour pos. Elle teste ensuite si mess contient le marqueur de fin "\n", sinon renvoie le nombre de caractères lus au début de la fonction. Le début de mess est ensuite testé : s il n est pas "", alors on affiche un message d erreur présentant ce message, on passe etat à ENVOYER_QUIT et on met pop3_ok à 0; sinon (en cas de réponse positive donc), d une part si etat est ATTENDRE_STAT_OK on appelle afficher_stats_mails, puis dans tous les cas on incrémente l état. Finalement on renvoie le nombre de caractères lus au début de la fonction. 6) On suppose disposer des macros etat_est_envoyer(x) qui s évalue à vrai si x vaut ENVOYER_USER, ENVOYER_PASS, ENVOYER_STAT ou ENVOYER_QUIT, et etat_est_attendre(x) qui s évalue à vrai si x vaut ATTENDRE_CONN_OK, ATTENDRE_USER_OK, ATTENDRE_PASS_OK, ATTENDRE_STAT_OK ou ATTENDRE_QUIT_OK. Écrire la fonction int dialoguer_en_pop3 (Moniteur *mon) dans laquelle on suppose que la socket soc est connectée au serveur POP3. La fonction fait une boucle infinie interruptible par SIGINT. À chaque itération, la fonction scrute la socket soc en lecture ou en écriture selon etat, avec un timeout de 10 secondes. En cas d erreur la fonction renvoie -1; si le délai est dépassé, la fonction affiche un message et renvoie 0. Si la socket est éligible, selon etat on appelle envoyer_message ou lire_et_traiter_reponse; si la fonction appelée renvoie une valeur 0 on renvoie cette valeur. À la fin de la boucle de scrutation on renvoie 0 si etat est TERMINER_CONN. 7) Écrire le programme principal dont l usage est : monipop3 host port user pass delai où host est l adresse du serveur et port le port du service POP3, user et pass identifient l utilisateur, et delai est le délai en secondes au bout duquel on se reconnecte au serveur pour redemander les statistiques. Le programme décode les arguments, les stocke dans une variable mon de type Moniteur, met en place les handlers de signaux habituels; ensuite le programme résout l adresse du serveur et la stocke ainsi que son port dans le champ adr_serveur de mon. Le programme entre ensuite dans une boucle infinie interruptible par SIGINT, dans laquelle il se connecte au serveur POP3, effectue un dialogue POP3 dans le but d afficher les statistiques, ferme la socket; s il n y a pas eu d erreur, en particulier dans le dialogue POP3, la boucle itère au bout du delai en secondes, sinon le programme se termine immédiatement. Réseau et Communication, UE SIN5U3, Edouard Thiel CC BY-NC http://pageperso.lif.univ-mrs.fr/~edouard.thiel/ens/rezo/ 2

Correction Vous pouvez appeler sans les recopier les fonctions de la boîte à outil réseau vues en TD. I. Moniteur POP3 de emails en C On se propose de réaliser un programme C monipop3.c qui affiche régulièrement le nombre de messages et leur taille totale présents dans un compte email via le protocole POP3. On rappelle que POP3 est un protocole ASCII 7 bits sur TCP/IP à base de question/réponses. Voici un exemple de session réalisé avec netcat (ici on se trompe volontairement de mot de passe pour montrer l effet); le résultat est qu il ya3messages pouruntotal de 9251 octets. $ netcat serveur 110 PASS mauvais mdp STAT QUIT $ POP3 ready -ERR Invalid login or pw -ERR Invalid command Mailbox ready 3 9251 On se donne le type Etat pour coder l état correspondant aux différentes phases du dialogue : typedef enum DEMARRER_CONN, ATTENDRE_CONN_OK, ENVOYER_USER, ATTENDRE_USER_OK, ENVOYER_PASS, ATTENDRE_PASS_OK, ENVOYER_STAT, ATTENDRE_STAT_OK, ENVOYER_QUIT, ATTENDRE_QUIT_OK, TERMINER_CONN Etat; On définit le type Moniteur pour mémoriser tous les paramètres de notre programme : Les champs user et pass servent à l identification; mess contient le message en émission ou en réception (selon etat), pos est la position d émission ou d insertion dans mess; delai est le délai en secondes au bout duquel on réinterroge le serveur POP3; pop3_ok est vrai si le dialogue en POP3 s est déroulé sans erreur (c est-à-dire si aucun message commançant par "-ERR" n a été reçu). #define MESS_SIZE 1024 typedef struct int soc; char *serveur_nom; struct sockaddr_in client_adr, serveur_adr; int serveur_port; char *user, *pass; Etat etat; char mess[mess_size]; int pos, delai, pop3_ok; Moniteur; 1) Écrire la fonction void changer_etat (Moniteur *mon, Etat etat) qui reçoit en paramètre un nouvel etat. La fonction le mémorise dans mon, puis initialise le champ pos à 0 (signifiant que dans ce nouvel etat, aucun octet n a encore été envoyé ou reçu). Si etat est ENVOYER_USER ou ENVOYER_PASS, le champ mess est affecté à "\n" ou à "PASS pass\n", respectivement, en remplaçant user ou pass par leur valeur; si etat est ENVOYER_STAT ou ENVOYER_QUIT, le champ mess est affecté à "STAT\n" ou "QUIT\n", respectivement; pour toutes les autres valeurs de etat, le champ mess est affecté à la chaîne vide. Par la suite, tous les changements d état seront faits en appelant cette fonction. Réseau et Communication, UE SIN5U3, Edouard Thiel CC BY-NC http://pageperso.lif.univ-mrs.fr/~edouard.thiel/ens/rezo/ 3

void changer_etat (Moniteur *mon, Etat etat) mon->etat = etat; mon->pos = 0; switch (etat) case ENVOYER_USER : sprintf (mon->mess, "USER %s\n", mon->user); break; case ENVOYER_PASS : sprintf (mon->mess, "PASS %s\n", mon->pass); break; case ENVOYER_STAT : sprintf (mon->mess, "STAT\n"); break; case ENVOYER_QUIT : sprintf (mon->mess, "QUIT\n"); break; default : mon->mess[0] = \0 ; 2) Écrire la fonction int connecter_pop3 (Moniteur *mon), qui passe le champ etat à DEMARRER_CONN, puis crée une socket TCP/IP qui sera mémorisée dans le champ soc; elle affiche l adresse IPv4 du serveur POP3 mémorisée dans le champ serveur_adr (on suppose que la résolution d adresse est faite dans le main), puis s y connecte. En cas d erreur, la fonction renvoie -1; en cas de succès elle passe etat à ATTENDRE_CONN_OK, pop3_ok à 1, puis renvoie 0. int connecter_pop3 (Moniteur *mon) changer_etat (mon, DEMARRER_CONN); mon->soc = bor_create_socket_in (SOCK_STREAM, 0, &mon->client_adr); if (mon->soc < 0) return -1; printf ("Connexion avec %s...\n", bor_adrtoa_in (&mon->serveur_adr)); if (bor_connect_in (mon->soc, &mon->serveur_adr) < 0) close (mon->soc); return -1; changer_etat (mon, ATTENDRE_CONN_OK); mon->pop3_ok = 1; return 0; 3) Écrire la fonction int envoyer_message (Moniteur *mon), dans laquelle on suppose que la socket soc est connectée au serveur POP3 et que le champ etat est dans la catégorie ENVOYER_*, ce qui signifie que le champ mess contient la chaîne à envoyer. La fonction écrit dans la socket le message mess à partir de la position pos en une seule opération. En cas d erreur elle renvoie -1, sinon elle met à jour pos, puis teste si la chaîne complète a été envoyée; si tel est le cas, etat est incrémenté. Enfin, la fonction renvoie le nombre de caractères qu elle a écrit lors de cet envoi. int envoyer_message (Moniteur *mon) //printf ("envoyer_message %s \n", mon->mess+mon->pos); int k = bor_write_str (mon->soc, mon->mess+mon->pos); mon->pos += k; // Tout a été envoyé? if (mon->pos >= (int)strlen(mon->mess)) changer_etat (mon, mon->etat+1); return k; Réseau et Communication, UE SIN5U3, Edouard Thiel CC BY-NC http://pageperso.lif.univ-mrs.fr/~edouard.thiel/ens/rezo/ 4

4) Écrire la fonction void afficher_stats_mails (char *reponse) qui reçoit en paramètre la reponse positive du serveur pour la commande STAT. La fonction en extrait le nombre de mails et leur taille totale en octets, puis les affiche dans une phrase dans la sortie standard si l extraction a réussi, sinon affiche un message d erreur de format dans la sortie d erreur. void afficher_stats_mails (char *reponse) int nb_mails, taille_mails; if (sscanf (reponse, " %d %d", &nb_mails, &taille_mails)!= 2) fprintf (stderr, "Erreur de format dans la réponse : \"%s\"\n", reponse); else printf ("STATS: il y a %d mails pour un total de %d octets \n", nb_mails, taille_mails); 5) Écrire la fonction int lire_et_traiter_reponse (Moniteur *mon), dans laquelle on suppose que la socket soc est connectée au serveur POP3 et que le champ etat est dans la catégorie ATTENDRE_*_OK, ce qui signifie que le champ mess contient la réponse partiellement lue. La fonction lit dans la socket la (suite de la) réponse et la stocke dans mess à partir de la position d insertion pos, en une seule opération. En cas d erreur ou de fin de fichier elle renvoie -1 ou 0, sinon elle met à jour pos. Elle teste ensuite si mess contient le marqueur de fin "\n", sinon renvoie le nombre de caractères lus au début de la fonction. Le début de mess est ensuite testé : s il n est pas "", alors on affiche un message d erreur présentant ce message, on passe etat à ENVOYER_QUIT et on met pop3_ok à 0; sinon (en cas de réponse positive donc), d une part si etat est ATTENDRE_STAT_OK on appelle afficher_stats_mails, puis dans tous les cas on incrémente l état. Finalement on renvoie le nombre de caractères lus au début de la fonction. int lire_et_traiter_reponse (Moniteur *mon) //printf ("lire_reponse...\n"); int k = bor_read_str (mon->soc, mon->mess+mon->pos, MESS_SIZE-mon->pos); mon->pos += k; //printf ("message lu %s \n", mon->mess); // Marqueur de fin reçu? if (!strstr(mon->mess, "\n")) return k; if (strncmp (mon->mess, "", 3)!= 0) fprintf (stderr, "POP3: %s", mon->mess+1); changer_etat (mon, ENVOYER_QUIT); mon->pop3_ok = 0; else if (mon->etat == ATTENDRE_STAT_OK) afficher_stats_mails (mon->mess); changer_etat (mon, mon->etat+1); return k; 6) On suppose disposer des macros etat_est_envoyer(x) qui s évalue à vrai si x vaut ENVOYER_USER, ENVOYER_PASS, ENVOYER_STAT ou ENVOYER_QUIT, et etat_est_attendre(x) qui s évalue à vrai si x vaut ATTENDRE_CONN_OK, ATTENDRE_USER_OK, ATTENDRE_PASS_OK, ATTENDRE_STAT_OK ou ATTENDRE_QUIT_OK. Réseau et Communication, UE SIN5U3, Edouard Thiel CC BY-NC http://pageperso.lif.univ-mrs.fr/~edouard.thiel/ens/rezo/ 5

Écrire la fonction int dialoguer_en_pop3 (Moniteur *mon) dans laquelle on suppose que la socket soc est connectée au serveur POP3. La fonction fait une boucle infinie interruptible par SIGINT. À chaque itération, la fonction scrute la socket soc en lecture ou en écriture selon etat, avec un timeout de 10 secondes. En cas d erreur la fonction renvoie -1; si le délai est dépassé, la fonction affiche un message et renvoie 0. Si la socket est éligible, selon etat on appelle envoyer_message ou lire_et_traiter_reponse; si la fonction appelée renvoie une valeur 0 on renvoie cette valeur. À la fin de la boucle de scrutation on renvoie 0 si etat est TERMINER_CONN. int dialoguer_en_pop3 (Moniteur *mon) while (boucle_princ) // voir question 7 fd_set set_in, set_out; FD_ZERO (&set_in); FD_ZERO (&set_out); if (etat_est_envoyer(mon->etat)) FD_SET (mon->soc, &set_out); if (etat_est_attendre(mon->etat)) FD_SET (mon->soc, &set_in); struct timeval t; t.tv_sec = 10; t.tv_usec = 0; int res = select (mon->soc+1, &set_in, &set_out, NULL, &t); if (res < 0) if (errno == EINTR) continue; perror ("select"); return -1; if (res == 0) fprintf (stderr, "Délai dépassé\n"); return -1; if (etat_est_envoyer(mon->etat) && FD_ISSET (mon->soc, &set_out)) int k = envoyer_message (mon); else if (etat_est_attendre(mon->etat) && FD_ISSET (mon->soc, &set_in)) int k = lire_et_traiter_reponse (mon); if (mon->etat == TERMINER_CONN) return 0; return -1; 7) Écrire le programme principal dont l usage est : monipop3 host port user pass delai où host est l adresse du serveur et port le port du service POP3, user et pass identifient l utilisateur, et delai est le délai en secondes au bout duquel on se reconnecte au serveur pour redemander les statistiques. Le programme décode les arguments, les stocke dans une variable mon de type Moniteur, met en place les handlers de signaux habituels; ensuite le programme résout l adresse du serveur et la stocke ainsi que son port dans le champ adr_serveur de mon. Le programme entre ensuite dans une boucle infinie interruptible par SIGINT, dans laquelle il se connecte au serveur POP3, effectue un dialogue POP3 dans le but d afficher les statistiques, ferme la socket; s il n y a pas eu d erreur, en particulier dans le dialogue POP3, la boucle itère au bout du delai en secondes, sinon le programme se termine immédiatement. Réseau et Communication, UE SIN5U3, Edouard Thiel CC BY-NC http://pageperso.lif.univ-mrs.fr/~edouard.thiel/ens/rezo/ 6

#include "bor-util.h" int boucle_princ = 1; void capter_fin () boucle_princ = 0; int main (int argc, char *argv[]) Moniteur mon; if (argc-1!= 5) fprintf (stderr, "USAGE: %s host port user pass delai\n", argv[0]); exit (1); mon.serveur_nom = argv[1]; mon.serveur_port = atoi(argv[2]); mon.user = argv[3]; mon.pass = argv[4]; mon.delai = atoi(argv[5]); bor_signal (SIGPIPE, SIG_IGN, SA_RESTART); bor_signal (SIGINT, capter_fin, 0); printf ("Résolution adresse...\n"); if (bor_resolve_address_in (mon.serveur_nom, mon.serveur_port, &mon.serveur_adr) < 0) exit (1); while (boucle_princ) if (connecter_pop3 (&mon) < 0) exit (1); int k = dialoguer_en_pop3 (&mon); close (mon.soc); if (k < 0!mon.pop3_ok) exit (1); sleep (mon.delai); exit (0); Réseau et Communication, UE SIN5U3, Edouard Thiel CC BY-NC http://pageperso.lif.univ-mrs.fr/~edouard.thiel/ens/rezo/ 7