/[libspopc]/objects.c
ViewVC logotype

Contents of /objects.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (show annotations)
Sun Apr 18 11:05:58 2010 UTC (10 years, 7 months ago) by ben
File MIME type: text/plain
File size: 9918 byte(s)
windows version revival (dev-cpp)
1 /* this is objects.c, 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://herewe.servebeer.com/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 <sys/types.h>
27
28 #ifdef WIN32
29 #include <winsock.h>
30 #else
31 #include <sys/socket.h>
32 #include <netdb.h>
33 #endif
34
35 #include "libspopc.h"
36
37 /***************************************
38 * high-level methods for a simple mua *
39 ***************************************/
40
41 DLLIMPORT char* popbegin(const char* servername, const char* user, const char* pass, popsession** sp){
42 /* prepares, connect and get lists of messages stored on pop server */
43 /* you must give a valid servername, user and pass */
44 /* returns an error message if a problem occurs, else NULL */
45 char* resp=NULL;
46 char* err=NULL;
47 char *hostname, *ptr_port;
48 int nport;
49 popsession* s = NULL;
50
51 if(!(servername && user && pass)){
52 err=strdup("popbegin: some NULL args !");
53 goto error;
54 }
55 s=(popsession*)malloc(sizeof(popsession));
56 if(!s){
57 err=strdup("popbegin.malloc: failed\n");
58 goto error;
59 }
60 /* basic default construction */
61 s->sock=BAD_SOCK;
62 s->connection=NULL;
63 s->server=NULL;
64 s->list=NULL;
65 s->uidl=NULL;
66 s->bytes=-1;
67 s->last=-1;
68 s->num=-1;
69 s->del=0; /* no deletion (by default) at this time */
70 s->sync=1; /* this is sync'ed at this time (no cnx yet) */
71
72 s->server=(struct hostent*)malloc(sizeof(struct hostent));
73 if(!(s->server)){
74 err=strdup("popbegin.malloc: failed\n");
75 goto error;
76 }
77 s->connection=(struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
78 if(!(s->connection)){
79 err=strdup("popbegin.malloc: failed\n");
80 goto error;
81 }
82 hostname = strdup (servername);
83 if (!hostname) {
84 err=strdup("popbegin.strdup: failed\n"); /* ahem... */
85 goto error;
86 }
87 ptr_port = strchr (hostname, ':');
88 if (!ptr_port)
89 nport = 110;
90 else {
91 *ptr_port = 0;
92 nport = (int) strtoul (++ptr_port, NULL, 10);
93 if (!nport)
94 nport = 110;
95 }
96 s->sock=pop3_prepare(hostname,nport,s->connection,s->server);
97 free (hostname);
98 if(s->sock==BAD_SOCK){
99 err=strdup("popbegin.pop3_prepare: failed\n");
100 goto error;
101 }
102 resp=pop3_connect(s->sock,s->connection);
103 if(!resp){
104 err=strdup("popbegin.pop3_connect: failed\n");
105 goto error;
106 }
107 free(resp);
108 resp=pop3_user(s->sock,user);
109 if((!resp) || pop3_error(resp)){
110 err=resp?resp:strdup("popbegin.pop3_user: failed\n");
111 goto error;
112 }
113 free(resp);
114 resp=pop3_pass(s->sock,pass);
115 if((!resp) || pop3_error(resp)){
116 err=resp?resp:strdup("popbegin.pop3_pass: failed\n");
117 goto error;
118 }
119 free(resp);
120 resp=pop3_stat(s->sock);
121 if((!resp) || pop3_error(resp)){
122 err=resp?resp:strdup("popbegin.pop3_stat: failed\n");
123 goto error;
124 }
125 s->bytes=stat2bytes(resp);
126 s->num=stat2num(resp);
127 s->last=stat2num(resp); /* safe here: we did not delete anything */
128 free(resp);
129 resp=pop3_list(s->sock,0);
130 if((!resp) || pop3_error(resp)){
131 err=resp?resp:strdup("popbegin.pop3_list: failed\n");
132 goto error;
133 }
134 s->list=list2array(resp);
135 free(resp);
136 resp=pop3_uidl(s->sock,0);
137 if((!resp) || pop3_error(resp)){
138 err=resp?resp:strdup("popbegin.pop3_uidl: failed\n");
139 goto error;
140 }
141 s->uidl=uidl2array(resp);
142 s->del=0;
143 (*sp)=s;
144 free(resp);
145 return (NULL);
146
147 error:
148 if (s) {
149 if (s->sock != BAD_SOCK)
150 {
151 pop3_disconnect (s->sock, s->server);
152 free(s->server);
153 }
154 free (s->connection);
155 free(s);
156 }
157 return (err);
158 }
159
160 DLLIMPORT char* popgethead(popsession* session, int id){
161 /* returns the header of a message id between 1 and last or NULL if bad id or error */
162 char* resp;
163 char* msg;
164 if(!session){
165 return(NULL);
166 }
167 if((id > session->last) || (id < 1)){
168 return(NULL);
169 }
170 resp=pop3_top(session->sock,id,0); /* 0 means only header */
171 if((!resp) || pop3_error(resp)){
172 if(resp){
173 free(resp);
174 }
175 return(NULL);
176 }
177 msg=retr2msg(resp);
178 if(!msg){
179 msg=resp;
180 }else{
181 free(resp);
182 }
183 return(msg);
184 }
185
186 DLLIMPORT char* popgetmsg(popsession* session, int id){
187 /* returns a message id between 1 to last or NULL if bad id or error */
188 char* resp=NULL;
189 char* msg=NULL;
190
191 if(!session){
192 return(NULL);
193 }
194 if((id > session->last) || (id < 1)){
195 return(NULL);
196 }
197 resp=pop3_retr(session->sock,id);
198 if((!resp) || pop3_error(resp)){
199 free(resp);
200 return(NULL);
201 }
202 msg=retr2msg(resp);
203 if(!msg){
204 msg=resp;
205 }else{
206 free(resp);
207 }
208 if(session->del){
209 popdelmsg(session, id);
210 }
211 return(msg);
212 }
213
214 DLLIMPORT int popdelmsg(popsession* session, int id){
215 /* deletes a message 'id' on pop server */
216 /* returns -1 if no deletion (server error), 0 else */
217 /* sets session->sync to 0 if last id unsync-ed , 1 if OK */
218 char* resp;
219 int ret;
220 if(!session){
221 return -1;
222 }
223 if((id > session->last) || (id < 1)){
224 return -1;
225 }
226 /* actualy delete the email */
227 resp=pop3_dele(session->sock,id);
228 if((!resp) || pop3_error(resp)){
229 free(resp);
230 return -1;
231 }
232 free(resp);
233 resp=pop3_stat(session->sock);
234 if((!resp) || pop3_error(resp)){
235 session->sync=0;
236 return -1;
237 }
238 ret = stat2bytes(resp);
239 if (ret < 0)
240 session->sync=0;
241
242 else
243 session->bytes=ret;
244 ret = stat2num(resp);
245 if (ret < 0)
246 session->sync=0;
247 else
248 session->num=ret;
249 free(resp);
250 ret=poplast(session); /* check actual last id */
251 if (ret < 0){
252 session->sync=0;
253 return -1;
254 }
255 session->last=ret;
256
257 /* no more message of this id*/
258 session->list[id]=0;
259 free(session->uidl[id]);
260 session->uidl[id]=NULL;
261 session->sync=1;
262 return 0;
263 }
264
265 DLLIMPORT int popcancel(popsession* session){
266 /* cancel all previous deletions on pop server */
267 /* returns -1 if server error, 0 else */
268 char* resp;
269 int ret;
270
271 if(!session){
272 return(-1);
273 }
274 resp=pop3_rset(session->sock);
275 if((!resp) || pop3_error(resp)){
276 free(resp);
277 return(-1);
278 }
279 free(resp);
280 resp=pop3_stat(session->sock);
281 if((!resp) || pop3_error(resp)){
282 session->sync=0;
283 return(-1);
284 }
285 /* sync number of bytes */
286 ret = stat2bytes(resp);
287 if (ret < 0)
288 session->sync=0;
289 else
290 session->bytes=ret;
291 /* sync number of messages */
292 ret = stat2num(resp);
293 if (ret < 0)
294 session->sync=0;
295 else
296 session->num=ret;
297 /* sync last mail id */
298 /* safe to use stat2num here since we cancel */
299 ret = stat2num(resp);
300 if (ret < 0)
301 session->sync=0;
302 else
303 session->last=ret;
304 free(resp);
305 resp=pop3_list(session->sock,0);
306 if((!resp) || pop3_error(resp)){
307 session->sync=0;
308 return -1;
309 }
310 freelistarray(session->list);
311 session->list=list2array(resp);
312 free(resp);
313 resp=pop3_uidl(session->sock,0);
314 if((!resp) || pop3_error(resp)){
315 session->sync=0;
316 return -1;
317 }
318 freeuidlarray(session->uidl);
319 session->uidl=uidl2array(resp);
320 free(resp);
321 session->sync=1;
322 return 0;
323 }
324
325 DLLIMPORT void popend(popsession* session){
326 /* quit and destroys pop session */
327 int i;
328 char* resp;
329
330 if(!session)
331 return;
332 resp=pop3_quit(session->sock);
333 free(resp);
334 pop3_disconnect(session->sock, session->server);
335 free(session->server);
336 free(session->connection);
337 free(session->list);
338 for(i=0;i<=session->last;i++){
339 free(session->uidl[i]);
340 }
341 free(session->uidl);
342 free(session);
343 return;
344 }
345
346 DLLIMPORT int popnum(popsession* session){
347 /* returns the number of current (non-deleted) messages */
348 char* r=NULL;
349 int n;
350
351 if(!session)
352 return -1;
353 r=pop3_stat(session->sock);
354 if(pop3_error(r)) {
355 free(r);
356 return -1; /* error (timeout, etc..) */
357 }
358 n=stat2num(r);
359 free(r);
360 return(n);
361 }
362
363 DLLIMPORT int poplast(popsession* session){
364 /* return the id of the last downloadable (non-deleted) message */
365 /* thanks to Francesco Gennai <francesco.gennai@isti.cnr.it> */
366 int i=0;
367 char* lines=NULL;
368 char* p=NULL;
369
370 if(!session)
371 return -1;
372 lines=pop3_list(session->sock, 0); /* 0 means 'all' */
373 if(pop3_error(lines)) {
374 free(lines);
375 return -1; /* error (timeout, etc..) */
376 }
377 p=lines;
378 p=nextline(p); /* skip +OK */
379 while (p[0]!='.'){ /* dot means list terminated */
380 i = atoi(p); /* first number is the id */
381 p=nextline(p);
382 }
383 /* i is now the greatest id */
384 free(lines);
385 return(i);
386 }
387
388 DLLIMPORT int popchkmsg(popsession* session, int id) {
389 /* check if the message 'id' is accessible in the current session */
390 /* thanks to Francesco Gennai <francesco.gennai@isti.cnr.it> */
391 if (popmsguid(session, id)) return 1; /* anything but 0 */
392 return 0;
393 }
394
395 /* re-synchronize the session object from the server */
396 DLLIMPORT int popsync(popsession* session) {
397 char* resp;
398 int ret;
399
400 if(!session){
401 return(-1);
402 }
403 resp=pop3_stat(session->sock);
404 if((!resp) || pop3_error(resp)){
405 session->sync=0;
406 return(-1);
407 }
408 session->bytes=stat2bytes(resp);
409 session->num=stat2num(resp);
410 ret=poplast(session); /* check actual last id */
411 if (ret < 0){
412 session->sync=0;
413 return(-1);
414 }
415 session->last=ret;
416 free(resp);
417 resp=pop3_list(session->sock,0);
418 if((!resp) || pop3_error(resp)){
419 session->sync=0;
420 return(-1);
421 }
422 freelistarray(session->list);
423 session->list=list2array(resp);
424 free(resp);
425 resp=pop3_uidl(session->sock,0);
426 if((!resp) || pop3_error(resp)){
427 session->sync=0;
428 return(-1);
429 }
430 freeuidlarray(session->uidl);
431 session->uidl=uidl2array(resp);
432 free(resp);
433 session->sync=1;
434 return(0);
435 }
436

  ViewVC Help
Powered by ViewVC 1.1.26