📄 aget.c
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <pthread.h>#include <unistd.h>#include <time.h>#include <fcntl.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include "Head.h"#include "Aget.h"#include "Misc.h"#include "Download.h"#include "Resume.h"#include "Data.h"extern struct thread_data *wthread;extern struct request *req;extern int fsuggested, nthreads;extern int bwritten;extern pthread_t hthread;extern int errno;void get(struct request *req){ int i, ret, fd, diff_sec, nok = 0; long soffset, foffset; char *fmt; if (req->proto == PROTO_HTTP) http_head_req(req); /* According to the content-length, get the * suggested number of threads to open. * if the user insists on his value, let it be that way, * use the user's value. */ ret = numofthreads(req->clength); if (fsuggested == 0) { if (ret == 0) nthreads = 1; else nthreads = ret; } wthread = (struct thread_data *)malloc(nthreads * sizeof(struct thread_data)); Log("Downloading %s (%d bytes) from site %s(%s:%d). Number of Threads: %d", req->url, req->clength, req->host, req->ip, req->port, nthreads); if (strlen(req->lfile) != 0) { if ((fd = open(req->lfile, O_CREAT | O_RDWR, S_IRWXU)) == -1) { fprintf(stderr, "get: cannot open file %s for writing: %s\n", req->lfile, strerror(errno)); exit(1); } } else { if ((fd = open(req->file, O_CREAT | O_RDWR, S_IRWXU)) == -1) { fprintf(stderr, "get: cannot open file %s for writing: %s\n", req->lfile, strerror(errno)); exit(1); } } if ((lseek(fd, req->clength - 1, SEEK_SET)) == -1) { fprintf(stderr, "get: couldn't lseek: %s\n", strerror(errno)); exit(1); } if ((write(fd, "0", 1)) == -1) { fprintf(stderr, "get: couldn't allocate space for download file: %s\n", strerror(errno)); exit(1); } /* Get the starting time, prepare GET format string, and start the threads */ fmt = (char *)calloc(GETREQSIZ - 2, sizeof(char)); time(&t_start); for (i = 0; i < nthreads; i++) { soffset = calc_offset(req->clength, i, nthreads); foffset = calc_offset(req->clength, i + 1, nthreads); wthread[i].soffset = soffset; wthread[i].foffset = (i == nthreads - 1 ? req->clength : foffset); wthread[i].sin.sin_family = AF_INET; wthread[i].sin.sin_addr.s_addr = inet_addr(req->ip); wthread[i].sin.sin_port = htons(req->port); wthread[i].fd = dup(fd); wthread[i].clength = req->clength; snprintf(fmt, GETREQSIZ, GETREQ, req->url, req->host, PROGVERSION, soffset); strncpy(wthread[i].getstr, fmt, GETREQSIZ); pthread_create(&(wthread[i].tid), NULL, http_get, &(wthread[i])); } free(fmt); /* Wait for all of the threads to finish... * * TODO: If a thread fails, restart that! */ for (i = 0; i < nthreads; i++) { pthread_join(wthread[i].tid, NULL); if (wthread[i].status == STAT_OK) nok++; } if (nok == nthreads) pthread_cancel(hthread); else pthread_join(hthread, NULL); /* Get the finish time, derive some stats */ time(&t_finish); if ((diff_sec = t_finish - t_start) == 0) diff_sec = 1; /* Avoid division by zero */ Log("Download completed, job completed in %d seconds. (%d Kb/sec)", diff_sec, (req->clength / diff_sec) / 1024); Log("Shutting down..."); close(fd);}void resume_get(struct hist_data *h){ int i, fd, diff_sec, nok = 0; char *fmt; nthreads = h->nthreads; fmt = (char *)calloc(GETREQSIZ - 2, sizeof(char)); wthread = (struct thread_data *)malloc(nthreads * sizeof(struct thread_data)); memcpy(req, &h->req, sizeof(struct request)); memcpy(wthread, h->wthread, sizeof(struct thread_data) * nthreads); Log("Resuming download %s (%d bytes) from site %s(%s:%d). Number of Threads: %d", req->url, req->clength, req->host, req->ip, req->port, nthreads); if (strlen(req->lfile) != 0) { if ((fd = open(req->lfile, O_RDWR, S_IRWXU)) == -1) { fprintf(stderr, "get: cannot open file %s for writing: %s\n", req->lfile, strerror(errno)); exit(1); } } else { if ((fd = open(req->file, O_RDWR, S_IRWXU)) == -1) { fprintf(stderr, "get: cannot open file %s for writing: %s\n", req->lfile, strerror(errno)); exit(1); } } time(&t_start);#ifdef DEBUG for (i = 0; i < nthreads; i++) printf("Start: %ld, Finish: %ld, Offset: %ld, Diff: %ld\n", wthread[i].soffset, wthread[i].foffset, wthread[i].offset, wthread[i].offset - wthread[i].soffset);#endif for (i = 0; i < nthreads; i++) { wthread[i].soffset = wthread[i].offset; wthread[i].fd = dup(fd); snprintf(fmt, GETREQSIZ, GETREQ, req->url, req->host, PROGVERSION, wthread[i].offset); strncpy(wthread[i].getstr, fmt, GETREQSIZ); pthread_create(&(wthread[i].tid), NULL, http_get, &(wthread[i])); } for (i = 0; i < nthreads; i++) pthread_join(wthread[i].tid, NULL); for (i = 0; i < nthreads; i++) { pthread_join(wthread[i].tid, NULL); if (wthread[i].status == STAT_OK) nok++; } if (nok == nthreads) pthread_cancel(hthread); else pthread_join(hthread, NULL); time(&t_finish); if ((diff_sec = t_finish - t_start) == 0) diff_sec = 1; /* Avoid division by zero */ Log("Download completed, job completed in %d seconds. (%d Kb/sec)", diff_sec, ((req->clength - h->bwritten) / diff_sec) / 1024); Log("Shutting down..."); close(fd);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -