/[libspopc]/objects.c
ViewVC logotype

Annotation of /objects.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide annotations)
Sun Dec 5 16:58:12 2010 UTC (10 years, 10 months ago) by ben
File MIME type: text/plain
File size: 10226 byte(s)
added possibility to change socket timeout on the fly
1 ben 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 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 <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 ben 6 DLLIMPORT char* popbegin(const char* servername, const char* user, const char* pass, popsession** sp){
42 ben 1 /* 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 ben 22 DLLIMPORT int popsettimeout(popsession* session, int timeout){
161     /* sets the timeout in seconds for a session, returns 0 on success, < 0 on error */
162     return pop3_timeout(session->sock, timeout);
163     }
164    
165 ben 6 DLLIMPORT char* popgethead(popsession* session, int id){
166 ben 1 /* returns the header of a message id between 1 and last or NULL if bad id or error */
167     char* resp;
168     char* msg;
169     if(!session){
170     return(NULL);
171     }
172     if((id > session->last) || (id < 1)){
173     return(NULL);
174     }
175     resp=pop3_top(session->sock,id,0); /* 0 means only header */
176     if((!resp) || pop3_error(resp)){
177     if(resp){
178     free(resp);
179     }
180     return(NULL);
181     }
182     msg=retr2msg(resp);
183     if(!msg){
184     msg=resp;
185     }else{
186     free(resp);
187     }
188     return(msg);
189     }
190    
191 ben 6 DLLIMPORT char* popgetmsg(popsession* session, int id){
192 ben 1 /* returns a message id between 1 to last or NULL if bad id or error */
193     char* resp=NULL;
194     char* msg=NULL;
195    
196     if(!session){
197     return(NULL);
198     }
199     if((id > session->last) || (id < 1)){
200     return(NULL);
201     }
202     resp=pop3_retr(session->sock,id);
203     if((!resp) || pop3_error(resp)){
204     free(resp);
205     return(NULL);
206     }
207     msg=retr2msg(resp);
208     if(!msg){
209     msg=resp;
210     }else{
211     free(resp);
212     }
213     if(session->del){
214     popdelmsg(session, id);
215     }
216     return(msg);
217     }
218    
219 ben 6 DLLIMPORT int popdelmsg(popsession* session, int id){
220 ben 1 /* deletes a message 'id' on pop server */
221     /* returns -1 if no deletion (server error), 0 else */
222     /* sets session->sync to 0 if last id unsync-ed , 1 if OK */
223     char* resp;
224     int ret;
225     if(!session){
226     return -1;
227     }
228     if((id > session->last) || (id < 1)){
229     return -1;
230     }
231     /* actualy delete the email */
232     resp=pop3_dele(session->sock,id);
233     if((!resp) || pop3_error(resp)){
234     free(resp);
235     return -1;
236     }
237     free(resp);
238     resp=pop3_stat(session->sock);
239     if((!resp) || pop3_error(resp)){
240     session->sync=0;
241 ben 19 free(resp);
242 ben 1 return -1;
243     }
244     ret = stat2bytes(resp);
245     if (ret < 0)
246     session->sync=0;
247    
248     else
249     session->bytes=ret;
250     ret = stat2num(resp);
251     if (ret < 0)
252     session->sync=0;
253     else
254     session->num=ret;
255     free(resp);
256     ret=poplast(session); /* check actual last id */
257     if (ret < 0){
258     session->sync=0;
259 ben 19 free(resp);
260 ben 1 return -1;
261     }
262     session->last=ret;
263    
264     /* no more message of this id*/
265     session->list[id]=0;
266     free(session->uidl[id]);
267     session->uidl[id]=NULL;
268     session->sync=1;
269     return 0;
270     }
271    
272 ben 6 DLLIMPORT int popcancel(popsession* session){
273 ben 1 /* cancel all previous deletions on pop server */
274     /* returns -1 if server error, 0 else */
275     char* resp;
276     int ret;
277    
278     if(!session){
279     return(-1);
280     }
281     resp=pop3_rset(session->sock);
282     if((!resp) || pop3_error(resp)){
283     free(resp);
284     return(-1);
285     }
286     free(resp);
287     resp=pop3_stat(session->sock);
288     if((!resp) || pop3_error(resp)){
289     session->sync=0;
290 ben 19 free(resp);
291 ben 1 return(-1);
292     }
293     /* sync number of bytes */
294     ret = stat2bytes(resp);
295     if (ret < 0)
296     session->sync=0;
297     else
298     session->bytes=ret;
299     /* sync number of messages */
300     ret = stat2num(resp);
301     if (ret < 0)
302     session->sync=0;
303     else
304     session->num=ret;
305     /* sync last mail id */
306     /* safe to use stat2num here since we cancel */
307     ret = stat2num(resp);
308     if (ret < 0)
309     session->sync=0;
310     else
311     session->last=ret;
312     free(resp);
313     resp=pop3_list(session->sock,0);
314     if((!resp) || pop3_error(resp)){
315     session->sync=0;
316 ben 19 free(resp);
317 ben 1 return -1;
318     }
319     freelistarray(session->list);
320     session->list=list2array(resp);
321     free(resp);
322     resp=pop3_uidl(session->sock,0);
323     if((!resp) || pop3_error(resp)){
324     session->sync=0;
325 ben 19 free(resp);
326 ben 1 return -1;
327     }
328     freeuidlarray(session->uidl);
329     session->uidl=uidl2array(resp);
330     free(resp);
331     session->sync=1;
332     return 0;
333     }
334    
335 ben 6 DLLIMPORT void popend(popsession* session){
336 ben 1 /* quit and destroys pop session */
337     int i;
338     char* resp;
339    
340     if(!session)
341     return;
342     resp=pop3_quit(session->sock);
343     free(resp);
344     pop3_disconnect(session->sock, session->server);
345     free(session->server);
346     free(session->connection);
347     free(session->list);
348     for(i=0;i<=session->last;i++){
349     free(session->uidl[i]);
350     }
351     free(session->uidl);
352     free(session);
353     return;
354     }
355    
356 ben 6 DLLIMPORT int popnum(popsession* session){
357 ben 1 /* returns the number of current (non-deleted) messages */
358     char* r=NULL;
359     int n;
360    
361     if(!session)
362     return -1;
363     r=pop3_stat(session->sock);
364     if(pop3_error(r)) {
365     free(r);
366     return -1; /* error (timeout, etc..) */
367     }
368     n=stat2num(r);
369     free(r);
370     return(n);
371     }
372    
373 ben 6 DLLIMPORT int poplast(popsession* session){
374 ben 1 /* return the id of the last downloadable (non-deleted) message */
375     /* thanks to Francesco Gennai <francesco.gennai@isti.cnr.it> */
376     int i=0;
377     char* lines=NULL;
378     char* p=NULL;
379    
380     if(!session)
381     return -1;
382     lines=pop3_list(session->sock, 0); /* 0 means 'all' */
383     if(pop3_error(lines)) {
384     free(lines);
385     return -1; /* error (timeout, etc..) */
386     }
387     p=lines;
388     p=nextline(p); /* skip +OK */
389     while (p[0]!='.'){ /* dot means list terminated */
390     i = atoi(p); /* first number is the id */
391     p=nextline(p);
392     }
393     /* i is now the greatest id */
394     free(lines);
395     return(i);
396     }
397    
398 ben 6 DLLIMPORT int popchkmsg(popsession* session, int id) {
399 ben 1 /* check if the message 'id' is accessible in the current session */
400     /* thanks to Francesco Gennai <francesco.gennai@isti.cnr.it> */
401     if (popmsguid(session, id)) return 1; /* anything but 0 */
402     return 0;
403     }
404    
405     /* re-synchronize the session object from the server */
406 ben 6 DLLIMPORT int popsync(popsession* session) {
407 ben 1 char* resp;
408     int ret;
409    
410     if(!session){
411     return(-1);
412     }
413     resp=pop3_stat(session->sock);
414     if((!resp) || pop3_error(resp)){
415     session->sync=0;
416     return(-1);
417     }
418     session->bytes=stat2bytes(resp);
419     session->num=stat2num(resp);
420     ret=poplast(session); /* check actual last id */
421     if (ret < 0){
422     session->sync=0;
423 ben 19 free(resp);
424 ben 1 return(-1);
425     }
426     session->last=ret;
427     free(resp);
428     resp=pop3_list(session->sock,0);
429     if((!resp) || pop3_error(resp)){
430     session->sync=0;
431 ben 19 free(resp);
432 ben 1 return(-1);
433     }
434     freelistarray(session->list);
435     session->list=list2array(resp);
436     free(resp);
437     resp=pop3_uidl(session->sock,0);
438     if((!resp) || pop3_error(resp)){
439     session->sync=0;
440 ben 19 free(resp);
441 ben 1 return(-1);
442     }
443     freeuidlarray(session->uidl);
444     session->uidl=uidl2array(resp);
445     free(resp);
446     session->sync=1;
447     return(0);
448     }
449    

  ViewVC Help
Powered by ViewVC 1.1.26