source: titan/titan/sock.h @ 24220

Last change on this file since 24220 was 24220, checked in by nit, 10 years ago

[titan] add parameter to get only http header

File size: 22.0 KB
RevLine 
[8507]1#ifndef SOCK_H
2#define SOCK_H
3
[8879]4int sockwrite(int fd, unsigned char* buf, int count, int tout)
[8878]5{
6        struct timeval timeout;
[10569]7        int ret = 0, usec = 0, sec = 0, tmpcount = count;
[8879]8        unsigned char* buffer = NULL;
[8507]9
[8879]10        if(fd < 0) return -1;
11
[10357]12        if(tout == -1) tout = 3000 * 1000;
[10569]13        usec = tout % 1000000;
14        sec = (tout - usec) / 1000000;
[9111]15
[8878]16        fd_set wfds;
17
18        while (tmpcount > 0)
19        {
20                buffer = buf + (count - tmpcount);
21                ret = send(fd, buffer, tmpcount, MSG_DONTWAIT | MSG_NOSIGNAL);
[9049]22                if(ret < 0)
[8878]23                {
[9049]24                        if(errno == EINTR || errno == EAGAIN)
[8878]25                        {
[9049]26                                FD_ZERO(&wfds);
27                                FD_SET(fd, &wfds);
[8878]28                       
[10569]29                                timeout.tv_sec = sec;
30                                timeout.tv_usec = usec;
[8878]31                       
[10380]32                                ret = TEMP_FAILURE_RETRY(select(fd + 1, NULL, &wfds, NULL, &timeout));
[9049]33                        }
[8878]34                       
35                        if(ret == 0)
36                        {
[10357]37                                perr("sock send timed out fd=%d", fd);
[8878]38                                return -1;
39                        }
[9049]40                        if(ret < 0)
[8878]41                        {
[10357]42                                perr("sock send data fd=%d", fd);
[8878]43                                return -1;
44                        }
45                }
46                else
47                        tmpcount -= ret;
48        }
[8944]49
[8878]50        return count;
51}
52
[10381]53//flag 0: normal
54//flag 1: from check
55int sockread(int fd, unsigned char *buf, int pos, int count, int tout, int flag)
[8507]56{
[8878]57        struct timeval timeout;
[10569]58        int ret = 0, usec = 0, sec = 0, tmpcount = count;
[8879]59        unsigned char* buffer = NULL;
[8878]60
[8879]61        if(fd < 0) return -1;
62
[10357]63        if(tout == -1) tout = 3000 * 1000;
[10569]64        usec = tout % 1000000;
65        sec = (tout - usec) / 1000000;
[9111]66
[8878]67        fd_set rfds;
68
69        while(tmpcount > 0)
[8507]70        {
[8878]71                FD_ZERO(&rfds);
72                FD_SET(fd, &rfds);
73               
[10569]74                timeout.tv_sec = sec;
75                timeout.tv_usec = usec;
[8878]76               
[10380]77                ret = TEMP_FAILURE_RETRY(select(fd + 1, &rfds , NULL, NULL, &timeout));
[8878]78                       
79                if(ret == 1)
80                {
81                        buffer = buf + (count - tmpcount);
[10566]82retry:
[8878]83                        ret = recv(fd, buffer, tmpcount, MSG_DONTWAIT | MSG_NOSIGNAL);
[8933]84                        if(ret == 0) //connection closed
85                        {
[9230]86                                if(count - tmpcount != 0) return count - tmpcount;
[23091]87                                debug(250, "connection closed fd=%d, count=%d", fd, count - tmpcount);
[10381]88                                if(flag == 1) return -1;
89                                return 0;
[8933]90                        }
[8878]91                        if(ret < 0) //error
92                        {
[10569]93                                if(errno == EAGAIN && tout > 0)
94                                {
95                                        tout = tout - 1000;
96                                        usleep(1000);
97                                        goto retry;
98                                }
[10357]99                                perr("sock read data fd=%d", fd);
[8878]100                                return ret;
101                        }
102                        else
103                                tmpcount -= ret;
104                }
[10357]105                else if(ret == 0)
106                {
107                        debug(250, "sock timeout fd=%d", fd);
108                        return ret;
109                }
[8878]110                else
[10357]111                {
112                        perr("sock select fd=%d", fd);
[8933]113                        return ret;
[10357]114                }
[8507]115        }
[8878]116        return count;
[8507]117}
118
[9012]119void sockclose(int *fd)
[8933]120{
[9012]121        if(*fd != -1)
122                close(*fd);
123        *fd = -1;
124}
125
126int sockcheck(int *fd)
127{
[8933]128        int ret = 0;
129        unsigned char buf[1];
130
[9012]131        if(*fd < 0) return 1;
[8933]132
[10381]133        ret = sockread(*fd, buf, 0, 1, 0, 1);
[8933]134        if(ret < 0)
[9012]135        {
136                sockclose(fd);
[8933]137                return 1;
[9012]138        }
[8933]139
140        return 0;
141}
142
[9230]143int sockportopen(int *fd, char* ip, int port, int tout)
144{
145        int ret = 0, rest = 0, optval;
146        socklen_t optlen = sizeof(optval);
147        struct timeval timeout;
148        struct sockaddr_in cliaddr;
[14415]149       
150        if(ip == NULL) return 1;
151        sockclose(fd);
[9230]152
153        memset(&cliaddr, 0, sizeof(struct sockaddr_in));
154        cliaddr.sin_family = AF_INET;
155        cliaddr.sin_port = htons(port);
156
157        if((*fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
158        {
159                perr("open port socket");
160                return 1;
161        }
162
163        ret = inet_pton(AF_INET, ip, (void *)(&(cliaddr.sin_addr.s_addr)));
164        if(ret < 0)
165        {
166                sockclose(fd);
167                perr("Can't set remote->sin_addr.s_addr");
168                return 1;
169        }
170        else if(ret == 0)
171        {
172                sockclose(fd);
[14407]173                err("%s is not a valid IP address", ip);
[9230]174                return 1;
175        }
176
177        fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) | O_NONBLOCK);
178
[10357]179        if(tout == -1) tout = 3000 * 1000;
[9230]180        rest = tout % 1000000;
181        tout = (tout - rest) / 1000000;
182
183        fd_set wfds;
184
185        ret = connect(*fd, (struct sockaddr*) &cliaddr, sizeof(struct sockaddr));
186        if(ret < 0)
187        {
188                if(errno == EINTR || errno == EINPROGRESS)
189                {
190                        FD_ZERO(&wfds);
191                        FD_SET(*fd, &wfds);
192
193                        timeout.tv_sec = tout;
194                        timeout.tv_usec = rest;
195                       
[10380]196                        ret = TEMP_FAILURE_RETRY(select(*fd + 1, NULL, &wfds, NULL, &timeout));
[9230]197
198                        if(ret == 1 && FD_ISSET(*fd, &wfds))
199                        {
200                                ret = getsockopt(*fd, SOL_SOCKET, SO_ERROR, &optval, &optlen);
201                                if(ret == -1)   
202                                {
203                                        sockclose(fd);
204                                        return 1;
205                                }
206                                if(optval == 0) return 0;
207                                sockclose(fd);
208                                return 1;
209                        }
210                }
211                       
212                if(ret <= 0)
213                {
214                        perr("connect");
215                        sockclose(fd);
216                        return 1;
217                }
218        }
219        return 0;
220}
221
[9049]222int sockopen(int *fd, char* sockname, int check, int tout)
[8507]223{
[8879]224        sockclose(fd);
[8507]225
[9111]226        int ret = 0, rest = 0, optval;
[9049]227        socklen_t optlen = sizeof(optval);
228        struct timeval timeout;
[8507]229        struct sockaddr_un servaddr;
[8878]230        socklen_t len;
[8507]231
232        memset(&servaddr, 0, sizeof(struct sockaddr_un));
233        servaddr.sun_family = AF_UNIX;
234        strncpy(servaddr.sun_path, sockname, sizeof(servaddr.sun_path) - 1);
235        servaddr.sun_path[sizeof(servaddr.sun_path) - 1] = '\0';
[8878]236        len = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
[8507]237
[8878]238        if((*fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
[8507]239        {
[8933]240                if(check == 0)
241                {
242                        perr("open socket");
243                }
[8507]244                return 1;
245        }
246
[9049]247        fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) | O_NONBLOCK);
248
[10357]249        if(tout == -1) tout = 3000 * 1000;
[9111]250        rest = tout % 1000000;
251        tout = (tout - rest) / 1000000;
252
[9049]253        fd_set wfds;
254
255        ret = connect(*fd, (struct sockaddr*) &servaddr, len);
256        if(ret < 0)
[8507]257        {
[9049]258                if(errno == EINTR || errno == EINPROGRESS)
[8933]259                {
[9049]260                        FD_ZERO(&wfds);
261                        FD_SET(*fd, &wfds);
262
[9111]263                        timeout.tv_sec = tout;
264                        timeout.tv_usec = rest;
[9049]265                       
[10380]266                        ret = TEMP_FAILURE_RETRY(select(*fd + 1, NULL, &wfds, NULL, &timeout));
[9049]267
268                        if(ret == 1 && FD_ISSET(*fd, &wfds))
269                        {
270                                ret = getsockopt(*fd, SOL_SOCKET, SO_ERROR, &optval, &optlen);
[9230]271                                if(ret == -1)   
272                                {
273                                        sockclose(fd);
274                                        return 1;
275                                }
[9049]276                                if(optval == 0) return 0;
[9230]277                                sockclose(fd);
[9049]278                                return 1;
279                        }
[8933]280                }
[9049]281                       
282                if(ret <= 0)
283                {
284                        if(check == 0)
285                        {
286                                perr("connect");
287                        }
288                        sockclose(fd);
289                        return 1;
290                }
[8507]291        }
292        return 0;
293}
294
[9212]295int sockportcreate(int *fd, int port, int maxconn)
[8944]296{
297        struct sockaddr_in servaddr;
298        servaddr.sin_family = AF_INET;
299        servaddr.sin_port = htons(port);
300        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
301        int sockoptactive = 1, ret = 0;
302
303        if(!port) return 1;
304
305        if((*fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
306        {
307                perr("open socket");
308                return 1;
309        }
310
311        if(setsockopt(*fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&sockoptactive, sizeof (int)) < 0)
312        {
313                perr("network port %u open: error setsockopt", port);
314
315                sockclose(fd);
316                return 1;
317        }
318
319        while(1)
320        {
321                ret = bind(*fd, &servaddr, sizeof(servaddr));
322                if(ret < 0)
323                {
324                        if(errno == EINTR) continue;
325                        perr("bind");
326                        sockclose(fd);
327                        return 1;
328                }
329                break;
330        }
331
332        while(1)
333        {
[9212]334                ret = listen(*fd, maxconn);
[8944]335                if(ret < 0)
336                {
337                        if(errno == EINTR) continue;
338                        perr("listen");
339                        sockclose(fd);
340                        return 1;
341                }
342                break;
343        }
344
345        return ret;
346}
347
[9212]348int sockcreate(int *fd, char* sockname, int maxconn)
[8507]349{
[8879]350        sockclose(fd);
[8507]351
352        struct sockaddr_un servaddr;
[8878]353        socklen_t len;
354        int ret = 0;
[8507]355
356        memset(&servaddr, 0, sizeof(struct sockaddr_un));
357        servaddr.sun_family = AF_UNIX;
358        strncpy(servaddr.sun_path, sockname, sizeof(servaddr.sun_path) - 1);
359        servaddr.sun_path[sizeof(servaddr.sun_path) - 1] = '\0';
[8878]360        len = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
[8507]361        unlink(servaddr.sun_path);
362
[8878]363        if((*fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
[8507]364        {
365                perr("open socket");
366                return 1;
367        }
368
369        while(1)
370        {
[8878]371                ret = bind(*fd, &servaddr, len);
[8507]372                if(ret < 0)
373                {
374                        if(errno == EINTR) continue;
375                        perr("bind");
[8879]376                        sockclose(fd);
[8507]377                        return 1;
378                }
379                break;
380        }
381
382        while(1)
383        {
[9212]384                ret = listen(*fd, maxconn);
[8507]385                if(ret < 0)
386                {
387                        if(errno == EINTR) continue;
388                        perr("listen");
[8879]389                        sockclose(fd);
[8507]390                        return 1;
391                }
392                break;
393        }
394
[8878]395        return ret;
[8507]396}
397
[8944]398//flag 0 = in blocking mode
399//flag 1 = in non blocking mode
400int sockaccept(int *fd, int flag)
[8507]401{
[9212]402        struct sockaddr_in cliaddr;
403        socklen_t clilen = sizeof(cliaddr);
[8878]404        int ret = 0;
[8507]405
[8944]406        if(*fd < 0) return -1;
407
408        while(1)
[8507]409        {
[8933]410                ret = accept(*fd, &cliaddr, &clilen);
[8878]411                if(ret < 0)
412                {
413                        if(errno == EINTR) continue;
414                        perr("accept");
[9049]415                        if(flag == 0 || (flag == 1 && errno != EAGAIN))
416                                sockclose(fd);
[8944]417                        return -1;
[8878]418                }
419                break;
[8507]420        }
421
[8878]422        return ret;
[8507]423}
424
[8933]425int socksend(int *fd, unsigned char* data, int count, int timeout)
[8507]426{
[8878]427        int ret = 0;
[8507]428
[8933]429        if(*fd == -1) return 1;
[8878]430       
[8933]431        ret = sockwrite(*fd, data, count, timeout);
[8878]432        if(ret < 0)
[8507]433        {
[8933]434                sockclose(fd);
[8507]435                return 1;
436        }
437        return 0;
438}
439
[8933]440int sockreceive(int *fd, unsigned char* data, int count, int timeout)
[8507]441{
[8878]442        int ret = 0;
[8507]443
[8933]444        if(*fd == -1) return 1;
[8507]445
[10381]446        ret = sockread(*fd, data, 0, count, timeout, 0);
[9132]447        if(ret <= 0)
[8878]448        {
[8933]449                sockclose(fd);
[8878]450                return 1;
451        }
[8507]452        return 0;
453}
454
455char *get_ip(char *host)
456{
[14597]457        struct hostent hent;
458        struct hostent *result = NULL;
[20466]459        int ret = 0, err = 0, iplen = 16, ext = 0;
460        char *ip = NULL, *buf = NULL, *tmpstr = NULL;
[8507]461
[9230]462        if(host == NULL) return NULL;
463
[19467]464        ip = calloc(1, iplen);
[8507]465        if(ip == NULL)
466        {
467                err("no mem");
468                return NULL;
469        }
470
[19467]471        buf = calloc(1, MINMALLOC);
[14597]472        if(buf == NULL)
[8507]473        {
[14597]474                err("no mem");
[8507]475                free(ip);
[14597]476                return NULL;
477        }
478
479        ret = gethostbyname_r(host, &hent, buf, MINMALLOC, &result, &err);
480        //if((hent = gethostbyname(host)) == NULL)
481        if(ret != 0 || result == NULL)
482        {
[20469]483                free(ip); ip = NULL;
484                free(buf); buf = NULL;
[20466]485                //workaround: if resolv.conf is changed, titan mußt stopped, so gethostbyname read resolv.conf new
486                //the external tool read resolv.conf on each start
487                err("can't get ip, test with extern tool (%s)", host);
488
[20468]489                tmpstr = ostrcat("getip ", host, 0, 0);
[20466]490                ip = command(tmpstr);
491                free(tmpstr); tmpstr = NULL;
492                if(ip == NULL)
493                {
494                        err("can't get ip (%s)", host);
495                        return NULL;
496                }
497                ext = 1;
[8507]498        }
499
500        //snprintf(ip, iplen, "%s", inet_ntoa(*((struct in_addr*)hent->h_addr)));
[14597]501        //snprintf(ip, iplen, "%s", inet_ntoa(*((struct in_addr*)result->h_addr)));
[20466]502
503        if(ext == 0)
[8507]504        {
[20466]505                //if(inet_ntop(AF_INET, (void *)hent->h_addr_list[0], ip, iplen) == NULL)
506                if(inet_ntop(AF_INET, (void *)result->h_addr_list[0], ip, iplen) == NULL)
507                {
508                        free(ip);
509                        free(buf);
510                        perr("can't resolve host");
511                        return NULL;
512                }
[8507]513        }
514
[14597]515        free(buf);
[8507]516        return ip;
517}
518
[12866]519char* createhttpheader(char *host, char *page, char* auth)
[8507]520{
[12866]521        char *query = NULL;
[8507]522        char *getpage = page;
523
[18397]524        if(getpage != NULL)
525        {
526                if(getpage[0] == '/')
527                        getpage = getpage + 1;
528        }
[12866]529
530        query = ostrcat("GET /", getpage, 0, 0);
[19036]531        query = ostrcat(query, " HTTP/1.0\r\nHost: ", 1, 0);
[12866]532        query = ostrcat(query, host, 1, 0);
533        query = ostrcat(query, "\r\nUser-Agent: ", 1, 0);
[18368]534        //query = ostrcat(query, PROGNAME, 1, 0);
[18369]535        query = ostrcat(query, "Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.99 Safari/535.1", 1, 0);
[12866]536        if(auth != NULL)
[8507]537        {
[12866]538                query = ostrcat(query, "\r\nAuthorization: Basic ", 1, 0);
539                query = ostrcat(query, auth, 1, 0);
[8507]540        }
[18356]541        query = ostrcat(query, "\r\nConnection: close", 1, 0);
[12866]542        query = ostrcat(query, "\r\n\r\n", 1, 0);
[9230]543
[8507]544        return query;
545}
546
[14073]547int checkhttpheader(char* tmpbuf, char** retstr)
[8507]548{
[14073]549        int stat = 0;
550        char* tmppos = NULL, *tmpstr = NULL;
551
[14573]552        if(tmpbuf == NULL) return 0;
[14073]553
554        tmpstr = malloc(MINMALLOC);
555        if(tmpstr == NULL)
556        {
557                err("no mem");
558                return 0;
559        }
560
[16471]561        tmppos = ostrstr(tmpbuf, "HTTP/1.1 ");
[14073]562        if(tmppos != NULL)
563        {
564                sscanf(tmppos, "HTTP/1.1 %s ", tmpstr);
565                if(tmpstr != NULL)
566                {
567                        stat = atoi(tmpstr);
568                        tmpstr[0] = '\0';
569                }
570        }
571
[14475]572        if(stat == 301 || stat == 302) // Redirect
[14073]573        {
[16471]574                tmppos = ostrstr(tmpbuf, "Location: ");
[14073]575                if(tmppos != NULL)
576                {
577                        sscanf(tmppos, "Location: %s", tmpstr);
578                        if(tmpstr != NULL)
579                                *retstr = ostrcat(tmpstr, NULL, 0, 0);
580                }
581        }
582
583        free(tmpstr); tmpstr = NULL;
584        return stat;
585}
586
[18366]587//flag 0: output without header
588//flag 1: output with header
[24220]589//flag 2: output only header
[19839]590char* gethttpreal(char* host, char* page, int port, char* filename, char* auth, struct download* dnode, int redirect, char* header, long* clen, int timeout, int flag)
[14073]591{
[17832]592        int sock = -1, ret = 0, count = 0, hret = 0, freeheader = 0;
[18366]593        int headerlen = 0;
[9230]594        unsigned int len = 0, maxret = 0;
[17832]595        char *ip = NULL;
[8507]596        char *tmpbuf = NULL, *buf = NULL;
[14073]597        char *tmppage = "/", *retstr = NULL;
[8507]598        FILE *fd = NULL;
599       
600        if(filename != NULL)
601        {
602                fd = fopen(filename, "wb");
603                if(fd == NULL)
604                {
[14407]605                        err("can't open file %s", filename);
[9230]606                        if(dnode != NULL) dnode->ret = 1;
[8507]607                        return NULL;
608                }
609        }
610
[9230]611        if(page == NULL) page = tmppage;
[8507]612
613        ip = get_ip(host);
614        if(ip == NULL)
615        {
[14407]616                err("can't get ip");
[8507]617                if(fd != NULL)
618                {
619                        fclose(fd);
620                        unlink(filename);
621                }
[9230]622                if(dnode != NULL) dnode->ret = 1;
[8507]623                return NULL;
624        }
625
[19839]626        ret = sockportopen(&sock, ip, port, timeout * 1000);
[9230]627        if(ret != 0)
[8507]628        {
629                if(fd != NULL)
630                {
631                        fclose(fd);
632                        unlink(filename);
633                }
[9230]634                free(ip);
635                if(dnode != NULL) dnode->ret = 1;
[8507]636                return NULL;
637        }
[9230]638        free(ip);
639
640        if(dnode != NULL) dnode->connfd = sock;
[17832]641        if(header == NULL)
642        {
643                header = createhttpheader(host, page, auth);
644                freeheader = 1;
645        }
[9230]646
647        //Send the query to the server
[19839]648        ret = socksend(&sock, (unsigned char*)header, strlen(header), timeout * 1000);
[9230]649        if(ret != 0)
[8507]650        {
[9230]651                perr("can't send query");
[8507]652                if(fd != NULL)
653                {
654                        fclose(fd);
655                        unlink(filename);
656                }
[17832]657                if(freeheader == 1) free(header);
[9230]658                if(dnode != NULL) dnode->ret = 1;
[8507]659                return NULL;
660        }
[17832]661        if(freeheader == 1) free(header);
[15948]662
[9230]663        //now it is time to receive the page
[19467]664        tmpbuf = calloc(1, MINMALLOC);
[9230]665        if(tmpbuf == NULL)
[8507]666        {
667                if(fd != NULL)
668                {
669                        fclose(fd);
670                        unlink(filename);
671                }
[9230]672                sockclose(&sock);
673                err("no mem");
674                if(dnode != NULL) dnode->ret = 1;
[8507]675                return NULL;
676        }
677
[9230]678        //read one line
679        char* pbuf = tmpbuf;
680        while(pbuf - tmpbuf < MINMALLOC)
681        {
682                unsigned char c;
[8507]683
[19839]684                ret = sockreceive(&sock, &c, 1, timeout * 1000);
[9230]685                if(ret != 0)
[8507]686                {
[9230]687                        err("no client data in buffer");
688                        break;
[8507]689                }
[9230]690
691                *pbuf = c;
[18366]692                headerlen++;
[9230]693
[16492]694                if(tmpbuf != NULL && (ostrstr(tmpbuf, "\n\n") != NULL || ostrstr(tmpbuf, "\r\n\r\n") != NULL))
[14073]695                {
696                        hret = checkhttpheader(tmpbuf, &retstr);
[14475]697                        if(hret == 301 || hret == 302) goto end;
[9230]698                        break;
[14073]699                }
[9230]700                pbuf++;
[8507]701        }
702
[24220]703        if(flag == 3)
704        {
705                if(headerlen > 0)
706                {
707                        count = headerlen;
708                        headerlen = 0;
709                        if(filename != NULL)
710                                fwrite(tmpbuf, count, 1, fd);
711                        else
712                        {
713                                buf = realloc(buf, count);
714                                memcpy(buf, tmpbuf, count);
715                        }
716                }
717       
718                goto end;
719        }
720
[9230]721        //TODO: case-sens check
[16471]722        char* contentlen = ostrstr(tmpbuf, "Content-Length:");
[9230]723        if(contentlen != NULL)
[8507]724        {
[9230]725                contentlen += 15;
726                len = strtoul(contentlen, NULL, 10);
[8507]727        }
728
[18366]729        if(flag == 0) headerlen = 0;
[19839]730        while((ret = sockread(sock, (unsigned char*)tmpbuf + headerlen, 0, MINMALLOC - headerlen, timeout * 1000, 0)) > 0)
[8507]731        {
[9230]732                maxret += ret;
733                if(len > 0)
[8507]734                {
[9230]735                        if(dnode != NULL)
[8507]736                        {
[9230]737                                dnode->proz = (int)ceil((((float)maxret / len) * 100));
738                                dnode->maxkb = len;
739                                dnode->aktkb = maxret;
[8507]740                        }
741                }
[9230]742
[18366]743                ret += headerlen;
744                headerlen = 0;
[9230]745                if(filename != NULL)
746                        fwrite(tmpbuf, ret, 1, fd);
[8507]747                else
748                {
[9230]749                        count = count + ret;
750                        buf = realloc(buf, count);
751                        memcpy(buf + count - ret, tmpbuf, ret);
[8507]752                }
[9230]753                memset(tmpbuf, 0, ret);
[8507]754        }
[9230]755        if(ret < 0)
[8507]756        {
[9230]757                perr("receiving data");
[8507]758                if(fd != NULL)
759                {
760                        fclose(fd);
761                        unlink(filename);
762                }
[9230]763                sockclose(&sock);
764                free(buf);
765                free(tmpbuf);
766                if(dnode != NULL) dnode->ret = 1;
[21620]767
[8507]768                return NULL;
769        }
770
[14073]771end:
[8507]772        free(tmpbuf);
773        if(fd != NULL) fclose(fd);
[9230]774        sockclose(&sock);
[8507]775
776        if(filename == NULL)
777        {
778                buf = realloc(buf, count + 1);
779                buf[count] = '\0';
780        }
781
[14475]782        if((hret == 301 || hret == 302) && retstr != NULL && redirect < 3) //redirect
[14073]783        {
784                char* pos = NULL, *rpage = NULL;
[18356]785                char* rhost = NULL;
[14073]786
[18356]787                if(strchr(retstr, '/') == retstr)
[14073]788                {
[18356]789                        rhost = ostrcat(host, NULL, 0, 0);
790                        rpage = retstr;
[14073]791                }
[18356]792                else
793                {
794                        rhost = string_replace("http://", "", retstr, 0);
[14073]795
[18356]796                        if(rhost != NULL)
797                                pos = strchr(rhost, '/');
798                        if(pos != NULL)
799                        {
800                                pos[0] = '\0';
801                                rpage = pos + 1;
802                        }
[14073]803                }
804
805                redirect++;
806                free(buf); buf = NULL;
[19839]807                buf = gethttpreal(rhost, rpage, port, filename, auth, dnode, redirect, NULL, clen, timeout, flag);
[18356]808                free(rhost); rhost = NULL;
[14073]809        }
810
[17832]811        if(clen != 0) *clen = maxret;
[9230]812        if(dnode != NULL) dnode->ret = 0;
[14073]813        free(retstr); retstr = NULL;
[21620]814
815        if(filename == NULL)
816                return buf;
817        else
818                return "0";
[8507]819}
820
[19884]821char* gethttp(char* host, char* page, int port, char* filename, char* auth, int timeout, struct download* dnode, int redirect)
[17832]822{
[19884]823        return gethttpreal(host, page, port, filename, auth, dnode, redirect, NULL, NULL, timeout, 0);
[17832]824}
825
[9230]826void gethttpstruct(struct stimerthread* timernode, struct download* node, int flag)
827{
828        if(node != NULL)
[19884]829                gethttp(node->host, node->page, node->port, node->filename, node->auth, node->timeout, node, 0);
[9230]830}
831
[20906]832void gethttpstructmsg(struct stimerthread* timernode, struct download* node, int flag)
833{
834        char* tmpstr = NULL;
835
836        if(node != NULL)
837        {
838                gethttp(node->host, node->page, node->port, node->filename, node->auth, node->timeout, node, 0);
839                tmpstr = ostrcat(_("Download finished!"), "\n\n", 0, 0);
840                tmpstr = ostrcat(tmpstr, node->filename, 1, 0);
841                textbox(_("Message"), tmpstr, _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 1100, 300, 7, 0);
842
843                free(tmpstr); tmpstr = NULL;
844        }
845}
846
[20736]847int sendmail(char* host, char* mailfrom, char* mailto, char* subject, int port, char* filename, char* string, int rtimeout, int wtimeout)
848{
849        int sock = -1, ret = 0;
850        char *ip = NULL, *tmpstr = NULL, *sendstr = NULL, *data = NULL;
851
852        if(filename == NULL && string == NULL) return 1;
853
854        ip = get_ip(host);
855        if(ip == NULL)
856        {
857                err("can't get ip");
858                return 1;
859        }
860
861        data = malloc(MINMALLOC);
862        if(data == NULL)
863        {
864                err("no memory");
865                return 1;
866        }
867
868        if(filename != NULL)
869                tmpstr = readfiletomem(filename, 0);
870        else if(string != NULL)
871                tmpstr = string;
872
873        //open connection
874        ret = sockportopen(&sock, ip, port, wtimeout);
875        if(ret != 0) goto end;
876
877        //wait for smtp answer
878        memset(data, 0, MINMALLOC);
879        sockread(sock, (unsigned char*)data, 0, MINMALLOC, wtimeout, 0);
880        debug(975, "rcv: %s", data);
881/*
882        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
883        {
884                debug(975, "incorrect answer: %s", data);
885                ret = 1;
886                goto end;
887        }
888*/
889
890        //send helo
891        ret = 1;
892        sendstr = ostrcat(sendstr, "HELO nit.at\r\n", 1, 0);
893        debug(975, "send: %s", sendstr);
894        if(sendstr != NULL)
895                ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
896        free(sendstr); sendstr = NULL;
897        if(ret != 0) goto end;
898
899        //wait for smtp answer
900        memset(data, 0, MINMALLOC);
901        sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
902        debug(975, "rcv: %s", data);
903        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
904        {
905                debug(975, "incorrect answer: %s", data);
906                ret = 1;
907                goto end;
908        }
909
910        //send mail from:
911        ret = 1;
912        sendstr = ostrcat(sendstr, "MAIL FROM:<", 1, 0);
913        sendstr = ostrcat(sendstr, mailfrom, 1, 0);
914        sendstr = ostrcat(sendstr, ">\r\n", 1, 0);
915        debug(975, "send: %s", sendstr);
916        if(sendstr != NULL)
917                ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
918        free(sendstr); sendstr = NULL;
919        if(ret != 0) goto end;
920
921        //wait for smtp answer
922        memset(data, 0, MINMALLOC);
923        sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
924        debug(975, "rcv: %s", data);
925        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
926        {
927                debug(975, "incorrect answer: %s", data);
928                ret = 1;
929                goto end;
930        }
931
932        //send rcpt to:
933        ret = 1;
934        sendstr = ostrcat(sendstr, "RCPT TO:<", 1, 0);
935        sendstr = ostrcat(sendstr, mailto, 1, 0);
936        sendstr = ostrcat(sendstr, ">\r\n", 1, 0);
937        debug(975, "send: %s", sendstr);
938        if(sendstr != NULL)
939                ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
940        free(sendstr); sendstr = NULL;
941        if(ret != 0) goto end;
942
943        //wait for smtp answer
944        memset(data, 0, MINMALLOC);
945        sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
946        debug(975, "rcv: %s", data);
947        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
948        {
949                debug(975, "incorrect answer: %s", data);
950                ret = 1;
951                goto end;
952        }
953
954        //send data
955        ret = 1;
956        sendstr = ostrcat(sendstr, "DATA\r\n", 1, 0);
957        debug(975, "send: %s", sendstr);
958        if(sendstr != NULL)
959                ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
960        free(sendstr); sendstr = NULL;
961        if(ret != 0) goto end;
962
963        //wait for smtp answer
964        memset(data, 0, MINMALLOC);
965        sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
966        debug(975, "rcv: %s", data);
967        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
968        {
969                debug(975, "incorrect answer: %s", data);
970                ret = 1;
971                goto end;
972        }
973
974        //send content
975        ret = 1;
976
977        sendstr = ostrcat(sendstr, "From: ", 1, 0);
978        sendstr = ostrcat(sendstr, mailfrom, 1, 0);
979        sendstr = ostrcat(sendstr, "\r\n", 1, 0);
980
981        sendstr = ostrcat(sendstr, "To: ", 1, 0);
982        sendstr = ostrcat(sendstr, mailto, 1, 0);
983        sendstr = ostrcat(sendstr, "\r\n", 1, 0);
984
985        sendstr = ostrcat(sendstr, "Subject: ", 1, 0);
986        sendstr = ostrcat(sendstr, subject, 1, 0);
987        sendstr = ostrcat(sendstr, "\r\n", 1, 0);
988
989        sendstr = ostrcat(sendstr, "Content-Type: text/plain\r\n\r\n", 1, 0);
990
991        sendstr = ostrcat(sendstr, tmpstr, 1, 0);
992        sendstr = ostrcat(sendstr, "\r\n.\r\n", 1, 0);
993
994        debug(975, "send: %s", sendstr);
995        if(sendstr != NULL)
996                ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
997        free(sendstr); sendstr = NULL;
998        if(ret != 0) goto end;
999
1000        //wait for smtp answer
1001        memset(data, 0, MINMALLOC);
1002        sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
1003        debug(975, "rcv: %s", data);
1004        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
1005        {
1006                debug(975, "incorrect answer: %s", data);
1007                ret = 1;
1008                goto end;
1009        }
1010
1011        //send quit
1012        ret = 1;
1013        sendstr = ostrcat(sendstr, "QUIT\r\n", 1, 0);
1014        debug(975, "send: %s", sendstr);
1015        if(sendstr != NULL)
1016                ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
1017        free(sendstr); sendstr = NULL;
1018        if(ret != 0) goto end;
1019
1020        //wait for smtp answer
1021        memset(data, 0, MINMALLOC);
1022        sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
1023        debug(975, "rcv: %s", data);
1024        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
1025        {
1026                debug(975, "incorrect answer: %s", data);
1027                ret = 1;
1028                goto end;
1029        }
1030
1031end:
1032        if(filename != NULL)
1033                free(tmpstr);
1034        tmpstr = NULL;
1035        return ret;
1036}
1037
[8507]1038#endif
Note: See TracBrowser for help on using the repository browser.