diff options
Diffstat (limited to 'lib')
45 files changed, 2491 insertions, 1808 deletions
diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am index 1bda5714..b2b6d0d2 100644 --- a/lib/libalpm/Makefile.am +++ b/lib/libalpm/Makefile.am @@ -35,13 +35,14 @@ libalpm_la_SOURCES = \ diskspace.h diskspace.c \ dload.h dload.c \ error.c \ - graph.h \ + graph.h graph.c \ group.h group.c \ handle.h handle.c \ log.h log.c \ package.h package.c \ pkghash.h pkghash.c \ remove.h remove.c \ + signing.c signing.h \ sync.h sync.c \ trans.h trans.c \ util.h util.c \ @@ -52,7 +53,12 @@ libalpm_la_SOURCES += \ md5.h md5.c endif -libalpm_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_INFO) +if HAVE_LIBGPGME +libalpm_la_SOURCES += \ + base64.h base64.c +endif + +libalpm_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_INFO) @LIBCURL@ libalpm_la_LIBADD = $(LTLIBINTL) # vim:set ts=2 sw=2 noet: diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index ad6ef17e..59d539c6 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -44,15 +44,10 @@ #include "backup.h" #include "package.h" #include "db.h" -#include "conflict.h" -#include "deps.h" #include "remove.h" #include "handle.h" -/** Add a package to the transaction. - * @param pkg the package to add - * @return 0 on success, -1 on error (pm_errno is set accordingly) - */ +/** Add a package to the transaction. */ int SYMEXPORT alpm_add_pkg(pmpkg_t *pkg) { const char *pkgname, *pkgver; @@ -60,19 +55,15 @@ int SYMEXPORT alpm_add_pkg(pmpkg_t *pkg) pmdb_t *db_local; pmpkg_t *local; - ALPM_LOG_FUNC; - /* Sanity checks */ ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); - trans = handle->trans; + trans = pkg->handle->trans; ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1)); - ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); - db_local = handle->db_local; + db_local = pkg->handle->db_local; - pkgname = alpm_pkg_get_name(pkg); - pkgver = alpm_pkg_get_version(pkg); + pkgname = pkg->name; + pkgver = pkg->version; _alpm_log(PM_LOG_DEBUG, "adding package '%s'\n", pkgname); @@ -91,7 +82,7 @@ int SYMEXPORT alpm_add_pkg(pmpkg_t *pkg) /* with the NEEDED flag, packages up to date are not reinstalled */ _alpm_log(PM_LOG_WARNING, _("%s-%s is up to date -- skipping\n"), localpkgname, localpkgver); - return(0); + return 0; } else if(!(trans->flags & PM_TRANS_FLAG_DOWNLOADONLY)) { _alpm_log(PM_LOG_WARNING, _("%s-%s is up to date -- reinstalling\n"), localpkgname, localpkgver); @@ -105,11 +96,11 @@ int SYMEXPORT alpm_add_pkg(pmpkg_t *pkg) /* add the package to the transaction */ pkg->reason = PM_PKG_REASON_EXPLICIT; - _alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n", + _alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction add list\n", pkgname, pkgver); trans->add = alpm_list_add(trans->add, pkg); - return(0); + return 0; } static int perform_extraction(struct archive *archive, @@ -132,14 +123,13 @@ static int perform_extraction(struct archive *archive, origname, archive_error_string(archive)); alpm_logaction("error: could not extract %s (%s)\n", origname, archive_error_string(archive)); - return(1); + return 1; } - return(0); + return 0; } -static int extract_single_file(struct archive *archive, - struct archive_entry *entry, pmpkg_t *newpkg, pmpkg_t *oldpkg, - pmtrans_t *trans, pmdb_t *db) +static int extract_single_file(pmhandle_t *handle, struct archive *archive, + struct archive_entry *entry, pmpkg_t *newpkg, pmpkg_t *oldpkg) { const char *entryname; mode_t entrymode; @@ -157,19 +147,19 @@ static int extract_single_file(struct archive *archive, if(strcmp(entryname, ".INSTALL") == 0) { /* the install script goes inside the db */ snprintf(filename, PATH_MAX, "%s%s-%s/install", - _alpm_db_path(db), newpkg->name, newpkg->version); + _alpm_db_path(handle->db_local), newpkg->name, newpkg->version); archive_entry_set_perm(entry, 0644); } else if(strcmp(entryname, ".CHANGELOG") == 0) { /* the changelog goes inside the db */ snprintf(filename, PATH_MAX, "%s%s-%s/changelog", - _alpm_db_path(db), newpkg->name, newpkg->version); + _alpm_db_path(handle->db_local), newpkg->name, newpkg->version); archive_entry_set_perm(entry, 0644); } else if(*entryname == '.') { /* for now, ignore all files starting with '.' that haven't * already been handled (for future possibilities) */ _alpm_log(PM_LOG_DEBUG, "skipping extraction of '%s'\n", entryname); archive_read_data_skip(archive); - return(0); + return 0; } else { /* build the new entryname relative to handle->root */ snprintf(filename, PATH_MAX, "%s%s", handle->root, entryname); @@ -182,7 +172,7 @@ static int extract_single_file(struct archive *archive, alpm_logaction("note: %s is in NoExtract, skipping extraction\n", entryname); archive_read_data_skip(archive); - return(0); + return 0; } /* Check for file existence. This is one of the more crucial parts @@ -226,13 +216,13 @@ static int extract_single_file(struct archive *archive, _alpm_log(PM_LOG_DEBUG, "extract: skipping dir extraction of %s\n", entryname); archive_read_data_skip(archive); - return(0); + return 0; } else { /* case 10/11: trying to overwrite dir with file/symlink, don't allow it */ _alpm_log(PM_LOG_ERROR, _("extract: not overwriting dir with file %s\n"), entryname); archive_read_data_skip(archive); - return(1); + return 1; } } else if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(entrymode)) { /* case 9: existing symlink, dir in package */ @@ -241,13 +231,13 @@ static int extract_single_file(struct archive *archive, _alpm_log(PM_LOG_DEBUG, "extract: skipping symlink overwrite of %s\n", entryname); archive_read_data_skip(archive); - return(0); + return 0; } else { /* this is BAD. symlink was not to a directory */ _alpm_log(PM_LOG_ERROR, _("extract: symlink %s does not point to dir\n"), entryname); archive_read_data_skip(archive); - return(1); + return 1; } } else if(S_ISREG(lsbuf.st_mode) && S_ISDIR(entrymode)) { /* case 6: trying to overwrite file with dir */ @@ -299,7 +289,7 @@ static int extract_single_file(struct archive *archive, /* error */ FREE(hash_orig); FREE(entryname_orig); - return(1); + return 1; } hash_local = alpm_compute_md5sum(filename); @@ -431,7 +421,7 @@ static int extract_single_file(struct archive *archive, _alpm_log(PM_LOG_DEBUG, "extracting %s\n", filename); } - if(trans->flags & PM_TRANS_FLAG_FORCE) { + if(handle->trans->flags & PM_TRANS_FLAG_FORCE) { /* if FORCE was used, unlink() each file (whether it's there * or not) before extracting. This prevents the old "Text file busy" * error that crops up if forcing a glibc or pacman upgrade. */ @@ -442,7 +432,7 @@ static int extract_single_file(struct archive *archive, if(ret == 1) { /* error */ FREE(entryname_orig); - return(1); + return 1; } /* calculate an hash if this is in newpkg's backup */ @@ -469,20 +459,18 @@ static int extract_single_file(struct archive *archive, } } FREE(entryname_orig); - return(errors); + return errors; } -static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current, - size_t pkg_count, pmtrans_t *trans, pmdb_t *db) +static int commit_single_pkg(pmhandle_t *handle, pmpkg_t *newpkg, + size_t pkg_current, size_t pkg_count) { int i, ret = 0, errors = 0; char scriptlet[PATH_MAX+1]; int is_upgrade = 0; pmpkg_t *oldpkg = NULL; - - ALPM_LOG_FUNC; - - ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); + pmdb_t *db = handle->db_local; + pmtrans_t *trans = handle->trans; snprintf(scriptlet, PATH_MAX, "%s%s-%s/install", _alpm_db_path(db), alpm_pkg_get_name(newpkg), @@ -508,8 +496,8 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current, /* pre_upgrade scriptlet */ if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { - _alpm_runscriptlet(handle->root, newpkg->origin_data.file, - "pre_upgrade", newpkg->version, oldpkg->version, trans); + _alpm_runscriptlet(newpkg->handle, newpkg->origin_data.file, + "pre_upgrade", newpkg->version, oldpkg->version); } } else { is_upgrade = 0; @@ -520,8 +508,8 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current, /* pre_install scriptlet */ if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { - _alpm_runscriptlet(handle->root, newpkg->origin_data.file, - "pre_install", newpkg->version, NULL, trans); + _alpm_runscriptlet(newpkg->handle, newpkg->origin_data.file, + "pre_install", newpkg->version, NULL); } } @@ -534,7 +522,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current, if(oldpkg) { /* set up fake remove transaction */ - if(_alpm_upgraderemove_package(oldpkg, newpkg, trans) == -1) { + if(_alpm_upgraderemove_package(newpkg->handle, oldpkg, newpkg) == -1) { pm_errno = PM_ERR_TRANS_ABORT; ret = -1; goto cleanup; @@ -559,7 +547,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current, _alpm_log(PM_LOG_DEBUG, "extracting files\n"); - if ((archive = archive_read_new()) == NULL) { + if((archive = archive_read_new()) == NULL) { pm_errno = PM_ERR_LIBARCHIVE; ret = -1; goto cleanup; @@ -584,8 +572,9 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current, } /* libarchive requires this for extracting hard links */ - if(chdir(handle->root) != 0) { - _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), handle->root, strerror(errno)); + if(chdir(newpkg->handle->root) != 0) { + _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), + newpkg->handle->root, strerror(errno)); ret = -1; goto cleanup; } @@ -629,8 +618,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current, } /* extract the next file from the archive */ - errors += extract_single_file(archive, entry, newpkg, oldpkg, - trans, db); + errors += extract_single_file(newpkg->handle, archive, entry, newpkg, oldpkg); } archive_read_finish(archive); @@ -688,12 +676,12 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current, if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { if(is_upgrade) { - _alpm_runscriptlet(handle->root, scriptlet, "post_upgrade", + _alpm_runscriptlet(newpkg->handle, scriptlet, "post_upgrade", alpm_pkg_get_version(newpkg), - oldpkg ? alpm_pkg_get_version(oldpkg) : NULL, trans); + oldpkg ? alpm_pkg_get_version(oldpkg) : NULL); } else { - _alpm_runscriptlet(handle->root, scriptlet, "post_install", - alpm_pkg_get_version(newpkg), NULL, trans); + _alpm_runscriptlet(newpkg->handle, scriptlet, "post_install", + alpm_pkg_get_version(newpkg), NULL); } } @@ -705,22 +693,18 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current, cleanup: _alpm_pkg_free(oldpkg); - return(ret); + return ret; } -int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db) +int _alpm_upgrade_packages(pmhandle_t *handle) { size_t pkg_count, pkg_current; int skip_ldconfig = 0, ret = 0; alpm_list_t *targ; - - ALPM_LOG_FUNC; - - ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); - ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); + pmtrans_t *trans = handle->trans; if(trans->add == NULL) { - return(0); + return 0; } pkg_count = alpm_list_count(trans->add); @@ -729,11 +713,11 @@ int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db) /* loop through our package list adding/upgrading one at a time */ for(targ = trans->add; targ; targ = targ->next) { if(handle->trans->state == STATE_INTERRUPTED) { - return(ret); + return ret; } pmpkg_t *newpkg = (pmpkg_t *)targ->data; - if(commit_single_pkg(newpkg, pkg_current, pkg_count, trans, db)) { + if(commit_single_pkg(handle, newpkg, pkg_current, pkg_count)) { /* something screwed up on the commit, abort the trans */ trans->state = STATE_INTERRUPTED; pm_errno = PM_ERR_TRANS_ABORT; @@ -747,10 +731,10 @@ int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db) if(!skip_ldconfig) { /* run ldconfig if it exists */ - _alpm_ldconfig(handle->root); + _alpm_ldconfig(handle); } - return(ret); + return ret; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/add.h b/lib/libalpm/add.h index afc7be26..1baab8d4 100644 --- a/lib/libalpm/add.h +++ b/lib/libalpm/add.h @@ -24,7 +24,7 @@ #include "alpm_list.h" #include "trans.h" -int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db); +int _alpm_upgrade_packages(pmhandle_t *handle); #endif /* _ALPM_ADD_H */ diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index a60a4bb6..d5168709 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -23,19 +23,20 @@ #include "config.h" -/* connection caching setup */ -#ifdef HAVE_LIBFETCH -#include <fetch.h> +#ifdef HAVE_LIBCURL +#include <curl/curl.h> #endif /* libalpm */ #include "alpm.h" #include "alpm_list.h" #include "handle.h" +#include "log.h" #include "util.h" /* Globals */ enum _pmerrno_t pm_errno SYMEXPORT; +extern pmhandle_t *handle; /** \addtogroup alpm_interface Interface Functions * @brief Functions to initialize and release libalpm @@ -44,64 +45,93 @@ enum _pmerrno_t pm_errno SYMEXPORT; /** Initializes the library. This must be called before any other * functions are called. - * @return 0 on success, -1 on error (pm_errno is set accordingly) + * @param root the root path for all filesystem operations + * @param dbpath the absolute path to the libalpm database + * @param err an optional variable to hold any error return codes + * @return a context handle on success, NULL on error, err will be set if provided */ -int SYMEXPORT alpm_initialize(void) +pmhandle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath, + enum _pmerrno_t *err) { - ASSERT(handle == NULL, RET_ERR(PM_ERR_HANDLE_NOT_NULL, -1)); - - handle = _alpm_handle_new(); - if(handle == NULL) { - RET_ERR(PM_ERR_MEMORY, -1); + enum _pmerrno_t myerr; + const char *lf = "db.lck"; + size_t lockfilelen; + pmhandle_t *myhandle = _alpm_handle_new(); + + if(myhandle == NULL) { + myerr = PM_ERR_MEMORY; + goto cleanup; + } + if((myerr = _alpm_set_directory_option(root, &(myhandle->root), 1))) { + goto cleanup; } - if(_alpm_db_register_local() == NULL) { - /* error code should be set */ - _alpm_handle_free(handle); - handle = NULL; - return(-1); + if((myerr = _alpm_set_directory_option(dbpath, &(myhandle->dbpath), 1))) { + goto cleanup; + } + + lockfilelen = strlen(myhandle->dbpath) + strlen(lf) + 1; + myhandle->lockfile = calloc(lockfilelen, sizeof(char)); + snprintf(myhandle->lockfile, lockfilelen, "%s%s", myhandle->dbpath, lf); + + if(_alpm_db_register_local(myhandle) == NULL) { + myerr = PM_ERR_DB_CREATE; + goto cleanup; } #ifdef ENABLE_NLS bindtextdomain("libalpm", LOCALEDIR); #endif -#ifdef HAVE_LIBFETCH - fetchConnectionCacheInit(5, 1); +#ifdef HAVE_LIBCURL + curl_global_init(CURL_GLOBAL_SSL); + myhandle->curl = curl_easy_init(); #endif - return(0); + /* TODO temporary until global var removed */ + handle = myhandle; + return myhandle; + +cleanup: + _alpm_handle_free(myhandle); + if(err && myerr) { + *err = myerr; + } + return NULL; } /** Release the library. This should be the last alpm call you make. - * @return 0 on success, -1 on error (pm_errno is set accordingly) + * After this returns, handle should be considered invalid and cannot be reused + * in any way. + * @param handle the context handle + * @return 0 on success, -1 on error */ -int SYMEXPORT alpm_release(void) +int SYMEXPORT alpm_release(pmhandle_t *myhandle) { pmdb_t *db; - ALPM_LOG_FUNC; - - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + ASSERT(myhandle != NULL, return -1); /* close local database */ - db = handle->db_local; + db = myhandle->db_local; if(db) { db->ops->unregister(db); - handle->db_local = NULL; + myhandle->db_local = NULL; } - if(alpm_db_unregister_all() == -1) { - return(-1); + if(alpm_db_unregister_all(myhandle) == -1) { + return -1; } - _alpm_handle_free(handle); + _alpm_handle_free(myhandle); + myhandle = NULL; + /* TODO temporary until global var removed */ handle = NULL; -#ifdef HAVE_LIBFETCH - fetchConnectionCacheClose(); +#ifdef HAVE_LIBCURL + curl_global_cleanup(); #endif - return(0); + return 0; } /** @} */ @@ -112,7 +142,7 @@ int SYMEXPORT alpm_release(void) /* Get the version of library */ const char SYMEXPORT *alpm_version(void) { - return(LIB_VERSION); + return LIB_VERSION; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index cb643d29..ee55d0b9 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -45,9 +45,36 @@ extern "C" { */ /* + * Enumerations + * These ones are used in multiple contexts, so are forward-declared. + */ + +/** + * Install reasons + * Why the package was installed. + */ +typedef enum _pmpkgreason_t { + /** Explicitly requested by the user. */ + PM_PKG_REASON_EXPLICIT = 0, + /** Installed as a dependency for another package. */ + PM_PKG_REASON_DEPEND = 1 +} pmpkgreason_t; + +/** + * GPG signature verification options + */ +typedef enum _pgp_verify_t { + PM_PGP_VERIFY_UNKNOWN, + PM_PGP_VERIFY_NEVER, + PM_PGP_VERIFY_OPTIONAL, + PM_PGP_VERIFY_ALWAYS +} pgp_verify_t; + +/* * Structures */ +typedef struct __pmhandle_t pmhandle_t; typedef struct __pmdb_t pmdb_t; typedef struct __pmpkg_t pmpkg_t; typedef struct __pmdelta_t pmdelta_t; @@ -59,18 +86,12 @@ typedef struct __pmconflict_t pmconflict_t; typedef struct __pmfileconflict_t pmfileconflict_t; /* - * Library - */ - -int alpm_initialize(void); -int alpm_release(void); -const char *alpm_version(void); - -/* * Logging facilities */ -/* Levels */ +/** + * Logging Levels + */ typedef enum _pmloglevel_t { PM_LOG_ERROR = 1, PM_LOG_WARNING = (1 << 1), @@ -85,9 +106,16 @@ int alpm_logaction(const char *fmt, ...); * Downloading */ +/** Type of download progress callbacks. + * @param filename the name of the file being downloaded + * @param xfered the number of transferred bytes + * @param total the total number of bytes to transfer + */ typedef void (*alpm_cb_download)(const char *filename, off_t xfered, off_t total); + typedef void (*alpm_cb_totaldl)(off_t total); + /** A callback for downloading files * @param url the URL of the file to be downloaded * @param localpath the directory to which the file should be downloaded @@ -109,100 +137,119 @@ char *alpm_fetch_pkgurl(const char *url); * @{ */ -/** @name The logging callback. */ -/* @{ */ +/** Returns the callback used for logging. */ alpm_cb_log alpm_option_get_logcb(void); -void alpm_option_set_logcb(alpm_cb_log cb); -/* @} */ +/** Sets the callback used for logging. */ +int alpm_option_set_logcb(alpm_cb_log cb); -/** Get/set the download progress callback. */ +/** Returns the callback used to report download progress. */ alpm_cb_download alpm_option_get_dlcb(void); -void alpm_option_set_dlcb(alpm_cb_download cb); +/** Sets the callback used to report download progress. */ +int alpm_option_set_dlcb(alpm_cb_download cb); -/** Get/set the downloader callback. */ +/** Returns the downloading callback. */ alpm_cb_fetch alpm_option_get_fetchcb(void); -void alpm_option_set_fetchcb(alpm_cb_fetch cb); +/** Sets the downloading callback. */ +int alpm_option_set_fetchcb(alpm_cb_fetch cb); -/** Get/set the callback used when download size is known. */ +/** Returns the callback used to report total download size. */ alpm_cb_totaldl alpm_option_get_totaldlcb(void); -void alpm_option_set_totaldlcb(alpm_cb_totaldl cb); +/** Sets the callback used to report total download size. */ +int alpm_option_set_totaldlcb(alpm_cb_totaldl cb); -/** Get/set the root of the destination filesystem. */ +/** Returns the root of the destination filesystem. Read-only. */ const char *alpm_option_get_root(void); -int alpm_option_set_root(const char *root); -/** Get/set the path to the database directory. */ +/** Returns the path to the database directory. Read-only. */ const char *alpm_option_get_dbpath(void); -int alpm_option_set_dbpath(const char *dbpath); -/** Get/set the list of package cache directories. */ -alpm_list_t *alpm_option_get_cachedirs(void); -void alpm_option_set_cachedirs(alpm_list_t *cachedirs); +/** Get the name of the database lock file. Read-only. */ +const char *alpm_option_get_lockfile(void); -/** Add a single directory to the package cache paths. */ +/** @name Accessors to the list of package cache directories. + * @{ + */ +alpm_list_t *alpm_option_get_cachedirs(void); +int alpm_option_set_cachedirs(alpm_list_t *cachedirs); int alpm_option_add_cachedir(const char *cachedir); - -/** Remove a single directory from the package cache paths. */ int alpm_option_remove_cachedir(const char *cachedir); +/** @} */ -/** Get/set the logfile name. */ +/** Returns the logfile name. */ const char *alpm_option_get_logfile(void); +/** Sets the logfile name. */ int alpm_option_set_logfile(const char *logfile); -/** Get the name of the database lock file. - * - * This properly is read-only, and determined from - * the database path. - * - * @sa alpm_option_set_dbpath(const char*) - */ -const char *alpm_option_get_lockfile(void); +/** Returns the signature directory path. */ +const char *alpm_option_get_signaturedir(void); +/** Sets the signature directory path. */ +int alpm_option_set_signaturedir(const char *signaturedir); -/** Get/set whether to use syslog (0 is FALSE, TRUE otherwise). */ +/** Returns whether to use syslog (0 is FALSE, TRUE otherwise). */ int alpm_option_get_usesyslog(void); -void alpm_option_set_usesyslog(int usesyslog); +/** Sets whether to use syslog (0 is FALSE, TRUE otherwise). */ +int alpm_option_set_usesyslog(int usesyslog); +/** @name Accessors to the list of no-upgrade files. + * These functions modify the list of files which should + * not be updated by package installation. + * @{ + */ alpm_list_t *alpm_option_get_noupgrades(void); -void alpm_option_add_noupgrade(const char *pkg); -void alpm_option_set_noupgrades(alpm_list_t *noupgrade); +int alpm_option_add_noupgrade(const char *pkg); +int alpm_option_set_noupgrades(alpm_list_t *noupgrade); int alpm_option_remove_noupgrade(const char *pkg); +/** @} */ +/** @name Accessors to the list of no-extract files. + * These functions modify the list of filenames which should + * be skipped packages which should + * not be upgraded by a sysupgrade operation. + * @{ + */ alpm_list_t *alpm_option_get_noextracts(void); -void alpm_option_add_noextract(const char *pkg); -void alpm_option_set_noextracts(alpm_list_t *noextract); +int alpm_option_add_noextract(const char *pkg); +int alpm_option_set_noextracts(alpm_list_t *noextract); int alpm_option_remove_noextract(const char *pkg); +/** @} */ +/** @name Accessors to the list of ignored packages. + * These functions modify the list of packages that + * should be ignored by a sysupgrade. + * @{ + */ alpm_list_t *alpm_option_get_ignorepkgs(void); -void alpm_option_add_ignorepkg(const char *pkg); -void alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs); +int alpm_option_add_ignorepkg(const char *pkg); +int alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs); int alpm_option_remove_ignorepkg(const char *pkg); +/** @} */ +/** @name Accessors to the list of ignored groups. + * These functions modify the list of groups whose packages + * should be ignored by a sysupgrade. + * @{ + */ alpm_list_t *alpm_option_get_ignoregrps(void); -void alpm_option_add_ignoregrp(const char *grp); -void alpm_option_set_ignoregrps(alpm_list_t *ignoregrps); +int alpm_option_add_ignoregrp(const char *grp); +int alpm_option_set_ignoregrps(alpm_list_t *ignoregrps); int alpm_option_remove_ignoregrp(const char *grp); +/** @} */ -/** Get/set the targeted architecture. */ +/** Returns the targeted architecture. */ const char *alpm_option_get_arch(void); -void alpm_option_set_arch(const char *arch); +/** Sets the targeted architecture. */ +int alpm_option_set_arch(const char *arch); int alpm_option_get_usedelta(void); -void alpm_option_set_usedelta(int usedelta); +int alpm_option_set_usedelta(int usedelta); int alpm_option_get_checkspace(void); -void alpm_option_set_checkspace(int checkspace); +int alpm_option_set_checkspace(int checkspace); -/** @} */ +pgp_verify_t alpm_option_get_default_sigverify(void); +int alpm_option_set_default_sigverify(pgp_verify_t level); -/** Install reasons - * Why the package was installed. - */ -typedef enum _pmpkgreason_t { - /** Explicitly requested by the user. */ - PM_PKG_REASON_EXPLICIT = 0, - /** Installed as a dependency for another package. */ - PM_PKG_REASON_DEPEND = 1 -} pmpkgreason_t; +/** @} */ /** @addtogroup alpm_api_databases Database Functions * Functions to query and manipulate the database of libalpm. @@ -237,9 +284,10 @@ pmdb_t *alpm_db_register_sync(const char *treename); int alpm_db_unregister(pmdb_t *db); /** Unregister all package databases. + * @param handle the context handle * @return 0 on success, -1 on error (pm_errno is set accordingly) */ -int alpm_db_unregister_all(void); +int alpm_db_unregister_all(pmhandle_t *handle); /** Get the name of a package database. * @param db pointer to the package database @@ -253,12 +301,14 @@ const char *alpm_db_get_name(const pmdb_t *db); */ const char *alpm_db_get_url(const pmdb_t *db); -/** Set the serverlist of a database. - * @param db database pointer - * @param url url of the server - * @return 0 on success, -1 on error (pm_errno is set accordingly) +/** @name Accessors to the list of servers for a database. + * @{ */ -int alpm_db_setserver(pmdb_t *db, const char *url); +alpm_list_t *alpm_db_get_servers(const pmdb_t *db); +int alpm_db_set_servers(pmdb_t *db, alpm_list_t *servers); +int alpm_db_add_server(pmdb_t *db, const char *url); +int alpm_db_remove_server(pmdb_t *db, const char *url); +/** @} */ int alpm_db_update(int level, pmdb_t *db); @@ -288,10 +338,10 @@ pmgrp_t *alpm_db_readgrp(pmdb_t *db, const char *name); */ alpm_list_t *alpm_db_get_grpcache(pmdb_t *db); -/** Searches a database. +/** Searches a database with regular expressions. * @param db pointer to the package database to search in - * @param needles the list of strings to search for - * @return the list of packages on success, NULL on error + * @param needles a list of regular expressions to search for + * @return the list of packages matching all regular expressions on success, NULL on error */ alpm_list_t *alpm_db_search(pmdb_t *db, const alpm_list_t* needles); @@ -313,14 +363,18 @@ int alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t reason); /** Create a package from a file. * If full is false, the archive is read only until all necessary * metadata is found. If it is true, the entire archive is read, which - * serves as a verfication of integrity and the filelist can be created. + * serves as a verification of integrity and the filelist can be created. + * The allocated structure should be freed using alpm_pkg_free(). * @param filename location of the package tarball * @param full whether to stop the load after metadata is read or continue - * through the full archive + * through the full archive + * @param check_sig what level of package signature checking to perform on the + * package; note that this must be a '.sig' file type verification * @param pkg address of the package pointer * @return 0 on success, -1 on error (pm_errno is set accordingly) */ -int alpm_pkg_load(const char *filename, int full, pmpkg_t **pkg); +int alpm_pkg_load(const char *filename, int full, pgp_verify_t check_sig, + pmpkg_t **pkg); /** Free a package. * @param pkg package pointer to free @@ -498,9 +552,9 @@ alpm_list_t *alpm_pkg_get_files(pmpkg_t *pkg); */ alpm_list_t *alpm_pkg_get_backup(pmpkg_t *pkg); -/** Returns the database containing pkg +/** Returns the database containing pkg. * Returns a pointer to the pmdb_t structure the package is - * originating from, or NULL is the package was loaded from a file. + * originating from, or NULL if the package was loaded from a file. * @param pkg a pointer to package * @return a pointer to the DB containing pkg, or NULL. */ @@ -534,6 +588,9 @@ size_t alpm_pkg_changelog_read(void *ptr, size_t size, int alpm_pkg_changelog_close(const pmpkg_t *pkg, void *fp); +/** Returns whether the package has an install scriptlet. + * @return 0 if FALSE, TRUE otherwise + */ int alpm_pkg_has_scriptlet(pmpkg_t *pkg); /** Returns the size of download. @@ -550,6 +607,15 @@ alpm_list_t *alpm_pkg_unused_deltas(pmpkg_t *pkg); /** @} */ /* + * Signatures + */ + +int alpm_pkg_check_pgp_signature(pmpkg_t *pkg); + +int alpm_db_check_pgp_signature(pmdb_t *db); +int alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify); + +/* * Deltas */ @@ -726,6 +792,9 @@ typedef void (*alpm_trans_cb_conv)(pmtransconv_t, void *, void *, /** Transaction Progress callback */ typedef void (*alpm_trans_cb_progress)(pmtransprog_t, const char *, int, size_t, size_t); +/** Returns the bitfield of flags for the current transaction. + * @sa _pmtransflag_t + */ int alpm_trans_get_flags(void); /** Returns a list of packages added by the transaction. @@ -776,9 +845,27 @@ int alpm_trans_release(void); /** @name Common Transactions */ /** @{ */ + +/** Search for packages to upgrade and add them to the transaction. + * @param enable_downgrade allow downgrading of packages if the remote version is lower + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ int alpm_sync_sysupgrade(int enable_downgrade); + +/** Add a package to the transaction. + * If the package was loaded by alpm_pkg_load(), it will be freed upon + * alpm_trans_release() invocation. + * @param pkg the package to add + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ int alpm_add_pkg(pmpkg_t *pkg); + +/** Add a package removal action to the transaction. + * @param pkg the package to uninstall + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ int alpm_remove_pkg(pmpkg_t *pkg); + /** @} */ /** @addtogroup alpm_api_depends Dependency Functions @@ -916,6 +1003,10 @@ enum _pmerrno_t { PM_ERR_PKG_INVALID_NAME, PM_ERR_PKG_INVALID_ARCH, PM_ERR_PKG_REPO_NOT_FOUND, + /* Signatures */ + PM_ERR_SIG_MISSINGDIR, + PM_ERR_SIG_INVALID, + PM_ERR_SIG_UNKNOWN, /* Deltas */ PM_ERR_DLT_INVALID, PM_ERR_DLT_PATCHFAILED, @@ -929,8 +1020,9 @@ enum _pmerrno_t { PM_ERR_INVALID_REGEX, /* External library errors */ PM_ERR_LIBARCHIVE, - PM_ERR_LIBFETCH, - PM_ERR_EXTERNAL_DOWNLOAD + PM_ERR_LIBCURL, + PM_ERR_EXTERNAL_DOWNLOAD, + PM_ERR_GPGME }; /** The number of the last error that occurred. */ @@ -945,6 +1037,11 @@ const char *alpm_strerrorlast(void); /* End of alpm_api_errors */ /** @} */ +pmhandle_t *alpm_initialize(const char *root, const char *dbpath, + enum _pmerrno_t *err); +int alpm_release(pmhandle_t *handle); +const char *alpm_version(void); + /* End of alpm_api */ /** @} */ diff --git a/lib/libalpm/alpm_list.c b/lib/libalpm/alpm_list.c index 42ef367a..c2b30adc 100644 --- a/lib/libalpm/alpm_list.c +++ b/lib/libalpm/alpm_list.c @@ -20,7 +20,6 @@ #include <stdlib.h> #include <string.h> -#include <stdio.h> /* libalpm */ #include "alpm_list.h" @@ -92,7 +91,7 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data) ptr = calloc(1, sizeof(alpm_list_t)); if(ptr == NULL) { - return(list); + return list; } ptr->data = data; @@ -101,7 +100,7 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data) /* Special case: the input list is empty */ if(list == NULL) { ptr->prev = ptr; - return(ptr); + return ptr; } lp = alpm_list_last(list); @@ -109,7 +108,7 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data) ptr->prev = lp; list->prev = ptr; - return(list); + return list; } /** @@ -124,13 +123,13 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data) alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_list_fn_cmp fn) { if(!fn || !list) { - return(alpm_list_add(list, data)); + return alpm_list_add(list, data); } else { alpm_list_t *add = NULL, *prev = NULL, *next = list; add = calloc(1, sizeof(alpm_list_t)); if(add == NULL) { - return(list); + return list; } add->data = data; @@ -146,19 +145,19 @@ alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_ add->prev = list->prev; /* list != NULL */ add->next = list; list->prev = add; - return(add); + return add; } else if(next == NULL) { /* another special case: add last element */ add->prev = prev; add->next = NULL; prev->next = add; list->prev = add; - return(list); + return list; } else { add->prev = prev; add->next = next; next->prev = add; prev->next = add; - return(list); + return list; } } } @@ -178,11 +177,11 @@ alpm_list_t SYMEXPORT *alpm_list_join(alpm_list_t *first, alpm_list_t *second) { alpm_list_t *tmp; - if (first == NULL) { - return(second); + if(first == NULL) { + return second; } - if (second == NULL) { - return(first); + if(second == NULL) { + return first; } /* tmp is the last element of the first list */ tmp = first->prev; @@ -193,7 +192,7 @@ alpm_list_t SYMEXPORT *alpm_list_join(alpm_list_t *first, alpm_list_t *second) /* set the back reference to the tail */ second->prev = tmp; - return(first); + return first; } /** @@ -209,12 +208,12 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a { alpm_list_t *newlist, *lp; - if (left == NULL) + if(left == NULL) return right; - if (right == NULL) + if(right == NULL) return left; - if (fn(left->data, right->data) <= 0) { + if(fn(left->data, right->data) <= 0) { newlist = left; left = left->next; } @@ -226,8 +225,8 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a newlist->next = NULL; lp = newlist; - while ((left != NULL) && (right != NULL)) { - if (fn(left->data, right->data) <= 0) { + while((left != NULL) && (right != NULL)) { + if(fn(left->data, right->data) <= 0) { lp->next = left; left->prev = lp; left = left->next; @@ -240,11 +239,11 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a lp = lp->next; lp->next = NULL; } - if (left != NULL) { + if(left != NULL) { lp->next = left; left->prev = lp; } - else if (right != NULL) { + else if(right != NULL) { lp->next = right; right->prev = lp; } @@ -257,7 +256,7 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a } newlist->prev = lp; - return(newlist); + return newlist; } /** @@ -271,7 +270,7 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a */ alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn_cmp fn) { - if (n > 1) { + if(n > 1) { alpm_list_t *left = list; alpm_list_t *lastleft = alpm_list_nth(list, n/2 - 1); alpm_list_t *right = lastleft->next; @@ -282,7 +281,7 @@ alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn right = alpm_list_msort(right, n - (n/2), fn); list = alpm_list_mmerge(left, right, fn); } - return(list); + return list; } /** @@ -298,7 +297,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove_item(alpm_list_t *haystack, alpm_list_t *item) { if(haystack == NULL || item == NULL) { - return(haystack); + return haystack; } if(item == haystack) { @@ -328,7 +327,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove_item(alpm_list_t *haystack, } } - return(haystack); + return haystack; } @@ -352,7 +351,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack, } if(needle == NULL) { - return(haystack); + return haystack; } while(i) { @@ -373,7 +372,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack, } } - return(haystack); + return haystack; } /** @@ -388,8 +387,8 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack, alpm_list_t SYMEXPORT *alpm_list_remove_str(alpm_list_t *haystack, const char *needle, char **data) { - return(alpm_list_remove(haystack, (const void *)needle, - (alpm_list_fn_cmp)strcmp, (void **)data)); + return alpm_list_remove(haystack, (const void *)needle, + (alpm_list_fn_cmp)strcmp, (void **)data); } /** @@ -411,7 +410,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove_dupes(const alpm_list_t *list) } lp = lp->next; } - return(newlist); + return newlist; } /** @@ -429,7 +428,7 @@ alpm_list_t SYMEXPORT *alpm_list_strdup(const alpm_list_t *list) newlist = alpm_list_add(newlist, strdup(lp->data)); lp = lp->next; } - return(newlist); + return newlist; } /** @@ -447,7 +446,7 @@ alpm_list_t SYMEXPORT *alpm_list_copy(const alpm_list_t *list) newlist = alpm_list_add(newlist, lp->data); lp = lp->next; } - return(newlist); + return newlist; } /** @@ -473,7 +472,7 @@ alpm_list_t SYMEXPORT *alpm_list_copy_data(const alpm_list_t *list, lp = lp->next; } } - return(newlist); + return newlist; } /** @@ -489,7 +488,7 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list) alpm_list_t *newlist = NULL, *backup; if(list == NULL) { - return(NULL); + return NULL; } lp = alpm_list_last(list); @@ -502,7 +501,7 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list) lp = lp->prev; } list->prev = backup; /* restore tail pointer */ - return(newlist); + return newlist; } /* Accessors */ @@ -517,9 +516,9 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list) inline alpm_list_t SYMEXPORT *alpm_list_first(const alpm_list_t *list) { if(list) { - return((alpm_list_t*)list); + return (alpm_list_t *)list; } else { - return(NULL); + return NULL; } } @@ -537,7 +536,7 @@ alpm_list_t SYMEXPORT *alpm_list_nth(const alpm_list_t *list, size_t n) while(n--) { i = i->next; } - return((alpm_list_t*)i); + return (alpm_list_t *)i; } /** @@ -550,9 +549,9 @@ alpm_list_t SYMEXPORT *alpm_list_nth(const alpm_list_t *list, size_t n) inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node) { if(node) { - return(node->next); + return node->next; } else { - return(NULL); + return NULL; } } @@ -566,9 +565,9 @@ inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node) alpm_list_t SYMEXPORT *alpm_list_last(const alpm_list_t *list) { if(list) { - return(list->prev); + return list->prev; } else { - return(NULL); + return NULL; } } @@ -581,8 +580,8 @@ alpm_list_t SYMEXPORT *alpm_list_last(const alpm_list_t *list) */ void SYMEXPORT *alpm_list_getdata(const alpm_list_t *node) { - if(node == NULL) return(NULL); - return(node->data); + if(node == NULL) return NULL; + return node->data; } /* Misc */ @@ -602,7 +601,7 @@ size_t SYMEXPORT alpm_list_count(const alpm_list_t *list) ++i; lp = lp->next; } - return(i); + return i; } /** @@ -620,17 +619,17 @@ void SYMEXPORT *alpm_list_find(const alpm_list_t *haystack, const void *needle, const alpm_list_t *lp = haystack; while(lp) { if(lp->data && fn(lp->data, needle) == 0) { - return(lp->data); + return lp->data; } lp = lp->next; } - return(NULL); + return NULL; } /* trivial helper function for alpm_list_find_ptr */ static int ptr_cmp(const void *p, const void *q) { - return(p != q); + return (p != q); } /** @@ -643,9 +642,10 @@ static int ptr_cmp(const void *p, const void *q) * * @return `needle` if found, NULL otherwise */ -void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, const void *needle) +void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, + const void *needle) { - return(alpm_list_find(haystack, needle, ptr_cmp)); + return alpm_list_find(haystack, needle, ptr_cmp); } /** @@ -659,8 +659,8 @@ void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, const void *need char SYMEXPORT *alpm_list_find_str(const alpm_list_t *haystack, const char *needle) { - return((char *)alpm_list_find(haystack, (const void*)needle, - (alpm_list_fn_cmp)strcmp)); + return (char *)alpm_list_find(haystack, (const void *)needle, + (alpm_list_fn_cmp)strcmp); } /** @@ -688,7 +688,7 @@ void SYMEXPORT alpm_list_diff_sorted(const alpm_list_t *left, return; } - while (l != NULL && r != NULL) { + while(l != NULL && r != NULL) { int cmp = fn(l->data, r->data); if(cmp < 0) { if(onlyleft) { @@ -706,13 +706,13 @@ void SYMEXPORT alpm_list_diff_sorted(const alpm_list_t *left, r = r->next; } } - while (l != NULL) { + while(l != NULL) { if(onlyleft) { *onlyleft = alpm_list_add(*onlyleft, l->data); } l = l->next; } - while (r != NULL) { + while(r != NULL) { if(onlyright) { *onlyright = alpm_list_add(*onlyright, r->data); } @@ -745,7 +745,7 @@ alpm_list_t SYMEXPORT *alpm_list_diff(const alpm_list_t *lhs, alpm_list_free(left); alpm_list_free(right); - return(ret); + return ret; } /** @} */ diff --git a/lib/libalpm/backup.c b/lib/libalpm/backup.c index ca955ca4..6431b286 100644 --- a/lib/libalpm/backup.c +++ b/lib/libalpm/backup.c @@ -47,7 +47,7 @@ static int backup_split(const char *string, char **file, char **hash) /* don't need our dup as the fname wasn't requested, so free it */ FREE(str); } - return(0); + return 0; } *ptr = '\0'; ptr++; @@ -59,21 +59,21 @@ static int backup_split(const char *string, char **file, char **hash) *hash = strdup(ptr); } FREE(str); - return(1); + return 1; } char *_alpm_backup_file(const char *string) { char *file = NULL; backup_split(string, &file, NULL); - return(file); + return file; } char *_alpm_backup_hash(const char *string) { char *hash = NULL; backup_split(string, NULL, &hash); - return(hash); + return hash; } /* Look for a filename in a pmpkg_t.backup list. If we find it, @@ -83,10 +83,8 @@ char *_alpm_needbackup(const char *file, const alpm_list_t *backup) { const alpm_list_t *lp; - ALPM_LOG_FUNC; - if(file == NULL || backup == NULL) { - return(NULL); + return NULL; } /* run through the backup list and parse out the hash for our file */ @@ -101,13 +99,13 @@ char *_alpm_needbackup(const char *file, const alpm_list_t *backup) } if(strcmp(file, filename) == 0) { FREE(filename); - return(hash); + return hash; } FREE(filename); FREE(hash); } - return(NULL); + return NULL; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/base64.c b/lib/libalpm/base64.c new file mode 100644 index 00000000..fa8bec5c --- /dev/null +++ b/lib/libalpm/base64.c @@ -0,0 +1,190 @@ +/* + * RFC 1521 base64 encoding/decoding + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +/* + * Pacman Notes: + * + * Taken from the PolarSSL project at www.polarssl.org under terms of the + * GPL. This is from version 0.14.2 of the library, and has been modified + * as following, which may be helpful for future updates: + * * remove "polarssl/config.h" include + * * change include from "polarssl/base64.h" to "base64.h" + * * removal of SELF_TEST code + */ + +#include "base64.h" + +static const unsigned char base64_enc_map[64] = +{ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '+', '/' +}; + +static const unsigned char base64_dec_map[128] = +{ + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, + 127, 64, 127, 127, 127, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 127, 127, 127, 127, 127 +}; + +/* + * Encode a buffer into base64 format + */ +int base64_encode( unsigned char *dst, int *dlen, + const unsigned char *src, int slen ) +{ + int i, n; + int C1, C2, C3; + unsigned char *p; + + if( slen == 0 ) + return( 0 ); + + n = (slen << 3) / 6; + + switch( (slen << 3) - (n * 6) ) + { + case 2: n += 3; break; + case 4: n += 2; break; + default: break; + } + + if( *dlen < n + 1 ) + { + *dlen = n + 1; + return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + n = (slen / 3) * 3; + + for( i = 0, p = dst; i < n; i += 3 ) + { + C1 = *src++; + C2 = *src++; + C3 = *src++; + + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; + *p++ = base64_enc_map[C3 & 0x3F]; + } + + if( i < slen ) + { + C1 = *src++; + C2 = ((i + 1) < slen) ? *src++ : 0; + + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + + if( (i + 1) < slen ) + *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; + else *p++ = '='; + + *p++ = '='; + } + + *dlen = p - dst; + *p = 0; + + return( 0 ); +} + +/* + * Decode a base64-formatted buffer + */ +int base64_decode( unsigned char *dst, int *dlen, + const unsigned char *src, int slen ) +{ + int i, j, n; + unsigned long x; + unsigned char *p; + + for( i = j = n = 0; i < slen; i++ ) + { + if( ( slen - i ) >= 2 && + src[i] == '\r' && src[i + 1] == '\n' ) + continue; + + if( src[i] == '\n' ) + continue; + + if( src[i] == '=' && ++j > 2 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + if( base64_dec_map[src[i]] < 64 && j != 0 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + n++; + } + + if( n == 0 ) + return( 0 ); + + n = ((n * 6) + 7) >> 3; + + if( *dlen < n ) + { + *dlen = n; + return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) + { + if( *src == '\r' || *src == '\n' ) + continue; + + j -= ( base64_dec_map[*src] == 64 ); + x = (x << 6) | ( base64_dec_map[*src] & 0x3F ); + + if( ++n == 4 ) + { + n = 0; + if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); + if( j > 1 ) *p++ = (unsigned char)( x >> 8 ); + if( j > 2 ) *p++ = (unsigned char)( x ); + } + } + + *dlen = p - dst; + + return( 0 ); +} diff --git a/lib/libalpm/base64.h b/lib/libalpm/base64.h new file mode 100644 index 00000000..0ae9612c --- /dev/null +++ b/lib/libalpm/base64.h @@ -0,0 +1,68 @@ +/** + * \file base64.h + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _BASE64_H +#define _BASE64_H + +#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL 0x0010 +#define POLARSSL_ERR_BASE64_INVALID_CHARACTER 0x0012 + +/** + * \brief Encode a buffer into base64 format + * + * \param dst destination buffer + * \param dlen size of the buffer + * \param src source buffer + * \param slen amount of data to be encoded + * + * \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL. + * *dlen is always updated to reflect the amount + * of data that has (or would have) been written. + * + * \note Call this function with *dlen = 0 to obtain the + * required buffer size in *dlen + */ +int base64_encode( unsigned char *dst, int *dlen, + const unsigned char *src, int slen ); + +/** + * \brief Decode a base64-formatted buffer + * + * \param dst destination buffer + * \param dlen size of the buffer + * \param src source buffer + * \param slen amount of data to be decoded + * + * \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or + * POLARSSL_ERR_BASE64_INVALID_DATA if the input data is not + * correct. *dlen is always updated to reflect the amount + * of data that has (or would have) been written. + * + * \note Call this function with *dlen = 0 to obtain the + * required buffer size in *dlen + */ +int base64_decode( unsigned char *dst, int *dlen, + const unsigned char *src, int slen ); + +#endif /* base64.h */ diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index d5edf34c..3a0887d0 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -31,10 +31,6 @@ #include <time.h> #include <limits.h> /* PATH_MAX */ -/* libarchive */ -#include <archive.h> -#include <archive_entry.h> - /* libalpm */ #include "db.h" #include "alpm_list.h" @@ -43,16 +39,10 @@ #include "alpm.h" #include "handle.h" #include "package.h" -#include "group.h" #include "deps.h" -#include "dload.h" - #define LAZY_LOAD(info, errret) \ do { \ - ALPM_LOG_FUNC; \ - ASSERT(handle != NULL, return(errret)); \ - ASSERT(pkg != NULL, return(errret)); \ if(pkg->origin != PKG_FROM_FILE && !(pkg->infolevel & info)) { \ _alpm_local_db_read(pkg->origin_data.db, pkg, info); \ } \ @@ -71,18 +61,6 @@ static const char *_cache_get_filename(pmpkg_t *pkg) return pkg->filename; } -static const char *_cache_get_name(pmpkg_t *pkg) -{ - ASSERT(pkg != NULL, return(NULL)); - return pkg->name; -} - -static const char *_cache_get_version(pmpkg_t *pkg) -{ - ASSERT(pkg != NULL, return(NULL)); - return pkg->version; -} - static const char *_cache_get_desc(pmpkg_t *pkg) { LAZY_LOAD(INFRQ_DESC, NULL); @@ -157,12 +135,6 @@ static alpm_list_t *_cache_get_groups(pmpkg_t *pkg) static int _cache_has_scriptlet(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(-1)); - ASSERT(pkg != NULL, return(-1)); - if(!(pkg->infolevel & INFRQ_SCRIPTLET)) { _alpm_local_db_read(pkg->origin_data.db, pkg, INFRQ_SCRIPTLET); } @@ -200,19 +172,13 @@ static alpm_list_t *_cache_get_replaces(pmpkg_t *pkg) } /* local packages can not have deltas */ -static alpm_list_t *_cache_get_deltas(pmpkg_t *pkg) +static alpm_list_t *_cache_get_deltas(pmpkg_t UNUSED *pkg) { return NULL; } static alpm_list_t *_cache_get_files(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - if(pkg->origin == PKG_FROM_LOCALDB && !(pkg->infolevel & INFRQ_FILES)) { _alpm_local_db_read(pkg->origin_data.db, pkg, INFRQ_FILES); @@ -222,12 +188,6 @@ static alpm_list_t *_cache_get_files(pmpkg_t *pkg) static alpm_list_t *_cache_get_backup(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - if(pkg->origin == PKG_FROM_LOCALDB && !(pkg->infolevel & INFRQ_FILES)) { _alpm_local_db_read(pkg->origin_data.db, pkg, INFRQ_FILES); @@ -243,12 +203,6 @@ static alpm_list_t *_cache_get_backup(pmpkg_t *pkg) */ static void *_cache_changelog_open(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); - char clfile[PATH_MAX]; snprintf(clfile, PATH_MAX, "%s/%s/%s-%s/changelog", alpm_option_get_dbpath(), @@ -268,18 +222,11 @@ static void *_cache_changelog_open(pmpkg_t *pkg) * @return the number of characters read, or 0 if there is no more data */ static size_t _cache_changelog_read(void *ptr, size_t size, - const pmpkg_t *pkg, const void *fp) + const pmpkg_t UNUSED *pkg, const void *fp) { - return ( fread(ptr, 1, size, (FILE*)fp) ); + return fread(ptr, 1, size, (FILE *)fp); } -/* -static int _cache_changelog_feof(const pmpkg_t *pkg, void *fp) -{ - return( feof((FILE*)fp) ); -} -*/ - /** * Close a package changelog for reading. Similar to fclose in functionality, * except that the 'file stream' is from the database. @@ -287,9 +234,9 @@ static int _cache_changelog_feof(const pmpkg_t *pkg, void *fp) * @param fp a 'file stream' to the package changelog * @return whether closing the package changelog stream was successful */ -static int _cache_changelog_close(const pmpkg_t *pkg, void *fp) +static int _cache_changelog_close(const pmpkg_t UNUSED *pkg, void *fp) { - return( fclose((FILE*)fp) ); + return fclose((FILE *)fp); } @@ -299,8 +246,6 @@ static int _cache_changelog_close(const pmpkg_t *pkg, void *fp) */ static struct pkg_operations local_pkg_ops = { .get_filename = _cache_get_filename, - .get_name = _cache_get_name, - .get_version = _cache_get_version, .get_desc = _cache_get_desc, .get_url = _cache_get_url, .get_builddate = _cache_get_builddate, @@ -345,14 +290,14 @@ static int checkdbdir(pmdb_t *db) RET_ERR(PM_ERR_SYSTEM, -1); } } - return(0); + return 0; } static int is_dir(const char *path, struct dirent *entry) { #ifdef HAVE_STRUCT_DIRENT_D_TYPE if(entry->d_type != DT_UNKNOWN) { - return(entry->d_type == DT_DIR); + return (entry->d_type == DT_DIR); } #endif { @@ -361,12 +306,12 @@ static int is_dir(const char *path, struct dirent *entry) snprintf(buffer, PATH_MAX, "%s/%s", path, entry->d_name); - if (!stat(buffer, &sbuf)) { - return(S_ISDIR(sbuf.st_mode)); + if(!stat(buffer, &sbuf)) { + return S_ISDIR(sbuf.st_mode); } } - return(0); + return 0; } static int local_db_populate(pmdb_t *db) @@ -378,8 +323,6 @@ static int local_db_populate(pmdb_t *db) const char *dbpath; DIR *dbdir; - ALPM_LOG_FUNC; - ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); dbpath = _alpm_db_path(db); @@ -391,7 +334,7 @@ static int local_db_populate(pmdb_t *db) if(dbdir == NULL) { if(errno == ENOENT) { /* no database existing yet is not an error */ - return(0); + return 0; } RET_ERR(PM_ERR_DB_OPEN, -1); } @@ -458,6 +401,7 @@ static int local_db_populate(pmdb_t *db) pkg->origin = PKG_FROM_LOCALDB; pkg->origin_data.db = db; pkg->ops = &local_pkg_ops; + pkg->handle = db->handle; /* explicitly read with only 'BASE' data, accessors will handle the rest */ if(_alpm_local_db_read(db, pkg, INFRQ_BASE) == -1) { @@ -467,7 +411,7 @@ static int local_db_populate(pmdb_t *db) } /* add to the collection */ - _alpm_log(PM_LOG_DEBUG, "adding '%s' to package cache for db '%s'\n", + _alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n", pkg->name, db->treename); db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg); count++; @@ -477,7 +421,10 @@ static int local_db_populate(pmdb_t *db) if(count > 0) { db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp); } - return(count); + _alpm_log(PM_LOG_DEBUG, "added %d packages to package cache for db '%s'\n", + count, db->treename); + + return count; } /* Note: the return value must be freed by the caller */ @@ -491,7 +438,7 @@ static char *get_pkgpath(pmdb_t *db, pmpkg_t *info) len = strlen(dbpath) + strlen(info->name) + strlen(info->version) + 3; MALLOC(pkgpath, len, RET_ERR(PM_ERR_MEMORY, NULL)); sprintf(pkgpath, "%s%s-%s/", dbpath, info->name, info->version); - return(pkgpath); + return pkgpath; } @@ -502,22 +449,20 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) char line[1024]; char *pkgpath = NULL; - ALPM_LOG_FUNC; - if(db == NULL) { RET_ERR(PM_ERR_DB_NULL, -1); } if(info == NULL || info->name == NULL || info->version == NULL) { _alpm_log(PM_LOG_DEBUG, "invalid package entry provided to _alpm_local_db_read, skipping\n"); - return(-1); + return -1; } if(info->origin != PKG_FROM_LOCALDB) { _alpm_log(PM_LOG_DEBUG, "request to read info for a non-local package '%s', skipping...\n", info->name); - return(-1); + return -1; } /* bitmask logic here: @@ -527,7 +472,7 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) * == to inforeq? nope, we need to load more info. */ if((info->infolevel & inforeq) == inforeq) { /* already loaded all of this info, do nothing */ - return(0); + return 0; } _alpm_log(PM_LOG_FUNCTION, "loading package data for %s : level=0x%x\n", info->name, inforeq); @@ -707,14 +652,14 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) info->infolevel |= inforeq; free(pkgpath); - return(0); + return 0; error: free(pkgpath); if(fp) { fclose(fp); } - return(-1); + return -1; } int _alpm_local_db_prepare(pmdb_t *db, pmpkg_t *info) @@ -724,7 +669,7 @@ int _alpm_local_db_prepare(pmdb_t *db, pmpkg_t *info) char *pkgpath = NULL; if(checkdbdir(db) != 0) { - return(-1); + return -1; } oldmask = umask(0000); @@ -738,7 +683,7 @@ int _alpm_local_db_prepare(pmdb_t *db, pmpkg_t *info) free(pkgpath); umask(oldmask); - return(retval); + return retval; } int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) @@ -750,10 +695,8 @@ int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) int retval = 0; char *pkgpath = NULL; - ALPM_LOG_FUNC; - if(db == NULL || info == NULL) { - return(-1); + return -1; } pkgpath = get_pkgpath(db, info); @@ -762,7 +705,7 @@ int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) oldmask = umask(0022); if(strcmp(db->treename, "local") != 0) { - return(-1); + return -1; } /* DESC */ @@ -905,7 +848,7 @@ cleanup: fclose(fp); } - return(retval); + return retval; } int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info) @@ -913,8 +856,6 @@ int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info) int ret = 0; char *pkgpath = NULL; - ALPM_LOG_FUNC; - if(db == NULL || info == NULL) { RET_ERR(PM_ERR_DB_NULL, -1); } @@ -926,7 +867,7 @@ int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info) if(ret != 0) { ret = -1; } - return(ret); + return ret; } static int local_db_version(pmdb_t *db) @@ -978,7 +919,7 @@ done: } _alpm_log(PM_LOG_DEBUG, "local database version %d\n", version); - return(version); + return version; } struct db_operations local_db_ops = { @@ -987,22 +928,21 @@ struct db_operations local_db_ops = { .version = local_db_version, }; -pmdb_t *_alpm_db_register_local(void) +pmdb_t *_alpm_db_register_local(pmhandle_t *handle) { pmdb_t *db; - ALPM_LOG_FUNC; - _alpm_log(PM_LOG_DEBUG, "registering local database\n"); db = _alpm_db_new("local", 1); if(db == NULL) { - RET_ERR(PM_ERR_DB_CREATE, NULL); + return NULL; } db->ops = &local_db_ops; + db->handle = handle; handle->db_local = db; - return(db); + return db; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index 6dfddd61..c89365a2 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -20,10 +20,8 @@ #include "config.h" -#include <stdio.h> #include <stdlib.h> #include <string.h> -#include <limits.h> #include <errno.h> /* libarchive */ @@ -34,9 +32,13 @@ #include "alpm_list.h" #include "util.h" #include "log.h" +#include "handle.h" #include "package.h" #include "deps.h" /* _alpm_splitdep */ +/* global handle variable */ +extern pmhandle_t *handle; + /** * Open a package changelog for reading. Similar to fopen in functionality, * except that the returned 'file stream' is from an archive. @@ -45,9 +47,7 @@ */ static void *_package_changelog_open(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - - ASSERT(pkg != NULL, return(NULL)); + ASSERT(pkg != NULL, return NULL); struct archive *archive = NULL; struct archive_entry *entry; @@ -60,7 +60,7 @@ static void *_package_changelog_open(pmpkg_t *pkg) archive_read_support_compression_all(archive); archive_read_support_format_all(archive); - if (archive_read_open_filename(archive, pkgfile, + if(archive_read_open_filename(archive, pkgfile, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { RET_ERR(PM_ERR_PKG_OPEN, NULL); } @@ -69,14 +69,14 @@ static void *_package_changelog_open(pmpkg_t *pkg) const char *entry_name = archive_entry_pathname(entry); if(strcmp(entry_name, ".CHANGELOG") == 0) { - return(archive); + return archive; } } /* we didn't find a changelog */ archive_read_finish(archive); errno = ENOENT; - return(NULL); + return NULL; } /** @@ -89,26 +89,18 @@ static void *_package_changelog_open(pmpkg_t *pkg) * @return the number of characters read, or 0 if there is no more data */ static size_t _package_changelog_read(void *ptr, size_t size, - const pmpkg_t *pkg, const void *fp) + const pmpkg_t UNUSED *pkg, const void *fp) { - ssize_t sret = archive_read_data((struct archive*)fp, ptr, size); + ssize_t sret = archive_read_data((struct archive *)fp, ptr, size); /* Report error (negative values) */ if(sret < 0) { pm_errno = PM_ERR_LIBARCHIVE; - return(0); + return 0; } else { - return((size_t)sret); + return (size_t)sret; } } -/* -static int _package_changelog_feof(const pmpkg_t *pkg, void *fp) -{ - // note: this doesn't quite work, no feof in libarchive - return( archive_read_data((struct archive*)fp, NULL, 0) ); -} -*/ - /** * Close a package changelog for reading. Similar to fclose in functionality, * except that the 'file stream' is from an archive. @@ -116,9 +108,9 @@ static int _package_changelog_feof(const pmpkg_t *pkg, void *fp) * @param fp a 'file stream' to the package changelog * @return whether closing the package changelog stream was successful */ -static int _package_changelog_close(const pmpkg_t *pkg, void *fp) +static int _package_changelog_close(const pmpkg_t UNUSED *pkg, void *fp) { - return( archive_read_finish((struct archive *)fp) ); + return archive_read_finish((struct archive *)fp); } /** Package file operations struct accessor. We implement this as a method @@ -137,7 +129,7 @@ static struct pkg_operations *get_file_pkg_ops(void) file_pkg_ops.changelog_close = _package_changelog_close; file_pkg_ops_initialized = 1; } - return(&file_pkg_ops); + return &file_pkg_ops; } /** @@ -145,23 +137,21 @@ static struct pkg_operations *get_file_pkg_ops(void) * @param archive the archive to read from, pointed at the .PKGINFO entry * @param newpkg an empty pmpkg_t struct to fill with package info * - * @return 0 on success, 1 on error + * @return 0 on success, -1 on error */ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) { char *ptr = NULL; char *key = NULL; - int linenum = 0; + int ret, linenum = 0; struct archive_read_buffer buf; - ALPM_LOG_FUNC; - memset(&buf, 0, sizeof(buf)); /* 512K for a line length seems reasonable */ buf.max_line_size = 512 * 1024; /* loop until we reach EOF or other error */ - while(_alpm_archive_fgets(a, &buf) == ARCHIVE_OK) { + while((ret = _alpm_archive_fgets(a, &buf)) == ARCHIVE_OK) { char *line = _alpm_strtrim(buf.line); linenum++; @@ -225,8 +215,12 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) } line[0] = '\0'; } + if(ret != ARCHIVE_EOF) { + _alpm_log(PM_LOG_DEBUG, "error parsing package descfile\n"); + return -1; + } - return(0); + return 0; } /** @@ -236,46 +230,68 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) * through the full archive * @return An information filled pmpkg_t struct */ -static pmpkg_t *pkg_load(const char *pkgfile, int full) +pmpkg_t *_alpm_pkg_load_internal(const char *pkgfile, int full, + const char *md5sum, const char *base64_sig, pgp_verify_t check_sig) { - int ret = ARCHIVE_OK; + int ret; int config = 0; struct archive *archive; struct archive_entry *entry; pmpkg_t *newpkg = NULL; struct stat st; - ALPM_LOG_FUNC; - if(pkgfile == NULL || strlen(pkgfile) == 0) { RET_ERR(PM_ERR_WRONG_ARGS, NULL); } - if(stat(pkgfile, &st) != 0) { + /* attempt to stat the package file, ensure it exists */ + if(stat(pkgfile, &st) == 0) { + newpkg = _alpm_pkg_new(); + if(newpkg == NULL) { + RET_ERR(PM_ERR_MEMORY, NULL); + } + newpkg->filename = strdup(pkgfile); + newpkg->size = st.st_size; + } else { + /* couldn't stat the pkgfile, return an error */ RET_ERR(PM_ERR_PKG_OPEN, NULL); } + /* first steps- validate the package file */ + _alpm_log(PM_LOG_DEBUG, "md5sum: %s\n", md5sum); + if(md5sum) { + _alpm_log(PM_LOG_DEBUG, "checking md5sum for %s\n", pkgfile); + if(_alpm_test_md5sum(pkgfile, md5sum) != 0) { + alpm_pkg_free(newpkg); + RET_ERR(PM_ERR_PKG_INVALID, NULL); + } + } + + _alpm_log(PM_LOG_DEBUG, "base64_sig: %s\n", base64_sig); + if(check_sig != PM_PGP_VERIFY_NEVER) { + _alpm_log(PM_LOG_DEBUG, "checking signature for %s\n", pkgfile); + ret = _alpm_gpgme_checksig(pkgfile, base64_sig); + if((check_sig == PM_PGP_VERIFY_ALWAYS && ret != 0) || + (check_sig == PM_PGP_VERIFY_OPTIONAL && ret == 1)) { + RET_ERR(PM_ERR_SIG_INVALID, NULL); + } + } + + /* next- try to create an archive object to read in the package */ if((archive = archive_read_new()) == NULL) { + alpm_pkg_free(newpkg); RET_ERR(PM_ERR_LIBARCHIVE, NULL); } archive_read_support_compression_all(archive); archive_read_support_format_all(archive); - if (archive_read_open_filename(archive, pkgfile, + if(archive_read_open_filename(archive, pkgfile, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { + alpm_pkg_free(newpkg); RET_ERR(PM_ERR_PKG_OPEN, NULL); } - newpkg = _alpm_pkg_new(); - if(newpkg == NULL) { - archive_read_finish(archive); - RET_ERR(PM_ERR_MEMORY, NULL); - } - - newpkg->filename = strdup(pkgfile); - newpkg->size = st.st_size; - _alpm_log(PM_LOG_DEBUG, "starting package load for %s\n", pkgfile); /* If full is false, only read through the archive until we find our needed @@ -340,9 +356,9 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full) /* internal fields for package struct */ newpkg->origin = PKG_FROM_FILE; - /* TODO eventually kill/move this? */ newpkg->origin_data.file = strdup(pkgfile); newpkg->ops = get_file_pkg_ops(); + newpkg->handle = handle; if(full) { /* "checking for conflicts" requires a sorted list, ensure that here */ @@ -356,7 +372,7 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full) newpkg->infolevel = INFRQ_BASE | INFRQ_DESC; } - return(newpkg); + return newpkg; pkg_invalid: pm_errno = PM_ERR_PKG_INVALID; @@ -364,25 +380,22 @@ error: _alpm_pkg_free(newpkg); archive_read_finish(archive); - return(NULL); + return NULL; } -int SYMEXPORT alpm_pkg_load(const char *filename, int full, pmpkg_t **pkg) +int SYMEXPORT alpm_pkg_load(const char *filename, int full, + pgp_verify_t check_sig, pmpkg_t **pkg) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(filename != NULL && strlen(filename) != 0, - RET_ERR(PM_ERR_WRONG_ARGS, -1)); ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); - *pkg = pkg_load(filename, full); + *pkg = _alpm_pkg_load_internal(filename, full, NULL, NULL, check_sig); if(*pkg == NULL) { /* pm_errno is set by pkg_load */ - return(-1); + return -1; } - return(0); + return 0; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index c440cd6b..aeba86f1 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -20,8 +20,7 @@ #include "config.h" -#include <errno.h> -#include <limits.h> +#include <sys/stat.h> /* libarchive */ #include <archive.h> @@ -79,26 +78,18 @@ */ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) { - char *dbfile, *syncpath; + char *syncpath; const char *dbpath; + alpm_list_t *i; struct stat buf; size_t len; - int ret; + int ret = -1; mode_t oldmask; - - ALPM_LOG_FUNC; + pgp_verify_t check_sig; /* Sanity checks */ - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); - ASSERT(db != NULL && db != handle->db_local, RET_ERR(PM_ERR_WRONG_ARGS, -1)); - - if(!alpm_list_find_ptr(handle->dbs_sync, db)) { - RET_ERR(PM_ERR_DB_NOT_FOUND, -1); - } - - len = strlen(db->treename) + 4; - MALLOC(dbfile, len, RET_ERR(PM_ERR_MEMORY, -1)); - sprintf(dbfile, "%s.db", db->treename); + ASSERT(db != NULL && db != db->handle->db_local, RET_ERR(PM_ERR_WRONG_ARGS, -1)); + ASSERT(db->servers != NULL, RET_ERR(PM_ERR_SERVER_NONE, -1)); dbpath = alpm_option_get_dbpath(); len = strlen(dbpath) + 6; @@ -112,38 +103,67 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) _alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n", syncpath); if(_alpm_makepath(syncpath) != 0) { - free(dbfile); free(syncpath); RET_ERR(PM_ERR_SYSTEM, -1); } } else if(!S_ISDIR(buf.st_mode)) { _alpm_log(PM_LOG_WARNING, _("removing invalid file: %s\n"), syncpath); if(unlink(syncpath) != 0 || _alpm_makepath(syncpath) != 0) { - free(dbfile); free(syncpath); RET_ERR(PM_ERR_SYSTEM, -1); } } - ret = _alpm_download_single_file(dbfile, db->servers, syncpath, force); - free(dbfile); - free(syncpath); - umask(oldmask); + check_sig = _alpm_db_get_sigverify_level(db); + + for(i = db->servers; i; i = i->next) { + const char *server = i->data; + char *fileurl; + size_t len; + int sig_ret = 0; + + /* print server + filename into a buffer (leave space for .sig) */ + len = strlen(server) + strlen(db->treename) + 9; + CALLOC(fileurl, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1)); + snprintf(fileurl, len, "%s/%s.db", server, db->treename); + + ret = _alpm_download(fileurl, syncpath, force, 0, 0); + + if(ret == 0 && (check_sig == PM_PGP_VERIFY_ALWAYS || + check_sig == PM_PGP_VERIFY_OPTIONAL)) { + int errors_ok = (check_sig == PM_PGP_VERIFY_OPTIONAL); + /* if we downloaded a DB, we want the .sig from the same server */ + snprintf(fileurl, len, "%s/%s.db.sig", server, db->treename); + + sig_ret = _alpm_download(fileurl, syncpath, 1, 0, errors_ok); + /* errors_ok suppresses error messages, but not the return code */ + sig_ret = errors_ok ? 0 : sig_ret; + } + + FREE(fileurl); + if(ret != -1 && sig_ret != -1) { + break; + } + } if(ret == 1) { /* files match, do nothing */ pm_errno = 0; - return(1); + goto cleanup; } else if(ret == -1) { /* pm_errno was set by the download code */ _alpm_log(PM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerrorlast()); - return(-1); + goto cleanup; } /* Cache needs to be rebuilt */ _alpm_db_free_pkgcache(db); - return(0); +cleanup: + + free(syncpath); + umask(oldmask); + return ret; } /* Forward decl so I don't reorganize the whole file right now */ @@ -206,7 +226,7 @@ static size_t estimate_package_count(struct stat *st, struct archive *archive) /* assume it is at least somewhat compressed */ per_package = 200; } - return((size_t)(st->st_size / per_package) + 1); + return (size_t)((st->st_size / per_package) + 1); } static int sync_db_populate(pmdb_t *db) @@ -219,8 +239,6 @@ static int sync_db_populate(pmdb_t *db) struct archive_entry *entry; pmpkg_t *pkg = NULL; - ALPM_LOG_FUNC; - ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); if((archive = archive_read_new()) == NULL) { @@ -276,6 +294,7 @@ static int sync_db_populate(pmdb_t *db) _alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"), name); _alpm_pkg_free(pkg); + pkg = NULL; continue; } @@ -283,12 +302,14 @@ static int sync_db_populate(pmdb_t *db) if(_alpm_pkghash_find(db->pkgcache, pkg->name)) { _alpm_log(PM_LOG_ERROR, _("duplicated database entry '%s'\n"), pkg->name); _alpm_pkg_free(pkg); + pkg = NULL; continue; } pkg->origin = PKG_FROM_SYNCDB; - pkg->ops = &default_pkg_ops; pkg->origin_data.db = db; + pkg->ops = &default_pkg_ops; + pkg->handle = db->handle; /* add to the collection */ _alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n", @@ -297,7 +318,14 @@ static int sync_db_populate(pmdb_t *db) count++; } else { /* we have desc, depends or deltas - parse it */ - sync_db_read(db, archive, entry, pkg); + if(sync_db_read(db, archive, entry, pkg) != 0) { + _alpm_log(PM_LOG_ERROR, + _("could not parse package '%s' description file from db '%s'\n"), + pkg->name, db->treename); + _alpm_pkg_free(pkg); + pkg = NULL; + continue; + } } } @@ -305,8 +333,10 @@ static int sync_db_populate(pmdb_t *db) db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp); } archive_read_finish(archive); + _alpm_log(PM_LOG_DEBUG, "added %d packages to package cache for db '%s'\n", + count, db->treename); - return(count); + return count; } #define READ_NEXT(s) do { \ @@ -335,8 +365,6 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, pmpkg_t *pkg; struct archive_read_buffer buf; - ALPM_LOG_FUNC; - if(db == NULL) { RET_ERR(PM_ERR_DB_NULL, -1); } @@ -346,7 +374,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, } if(entryname == NULL) { _alpm_log(PM_LOG_DEBUG, "invalid archive entry provided to _alpm_sync_db_read, skipping\n"); - return(-1); + return -1; } _alpm_log(PM_LOG_FUNCTION, "loading package data from archive entry %s\n", @@ -377,12 +405,13 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, if(pkg == NULL) { _alpm_log(PM_LOG_DEBUG, "package %s not found in %s sync database", pkgname, db->treename); - return(-1); + return -1; } if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0 || strcmp(filename, "deltas") == 0) { - while(_alpm_archive_fgets(archive, &buf) == ARCHIVE_OK) { + int ret; + while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) { char *line = _alpm_strtrim(buf.line); if(strcmp(line, "%NAME%") == 0) { @@ -434,8 +463,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, /* we don't do anything with this value right now */ READ_NEXT(line); } else if(strcmp(line, "%PGPSIG%") == 0) { - /* we don't do anything with this value right now */ - READ_NEXT(line); + READ_AND_STORE(pkg->base64_sig); } else if(strcmp(line, "%REPLACES%") == 0) { READ_AND_STORE_ALL(pkg->replaces); } else if(strcmp(line, "%DEPENDS%") == 0) { @@ -460,6 +488,9 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, } } } + if(ret != ARCHIVE_EOF) { + goto error; + } } else if(strcmp(filename, "files") == 0) { /* currently do nothing with this file */ } else { @@ -467,15 +498,16 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, _alpm_log(PM_LOG_DEBUG, "unknown database file: %s\n", filename); } + return 0; + error: FREE(pkgname); - /* TODO: return 0 always? */ - return(0); + return -1; } -static int sync_db_version(pmdb_t *db) +static int sync_db_version(pmdb_t UNUSED *db) { - return(2); + return 2; } struct db_operations sync_db_ops = { @@ -484,20 +516,9 @@ struct db_operations sync_db_ops = { .version = sync_db_version, }; -pmdb_t *_alpm_db_register_sync(const char *treename) +pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename) { pmdb_t *db; - alpm_list_t *i; - - ALPM_LOG_FUNC; - - for(i = handle->dbs_sync; i; i = i->next) { - pmdb_t *sdb = i->data; - if(strcmp(treename, sdb->treename) == 0) { - _alpm_log(PM_LOG_DEBUG, "attempt to re-register the '%s' database, using existing\n", sdb->treename); - return sdb; - } - } _alpm_log(PM_LOG_DEBUG, "registering sync database '%s'\n", treename); @@ -506,9 +527,10 @@ pmdb_t *_alpm_db_register_sync(const char *treename) RET_ERR(PM_ERR_DB_CREATE, NULL); } db->ops = &sync_db_ops; + db->handle = handle; handle->dbs_sync = alpm_list_add(handle->dbs_sync, db); - return(db); + return db; } diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index 6faced16..89214707 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -45,15 +45,13 @@ pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2, { pmconflict_t *conflict; - ALPM_LOG_FUNC; - MALLOC(conflict, sizeof(pmconflict_t), RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(conflict->package1, package1, RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(conflict->package2, package2, RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(conflict->reason, reason, RET_ERR(PM_ERR_MEMORY, NULL)); - return(conflict); + return conflict; } void _alpm_conflict_free(pmconflict_t *conflict) @@ -73,7 +71,7 @@ pmconflict_t *_alpm_conflict_dup(const pmconflict_t *conflict) STRDUP(newconflict->package2, conflict->package2, RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(newconflict->reason, conflict->reason, RET_ERR(PM_ERR_MEMORY, NULL)); - return(newconflict); + return newconflict; } static int conflict_isin(pmconflict_t *needle, alpm_list_t *haystack) @@ -82,19 +80,17 @@ static int conflict_isin(pmconflict_t *needle, alpm_list_t *haystack) const char *npkg1 = needle->package1; const char *npkg2 = needle->package2; - ALPM_LOG_FUNC; - for(i = haystack; i; i = i->next) { pmconflict_t *conflict = i->data; const char *cpkg1 = conflict->package1; const char *cpkg2 = conflict->package2; if((strcmp(cpkg1, npkg1) == 0 && strcmp(cpkg2, npkg2) == 0) || (strcmp(cpkg1, npkg2) == 0 && strcmp(cpkg2, npkg1) == 0)) { - return(1); + return 1; } } - return(0); + return 0; } /** Adds the pkg1/pkg2 conflict to the baddeps list @@ -168,12 +164,10 @@ alpm_list_t *_alpm_innerconflicts(alpm_list_t *packages) { alpm_list_t *baddeps = NULL; - ALPM_LOG_FUNC; - _alpm_log(PM_LOG_DEBUG, "check targets vs targets\n"); check_conflict(packages, packages, &baddeps, 0); - return(baddeps); + return baddeps; } /* Check for target vs (db - target) conflicts @@ -184,10 +178,8 @@ alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages) { alpm_list_t *baddeps = NULL; - ALPM_LOG_FUNC; - if(db == NULL) { - return(NULL); + return NULL; } alpm_list_t *dblist = alpm_list_diff(_alpm_db_get_pkgcache(db), @@ -200,7 +192,7 @@ alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages) check_conflict(dblist, packages, &baddeps, -1); alpm_list_free(dblist); - return(baddeps); + return baddeps; } /** Check the package conflicts in a database @@ -209,14 +201,20 @@ alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages) * @return an alpm_list_t of pmconflict_t */ alpm_list_t SYMEXPORT *alpm_checkconflicts(alpm_list_t *pkglist) { - return(_alpm_innerconflicts(pkglist)); + return _alpm_innerconflicts(pkglist); } -/* Returns a alpm_list_t* of file conflicts. - * Hooray for set-intersects! - * Pre-condition: both lists are sorted! +static const int DIFFERENCE = 0; +static const int INTERSECT = 1; +/* Returns a set operation on the provided two lists of files. + * Pre-condition: both lists are sorted! + * + * Operations: + * DIFFERENCE - a difference operation is performed. filesA - filesB. + * INTERSECT - an intersection operation is performed. filesA & filesB. */ -static alpm_list_t *chk_fileconflicts(alpm_list_t *filesA, alpm_list_t *filesB) +static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB, + int operation) { alpm_list_t *ret = NULL; alpm_list_t *pA = filesA, *pB = filesB; @@ -224,7 +222,7 @@ static alpm_list_t *chk_fileconflicts(alpm_list_t *filesA, alpm_list_t *filesB) while(pA && pB) { const char *strA = pA->data; const char *strB = pB->data; - /* skip directories, we don't care about dir conflicts */ + /* skip directories, we don't care about them */ if(strA[strlen(strA)-1] == '/') { pA = pA->next; } else if(strB[strlen(strB)-1] == '/') { @@ -232,59 +230,26 @@ static alpm_list_t *chk_fileconflicts(alpm_list_t *filesA, alpm_list_t *filesB) } else { int cmp = strcmp(strA, strB); if(cmp < 0) { - /* item only in filesA, ignore it */ + if(operation == DIFFERENCE) { + /* item only in filesA, qualifies as a difference */ + ret = alpm_list_add(ret, strdup(strA)); + } pA = pA->next; } else if(cmp > 0) { - /* item only in filesB, ignore it */ pB = pB->next; } else { - /* item in both, record it */ - ret = alpm_list_add(ret, strdup(strA)); + if(operation == INTERSECT) { + /* item in both, qualifies as an intersect */ + ret = alpm_list_add(ret, strdup(strA)); + } pA = pA->next; pB = pB->next; } } } - return(ret); -} - -/* Returns a alpm_list_t* of files that are in filesA but *NOT* in filesB - * This is an 'A minus B' set operation - * Pre-condition: both lists are sorted! - */ -static alpm_list_t *chk_filedifference(alpm_list_t *filesA, alpm_list_t *filesB) -{ - alpm_list_t *ret = NULL; - alpm_list_t *pA = filesA, *pB = filesB; - - /* if both filesA and filesB have entries, do this loop */ - while(pA && pB) { - const char *strA = pA->data; - const char *strB = pB->data; - /* skip directories, we don't care about dir conflicts */ - if(strA[strlen(strA)-1] == '/') { - pA = pA->next; - } else if(strB[strlen(strB)-1] == '/') { - pB = pB->next; - } else { - int cmp = strcmp(strA, strB); - if(cmp < 0) { - /* item only in filesA, record it */ - ret = alpm_list_add(ret, strdup(strA)); - pA = pA->next; - } else if(cmp > 0) { - /* item only in fileB, but this means nothing */ - pB = pB->next; - } else { - /* item in both, ignore it */ - pA = pA->next; - pB = pB->next; - } - } - } - /* ensure we have completely emptied pA */ - while(pA) { + /* if doing a difference, ensure we have completely emptied pA */ + while(operation == DIFFERENCE && pA) { const char *strA = pA->data; /* skip directories */ if(strA[strlen(strA)-1] != '/') { @@ -293,7 +258,7 @@ static alpm_list_t *chk_filedifference(alpm_list_t *filesA, alpm_list_t *filesB) pA = pA->next; } - return(ret); + return ret; } /* Adds pmfileconflict_t to a conflicts list. Pass the conflicts list, type (either @@ -314,22 +279,20 @@ static alpm_list_t *add_fileconflict(alpm_list_t *conflicts, if(name2) { STRDUP(conflict->ctarget, name2, RET_ERR(PM_ERR_MEMORY, NULL)); } else { - conflict->ctarget = ""; + STRDUP(conflict->ctarget, "", RET_ERR(PM_ERR_MEMORY, NULL)); } conflicts = alpm_list_add(conflicts, conflict); _alpm_log(PM_LOG_DEBUG, "found file conflict %s, packages %s and %s\n", filestr, name1, name2 ? name2 : "(filesystem)"); - return(conflicts); + return conflicts; } void _alpm_fileconflict_free(pmfileconflict_t *conflict) { - if(strlen(conflict->ctarget) > 0) { - FREE(conflict->ctarget); - } - FREE(conflict->file);; + FREE(conflict->ctarget); + FREE(conflict->file); FREE(conflict->target); FREE(conflict); } @@ -342,10 +305,10 @@ static int dir_belongsto_pkg(char *dirpath, pmpkg_t *pkg) char abspath[PATH_MAX]; DIR *dir; - snprintf(abspath, PATH_MAX, "%s%s", handle->root, dirpath); + snprintf(abspath, PATH_MAX, "%s%s", pkg->handle->root, dirpath); dir = opendir(abspath); if(dir == NULL) { - return(1); + return 1; } while((ent = readdir(dir)) != NULL) { const char *name = ent->d_name; @@ -354,7 +317,7 @@ static int dir_belongsto_pkg(char *dirpath, pmpkg_t *pkg) continue; } snprintf(path, PATH_MAX, "%s/%s", dirpath, name); - snprintf(abspath, PATH_MAX, "%s%s", handle->root, path); + snprintf(abspath, PATH_MAX, "%s%s", pkg->handle->root, path); if(stat(abspath, &sbuf) != 0) { continue; } @@ -363,35 +326,34 @@ static int dir_belongsto_pkg(char *dirpath, pmpkg_t *pkg) continue; } else { closedir(dir); - return(0); + return 0; } } else { if(alpm_list_find_str(alpm_pkg_get_files(pkg), path)) { continue; } else { closedir(dir); - return(0); + return 0; } } } closedir(dir); - return(1); + return 1; } /* Find file conflicts that may occur during the transaction with two checks: * 1: check every target against every target * 2: check every target against the filesystem */ -alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, +alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, alpm_list_t *upgrade, alpm_list_t *remove) { alpm_list_t *i, *j, *conflicts = NULL; size_t numtargs = alpm_list_count(upgrade); size_t current; + pmtrans_t *trans = handle->trans; - ALPM_LOG_FUNC; - - if(db == NULL || upgrade == NULL || trans == NULL) { - return(NULL); + if(!upgrade) { + return NULL; } /* TODO this whole function needs a huge change, which hopefully will @@ -419,7 +381,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, if(!p2) { continue; } - tmpfiles = chk_fileconflicts(alpm_pkg_get_files(p1), alpm_pkg_get_files(p2)); + tmpfiles = filelist_operation( alpm_pkg_get_files(p1), + alpm_pkg_get_files(p2), INTERSECT); if(tmpfiles) { for(k = tmpfiles; k; k = k->next) { @@ -437,15 +400,15 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, /* CHECK 2: check every target against the filesystem */ _alpm_log(PM_LOG_DEBUG, "searching for filesystem conflicts: %s\n", p1->name); - dbpkg = _alpm_db_get_pkgfromcache(db, p1->name); + dbpkg = _alpm_db_get_pkgfromcache(handle->db_local, p1->name); /* Do two different checks here. If the package is currently installed, * then only check files that are new in the new package. If the package * is not currently installed, then simply stat the whole filelist */ if(dbpkg) { /* older ver of package currently installed */ - tmpfiles = chk_filedifference(alpm_pkg_get_files(p1), - alpm_pkg_get_files(dbpkg)); + tmpfiles = filelist_operation(alpm_pkg_get_files(p1), + alpm_pkg_get_files(dbpkg), DIFFERENCE); } else { /* no version of package currently installed */ tmpfiles = alpm_list_strdup(alpm_pkg_get_files(p1)); @@ -491,7 +454,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, if(!p2 || strcmp(p1->name, p2->name) == 0) { continue; } - pmpkg_t *localp2 = _alpm_db_get_pkgfromcache(db, p2->name); + pmpkg_t *localp2 = _alpm_db_get_pkgfromcache(handle->db_local, p2->name); /* localp2->files will be removed (target conflicts are handled by CHECK 1) */ if(localp2 && alpm_list_find_str(alpm_pkg_get_files(localp2), filestr)) { @@ -540,82 +503,61 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, PROGRESS(trans, PM_TRANS_PROGRESS_CONFLICTS_START, "", 100, numtargs, current); - return(conflicts); + return conflicts; } const char SYMEXPORT *alpm_conflict_get_package1(pmconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(conflict != NULL, return NULL); return conflict->package1; } const char SYMEXPORT *alpm_conflict_get_package2(pmconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(conflict != NULL, return NULL); return conflict->package2; } const char SYMEXPORT *alpm_conflict_get_reason(pmconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(conflict != NULL, return NULL); return conflict->reason; } const char SYMEXPORT *alpm_fileconflict_get_target(pmfileconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(conflict != NULL, return NULL); return conflict->target; } pmfileconflicttype_t SYMEXPORT alpm_fileconflict_get_type(pmfileconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(-1)); - ASSERT(conflict != NULL, return(-1)); + ASSERT(conflict != NULL, return -1); return conflict->type; } const char SYMEXPORT *alpm_fileconflict_get_file(pmfileconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(conflict != NULL, return NULL); return conflict->file; } const char SYMEXPORT *alpm_fileconflict_get_ctarget(pmfileconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(conflict != NULL, return NULL); return conflict->ctarget; } diff --git a/lib/libalpm/conflict.h b/lib/libalpm/conflict.h index 418d3f61..d00314de 100644 --- a/lib/libalpm/conflict.h +++ b/lib/libalpm/conflict.h @@ -42,8 +42,8 @@ pmconflict_t *_alpm_conflict_dup(const pmconflict_t *conflict); void _alpm_conflict_free(pmconflict_t *conflict); alpm_list_t *_alpm_innerconflicts(alpm_list_t *packages); alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages); -alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, - alpm_list_t *upgrade, alpm_list_t *remove); +alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, + alpm_list_t *upgrade, alpm_list_t *remove); void _alpm_fileconflict_free(pmfileconflict_t *conflict); diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index 1a3168b4..fda8428a 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -26,11 +26,8 @@ #include <stdio.h> #include <stdlib.h> -#include <errno.h> #include <string.h> -#include <sys/stat.h> #include <regex.h> -#include <time.h> /* libalpm */ #include "db.h" @@ -42,6 +39,9 @@ #include "package.h" #include "group.h" +/* global handle variable */ +extern pmhandle_t *handle; + /** \addtogroup alpm_databases Database Functions * @brief Functions to query and manipulate the database of libalpm * @{ @@ -50,15 +50,13 @@ /** Register a sync database of packages. */ pmdb_t SYMEXPORT *alpm_db_register_sync(const char *treename) { - ALPM_LOG_FUNC; - /* Sanity checks */ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, NULL)); ASSERT(treename != NULL && strlen(treename) != 0, RET_ERR(PM_ERR_WRONG_ARGS, NULL)); /* Do not register a database if a transaction is on-going */ ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, NULL)); - return(_alpm_db_register_sync(treename)); + return _alpm_db_register_sync(handle, treename); } /* Helper function for alpm_db_unregister{_all} */ @@ -73,13 +71,11 @@ void _alpm_db_unregister(pmdb_t *db) } /** Unregister all package databases. */ -int SYMEXPORT alpm_db_unregister_all(void) +int SYMEXPORT alpm_db_unregister_all(pmhandle_t *handle) { alpm_list_t *i; pmdb_t *db; - ALPM_LOG_FUNC; - /* Sanity checks */ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); /* Do not unregister a database if a transaction is on-going */ @@ -92,7 +88,7 @@ int SYMEXPORT alpm_db_unregister_all(void) i->data = NULL; } FREELIST(handle->dbs_sync); - return(0); + return 0; } /** Unregister a package database. */ @@ -100,16 +96,13 @@ int SYMEXPORT alpm_db_unregister(pmdb_t *db) { int found = 0; - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); ASSERT(db != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); /* Do not unregister a database if a transaction is on-going */ - ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1)); + ASSERT(db->handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1)); - if(db == handle->db_local) { - handle->db_local = NULL; + if(db == db->handle->db_local) { + db->handle->db_local = NULL; found = 1; } else { /* Warning : this function shouldn't be used to unregister all sync @@ -117,7 +110,7 @@ int SYMEXPORT alpm_db_unregister(pmdb_t *db) * alpm_option_get_syncdbs, because the db is removed from that list here. */ void *data; - handle->dbs_sync = alpm_list_remove(handle->dbs_sync, + db->handle->dbs_sync = alpm_list_remove(db->handle->dbs_sync, db, _alpm_db_cmp, &data); if(data) { found = 1; @@ -129,60 +122,117 @@ int SYMEXPORT alpm_db_unregister(pmdb_t *db) } db->ops->unregister(db); - return(0); + return 0; +} + +/** Get the serverlist of a database. */ +alpm_list_t SYMEXPORT *alpm_db_get_servers(const pmdb_t *db) +{ + /* Sanity checks */ + ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, NULL)); + + return(db->servers); } /** Set the serverlist of a database. */ -int SYMEXPORT alpm_db_setserver(pmdb_t *db, const char *url) +int SYMEXPORT alpm_db_set_servers(pmdb_t *db, alpm_list_t *servers) +{ + /* Sanity checks */ + ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); + + if(db->servers) FREELIST(db->servers); + db->servers = servers; + return 0; +} + +static char *sanitize_url(const char *url) { - alpm_list_t *i; - int found = 0; char *newurl; - size_t len = 0; + size_t len = strlen(url); - ALPM_LOG_FUNC; + STRDUP(newurl, url, RET_ERR(PM_ERR_MEMORY, NULL)); + /* strip the trailing slash if one exists */ + if(newurl[len - 1] == '/') { + newurl[len - 1] = '\0'; + } + return newurl; +} + +/** Add a download server to a database. + * @param db database pointer + * @param url url of the server + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ +int SYMEXPORT alpm_db_add_server(pmdb_t *db, const char *url) +{ + char *newurl; /* Sanity checks */ ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); + ASSERT(url != NULL && strlen(url) != 0, RET_ERR(PM_ERR_WRONG_ARGS, -1)); - for(i = handle->dbs_sync; i && !found; i = i->next) { - pmdb_t *sdb = i->data; - if(strcmp(db->treename, sdb->treename) == 0) { - found = 1; - } - } - if(!found) { - RET_ERR(PM_ERR_DB_NOT_FOUND, -1); + newurl = sanitize_url(url); + if(!newurl) { + return -1; } + db->servers = alpm_list_add(db->servers, newurl); + _alpm_log(PM_LOG_DEBUG, "adding new server URL to database '%s': %s\n", + db->treename, newurl); - if(url) { - len = strlen(url); + return 0; +} + +/** Remove a download server from a database. + * @param db database pointer + * @param url url of the server + * @return 0 on success, 1 on server not present, + * -1 on error (pm_errno is set accordingly) + */ +int SYMEXPORT alpm_db_remove_server(pmdb_t *db, const char *url) +{ + char *newurl, *vdata = NULL; + + /* Sanity checks */ + ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); + ASSERT(url != NULL && strlen(url) != 0, RET_ERR(PM_ERR_WRONG_ARGS, -1)); + + newurl = sanitize_url(url); + if(!newurl) { + return -1; } - if(len) { - newurl = strdup(url); - /* strip the trailing slash if one exists */ - if(newurl[len - 1] == '/') { - newurl[len - 1] = '\0'; - } - db->servers = alpm_list_add(db->servers, newurl); - _alpm_log(PM_LOG_DEBUG, "adding new server URL to database '%s': %s\n", + db->servers = alpm_list_remove_str(db->servers, newurl, &vdata); + free(newurl); + if(vdata) { + _alpm_log(PM_LOG_DEBUG, "removed server URL from database '%s': %s\n", db->treename, newurl); - } else { - FREELIST(db->servers); - _alpm_log(PM_LOG_DEBUG, "serverlist flushed for '%s'\n", db->treename); + free(vdata); + return 0; } + return 1; +} +/** Set the verify gpg signature option for a database. + * @param db database pointer + * @param verify enum pgp_verify_t + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ +int SYMEXPORT alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify) +{ + /* Sanity checks */ + ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); + + db->pgp_verify = verify; + _alpm_log(PM_LOG_DEBUG, "adding VerifySig option to database '%s': %d\n", + db->treename, verify); + return(0); } /** Get the name of a package database. */ const char SYMEXPORT *alpm_db_get_name(const pmdb_t *db) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); + ASSERT(db != NULL, return NULL); return db->treename; } @@ -192,88 +242,67 @@ const char SYMEXPORT *alpm_db_get_url(const pmdb_t *db) { char *url; - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); - ASSERT(db->servers != NULL, return(NULL)); + ASSERT(db != NULL, return NULL); + ASSERT(db->servers != NULL, return NULL); - url = (char*)db->servers->data; + url = (char *)db->servers->data; - return(url); + return url; } /** Get a package entry from a package database. */ pmpkg_t SYMEXPORT *alpm_db_get_pkg(pmdb_t *db, const char *name) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); - ASSERT(name != NULL && strlen(name) != 0, return(NULL)); + ASSERT(db != NULL, return NULL); + ASSERT(name != NULL && strlen(name) != 0, return NULL); - return(_alpm_db_get_pkgfromcache(db, name)); + return _alpm_db_get_pkgfromcache(db, name); } /** Get the package cache of a package database. */ alpm_list_t SYMEXPORT *alpm_db_get_pkgcache(pmdb_t *db) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); + ASSERT(db != NULL, return NULL); - return(_alpm_db_get_pkgcache(db)); + return _alpm_db_get_pkgcache(db); } /** Get a group entry from a package database. */ pmgrp_t SYMEXPORT *alpm_db_readgrp(pmdb_t *db, const char *name) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); - ASSERT(name != NULL && strlen(name) != 0, return(NULL)); + ASSERT(db != NULL, return NULL); + ASSERT(name != NULL && strlen(name) != 0, return NULL); - return(_alpm_db_get_grpfromcache(db, name)); + return _alpm_db_get_grpfromcache(db, name); } /** Get the group cache of a package database. */ alpm_list_t SYMEXPORT *alpm_db_get_grpcache(pmdb_t *db) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); + ASSERT(db != NULL, return NULL); - return(_alpm_db_get_grpcache(db)); + return _alpm_db_get_grpcache(db); } /** Searches a database. */ alpm_list_t SYMEXPORT *alpm_db_search(pmdb_t *db, const alpm_list_t* needles) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); + ASSERT(db != NULL, return NULL); - return(_alpm_db_search(db, needles)); + return _alpm_db_search(db, needles); } /** Set install reason for a package in db. */ int SYMEXPORT alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t reason) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); ASSERT(db != NULL && name != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); pmpkg_t *pkg = _alpm_db_get_pkgfromcache(db, name); @@ -284,7 +313,7 @@ int SYMEXPORT alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t _alpm_log(PM_LOG_DEBUG, "setting install reason %u for %s/%s\n", reason, db->treename, name); if(alpm_pkg_get_reason(pkg) == reason) { /* we are done */ - return(0); + return 0; } /* set reason (in pkgcache) */ pkg->reason = reason; @@ -293,7 +322,7 @@ int SYMEXPORT alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t RET_ERR(PM_ERR_DB_WRITE, -1); } - return(0); + return 0; } /** @} */ @@ -302,19 +331,15 @@ pmdb_t *_alpm_db_new(const char *treename, int is_local) { pmdb_t *db; - ALPM_LOG_FUNC; - CALLOC(db, 1, sizeof(pmdb_t), RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(db->treename, treename, RET_ERR(PM_ERR_MEMORY, NULL)); db->is_local = is_local; - return(db); + return db; } void _alpm_db_free(pmdb_t *db) { - ALPM_LOG_FUNC; - /* cleanup pkgcache */ _alpm_db_free_pkgcache(db); /* cleanup server list */ @@ -329,7 +354,7 @@ void _alpm_db_free(pmdb_t *db) const char *_alpm_db_path(pmdb_t *db) { if(!db) { - return(NULL); + return NULL; } if(!db->_path) { const char *dbpath; @@ -354,22 +379,22 @@ const char *_alpm_db_path(pmdb_t *db) _alpm_log(PM_LOG_DEBUG, "database path for tree %s set to %s\n", db->treename, db->_path); } - return(db->_path); + return db->_path; } int _alpm_db_version(pmdb_t *db) { if(!db) { - return(-1); + return -1; } - return(db->ops->version(db)); + return db->ops->version(db); } int _alpm_db_cmp(const void *d1, const void *d2) { pmdb_t *db1 = (pmdb_t *)d1; pmdb_t *db2 = (pmdb_t *)d2; - return(strcmp(db1->treename, db2->treename)); + return strcmp(db1->treename, db2->treename); } alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) @@ -379,8 +404,6 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) /* copy the pkgcache- we will free the list var after each needle */ alpm_list_t *list = alpm_list_copy(_alpm_db_get_pkgcache(db)); - ALPM_LOG_FUNC; - for(i = needles; i; i = i->next) { char *targ; regex_t reg; @@ -407,7 +430,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) matched = name; } /* check desc */ - else if (desc && regexec(®, desc, 0, 0, 0) == 0) { + else if(desc && regexec(®, desc, 0, 0, 0) == 0) { matched = desc; } /* TODO: should we be doing this, and should we print something @@ -415,7 +438,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) if(!matched) { /* check provides */ for(k = alpm_pkg_get_provides(pkg); k; k = k->next) { - if (regexec(®, k->data, 0, 0, 0) == 0) { + if(regexec(®, k->data, 0, 0, 0) == 0) { matched = k->data; break; } @@ -424,7 +447,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) if(!matched) { /* check groups */ for(k = alpm_pkg_get_groups(pkg); k; k = k->next) { - if (regexec(®, k->data, 0, 0, 0) == 0) { + if(regexec(®, k->data, 0, 0, 0) == 0) { matched = k->data; break; } @@ -445,7 +468,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) regfree(®); } - return(ret); + return ret; } /* Returns a new package cache from db. @@ -453,10 +476,8 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) */ int _alpm_db_load_pkgcache(pmdb_t *db) { - ALPM_LOG_FUNC; - if(db == NULL) { - return(-1); + return -1; } _alpm_db_free_pkgcache(db); @@ -465,17 +486,15 @@ int _alpm_db_load_pkgcache(pmdb_t *db) if(db->ops->populate(db) == -1) { _alpm_log(PM_LOG_DEBUG, "failed to load package cache for repository '%s'\n", db->treename); - return(-1); + return -1; } db->pkgcache_loaded = 1; - return(0); + return 0; } void _alpm_db_free_pkgcache(pmdb_t *db) { - ALPM_LOG_FUNC; - if(db == NULL || !db->pkgcache_loaded) { return; } @@ -493,10 +512,8 @@ void _alpm_db_free_pkgcache(pmdb_t *db) pmpkghash_t *_alpm_db_get_pkgcache_hash(pmdb_t *db) { - ALPM_LOG_FUNC; - if(db == NULL) { - return(NULL); + return NULL; } if(!db->pkgcache_loaded) { @@ -508,20 +525,18 @@ pmpkghash_t *_alpm_db_get_pkgcache_hash(pmdb_t *db) _alpm_log(PM_LOG_DEBUG, "warning: pkgcache is NULL for db '%s'\n", db->treename); } - return(db->pkgcache); + return db->pkgcache; } alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db) { - ALPM_LOG_FUNC; - pmpkghash_t *hash = _alpm_db_get_pkgcache_hash(db); if(hash == NULL) { - return(NULL); + return NULL; } - return(hash->list); + return hash->list; } /* "duplicate" pkg then add it to pkgcache */ @@ -529,15 +544,13 @@ int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg) { pmpkg_t *newpkg; - ALPM_LOG_FUNC; - if(db == NULL || !db->pkgcache_loaded || pkg == NULL) { - return(-1); + return -1; } newpkg = _alpm_pkg_dup(pkg); if(newpkg == NULL) { - return(-1); + return -1; } _alpm_log(PM_LOG_DEBUG, "adding entry '%s' in '%s' cache\n", @@ -546,17 +559,15 @@ int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg) _alpm_db_free_grpcache(db); - return(0); + return 0; } int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg) { pmpkg_t *data = NULL; - ALPM_LOG_FUNC; - if(db == NULL || !db->pkgcache_loaded || pkg == NULL) { - return(-1); + return -1; } _alpm_log(PM_LOG_DEBUG, "removing entry '%s' from '%s' cache\n", @@ -567,32 +578,30 @@ int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg) /* package not found */ _alpm_log(PM_LOG_DEBUG, "cannot remove entry '%s' from '%s' cache: not found\n", alpm_pkg_get_name(pkg), db->treename); - return(-1); + return -1; } _alpm_pkg_free(data); _alpm_db_free_grpcache(db); - return(0); + return 0; } pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target) { - ALPM_LOG_FUNC; - if(db == NULL) { - return(NULL); + return NULL; } pmpkghash_t *pkgcache = _alpm_db_get_pkgcache_hash(db); if(!pkgcache) { _alpm_log(PM_LOG_DEBUG, "warning: failed to get '%s' from NULL pkgcache\n", target); - return(NULL); + return NULL; } - return(_alpm_pkghash_find(pkgcache, target)); + return _alpm_pkghash_find(pkgcache, target); } /* Returns a new group cache from db. @@ -601,10 +610,8 @@ int _alpm_db_load_grpcache(pmdb_t *db) { alpm_list_t *lp; - ALPM_LOG_FUNC; - if(db == NULL) { - return(-1); + return -1; } _alpm_log(PM_LOG_DEBUG, "loading group cache for repository '%s'\n", @@ -642,15 +649,13 @@ int _alpm_db_load_grpcache(pmdb_t *db) } db->grpcache_loaded = 1; - return(0); + return 0; } void _alpm_db_free_grpcache(pmdb_t *db) { alpm_list_t *lg; - ALPM_LOG_FUNC; - if(db == NULL || !db->grpcache_loaded) { return; } @@ -668,38 +673,34 @@ void _alpm_db_free_grpcache(pmdb_t *db) alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db) { - ALPM_LOG_FUNC; - if(db == NULL) { - return(NULL); + return NULL; } if(!db->grpcache_loaded) { _alpm_db_load_grpcache(db); } - return(db->grpcache); + return db->grpcache; } pmgrp_t *_alpm_db_get_grpfromcache(pmdb_t *db, const char *target) { alpm_list_t *i; - ALPM_LOG_FUNC; - if(db == NULL || target == NULL || strlen(target) == 0) { - return(NULL); + return NULL; } for(i = _alpm_db_get_grpcache(db); i; i = i->next) { pmgrp_t *info = i->data; if(strcmp(info->name, target) == 0) { - return(info); + return info; } } - return(NULL); + return NULL; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h index 75776d71..9ecf31f7 100644 --- a/lib/libalpm/db.h +++ b/lib/libalpm/db.h @@ -22,15 +22,16 @@ #ifndef _ALPM_DB_H #define _ALPM_DB_H -#include "alpm.h" -#include "pkghash.h" - #include <time.h> /* libarchive */ #include <archive.h> #include <archive_entry.h> +#include "alpm.h" +#include "pkghash.h" +#include "signing.h" + /* Database entries */ typedef enum _pmdbinfrq_t { INFRQ_BASE = 1, @@ -50,6 +51,7 @@ struct db_operations { /* Database */ struct __pmdb_t { + pmhandle_t *handle; char *treename; /* do not access directly, use _alpm_db_path(db) for lazy access */ char *_path; @@ -60,6 +62,7 @@ struct __pmdb_t { pmpkghash_t *pkgcache; alpm_list_t *grpcache; alpm_list_t *servers; + pgp_verify_t pgp_verify; struct db_operations *ops; }; @@ -72,8 +75,8 @@ const char *_alpm_db_path(pmdb_t *db); int _alpm_db_version(pmdb_t *db); int _alpm_db_cmp(const void *d1, const void *d2); alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles); -pmdb_t *_alpm_db_register_local(void); -pmdb_t *_alpm_db_register_sync(const char *treename); +pmdb_t *_alpm_db_register_local(pmhandle_t *handle); +pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename); void _alpm_db_unregister(pmdb_t *db); /* be_*.c, backend specific calls */ diff --git a/lib/libalpm/delta.c b/lib/libalpm/delta.c index 10c982f2..cd234874 100644 --- a/lib/libalpm/delta.c +++ b/lib/libalpm/delta.c @@ -41,32 +41,32 @@ const char SYMEXPORT *alpm_delta_get_from(pmdelta_t *delta) { - ASSERT(delta != NULL, return(NULL)); - return(delta->from); + ASSERT(delta != NULL, return NULL); + return delta->from; } const char SYMEXPORT *alpm_delta_get_to(pmdelta_t *delta) { - ASSERT(delta != NULL, return(NULL)); - return(delta->to); + ASSERT(delta != NULL, return NULL); + return delta->to; } const char SYMEXPORT *alpm_delta_get_filename(pmdelta_t *delta) { - ASSERT(delta != NULL, return(NULL)); - return(delta->delta); + ASSERT(delta != NULL, return NULL); + return delta->delta; } const char SYMEXPORT *alpm_delta_get_md5sum(pmdelta_t *delta) { - ASSERT(delta != NULL, return(NULL)); - return(delta->delta_md5); + ASSERT(delta != NULL, return NULL); + return delta->delta_md5; } off_t SYMEXPORT alpm_delta_get_size(pmdelta_t *delta) { - ASSERT(delta != NULL, return(-1)); - return(delta->delta_size); + ASSERT(delta != NULL, return -1); + return delta->delta_size; } /** @} */ @@ -108,7 +108,7 @@ static alpm_list_t *graph_init(alpm_list_t *deltas, int reverse) } v_i->childptr = v_i->children; } - return(vertices); + return vertices; } static void graph_init_size(alpm_list_t *vertices) @@ -205,7 +205,7 @@ static off_t shortest_path(alpm_list_t *vertices, const char *to, alpm_list_t ** *path = alpm_list_reverse(rpath); alpm_list_free(rpath); - return(bestsize); + return bestsize; } /** Calculates the shortest path from one version to another. @@ -225,11 +225,9 @@ off_t _alpm_shortest_delta_path(alpm_list_t *deltas, alpm_list_t *vertices; off_t bestsize = LONG_MAX; - ALPM_LOG_FUNC; - if(deltas == NULL) { *path = NULL; - return(bestsize); + return bestsize; } _alpm_log(PM_LOG_DEBUG, "started delta shortest-path search for '%s'\n", to); @@ -245,7 +243,7 @@ off_t _alpm_shortest_delta_path(alpm_list_t *deltas, alpm_list_free(vertices); *path = bestpath; - return(bestsize); + return bestsize; } static alpm_list_t *find_unused(alpm_list_t *deltas, const char *to, off_t quota) @@ -273,7 +271,7 @@ static alpm_list_t *find_unused(alpm_list_t *deltas, const char *to, off_t quota } alpm_list_free_inner(vertices, _alpm_graph_free); alpm_list_free(vertices); - return(unused); + return unused; } alpm_list_t SYMEXPORT *alpm_pkg_unused_deltas(pmpkg_t *pkg) @@ -283,7 +281,7 @@ alpm_list_t SYMEXPORT *alpm_pkg_unused_deltas(pmpkg_t *pkg) alpm_pkg_get_deltas(pkg), alpm_pkg_get_filename(pkg), pkgsize * MAX_DELTA_RATIO); - return(unused); + return unused; } @@ -308,7 +306,7 @@ pmdelta_t *_alpm_delta_parse(char *line) if(regexec(®, line, 0, 0, 0) != 0) { /* delta line is invalid, return NULL */ regfree(®); - return(NULL); + return NULL; } regfree(®); @@ -339,7 +337,7 @@ pmdelta_t *_alpm_delta_parse(char *line) _alpm_log(PM_LOG_DEBUG, "delta : %s %s '%jd'\n", delta->from, delta->to, (intmax_t)delta->delta_size); - return(delta); + return delta; } void _alpm_delta_free(pmdelta_t *delta) diff --git a/lib/libalpm/delta.h b/lib/libalpm/delta.h index d7a81c47..bd196bab 100644 --- a/lib/libalpm/delta.h +++ b/lib/libalpm/delta.h @@ -20,6 +20,8 @@ #ifndef _ALPM_DELTA_H #define _ALPM_DELTA_H +#include "config.h" /* ensure off_t is correct length */ + #include <sys/types.h> /* off_t */ #include "alpm.h" @@ -29,12 +31,12 @@ struct __pmdelta_t { char *delta; /** md5sum of the delta file */ char *delta_md5; - /** filesize of the delta file */ - off_t delta_size; /** filename of the 'before' file */ char *from; /** filename of the 'after' file */ char *to; + /** filesize of the delta file */ + off_t delta_size; /** download filesize of the delta file */ off_t download_size; }; diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index 36d6e1aa..62e8702c 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -35,6 +35,10 @@ #include "package.h" #include "db.h" #include "handle.h" +#include "trans.h" + +/* global handle variable */ +extern pmhandle_t *handle; void _alpm_dep_free(pmdepend_t *dep) { @@ -48,15 +52,13 @@ static pmdepmissing_t *depmiss_new(const char *target, pmdepend_t *dep, { pmdepmissing_t *miss; - ALPM_LOG_FUNC; - MALLOC(miss, sizeof(pmdepmissing_t), RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(miss->target, target, RET_ERR(PM_ERR_MEMORY, NULL)); miss->depend = _alpm_dep_dup(dep); STRDUP(miss->causingpkg, causingpkg, RET_ERR(PM_ERR_MEMORY, NULL)); - return(miss); + return miss; } void _alpm_depmiss_free(pmdepmissing_t *miss) @@ -73,10 +75,10 @@ static int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2) alpm_list_t *i; for(i = alpm_pkg_get_depends(pkg1); i; i = i->next) { if(_alpm_depcmp(pkg2, i->data)) { - return(1); + return 1; } } - return(0); + return 0; } /* Convert a list of pmpkg_t * to a graph structure, @@ -110,7 +112,7 @@ static alpm_list_t *dep_graph_init(alpm_list_t *targets) } vertex_i->childptr = vertex_i->children; } - return(vertices); + return vertices; } /* Re-order a list of target packages with respect to their dependencies. @@ -134,10 +136,8 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse) alpm_list_t *vptr; pmgraph_t *vertex; - ALPM_LOG_FUNC; - if(targets == NULL) { - return(NULL); + return NULL; } _alpm_log(PM_LOG_DEBUG, "started sorting dependencies\n"); @@ -153,7 +153,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse) while(vertex->childptr && !found) { pmgraph_t *nextchild = vertex->childptr->data; vertex->childptr = vertex->childptr->next; - if (nextchild->state == 0) { + if(nextchild->state == 0) { found = 1; nextchild->parent = vertex; vertex = nextchild; @@ -181,7 +181,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse) vptr = vptr->next; while(vptr) { vertex = vptr->data; - if (vertex->state == 0) break; + if(vertex->state == 0) break; vptr = vptr->next; } } @@ -201,7 +201,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse) alpm_list_free_inner(vertices, _alpm_graph_free); alpm_list_free(vertices); - return(newtargs); + return newtargs; } static int no_dep_version(void) @@ -214,7 +214,7 @@ static pmdepend_t *filtered_depend(pmdepend_t *dep, int nodepversion) { if(nodepversion) { pmdepend_t *newdep = _alpm_dep_dup(dep); - ASSERT(newdep, return(dep)); + ASSERT(newdep, return dep); newdep->mod = PM_DEP_MOD_ANY; dep = newdep; } @@ -235,10 +235,10 @@ static pmpkg_t *find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep) for(i = pkgs; i; i = alpm_list_next(i)) { pmpkg_t *pkg = i->data; if(_alpm_depcmp(pkg, dep)) { - return(pkg); + return pkg; } } - return(NULL); + return NULL; } /** Find a package satisfying a specified dependency. @@ -252,7 +252,7 @@ pmpkg_t SYMEXPORT *alpm_find_satisfier(alpm_list_t *pkgs, const char *depstring) pmdepend_t *dep = _alpm_splitdep(depstring); pmpkg_t *pkg = find_dep_satisfier(pkgs, dep); _alpm_dep_free(dep); - return(pkg); + return pkg; } /** Checks dependencies and returns missing ones in a list. @@ -271,8 +271,6 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps, alpm_list_t *baddeps = NULL; int nodepversion; - ALPM_LOG_FUNC; - targets = alpm_list_join(alpm_list_copy(remove), alpm_list_copy(upgrade)); for(i = pkglist; i; i = i->next) { pmpkg_t *pkg = i->data; @@ -343,7 +341,7 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps, alpm_list_free(modified); alpm_list_free(dblist); - return(baddeps); + return baddeps; } static int dep_vercmp(const char *version1, pmdepmod_t mod, @@ -364,7 +362,7 @@ static int dep_vercmp(const char *version1, pmdepmod_t mod, default: equal = 1; break; } } - return(equal); + return equal; } int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep) @@ -380,7 +378,7 @@ int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep) satisfy = (strcmp(pkg->name, dep->name) == 0 && dep_vercmp(pkg->version, dep->mod, dep->version)); if(satisfy) { - return(satisfy); + return satisfy; } } @@ -406,7 +404,7 @@ int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep) } } - return(satisfy); + return satisfy; } pmdepend_t *_alpm_splitdep(const char *depstring) @@ -415,7 +413,7 @@ pmdepend_t *_alpm_splitdep(const char *depstring) const char *ptr, *version = NULL; if(depstring == NULL) { - return(NULL); + return NULL; } CALLOC(depend, 1, sizeof(pmdepend_t), RET_ERR(PM_ERR_MEMORY, NULL)); @@ -451,7 +449,7 @@ pmdepend_t *_alpm_splitdep(const char *depstring) STRDUP(depend->version, version, RET_ERR(PM_ERR_MEMORY, NULL)); } - return(depend); + return depend; } pmdepend_t *_alpm_dep_dup(const pmdepend_t *dep) @@ -464,7 +462,7 @@ pmdepend_t *_alpm_dep_dup(const pmdepend_t *dep) STRDUP(newdep->version, dep->version, RET_ERR(PM_ERR_MEMORY, NULL)); newdep->mod = dep->mod; - return(newdep); + return newdep; } /* These parameters are messy. We check if this package, given a list of @@ -477,7 +475,7 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets, alpm_list_t *i; if(_alpm_pkg_find(targets, alpm_pkg_get_name(pkg))) { - return(0); + return 0; } if(!include_explicit) { @@ -485,7 +483,7 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets, if(alpm_pkg_get_reason(pkg) == PM_PKG_REASON_EXPLICIT) { _alpm_log(PM_LOG_DEBUG, "excluding %s -- explicitly installed\n", alpm_pkg_get_name(pkg)); - return(0); + return 0; } } @@ -499,12 +497,12 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets, for(i = _alpm_db_get_pkgcache(db); i; i = i->next) { pmpkg_t *lpkg = i->data; if(_alpm_dep_edge(lpkg, pkg) && !_alpm_pkg_find(targets, lpkg->name)) { - return(0); + return 0; } } /* it's ok to remove */ - return(1); + return 1; } /** @@ -521,8 +519,6 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit) { alpm_list_t *i, *j; - ALPM_LOG_FUNC; - if(db == NULL || targs == NULL) { return; } @@ -569,7 +565,7 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs, if(pkg && _alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(pkg)) { int install = 0; - if (prompt) { + if(prompt) { QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, NULL, NULL, &install); } else { @@ -580,7 +576,7 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs, continue; } } - return(pkg); + return pkg; } } /* 2. satisfiers (skip literals here) */ @@ -591,7 +587,7 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs, !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(pkg)) { int install = 0; - if (prompt) { + if(prompt) { QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, NULL, NULL, &install); } else { @@ -613,13 +609,13 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs, /* first check if one provider is already installed locally */ for(i = providers; i; i = i->next) { pmpkg_t *pkg = i->data; - if (_alpm_pkghash_find(_alpm_db_get_pkgcache_hash(handle->db_local), pkg->name)) { + if(_alpm_pkghash_find(_alpm_db_get_pkgcache_hash(handle->db_local), pkg->name)) { alpm_list_free(providers); - return(pkg); + return pkg; } } count = alpm_list_count(providers); - if (count >= 1) { + if(count >= 1) { /* default to first provider if there is no QUESTION callback */ int index = 0; if(count > 1) { @@ -630,7 +626,7 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs, if(index >= 0 && index < count) { pmpkg_t *pkg = alpm_list_getdata(alpm_list_nth(providers, index)); alpm_list_free(providers); - return(pkg); + return pkg; } alpm_list_free(providers); providers = NULL; @@ -641,7 +637,7 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs, } else { pm_errno = PM_ERR_PKG_NOT_FOUND; } - return(NULL); + return NULL; } /** Find a package satisfying a specified dependency. @@ -657,13 +653,13 @@ pmpkg_t SYMEXPORT *alpm_find_dbs_satisfier(alpm_list_t *dbs, const char *depstri pmdepend_t *dep; pmpkg_t *pkg; - ASSERT(dbs, return(NULL)); + ASSERT(dbs, return NULL); dep = _alpm_splitdep(depstring); - ASSERT(dep, return(NULL)); + ASSERT(dep, return NULL); pkg = resolvedep(dep, dbs, NULL, 1); _alpm_dep_free(dep); - return(pkg); + return pkg; } /** @@ -696,10 +692,8 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk alpm_list_t *deps = NULL; alpm_list_t *packages_copy; - ALPM_LOG_FUNC; - if(_alpm_pkg_find(*packages, pkg->name) != NULL) { - return(0); + return 0; } /* Create a copy of the packages list, so that it can be restored @@ -760,67 +754,55 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk alpm_list_free(packages_copy); } _alpm_log(PM_LOG_DEBUG, "finished resolving dependencies\n"); - return(ret); + return ret; } const char SYMEXPORT *alpm_miss_get_target(const pmdepmissing_t *miss) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(miss != NULL, return(NULL)); + ASSERT(miss != NULL, return NULL); - return(miss->target); + return miss->target; } const char SYMEXPORT *alpm_miss_get_causingpkg(const pmdepmissing_t *miss) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(miss != NULL, return(NULL)); + ASSERT(miss != NULL, return NULL); return miss->causingpkg; } pmdepend_t SYMEXPORT *alpm_miss_get_dep(pmdepmissing_t *miss) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(miss != NULL, return(NULL)); + ASSERT(miss != NULL, return NULL); - return(miss->depend); + return miss->depend; } pmdepmod_t SYMEXPORT alpm_dep_get_mod(const pmdepend_t *dep) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(dep != NULL, return(-1)); + ASSERT(dep != NULL, return -1); - return(dep->mod); + return dep->mod; } const char SYMEXPORT *alpm_dep_get_name(const pmdepend_t *dep) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(dep != NULL, return(NULL)); + ASSERT(dep != NULL, return NULL); - return(dep->name); + return dep->name; } const char SYMEXPORT *alpm_dep_get_version(const pmdepend_t *dep) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(dep != NULL, return(NULL)); + ASSERT(dep != NULL, return NULL); - return(dep->version); + return dep->version; } /** Reverse of splitdep; make a dep string from a pmdepend_t struct. @@ -834,10 +816,8 @@ char SYMEXPORT *alpm_dep_compute_string(const pmdepend_t *dep) char *str; size_t len; - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(dep != NULL, return(NULL)); + ASSERT(dep != NULL, return NULL); if(dep->name) { name = dep->name; @@ -882,6 +862,6 @@ char SYMEXPORT *alpm_dep_compute_string(const pmdepend_t *dep) MALLOC(str, len, RET_ERR(PM_ERR_MEMORY, NULL)); snprintf(str, len, "%s%s%s", name, opr, ver); - return(str); + return str; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c index 066107d7..c6c0b98f 100644 --- a/lib/libalpm/diskspace.c +++ b/lib/libalpm/diskspace.c @@ -56,7 +56,7 @@ static int mount_point_cmp(const void *p1, const void *p2) const alpm_mountpoint_t *mp1 = p1; const alpm_mountpoint_t *mp2 = p2; /* the negation will sort all mountpoints before their parent */ - return(-strcmp(mp1->mount_dir, mp2->mount_dir)); + return -strcmp(mp1->mount_dir, mp2->mount_dir); } static alpm_list_t *mount_point_list(void) @@ -71,8 +71,8 @@ static alpm_list_t *mount_point_list(void) fp = setmntent(MOUNTED, "r"); - if (fp == NULL) { - return(NULL); + if(fp == NULL) { + return NULL; } while((mnt = getmntent(fp))) { @@ -103,8 +103,8 @@ static alpm_list_t *mount_point_list(void) entries = getmntinfo(&fsp, MNT_NOWAIT); - if (entries < 0) { - return(NULL); + if(entries < 0) { + return NULL; } for(; entries-- > 0; fsp++) { @@ -128,7 +128,7 @@ static alpm_list_t *mount_point_list(void) mp = ptr->data; _alpm_log(PM_LOG_DEBUG, "mountpoint: %s\n", mp->mount_dir); } - return(mount_points); + return mount_points; } static alpm_mountpoint_t *match_mount_point(const alpm_list_t *mount_points, @@ -140,16 +140,16 @@ static alpm_mountpoint_t *match_mount_point(const alpm_list_t *mount_points, alpm_mountpoint_t *data = mp->data; if(strncmp(data->mount_dir, real_path, data->mount_dir_len) == 0) { - return(data); + return data; } } /* should not get here... */ - return(NULL); + return NULL; } -static int calculate_removed_size(const alpm_list_t *mount_points, - pmpkg_t *pkg) +static int calculate_removed_size(pmhandle_t *handle, + const alpm_list_t *mount_points, pmpkg_t *pkg) { alpm_list_t *file; @@ -182,17 +182,17 @@ static int calculate_removed_size(const alpm_list_t *mount_points, mp->used |= USED_REMOVE; } - return(0); + return 0; } -static int calculate_installed_size(const alpm_list_t *mount_points, - pmpkg_t *pkg) +static int calculate_installed_size(pmhandle_t *handle, + const alpm_list_t *mount_points, pmpkg_t *pkg) { int ret=0; struct archive *archive; struct archive_entry *entry; - if ((archive = archive_read_new()) == NULL) { + if((archive = archive_read_new()) == NULL) { pm_errno = PM_ERR_LIBARCHIVE; ret = -1; goto cleanup; @@ -254,28 +254,29 @@ static int calculate_installed_size(const alpm_list_t *mount_points, archive_read_finish(archive); cleanup: - return(ret); + return ret; } -int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local) +int _alpm_check_diskspace(pmhandle_t *handle) { alpm_list_t *mount_points, *i; alpm_mountpoint_t *root_mp; size_t replaces = 0, current = 0, numtargs; int abort = 0; alpm_list_t *targ; + pmtrans_t *trans = handle->trans; numtargs = alpm_list_count(trans->add); mount_points = mount_point_list(); if(mount_points == NULL) { _alpm_log(PM_LOG_ERROR, _("could not determine filesystem mount points\n")); - return(-1); + return -1; } root_mp = match_mount_point(mount_points, handle->root); if(root_mp == NULL) { _alpm_log(PM_LOG_ERROR, _("could not determine root mount point %s\n"), handle->root); - return(-1); + return -1; } replaces = alpm_list_count(trans->remove); @@ -288,7 +289,7 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local) numtargs, current); local_pkg = targ->data; - calculate_removed_size(mount_points, local_pkg); + calculate_removed_size(handle, mount_points, local_pkg); } } @@ -300,11 +301,11 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local) pkg = targ->data; /* is this package already installed? */ - local_pkg = _alpm_db_get_pkgfromcache(db_local, pkg->name); + local_pkg = _alpm_db_get_pkgfromcache(handle->db_local, pkg->name); if(local_pkg) { - calculate_removed_size(mount_points, local_pkg); + calculate_removed_size(handle, mount_points, local_pkg); } - calculate_installed_size(mount_points, pkg); + calculate_installed_size(handle, mount_points, pkg); for(i = mount_points; i; i = alpm_list_next(i)) { alpm_mountpoint_t *data = i->data; @@ -352,7 +353,7 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local) RET_ERR(PM_ERR_DISK_SPACE, -1); } - return(0); + return 0; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/diskspace.h b/lib/libalpm/diskspace.h index 2894a0c2..28aca7e9 100644 --- a/lib/libalpm/diskspace.h +++ b/lib/libalpm/diskspace.h @@ -46,7 +46,7 @@ typedef struct __alpm_mountpoint_t { FSSTATSTYPE fsp; } alpm_mountpoint_t; -int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local); +int _alpm_check_diskspace(pmhandle_t *handle); #endif /* _ALPM_DISKSPACE_H */ diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index a98d84ac..8591c9d5 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -29,14 +29,9 @@ #include <sys/types.h> #include <sys/stat.h> #include <signal.h> -/* 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 -#ifdef HAVE_LIBFETCH -#include <fetch.h> +#ifdef HAVE_LIBCURL +#include <curl/curl.h> #endif /* libalpm */ @@ -47,112 +42,187 @@ #include "util.h" #include "handle.h" -static char *get_filename(const char *url) { +/* global handle variable */ +extern pmhandle_t *handle; + +#ifdef HAVE_LIBCURL +static double prevprogress; /* last download amount */ +#endif + +static const char *get_filename(const char *url) +{ char *filename = strrchr(url, '/'); if(filename != NULL) { filename++; } - return(filename); + return filename; } -#ifdef HAVE_LIBFETCH -static char *get_destfile(const char *path, const char *filename) { - char *destfile; - /* len = localpath len + filename len + null */ - size_t len = strlen(path) + strlen(filename) + 1; - CALLOC(destfile, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL)); - snprintf(destfile, len, "%s%s", path, filename); +#ifdef HAVE_LIBCURL +static char *get_fullpath(const char *path, const char *filename, + const char *suffix) +{ + 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)); + snprintf(filepath, len, "%s%s%s", path, filename, suffix); - return(destfile); + return filepath; } -static char *get_tempfile(const char *path, const char *filename) { - char *tempfile; - /* len = localpath len + filename len + '.part' len + null */ - size_t len = strlen(path) + strlen(filename) + 6; - CALLOC(tempfile, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL)); - snprintf(tempfile, len, "%s%s.part", path, filename); +#define check_stop() if(dload_interrupted) { ret = -1; goto cleanup; } +enum sighandlers { OLD = 0, NEW = 1 }; - return(tempfile); +static int dload_interrupted; +static void inthandler(int UNUSED signum) +{ + dload_interrupted = 1; } -static const char *gethost(struct url *fileurl) +static int curl_progress(void *file, double dltotal, double dlnow, + double UNUSED ultotal, double UNUSED ulnow) { - const char *host = _("disk"); - if(strcmp(SCHEME_FILE, fileurl->scheme) != 0) { - host = fileurl->host; + struct fileinfo *dlfile = (struct fileinfo *)file; + double current_size, total_size; + + /* SIGINT sent, abort by alerting curl */ + if(dload_interrupted) { + return 1; } - return(host); + + /* none of what follows matters if the front end has no callback */ + if(handle->dlcb == NULL) { + return 0; + } + + current_size = dlfile->initial_size + dlnow; + total_size = dlfile->initial_size + dltotal; + + if(DOUBLE_EQ(dltotal, 0) || DOUBLE_EQ(prevprogress, total_size)) { + return 0; + } + + /* 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); + } + + handle->dlcb(dlfile->filename, (long)current_size, (long)total_size); + + prevprogress = current_size; + + return 0; } -int dload_interrupted; -static void inthandler(int signum) +static int curl_gethost(const char *url, char *buffer) { - dload_interrupted = 1; + size_t hostlen; + char *p; + + if(strncmp(url, "file://", 7) == 0) { + strcpy(buffer, _("disk")); + } else { + p = strstr(url, "//"); + if(!p) { + return 1; + } + p += 2; /* jump over the found // */ + 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); + } + + return 0; } -#define check_stop() if(dload_interrupted) { ret = -1; goto cleanup; } -enum sighandlers { OLD = 0, NEW = 1 }; +static int utimes_long(const char *path, long time) +{ + if(time != -1) { + struct timeval tv[2]; + memset(&tv, 0, sizeof(tv)); + tv[0].tv_sec = tv[1].tv_sec = time; + return utimes(path, tv); + } + return 0; +} -static int download_internal(const char *url, const char *localpath, - int force) { + +static int curl_download_internal(const char *url, const char *localpath, + int force, int allow_resume, int errors_ok) +{ + int ret = -1; FILE *localf = NULL; + const char *useragent; + const char *open_mode = "wb"; + char *destfile, *tempfile; + /* RFC1123 states applications should support this length */ + char hostname[256]; + char error_buffer[CURL_ERROR_SIZE]; struct stat st; - int ret = 0; - off_t dl_thisfile = 0; - ssize_t nread = 0; - char *tempfile, *destfile, *filename; + long timecond, remote_time; + double remote_size, bytes_dl; struct sigaction sig_pipe[2], sig_int[2]; + struct fileinfo dlfile; - off_t local_size = 0; - time_t local_time = 0; - - struct url *fileurl; - struct url_stat ust; - fetchIO *dlf = NULL; - - char buffer[PM_DLBUF_LEN]; - - filename = get_filename(url); - if(!filename) { + 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); } - fileurl = fetchParseURL(url); - if(!fileurl) { - _alpm_log(PM_LOG_ERROR, _("url '%s' is invalid\n"), url); - RET_ERR(PM_ERR_LIBFETCH, -1); + destfile = get_fullpath(localpath, dlfile.filename, ""); + tempfile = get_fullpath(localpath, dlfile.filename, ".part"); + if(!destfile || !tempfile) { + goto cleanup; } - destfile = get_destfile(localpath, filename); - tempfile = get_tempfile(localpath, filename); - - 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 && 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; - } else { - _alpm_log(PM_LOG_DEBUG, "no file found matching criteria, starting from scratch\n"); + error_buffer[0] = '\0'; + + /* the curl_easy handle is initialized with the alpm handle, so we only need + * to reset the curl handle set parameters for each time it's used. */ + curl_easy_reset(handle->curl); + curl_easy_setopt(handle->curl, CURLOPT_URL, url); + curl_easy_setopt(handle->curl, CURLOPT_FAILONERROR, 1L); + curl_easy_setopt(handle->curl, CURLOPT_ERRORBUFFER, error_buffer); + curl_easy_setopt(handle->curl, CURLOPT_CONNECTTIMEOUT, 10L); + curl_easy_setopt(handle->curl, CURLOPT_FILETIME, 1L); + curl_easy_setopt(handle->curl, CURLOPT_NOPROGRESS, 0L); + 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); } - /* pass the raw filename for passing to the callback function */ - _alpm_log(PM_LOG_DEBUG, "using '%s' for download progress\n", filename); + 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"); + dlfile.initial_size = (double)st.st_size; + } - /* print proxy info for debug purposes */ - _alpm_log(PM_LOG_DEBUG, "HTTP_PROXY: %s\n", getenv("HTTP_PROXY")); - _alpm_log(PM_LOG_DEBUG, "http_proxy: %s\n", getenv("http_proxy")); - _alpm_log(PM_LOG_DEBUG, "FTP_PROXY: %s\n", getenv("FTP_PROXY")); - _alpm_log(PM_LOG_DEBUG, "ftp_proxy: %s\n", getenv("ftp_proxy")); + localf = fopen(tempfile, open_mode); + if(localf == NULL) { + goto cleanup; + } - /* 10s timeout */ - fetchTimeout = 10; + curl_easy_setopt(handle->curl, CURLOPT_WRITEDATA, localf); /* ignore any SIGPIPE signals- these may occur if our FTP socket dies or * something along those lines. Store the old signal handler first. */ @@ -169,168 +239,67 @@ static int download_internal(const char *url, const char *localpath, sigaction(SIGINT, NULL, &sig_int[OLD]); sigaction(SIGINT, &sig_int[NEW], NULL); - /* 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. */ - fetchLastErrCode = 0; - if(fetchStat(fileurl, &ust, "") == -1) { - pm_errno = PM_ERR_LIBFETCH; - _alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"), - filename, gethost(fileurl), fetchLastErrString); - ret = -1; - goto cleanup; - } - check_stop(); - - _alpm_log(PM_LOG_DEBUG, "ust.mtime: %ld local_time: %ld compare: %ld\n", - ust.mtime, local_time, local_time - ust.mtime); - _alpm_log(PM_LOG_DEBUG, "ust.size: %jd local_size: %jd compare: %jd\n", - (intmax_t)ust.size, (intmax_t)local_size, (intmax_t)(local_size - ust.size)); - if(!force && ust.mtime && ust.mtime == local_time - && ust.size && ust.size == local_size) { - /* the remote time and size values agreed with what we have, so move on - * because there is nothing more to do. */ - _alpm_log(PM_LOG_DEBUG, "files are identical, skipping %s\n", filename); - ret = 1; - goto cleanup; - } - if(!ust.mtime || ust.mtime != local_time) { - _alpm_log(PM_LOG_DEBUG, "mtimes were different or unavailable, downloading %s from beginning\n", filename); - fileurl->offset = 0; - } + /* Progress 0 - initialize */ + prevprogress = 0; - fetchLastErrCode = 0; - dlf = fetchGet(fileurl, ""); - check_stop(); + /* perform transfer */ + handle->curlerr = curl_easy_perform(handle->curl); - if(fetchLastErrCode != 0 || dlf == NULL) { - pm_errno = PM_ERR_LIBFETCH; - _alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"), - filename, gethost(fileurl), fetchLastErrString); - ret = -1; + /* was it a success? */ + if(handle->curlerr == CURLE_ABORTED_BY_CALLBACK) { goto cleanup; - } else { - _alpm_log(PM_LOG_DEBUG, "connected to %s successfully\n", fileurl->host); - } - - if(localf && fileurl->offset == 0) { - _alpm_log(PM_LOG_WARNING, _("resuming download of %s not possible; starting over\n"), filename); - fclose(localf); - localf = NULL; - } else if(fileurl->offset) { - _alpm_log(PM_LOG_DEBUG, "resuming download at position %jd\n", (intmax_t)fileurl->offset); - } - - - if(localf == NULL) { - _alpm_rmrf(tempfile); - fileurl->offset = (off_t)0; - dl_thisfile = 0; - localf = fopen(tempfile, "wb"); - if(localf == NULL) { /* still null? */ - pm_errno = PM_ERR_RETRIEVE; - _alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"), - tempfile, strerror(errno)); - ret = -1; - 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"), + dlfile.filename, hostname, error_buffer); + } else { + _alpm_log(PM_LOG_DEBUG, "failed retrieving file '%s' from %s : %s\n", + dlfile.filename, hostname, error_buffer); } + unlink(tempfile); + goto cleanup; } - /* Progress 0 - initialize */ - if(handle->dlcb) { - handle->dlcb(filename, 0, ust.size); - } + /* retrieve info about the state of the transfer */ + curl_easy_getinfo(handle->curl, CURLINFO_FILETIME, &remote_time); + curl_easy_getinfo(handle->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &remote_size); + curl_easy_getinfo(handle->curl, CURLINFO_SIZE_DOWNLOAD, &bytes_dl); + curl_easy_getinfo(handle->curl, CURLINFO_CONDITION_UNMET, &timecond); - while((nread = fetchIO_read(dlf, buffer, PM_DLBUF_LEN)) > 0) { - check_stop(); - size_t nwritten = 0; - 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)); - ret = -1; - goto cleanup; - } - dl_thisfile += nread; - - if(handle->dlcb) { - handle->dlcb(filename, dl_thisfile, ust.size); - } - } - - /* 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; + /* time condition was met and we didn't download anything. we need to + * clean up the 0 byte .part file that's left behind. */ + if(timecond == 1 && DOUBLE_EQ(bytes_dl, 0)) { + ret = 1; + unlink(tempfile); goto cleanup; } - if (ust.size != -1 && dl_thisfile < ust.size) { + /* remote_size isn't necessarily the full size of the file, just what the + * server reported as remaining to download. compare it to what curl reported + * 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"), - filename, (intmax_t)dl_thisfile, (intmax_t)ust.size); - ret = -1; + dlfile.filename, (intmax_t)bytes_dl, (intmax_t)remote_size); goto cleanup; } - /* probably safer to close the file descriptors now before renaming the file, - * for example to make sure the buffers are flushed. - */ - fclose(localf); - localf = NULL; - fetchIO_close(dlf); - dlf = NULL; - - /* set the times on the file to the same as that of the remote file */ - if(ust.mtime) { - struct timeval tv[2]; - memset(&tv, 0, sizeof(tv)); - tv[0].tv_sec = ust.atime; - tv[1].tv_sec = ust.mtime; - utimes(tempfile, tv); - } - 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: - FREE(tempfile); - FREE(destfile); if(localf != NULL) { - /* if we still had a local file open, we got interrupted. set the mtimes on - * the file accordingly. */ - fflush(localf); - if(ust.mtime) { - struct timeval tv[2]; - memset(&tv, 0, sizeof(tv)); - tv[0].tv_sec = ust.atime; - tv[1].tv_sec = ust.mtime; - futimes(fileno(localf), tv); - } fclose(localf); + utimes_long(tempfile, remote_time); } - if(dlf != NULL) { - fetchIO_close(dlf); + + if(ret == 0) { + rename(tempfile, destfile); } - fetchFreeURL(fileurl); + + FREE(tempfile); + FREE(destfile); /* restore the old signal handlers */ sigaction(SIGINT, &sig_int[OLD], NULL); @@ -340,106 +309,73 @@ cleanup: raise(SIGINT); } - return(ret); + return ret; } #endif -static int download(const char *url, const char *localpath, - int force) { +int _alpm_download(const char *url, const char *localpath, + int force, int allow_resume, int errors_ok) +{ if(handle->fetchcb == NULL) { -#ifdef HAVE_LIBFETCH - return(download_internal(url, localpath, force)); +#ifdef HAVE_LIBCURL + return curl_download_internal(url, localpath, force, allow_resume, errors_ok); #else RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1); #endif } else { int ret = handle->fetchcb(url, localpath, force); - if(ret == -1) { + if(ret == -1 && !errors_ok) { RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1); } - return(ret); - } -} - -/* - * Download a single file - * - servers must be a list of urls WITHOUT trailing slashes. - * - * RETURN: 0 for successful download - * 1 if the files are identical - * -1 on error - */ -int _alpm_download_single_file(const char *filename, - alpm_list_t *servers, const char *localpath, - int force) -{ - alpm_list_t *i; - int ret = -1; - - ASSERT(servers != NULL, RET_ERR(PM_ERR_SERVER_NONE, -1)); - - for(i = servers; i; i = i->next) { - const char *server = i->data; - char *fileurl = NULL; - size_t len; - - /* print server + filename into a buffer */ - len = strlen(server) + strlen(filename) + 2; - CALLOC(fileurl, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1)); - snprintf(fileurl, len, "%s/%s", server, filename); - - ret = download(fileurl, localpath, force); - FREE(fileurl); - if(ret != -1) { - break; - } - } - - return(ret); -} - -int _alpm_download_files(alpm_list_t *files, - alpm_list_t *servers, const char *localpath) -{ - int ret = 0; - alpm_list_t *lp; - - for(lp = files; lp; lp = lp->next) { - char *filename = lp->data; - if(_alpm_download_single_file(filename, servers, - localpath, 0) == -1) { - ret++; - } + return ret; } - - return(ret); } /** Fetch a remote pkg. */ char SYMEXPORT *alpm_fetch_pkgurl(const char *url) { - char *filename, *filepath; - const char *cachedir; + 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(); /* download the file */ - ret = download(url, cachedir, 0); + ret = _alpm_download(url, cachedir, 0, 1, 0); if(ret == -1) { _alpm_log(PM_LOG_WARNING, _("failed to download %s\n"), url); - return(NULL); + return NULL; } _alpm_log(PM_LOG_DEBUG, "successfully downloaded %s\n", url); + /* attempt to download the signature */ + if(ret == 0 && (handle->sigverify == PM_PGP_VERIFY_ALWAYS || + handle->sigverify == PM_PGP_VERIFY_OPTIONAL)) { + char *sig_url; + size_t len; + 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)); + snprintf(sig_url, len, "%s.sig", url); + + ret = _alpm_download(sig_url, cachedir, 1, 0, errors_ok); + if(ret == -1 && !errors_ok) { + _alpm_log(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); + } + FREE(sig_url); + } + /* we should be able to find the file the second time around */ filepath = _alpm_filecache_find(filename); - return(filepath); + return filepath; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/dload.h b/lib/libalpm/dload.h index 63266491..f4fd14cd 100644 --- a/lib/libalpm/dload.h +++ b/lib/libalpm/dload.h @@ -25,14 +25,14 @@ #include <time.h> -#define PM_DLBUF_LEN (1024 * 16) +/* internal structure for communicating with curl progress callback */ +struct fileinfo { + const char *filename; + double initial_size; +}; -int _alpm_download_single_file(const char *filename, - alpm_list_t *servers, const char *localpath, - int force); - -int _alpm_download_files(alpm_list_t *files, - alpm_list_t *servers, const char *localpath); +int _alpm_download(const char *url, const char *localpath, + int force, int allow_resume, int errors_ok); #endif /* _ALPM_DLOAD_H */ diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c index 21fbb48f..294ec214 100644 --- a/lib/libalpm/error.c +++ b/lib/libalpm/error.c @@ -20,21 +20,17 @@ #include "config.h" -/* TODO: needed for the libfetch stuff, unfortunately- we should kill it */ -#include <stdio.h> -/* 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 - -#ifdef HAVE_LIBFETCH -#include <fetch.h> /* fetchLastErrString */ +#ifdef HAVE_LIBCURL +#include <curl/curl.h> #endif /* libalpm */ #include "util.h" #include "alpm.h" +#include "handle.h" + +/* global handle variable */ +extern pmhandle_t *handle; const char SYMEXPORT *alpm_strerrorlast(void) { @@ -122,6 +118,13 @@ const char SYMEXPORT *alpm_strerror(int err) return _("package architecture is not valid"); case PM_ERR_PKG_REPO_NOT_FOUND: return _("could not find repository for target"); + /* Signatures */ + case PM_ERR_SIG_MISSINGDIR: + return _("signature directory not configured correctly"); + case PM_ERR_SIG_INVALID: + return _("invalid PGP signature"); + case PM_ERR_SIG_UNKNOWN: + return _("unknown PGP signature"); /* Deltas */ case PM_ERR_DLT_INVALID: return _("invalid or corrupted delta"); @@ -147,13 +150,15 @@ const char SYMEXPORT *alpm_strerror(int err) * requires the archive struct, so we can't. Just use a generic * error string instead. */ return _("libarchive error"); - case PM_ERR_LIBFETCH: -#ifdef HAVE_LIBFETCH - return fetchLastErrString; + case PM_ERR_LIBCURL: +#ifdef HAVE_LIBCURL + return curl_easy_strerror(handle->curlerr); #else /* obviously shouldn't get here... */ return _("download library error"); #endif + case PM_ERR_GPGME: + return _("gpgme error"); case PM_ERR_EXTERNAL_DOWNLOAD: return _("error invoking external downloader"); /* Unknown error! */ diff --git a/lib/libalpm/graph.c b/lib/libalpm/graph.c new file mode 100644 index 00000000..2e2ba236 --- /dev/null +++ b/lib/libalpm/graph.c @@ -0,0 +1,52 @@ +/* + * graph.c - helpful graph structure and setup/teardown methods + * + * Copyright (c) 2007-2011 Pacman Development Team <pacman-dev@archlinux.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "graph.h" +#include "util.h" +#include "log.h" + +pmgraph_t *_alpm_graph_new(void) +{ + pmgraph_t *graph = NULL; + + CALLOC(graph, 1, sizeof(pmgraph_t), RET_ERR(PM_ERR_MEMORY, NULL)); + return graph; +} + +void _alpm_graph_free(void *data) +{ + pmgraph_t *graph = data; + /* make my children forget about me */ + for(alpm_list_t *i = graph->children; i; i = i->next) { + pmgraph_t *child = i->data; + child->parent = NULL; + } + alpm_list_free(graph->children); + /* and make my parents forget about me too */ + if(graph->parent) { + alpm_list_t *me = alpm_list_find_ptr(graph->parent->children, &data); + graph->parent->children = alpm_list_remove_item(graph->parent->children, + me); + } + free(graph); +} + +/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/graph.h b/lib/libalpm/graph.h index 07986f66..f76c6004 100644 --- a/lib/libalpm/graph.h +++ b/lib/libalpm/graph.h @@ -1,8 +1,7 @@ /* * graph.h - helpful graph structure and setup/teardown methods * - * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org> - * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> + * Copyright (c) 2007-2011 Pacman Development Team <pacman-dev@archlinux.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,34 +16,27 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#ifndef _ALPM_GRAPH_H +#define _ALPM_GRAPH_H + +#include "config.h" /* ensure off_t is correct length */ #include <sys/types.h> /* off_t */ #include "alpm_list.h" -#include "util.h" /* CALLOC() */ -struct __pmgraph_t { +typedef struct __pmgraph_t { char state; /* 0: untouched, -1: entered, other: leaving time */ - void *data; off_t weight; /* weight of the node */ + void *data; struct __pmgraph_t *parent; /* where did we come from? */ alpm_list_t *children; alpm_list_t *childptr; /* points to a child in children list */ -}; -typedef struct __pmgraph_t pmgraph_t; - -static pmgraph_t *_alpm_graph_new(void) -{ - pmgraph_t *graph = NULL; +} pmgraph_t; - CALLOC(graph, 1, sizeof(pmgraph_t), RET_ERR(PM_ERR_MEMORY, NULL)); - return(graph); -} +pmgraph_t *_alpm_graph_new(void); +void _alpm_graph_free(void *data); -static void _alpm_graph_free(void *data) -{ - pmgraph_t *graph = data; - alpm_list_free(graph->children); - free(graph); -} +#endif /* _ALPM_GRAPH_H */ +/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/group.c b/lib/libalpm/group.c index 398c2588..383d0163 100644 --- a/lib/libalpm/group.c +++ b/lib/libalpm/group.c @@ -21,7 +21,6 @@ #include "config.h" #include <stdlib.h> -#include <stdio.h> #include <string.h> /* libalpm */ @@ -35,18 +34,14 @@ pmgrp_t *_alpm_grp_new(const char *name) { pmgrp_t* grp; - ALPM_LOG_FUNC; - CALLOC(grp, 1, sizeof(pmgrp_t), RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(grp->name, name, RET_ERR(PM_ERR_MEMORY, NULL)); - return(grp); + return grp; } void _alpm_grp_free(pmgrp_t *grp) { - ALPM_LOG_FUNC; - if(grp == NULL) { return; } @@ -59,20 +54,16 @@ void _alpm_grp_free(pmgrp_t *grp) const char SYMEXPORT *alpm_grp_get_name(const pmgrp_t *grp) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(grp != NULL, return(NULL)); + ASSERT(grp != NULL, return NULL); return grp->name; } alpm_list_t SYMEXPORT *alpm_grp_get_pkgs(const pmgrp_t *grp) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(grp != NULL, return(NULL)); + ASSERT(grp != NULL, return NULL); return grp->packages; } diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index 586aad1e..80ad5601 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -27,9 +27,7 @@ #include <limits.h> #include <sys/types.h> #include <syslog.h> -#include <time.h> #include <sys/stat.h> -#include <errno.h> /* libalpm */ #include "handle.h" @@ -48,13 +46,13 @@ pmhandle_t *_alpm_handle_new() CALLOC(handle, 1, sizeof(pmhandle_t), RET_ERR(PM_ERR_MEMORY, NULL)); - return(handle); + handle->sigverify = PM_PGP_VERIFY_OPTIONAL; + + return handle; } void _alpm_handle_free(pmhandle_t *handle) { - ALPM_LOG_FUNC; - if(handle == NULL) { return; } @@ -69,6 +67,11 @@ void _alpm_handle_free(pmhandle_t *handle) closelog(); } +#ifdef HAVE_LIBCURL + /* release curl handle */ + curl_easy_cleanup(handle->curl); +#endif + /* free memory */ _alpm_trans_free(handle->trans); FREE(handle->root); @@ -77,17 +80,19 @@ void _alpm_handle_free(pmhandle_t *handle) FREE(handle->logfile); FREE(handle->lockfile); FREE(handle->arch); + FREE(handle->signaturedir); FREELIST(handle->dbs_sync); FREELIST(handle->noupgrade); FREELIST(handle->noextract); FREELIST(handle->ignorepkg); FREELIST(handle->ignoregrp); FREE(handle); + } alpm_cb_log SYMEXPORT alpm_option_get_logcb() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -96,7 +101,7 @@ alpm_cb_log SYMEXPORT alpm_option_get_logcb() alpm_cb_download SYMEXPORT alpm_option_get_dlcb() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -105,7 +110,7 @@ alpm_cb_download SYMEXPORT alpm_option_get_dlcb() alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -114,7 +119,7 @@ alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb() alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -123,7 +128,7 @@ alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb() const char SYMEXPORT *alpm_option_get_root() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -132,7 +137,7 @@ const char SYMEXPORT *alpm_option_get_root() const char SYMEXPORT *alpm_option_get_dbpath() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -141,7 +146,7 @@ const char SYMEXPORT *alpm_option_get_dbpath() alpm_list_t SYMEXPORT *alpm_option_get_cachedirs() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -150,7 +155,7 @@ alpm_list_t SYMEXPORT *alpm_option_get_cachedirs() const char SYMEXPORT *alpm_option_get_logfile() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -159,16 +164,25 @@ const char SYMEXPORT *alpm_option_get_logfile() const char SYMEXPORT *alpm_option_get_lockfile() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } return handle->lockfile; } +const char SYMEXPORT *alpm_option_get_signaturedir() +{ + if(handle == NULL) { + pm_errno = PM_ERR_HANDLE_NULL; + return NULL; + } + return handle->signaturedir; +} + int SYMEXPORT alpm_option_get_usesyslog() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return -1; } @@ -177,7 +191,7 @@ int SYMEXPORT alpm_option_get_usesyslog() alpm_list_t SYMEXPORT *alpm_option_get_noupgrades() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -186,7 +200,7 @@ alpm_list_t SYMEXPORT *alpm_option_get_noupgrades() alpm_list_t SYMEXPORT *alpm_option_get_noextracts() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -195,7 +209,7 @@ alpm_list_t SYMEXPORT *alpm_option_get_noextracts() alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -204,7 +218,7 @@ alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs() alpm_list_t SYMEXPORT *alpm_option_get_ignoregrps() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -213,7 +227,7 @@ alpm_list_t SYMEXPORT *alpm_option_get_ignoregrps() const char SYMEXPORT *alpm_option_get_arch() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -222,7 +236,7 @@ const char SYMEXPORT *alpm_option_get_arch() int SYMEXPORT alpm_option_get_usedelta() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return -1; } @@ -231,7 +245,7 @@ int SYMEXPORT alpm_option_get_usedelta() int SYMEXPORT alpm_option_get_checkspace() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return -1; } @@ -240,7 +254,7 @@ int SYMEXPORT alpm_option_get_checkspace() pmdb_t SYMEXPORT *alpm_option_get_localdb() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -249,164 +263,119 @@ pmdb_t SYMEXPORT *alpm_option_get_localdb() alpm_list_t SYMEXPORT *alpm_option_get_syncdbs() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } return handle->dbs_sync; } -void SYMEXPORT alpm_option_set_logcb(alpm_cb_log cb) +int SYMEXPORT alpm_option_set_logcb(alpm_cb_log cb) { - if (handle == NULL) { - pm_errno = PM_ERR_HANDLE_NULL; - return; - } + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->logcb = cb; + return 0; } -void SYMEXPORT alpm_option_set_dlcb(alpm_cb_download cb) +int SYMEXPORT alpm_option_set_dlcb(alpm_cb_download cb) { - if (handle == NULL) { - pm_errno = PM_ERR_HANDLE_NULL; - return; - } + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->dlcb = cb; + return 0; } -void SYMEXPORT alpm_option_set_fetchcb(alpm_cb_fetch cb) +int SYMEXPORT alpm_option_set_fetchcb(alpm_cb_fetch cb) { - if (handle == NULL) { - pm_errno = PM_ERR_HANDLE_NULL; - return; - } + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->fetchcb = cb; + return 0; } -void SYMEXPORT alpm_option_set_totaldlcb(alpm_cb_totaldl cb) +int SYMEXPORT alpm_option_set_totaldlcb(alpm_cb_totaldl cb) { - if (handle == NULL) { - pm_errno = PM_ERR_HANDLE_NULL; - return; - } + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->totaldlcb = cb; + return 0; } -int SYMEXPORT alpm_option_set_root(const char *root) -{ - struct stat st; - char *realroot; - size_t rootlen; - - ALPM_LOG_FUNC; - - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); - - if(!root) { - pm_errno = PM_ERR_WRONG_ARGS; - return(-1); - } - if(stat(root, &st) == -1 || !S_ISDIR(st.st_mode)) { - pm_errno = PM_ERR_NOT_A_DIR; - return(-1); - } +static char *canonicalize_path(const char *path) { + char *new_path; + size_t len; - realroot = calloc(PATH_MAX+1, sizeof(char)); - if(!realpath(root, realroot)) { - FREE(realroot); - pm_errno = PM_ERR_NOT_A_DIR; - return(-1); + /* verify path ends in a '/' */ + len = strlen(path); + if(path[len - 1] != '/') { + len += 1; } - - /* verify root ends in a '/' */ - rootlen = strlen(realroot); - if(realroot[rootlen-1] != '/') { - rootlen += 1; - } - if(handle->root) { - FREE(handle->root); - } - handle->root = calloc(rootlen + 1, sizeof(char)); - strncpy(handle->root, realroot, rootlen); - handle->root[rootlen-1] = '/'; - FREE(realroot); - _alpm_log(PM_LOG_DEBUG, "option 'root' = %s\n", handle->root); - return(0); + new_path = calloc(len + 1, sizeof(char)); + strncpy(new_path, path, len); + new_path[len - 1] = '/'; + return new_path; } -int SYMEXPORT alpm_option_set_dbpath(const char *dbpath) -{ +enum _pmerrno_t _alpm_set_directory_option(const char *value, + char **storage, int must_exist) + { struct stat st; - size_t dbpathlen, lockfilelen; - const char *lf = "db.lck"; + char *real = NULL; + const char *path; - ALPM_LOG_FUNC; - - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); - if(!dbpath) { - pm_errno = PM_ERR_WRONG_ARGS; - return(-1); + path = value; + if(!path) { + return PM_ERR_WRONG_ARGS; } - if(stat(dbpath, &st) == -1 || !S_ISDIR(st.st_mode)) { - pm_errno = PM_ERR_NOT_A_DIR; - return(-1); + if(must_exist) { + if(stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) { + return PM_ERR_NOT_A_DIR; + } + real = calloc(PATH_MAX + 1, sizeof(char)); + if(!realpath(path, real)) { + free(real); + return PM_ERR_NOT_A_DIR; + } + path = real; } - /* verify dbpath ends in a '/' */ - dbpathlen = strlen(dbpath); - if(dbpath[dbpathlen-1] != '/') { - dbpathlen += 1; - } - if(handle->dbpath) { - FREE(handle->dbpath); - } - handle->dbpath = calloc(dbpathlen+1, sizeof(char)); - strncpy(handle->dbpath, dbpath, dbpathlen); - handle->dbpath[dbpathlen-1] = '/'; - _alpm_log(PM_LOG_DEBUG, "option 'dbpath' = %s\n", handle->dbpath); - if(handle->lockfile) { - FREE(handle->lockfile); + if(*storage) { + FREE(*storage); } - lockfilelen = strlen(handle->dbpath) + strlen(lf) + 1; - handle->lockfile = calloc(lockfilelen, sizeof(char)); - snprintf(handle->lockfile, lockfilelen, "%s%s", handle->dbpath, lf); - _alpm_log(PM_LOG_DEBUG, "option 'lockfile' = %s\n", handle->lockfile); - return(0); + *storage = canonicalize_path(path); + free(real); + return 0; } int SYMEXPORT alpm_option_add_cachedir(const char *cachedir) { char *newcachedir; - size_t cachedirlen; - - ALPM_LOG_FUNC; ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(!cachedir) { pm_errno = PM_ERR_WRONG_ARGS; - return(-1); + return -1; } /* don't stat the cachedir yet, as it may not even be needed. we can * fail later if it is needed and the path is invalid. */ - /* verify cachedir ends in a '/' */ - cachedirlen = strlen(cachedir); - if(cachedir[cachedirlen-1] != '/') { - cachedirlen += 1; - } - newcachedir = calloc(cachedirlen + 1, sizeof(char)); - strncpy(newcachedir, cachedir, cachedirlen); - newcachedir[cachedirlen-1] = '/'; + newcachedir = canonicalize_path(cachedir); handle->cachedirs = alpm_list_add(handle->cachedirs, newcachedir); - _alpm_log(PM_LOG_DEBUG, "option 'cachedir' = %s\n", newcachedir); - return(0); + _alpm_log(PM_LOG_DEBUG, "backend option 'cachedir' = %s\n", newcachedir); + return 0; } -void SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs) +int SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); - if(handle->cachedirs) FREELIST(handle->cachedirs); - if(cachedirs) handle->cachedirs = cachedirs; + alpm_list_t *i; + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + if(handle->cachedirs) { + FREELIST(handle->cachedirs); + } + for(i = cachedirs; i; i = i->next) { + int ret = alpm_option_add_cachedir(i->data); + if(ret) { + return ret; + } + } + return 0; } int SYMEXPORT alpm_option_remove_cachedir(const char *cachedir) @@ -427,21 +396,19 @@ int SYMEXPORT alpm_option_remove_cachedir(const char *cachedir) FREE(newcachedir); if(vdata != NULL) { FREE(vdata); - return(1); + return 1; } - return(0); + return 0; } int SYMEXPORT alpm_option_set_logfile(const char *logfile) { char *oldlogfile = handle->logfile; - ALPM_LOG_FUNC; - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(!logfile) { pm_errno = PM_ERR_WRONG_ARGS; - return(-1); + return -1; } handle->logfile = strdup(logfile); @@ -456,26 +423,45 @@ int SYMEXPORT alpm_option_set_logfile(const char *logfile) handle->logstream = NULL; } _alpm_log(PM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile); - return(0); + return 0; +} + +int SYMEXPORT alpm_option_set_signaturedir(const char *signaturedir) +{ + if(!signaturedir) { + pm_errno = PM_ERR_WRONG_ARGS; + return -1; + } + + if(handle->signaturedir) { + FREE(handle->signaturedir); + } + handle->signaturedir = strdup(signaturedir); + + _alpm_log(PM_LOG_DEBUG, "option 'signaturedir' = %s\n", handle->signaturedir); + return 0; } -void SYMEXPORT alpm_option_set_usesyslog(int usesyslog) +int SYMEXPORT alpm_option_set_usesyslog(int usesyslog) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->usesyslog = usesyslog; + return 0; } -void SYMEXPORT alpm_option_add_noupgrade(const char *pkg) +int SYMEXPORT alpm_option_add_noupgrade(const char *pkg) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->noupgrade = alpm_list_add(handle->noupgrade, strdup(pkg)); + return 0; } -void SYMEXPORT alpm_option_set_noupgrades(alpm_list_t *noupgrade) +int SYMEXPORT alpm_option_set_noupgrades(alpm_list_t *noupgrade) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->noupgrade) FREELIST(handle->noupgrade); - if(noupgrade) handle->noupgrade = noupgrade; + handle->noupgrade = alpm_list_strdup(noupgrade); + return 0; } int SYMEXPORT alpm_option_remove_noupgrade(const char *pkg) @@ -485,22 +471,24 @@ int SYMEXPORT alpm_option_remove_noupgrade(const char *pkg) handle->noupgrade = alpm_list_remove_str(handle->noupgrade, pkg, &vdata); if(vdata != NULL) { FREE(vdata); - return(1); + return 1; } - return(0); + return 0; } -void SYMEXPORT alpm_option_add_noextract(const char *pkg) +int SYMEXPORT alpm_option_add_noextract(const char *pkg) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->noextract = alpm_list_add(handle->noextract, strdup(pkg)); + return 0; } -void SYMEXPORT alpm_option_set_noextracts(alpm_list_t *noextract) +int SYMEXPORT alpm_option_set_noextracts(alpm_list_t *noextract) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->noextract) FREELIST(handle->noextract); - if(noextract) handle->noextract = noextract; + handle->noextract = alpm_list_strdup(noextract); + return 0; } int SYMEXPORT alpm_option_remove_noextract(const char *pkg) @@ -510,22 +498,24 @@ int SYMEXPORT alpm_option_remove_noextract(const char *pkg) handle->noextract = alpm_list_remove_str(handle->noextract, pkg, &vdata); if(vdata != NULL) { FREE(vdata); - return(1); + return 1; } - return(0); + return 0; } -void SYMEXPORT alpm_option_add_ignorepkg(const char *pkg) +int SYMEXPORT alpm_option_add_ignorepkg(const char *pkg) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->ignorepkg = alpm_list_add(handle->ignorepkg, strdup(pkg)); + return 0; } -void SYMEXPORT alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs) +int SYMEXPORT alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->ignorepkg) FREELIST(handle->ignorepkg); - if(ignorepkgs) handle->ignorepkg = ignorepkgs; + handle->ignorepkg = alpm_list_strdup(ignorepkgs); + return 0; } int SYMEXPORT alpm_option_remove_ignorepkg(const char *pkg) @@ -535,22 +525,24 @@ int SYMEXPORT alpm_option_remove_ignorepkg(const char *pkg) handle->ignorepkg = alpm_list_remove_str(handle->ignorepkg, pkg, &vdata); if(vdata != NULL) { FREE(vdata); - return(1); + return 1; } - return(0); + return 0; } -void SYMEXPORT alpm_option_add_ignoregrp(const char *grp) +int SYMEXPORT alpm_option_add_ignoregrp(const char *grp) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->ignoregrp = alpm_list_add(handle->ignoregrp, strdup(grp)); + return 0; } -void SYMEXPORT alpm_option_set_ignoregrps(alpm_list_t *ignoregrps) +int SYMEXPORT alpm_option_set_ignoregrps(alpm_list_t *ignoregrps) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->ignoregrp) FREELIST(handle->ignoregrp); - if(ignoregrps) handle->ignoregrp = ignoregrps; + handle->ignoregrp = alpm_list_strdup(ignoregrps); + return 0; } int SYMEXPORT alpm_option_remove_ignoregrp(const char *grp) @@ -560,28 +552,49 @@ int SYMEXPORT alpm_option_remove_ignoregrp(const char *grp) handle->ignoregrp = alpm_list_remove_str(handle->ignoregrp, grp, &vdata); if(vdata != NULL) { FREE(vdata); - return(1); + return 1; } - return(0); + return 0; } -void SYMEXPORT alpm_option_set_arch(const char *arch) +int SYMEXPORT alpm_option_set_arch(const char *arch) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->arch) FREE(handle->arch); - if(arch) handle->arch = strdup(arch); + if(arch) { + handle->arch = strdup(arch); + } else { + handle->arch = NULL; + } + return 0; } -void SYMEXPORT alpm_option_set_usedelta(int usedelta) +int SYMEXPORT alpm_option_set_usedelta(int usedelta) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->usedelta = usedelta; + return 0; } -void SYMEXPORT alpm_option_set_checkspace(int checkspace) +int SYMEXPORT alpm_option_set_checkspace(int checkspace) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->checkspace = checkspace; + return 0; +} + +int SYMEXPORT alpm_option_set_default_sigverify(pgp_verify_t level) +{ + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + ASSERT(level != PM_PGP_VERIFY_UNKNOWN, RET_ERR(PM_ERR_WRONG_ARGS, -1)); + handle->sigverify = level; + return 0; +} + +pgp_verify_t SYMEXPORT alpm_option_get_default_sigverify() +{ + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, PM_PGP_VERIFY_UNKNOWN)); + return handle->sigverify; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 2d962fe6..ecfefccc 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -24,12 +24,13 @@ #include <sys/types.h> #include "alpm_list.h" -#include "db.h" -#include "log.h" #include "alpm.h" -#include "trans.h" -typedef struct _pmhandle_t { +#ifdef HAVE_LIBCURL +#include <curl/curl.h> +#endif + +struct __pmhandle_t { /* internal usage */ pmdb_t *db_local; /* local db pointer */ alpm_list_t *dbs_sync; /* List of (pmdb_t *) */ @@ -37,6 +38,12 @@ typedef struct _pmhandle_t { FILE *lckstream; /* lock file stream pointer if one exists */ pmtrans_t *trans; +#ifdef HAVE_LIBCURL + /* libcurl handle */ + CURL *curl; /* reusable curl_easy handle */ + CURLcode curlerr; /* last error produced by curl */ +#endif + /* callback functions */ alpm_cb_log logcb; /* Log callback function */ alpm_cb_download dlcb; /* Download callback function */ @@ -48,6 +55,7 @@ typedef struct _pmhandle_t { char *dbpath; /* Base path to pacman's DBs */ char *logfile; /* Name of the log file */ char *lockfile; /* Name of the lock file */ + char *signaturedir; /* Directory where GnuPG files are stored */ alpm_list_t *cachedirs; /* Paths to pacman cache directories */ /* package lists */ @@ -57,18 +65,19 @@ typedef struct _pmhandle_t { alpm_list_t *ignoregrp; /* List of groups to ignore */ /* options */ - int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */ - char *arch; /* Architecture of packages we should allow */ - int usedelta; /* Download deltas if possible */ - int checkspace; /* Check disk space before installing */ -} pmhandle_t; - -/* global handle variable */ -extern pmhandle_t *handle; + int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */ + char *arch; /* Architecture of packages we should allow */ + int usedelta; /* Download deltas if possible */ + int checkspace; /* Check disk space before installing */ + pgp_verify_t sigverify; /* Default signature verification level */ +}; pmhandle_t *_alpm_handle_new(void); void _alpm_handle_free(pmhandle_t *handle); +enum _pmerrno_t _alpm_set_directory_option(const char *value, + char **storage, int must_exist); + #endif /* _ALPM_HANDLE_H */ /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/log.c b/lib/libalpm/log.c index 09c6fb84..20d1ec37 100644 --- a/lib/libalpm/log.c +++ b/lib/libalpm/log.c @@ -22,10 +22,7 @@ #include <stdio.h> #include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> #include <errno.h> -#include <time.h> /* libalpm */ #include "log.h" @@ -33,6 +30,9 @@ #include "util.h" #include "alpm.h" +/* global handle variable */ +extern pmhandle_t *handle; + /** \addtogroup alpm_log Logging Functions * @brief Functions to log using libalpm * @{ @@ -47,8 +47,6 @@ int SYMEXPORT alpm_logaction(const char *fmt, ...) int ret; va_list args; - ALPM_LOG_FUNC; - /* Sanity checks */ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); @@ -64,7 +62,7 @@ int SYMEXPORT alpm_logaction(const char *fmt, ...) } else { pm_errno = PM_ERR_SYSTEM; } - return(-1); + return -1; } } @@ -83,7 +81,7 @@ int SYMEXPORT alpm_logaction(const char *fmt, ...) * kpacman: "KPACMAN" * This would allow us to share the log file between several frontends * and know who does what */ - return(ret); + return ret; } /** @} */ diff --git a/lib/libalpm/log.h b/lib/libalpm/log.h index 9a2961fb..1fd66a6d 100644 --- a/lib/libalpm/log.h +++ b/lib/libalpm/log.h @@ -22,13 +22,6 @@ #include "alpm.h" -#ifdef PACMAN_DEBUG -/* Log funtion entry points if debugging is enabled */ -#define ALPM_LOG_FUNC _alpm_log(PM_LOG_FUNCTION, "Enter %s\n", __func__) -#else -#define ALPM_LOG_FUNC -#endif - void _alpm_log(pmloglevel_t flag, const char *fmt, ...) __attribute__((format(printf,2,3))); #endif /* _ALPM_LOG_H */ diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index f2f15af4..d6edca1f 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -23,13 +23,9 @@ #include "config.h" -#include <stdio.h> #include <stdlib.h> #include <string.h> -#include <ctype.h> -#include <errno.h> #include <sys/types.h> -#include <sys/stat.h> /* libalpm */ #include "package.h" @@ -49,8 +45,6 @@ /** Free a package. */ int SYMEXPORT alpm_pkg_free(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); /* Only free packages loaded in user space */ @@ -58,7 +52,7 @@ int SYMEXPORT alpm_pkg_free(pmpkg_t *pkg) _alpm_pkg_free(pkg); } - return(0); + return 0; } /** Check the integrity (with md5) of a package from the sync cache. */ @@ -67,8 +61,6 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg) char *fpath; int retval; - ALPM_LOG_FUNC; - ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); /* We only inspect packages from sync repositories */ ASSERT(pkg->origin == PKG_FROM_SYNCDB, RET_ERR(PM_ERR_PKG_INVALID, -1)); @@ -78,13 +70,13 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg) retval = _alpm_test_md5sum(fpath, alpm_pkg_get_md5sum(pkg)); if(retval == 0) { - return(0); - } else if (retval == 1) { + return 0; + } else if(retval == 1) { pm_errno = PM_ERR_PKG_INVALID; retval = -1; } - return(retval); + return retval; } /* Default package accessor functions. These will get overridden by any @@ -92,8 +84,6 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg) * a lazy-load cache. However, the defaults will work just fine for fully- * populated package structures. */ static const char *_pkg_get_filename(pmpkg_t *pkg) { return pkg->filename; } -static const char *_pkg_get_name(pmpkg_t *pkg) { return pkg->name; } -static const char *_pkg_get_version(pmpkg_t *pkg) { return pkg->version; } static const char *_pkg_get_desc(pmpkg_t *pkg) { return pkg->desc; } static const char *_pkg_get_url(pmpkg_t *pkg) { return pkg->url; } static time_t _pkg_get_builddate(pmpkg_t *pkg) { return pkg->builddate; } @@ -117,17 +107,28 @@ static alpm_list_t *_pkg_get_deltas(pmpkg_t *pkg) { return pkg->deltas; } static alpm_list_t *_pkg_get_files(pmpkg_t *pkg) { return pkg->files; } static alpm_list_t *_pkg_get_backup(pmpkg_t *pkg) { return pkg->backup; } -static void *_pkg_changelog_open(pmpkg_t *pkg) { return NULL; } -static size_t _pkg_changelog_read(void *ptr, size_t size, const pmpkg_t *pkg, const void *fp) { return 0; } -static int _pkg_changelog_close(const pmpkg_t *pkg, void *fp) { return EOF; } +static void *_pkg_changelog_open(pmpkg_t UNUSED *pkg) +{ + return NULL; +} + +static size_t _pkg_changelog_read(void UNUSED *ptr, size_t UNUSED size, + const pmpkg_t UNUSED *pkg, const UNUSED void *fp) +{ + return 0; +} + +static int _pkg_changelog_close(const pmpkg_t UNUSED *pkg, + void UNUSED *fp) +{ + return EOF; +} /** The standard package operations struct. Get fields directly from the * struct itself with no abstraction layer or any type of lazy loading. */ struct pkg_operations default_pkg_ops = { .get_filename = _pkg_get_filename, - .get_name = _pkg_get_name, - .get_version = _pkg_get_version, .get_desc = _pkg_get_desc, .get_url = _pkg_get_url, .get_builddate = _pkg_get_builddate, @@ -166,12 +167,12 @@ const char SYMEXPORT *alpm_pkg_get_filename(pmpkg_t *pkg) const char SYMEXPORT *alpm_pkg_get_name(pmpkg_t *pkg) { - return pkg->ops->get_name(pkg); + return pkg->name; } const char SYMEXPORT *alpm_pkg_get_version(pmpkg_t *pkg) { - return pkg->ops->get_version(pkg); + return pkg->version; } const char SYMEXPORT *alpm_pkg_get_desc(pmpkg_t *pkg) @@ -277,10 +278,10 @@ alpm_list_t SYMEXPORT *alpm_pkg_get_backup(pmpkg_t *pkg) pmdb_t SYMEXPORT *alpm_pkg_get_db(pmpkg_t *pkg) { /* Sanity checks */ - ASSERT(pkg != NULL, return(NULL)); - ASSERT(pkg->origin != PKG_FROM_FILE, return(NULL)); + ASSERT(pkg != NULL, return NULL); + ASSERT(pkg->origin != PKG_FROM_FILE, return NULL); - return(pkg->origin_data.db); + return pkg->origin_data.db; } /** Open a package changelog for reading. */ @@ -349,14 +350,14 @@ alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(pmpkg_t *pkg) if(db->is_local) { find_requiredby(pkg, db, &reqs); } else { - for(i = handle->dbs_sync; i; i = i->next) { + for(i = pkg->handle->dbs_sync; i; i = i->next) { db = i->data; find_requiredby(pkg, db, &reqs); } reqs = alpm_list_msort(reqs, alpm_list_count(reqs), _alpm_str_cmp); } } - return(reqs); + return reqs; } /** @} */ @@ -365,11 +366,9 @@ pmpkg_t *_alpm_pkg_new(void) { pmpkg_t* pkg; - ALPM_LOG_FUNC; - CALLOC(pkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL)); - return(pkg); + return pkg; } pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg) @@ -377,8 +376,6 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg) pmpkg_t *newpkg; alpm_list_t *i; - ALPM_LOG_FUNC; - CALLOC(newpkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL)); newpkg->name_hash = pkg->name_hash; @@ -411,22 +408,21 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg) newpkg->deltas = alpm_list_copy_data(pkg->deltas, sizeof(pmdelta_t)); /* internal */ + newpkg->infolevel = pkg->infolevel; newpkg->origin = pkg->origin; - newpkg->ops = pkg->ops; if(newpkg->origin == PKG_FROM_FILE) { newpkg->origin_data.file = strdup(pkg->origin_data.file); } else { newpkg->origin_data.db = pkg->origin_data.db; } - newpkg->infolevel = pkg->infolevel; + newpkg->ops = pkg->ops; + newpkg->handle = pkg->handle; - return(newpkg); + return newpkg; } void _alpm_pkg_free(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - if(pkg == NULL) { return; } @@ -438,6 +434,7 @@ void _alpm_pkg_free(pmpkg_t *pkg) FREE(pkg->url); FREE(pkg->packager); FREE(pkg->md5sum); + FREE(pkg->base64_sig); FREE(pkg->arch); FREELIST(pkg->licenses); FREELIST(pkg->replaces); @@ -467,8 +464,6 @@ void _alpm_pkg_free(pmpkg_t *pkg) */ void _alpm_pkg_free_trans(pmpkg_t *pkg) { - ALPM_LOG_FUNC; - if(pkg == NULL) { return; } @@ -485,8 +480,6 @@ void _alpm_pkg_free_trans(pmpkg_t *pkg) /* Is spkg an upgrade for localpkg? */ int _alpm_pkg_compare_versions(pmpkg_t *spkg, pmpkg_t *localpkg) { - ALPM_LOG_FUNC; - return alpm_pkg_vercmp(alpm_pkg_get_version(spkg), alpm_pkg_get_version(localpkg)); } @@ -497,7 +490,7 @@ int _alpm_pkg_cmp(const void *p1, const void *p2) { pmpkg_t *pkg1 = (pmpkg_t *)p1; pmpkg_t *pkg2 = (pmpkg_t *)p2; - return(strcoll(pkg1->name, pkg2->name)); + return strcoll(pkg1->name, pkg2->name); } /* Test for existence of a package in a alpm_list_t* @@ -508,10 +501,8 @@ pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle) alpm_list_t *lp; unsigned long needle_hash; - ALPM_LOG_FUNC; - if(needle == NULL || haystack == NULL) { - return(NULL); + return NULL; } needle_hash = _alpm_hash_sdbm(needle); @@ -527,11 +518,11 @@ pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle) /* finally: we had hash match, verify string match */ if(strcmp(info->name, needle) == 0) { - return(info); + return info; } } } - return(NULL); + return NULL; } /** Test if a package should be ignored. @@ -548,19 +539,19 @@ int _alpm_pkg_should_ignore(pmpkg_t *pkg) alpm_list_t *groups = NULL; /* first see if the package is ignored */ - if(alpm_list_find_str(handle->ignorepkg, alpm_pkg_get_name(pkg))) { - return(1); + if(alpm_list_find_str(pkg->handle->ignorepkg, alpm_pkg_get_name(pkg))) { + return 1; } /* next see if the package is in a group that is ignored */ - for(groups = handle->ignoregrp; groups; groups = alpm_list_next(groups)) { + for(groups = pkg->handle->ignoregrp; groups; groups = alpm_list_next(groups)) { char *grp = (char *)alpm_list_getdata(groups); if(alpm_list_find_str(alpm_pkg_get_groups(pkg), grp)) { - return(1); + return 1; } } - return(0); + return 0; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h index b161d5f1..4e2dcf3d 100644 --- a/lib/libalpm/package.h +++ b/lib/libalpm/package.h @@ -24,11 +24,14 @@ #ifndef _ALPM_PACKAGE_H #define _ALPM_PACKAGE_H +#include "config.h" /* ensure off_t is correct length */ + #include <sys/types.h> /* off_t */ #include <time.h> /* time_t */ #include "alpm.h" #include "db.h" +#include "signing.h" typedef enum _pmpkgfrom_t { PKG_FROM_FILE = 1, @@ -45,8 +48,6 @@ typedef enum _pmpkgfrom_t { */ struct pkg_operations { const char *(*get_filename) (pmpkg_t *); - const char *(*get_name) (pmpkg_t *); - const char *(*get_version) (pmpkg_t *); const char *(*get_desc) (pmpkg_t *); const char *(*get_url) (pmpkg_t *); time_t (*get_builddate) (pmpkg_t *); @@ -96,6 +97,7 @@ struct __pmpkg_t { char *url; char *packager; char *md5sum; + char *base64_sig; char *arch; time_t builddate; @@ -108,6 +110,7 @@ struct __pmpkg_t { int scriptlet; pmpkgreason_t reason; + pmdbinfrq_t infolevel; pmpkgfrom_t origin; /* origin == PKG_FROM_FILE, use pkg->origin_data.file * origin == PKG_FROM_*DB, use pkg->origin_data.db */ @@ -115,7 +118,7 @@ struct __pmpkg_t { pmdb_t *db; char *file; } origin_data; - pmdbinfrq_t infolevel; + pmhandle_t *handle; alpm_list_t *licenses; alpm_list_t *replaces; @@ -137,6 +140,10 @@ pmpkg_t* _alpm_pkg_new(void); pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg); void _alpm_pkg_free(pmpkg_t *pkg); void _alpm_pkg_free_trans(pmpkg_t *pkg); + +pmpkg_t *_alpm_pkg_load_internal(const char *filename, int full, + const char *md5sum, const char *base64_sig, pgp_verify_t check_sig); + int _alpm_pkg_cmp(const void *p1, const void *p2); int _alpm_pkg_compare_versions(pmpkg_t *local_pkg, pmpkg_t *pkg); pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle); diff --git a/lib/libalpm/pkghash.c b/lib/libalpm/pkghash.c index 6dc43243..7e5e1fce 100644 --- a/lib/libalpm/pkghash.c +++ b/lib/libalpm/pkghash.c @@ -72,13 +72,13 @@ pmpkghash_t *_alpm_pkghash_create(size_t size) if(hash->buckets < size) { _alpm_log(PM_LOG_ERROR, _("database larger than maximum size\n")); free(hash); - return(NULL); + return NULL; } - CALLOC(hash->hash_table, hash->buckets, sizeof(alpm_list_t*), \ + CALLOC(hash->hash_table, hash->buckets, sizeof(alpm_list_t *), \ free(hash); RET_ERR(PM_ERR_MEMORY, NULL)); - return(hash); + return hash; } static size_t get_hash_position(unsigned long name_hash, pmpkghash_t *hash) @@ -92,7 +92,7 @@ static size_t get_hash_position(unsigned long name_hash, pmpkghash_t *hash) position = (position + 1) % hash->buckets; } - return(position); + return position; } /* Expand the hash table size to the next increment and rebin the entries */ @@ -123,7 +123,7 @@ static pmpkghash_t *rehash(pmpkghash_t *oldhash) newhash = _alpm_pkghash_create(newsize); if(newhash == NULL) { /* creation of newhash failed, stick with old one... */ - return(oldhash); + return oldhash; } newhash->list = oldhash->list; @@ -144,7 +144,7 @@ static pmpkghash_t *rehash(pmpkghash_t *oldhash) _alpm_pkghash_free(oldhash); - return(newhash); + return newhash; } static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted) @@ -153,7 +153,7 @@ static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted) size_t position; if(pkg == NULL || hash == NULL) { - return(hash); + return hash; } if((hash->entries + 1) / MAX_HASH_LOAD > hash->buckets) { @@ -164,7 +164,7 @@ static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted) ptr = calloc(1, sizeof(alpm_list_t)); if(ptr == NULL) { - return(hash); + return hash; } ptr->data = pkg; @@ -179,17 +179,17 @@ static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted) } hash->entries += 1; - return(hash); + return hash; } pmpkghash_t *_alpm_pkghash_add(pmpkghash_t *hash, pmpkg_t *pkg) { - return(pkghash_add_pkg(hash, pkg, 0)); + return pkghash_add_pkg(hash, pkg, 0); } pmpkghash_t *_alpm_pkghash_add_sorted(pmpkghash_t *hash, pmpkg_t *pkg) { - return(pkghash_add_pkg(hash, pkg, 1)); + return pkghash_add_pkg(hash, pkg, 1); } static size_t move_one_entry(pmpkghash_t *hash, size_t start, size_t end) @@ -217,7 +217,7 @@ static size_t move_one_entry(pmpkghash_t *hash, size_t start, size_t end) * e.g. (47 + 0 - 1) % 47 == 46 */ end = (hash->buckets + end - 1) % hash->buckets; } - return(end); + return end; } /** @@ -240,7 +240,7 @@ pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg, } if(pkg == NULL || hash == NULL) { - return(hash); + return hash; } position = pkg->name_hash % hash->buckets; @@ -277,13 +277,13 @@ pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg, position = prev; } - return(hash); + return hash; } position = (position + 1) % hash->buckets; } - return(hash); + return hash; } void _alpm_pkghash_free(pmpkghash_t *hash) @@ -304,10 +304,8 @@ pmpkg_t *_alpm_pkghash_find(pmpkghash_t *hash, const char *name) unsigned long name_hash; size_t position; - ALPM_LOG_FUNC; - if(name == NULL || hash == NULL) { - return(NULL); + return NULL; } name_hash = _alpm_hash_sdbm(name); @@ -318,13 +316,13 @@ pmpkg_t *_alpm_pkghash_find(pmpkghash_t *hash, const char *name) pmpkg_t *info = lp->data; if(info->name_hash == name_hash && strcmp(info->name, name) == 0) { - return(info); + return info; } position = (position + 1) % hash->buckets; } - return(NULL); + return NULL; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index 22ae2bb8..27305ae3 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -26,8 +26,6 @@ #include <stdlib.h> #include <errno.h> -#include <time.h> -#include <fcntl.h> #include <string.h> #include <limits.h> #include <unistd.h> @@ -36,6 +34,7 @@ /* libalpm */ #include "remove.h" #include "alpm_list.h" +#include "alpm.h" #include "trans.h" #include "util.h" #include "log.h" @@ -44,39 +43,34 @@ #include "db.h" #include "deps.h" #include "handle.h" -#include "alpm.h" int SYMEXPORT alpm_remove_pkg(pmpkg_t *pkg) { pmtrans_t *trans; const char *pkgname; - ALPM_LOG_FUNC; - /* Sanity checks */ ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); - trans = handle->trans; + trans = pkg->handle->trans; ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1)); - pkgname = alpm_pkg_get_name(pkg); + pkgname = pkg->name; if(_alpm_pkg_find(trans->remove, pkgname)) { RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1); } - _alpm_log(PM_LOG_DEBUG, "adding %s in the target list\n", pkgname); + _alpm_log(PM_LOG_DEBUG, "adding package %s to the transaction remove list\n", + pkgname); trans->remove = alpm_list_add(trans->remove, _alpm_pkg_dup(pkg)); - return(0); + return 0; } static void remove_prepare_cascade(pmtrans_t *trans, pmdb_t *db, alpm_list_t *lp) { - ALPM_LOG_FUNC; - while(lp) { alpm_list_t *i; for(i = lp; i; i = i->next) { @@ -102,8 +96,6 @@ static void remove_prepare_cascade(pmtrans_t *trans, pmdb_t *db, static void remove_prepare_keep_needed(pmtrans_t *trans, pmdb_t *db, alpm_list_t *lp) { - ALPM_LOG_FUNC; - /* Remove needed packages (which break dependencies) from target list */ while(lp != NULL) { alpm_list_t *i; @@ -133,18 +125,14 @@ static void remove_prepare_keep_needed(pmtrans_t *trans, pmdb_t *db, * This functions takes a pointer to a alpm_list_t which will be * filled with a list of pmdepmissing_t* objects representing * the packages blocking the transaction. - * @param trans the transaction object - * @param db the database of local packages + * @param handle the context handle * @param data a pointer to an alpm_list_t* to fill */ -int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) +int _alpm_remove_prepare(pmhandle_t *handle, alpm_list_t **data) { alpm_list_t *lp; - - ALPM_LOG_FUNC; - - ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); - ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); + pmtrans_t *trans = handle->trans; + pmdb_t *db = handle->db_local; if((trans->flags & PM_TRANS_FLAG_RECURSE) && !(trans->flags & PM_TRANS_FLAG_CASCADE)) { _alpm_log(PM_LOG_DEBUG, "finding removable dependencies\n"); @@ -160,7 +148,7 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) if(trans->flags & PM_TRANS_FLAG_CASCADE) { remove_prepare_cascade(trans, db, lp); - } else if (trans->flags & PM_TRANS_FLAG_UNNEEDED) { + } else if(trans->flags & PM_TRANS_FLAG_UNNEEDED) { /* Remove needed packages (which would break dependencies) * from target list */ remove_prepare_keep_needed(trans, db, lp); @@ -193,10 +181,10 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL); } - return(0); + return 0; } -static int can_remove_file(const char *path, alpm_list_t *skip) +static int can_remove_file(pmhandle_t *handle, const char *path, alpm_list_t *skip) { char file[PATH_MAX+1]; @@ -204,7 +192,7 @@ static int can_remove_file(const char *path, alpm_list_t *skip) if(alpm_list_find_str(skip, file)) { /* return success because we will never actually remove this file */ - return(1); + return 1; } /* If we fail write permissions due to a read-only filesystem, abort. * Assume all other possible failures are covered somewhere else */ @@ -214,22 +202,21 @@ static int can_remove_file(const char *path, alpm_list_t *skip) * it - ignore "chmod -w" simple permission failures */ _alpm_log(PM_LOG_ERROR, _("cannot remove file '%s': %s\n"), file, strerror(errno)); - return(0); + return 0; } } - return(1); + return 1; } /* Helper function for iterating through a package's file and deleting them * Used by _alpm_remove_commit. */ -static void unlink_file(pmpkg_t *info, char *filename, alpm_list_t *skip_remove, int nosave) +static void unlink_file(pmhandle_t *handle, pmpkg_t *info, char *filename, + alpm_list_t *skip_remove, int nosave) { struct stat buf; char file[PATH_MAX+1]; - ALPM_LOG_FUNC; - snprintf(file, PATH_MAX, "%s%s", handle->root, filename); /* check the remove skip list before removing the file. @@ -289,8 +276,8 @@ static void unlink_file(pmpkg_t *info, char *filename, alpm_list_t *skip_remove, } } -int _alpm_upgraderemove_package(pmpkg_t *oldpkg, pmpkg_t *newpkg, - pmtrans_t *trans) +int _alpm_upgraderemove_package(pmhandle_t *handle, + pmpkg_t *oldpkg, pmpkg_t *newpkg) { alpm_list_t *skip_remove, *b; alpm_list_t *newfiles, *lp; @@ -298,18 +285,16 @@ int _alpm_upgraderemove_package(pmpkg_t *oldpkg, pmpkg_t *newpkg, alpm_list_t *files = alpm_pkg_get_files(oldpkg); const char *pkgname = alpm_pkg_get_name(oldpkg); - ALPM_LOG_FUNC; - _alpm_log(PM_LOG_DEBUG, "removing old package first (%s-%s)\n", oldpkg->name, oldpkg->version); - if(trans->flags & PM_TRANS_FLAG_DBONLY) { + if(handle->trans->flags & PM_TRANS_FLAG_DBONLY) { goto db; } /* copy the remove skiplist over */ skip_remove = alpm_list_join( - alpm_list_strdup(trans->skip_remove), + alpm_list_strdup(handle->trans->skip_remove), alpm_list_strdup(handle->noupgrade)); /* Add files in the NEW backup array to the skip_remove array * so this removal operation doesn't kill them */ @@ -327,7 +312,7 @@ int _alpm_upgraderemove_package(pmpkg_t *oldpkg, pmpkg_t *newpkg, } for(lp = files; lp; lp = lp->next) { - if(!can_remove_file(lp->data, skip_remove)) { + if(!can_remove_file(handle, lp->data, skip_remove)) { _alpm_log(PM_LOG_DEBUG, "not removing package '%s', can't remove all files\n", pkgname); RET_ERR(PM_ERR_PKG_CANT_REMOVE, -1); @@ -340,7 +325,7 @@ int _alpm_upgraderemove_package(pmpkg_t *oldpkg, pmpkg_t *newpkg, /* iterate through the list backwards, unlinking files */ newfiles = alpm_list_reverse(files); for(lp = newfiles; lp; lp = alpm_list_next(lp)) { - unlink_file(oldpkg, lp->data, skip_remove, 0); + unlink_file(handle, oldpkg, lp->data, skip_remove, 0); } alpm_list_free(newfiles); FREELIST(skip_remove); @@ -359,37 +344,33 @@ db: pkgname); } - return(0); + return 0; } -int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db) +int _alpm_remove_packages(pmhandle_t *handle) { pmpkg_t *info; alpm_list_t *targ, *lp; size_t pkg_count; - - ALPM_LOG_FUNC; - - ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); - ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); + pmtrans_t *trans = handle->trans; pkg_count = alpm_list_count(trans->remove); for(targ = trans->remove; targ; targ = targ->next) { int position = 0; char scriptlet[PATH_MAX]; - info = (pmpkg_t*)targ->data; + info = (pmpkg_t *)targ->data; const char *pkgname = NULL; size_t targcount = alpm_list_count(targ); - if(handle->trans->state == STATE_INTERRUPTED) { - return(0); + if(trans->state == STATE_INTERRUPTED) { + return 0; } /* get the name now so we can use it after package is removed */ pkgname = alpm_pkg_get_name(info); snprintf(scriptlet, PATH_MAX, "%s%s-%s/install", - _alpm_db_path(db), pkgname, alpm_pkg_get_version(info)); + _alpm_db_path(handle->db_local), pkgname, alpm_pkg_get_version(info)); EVENT(trans, PM_TRANS_EVT_REMOVE_START, info, NULL); _alpm_log(PM_LOG_DEBUG, "removing package %s-%s\n", @@ -397,8 +378,8 @@ int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db) /* run the pre-remove scriptlet if it exists */ if(alpm_pkg_has_scriptlet(info) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { - _alpm_runscriptlet(handle->root, scriptlet, "pre_remove", - alpm_pkg_get_version(info), NULL, trans); + _alpm_runscriptlet(handle, scriptlet, "pre_remove", + alpm_pkg_get_version(info), NULL); } if(!(trans->flags & PM_TRANS_FLAG_DBONLY)) { @@ -407,7 +388,7 @@ int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db) size_t filenum; for(lp = files; lp; lp = lp->next) { - if(!can_remove_file(lp->data, NULL)) { + if(!can_remove_file(handle, lp->data, NULL)) { _alpm_log(PM_LOG_DEBUG, "not removing package '%s', can't remove all files\n", pkgname); RET_ERR(PM_ERR_PKG_CANT_REMOVE, -1); @@ -425,7 +406,7 @@ int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db) newfiles = alpm_list_reverse(files); for(lp = newfiles; lp; lp = alpm_list_next(lp)) { int percent; - unlink_file(info, lp->data, NULL, trans->flags & PM_TRANS_FLAG_NOSAVE); + unlink_file(handle, info, lp->data, NULL, trans->flags & PM_TRANS_FLAG_NOSAVE); /* update progress bar after each file */ percent = (position * 100) / filenum; @@ -442,19 +423,19 @@ int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db) /* run the post-remove script if it exists */ if(alpm_pkg_has_scriptlet(info) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { - _alpm_runscriptlet(handle->root, scriptlet, "post_remove", - alpm_pkg_get_version(info), NULL, trans); + _alpm_runscriptlet(handle, scriptlet, "post_remove", + alpm_pkg_get_version(info), NULL); } /* remove the package from the database */ _alpm_log(PM_LOG_DEBUG, "updating database\n"); _alpm_log(PM_LOG_DEBUG, "removing database entry '%s'\n", pkgname); - if(_alpm_local_db_remove(db, info) == -1) { + if(_alpm_local_db_remove(handle->db_local, info) == -1) { _alpm_log(PM_LOG_ERROR, _("could not remove database entry %s-%s\n"), pkgname, alpm_pkg_get_version(info)); } /* remove the package from the cache */ - if(_alpm_db_remove_pkgfromcache(db, info) == -1) { + if(_alpm_db_remove_pkgfromcache(handle->db_local, info) == -1) { _alpm_log(PM_LOG_ERROR, _("could not remove entry '%s' from cache\n"), pkgname); } @@ -463,9 +444,9 @@ int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db) } /* run ldconfig if it exists */ - _alpm_ldconfig(handle->root); + _alpm_ldconfig(handle); - return(0); + return 0; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/remove.h b/lib/libalpm/remove.h index a67e37a1..5cab526a 100644 --- a/lib/libalpm/remove.h +++ b/lib/libalpm/remove.h @@ -24,10 +24,11 @@ #include "alpm_list.h" #include "trans.h" -int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data); -int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db); +int _alpm_remove_prepare(pmhandle_t *handle, alpm_list_t **data); +int _alpm_remove_packages(pmhandle_t *handle); -int _alpm_upgraderemove_package(pmpkg_t *oldpkg, pmpkg_t *newpkg, pmtrans_t *trans); +int _alpm_upgraderemove_package(pmhandle_t *handle, + pmpkg_t *oldpkg, pmpkg_t *newpkg); #endif /* _ALPM_REMOVE_H */ diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c new file mode 100644 index 00000000..f6a5a1ae --- /dev/null +++ b/lib/libalpm/signing.c @@ -0,0 +1,403 @@ +/* + * signing.c + * + * Copyright (c) 2008-2011 Pacman Development Team <pacman-dev@archlinux.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#if HAVE_LIBGPGME +#include <locale.h> /* setlocale() */ +#include <gpgme.h> +#include "base64.h" +#endif + +/* libalpm */ +#include "signing.h" +#include "package.h" +#include "util.h" +#include "log.h" +#include "alpm.h" + +#if HAVE_LIBGPGME +#define CHECK_ERR(void) do { \ + if(err != GPG_ERR_NO_ERROR) { goto error; } \ + } while(0) + +static const char *gpgme_string_validity(gpgme_validity_t validity) +{ + switch(validity) { + case GPGME_VALIDITY_UNKNOWN: + return "unknown"; + case GPGME_VALIDITY_UNDEFINED: + return "undefined"; + case GPGME_VALIDITY_NEVER: + return "never"; + case GPGME_VALIDITY_MARGINAL: + return "marginal"; + case GPGME_VALIDITY_FULL: + return "full"; + case GPGME_VALIDITY_ULTIMATE: + return "ultimate"; + } + return "???"; +} + +static alpm_list_t *sigsum_test_bit(gpgme_sigsum_t sigsum, alpm_list_t *summary, + gpgme_sigsum_t bit, const char *value) +{ + if(sigsum & bit) { + summary = alpm_list_add(summary, (void *)value); + } + return summary; +} + +static alpm_list_t *gpgme_list_sigsum(gpgme_sigsum_t sigsum) +{ + alpm_list_t *summary = NULL; + /* The docs say this can be a bitmask...not sure I believe it, but we'll code + * for it anyway and show all possible flags in the returned string. */ + + /* The signature is fully valid. */ + summary = sigsum_test_bit(sigsum, summary, GPGME_SIGSUM_VALID, "valid"); + /* The signature is good. */ + summary = sigsum_test_bit(sigsum, summary, GPGME_SIGSUM_GREEN, "green"); + /* The signature is bad. */ + summary = sigsum_test_bit(sigsum, summary, GPGME_SIGSUM_RED, "red"); + /* One key has been revoked. */ + summary = sigsum_test_bit(sigsum, summary, GPGME_SIGSUM_KEY_REVOKED, "key revoked"); + /* One key has expired. */ + summary = sigsum_test_bit(sigsum, summary, GPGME_SIGSUM_KEY_EXPIRED, "key expired"); + /* The signature has expired. */ + summary = sigsum_test_bit(sigsum, summary, GPGME_SIGSUM_SIG_EXPIRED, "sig expired"); + /* Can't verify: key missing. */ + summary = sigsum_test_bit(sigsum, summary, GPGME_SIGSUM_KEY_MISSING, "key missing"); + /* CRL not available. */ + summary = sigsum_test_bit(sigsum, summary, GPGME_SIGSUM_CRL_MISSING, "crl missing"); + /* Available CRL is too old. */ + summary = sigsum_test_bit(sigsum, summary, GPGME_SIGSUM_CRL_TOO_OLD, "crl too old"); + /* A policy was not met. */ + summary = sigsum_test_bit(sigsum, summary, GPGME_SIGSUM_BAD_POLICY, "bad policy"); + /* A system error occured. */ + summary = sigsum_test_bit(sigsum, summary, GPGME_SIGSUM_SYS_ERROR, "sys error"); + /* Fallback case */ + if(!sigsum) { + summary = alpm_list_add(summary, (void *)"(empty)"); + } + return summary; +} + +static int gpgme_init(void) +{ + static int init = 0; + const char *version; + gpgme_error_t err; + gpgme_engine_info_t enginfo; + + if(init) { + /* we already successfully initialized the library */ + return 0; + } + + if(!alpm_option_get_signaturedir()) { + RET_ERR(PM_ERR_SIG_MISSINGDIR, 1); + } + + /* calling gpgme_check_version() returns the current version and runs + * some internal library setup code */ + version = gpgme_check_version(NULL); + _alpm_log(PM_LOG_DEBUG, "GPGME version: %s\n", version); + gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); +#ifdef LC_MESSAGES + gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL)); +#endif + /* NOTE: + * The GPGME library installs a SIGPIPE signal handler automatically if + * the default signal hander is in use. The only time we set a handler + * for SIGPIPE is in dload.c, and we reset it when we are done. Given that + * we do this, we can let GPGME do its automagic. However, if we install + * a library-wide SIGPIPE handler, we will have to be careful. + */ + + /* check for OpenPGP support (should be a no-brainer, but be safe) */ + err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); + CHECK_ERR(); + + /* set and check engine information */ + err = gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, NULL, + alpm_option_get_signaturedir()); + CHECK_ERR(); + err = gpgme_get_engine_info(&enginfo); + CHECK_ERR(); + _alpm_log(PM_LOG_DEBUG, "GPGME engine info: file=%s, home=%s\n", + enginfo->file_name, enginfo->home_dir); + + init = 1; + return 0; + +error: + _alpm_log(PM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err)); + RET_ERR(PM_ERR_GPGME, 1); +} + +/** + * Decode a loaded signature in base64 form. + * @param base64_data the signature to attempt to decode + * @param data the decoded data; must be freed by the caller + * @param data_len the length of the returned data + * @return 0 on success, 1 on failure to properly decode + */ +static int decode_signature(const char *base64_data, + unsigned char **data, int *data_len) { + unsigned char *usline; + int len; + + len = strlen(base64_data); + usline = (unsigned char *)base64_data; + int ret, destlen = 0; + /* get the necessary size for the buffer by passing 0 */ + ret = base64_decode(NULL, &destlen, usline, len); + if(ret != 0 && ret != POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL) { + goto error; + } + /* alloc our memory and repeat the call to decode */ + MALLOC(*data, (size_t)destlen, goto error); + ret = base64_decode(*data, &destlen, usline, len); + if(ret != 0) { + goto error; + } + *data_len = destlen; + return 0; + +error: + *data = NULL; + *data_len = 0; + return 1; +} + +/** + * Check the PGP signature for the given file. + * @param path the full path to a file + * @param base64_sig PGP signature data in base64 encoding; if NULL, expect a + * signature file next to 'path' + * @return a int value : 0 (valid), 1 (invalid), -1 (an error occured) + */ +int _alpm_gpgme_checksig(const char *path, const char *base64_sig) +{ + int ret = 0; + gpgme_error_t err; + gpgme_ctx_t ctx; + gpgme_data_t filedata, sigdata; + gpgme_verify_result_t result; + gpgme_signature_t gpgsig; + char *sigpath = NULL; + unsigned char *decoded_sigdata = NULL; + FILE *file = NULL, *sigfile = NULL; + + if(!path || access(path, R_OK) != 0) { + RET_ERR(PM_ERR_NOT_A_FILE, -1); + } + + if(!base64_sig) { + size_t len = strlen(path) + 5; + CALLOC(sigpath, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1)); + snprintf(sigpath, len, "%s.sig", path); + + if(!access(sigpath, R_OK) == 0) { + FREE(sigpath); + RET_ERR(PM_ERR_SIG_UNKNOWN, -1); + } + } + + if(gpgme_init()) { + /* pm_errno was set in gpgme_init() */ + return -1; + } + + _alpm_log(PM_LOG_DEBUG, "checking signature for %s\n", path); + + memset(&ctx, 0, sizeof(ctx)); + memset(&sigdata, 0, sizeof(sigdata)); + memset(&filedata, 0, sizeof(filedata)); + + err = gpgme_new(&ctx); + CHECK_ERR(); + + /* create our necessary data objects to verify the signature */ + file = fopen(path, "rb"); + if(file == NULL) { + pm_errno = PM_ERR_NOT_A_FILE; + ret = -1; + goto error; + } + err = gpgme_data_new_from_stream(&filedata, file); + CHECK_ERR(); + + /* next create data object for the signature */ + if(base64_sig) { + /* memory-based, we loaded it from a sync DB */ + int data_len; + int decode_ret = decode_signature(base64_sig, + &decoded_sigdata, &data_len); + if(decode_ret) { + ret = -1; + goto error; + } + err = gpgme_data_new_from_mem(&sigdata, + (char *)decoded_sigdata, data_len, 0); + } else { + /* file-based, it is on disk */ + sigfile = fopen(sigpath, "rb"); + if(sigfile == NULL) { + pm_errno = PM_ERR_NOT_A_FILE; + ret = -1; + goto error; + } + err = gpgme_data_new_from_stream(&sigdata, sigfile); + } + CHECK_ERR(); + + /* here's where the magic happens */ + err = gpgme_op_verify(ctx, sigdata, filedata, NULL); + CHECK_ERR(); + result = gpgme_op_verify_result(ctx); + gpgsig = result->signatures; + if(!gpgsig || gpgsig->next) { + int count = 0; + while(gpgsig) { + count++; + gpgsig = gpgsig->next; + } + _alpm_log(PM_LOG_ERROR, _("Unexpected number of signatures (%d)\n"), + count); + ret = -1; + goto error; + } + + { + alpm_list_t *summary_list, *summary; + + _alpm_log(PM_LOG_DEBUG, "fingerprint: %s\n", gpgsig->fpr); + summary_list = gpgme_list_sigsum(gpgsig->summary); + for(summary = summary_list; summary; summary = summary->next) { + _alpm_log(PM_LOG_DEBUG, "summary: %s\n", (const char *)summary->data); + } + alpm_list_free(summary_list); + _alpm_log(PM_LOG_DEBUG, "status: %s\n", gpgme_strerror(gpgsig->status)); + _alpm_log(PM_LOG_DEBUG, "timestamp: %lu\n", gpgsig->timestamp); + _alpm_log(PM_LOG_DEBUG, "exp_timestamp: %lu\n", gpgsig->exp_timestamp); + _alpm_log(PM_LOG_DEBUG, "validity: %s\n", + gpgme_string_validity(gpgsig->validity)); + _alpm_log(PM_LOG_DEBUG, "validity_reason: %s\n", + gpgme_strerror(gpgsig->validity_reason)); + _alpm_log(PM_LOG_DEBUG, "pubkey algo: %s\n", + gpgme_pubkey_algo_name(gpgsig->pubkey_algo)); + _alpm_log(PM_LOG_DEBUG, "hash algo: %s\n", + gpgme_hash_algo_name(gpgsig->hash_algo)); + } + + if(gpgsig->summary & GPGME_SIGSUM_VALID) { + /* good signature, continue */ + _alpm_log(PM_LOG_DEBUG, _("File %s has a valid signature.\n"), + path); + } else if(gpgsig->summary & GPGME_SIGSUM_GREEN) { + /* 'green' signature, not sure what to do here */ + _alpm_log(PM_LOG_WARNING, _("File %s has a green signature.\n"), + path); + } else if(gpgsig->summary & GPGME_SIGSUM_KEY_MISSING) { + pm_errno = PM_ERR_SIG_UNKNOWN; + _alpm_log(PM_LOG_WARNING, _("File %s has a signature from an unknown key.\n"), + path); + ret = -1; + } else { + /* we'll capture everything else here */ + pm_errno = PM_ERR_SIG_INVALID; + _alpm_log(PM_LOG_ERROR, _("File %s has an invalid signature.\n"), + path); + ret = 1; + } + +error: + gpgme_data_release(sigdata); + gpgme_data_release(filedata); + gpgme_release(ctx); + if(sigfile) { + fclose(sigfile); + } + if(file) { + fclose(file); + } + FREE(sigpath); + FREE(decoded_sigdata); + if(err != GPG_ERR_NO_ERROR) { + _alpm_log(PM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err)); + RET_ERR(PM_ERR_GPGME, -1); + } + return ret; +} +#else +int _alpm_gpgme_checksig(const char *path, const char *base64_sig) +{ + return -1; +} +#endif + +/** + * Determines the necessity of checking for a valid PGP signature + * @param db the sync database to query + * + * @return signature verification level + */ +pgp_verify_t _alpm_db_get_sigverify_level(pmdb_t *db) +{ + ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, PM_PGP_VERIFY_UNKNOWN)); + + if(db->pgp_verify != PM_PGP_VERIFY_UNKNOWN) { + return db->pgp_verify; + } else { + return alpm_option_get_default_sigverify(); + } +} + +/** + * Check the PGP signature for the given package file. + * @param pkg the package to check + * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred) + */ +int SYMEXPORT alpm_pkg_check_pgp_signature(pmpkg_t *pkg) +{ + ASSERT(pkg != NULL, return 0); + + return _alpm_gpgme_checksig(alpm_pkg_get_filename(pkg), pkg->base64_sig); +} + +/** + * Check the PGP signature for the given database. + * @param db the database to check + * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred) + */ +int SYMEXPORT alpm_db_check_pgp_signature(pmdb_t *db) +{ + ASSERT(db != NULL, return 0); + + return _alpm_gpgme_checksig(_alpm_db_path(db), NULL); +} + +/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/signing.h b/lib/libalpm/signing.h new file mode 100644 index 00000000..8d8c1643 --- /dev/null +++ b/lib/libalpm/signing.h @@ -0,0 +1,29 @@ +/* + * signing.h + * + * Copyright (c) 2008-2011 Pacman Development Team <pacman-dev@archlinux.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef _ALPM_SIGNING_H +#define _ALPM_SIGNING_H + +#include "alpm.h" + +int _alpm_gpgme_checksig(const char *path, const char *base64_sig); +pgp_verify_t _alpm_db_get_sigverify_level(pmdb_t *db); + +#endif /* _ALPM_SIGNING_H */ + +/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index f83b0ef9..7a33bc97 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -26,11 +26,9 @@ #include <sys/types.h> /* off_t */ #include <stdlib.h> #include <stdio.h> -#include <fcntl.h> #include <string.h> #include <stdint.h> /* intmax_t */ #include <unistd.h> -#include <time.h> #include <limits.h> /* libalpm */ @@ -50,13 +48,17 @@ #include "delta.h" #include "remove.h" #include "diskspace.h" +#include "signing.h" + +/* global handle variable */ +extern pmhandle_t *handle; /** Check for new version of pkg in sync repos * (only the first occurrence is considered in sync) */ pmpkg_t SYMEXPORT *alpm_sync_newversion(pmpkg_t *pkg, alpm_list_t *dbs_sync) { - ASSERT(pkg != NULL, return(NULL)); + ASSERT(pkg != NULL, return NULL); alpm_list_t *i; pmpkg_t *spkg = NULL; @@ -68,7 +70,7 @@ pmpkg_t SYMEXPORT *alpm_sync_newversion(pmpkg_t *pkg, alpm_list_t *dbs_sync) if(spkg == NULL) { _alpm_log(PM_LOG_DEBUG, "'%s' not found in sync db => no upgrade\n", alpm_pkg_get_name(pkg)); - return(NULL); + return NULL; } /* compare versions and see if spkg is an upgrade */ @@ -76,15 +78,13 @@ pmpkg_t SYMEXPORT *alpm_sync_newversion(pmpkg_t *pkg, alpm_list_t *dbs_sync) _alpm_log(PM_LOG_DEBUG, "new version of '%s' found (%s => %s)\n", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg), alpm_pkg_get_version(spkg)); - return(spkg); + return spkg; } /* spkg is not an upgrade */ - return(NULL); + return NULL; } -/** Search for packages to upgrade and add them to the transaction. - * @return 0 on success, -1 on error (pm_errno is set accordingly) - */ +/** Search for packages to upgrade and add them to the transaction. */ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade) { alpm_list_t *i, *j, *k; @@ -92,8 +92,6 @@ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade) pmdb_t *db_local; alpm_list_t *dbs_sync; - ALPM_LOG_FUNC; - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); trans = handle->trans; db_local = handle->db_local; @@ -116,7 +114,8 @@ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade) pmdb_t *sdb = j->data; /* Check sdb */ pmpkg_t *spkg = _alpm_db_get_pkgfromcache(sdb, lpkg->name); - if(spkg) { /* 1. literal was found in sdb */ + if(spkg) { + /* 1. literal was found in sdb */ int cmp = _alpm_pkg_compare_versions(spkg, lpkg); if(cmp > 0) { _alpm_log(PM_LOG_DEBUG, "new version of '%s' found (%s => %s)\n", @@ -146,8 +145,10 @@ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade) lpkg->name, lpkg->version, sdb->treename, spkg->version); } } - break; /* jump to next local package */ - } else { /* 2. search for replacers in sdb */ + /* jump to next local package */ + break; + } else { + /* 2. search for replacers in sdb */ int found = 0; for(k = _alpm_db_get_pkgcache(sdb); k; k = k->next) { spkg = k->data; @@ -183,7 +184,8 @@ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade) if(alpm_pkg_get_reason(lpkg) == PM_PKG_REASON_EXPLICIT) { tpkg->reason = PM_PKG_REASON_EXPLICIT; } - } else { /* add spkg to the target list */ + } else { + /* add spkg to the target list */ /* copy over reason */ spkg->reason = alpm_pkg_get_reason(lpkg); spkg->removes = alpm_list_add(NULL, lpkg); @@ -200,7 +202,7 @@ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade) } } - return(0); + return 0; } /** Find group members across a list of databases. @@ -231,7 +233,7 @@ alpm_list_t SYMEXPORT *alpm_find_grp_pkgs(alpm_list_t *dbs, if(_alpm_pkg_should_ignore(pkg)) { ignorelist = alpm_list_add(ignorelist, pkg); int install = 0; - QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, + QUESTION(db->handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, NULL, NULL, &install); if(!install) continue; @@ -242,7 +244,7 @@ alpm_list_t SYMEXPORT *alpm_find_grp_pkgs(alpm_list_t *dbs, } } alpm_list_free(ignorelist); - return(pkgs); + return pkgs; } /** Compute the size of the files that will be downloaded to install a @@ -258,7 +260,7 @@ static int compute_download_size(pmpkg_t *newpkg) if(newpkg->origin != PKG_FROM_SYNCDB) { newpkg->infolevel |= INFRQ_DSIZE; newpkg->download_size = 0; - return(0); + return 0; } fname = alpm_pkg_get_filename(newpkg); @@ -268,7 +270,7 @@ static int compute_download_size(pmpkg_t *newpkg) if(fpath) { FREE(fpath); size = 0; - } else if(handle->usedelta) { + } else if(newpkg->handle->usedelta) { off_t dltsize; off_t pkgsize = alpm_pkg_get_size(newpkg); @@ -295,21 +297,18 @@ static int compute_download_size(pmpkg_t *newpkg) newpkg->infolevel |= INFRQ_DSIZE; newpkg->download_size = size; - return(0); + return 0; } -int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **data) +int _alpm_sync_prepare(pmhandle_t *handle, alpm_list_t **data) { alpm_list_t *deps = NULL; alpm_list_t *unresolvable = NULL; alpm_list_t *i, *j; alpm_list_t *remove = NULL; int ret = 0; - - ALPM_LOG_FUNC; - - ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); - ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); + pmtrans_t *trans = handle->trans; + pmdb_t *db_local = handle->db_local; if(data) { *data = NULL; @@ -340,7 +339,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync building up a list of packages which could not be resolved. */ for(i = trans->add; i; i = i->next) { pmpkg_t *pkg = i->data; - if(_alpm_resolvedeps(localpkgs, dbs_sync, pkg, trans->add, + if(_alpm_resolvedeps(localpkgs, handle->dbs_sync, pkg, trans->add, &resolved, remove, data) == -1) { unresolvable = alpm_list_add(unresolvable, pkg); } @@ -355,7 +354,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync int remove_unresolvable = 0; QUESTION(handle->trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable, NULL, NULL, &remove_unresolvable); - if (remove_unresolvable) { + if(remove_unresolvable) { /* User wants to remove the unresolvable packages from the transaction. The packages will be removed from the actual transaction when the transaction packages are replaced with a @@ -551,7 +550,7 @@ cleanup: alpm_list_free(unresolvable); alpm_list_free(remove); - return(ret); + return ret; } /** Returns the size of the files that will be downloaded to install a @@ -564,13 +563,13 @@ off_t SYMEXPORT alpm_pkg_download_size(pmpkg_t *newpkg) if(!(newpkg->infolevel & INFRQ_DSIZE)) { compute_download_size(newpkg); } - return(newpkg->download_size); + return newpkg->download_size; } static int endswith(const char *filename, const char *extension) { const char *s = filename + strlen(filename) - strlen(extension); - return(strcmp(s, extension) == 0); + return strcmp(s, extension) == 0; } /** Applies delta files to create an upgraded package file. @@ -650,13 +649,14 @@ static int apply_deltas(pmtrans_t *trans) if(retval != 0) { /* one delta failed for this package, cancel the remaining ones */ EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_FAILED, NULL, NULL); + pm_errno = PM_ERR_DLT_PATCHFAILED; ret = 1; break; } } } - return(ret); + return ret; } /** Compares the md5sum of a file to the expected value. @@ -665,50 +665,74 @@ static int apply_deltas(pmtrans_t *trans) * should be deleted. * * @param trans the transaction - * @param filename the filename of the file to test + * @param filename the absolute path of the file to test * @param md5sum the expected md5sum of the file * * @return 0 if the md5sum matched, 1 if not, -1 in case of errors */ -static int test_md5sum(pmtrans_t *trans, const char *filename, +static int test_md5sum(pmtrans_t *trans, const char *filepath, const char *md5sum) { - char *filepath; - int ret; - - filepath = _alpm_filecache_find(filename); - - ret = _alpm_test_md5sum(filepath, md5sum); - + int ret = _alpm_test_md5sum(filepath, md5sum); if(ret == 1) { int doremove = 0; - QUESTION(trans, PM_TRANS_CONV_CORRUPTED_PKG, (char *)filename, + QUESTION(trans, PM_TRANS_CONV_CORRUPTED_PKG, (char *)filepath, NULL, NULL, &doremove); if(doremove) { unlink(filepath); } } - FREE(filepath); - - return(ret); + return ret; } -int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) +static int validate_deltas(pmtrans_t *trans, alpm_list_t *deltas, + alpm_list_t **data) { - alpm_list_t *i, *j, *files = NULL; - alpm_list_t *deltas = NULL; - size_t numtargs, current = 0, replaces = 0; - int errors = 0; - const char *cachedir = NULL; - int ret = -1; + int errors = 0, ret = 0; + alpm_list_t *i; - ALPM_LOG_FUNC; + if(!deltas) { + return 0; + } - ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); + /* Check integrity of deltas */ + EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_START, NULL, NULL); + + for(i = deltas; i; i = i->next) { + pmdelta_t *d = alpm_list_getdata(i); + const char *filename = alpm_delta_get_filename(d); + char *filepath = _alpm_filecache_find(filename); + const char *md5sum = alpm_delta_get_md5sum(d); + + if(test_md5sum(trans, filepath, md5sum) != 0) { + errors++; + *data = alpm_list_add(*data, strdup(filename)); + } + FREE(filepath); + } + if(errors) { + pm_errno = PM_ERR_DLT_INVALID; + return -1; + } + EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_DONE, NULL, NULL); + + /* Use the deltas to generate the packages */ + EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_START, NULL, NULL); + ret = apply_deltas(trans); + EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_DONE, NULL, NULL); + return ret; +} + +static int download_files(pmhandle_t *handle, alpm_list_t **deltas) +{ + const char *cachedir; + alpm_list_t *i, *j; + alpm_list_t *files = NULL; + int errors = 0; cachedir = _alpm_filecache_setup(); - trans->state = STATE_DOWNLOADING; + handle->trans->state = STATE_DOWNLOADING; /* Total progress - figure out the total download size if required to * pass to the callback. This function is called once, and it is up to the @@ -716,7 +740,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) if(handle->totaldlcb) { off_t total_size = (off_t)0; /* sum up the download size for each package and store total */ - for(i = trans->add; i; i = i->next) { + for(i = handle->trans->add; i; i = i->next) { pmpkg_t *spkg = i->data; total_size += spkg->download_size; } @@ -727,7 +751,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) for(i = handle->dbs_sync; i; i = i->next) { pmdb_t *current = i->data; - for(j = trans->add; j; j = j->next) { + for(j = handle->trans->add; j; j = j->next) { pmpkg_t *spkg = j->data; if(spkg->origin != PKG_FROM_FILE && current == spkg->origin_data.db) { @@ -738,48 +762,63 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) alpm_list_t *delta_path = spkg->delta_path; if(delta_path) { /* using deltas */ - alpm_list_t *dlts = NULL; - + alpm_list_t *dlts; for(dlts = delta_path; dlts; dlts = dlts->next) { - pmdelta_t *d = dlts->data; - - if(d->download_size != 0) { - /* add the delta filename to the download list if needed */ - files = alpm_list_add(files, strdup(d->delta)); + pmdelta_t *delta = dlts->data; + if(delta->download_size != 0) { + files = alpm_list_add(files, strdup(delta->delta)); } - /* keep a list of all the delta files for md5sums */ - deltas = alpm_list_add(deltas, d); + *deltas = alpm_list_add(*deltas, delta); } - } else { - /* not using deltas */ - if(spkg->download_size != 0) { - /* add the filename to the download list if needed */ - files = alpm_list_add(files, strdup(fname)); - } + } else if(spkg->download_size != 0) { + files = alpm_list_add(files, strdup(fname)); } } } if(files) { - EVENT(trans, PM_TRANS_EVT_RETRIEVE_START, current->treename, NULL); - errors = _alpm_download_files(files, current->servers, cachedir); + EVENT(handle->trans, PM_TRANS_EVT_RETRIEVE_START, current->treename, NULL); + for(j = files; j; j = j->next) { + const char *filename = j->data; + alpm_list_t *server; + int ret = -1; + for(server = current->servers; server; server = server->next) { + const char *server_url = server->data; + char *fileurl; + size_t len; + + /* print server + filename into a buffer */ + len = strlen(server_url) + strlen(filename) + 2; + CALLOC(fileurl, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1)); + snprintf(fileurl, len, "%s/%s", server_url, filename); + + ret = _alpm_download(fileurl, cachedir, 0, 1, 0); + FREE(fileurl); + if(ret != -1) { + break; + } + } + if(ret == -1) { + errors++; + } + } - if (errors) { + FREELIST(files); + if(errors) { _alpm_log(PM_LOG_WARNING, _("failed to retrieve some files from %s\n"), current->treename); if(pm_errno == 0) { pm_errno = PM_ERR_RETRIEVE; } - goto error; + return -1; } - FREELIST(files); } } - for(j = trans->add; j; j = j->next) { + for(j = handle->trans->add; j; j = j->next) { pmpkg_t *pkg = j->data; pkg->infolevel &= ~INFRQ_DSIZE; pkg->download_size = 0; @@ -789,70 +828,58 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) if(handle->totaldlcb) { handle->totaldlcb(0); } + return 0; +} - /* if we have deltas to work with */ - if(handle->usedelta && deltas) { - int ret = 0; - errors = 0; - /* Check integrity of deltas */ - EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_START, NULL, NULL); - - for(i = deltas; i; i = i->next) { - pmdelta_t *d = alpm_list_getdata(i); - const char *filename = alpm_delta_get_filename(d); - const char *md5sum = alpm_delta_get_md5sum(d); - - if(test_md5sum(trans, filename, md5sum) != 0) { - errors++; - *data = alpm_list_add(*data, strdup(filename)); - } - } - if(errors) { - pm_errno = PM_ERR_DLT_INVALID; - goto error; - } - EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_DONE, NULL, NULL); +int _alpm_sync_commit(pmhandle_t *handle, alpm_list_t **data) +{ + alpm_list_t *i; + alpm_list_t *deltas = NULL; + size_t numtargs, current = 0, replaces = 0; + int errors; + pmtrans_t *trans = handle->trans; - /* Use the deltas to generate the packages */ - EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_START, NULL, NULL); - ret = apply_deltas(trans); - EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_DONE, NULL, NULL); + if(download_files(handle, &deltas)) { + alpm_list_free(deltas); + return -1; + } - if(ret) { - pm_errno = PM_ERR_DLT_PATCHFAILED; - goto error; - } + if(validate_deltas(trans, deltas, data)) { + alpm_list_free(deltas); + return -1; } + alpm_list_free(deltas); /* Check integrity of packages */ numtargs = alpm_list_count(trans->add); EVENT(trans, PM_TRANS_EVT_INTEGRITY_START, NULL, NULL); errors = 0; + for(i = trans->add; i; i = i->next, current++) { pmpkg_t *spkg = i->data; int percent = (current * 100) / numtargs; + const char *filename; + char *filepath; + pgp_verify_t check_sig; + + PROGRESS(trans, PM_TRANS_PROGRESS_INTEGRITY_START, "", percent, + numtargs, current); if(spkg->origin == PKG_FROM_FILE) { continue; /* pkg_load() has been already called, this package is valid */ } - PROGRESS(trans, PM_TRANS_PROGRESS_INTEGRITY_START, "", percent, - numtargs, current); - const char *filename = alpm_pkg_get_filename(spkg); - const char *md5sum = alpm_pkg_get_md5sum(spkg); + filename = alpm_pkg_get_filename(spkg); + filepath = _alpm_filecache_find(filename); + pmdb_t *sdb = alpm_pkg_get_db(spkg); + check_sig = _alpm_db_get_sigverify_level(sdb); - if(test_md5sum(trans, filename, md5sum) != 0) { - errors++; - *data = alpm_list_add(*data, strdup(filename)); - continue; - } /* load the package file and replace pkgcache entry with it in the target list */ /* TODO: alpm_pkg_get_db() will not work on this target anymore */ _alpm_log(PM_LOG_DEBUG, "replacing pkgcache entry with package file for target %s\n", spkg->name); - char *filepath = _alpm_filecache_find(filename); - pmpkg_t *pkgfile; - if(alpm_pkg_load(filepath, 1, &pkgfile) != 0) { - _alpm_pkg_free(pkgfile); + pmpkg_t *pkgfile =_alpm_pkg_load_internal(filepath, 1, spkg->md5sum, + spkg->base64_sig, check_sig); + if(!pkgfile) { errors++; *data = alpm_list_add(*data, strdup(filename)); FREE(filepath); @@ -863,17 +890,18 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) i->data = pkgfile; _alpm_pkg_free_trans(spkg); /* spkg has been removed from the target list */ } + PROGRESS(trans, PM_TRANS_PROGRESS_INTEGRITY_START, "", 100, numtargs, current); EVENT(trans, PM_TRANS_EVT_INTEGRITY_DONE, NULL, NULL); + + if(errors) { - pm_errno = PM_ERR_PKG_INVALID; - goto error; + RET_ERR(PM_ERR_PKG_INVALID, -1); } if(trans->flags & PM_TRANS_FLAG_DOWNLOADONLY) { - ret = 0; - goto error; + return 0; } trans->state = STATE_COMMITING; @@ -885,17 +913,16 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) EVENT(trans, PM_TRANS_EVT_FILECONFLICTS_START, NULL, NULL); _alpm_log(PM_LOG_DEBUG, "looking for file conflicts\n"); - alpm_list_t *conflict = _alpm_db_find_fileconflicts(db_local, trans, - trans->add, trans->remove); + alpm_list_t *conflict = _alpm_db_find_fileconflicts(handle, + trans->add, trans->remove); if(conflict) { - pm_errno = PM_ERR_FILE_CONFLICTS; if(data) { *data = conflict; } else { alpm_list_free_inner(conflict, (alpm_list_fn_free)_alpm_fileconflict_free); alpm_list_free(conflict); } - goto error; + RET_ERR(PM_ERR_FILE_CONFLICTS, -1); } EVENT(trans, PM_TRANS_EVT_FILECONFLICTS_DONE, NULL, NULL); @@ -906,9 +933,9 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) EVENT(trans, PM_TRANS_EVT_DISKSPACE_START, NULL, NULL); _alpm_log(PM_LOG_DEBUG, "checking available disk space\n"); - if(_alpm_check_diskspace(trans, handle->db_local) == -1) { + if(_alpm_check_diskspace(handle) == -1) { _alpm_log(PM_LOG_ERROR, "%s\n", _("not enough free disk space")); - goto error; + return -1; } EVENT(trans, PM_TRANS_EVT_DISKSPACE_DONE, NULL, NULL); @@ -918,24 +945,20 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) if(replaces) { _alpm_log(PM_LOG_DEBUG, "removing conflicting and to-be-replaced packages\n"); /* we want the frontend to be aware of commit details */ - if(_alpm_remove_packages(trans, handle->db_local) == -1) { + if(_alpm_remove_packages(handle) == -1) { _alpm_log(PM_LOG_ERROR, _("could not commit removal transaction\n")); - goto error; + return -1; } } /* install targets */ _alpm_log(PM_LOG_DEBUG, "installing packages\n"); - if(_alpm_upgrade_packages(trans, handle->db_local) == -1) { + if(_alpm_upgrade_packages(handle) == -1) { _alpm_log(PM_LOG_ERROR, _("could not commit transaction\n")); - goto error; + return -1; } - ret = 0; -error: - FREELIST(files); - alpm_list_free(deltas); - return(ret); + return 0; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/sync.h b/lib/libalpm/sync.h index 90a2d40d..3049dd21 100644 --- a/lib/libalpm/sync.h +++ b/lib/libalpm/sync.h @@ -24,8 +24,8 @@ #include "alpm.h" -int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **data); -int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data); +int _alpm_sync_prepare(pmhandle_t *handle, alpm_list_t **data); +int _alpm_sync_commit(pmhandle_t *handle, alpm_list_t **data); #endif /* _ALPM_SYNC_H */ diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index bf9ef722..58bcc38b 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -28,8 +28,6 @@ #include <string.h> #include <unistd.h> #include <sys/types.h> -#include <sys/stat.h> -#include <sys/statvfs.h> #include <errno.h> #include <limits.h> #include <fcntl.h> @@ -41,11 +39,12 @@ #include "util.h" #include "log.h" #include "handle.h" -#include "add.h" #include "remove.h" #include "sync.h" #include "alpm.h" -#include "deps.h" + +/* global handle variable */ +extern pmhandle_t *handle; /** \addtogroup alpm_trans Transaction Functions * @brief Functions to manipulate libalpm transactions @@ -68,22 +67,22 @@ static int make_lock(pmhandle_t *handle) } if(_alpm_makepath(dir)) { FREE(dir); - return(-1); + return -1; } FREE(dir); do { fd = open(handle->lockfile, O_WRONLY | O_CREAT | O_EXCL, 0000); - } while (fd == -1 && errno == EINTR); + } while(fd == -1 && errno == EINTR); if(fd > 0) { FILE *f = fdopen(fd, "w"); fprintf(f, "%ld\n", (long)getpid()); fflush(f); fsync(fd); handle->lckstream = f; - return(0); + return 0; } - return(-1); + return -1; } /* Remove a lock file */ @@ -94,9 +93,9 @@ static int remove_lock(pmhandle_t *handle) handle->lckstream = NULL; } if(unlink(handle->lockfile) == -1 && errno != ENOENT) { - return(-1); + return -1; } - return(0); + return 0; } /** Initialize the transaction. */ @@ -108,8 +107,6 @@ int SYMEXPORT alpm_trans_init(pmtransflag_t flags, const int required_db_version = 2; int db_version; - ALPM_LOG_FUNC; - /* Sanity checks */ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1)); @@ -144,7 +141,7 @@ int SYMEXPORT alpm_trans_init(pmtransflag_t flags, RET_ERR(PM_ERR_DB_VERSION, -1); } - return(0); + return 0; } static alpm_list_t *check_arch(alpm_list_t *pkgs) @@ -154,7 +151,7 @@ static alpm_list_t *check_arch(alpm_list_t *pkgs) const char *arch = alpm_option_get_arch(); if(!arch) { - return(NULL); + return NULL; } for(i = pkgs; i; i = i->next) { pmpkg_t *pkg = i->data; @@ -169,7 +166,7 @@ static alpm_list_t *check_arch(alpm_list_t *pkgs) invalid = alpm_list_add(invalid, string); } } - return(invalid); + return invalid; } /** Prepare a transaction. */ @@ -177,8 +174,6 @@ int SYMEXPORT alpm_trans_prepare(alpm_list_t **data) { pmtrans_t *trans; - ALPM_LOG_FUNC; - /* Sanity checks */ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); ASSERT(data != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); @@ -190,7 +185,7 @@ int SYMEXPORT alpm_trans_prepare(alpm_list_t **data) /* If there's nothing to do, return without complaining */ if(trans->add == NULL && trans->remove == NULL) { - return(0); + return 0; } alpm_list_t *invalid = check_arch(trans->add); @@ -202,20 +197,20 @@ int SYMEXPORT alpm_trans_prepare(alpm_list_t **data) } if(trans->add == NULL) { - if(_alpm_remove_prepare(trans, handle->db_local, data) == -1) { + if(_alpm_remove_prepare(handle, data) == -1) { /* pm_errno is set by _alpm_remove_prepare() */ - return(-1); + return -1; } } else { - if(_alpm_sync_prepare(trans, handle->db_local, handle->dbs_sync, data) == -1) { + if(_alpm_sync_prepare(handle, data) == -1) { /* pm_errno is set by _alpm_sync_prepare() */ - return(-1); + return -1; } } trans->state = STATE_PREPARED; - return(0); + return 0; } /** Commit a transaction. */ @@ -223,8 +218,6 @@ int SYMEXPORT alpm_trans_commit(alpm_list_t **data) { pmtrans_t *trans; - ALPM_LOG_FUNC; - /* Sanity checks */ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); @@ -237,26 +230,26 @@ int SYMEXPORT alpm_trans_commit(alpm_list_t **data) /* If there's nothing to do, return without complaining */ if(trans->add == NULL && trans->remove == NULL) { - return(0); + return 0; } trans->state = STATE_COMMITING; if(trans->add == NULL) { - if(_alpm_remove_packages(trans, handle->db_local) == -1) { + if(_alpm_remove_packages(handle) == -1) { /* pm_errno is set by _alpm_remove_commit() */ - return(-1); + return -1; } } else { - if(_alpm_sync_commit(trans, handle->db_local, data) == -1) { + if(_alpm_sync_commit(handle, data) == -1) { /* pm_errno is set by _alpm_sync_commit() */ - return(-1); + return -1; } } trans->state = STATE_COMMITED; - return(0); + return 0; } /** Interrupt a transaction. */ @@ -264,8 +257,6 @@ int SYMEXPORT alpm_trans_interrupt(void) { pmtrans_t *trans; - ALPM_LOG_FUNC; - /* Sanity checks */ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); @@ -276,7 +267,7 @@ int SYMEXPORT alpm_trans_interrupt(void) trans->state = STATE_INTERRUPTED; - return(0); + return 0; } /** Release a transaction. */ @@ -284,8 +275,6 @@ int SYMEXPORT alpm_trans_release(void) { pmtrans_t *trans; - ALPM_LOG_FUNC; - /* Sanity checks */ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); @@ -308,7 +297,7 @@ int SYMEXPORT alpm_trans_release(void) } } - return(0); + return 0; } /** @} */ @@ -317,18 +306,14 @@ pmtrans_t *_alpm_trans_new(void) { pmtrans_t *trans; - ALPM_LOG_FUNC; - CALLOC(trans, 1, sizeof(pmtrans_t), RET_ERR(PM_ERR_MEMORY, NULL)); trans->state = STATE_IDLE; - return(trans); + return trans; } void _alpm_trans_free(pmtrans_t *trans) { - ALPM_LOG_FUNC; - if(trans == NULL) { return; } @@ -351,7 +336,7 @@ static int grep(const char *fn, const char *needle) FILE *fp; if((fp = fopen(fn, "r")) == NULL) { - return(0); + return 0; } while(!feof(fp)) { char line[1024]; @@ -362,16 +347,15 @@ static int grep(const char *fn, const char *needle) * ends up being split across line reads */ if(strstr(line, needle)) { fclose(fp); - return(1); + return 1; } } fclose(fp); - return(0); + return 0; } -int _alpm_runscriptlet(const char *root, const char *installfn, - const char *script, const char *ver, - const char *oldver, pmtrans_t *trans) +int _alpm_runscriptlet(pmhandle_t *handle, const char *installfn, + const char *script, const char *ver, const char *oldver) { char scriptfn[PATH_MAX]; char cmdline[PATH_MAX]; @@ -381,23 +365,21 @@ int _alpm_runscriptlet(const char *root, const char *installfn, int clean_tmpdir = 0; int retval = 0; - ALPM_LOG_FUNC; - if(access(installfn, R_OK)) { /* not found */ _alpm_log(PM_LOG_DEBUG, "scriptlet '%s' not found\n", installfn); - return(0); + return 0; } /* creates a directory in $root/tmp/ for copying/extracting the scriptlet */ - snprintf(tmpdir, PATH_MAX, "%stmp/", root); + snprintf(tmpdir, PATH_MAX, "%stmp/", handle->root); if(access(tmpdir, F_OK) != 0) { _alpm_makepath_mode(tmpdir, 01777); } - snprintf(tmpdir, PATH_MAX, "%stmp/alpm_XXXXXX", root); + snprintf(tmpdir, PATH_MAX, "%stmp/alpm_XXXXXX", handle->root); if(mkdtemp(tmpdir) == NULL) { _alpm_log(PM_LOG_ERROR, _("could not create temp directory\n")); - return(1); + return 1; } else { clean_tmpdir = 1; } @@ -419,7 +401,7 @@ int _alpm_runscriptlet(const char *root, const char *installfn, } /* chop off the root so we can find the tmpdir in the chroot */ - scriptpath = scriptfn + strlen(root) - 1; + scriptpath = scriptfn + strlen(handle->root) - 1; if(!grep(scriptfn, script)) { /* script not found in scriptlet file */ @@ -436,14 +418,14 @@ int _alpm_runscriptlet(const char *root, const char *installfn, _alpm_log(PM_LOG_DEBUG, "executing \"%s\"\n", cmdline); - retval = _alpm_run_chroot(root, "/bin/sh", argv); + retval = _alpm_run_chroot(handle, "/bin/sh", argv); cleanup: if(clean_tmpdir && _alpm_rmrf(tmpdir)) { _alpm_log(PM_LOG_WARNING, _("could not remove tmpdir %s\n"), tmpdir); } - return(retval); + return retval; } int SYMEXPORT alpm_trans_get_flags() @@ -458,8 +440,8 @@ int SYMEXPORT alpm_trans_get_flags() alpm_list_t SYMEXPORT * alpm_trans_get_add() { /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(handle->trans != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(handle->trans != NULL, return NULL); return handle->trans->add; } @@ -467,8 +449,8 @@ alpm_list_t SYMEXPORT * alpm_trans_get_add() alpm_list_t SYMEXPORT * alpm_trans_get_remove() { /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(handle->trans != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(handle->trans != NULL, return NULL); return handle->trans->remove; } diff --git a/lib/libalpm/trans.h b/lib/libalpm/trans.h index 6702881b..8c9e7fac 100644 --- a/lib/libalpm/trans.h +++ b/lib/libalpm/trans.h @@ -71,9 +71,8 @@ void _alpm_trans_free(pmtrans_t *trans); int _alpm_trans_init(pmtrans_t *trans, pmtransflag_t flags, alpm_trans_cb_event event, alpm_trans_cb_conv conv, alpm_trans_cb_progress progress); -int _alpm_runscriptlet(const char *root, const char *installfn, - const char *script, const char *ver, - const char *oldver, pmtrans_t *trans); +int _alpm_runscriptlet(pmhandle_t *handle, const char *installfn, + const char *script, const char *ver, const char *oldver); #endif /* _ALPM_TRANS_H */ diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 430da92a..6f0763d5 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -53,10 +53,10 @@ /* libalpm */ #include "util.h" #include "log.h" -#include "package.h" #include "alpm.h" #include "alpm_list.h" #include "handle.h" +#include "trans.h" #ifndef HAVE_STRSEP /* This is a replacement for strsep which is not portable (missing on Solaris). @@ -65,14 +65,14 @@ char* strsep(char** str, const char* delims) { char* token; - if (*str==NULL) { + if(*str==NULL) { /* No more tokens */ return NULL; } token=*str; - while (**str!='\0') { - if (strchr(delims,**str)!=NULL) { + while(**str!='\0') { + if(strchr(delims,**str)!=NULL) { **str='\0'; (*str)++; return token; @@ -87,7 +87,7 @@ char* strsep(char** str, const char* delims) int _alpm_makepath(const char *path) { - return(_alpm_makepath_mode(path, 0755)); + return _alpm_makepath_mode(path, 0755); } /* does the same thing as 'mkdir -p' */ @@ -123,7 +123,7 @@ int _alpm_makepath_mode(const char *path, mode_t mode) free(orig); free(incr); umask(oldmask); - return(ret); + return ret; } #define CPBUFSIZE 8 * 1024 @@ -137,12 +137,12 @@ int _alpm_copyfile(const char *src, const char *dest) in = fopen(src, "rb"); if(in == NULL) { - return(1); + return 1; } out = fopen(dest, "wb"); if(out == NULL) { fclose(in); - return(1); + return 1; } CALLOC(buf, (size_t)CPBUFSIZE, (size_t)1, ret = 1; goto cleanup;); @@ -175,7 +175,7 @@ cleanup: fclose(in); fclose(out); FREE(buf); - return(ret); + return ret; } /* Trim whitespace and newlines from a string @@ -186,7 +186,7 @@ char *_alpm_strtrim(char *str) if(*str == '\0') { /* string is empty, so we're done. */ - return(str); + return str; } while(isspace((unsigned char)*pch)) { @@ -198,7 +198,7 @@ char *_alpm_strtrim(char *str) /* check if there wasn't anything but whitespace in the string. */ if(*str == '\0') { - return(str); + return str; } pch = (str + (strlen(str) - 1)); @@ -207,7 +207,7 @@ char *_alpm_strtrim(char *str) } *++pch = '\0'; - return(str); + return str; } /* Compression functions */ @@ -225,12 +225,12 @@ int _alpm_unpack_single(const char *archive, const char *prefix, const char *fn) alpm_list_t *list = NULL; int ret = 0; if(fn == NULL) { - return(1); + return 1; } list = alpm_list_add(list, (void *)fn); ret = _alpm_unpack(archive, prefix, list, 1); alpm_list_free(list); - return(ret); + return ret; } /** @@ -253,8 +253,6 @@ int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int char cwd[PATH_MAX]; int restore_cwd = 0; - ALPM_LOG_FUNC; - if((_archive = archive_read_new()) == NULL) RET_ERR(PM_ERR_LIBARCHIVE, 1); @@ -307,7 +305,7 @@ int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int char *found = alpm_list_find_str(list, prefix); free(prefix); if(!found) { - if (archive_read_data_skip(_archive) != ARCHIVE_OK) { + if(archive_read_data_skip(_archive) != ARCHIVE_OK) { ret = 1; goto cleanup; } @@ -341,7 +339,7 @@ cleanup: if(restore_cwd && chdir(cwd) != 0) { _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno)); } - return(ret); + return ret; } /* does the same thing as 'rm -rf' */ @@ -356,18 +354,18 @@ int _alpm_rmrf(const char *path) if(_alpm_lstat(path, &st) == 0) { if(!S_ISDIR(st.st_mode)) { if(!unlink(path)) { - return(0); + return 0; } else { if(errno == ENOENT) { - return(0); + return 0; } else { - return(1); + return 1; } } } else { dirp = opendir(path); if(!dirp) { - return(1); + return 1; } for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { if(dp->d_ino) { @@ -382,9 +380,9 @@ int _alpm_rmrf(const char *path) errflag++; } } - return(errflag); + return errflag; } - return(0); + return 0; } int _alpm_logaction(int usesyslog, FILE *f, const char *fmt, va_list args) @@ -415,10 +413,10 @@ int _alpm_logaction(int usesyslog, FILE *f, const char *fmt, va_list args) fflush(f); } - return(ret); + return ret; } -int _alpm_run_chroot(const char *root, const char *path, char *const argv[]) +int _alpm_run_chroot(pmhandle_t *handle, const char *path, char *const argv[]) { char cwd[PATH_MAX]; pid_t pid; @@ -426,8 +424,6 @@ int _alpm_run_chroot(const char *root, const char *path, char *const argv[]) int restore_cwd = 0; int retval = 0; - ALPM_LOG_FUNC; - /* save the cwd so we can restore it later */ if(getcwd(cwd, PATH_MAX) == NULL) { _alpm_log(PM_LOG_ERROR, _("could not get current working directory\n")); @@ -436,12 +432,14 @@ int _alpm_run_chroot(const char *root, const char *path, char *const argv[]) } /* just in case our cwd was removed in the upgrade operation */ - if(chdir(root) != 0) { - _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), root, strerror(errno)); + if(chdir(handle->root) != 0) { + _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), + handle->root, strerror(errno)); goto cleanup; } - _alpm_log(PM_LOG_DEBUG, "executing \"%s\" under chroot \"%s\"\n", path, root); + _alpm_log(PM_LOG_DEBUG, "executing \"%s\" under chroot \"%s\"\n", + path, handle->root); /* Flush open fds before fork() to avoid cloning buffers */ fflush(NULL); @@ -470,7 +468,7 @@ int _alpm_run_chroot(const char *root, const char *path, char *const argv[]) close(pipefd[1]); /* use fprintf instead of _alpm_log to send output through the parent */ - if(chroot(root) != 0) { + if(chroot(handle->root) != 0) { fprintf(stderr, _("could not change the root directory (%s)\n"), strerror(errno)); exit(1); } @@ -532,32 +530,32 @@ cleanup: _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno)); } - return(retval); + return retval; } -int _alpm_ldconfig(const char *root) +int _alpm_ldconfig(pmhandle_t *handle) { char line[PATH_MAX]; _alpm_log(PM_LOG_DEBUG, "running ldconfig\n"); - snprintf(line, PATH_MAX, "%setc/ld.so.conf", root); + snprintf(line, PATH_MAX, "%setc/ld.so.conf", handle->root); if(access(line, F_OK) == 0) { - snprintf(line, PATH_MAX, "%ssbin/ldconfig", root); + snprintf(line, PATH_MAX, "%ssbin/ldconfig", handle->root); if(access(line, X_OK) == 0) { char *argv[] = { "ldconfig", NULL }; - _alpm_run_chroot(root, "/sbin/ldconfig", argv); + _alpm_run_chroot(handle, "/sbin/ldconfig", argv); } } - return(0); + return 0; } /* Helper function for comparing strings using the * alpm "compare func" signature */ int _alpm_str_cmp(const void *s1, const void *s2) { - return(strcmp(s1, s2)); + return strcmp(s1, s2); } /** Find a filename in a registered alpm cachedir. @@ -573,12 +571,12 @@ char *_alpm_filecache_find(const char* filename) /* Loop through the cache dirs until we find a matching file */ for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) { - snprintf(path, PATH_MAX, "%s%s", (char*)alpm_list_getdata(i), + snprintf(path, PATH_MAX, "%s%s", (char *)alpm_list_getdata(i), filename); if(stat(path, &buf) == 0 && S_ISREG(buf.st_mode)) { retpath = strdup(path); _alpm_log(PM_LOG_DEBUG, "found cached pkg: %s\n", retpath); - return(retpath); + return retpath; } } /* package wasn't found in any cachedir */ @@ -604,20 +602,23 @@ const char *_alpm_filecache_setup(void) cachedir); if(_alpm_makepath(cachedir) == 0) { _alpm_log(PM_LOG_DEBUG, "using cachedir: %s\n", cachedir); - return(cachedir); + return cachedir; } } else if(S_ISDIR(buf.st_mode) && (buf.st_mode & S_IWUSR)) { _alpm_log(PM_LOG_DEBUG, "using cachedir: %s\n", cachedir); - return(cachedir); + return cachedir; + } else { + _alpm_log(PM_LOG_DEBUG, "skipping cachedir: %s\n", cachedir); } } /* we didn't find a valid cache directory. use /tmp. */ - tmp = alpm_list_add(NULL, strdup("/tmp/")); + tmp = alpm_list_add(NULL, "/tmp/"); alpm_option_set_cachedirs(tmp); - _alpm_log(PM_LOG_DEBUG, "using cachedir: %s", "/tmp/\n"); + alpm_list_free(tmp); + _alpm_log(PM_LOG_DEBUG, "using cachedir: %s\n", "/tmp/"); _alpm_log(PM_LOG_WARNING, _("couldn't create package cache, using /tmp instead\n")); - return(alpm_list_getdata(tmp)); + return "/tmp/"; } /** lstat wrapper that treats /path/dirsymlink/ the same as /path/dirsymlink. @@ -641,7 +642,7 @@ int _alpm_lstat(const char *path, struct stat *buf) ret = lstat(newpath, buf); FREE(newpath); - return(ret); + return ret; } #ifdef HAVE_LIBSSL @@ -652,11 +653,11 @@ static int md5_file(const char *path, unsigned char output[16]) MD5_CTX ctx; unsigned char *buf; - CALLOC(buf, 8192, sizeof(unsigned char), return(1)); + CALLOC(buf, 8192, sizeof(unsigned char), RET_ERR(PM_ERR_MEMORY, 1)); if((f = fopen(path, "rb")) == NULL) { free(buf); - return(1); + return 1; } MD5_Init(&ctx); @@ -672,11 +673,11 @@ static int md5_file(const char *path, unsigned char output[16]) if(ferror(f) != 0) { fclose(f); - return(2); + return 2; } fclose(f); - return(0); + return 0; } #endif @@ -691,16 +692,14 @@ char SYMEXPORT *alpm_compute_md5sum(const char *filename) char *md5sum; int ret, i; - ALPM_LOG_FUNC; - - ASSERT(filename != NULL, return(NULL)); + ASSERT(filename != NULL, return NULL); /* allocate 32 chars plus 1 for null */ md5sum = calloc(33, sizeof(char)); /* defined above for OpenSSL, otherwise defined in md5.h */ ret = md5_file(filename, output); - if (ret > 0) { + if(ret > 0) { RET_ERR(PM_ERR_NOT_A_FILE, NULL); } @@ -712,7 +711,7 @@ char SYMEXPORT *alpm_compute_md5sum(const char *filename) md5sum[32] = '\0'; _alpm_log(PM_LOG_DEBUG, "md5(%s) = %s\n", filename, md5sum); - return(md5sum); + return md5sum; } int _alpm_test_md5sum(const char *filepath, const char *md5sum) @@ -731,7 +730,7 @@ int _alpm_test_md5sum(const char *filepath, const char *md5sum) } FREE(md5sum2); - return(ret); + return ret; } /* Note: does NOT handle sparse files on purpose for speed. */ @@ -753,7 +752,7 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b) } /* zero-copy - this is the entire next block of data. */ - b->ret = archive_read_data_block(a, (void*)&b->block, + b->ret = archive_read_data_block(a, (void *)&b->block, &b->block_size, &offset); b->block_offset = b->block; @@ -776,20 +775,19 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b) /* allocate our buffer, or ensure our existing one is big enough */ if(!b->line) { /* set the initial buffer to the read block_size */ - CALLOC(b->line, b->block_size + 1, sizeof(char), - RET_ERR(PM_ERR_MEMORY, -1)); + CALLOC(b->line, b->block_size + 1, sizeof(char), return ENOMEM); b->line_size = b->block_size + 1; b->line_offset = b->line; } else { size_t needed = (size_t)((b->line_offset - b->line) + (i - b->block_offset) + 1); if(needed > b->max_line_size) { - RET_ERR(PM_ERR_MEMORY, -1); + return ERANGE; } if(needed > b->line_size) { /* need to realloc + copy data to fit total length */ char *new; - CALLOC(new, needed, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1)); + CALLOC(new, needed, sizeof(char), return ENOMEM); memcpy(new, b->line, b->line_size); b->line_size = needed; b->line_offset = new + (b->line_offset - b->line); @@ -804,7 +802,7 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b) b->line_offset[len] = '\0'; b->block_offset = ++i; /* this is the main return point; from here you can read b->line */ - return(ARCHIVE_OK); + return ARCHIVE_OK; } else { /* we've looked through the whole block but no newline, copy it */ size_t len = (size_t)(b->block + b->block_size - b->block_offset); @@ -819,7 +817,7 @@ cleanup: int ret = b->ret; FREE(b->line); memset(b, 0, sizeof(b)); - return(ret); + return ret; } } @@ -833,12 +831,12 @@ int _alpm_splitname(const char *target, pmpkg_t *pkg) const char *version, *end; if(target == NULL || pkg == NULL) { - return(-1); + return -1; } end = target + strlen(target); /* remove any trailing '/' */ - while (*(end - 1) == '/') { + while(*(end - 1) == '/') { --end; } @@ -847,7 +845,7 @@ int _alpm_splitname(const char *target, pmpkg_t *pkg) for(version = end - 1; *version && *version != '-'; version--); for(version = version - 1; *version && *version != '-'; version--); if(*version != '-' || version == target) { - return(-1); + return -1; } /* copy into fields and return */ @@ -865,7 +863,7 @@ int _alpm_splitname(const char *target, pmpkg_t *pkg) STRNDUP(pkg->name, target, version - target, RET_ERR(PM_ERR_MEMORY, -1)); pkg->name_hash = _alpm_hash_sdbm(pkg->name); - return(0); + return 0; } /** @@ -880,13 +878,13 @@ unsigned long _alpm_hash_sdbm(const char *str) int c; if(!str) { - return(hash); + return hash; } while((c = *str++)) { hash = c + (hash << 6) + (hash << 16) - hash; } - return(hash); + return hash; } long _alpm_parsedate(const char *line) @@ -897,9 +895,9 @@ long _alpm_parsedate(const char *line) setlocale(LC_TIME, "C"); strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm); setlocale(LC_TIME, ""); - return(mktime(&tmp_tm)); + return mktime(&tmp_tm); } - return(atol(line)); + return atol(line); } #ifndef HAVE_STRNDUP @@ -908,7 +906,7 @@ static size_t strnlen(const char *s, size_t max) { register const char *p; for(p = s; *p && max--; ++p); - return(p - s); + return (p - s); } char *strndup(const char *s, size_t n) @@ -916,11 +914,11 @@ char *strndup(const char *s, size_t n) size_t len = strnlen(s, n); char *new = (char *) malloc(len + 1); - if (new == NULL) + if(new == NULL) return NULL; new[len] = '\0'; - return (char *) memcpy(new, s, len); + return (char *)memcpy(new, s, len); } #endif diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index c66e9881..c1a92a08 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -27,6 +27,7 @@ #include "config.h" #include "alpm_list.h" +#include "alpm.h" #include "package.h" /* pmpkg_t */ #include <stdio.h> @@ -36,6 +37,8 @@ #include <time.h> #include <sys/stat.h> /* struct stat */ #include <archive.h> /* struct archive */ +#include <math.h> /* fabs */ +#include <float.h> /* DBL_EPSILON */ #ifdef ENABLE_NLS #include <libintl.h> /* here so it doesn't need to be included elsewhere */ @@ -63,7 +66,9 @@ #define RET_ERR(err, ret) do { pm_errno = (err); \ _alpm_log(PM_LOG_DEBUG, "returning error %d from %s : %s\n", err, __func__, alpm_strerrorlast()); \ - return(ret); } while(0) + return (ret); } while(0) + +#define DOUBLE_EQ(x, y) (fabs((x) - (y)) < DBL_EPSILON) /** * Used as a buffer/state holder for _alpm_archive_fgets(). @@ -89,8 +94,8 @@ int _alpm_unpack_single(const char *archive, const char *prefix, const char *fn) int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int breakfirst); int _alpm_rmrf(const char *path); int _alpm_logaction(int usesyslog, FILE *f, const char *fmt, va_list args); -int _alpm_run_chroot(const char *root, const char *path, char *const argv[]); -int _alpm_ldconfig(const char *root); +int _alpm_run_chroot(pmhandle_t *handle, const char *path, char *const argv[]); +int _alpm_ldconfig(pmhandle_t *handle); int _alpm_str_cmp(const void *s1, const void *s2); char *_alpm_filecache_find(const char *filename); const char *_alpm_filecache_setup(void); @@ -113,6 +118,8 @@ char *strndup(const char *s, size_t n); #define SYMEXPORT __attribute__((visibility("default"))) #define SYMHIDDEN __attribute__((visibility("internal"))) +#define UNUSED __attribute__((unused)) + #endif /* _ALPM_UTIL_H */ /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/version.c b/lib/libalpm/version.c index eba66210..9f3a9b71 100644 --- a/lib/libalpm/version.c +++ b/lib/libalpm/version.c @@ -93,7 +93,7 @@ static int rpmvercmp(const char *a, const char *b) int ret = 0; /* easy comparison to see if versions are identical */ - if(strcmp(a, b) == 0) return(0); + if(strcmp(a, b) == 0) return 0; str1 = strdup(a); str2 = strdup(b); @@ -209,7 +209,7 @@ static int rpmvercmp(const char *a, const char *b) cleanup: free(str1); free(str2); - return(ret); + return ret; } /** Compare two version strings and determine which one is 'newer'. @@ -235,15 +235,15 @@ int SYMEXPORT alpm_pkg_vercmp(const char *a, const char *b) /* ensure our strings are not null */ if(!a && !b) { - return(0); + return 0; } else if(!a) { - return(-1); + return -1; } else if(!b) { - return(1); + return 1; } /* another quick shortcut- if full version specs are equal */ if(strcmp(a, b) == 0) { - return(0); + return 0; } /* Parse both versions into [epoch:]version[-release] triplets. We probably @@ -266,7 +266,7 @@ int SYMEXPORT alpm_pkg_vercmp(const char *a, const char *b) free(full1); free(full2); - return(ret); + return ret; } /* vim: set ts=2 sw=2 noet: */ |