summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Reisner <d@falconindy.com>2011-03-21 21:54:00 +0100
committerDan McGee <dan@archlinux.org>2011-03-28 03:12:17 +0200
commit283bf7e87cab1fa187334830fe2d05dd28bc5b77 (patch)
tree27ff66e0a3a6db3e702088137b96618782b27013
parent86e7f6075671e08c456f389d8ecba47190c03f0f (diff)
downloadpacman-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.c34
-rw-r--r--lib/libalpm/dload.h6
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);