#define _XOPEN_SOURCE 500 #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Head.h" #include "Data.h" #include "Defs.h" #include "Misc.h" #include "Download.h" extern sigset_t signal_set; extern int errno; unsigned int bwritten = 0; pthread_mutex_t bwritten_mutex = PTHREAD_MUTEX_INITIALIZER; void * http_get(void *arg) { struct thread_data *td; int sd; char *rbuf, *s; int dr, dw, i; long foffset; pthread_t tid; tid = pthread_self(); /* Block out all signals */ pthread_sigmask(SIG_BLOCK, &signal_set, NULL); /* Set Cancellation Type to Asynchronous */ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); td = (struct thread_data *)arg; foffset = td->foffset; rbuf = (char *)calloc(GETRECVSIZ, sizeof(char)); if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { Log(" socket creation failed: %s", tid, strerror(errno)); pthread_exit((void *)1); } if ((connect(sd, (const struct sockaddr *)&td->sin, sizeof(struct sockaddr))) == -1) { Log(" connection failed: %s", tid, strerror(errno)); pthread_exit((void *)1); } if ((send(sd, td->getstr, strlen(td->getstr), 0)) == -1) { Log(" send failed: %s", tid, strerror(errno)); pthread_exit((void *)1); } if ((dr = recv(sd, rbuf, GETRECVSIZ, 0)) == -1) { Log(" recv failed: %s", tid, strerror(errno)); pthread_exit((void *)1); } handleHttpRetcode(rbuf); if ((strstr(rbuf, "HTTP/1.1 206")) == NULL) { fprintf(stderr, "Something unhandled happened, shutting down...\n"); exit(1); } s = rbuf; i = 0; while(1) { if (*s == '\n' && *(s - 1) == '\r' && *(s - 2) == '\n' && *(s - 3) == '\r') { s++; i++; break; } s++; i++; } td->offset = td->soffset; if ((dr - i ) > foffset) dw = pwrite(td->fd, s, (foffset - i), td->soffset); else dw = pwrite(td->fd, s, (dr - i), td->soffset); td->offset = td->soffset + dw; pthread_mutex_lock(&bwritten_mutex); bwritten += dw; pthread_mutex_unlock(&bwritten_mutex); while (td->offset < foffset) { memset(rbuf, GETRECVSIZ, 0); dr = recv(sd, rbuf, GETRECVSIZ, 0); if ((td->offset + dr) > foffset) dw = pwrite(td->fd, rbuf, foffset - td->offset, td->offset); else dw = pwrite(td->fd, rbuf, dr, td->offset); td->offset += dw; pthread_mutex_lock(&bwritten_mutex); bwritten += dw; pthread_mutex_unlock(&bwritten_mutex); updateProgressBar(bwritten, td->clength); } if (td->offset == td->foffset) td->status = STAT_OK; /* Tell thet download is OK. */ close(sd); /* printf(" Part %d completed, leaving thread...\n", tid, td->tind);*/ pthread_exit(NULL); return NULL; }