/[libspopc]/queries.c
ViewVC logotype

Annotation of /queries.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26