/[libspopc]/format.c
ViewVC logotype

Contents of /format.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 25 - (show annotations)
Wed Apr 11 14:06:48 2012 UTC (7 years, 1 month ago) by ben
File MIME type: text/plain
File size: 7535 byte(s)
Removed old homepage reference in docs and headers

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

  ViewVC Help
Powered by ViewVC 1.1.26