/[libspopc]/format.c
ViewVC logotype

Annotation of /format.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 24 - (hide annotations)
Sun Apr 8 22:56:53 2012 UTC (8 years, 6 months ago) by ben
File MIME type: text/plain
File size: 7596 byte(s)
speedup dotline()

1 ben 1 /* this is format.c file, part of the libspopc library sources
2     * copyright © 2002- Benoit Rouits <brouits@free.fr>
3     * released under the terms of the GNU Lesser General Public Licence.
4     *
5     * libspopc offers simple API for a pop3 client.
6     * See RFC 1725 for pop3 specifications.
7 ben 2 * more information on http://herewe.servebeer.com/libspopc/
8 ben 1 *
9     * This library is free software; you can redistribute it and/or
10     * modify it under the terms of the GNU Lesser General Public
11     * License as published by the Free Software Foundation; either
12     * version 2.1 of the License, or (at your option) any later version.
13     *
14     * This library is distributed in the hope that it will be useful,
15     * but WITHOUT ANY WARRANTY; without even the implied warranty of
16     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17     * Lesser General Public License for more details.
18     *
19     * You should have received a copy of the GNU Lesser General Public
20     * License along with this library; if not, write to the Free Software
21     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22     */
23    
24     #include <stdlib.h>
25     #include <string.h>
26     #include <stdio.h>
27     #include "libspopc.h"
28    
29     /************************************************************
30     * libspopc functions to format pop data returned by server *
31     ************************************************************/
32    
33 ben 6 DLLIMPORT char* nextline(char* string){
34 ben 1 /* returns a pointer to the next line of given string */
35     while(((*string) != '\n')&&((*string) != '\0')){
36     string++;
37     }
38     if(!(*string)){
39     return (NULL);
40     }
41     return(string+1);
42     }
43    
44 ben 6 DLLIMPORT char* retr2msg(char* data){
45 ben 1 /* retruns formatted mail from a pop RETR X query */
46     /* should only be called on data returned by pop3_retr() */
47     char* msg=NULL;
48     char* cur;
49    
50     if((!data)||pop3_error(data)){
51     return(NULL);/* any suggestions ? */
52     }
53     while (( data != NULL ) && (strncmp("+OK", data, 3) != 0)){
54     data=nextline(data); /* skip ...\n before +OK */
55     }
56     if(( data != NULL ) && (strncmp("+OK", data, 3) == 0)) {
57     data=nextline(data); /* skip +OK ...\n */
58     }
59     msg=data?(char*)malloc(strlen(data)):NULL;
60     if(!msg){
61     return(NULL);
62     }
63     cur=msg;
64     while(*data){
65     if(DOTBEGIN(data)){
66     (*cur)=(*data); /* keep \n */
67     data+=2; /* skip first dot */
68     cur++;
69     }else{
70     (*cur)=(*data);
71     cur++;data++;
72     }
73     }
74     (*(cur-2))='\0'; /* erase \r\n */
75     return(msg);
76     }
77    
78 ben 6 DLLIMPORT void freemsg(char* msg){
79 ben 1 free(msg);
80     }
81    
82 ben 6 DLLIMPORT int* list2array(char* poplist){
83 ben 1 /* returns an int array of sizes of messages from a LIST pop query */
84     /* array[0] holds id of the array's element */
85     /* should only be called on data received by a pop3_list() request */
86     int* array=NULL;
87     int len,size;
88     int id=0;
89     char* cur;
90    
91     if((!poplist)||pop3_error(poplist)){
92     return(NULL); /* any suggestions ? */
93     }
94 ben 24 if(!dotline(poplist, -1)){/* if simple element list */
95 ben 1 /* one should't use this function for simple element... */
96     /* one should better use listi2size() */
97     /* skip '+OK ': look for first mail int id */
98     for(cur=poplist;(*cur<'0')||(*cur>'9');cur++);
99     /* not dot line here */
100     sscanf(cur,"%d %d\n",&id,&size);
101     array=(int*)malloc((id+1)*sizeof(int));
102     memset(array,0,(id+1)*sizeof(int));
103     array[0]=id;
104     array[id]=size;
105     return(array);
106     }
107     /* else this is a true list */
108     /* skip '+OK\r\n' :*/
109     for(cur=poplist;(*cur!='.')&&(*cur!='\n'); cur++);
110     cur ++; /* one more time to get behind '\n' */
111     len=1; /* array len */
112     while((*cur)!='.'){
113     sscanf(cur,"%d %d\n",&id,&size);
114     while(id > len){ /* pad array while id > len */
115     len++;
116     array=(int*)realloc(array,len*sizeof(int));
117     array[len-1]=0; /* no mail */
118     }
119     len++;
120     array=(int*)realloc(array,len*sizeof(int));
121     array[id]=size;
122     cur=nextline(cur);
123     }
124     if(id){
125     array[0]=id; /* last id */
126     }else{ /* no mail */
127     array=(int*)realloc(array, 1*sizeof(int));
128     array[0]=0;
129     }
130     return(array);
131     }
132    
133 ben 6 DLLIMPORT void freelistarray(int* array){
134 ben 1 /* free array allocated by list2array() */
135     free(array);
136     }
137    
138 ben 6 DLLIMPORT int listi2size(char* resp){
139 ben 1 /* grep the given size (in bytes) in resp after a pop3_list(sock,ID) request */
140     int i;
141     int r;
142    
143     if(pop3_error(resp)){
144     return(0); /* no message ! */
145     }
146     r=sscanf(resp+5,"%d\n",&i);/* skip '+OK ' should be safer FIXME */
147     if(!r){ /* special case when no messages on server */
148     return(0);
149     }
150     return(i);
151     }
152    
153 ben 6 DLLIMPORT int stat2num(char* resp){
154 ben 1 /* returns the num of retrievable (non-deleted) messages */
155     /* should only be called just after a pop3_stat() request */
156     int n,s,r;
157    
158     if((!resp)||pop3_error(resp)){
159     return(-1);
160     }
161     r=sscanf(resp+4,"%d %d\n",&n,&s); /* with skip '+OK ' */
162     if (r == 2)
163     return n;
164     else
165     return -1;
166     }
167    
168 ben 6 DLLIMPORT int stat2bytes(char* resp){
169 ben 1 /* returns the sumsize in bytes of all stored messages on server */
170     /* should only be called just after a pop3_stat() request */
171     int n,s,r;
172    
173     if((!resp)||pop3_error(resp)){
174     return(-1);
175     }
176     r=sscanf(resp+4,"%d %d\n",&n,&s); /* skip '+OK ' */
177     if (r == 2)
178     return(s);
179     else
180     return -1;
181     }
182    
183 ben 6 DLLIMPORT char** uidl2array(char* resp){
184 ben 1 /* returns an array of unique strings for each message id */
185     /* array[0] gives array's last id */
186     /* should only be called just after a pop3_uidl() request */
187     char** array=NULL;
188     int l,i=0; /* l is array lenth, i is id of msg */
189     char s[POPBUF]; /* temp signature string : sig theorically <=512B */
190     char* cur;
191    
192     if((!resp)||pop3_error(resp)){
193     return(NULL); /* any suggestions ? */
194     }
195 ben 24 if(!dotline(resp, -1)){ /* simple element uidl */
196 ben 1 /* one should not use this function for simple element */
197     /* one would better use uidli2sig() */
198     /* skip '+OK ': look for first mail int id */
199     for(cur=resp;(*cur<'0')||(*cur>'9');cur++);
200     /* no dot line here */
201     sscanf(cur,"%d %s\n",&i,s);
202     array=(char**)malloc((i+1)*sizeof(char*));
203     memset(array,0,(i+1)*sizeof(char*));
204     array[0]=(char*)malloc(POPBUF); /* up to 512B */
205     snprintf(array[0],POPBUF,"%d",i);
206     array[i]=strdup(s);
207     return(array);
208     }
209     /* else this is a true uid list */
210     /* skip '+OK\r\n : look for first mail integer id */
211     for(cur=resp;(*cur!='.')&&(*cur!='\n'); cur++);
212     cur ++; /* one more time to get behind '\n' */
213     l=1; /* array len */
214     while((*cur)!='.'){
215     sscanf(cur,"%d %s\n",&i,s);
216     while(i > l){ /* pad array while id > len */
217     l++;
218     array=(char**)realloc(array,l*sizeof(char*));
219     #if 0
220     array[l-1]=(char*)malloc(sizeof(char));
221     array[l-1]='\0';
222     #else
223     array[l-1]=NULL; /* for consitency with popchkmsg() */
224     #endif
225    
226     }
227     l++;
228     array=(char**)realloc(array,l*sizeof(char*));
229     array[i]=(char*)malloc(POPBUF); /* up to 512B */
230     array[i]=strncpy(array[i],s,POPBUF);
231     cur=nextline(cur);
232     }
233     if(i){ /* i is now the last message id met in this session */
234     array[0]=(char*)malloc(9); /* up to 99999999 msg uids FIXME */
235     snprintf(array[0],9,"%d",i);
236     /* contains the id of the last msg (char*) (also tab length) */
237     }else{ /* zero message */
238     array=(char**)malloc(1*sizeof(char*));
239     array[0]=(char*)malloc(2*sizeof(char)); /* 2 because of '\0' */
240     snprintf(array[0],2,"%d",0);
241     }
242     return(array);
243     }
244    
245 ben 6 DLLIMPORT void freeuidlarray(char** array){
246 ben 1 /* free the array allocated by uidl2array() */
247     int i,last;
248    
249     last= atoi(array[0]);
250     for (i=1;i<=last;i++){
251     free(array[i]);
252     }
253     free(array[0]);
254     free(array);
255     }
256    
257 ben 6 DLLIMPORT char* uidli2sig(char* resp){
258 ben 1 /* greps signature from server resp */
259     /* should only be called after a pop3_uidl(sock,ID) */
260     char* sig=NULL;
261    
262     if(pop3_error(resp)){
263     return(NULL);/* no message ! */
264     }
265     sig=strdup(resp+5); /* skip '+OK ID' should be safer, FIXME */
266     if(sig[1]=='.'){/* special case when no messages on the server */
267     free(sig);
268     return(NULL);
269     }
270     return(sig);
271     }
272    

  ViewVC Help
Powered by ViewVC 1.1.26