diff options
Diffstat (limited to 'lib/libalpm/dload.c')
-rw-r--r-- | lib/libalpm/dload.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index c11148d1..7a98eb12 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -1,7 +1,7 @@ /* * download.c * - * Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify @@ -29,16 +29,13 @@ #include <sys/types.h> #include <sys/stat.h> #include <signal.h> -#include <limits.h> -/* the following two are needed on BSD for libfetch */ -#if defined(HAVE_SYS_SYSLIMITS_H) -#include <sys/syslimits.h> /* PATH_MAX */ -#endif +/* the following two are needed for FreeBSD's libfetch */ +#include <limits.h> /* PATH_MAX */ #if defined(HAVE_SYS_PARAM_H) #include <sys/param.h> /* MAXHOSTNAMELEN */ #endif -#if defined(INTERNAL_DOWNLOAD) +#ifdef HAVE_LIBFETCH #include <fetch.h> #endif @@ -58,7 +55,7 @@ static char *get_filename(const char *url) { return(filename); } -#if defined(INTERNAL_DOWNLOAD) +#ifdef HAVE_LIBFETCH static char *get_destfile(const char *path, const char *filename) { char *destfile; /* len = localpath len + filename len + null */ @@ -89,7 +86,7 @@ static const char *gethost(struct url *fileurl) } int dload_interrupted; -static RETSIGTYPE inthandler(int signum) +static void inthandler(int signum) { dload_interrupted = 1; } @@ -131,13 +128,13 @@ static int download_internal(const char *url, const char *localpath, destfile = get_destfile(localpath, filename); tempfile = get_tempfile(localpath, filename); - if(stat(tempfile, &st) == 0 && st.st_size > 0) { + if(stat(tempfile, &st) == 0 && S_ISREG(st.st_mode) && st.st_size > 0) { _alpm_log(PM_LOG_DEBUG, "tempfile found, attempting continuation\n"); local_time = fileurl->last_modified = st.st_mtime; local_size = fileurl->offset = (off_t)st.st_size; dl_thisfile = st.st_size; localf = fopen(tempfile, "ab"); - } else if(!force && stat(destfile, &st) == 0 && st.st_size > 0) { + } else if(!force && stat(destfile, &st) == 0 && S_ISREG(st.st_mode) && st.st_size > 0) { _alpm_log(PM_LOG_DEBUG, "destfile found, using mtime only\n"); local_time = fileurl->last_modified = st.st_mtime; local_size = /* no fu->off here */ (off_t)st.st_size; @@ -175,6 +172,14 @@ static int download_internal(const char *url, const char *localpath, /* NOTE: libfetch does not reset the error code, be sure to do it before * calls into the library */ + /* TODO: if we call fetchStat() and get a redirect (disabling automagic + * redirect following), we should repeat the file locator stuff and get a new + * filename rather than only base if off the first URL, and then verify + * get_filename() didn't return ''. Of course, libfetch might not even allow + * us to even get that URL...FS#22645. This would allow us to download things + * without totally puking like + * http://www.archlinux.org/packages/community/x86_64/exim/download/ */ + /* find out the remote size *and* mtime in one go. there is a lot of * trouble in trying to do both size and "if-modified-since" logic in a * non-stat request, so avoid it. */ @@ -250,8 +255,8 @@ static int download_internal(const char *url, const char *localpath, while((nread = fetchIO_read(dlf, buffer, PM_DLBUF_LEN)) > 0) { check_stop(); size_t nwritten = 0; - nwritten = fwrite(buffer, 1, nread, localf); - if((nwritten != nread) || ferror(localf)) { + nwritten = fwrite(buffer, 1, (size_t)nread, localf); + if((nwritten != (size_t)nread) || ferror(localf)) { pm_errno = PM_ERR_RETRIEVE; _alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"), tempfile, strerror(errno)); @@ -299,7 +304,11 @@ static int download_internal(const char *url, const char *localpath, tv[1].tv_sec = ust.mtime; utimes(tempfile, tv); } - rename(tempfile, destfile); + if(rename(tempfile, destfile)) { + _alpm_log(PM_LOG_ERROR, _("could not rename %s to %s (%s)\n"), + tempfile, destfile, strerror(errno)); + ret = -1; + } ret = 0; cleanup: @@ -338,7 +347,7 @@ cleanup: static int download(const char *url, const char *localpath, int force) { if(handle->fetchcb == NULL) { -#if defined(INTERNAL_DOWNLOAD) +#ifdef HAVE_LIBFETCH return(download_internal(url, localpath, force)); #else RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1); |