Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3015 connectés 

  FORUM HardWare.fr
  Programmation
  C

  programme pour recupérer des mails

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

programme pour recupérer des mails

n°1570536
minokitaro
Posté le 05-06-2007 à 18:52:13  profilanswer
 

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. }


mood
Publicité
Posté le 05-06-2007 à 18:52:13  profilanswer
 

n°1570624
minokitaro
Posté le 05-06-2007 à 22:53:17  profilanswer
 

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...

n°1570675
dnlilas
Posté le 06-06-2007 à 09:00:16  profilanswer
 

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);

n°1570827
minokitaro
Posté le 06-06-2007 à 11:59:03  profilanswer
 

oki c'etait bien ca merci =)

n°1570860
minokitaro
Posté le 06-06-2007 à 12:39:27  profilanswer
 

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 ?

n°1571079
dnlilas
Posté le 06-06-2007 à 16:06:39  profilanswer
 

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
n°1571162
minokitaro
Posté le 06-06-2007 à 17:39:28  profilanswer
 

oki


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  programme pour recupérer des mails

 

Sujets relatifs
éxécution anormale de programme compile VC6[C#/Java] Récupérer le token d'identification AD de l'utilisateur
comment recuperer le contenu d'une valeur[C][Windows] Récupérer le PID d'un programme
Récupérer un fichier et le retransmettre par la suite.Recuperer plage de valeur pour userform
[VBA-E]souci avec un programmeExecuter une commande et recuperer la sortie standard
mozilla , recupérer le cache 
Plus de sujets relatifs à : programme pour recupérer des mails


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR