client pop3


Voici le code d'un petit ( tout petit ) client POP3, ca permet de voir comment ca marche.

Pour tester, n'oublier de modifier 'SERVEUR POP3', USERNAME et PASSWORD.


#include <arpa/telnet.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PACKET_SIZE  1024

#define DEBUG 1

void appli ( void ) ;
int writen(int fd, char *ptr, int n);
int readn(int fd, char *ptr, int n);

char *proxy_name = "Le SERVEUR POP3";
unsigned short proxy_port=110;

char *user= "USERNAME";
char *pass= "PASSWORD";

int to_server_socket = -1;


int main (int argc, char *argv[])
{
struct sockaddr_in serverSockAddr;    /* addresse de la socket */
struct hostent *serverHostEnt;        /* description du host serveur */
unsigned long hostAddr;                       /* addr du serveur */
long status;
char buffer[PACKET_SIZE+1];
int optval = 1;

  bzero(&serverSockAddr,sizeof(serverSockAddr));/*init a zero serverSockAddr*/
  hostAddr = inet_addr(proxy_name); /* converti l'adress ip 9.100.1.1 
                                       en entier long */

  if ( (long)hostAddr != (long)-1)
          bcopy(&hostAddr,&serverSockAddr.sin_addr,sizeof(hostAddr));
  else                           /* si on a donne un nom  */
  {
     serverHostEnt = gethostbyname(proxy_name);
     if (serverHostEnt == NULL)
     {
             printf("ca chie gethost\n");
             exit(0);
     }
     bcopy(serverHostEnt->h_addr,&serverSockAddr.sin_addr,
           serverHostEnt->h_length);
  }

  serverSockAddr.sin_port = htons(proxy_port); /* host to network port  */
  serverSockAddr.sin_family = AF_INET;  /* AF_*** : INET=internet */
  /* creation de la socket */

  if ( (to_server_socket = socket(AF_INET,SOCK_STREAM,0)) < 0)
  {
          printf("ca chie creation socket client\n");
          exit(0);
  }
/*
  if (setsockopt(to_server_socket,SOL_SOCKET,SO_KEEPALIVE,
      (char *)&optval,sizeof(int))                           <0)
  {
          printf("ca chie setsockopt\n");
          exit(0);
  }
*/
  /* requete de connexion */
  if(connect(to_server_socket,(struct sockaddr *)&serverSockAddr,
             sizeof(serverSockAddr))<0)
  {
          printf("ca chie demande de connection\n");
          exit(0);
  }
  appli();

  /* fermeture de la connection */
  shutdown(to_server_socket,2);
  close(to_server_socket);
  return 0;
}


int writen(int fd, char *ptr, int n)
{
char *p;
int nl, nw;
        nl = n;
        while ( nl > 0 ) {
                nw = write(fd, ptr, nl);
                if ( nw <= 0 )
                        return nw;     /*error*/
                nl -= nw;
                ptr += nw;
        }
        return (n-nl);
}

void writehex(char *buf) {
int n = strlen(buf);

  do {
    printf("0x%X ", buf[n]);
  } while (n--);
}

int readn(int fd, char *ptr, int n){
int nl, nr, retry=0;

        nl = n;
        bzero(ptr,n);
        while ( nl > 0 ) {
                nr = read(fd,ptr,nl);
                if (nr < 0 ) {
                    if (errno != EAGAIN) { printf("EAGAIN\n"); exit(1); }
                    retry++;
                    usleep(100);
                    if ( retry >= 5 ) return nr;     /*error*/
                } else {
                    if ( nr == 0 )
                           break;
                }
                nl -= nr;
                ptr += nr;
                if ( *(ptr-2) == '\r' && *(ptr-1) == '\n' )
                  break;
        }
        *ptr = 0x00;
        return (n-nl);
}


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 (DEBUG) printf("%s", buf);
        if ( strstr(buf, "-ERR") ) {
          printf("ERROR: -->%s<--\n", buf);
          exit(1);
        }
      if (do_exit ) exit(1);
      else return 1;
    } else {
      if (DEBUG) printf("-->%s<--\n",ptr);
      while(*ptr != '\n') ptr++ ;
      bcopy(ptr+1,tmp,strlen(ptr));
      bzero(buf,PACKET_SIZE+1);
      bcopy(tmp, buf, strlen(tmp));
    }
    return 0;
}

void appli ( void )
{
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(bufw, PACKET_SIZE+1);
  bzero(bufr, PACKET_SIZE+1);

  do {
    n=readn(to_server_socket,bufr,PACKET_SIZE);
    retry--;
  } while(test_OK(bufr,retry==0));

  sprintf(bufw,"USER %s\r\n",user);
  writen(to_server_socket,bufw,strlen(bufw));
  n=readn(to_server_socket,bufr,PACKET_SIZE);
  if (DEBUG) printf("USER: ");
  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);
  if (DEBUG) printf("PASS: ");
  test_OK(bufr,1);

  sprintf(bufw,"LIST\r\n");
  writen(to_server_socket,bufw,strlen(bufw));
  n=readn(to_server_socket,bufr,PACKET_SIZE);
  if (DEBUG) printf("LIST: ");
  test_OK(bufr,1);

  if (strlen(bufr) == 0 ) n=readn(to_server_socket,list,PACKET_SIZE);
  else bcopy(bufr, list, strlen(bufr) + 1) ;
  if (DEBUG) printf(list);

  index = 0;
  while ( list[index] != '.' ) {

    sscanf(&list[index], "%d", &msg);
    while(list[index++] != '\n');

    sprintf(bufw,"RETR %d\r\n",msg);
    if (DEBUG) printf("^[[34m %s^[[30m",bufw);

    writen(to_server_socket,bufw,strlen(bufw));
    n=readn(to_server_socket,bufr,PACKET_SIZE);
    test_OK(bufr,1);
    if (!DEBUG) printf("%s",bufr);

    n=strlen(bufr);
    do {
      if (strlen(bufr) == 0 ) n=readn(to_server_socket,bufr, PACKET_SIZE);
      if (!DEBUG) printf("%s",bufr);
      if ( ! strncmp("\r\n.\r\n",&bufr[n-5],5) ) break;
      bzero(bufr, PACKET_SIZE+1);
    } while ( 1 );

  }
}