/[libspopc]/objects.c
ViewVC logotype

Annotation of /objects.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Thu Oct 8 11:53:59 2009 UTC (11 years, 3 months ago) by ben
File MIME type: text/plain
File size: 9813 byte(s)
import from old repo, version 0.10.2
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     * 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 <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     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     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     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     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     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     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     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     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     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     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