From 283bf7e87cab1fa187334830fe2d05dd28bc5b77 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Mon, 21 Mar 2011 16:54:00 -0400 Subject: 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 Signed-off-by: Dan McGee --- lib/libalpm/dload.c | 34 +++++++++++++++++++++------------- lib/libalpm/dload.h | 6 ++++++ 2 files changed, 27 insertions(+), 13 deletions(-) (limited to 'lib/libalpm') 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 +/* 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); -- cgit v1.2.3-70-g09d2