programme pour recupérer des mails

programme pour recupérer des mails - C - Programmation

Marsh Posté le 05-06-2007 à 18:52:13    

Bonjour, je voulais faire un programme qui me permettrais de récupérer tous mes mails et de les stocker dans un dossier.
Le problème c'est qu'il plante avec "certain mail" sans que je puisse savoir pourquoi...
exemple :
j'ai 100 mails dans ma boites il récupère puis plante au 10eme.
je recommence cette fois en commencer par le 20eme et je peux récupérer tous le reste.
si je supprime le mail qui me plante je récupère tous sans problème...
 
procédé :
- je récupère la liste pour avoir le nombre de mails
- je fais une boucle pour récupérer les mails et les stocks dans des fichiers séparer
 
NB: il ouvre un fichier connection.txt ou il y a les infos d'un compte mail d'un server (sans SSL ou autre) :
smtp.fournisseur.com
compte
pass
port
 
donc j'aimerais savoir si le problème vous arrive aussi, et si vous avez des conseils. =)
 
http://dl.free.fr/pqTkKEKO/main.txt

Code :
  1. #ifdef WIN32
  2. #include <winsock2.h>
  3. #pragma comment(lib, "ws2_32.lib" )
  4. #elif defined (linux)
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <unistd.h> /* close */
  10. #include <netdb.h> /* gethostbyname */
  11. #define INVALID_SOCKET -1
  12. #define SOCKET_ERROR -1
  13. #define closesocket(s) close(s)
  14. typedef int SOCKET;
  15. typedef struct sockaddr_in SOCKADDR_IN;
  16. typedef struct sockaddr SOCKADDR;
  17. typedef struct in_addr IN_ADDR;
  18. #else
  19. #error not defined for this platform
  20. #endif
  21. #define USER        "USER"
  22. #define PASS  "PASS"
  23. #define PASSWORD "2t2k9q"
  24. #define LIST  "LIST"
  25. #define RETR        "RETR"
  26. #define END_DATA    "."
  27. #define QUIT        "QUIT"
  28. #define PORT        110
  29. #define BUF_SIZE    1024
  30. #define RECV_SIZE   32768
  31. #define CRLF        "\r\n"
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. int _server_response(SOCKET sock, char *buffer);
  35. int send_server(SOCKET sock, char *command);
  36. int _pop_retrieve_list();
  37. int main()
  38. {
  39. int a=0;
  40. a = _pop_retrieve_list();
  41. if(a==0)
  42.  printf("failed\n" );
  43. else
  44.  printf("succeeded\n" );
  45. }
  46. int _server_response(SOCKET sock, char *buffer)
  47. {
  48. if(recv(sock, buffer, BUF_SIZE, 0) < 0)
  49. {
  50.         perror("recv()" );
  51.  return 0;
  52.     }
  53.  strtok(buffer, " \r\n" );
  54. if (strcmp(buffer,"+OK" ) != 0)
  55. {
  56.  printf("Connexion failed\n" );
  57.  return 0;
  58. }
  59. return 1;
  60. }
  61. int send_server(SOCKET sock, char *command)
  62. {
  63.     if(send(sock, command, strlen(command), 0) < 0)
  64. {
  65.  perror("send()" );
  66.  return 0;
  67. }
  68. return 1;
  69. }
  70. int _pop_retrieve_list()
  71. {
  72. SOCKET sock;
  73. SOCKADDR_IN sin;
  74.     FILE *fichier = NULL;
  75. struct hostent *hostinfo;
  76. char command[BUF_SIZE];
  77. char hostname[128];
  78. char account[128];
  79. char pass[128];
  80. char port[5];
  81. long port_long;
  82. char list[RECV_SIZE];
  83. char text[128];
  84. char text_dump[128];
  85. char* buffer = (char*)malloc(BUF_SIZE);
  86. char* temp = (char*)malloc(BUF_SIZE);
  87. int check = 0;
  88. int nombre_mail=0;
  89. int i;
  90. #ifdef WIN32
  91.  WSADATA wsa;
  92.  int err = WSAStartup(MAKEWORD(2, 2), &wsa);
  93.  if(err < 0)
  94.  {
  95.   printf("WSAStartup failed !\n" );
  96.   return 0;
  97.  }
  98. #endif
  99. sock = socket(AF_INET, SOCK_STREAM, 0);
  100.     if (sock == INVALID_SOCKET)
  101.     {
  102.         perror("socket()" );
  103.  return 0;
  104.     }
  105. fichier = fopen("connection.txt", "r" );
  106. if (fichier == NULL)
  107. {
  108.  perror("fopen()" );
  109.  return 0;
  110. }
  111. fgets(hostname, 128, fichier);
  112. fgets(account, 128, fichier);
  113. fgets(pass, 128, fichier);
  114. fgets(port, 128, fichier);
  115. fclose(fichier);
  116. strtok(hostname, "\n" );
  117. strtok(account, "\n" );
  118. strtok(pass, "\n" );
  119. strtok(port, "\n" );
  120. port_long = strtol(port, NULL, NULL);
  121. hostinfo = gethostbyname(hostname);
  122.     if (hostinfo == NULL)
  123.     {
  124.         printf(stderr, "Unknown host %s.\n", BUF_SIZE);
  125.  return 0;
  126.     }
  127. sin.sin_addr = *(IN_ADDR *) hostinfo->h_addr;
  128.     sin.sin_port = htons(port_long);
  129.     sin.sin_family = PF_INET;
  130. if(connect(sock,(SOCKADDR *) &sin, sizeof(SOCKADDR)) == SOCKET_ERROR)
  131.     {
  132.         perror("connect()" );
  133.  return 0;
  134.     }
  135. //to check the reception
  136. check = _server_response(sock, buffer);
  137.  if(check == 0)
  138.   return 0;
  139. // send user account
  140. sprintf(command, "USER %s%s", account, CRLF);
  141. check = send_server(sock, command);
  142.  if(check == 0)
  143.   return 0;
  144. check = _server_response(sock, buffer);
  145.  if(check == 0)
  146.   return 0;
  147. // send user pass
  148. sprintf(command, "PASS %s%s", pass, CRLF);
  149. check = send_server(sock, command);
  150.  if(check == 0)
  151.   return 0;
  152. check = _server_response(sock, buffer);
  153.  if(check == 0)
  154.   return 0;
  155. // send LIST command
  156. sprintf(command, "LIST%s",  CRLF);
  157. check = send_server(sock, command);
  158.  if(check == 0)
  159.   return 0;
  160. // retrieve LIST response
  161. sprintf(text, "%s@%s/list.txt", account, hostname);
  162. fichier = fopen(text, "w+" );
  163. if(fichier==NULL)// to create a new list file in a folder account@provider
  164. {
  165.  sprintf(text, "mkdir %s@%s", account, hostname);
  166.  system(text);
  167.  sprintf(text, "%s@%s/list.txt", account, hostname);
  168.  fichier = fopen(text, "w+" );
  169. }
  170. fclose(fichier);
  171. fichier = fopen(text, "a" );
  172. do
  173. {
  174.  memset (list,0,RECV_SIZE);
  175.  if(recv(sock, list, RECV_SIZE, 0) < 0)
  176.  {
  177.   perror("recv()" );
  178.   return 0;
  179.  }
  180.   fprintf(fichier, list);
  181. }while(strstr(list, "\r\n.\r\n" )==0);
  182. fclose(fichier);
  183. // retrive the number of mail from the mail list
  184. fichier = fopen(text, "r" );
  185. if(fichier == NULL)
  186. {
  187.  printf("error" );
  188. }
  189. else
  190. {
  191.  fgets(text_dump, 128, fichier);
  192.  do
  193.  {
  194.   nombre_mail++;
  195.  }while(fgets(text_dump, 128, fichier)!=NULL);
  196.  fclose(fichier);
  197.  nombre_mail = nombre_mail-1;
  198. }
  199. for( i=1 ; i<nombre_mail ; i++)
  200. {
  201.  // send RETR command
  202.  sprintf(command, "RETR %ld%s", i, CRLF);
  203.  check = send_server(sock, command);
  204.   if(check == 0)
  205.    return 0;
  206.  // retrieve RETR response
  207.  sprintf(text, "%s@%s/mail %3ld.txt", account, hostname, i);
  208.  fichier = fopen(text, "w+" );
  209.  fclose(fichier);
  210.  fichier = fopen(text, "a" );
  211.  strcpy(list, "" );
  212.  printf(list);
  213.  do
  214.  {
  215.     memset (list,0,16384);
  216.   if(recv(sock, list, 16384, 0) < 0)
  217.   {
  218.    perror("recv()" );
  219.    return 0;
  220.   }
  221.    fprintf(fichier, list);
  222.  }while(strstr(list, "\r\n.\r\n" )==0);
  223.   fclose(fichier);
  224.   printf("%ld/%ld\n", i, nombre_mail-1);
  225. }
  226. return 1;
  227. }


