diff options
Diffstat (limited to 'lib/libalpm')
54 files changed, 648 insertions, 435 deletions
diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am index 945a6121..f4f20e61 100644 --- a/lib/libalpm/Makefile.am +++ b/lib/libalpm/Makefile.am @@ -65,13 +65,15 @@ libalpm_la_CFLAGS = \ $(GPGME_CFLAGS) \ $(LIBARCHIVE_CFLAGS) \ $(LIBCURL_CFLAGS) \ - $(LIBSSL_CFLAGS) + $(LIBSSL_CFLAGS) \ + $(NETTLE_CFLAGS) libalpm_la_LIBADD = \ $(LTLIBINTL) \ $(GPGME_LIBS) \ $(LIBARCHIVE_LIBS) \ $(LIBCURL_LIBS) \ - $(LIBSSL_LIBS) + $(LIBSSL_LIBS) \ + $(NETTLE_LIBS) # vim:set noet: diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index d132e522..0beed01c 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -1,7 +1,7 @@ /* * add.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify @@ -110,6 +110,7 @@ static int perform_extraction(alpm_handle_t *handle, struct archive *archive, struct archive_entry *entry, const char *filename) { int ret; + struct archive *archive_writer; const int archive_flags = ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | @@ -118,7 +119,20 @@ static int perform_extraction(alpm_handle_t *handle, struct archive *archive, archive_entry_set_pathname(entry, filename); - ret = archive_read_extract(archive, entry, archive_flags); + archive_writer = archive_write_disk_new(); + if (archive_writer == NULL) { + _alpm_log(handle, ALPM_LOG_ERROR, _("cannot allocate disk archive object")); + alpm_logaction(handle, ALPM_CALLER_PREFIX, + "error: cannot allocate disk archive object"); + return 1; + } + + archive_write_disk_set_options(archive_writer, archive_flags); + + ret = archive_read_extract2(archive, entry, archive_writer); + + archive_write_free(archive_writer); + if(ret == ARCHIVE_WARN && archive_errno(archive) != ENOSPC) { /* operation succeeded but a "non-critical" error was encountered */ _alpm_log(handle, ALPM_LOG_WARNING, _("warning given when extracting %s (%s)\n"), @@ -405,6 +419,10 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg, alpm_event_package_operation_t event; const char *log_msg = "adding"; const char *pkgfile; + struct archive *archive; + struct archive_entry *entry; + int fd, cwdfd; + struct stat buf; ASSERT(trans != NULL, return -1); @@ -477,39 +495,44 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg, goto cleanup; } - if(!(trans->flags & ALPM_TRANS_FLAG_DBONLY)) { - struct archive *archive; - struct archive_entry *entry; - struct stat buf; - int fd, cwdfd; - - _alpm_log(handle, ALPM_LOG_DEBUG, "extracting files\n"); + fd = _alpm_open_archive(db->handle, pkgfile, &buf, + &archive, ALPM_ERR_PKG_OPEN); + if(fd < 0) { + ret = -1; + goto cleanup; + } - fd = _alpm_open_archive(db->handle, pkgfile, &buf, - &archive, ALPM_ERR_PKG_OPEN); - if(fd < 0) { - ret = -1; - goto cleanup; - } + /* save the cwd so we can restore it later */ + OPEN(cwdfd, ".", O_RDONLY | O_CLOEXEC); + if(cwdfd < 0) { + _alpm_log(handle, ALPM_LOG_ERROR, _("could not get current working directory\n")); + } - /* save the cwd so we can restore it later */ - OPEN(cwdfd, ".", O_RDONLY | O_CLOEXEC); - if(cwdfd < 0) { - _alpm_log(handle, ALPM_LOG_ERROR, _("could not get current working directory\n")); + /* libarchive requires this for extracting hard links */ + if(chdir(handle->root) != 0) { + _alpm_log(handle, ALPM_LOG_ERROR, _("could not change directory to %s (%s)\n"), + handle->root, strerror(errno)); + _alpm_archive_read_free(archive); + if(cwdfd >= 0) { + close(cwdfd); } + close(fd); + ret = -1; + goto cleanup; + } - /* libarchive requires this for extracting hard links */ - if(chdir(handle->root) != 0) { - _alpm_log(handle, ALPM_LOG_ERROR, _("could not change directory to %s (%s)\n"), - handle->root, strerror(errno)); - _alpm_archive_read_free(archive); - if(cwdfd >= 0) { - close(cwdfd); + if(trans->flags & ALPM_TRANS_FLAG_DBONLY) { + _alpm_log(handle, ALPM_LOG_DEBUG, "extracting db files\n"); + while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) { + const char *entryname = archive_entry_pathname(entry); + if(entryname[0] == '.') { + errors += extract_db_file(handle, archive, entry, newpkg, entryname); + } else { + archive_read_data_skip(archive); } - close(fd); - ret = -1; - goto cleanup; } + } else { + _alpm_log(handle, ALPM_LOG_DEBUG, "extracting files\n"); /* call PROGRESS once with 0 percent, as we sort-of skip that here */ PROGRESS(handle, progress, newpkg->name, 0, pkg_count, pkg_current); @@ -535,33 +558,34 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg, /* extract the next file from the archive */ errors += extract_single_file(handle, archive, entry, newpkg, oldpkg); } - _alpm_archive_read_free(archive); - close(fd); + } - /* restore the old cwd if we have it */ - if(cwdfd >= 0) { - if(fchdir(cwdfd) != 0) { - _alpm_log(handle, ALPM_LOG_ERROR, - _("could not restore working directory (%s)\n"), strerror(errno)); - } - close(cwdfd); + _alpm_archive_read_free(archive); + close(fd); + + /* restore the old cwd if we have it */ + if(cwdfd >= 0) { + if(fchdir(cwdfd) != 0) { + _alpm_log(handle, ALPM_LOG_ERROR, + _("could not restore working directory (%s)\n"), strerror(errno)); } + close(cwdfd); + } - if(errors) { - ret = -1; - if(is_upgrade) { - _alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while upgrading %s\n"), - newpkg->name); - alpm_logaction(handle, ALPM_CALLER_PREFIX, - "error: problem occurred while upgrading %s\n", - newpkg->name); - } else { - _alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while installing %s\n"), - newpkg->name); - alpm_logaction(handle, ALPM_CALLER_PREFIX, - "error: problem occurred while installing %s\n", - newpkg->name); - } + if(errors) { + ret = -1; + if(is_upgrade) { + _alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while upgrading %s\n"), + newpkg->name); + alpm_logaction(handle, ALPM_CALLER_PREFIX, + "error: problem occurred while upgrading %s\n", + newpkg->name); + } else { + _alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while installing %s\n"), + newpkg->name); + alpm_logaction(handle, ALPM_CALLER_PREFIX, + "error: problem occurred while installing %s\n", + newpkg->name); } } diff --git a/lib/libalpm/add.h b/lib/libalpm/add.h index c1ab62a2..d30f9b0b 100644 --- a/lib/libalpm/add.h +++ b/lib/libalpm/add.h @@ -1,7 +1,7 @@ /* * add.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index 6b7fa7a9..d3f951d5 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -1,7 +1,7 @@ /* * alpm.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> @@ -152,7 +152,7 @@ const char SYMEXPORT *alpm_version(void) /** Get the capabilities of the library. * @return a bitmask of the capabilities * */ -enum alpm_caps SYMEXPORT alpm_capabilities(void) +int SYMEXPORT alpm_capabilities(void) { return 0 #ifdef ENABLE_NLS diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 7955585a..2637a055 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -1,7 +1,7 @@ /* * alpm.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> @@ -53,7 +53,8 @@ typedef struct __alpm_trans_t alpm_trans_t; * @{ */ typedef enum _alpm_errno_t { - ALPM_ERR_MEMORY = 1, + ALPM_ERR_OK = 0, + ALPM_ERR_MEMORY, ALPM_ERR_SYSTEM, ALPM_ERR_BADPERMS, ALPM_ERR_NOT_A_FILE, @@ -829,6 +830,11 @@ int alpm_option_add_hookdir(alpm_handle_t *handle, const char *hookdir); int alpm_option_remove_hookdir(alpm_handle_t *handle, const char *hookdir); /** @} */ +alpm_list_t *alpm_option_get_overwrite_files(alpm_handle_t *handle); +int alpm_option_set_overwrite_files(alpm_handle_t *handle, alpm_list_t *globs); +int alpm_option_add_overwrite_file(alpm_handle_t *handle, const char *glob); +int alpm_option_remove_overwrite_file(alpm_handle_t *handle, const char *glob); + /** Returns the logfile name. */ const char *alpm_option_get_logfile(alpm_handle_t *handle); /** Sets the logfile name. */ @@ -916,14 +922,16 @@ int alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace); const char *alpm_option_get_dbext(alpm_handle_t *handle); int alpm_option_set_dbext(alpm_handle_t *handle, const char *dbext); -alpm_siglevel_t alpm_option_get_default_siglevel(alpm_handle_t *handle); -int alpm_option_set_default_siglevel(alpm_handle_t *handle, alpm_siglevel_t level); +int alpm_option_get_default_siglevel(alpm_handle_t *handle); +int alpm_option_set_default_siglevel(alpm_handle_t *handle, int level); + +int alpm_option_get_local_file_siglevel(alpm_handle_t *handle); +int alpm_option_set_local_file_siglevel(alpm_handle_t *handle, int level); -alpm_siglevel_t alpm_option_get_local_file_siglevel(alpm_handle_t *handle); -int alpm_option_set_local_file_siglevel(alpm_handle_t *handle, alpm_siglevel_t level); +int alpm_option_get_remote_file_siglevel(alpm_handle_t *handle); +int alpm_option_set_remote_file_siglevel(alpm_handle_t *handle, int level); -alpm_siglevel_t alpm_option_get_remote_file_siglevel(alpm_handle_t *handle); -int alpm_option_set_remote_file_siglevel(alpm_handle_t *handle, alpm_siglevel_t level); +int alpm_option_set_disable_dl_timeout(alpm_handle_t *handle, unsigned short disable_dl_timeout); /** @} */ @@ -956,7 +964,7 @@ alpm_list_t *alpm_get_syncdbs(alpm_handle_t *handle); * @return an alpm_db_t* on success (the value), NULL on error */ alpm_db_t *alpm_register_syncdb(alpm_handle_t *handle, const char *treename, - alpm_siglevel_t level); + int level); /** Unregister all package databases. * @param handle the context handle @@ -982,7 +990,7 @@ const char *alpm_db_get_name(const alpm_db_t *db); * @param db pointer to the package database * @return the signature verification level */ -alpm_siglevel_t alpm_db_get_siglevel(alpm_db_t *db); +int alpm_db_get_siglevel(alpm_db_t *db); /** Check the validity of a database. * This is most useful for sync databases and verifying signature status. @@ -1049,14 +1057,14 @@ typedef enum _alpm_db_usage_ { * @param usage a bitmask of alpm_db_usage_t values * @return 0 on success, or -1 on error */ -int alpm_db_set_usage(alpm_db_t *db, alpm_db_usage_t usage); +int alpm_db_set_usage(alpm_db_t *db, int usage); /** Gets the usage of a database. * @param db pointer to the package database to get the status of * @param usage pointer to an alpm_db_usage_t to store db's status * @return 0 on success, or -1 on error */ -int alpm_db_get_usage(alpm_db_t *db, alpm_db_usage_t *usage); +int alpm_db_get_usage(alpm_db_t *db, int *usage); /** @} */ @@ -1080,7 +1088,7 @@ int alpm_db_get_usage(alpm_db_t *db, alpm_db_usage_t *usage); * @return 0 on success, -1 on error (pm_errno is set accordingly) */ int alpm_pkg_load(alpm_handle_t *handle, const char *filename, int full, - alpm_siglevel_t level, alpm_pkg_t **pkg); + int level, alpm_pkg_t **pkg); /** Find a package in a list by name. * @param haystack a list of alpm_pkg_t @@ -1260,6 +1268,18 @@ alpm_list_t *alpm_pkg_get_depends(alpm_pkg_t *pkg); */ alpm_list_t *alpm_pkg_get_optdepends(alpm_pkg_t *pkg); +/** Returns a list of package check dependencies + * @param pkg a pointer to package + * @return a reference to an internal list of alpm_depend_t structures. + */ +alpm_list_t *alpm_pkg_get_checkdepends(alpm_pkg_t *pkg); + +/** Returns a list of package make dependencies + * @param pkg a pointer to package + * @return a reference to an internal list of alpm_depend_t structures. + */ +alpm_list_t *alpm_pkg_get_makedepends(alpm_pkg_t *pkg); + /** Returns the list of packages conflicting with pkg. * @param pkg a pointer to package * @return a reference to an internal list of alpm_depend_t structures. @@ -1317,7 +1337,7 @@ const char *alpm_pkg_get_base64_sig(alpm_pkg_t *pkg); * @param pkg a pointer to package * @return an enum member giving the validation method */ -alpm_pkgvalidation_t alpm_pkg_get_validation(alpm_pkg_t *pkg); +int alpm_pkg_get_validation(alpm_pkg_t *pkg); /* End of alpm_pkg_t accessors */ /* @} */ @@ -1479,7 +1499,7 @@ typedef enum _alpm_transflag_t { * @param handle the context handle * @return the bitfield of transaction flags */ -alpm_transflag_t alpm_trans_get_flags(alpm_handle_t *handle); +int alpm_trans_get_flags(alpm_handle_t *handle); /** Returns a list of packages added by the transaction. * @param handle the context handle @@ -1495,10 +1515,10 @@ alpm_list_t *alpm_trans_get_remove(alpm_handle_t *handle); /** Initialize the transaction. * @param handle the context handle - * @param flags flags of the transaction (like nodeps, etc) + * @param flags flags of the transaction (like nodeps, etc; see alpm_transflag_t) * @return 0 on success, -1 on error (pm_errno is set accordingly) */ -int alpm_trans_init(alpm_handle_t *handle, alpm_transflag_t flags); +int alpm_trans_init(alpm_handle_t *handle, int flags); /** Prepare a transaction. * @param handle the context handle @@ -1612,7 +1632,8 @@ enum alpm_caps { }; const char *alpm_version(void); -enum alpm_caps alpm_capabilities(void); +/* Return a bitfield of capabilities using values from 'enum alpm_caps' */ +int alpm_capabilities(void); void alpm_fileconflict_free(alpm_fileconflict_t *conflict); void alpm_depmissing_free(alpm_depmissing_t *miss); diff --git a/lib/libalpm/alpm_list.c b/lib/libalpm/alpm_list.c index f3effc72..0f1b819c 100644 --- a/lib/libalpm/alpm_list.c +++ b/lib/libalpm/alpm_list.c @@ -1,7 +1,7 @@ /* * alpm_list.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify @@ -132,6 +132,26 @@ alpm_list_t SYMEXPORT *alpm_list_append(alpm_list_t **list, void *data) } /** + * @brief Duplicate and append a string to a list. + * + * @param list the list to append to + * @param data the string to duplicate and append + * + * @return the newly added item + */ +alpm_list_t SYMEXPORT *alpm_list_append_strdup(alpm_list_t **list, const char *data) +{ + alpm_list_t *ret; + char *dup; + if((dup = strdup(data)) && (ret = alpm_list_append(list, dup))) { + return ret; + } else { + free(dup); + return NULL; + } +} + +/** * @brief Add items to a list in sorted order. * * @param list the list to add to diff --git a/lib/libalpm/alpm_list.h b/lib/libalpm/alpm_list.h index cf7d463f..1cb237d0 100644 --- a/lib/libalpm/alpm_list.h +++ b/lib/libalpm/alpm_list.h @@ -1,7 +1,7 @@ /* * alpm_list.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify @@ -58,6 +58,7 @@ void alpm_list_free_inner(alpm_list_t *list, alpm_list_fn_free fn); /* item mutators */ alpm_list_t *alpm_list_add(alpm_list_t *list, void *data); alpm_list_t *alpm_list_append(alpm_list_t **list, void *data); +alpm_list_t *alpm_list_append_strdup(alpm_list_t **list, const char *data); alpm_list_t *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_list_fn_cmp fn); alpm_list_t *alpm_list_join(alpm_list_t *first, alpm_list_t *second); alpm_list_t *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, alpm_list_fn_cmp fn); diff --git a/lib/libalpm/backup.c b/lib/libalpm/backup.c index 50bad5e6..f00440f0 100644 --- a/lib/libalpm/backup.c +++ b/lib/libalpm/backup.c @@ -1,7 +1,7 @@ /* * backup.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2005 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> diff --git a/lib/libalpm/backup.h b/lib/libalpm/backup.h index 5cf3f90a..17ff9ae0 100644 --- a/lib/libalpm/backup.h +++ b/lib/libalpm/backup.h @@ -1,7 +1,7 @@ /* * backup.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index 43c6bc93..97a49688 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -1,7 +1,7 @@ /* * be_local.c : backend for the local database * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify @@ -47,9 +47,9 @@ /* local database format version */ size_t ALPM_LOCAL_DB_VERSION = 9; -static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq); +static int local_db_read(alpm_pkg_t *info, int inforeq); -#define LAZY_LOAD(info, errret) \ +#define LAZY_LOAD(info) \ do { \ if(!(pkg->infolevel & info)) { \ local_db_read(pkg, info); \ @@ -65,121 +65,121 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq); static const char *_cache_get_base(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, NULL); + LAZY_LOAD(INFRQ_DESC); return pkg->base; } static const char *_cache_get_desc(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, NULL); + LAZY_LOAD(INFRQ_DESC); return pkg->desc; } static const char *_cache_get_url(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, NULL); + LAZY_LOAD(INFRQ_DESC); return pkg->url; } static alpm_time_t _cache_get_builddate(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, 0); + LAZY_LOAD(INFRQ_DESC); return pkg->builddate; } static alpm_time_t _cache_get_installdate(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, 0); + LAZY_LOAD(INFRQ_DESC); return pkg->installdate; } static const char *_cache_get_packager(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, NULL); + LAZY_LOAD(INFRQ_DESC); return pkg->packager; } static const char *_cache_get_arch(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, NULL); + LAZY_LOAD(INFRQ_DESC); return pkg->arch; } static off_t _cache_get_isize(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, -1); + LAZY_LOAD(INFRQ_DESC); return pkg->isize; } static alpm_pkgreason_t _cache_get_reason(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, -1); + LAZY_LOAD(INFRQ_DESC); return pkg->reason; } -static alpm_pkgvalidation_t _cache_get_validation(alpm_pkg_t *pkg) +static int _cache_get_validation(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, -1); + LAZY_LOAD(INFRQ_DESC); return pkg->validation; } static alpm_list_t *_cache_get_licenses(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, NULL); + LAZY_LOAD(INFRQ_DESC); return pkg->licenses; } static alpm_list_t *_cache_get_groups(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, NULL); + LAZY_LOAD(INFRQ_DESC); return pkg->groups; } static int _cache_has_scriptlet(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_SCRIPTLET, NULL); + LAZY_LOAD(INFRQ_SCRIPTLET); return pkg->scriptlet; } static alpm_list_t *_cache_get_depends(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, NULL); + LAZY_LOAD(INFRQ_DESC); return pkg->depends; } static alpm_list_t *_cache_get_optdepends(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, NULL); + LAZY_LOAD(INFRQ_DESC); return pkg->optdepends; } static alpm_list_t *_cache_get_conflicts(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, NULL); + LAZY_LOAD(INFRQ_DESC); return pkg->conflicts; } static alpm_list_t *_cache_get_provides(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, NULL); + LAZY_LOAD(INFRQ_DESC); return pkg->provides; } static alpm_list_t *_cache_get_replaces(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_DESC, NULL); + LAZY_LOAD(INFRQ_DESC); return pkg->replaces; } static alpm_filelist_t *_cache_get_files(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_FILES, NULL); + LAZY_LOAD(INFRQ_FILES); return &(pkg->files); } static alpm_list_t *_cache_get_backup(alpm_pkg_t *pkg) { - LAZY_LOAD(INFRQ_FILES, NULL); + LAZY_LOAD(INFRQ_FILES); return pkg->backup; } @@ -660,7 +660,7 @@ char *_alpm_local_db_pkgpath(alpm_db_t *db, alpm_pkg_t *info, f = alpm_list_add(f, alpm_dep_from_string(line)); \ } while(1) /* note the while(1) and not (0) */ -static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq) +static int local_db_read(alpm_pkg_t *info, int inforeq) { FILE *fp = NULL; char line[1024]; @@ -817,14 +817,12 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq) if(newfiles != NULL) { files = newfiles; } - - /* make sure the list is sorted */ - qsort(files, files_count, sizeof(alpm_file_t), _alpm_files_cmp); } else { FREE(files); } info->files.count = files_count; info->files.files = files; + _alpm_filelist_sort(&info->files); continue; nomem: while(files_count > 0) { @@ -910,7 +908,7 @@ static void write_deps(FILE *fp, const char *header, alpm_list_t *deplist) fputc('\n', fp); } -int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq) +int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, int inforeq) { FILE *fp = NULL; mode_t oldmask; diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index 430d2aeb..7e8b7920 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -1,7 +1,7 @@ /* * be_package.c : backend for packages * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify @@ -223,9 +223,11 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t * alpm_depend_t *optdep = alpm_dep_from_string(ptr); newpkg->optdepends = alpm_list_add(newpkg->optdepends, optdep); } else if(strcmp(key, "makedepend") == 0) { - /* not used atm */ + alpm_depend_t *makedep = alpm_dep_from_string(ptr); + newpkg->makedepends = alpm_list_add(newpkg->makedepends, makedep); } else if(strcmp(key, "checkdepend") == 0) { - /* not used atm */ + alpm_depend_t *checkdep = alpm_dep_from_string(ptr); + newpkg->checkdepends = alpm_list_add(newpkg->checkdepends, checkdep); } else if(strcmp(key, "conflict") == 0) { alpm_depend_t *conflict = alpm_dep_from_string(ptr); newpkg->conflicts = alpm_list_add(newpkg->conflicts, conflict); @@ -270,11 +272,11 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t * * @return 0 if package is fully valid, -1 and pm_errno otherwise */ int _alpm_pkg_validate_internal(alpm_handle_t *handle, - const char *pkgfile, alpm_pkg_t *syncpkg, alpm_siglevel_t level, - alpm_siglist_t **sigdata, alpm_pkgvalidation_t *validation) + const char *pkgfile, alpm_pkg_t *syncpkg, int level, + alpm_siglist_t **sigdata, int *validation) { int has_sig; - handle->pm_errno = 0; + handle->pm_errno = ALPM_ERR_OK; if(pkgfile == NULL || strlen(pkgfile) == 0) { RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1); @@ -676,8 +678,7 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, _alpm_log(handle, ALPM_LOG_DEBUG, "sorting package filelist for %s\n", pkgfile); - qsort(newpkg->files.files, newpkg->files.count, - sizeof(alpm_file_t), _alpm_files_cmp); + _alpm_filelist_sort(&newpkg->files); } newpkg->infolevel |= INFRQ_FILES; } @@ -726,9 +727,9 @@ static int read_sigfile(const char *sigpath, unsigned char **sig) } int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int full, - alpm_siglevel_t level, alpm_pkg_t **pkg) + int level, alpm_pkg_t **pkg) { - alpm_pkgvalidation_t validation = 0; + int validation = 0; char *sigpath; CHECK_HANDLE(handle, return -1); diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index a8362778..5f7d31ab 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -1,7 +1,7 @@ /* * be_sync.c : backend for sync databases * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify @@ -71,7 +71,7 @@ static char *get_sync_dir(alpm_handle_t *handle) static int sync_db_validate(alpm_db_t *db) { - alpm_siglevel_t level; + int siglevel; const char *dbpath; if(db->status & DB_STATUS_VALID || db->status & DB_STATUS_MISSING) { @@ -104,20 +104,20 @@ static int sync_db_validate(alpm_db_t *db) /* this takes into account the default verification level if UNKNOWN * was assigned to this db */ - level = alpm_db_get_siglevel(db); + siglevel = alpm_db_get_siglevel(db); - if(level & ALPM_SIG_DATABASE) { + if(siglevel & ALPM_SIG_DATABASE) { int retry, ret; do { retry = 0; alpm_siglist_t *siglist; ret = _alpm_check_pgp_helper(db->handle, dbpath, NULL, - level & ALPM_SIG_DATABASE_OPTIONAL, level & ALPM_SIG_DATABASE_MARGINAL_OK, - level & ALPM_SIG_DATABASE_UNKNOWN_OK, &siglist); + siglevel & ALPM_SIG_DATABASE_OPTIONAL, siglevel & ALPM_SIG_DATABASE_MARGINAL_OK, + siglevel & ALPM_SIG_DATABASE_UNKNOWN_OK, &siglist); if(ret) { retry = _alpm_process_siglist(db->handle, db->treename, siglist, - level & ALPM_SIG_DATABASE_OPTIONAL, level & ALPM_SIG_DATABASE_MARGINAL_OK, - level & ALPM_SIG_DATABASE_UNKNOWN_OK); + siglevel & ALPM_SIG_DATABASE_OPTIONAL, siglevel & ALPM_SIG_DATABASE_MARGINAL_OK, + siglevel & ALPM_SIG_DATABASE_UNKNOWN_OK); } alpm_siglist_cleanup(siglist); free(siglist); @@ -181,12 +181,12 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) int ret = -1; mode_t oldmask; alpm_handle_t *handle; - alpm_siglevel_t level; + int siglevel; /* Sanity checks */ ASSERT(db != NULL, return -1); handle = db->handle; - handle->pm_errno = 0; + handle->pm_errno = ALPM_ERR_OK; ASSERT(db != handle->db_local, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1)); ASSERT(db->servers != NULL, RET_ERR(handle, ALPM_ERR_SERVER_NONE, -1)); @@ -207,7 +207,7 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) /* make sure we have a sane umask */ oldmask = umask(0022); - level = alpm_db_get_siglevel(db); + siglevel = alpm_db_get_siglevel(db); /* attempt to grab a lock */ if(_alpm_handle_lock(handle)) { @@ -247,7 +247,7 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) _alpm_dload_payload_reset(&payload); updated = (updated || ret == 0); - if(ret != -1 && updated && (level & ALPM_SIG_DATABASE)) { + if(ret != -1 && updated && (siglevel & ALPM_SIG_DATABASE)) { /* an existing sig file is no good at this point */ char *sigpath = _alpm_sigpath(handle, _alpm_db_path(db)); if(!sigpath) { @@ -292,7 +292,7 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) payload.handle = handle; payload.force = 1; - payload.errors_ok = (level & ALPM_SIG_DATABASE_OPTIONAL); + payload.errors_ok = (siglevel & ALPM_SIG_DATABASE_OPTIONAL); /* set hard upper limit of 16KiB */ payload.max_size = 16 * 1024; @@ -330,7 +330,7 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) _alpm_log(handle, ALPM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerror(handle->pm_errno)); } else { - handle->pm_errno = 0; + handle->pm_errno = ALPM_ERR_OK; } _alpm_handle_unlock(handle); @@ -343,7 +343,7 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) static int sync_db_read(alpm_db_t *db, struct archive *archive, struct archive_entry *entry, alpm_pkg_t **likely_pkg); -static alpm_pkgvalidation_t _sync_get_validation(alpm_pkg_t *pkg) +static int _sync_get_validation(alpm_pkg_t *pkg) { if(pkg->validation) { return pkg->validation; @@ -735,13 +735,12 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive, /* attempt to hand back any memory we don't need */ if(files_count > 0) { files = realloc(files, sizeof(alpm_file_t) * files_count); - /* make sure the list is sorted */ - qsort(files, files_count, sizeof(alpm_file_t), _alpm_files_cmp); } else { FREE(files); } pkg->files.count = files_count; pkg->files.files = files; + _alpm_filelist_sort(&pkg->files); } } if(ret != ARCHIVE_EOF) { @@ -769,7 +768,7 @@ struct db_operations sync_db_ops = { }; alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename, - alpm_siglevel_t level) + int level) { alpm_db_t *db; diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index 092b019a..d52f8942 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -1,7 +1,7 @@ /* * conflict.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2006 by David Kimpe <dnaku@frugalware.org> @@ -278,12 +278,15 @@ static alpm_list_t *add_fileconflict(alpm_handle_t *handle, STRDUP(conflict->target, pkg1->name, goto error); STRDUP(conflict->file, filestr, goto error); - if(pkg2) { - conflict->type = ALPM_FILECONFLICT_TARGET; - STRDUP(conflict->ctarget, pkg2->name, goto error); - } else { + if(!pkg2) { conflict->type = ALPM_FILECONFLICT_FILESYSTEM; STRDUP(conflict->ctarget, "", goto error); + } else if(pkg2->origin == ALPM_PKG_FROM_LOCALDB) { + conflict->type = ALPM_FILECONFLICT_FILESYSTEM; + STRDUP(conflict->ctarget, pkg2->name, goto error); + } else { + conflict->type = ALPM_FILECONFLICT_TARGET; + STRDUP(conflict->ctarget, pkg2->name, goto error); } conflicts = alpm_list_add(conflicts, conflict); @@ -385,6 +388,23 @@ static alpm_list_t *alpm_db_find_file_owners(alpm_db_t* db, const char *path) return owners; } +static alpm_pkg_t *_alpm_find_file_owner(alpm_handle_t *handle, const char *path) +{ + alpm_list_t *i; + for(i = alpm_db_get_pkgcache(handle->db_local); i; i = i->next) { + if(alpm_filelist_contains(alpm_pkg_get_files(i->data), path)) { + return i->data; + } + } + return NULL; +} + +static int _alpm_can_overwrite_file(alpm_handle_t *handle, const char *path) +{ + return handle->trans->flags & ALPM_TRANS_FLAG_FORCE + || _alpm_fnmatch_patterns(handle->overwrite_files, path) == 0; +} + /** * @brief Find file conflicts that may occur during the transaction. * @@ -419,7 +439,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, for(current = 0, i = upgrade; i; i = i->next, current++) { alpm_pkg_t *p1 = i->data; alpm_list_t *j; - alpm_list_t *tmpfiles = NULL; + alpm_list_t *newfiles = NULL; alpm_pkg_t *dbpkg; int percent = (current * 100) / numtargs; @@ -448,8 +468,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, /* can skip file-file conflicts when forced * * checking presence in p2_files detects dir-file or file-dir * conflicts as the path from p1 is returned */ - if((handle->trans->flags & ALPM_TRANS_FLAG_FORCE) && - alpm_filelist_contains(p2_files, filename)) { + if(_alpm_can_overwrite_file(handle, filename) + && alpm_filelist_contains(p2_files, filename)) { _alpm_log(handle, ALPM_LOG_DEBUG, "%s exists in both '%s' and '%s'\n", filename, p1->name, p2->name); @@ -483,18 +503,18 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, * be freed. */ if(dbpkg) { /* older ver of package currently installed */ - tmpfiles = _alpm_filelist_difference(alpm_pkg_get_files(p1), + newfiles = _alpm_filelist_difference(alpm_pkg_get_files(p1), alpm_pkg_get_files(dbpkg)); } else { /* no version of package currently installed */ alpm_filelist_t *fl = alpm_pkg_get_files(p1); size_t filenum; for(filenum = 0; filenum < fl->count; filenum++) { - tmpfiles = alpm_list_add(tmpfiles, fl->files[filenum].name); + newfiles = alpm_list_add(newfiles, fl->files[filenum].name); } } - for(j = tmpfiles; j; j = j->next) { + for(j = newfiles; j; j = j->next) { const char *filestr = j->data; const char *relative_path; alpm_list_t *k; @@ -503,6 +523,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, struct stat lsbuf; char path[PATH_MAX]; size_t pathlen; + int pfile_isdir; pathlen = snprintf(path, PATH_MAX, "%s%s", handle->root, filestr); relative_path = path + rootlen; @@ -514,7 +535,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, _alpm_log(handle, ALPM_LOG_DEBUG, "checking possible conflict: %s\n", path); - if(path[pathlen - 1] == '/') { + pfile_isdir = path[pathlen - 1] == '/'; + if(pfile_isdir) { if(S_ISDIR(lsbuf.st_mode)) { _alpm_log(handle, ALPM_LOG_DEBUG, "file is a directory, not a conflict\n"); continue; @@ -551,6 +573,18 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, _alpm_log(handle, ALPM_LOG_DEBUG, "local file will be removed, not a conflict\n"); resolved_conflict = 1; + if(pfile_isdir) { + /* go ahead and skip any files inside filestr as they will + * necessarily be resolved by replacing the file with a dir + * NOTE: afterward, j will point to the last file inside filestr */ + size_t fslen = strlen(filestr); + for( ; j->next; j = j->next) { + const char *filestr2 = j->next->data; + if(strncmp(filestr, filestr2, fslen) != 0) { + break; + } + } + } } } @@ -640,25 +674,26 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, } /* skip file-file conflicts when being forced */ - if((handle->trans->flags & ALPM_TRANS_FLAG_FORCE) && - !S_ISDIR(lsbuf.st_mode)) { + if(!S_ISDIR(lsbuf.st_mode) + && _alpm_can_overwrite_file(handle, filestr)) { _alpm_log(handle, ALPM_LOG_DEBUG, "conflict with file on filesystem being forced\n"); resolved_conflict = 1; } if(!resolved_conflict) { - conflicts = add_fileconflict(handle, conflicts, path, p1, NULL); + conflicts = add_fileconflict(handle, conflicts, path, p1, + _alpm_find_file_owner(handle, relative_path)); if(handle->pm_errno == ALPM_ERR_MEMORY) { alpm_list_free_inner(conflicts, (alpm_list_fn_free) alpm_conflict_free); alpm_list_free(conflicts); - alpm_list_free(tmpfiles); + alpm_list_free(newfiles); return NULL; } } } - alpm_list_free(tmpfiles); + alpm_list_free(newfiles); } PROGRESS(handle, ALPM_PROGRESS_CONFLICTS_START, "", 100, numtargs, current); diff --git a/lib/libalpm/conflict.h b/lib/libalpm/conflict.h index 801c201c..a2ae332d 100644 --- a/lib/libalpm/conflict.h +++ b/lib/libalpm/conflict.h @@ -1,7 +1,7 @@ /* * conflict.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index f70f83c1..789478e8 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -1,7 +1,7 @@ /* * db.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> @@ -44,7 +44,7 @@ /** Register a sync database of packages. */ alpm_db_t SYMEXPORT *alpm_register_syncdb(alpm_handle_t *handle, - const char *treename, alpm_siglevel_t level) + const char *treename, int siglevel) { alpm_list_t *i; @@ -67,7 +67,7 @@ alpm_db_t SYMEXPORT *alpm_register_syncdb(alpm_handle_t *handle, } } - return _alpm_db_register_sync(handle, treename, level); + return _alpm_db_register_sync(handle, treename, siglevel); } /* Helper function for alpm_db_unregister{_all} */ @@ -112,7 +112,7 @@ int SYMEXPORT alpm_db_unregister(alpm_db_t *db) ASSERT(db != NULL, return -1); /* Do not unregister a database if a transaction is on-going */ handle = db->handle; - handle->pm_errno = 0; + handle->pm_errno = ALPM_ERR_OK; ASSERT(handle->trans == NULL, RET_ERR(handle, ALPM_ERR_TRANS_NOT_NULL, -1)); if(db == handle->db_local) { @@ -179,7 +179,7 @@ int SYMEXPORT alpm_db_add_server(alpm_db_t *db, const char *url) /* Sanity checks */ ASSERT(db != NULL, return -1); - db->handle->pm_errno = 0; + db->handle->pm_errno = ALPM_ERR_OK; ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1)); newurl = sanitize_url(url); @@ -206,7 +206,7 @@ int SYMEXPORT alpm_db_remove_server(alpm_db_t *db, const char *url) /* Sanity checks */ ASSERT(db != NULL, return -1); - db->handle->pm_errno = 0; + db->handle->pm_errno = ALPM_ERR_OK; ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1)); newurl = sanitize_url(url); @@ -235,7 +235,7 @@ const char SYMEXPORT *alpm_db_get_name(const alpm_db_t *db) } /** Get the signature verification level for a database. */ -alpm_siglevel_t SYMEXPORT alpm_db_get_siglevel(alpm_db_t *db) +int SYMEXPORT alpm_db_get_siglevel(alpm_db_t *db) { ASSERT(db != NULL, return -1); if(db->siglevel & ALPM_SIG_USE_DEFAULT) { @@ -249,7 +249,7 @@ alpm_siglevel_t SYMEXPORT alpm_db_get_siglevel(alpm_db_t *db) int SYMEXPORT alpm_db_get_valid(alpm_db_t *db) { ASSERT(db != NULL, return -1); - db->handle->pm_errno = 0; + db->handle->pm_errno = ALPM_ERR_OK; return db->ops->validate(db); } @@ -258,7 +258,7 @@ alpm_pkg_t SYMEXPORT *alpm_db_get_pkg(alpm_db_t *db, const char *name) { alpm_pkg_t *pkg; ASSERT(db != NULL, return NULL); - db->handle->pm_errno = 0; + db->handle->pm_errno = ALPM_ERR_OK; ASSERT(name != NULL && strlen(name) != 0, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, NULL)); @@ -273,7 +273,7 @@ alpm_pkg_t SYMEXPORT *alpm_db_get_pkg(alpm_db_t *db, const char *name) alpm_list_t SYMEXPORT *alpm_db_get_pkgcache(alpm_db_t *db) { ASSERT(db != NULL, return NULL); - db->handle->pm_errno = 0; + db->handle->pm_errno = ALPM_ERR_OK; return _alpm_db_get_pkgcache(db); } @@ -292,7 +292,7 @@ alpm_group_t SYMEXPORT *alpm_db_get_group(alpm_db_t *db, const char *name) alpm_list_t SYMEXPORT *alpm_db_get_groupcache(alpm_db_t *db) { ASSERT(db != NULL, return NULL); - db->handle->pm_errno = 0; + db->handle->pm_errno = ALPM_ERR_OK; return _alpm_db_get_groupcache(db); } @@ -301,13 +301,13 @@ alpm_list_t SYMEXPORT *alpm_db_get_groupcache(alpm_db_t *db) alpm_list_t SYMEXPORT *alpm_db_search(alpm_db_t *db, const alpm_list_t *needles) { ASSERT(db != NULL, return NULL); - db->handle->pm_errno = 0; + db->handle->pm_errno = ALPM_ERR_OK; return _alpm_db_search(db, needles); } /** Sets the usage bitmask for a repo */ -int SYMEXPORT alpm_db_set_usage(alpm_db_t *db, alpm_db_usage_t usage) +int SYMEXPORT alpm_db_set_usage(alpm_db_t *db, int usage) { ASSERT(db != NULL, return -1); db->usage = usage; @@ -315,7 +315,7 @@ int SYMEXPORT alpm_db_set_usage(alpm_db_t *db, alpm_db_usage_t usage) } /** Gets the usage bitmask for a repo */ -int SYMEXPORT alpm_db_get_usage(alpm_db_t *db, alpm_db_usage_t *usage) +int SYMEXPORT alpm_db_get_usage(alpm_db_t *db, int *usage) { ASSERT(db != NULL, return -1); ASSERT(usage != NULL, return -1); diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h index e6962985..e1c47d32 100644 --- a/lib/libalpm/db.h +++ b/lib/libalpm/db.h @@ -1,7 +1,7 @@ /* * db.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> @@ -71,10 +71,14 @@ struct __alpm_db_t { alpm_list_t *grpcache; alpm_list_t *servers; struct db_operations *ops; - /* flags determining validity, local, loaded caches, etc. */ - enum _alpm_dbstatus_t status; - alpm_siglevel_t siglevel; - alpm_db_usage_t usage; + + /* bitfields for validity, local, loaded caches, etc. */ + /* From _alpm_dbstatus_t */ + int status; + /* alpm_siglevel_t */ + int siglevel; + /* alpm_db_usage_t */ + int usage; }; @@ -86,12 +90,12 @@ int _alpm_db_cmp(const void *d1, const void *d2); alpm_list_t *_alpm_db_search(alpm_db_t *db, const alpm_list_t *needles); alpm_db_t *_alpm_db_register_local(alpm_handle_t *handle); alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename, - alpm_siglevel_t level); + int level); void _alpm_db_unregister(alpm_db_t *db); /* be_*.c, backend specific calls */ int _alpm_local_db_prepare(alpm_db_t *db, alpm_pkg_t *info); -int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq); +int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, int inforeq); int _alpm_local_db_remove(alpm_db_t *db, alpm_pkg_t *info); char *_alpm_local_db_pkgpath(alpm_db_t *db, alpm_pkg_t *info, const char *filename); diff --git a/lib/libalpm/delta.c b/lib/libalpm/delta.c index 6d6de056..89bc32ff 100644 --- a/lib/libalpm/delta.c +++ b/lib/libalpm/delta.c @@ -1,7 +1,7 @@ /* * delta.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2007-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify @@ -71,7 +71,7 @@ static alpm_list_t *graph_init(alpm_list_t *deltas, int reverse) v_i->children = alpm_list_add(v_i->children, v_j); } } - v_i->childptr = v_i->children; + v_i->iterator = v_i->children; } return vertices; } @@ -130,7 +130,7 @@ static void dijkstra(alpm_list_t *vertices) for(i = vertices; i; i = i->next) { alpm_graph_t *v_i = i->data; - if(v_i->state == -1) { + if(v_i->state == ALPM_GRAPH_STATE_PROCESSING) { continue; } @@ -142,18 +142,18 @@ static void dijkstra(alpm_list_t *vertices) break; } - v->state = -1; + v->state = ALPM_GRAPH_STATE_PROCESSING; - v->childptr = v->children; - while(v->childptr) { - alpm_graph_t *v_c = v->childptr->data; + v->iterator = v->children; + while(v->iterator) { + alpm_graph_t *v_c = v->iterator->data; alpm_delta_t *d_c = v_c->data; if(v_c->weight > v->weight + d_c->download_size) { v_c->weight = v->weight + d_c->download_size; v_c->parent = v; } - v->childptr = (v->childptr)->next; + v->iterator = (v->iterator)->next; } } diff --git a/lib/libalpm/delta.h b/lib/libalpm/delta.h index 26c3c4ce..8fd02e7e 100644 --- a/lib/libalpm/delta.h +++ b/lib/libalpm/delta.h @@ -1,7 +1,7 @@ /* * delta.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2007-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index ae5d60bc..96f91739 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -1,7 +1,7 @@ /* * deps.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org> @@ -152,12 +152,48 @@ static alpm_list_t *dep_graph_init(alpm_handle_t *handle, j = next; } - vertex_i->childptr = vertex_i->children; + vertex_i->iterator = vertex_i->children; } alpm_list_free(localpkgs); return vertices; } +static void _alpm_warn_dep_cycle(alpm_handle_t *handle, alpm_list_t *targets, + alpm_graph_t *ancestor, alpm_graph_t *vertex, int reverse) +{ + /* vertex depends on and is required by ancestor */ + if(!alpm_list_find_ptr(targets, vertex->data)) { + /* child is not part of the transaction, not a problem */ + return; + } + + /* find the nearest ancestor that's part of the transaction */ + while(ancestor) { + if(alpm_list_find_ptr(targets, ancestor->data)) { + break; + } + ancestor = ancestor->parent; + } + + if(!ancestor || ancestor == vertex) { + /* no transaction package in our ancestry or the package has + * a circular dependency with itself, not a problem */ + } else { + alpm_pkg_t *ancestorpkg = ancestor->data; + alpm_pkg_t *childpkg = vertex->data; + _alpm_log(handle, ALPM_LOG_WARNING, _("dependency cycle detected:\n")); + if(reverse) { + _alpm_log(handle, ALPM_LOG_WARNING, + _("%s will be removed after its %s dependency\n"), + ancestorpkg->name, childpkg->name); + } else { + _alpm_log(handle, ALPM_LOG_WARNING, + _("%s will be installed before its %s dependency\n"), + ancestorpkg->name, childpkg->name); + } + } +} + /* Re-order a list of target packages with respect to their dependencies. * * Example (reverse == 0): @@ -179,7 +215,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_handle_t *handle, { alpm_list_t *newtargs = NULL; alpm_list_t *vertices = NULL; - alpm_list_t *vptr; + alpm_list_t *i; alpm_graph_t *vertex; if(targets == NULL) { @@ -190,67 +226,35 @@ alpm_list_t *_alpm_sortbydeps(alpm_handle_t *handle, vertices = dep_graph_init(handle, targets, ignore); - vptr = vertices; + i = vertices; vertex = vertices->data; - while(vptr) { + while(i) { /* mark that we touched the vertex */ - vertex->state = -1; - int found = 0; - while(vertex->childptr && !found) { - alpm_graph_t *nextchild = vertex->childptr->data; - vertex->childptr = vertex->childptr->next; - if(nextchild->state == 0) { - found = 1; + vertex->state = ALPM_GRAPH_STATE_PROCESSING; + int switched_to_child = 0; + while(vertex->iterator && !switched_to_child) { + alpm_graph_t *nextchild = vertex->iterator->data; + vertex->iterator = vertex->iterator->next; + if(nextchild->state == ALPM_GRAPH_STATE_UNPROCESSED) { + switched_to_child = 1; nextchild->parent = vertex; vertex = nextchild; - } else if(nextchild->state == -1) { - /* child is an ancestor of vertex */ - alpm_graph_t *transvertex = vertex; - - if(!alpm_list_find_ptr(targets, nextchild->data)) { - /* child is not part of the transaction, not a problem */ - continue; - } - - /* find the nearest parent that's part of the transaction */ - while(transvertex) { - if(alpm_list_find_ptr(targets, transvertex->data)) { - break; - } - transvertex = transvertex->parent; - } - - if(!transvertex || transvertex == nextchild) { - /* no transaction package in our ancestry or the package has - * a circular dependency with itself, not a problem */ - } else { - alpm_pkg_t *transpkg = transvertex->data; - alpm_pkg_t *childpkg = nextchild->data; - _alpm_log(handle, ALPM_LOG_WARNING, _("dependency cycle detected:\n")); - if(reverse) { - _alpm_log(handle, ALPM_LOG_WARNING, - _("%s will be removed after its %s dependency\n"), - transpkg->name, childpkg->name); - } else { - _alpm_log(handle, ALPM_LOG_WARNING, - _("%s will be installed before its %s dependency\n"), - transpkg->name, childpkg->name); - } - } + } else if(nextchild->state == ALPM_GRAPH_STATE_PROCESSING) { + _alpm_warn_dep_cycle(handle, targets, vertex, nextchild, reverse); } } - if(!found) { + if(!switched_to_child) { if(alpm_list_find_ptr(targets, vertex->data)) { newtargs = alpm_list_add(newtargs, vertex->data); } /* mark that we've left this vertex */ - vertex->state = 1; + vertex->state = ALPM_GRAPH_STATE_PROCESSED; vertex = vertex->parent; if(!vertex) { /* top level vertex reached, move to the next unprocessed vertex */ - for( vptr = vptr->next; vptr; vptr = vptr->next) { - vertex = vptr->data; - if(vertex->state == 0) { + for(i = i->next; i; i = i->next) { + vertex = i->data; + if(vertex->state == ALPM_GRAPH_STATE_UNPROCESSED) { break; } } diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h index 91c6eb62..d1bb66ae 100644 --- a/lib/libalpm/deps.h +++ b/lib/libalpm/deps.h @@ -1,7 +1,7 @@ /* * deps.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c index da4ad560..7d80202c 100644 --- a/lib/libalpm/diskspace.c +++ b/lib/libalpm/diskspace.c @@ -1,7 +1,7 @@ /* * diskspace.c * - * Copyright (c) 2010-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2010-2017 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 @@ -348,11 +348,11 @@ static int check_mountpoint(alpm_handle_t *handle, alpm_mountpoint_t *mp) _alpm_log(handle, ALPM_LOG_DEBUG, "partition %s, needed %jd, cushion %ju, free %ju\n", mp->mount_dir, (intmax_t)mp->max_blocks_needed, - (uintmax_t)cushion, (uintmax_t)mp->fsp.f_bfree); - if(needed >= 0 && (fsblkcnt_t)needed > mp->fsp.f_bfree) { + (uintmax_t)cushion, (uintmax_t)mp->fsp.f_bavail); + if(needed >= 0 && (fsblkcnt_t)needed > mp->fsp.f_bavail) { _alpm_log(handle, ALPM_LOG_ERROR, _("Partition %s too full: %jd blocks needed, %ju blocks free\n"), - mp->mount_dir, (intmax_t)needed, (uintmax_t)mp->fsp.f_bfree); + mp->mount_dir, (intmax_t)needed, (uintmax_t)mp->fsp.f_bavail); return 1; } return 0; diff --git a/lib/libalpm/diskspace.h b/lib/libalpm/diskspace.h index 8c0e4e60..86bc4e45 100644 --- a/lib/libalpm/diskspace.h +++ b/lib/libalpm/diskspace.h @@ -1,7 +1,7 @@ /* * diskspace.h * - * Copyright (c) 2010-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2010-2017 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 diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index dc57c929..875b689c 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -1,7 +1,7 @@ /* * download.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify @@ -246,47 +246,6 @@ static size_t dload_parseheader_cb(void *ptr, size_t size, size_t nmemb, void *u return realsize; } -static int dload_sockopt_cb(void *userdata, curl_socket_t curlfd, - curlsocktype purpose) -{ - alpm_handle_t *handle = userdata; - int optval = 1; - - /* this whole method is to prevent FTP control connections from going sour - * during a long data transfer; crappy firewalls love to drop otherwise idle - * connections if there is no traffic. */ - if(purpose != CURLSOCKTYPE_IPCXN) { - return 0; - } - - /* don't abort operation if any setsockopt fails, just log to debug */ - if(setsockopt(curlfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval, - sizeof(optval)) < 0) { - _alpm_log(handle, ALPM_LOG_DEBUG, - "Failed to set SO_KEEPALIVE on fd %d\n", curlfd); - } - else { -#ifdef TCP_KEEPIDLE - optval = 60; - if(setsockopt(curlfd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&optval, - sizeof(optval)) < 0) { - _alpm_log(handle, ALPM_LOG_DEBUG, - "Failed to set TCP_KEEPIDLE on fd %d\n", curlfd); - } -#endif -#ifdef TCP_KEEPINTVL - optval = 60; - if(setsockopt(curlfd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&optval, - sizeof(optval)) < 0) { - _alpm_log(handle, ALPM_LOG_DEBUG, - "Failed to set TCP_KEEPINTVL on fd %d\n", curlfd); - } -#endif - } - - return 0; -} - static void curl_set_handle_opts(struct dload_payload *payload, CURL *curl, char *error_buffer) { @@ -305,13 +264,16 @@ static void curl_set_handle_opts(struct dload_payload *payload, curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, dload_progress_cb); curl_easy_setopt(curl, CURLOPT_XFERINFODATA, (void *)payload); - curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1L); - curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 10L); + if(!handle->disable_dl_timeout) { + curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1L); + curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 10L); + } curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, dload_parseheader_cb); - curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *)payload); + curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void *)payload); curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); - curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, dload_sockopt_cb); - curl_easy_setopt(curl, CURLOPT_SOCKOPTDATA, (void *)handle); + curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); + curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 60L); + curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L); curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); _alpm_log(handle, ALPM_LOG_DEBUG, "url: %s\n", payload->fileurl); @@ -412,7 +374,7 @@ static int curl_download_internal(struct dload_payload *payload, /* shortcut to our handle within the payload */ alpm_handle_t *handle = payload->handle; CURL *curl = get_libcurl_handle(handle); - handle->pm_errno = 0; + handle->pm_errno = ALPM_ERR_OK; /* make sure these are NULL */ FREE(payload->tempfile_name); @@ -712,7 +674,7 @@ char SYMEXPORT *alpm_fetch_pkgurl(alpm_handle_t *handle, const char *url) size_t len; len = strlen(final_pkg_url) + 5; - MALLOC(payload.fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); + MALLOC(payload.fileurl, len, free(final_file); RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); snprintf(payload.fileurl, len, "%s.sig", final_pkg_url); sig_filepath = filecache_find_url(handle, payload.fileurl); @@ -762,4 +724,14 @@ void _alpm_dload_payload_reset(struct dload_payload *payload) memset(payload, '\0', sizeof(*payload)); } +void _alpm_dload_payload_reset_for_retry(struct dload_payload *payload) +{ + ASSERT(payload, return); + + FREE(payload->fileurl); + payload->initial_size += payload->prevprogress; + payload->prevprogress = 0; + payload->unlink_on_fail = 0; +} + /* vim: set noet: */ diff --git a/lib/libalpm/dload.h b/lib/libalpm/dload.h index 427c4860..6ca775a7 100644 --- a/lib/libalpm/dload.h +++ b/lib/libalpm/dload.h @@ -1,7 +1,7 @@ /* * dload.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify @@ -47,6 +47,7 @@ struct dload_payload { }; void _alpm_dload_payload_reset(struct dload_payload *payload); +void _alpm_dload_payload_reset_for_retry(struct dload_payload *payload); int _alpm_download(struct dload_payload *payload, const char *localpath, char **final_file, const char **final_url); diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c index 2d6d0715..b87c3f2e 100644 --- a/lib/libalpm/error.c +++ b/lib/libalpm/error.c @@ -1,7 +1,7 @@ /* * error.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify diff --git a/lib/libalpm/filelist.c b/lib/libalpm/filelist.c index 5783373e..97f639a9 100644 --- a/lib/libalpm/filelist.c +++ b/lib/libalpm/filelist.c @@ -1,7 +1,7 @@ /* * filelist.c * - * Copyright (c) 2012-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2012-2017 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 @@ -111,7 +111,7 @@ alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA, /* Helper function for comparing files list entries */ -int _alpm_files_cmp(const void *f1, const void *f2) +static int _alpm_files_cmp(const void *f1, const void *f2) { const alpm_file_t *file1 = f1; const alpm_file_t *file2 = f2; @@ -133,4 +133,17 @@ alpm_file_t SYMEXPORT *alpm_filelist_contains(alpm_filelist_t *filelist, sizeof(alpm_file_t), _alpm_files_cmp); } +void _alpm_filelist_sort(alpm_filelist_t *filelist) +{ + size_t i; + for(i = 1; i < filelist->count; i++) { + if(strcmp(filelist->files[i - 1].name, filelist->files[i].name) > 0) { + /* filelist is not pre-sorted */ + qsort(filelist->files, filelist->count, + sizeof(alpm_file_t), _alpm_files_cmp); + return; + } + } +} + /* vim: set noet: */ diff --git a/lib/libalpm/filelist.h b/lib/libalpm/filelist.h index a74bdea0..c879058d 100644 --- a/lib/libalpm/filelist.h +++ b/lib/libalpm/filelist.h @@ -1,7 +1,7 @@ /* * filelist.h * - * Copyright (c) 2012-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2012-2017 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 @@ -27,7 +27,7 @@ alpm_list_t *_alpm_filelist_difference(alpm_filelist_t *filesA, alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA, alpm_filelist_t *filesB); -int _alpm_files_cmp(const void *f1, const void *f2); +void _alpm_filelist_sort(alpm_filelist_t *filelist); #endif /* ALPM_FILELIST_H */ diff --git a/lib/libalpm/graph.c b/lib/libalpm/graph.c index 8492ebee..137cd686 100644 --- a/lib/libalpm/graph.c +++ b/lib/libalpm/graph.c @@ -1,7 +1,7 @@ /* * graph.c - helpful graph structure and setup/teardown methods * - * Copyright (c) 2007-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2007-2017 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 diff --git a/lib/libalpm/graph.h b/lib/libalpm/graph.h index 22f0aa9d..75cec937 100644 --- a/lib/libalpm/graph.h +++ b/lib/libalpm/graph.h @@ -1,7 +1,7 @@ /* * graph.h - helpful graph structure and setup/teardown methods * - * Copyright (c) 2007-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2007-2017 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 @@ -23,13 +23,19 @@ #include "alpm_list.h" +enum __alpm_graph_vertex_state { + ALPM_GRAPH_STATE_UNPROCESSED, + ALPM_GRAPH_STATE_PROCESSING, + ALPM_GRAPH_STATE_PROCESSED +}; + typedef struct __alpm_graph_t { void *data; struct __alpm_graph_t *parent; /* where did we come from? */ alpm_list_t *children; - alpm_list_t *childptr; /* points to a child in children list */ + alpm_list_t *iterator; /* used for DFS without recursion */ off_t weight; /* weight of the node */ - signed char state; /* 0: untouched, -1: entered, other: leaving time */ + enum __alpm_graph_vertex_state state; } alpm_graph_t; alpm_graph_t *_alpm_graph_new(void); diff --git a/lib/libalpm/group.c b/lib/libalpm/group.c index ecc4664b..19ddb72b 100644 --- a/lib/libalpm/group.c +++ b/lib/libalpm/group.c @@ -1,7 +1,7 @@ /* * group.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify diff --git a/lib/libalpm/group.h b/lib/libalpm/group.h index aa330761..c144c0d9 100644 --- a/lib/libalpm/group.h +++ b/lib/libalpm/group.h @@ -1,7 +1,7 @@ /* * group.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index e9439a0b..b6b27881 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -1,7 +1,7 @@ /* * handle.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org> @@ -283,6 +283,12 @@ alpm_list_t SYMEXPORT *alpm_option_get_ignoregroups(alpm_handle_t *handle) return handle->ignoregroup; } +alpm_list_t SYMEXPORT *alpm_option_get_overwrite_files(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return NULL); + return handle->overwrite_files; +} + alpm_list_t SYMEXPORT *alpm_option_get_assumeinstalled(alpm_handle_t *handle) { CHECK_HANDLE(handle, return NULL); @@ -657,6 +663,21 @@ int SYMEXPORT alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char * return _alpm_option_strlist_rem(handle, &(handle->ignoregroup), grp); } +int SYMEXPORT alpm_option_add_overwrite_file(alpm_handle_t *handle, const char *glob) +{ + return _alpm_option_strlist_add(handle, &(handle->overwrite_files), glob); +} + +int SYMEXPORT alpm_option_set_overwrite_files(alpm_handle_t *handle, alpm_list_t *globs) +{ + return _alpm_option_strlist_set(handle, &(handle->overwrite_files), globs); +} + +int SYMEXPORT alpm_option_remove_overwrite_file(alpm_handle_t *handle, const char *glob) +{ + return _alpm_option_strlist_rem(handle, &(handle->overwrite_files), glob); +} + int SYMEXPORT alpm_option_add_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep) { alpm_depend_t *depcpy; @@ -777,7 +798,7 @@ int SYMEXPORT alpm_option_set_dbext(alpm_handle_t *handle, const char *dbext) } int SYMEXPORT alpm_option_set_default_siglevel(alpm_handle_t *handle, - alpm_siglevel_t level) + int level) { CHECK_HANDLE(handle, return -1); #ifdef HAVE_LIBGPGME @@ -790,14 +811,14 @@ int SYMEXPORT alpm_option_set_default_siglevel(alpm_handle_t *handle, return 0; } -alpm_siglevel_t SYMEXPORT alpm_option_get_default_siglevel(alpm_handle_t *handle) +int SYMEXPORT alpm_option_get_default_siglevel(alpm_handle_t *handle) { CHECK_HANDLE(handle, return -1); return handle->siglevel; } int SYMEXPORT alpm_option_set_local_file_siglevel(alpm_handle_t *handle, - alpm_siglevel_t level) + int level) { CHECK_HANDLE(handle, return -1); #ifdef HAVE_LIBGPGME @@ -810,7 +831,7 @@ int SYMEXPORT alpm_option_set_local_file_siglevel(alpm_handle_t *handle, return 0; } -alpm_siglevel_t SYMEXPORT alpm_option_get_local_file_siglevel(alpm_handle_t *handle) +int SYMEXPORT alpm_option_get_local_file_siglevel(alpm_handle_t *handle) { CHECK_HANDLE(handle, return -1); if(handle->localfilesiglevel & ALPM_SIG_USE_DEFAULT) { @@ -821,7 +842,7 @@ alpm_siglevel_t SYMEXPORT alpm_option_get_local_file_siglevel(alpm_handle_t *han } int SYMEXPORT alpm_option_set_remote_file_siglevel(alpm_handle_t *handle, - alpm_siglevel_t level) + int level) { CHECK_HANDLE(handle, return -1); #ifdef HAVE_LIBGPGME @@ -834,7 +855,7 @@ int SYMEXPORT alpm_option_set_remote_file_siglevel(alpm_handle_t *handle, return 0; } -alpm_siglevel_t SYMEXPORT alpm_option_get_remote_file_siglevel(alpm_handle_t *handle) +int SYMEXPORT alpm_option_get_remote_file_siglevel(alpm_handle_t *handle) { CHECK_HANDLE(handle, return -1); if(handle->remotefilesiglevel & ALPM_SIG_USE_DEFAULT) { @@ -844,4 +865,14 @@ alpm_siglevel_t SYMEXPORT alpm_option_get_remote_file_siglevel(alpm_handle_t *ha } } +int SYMEXPORT alpm_option_set_disable_dl_timeout(alpm_handle_t *handle, + unsigned short disable_dl_timeout) +{ + CHECK_HANDLE(handle, return -1); +#ifdef HAVE_LIBCURL + handle->disable_dl_timeout = disable_dl_timeout; +#endif + return 0; +} + /* vim: set noet: */ diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index ecbe8370..115c3481 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -1,7 +1,7 @@ /* * handle.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify @@ -60,6 +60,7 @@ struct __alpm_handle_t { #ifdef HAVE_LIBCURL /* libcurl handle */ CURL *curl; /* reusable curl_easy handle */ + unsigned short disable_dl_timeout; #endif #ifdef HAVE_LIBGPGME @@ -83,6 +84,7 @@ struct __alpm_handle_t { char *gpgdir; /* Directory where GnuPG files are stored */ alpm_list_t *cachedirs; /* Paths to pacman cache directories */ alpm_list_t *hookdirs; /* Paths to hook directories */ + alpm_list_t *overwrite_files; /* Paths that may be overwritten */ /* package lists */ alpm_list_t *noupgrade; /* List of packages NOT to be upgraded */ @@ -97,10 +99,10 @@ struct __alpm_handle_t { int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */ int checkspace; /* Check disk space before installing */ char *dbext; /* Sync DB extension */ - alpm_siglevel_t siglevel; /* Default signature verification level */ - alpm_siglevel_t localfilesiglevel; /* Signature verification level for local file + int siglevel; /* Default signature verification level */ + int localfilesiglevel; /* Signature verification level for local file upgrade operations */ - alpm_siglevel_t remotefilesiglevel; /* Signature verification level for remote file + int remotefilesiglevel; /* Signature verification level for remote file upgrade operations */ /* error code */ diff --git a/lib/libalpm/hook.c b/lib/libalpm/hook.c index ccde225e..4ec2a906 100644 --- a/lib/libalpm/hook.c +++ b/lib/libalpm/hook.c @@ -1,7 +1,7 @@ /* * hook.c * - * Copyright (c) 2015-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2015-2017 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 diff --git a/lib/libalpm/hook.h b/lib/libalpm/hook.h index f33dfe13..36528621 100644 --- a/lib/libalpm/hook.h +++ b/lib/libalpm/hook.h @@ -1,7 +1,7 @@ /* * hook.h * - * Copyright (c) 2015-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2015-2017 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 diff --git a/lib/libalpm/libalpm.pc.in b/lib/libalpm/libalpm.pc.in index e4be1741..e1d74ef9 100644 --- a/lib/libalpm/libalpm.pc.in +++ b/lib/libalpm/libalpm.pc.in @@ -9,4 +9,4 @@ URL: http://www.archlinux.org/pacman/ Version: @LIB_VERSION@ Cflags: -I${includedir} @LFS_CFLAGS@ Libs: -L${libdir} -lalpm -Libs.private: @LIBS@ @LIBARCHIVE_LIBS@ @LIBSSL_LIBS@ @LIBCURL_LIBS@ @GPGME_LIBS@ +Libs.private: @LIBS@ @LIBARCHIVE_LIBS@ @LIBSSL_LIBS@ @NETTLE_LIBS@ @LIBCURL_LIBS@ @GPGME_LIBS@ diff --git a/lib/libalpm/libarchive-compat.h b/lib/libalpm/libarchive-compat.h index d4aa4fa2..9f081568 100644 --- a/lib/libalpm/libarchive-compat.h +++ b/lib/libalpm/libarchive-compat.h @@ -4,7 +4,7 @@ /* * libarchive-compat.h * - * Copyright (c) 2013-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2013-2017 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 diff --git a/lib/libalpm/log.c b/lib/libalpm/log.c index 56a788e6..9e986d69 100644 --- a/lib/libalpm/log.c +++ b/lib/libalpm/log.c @@ -1,7 +1,7 @@ /* * log.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify diff --git a/lib/libalpm/log.h b/lib/libalpm/log.h index 79074fc6..6ec04561 100644 --- a/lib/libalpm/log.h +++ b/lib/libalpm/log.h @@ -1,7 +1,7 @@ /* * log.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index f08df8b2..e9ecc178 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -1,7 +1,7 @@ /* * package.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005, 2006 by Christian Hamar <krics@linuxforum.hu> @@ -60,7 +60,7 @@ int SYMEXPORT alpm_pkg_checkmd5sum(alpm_pkg_t *pkg) int retval; ASSERT(pkg != NULL, return -1); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; /* We only inspect packages from sync repositories */ ASSERT(pkg->origin == ALPM_PKG_FROM_SYNCDB, RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1)); @@ -69,9 +69,9 @@ int SYMEXPORT alpm_pkg_checkmd5sum(alpm_pkg_t *pkg) retval = _alpm_test_checksum(fpath, pkg->md5sum, ALPM_PKG_VALIDATION_MD5SUM); - if(retval == 0) { - return 0; - } else if(retval == 1) { + FREE(fpath); + + if(retval == 1) { pkg->handle->pm_errno = ALPM_ERR_PKG_INVALID; retval = -1; } @@ -92,13 +92,15 @@ static const char *_pkg_get_packager(alpm_pkg_t *pkg) { return pkg->packager; static const char *_pkg_get_arch(alpm_pkg_t *pkg) { return pkg->arch; } static off_t _pkg_get_isize(alpm_pkg_t *pkg) { return pkg->isize; } static alpm_pkgreason_t _pkg_get_reason(alpm_pkg_t *pkg) { return pkg->reason; } -static alpm_pkgvalidation_t _pkg_get_validation(alpm_pkg_t *pkg) { return pkg->validation; } +static int _pkg_get_validation(alpm_pkg_t *pkg) { return pkg->validation; } static int _pkg_has_scriptlet(alpm_pkg_t *pkg) { return pkg->scriptlet; } static alpm_list_t *_pkg_get_licenses(alpm_pkg_t *pkg) { return pkg->licenses; } static alpm_list_t *_pkg_get_groups(alpm_pkg_t *pkg) { return pkg->groups; } static alpm_list_t *_pkg_get_depends(alpm_pkg_t *pkg) { return pkg->depends; } static alpm_list_t *_pkg_get_optdepends(alpm_pkg_t *pkg) { return pkg->optdepends; } +static alpm_list_t *_pkg_get_checkdepends(alpm_pkg_t *pkg) { return pkg->checkdepends; } +static alpm_list_t *_pkg_get_makedepends(alpm_pkg_t *pkg) { return pkg->makedepends; } static alpm_list_t *_pkg_get_conflicts(alpm_pkg_t *pkg) { return pkg->conflicts; } static alpm_list_t *_pkg_get_provides(alpm_pkg_t *pkg) { return pkg->provides; } static alpm_list_t *_pkg_get_replaces(alpm_pkg_t *pkg) { return pkg->replaces; } @@ -161,6 +163,8 @@ struct pkg_operations default_pkg_ops = { .get_groups = _pkg_get_groups, .get_depends = _pkg_get_depends, .get_optdepends = _pkg_get_optdepends, + .get_checkdepends = _pkg_get_checkdepends, + .get_makedepends = _pkg_get_makedepends, .get_conflicts = _pkg_get_conflicts, .get_provides = _pkg_get_provides, .get_replaces = _pkg_get_replaces, @@ -184,196 +188,210 @@ struct pkg_operations default_pkg_ops = { const char SYMEXPORT *alpm_pkg_get_filename(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->filename; } const char SYMEXPORT *alpm_pkg_get_base(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_base(pkg); } const char SYMEXPORT *alpm_pkg_get_name(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->name; } const char SYMEXPORT *alpm_pkg_get_version(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->version; } alpm_pkgfrom_t SYMEXPORT alpm_pkg_get_origin(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return -1); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->origin; } const char SYMEXPORT *alpm_pkg_get_desc(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_desc(pkg); } const char SYMEXPORT *alpm_pkg_get_url(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_url(pkg); } alpm_time_t SYMEXPORT alpm_pkg_get_builddate(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return -1); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_builddate(pkg); } alpm_time_t SYMEXPORT alpm_pkg_get_installdate(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return -1); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_installdate(pkg); } const char SYMEXPORT *alpm_pkg_get_packager(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_packager(pkg); } const char SYMEXPORT *alpm_pkg_get_md5sum(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->md5sum; } const char SYMEXPORT *alpm_pkg_get_sha256sum(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->sha256sum; } const char SYMEXPORT *alpm_pkg_get_base64_sig(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->base64_sig; } const char SYMEXPORT *alpm_pkg_get_arch(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_arch(pkg); } off_t SYMEXPORT alpm_pkg_get_size(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return -1); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->size; } off_t SYMEXPORT alpm_pkg_get_isize(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return -1); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_isize(pkg); } alpm_pkgreason_t SYMEXPORT alpm_pkg_get_reason(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return -1); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_reason(pkg); } -alpm_pkgvalidation_t SYMEXPORT alpm_pkg_get_validation(alpm_pkg_t *pkg) +int SYMEXPORT alpm_pkg_get_validation(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return -1); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_validation(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_licenses(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_licenses(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_groups(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_groups(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_depends(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_depends(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_optdepends(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_optdepends(pkg); } +alpm_list_t SYMEXPORT *alpm_pkg_get_checkdepends(alpm_pkg_t *pkg) +{ + ASSERT(pkg != NULL, return NULL); + pkg->handle->pm_errno = ALPM_ERR_OK; + return pkg->ops->get_checkdepends(pkg); +} + +alpm_list_t SYMEXPORT *alpm_pkg_get_makedepends(alpm_pkg_t *pkg) +{ + ASSERT(pkg != NULL, return NULL); + pkg->handle->pm_errno = ALPM_ERR_OK; + return pkg->ops->get_makedepends(pkg); +} + alpm_list_t SYMEXPORT *alpm_pkg_get_conflicts(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_conflicts(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_provides(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_provides(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_replaces(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_replaces(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_deltas(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->deltas; } alpm_filelist_t SYMEXPORT *alpm_pkg_get_files(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_files(pkg); } alpm_list_t SYMEXPORT *alpm_pkg_get_backup(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->get_backup(pkg); } @@ -382,7 +400,7 @@ alpm_db_t SYMEXPORT *alpm_pkg_get_db(alpm_pkg_t *pkg) /* Sanity checks */ ASSERT(pkg != NULL, return NULL); ASSERT(pkg->origin != ALPM_PKG_FROM_FILE, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->origin_data.db; } @@ -391,7 +409,7 @@ alpm_db_t SYMEXPORT *alpm_pkg_get_db(alpm_pkg_t *pkg) void SYMEXPORT *alpm_pkg_changelog_open(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->changelog_open(pkg); } @@ -400,7 +418,7 @@ size_t SYMEXPORT alpm_pkg_changelog_read(void *ptr, size_t size, const alpm_pkg_t *pkg, void *fp) { ASSERT(pkg != NULL, return 0); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->changelog_read(ptr, size, pkg, fp); } @@ -408,7 +426,7 @@ size_t SYMEXPORT alpm_pkg_changelog_read(void *ptr, size_t size, int SYMEXPORT alpm_pkg_changelog_close(const alpm_pkg_t *pkg, void *fp) { ASSERT(pkg != NULL, return -1); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->changelog_close(pkg, fp); } @@ -416,7 +434,7 @@ int SYMEXPORT alpm_pkg_changelog_close(const alpm_pkg_t *pkg, void *fp) struct archive SYMEXPORT *alpm_pkg_mtree_open(alpm_pkg_t * pkg) { ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->mtree_open(pkg); } @@ -425,7 +443,7 @@ int SYMEXPORT alpm_pkg_mtree_next(const alpm_pkg_t * pkg, struct archive *archiv struct archive_entry **entry) { ASSERT(pkg != NULL, return -1); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->mtree_next(pkg, archive, entry); } @@ -433,14 +451,14 @@ int SYMEXPORT alpm_pkg_mtree_next(const alpm_pkg_t * pkg, struct archive *archiv int SYMEXPORT alpm_pkg_mtree_close(const alpm_pkg_t * pkg, struct archive *archive) { ASSERT(pkg != NULL, return -1); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->mtree_close(pkg, archive); } int SYMEXPORT alpm_pkg_has_scriptlet(alpm_pkg_t *pkg) { ASSERT(pkg != NULL, return -1); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return pkg->ops->has_scriptlet(pkg); } @@ -448,7 +466,7 @@ static void find_requiredby(alpm_pkg_t *pkg, alpm_db_t *db, alpm_list_t **reqs, int optional) { const alpm_list_t *i; - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; for(i = _alpm_db_get_pkgcache(db); i; i = i->next) { alpm_pkg_t *cachepkg = i->data; @@ -478,7 +496,7 @@ static alpm_list_t *compute_requiredby(alpm_pkg_t *pkg, int optional) alpm_db_t *db; ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; if(pkg->origin == ALPM_PKG_FROM_FILE) { /* The sane option; search locally for things that require this. */ diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h index 114d2250..8531b212 100644 --- a/lib/libalpm/package.h +++ b/lib/libalpm/package.h @@ -1,7 +1,7 @@ /* * package.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2006 by David Kimpe <dnaku@frugalware.org> @@ -52,13 +52,15 @@ struct pkg_operations { const char *(*get_arch) (alpm_pkg_t *); off_t (*get_isize) (alpm_pkg_t *); alpm_pkgreason_t (*get_reason) (alpm_pkg_t *); - alpm_pkgvalidation_t (*get_validation) (alpm_pkg_t *); + int (*get_validation) (alpm_pkg_t *); int (*has_scriptlet) (alpm_pkg_t *); alpm_list_t *(*get_licenses) (alpm_pkg_t *); alpm_list_t *(*get_groups) (alpm_pkg_t *); alpm_list_t *(*get_depends) (alpm_pkg_t *); alpm_list_t *(*get_optdepends) (alpm_pkg_t *); + alpm_list_t *(*get_checkdepends) (alpm_pkg_t *); + alpm_list_t *(*get_makedepends) (alpm_pkg_t *); alpm_list_t *(*get_conflicts) (alpm_pkg_t *); alpm_list_t *(*get_provides) (alpm_pkg_t *); alpm_list_t *(*get_replaces) (alpm_pkg_t *); @@ -112,6 +114,8 @@ struct __alpm_pkg_t { alpm_list_t *backup; alpm_list_t *depends; alpm_list_t *optdepends; + alpm_list_t *checkdepends; + alpm_list_t *makedepends; alpm_list_t *conflicts; alpm_list_t *provides; alpm_list_t *deltas; @@ -130,11 +134,14 @@ struct __alpm_pkg_t { char *file; } origin_data; - alpm_dbinfrq_t infolevel; - alpm_pkgvalidation_t validation; alpm_pkgfrom_t origin; alpm_pkgreason_t reason; int scriptlet; + + /* Bitfield from alpm_dbinfrq_t */ + int infolevel; + /* Bitfield from alpm_pkgvalidation_t */ + int validation; }; alpm_file_t *_alpm_file_copy(alpm_file_t *dest, const alpm_file_t *src); @@ -145,8 +152,8 @@ void _alpm_pkg_free(alpm_pkg_t *pkg); void _alpm_pkg_free_trans(alpm_pkg_t *pkg); int _alpm_pkg_validate_internal(alpm_handle_t *handle, - const char *pkgfile, alpm_pkg_t *syncpkg, alpm_siglevel_t level, - alpm_siglist_t **sigdata, alpm_pkgvalidation_t *validation); + const char *pkgfile, alpm_pkg_t *syncpkg, int level, + alpm_siglist_t **sigdata, int *validation); alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile, int full); diff --git a/lib/libalpm/pkghash.c b/lib/libalpm/pkghash.c index 968218e2..45e63082 100644 --- a/lib/libalpm/pkghash.c +++ b/lib/libalpm/pkghash.c @@ -1,7 +1,7 @@ /* * pkghash.c * - * Copyright (c) 2011-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2011-2017 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 diff --git a/lib/libalpm/pkghash.h b/lib/libalpm/pkghash.h index be064f69..dd163346 100644 --- a/lib/libalpm/pkghash.h +++ b/lib/libalpm/pkghash.h @@ -1,7 +1,7 @@ /* * pkghash.h * - * Copyright (c) 2011-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2011-2017 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 diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index 173dbc69..ffe92518 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -1,7 +1,7 @@ /* * remove.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> @@ -440,8 +440,19 @@ static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *oldpkg, { struct stat buf; char file[PATH_MAX]; + int file_len; - snprintf(file, PATH_MAX, "%s%s", handle->root, fileobj->name); + file_len = snprintf(file, PATH_MAX, "%s%s", handle->root, fileobj->name); + if(file_len <= 0 || file_len >= PATH_MAX) { + /* 0 is a valid value from snprintf, but should be impossible here */ + _alpm_log(handle, ALPM_LOG_DEBUG, "path too long to unlink %s%s\n", + handle->root, fileobj->name); + return -1; + } else if(file[file_len-1] == '/') { + /* trailing slashes cause errors and confusing messages if the user has + * replaced a directory with a symlink */ + file[--file_len] = '\0'; + } if(llstat(file, &buf)) { _alpm_log(handle, ALPM_LOG_DEBUG, "file %s does not exist\n", file); diff --git a/lib/libalpm/remove.h b/lib/libalpm/remove.h index b26ea602..c7c5fba9 100644 --- a/lib/libalpm/remove.h +++ b/lib/libalpm/remove.h @@ -1,7 +1,7 @@ /* * remove.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c index 6557c200..95cb3280 100644 --- a/lib/libalpm/signing.c +++ b/lib/libalpm/signing.c @@ -1,7 +1,7 @@ /* * signing.c * - * Copyright (c) 2008-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2008-2017 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 @@ -356,6 +356,10 @@ static int key_search(alpm_handle_t *handle, const char *fpr, #if GPGME_VERSION_NUMBER >= 0x010500 case GPGME_PK_ECC: #endif +/* value added in gpgme 1.7.0 */ +#if GPGME_VERSION_NUMBER >= 0x010700 + case GPGME_PK_EDDSA: +#endif pgpkey->pubkey_algo = 'E'; break; } @@ -771,7 +775,7 @@ int _alpm_check_pgp_helper(alpm_handle_t *handle, const char *path, if(ret && handle->pm_errno == ALPM_ERR_SIG_MISSING) { if(optional) { _alpm_log(handle, ALPM_LOG_DEBUG, "missing optional signature\n"); - handle->pm_errno = 0; + handle->pm_errno = ALPM_ERR_OK; ret = 0; } else { _alpm_log(handle, ALPM_LOG_DEBUG, "missing required signature\n"); @@ -931,7 +935,7 @@ int SYMEXPORT alpm_pkg_check_pgp_signature(alpm_pkg_t *pkg, { ASSERT(pkg != NULL, return -1); ASSERT(siglist != NULL, RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1)); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; return _alpm_gpgme_checksig(pkg->handle, pkg->filename, pkg->base64_sig, siglist); @@ -948,7 +952,7 @@ int SYMEXPORT alpm_db_check_pgp_signature(alpm_db_t *db, { ASSERT(db != NULL, return -1); ASSERT(siglist != NULL, RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1)); - db->handle->pm_errno = 0; + db->handle->pm_errno = ALPM_ERR_OK; return _alpm_gpgme_checksig(db->handle, _alpm_db_path(db), NULL, siglist); } diff --git a/lib/libalpm/signing.h b/lib/libalpm/signing.h index 960b644c..3507f584 100644 --- a/lib/libalpm/signing.h +++ b/lib/libalpm/signing.h @@ -1,7 +1,7 @@ /* * signing.h * - * Copyright (c) 2008-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2008-2017 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 diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 00b68d05..ae0f1e49 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -1,7 +1,7 @@ /* * sync.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> @@ -57,7 +57,7 @@ alpm_pkg_t SYMEXPORT *alpm_sync_newversion(alpm_pkg_t *pkg, alpm_list_t *dbs_syn alpm_pkg_t *spkg = NULL; ASSERT(pkg != NULL, return NULL); - pkg->handle->pm_errno = 0; + pkg->handle->pm_errno = ALPM_ERR_OK; for(i = dbs_sync; !spkg && i; i = i->next) { alpm_db_t *db = i->data; @@ -460,7 +460,7 @@ int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data) transaction. The packages will be removed from the actual transaction when the transaction packages are replaced with a dependency-reordered list below */ - handle->pm_errno = 0; + handle->pm_errno = ALPM_ERR_OK; if(data) { alpm_list_free_inner(*data, (alpm_list_fn_free)alpm_depmissing_free); @@ -946,9 +946,7 @@ static int download_single_file(alpm_handle_t *handle, struct dload_payload *pay EVENT(handle, &event); return 0; } - - FREE(payload->fileurl); - payload->unlink_on_fail = 0; + _alpm_dload_payload_reset_for_retry(payload); } event.type = ALPM_EVENT_PKGDOWNLOAD_FAILED; @@ -1056,7 +1054,7 @@ static int check_keyring(alpm_handle_t *handle) for(i = handle->trans->add; i; i = i->next, current++) { alpm_pkg_t *pkg = i->data; - alpm_siglevel_t level; + int level; int percent = (current * 100) / numtargs; PROGRESS(handle, ALPM_PROGRESS_KEYRING_START, "", percent, @@ -1126,8 +1124,8 @@ static int check_validity(alpm_handle_t *handle, alpm_pkg_t *pkg; char *path; alpm_siglist_t *siglist; - alpm_siglevel_t level; - alpm_pkgvalidation_t validation; + int siglevel; + int validation; alpm_errno_t error; }; size_t current = 0; @@ -1151,10 +1149,10 @@ static int check_validity(alpm_handle_t *handle, current_bytes += v.pkg->size; v.path = _alpm_filecache_find(handle, v.pkg->filename); - v.level = alpm_db_get_siglevel(alpm_pkg_get_db(v.pkg)); + v.siglevel = alpm_db_get_siglevel(alpm_pkg_get_db(v.pkg)); if(_alpm_pkg_validate_internal(handle, v.path, v.pkg, - v.level, &v.siglist, &v.validation) == -1) { + v.siglevel, &v.siglist, &v.validation) == -1) { struct validity *invalid; v.error = handle->pm_errno; MALLOC(invalid, sizeof(struct validity), return -1); @@ -1181,9 +1179,9 @@ static int check_validity(alpm_handle_t *handle, _("%s: missing required signature\n"), v->pkg->name); } else if(v->error == ALPM_ERR_PKG_INVALID_SIG) { _alpm_process_siglist(handle, v->pkg->name, v->siglist, - v->level & ALPM_SIG_PACKAGE_OPTIONAL, - v->level & ALPM_SIG_PACKAGE_MARGINAL_OK, - v->level & ALPM_SIG_PACKAGE_UNKNOWN_OK); + v->siglevel & ALPM_SIG_PACKAGE_OPTIONAL, + v->siglevel & ALPM_SIG_PACKAGE_MARGINAL_OK, + v->siglevel & ALPM_SIG_PACKAGE_UNKNOWN_OK); prompt_to_delete(handle, v->path, v->error); } else if(v->error == ALPM_ERR_PKG_INVALID_CHECKSUM) { prompt_to_delete(handle, v->path, v->error); @@ -1195,7 +1193,7 @@ static int check_validity(alpm_handle_t *handle, } alpm_list_free(errors); - if(!handle->pm_errno) { + if(handle->pm_errno == ALPM_ERR_OK) { RET_ERR(handle, ALPM_ERR_PKG_INVALID, -1); } return -1; @@ -1280,7 +1278,7 @@ static int load_packages(alpm_handle_t *handle, alpm_list_t **data, EVENT(handle, &event); if(errors) { - if(!handle->pm_errno) { + if(handle->pm_errno == ALPM_ERR_OK) { RET_ERR(handle, ALPM_ERR_PKG_INVALID, -1); } return -1; diff --git a/lib/libalpm/sync.h b/lib/libalpm/sync.h index 1aa48b7a..882e90f0 100644 --- a/lib/libalpm/sync.h +++ b/lib/libalpm/sync.h @@ -1,7 +1,7 @@ /* * sync.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org> diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index 13984707..7689079b 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -1,7 +1,7 @@ /* * trans.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> @@ -48,7 +48,7 @@ */ /** Initialize the transaction. */ -int SYMEXPORT alpm_trans_init(alpm_handle_t *handle, alpm_transflag_t flags) +int SYMEXPORT alpm_trans_init(alpm_handle_t *handle, int flags) { alpm_trans_t *trans; @@ -305,6 +305,7 @@ void _alpm_trans_free(alpm_trans_t *trans) static int grep(const char *fn, const char *needle) { FILE *fp; + char *ptr; if((fp = fopen(fn, "r")) == NULL) { return 0; @@ -314,6 +315,9 @@ static int grep(const char *fn, const char *needle) if(safe_fgets(line, sizeof(line), fp) == NULL) { continue; } + if((ptr = strchr(line, '#')) != NULL) { + *ptr = '\0'; + } /* TODO: this will not work if the search string * ends up being split across line reads */ if(strstr(line, needle)) { @@ -415,7 +419,7 @@ cleanup: return retval; } -alpm_transflag_t SYMEXPORT alpm_trans_get_flags(alpm_handle_t *handle) +int SYMEXPORT alpm_trans_get_flags(alpm_handle_t *handle) { /* Sanity checks */ CHECK_HANDLE(handle, return -1); diff --git a/lib/libalpm/trans.h b/lib/libalpm/trans.h index 73111be4..f97db9ee 100644 --- a/lib/libalpm/trans.h +++ b/lib/libalpm/trans.h @@ -1,7 +1,7 @@ /* * trans.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> @@ -37,7 +37,8 @@ typedef enum _alpm_transstate_t { /* Transaction */ struct __alpm_trans_t { - alpm_transflag_t flags; + /* bitfield of alpm_transflag_t flags */ + int flags; alpm_transstate_t state; alpm_list_t *unresolvable; /* list of (alpm_pkg_t *) */ alpm_list_t *add; /* list of (alpm_pkg_t *) */ @@ -46,7 +47,8 @@ struct __alpm_trans_t { }; void _alpm_trans_free(alpm_trans_t *trans); -int _alpm_trans_init(alpm_trans_t *trans, alpm_transflag_t flags); +/* flags is a bitfield of alpm_transflag_t flags */ +int _alpm_trans_init(alpm_trans_t *trans, int flags); int _alpm_runscriptlet(alpm_handle_t *handle, const char *filepath, const char *script, const char *ver, const char *oldver, int is_archive); diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 7ef4bf34..35fc7f41 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -1,7 +1,7 @@ /* * util.c * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> @@ -30,6 +30,7 @@ #include <errno.h> #include <limits.h> #include <sys/wait.h> +#include <sys/socket.h> #include <fnmatch.h> #include <poll.h> @@ -42,6 +43,11 @@ #include <openssl/sha.h> #endif +#ifdef HAVE_LIBNETTLE +#include <nettle/md5.h> +#include <nettle/sha2.h> +#endif + /* libalpm */ #include "util.h" #include "log.h" @@ -458,7 +464,6 @@ static int _alpm_chroot_write_to_child(alpm_handle_t *handle, int fd, _alpm_cb_io out_cb, void *cb_ctx) { ssize_t nwrite; - struct sigaction newaction, oldaction; if(*buf_size == 0) { /* empty buffer, ask the callback for more */ @@ -468,16 +473,7 @@ static int _alpm_chroot_write_to_child(alpm_handle_t *handle, int fd, } } - /* ignore SIGPIPE in case the pipe has been closed */ - newaction.sa_handler = SIG_IGN; - sigemptyset(&newaction.sa_mask); - newaction.sa_flags = 0; - sigaction(SIGPIPE, &newaction, &oldaction); - - nwrite = write(fd, buf, *buf_size); - - /* restore previous SIGPIPE handler */ - sigaction(SIGPIPE, &oldaction, NULL); + nwrite = send(fd, buf, *buf_size, MSG_NOSIGNAL); if(nwrite != -1) { /* write was successful, remove the written data from the buffer */ @@ -568,6 +564,9 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[], int cwdfd; int retval = 0; +#define HEAD 1 +#define TAIL 0 + /* save the cwd so we can restore it later */ OPEN(cwdfd, ".", O_RDONLY | O_CLOEXEC); if(cwdfd < 0) { @@ -587,13 +586,13 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[], /* Flush open fds before fork() to avoid cloning buffers */ fflush(NULL); - if(pipe(child2parent_pipefd) == -1) { + if(socketpair(AF_UNIX, SOCK_STREAM, 0, child2parent_pipefd) == -1) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not create pipe (%s)\n"), strerror(errno)); retval = 1; goto cleanup; } - if(pipe(parent2child_pipefd) == -1) { + if(socketpair(AF_UNIX, SOCK_STREAM, 0, parent2child_pipefd) == -1) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not create pipe (%s)\n"), strerror(errno)); retval = 1; goto cleanup; @@ -612,13 +611,13 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[], close(0); close(1); close(2); - while(dup2(child2parent_pipefd[1], 1) == -1 && errno == EINTR); - while(dup2(child2parent_pipefd[1], 2) == -1 && errno == EINTR); - while(dup2(parent2child_pipefd[0], 0) == -1 && errno == EINTR); - close(parent2child_pipefd[0]); - close(parent2child_pipefd[1]); - close(child2parent_pipefd[0]); - close(child2parent_pipefd[1]); + while(dup2(child2parent_pipefd[HEAD], 1) == -1 && errno == EINTR); + while(dup2(child2parent_pipefd[HEAD], 2) == -1 && errno == EINTR); + while(dup2(parent2child_pipefd[TAIL], 0) == -1 && errno == EINTR); + close(parent2child_pipefd[TAIL]); + close(parent2child_pipefd[HEAD]); + close(child2parent_pipefd[TAIL]); + close(child2parent_pipefd[HEAD]); if(cwdfd >= 0) { close(cwdfd); } @@ -647,20 +646,20 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[], nfds_t nfds = 2; struct pollfd fds[2], *child2parent = &(fds[0]), *parent2child = &(fds[1]); - child2parent->fd = child2parent_pipefd[0]; + child2parent->fd = child2parent_pipefd[TAIL]; child2parent->events = POLLIN; fcntl(child2parent->fd, F_SETFL, O_NONBLOCK); - close(child2parent_pipefd[1]); - close(parent2child_pipefd[0]); + close(child2parent_pipefd[HEAD]); + close(parent2child_pipefd[TAIL]); if(stdin_cb) { - parent2child->fd = parent2child_pipefd[1]; + parent2child->fd = parent2child_pipefd[HEAD]; parent2child->events = POLLOUT; fcntl(parent2child->fd, F_SETFL, O_NONBLOCK); } else { parent2child->fd = -1; parent2child->events = 0; - close(parent2child_pipefd[1]); + close(parent2child_pipefd[HEAD]); } #define STOP_POLLING(p) do { close(p->fd); p->fd = -1; } while(0) @@ -695,6 +694,8 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[], } #undef STOP_POLLING +#undef HEAD +#undef TAIL if(parent2child->fd != -1) { close(parent2child->fd); @@ -856,7 +857,7 @@ const char *_alpm_filecache_setup(alpm_handle_t *handle) return cachedir; } -#ifdef HAVE_LIBSSL +#if defined HAVE_LIBSSL || defined HAVE_LIBNETTLE /** Compute the MD5 message digest of a file. * @param path file path of file to compute MD5 digest of * @param output string to hold computed MD5 digest @@ -864,7 +865,11 @@ const char *_alpm_filecache_setup(alpm_handle_t *handle) */ static int md5_file(const char *path, unsigned char output[16]) { +#if HAVE_LIBSSL MD5_CTX ctx; +#else /* HAVE_LIBNETTLE */ + struct md5_ctx ctx; +#endif unsigned char *buf; ssize_t n; int fd; @@ -877,13 +882,21 @@ static int md5_file(const char *path, unsigned char output[16]) return 1; } +#if HAVE_LIBSSL MD5_Init(&ctx); +#else /* HAVE_LIBNETTLE */ + md5_init(&ctx); +#endif while((n = read(fd, buf, ALPM_BUFFER_SIZE)) > 0 || errno == EINTR) { if(n < 0) { continue; } +#if HAVE_LIBSSL MD5_Update(&ctx, buf, n); +#else /* HAVE_LIBNETTLE */ + md5_update(&ctx, n, buf); +#endif } close(fd); @@ -893,7 +906,11 @@ static int md5_file(const char *path, unsigned char output[16]) return 2; } +#if HAVE_LIBSSL MD5_Final(output, &ctx); +#else /* HAVE_LIBNETTLE */ + md5_digest(&ctx, MD5_DIGEST_SIZE, output); +#endif return 0; } @@ -904,7 +921,11 @@ static int md5_file(const char *path, unsigned char output[16]) */ static int sha256_file(const char *path, unsigned char output[32]) { +#if HAVE_LIBSSL SHA256_CTX ctx; +#else /* HAVE_LIBNETTLE */ + struct sha256_ctx ctx; +#endif unsigned char *buf; ssize_t n; int fd; @@ -917,13 +938,21 @@ static int sha256_file(const char *path, unsigned char output[32]) return 1; } +#if HAVE_LIBSSL SHA256_Init(&ctx); +#else /* HAVE_LIBNETTLE */ + sha256_init(&ctx); +#endif while((n = read(fd, buf, ALPM_BUFFER_SIZE)) > 0 || errno == EINTR) { if(n < 0) { continue; } +#if HAVE_LIBSSL SHA256_Update(&ctx, buf, n); +#else /* HAVE_LIBNETTLE */ + sha256_update(&ctx, n, buf); +#endif } close(fd); @@ -933,10 +962,14 @@ static int sha256_file(const char *path, unsigned char output[32]) return 2; } +#if HAVE_LIBSSL SHA256_Final(output, &ctx); +#else /* HAVE_LIBNETTLE */ + sha256_digest(&ctx, SHA256_DIGEST_SIZE, output); +#endif return 0; } -#endif +#endif /* HAVE_LIBSSL || HAVE_LIBNETTLE */ /** Create a string representing bytes in hexadecimal. * @param bytes the bytes to represent in hexadecimal diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 5a2c105d..e1423ce3 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -1,7 +1,7 @@ /* * util.h * - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> @@ -77,7 +77,7 @@ void _alpm_alloc_fail(size_t size); #define DOUBLE_EQ(x, y) (fabs((x) - (y)) < DBL_EPSILON) -#define CHECK_HANDLE(handle, action) do { if(!(handle)) { action; } (handle)->pm_errno = 0; } while(0) +#define CHECK_HANDLE(handle, action) do { if(!(handle)) { action; } (handle)->pm_errno = ALPM_ERR_OK; } while(0) /** Standard buffer size used throughout the library. */ #ifdef BUFSIZ @@ -131,6 +131,8 @@ int _alpm_ldconfig(alpm_handle_t *handle); int _alpm_str_cmp(const void *s1, const void *s2); char *_alpm_filecache_find(alpm_handle_t *handle, const char *filename); const char *_alpm_filecache_setup(alpm_handle_t *handle); +/* Unlike many uses of alpm_pkgvalidation_t, _alpm_test_checksum expects + * an enum value rather than a bitfield. */ int _alpm_test_checksum(const char *filepath, const char *expected, alpm_pkgvalidation_t type); int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b); int _alpm_splitname(const char *target, char **name, char **version, diff --git a/lib/libalpm/version.c b/lib/libalpm/version.c index 29c41834..64dbe6f0 100644 --- a/lib/libalpm/version.c +++ b/lib/libalpm/version.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2017 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 |