Allow disabling of internal (libdownload) code
Add a new --disable-internal-download flag to configure allowing the internal download code to be skipped. This will be helpful on platforms that currently don't support either libdownload or libfetch (such as Cygwin) and for just compiling a lighter weight pacman binary. This was made really easy by our recent refactoring of the download code into separate internal and external functions, as well as some error code cleanup. Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
9c7ebe6872
commit
a708c6eadc
4 changed files with 76 additions and 37 deletions
23
configure.ac
23
configure.ac
|
@ -98,6 +98,11 @@ AC_ARG_WITH(db-ext,
|
||||||
AC_HELP_STRING([--with-db-ext=ext], [set the file extension used by the database]),
|
AC_HELP_STRING([--with-db-ext=ext], [set the file extension used by the database]),
|
||||||
[DBEXT=$withval], [DBEXT=.db.tar.gz])
|
[DBEXT=$withval], [DBEXT=.db.tar.gz])
|
||||||
|
|
||||||
|
# Help line for libdownload/libfetch
|
||||||
|
AC_ARG_ENABLE(internal-download,
|
||||||
|
AC_HELP_STRING([--disable-internal-download], [do not build with libdownload/libfetch support]),
|
||||||
|
[internaldownload=$enableval], [internaldownload=yes])
|
||||||
|
|
||||||
# Help line for documentation
|
# Help line for documentation
|
||||||
AC_ARG_ENABLE(doc,
|
AC_ARG_ENABLE(doc,
|
||||||
AC_HELP_STRING([--disable-doc], [prevent make from looking at doc/ dir]),
|
AC_HELP_STRING([--disable-doc], [prevent make from looking at doc/ dir]),
|
||||||
|
@ -137,10 +142,21 @@ AM_GNU_GETTEXT([external])
|
||||||
AM_GNU_GETTEXT_VERSION(0.13.1)
|
AM_GNU_GETTEXT_VERSION(0.13.1)
|
||||||
|
|
||||||
# Check for libarchive
|
# Check for libarchive
|
||||||
AC_CHECK_LIB([archive], [archive_read_data], , AC_MSG_ERROR([libarchive is needed to compile pacman!]))
|
AC_CHECK_LIB([archive], [archive_read_data], ,
|
||||||
|
AC_MSG_ERROR([libarchive is needed to compile pacman!]))
|
||||||
|
|
||||||
# Check for libdownload
|
# Enable or disable usage of libdownload/libfetch
|
||||||
AC_CHECK_LIB([download], [downloadParseURL], , AC_MSG_ERROR([libdownload is needed to compile pacman!]))
|
AC_MSG_CHECKING(whether to link with download library)
|
||||||
|
if test "x$internaldownload" = "xyes" ; then
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE([INTERNAL_DOWNLOAD], , [Use internal download library])
|
||||||
|
# Check for libdownload if it was actually requested
|
||||||
|
AC_CHECK_LIB([download], [downloadParseURL], ,
|
||||||
|
AC_MSG_ERROR([libdownload is needed to compile pacman!]))
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(INTERNAL_DOWNLOAD, test "x$internaldownload" = "xyes")
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
AC_CHECK_HEADERS([fcntl.h libintl.h limits.h locale.h string.h strings.h sys/ioctl.h sys/statvfs.h sys/time.h syslog.h wchar.h])
|
AC_CHECK_HEADERS([fcntl.h libintl.h limits.h locale.h string.h strings.h sys/ioctl.h sys/statvfs.h sys/time.h syslog.h wchar.h])
|
||||||
|
@ -352,6 +368,7 @@ pacman_display_version:
|
||||||
|
|
||||||
Compilation options:
|
Compilation options:
|
||||||
Run make in doc/ dir : ${wantdoc}
|
Run make in doc/ dir : ${wantdoc}
|
||||||
|
Use download library : ${internaldownload}
|
||||||
Doxygen support : ${usedoxygen}
|
Doxygen support : ${usedoxygen}
|
||||||
Asciidoc support : ${useasciidoc}
|
Asciidoc support : ${useasciidoc}
|
||||||
debug support : ${debug}
|
debug support : ${debug}
|
||||||
|
|
|
@ -468,12 +468,10 @@ enum _pmerrno_t {
|
||||||
PM_ERR_RETRIEVE,
|
PM_ERR_RETRIEVE,
|
||||||
PM_ERR_PKG_HOLD,
|
PM_ERR_PKG_HOLD,
|
||||||
PM_ERR_INVALID_REGEX,
|
PM_ERR_INVALID_REGEX,
|
||||||
/* Downloading */
|
|
||||||
PM_ERR_CONNECT_FAILED,
|
|
||||||
PM_ERR_FORK_FAILED,
|
|
||||||
/* External library errors */
|
/* External library errors */
|
||||||
PM_ERR_LIBARCHIVE,
|
PM_ERR_LIBARCHIVE,
|
||||||
PM_ERR_LIBDOWNLOAD
|
PM_ERR_LIBDOWNLOAD,
|
||||||
|
PM_ERR_EXTERNAL_DOWNLOAD
|
||||||
};
|
};
|
||||||
|
|
||||||
extern enum _pmerrno_t pm_errno;
|
extern enum _pmerrno_t pm_errno;
|
||||||
|
|
|
@ -24,7 +24,9 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#if defined(INTERNAL_DOWNLOAD)
|
||||||
#include <download.h> /* libdownload */
|
#include <download.h> /* libdownload */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* libalpm */
|
/* libalpm */
|
||||||
#include "dload.h"
|
#include "dload.h"
|
||||||
|
@ -34,30 +36,6 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "handle.h"
|
#include "handle.h"
|
||||||
|
|
||||||
/* Build a 'struct url' from an url. */
|
|
||||||
static struct url *url_for_string(const char *url)
|
|
||||||
{
|
|
||||||
struct url *ret = NULL;
|
|
||||||
ret = downloadParseURL(url);
|
|
||||||
if(!ret) {
|
|
||||||
_alpm_log(PM_LOG_ERROR, _("url '%s' is invalid\n"), url);
|
|
||||||
RET_ERR(PM_ERR_SERVER_BAD_URL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if no URL scheme specified, assume HTTP */
|
|
||||||
if(strlen(ret->scheme) == 0) {
|
|
||||||
_alpm_log(PM_LOG_WARNING, _("url scheme not specified, assuming HTTP\n"));
|
|
||||||
strcpy(ret->scheme, SCHEME_HTTP);
|
|
||||||
}
|
|
||||||
/* add a user & password for anonymous FTP */
|
|
||||||
if(strcmp(ret->scheme,SCHEME_FTP) == 0 && strlen(ret->user) == 0) {
|
|
||||||
strcpy(ret->user, "anonymous");
|
|
||||||
strcpy(ret->pwd, "libalpm@guest");
|
|
||||||
}
|
|
||||||
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *get_filename(const char *url) {
|
static char *get_filename(const char *url) {
|
||||||
char *filename = strrchr(url, '/');
|
char *filename = strrchr(url, '/');
|
||||||
if(filename != NULL) {
|
if(filename != NULL) {
|
||||||
|
@ -86,6 +64,31 @@ static char *get_tempfile(const char *path, const char *filename) {
|
||||||
return(tempfile);
|
return(tempfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(INTERNAL_DOWNLOAD)
|
||||||
|
/* Build a 'struct url' from an url. */
|
||||||
|
static struct url *url_for_string(const char *url)
|
||||||
|
{
|
||||||
|
struct url *ret = NULL;
|
||||||
|
ret = downloadParseURL(url);
|
||||||
|
if(!ret) {
|
||||||
|
_alpm_log(PM_LOG_ERROR, _("url '%s' is invalid\n"), url);
|
||||||
|
RET_ERR(PM_ERR_SERVER_BAD_URL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if no URL scheme specified, assume HTTP */
|
||||||
|
if(strlen(ret->scheme) == 0) {
|
||||||
|
_alpm_log(PM_LOG_WARNING, _("url scheme not specified, assuming HTTP\n"));
|
||||||
|
strcpy(ret->scheme, SCHEME_HTTP);
|
||||||
|
}
|
||||||
|
/* add a user & password for anonymous FTP */
|
||||||
|
if(strcmp(ret->scheme,SCHEME_FTP) == 0 && strlen(ret->user) == 0) {
|
||||||
|
strcpy(ret->user, "anonymous");
|
||||||
|
strcpy(ret->pwd, "libalpm@guest");
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
static int download_internal(const char *url, const char *localpath,
|
static int download_internal(const char *url, const char *localpath,
|
||||||
time_t mtimeold, time_t *mtimenew) {
|
time_t mtimeold, time_t *mtimenew) {
|
||||||
FILE *dlf, *localf = NULL;
|
FILE *dlf, *localf = NULL;
|
||||||
|
@ -230,6 +233,7 @@ cleanup:
|
||||||
downloadFreeURL(fileurl);
|
downloadFreeURL(fileurl);
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int download_external(const char *url, const char *localpath,
|
static int download_external(const char *url, const char *localpath,
|
||||||
time_t mtimeold, time_t *mtimenew) {
|
time_t mtimeold, time_t *mtimenew) {
|
||||||
|
@ -242,9 +246,13 @@ static int download_external(const char *url, const char *localpath,
|
||||||
char cwd[PATH_MAX];
|
char cwd[PATH_MAX];
|
||||||
char *destfile, *tempfile, *filename;
|
char *destfile, *tempfile, *filename;
|
||||||
|
|
||||||
|
if(!handle->xfercommand) {
|
||||||
|
RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1);
|
||||||
|
}
|
||||||
|
|
||||||
filename = get_filename(url);
|
filename = get_filename(url);
|
||||||
if(!filename) {
|
if(!filename) {
|
||||||
return(-1);
|
RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1);
|
||||||
}
|
}
|
||||||
destfile = get_destfile(localpath, filename);
|
destfile = get_destfile(localpath, filename);
|
||||||
tempfile = get_tempfile(localpath, filename);
|
tempfile = get_tempfile(localpath, filename);
|
||||||
|
@ -275,7 +283,7 @@ static int download_external(const char *url, const char *localpath,
|
||||||
getcwd(cwd, PATH_MAX);
|
getcwd(cwd, PATH_MAX);
|
||||||
if(chdir(localpath)) {
|
if(chdir(localpath)) {
|
||||||
_alpm_log(PM_LOG_WARNING, _("could not chdir to %s\n"), localpath);
|
_alpm_log(PM_LOG_WARNING, _("could not chdir to %s\n"), localpath);
|
||||||
pm_errno = PM_ERR_CONNECT_FAILED;
|
pm_errno = PM_ERR_EXTERNAL_DOWNLOAD;
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -285,7 +293,7 @@ static int download_external(const char *url, const char *localpath,
|
||||||
|
|
||||||
if(retval == -1) {
|
if(retval == -1) {
|
||||||
_alpm_log(PM_LOG_WARNING, _("running XferCommand: fork failed!\n"));
|
_alpm_log(PM_LOG_WARNING, _("running XferCommand: fork failed!\n"));
|
||||||
pm_errno = PM_ERR_FORK_FAILED;
|
pm_errno = PM_ERR_EXTERNAL_DOWNLOAD;
|
||||||
ret = -1;
|
ret = -1;
|
||||||
} else if(retval != 0) {
|
} else if(retval != 0) {
|
||||||
/* download failed */
|
/* download failed */
|
||||||
|
@ -331,8 +339,18 @@ static int download(const char *url, const char *localpath,
|
||||||
return(ret ? -1 : 0);
|
return(ret ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We have a few things to take into account here.
|
||||||
|
* 1. If we have both internal/external available, choose based on
|
||||||
|
* whether xfercommand is populated.
|
||||||
|
* 2. If we only have external available, we should first check
|
||||||
|
* if a command was provided before we drop into download_external.
|
||||||
|
*/
|
||||||
if(handle->xfercommand == NULL) {
|
if(handle->xfercommand == NULL) {
|
||||||
|
#if defined(INTERNAL_DOWNLOAD)
|
||||||
ret = download_internal(url, localpath, mtimeold, mtimenew);
|
ret = download_internal(url, localpath, mtimeold, mtimenew);
|
||||||
|
#else
|
||||||
|
RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
ret = download_external(url, localpath, mtimeold, mtimenew);
|
ret = download_external(url, localpath, mtimeold, mtimenew);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,9 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined(INTERNAL_DOWNLOAD)
|
||||||
#include <download.h> /* downloadLastErrString */
|
#include <download.h> /* downloadLastErrString */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* libalpm */
|
/* libalpm */
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -132,9 +134,6 @@ const char SYMEXPORT *alpm_strerror(int err)
|
||||||
return _("not confirmed");
|
return _("not confirmed");
|
||||||
case PM_ERR_INVALID_REGEX:
|
case PM_ERR_INVALID_REGEX:
|
||||||
return _("invalid regular expression");
|
return _("invalid regular expression");
|
||||||
/* Downloading */
|
|
||||||
case PM_ERR_CONNECT_FAILED:
|
|
||||||
return _("connection to remote host failed");
|
|
||||||
/* Errors from external libraries- our own wrapper error */
|
/* Errors from external libraries- our own wrapper error */
|
||||||
case PM_ERR_LIBARCHIVE:
|
case PM_ERR_LIBARCHIVE:
|
||||||
/* it would be nice to use archive_error_string() here, but that
|
/* it would be nice to use archive_error_string() here, but that
|
||||||
|
@ -142,7 +141,14 @@ const char SYMEXPORT *alpm_strerror(int err)
|
||||||
* error string instead. */
|
* error string instead. */
|
||||||
return _("libarchive error");
|
return _("libarchive error");
|
||||||
case PM_ERR_LIBDOWNLOAD:
|
case PM_ERR_LIBDOWNLOAD:
|
||||||
|
#if defined(INTERNAL_DOWNLOAD)
|
||||||
return downloadLastErrString;
|
return downloadLastErrString;
|
||||||
|
#else
|
||||||
|
/* obviously shouldn't get here... */
|
||||||
|
return _("libdownload error");
|
||||||
|
#endif
|
||||||
|
case PM_ERR_EXTERNAL_DOWNLOAD:
|
||||||
|
return _("error invoking external downloader");
|
||||||
/* Unknown error! */
|
/* Unknown error! */
|
||||||
default:
|
default:
|
||||||
return _("unexpected error");
|
return _("unexpected error");
|
||||||
|
|
Loading…
Add table
Reference in a new issue