summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Chantry <shiningxc@gmail.com>2009-09-29 19:19:54 +0200
committerDan McGee <dan@archlinux.org>2009-09-30 03:52:56 +0200
commit20392c0a025d01128eb78c6656db7c15b3fbcd89 (patch)
tree69c5a125d64409e55fea23508fe3e5e7203951c6
parent7f14f185a2d05650e1f99f4ec40d60b597e8b0c7 (diff)
downloadpacman-20392c0a025d01128eb78c6656db7c15b3fbcd89.tar.gz
pacman-20392c0a025d01128eb78c6656db7c15b3fbcd89.tar.xz
dload : fix infinite download (big type mistake)
fetchIO_read returns -1 in case of error, and the return type is ssize_t, not size_t ! So we converted -1 to an unsigned, which led to huge file write. The rest is just changing the error return a bit. Signed-off-by: Xavier Chantry <shiningxc@gmail.com> Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r--lib/libalpm/dload.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c
index 4695731a..10be5e9d 100644
--- a/lib/libalpm/dload.c
+++ b/lib/libalpm/dload.c
@@ -100,6 +100,15 @@ static struct url *url_for_string(const char *url)
return(ret);
}
+static const char *gethost(struct url *fileurl)
+{
+ const char *host = _("disk");
+ if(strcmp(SCHEME_FILE, fileurl->scheme) != 0) {
+ host = fileurl->host;
+ }
+ return(host);
+}
+
static int download_internal(const char *url, const char *localpath,
time_t mtimeold, time_t *mtimenew) {
fetchIO *dlf = NULL;
@@ -107,7 +116,8 @@ static int download_internal(const char *url, const char *localpath,
struct url_stat ust;
struct stat st;
int chk_resume = 0, ret = 0;
- size_t dl_thisfile = 0, nread = 0;
+ size_t dl_thisfile = 0;
+ ssize_t nread = 0;
char *tempfile, *destfile, *filename;
struct sigaction new_action, old_action;
struct url *fileurl = url_for_string(url);
@@ -170,13 +180,9 @@ static int download_internal(const char *url, const char *localpath,
}
if(fetchLastErrCode != 0 || dlf == NULL) {
- const char *host = _("disk");
- if(strcmp(SCHEME_FILE, fileurl->scheme) != 0) {
- host = fileurl->host;
- }
pm_errno = PM_ERR_LIBFETCH;
_alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"),
- filename, host, fetchLastErrString);
+ filename, gethost(fileurl), fetchLastErrString);
ret = -1;
goto cleanup;
} else {
@@ -231,8 +237,17 @@ static int download_internal(const char *url, const char *localpath,
}
/* did the transfer complete normally? */
+ if (nread == -1) {
+ /* not PM_ERR_LIBFETCH here because libfetch error string might be empty */
+ pm_errno = PM_ERR_RETRIEVE;
+ _alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s\n"),
+ filename, gethost(fileurl));
+ ret = -1;
+ goto cleanup;
+ }
+
if (ust.size != -1 && dl_thisfile < ust.size) {
- pm_errno = PM_ERR_LIBFETCH;
+ pm_errno = PM_ERR_RETRIEVE;
_alpm_log(PM_LOG_ERROR, _("%s appears to be truncated: %jd/%jd bytes\n"),
filename, (intmax_t)dl_thisfile, (intmax_t)ust.size);
ret = -1;