diff options
author | Dave Reisner <d@falconindy.com> | 2011-03-21 21:54:00 +0100 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2011-03-28 03:12:17 +0200 |
commit | 283bf7e87cab1fa187334830fe2d05dd28bc5b77 (patch) | |
tree | 27ff66e0a3a6db3e702088137b96618782b27013 | |
parent | 86e7f6075671e08c456f389d8ecba47190c03f0f (diff) | |
download | pacman-283bf7e87cab1fa187334830fe2d05dd28bc5b77.tar.gz pacman-283bf7e87cab1fa187334830fe2d05dd28bc5b77.tar.xz |
lib/dload: pass a struct with filename and size to curl_progress
This lets us determine the real size of the file on disk so that we can
properly bump the progress bar when we're resuming a download.
Signed-off-by: Dave Reisner <d@falconindy.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r-- | lib/libalpm/dload.c | 34 | ||||
-rw-r--r-- | lib/libalpm/dload.h | 6 |
2 files changed, 27 insertions, 13 deletions
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 7e9c3476..a6225fa4 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -87,9 +87,11 @@ static void inthandler(int signum) dload_interrupted = 1; } -static int curl_progress(void *filename, double dltotal, double dlnow, +static int curl_progress(void *file, double dltotal, double dlnow, double ultotal, double ulnow) { + struct fileinfo *dlfile = (struct fileinfo *)file; + double current_size, total_size; /* unused parameters */ (void)ultotal; @@ -105,19 +107,22 @@ static int curl_progress(void *filename, double dltotal, double dlnow, return 0; } - if(DOUBLE_EQ(dltotal, 0) || DOUBLE_EQ(prevprogress, dltotal)) { + current_size = dlfile->initial_size + dlnow; + total_size = dlfile->initial_size + dltotal; + + if(DOUBLE_EQ(dltotal, 0) || DOUBLE_EQ(prevprogress, total_size)) { return 0; } /* initialize the progress bar here to avoid displaying it when * a repo is up to date and nothing gets downloaded */ if(DOUBLE_EQ(prevprogress, 0)) { - handle->dlcb((const char*)filename, 0, (long)dltotal); + handle->dlcb(dlfile->filename, 0, (long)dltotal); } - handle->dlcb((const char*)filename, (long)dlnow, (long)dltotal); + handle->dlcb(dlfile->filename, (long)current_size, (long)total_size); - prevprogress = dlnow; + prevprogress = current_size; return 0; } @@ -152,21 +157,23 @@ static int curl_download_internal(const char *url, const char *localpath, { int ret = -1; FILE *localf = NULL; - char *destfile, *filename, *tempfile; + char *destfile, *tempfile; char hostname[256]; /* RFC1123 states applications should support this length */ struct stat st; long httpresp, timecond, remote_time, local_time; double remote_size, bytes_dl; struct sigaction sig_pipe[2], sig_int[2]; + struct fileinfo dlfile; - filename = get_filename(url); - if(!filename || curl_gethost(url, hostname) != 0) { + dlfile.initial_size = 0.0; + dlfile.filename = get_filename(url); + if(!dlfile.filename || curl_gethost(url, hostname) != 0) { _alpm_log(PM_LOG_ERROR, _("url '%s' is invalid\n"), url); RET_ERR(PM_ERR_SERVER_BAD_URL, -1); } - destfile = get_destfile(localpath, filename); - tempfile = get_tempfile(localpath, filename); + destfile = get_destfile(localpath, dlfile.filename); + tempfile = get_tempfile(localpath, dlfile.filename); /* the curl_easy handle is initialized with the alpm handle, so we only need * to reset the curl handle set parameters for each time it's used. */ @@ -178,7 +185,7 @@ static int curl_download_internal(const char *url, const char *localpath, curl_easy_setopt(handle->curl, CURLOPT_NOPROGRESS, 0L); curl_easy_setopt(handle->curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(handle->curl, CURLOPT_PROGRESSFUNCTION, curl_progress); - curl_easy_setopt(handle->curl, CURLOPT_PROGRESSDATA, filename); + curl_easy_setopt(handle->curl, CURLOPT_PROGRESSDATA, (void*)&dlfile); if(!force && stat(destfile, &st) == 0) { /* assume its a sync, so we're starting from scratch. but, only download @@ -192,6 +199,7 @@ static int curl_download_internal(const char *url, const char *localpath, localf = fopen(tempfile, "ab"); curl_easy_setopt(handle->curl, CURLOPT_RESUME_FROM, (long)st.st_size); _alpm_log(PM_LOG_DEBUG, "tempfile found, attempting continuation"); + dlfile.initial_size = (double)st.st_size; } /* no destfile and no tempfile. start from scratch */ @@ -252,7 +260,7 @@ static int curl_download_internal(const char *url, const char *localpath, } else if(handle->curlerr != CURLE_OK) { pm_errno = PM_ERR_LIBCURL; _alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"), - filename, hostname, curl_easy_strerror(handle->curlerr)); + dlfile.filename, hostname, curl_easy_strerror(handle->curlerr)); unlink(tempfile); goto cleanup; } @@ -264,7 +272,7 @@ static int curl_download_internal(const char *url, const char *localpath, !DOUBLE_EQ(bytes_dl, remote_size)) { pm_errno = PM_ERR_RETRIEVE; _alpm_log(PM_LOG_ERROR, _("%s appears to be truncated: %jd/%jd bytes\n"), - filename, (intmax_t)bytes_dl, (intmax_t)remote_size); + dlfile.filename, (intmax_t)bytes_dl, (intmax_t)remote_size); goto cleanup; } diff --git a/lib/libalpm/dload.h b/lib/libalpm/dload.h index e8d99b23..5ce44b8a 100644 --- a/lib/libalpm/dload.h +++ b/lib/libalpm/dload.h @@ -25,6 +25,12 @@ #include <time.h> +/* internal structure for communicating with curl progress callback */ +struct fileinfo { + char *filename; + double initial_size; +}; + int _alpm_download_single_file(const char *filename, alpm_list_t *servers, const char *localpath, int force); |