Reply

Marsh Posté le 05-06-2007 à 18:52:13   

Reply

Marsh Posté le 05-06-2007 à 22:53:17    

bon âpres moult tentative je comprend toujours pas pourquoi ca plante, mais apparemment c'est fprintf qui fait planté...
je l'ai remplacé par fputs et ça à l'air de mieux fonctionner.
faudrait qu'on m'explique pourquoi quand même, parce que je ne vois vraiment pas pourquoi =/
ensuite je pourrais remettre un code un peu plus propre si jamais ca interesse...

Reply

Marsh Posté le 06-06-2007 à 09:00:16    

Ancien code :

Code :
  1. fprintf(fichier, list);


Ce code a un problème.
fprintf() a besoin (comme printf, sprintf etc...) d'au moins 3 paramètres. Le plantage aléatoire vient du fait que si "list" contient
la chaîne "%s" par exemple, alors le programme (fonction frprintf()) va chercher le pointeur associé sur la pile, ce qui donne vraisemblablement un pointeur invalide d'où plantage.
 
Il faut donc que tu précises explicitement le deuxième paramètre "%s", comme cela ton fprintf() maintenant est solide et ne plantera plus aléatoirement selon les données reçues.
 
Nouveau code :

Code :
  1. fprintf(fichier, "%s", list);

