/[libspopc]/format.c
ViewVC logotype

Contents of /format.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Thu Oct 8 11:53:59 2009 UTC (11 years ago) by ben
File MIME type: text/plain
File size: 7484 byte(s)
import from old repo, version 0.10.2
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 * more information on http://brouits.free.fr/libspopc/
8 *
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 char* nextline(char* string){
34 /* 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 char* retr2msg(char* data){
45 /* 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 void freemsg(char* msg){
79 free(msg);
80 msg=NULL;
81 }
82
83 int* list2array(char* poplist){
84 /* returns an int array of sizes of messages from a LIST pop query */
85 /* array[0] holds id of the array's element */
86 /* should only be called on data received by a pop3_list() request */
87 int* array=NULL;
88 int len,size;
89 int id=0;
90 char* cur;
91
92 if((!poplist)||pop3_error(poplist)){
93 return(NULL); /* any suggestions ? */
94 }
95 if(!dotline(poplist)){/* if simple element list */
96 /* one should't use this function for simple element... */
97 /* one should better use listi2size() */
98 /* skip '+OK ': look for first mail int id */
99 for(cur=poplist;(*cur<'0')||(*cur>'9');cur++);
100 /* not dot line here */
101 sscanf(cur,"%d %d\n",&id,&size);
102 array=(int*)malloc((id+1)*sizeof(int));
103 memset(array,0,(id+1)*sizeof(int));
104 array[0]=id;
105 array[id]=size;
106 return(array);
107 }
108 /* else this is a true list */
109 /* skip '+OK\r\n' :*/
110 for(cur=poplist;(*cur!='.')&&(*cur!='\n'); cur++);
111 cur ++; /* one more time to get behind '\n' */
112 len=1; /* array len */
113 while((*cur)!='.'){
114 sscanf(cur,"%d %d\n",&id,&size);
115 while(id > len){ /* pad array while id > len */
116 len++;
117 array=(int*)realloc(array,len*sizeof(int));
118 array[len-1]=0; /* no mail */
119 }
120 len++;
121 array=(int*)realloc(array,len*sizeof(int));
122 array[id]=size;
123 cur=nextline(cur);
124 }
125 if(id){
126 array[0]=id; /* last id */
127 }else{ /* no mail */
128 array=(int*)realloc(array, 1*sizeof(int));
129 array[0]=0;
130 }
131 return(array);
132 }
133
134 void freelistarray(int* array){
135 /* free array allocated by list2array() */
136 free(array);
137 }
138
139 int listi2size(char* resp){
140 /* grep the given size (in bytes) in resp after a pop3_list(sock,ID) request */
141 int i;
142 int r;
143
144 if(pop3_error(resp)){
145 return(0); /* no message ! */
146 }
147 r=sscanf(resp+5,"%d\n",&i);/* skip '+OK ' should be safer FIXME */
148 if(!r){ /* special case when no messages on server */
149 return(0);
150 }
151 return(i);
152 }
153
154 int stat2num(char* resp){
155 /* returns the num of retrievable (non-deleted) messages */
156 /* should only be called just after a pop3_stat() request */
157 int n,s,r;
158
159 if((!resp)||pop3_error(resp)){
160 return(-1);
161 }
162 r=sscanf(resp+4,"%d %d\n",&n,&s); /* with skip '+OK ' */
163 if (r == 2)
164 return n;
165 else
166 return -1;
167 }
168
169 int stat2bytes(char* resp){
170 /* returns the sumsize in bytes of all stored messages on server */
171 /* should only be called just after a pop3_stat() request */
172 int n,s,r;
173
174 if((!resp)||pop3_error(resp)){
175 return(-1);
176 }
177 r=sscanf(resp+4,"%d %d\n",&n,&s); /* skip '+OK ' */
178 if (r == 2)
179 return(s);
180 else
181 return -1;
182 }
183
184 char** uidl2array(char* resp){
185 /* returns an array of unique strings for each message id */
186 /* array[0] gives array's last id */
187 /* should only be called just after a pop3_uidl() request */
188 char** array=NULL;
189 int l,i=0; /* l is array lenth, i is id of msg */
190 char s[POPBUF]; /* temp signature string : sig theorically <=512B */
191 char* cur;
192
193 if((!resp)||pop3_error(resp)){
194 return(NULL); /* any suggestions ? */
195 }
196 if(!dotline(resp)){ /* simple element uidl */
197 /* one should not use this function for simple element */
198 /* one would better use uidli2sig() */
199 /* skip '+OK ': look for first mail int id */
200 for(cur=resp;(*cur<'0')||(*cur>'9');cur++);
201 /* no dot line here */
202 sscanf(cur,"%d %s\n",&i,s);
203 array=(char**)malloc((i+1)*sizeof(char*));
204 memset(array,0,(i+1)*sizeof(char*));
205 array[0]=(char*)malloc(POPBUF); /* up to 512B */
206 snprintf(array[0],POPBUF,"%d",i);
207 array[i]=strdup(s);
208 return(array);
209 }
210 /* else this is a true uid list */
211 /* skip '+OK\r\n : look for first mail integer id */
212 for(cur=resp;(*cur!='.')&&(*cur!='\n'); cur++);
213 cur ++; /* one more time to get behind '\n' */
214 l=1; /* array len */
215 while((*cur)!='.'){
216 sscanf(cur,"%d %s\n",&i,s);
217 while(i > l){ /* pad array while id > len */
218 l++;
219 array=(char**)realloc(array,l*sizeof(char*));
220 #if 0
221 array[l-1]=(char*)malloc(sizeof(char));
222 array[l-1]='\0';
223 #else
224 array[l-1]=NULL; /* for consitency with popchkmsg() */
225 #endif
226
227 }
228 l++;
229 array=(char**)realloc(array,l*sizeof(char*));
230 array[i]=(char*)malloc(POPBUF); /* up to 512B */
231 array[i]=strncpy(array[i],s,POPBUF);
232 cur=nextline(cur);
233 }
234 if(i){ /* i is now the last message id met in this session */
235 array[0]=(char*)malloc(9); /* up to 99999999 msg uids FIXME */
236 snprintf(array[0],9,"%d",i);
237 /* contains the id of the last msg (char*) (also tab length) */
238 }else{ /* zero message */
239 array=(char**)malloc(1*sizeof(char*));
240 array[0]=(char*)malloc(2*sizeof(char)); /* 2 because of '\0' */
241 snprintf(array[0],2,"%d",0);
242 }
243 return(array);
244 }
245
246 void freeuidlarray(char** array){
247 /* free the array allocated by uidl2array() */
248 int i,last;
249
250 last= atoi(array[0]);
251 for (i=1;i<=last;i++){
252 free(array[i]);
253 }
254 free(array[0]);
255 free(array);
256 }
257
258 char* uidli2sig(char* resp){
259 /* greps signature from server resp */
260 /* should only be called after a pop3_uidl(sock,ID) */
261 char* sig=NULL;
262
263 if(pop3_error(resp)){
264 return(NULL);/* no message ! */
265 }
266 sig=strdup(resp+5); /* skip '+OK ID' should be safer, FIXME */
267 if(sig[1]=='.'){/* special case when no messages on the server */
268 free(sig);
269 return(NULL);
270 }
271 return(sig);
272 }
273

  ViewVC Help
Powered by ViewVC 1.1.26