format.c

Go to the documentation of this file.
00001 /* this is format.c file.
00002  * this is part of the libspopc library sources
00003  * copyright © 2002 Benoit Rouits <brouits@free.fr>
00004  * released under the terms of GNU LGPL
00005  * (GNU Lesser General Public Licence).
00006  * libspopc offers simple API for a pop3 client (MTA).
00007  * See RFC 1725 for pop3 specifications.
00008  * more information on http://brouits.free.fr/libspopc/
00009  */
00010 
00011 #include <stdlib.h>
00012 #include <stdio.h>
00013 #include <string.h>
00014 #include "libspopc.h"
00015 
00016 /************************************************************
00017  * libspopc functions to format pop data returned by server *
00018  ************************************************************/
00019 
00020 char* nextline(char* string){
00021 /* returns a pointer to the next line of given string */
00022 
00023         while(((*string) != '\n')&&((*string) != '\0')){
00024                 string++;
00025         }
00026         if(!(*string)){
00027                 return (NULL);
00028         }
00029         return(string+1);
00030 }
00031 
00032 char* retr2msg(char* data){
00033 /* retruns formatted mail from a pop RETR X query */
00034 /* should only be called on data returned by pop3_retr() */
00035 char* msg=NULL;
00036 char* cur;
00037 
00038 #ifdef EBUG
00039         fprintf(stderr,"<retr2msg>\n");
00040 #endif
00041         if((!data)||pop3_error(data)){
00042                 return(NULL);/* any suggestions ? */
00043         }
00044         data=nextline(data); /* skip +OK ... */
00045         msg=(char*)malloc(strlen(data));
00046         if(!msg){
00047 #ifdef EBUG
00048                 perror("retr2msg.malloc");
00049 #endif
00050                 return(NULL);
00051         }
00052         cur=msg;
00053         while(*data){
00054                 if(DOTBEGIN(data)){
00055                         (*cur)=(*data);/* keep \n */
00056                         data+=2;/* skip first dot */
00057                         cur++;
00058                 }else{
00059                         (*cur)=(*data);
00060                         cur++;data++;
00061                 }
00062         }
00063         (*(cur-2))='\0'; /* erase \r\n */
00064 #ifdef EBUG
00065         fprintf(stderr,"</retr2msg>\n");
00066 #endif
00067         return(msg);
00068 }
00069 
00070 void freemsg(char* msg){
00071         free(msg);
00072         msg=NULL;
00073 }
00074 
00075 int* list2array(char* poplist){
00076 /* returns an int array of sizes of messages from a LIST pop query */
00077 /* array[0] holds id of the array's element */
00078 /* should only be called on data received by a pop3_list() request */
00079 int* array=NULL;
00080 int l,s;
00081 int i=0;
00082 char* cur;
00083 
00084 #ifdef EBUG
00085         fprintf(stderr,"<list2array>\n");
00086 #endif
00087         if((!poplist)||pop3_error(poplist)){
00088                 return(NULL); /* any suggestions ? */
00089         }
00090         if(!dotline(poplist)){/* if simple element list */
00091         /* you should't use this function for simple element... */
00092         /* you should better use listi2size() */
00093                 /* skip '+OK ': look for first mail int id */
00094                 for(cur=poplist;(*cur<'0')||(*cur>'9');cur++);
00095                 /* not dot line here */
00096                 sscanf(cur,"%d %d\n",&i,&s);
00097                 array=(int*)malloc((i+1)*sizeof(int));
00098                 memset(array,0,(i+1)*sizeof(int));
00099                 array[0]=i;
00100                 array[i]=s;
00101                 return(array);
00102         }
00103         /* else this is a true list */
00104         /* skip '+OK\r\n' :*/
00105         for(cur=poplist;(*cur!='.')&&(*cur!='\n'); cur++);
00106         cur ++; /* one more time to get behind '\n' */
00107         l=1; /* array len */
00108         while((*cur)!='.'){
00109                 sscanf(cur,"%d %d\n",&i,&s);
00110                 l++;
00111                 array=(int*)realloc(array,l*sizeof(int));
00112                 array[i]=s;
00113                 cur=nextline(cur);
00114         }
00115         if(i){
00116                 array[0]=i;
00117         }else{
00118                 array=(int*)malloc(1*sizeof(int));
00119                 array[0]=0;
00120         }
00121 #ifdef EBUG
00122         fprintf(stderr,"%d message(s)\n",i);
00123         fprintf(stderr,"</list2array>\n");
00124 #endif
00125         return(array);
00126 }
00127 
00128 void freelistarray(int* array){
00129 /* free array allocated by list2array() */
00130         free(array);
00131         array=NULL;
00132 }
00133 
00134 int listi2size(char* resp){
00135 /* grep the given size (in bytes) in resp after a pop3_list(sock,ID) request */
00136 int i;
00137 int r;
00138 
00139         if(pop3_error(resp)){
00140                         return(0);/* no message ! */
00141         }
00142         r=sscanf(resp+5,"%d\n",&i);/* skip '+OK ' should be safer FIXME */
00143         if(!r){/* special case when no messages on server */
00144                 return(0);
00145         }
00146         return(i);
00147 }
00148 
00149 int stat2last(char* resp){
00150 /* returns the last id of retrievable messages */
00151 /* should only be called just after a pop3_stat() request */
00152 int n,s;
00153 
00154 #ifdef EBUG
00155         fprintf(stderr,"<stat2last>\n");
00156 #endif
00157         if((!resp)||pop3_error(resp)){
00158                 return(-1);
00159         }
00160         sscanf(resp+4,"%d %d\n",&n,&s); /* with skip '+OK ', safer?  FIXME */
00161 #ifdef EBUG
00162         fprintf(stderr,"last is %d\n",n);
00163         fprintf(stderr,"</stat2last>\n");
00164 #endif
00165         return(n);
00166 }
00167 
00168 int stat2bytes(char* resp){
00169 /* returns the sumsize in bytes of all stored messages on server */
00170 /* should only be called just after a pop3_stat() request */
00171 int n,s;
00172 
00173 #ifdef EBUG
00174         fprintf(stderr,"<stat2bytes>\n");
00175 #endif
00176         if((!resp)||pop3_error(resp)){
00177                 return(-1);
00178         }
00179         sscanf(resp+4,"%d %d\n",&n,&s); /* skip '+OK ', safer? FIXME */
00180 #ifdef EBUG
00181         fprintf(stderr,"%d bytes stored\n",s);
00182         fprintf(stderr,"</stat2bytes>\n");
00183 #endif
00184         return(s);
00185 }
00186 
00187 char** uidl2array(char* resp){
00188 /* returns an array of unique strings for each message id */
00189 /* array[0] gives array's last id */
00190 /* should only be called just after a pop3_uidl() request */
00191 char** array=NULL;
00192 int l,i=0; /* l is array lenth, i is id of msg */
00193 char s[512]; /* temp signature string : sig theorically <512 chars */
00194 char* cur;
00195 
00196 #ifdef EBUG
00197         fprintf(stderr,"<uidl2array>\n");
00198 #endif
00199         if((!resp)||pop3_error(resp)){
00200                 return(NULL); /* any suggestions ? */
00201         }
00202         if(!dotline(resp)){ /* simple element uidl */
00203         /* you should not use this function for simple element */
00204         /* you would better use uidli2sig() */
00205 #ifdef EBUG
00206                 fprintf(stderr,"bad way of use of uidl2array()\n");
00207 #endif
00208                 /* skip '+OK ': look for first mail int id */
00209                 for(cur=resp;(*cur<'0')||(*cur>'9');cur++);
00210                 /* no dot line here */
00211                 sscanf(cur,"%d %s\n",&i,s);
00212                 array=(char**)malloc((i+1)*sizeof(char*));
00213                 memset(array,0,(i+1)*sizeof(char*));
00214                 array[0]=(char*)malloc(512); /* up to 512 chars */
00215                 sprintf(array[0],"%d",i);
00216                 array[i]=strdup(s);
00217                 return(array);
00218         }
00219         /* else this is a true uid list */
00220         /* skip '+OK\r\n : look for first mail integer id */
00221         for(cur=resp;(*cur!='.')&&(*cur!='\n'); cur++);
00222         cur ++; /* one more time to get behind '\n' */
00223         l=1; /* array len */
00224         while((*cur)!='.'){
00225                 sscanf(cur,"%d %s\n",&i,s);
00226                 l++;
00227                 array=(char**)realloc(array,l*sizeof(char*));
00228                 array[i]=(char*)malloc(512); /* up to 512 chars */
00229                 array[i]=strncpy(array[i],s,512); 
00230                 cur=nextline(cur);
00231         }
00232         if(i){ /* i is now the last message id met in this session */
00233                 array[0]=(char*)malloc(4); /* up to 9999 msg uids FIXME */
00234                 sprintf(array[0],"%d",i);
00235                 /* contains the id of the last msg (char*) */
00236         }else{
00237                 array=(char**)malloc(1*sizeof(char*));
00238                 array[0]=(char*)malloc(2*sizeof(char)); /* 2 because of '\0' */
00239                 sprintf(array[0],"%d",0);
00240         }
00241 #ifdef EBUG
00242         fprintf(stderr,"%s signature(s)\n",array[0]);
00243         fprintf(stderr,"</uidl2array>\n");
00244 #endif
00245         return(array);
00246 }
00247 
00248 void freeuidlarray(char** array){
00249 /* free the array allocated by uidl2array() */
00250 int i,last;
00251         last= atoi(array[0]);
00252         for (i=1;i<=last;i++){
00253                 free(array[i]);
00254         }
00255         free(array[0]);
00256    free(array);
00257    array=NULL;
00258 }
00259 
00260 char* uidli2sig(char* resp){
00261 /* greps signature from server resp */
00262 /* should only be called after a pop3_uidl(sock,ID) */
00263 char* sig=NULL;
00264 
00265         if(pop3_error(resp)){
00266                 return(NULL);/* no message ! */
00267         }
00268         sig=strdup(resp+5); /* skip '+OK ID' should be safer, FIXME */
00269         if(sig[1]=='.'){/* special case when no messages on the server */
00270                 free(sig);
00271                 return(NULL);
00272         }
00273         return(sig);
00274 }
00275 
Generated on Wed Feb 29 22:50:05 2012 for CXXUtilities by  doxygen 1.6.3