/[libspopc]/queries.c
ViewVC logotype

Annotation of /queries.c

Parent Directory Parent Directory | Revision Log Revision Log


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

1 ben 1 /* this is queries.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     #ifdef WIN32
24     #include <winsock.h>
25     #else
26     #include <sys/socket.h>
27     #endif
28    
29     #include <stdlib.h>
30     #include <stdio.h>
31     #include <string.h>
32    
33     #include <sys/time.h>
34     #include <sys/types.h>
35     #ifndef WIN32
36     #include <unistd.h>
37     #endif
38    
39     #include "libspopc.h"
40    
41     #ifdef USE_SSL
42    
43 ben 6 DLLIMPORT int pop3_recv (pop3sock_t sock, char* buf, int len){
44 ben 1 return sock->ssl?SSL_read(sock->ssl,buf,len):recv(sock->sock,buf,len,0);
45     }
46    
47 ben 6 DLLIMPORT int pop3_send (pop3sock_t sock, char* buf, int len){
48 ben 1 return sock->ssl?SSL_write(sock->ssl,buf,len):send(sock->sock,buf,len,0);
49     }
50    
51     #else
52    
53 ben 6 DLLIMPORT int pop3_recv (pop3sock_t sock, char* buf, int len){
54 ben 1 return recv(sock,buf,len,0);
55     }
56    
57 ben 6 DLLIMPORT int pop3_send (pop3sock_t sock, char* buf, int len){
58 ben 1 return send(sock,buf,len,0);
59     }
60    
61     #endif
62    
63 ben 6 DLLIMPORT char* pop3_query(pop3sock_t sock, const char* query){
64 ben 1 /* performs a simple pop query and returns server's <=512 bytes resp */
65     int r=0;
66     int bytes=0;
67     char* buf=NULL;
68    
69     r=pop3_send(sock,(char *)query,strlen(query));
70     if(r==-1){ /* send timeout reached */
71     perror("pop3_query.pop3_send");
72     return(NULL);
73     }
74     buf=(char*)malloc(POPBUF); /* 512B + EOS */
75     if(!buf){
76     perror("pop3_query.malloc");
77     return(NULL);
78     }
79     do {
80     r=pop3_recv(sock, buf+bytes, POPBUF-bytes-1);
81     if (r>0)
82     bytes+=r;
83     else { /* closed (0) or timeout reached (-1) */
84     free(buf);
85     return NULL;
86     }
87     } while (bytes < 2 || (buf[bytes-2] != '\r' && buf[bytes-1] != '\n'));
88     buf[bytes]='\0';
89     return(buf);
90     }
91    
92 ben 6 DLLIMPORT char* pop3_user(pop3sock_t sock, const char* name){
93 ben 1 /* performs "USER" pop query and returns server's <512 bytes response */
94     char query[POPBUF]; /* total "USER ****your_name****\n" is <= 512 */
95    
96     snprintf(query,POPBUF,"USER %s\r\n",name);
97     return(pop3_query(sock,query));
98     }
99    
100 ben 6 DLLIMPORT char* pop3_pass(pop3sock_t sock, const char* pw){
101 ben 1 /* performs "PASS" pop query and return server's <=512 bytes response */
102     char query[POPBUF]; /* total "PASS ****your_pass****\n" is <=512 */
103    
104     snprintf(query,POPBUF,"PASS %s\r\n",pw);
105     return(pop3_query(sock,query));
106     }
107    
108 ben 6 DLLIMPORT char* pop3_quit(pop3sock_t sock){
109 ben 1 /* performs "QUIT" pop query and returns server's <=512 bytes response */
110     char query[]="QUIT\r\n";
111    
112     return(pop3_query(sock,query));
113     }
114    
115 ben 6 DLLIMPORT char* pop3_stat(pop3sock_t sock){
116 ben 1 /* performs "STAT" pop query and returns server's <=512 bytes response */
117     char query[]="STAT\r\n";
118    
119     return(pop3_query(sock,query));
120     }
121    
122     char* recv_rest(pop3sock_t sock, char* buf, int cursize, int bufsize){
123     /* recv rest of data through sock, given a cs pre-filled buffer sized of bs.
124     * end of data is assumed when data has a "\r\n.\r\n" string
125     * recv() is TCPBUFLEN bytes stepped, Warning: after calling this function,
126     * buf must never be used again -not even for a free(buf)- since it may be
127     * reallocated. Use the return value instead:
128     * usage example: buf=recv_rest(sock,buf,cs,bs); free(buf);
129     */
130     char* ret = NULL;
131     char* cur = NULL; /* current position ready to receive */
132     int total; /* total received */
133     if(!buf){
134     return(NULL);
135     }
136     total = cursize;
137     cur = buf;
138     if(cursize == bufsize){
139     ret=(char*)realloc(buf,bufsize+1);
140     if(!ret){
141     perror("recv_rest.realloc");
142     free(buf);
143     return NULL;
144     }
145     cur = buf = ret;
146     }
147     cur[total]='\0';
148 ben 24 while(!dotline(buf, total)){ /* recv until "\r\n.\r\n" */
149 ben 1 if (total >= (bufsize - TCPBUFLEN)){
150     ret = (char*)realloc(buf, (bufsize *=2) +1);
151     }
152     if(!ret){
153     perror("recv_rest.realloc");
154     free(buf);
155     return NULL;
156     }
157     buf = ret;
158     cur = buf + total;
159     /* we use blocking sockets WITH TIMEOUT: no need for select() */
160     cursize=pop3_recv(sock, cur, TCPBUFLEN);
161     if (cursize <= 0){ /* timeout (-1) or closed (0) */
162     perror("recv_rest.pop3_recv");
163     free(buf);
164     return(NULL);
165     } /* else, we got some bytes */
166     total+=cursize;
167     cur[cursize] = '\0';
168     /* SUGGEST: we can strdup to a callback here */
169     }
170     return(buf);
171     }
172    
173 ben 6 DLLIMPORT char* pop3_list(pop3sock_t sock, int id){
174 ben 1 /* performs a "LIST" pop query and returns server's (long) response */
175     int r;
176     char query[POPBUF]; /* total query "LIST ID\n" string is <=512 */
177     char* buf;
178    
179     if(id>0){
180     snprintf(query,POPBUF,"LIST %d\r\n",id);
181     }else{
182     snprintf(query,POPBUF,"LIST\r\n");
183     }
184     r=pop3_send(sock,query,strlen(query));
185     if(r==-1){
186     perror("pop3_list.pop3_send");
187     return(NULL);
188     }
189     /* now prepare a first short 512 bytes recv() */
190     /* it might be now enough for recv() from "LIST X" */
191     buf=(char*)malloc(POPBUF); /* 512 chars + '\0' */
192     if(!buf){
193     perror("pop3_list.malloc");
194     return(NULL);
195     }
196     r=pop3_recv(sock,buf,POPBUF-1);
197     if(r <= 0){ /* close (0) or timeout (-1) */
198     perror("pop3_list.pop3_recv");
199     free(buf);
200     return(NULL);
201     } /* else, got some bytes */
202     buf[r]='\0';
203     if(id>0){/* +OK id size */
204     return(buf); /* 512 bytes are enough as say RFC 1939 */
205     }
206     /* else : +OK X messages (YYY octets)\n id size\n... */
207     if(pop3_error(buf)){
208     return(buf);
209     }
210     return(recv_rest(sock,buf,r,POPBUF-1));
211     }
212    
213 ben 6 DLLIMPORT char* pop3_retr(pop3sock_t sock, int id){
214 ben 1 /* performs a "RETR" pop query and returns server's (long) response */
215     int r;
216     char query[POPBUF];
217     char *buf;
218    
219     snprintf(query, POPBUF, "RETR %d\r\n", id);
220     r=pop3_send(sock, query, strlen(query));
221     if(r==-1){
222     perror("pop3_retr.pop3_send");
223     return(NULL);
224     }
225     buf=(char*)malloc(POPBUF);/* 512 chars + '\0' */
226     if(!buf) {
227     perror("pop3_retr.malloc");
228     return(NULL);
229     }
230     /* using blocking sockets WITH TIMEOUT: no need for select() */
231     r=pop3_recv(sock, buf, POPBUF-1);
232     if(r <= 0){ /* timeout (-1) or close (0) */
233     perror("pop3_retr.pop3_recv");
234     free(buf);
235     return(NULL);
236     } /* else, got some bytes */
237     if(pop3_error(buf)){
238     buf[r] = '\0';
239     return(buf); /* 512 are enough as say RFC 1939 */
240     }
241     return(recv_rest(sock, buf, r, POPBUF-1));
242     }
243    
244 ben 6 DLLIMPORT char* pop3_dele(pop3sock_t sock, int id){
245 ben 1 /* performs a "DELE" pop query and returns server's <=512 bytes response */
246     char query[POPBUF]; /* total "DELE X\n" string <=512 */
247    
248     if(id<=0){
249     return(NULL);
250     }
251     snprintf(query,POPBUF,"DELE %d\r\n",id);
252     return(pop3_query(sock,query));
253     }
254    
255 ben 6 DLLIMPORT char* pop3_noop(pop3sock_t sock){
256 ben 1 /* performs a "NOOP" pop query and returns server's <=512 bytes response */
257     char query[]="NOOP\r\n";
258    
259     return(pop3_query(sock,query));
260     }
261    
262 ben 6 DLLIMPORT char* pop3_rset(pop3sock_t sock){
263 ben 1 /* performs a "RSET" pop query and returns server's <=512 bytes response */
264     char query[]="RSET\r\n";
265    
266     return(pop3_query(sock,query));
267     }
268    
269 ben 6 DLLIMPORT char* pop3_top(pop3sock_t sock, int id, int lines){
270 ben 1 /* performs a "TOP" pop query and returns server's (long) response */
271     int r;
272     char query[POPBUF]; /* total "TOP X Y\n" is <=512 */
273     char* buf;
274    
275     snprintf(query,POPBUF,"TOP %d %d\r\n",id,lines);
276     r=pop3_send(sock,query,strlen(query));
277     if(r==-1){
278     perror("pop3_top.pop3_send");
279     return(NULL);
280     }
281     /* prepare first recv() of 512 bytes */
282     buf=(char*)malloc(POPBUF); /* 512 chars + '\0' */
283     if(!buf){
284     perror("pop3_top.malloc");
285     return(NULL);
286     }
287     r=pop3_recv(sock,buf,POPBUF-1);
288     if(r <= 0){ /* timeout (-1) or close (0) */
289     perror("pop3_top.pop3_recv");
290     free(buf);
291     return(NULL);
292     } /* else, got some bytes */
293     buf[r]='\0';
294     if(pop3_error(buf)){
295     return(buf); /* 512 bytes are enough as say RFC 1939 */
296     }
297     return(recv_rest(sock,buf,r,POPBUF-1));
298     }
299    
300 ben 6 DLLIMPORT char* pop3_uidl(pop3sock_t sock, int id){
301 ben 1 /* performs a "UIDL" pop query and returns server's (long) response */
302     int r;
303     char query[POPBUF]; /* total "UIDL X\n" is <=512 */
304     char* buf;
305    
306     if(id>0){
307     snprintf(query,POPBUF,"UIDL %d\r\n",id);
308     }else{
309     snprintf(query,POPBUF,"UIDL\r\n");
310     }
311     r=pop3_send(sock,query,strlen(query));
312     if(r==-1){
313     perror("pop3_uidl.pop3_send");
314     return(NULL);
315     }
316     /* prepare first 512 bytes for recv() */
317     /* i hope this is also enough for the 'one line' short response */
318     buf=(char*)malloc(POPBUF); /* 512 chars + '\0' */
319     if(!buf){
320     perror("pop3_uidl.malloc");
321     return(NULL);
322     }
323     memset(buf,0,POPBUF);
324     r=pop3_recv(sock,buf,POPBUF-1);
325     if (r <= 0){ /* timeout (-1) or close (0) */
326     perror("pop3_uidl.pop3_recv");
327     free(buf);
328     return(NULL);
329     } /* else, got some bytes */
330     buf[r]='\0';
331     if(id>0){/* +OK id sig */
332     /* return the short buf, error or not */
333     return(buf); /* 512 are enough as say RFC 1939 */
334     }
335     /* else : +OK\n id sig\nid sig\nid sig\n... */
336     if(pop3_error(buf)){
337     return(buf); /* hope error msg were <=512 bytes */
338     }
339     return(recv_rest(sock,buf,r,POPBUF-1));
340     }
341    
342 ben 6 DLLIMPORT char* pop3_apop(pop3sock_t sock, const char* name, const char* digest){
343 ben 1 /* performs a "APOP" secure query and returns server's <=512 bytes response */
344     char query[POPBUF]; /* total "APOP name digest\r\n" is <=512 */
345    
346     snprintf(query,POPBUF,"APOP %s %s\r\n",name,digest);
347     return(pop3_query(sock,query));
348     }
349    

  ViewVC Help
Powered by ViewVC 1.1.26