#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;
}