summaryrefslogtreecommitdiffstats
path: root/lib/libalpm/dload.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/dload.c')
-rw-r--r--lib/libalpm/dload.c39
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);