Les protocoles de messagerie : SMTP, POP et IMAP

POP :: Codes sources

Il est possible de télécharger le fichier source en C ici, celui en Java ici et l'archive contenant les deux fichiers ici.

En C

#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PACKET_SIZE 1024

int writen(int fd, char* ptr, int n);
int readn(int fd, char* ptr, int n);
int test_OK(char* buf, int do_exit);	/*test attente du +OK du server*/

char* server_name = "pop.free.fr";
unsigned short server_port = 110;

char* user = "gtre.diam";
char* pass = "password";

int to_server_socket = -1;

int main(int argc, char* argv[])
{
	struct sockaddr_in serverSockAddr;	/*adresse de la socket*/
	struct hostent* serverHostEnt;		/*description du host server*/
	unsigned long hostAddr;				/*adresse du server*/
	unsigned char bufw[PACKET_SIZE+1];
	unsigned char bufr[PACKET_SIZE+1];
	unsigned char list[PACKET_SIZE+1];
	int n, msg, index, retry = 4;
	
	bzero(&serverSockAddr, sizeof(serverSockAddr));
	hostAddr = inet_addr(server_name);

	if( (long)hostAddr!=(long)-1)
		bcopy(&hostAddr,&serverSockAddr.sin_addr,sizeof(hostAddr));
	else	/*si on donne un nom*/
	{
			serverHostEnt = gethostbyname(server_name);
			bcopy((void*)serverHostEnt->h_addr,&serverSockAddr.sin_addr, serverHostEnt->h_length);
	}

	serverSockAddr.sin_port = htons(server_port);
	serverSockAddr.sin_family = AF_INET;	/* AF_*** : INET=internet */
	/*creation de la socket */
	to_server_socket = socket(AF_INET, SOCK_STREAM, 0);
	/* requete de la connexion */
	connect(to_server_socket,(struct sockaddr *)&serverSockAddr, sizeof(serverSockAddr));

	bzero(bufw, PACKET_SIZE+1);	
	bzero(bufr, PACKET_SIZE+1);

	do {	/*attente ouverture connexion par le serveur */
		n = readn(to_server_socket, bufr, PACKET_SIZE);
		retry--;
	}while(test_OK(bufr,retry==0));

	/* authentification */
	sprintf(bufw, "USER %s\r\n", user);
	writen(to_server_socket, bufw, strlen(bufw));
	n = readn(to_server_socket, bufr, PACKET_SIZE);
	test_OK(bufr,1);

	sprintf(bufw, "PASS %s\r\n", pass);
	writen(to_server_socket, bufw, strlen(bufw));
	n = readn(to_server_socket, bufr, PACKET_SIZE);
	test_OK(bufr,1);


	/* liste des messages dans la boite aux lettres */
	sprintf(bufw, "LIST\r\n");
	writen(to_server_socket, bufw, strlen(bufw));
	n = readn(to_server_socket, bufr, PACKET_SIZE);
	test_OK(bufr,1);
	if( strlen(bufr)==0 )
		n=readn(to_server_socket, list, PACKET_SIZE);
	else
		bcopy(bufr, list, strlen(bufr)+1);
		
	/* récupération de tous les messages */
	index = 0;
	while( list[index]!='.') {
		sscanf(&list[index], "%d",&msg);
		while( list[index++]!='\n');
		
		/* récupération du message msg */
		sprintf(bufw, "RETR %d\r\n", msg);
		writen(to_server_socket, bufw, strlen(bufw));
		do {
			n=readn(to_server_socket, bufr, PACKET_SIZE);
			printf("%s",bufr);
			if(!strncmp("\r\n.\r\n",&bufr[n-5], 5)) break;
			bzero(bufr, PACKET_SIZE+1);
		}while(1);
	}	
	
	/*fermeture de la connexion */
	shutdown(to_server_socket,2);
	close(to_server_socket);
	return 0;
}


/*fonction qui affiche le message*/
int writen(int fd, char* ptr, int n)
{
	int nl, nw;
	nl=n;
	while(nl>0)
	{
		nw=write(fd,ptr,nl);
		if(nw<=0) return nw;	/*erreur*/
		nl-=nw;
		ptr+=nw;
	}
	return (n-nl);
}


/*fonction qui lit le message*/
int readn(int fd, char* ptr, int n)
{
	int nl, nr;
	nl = n;
	while( nl>0)
	{
		nr = read(fd, ptr, nl);
		if(nr<0) return nr;	/*erreur*/
		else if(nr==0) break;
		nl-=nr;
		ptr+=nr;
		if( *(ptr-2)=='\r' && *(ptr-1)=='\n')
			break;
	}
	*ptr = 0x00;
	return (n-nl);
}


/*fonction qui test la valeur de retour du serveur*/
int test_OK(char* buf, int do_exit)
{
	char* ptr, tmp[PACKET_SIZE+1];
	
	bzero(tmp, PACKET_SIZE+1);
	if( (ptr=strstr(buf, "+OK")) == NULL) {
		if( strstr(buf, "-ERR")) {
			printf("ERROR:  %s\n", buf);
			exit(1);
		}
		if(do_exit) exit(1);
		else return 1;
	} else {
		while(*ptr != '\n') ptr++;
		bcopy(ptr+1, tmp, strlen(ptr));
		bzero(buf, PACKET_SIZE+1);
		bcopy(tmp, buf, strlen(tmp));
	}
	return 0;	
}



en Java


/*
 * Created on 2 nov. 2004
 *
 */
package pop;

import java.io.*;
import java.net.*;
import java.util.*;

/**
 * @author Adrien BOUVET
 * 
 */
public class Pop
{
	String server;
	String user;
	String pass;
	
	Pop(String zserver, String zuser, String zpass)
	{
		server = zserver;
		user = zuser;
		pass = zpass;
	}
	
	void lit()
	{
		PrintWriter to;
		BufferedReader from;
		String str, title, msg;
		Vector v = new Vector();
		
		try{
			Socket socket = new Socket(InetAddress.getByName(server), 110);
			
			to = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
			from = new BufferedReader( new InputStreamReader(socket.getInputStream()));
		
			while( !(from.readLine()).startsWith("+OK"));
			to.println("USER "+user);
			while( !(from.readLine()).startsWith("+OK"));
			to.println("PASS "+pass);
			while( !(from.readLine()).startsWith("+OK"));
			to.println("LIST");
			while( !(from.readLine()).startsWith("+OK"));
			
			do{
				str = from.readLine();
				if( str.compareTo(".")!=0) v.add(str);	//v contient le résultat de la commande LIST (= nbre msgs)
			}while( str.compareTo(".")!=0);
			
			for(int i=0; i<v.size(); i++) {
				title = (String)v.elementAt(i);
				to.println("RETR " +(new StringTokenizer(title)).nextToken()+"\r");
				while( !(from.readLine()).startsWith("+OK") );
				msg = "";
				do {
					msg += from.readLine() + "\n";
				}while( !msg.endsWith("\n.\n") );
				System.out.println(msg);				
			}
			
			socket.close();						
		}catch(Exception e){ System.err.println(e);}
	}
	
	
	
	public static void main(String[] args)
	{
		Pop p = new Pop("212.27.42.14", "login", "password"); //IP de pop.free.fr
		p.lit();
	}
}