Reply

Marsh Posté le 06-06-2007 à 11:59:03    

oki c'etait bien ca merci =)

Reply

Marsh Posté le 06-06-2007 à 12:39:27    

ha oui un autre probleme lorsqu'il recupere des mails, il arrive parfois que ca reste figée...
vous avez une idée de comment évitez cela ?

Reply

Marsh Posté le 06-06-2007 à 16:06:39    

minokitaro a écrit :

ha oui un autre probleme lorsqu'il recupere des mails, il arrive parfois que ca reste figée...
vous avez une idée de comment évitez cela ?


 
Ton problème vient de ceci:

Code :
  1. while(strstr(list, "\r\n.\r\n" )


 
Selon le buffering et la réception (problème aléatoire), tu peux recevoir cette séquence de fin en plusieurs paquets
comme "xxx\r\n." suivi de "\r\n", ou "xxx\r\n" suivi de ".\r\n" etc.. ou autres combinaisons (xxx= exemples de caractères de longueur variable de fin de l'email reçu).
Ce qui fait que pour le serveur il a tout envoyé et tu as tout reçu mais tu n'as pas détecté la condition de fin pour finir
le protocole POP3.
 
A mieux détecter toutes les conditions de fin possible, ou voir des exemples de codes existants (chercher Google pour code source de client POP3).


Message édité par dnlilas le 06-06-2007 à 18:03:52
Reply

Marsh Posté le 06-06-2007 à 17:39:28    

oki

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed