00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <sys/types.h>
00012
00013 #ifdef _MSC_VER
00014 #include <winsock.h>
00015 #else
00016 #include <sys/socket.h>
00017 #endif
00018
00019 #include <stdlib.h>
00020 #include <stdio.h>
00021 #include <string.h>
00022 #include "libspopc.h"
00023
00024
00025 int timedrselect(fd_set *rfds, int max, int time){
00026 struct timeval timeout;
00027 timeout.tv_sec = time;
00028 timeout.tv_usec = 0;
00029
00030 if(select(max, rfds, NULL, NULL, &timeout) <= 0){
00031 perror("timeout reached\n");
00032 return(1);
00033 }
00034 return(0);
00035 }
00036
00037 int timedrread(int sock, int time) {
00038 fd_set rfds;
00039
00040 FD_ZERO(&rfds);
00041 FD_SET(sock, &rfds);
00042 timedrselect(&rfds, sock + 1, time);
00043 return FD_ISSET(sock, &rfds);
00044 }
00045
00046 char* pop3_query(int sock, const char* query){
00047
00048 int r;
00049 char* buf;
00050
00051 #ifdef EBUG
00052 fprintf(stderr,"<pop3_query>\n");
00053 fprintf(stderr,"send %s",query);
00054 #endif
00055 r=send(sock,query,strlen(query),0);
00056 if(r==-1){
00057 perror("pop3_query.send");
00058 return(NULL);
00059 }
00060 buf=(char*)malloc(512 +1);
00061 if(!buf){
00062 perror("pop3_query.malloc");
00063 return(NULL);
00064 }
00065
00066 r=recv(sock,buf,512,0);
00067 buf[r]='\0';
00068 #ifdef EBUG
00069 fprintf(stderr,"recv %s",buf);
00070 fprintf(stderr,"</pop3_query>\n");
00071 #endif
00072 return(buf);
00073 }
00074
00075 char* pop3_user(int sock, const char* name){
00076
00077 char query[512];
00078
00079 sprintf(query,"USER %s\r\n",name);
00080 return(pop3_query(sock,query));
00081 }
00082
00083 char* pop3_pass(int sock, const char* pw){
00084
00085 char query[512];
00086
00087 sprintf(query,"PASS %s\r\n",pw);
00088 return(pop3_query(sock,query));
00089 }
00090
00091 char* pop3_quit(int sock){
00092
00093 char query[]="QUIT\r\n";
00094
00095 return(pop3_query(sock,query));
00096 }
00097
00098 char* pop3_stat(int sock){
00099
00100 char query[]="STAT\r\n";
00101
00102 return(pop3_query(sock,query));
00103 }
00104
00105 char* recv_rest(int sock, char* buf, int cs, int bs){
00106
00107
00108
00109 char* ret;
00110 char* cur;
00111 int tr;
00112 #ifdef EBUG
00113 fprintf(stderr,"<recv_rest>\n");
00114 #endif
00115 if(!buf){
00116 #ifdef EBUG
00117 fprintf(stderr,"was given NULL buf !\n");
00118 #endif
00119 return(NULL);
00120 }
00121 tr = cs;
00122 cur = buf;
00123 while(!dotline(cur)){
00124 if (tr >= (bs - TCPBUFLEN)){
00125 #ifdef EBUG
00126 fprintf(stderr,"realloc bs*2 + 1 == %d\n", bs*2 +1);
00127 #endif
00128 ret = (char*)realloc(buf, (bs *=2) +1);
00129 }
00130 if(!ret){
00131 perror("recv_rest.realloc");
00132 return(buf);
00133 }
00134 buf = ret;
00135 cur = buf + tr;
00136 if(timedrread(sock, SOCKET_TIMEOUT)){
00137 cs=recv(sock, cur, TCPBUFLEN, 0);
00138 if (cs < 0){
00139 perror("Socket Error");
00140 free(cur);
00141 return(NULL);
00142 }
00143 }else{
00144 printf("timeout reached\n");
00145 return(buf);
00146 }
00147 if (cs > 0){
00148 tr+=cs;
00149 cur[cs] = '\0';
00150 }else{
00151 cs = 0;
00152 }
00153 }
00154 cur[cs] = '\0';
00155 #ifdef EBUG
00156 fprintf(stderr, "total recv %d bytes\n", tr);
00157 fprintf(stderr, "</recv_rest>\n");
00158 #endif
00159 return(buf);
00160 }
00161
00162 char* pop3_list(int sock, int id){
00163
00164 int r;
00165 char query[512];
00166 char* buf;
00167
00168 #ifdef EBUG
00169 fprintf(stderr,"<pop3_list>\n");
00170 #endif
00171 if(id>0){
00172 sprintf(query,"LIST %d\r\n",id);
00173 }else{
00174 sprintf(query,"LIST\r\n");
00175 }
00176 #ifdef EBUG
00177 fprintf(stderr,"send %s",query);
00178 #endif
00179 r=send(sock,query,strlen(query),0);
00180 if(r==-1){
00181 perror("pop3_list.send");
00182 return(NULL);
00183 }
00184
00185
00186 buf=(char*)malloc(512 +1);
00187 if(!buf){
00188 perror("pop3_list.malloc");
00189 return(NULL);
00190 }
00191 r=recv(sock,buf,512,0);
00192 if(r < 0){
00193 perror("Socket Error");
00194 free(buf);
00195 return(NULL);
00196 }
00197 buf[r]='\0';
00198 if(id>0){
00199 return(buf);
00200 }
00201
00202 if(pop3_error(buf)){
00203 #ifdef EBUG
00204 fprintf(stderr,"%s",buf);
00205 #endif
00206 return(buf);
00207 }
00208 #ifdef EBUG
00209 fprintf(stderr,"</>\n");
00210 #endif
00211 return(recv_rest(sock,buf,r,512));
00212 }
00213
00214 char* pop3_retr(int sock, int id){
00215 int r;
00216 char query[512];
00217 char *buf;
00218
00219 #ifdef EBUG
00220 fprintf(stderr, "<pop3_retr>\n");
00221 #endif
00222 sprintf(query, "RETR %d\r\n", id);
00223 r=send(sock, query, strlen(query), 0);
00224 if(r == -1){
00225 perror("pop3_retr.send");
00226 return(NULL);
00227 }
00228 buf=(char*)malloc(512 +1);
00229 if(!buf) {
00230 perror("pop3_retr.malloc");
00231 return(NULL);
00232 }
00233 if(timedrread(sock, SOCKET_TIMEOUT)){
00234 r=recv(sock, buf, 512, 0);
00235 if(r < 0){
00236 perror("Socket Error");
00237 free(buf);
00238 return(NULL);
00239 }
00240 }else{
00241 perror("timeout reached\n");
00242 return(NULL);
00243 }
00244 if(pop3_error(buf)){
00245 buf[r+1] = '\0';
00246 return(buf);
00247 }
00248 #ifdef EBUG
00249 fprintf(stderr,"</>\n");
00250 #endif
00251 if (r > 0) {
00252 return(recv_rest(sock, buf, r, 512));
00253 }else{
00254 perror("nothing returned\n");
00255 return(NULL);
00256 }
00257 }
00258
00259 char* pop3_dele(int sock, int id){
00260
00261 char query[512];
00262
00263 if(id<=0){
00264 #ifdef EBUG
00265 fprintf(stderr,"pop3_dele : won't delete %d\n",id);
00266 #endif
00267 return(NULL);
00268 }
00269 sprintf(query,"DELE %d\r\n",id);
00270 return(pop3_query(sock,query));
00271 }
00272
00273 char* pop3_noop(int sock){
00274
00275 char query[]="NOOP\r\n";
00276
00277 return(pop3_query(sock,query));
00278 }
00279
00280 char* pop3_rset(int sock){
00281
00282 char query[]="RSET\r\n";
00283
00284 return(pop3_query(sock,query));
00285 }
00286
00287 char* pop3_top(int sock, int id, int lines){
00288
00289 int r;
00290 char query[512];
00291 char* buf;
00292
00293 #ifdef EBUG
00294 fprintf(stderr,"<pop3_top>\n");
00295 #endif
00296 sprintf(query,"TOP %d %d\r\n",id,lines);
00297 #ifdef EBUG
00298 fprintf(stderr,"send %s",query);
00299 #endif
00300 r=send(sock,query,strlen(query),0);
00301 if(r==-1){
00302 perror("pop3_top.send");
00303 return(NULL);
00304 }
00305
00306 buf=(char*)malloc(512 +1);
00307 if(!buf){
00308 perror("pop3_top.malloc");
00309 return(NULL);
00310 }
00311
00312 r=recv(sock,buf,512,0);
00313 if(r < 0){
00314 perror("Socket Error");
00315 free(buf);
00316 return(NULL);
00317 }
00318 buf[r]='\0';
00319
00320 if(pop3_error(buf)){
00321 #ifdef EBUG
00322 fprintf(stderr,"%s",buf);
00323 #endif
00324 return(buf);
00325 }
00326 #ifdef EBUG
00327 fprintf(stderr,"</>\n");
00328 #endif
00329 return(recv_rest(sock,buf,r,512));
00330 }
00331
00332 char* pop3_uidl(int sock, int id){
00333
00334 int r;
00335 char query[512];
00336 char* buf;
00337
00338 #ifdef EBUG
00339 fprintf(stderr,"<pop3_uidl>\n");
00340 #endif
00341 if(id>0){
00342 sprintf(query,"UIDL %d\r\n",id);
00343 }else{
00344 sprintf(query,"UIDL\r\n");
00345 }
00346 #ifdef EBUG
00347 fprintf(stderr,"send %s",query);
00348 #endif
00349 r=send(sock,query,strlen(query),0);
00350 if(r==-1){
00351 perror("pop3_uidl.send");
00352 return(NULL);
00353 }
00354
00355
00356 buf=(char*)malloc(512 +1);
00357 if(!buf){
00358 perror("pop3_uidl.malloc");
00359 return(NULL);
00360 }
00361 memset(buf,0,512);
00362 r=recv(sock,buf,512,0);
00363 if (r < 0){
00364 perror("Socket Error");
00365 free(buf);
00366 return(NULL);
00367 }
00368 buf[r]='\0';
00369
00370 if(id>0){
00371 #ifdef EBUG
00372 if(pop3_error(buf)){
00373 fprintf(stderr,"%s",buf);
00374 }
00375 #endif
00376
00377 return(buf);
00378 }
00379
00380 if(pop3_error(buf)){
00381 #ifdef EBUG
00382 fprintf(stderr,"%s",buf);
00383 #endif
00384 return(buf);
00385 }
00386 #ifdef EBUG
00387 fprintf(stderr,"buf=%s</>\n",buf);
00388 #endif
00389 return(recv_rest(sock,buf,r,512));
00390 }
00391
00392 char* pop3_apop(int sock, const char* name, const char* digest){
00393
00394 char query[512];
00395
00396 sprintf(query,"APOP %s %s\r\n",name,digest);
00397 return(pop3_query(sock,query));
00398 }