index : pacman | |
Archlinux32 fork of pacman | gitolite user |
summaryrefslogtreecommitdiff |
-rw-r--r-- | lib/libalpm/dload.c | 68 |
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index d024c736..46925a99 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -62,7 +62,7 @@ static char *get_fullpath(const char *path, const char *filename, char *filepath; /* len = localpath len + filename len + suffix len + null */ size_t len = strlen(path) + strlen(filename) + strlen(suffix) + 1; - CALLOC(filepath, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL)); + CALLOC(filepath, len, sizeof(char), return NULL); snprintf(filepath, len, "%s%s%s", path, filename, suffix); return filepath; @@ -89,7 +89,7 @@ static int curl_progress(void *file, double dltotal, double dlnow, } /* none of what follows matters if the front end has no callback */ - if(handle->dlcb == NULL) { + if(dlfile->handle->dlcb == NULL) { return 0; } @@ -103,10 +103,10 @@ static int curl_progress(void *file, double dltotal, double dlnow, /* 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(dlfile->filename, 0, (long)dltotal); + dlfile->handle->dlcb(dlfile->filename, 0, (long)dltotal); } - handle->dlcb(dlfile->filename, (long)current_size, (long)total_size); + dlfile->handle->dlcb(dlfile->filename, (long)current_size, (long)total_size); prevprogress = current_size; @@ -129,7 +129,6 @@ static int curl_gethost(const char *url, char *buffer) hostlen = strcspn(p, "/"); if(hostlen > 255) { /* buffer overflow imminent */ - _alpm_log(PM_LOG_ERROR, _("buffer overflow detected")); return 1; } snprintf(buffer, hostlen + 1, "%s", p); @@ -150,7 +149,8 @@ static int utimes_long(const char *path, long time) } -static int curl_download_internal(const char *url, const char *localpath, +static int curl_download_internal(pmhandle_t *handle, + const char *url, const char *localpath, int force, int allow_resume, int errors_ok) { int ret = -1; @@ -167,11 +167,12 @@ static int curl_download_internal(const char *url, const char *localpath, struct sigaction sig_pipe[2], sig_int[2]; struct fileinfo dlfile; + dlfile.handle = handle; 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); + _alpm_log(handle, PM_LOG_ERROR, _("url '%s' is invalid\n"), url); + RET_ERR(handle, PM_ERR_SERVER_BAD_URL, -1); } destfile = get_fullpath(localpath, dlfile.filename, ""); @@ -194,23 +195,23 @@ static int curl_download_internal(const char *url, const char *localpath, curl_easy_setopt(handle->curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(handle->curl, CURLOPT_PROGRESSFUNCTION, curl_progress); curl_easy_setopt(handle->curl, CURLOPT_PROGRESSDATA, (void *)&dlfile); + curl_easy_setopt(handle->curl, CURLOPT_LOW_SPEED_LIMIT, 1024L); + curl_easy_setopt(handle->curl, CURLOPT_LOW_SPEED_TIME, 10L); useragent = getenv("HTTP_USER_AGENT"); if(useragent != NULL) { curl_easy_setopt(handle->curl, CURLOPT_USERAGENT, useragent); } - /* TODO: no assuming here. the calling function should tell us what's kosher */ - if(!force && stat(destfile, &st) == 0) { - /* assume its a sync, so we're starting from scratch. but, only download - * our local is out of date. */ + if(!allow_resume && !force && stat(destfile, &st) == 0) { + /* start from scratch, but only download if our local is out of date. */ curl_easy_setopt(handle->curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); curl_easy_setopt(handle->curl, CURLOPT_TIMEVALUE, (long)st.st_mtime); } else if(stat(tempfile, &st) == 0 && allow_resume) { /* a previous partial download exists, resume from end of file. */ open_mode = "ab"; curl_easy_setopt(handle->curl, CURLOPT_RESUME_FROM, (long)st.st_size); - _alpm_log(PM_LOG_DEBUG, "tempfile found, attempting continuation"); + _alpm_log(handle, PM_LOG_DEBUG, "tempfile found, attempting continuation"); dlfile.initial_size = (double)st.st_size; } @@ -247,11 +248,11 @@ static int curl_download_internal(const char *url, const char *localpath, goto cleanup; } else if(handle->curlerr != CURLE_OK) { if(!errors_ok) { - pm_errno = PM_ERR_LIBCURL; - _alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"), + handle->pm_errno = PM_ERR_LIBCURL; + _alpm_log(handle, PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"), dlfile.filename, hostname, error_buffer); } else { - _alpm_log(PM_LOG_DEBUG, "failed retrieving file '%s' from %s : %s\n", + _alpm_log(handle, PM_LOG_DEBUG, "failed retrieving file '%s' from %s : %s\n", dlfile.filename, hostname, error_buffer); } unlink(tempfile); @@ -277,8 +278,8 @@ static int curl_download_internal(const char *url, const char *localpath, * as actually being transferred during curl_easy_perform() */ if(!DOUBLE_EQ(remote_size, -1) && !DOUBLE_EQ(bytes_dl, -1) && !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"), + handle->pm_errno = PM_ERR_RETRIEVE; + _alpm_log(handle, PM_LOG_ERROR, _("%s appears to be truncated: %jd/%jd bytes\n"), dlfile.filename, (intmax_t)bytes_dl, (intmax_t)remote_size); goto cleanup; } @@ -310,45 +311,44 @@ cleanup: } #endif -int _alpm_download(const char *url, const char *localpath, +int _alpm_download(pmhandle_t *handle, const char *url, const char *localpath, int force, int allow_resume, int errors_ok) { if(handle->fetchcb == NULL) { #ifdef HAVE_LIBCURL - return curl_download_internal(url, localpath, force, allow_resume, errors_ok); + return curl_download_internal(handle, url, localpath, + force, allow_resume, errors_ok); #else - RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1); + RET_ERR(handle, PM_ERR_EXTERNAL_DOWNLOAD, -1); #endif } else { int ret = handle->fetchcb(url, localpath, force); if(ret == -1 && !errors_ok) { - RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1); + RET_ERR(handle, PM_ERR_EXTERNAL_DOWNLOAD, -1); } return ret; } } /** Fetch a remote pkg. */ -char SYMEXPORT *alpm_fetch_pkgurl(const char *url) +char SYMEXPORT *alpm_fetch_pkgurl(pmhandle_t *handle, const char *url) { char *filepath; const char *filename, *cachedir; int ret; - ALPM_LOG_FUNC; - filename = get_filename(url); /* find a valid cache dir to download to */ - cachedir = _alpm_filecache_setup(); + cachedir = _alpm_filecache_setup(handle); /* download the file */ - ret = _alpm_download(url, cachedir, 0, 1, 0); + ret = _alpm_download(handle, url, cachedir, 0, 1, 0); if(ret == -1) { - _alpm_log(PM_LOG_WARNING, _("failed to download %s\n"), url); + _alpm_log(handle, PM_LOG_WARNING, _("failed to download %s\n"), url); return NULL; } - _alpm_log(PM_LOG_DEBUG, "successfully downloaded %s\n", url); + _alpm_log(handle, PM_LOG_DEBUG, "successfully downloaded %s\n", url); /* attempt to download the signature */ if(ret == 0 && (handle->sigverify == PM_PGP_VERIFY_ALWAYS || @@ -358,22 +358,22 @@ char SYMEXPORT *alpm_fetch_pkgurl(const char *url) int errors_ok = (handle->sigverify == PM_PGP_VERIFY_OPTIONAL); len = strlen(url) + 5; - CALLOC(sig_url, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL)); + CALLOC(sig_url, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, NULL)); snprintf(sig_url, len, "%s.sig", url); - ret = _alpm_download(sig_url, cachedir, 1, 0, errors_ok); + ret = _alpm_download(handle, sig_url, cachedir, 1, 0, errors_ok); if(ret == -1 && !errors_ok) { - _alpm_log(PM_LOG_WARNING, _("failed to download %s\n"), sig_url); + _alpm_log(handle, PM_LOG_WARNING, _("failed to download %s\n"), sig_url); /* Warn now, but don't return NULL. We will fail later during package * load time. */ } else if(ret == 0) { - _alpm_log(PM_LOG_DEBUG, "successfully downloaded %s\n", sig_url); + _alpm_log(handle, PM_LOG_DEBUG, "successfully downloaded %s\n", sig_url); } FREE(sig_url); } /* we should be able to find the file the second time around */ - filepath = _alpm_filecache_find(filename); + filepath = _alpm_filecache_find(handle, filename); return filepath; } |