source: titan/titan/sock.h @ 41541

Last change on this file since 41541 was 41541, checked in by obi, 4 years ago

six

File size: 23.5 KB
Line 
1#ifndef SOCK_H
2#define SOCK_H
3
4int sockwrite(int fd, unsigned char* buf, int count, int tout)
5{
6        struct timeval timeout;
7        int ret = 0, usec = 0, sec = 0, tmpcount = count;
8        unsigned char* buffer = NULL;
9
10        if(fd < 0) return -1;
11
12        if(tout == -1) tout = 3000 * 1000;
13        usec = tout % 1000000;
14        sec = (tout - usec) / 1000000;
15
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);
22                if(ret < 0)
23                {
24                        if(errno == EINTR || errno == EAGAIN)
25                        {
26                                FD_ZERO(&wfds);
27                                FD_SET(fd, &wfds);
28                       
29                                timeout.tv_sec = sec;
30                                timeout.tv_usec = usec;
31                       
32                                ret = TEMP_FAILURE_RETRY(select(fd + 1, NULL, &wfds, NULL, &timeout));
33                        }
34                       
35                        if(ret == 0)
36                        {
37                                perr("sock send timed out fd=%d", fd);
38                                return -1;
39                        }
40                        if(ret < 0)
41                        {
42                                perr("sock send data fd=%d", fd);
43                                return -1;
44                        }
45                }
46                else
47                        tmpcount -= ret;
48        }
49
50        return count;
51}
52
53//flag 0: normal
54//flag 1: from check
55int sockread(int fd, unsigned char *buf, int pos, int count, int tout, int flag)
56{
57        struct timeval timeout;
58        int ret = 0, usec = 0, sec = 0, tmpcount = count;
59        unsigned char* buffer = NULL;
60
61        if(fd < 0) return -1;
62
63        if(tout == -1) tout = 3000 * 1000;
64        usec = tout % 1000000;
65        sec = (tout - usec) / 1000000;
66
67        fd_set rfds;
68
69        while(tmpcount > 0)
70        {
71                FD_ZERO(&rfds);
72                FD_SET(fd, &rfds);
73               
74                timeout.tv_sec = sec;
75                timeout.tv_usec = usec;
76               
77                ret = TEMP_FAILURE_RETRY(select(fd + 1, &rfds , NULL, NULL, &timeout));
78                       
79                if(ret == 1)
80                {
81                        buffer = buf + (count - tmpcount);
82retry:
83                        ret = recv(fd, buffer, tmpcount, MSG_DONTWAIT | MSG_NOSIGNAL);
84                        if(ret == 0) //connection closed
85                        {
86                                if(count - tmpcount != 0) return count - tmpcount;
87                                debug(250, "connection closed fd=%d, count=%d", fd, count - tmpcount);
88                                if(flag == 1) return -1;
89                                return 0;
90                        }
91                        if(ret < 0) //error
92                        {
93                                if(errno == EAGAIN && tout > 0)
94                                {
95                                        tout = tout - 1000;
96                                        usleep(1000);
97                                        goto retry;
98                                }
99                                perr("sock read data fd=%d", fd);
100                                return ret;
101                        }
102                        else
103                                tmpcount -= ret;
104                }
105                else if(ret == 0)
106                {
107                        debug(250, "sock timeout fd=%d", fd);
108                        return ret;
109                }
110                else
111                {
112                        perr("sock select fd=%d", fd);
113                        return ret;
114                }
115        }
116        return count;
117}
118
119void sockclose(int *fd)
120{
121        if(*fd != -1)
122                close(*fd);
123        *fd = -1;
124}
125
126int sockcheck(int *fd)
127{
128        int ret = 0;
129        unsigned char buf[1];
130
131        if(*fd < 0) return 1;
132
133        ret = sockread(*fd, buf, 0, 1, 0, 1);
134        if(ret < 0)
135        {
136                sockclose(fd);
137                return 1;
138        }
139
140        return 0;
141}
142
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;
149       
150        if(ip == NULL) return 1;
151        sockclose(fd);
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);
173                err("%s is not a valid IP address", ip);
174                return 1;
175        }
176
177        fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) | O_NONBLOCK);
178
179        if(tout == -1) tout = 3000 * 1000;
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                       
196                        ret = TEMP_FAILURE_RETRY(select(*fd + 1, NULL, &wfds, NULL, &timeout));
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
222int sockopen(int *fd, char* sockname, int check, int tout)
223{
224        sockclose(fd);
225
226        int ret = 0, rest = 0, optval;
227        socklen_t optlen = sizeof(optval);
228        struct timeval timeout;
229        struct sockaddr_un servaddr;
230        socklen_t len;
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';
236        len = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
237
238        if((*fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
239        {
240                if(check == 0)
241                {
242                        perr("open socket");
243                }
244                return 1;
245        }
246
247        fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) | O_NONBLOCK);
248
249        if(tout == -1) tout = 3000 * 1000;
250        rest = tout % 1000000;
251        tout = (tout - rest) / 1000000;
252
253        fd_set wfds;
254
255        ret = connect(*fd, (struct sockaddr*) &servaddr, len);
256        if(ret < 0)
257        {
258                if(errno == EINTR || errno == EINPROGRESS)
259                {
260                        FD_ZERO(&wfds);
261                        FD_SET(*fd, &wfds);
262
263                        timeout.tv_sec = tout;
264                        timeout.tv_usec = rest;
265                       
266                        ret = TEMP_FAILURE_RETRY(select(*fd + 1, NULL, &wfds, NULL, &timeout));
267
268                        if(ret == 1 && FD_ISSET(*fd, &wfds))
269                        {
270                                ret = getsockopt(*fd, SOL_SOCKET, SO_ERROR, &optval, &optlen);
271                                if(ret == -1)   
272                                {
273                                        sockclose(fd);
274                                        return 1;
275                                }
276                                if(optval == 0) return 0;
277                                sockclose(fd);
278                                return 1;
279                        }
280                }
281                       
282                if(ret <= 0)
283                {
284                        if(check == 0)
285                        {
286                                perr("connect");
287                        }
288                        sockclose(fd);
289                        return 1;
290                }
291        }
292        return 0;
293}
294
295int sockportcreate(int *fd, int port, int maxconn)
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        {
334                ret = listen(*fd, maxconn);
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
348int sockcreate(int *fd, char* sockname, int maxconn)
349{
350        sockclose(fd);
351
352        struct sockaddr_un servaddr;
353        socklen_t len;
354        int ret = 0;
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';
360        len = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
361        unlink(servaddr.sun_path);
362
363        if((*fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
364        {
365                perr("open socket");
366                return 1;
367        }
368
369        while(1)
370        {
371                ret = bind(*fd, &servaddr, len);
372                if(ret < 0)
373                {
374                        if(errno == EINTR) continue;
375                        perr("bind");
376                        sockclose(fd);
377                        return 1;
378                }
379                break;
380        }
381
382        while(1)
383        {
384                ret = listen(*fd, maxconn);
385                if(ret < 0)
386                {
387                        if(errno == EINTR) continue;
388                        perr("listen");
389                        sockclose(fd);
390                        return 1;
391                }
392                break;
393        }
394
395        return ret;
396}
397
398//flag 0 = in blocking mode
399//flag 1 = in non blocking mode
400int sockaccept(int *fd, int flag)
401{
402        struct sockaddr_in cliaddr;
403        socklen_t clilen = sizeof(cliaddr);
404        int ret = 0;
405
406        if(*fd < 0) return -1;
407
408        while(1)
409        {
410                ret = accept(*fd, &cliaddr, &clilen);
411                if(ret < 0)
412                {
413                        if(errno == EINTR) continue;
414                        perr("accept");
415                        if(flag == 0 || (flag == 1 && errno != EAGAIN))
416                                sockclose(fd);
417                        return -1;
418                }
419                break;
420        }
421
422        return ret;
423}
424
425int socksend(int *fd, unsigned char* data, int count, int timeout)
426{
427        int ret = 0;
428
429        if(*fd == -1) return 1;
430       
431        ret = sockwrite(*fd, data, count, timeout);
432        if(ret < 0)
433        {
434                sockclose(fd);
435                return 1;
436        }
437        return 0;
438}
439
440int sockreceive(int *fd, unsigned char* data, int count, int timeout)
441{
442        int ret = 0;
443
444        if(*fd == -1) return 1;
445
446        ret = sockread(*fd, data, 0, count, timeout, 0);
447        if(ret <= 0)
448        {
449                sockclose(fd);
450                return 1;
451        }
452        return 0;
453}
454
455char *get_ip(char *host)
456{
457        struct hostent hent;
458        struct hostent *result = NULL;
459        int ret = 0, err = 0, iplen = 16, ext = 0;
460        char *ip = NULL, *buf = NULL, *tmpstr = NULL;
461
462        if(host == NULL) return NULL;
463
464        ip = calloc(1, iplen);
465        if(ip == NULL)
466        {
467                err("no mem");
468                return NULL;
469        }
470
471        buf = calloc(1, MINMALLOC);
472        if(buf == NULL)
473        {
474                err("no mem");
475                free(ip);
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        {
483                free(ip); ip = NULL;
484                free(buf); buf = NULL;
485                //workaround: if resolv.conf is changed, titan must 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
489                tmpstr = ostrcat("getip ", host, 0, 0);
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;
498        }
499
500        //snprintf(ip, iplen, "%s", inet_ntoa(*((struct in_addr*)hent->h_addr)));
501        //snprintf(ip, iplen, "%s", inet_ntoa(*((struct in_addr*)result->h_addr)));
502
503        if(ext == 0)
504        {
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                }
513        }
514
515        free(buf);
516        return ip;
517}
518
519char* createhttpheader(char *host, char *page, char* auth)
520{
521        char *query = NULL;
522        char *getpage = page;
523
524        if(getpage != NULL)
525        {
526                if(getpage[0] == '/')
527                        getpage = getpage + 1;
528        }
529
530        query = ostrcat("GET /", getpage, 0, 0);
531        query = ostrcat(query, " HTTP/1.0\r\nHost: ", 1, 0);
532        query = ostrcat(query, host, 1, 0);
533        query = ostrcat(query, "\r\nUser-Agent: ", 1, 0);
534        //query = ostrcat(query, PROGNAME, 1, 0);
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);
536        if(auth != NULL)
537        {
538                query = ostrcat(query, "\r\nAuthorization: Basic ", 1, 0);
539                query = ostrcat(query, auth, 1, 0);
540        }
541        query = ostrcat(query, "\r\nConnection: close", 1, 0);
542        query = ostrcat(query, "\r\n\r\n", 1, 0);
543
544        return query;
545}
546
547int checkhttpheader(char* tmpbuf, char** retstr)
548{
549        int stat = 0;
550        char* tmppos = NULL, *tmpstr = NULL;
551
552        if(tmpbuf == NULL) return 0;
553
554        tmpstr = malloc(MINMALLOC);
555        if(tmpstr == NULL)
556        {
557                err("no mem");
558                return 0;
559        }
560
561        tmppos = ostrstr(tmpbuf, "HTTP/1.1 ");
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
572        if(stat == 301 || stat == 302) // Redirect
573        {
574                tmppos = ostrstr(tmpbuf, "Location: ");
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
587unsigned long getchunkedlen(int sock, int timeout)
588{
589        unsigned long len = 0;
590        int ret = 0;
591        char chunked[16] = {'\0'};
592        int chunkedid = 0;
593
594        while(chunkedid < 15)
595        {
596                unsigned char c = '\0';
597
598                ret = sockreceive(&sock, &c, 1, timeout * 1000);
599                if(ret != 0)
600                {
601                        printf("no client data in buffer");
602                        break;
603                }
604                if(c == ';') break;
605
606                chunked[chunkedid] = c;
607                chunkedid++;
608                if(chunkedid > 2 && c == '\n')
609                        break;
610        }
611
612        len = strtol(chunked, NULL, 16);
613        debug(88, "chunkedlen=%u", len);
614        return len;
615}
616
617//flag 0: output without header
618//flag 1: output with header
619//flag 2: output only header
620char* gethttpreal(char* host, char* page, int port, char* filename, char* auth, struct download* dnode, int redirect, char* header, long* clen, int timeout, int flag)
621{
622        int sock = -1, ret = 0, count = 0, hret = 0, freeheader = 0, gzip = 0;
623        int headerlen = 0, chunkedlen = 0, chunked = 0, readsize = 0;
624        unsigned int len = 0, maxret = 0;
625        char *ip = NULL;
626        char *tmpbuf = NULL, *buf = NULL;
627        char *tmppage = "/", *retstr = NULL;
628        FILE *fd = NULL;
629       
630        if(filename != NULL)
631        {
632                fd = fopen(filename, "wb");
633                if(fd == NULL)
634                {
635                        err("can't open file %s", filename);
636                        if(dnode != NULL) dnode->ret = 1;
637                        return NULL;
638                }
639        }
640
641        if(page == NULL) page = tmppage;
642
643        ip = get_ip(host);
644        if(ip == NULL)
645        {
646                err("can't get ip");
647                if(fd != NULL)
648                {
649                        fclose(fd);
650                        unlink(filename);
651                }
652                if(dnode != NULL) dnode->ret = 1;
653                return NULL;
654        }
655
656        ret = sockportopen(&sock, ip, port, timeout * 1000);
657        if(ret != 0)
658        {
659                if(fd != NULL)
660                {
661                        fclose(fd);
662                        unlink(filename);
663                }
664                free(ip);
665                if(dnode != NULL) dnode->ret = 1;
666                return NULL;
667        }
668        free(ip);
669
670        if(dnode != NULL) dnode->connfd = sock;
671        if(header == NULL)
672        {
673                header = createhttpheader(host, page, auth);
674                freeheader = 1;
675        }
676
677        //Send the query to the server
678        ret = socksend(&sock, (unsigned char*)header, strlen(header), timeout * 1000);
679        if(ret != 0)
680        {
681                perr("can't send query");
682                if(fd != NULL)
683                {
684                        fclose(fd);
685                        unlink(filename);
686                }
687                if(freeheader == 1) free(header);
688                if(dnode != NULL) dnode->ret = 1;
689                return NULL;
690        }
691        if(freeheader == 1) free(header);
692
693        //now it is time to receive the page
694        tmpbuf = calloc(1, MINMALLOC);
695        if(tmpbuf == NULL)
696        {
697                if(fd != NULL)
698                {
699                        fclose(fd);
700                        unlink(filename);
701                }
702                sockclose(&sock);
703                err("no mem");
704                if(dnode != NULL) dnode->ret = 1;
705                return NULL;
706        }
707
708        //read one line
709        char* pbuf = tmpbuf;
710        while(pbuf - tmpbuf < MINMALLOC)
711        {
712                unsigned char c = '\0';
713
714                ret = sockreceive(&sock, &c, 1, timeout * 1000);
715                if(ret != 0)
716                {
717                        err("no client data in buffer");
718                        break;
719                }
720
721                *pbuf = c;
722                headerlen++;
723
724                if(tmpbuf != NULL && (ostrstr(tmpbuf, "\n\n") != NULL || ostrstr(tmpbuf, "\r\n\r\n") != NULL))
725                {
726                        hret = checkhttpheader(tmpbuf, &retstr);
727                        if(hret == 301 || hret == 302) goto end;
728                        break;
729                }
730                pbuf++;
731        }
732       
733        debug(88, "-----------------------------------------------------------------");
734        debug(88, "host: %s page: %s", host, page);
735        debug(88, "header: %s", tmpbuf);
736        debug(88, "-----------------------------------------------------------------");
737
738        if(flag == 2)
739        {
740                if(headerlen > 0)
741                {
742                        count = headerlen;
743                        headerlen = 0;
744                        if(filename != NULL)
745                                fwrite(tmpbuf, count, 1, fd);
746                        else
747                        {
748                                buf = realloc(buf, count);
749                                if(buf != NULL)
750                                        memcpy(buf, tmpbuf, count);
751                        }
752                }
753       
754                goto end;
755        }
756       
757        if(flag == 0) headerlen = 0;
758
759        char* contentlen = ostrstrcase(tmpbuf, "Content-Length:");
760        if(contentlen != NULL)
761        {
762                contentlen += 15;
763                len = strtoul(contentlen, NULL, 10);
764        }
765       
766        if(filename == NULL && (flag == 0 || flag == 1) && ostrstrcase(tmpbuf, "gzip") != NULL)
767        {
768                if(flag == 0) gzip = -1;
769                else if(flag == 1) gzip = headerlen;
770        }
771       
772        if(ostrstrcase(tmpbuf, "Transfer-Encoding: chunked") != NULL)
773        {
774                chunked = 1;
775                chunkedlen = getchunkedlen(sock, timeout);
776                if(chunkedlen + headerlen > MINMALLOC)
777                        readsize = MINMALLOC - headerlen;
778                else
779                        readsize = chunkedlen;
780        }
781
782        if(chunked == 0) readsize = MINMALLOC - headerlen;
783        while((ret = sockread(sock, (unsigned char*)tmpbuf + headerlen, 0, readsize, timeout * 1000, 0)) > 0)
784        {
785                if(chunked == 1) chunkedlen -= ret;
786
787                maxret += ret;
788                if(len > 0)
789                {
790                        if(dnode != NULL)
791                        {
792                                dnode->proz = (int)ceil((((float)maxret / len) * 100));
793                                dnode->maxkb = len;
794                                dnode->aktkb = maxret;
795                        }
796                }
797
798                ret += headerlen;
799                headerlen = 0;
800                if(filename != NULL)
801                        fwrite(tmpbuf, ret, 1, fd);
802                else
803                {
804                        count = count + ret;
805                        buf = realloc(buf, count);
806                        if(buf != NULL)
807                                memcpy(buf + count - ret, tmpbuf, ret);
808                }
809                memset(tmpbuf, 0, ret);
810               
811                if(chunked == 1 && chunkedlen == 0)
812                {
813                        chunkedlen = getchunkedlen(sock, timeout);
814                        if(chunkedlen + headerlen > MINMALLOC)
815                                readsize = MINMALLOC - headerlen;
816                        else
817                                readsize = chunkedlen;
818                }
819                if(chunked == 1 && chunkedlen > 0)
820                {
821                        if(chunkedlen + headerlen > MINMALLOC)
822                                readsize = MINMALLOC - headerlen;
823                        else
824                                readsize = chunkedlen;
825                }
826                if(chunked == 0) readsize = MINMALLOC - headerlen;
827        }
828        if(ret < 0)
829        {
830                perr("receiving data");
831                if(fd != NULL)
832                {
833                        fclose(fd);
834                        unlink(filename);
835                }
836                sockclose(&sock);
837                free(buf);
838                free(tmpbuf);
839                if(dnode != NULL) dnode->ret = 1;
840
841                return NULL;
842        }
843
844end:
845
846        free(tmpbuf);
847        if(fd != NULL) fclose(fd);
848        sockclose(&sock);
849
850        if(gzip != 0)
851        {
852                debug(88, "http unzip start");
853                int unzipret = 0, outlen = 0;
854                char* outbuf = NULL;
855               
856                if(gzip == -1)
857                        outbuf = malloc(MINMALLOC * 100);
858                else
859                        outbuf = malloc((MINMALLOC * 100) + gzip);
860                       
861                if(outbuf != NULL)
862                {
863                        if(gzip == -1)
864                                unzipret = ounzip(buf, count, &outbuf, &outlen, MINMALLOC * 100, 3);
865                        else
866                        {
867                                memcpy(outbuf, buf, gzip);
868                                char* tmpoutbuf = outbuf + gzip;
869                                unzipret = ounzip(buf + gzip, count - gzip, &tmpoutbuf, &outlen, MINMALLOC * 100, 3);
870                                outlen += gzip;                 
871                        }
872                        if(unzipret == 0)
873                        {
874                                free(buf); buf = outbuf;
875                                count = outlen;
876                        }
877                        else
878                        {
879                                free(outbuf); outbuf = NULL;
880                                err("unzip http data");
881                        }
882                }
883                else
884                {
885                        err("no mem");
886                }
887                debug(88, "http unzip end");
888        }
889
890        if(filename == NULL)
891        {
892                buf = realloc(buf, count + 1);
893                buf[count] = '\0';
894        }
895
896        if((hret == 301 || hret == 302) && retstr != NULL && redirect < 3) //redirect
897        {
898                char* pos = NULL, *rpage = NULL;
899                char* rhost = NULL;
900
901                if(strchr(retstr, '/') == retstr)
902                {
903                        rhost = ostrcat(host, NULL, 0, 0);
904                        rpage = retstr;
905                }
906                else
907                {
908                        rhost = string_replace("http://", "", retstr, 0);
909
910                        if(rhost != NULL)
911                                pos = strchr(rhost, '/');
912                        if(pos != NULL)
913                        {
914                                pos[0] = '\0';
915                                rpage = pos + 1;
916                        }
917                }
918
919                redirect++;
920                free(buf); buf = NULL;
921                buf = gethttpreal(rhost, rpage, port, filename, auth, dnode, redirect, NULL, clen, timeout, flag);
922                free(rhost); rhost = NULL;
923        }
924
925        if(clen != 0) *clen = maxret;
926        if(dnode != NULL) dnode->ret = 0;
927        free(retstr); retstr = NULL;
928
929        if(filename == NULL)
930                return buf;
931        else
932                return "0";
933}
934
935char* gethttp(char* host, char* page, int port, char* filename, char* auth, int timeout, struct download* dnode, int redirect)
936{
937        return gethttpreal(host, page, port, filename, auth, dnode, redirect, NULL, NULL, timeout, 0);
938}
939
940void gethttpstruct(struct stimerthread* timernode, struct download* node, int flag)
941{
942        if(node != NULL)
943                gethttp(node->host, node->page, node->port, node->filename, node->auth, node->timeout, node, 0);
944}
945
946void gethttpstructmsg(struct stimerthread* timernode, struct download* node, int flag)
947{
948        char* tmpstr = NULL;
949
950        if(node != NULL)
951        {
952                gethttp(node->host, node->page, node->port, node->filename, node->auth, node->timeout, node, 0);
953                tmpstr = ostrcat(_("Download finished!"), "\n\n", 0, 0);
954                tmpstr = ostrcat(tmpstr, node->filename, 1, 0);
955                textbox(_("Message"), tmpstr, _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 1100, 300, 7, 0);
956
957                free(tmpstr); tmpstr = NULL;
958        }
959}
960
961int sendmail(char* host, char* mailfrom, char* mailto, char* subject, int port, char* filename, char* string, int rtimeout, int wtimeout)
962{
963        int sock = -1, ret = 0;
964        char *ip = NULL, *tmpstr = NULL, *sendstr = NULL, *data = NULL;
965
966        if(filename == NULL && string == NULL) return 1;
967
968        ip = get_ip(host);
969        if(ip == NULL)
970        {
971                err("can't get ip");
972                return 1;
973        }
974
975        data = malloc(MINMALLOC);
976        if(data == NULL)
977        {
978                err("no memory");
979                return 1;
980        }
981
982        if(filename != NULL)
983                tmpstr = readfiletomem(filename, 0);
984        else if(string != NULL)
985                tmpstr = string;
986
987        //open connection
988        ret = sockportopen(&sock, ip, port, wtimeout);
989        if(ret != 0) goto end;
990
991        //wait for smtp answer
992        memset(data, 0, MINMALLOC);
993        sockread(sock, (unsigned char*)data, 0, MINMALLOC, wtimeout, 0);
994        debug(975, "rcv: %s", data);
995/*
996        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
997        {
998                debug(975, "incorrect answer: %s", data);
999                ret = 1;
1000                goto end;
1001        }
1002*/
1003
1004        //send helo
1005        ret = 1;
1006        sendstr = ostrcat(sendstr, "HELO nit.at\r\n", 1, 0);
1007        debug(975, "send: %s", sendstr);
1008        if(sendstr != NULL)
1009                ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
1010        free(sendstr); sendstr = NULL;
1011        if(ret != 0) goto end;
1012
1013        //wait for smtp answer
1014        memset(data, 0, MINMALLOC);
1015        sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
1016        debug(975, "rcv: %s", data);
1017        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
1018        {
1019                debug(975, "incorrect answer: %s", data);
1020                ret = 1;
1021                goto end;
1022        }
1023
1024        //send mail from:
1025        ret = 1;
1026        sendstr = ostrcat(sendstr, "MAIL FROM:<", 1, 0);
1027        sendstr = ostrcat(sendstr, mailfrom, 1, 0);
1028        sendstr = ostrcat(sendstr, ">\r\n", 1, 0);
1029        debug(975, "send: %s", sendstr);
1030        if(sendstr != NULL)
1031                ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
1032        free(sendstr); sendstr = NULL;
1033        if(ret != 0) goto end;
1034
1035        //wait for smtp answer
1036        memset(data, 0, MINMALLOC);
1037        sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
1038        debug(975, "rcv: %s", data);
1039        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
1040        {
1041                debug(975, "incorrect answer: %s", data);
1042                ret = 1;
1043                goto end;
1044        }
1045
1046        //send rcpt to:
1047        ret = 1;
1048        sendstr = ostrcat(sendstr, "RCPT TO:<", 1, 0);
1049        sendstr = ostrcat(sendstr, mailto, 1, 0);
1050        sendstr = ostrcat(sendstr, ">\r\n", 1, 0);
1051        debug(975, "send: %s", sendstr);
1052        if(sendstr != NULL)
1053                ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
1054        free(sendstr); sendstr = NULL;
1055        if(ret != 0) goto end;
1056
1057        //wait for smtp answer
1058        memset(data, 0, MINMALLOC);
1059        sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
1060        debug(975, "rcv: %s", data);
1061        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
1062        {
1063                debug(975, "incorrect answer: %s", data);
1064                ret = 1;
1065                goto end;
1066        }
1067
1068        //send data
1069        ret = 1;
1070        sendstr = ostrcat(sendstr, "DATA\r\n", 1, 0);
1071        debug(975, "send: %s", sendstr);
1072        if(sendstr != NULL)
1073                ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
1074        free(sendstr); sendstr = NULL;
1075        if(ret != 0) goto end;
1076
1077        //wait for smtp answer
1078        memset(data, 0, MINMALLOC);
1079        sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
1080        debug(975, "rcv: %s", data);
1081        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
1082        {
1083                debug(975, "incorrect answer: %s", data);
1084                ret = 1;
1085                goto end;
1086        }
1087
1088        //send content
1089        ret = 1;
1090
1091        sendstr = ostrcat(sendstr, "From: ", 1, 0);
1092        sendstr = ostrcat(sendstr, mailfrom, 1, 0);
1093        sendstr = ostrcat(sendstr, "\r\n", 1, 0);
1094
1095        sendstr = ostrcat(sendstr, "To: ", 1, 0);
1096        sendstr = ostrcat(sendstr, mailto, 1, 0);
1097        sendstr = ostrcat(sendstr, "\r\n", 1, 0);
1098
1099        sendstr = ostrcat(sendstr, "Subject: ", 1, 0);
1100        sendstr = ostrcat(sendstr, subject, 1, 0);
1101        sendstr = ostrcat(sendstr, "\r\n", 1, 0);
1102
1103        sendstr = ostrcat(sendstr, "Content-Type: text/plain\r\n\r\n", 1, 0);
1104
1105        sendstr = ostrcat(sendstr, tmpstr, 1, 0);
1106        sendstr = ostrcat(sendstr, "\r\n.\r\n", 1, 0);
1107
1108        debug(975, "send: %s", sendstr);
1109        if(sendstr != NULL)
1110                ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
1111        free(sendstr); sendstr = NULL;
1112        if(ret != 0) goto end;
1113
1114        //wait for smtp answer
1115        memset(data, 0, MINMALLOC);
1116        sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
1117        debug(975, "rcv: %s", data);
1118        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
1119        {
1120                debug(975, "incorrect answer: %s", data);
1121                ret = 1;
1122                goto end;
1123        }
1124
1125        //send quit
1126        ret = 1;
1127        sendstr = ostrcat(sendstr, "QUIT\r\n", 1, 0);
1128        debug(975, "send: %s", sendstr);
1129        if(sendstr != NULL)
1130                ret = socksend(&sock, (unsigned char*)sendstr, strlen(sendstr), wtimeout);
1131        free(sendstr); sendstr = NULL;
1132        if(ret != 0) goto end;
1133
1134        //wait for smtp answer
1135        memset(data, 0, MINMALLOC);
1136        sockread(sock, (unsigned char*)data, 0, MINMALLOC, rtimeout, 0);
1137        debug(975, "rcv: %s", data);
1138        if(ostrstr(data, "1") != data && ostrstr(data, "2") != data && ostrstr(data, "3") != data)
1139        {
1140                debug(975, "incorrect answer: %s", data);
1141                ret = 1;
1142                goto end;
1143        }
1144
1145end:
1146        if(filename != NULL)
1147                free(tmpstr);
1148        tmpstr = NULL;
1149        return ret;
1150}
1151
1152#endif
Note: See TracBrowser for help on using the repository browser.