diff options
Diffstat (limited to 'lib')
46 files changed, 3428 insertions, 2721 deletions
| diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am index 1bda5714..b2b6d0d2 100644 --- a/lib/libalpm/Makefile.am +++ b/lib/libalpm/Makefile.am @@ -35,13 +35,14 @@ libalpm_la_SOURCES = \  	diskspace.h diskspace.c \  	dload.h dload.c \  	error.c \ -	graph.h \ +	graph.h graph.c \  	group.h group.c \  	handle.h handle.c \  	log.h log.c \  	package.h package.c \  	pkghash.h pkghash.c \  	remove.h remove.c \ +	signing.c signing.h \  	sync.h sync.c \  	trans.h trans.c \  	util.h util.c \ @@ -52,7 +53,12 @@ libalpm_la_SOURCES += \  	md5.h md5.c  endif -libalpm_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_INFO) +if HAVE_LIBGPGME +libalpm_la_SOURCES += \ +	base64.h base64.c +endif + +libalpm_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_INFO) @LIBCURL@  libalpm_la_LIBADD = $(LTLIBINTL)  # vim:set ts=2 sw=2 noet: diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index ad6ef17e..7b394a5b 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -37,50 +37,44 @@  /* libalpm */  #include "add.h" +#include "alpm.h"  #include "alpm_list.h" +#include "handle.h"  #include "trans.h"  #include "util.h"  #include "log.h"  #include "backup.h"  #include "package.h"  #include "db.h" -#include "conflict.h" -#include "deps.h"  #include "remove.h"  #include "handle.h" -/** Add a package to the transaction. - * @param pkg the package to add - * @return 0 on success, -1 on error (pm_errno is set accordingly) - */ -int SYMEXPORT alpm_add_pkg(pmpkg_t *pkg) +/** Add a package to the transaction. */ +int SYMEXPORT alpm_add_pkg(pmhandle_t *handle, pmpkg_t *pkg)  {  	const char *pkgname, *pkgver;  	pmtrans_t *trans; -	pmdb_t *db_local;  	pmpkg_t *local; -	ALPM_LOG_FUNC; -  	/* Sanity checks */ -	ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1); +	ASSERT(pkg != NULL, RET_ERR(handle, PM_ERR_WRONG_ARGS, -1)); +	ASSERT(handle == pkg->handle, RET_ERR(handle, PM_ERR_WRONG_ARGS, -1));  	trans = handle->trans; -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); -	ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1)); -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); -	db_local = handle->db_local; +	ASSERT(trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1)); +	ASSERT(trans->state == STATE_INITIALIZED, +			RET_ERR(handle, PM_ERR_TRANS_NOT_INITIALIZED, -1)); -	pkgname = alpm_pkg_get_name(pkg); -	pkgver = alpm_pkg_get_version(pkg); +	pkgname = pkg->name; +	pkgver = pkg->version; -	_alpm_log(PM_LOG_DEBUG, "adding package '%s'\n", pkgname); +	_alpm_log(handle, PM_LOG_DEBUG, "adding package '%s'\n", pkgname);  	if(_alpm_pkg_find(trans->add, pkgname)) { -		RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1); +		RET_ERR(handle, PM_ERR_TRANS_DUP_TARGET, -1);  	} -	local = _alpm_db_get_pkgfromcache(db_local, pkgname); +	local = _alpm_db_get_pkgfromcache(handle->db_local, pkgname);  	if(local) {  		const char *localpkgname = alpm_pkg_get_name(local);  		const char *localpkgver = alpm_pkg_get_version(local); @@ -89,30 +83,30 @@ int SYMEXPORT alpm_add_pkg(pmpkg_t *pkg)  		if(cmp == 0) {  			if(trans->flags & PM_TRANS_FLAG_NEEDED) {  				/* with the NEEDED flag, packages up to date are not reinstalled */ -				_alpm_log(PM_LOG_WARNING, _("%s-%s is up to date -- skipping\n"), +				_alpm_log(handle, PM_LOG_WARNING, _("%s-%s is up to date -- skipping\n"),  						localpkgname, localpkgver); -				return(0); +				return 0;  			} else if(!(trans->flags & PM_TRANS_FLAG_DOWNLOADONLY)) { -				_alpm_log(PM_LOG_WARNING, _("%s-%s is up to date -- reinstalling\n"), +				_alpm_log(handle, PM_LOG_WARNING, _("%s-%s is up to date -- reinstalling\n"),  						localpkgname, localpkgver);  			}  		} else if(cmp < 0) {  			/* local version is newer */ -			_alpm_log(PM_LOG_WARNING, _("downgrading package %s (%s => %s)\n"), +			_alpm_log(handle, PM_LOG_WARNING, _("downgrading package %s (%s => %s)\n"),  					localpkgname, localpkgver, pkgver);  		}  	}  	/* add the package to the transaction */  	pkg->reason = PM_PKG_REASON_EXPLICIT; -	_alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n", +	_alpm_log(handle, PM_LOG_DEBUG, "adding package %s-%s to the transaction add list\n",  						pkgname, pkgver);  	trans->add = alpm_list_add(trans->add, pkg); -	return(0); +	return 0;  } -static int perform_extraction(struct archive *archive, +static int perform_extraction(pmhandle_t *handle, struct archive *archive,  		struct archive_entry *entry, const char *filename, const char *origname)  {  	int ret; @@ -125,21 +119,20 @@ static int perform_extraction(struct archive *archive,  	ret = archive_read_extract(archive, entry, archive_flags);  	if(ret == ARCHIVE_WARN && archive_errno(archive) != ENOSPC) {  		/* operation succeeded but a "non-critical" error was encountered */ -		_alpm_log(PM_LOG_WARNING, _("warning given when extracting %s (%s)\n"), +		_alpm_log(handle, PM_LOG_WARNING, _("warning given when extracting %s (%s)\n"),  				origname, archive_error_string(archive));  	} else if(ret != ARCHIVE_OK) { -		_alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)\n"), +		_alpm_log(handle, PM_LOG_ERROR, _("could not extract %s (%s)\n"),  				origname, archive_error_string(archive)); -		alpm_logaction("error: could not extract %s (%s)\n", +		alpm_logaction(handle, "error: could not extract %s (%s)\n",  				origname, archive_error_string(archive)); -		return(1); +		return 1;  	} -	return(0); +	return 0;  } -static int extract_single_file(struct archive *archive, -		struct archive_entry *entry, pmpkg_t *newpkg, pmpkg_t *oldpkg, -		pmtrans_t *trans, pmdb_t *db) +static int extract_single_file(pmhandle_t *handle, struct archive *archive, +		struct archive_entry *entry, pmpkg_t *newpkg, pmpkg_t *oldpkg)  {  	const char *entryname;  	mode_t entrymode; @@ -157,19 +150,19 @@ static int extract_single_file(struct archive *archive,  	if(strcmp(entryname, ".INSTALL") == 0) {  		/* the install script goes inside the db */  		snprintf(filename, PATH_MAX, "%s%s-%s/install", -				_alpm_db_path(db), newpkg->name, newpkg->version); +				_alpm_db_path(handle->db_local), newpkg->name, newpkg->version);  		archive_entry_set_perm(entry, 0644);  	} else if(strcmp(entryname, ".CHANGELOG") == 0) {  		/* the changelog goes inside the db */  		snprintf(filename, PATH_MAX, "%s%s-%s/changelog", -				_alpm_db_path(db), newpkg->name, newpkg->version); +				_alpm_db_path(handle->db_local), newpkg->name, newpkg->version);  		archive_entry_set_perm(entry, 0644);  	} else if(*entryname == '.') {  		/* for now, ignore all files starting with '.' that haven't  		 * already been handled (for future possibilities) */ -		_alpm_log(PM_LOG_DEBUG, "skipping extraction of '%s'\n", entryname); +		_alpm_log(handle, PM_LOG_DEBUG, "skipping extraction of '%s'\n", entryname);  		archive_read_data_skip(archive); -		return(0); +		return 0;  	} else {  		/* build the new entryname relative to handle->root */  		snprintf(filename, PATH_MAX, "%s%s", handle->root, entryname); @@ -177,12 +170,12 @@ static int extract_single_file(struct archive *archive,  	/* if a file is in NoExtract then we never extract it */  	if(alpm_list_find_str(handle->noextract, entryname)) { -		_alpm_log(PM_LOG_DEBUG, "%s is in NoExtract, skipping extraction\n", +		_alpm_log(handle, PM_LOG_DEBUG, "%s is in NoExtract, skipping extraction\n",  				entryname); -		alpm_logaction("note: %s is in NoExtract, skipping extraction\n", +		alpm_logaction(handle, "note: %s is in NoExtract, skipping extraction\n",  				entryname);  		archive_read_data_skip(archive); -		return(0); +		return 0;  	}  	/* Check for file existence. This is one of the more crucial parts @@ -216,42 +209,42 @@ static int extract_single_file(struct archive *archive,  				if(lsbuf.st_mode != entrymode) {  					/* if filesystem perms are different than pkg perms, warn user */  					mode_t mask = 07777; -					_alpm_log(PM_LOG_WARNING, _("directory permissions differ on %s\n" +					_alpm_log(handle, PM_LOG_WARNING, _("directory permissions differ on %s\n"  								"filesystem: %o  package: %o\n"), entryname, lsbuf.st_mode & mask,  							entrymode & mask); -					alpm_logaction("warning: directory permissions differ on %s\n" +					alpm_logaction(handle, "warning: directory permissions differ on %s\n"  							"filesystem: %o  package: %o\n", entryname, lsbuf.st_mode & mask,  							entrymode & mask);  				} -				_alpm_log(PM_LOG_DEBUG, "extract: skipping dir extraction of %s\n", +				_alpm_log(handle, PM_LOG_DEBUG, "extract: skipping dir extraction of %s\n",  						entryname);  				archive_read_data_skip(archive); -				return(0); +				return 0;  			} else {  				/* case 10/11: trying to overwrite dir with file/symlink, don't allow it */ -				_alpm_log(PM_LOG_ERROR, _("extract: not overwriting dir with file %s\n"), +				_alpm_log(handle, PM_LOG_ERROR, _("extract: not overwriting dir with file %s\n"),  						entryname);  				archive_read_data_skip(archive); -				return(1); +				return 1;  			}  		} else if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(entrymode)) {  			/* case 9: existing symlink, dir in package */  			if(S_ISDIR(sbuf.st_mode)) {  				/* the symlink on FS is to a directory, so we'll use it */ -				_alpm_log(PM_LOG_DEBUG, "extract: skipping symlink overwrite of %s\n", +				_alpm_log(handle, PM_LOG_DEBUG, "extract: skipping symlink overwrite of %s\n",  						entryname);  				archive_read_data_skip(archive); -				return(0); +				return 0;  			} else {  				/* this is BAD. symlink was not to a directory */ -				_alpm_log(PM_LOG_ERROR, _("extract: symlink %s does not point to dir\n"), +				_alpm_log(handle, PM_LOG_ERROR, _("extract: symlink %s does not point to dir\n"),  						entryname);  				archive_read_data_skip(archive); -				return(1); +				return 1;  			}  		} else if(S_ISREG(lsbuf.st_mode) && S_ISDIR(entrymode)) {  			/* case 6: trying to overwrite file with dir */ -			_alpm_log(PM_LOG_DEBUG, "extract: overwriting file with dir %s\n", +			_alpm_log(handle, PM_LOG_DEBUG, "extract: overwriting file with dir %s\n",  					entryname);  		} else if(S_ISREG(entrymode)) {  			/* case 4,7: */ @@ -275,7 +268,7 @@ static int extract_single_file(struct archive *archive,  				/* if we force hash_orig to be non-NULL retroactive backup works */  				if(needbackup && !hash_orig) { -					STRDUP(hash_orig, "", RET_ERR(PM_ERR_MEMORY, -1)); +					STRDUP(hash_orig, "", RET_ERR(handle, PM_ERR_MEMORY, -1));  				}  			}  		} @@ -285,7 +278,7 @@ static int extract_single_file(struct archive *archive,  	/* we need access to the original entryname later after calls to  	 * archive_entry_set_pathname(), so we need to dupe it and free() later */ -	STRDUP(entryname_orig, entryname, RET_ERR(PM_ERR_MEMORY, -1)); +	STRDUP(entryname_orig, entryname, RET_ERR(handle, PM_ERR_MEMORY, -1));  	if(needbackup) {  		char checkfile[PATH_MAX]; @@ -294,12 +287,12 @@ static int extract_single_file(struct archive *archive,  		snprintf(checkfile, PATH_MAX, "%s.paccheck", filename); -		ret = perform_extraction(archive, entry, checkfile, entryname_orig); +		ret = perform_extraction(handle, archive, entry, checkfile, entryname_orig);  		if(ret == 1) {  			/* error */  			FREE(hash_orig);  			FREE(entryname_orig); -			return(1); +			return 1;  		}  		hash_local = alpm_compute_md5sum(filename); @@ -317,7 +310,7 @@ static int extract_single_file(struct archive *archive,  			char *backup = NULL;  			/* length is tab char, null byte and MD5 (32 char) */  			size_t backup_len = strlen(oldbackup) + 34; -			MALLOC(backup, backup_len, RET_ERR(PM_ERR_MEMORY, -1)); +			MALLOC(backup, backup_len, RET_ERR(handle, PM_ERR_MEMORY, -1));  			sprintf(backup, "%s\t%s", oldbackup, hash_pkg);  			backup[backup_len-1] = '\0'; @@ -325,10 +318,10 @@ static int extract_single_file(struct archive *archive,  			backups->data = backup;  		} -		_alpm_log(PM_LOG_DEBUG, "checking hashes for %s\n", entryname_orig); -		_alpm_log(PM_LOG_DEBUG, "current:  %s\n", hash_local); -		_alpm_log(PM_LOG_DEBUG, "new:      %s\n", hash_pkg); -		_alpm_log(PM_LOG_DEBUG, "original: %s\n", hash_orig); +		_alpm_log(handle, PM_LOG_DEBUG, "checking hashes for %s\n", entryname_orig); +		_alpm_log(handle, PM_LOG_DEBUG, "current:  %s\n", hash_local); +		_alpm_log(handle, PM_LOG_DEBUG, "new:      %s\n", hash_pkg); +		_alpm_log(handle, PM_LOG_DEBUG, "original: %s\n", hash_orig);  		if(!oldpkg) {  			if(strcmp(hash_local, hash_pkg) != 0) { @@ -339,22 +332,22 @@ static int extract_single_file(struct archive *archive,  				/* move the existing file to the "pacorig" */  				if(rename(filename, newpath)) { -					_alpm_log(PM_LOG_ERROR, _("could not rename %s to %s (%s)\n"), +					_alpm_log(handle, PM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),  							filename, newpath, strerror(errno)); -					alpm_logaction("error: could not rename %s to %s (%s)\n", +					alpm_logaction(handle, "error: could not rename %s to %s (%s)\n",  							filename, newpath, strerror(errno));  					errors++;  				} else {  					/* rename the file we extracted to the real name */  					if(rename(checkfile, filename)) { -						_alpm_log(PM_LOG_ERROR, _("could not rename %s to %s (%s)\n"), +						_alpm_log(handle, PM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),  								checkfile, filename, strerror(errno)); -						alpm_logaction("error: could not rename %s to %s (%s)\n", +						alpm_logaction(handle, "error: could not rename %s to %s (%s)\n",  								checkfile, filename, strerror(errno));  						errors++;  					} else { -						_alpm_log(PM_LOG_WARNING, _("%s saved as %s\n"), filename, newpath); -						alpm_logaction("warning: %s saved as %s\n", filename, newpath); +						_alpm_log(handle, PM_LOG_WARNING, _("%s saved as %s\n"), filename, newpath); +						alpm_logaction(handle, "warning: %s saved as %s\n", filename, newpath);  					}  				}  			} else { @@ -367,48 +360,48 @@ static int extract_single_file(struct archive *archive,  			if(strcmp(hash_orig, hash_local) == 0) {  				/* installed file has NOT been changed by user */  				if(strcmp(hash_orig, hash_pkg) != 0) { -					_alpm_log(PM_LOG_DEBUG, "action: installing new file: %s\n", +					_alpm_log(handle, PM_LOG_DEBUG, "action: installing new file: %s\n",  							entryname_orig);  					if(rename(checkfile, filename)) { -						_alpm_log(PM_LOG_ERROR, _("could not rename %s to %s (%s)\n"), +						_alpm_log(handle, PM_LOG_ERROR, _("could not rename %s to %s (%s)\n"),  								checkfile, filename, strerror(errno)); -						alpm_logaction("error: could not rename %s to %s (%s)\n", +						alpm_logaction(handle, "error: could not rename %s to %s (%s)\n",  								checkfile, filename, strerror(errno));  						errors++;  					}  				} else {  					/* there's no sense in installing the same file twice, install  					 * ONLY is the original and package hashes differ */ -					_alpm_log(PM_LOG_DEBUG, "action: leaving existing file in place\n"); +					_alpm_log(handle, PM_LOG_DEBUG, "action: leaving existing file in place\n");  					unlink(checkfile);  				}  			} else if(strcmp(hash_orig, hash_pkg) == 0) {  				/* originally installed file and new file are the same - this  				 * implies the case above failed - i.e. the file was changed by a  				 * user */ -				_alpm_log(PM_LOG_DEBUG, "action: leaving existing file in place\n"); +				_alpm_log(handle, PM_LOG_DEBUG, "action: leaving existing file in place\n");  				unlink(checkfile);  			} else if(strcmp(hash_local, hash_pkg) == 0) {  				/* this would be magical.  The above two cases failed, but the  				 * user changes just so happened to make the new file exactly the  				 * same as the one in the package... skip it */ -				_alpm_log(PM_LOG_DEBUG, "action: leaving existing file in place\n"); +				_alpm_log(handle, PM_LOG_DEBUG, "action: leaving existing file in place\n");  				unlink(checkfile);  			} else {  				char newpath[PATH_MAX]; -				_alpm_log(PM_LOG_DEBUG, "action: keeping current file and installing" +				_alpm_log(handle, PM_LOG_DEBUG, "action: keeping current file and installing"  						" new one with .pacnew ending\n");  				snprintf(newpath, PATH_MAX, "%s.pacnew", filename);  				if(rename(checkfile, newpath)) { -					_alpm_log(PM_LOG_ERROR, _("could not install %s as %s (%s)\n"), +					_alpm_log(handle, PM_LOG_ERROR, _("could not install %s as %s (%s)\n"),  							filename, newpath, strerror(errno)); -					alpm_logaction("error: could not install %s as %s (%s)\n", +					alpm_logaction(handle, "error: could not install %s as %s (%s)\n",  							filename, newpath, strerror(errno));  				} else { -					_alpm_log(PM_LOG_WARNING, _("%s installed as %s\n"), +					_alpm_log(handle, PM_LOG_WARNING, _("%s installed as %s\n"),  							filename, newpath); -					alpm_logaction("warning: %s installed as %s\n", +					alpm_logaction(handle, "warning: %s installed as %s\n",  							filename, newpath);  				}  			} @@ -423,26 +416,26 @@ static int extract_single_file(struct archive *archive,  		/* we didn't need a backup */  		if(notouch) {  			/* change the path to a .pacnew extension */ -			_alpm_log(PM_LOG_DEBUG, "%s is in NoUpgrade -- skipping\n", filename); -			_alpm_log(PM_LOG_WARNING, _("extracting %s as %s.pacnew\n"), filename, filename); -			alpm_logaction("warning: extracting %s as %s.pacnew\n", filename, filename); +			_alpm_log(handle, PM_LOG_DEBUG, "%s is in NoUpgrade -- skipping\n", filename); +			_alpm_log(handle, PM_LOG_WARNING, _("extracting %s as %s.pacnew\n"), filename, filename); +			alpm_logaction(handle, "warning: extracting %s as %s.pacnew\n", filename, filename);  			strncat(filename, ".pacnew", PATH_MAX - strlen(filename));  		} else { -			_alpm_log(PM_LOG_DEBUG, "extracting %s\n", filename); +			_alpm_log(handle, PM_LOG_DEBUG, "extracting %s\n", filename);  		} -		if(trans->flags & PM_TRANS_FLAG_FORCE) { +		if(handle->trans->flags & PM_TRANS_FLAG_FORCE) {  			/* if FORCE was used, unlink() each file (whether it's there  			 * or not) before extracting. This prevents the old "Text file busy"  			 * error that crops up if forcing a glibc or pacman upgrade. */  			unlink(filename);  		} -		ret = perform_extraction(archive, entry, filename, entryname_orig); +		ret = perform_extraction(handle, archive, entry, filename, entryname_orig);  		if(ret == 1) {  			/* error */  			FREE(entryname_orig); -			return(1); +			return 1;  		}  		/* calculate an hash if this is in newpkg's backup */ @@ -456,10 +449,10 @@ static int extract_single_file(struct archive *archive,  			if(!oldbackup || strcmp(oldbackup, entryname_orig) != 0) {  				continue;  			} -			_alpm_log(PM_LOG_DEBUG, "appending backup entry for %s\n", filename); +			_alpm_log(handle, PM_LOG_DEBUG, "appending backup entry for %s\n", filename);  			hash = alpm_compute_md5sum(filename); -			MALLOC(backup, backup_len, RET_ERR(PM_ERR_MEMORY, -1)); +			MALLOC(backup, backup_len, RET_ERR(handle, PM_ERR_MEMORY, -1));  			sprintf(backup, "%s\t%s", oldbackup, hash);  			backup[backup_len-1] = '\0'; @@ -469,20 +462,18 @@ static int extract_single_file(struct archive *archive,  		}  	}  	FREE(entryname_orig); -	return(errors); +	return errors;  } -static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current, -		size_t pkg_count, pmtrans_t *trans, pmdb_t *db) +static int commit_single_pkg(pmhandle_t *handle, pmpkg_t *newpkg, +		size_t pkg_current, size_t pkg_count)  {  	int i, ret = 0, errors = 0; -	char scriptlet[PATH_MAX+1]; +	char scriptlet[PATH_MAX];  	int is_upgrade = 0;  	pmpkg_t *oldpkg = NULL; - -	ALPM_LOG_FUNC; - -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); +	pmdb_t *db = handle->db_local; +	pmtrans_t *trans = handle->trans;  	snprintf(scriptlet, PATH_MAX, "%s%s-%s/install",  			_alpm_db_path(db), alpm_pkg_get_name(newpkg), @@ -500,7 +491,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,  		_alpm_local_db_read(oldpkg->origin_data.db, oldpkg, INFRQ_ALL);  		EVENT(trans, PM_TRANS_EVT_UPGRADE_START, newpkg, oldpkg); -		_alpm_log(PM_LOG_DEBUG, "upgrading package %s-%s\n", +		_alpm_log(handle, PM_LOG_DEBUG, "upgrading package %s-%s\n",  				newpkg->name, newpkg->version);  		/* copy over the install reason */ @@ -508,20 +499,20 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,  		/* pre_upgrade scriptlet */  		if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { -			_alpm_runscriptlet(handle->root, newpkg->origin_data.file, -					"pre_upgrade", newpkg->version, oldpkg->version, trans); +			_alpm_runscriptlet(handle, newpkg->origin_data.file, +					"pre_upgrade", newpkg->version, oldpkg->version);  		}  	} else {  		is_upgrade = 0;  		EVENT(trans, PM_TRANS_EVT_ADD_START, newpkg, NULL); -		_alpm_log(PM_LOG_DEBUG, "adding package %s-%s\n", +		_alpm_log(handle, PM_LOG_DEBUG, "adding package %s-%s\n",  				newpkg->name, newpkg->version);  		/* pre_install scriptlet */  		if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { -			_alpm_runscriptlet(handle->root, newpkg->origin_data.file, -					"pre_install", newpkg->version, NULL, trans); +			_alpm_runscriptlet(handle, newpkg->origin_data.file, +					"pre_install", newpkg->version, NULL);  		}  	} @@ -534,8 +525,8 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,  	if(oldpkg) {  		/* set up fake remove transaction */ -		if(_alpm_upgraderemove_package(oldpkg, newpkg, trans) == -1) { -			pm_errno = PM_ERR_TRANS_ABORT; +		if(_alpm_upgraderemove_package(handle, oldpkg, newpkg) == -1) { +			handle->pm_errno = PM_ERR_TRANS_ABORT;  			ret = -1;  			goto cleanup;  		} @@ -544,9 +535,9 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,  	/* prepare directory for database entries so permission are correct after  	   changelog/install script installation (FS#12263) */  	if(_alpm_local_db_prepare(db, newpkg)) { -		alpm_logaction("error: could not create database entry %s-%s\n", +		alpm_logaction(handle, "error: could not create database entry %s-%s\n",  				alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg)); -		pm_errno = PM_ERR_DB_WRITE; +		handle->pm_errno = PM_ERR_DB_WRITE;  		ret = -1;  		goto cleanup;  	} @@ -557,10 +548,10 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,  		char cwd[PATH_MAX] = "";  		int restore_cwd = 0; -		_alpm_log(PM_LOG_DEBUG, "extracting files\n"); +		_alpm_log(handle, PM_LOG_DEBUG, "extracting files\n"); -		if ((archive = archive_read_new()) == NULL) { -			pm_errno = PM_ERR_LIBARCHIVE; +		if((archive = archive_read_new()) == NULL) { +			handle->pm_errno = PM_ERR_LIBARCHIVE;  			ret = -1;  			goto cleanup;  		} @@ -568,24 +559,25 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,  		archive_read_support_compression_all(archive);  		archive_read_support_format_all(archive); -		_alpm_log(PM_LOG_DEBUG, "archive: %s\n", newpkg->origin_data.file); +		_alpm_log(handle, PM_LOG_DEBUG, "archive: %s\n", newpkg->origin_data.file);  		if(archive_read_open_filename(archive, newpkg->origin_data.file,  					ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { -			pm_errno = PM_ERR_PKG_OPEN; +			handle->pm_errno = PM_ERR_PKG_OPEN;  			ret = -1;  			goto cleanup;  		}  		/* save the cwd so we can restore it later */  		if(getcwd(cwd, PATH_MAX) == NULL) { -			_alpm_log(PM_LOG_ERROR, _("could not get current working directory\n")); +			_alpm_log(handle, PM_LOG_ERROR, _("could not get current working directory\n"));  		} else {  			restore_cwd = 1;  		}  		/* libarchive requires this for extracting hard links */  		if(chdir(handle->root) != 0) { -			_alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), handle->root, strerror(errno)); +			_alpm_log(handle, PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), +					handle->root, strerror(errno));  			ret = -1;  			goto cleanup;  		} @@ -608,7 +600,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,  				 * (missing metadata sizes) */  				int64_t pos = archive_position_compressed(archive);  				percent = (pos * 100) / newpkg->size; -				_alpm_log(PM_LOG_DEBUG, "decompression progress: " +				_alpm_log(handle, PM_LOG_DEBUG, "decompression progress: "  						"%d%% (%"PRId64" / %jd)\n",  						percent, pos, (intmax_t)newpkg->size);  				if(percent >= 100) { @@ -629,27 +621,26 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,  			}  			/* extract the next file from the archive */ -			errors += extract_single_file(archive, entry, newpkg, oldpkg, -					trans, db); +			errors += extract_single_file(handle, archive, entry, newpkg, oldpkg);  		}  		archive_read_finish(archive);  		/* restore the old cwd if we have it */  		if(restore_cwd && chdir(cwd) != 0) { -			_alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno)); +			_alpm_log(handle, PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno));  		}  		if(errors) {  			ret = -1;  			if(is_upgrade) { -				_alpm_log(PM_LOG_ERROR, _("problem occurred while upgrading %s\n"), +				_alpm_log(handle, PM_LOG_ERROR, _("problem occurred while upgrading %s\n"),  						newpkg->name); -				alpm_logaction("error: problem occurred while upgrading %s\n", +				alpm_logaction(handle, "error: problem occurred while upgrading %s\n",  						newpkg->name);  			} else { -				_alpm_log(PM_LOG_ERROR, _("problem occurred while installing %s\n"), +				_alpm_log(handle, PM_LOG_ERROR, _("problem occurred while installing %s\n"),  						newpkg->name); -				alpm_logaction("error: problem occurred while installing %s\n", +				alpm_logaction(handle, "error: problem occurred while installing %s\n",  						newpkg->name);  			}  		} @@ -658,21 +649,21 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,  	/* make an install date (in UTC) */  	newpkg->installdate = time(NULL); -	_alpm_log(PM_LOG_DEBUG, "updating database\n"); -	_alpm_log(PM_LOG_DEBUG, "adding database entry '%s'\n", newpkg->name); +	_alpm_log(handle, PM_LOG_DEBUG, "updating database\n"); +	_alpm_log(handle, PM_LOG_DEBUG, "adding database entry '%s'\n", newpkg->name);  	if(_alpm_local_db_write(db, newpkg, INFRQ_ALL)) { -		_alpm_log(PM_LOG_ERROR, _("could not update database entry %s-%s\n"), +		_alpm_log(handle, PM_LOG_ERROR, _("could not update database entry %s-%s\n"),  				alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg)); -		alpm_logaction("error: could not update database entry %s-%s\n", +		alpm_logaction(handle, "error: could not update database entry %s-%s\n",  				alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg)); -		pm_errno = PM_ERR_DB_WRITE; +		handle->pm_errno = PM_ERR_DB_WRITE;  		ret = -1;  		goto cleanup;  	}  	if(_alpm_db_add_pkgincache(db, newpkg) == -1) { -		_alpm_log(PM_LOG_ERROR, _("could not add entry '%s' in cache\n"), +		_alpm_log(handle, PM_LOG_ERROR, _("could not add entry '%s' in cache\n"),  				alpm_pkg_get_name(newpkg));  	} @@ -688,12 +679,12 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,  	if(alpm_pkg_has_scriptlet(newpkg)  			&& !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {  		if(is_upgrade) { -			_alpm_runscriptlet(handle->root, scriptlet, "post_upgrade", +			_alpm_runscriptlet(handle, scriptlet, "post_upgrade",  					alpm_pkg_get_version(newpkg), -					oldpkg ? alpm_pkg_get_version(oldpkg) : NULL, trans); +					oldpkg ? alpm_pkg_get_version(oldpkg) : NULL);  		} else { -			_alpm_runscriptlet(handle->root, scriptlet, "post_install", -					alpm_pkg_get_version(newpkg), NULL, trans); +			_alpm_runscriptlet(handle, scriptlet, "post_install", +					alpm_pkg_get_version(newpkg), NULL);  		}  	} @@ -705,22 +696,18 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current,  cleanup:  	_alpm_pkg_free(oldpkg); -	return(ret); +	return ret;  } -int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db) +int _alpm_upgrade_packages(pmhandle_t *handle)  {  	size_t pkg_count, pkg_current;  	int skip_ldconfig = 0, ret = 0;  	alpm_list_t *targ; - -	ALPM_LOG_FUNC; - -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); -	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); +	pmtrans_t *trans = handle->trans;  	if(trans->add == NULL) { -		return(0); +		return 0;  	}  	pkg_count = alpm_list_count(trans->add); @@ -728,15 +715,16 @@ int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db)  	/* loop through our package list adding/upgrading one at a time */  	for(targ = trans->add; targ; targ = targ->next) { +		pmpkg_t *newpkg = targ->data; +  		if(handle->trans->state == STATE_INTERRUPTED) { -			return(ret); +			return ret;  		} -		pmpkg_t *newpkg = (pmpkg_t *)targ->data; -		if(commit_single_pkg(newpkg, pkg_current, pkg_count, trans, db)) { +		if(commit_single_pkg(handle, newpkg, pkg_current, pkg_count)) {  			/* something screwed up on the commit, abort the trans */  			trans->state = STATE_INTERRUPTED; -			pm_errno = PM_ERR_TRANS_ABORT; +			handle->pm_errno = PM_ERR_TRANS_ABORT;  			/* running ldconfig at this point could possibly screw system */  			skip_ldconfig = 1;  			ret = -1; @@ -747,10 +735,10 @@ int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db)  	if(!skip_ldconfig) {  		/* run ldconfig if it exists */ -		_alpm_ldconfig(handle->root); +		_alpm_ldconfig(handle);  	} -	return(ret); +	return ret;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/add.h b/lib/libalpm/add.h index afc7be26..1baab8d4 100644 --- a/lib/libalpm/add.h +++ b/lib/libalpm/add.h @@ -24,7 +24,7 @@  #include "alpm_list.h"  #include "trans.h" -int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db); +int _alpm_upgrade_packages(pmhandle_t *handle);  #endif /* _ALPM_ADD_H */ diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index a60a4bb6..9b9719d1 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -23,20 +23,17 @@  #include "config.h" -/* connection caching setup */ -#ifdef HAVE_LIBFETCH -#include <fetch.h> +#ifdef HAVE_LIBCURL +#include <curl/curl.h>  #endif  /* libalpm */  #include "alpm.h"  #include "alpm_list.h"  #include "handle.h" +#include "log.h"  #include "util.h" -/* Globals */ -enum _pmerrno_t pm_errno SYMEXPORT; -  /** \addtogroup alpm_interface Interface Functions   * @brief Functions to initialize and release libalpm   * @{ @@ -44,64 +41,89 @@ enum _pmerrno_t pm_errno SYMEXPORT;  /** Initializes the library.  This must be called before any other   * functions are called. - * @return 0 on success, -1 on error (pm_errno is set accordingly) + * @param root the root path for all filesystem operations + * @param dbpath the absolute path to the libalpm database + * @param err an optional variable to hold any error return codes + * @return a context handle on success, NULL on error, err will be set if provided   */ -int SYMEXPORT alpm_initialize(void) +pmhandle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath, +		enum _pmerrno_t *err)  { -	ASSERT(handle == NULL, RET_ERR(PM_ERR_HANDLE_NOT_NULL, -1)); - -	handle = _alpm_handle_new(); -	if(handle == NULL) { -		RET_ERR(PM_ERR_MEMORY, -1); +	enum _pmerrno_t myerr; +	const char *lf = "db.lck"; +	size_t lockfilelen; +	pmhandle_t *myhandle = _alpm_handle_new(); + +	if(myhandle == NULL) { +		myerr = PM_ERR_MEMORY; +		goto cleanup; +	} +	if((myerr = _alpm_set_directory_option(root, &(myhandle->root), 1))) { +		goto cleanup;  	} -	if(_alpm_db_register_local() == NULL) { -		/* error code should be set */ -		_alpm_handle_free(handle); -		handle = NULL; -		return(-1); +	if((myerr = _alpm_set_directory_option(dbpath, &(myhandle->dbpath), 1))) { +		goto cleanup; +	} + +	lockfilelen = strlen(myhandle->dbpath) + strlen(lf) + 1; +	myhandle->lockfile = calloc(lockfilelen, sizeof(char)); +	snprintf(myhandle->lockfile, lockfilelen, "%s%s", myhandle->dbpath, lf); + +	if(_alpm_db_register_local(myhandle) == NULL) { +		myerr = PM_ERR_DB_CREATE; +		goto cleanup;  	}  #ifdef ENABLE_NLS  	bindtextdomain("libalpm", LOCALEDIR);  #endif -#ifdef HAVE_LIBFETCH -	fetchConnectionCacheInit(5, 1); +#ifdef HAVE_LIBCURL +	curl_global_init(CURL_GLOBAL_SSL); +	myhandle->curl = curl_easy_init();  #endif -	return(0); +	return myhandle; + +cleanup: +	_alpm_handle_free(myhandle); +	if(err && myerr) { +		*err = myerr; +	} +	return NULL;  }  /** Release the library.  This should be the last alpm call you make. - * @return 0 on success, -1 on error (pm_errno is set accordingly) + * After this returns, handle should be considered invalid and cannot be reused + * in any way. + * @param handle the context handle + * @return 0 on success, -1 on error   */ -int SYMEXPORT alpm_release(void) +int SYMEXPORT alpm_release(pmhandle_t *myhandle)  { +	int ret = 0;  	pmdb_t *db; -	ALPM_LOG_FUNC; - -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(myhandle, return -1);  	/* close local database */ -	db = handle->db_local; +	db = myhandle->db_local;  	if(db) {  		db->ops->unregister(db); -		handle->db_local = NULL; +		myhandle->db_local = NULL;  	} -	if(alpm_db_unregister_all() == -1) { -		return(-1); +	if(alpm_db_unregister_all(myhandle) == -1) { +		ret = -1;  	} -	_alpm_handle_free(handle); -	handle = NULL; +	_alpm_handle_free(myhandle); -#ifdef HAVE_LIBFETCH -	fetchConnectionCacheClose(); +#ifdef HAVE_LIBCURL +	curl_global_cleanup();  #endif -	return(0); +	return ret;  }  /** @} */ @@ -112,7 +134,7 @@ int SYMEXPORT alpm_release(void)  /* Get the version of library */  const char SYMEXPORT *alpm_version(void) { -	return(LIB_VERSION); +	return LIB_VERSION;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index cb643d29..845bd478 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -45,9 +45,36 @@ extern "C" {   */  /* + * Enumerations + * These ones are used in multiple contexts, so are forward-declared. + */ + +/** + * Install reasons + * Why the package was installed. + */ +typedef enum _pmpkgreason_t { +	/** Explicitly requested by the user. */ +	PM_PKG_REASON_EXPLICIT = 0, +	/** Installed as a dependency for another package. */ +	PM_PKG_REASON_DEPEND = 1 +} pmpkgreason_t; + +/** + * GPG signature verification options + */ +typedef enum _pgp_verify_t { +	PM_PGP_VERIFY_UNKNOWN, +	PM_PGP_VERIFY_NEVER, +	PM_PGP_VERIFY_OPTIONAL, +	PM_PGP_VERIFY_ALWAYS +} pgp_verify_t; + +/*   * Structures   */ +typedef struct __pmhandle_t pmhandle_t;  typedef struct __pmdb_t pmdb_t;  typedef struct __pmpkg_t pmpkg_t;  typedef struct __pmdelta_t pmdelta_t; @@ -59,18 +86,12 @@ typedef struct __pmconflict_t pmconflict_t;  typedef struct __pmfileconflict_t pmfileconflict_t;  /* - * Library - */ - -int alpm_initialize(void); -int alpm_release(void); -const char *alpm_version(void); - -/*   * Logging facilities   */ -/* Levels */ +/** + * Logging Levels + */  typedef enum _pmloglevel_t {  	PM_LOG_ERROR    = 1,  	PM_LOG_WARNING  = (1 << 1), @@ -79,15 +100,22 @@ typedef enum _pmloglevel_t {  } pmloglevel_t;  typedef void (*alpm_cb_log)(pmloglevel_t, const char *, va_list); -int alpm_logaction(const char *fmt, ...); +int alpm_logaction(pmhandle_t *handle, const char *fmt, ...);  /*   * Downloading   */ +/** Type of download progress callbacks. + * @param filename the name of the file being downloaded + * @param xfered the number of transferred bytes + * @param total the total number of bytes to transfer + */  typedef void (*alpm_cb_download)(const char *filename,  		off_t xfered, off_t total); +  typedef void (*alpm_cb_totaldl)(off_t total); +  /** A callback for downloading files   * @param url the URL of the file to be downloaded   * @param localpath the directory to which the file should be downloaded @@ -99,111 +127,131 @@ typedef int (*alpm_cb_fetch)(const char *url, const char *localpath,  		int force);  /** Fetch a remote pkg. + * @param handle the context handle   * @param url URL of the package to download   * @return the downloaded filepath on success, NULL on error   */ -char *alpm_fetch_pkgurl(const char *url); +char *alpm_fetch_pkgurl(pmhandle_t *handle, const char *url);  /** @addtogroup alpm_api_options Options   * Libalpm option getters and setters   * @{   */ -/** @name The logging callback. */ -/* @{ */ -alpm_cb_log alpm_option_get_logcb(void); -void alpm_option_set_logcb(alpm_cb_log cb); -/* @} */ +/** Returns the callback used for logging. */ +alpm_cb_log alpm_option_get_logcb(pmhandle_t *handle); +/** Sets the callback used for logging. */ +int alpm_option_set_logcb(pmhandle_t *handle, alpm_cb_log cb); -/** Get/set the download progress callback. */ -alpm_cb_download alpm_option_get_dlcb(void); -void alpm_option_set_dlcb(alpm_cb_download cb); +/** Returns the callback used to report download progress. */ +alpm_cb_download alpm_option_get_dlcb(pmhandle_t *handle); +/** Sets the callback used to report download progress. */ +int alpm_option_set_dlcb(pmhandle_t *handle, alpm_cb_download cb); -/** Get/set the downloader callback. */ -alpm_cb_fetch alpm_option_get_fetchcb(void); -void alpm_option_set_fetchcb(alpm_cb_fetch cb); +/** Returns the downloading callback. */ +alpm_cb_fetch alpm_option_get_fetchcb(pmhandle_t *handle); +/** Sets the downloading callback. */ +int alpm_option_set_fetchcb(pmhandle_t *handle, alpm_cb_fetch cb); -/** Get/set the callback used when download size is known. */ -alpm_cb_totaldl alpm_option_get_totaldlcb(void); -void alpm_option_set_totaldlcb(alpm_cb_totaldl cb); +/** Returns the callback used to report total download size. */ +alpm_cb_totaldl alpm_option_get_totaldlcb(pmhandle_t *handle); +/** Sets the callback used to report total download size. */ +int alpm_option_set_totaldlcb(pmhandle_t *handle, alpm_cb_totaldl cb); -/** Get/set the root of the destination filesystem. */ -const char *alpm_option_get_root(void); -int alpm_option_set_root(const char *root); +/** Returns the root of the destination filesystem. Read-only. */ +const char *alpm_option_get_root(pmhandle_t *handle); -/** Get/set the path to the database directory. */ -const char *alpm_option_get_dbpath(void); -int alpm_option_set_dbpath(const char *dbpath); +/** Returns the path to the database directory. Read-only. */ +const char *alpm_option_get_dbpath(pmhandle_t *handle); -/** Get/set the list of package cache directories. */ -alpm_list_t *alpm_option_get_cachedirs(void); -void alpm_option_set_cachedirs(alpm_list_t *cachedirs); +/** Get the name of the database lock file. Read-only. */ +const char *alpm_option_get_lockfile(pmhandle_t *handle); -/** Add a single directory to the package cache paths. */ -int alpm_option_add_cachedir(const char *cachedir); +/** @name Accessors to the list of package cache directories. + * @{ + */ +alpm_list_t *alpm_option_get_cachedirs(pmhandle_t *handle); +int alpm_option_set_cachedirs(pmhandle_t *handle, alpm_list_t *cachedirs); +int alpm_option_add_cachedir(pmhandle_t *handle, const char *cachedir); +int alpm_option_remove_cachedir(pmhandle_t *handle, const char *cachedir); +/** @} */ -/** Remove a single directory from the package cache paths. */ -int alpm_option_remove_cachedir(const char *cachedir); +/** Returns the logfile name. */ +const char *alpm_option_get_logfile(pmhandle_t *handle); +/** Sets the logfile name. */ +int alpm_option_set_logfile(pmhandle_t *handle, const char *logfile); -/** Get/set the logfile name. */ -const char *alpm_option_get_logfile(void); -int alpm_option_set_logfile(const char *logfile); +/** Returns the signature directory path. */ +const char *alpm_option_get_signaturedir(pmhandle_t *handle); +/** Sets the signature directory path. */ +int alpm_option_set_signaturedir(pmhandle_t *handle, const char *signaturedir); -/** Get the name of the database lock file. - * - * This properly is read-only, and determined from - * the database path. - * - * @sa alpm_option_set_dbpath(const char*) - */ -const char *alpm_option_get_lockfile(void); +/** Returns whether to use syslog (0 is FALSE, TRUE otherwise). */ +int alpm_option_get_usesyslog(pmhandle_t *handle); +/** Sets whether to use syslog (0 is FALSE, TRUE otherwise). */ +int alpm_option_set_usesyslog(pmhandle_t *handle, int usesyslog); -/** Get/set whether to use syslog (0 is FALSE, TRUE otherwise). */ -int alpm_option_get_usesyslog(void); -void alpm_option_set_usesyslog(int usesyslog); +/** @name Accessors to the list of no-upgrade files. + * These functions modify the list of files which should + * not be updated by package installation. + * @{ + */ +alpm_list_t *alpm_option_get_noupgrades(pmhandle_t *handle); +int alpm_option_add_noupgrade(pmhandle_t *handle, const char *pkg); +int alpm_option_set_noupgrades(pmhandle_t *handle, alpm_list_t *noupgrade); +int alpm_option_remove_noupgrade(pmhandle_t *handle, const char *pkg); +/** @} */ -alpm_list_t *alpm_option_get_noupgrades(void); -void alpm_option_add_noupgrade(const char *pkg); -void alpm_option_set_noupgrades(alpm_list_t *noupgrade); -int alpm_option_remove_noupgrade(const char *pkg); +/** @name Accessors to the list of no-extract files. + * These functions modify the list of filenames which should + * be skipped packages which should + * not be upgraded by a sysupgrade operation. + * @{ + */ +alpm_list_t *alpm_option_get_noextracts(pmhandle_t *handle); +int alpm_option_add_noextract(pmhandle_t *handle, const char *pkg); +int alpm_option_set_noextracts(pmhandle_t *handle, alpm_list_t *noextract); +int alpm_option_remove_noextract(pmhandle_t *handle, const char *pkg); +/** @} */ -alpm_list_t *alpm_option_get_noextracts(void); -void alpm_option_add_noextract(const char *pkg); -void alpm_option_set_noextracts(alpm_list_t *noextract); -int alpm_option_remove_noextract(const char *pkg); +/** @name Accessors to the list of ignored packages. + * These functions modify the list of packages that + * should be ignored by a sysupgrade. + * @{ + */ +alpm_list_t *alpm_option_get_ignorepkgs(pmhandle_t *handle); +int alpm_option_add_ignorepkg(pmhandle_t *handle, const char *pkg); +int alpm_option_set_ignorepkgs(pmhandle_t *handle, alpm_list_t *ignorepkgs); +int alpm_option_remove_ignorepkg(pmhandle_t *handle, const char *pkg); +/** @} */ -alpm_list_t *alpm_option_get_ignorepkgs(void); -void alpm_option_add_ignorepkg(const char *pkg); -void alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs); -int alpm_option_remove_ignorepkg(const char *pkg); +/** @name Accessors to the list of ignored groups. + * These functions modify the list of groups whose packages + * should be ignored by a sysupgrade. + * @{ + */ +alpm_list_t *alpm_option_get_ignoregrps(pmhandle_t *handle); +int alpm_option_add_ignoregrp(pmhandle_t *handle, const char *grp); +int alpm_option_set_ignoregrps(pmhandle_t *handle, alpm_list_t *ignoregrps); +int alpm_option_remove_ignoregrp(pmhandle_t *handle, const char *grp); +/** @} */ -alpm_list_t *alpm_option_get_ignoregrps(void); -void alpm_option_add_ignoregrp(const char *grp); -void alpm_option_set_ignoregrps(alpm_list_t *ignoregrps); -int alpm_option_remove_ignoregrp(const char *grp); +/** Returns the targeted architecture. */ +const char *alpm_option_get_arch(pmhandle_t *handle); +/** Sets the targeted architecture. */ +int alpm_option_set_arch(pmhandle_t *handle, const char *arch); -/** Get/set the targeted architecture. */ -const char *alpm_option_get_arch(void); -void alpm_option_set_arch(const char *arch); +int alpm_option_get_usedelta(pmhandle_t *handle); +int alpm_option_set_usedelta(pmhandle_t *handle, int usedelta); -int alpm_option_get_usedelta(void); -void alpm_option_set_usedelta(int usedelta); +int alpm_option_get_checkspace(pmhandle_t *handle); +int alpm_option_set_checkspace(pmhandle_t *handle, int checkspace); -int alpm_option_get_checkspace(void); -void alpm_option_set_checkspace(int checkspace); +pgp_verify_t alpm_option_get_default_sigverify(pmhandle_t *handle); +int alpm_option_set_default_sigverify(pmhandle_t *handle, pgp_verify_t level);  /** @} */ -/** Install reasons - * Why the package was installed. - */ -typedef enum _pmpkgreason_t { -	/** Explicitly requested by the user. */ -	PM_PKG_REASON_EXPLICIT = 0, -	/** Installed as a dependency for another package. */ -	PM_PKG_REASON_DEPEND = 1 -} pmpkgreason_t; -  /** @addtogroup alpm_api_databases Database Functions   * Functions to query and manipulate the database of libalpm.   * @{ @@ -215,20 +263,22 @@ typedef enum _pmpkgreason_t {   * libalpm functions.   * @return a reference to the local database   */ -pmdb_t *alpm_option_get_localdb(void); +pmdb_t *alpm_option_get_localdb(pmhandle_t *handle);  /** Get the list of sync databases.   * Returns a list of pmdb_t structures, one for each registered   * sync database. + * @param handle the context handle   * @return a reference to an internal list of pmdb_t structures   */ -alpm_list_t *alpm_option_get_syncdbs(void); +alpm_list_t *alpm_option_get_syncdbs(pmhandle_t *handle);  /** Register a sync database of packages. + * @param handle the context handle   * @param treename the name of the sync repository   * @return a pmdb_t* on success (the value), NULL on error   */ -pmdb_t *alpm_db_register_sync(const char *treename); +pmdb_t *alpm_db_register_sync(pmhandle_t *handle, const char *treename);  /** Unregister a package database.   * @param db pointer to the package database to unregister @@ -237,9 +287,10 @@ pmdb_t *alpm_db_register_sync(const char *treename);  int alpm_db_unregister(pmdb_t *db);  /** Unregister all package databases. + * @param handle the context handle   * @return 0 on success, -1 on error (pm_errno is set accordingly)   */ -int alpm_db_unregister_all(void); +int alpm_db_unregister_all(pmhandle_t *handle);  /** Get the name of a package database.   * @param db pointer to the package database @@ -247,18 +298,14 @@ int alpm_db_unregister_all(void);   */  const char *alpm_db_get_name(const pmdb_t *db); -/** Get a download URL for the package database. - * @param db pointer to the package database - * @return a fully-specified download URL, NULL on error - */ -const char *alpm_db_get_url(const pmdb_t *db); - -/** Set the serverlist of a database. - * @param db database pointer - * @param url url of the server - * @return 0 on success, -1 on error (pm_errno is set accordingly) +/** @name Accessors to the list of servers for a database. + * @{   */ -int alpm_db_setserver(pmdb_t *db, const char *url); +alpm_list_t *alpm_db_get_servers(const pmdb_t *db); +int alpm_db_set_servers(pmdb_t *db, alpm_list_t *servers); +int alpm_db_add_server(pmdb_t *db, const char *url); +int alpm_db_remove_server(pmdb_t *db, const char *url); +/** @} */  int alpm_db_update(int level, pmdb_t *db); @@ -288,10 +335,10 @@ pmgrp_t *alpm_db_readgrp(pmdb_t *db, const char *name);   */  alpm_list_t *alpm_db_get_grpcache(pmdb_t *db); -/** Searches a database. +/** Searches a database with regular expressions.   * @param db pointer to the package database to search in - * @param needles the list of strings to search for - * @return the list of packages on success, NULL on error + * @param needles a list of regular expressions to search for + * @return the list of packages matching all regular expressions on success, NULL on error   */  alpm_list_t *alpm_db_search(pmdb_t *db, const alpm_list_t* needles); @@ -313,14 +360,19 @@ int alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t reason);  /** Create a package from a file.   * If full is false, the archive is read only until all necessary   * metadata is found. If it is true, the entire archive is read, which - * serves as a verfication of integrity and the filelist can be created. + * serves as a verification of integrity and the filelist can be created. + * The allocated structure should be freed using alpm_pkg_free(). + * @param handle the context handle   * @param filename location of the package tarball   * @param full whether to stop the load after metadata is read or continue - *             through the full archive + * through the full archive + * @param check_sig what level of package signature checking to perform on the + * package; note that this must be a '.sig' file type verification   * @param pkg address of the package pointer   * @return 0 on success, -1 on error (pm_errno is set accordingly)   */ -int alpm_pkg_load(const char *filename, int full, pmpkg_t **pkg); +int alpm_pkg_load(pmhandle_t *handle, const char *filename, int full, +		pgp_verify_t check_sig, pmpkg_t **pkg);  /** Free a package.   * @param pkg package pointer to free @@ -498,9 +550,9 @@ alpm_list_t *alpm_pkg_get_files(pmpkg_t *pkg);   */  alpm_list_t *alpm_pkg_get_backup(pmpkg_t *pkg); -/** Returns the database containing pkg +/** Returns the database containing pkg.   * Returns a pointer to the pmdb_t structure the package is - * originating from, or NULL is the package was loaded from a file. + * originating from, or NULL if the package was loaded from a file.   * @param pkg a pointer to package   * @return a pointer to the DB containing pkg, or NULL.   */ @@ -534,6 +586,9 @@ size_t alpm_pkg_changelog_read(void *ptr, size_t size,  int alpm_pkg_changelog_close(const pmpkg_t *pkg, void *fp); +/** Returns whether the package has an install scriptlet. + * @return 0 if FALSE, TRUE otherwise + */  int alpm_pkg_has_scriptlet(pmpkg_t *pkg);  /** Returns the size of download. @@ -550,6 +605,15 @@ alpm_list_t *alpm_pkg_unused_deltas(pmpkg_t *pkg);  /** @} */  /* + * Signatures + */ + +int alpm_pkg_check_pgp_signature(pmpkg_t *pkg); + +int alpm_db_check_pgp_signature(pmdb_t *db); +int alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify); + +/*   * Deltas   */ @@ -726,59 +790,91 @@ typedef void (*alpm_trans_cb_conv)(pmtransconv_t, void *, void *,  /** Transaction Progress callback */  typedef void (*alpm_trans_cb_progress)(pmtransprog_t, const char *, int, size_t, size_t); -int alpm_trans_get_flags(void); +/** Returns the bitfield of flags for the current transaction. + * @param handle the context handle + * @return the bitfield of transaction flags + */ +pmtransflag_t alpm_trans_get_flags(pmhandle_t *handle);  /** Returns a list of packages added by the transaction. + * @param handle the context handle   * @return a list of pmpkg_t structures   */ -alpm_list_t * alpm_trans_get_add(void); +alpm_list_t * alpm_trans_get_add(pmhandle_t *handle);  /** Returns the list of packages removed by the transaction. + * @param handle the context handle   * @return a list of pmpkg_t structures   */ -alpm_list_t * alpm_trans_get_remove(void); +alpm_list_t * alpm_trans_get_remove(pmhandle_t *handle);  /** Initialize the transaction. + * @param handle the context handle   * @param flags flags of the transaction (like nodeps, etc)   * @param event event callback function pointer   * @param conv question callback function pointer   * @param progress progress callback function pointer   * @return 0 on success, -1 on error (pm_errno is set accordingly)   */ -int alpm_trans_init(pmtransflag_t flags, +int alpm_trans_init(pmhandle_t *handle, pmtransflag_t flags,                      alpm_trans_cb_event cb_event, alpm_trans_cb_conv conv,                      alpm_trans_cb_progress cb_progress);  /** Prepare a transaction. + * @param handle the context handle   * @param data the address of an alpm_list where a list   * of pmdepmissing_t objects is dumped (conflicting packages)   * @return 0 on success, -1 on error (pm_errno is set accordingly)   */ -int alpm_trans_prepare(alpm_list_t **data); +int alpm_trans_prepare(pmhandle_t *handle, alpm_list_t **data);  /** Commit a transaction. + * @param handle the context handle   * @param data the address of an alpm_list where detailed description   * of an error can be dumped (ie. list of conflicting files)   * @return 0 on success, -1 on error (pm_errno is set accordingly)   */ -int alpm_trans_commit(alpm_list_t **data); +int alpm_trans_commit(pmhandle_t *handle, alpm_list_t **data);  /** Interrupt a transaction. + * @param handle the context handle   * @return 0 on success, -1 on error (pm_errno is set accordingly)   */ -int alpm_trans_interrupt(void); +int alpm_trans_interrupt(pmhandle_t *handle);  /** Release a transaction. + * @param handle the context handle   * @return 0 on success, -1 on error (pm_errno is set accordingly)   */ -int alpm_trans_release(void); +int alpm_trans_release(pmhandle_t *handle);  /** @} */  /** @name Common Transactions */  /** @{ */ -int alpm_sync_sysupgrade(int enable_downgrade); -int alpm_add_pkg(pmpkg_t *pkg); -int alpm_remove_pkg(pmpkg_t *pkg); + +/** Search for packages to upgrade and add them to the transaction. + * @param handle the context handle + * @param enable_downgrade allow downgrading of packages if the remote version is lower + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ +int alpm_sync_sysupgrade(pmhandle_t *handle, int enable_downgrade); + +/** Add a package to the transaction. + * If the package was loaded by alpm_pkg_load(), it will be freed upon + * alpm_trans_release() invocation. + * @param handle the context handle + * @param pkg the package to add + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ +int alpm_add_pkg(pmhandle_t *handle, pmpkg_t *pkg); + +/** Add a package removal action to the transaction. + * @param handle the context handle + * @param pkg the package to uninstall + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ +int alpm_remove_pkg(pmhandle_t *handle, pmpkg_t *pkg); +  /** @} */  /** @addtogroup alpm_api_depends Dependency Functions @@ -803,16 +899,17 @@ typedef enum _pmdepmod_t {  	PM_DEP_MOD_LT  } pmdepmod_t; -alpm_list_t *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps, -		alpm_list_t *remove, alpm_list_t *upgrade); +alpm_list_t *alpm_checkdeps(pmhandle_t *handle, alpm_list_t *pkglist, +		alpm_list_t *remove, alpm_list_t *upgrade, int reversedeps);  pmpkg_t *alpm_find_satisfier(alpm_list_t *pkgs, const char *depstring); -pmpkg_t *alpm_find_dbs_satisfier(alpm_list_t *dbs, const char *depstring); +pmpkg_t *alpm_find_dbs_satisfier(pmhandle_t *handle, +		alpm_list_t *dbs, const char *depstring);  const char *alpm_miss_get_target(const pmdepmissing_t *miss);  pmdepend_t *alpm_miss_get_dep(pmdepmissing_t *miss);  const char *alpm_miss_get_causingpkg(const pmdepmissing_t *miss); -alpm_list_t *alpm_checkconflicts(alpm_list_t *pkglist); +alpm_list_t *alpm_checkconflicts(pmhandle_t *handle, alpm_list_t *pkglist);  const char *alpm_conflict_get_package1(pmconflict_t *conflict);  const char *alpm_conflict_get_package2(pmconflict_t *conflict); @@ -916,6 +1013,10 @@ enum _pmerrno_t {  	PM_ERR_PKG_INVALID_NAME,  	PM_ERR_PKG_INVALID_ARCH,  	PM_ERR_PKG_REPO_NOT_FOUND, +	/* Signatures */ +	PM_ERR_SIG_MISSINGDIR, +	PM_ERR_SIG_INVALID, +	PM_ERR_SIG_UNKNOWN,  	/* Deltas */  	PM_ERR_DLT_INVALID,  	PM_ERR_DLT_PATCHFAILED, @@ -925,26 +1026,28 @@ enum _pmerrno_t {  	PM_ERR_FILE_CONFLICTS,  	/* Misc */  	PM_ERR_RETRIEVE, -	PM_ERR_WRITE,  	PM_ERR_INVALID_REGEX,  	/* External library errors */  	PM_ERR_LIBARCHIVE, -	PM_ERR_LIBFETCH, -	PM_ERR_EXTERNAL_DOWNLOAD +	PM_ERR_LIBCURL, +	PM_ERR_EXTERNAL_DOWNLOAD, +	PM_ERR_GPGME  }; -/** The number of the last error that occurred. */ -extern enum _pmerrno_t pm_errno; +/** Returns the current error code from the handle. */ +enum _pmerrno_t alpm_errno(pmhandle_t *handle);  /** Returns the string corresponding to an error number. */ -const char *alpm_strerror(int err); - -/** Returns the string corresponding to pm_errno. */ -const char *alpm_strerrorlast(void); +const char *alpm_strerror(enum _pmerrno_t err);  /* End of alpm_api_errors */  /** @} */ +pmhandle_t *alpm_initialize(const char *root, const char *dbpath, +		enum _pmerrno_t *err); +int alpm_release(pmhandle_t *handle); +const char *alpm_version(void); +  /* End of alpm_api */  /** @} */ diff --git a/lib/libalpm/alpm_list.c b/lib/libalpm/alpm_list.c index 42ef367a..c2b30adc 100644 --- a/lib/libalpm/alpm_list.c +++ b/lib/libalpm/alpm_list.c @@ -20,7 +20,6 @@  #include <stdlib.h>  #include <string.h> -#include <stdio.h>  /* libalpm */  #include "alpm_list.h" @@ -92,7 +91,7 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)  	ptr = calloc(1, sizeof(alpm_list_t));  	if(ptr == NULL) { -		return(list); +		return list;  	}  	ptr->data = data; @@ -101,7 +100,7 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)  	/* Special case: the input list is empty */  	if(list == NULL) {  		ptr->prev = ptr; -		return(ptr); +		return ptr;  	}  	lp = alpm_list_last(list); @@ -109,7 +108,7 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)  	ptr->prev = lp;  	list->prev = ptr; -	return(list); +	return list;  }  /** @@ -124,13 +123,13 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)  alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_list_fn_cmp fn)  {  	if(!fn || !list) { -		return(alpm_list_add(list, data)); +		return alpm_list_add(list, data);  	} else {  		alpm_list_t *add = NULL, *prev = NULL, *next = list;  		add = calloc(1, sizeof(alpm_list_t));  		if(add == NULL) { -			return(list); +			return list;  		}  		add->data = data; @@ -146,19 +145,19 @@ alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_  			add->prev = list->prev; /* list != NULL */  			add->next = list;  			list->prev = add; -			return(add); +			return add;  		} else if(next == NULL) { /* another special case: add last element */  			add->prev = prev;  			add->next = NULL;  			prev->next = add;  			list->prev = add; -			return(list); +			return list;  		} else {  			add->prev = prev;  			add->next = next;  			next->prev = add;  			prev->next = add; -			return(list); +			return list;  		}  	}  } @@ -178,11 +177,11 @@ alpm_list_t SYMEXPORT *alpm_list_join(alpm_list_t *first, alpm_list_t *second)  {  	alpm_list_t *tmp; -	if (first == NULL) { -		return(second); +	if(first == NULL) { +		return second;  	} -	if (second == NULL) { -		return(first); +	if(second == NULL) { +		return first;  	}  	/* tmp is the last element of the first list */  	tmp = first->prev; @@ -193,7 +192,7 @@ alpm_list_t SYMEXPORT *alpm_list_join(alpm_list_t *first, alpm_list_t *second)  	/* set the back reference to the tail */  	second->prev = tmp; -	return(first); +	return first;  }  /** @@ -209,12 +208,12 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a  {  	alpm_list_t *newlist, *lp; -	if (left == NULL) +	if(left == NULL)  		return right; -	if (right == NULL) +	if(right == NULL)  		return left; -	if (fn(left->data, right->data) <= 0) { +	if(fn(left->data, right->data) <= 0) {  		newlist = left;  		left = left->next;  	} @@ -226,8 +225,8 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a  	newlist->next = NULL;  	lp = newlist; -	while ((left != NULL) && (right != NULL)) { -		if (fn(left->data, right->data) <= 0) { +	while((left != NULL) && (right != NULL)) { +		if(fn(left->data, right->data) <= 0) {  			lp->next = left;  			left->prev = lp;  			left = left->next; @@ -240,11 +239,11 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a  		lp = lp->next;  		lp->next = NULL;  	} -	if (left != NULL) { +	if(left != NULL) {  		lp->next = left;  		left->prev = lp;  	} -	else if (right != NULL) { +	else if(right != NULL) {  		lp->next = right;  		right->prev = lp;  	} @@ -257,7 +256,7 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a  	}  	newlist->prev = lp; -	return(newlist); +	return newlist;  }  /** @@ -271,7 +270,7 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a   */  alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn_cmp fn)  { -	if (n > 1) { +	if(n > 1) {  		alpm_list_t *left = list;  		alpm_list_t *lastleft = alpm_list_nth(list, n/2 - 1);  		alpm_list_t *right = lastleft->next; @@ -282,7 +281,7 @@ alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn  		right = alpm_list_msort(right, n - (n/2), fn);  		list = alpm_list_mmerge(left, right, fn);  	} -	return(list); +	return list;  }  /** @@ -298,7 +297,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove_item(alpm_list_t *haystack,  		alpm_list_t *item)  {  	if(haystack == NULL || item == NULL) { -		return(haystack); +		return haystack;  	}  	if(item == haystack) { @@ -328,7 +327,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove_item(alpm_list_t *haystack,  		}  	} -	return(haystack); +	return haystack;  } @@ -352,7 +351,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack,  	}  	if(needle == NULL) { -		return(haystack); +		return haystack;  	}  	while(i) { @@ -373,7 +372,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack,  		}  	} -	return(haystack); +	return haystack;  }  /** @@ -388,8 +387,8 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack,  alpm_list_t SYMEXPORT *alpm_list_remove_str(alpm_list_t *haystack,  		const char *needle, char **data)  { -	return(alpm_list_remove(haystack, (const void *)needle, -				(alpm_list_fn_cmp)strcmp, (void **)data)); +	return alpm_list_remove(haystack, (const void *)needle, +			(alpm_list_fn_cmp)strcmp, (void **)data);  }  /** @@ -411,7 +410,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove_dupes(const alpm_list_t *list)  		}  		lp = lp->next;  	} -	return(newlist); +	return newlist;  }  /** @@ -429,7 +428,7 @@ alpm_list_t SYMEXPORT *alpm_list_strdup(const alpm_list_t *list)  		newlist = alpm_list_add(newlist, strdup(lp->data));  		lp = lp->next;  	} -	return(newlist); +	return newlist;  }  /** @@ -447,7 +446,7 @@ alpm_list_t SYMEXPORT *alpm_list_copy(const alpm_list_t *list)  		newlist = alpm_list_add(newlist, lp->data);  		lp = lp->next;  	} -	return(newlist); +	return newlist;  }  /** @@ -473,7 +472,7 @@ alpm_list_t SYMEXPORT *alpm_list_copy_data(const alpm_list_t *list,  			lp = lp->next;  		}  	} -	return(newlist); +	return newlist;  }  /** @@ -489,7 +488,7 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)  	alpm_list_t *newlist = NULL, *backup;  	if(list == NULL) { -		return(NULL); +		return NULL;  	}  	lp = alpm_list_last(list); @@ -502,7 +501,7 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)  		lp = lp->prev;  	}  	list->prev = backup; /* restore tail pointer */ -	return(newlist); +	return newlist;  }  /* Accessors */ @@ -517,9 +516,9 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)  inline alpm_list_t SYMEXPORT *alpm_list_first(const alpm_list_t *list)  {  	if(list) { -		return((alpm_list_t*)list); +		return (alpm_list_t *)list;  	} else { -		return(NULL); +		return NULL;  	}  } @@ -537,7 +536,7 @@ alpm_list_t SYMEXPORT *alpm_list_nth(const alpm_list_t *list, size_t n)  	while(n--) {  		i = i->next;  	} -	return((alpm_list_t*)i); +	return (alpm_list_t *)i;  }  /** @@ -550,9 +549,9 @@ alpm_list_t SYMEXPORT *alpm_list_nth(const alpm_list_t *list, size_t n)  inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node)  {  	if(node) { -		return(node->next); +		return node->next;  	} else { -		return(NULL); +		return NULL;  	}  } @@ -566,9 +565,9 @@ inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node)  alpm_list_t SYMEXPORT *alpm_list_last(const alpm_list_t *list)  {  	if(list) { -		return(list->prev); +		return list->prev;  	} else { -		return(NULL); +		return NULL;  	}  } @@ -581,8 +580,8 @@ alpm_list_t SYMEXPORT *alpm_list_last(const alpm_list_t *list)   */  void SYMEXPORT *alpm_list_getdata(const alpm_list_t *node)  { -	if(node == NULL) return(NULL); -	return(node->data); +	if(node == NULL) return NULL; +	return node->data;  }  /* Misc */ @@ -602,7 +601,7 @@ size_t SYMEXPORT alpm_list_count(const alpm_list_t *list)  		++i;  		lp = lp->next;  	} -	return(i); +	return i;  }  /** @@ -620,17 +619,17 @@ void SYMEXPORT *alpm_list_find(const alpm_list_t *haystack, const void *needle,  	const alpm_list_t *lp = haystack;  	while(lp) {  		if(lp->data && fn(lp->data, needle) == 0) { -			return(lp->data); +			return lp->data;  		}  		lp = lp->next;  	} -	return(NULL); +	return NULL;  }  /* trivial helper function for alpm_list_find_ptr */  static int ptr_cmp(const void *p, const void *q)  { -	return(p != q); +	return (p != q);  }  /** @@ -643,9 +642,10 @@ static int ptr_cmp(const void *p, const void *q)   *   * @return `needle` if found, NULL otherwise   */ -void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, const void *needle) +void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, +		const void *needle)  { -	return(alpm_list_find(haystack, needle, ptr_cmp)); +	return alpm_list_find(haystack, needle, ptr_cmp);  }  /** @@ -659,8 +659,8 @@ void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, const void *need  char SYMEXPORT *alpm_list_find_str(const alpm_list_t *haystack,  		const char *needle)  { -	return((char *)alpm_list_find(haystack, (const void*)needle, -				(alpm_list_fn_cmp)strcmp)); +	return (char *)alpm_list_find(haystack, (const void *)needle, +			(alpm_list_fn_cmp)strcmp);  }  /** @@ -688,7 +688,7 @@ void SYMEXPORT alpm_list_diff_sorted(const alpm_list_t *left,  		return;  	} -	while (l != NULL && r != NULL) { +	while(l != NULL && r != NULL) {  		int cmp = fn(l->data, r->data);  		if(cmp < 0) {  			if(onlyleft) { @@ -706,13 +706,13 @@ void SYMEXPORT alpm_list_diff_sorted(const alpm_list_t *left,  			r = r->next;  		}  	} -	while (l != NULL) { +	while(l != NULL) {  		if(onlyleft) {  			*onlyleft = alpm_list_add(*onlyleft, l->data);  		}  		l = l->next;  	} -	while (r != NULL) { +	while(r != NULL) {  		if(onlyright) {  			*onlyright = alpm_list_add(*onlyright, r->data);  		} @@ -745,7 +745,7 @@ alpm_list_t SYMEXPORT *alpm_list_diff(const alpm_list_t *lhs,  	alpm_list_free(left);  	alpm_list_free(right); -	return(ret); +	return ret;  }  /** @} */ diff --git a/lib/libalpm/backup.c b/lib/libalpm/backup.c index ca955ca4..6431b286 100644 --- a/lib/libalpm/backup.c +++ b/lib/libalpm/backup.c @@ -47,7 +47,7 @@ static int backup_split(const char *string, char **file, char **hash)  			/* don't need our dup as the fname wasn't requested, so free it */  			FREE(str);  		} -		return(0); +		return 0;  	}  	*ptr = '\0';  	ptr++; @@ -59,21 +59,21 @@ static int backup_split(const char *string, char **file, char **hash)  		*hash = strdup(ptr);  	}  	FREE(str); -	return(1); +	return 1;  }  char *_alpm_backup_file(const char *string)  {  	char *file = NULL;  	backup_split(string, &file, NULL); -	return(file); +	return file;  }  char *_alpm_backup_hash(const char *string)  {  	char *hash = NULL;  	backup_split(string, NULL, &hash); -	return(hash); +	return hash;  }  /* Look for a filename in a pmpkg_t.backup list.  If we find it, @@ -83,10 +83,8 @@ char *_alpm_needbackup(const char *file, const alpm_list_t *backup)  {  	const alpm_list_t *lp; -	ALPM_LOG_FUNC; -  	if(file == NULL || backup == NULL) { -		return(NULL); +		return NULL;  	}  	/* run through the backup list and parse out the hash for our file */ @@ -101,13 +99,13 @@ char *_alpm_needbackup(const char *file, const alpm_list_t *backup)  		}  		if(strcmp(file, filename) == 0) {  			FREE(filename); -			return(hash); +			return hash;  		}  		FREE(filename);  		FREE(hash);  	} -	return(NULL); +	return NULL;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/base64.c b/lib/libalpm/base64.c new file mode 100644 index 00000000..fa8bec5c --- /dev/null +++ b/lib/libalpm/base64.c @@ -0,0 +1,190 @@ +/* + *  RFC 1521 base64 encoding/decoding + * + *  Copyright (C) 2006-2010, Brainspark B.V. + * + *  This file is part of PolarSSL (http://www.polarssl.org) + *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + *  All rights reserved. + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ +/* + *  Pacman Notes: + * + *  Taken from the PolarSSL project at www.polarssl.org under terms of the + *  GPL. This is from version 0.14.2 of the library, and has been modified + *  as following, which may be helpful for future updates: + *  * remove "polarssl/config.h" include + *  * change include from "polarssl/base64.h" to "base64.h" + *  * removal of SELF_TEST code + */ + +#include "base64.h" + +static const unsigned char base64_enc_map[64] = +{ +    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', +    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', +    'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', +    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', +    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', +    'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', +    '8', '9', '+', '/' +}; + +static const unsigned char base64_dec_map[128] = +{ +    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, +    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, +    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, +    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, +    127, 127, 127,  62, 127, 127, 127,  63,  52,  53, +     54,  55,  56,  57,  58,  59,  60,  61, 127, 127, +    127,  64, 127, 127, 127,   0,   1,   2,   3,   4, +      5,   6,   7,   8,   9,  10,  11,  12,  13,  14, +     15,  16,  17,  18,  19,  20,  21,  22,  23,  24, +     25, 127, 127, 127, 127, 127, 127,  26,  27,  28, +     29,  30,  31,  32,  33,  34,  35,  36,  37,  38, +     39,  40,  41,  42,  43,  44,  45,  46,  47,  48, +     49,  50,  51, 127, 127, 127, 127, 127 +}; + +/* + * Encode a buffer into base64 format + */ +int base64_encode( unsigned char *dst, int *dlen, +                   const unsigned char *src, int  slen ) +{ +    int i, n; +    int C1, C2, C3; +    unsigned char *p; + +    if( slen == 0 ) +        return( 0 ); + +    n = (slen << 3) / 6; + +    switch( (slen << 3) - (n * 6) ) +    { +        case  2: n += 3; break; +        case  4: n += 2; break; +        default: break; +    } + +    if( *dlen < n + 1 ) +    { +        *dlen = n + 1; +        return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); +    } + +    n = (slen / 3) * 3; + +    for( i = 0, p = dst; i < n; i += 3 ) +    { +        C1 = *src++; +        C2 = *src++; +        C3 = *src++; + +        *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; +        *p++ = base64_enc_map[(((C1 &  3) << 4) + (C2 >> 4)) & 0x3F]; +        *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; +        *p++ = base64_enc_map[C3 & 0x3F]; +    } + +    if( i < slen ) +    { +        C1 = *src++; +        C2 = ((i + 1) < slen) ? *src++ : 0; + +        *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; +        *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + +        if( (i + 1) < slen ) +             *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; +        else *p++ = '='; + +        *p++ = '='; +    } + +    *dlen = p - dst; +    *p = 0; + +    return( 0 ); +} + +/* + * Decode a base64-formatted buffer + */ +int base64_decode( unsigned char *dst, int *dlen, +                   const unsigned char *src, int  slen ) +{ +    int i, j, n; +    unsigned long x; +    unsigned char *p; + +    for( i = j = n = 0; i < slen; i++ ) +    { +        if( ( slen - i ) >= 2 && +            src[i] == '\r' && src[i + 1] == '\n' ) +            continue; + +        if( src[i] == '\n' ) +            continue; + +        if( src[i] == '=' && ++j > 2 ) +            return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + +        if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) +            return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + +        if( base64_dec_map[src[i]] < 64 && j != 0 ) +            return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + +        n++; +    } + +    if( n == 0 ) +        return( 0 ); + +    n = ((n * 6) + 7) >> 3; + +    if( *dlen < n ) +    { +        *dlen = n; +        return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); +    } + +   for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) +   { +        if( *src == '\r' || *src == '\n' ) +            continue; + +        j -= ( base64_dec_map[*src] == 64 ); +        x  = (x << 6) | ( base64_dec_map[*src] & 0x3F ); + +        if( ++n == 4 ) +        { +            n = 0; +            if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); +            if( j > 1 ) *p++ = (unsigned char)( x >>  8 ); +            if( j > 2 ) *p++ = (unsigned char)( x       ); +        } +    } + +    *dlen = p - dst; + +    return( 0 ); +} diff --git a/lib/libalpm/base64.h b/lib/libalpm/base64.h new file mode 100644 index 00000000..0ae9612c --- /dev/null +++ b/lib/libalpm/base64.h @@ -0,0 +1,68 @@ +/** + * \file base64.h + * + *  Copyright (C) 2006-2010, Brainspark B.V. + * + *  This file is part of PolarSSL (http://www.polarssl.org) + *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + *  All rights reserved. + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _BASE64_H +#define _BASE64_H + +#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL               0x0010 +#define POLARSSL_ERR_BASE64_INVALID_CHARACTER              0x0012 + +/** + * \brief          Encode a buffer into base64 format + * + * \param dst      destination buffer + * \param dlen     size of the buffer + * \param src      source buffer + * \param slen     amount of data to be encoded + * + * \return         0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL. + *                 *dlen is always updated to reflect the amount + *                 of data that has (or would have) been written. + * + * \note           Call this function with *dlen = 0 to obtain the + *                 required buffer size in *dlen + */ +int base64_encode( unsigned char *dst, int *dlen, +                   const unsigned char *src, int  slen ); + +/** + * \brief          Decode a base64-formatted buffer + * + * \param dst      destination buffer + * \param dlen     size of the buffer + * \param src      source buffer + * \param slen     amount of data to be decoded + * + * \return         0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or + *                 POLARSSL_ERR_BASE64_INVALID_DATA if the input data is not + *                 correct. *dlen is always updated to reflect the amount + *                 of data that has (or would have) been written. + * + * \note           Call this function with *dlen = 0 to obtain the + *                 required buffer size in *dlen + */ +int base64_decode( unsigned char *dst, int *dlen, +                   const unsigned char *src, int  slen ); + +#endif /* base64.h */ diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index d5edf34c..d9a76cc2 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -31,10 +31,6 @@  #include <time.h>  #include <limits.h> /* PATH_MAX */ -/* libarchive */ -#include <archive.h> -#include <archive_entry.h> -  /* libalpm */  #include "db.h"  #include "alpm_list.h" @@ -43,16 +39,10 @@  #include "alpm.h"  #include "handle.h"  #include "package.h" -#include "group.h"  #include "deps.h" -#include "dload.h" -  #define LAZY_LOAD(info, errret) \  	do { \ -		ALPM_LOG_FUNC; \ -		ASSERT(handle != NULL, return(errret)); \ -		ASSERT(pkg != NULL, return(errret)); \  		if(pkg->origin != PKG_FROM_FILE && !(pkg->infolevel & info)) { \  			_alpm_local_db_read(pkg->origin_data.db, pkg, info); \  		} \ @@ -71,18 +61,6 @@ static const char *_cache_get_filename(pmpkg_t *pkg)  	return pkg->filename;  } -static const char *_cache_get_name(pmpkg_t *pkg) -{ -	ASSERT(pkg != NULL, return(NULL)); -	return pkg->name; -} - -static const char *_cache_get_version(pmpkg_t *pkg) -{ -	ASSERT(pkg != NULL, return(NULL)); -	return pkg->version; -} -  static const char *_cache_get_desc(pmpkg_t *pkg)  {  	LAZY_LOAD(INFRQ_DESC, NULL); @@ -157,12 +135,6 @@ static alpm_list_t *_cache_get_groups(pmpkg_t *pkg)  static int _cache_has_scriptlet(pmpkg_t *pkg)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(-1)); -	ASSERT(pkg != NULL, return(-1)); -  	if(!(pkg->infolevel & INFRQ_SCRIPTLET)) {  		_alpm_local_db_read(pkg->origin_data.db, pkg, INFRQ_SCRIPTLET);  	} @@ -200,19 +172,13 @@ static alpm_list_t *_cache_get_replaces(pmpkg_t *pkg)  }  /* local packages can not have deltas */ -static alpm_list_t *_cache_get_deltas(pmpkg_t *pkg) +static alpm_list_t *_cache_get_deltas(pmpkg_t UNUSED *pkg)  {  	return NULL;  }  static alpm_list_t *_cache_get_files(pmpkg_t *pkg)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(pkg != NULL, return(NULL)); -  	if(pkg->origin == PKG_FROM_LOCALDB  		 && !(pkg->infolevel & INFRQ_FILES)) {  		_alpm_local_db_read(pkg->origin_data.db, pkg, INFRQ_FILES); @@ -222,12 +188,6 @@ static alpm_list_t *_cache_get_files(pmpkg_t *pkg)  static alpm_list_t *_cache_get_backup(pmpkg_t *pkg)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(pkg != NULL, return(NULL)); -  	if(pkg->origin == PKG_FROM_LOCALDB  		 && !(pkg->infolevel & INFRQ_FILES)) {  		_alpm_local_db_read(pkg->origin_data.db, pkg, INFRQ_FILES); @@ -243,15 +203,9 @@ static alpm_list_t *_cache_get_backup(pmpkg_t *pkg)   */  static void *_cache_changelog_open(pmpkg_t *pkg)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(pkg != NULL, return(NULL)); -  	char clfile[PATH_MAX];  	snprintf(clfile, PATH_MAX, "%s/%s/%s-%s/changelog", -			alpm_option_get_dbpath(), +			alpm_option_get_dbpath(pkg->handle),  			alpm_db_get_name(alpm_pkg_get_db(pkg)),  			alpm_pkg_get_name(pkg),  			alpm_pkg_get_version(pkg)); @@ -268,17 +222,10 @@ static void *_cache_changelog_open(pmpkg_t *pkg)   * @return the number of characters read, or 0 if there is no more data   */  static size_t _cache_changelog_read(void *ptr, size_t size, -		const pmpkg_t *pkg, const void *fp) -{ -	return ( fread(ptr, 1, size, (FILE*)fp) ); -} - -/* -static int _cache_changelog_feof(const pmpkg_t *pkg, void *fp) +		const pmpkg_t UNUSED *pkg, const void *fp)  { -	return( feof((FILE*)fp) ); +	return fread(ptr, 1, size, (FILE *)fp);  } -*/  /**   * Close a package changelog for reading. Similar to fclose in functionality, @@ -287,9 +234,9 @@ static int _cache_changelog_feof(const pmpkg_t *pkg, void *fp)   * @param fp a 'file stream' to the package changelog   * @return whether closing the package changelog stream was successful   */ -static int _cache_changelog_close(const pmpkg_t *pkg, void *fp) +static int _cache_changelog_close(const pmpkg_t UNUSED *pkg, void *fp)  { -	return( fclose((FILE*)fp) ); +	return fclose((FILE *)fp);  } @@ -299,8 +246,6 @@ static int _cache_changelog_close(const pmpkg_t *pkg, void *fp)   */  static struct pkg_operations local_pkg_ops = {  	.get_filename    = _cache_get_filename, -	.get_name        = _cache_get_name, -	.get_version     = _cache_get_version,  	.get_desc        = _cache_get_desc,  	.get_url         = _cache_get_url,  	.get_builddate   = _cache_get_builddate, @@ -334,25 +279,25 @@ static int checkdbdir(pmdb_t *db)  	const char *path = _alpm_db_path(db);  	if(stat(path, &buf) != 0) { -		_alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n", +		_alpm_log(db->handle, PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n",  				path);  		if(_alpm_makepath(path) != 0) { -			RET_ERR(PM_ERR_SYSTEM, -1); +			RET_ERR(db->handle, PM_ERR_SYSTEM, -1);  		}  	} else if(!S_ISDIR(buf.st_mode)) { -		_alpm_log(PM_LOG_WARNING, _("removing invalid database: %s\n"), path); +		_alpm_log(db->handle, PM_LOG_WARNING, _("removing invalid database: %s\n"), path);  		if(unlink(path) != 0 || _alpm_makepath(path) != 0) { -			RET_ERR(PM_ERR_SYSTEM, -1); +			RET_ERR(db->handle, PM_ERR_SYSTEM, -1);  		}  	} -	return(0); +	return 0;  }  static int is_dir(const char *path, struct dirent *entry)  {  #ifdef HAVE_STRUCT_DIRENT_D_TYPE  	if(entry->d_type != DT_UNKNOWN) { -		return(entry->d_type == DT_DIR); +		return (entry->d_type == DT_DIR);  	}  #endif  	{ @@ -361,12 +306,12 @@ static int is_dir(const char *path, struct dirent *entry)  		snprintf(buffer, PATH_MAX, "%s/%s", path, entry->d_name); -		if (!stat(buffer, &sbuf)) { -			return(S_ISDIR(sbuf.st_mode)); +		if(!stat(buffer, &sbuf)) { +			return S_ISDIR(sbuf.st_mode);  		}  	} -	return(0); +	return 0;  }  static int local_db_populate(pmdb_t *db) @@ -378,10 +323,6 @@ static int local_db_populate(pmdb_t *db)  	const char *dbpath;  	DIR *dbdir; -	ALPM_LOG_FUNC; - -	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); -  	dbpath = _alpm_db_path(db);  	if(dbpath == NULL) {  		/* pm_errno set in _alpm_db_path() */ @@ -391,12 +332,12 @@ static int local_db_populate(pmdb_t *db)  	if(dbdir == NULL) {  		if(errno == ENOENT) {  			/* no database existing yet is not an error */ -			return(0); +			return 0;  		} -		RET_ERR(PM_ERR_DB_OPEN, -1); +		RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);  	}  	if(fstat(dirfd(dbdir), &buf) != 0) { -		RET_ERR(PM_ERR_DB_OPEN, -1); +		RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);  	}  	if(buf.st_nlink >= 2) {  		est_count = buf.st_nlink; @@ -420,7 +361,7 @@ static int local_db_populate(pmdb_t *db)  	db->pkgcache = _alpm_pkghash_create(est_count * 2);  	if(db->pkgcache == NULL){  		closedir(dbdir); -		RET_ERR(PM_ERR_MEMORY, -1); +		RET_ERR(db->handle, PM_ERR_MEMORY, -1);  	}  	while((ent = readdir(dbdir)) != NULL) { @@ -438,11 +379,11 @@ static int local_db_populate(pmdb_t *db)  		pkg = _alpm_pkg_new();  		if(pkg == NULL) {  			closedir(dbdir); -			RET_ERR(PM_ERR_MEMORY, -1); +			RET_ERR(db->handle, PM_ERR_MEMORY, -1);  		}  		/* split the db entry name */  		if(_alpm_splitname(name, pkg) != 0) { -			_alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"), +			_alpm_log(db->handle, PM_LOG_ERROR, _("invalid name for database entry '%s'\n"),  					name);  			_alpm_pkg_free(pkg);  			continue; @@ -450,7 +391,7 @@ static int local_db_populate(pmdb_t *db)  		/* duplicated database entries are not allowed */  		if(_alpm_pkghash_find(db->pkgcache, pkg->name)) { -			_alpm_log(PM_LOG_ERROR, _("duplicated database entry '%s'\n"), pkg->name); +			_alpm_log(db->handle, PM_LOG_ERROR, _("duplicated database entry '%s'\n"), pkg->name);  			_alpm_pkg_free(pkg);  			continue;  		} @@ -458,16 +399,17 @@ static int local_db_populate(pmdb_t *db)  		pkg->origin = PKG_FROM_LOCALDB;  		pkg->origin_data.db = db;  		pkg->ops = &local_pkg_ops; +		pkg->handle = db->handle;  		/* explicitly read with only 'BASE' data, accessors will handle the rest */  		if(_alpm_local_db_read(db, pkg, INFRQ_BASE) == -1) { -			_alpm_log(PM_LOG_ERROR, _("corrupted database entry '%s'\n"), name); +			_alpm_log(db->handle, PM_LOG_ERROR, _("corrupted database entry '%s'\n"), name);  			_alpm_pkg_free(pkg);  			continue;  		}  		/* add to the collection */ -		_alpm_log(PM_LOG_DEBUG, "adding '%s' to package cache for db '%s'\n", +		_alpm_log(db->handle, PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",  				pkg->name, db->treename);  		db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg);  		count++; @@ -477,7 +419,10 @@ static int local_db_populate(pmdb_t *db)  	if(count > 0) {  		db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp);  	} -	return(count); +	_alpm_log(db->handle, PM_LOG_DEBUG, "added %d packages to package cache for db '%s'\n", +			count, db->treename); + +	return count;  }  /* Note: the return value must be freed by the caller */ @@ -489,9 +434,9 @@ static char *get_pkgpath(pmdb_t *db, pmpkg_t *info)  	dbpath = _alpm_db_path(db);  	len = strlen(dbpath) + strlen(info->name) + strlen(info->version) + 3; -	MALLOC(pkgpath, len, RET_ERR(PM_ERR_MEMORY, NULL)); +	MALLOC(pkgpath, len, RET_ERR(db->handle, PM_ERR_MEMORY, NULL));  	sprintf(pkgpath, "%s%s-%s/", dbpath, info->name, info->version); -	return(pkgpath); +	return pkgpath;  } @@ -502,22 +447,17 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)  	char line[1024];  	char *pkgpath = NULL; -	ALPM_LOG_FUNC; - -	if(db == NULL) { -		RET_ERR(PM_ERR_DB_NULL, -1); -	} -  	if(info == NULL || info->name == NULL || info->version == NULL) { -		_alpm_log(PM_LOG_DEBUG, "invalid package entry provided to _alpm_local_db_read, skipping\n"); -		return(-1); +		_alpm_log(db->handle, PM_LOG_DEBUG, +				"invalid package entry provided to _alpm_local_db_read, skipping\n"); +		return -1;  	}  	if(info->origin != PKG_FROM_LOCALDB) { -		_alpm_log(PM_LOG_DEBUG, +		_alpm_log(db->handle, PM_LOG_DEBUG,  				"request to read info for a non-local package '%s', skipping...\n",  				info->name); -		return(-1); +		return -1;  	}  	/* bitmask logic here: @@ -527,9 +467,9 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)  	 * == to inforeq? nope, we need to load more info. */  	if((info->infolevel & inforeq) == inforeq) {  		/* already loaded all of this info, do nothing */ -		return(0); +		return 0;  	} -	_alpm_log(PM_LOG_FUNCTION, "loading package data for %s : level=0x%x\n", +	_alpm_log(db->handle, PM_LOG_FUNCTION, "loading package data for %s : level=0x%x\n",  			info->name, inforeq);  	/* clear out 'line', to be certain - and to make valgrind happy */ @@ -539,7 +479,7 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)  	if(access(pkgpath, F_OK)) {  		/* directory doesn't exist or can't be opened */ -		_alpm_log(PM_LOG_DEBUG, "cannot find '%s-%s' in db '%s'\n", +		_alpm_log(db->handle, PM_LOG_DEBUG, "cannot find '%s-%s' in db '%s'\n",  				info->name, info->version, db->treename);  		goto error;  	} @@ -548,7 +488,7 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)  	if(inforeq & INFRQ_DESC && !(info->infolevel & INFRQ_DESC)) {  		snprintf(path, PATH_MAX, "%sdesc", pkgpath);  		if((fp = fopen(path, "r")) == NULL) { -			_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); +			_alpm_log(db->handle, PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));  			goto error;  		}  		while(!feof(fp)) { @@ -561,7 +501,7 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)  					goto error;  				}  				if(strcmp(_alpm_strtrim(line), info->name) != 0) { -					_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: name " +					_alpm_log(db->handle, PM_LOG_ERROR, _("%s database is inconsistent: name "  								"mismatch on package %s\n"), db->treename, info->name);  				}  			} else if(strcmp(line, "%VERSION%") == 0) { @@ -569,7 +509,7 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)  					goto error;  				}  				if(strcmp(_alpm_strtrim(line), info->version) != 0) { -					_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: version " +					_alpm_log(db->handle, PM_LOG_ERROR, _("%s database is inconsistent: version "  								"mismatch on package %s\n"), db->treename, info->name);  				}  			} else if(strcmp(line, "%DESC%") == 0) { @@ -672,7 +612,7 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)  	if(inforeq & INFRQ_FILES && !(info->infolevel & INFRQ_FILES)) {  		snprintf(path, PATH_MAX, "%sfiles", pkgpath);  		if((fp = fopen(path, "r")) == NULL) { -			_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); +			_alpm_log(db->handle, PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));  			goto error;  		}  		while(fgets(line, sizeof(line), fp)) { @@ -707,14 +647,14 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)  	info->infolevel |= inforeq;  	free(pkgpath); -	return(0); +	return 0;  error:  	free(pkgpath);  	if(fp) {  		fclose(fp);  	} -	return(-1); +	return -1;  }  int _alpm_local_db_prepare(pmdb_t *db, pmpkg_t *info) @@ -724,21 +664,21 @@ int _alpm_local_db_prepare(pmdb_t *db, pmpkg_t *info)  	char *pkgpath = NULL;  	if(checkdbdir(db) != 0) { -		return(-1); +		return -1;  	}  	oldmask = umask(0000);  	pkgpath = get_pkgpath(db, info);  	if((retval = mkdir(pkgpath, 0755)) != 0) { -		_alpm_log(PM_LOG_ERROR, _("could not create directory %s: %s\n"), +		_alpm_log(db->handle, PM_LOG_ERROR, _("could not create directory %s: %s\n"),  				pkgpath, strerror(errno));  	}  	free(pkgpath);  	umask(oldmask); -	return(retval); +	return retval;  }  int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) @@ -750,10 +690,8 @@ int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)  	int retval = 0;  	char *pkgpath = NULL; -	ALPM_LOG_FUNC; -  	if(db == NULL || info == NULL) { -		return(-1); +		return -1;  	}  	pkgpath = get_pkgpath(db, info); @@ -762,16 +700,17 @@ int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)  	oldmask = umask(0022);  	if(strcmp(db->treename, "local") != 0) { -		return(-1); +		return -1;  	}  	/* DESC */  	if(inforeq & INFRQ_DESC) { -		_alpm_log(PM_LOG_DEBUG, "writing %s-%s DESC information back to db\n", +		_alpm_log(db->handle, PM_LOG_DEBUG, "writing %s-%s DESC information back to db\n",  				info->name, info->version);  		snprintf(path, PATH_MAX, "%sdesc", pkgpath);  		if((fp = fopen(path, "w")) == NULL) { -			_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); +			_alpm_log(db->handle, PM_LOG_ERROR, _("could not open file %s: %s\n"), +					path, strerror(errno));  			retval = -1;  			goto cleanup;  		} @@ -868,11 +807,12 @@ int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)  	/* FILES */  	if(inforeq & INFRQ_FILES) { -		_alpm_log(PM_LOG_DEBUG, "writing %s-%s FILES information back to db\n", +		_alpm_log(db->handle, PM_LOG_DEBUG, "writing %s-%s FILES information back to db\n",  				info->name, info->version);  		snprintf(path, PATH_MAX, "%sfiles", pkgpath);  		if((fp = fopen(path, "w")) == NULL) { -			_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); +			_alpm_log(db->handle, PM_LOG_ERROR, _("could not open file %s: %s\n"), +					path, strerror(errno));  			retval = -1;  			goto cleanup;  		} @@ -905,7 +845,7 @@ cleanup:  		fclose(fp);  	} -	return(retval); +	return retval;  }  int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info) @@ -913,12 +853,6 @@ int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info)  	int ret = 0;  	char *pkgpath = NULL; -	ALPM_LOG_FUNC; - -	if(db == NULL || info == NULL) { -		RET_ERR(PM_ERR_DB_NULL, -1); -	} -  	pkgpath = get_pkgpath(db, info);  	ret = _alpm_rmrf(pkgpath); @@ -926,7 +860,7 @@ int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info)  	if(ret != 0) {  		ret = -1;  	} -	return(ret); +	return ret;  }  static int local_db_version(pmdb_t *db) @@ -938,7 +872,7 @@ static int local_db_version(pmdb_t *db)  	dbpath = _alpm_db_path(db);  	if(dbpath == NULL) { -		RET_ERR(PM_ERR_DB_OPEN, -1); +		RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);  	}  	dbdir = opendir(dbpath);  	if(dbdir == NULL) { @@ -947,7 +881,7 @@ static int local_db_version(pmdb_t *db)  			version = 2;  			goto done;  		} else { -			RET_ERR(PM_ERR_DB_OPEN, -1); +			RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);  		}  	} @@ -977,8 +911,8 @@ done:  		closedir(dbdir);  	} -	_alpm_log(PM_LOG_DEBUG, "local database version %d\n", version); -	return(version); +	_alpm_log(db->handle, PM_LOG_DEBUG, "local database version %d\n", version); +	return version;  }  struct db_operations local_db_ops = { @@ -987,22 +921,21 @@ struct db_operations local_db_ops = {  	.version          = local_db_version,  }; -pmdb_t *_alpm_db_register_local(void) +pmdb_t *_alpm_db_register_local(pmhandle_t *handle)  {  	pmdb_t *db; -	ALPM_LOG_FUNC; - -	_alpm_log(PM_LOG_DEBUG, "registering local database\n"); +	_alpm_log(handle, PM_LOG_DEBUG, "registering local database\n");  	db = _alpm_db_new("local", 1);  	if(db == NULL) { -		RET_ERR(PM_ERR_DB_CREATE, NULL); +		return NULL;  	}  	db->ops = &local_db_ops; +	db->handle = handle;  	handle->db_local = db; -	return(db); +	return db;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index 6dfddd61..a0261d07 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -20,10 +20,8 @@  #include "config.h" -#include <stdio.h>  #include <stdlib.h>  #include <string.h> -#include <limits.h>  #include <errno.h>  /* libarchive */ @@ -32,8 +30,10 @@  /* libalpm */  #include "alpm_list.h" +#include "alpm.h"  #include "util.h"  #include "log.h" +#include "handle.h"  #include "package.h"  #include "deps.h" /* _alpm_splitdep */ @@ -45,38 +45,36 @@   */  static void *_package_changelog_open(pmpkg_t *pkg)  { -	ALPM_LOG_FUNC; - -	ASSERT(pkg != NULL, return(NULL)); +	ASSERT(pkg != NULL, return NULL);  	struct archive *archive = NULL;  	struct archive_entry *entry;  	const char *pkgfile = pkg->origin_data.file;  	if((archive = archive_read_new()) == NULL) { -		RET_ERR(PM_ERR_LIBARCHIVE, NULL); +		RET_ERR(pkg->handle, PM_ERR_LIBARCHIVE, NULL);  	}  	archive_read_support_compression_all(archive);  	archive_read_support_format_all(archive); -	if (archive_read_open_filename(archive, pkgfile, +	if(archive_read_open_filename(archive, pkgfile,  				ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { -		RET_ERR(PM_ERR_PKG_OPEN, NULL); +		RET_ERR(pkg->handle, PM_ERR_PKG_OPEN, NULL);  	}  	while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {  		const char *entry_name = archive_entry_pathname(entry);  		if(strcmp(entry_name, ".CHANGELOG") == 0) { -			return(archive); +			return archive;  		}  	}  	/* we didn't find a changelog */  	archive_read_finish(archive);  	errno = ENOENT; -	return(NULL); +	return NULL;  }  /** @@ -89,26 +87,17 @@ static void *_package_changelog_open(pmpkg_t *pkg)   * @return the number of characters read, or 0 if there is no more data   */  static size_t _package_changelog_read(void *ptr, size_t size, -		const pmpkg_t *pkg, const void *fp) +		const pmpkg_t UNUSED *pkg, const void *fp)  { -	ssize_t sret = archive_read_data((struct archive*)fp, ptr, size); +	ssize_t sret = archive_read_data((struct archive *)fp, ptr, size);  	/* Report error (negative values) */  	if(sret < 0) { -		pm_errno = PM_ERR_LIBARCHIVE; -		return(0); +		RET_ERR(pkg->handle, PM_ERR_LIBARCHIVE, 0);  	} else { -		return((size_t)sret); +		return (size_t)sret;  	}  } -/* -static int _package_changelog_feof(const pmpkg_t *pkg, void *fp) -{ -	// note: this doesn't quite work, no feof in libarchive -	return( archive_read_data((struct archive*)fp, NULL, 0) ); -} -*/ -  /**   * Close a package changelog for reading. Similar to fclose in functionality,   * except that the 'file stream' is from an archive. @@ -116,9 +105,9 @@ static int _package_changelog_feof(const pmpkg_t *pkg, void *fp)   * @param fp a 'file stream' to the package changelog   * @return whether closing the package changelog stream was successful   */ -static int _package_changelog_close(const pmpkg_t *pkg, void *fp) +static int _package_changelog_close(const pmpkg_t UNUSED *pkg, void *fp)  { -	return( archive_read_finish((struct archive *)fp) ); +	return archive_read_finish((struct archive *)fp);  }  /** Package file operations struct accessor. We implement this as a method @@ -137,7 +126,7 @@ static struct pkg_operations *get_file_pkg_ops(void)  		file_pkg_ops.changelog_close = _package_changelog_close;  		file_pkg_ops_initialized = 1;  	} -	return(&file_pkg_ops); +	return &file_pkg_ops;  }  /** @@ -145,23 +134,21 @@ static struct pkg_operations *get_file_pkg_ops(void)   * @param archive the archive to read from, pointed at the .PKGINFO entry   * @param newpkg an empty pmpkg_t struct to fill with package info   * - * @return 0 on success, 1 on error + * @return 0 on success, -1 on error   */ -static int parse_descfile(struct archive *a, pmpkg_t *newpkg) +static int parse_descfile(pmhandle_t *handle, struct archive *a, pmpkg_t *newpkg)  {  	char *ptr = NULL;  	char *key = NULL; -	int linenum = 0; +	int ret, linenum = 0;  	struct archive_read_buffer buf; -	ALPM_LOG_FUNC; -  	memset(&buf, 0, sizeof(buf));  	/* 512K for a line length seems reasonable */  	buf.max_line_size = 512 * 1024;  	/* loop until we reach EOF or other error */ -	while(_alpm_archive_fgets(a, &buf) == ARCHIVE_OK) { +	while((ret = _alpm_archive_fgets(a, &buf)) == ARCHIVE_OK) {  		char *line = _alpm_strtrim(buf.line);  		linenum++; @@ -171,33 +158,33 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg)  		ptr = line;  		key = strsep(&ptr, "=");  		if(key == NULL || ptr == NULL) { -			_alpm_log(PM_LOG_DEBUG, "%s: syntax error in description file line %d\n", +			_alpm_log(handle, PM_LOG_DEBUG, "%s: syntax error in description file line %d\n",  								newpkg->name ? newpkg->name : "error", linenum);  		} else {  			key = _alpm_strtrim(key);  			while(*ptr == ' ') ptr++;  			ptr = _alpm_strtrim(ptr);  			if(strcmp(key, "pkgname") == 0) { -				STRDUP(newpkg->name, ptr, RET_ERR(PM_ERR_MEMORY, -1)); +				STRDUP(newpkg->name, ptr, return -1);  				newpkg->name_hash = _alpm_hash_sdbm(newpkg->name);  			} else if(strcmp(key, "pkgbase") == 0) {  				/* not used atm */  			} else if(strcmp(key, "pkgver") == 0) { -				STRDUP(newpkg->version, ptr, RET_ERR(PM_ERR_MEMORY, -1)); +				STRDUP(newpkg->version, ptr, return -1);  			} else if(strcmp(key, "pkgdesc") == 0) { -				STRDUP(newpkg->desc, ptr, RET_ERR(PM_ERR_MEMORY, -1)); +				STRDUP(newpkg->desc, ptr, return -1);  			} else if(strcmp(key, "group") == 0) {  				newpkg->groups = alpm_list_add(newpkg->groups, strdup(ptr));  			} else if(strcmp(key, "url") == 0) { -				STRDUP(newpkg->url, ptr, RET_ERR(PM_ERR_MEMORY, -1)); +				STRDUP(newpkg->url, ptr, return -1);  			} else if(strcmp(key, "license") == 0) {  				newpkg->licenses = alpm_list_add(newpkg->licenses, strdup(ptr));  			} else if(strcmp(key, "builddate") == 0) {  				newpkg->builddate = _alpm_parsedate(ptr);  			} else if(strcmp(key, "packager") == 0) { -				STRDUP(newpkg->packager, ptr, RET_ERR(PM_ERR_MEMORY, -1)); +				STRDUP(newpkg->packager, ptr, return -1);  			} else if(strcmp(key, "arch") == 0) { -				STRDUP(newpkg->arch, ptr, RET_ERR(PM_ERR_MEMORY, -1)); +				STRDUP(newpkg->arch, ptr, return -1);  			} else if(strcmp(key, "size") == 0) {  				/* size in the raw package is uncompressed (installed) size */  				newpkg->isize = atol(ptr); @@ -219,64 +206,93 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg)  			} else if(strcmp(key, "makepkgopt") == 0) {  				/* not used atm */  			} else { -				_alpm_log(PM_LOG_DEBUG, "%s: unknown key '%s' in description file line %d\n", +				_alpm_log(handle, PM_LOG_DEBUG, "%s: unknown key '%s' in description file line %d\n",  									newpkg->name ? newpkg->name : "error", key, linenum);  			}  		}  		line[0] = '\0';  	} +	if(ret != ARCHIVE_EOF) { +		_alpm_log(handle, PM_LOG_DEBUG, "error parsing package descfile\n"); +		return -1; +	} -	return(0); +	return 0;  }  /**   * Load a package and create the corresponding pmpkg_t struct. + * @param handle the context handle   * @param pkgfile path to the package file   * @param full whether to stop the load after metadata is read or continue   *             through the full archive   * @return An information filled pmpkg_t struct   */ -static pmpkg_t *pkg_load(const char *pkgfile, int full) +pmpkg_t *_alpm_pkg_load_internal(pmhandle_t *handle, const char *pkgfile, +		int full, const char *md5sum, const char *base64_sig, +		pgp_verify_t check_sig)  { -	int ret = ARCHIVE_OK; +	int ret;  	int config = 0;  	struct archive *archive;  	struct archive_entry *entry;  	pmpkg_t *newpkg = NULL;  	struct stat st; -	ALPM_LOG_FUNC; -  	if(pkgfile == NULL || strlen(pkgfile) == 0) { -		RET_ERR(PM_ERR_WRONG_ARGS, NULL); +		RET_ERR(handle, PM_ERR_WRONG_ARGS, NULL); +	} + +	/* attempt to stat the package file, ensure it exists */ +	if(stat(pkgfile, &st) == 0) { +		newpkg = _alpm_pkg_new(); +		if(newpkg == NULL) { +			RET_ERR(handle, PM_ERR_MEMORY, NULL); +		} +		newpkg->filename = strdup(pkgfile); +		newpkg->size = st.st_size; +	} else { +		/* couldn't stat the pkgfile, return an error */ +		RET_ERR(handle, PM_ERR_PKG_OPEN, NULL); +	} + +	/* first steps- validate the package file */ +	_alpm_log(handle, PM_LOG_DEBUG, "md5sum: %s\n", md5sum); +	if(md5sum) { +		_alpm_log(handle, PM_LOG_DEBUG, "checking md5sum for %s\n", pkgfile); +		if(_alpm_test_md5sum(pkgfile, md5sum) != 0) { +			alpm_pkg_free(newpkg); +			RET_ERR(handle, PM_ERR_PKG_INVALID, NULL); +		}  	} -	if(stat(pkgfile, &st) != 0) { -		RET_ERR(PM_ERR_PKG_OPEN, NULL); +	_alpm_log(handle, PM_LOG_DEBUG, "base64_sig: %s\n", base64_sig); +	if(check_sig != PM_PGP_VERIFY_NEVER) { +		_alpm_log(handle, PM_LOG_DEBUG, "checking signature for %s\n", pkgfile); +		ret = _alpm_gpgme_checksig(handle, pkgfile, base64_sig); +		if((check_sig == PM_PGP_VERIFY_ALWAYS && ret != 0) || +				(check_sig == PM_PGP_VERIFY_OPTIONAL && ret == 1)) { +			alpm_pkg_free(newpkg); +			RET_ERR(handle, PM_ERR_SIG_INVALID, NULL); +		}  	} +	/* next- try to create an archive object to read in the package */  	if((archive = archive_read_new()) == NULL) { -		RET_ERR(PM_ERR_LIBARCHIVE, NULL); +		alpm_pkg_free(newpkg); +		RET_ERR(handle, PM_ERR_LIBARCHIVE, NULL);  	}  	archive_read_support_compression_all(archive);  	archive_read_support_format_all(archive); -	if (archive_read_open_filename(archive, pkgfile, +	if(archive_read_open_filename(archive, pkgfile,  				ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { -		RET_ERR(PM_ERR_PKG_OPEN, NULL); -	} - -	newpkg = _alpm_pkg_new(); -	if(newpkg == NULL) { -		archive_read_finish(archive); -		RET_ERR(PM_ERR_MEMORY, NULL); +		alpm_pkg_free(newpkg); +		RET_ERR(handle, PM_ERR_PKG_OPEN, NULL);  	} -	newpkg->filename = strdup(pkgfile); -	newpkg->size = st.st_size; - -	_alpm_log(PM_LOG_DEBUG, "starting package load for %s\n", pkgfile); +	_alpm_log(handle, PM_LOG_DEBUG, "starting package load for %s\n", pkgfile);  	/* If full is false, only read through the archive until we find our needed  	 * metadata. If it is true, read through the entire archive, which serves @@ -286,17 +302,17 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full)  		if(strcmp(entry_name, ".PKGINFO") == 0) {  			/* parse the info file */ -			if(parse_descfile(archive, newpkg) != 0) { -				_alpm_log(PM_LOG_ERROR, _("could not parse package description file in %s\n"), +			if(parse_descfile(handle, archive, newpkg) != 0) { +				_alpm_log(handle, PM_LOG_ERROR, _("could not parse package description file in %s\n"),  						pkgfile);  				goto pkg_invalid;  			}  			if(newpkg->name == NULL || strlen(newpkg->name) == 0) { -				_alpm_log(PM_LOG_ERROR, _("missing package name in %s\n"), pkgfile); +				_alpm_log(handle, PM_LOG_ERROR, _("missing package name in %s\n"), pkgfile);  				goto pkg_invalid;  			}  			if(newpkg->version == NULL || strlen(newpkg->version) == 0) { -				_alpm_log(PM_LOG_ERROR, _("missing package version in %s\n"), pkgfile); +				_alpm_log(handle, PM_LOG_ERROR, _("missing package version in %s\n"), pkgfile);  				goto pkg_invalid;  			}  			config = 1; @@ -312,9 +328,9 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full)  		}  		if(archive_read_data_skip(archive)) { -			_alpm_log(PM_LOG_ERROR, _("error while reading package %s: %s\n"), +			_alpm_log(handle, PM_LOG_ERROR, _("error while reading package %s: %s\n"),  					pkgfile, archive_error_string(archive)); -			pm_errno = PM_ERR_LIBARCHIVE; +			handle->pm_errno = PM_ERR_LIBARCHIVE;  			goto error;  		} @@ -325,14 +341,14 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full)  	}  	if(ret != ARCHIVE_EOF && ret != ARCHIVE_OK) { /* An error occured */ -		_alpm_log(PM_LOG_ERROR, _("error while reading package %s: %s\n"), +		_alpm_log(handle, PM_LOG_ERROR, _("error while reading package %s: %s\n"),  				pkgfile, archive_error_string(archive)); -		pm_errno = PM_ERR_LIBARCHIVE; +		handle->pm_errno = PM_ERR_LIBARCHIVE;  		goto error;  	}  	if(!config) { -		_alpm_log(PM_LOG_ERROR, _("missing package metadata in %s\n"), pkgfile); +		_alpm_log(handle, PM_LOG_ERROR, _("missing package metadata in %s\n"), pkgfile);  		goto pkg_invalid;  	} @@ -340,13 +356,13 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full)  	/* internal fields for package struct */  	newpkg->origin = PKG_FROM_FILE; -	/* TODO eventually kill/move this? */  	newpkg->origin_data.file = strdup(pkgfile);  	newpkg->ops = get_file_pkg_ops(); +	newpkg->handle = handle;  	if(full) {  		/* "checking for conflicts" requires a sorted list, ensure that here */ -		_alpm_log(PM_LOG_DEBUG, "sorting package filelist for %s\n", pkgfile); +		_alpm_log(handle, PM_LOG_DEBUG, "sorting package filelist for %s\n", pkgfile);  		newpkg->files = alpm_list_msort(newpkg->files, alpm_list_count(newpkg->files),  				_alpm_str_cmp);  		newpkg->infolevel = INFRQ_ALL; @@ -356,33 +372,30 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full)  		newpkg->infolevel = INFRQ_BASE | INFRQ_DESC;  	} -	return(newpkg); +	return newpkg;  pkg_invalid: -	pm_errno = PM_ERR_PKG_INVALID; +	handle->pm_errno = PM_ERR_PKG_INVALID;  error:  	_alpm_pkg_free(newpkg);  	archive_read_finish(archive); -	return(NULL); +	return NULL;  } -int SYMEXPORT alpm_pkg_load(const char *filename, int full, pmpkg_t **pkg) +int SYMEXPORT alpm_pkg_load(pmhandle_t *handle, const char *filename, int full, +		pgp_verify_t check_sig, pmpkg_t **pkg)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(filename != NULL && strlen(filename) != 0, -			RET_ERR(PM_ERR_WRONG_ARGS, -1)); -	ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); +	CHECK_HANDLE(handle, return -1); +	ASSERT(pkg != NULL, RET_ERR(handle, PM_ERR_WRONG_ARGS, -1)); -	*pkg = pkg_load(filename, full); +	*pkg = _alpm_pkg_load_internal(handle, filename, full, NULL, NULL, check_sig);  	if(*pkg == NULL) {  		/* pm_errno is set by pkg_load */ -		return(-1); +		return -1;  	} -	return(0); +	return 0;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index c440cd6b..bb109284 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -20,8 +20,7 @@  #include "config.h" -#include <errno.h> -#include <limits.h> +#include <sys/stat.h>  /* libarchive */  #include <archive.h> @@ -38,6 +37,34 @@  #include "deps.h"  #include "dload.h" +static char *get_sync_dir(pmhandle_t *handle) +{ +	const char *dbpath = alpm_option_get_dbpath(handle); +	size_t len = strlen(dbpath) + 6; +	char *syncpath; +	struct stat buf; + +	MALLOC(syncpath, len, RET_ERR(handle, PM_ERR_MEMORY, NULL)); +	sprintf(syncpath, "%s%s", dbpath, "sync/"); + +	if(stat(syncpath, &buf) != 0) { +		_alpm_log(handle, PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n", +				syncpath); +		if(_alpm_makepath(syncpath) != 0) { +			free(syncpath); +			RET_ERR(handle, PM_ERR_SYSTEM, NULL); +		} +	} else if(!S_ISDIR(buf.st_mode)) { +		_alpm_log(handle, PM_LOG_WARNING, _("removing invalid file: %s\n"), syncpath); +		if(unlink(syncpath) != 0 || _alpm_makepath(syncpath) != 0) { +			free(syncpath); +			RET_ERR(handle, PM_ERR_SYSTEM, NULL); +		} +	} + +	return syncpath; +} +  /** Update a package database   *   * An update of the package database \a db will be attempted. Unless @@ -79,71 +106,78 @@   */  int SYMEXPORT alpm_db_update(int force, pmdb_t *db)  { -	char *dbfile, *syncpath; -	const char *dbpath; -	struct stat buf; -	size_t len; -	int ret; +	char *syncpath; +	alpm_list_t *i; +	int ret = -1;  	mode_t oldmask; - -	ALPM_LOG_FUNC; +	pmhandle_t *handle; +	pgp_verify_t check_sig;  	/* Sanity checks */ -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); -	ASSERT(db != NULL && db != handle->db_local, RET_ERR(PM_ERR_WRONG_ARGS, -1)); - -	if(!alpm_list_find_ptr(handle->dbs_sync, db)) { -		RET_ERR(PM_ERR_DB_NOT_FOUND, -1); -	} - -	len = strlen(db->treename) + 4; -	MALLOC(dbfile, len, RET_ERR(PM_ERR_MEMORY, -1)); -	sprintf(dbfile, "%s.db", db->treename); - -	dbpath = alpm_option_get_dbpath(); -	len = strlen(dbpath) + 6; -	MALLOC(syncpath, len, RET_ERR(PM_ERR_MEMORY, -1)); -	sprintf(syncpath, "%s%s", dbpath, "sync/"); +	ASSERT(db != NULL, return -1); +	handle = db->handle; +	handle->pm_errno = 0; +	ASSERT(db != handle->db_local, RET_ERR(handle, PM_ERR_WRONG_ARGS, -1)); +	ASSERT(db->servers != NULL, RET_ERR(handle, PM_ERR_SERVER_NONE, -1));  	/* make sure we have a sane umask */  	oldmask = umask(0022); -	if(stat(syncpath, &buf) != 0) { -		_alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n", -				syncpath); -		if(_alpm_makepath(syncpath) != 0) { -			free(dbfile); -			free(syncpath); -			RET_ERR(PM_ERR_SYSTEM, -1); +	syncpath = get_sync_dir(handle); +	if(!syncpath) { +		return -1; +	} +	check_sig = _alpm_db_get_sigverify_level(db); + +	for(i = db->servers; i; i = i->next) { +		const char *server = i->data; +		char *fileurl; +		size_t len; +		int sig_ret = 0; + +		/* print server + filename into a buffer (leave space for .sig) */ +		len = strlen(server) + strlen(db->treename) + 9; +		CALLOC(fileurl, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, -1)); +		snprintf(fileurl, len, "%s/%s.db", server, db->treename); + +		ret = _alpm_download(handle, fileurl, syncpath, force, 0, 0); + +		if(ret == 0 && (check_sig == PM_PGP_VERIFY_ALWAYS || +					check_sig == PM_PGP_VERIFY_OPTIONAL)) { +			int errors_ok = (check_sig == PM_PGP_VERIFY_OPTIONAL); +			/* if we downloaded a DB, we want the .sig from the same server */ +			snprintf(fileurl, len, "%s/%s.db.sig", server, db->treename); + +			sig_ret = _alpm_download(handle, fileurl, syncpath, 1, 0, errors_ok); +			/* errors_ok suppresses error messages, but not the return code */ +			sig_ret = errors_ok ? 0 : sig_ret;  		} -	} else if(!S_ISDIR(buf.st_mode)) { -		_alpm_log(PM_LOG_WARNING, _("removing invalid file: %s\n"), syncpath); -		if(unlink(syncpath) != 0 || _alpm_makepath(syncpath) != 0) { -			free(dbfile); -			free(syncpath); -			RET_ERR(PM_ERR_SYSTEM, -1); + +		FREE(fileurl); +		if(ret != -1 && sig_ret != -1) { +			break;  		}  	} -	ret = _alpm_download_single_file(dbfile, db->servers, syncpath, force); -	free(dbfile); -	free(syncpath); -	umask(oldmask); -  	if(ret == 1) {  		/* files match, do nothing */ -		pm_errno = 0; -		return(1); +		handle->pm_errno = 0; +		goto cleanup;  	} else if(ret == -1) {  		/* pm_errno was set by the download code */ -		_alpm_log(PM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerrorlast()); -		return(-1); +		_alpm_log(handle, PM_LOG_DEBUG, "failed to sync db: %s\n", +				alpm_strerror(handle->pm_errno)); +		goto cleanup;  	}  	/* Cache needs to be rebuilt */  	_alpm_db_free_pkgcache(db); -	return(0); +cleanup: + +	free(syncpath); +	umask(oldmask); +	return ret;  }  /* Forward decl so I don't reorganize the whole file right now */ @@ -206,7 +240,7 @@ static size_t estimate_package_count(struct stat *st, struct archive *archive)  			/* assume it is at least somewhat compressed */  			per_package = 200;  	} -	return((size_t)(st->st_size / per_package) + 1); +	return (size_t)((st->st_size / per_package) + 1);  }  static int sync_db_populate(pmdb_t *db) @@ -219,12 +253,8 @@ static int sync_db_populate(pmdb_t *db)  	struct archive_entry *entry;  	pmpkg_t *pkg = NULL; -	ALPM_LOG_FUNC; - -	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); -  	if((archive = archive_read_new()) == NULL) { -		RET_ERR(PM_ERR_LIBARCHIVE, -1); +		RET_ERR(db->handle, PM_ERR_LIBARCHIVE, -1);  	}  	archive_read_support_compression_all(archive); @@ -236,24 +266,24 @@ static int sync_db_populate(pmdb_t *db)  		return -1;  	} -	_alpm_log(PM_LOG_DEBUG, "opening database archive %s\n", dbpath); +	_alpm_log(db->handle, PM_LOG_DEBUG, "opening database archive %s\n", dbpath);  	if(archive_read_open_filename(archive, dbpath,  				ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { -		_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), dbpath, +		_alpm_log(db->handle, PM_LOG_ERROR, _("could not open file %s: %s\n"), dbpath,  				archive_error_string(archive));  		archive_read_finish(archive); -		RET_ERR(PM_ERR_DB_OPEN, -1); +		RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);  	}  	if(stat(dbpath, &buf) != 0) { -		RET_ERR(PM_ERR_DB_OPEN, -1); +		RET_ERR(db->handle, PM_ERR_DB_OPEN, -1);  	}  	est_count = estimate_package_count(&buf, archive);  	/* initialize hash at 66% full */  	db->pkgcache = _alpm_pkghash_create(est_count * 3 / 2);  	if(db->pkgcache == NULL) { -		RET_ERR(PM_ERR_MEMORY, -1); +		RET_ERR(db->handle, PM_ERR_MEMORY, -1);  	}  	while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) { @@ -267,37 +297,47 @@ static int sync_db_populate(pmdb_t *db)  			pkg = _alpm_pkg_new();  			if(pkg == NULL) {  				archive_read_finish(archive); -				RET_ERR(PM_ERR_MEMORY, -1); +				RET_ERR(db->handle, PM_ERR_MEMORY, -1);  			}  			name = archive_entry_pathname(entry);  			if(_alpm_splitname(name, pkg) != 0) { -				_alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"), +				_alpm_log(db->handle, PM_LOG_ERROR, _("invalid name for database entry '%s'\n"),  						name);  				_alpm_pkg_free(pkg); +				pkg = NULL;  				continue;  			}  			/* duplicated database entries are not allowed */  			if(_alpm_pkghash_find(db->pkgcache, pkg->name)) { -				_alpm_log(PM_LOG_ERROR, _("duplicated database entry '%s'\n"), pkg->name); +				_alpm_log(db->handle, PM_LOG_ERROR, _("duplicated database entry '%s'\n"), pkg->name);  				_alpm_pkg_free(pkg); +				pkg = NULL;  				continue;  			}  			pkg->origin = PKG_FROM_SYNCDB; -			pkg->ops = &default_pkg_ops;  			pkg->origin_data.db = db; +			pkg->ops = &default_pkg_ops; +			pkg->handle = db->handle;  			/* add to the collection */ -			_alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n", +			_alpm_log(db->handle, PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",  					pkg->name, db->treename);  			db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg);  			count++;  		} else {  			/* we have desc, depends or deltas - parse it */ -			sync_db_read(db, archive, entry, pkg); +			if(sync_db_read(db, archive, entry, pkg) != 0) { +				_alpm_log(db->handle, PM_LOG_ERROR, +						_("could not parse package '%s' description file from db '%s'\n"), +						pkg->name, db->treename); +				_alpm_pkg_free(pkg); +				pkg = NULL; +				continue; +			}  		}  	} @@ -305,8 +345,10 @@ static int sync_db_populate(pmdb_t *db)  		db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp);  	}  	archive_read_finish(archive); +	_alpm_log(db->handle, PM_LOG_DEBUG, "added %d packages to package cache for db '%s'\n", +			count, db->treename); -	return(count); +	return count;  }  #define READ_NEXT(s) do { \ @@ -330,26 +372,19 @@ static int sync_db_populate(pmdb_t *db)  static int sync_db_read(pmdb_t *db, struct archive *archive,  		struct archive_entry *entry, pmpkg_t *likely_pkg)  { -	const char *entryname = NULL, *filename; +	const char *entryname, *filename;  	char *pkgname, *p, *q;  	pmpkg_t *pkg;  	struct archive_read_buffer buf; -	ALPM_LOG_FUNC; - -	if(db == NULL) { -		RET_ERR(PM_ERR_DB_NULL, -1); -	} - -	if(entry != NULL) { -		entryname = archive_entry_pathname(entry); -	} +	entryname = archive_entry_pathname(entry);  	if(entryname == NULL) { -		_alpm_log(PM_LOG_DEBUG, "invalid archive entry provided to _alpm_sync_db_read, skipping\n"); -		return(-1); +		_alpm_log(db->handle, PM_LOG_DEBUG, +				"invalid archive entry provided to _alpm_sync_db_read, skipping\n"); +		return -1;  	} -	_alpm_log(PM_LOG_FUNCTION, "loading package data from archive entry %s\n", +	_alpm_log(db->handle, PM_LOG_FUNCTION, "loading package data from archive entry %s\n",  			entryname);  	memset(&buf, 0, sizeof(buf)); @@ -357,7 +392,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,  	buf.max_line_size = 512 * 1024;  	/* get package and db file names */ -	STRDUP(pkgname, entryname, RET_ERR(PM_ERR_MEMORY, -1)); +	STRDUP(pkgname, entryname, RET_ERR(db->handle, PM_ERR_MEMORY, -1));  	p = pkgname + strlen(pkgname);  	for(q = --p; *q && *q != '/'; q--);  	filename = q + 1; @@ -370,31 +405,32 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,  		pkg = likely_pkg;  	} else {  		if(db->pkgcache == NULL) { -			RET_ERR(PM_ERR_MEMORY, -1); +			RET_ERR(db->handle, PM_ERR_MEMORY, -1);  		}  		pkg = _alpm_pkghash_find(db->pkgcache, pkgname);  	}  	if(pkg == NULL) { -		_alpm_log(PM_LOG_DEBUG, "package %s not found in %s sync database", +		_alpm_log(db->handle, PM_LOG_DEBUG, "package %s not found in %s sync database",  					pkgname, db->treename); -		return(-1); +		return -1;  	}  	if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0  			|| strcmp(filename, "deltas") == 0) { -		while(_alpm_archive_fgets(archive, &buf) == ARCHIVE_OK) { +		int ret; +		while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {  			char *line = _alpm_strtrim(buf.line);  			if(strcmp(line, "%NAME%") == 0) {  				READ_NEXT(line);  				if(strcmp(line, pkg->name) != 0) { -					_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: name " +					_alpm_log(db->handle, PM_LOG_ERROR, _("%s database is inconsistent: name "  								"mismatch on package %s\n"), db->treename, pkg->name);  				}  			} else if(strcmp(line, "%VERSION%") == 0) {  				READ_NEXT(line);  				if(strcmp(line, pkg->version) != 0) { -					_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: version " +					_alpm_log(db->handle, PM_LOG_ERROR, _("%s database is inconsistent: version "  								"mismatch on package %s\n"), db->treename, pkg->name);  				}  			} else if(strcmp(line, "%FILENAME%") == 0) { @@ -434,8 +470,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,  				/* we don't do anything with this value right now */  				READ_NEXT(line);  			} else if(strcmp(line, "%PGPSIG%") == 0) { -				/* we don't do anything with this value right now */ -				READ_NEXT(line); +				READ_AND_STORE(pkg->base64_sig);  			} else if(strcmp(line, "%REPLACES%") == 0) {  				READ_AND_STORE_ALL(pkg->replaces);  			} else if(strcmp(line, "%DEPENDS%") == 0) { @@ -460,22 +495,28 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,  				}  			}  		} +		if(ret != ARCHIVE_EOF) { +			goto error; +		}  	} else if(strcmp(filename, "files") == 0) {  		/* currently do nothing with this file */  	} else {  		/* unknown database file */ -		_alpm_log(PM_LOG_DEBUG, "unknown database file: %s\n", filename); +		_alpm_log(db->handle, PM_LOG_DEBUG, "unknown database file: %s\n", filename);  	} +	FREE(pkgname); +	return 0; +  error: +	_alpm_log(db->handle, PM_LOG_DEBUG, "error parsing database file: %s\n", filename);  	FREE(pkgname); -	/* TODO: return 0 always? */ -	return(0); +	return -1;  } -static int sync_db_version(pmdb_t *db) +static int sync_db_version(pmdb_t UNUSED *db)  { -	return(2); +	return 2;  }  struct db_operations sync_db_ops = { @@ -484,31 +525,21 @@ struct db_operations sync_db_ops = {  	.version          = sync_db_version,  }; -pmdb_t *_alpm_db_register_sync(const char *treename) +pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename)  {  	pmdb_t *db; -	alpm_list_t *i; - -	ALPM_LOG_FUNC; - -	for(i = handle->dbs_sync; i; i = i->next) { -		pmdb_t *sdb = i->data; -		if(strcmp(treename, sdb->treename) == 0) { -			_alpm_log(PM_LOG_DEBUG, "attempt to re-register the '%s' database, using existing\n", sdb->treename); -			return sdb; -		} -	} -	_alpm_log(PM_LOG_DEBUG, "registering sync database '%s'\n", treename); +	_alpm_log(handle, PM_LOG_DEBUG, "registering sync database '%s'\n", treename);  	db = _alpm_db_new(treename, 0);  	if(db == NULL) { -		RET_ERR(PM_ERR_DB_CREATE, NULL); +		RET_ERR(handle, PM_ERR_DB_CREATE, NULL);  	}  	db->ops = &sync_db_ops; +	db->handle = handle;  	handle->dbs_sync = alpm_list_add(handle->dbs_sync, db); -	return(db); +	return db;  } diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index 6faced16..a6bbe093 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -40,20 +40,18 @@  #include "log.h"  #include "deps.h" -pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2, +static pmconflict_t *conflict_new(const char *package1, const char *package2,  		const char *reason)  {  	pmconflict_t *conflict; -	ALPM_LOG_FUNC; +	MALLOC(conflict, sizeof(pmconflict_t), return NULL); -	MALLOC(conflict, sizeof(pmconflict_t), RET_ERR(PM_ERR_MEMORY, NULL)); +	STRDUP(conflict->package1, package1, return NULL); +	STRDUP(conflict->package2, package2, return NULL); +	STRDUP(conflict->reason, reason, return NULL); -	STRDUP(conflict->package1, package1, RET_ERR(PM_ERR_MEMORY, NULL)); -	STRDUP(conflict->package2, package2, RET_ERR(PM_ERR_MEMORY, NULL)); -	STRDUP(conflict->reason, reason, RET_ERR(PM_ERR_MEMORY, NULL)); - -	return(conflict); +	return conflict;  }  void _alpm_conflict_free(pmconflict_t *conflict) @@ -67,13 +65,13 @@ void _alpm_conflict_free(pmconflict_t *conflict)  pmconflict_t *_alpm_conflict_dup(const pmconflict_t *conflict)  {  	pmconflict_t *newconflict; -	CALLOC(newconflict, 1, sizeof(pmconflict_t), RET_ERR(PM_ERR_MEMORY, NULL)); +	CALLOC(newconflict, 1, sizeof(pmconflict_t), ); -	STRDUP(newconflict->package1, conflict->package1, RET_ERR(PM_ERR_MEMORY, NULL)); -	STRDUP(newconflict->package2, conflict->package2, RET_ERR(PM_ERR_MEMORY, NULL)); -	STRDUP(newconflict->reason, conflict->reason, RET_ERR(PM_ERR_MEMORY, NULL)); +	STRDUP(newconflict->package1, conflict->package1, return NULL); +	STRDUP(newconflict->package2, conflict->package2, return NULL); +	STRDUP(newconflict->reason, conflict->reason, return NULL); -	return(newconflict); +	return newconflict;  }  static int conflict_isin(pmconflict_t *needle, alpm_list_t *haystack) @@ -82,37 +80,41 @@ static int conflict_isin(pmconflict_t *needle, alpm_list_t *haystack)  	const char *npkg1 = needle->package1;  	const char *npkg2 = needle->package2; -	ALPM_LOG_FUNC; -  	for(i = haystack; i; i = i->next) {  		pmconflict_t *conflict = i->data;  		const char *cpkg1 = conflict->package1;  		const char *cpkg2 = conflict->package2;  		if((strcmp(cpkg1, npkg1) == 0  && strcmp(cpkg2, npkg2) == 0)  				|| (strcmp(cpkg1, npkg2) == 0 && strcmp(cpkg2, npkg1) == 0)) { -			return(1); +			return 1;  		}  	} -	return(0); +	return 0;  } -/** Adds the pkg1/pkg2 conflict to the baddeps list - * @param *baddeps list to add conflict to +/** Adds the pkg1/pkg2 conflict to the baddeps list. + * @param handle the context handle + * @param baddeps list to add conflict to   * @param pkg1 first package   * @param pkg2 package causing conflict + * @param reason reason for this conflict   */ -static void add_conflict(alpm_list_t **baddeps, const char *pkg1, -		const char *pkg2, const char *reason) +static int add_conflict(pmhandle_t *handle, alpm_list_t **baddeps, +		const char *pkg1, const char *pkg2, const char *reason)  { -	pmconflict_t *conflict = _alpm_conflict_new(pkg1, pkg2, reason); -	_alpm_log(PM_LOG_DEBUG, "package %s conflicts with %s (by %s)\n", +	pmconflict_t *conflict = conflict_new(pkg1, pkg2, reason); +	if(!conflict) { +		return -1; +	} +	_alpm_log(handle, PM_LOG_DEBUG, "package %s conflicts with %s (by %s)\n",  			pkg1, pkg2, reason); -	if(conflict && !conflict_isin(conflict, *baddeps)) { +	if(!conflict_isin(conflict, *baddeps)) {  		*baddeps = alpm_list_add(*baddeps, conflict);  	} else {  		_alpm_conflict_free(conflict);  	} +	return 0;  }  /** Check if packages from list1 conflict with packages from list2. @@ -121,14 +123,16 @@ static void add_conflict(alpm_list_t **baddeps, const char *pkg1,   * If a conflict (pkg1, pkg2) is found, it is added to the baddeps list   * in this order if order >= 0, or reverse order (pkg2,pkg1) otherwise.   * + * @param handle the context handle   * @param list1 first list of packages   * @param list2 second list of packages - * @param *baddeps list to store conflicts + * @param baddeps list to store conflicts   * @param order if >= 0 the conflict order is preserved, if < 0 it's reversed   */ -static void check_conflict(alpm_list_t *list1, alpm_list_t *list2, +static void check_conflict(pmhandle_t *handle, +		alpm_list_t *list1, alpm_list_t *list2,  		alpm_list_t **baddeps, int order) { -	alpm_list_t *i, *j, *k; +	alpm_list_t *i;  	if(!baddeps) {  		return; @@ -136,9 +140,11 @@ static void check_conflict(alpm_list_t *list1, alpm_list_t *list2,  	for(i = list1; i; i = i->next) {  		pmpkg_t *pkg1 = i->data;  		const char *pkg1name = alpm_pkg_get_name(pkg1); +		alpm_list_t *j;  		for(j = alpm_pkg_get_conflicts(pkg1); j; j = j->next) {  			const char *conflict = j->data; +			alpm_list_t *k;  			pmdepend_t *parsed_conflict = _alpm_splitdep(conflict);  			for(k = list2; k; k = k->next) { @@ -152,9 +158,9 @@ static void check_conflict(alpm_list_t *list1, alpm_list_t *list2,  				if(_alpm_depcmp(pkg2, parsed_conflict)) {  					if(order >= 0) { -						add_conflict(baddeps, pkg1name, pkg2name, conflict); +						add_conflict(handle, baddeps, pkg1name, pkg2name, conflict);  					} else { -						add_conflict(baddeps, pkg2name, pkg1name, conflict); +						add_conflict(handle, baddeps, pkg2name, pkg1name, conflict);  					}  				}  			} @@ -164,16 +170,14 @@ static void check_conflict(alpm_list_t *list1, alpm_list_t *list2,  }  /* Check for inter-conflicts */ -alpm_list_t *_alpm_innerconflicts(alpm_list_t *packages) +alpm_list_t *_alpm_innerconflicts(pmhandle_t *handle, alpm_list_t *packages)  {  	alpm_list_t *baddeps = NULL; -	ALPM_LOG_FUNC; +	_alpm_log(handle, PM_LOG_DEBUG, "check targets vs targets\n"); +	check_conflict(handle, packages, packages, &baddeps, 0); -	_alpm_log(PM_LOG_DEBUG, "check targets vs targets\n"); -	check_conflict(packages, packages, &baddeps, 0); - -	return(baddeps); +	return baddeps;  }  /* Check for target vs (db - target) conflicts @@ -184,85 +188,55 @@ alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages)  {  	alpm_list_t *baddeps = NULL; -	ALPM_LOG_FUNC; -  	if(db == NULL) { -		return(NULL); +		return NULL;  	}  	alpm_list_t *dblist = alpm_list_diff(_alpm_db_get_pkgcache(db),  			packages, _alpm_pkg_cmp);  	/* two checks to be done here for conflicts */ -	_alpm_log(PM_LOG_DEBUG, "check targets vs db\n"); -	check_conflict(packages, dblist, &baddeps, 1); -	_alpm_log(PM_LOG_DEBUG, "check db vs targets\n"); -	check_conflict(dblist, packages, &baddeps, -1); +	_alpm_log(db->handle, PM_LOG_DEBUG, "check targets vs db\n"); +	check_conflict(db->handle, packages, dblist, &baddeps, 1); +	_alpm_log(db->handle, PM_LOG_DEBUG, "check db vs targets\n"); +	check_conflict(db->handle, dblist, packages, &baddeps, -1);  	alpm_list_free(dblist); -	return(baddeps); +	return baddeps;  }  /** Check the package conflicts in a database   * + * @param handle the context handle   * @param pkglist the list of packages to check   * @return an alpm_list_t of pmconflict_t   */ -alpm_list_t SYMEXPORT *alpm_checkconflicts(alpm_list_t *pkglist) { -	return(_alpm_innerconflicts(pkglist)); -} - -/* Returns a alpm_list_t* of file conflicts. - *  Hooray for set-intersects! - *  Pre-condition: both lists are sorted! - */ -static alpm_list_t *chk_fileconflicts(alpm_list_t *filesA, alpm_list_t *filesB) +alpm_list_t SYMEXPORT *alpm_checkconflicts(pmhandle_t *handle, +		alpm_list_t *pkglist)  { -	alpm_list_t *ret = NULL; -	alpm_list_t *pA = filesA, *pB = filesB; - -	while(pA && pB) { -		const char *strA = pA->data; -		const char *strB = pB->data; -		/* skip directories, we don't care about dir conflicts */ -		if(strA[strlen(strA)-1] == '/') { -			pA = pA->next; -		} else if(strB[strlen(strB)-1] == '/') { -			pB = pB->next; -		} else { -			int cmp = strcmp(strA, strB); -			if(cmp < 0) { -				/* item only in filesA, ignore it */ -				pA = pA->next; -			} else if(cmp > 0) { -				/* item only in filesB, ignore it */ -				pB = pB->next; -			} else { -				/* item in both, record it */ -				ret = alpm_list_add(ret, strdup(strA)); -				pA = pA->next; -				pB = pB->next; -			} -	  } -	} - -	return(ret); +	CHECK_HANDLE(handle, return NULL); +	return _alpm_innerconflicts(handle, pkglist);  } -/* Returns a alpm_list_t* of files that are in filesA but *NOT* in filesB - *  This is an 'A minus B' set operation - *  Pre-condition: both lists are sorted! +static const int DIFFERENCE = 0; +static const int INTERSECT = 1; +/* Returns a set operation on the provided two lists of files. + * Pre-condition: both lists are sorted! + * + * Operations: + *   DIFFERENCE - a difference operation is performed. filesA - filesB. + *   INTERSECT - an intersection operation is performed. filesA & filesB.   */ -static alpm_list_t *chk_filedifference(alpm_list_t *filesA, alpm_list_t *filesB) +static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB, +		int operation)  {  	alpm_list_t *ret = NULL;  	alpm_list_t *pA = filesA, *pB = filesB; -	/* if both filesA and filesB have entries, do this loop */  	while(pA && pB) {  		const char *strA = pA->data;  		const char *strB = pB->data; -		/* skip directories, we don't care about dir conflicts */ +		/* skip directories, we don't care about them */  		if(strA[strlen(strA)-1] == '/') {  			pA = pA->next;  		} else if(strB[strlen(strB)-1] == '/') { @@ -270,21 +244,26 @@ static alpm_list_t *chk_filedifference(alpm_list_t *filesA, alpm_list_t *filesB)  		} else {  			int cmp = strcmp(strA, strB);  			if(cmp < 0) { -				/* item only in filesA, record it */ -				ret = alpm_list_add(ret, strdup(strA)); +				if(operation == DIFFERENCE) { +					/* item only in filesA, qualifies as a difference */ +					ret = alpm_list_add(ret, strdup(strA)); +				}  				pA = pA->next;  			} else if(cmp > 0) { -				/* item only in fileB, but this means nothing */  				pB = pB->next;  			} else { -				/* item in both, ignore it */ +				if(operation == INTERSECT) { +					/* item in both, qualifies as an intersect */ +					ret = alpm_list_add(ret, strdup(strA)); +				}  				pA = pA->next;  				pB = pB->next;  			}  	  }  	} -	/* ensure we have completely emptied pA */ -	while(pA) { + +	/* if doing a difference, ensure we have completely emptied pA */ +	while(operation == DIFFERENCE && pA) {  		const char *strA = pA->data;  		/* skip directories */  		if(strA[strlen(strA)-1] != '/') { @@ -293,7 +272,7 @@ static alpm_list_t *chk_filedifference(alpm_list_t *filesA, alpm_list_t *filesB)  		pA = pA->next;  	} -	return(ret); +	return ret;  }  /* Adds pmfileconflict_t to a conflicts list. Pass the conflicts list, type (either @@ -301,40 +280,42 @@ static alpm_list_t *chk_filedifference(alpm_list_t *filesA, alpm_list_t *filesB)   * two package names or one package name and NULL. This is a wrapper for former   * functionality that was done inline.   */ -static alpm_list_t *add_fileconflict(alpm_list_t *conflicts, -                    pmfileconflicttype_t type, const char *filestr, -                    const char* name1, const char* name2) +static alpm_list_t *add_fileconflict(pmhandle_t *handle, +		alpm_list_t *conflicts, pmfileconflicttype_t type, const char *filestr, +		const char *name1, const char *name2)  {  	pmfileconflict_t *conflict; -	MALLOC(conflict, sizeof(pmfileconflict_t), RET_ERR(PM_ERR_MEMORY, NULL)); +	MALLOC(conflict, sizeof(pmfileconflict_t), goto error);  	conflict->type = type; -	STRDUP(conflict->target, name1, RET_ERR(PM_ERR_MEMORY, NULL)); -	STRDUP(conflict->file, filestr, RET_ERR(PM_ERR_MEMORY, NULL)); +	STRDUP(conflict->target, name1, goto error); +	STRDUP(conflict->file, filestr, goto error);  	if(name2) { -		STRDUP(conflict->ctarget, name2, RET_ERR(PM_ERR_MEMORY, NULL)); +		STRDUP(conflict->ctarget, name2, goto error);  	} else { -		conflict->ctarget = ""; +		STRDUP(conflict->ctarget, "", goto error);  	}  	conflicts = alpm_list_add(conflicts, conflict); -	_alpm_log(PM_LOG_DEBUG, "found file conflict %s, packages %s and %s\n", +	_alpm_log(handle, PM_LOG_DEBUG, "found file conflict %s, packages %s and %s\n",  	          filestr, name1, name2 ? name2 : "(filesystem)"); -	return(conflicts); +	return conflicts; + +error: +	RET_ERR(handle, PM_ERR_MEMORY, conflicts);  }  void _alpm_fileconflict_free(pmfileconflict_t *conflict)  { -	if(strlen(conflict->ctarget) > 0) { -		FREE(conflict->ctarget); -	} -	FREE(conflict->file);; +	FREE(conflict->ctarget); +	FREE(conflict->file);  	FREE(conflict->target);  	FREE(conflict);  } -static int dir_belongsto_pkg(char *dirpath, pmpkg_t *pkg) +static int dir_belongsto_pkg(const char *root, const char *dirpath, +		pmpkg_t *pkg)  {  	struct dirent *ent = NULL;  	struct stat sbuf; @@ -342,10 +323,10 @@ static int dir_belongsto_pkg(char *dirpath, pmpkg_t *pkg)  	char abspath[PATH_MAX];  	DIR *dir; -	snprintf(abspath, PATH_MAX, "%s%s", handle->root, dirpath); +	snprintf(abspath, PATH_MAX, "%s%s", root, dirpath);  	dir = opendir(abspath);  	if(dir == NULL) { -		return(1); +		return 1;  	}  	while((ent = readdir(dir)) != NULL) {  		const char *name = ent->d_name; @@ -354,44 +335,43 @@ static int dir_belongsto_pkg(char *dirpath, pmpkg_t *pkg)  			continue;  		}  		snprintf(path, PATH_MAX, "%s/%s", dirpath, name); -		snprintf(abspath, PATH_MAX, "%s%s", handle->root, path); +		snprintf(abspath, PATH_MAX, "%s%s", root, path);  		if(stat(abspath, &sbuf) != 0) {  			continue;  		}  		if(S_ISDIR(sbuf.st_mode)) { -			if(dir_belongsto_pkg(path, pkg)) { +			if(dir_belongsto_pkg(root, path, pkg)) {  				continue;  			} else {  				closedir(dir); -				return(0); +				return 0;  			}  		} else {  			if(alpm_list_find_str(alpm_pkg_get_files(pkg), path)) {  				continue;  			} else {  				closedir(dir); -				return(0); +				return 0;  			}  		}  	}  	closedir(dir); -	return(1); +	return 1;  }  /* Find file conflicts that may occur during the transaction with two checks:   * 1: check every target against every target   * 2: check every target against the filesystem */ -alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, +alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle,  		alpm_list_t *upgrade, alpm_list_t *remove)  {  	alpm_list_t *i, *j, *conflicts = NULL;  	size_t numtargs = alpm_list_count(upgrade);  	size_t current; +	pmtrans_t *trans = handle->trans; -	ALPM_LOG_FUNC; - -	if(db == NULL || upgrade == NULL || trans == NULL) { -		return(NULL); +	if(!upgrade) { +		return NULL;  	}  	/* TODO this whole function needs a huge change, which hopefully will @@ -399,9 +379,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans,  	 * here as we do when we actually extract files in add.c with our 12  	 * different cases. */  	for(current = 0, i = upgrade; i; i = i->next, current++) { -		alpm_list_t *k, *tmpfiles = NULL; +		alpm_list_t *k, *tmpfiles;  		pmpkg_t *p1, *p2, *dbpkg; -		char path[PATH_MAX+1]; +		char path[PATH_MAX];  		p1 = i->data;  		if(!p1) { @@ -412,47 +392,55 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans,  		PROGRESS(trans, PM_TRANS_PROGRESS_CONFLICTS_START, "", percent,  		         numtargs, current);  		/* CHECK 1: check every target against every target */ -		_alpm_log(PM_LOG_DEBUG, "searching for file conflicts: %s\n", +		_alpm_log(handle, PM_LOG_DEBUG, "searching for file conflicts: %s\n",  								alpm_pkg_get_name(p1));  		for(j = i->next; j; j = j->next) { +			alpm_list_t *common_files;  			p2 = j->data;  			if(!p2) {  				continue;  			} -			tmpfiles = chk_fileconflicts(alpm_pkg_get_files(p1), alpm_pkg_get_files(p2)); +			common_files = filelist_operation(alpm_pkg_get_files(p1), +					alpm_pkg_get_files(p2), INTERSECT); -			if(tmpfiles) { -				for(k = tmpfiles; k; k = k->next) { +			if(common_files) { +				for(k = common_files; k; k = k->next) {  					snprintf(path, PATH_MAX, "%s%s", handle->root, (char *)k->data); -					conflicts = add_fileconflict(conflicts, PM_FILECONFLICT_TARGET, path, +					conflicts = add_fileconflict(handle, conflicts, +							PM_FILECONFLICT_TARGET, path,  							alpm_pkg_get_name(p1), alpm_pkg_get_name(p2)); +					if(handle->pm_errno == PM_ERR_MEMORY) { +						FREELIST(conflicts); +						FREELIST(common_files); +						return NULL; +					}  				} -				FREELIST(tmpfiles); +				FREELIST(common_files);  			}  		} -		/* declarations for second check */ -		struct stat lsbuf, sbuf; -		char *filestr = NULL; -  		/* CHECK 2: check every target against the filesystem */ -		_alpm_log(PM_LOG_DEBUG, "searching for filesystem conflicts: %s\n", p1->name); -		dbpkg = _alpm_db_get_pkgfromcache(db, p1->name); +		_alpm_log(handle, PM_LOG_DEBUG, "searching for filesystem conflicts: %s\n", +				p1->name); +		dbpkg = _alpm_db_get_pkgfromcache(handle->db_local, p1->name);  		/* Do two different checks here. If the package is currently installed,  		 * then only check files that are new in the new package. If the package -		 * is not currently installed, then simply stat the whole filelist */ +		 * is not currently installed, then simply stat the whole filelist. Note +		 * that the former list needs to be freed while the latter list should NOT +		 * be freed. */  		if(dbpkg) {  			/* older ver of package currently installed */ -			tmpfiles = chk_filedifference(alpm_pkg_get_files(p1), -					alpm_pkg_get_files(dbpkg)); +			tmpfiles = filelist_operation(alpm_pkg_get_files(p1), +					alpm_pkg_get_files(dbpkg), DIFFERENCE);  		} else {  			/* no version of package currently installed */ -			tmpfiles = alpm_list_strdup(alpm_pkg_get_files(p1)); +			tmpfiles = alpm_pkg_get_files(p1);  		}  		for(j = tmpfiles; j; j = j->next) { -			filestr = j->data; +			struct stat lsbuf; +			const char *filestr = j->data;  			snprintf(path, PATH_MAX, "%s%s", handle->root, filestr); @@ -460,19 +448,21 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans,  			if(_alpm_lstat(path, &lsbuf) != 0) {  				continue;  			} -			stat(path, &sbuf);  			if(path[strlen(path)-1] == '/') { +				struct stat sbuf;  				if(S_ISDIR(lsbuf.st_mode)) { -					_alpm_log(PM_LOG_DEBUG, "%s is a directory, not a conflict\n", path); +					_alpm_log(handle, PM_LOG_DEBUG, "%s is a directory, not a conflict\n", path);  					continue; -				} else if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(sbuf.st_mode)) { -					_alpm_log(PM_LOG_DEBUG, +				} +				stat(path, &sbuf); +				if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(sbuf.st_mode)) { +					_alpm_log(handle, PM_LOG_DEBUG,  							"%s is a symlink to a dir, hopefully not a conflict\n", path);  					continue;  				}  			} -			_alpm_log(PM_LOG_DEBUG, "checking possible conflict: %s\n", path); +			_alpm_log(handle, PM_LOG_DEBUG, "checking possible conflict: %s\n", path);  			int resolved_conflict = 0; /* have we acted on this conflict? */ @@ -480,7 +470,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans,  			for(k = remove; k && !resolved_conflict; k = k->next) {  				pmpkg_t *rempkg = k->data;  				if(rempkg && alpm_list_find_str(alpm_pkg_get_files(rempkg), filestr)) { -					_alpm_log(PM_LOG_DEBUG, "local file will be removed, not a conflict: %s\n", filestr); +					_alpm_log(handle, PM_LOG_DEBUG, +							"local file will be removed, not a conflict: %s\n", filestr);  					resolved_conflict = 1;  				}  			} @@ -491,15 +482,17 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans,  				if(!p2 || strcmp(p1->name, p2->name) == 0) {  					continue;  				} -				pmpkg_t *localp2 = _alpm_db_get_pkgfromcache(db, p2->name); +				pmpkg_t *localp2 = _alpm_db_get_pkgfromcache(handle->db_local, p2->name);  				/* localp2->files will be removed (target conflicts are handled by CHECK 1) */  				if(localp2 && alpm_list_find_str(alpm_pkg_get_files(localp2), filestr)) {  					/* skip removal of file, but not add. this will prevent a second  					 * package from removing the file when it was already installed  					 * by its new owner (whether the file is in backup array or not */ -					trans->skip_remove = alpm_list_add(trans->skip_remove, strdup(filestr)); -					_alpm_log(PM_LOG_DEBUG, "file changed packages, adding to remove skiplist: %s\n", filestr); +					handle->trans->skip_remove = +						alpm_list_add(handle->trans->skip_remove, strdup(filestr)); +					_alpm_log(handle, PM_LOG_DEBUG, +							"file changed packages, adding to remove skiplist: %s\n", filestr);  					resolved_conflict = 1;  				}  			} @@ -509,114 +502,91 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans,  				char *dir = malloc(strlen(filestr) + 2);  				sprintf(dir, "%s/", filestr);  				if(alpm_list_find_str(alpm_pkg_get_files(dbpkg),dir)) { -					_alpm_log(PM_LOG_DEBUG, "check if all files in %s belongs to %s\n", +					_alpm_log(handle, PM_LOG_DEBUG, +							"check if all files in %s belongs to %s\n",  							dir, dbpkg->name); -					resolved_conflict = dir_belongsto_pkg(filestr, dbpkg); +					resolved_conflict = dir_belongsto_pkg(handle->root, filestr, dbpkg);  				}  				free(dir);  			}  			if(!resolved_conflict && dbpkg) { -				char *rpath = calloc(PATH_MAX+1, sizeof(char)); +				char *rpath = calloc(PATH_MAX, sizeof(char));  				if(!realpath(path, rpath)) { -					FREE(rpath); +					free(rpath);  					continue;  				}  				char *filestr = rpath + strlen(handle->root); -				if(alpm_list_find_str(alpm_pkg_get_files(dbpkg),filestr)) { +				if(alpm_list_find_str(alpm_pkg_get_files(dbpkg), filestr)) {  					resolved_conflict = 1;  				}  				free(rpath);  			}  			if(!resolved_conflict) { -				_alpm_log(PM_LOG_DEBUG, "file found in conflict: %s\n", path); -				conflicts = add_fileconflict(conflicts, PM_FILECONFLICT_FILESYSTEM, -						path, p1->name, NULL); +				conflicts = add_fileconflict(handle, conflicts, +						PM_FILECONFLICT_FILESYSTEM, path, p1->name, NULL); +				if(handle->pm_errno == PM_ERR_MEMORY) { +					FREELIST(conflicts); +					if(dbpkg) { +						/* only freed if it was generated from filelist_operation() */ +						FREELIST(tmpfiles); +					} +					return NULL; +				}  			}  		} -		FREELIST(tmpfiles); +		if(dbpkg) { +			/* only freed if it was generated from filelist_operation() */ +			FREELIST(tmpfiles); +		}  	}  	PROGRESS(trans, PM_TRANS_PROGRESS_CONFLICTS_START, "", 100,  			numtargs, current); -	return(conflicts); +	return conflicts;  }  const char SYMEXPORT *alpm_conflict_get_package1(pmconflict_t *conflict)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(conflict != NULL, return(NULL)); - +	ASSERT(conflict != NULL, return NULL);  	return conflict->package1;  }  const char SYMEXPORT *alpm_conflict_get_package2(pmconflict_t *conflict)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(conflict != NULL, return(NULL)); - +	ASSERT(conflict != NULL, return NULL);  	return conflict->package2;  }  const char SYMEXPORT *alpm_conflict_get_reason(pmconflict_t *conflict)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(conflict != NULL, return(NULL)); - +	ASSERT(conflict != NULL, return NULL);  	return conflict->reason;  }  const char SYMEXPORT *alpm_fileconflict_get_target(pmfileconflict_t *conflict)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(conflict != NULL, return(NULL)); - +	ASSERT(conflict != NULL, return NULL);  	return conflict->target;  }  pmfileconflicttype_t SYMEXPORT alpm_fileconflict_get_type(pmfileconflict_t *conflict)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(-1)); -	ASSERT(conflict != NULL, return(-1)); - +	ASSERT(conflict != NULL, return -1);  	return conflict->type;  }  const char SYMEXPORT *alpm_fileconflict_get_file(pmfileconflict_t *conflict)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(conflict != NULL, return(NULL)); - +	ASSERT(conflict != NULL, return NULL);  	return conflict->file;  }  const char SYMEXPORT *alpm_fileconflict_get_ctarget(pmfileconflict_t *conflict)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(conflict != NULL, return(NULL)); - +	ASSERT(conflict != NULL, return NULL);  	return conflict->ctarget;  } +  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/conflict.h b/lib/libalpm/conflict.h index 418d3f61..7a3784a2 100644 --- a/lib/libalpm/conflict.h +++ b/lib/libalpm/conflict.h @@ -37,13 +37,12 @@ struct __pmfileconflict_t {  	char *ctarget;  }; -pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2, const char *reason);  pmconflict_t *_alpm_conflict_dup(const pmconflict_t *conflict);  void _alpm_conflict_free(pmconflict_t *conflict); -alpm_list_t *_alpm_innerconflicts(alpm_list_t *packages); +alpm_list_t *_alpm_innerconflicts(pmhandle_t *handle, alpm_list_t *packages);  alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages); -alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, -					 alpm_list_t *upgrade, alpm_list_t *remove); +alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, +		alpm_list_t *upgrade, alpm_list_t *remove);  void _alpm_fileconflict_free(pmfileconflict_t *conflict); diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index 1a3168b4..c3a7abd2 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -26,11 +26,8 @@  #include <stdio.h>  #include <stdlib.h> -#include <errno.h>  #include <string.h> -#include <sys/stat.h>  #include <regex.h> -#include <time.h>  /* libalpm */  #include "db.h" @@ -48,17 +45,16 @@   */  /** Register a sync database of packages. */ -pmdb_t SYMEXPORT *alpm_db_register_sync(const char *treename) +pmdb_t SYMEXPORT *alpm_db_register_sync(pmhandle_t *handle, const char *treename)  { -	ALPM_LOG_FUNC; -  	/* Sanity checks */ -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, NULL)); -	ASSERT(treename != NULL && strlen(treename) != 0, RET_ERR(PM_ERR_WRONG_ARGS, NULL)); +	CHECK_HANDLE(handle, return NULL); +	ASSERT(treename != NULL && strlen(treename) != 0, +			RET_ERR(handle, PM_ERR_WRONG_ARGS, NULL));  	/* Do not register a database if a transaction is on-going */ -	ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, NULL)); +	ASSERT(handle->trans == NULL, RET_ERR(handle, PM_ERR_TRANS_NOT_NULL, NULL)); -	return(_alpm_db_register_sync(treename)); +	return _alpm_db_register_sync(handle, treename);  }  /* Helper function for alpm_db_unregister{_all} */ @@ -68,22 +64,20 @@ void _alpm_db_unregister(pmdb_t *db)  		return;  	} -	_alpm_log(PM_LOG_DEBUG, "unregistering database '%s'\n", db->treename); +	_alpm_log(db->handle, PM_LOG_DEBUG, "unregistering database '%s'\n", db->treename);  	_alpm_db_free(db);  }  /** Unregister all package databases. */ -int SYMEXPORT alpm_db_unregister_all(void) +int SYMEXPORT alpm_db_unregister_all(pmhandle_t *handle)  {  	alpm_list_t *i;  	pmdb_t *db; -	ALPM_LOG_FUNC; -  	/* Sanity checks */ -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1);  	/* Do not unregister a database if a transaction is on-going */ -	ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1)); +	ASSERT(handle->trans == NULL, RET_ERR(handle, PM_ERR_TRANS_NOT_NULL, -1));  	/* unregister all sync dbs */  	for(i = handle->dbs_sync; i; i = i->next) { @@ -92,21 +86,21 @@ int SYMEXPORT alpm_db_unregister_all(void)  		i->data = NULL;  	}  	FREELIST(handle->dbs_sync); -	return(0); +	return 0;  }  /** Unregister a package database. */  int SYMEXPORT alpm_db_unregister(pmdb_t *db)  {  	int found = 0; - -	ALPM_LOG_FUNC; +	pmhandle_t *handle;  	/* Sanity checks */ -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); -	ASSERT(db != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); +	ASSERT(db != NULL, return -1);  	/* Do not unregister a database if a transaction is on-going */ -	ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1)); +	handle = db->handle; +	handle->pm_errno = 0; +	ASSERT(handle->trans == NULL, RET_ERR(handle, PM_ERR_TRANS_NOT_NULL, -1));  	if(db == handle->db_local) {  		handle->db_local = NULL; @@ -125,175 +119,196 @@ int SYMEXPORT alpm_db_unregister(pmdb_t *db)  	}  	if(!found) { -		RET_ERR(PM_ERR_DB_NOT_FOUND, -1); +		RET_ERR(handle, PM_ERR_DB_NOT_FOUND, -1);  	}  	db->ops->unregister(db); -	return(0); +	return 0; +} + +/** Get the serverlist of a database. */ +alpm_list_t SYMEXPORT *alpm_db_get_servers(const pmdb_t *db) +{ +	ASSERT(db != NULL, return NULL); +	return db->servers;  }  /** Set the serverlist of a database. */ -int SYMEXPORT alpm_db_setserver(pmdb_t *db, const char *url) +int SYMEXPORT alpm_db_set_servers(pmdb_t *db, alpm_list_t *servers) +{ +	ASSERT(db != NULL, return -1); +	if(db->servers) FREELIST(db->servers); +	db->servers = servers; +	return 0; +} + +static char *sanitize_url(const char *url)  { -	alpm_list_t *i; -	int found = 0;  	char *newurl; -	size_t len = 0; +	size_t len = strlen(url); -	ALPM_LOG_FUNC; +	STRDUP(newurl, url, return NULL); +	/* strip the trailing slash if one exists */ +	if(newurl[len - 1] == '/') { +		newurl[len - 1] = '\0'; +	} +	return newurl; +} -	/* Sanity checks */ -	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); +/** Add a download server to a database. + * @param db database pointer + * @param url url of the server + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ +int SYMEXPORT alpm_db_add_server(pmdb_t *db, const char *url) +{ +	char *newurl; -	for(i = handle->dbs_sync; i && !found; i = i->next) { -		pmdb_t *sdb = i->data; -		if(strcmp(db->treename, sdb->treename) == 0) { -			found = 1; -		} -	} -	if(!found) { -		RET_ERR(PM_ERR_DB_NOT_FOUND, -1); -	} +	/* Sanity checks */ +	ASSERT(db != NULL, return -1); +	db->handle->pm_errno = 0; +	ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, PM_ERR_WRONG_ARGS, -1)); -	if(url) { -		len = strlen(url); -	} -	if(len) { -		newurl = strdup(url); -		/* strip the trailing slash if one exists */ -		if(newurl[len - 1] == '/') { -			newurl[len - 1] = '\0'; -		} -		db->servers = alpm_list_add(db->servers, newurl); -		_alpm_log(PM_LOG_DEBUG, "adding new server URL to database '%s': %s\n", -				db->treename, newurl); -	} else { -		FREELIST(db->servers); -		_alpm_log(PM_LOG_DEBUG, "serverlist flushed for '%s'\n", db->treename); +	newurl = sanitize_url(url); +	if(!newurl) { +		return -1;  	} +	db->servers = alpm_list_add(db->servers, newurl); +	_alpm_log(db->handle, PM_LOG_DEBUG, "adding new server URL to database '%s': %s\n", +			db->treename, newurl); -	return(0); +	return 0;  } -/** Get the name of a package database. */ -const char SYMEXPORT *alpm_db_get_name(const pmdb_t *db) +/** Remove a download server from a database. + * @param db database pointer + * @param url url of the server + * @return 0 on success, 1 on server not present, + * -1 on error (pm_errno is set accordingly) + */ +int SYMEXPORT alpm_db_remove_server(pmdb_t *db, const char *url)  { -	ALPM_LOG_FUNC; +	char *newurl, *vdata = NULL;  	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(db != NULL, return(NULL)); +	ASSERT(db != NULL, return -1); +	db->handle->pm_errno = 0; +	ASSERT(url != NULL && strlen(url) != 0, RET_ERR(db->handle, PM_ERR_WRONG_ARGS, -1)); + +	newurl = sanitize_url(url); +	if(!newurl) { +		return -1; +	} +	db->servers = alpm_list_remove_str(db->servers, newurl, &vdata); +	free(newurl); +	if(vdata) { +		_alpm_log(db->handle, PM_LOG_DEBUG, "removed server URL from database '%s': %s\n", +				db->treename, newurl); +		free(vdata); +		return 0; +	} -	return db->treename; +	return 1;  } - -/** Get a download URL for the package database. */ -const char SYMEXPORT *alpm_db_get_url(const pmdb_t *db) +/** Set the verify gpg signature option for a database. + * @param db database pointer + * @param verify enum pgp_verify_t + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ +int SYMEXPORT alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify)  { -	char *url; - -	ALPM_LOG_FUNC; -  	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(db != NULL, return(NULL)); -	ASSERT(db->servers != NULL, return(NULL)); +	ASSERT(db != NULL, return -1); +	db->handle->pm_errno = 0; -	url = (char*)db->servers->data; +	db->pgp_verify = verify; +	_alpm_log(db->handle, PM_LOG_DEBUG, "adding VerifySig option to database '%s': %d\n", +			db->treename, verify); -	return(url); +	return 0;  } +/** Get the name of a package database. */ +const char SYMEXPORT *alpm_db_get_name(const pmdb_t *db) +{ +	ASSERT(db != NULL, return NULL); +	return db->treename; +}  /** Get a package entry from a package database. */  pmpkg_t SYMEXPORT *alpm_db_get_pkg(pmdb_t *db, const char *name)  { -	ALPM_LOG_FUNC; +	ASSERT(db != NULL, return NULL); +	db->handle->pm_errno = 0; +	ASSERT(name != NULL && strlen(name) != 0, +			RET_ERR(db->handle, PM_ERR_WRONG_ARGS, NULL)); -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(db != NULL, return(NULL)); -	ASSERT(name != NULL && strlen(name) != 0, return(NULL)); - -	return(_alpm_db_get_pkgfromcache(db, name)); +	return _alpm_db_get_pkgfromcache(db, name);  }  /** Get the package cache of a package database. */  alpm_list_t SYMEXPORT *alpm_db_get_pkgcache(pmdb_t *db)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(db != NULL, return(NULL)); - -	return(_alpm_db_get_pkgcache(db)); +	ASSERT(db != NULL, return NULL); +	db->handle->pm_errno = 0; +	return _alpm_db_get_pkgcache(db);  }  /** Get a group entry from a package database. */  pmgrp_t SYMEXPORT *alpm_db_readgrp(pmdb_t *db, const char *name)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(db != NULL, return(NULL)); -	ASSERT(name != NULL && strlen(name) != 0, return(NULL)); +	ASSERT(db != NULL, return NULL); +	db->handle->pm_errno = 0; +	ASSERT(name != NULL && strlen(name) != 0, +			RET_ERR(db->handle, PM_ERR_WRONG_ARGS, NULL)); -	return(_alpm_db_get_grpfromcache(db, name)); +	return _alpm_db_get_grpfromcache(db, name);  }  /** Get the group cache of a package database. */  alpm_list_t SYMEXPORT *alpm_db_get_grpcache(pmdb_t *db)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(db != NULL, return(NULL)); +	ASSERT(db != NULL, return NULL); +	db->handle->pm_errno = 0; -	return(_alpm_db_get_grpcache(db)); +	return _alpm_db_get_grpcache(db);  }  /** Searches a database. */  alpm_list_t SYMEXPORT *alpm_db_search(pmdb_t *db, const alpm_list_t* needles)  { -	ALPM_LOG_FUNC; +	ASSERT(db != NULL, return NULL); +	db->handle->pm_errno = 0; -	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(db != NULL, return(NULL)); - -	return(_alpm_db_search(db, needles)); +	return _alpm_db_search(db, needles);  }  /** Set install reason for a package in db. */  int SYMEXPORT alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t reason)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); -	ASSERT(db != NULL && name != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); +	ASSERT(db != NULL, return -1); +	db->handle->pm_errno = 0; +	/* TODO assert db == db_local ? shouldn't need a db param at all here... */ +	ASSERT(name != NULL, RET_ERR(db->handle, PM_ERR_WRONG_ARGS, -1));  	pmpkg_t *pkg = _alpm_db_get_pkgfromcache(db, name);  	if(pkg == NULL) { -		RET_ERR(PM_ERR_PKG_NOT_FOUND, -1); +		RET_ERR(db->handle, PM_ERR_PKG_NOT_FOUND, -1);  	} -	_alpm_log(PM_LOG_DEBUG, "setting install reason %u for %s/%s\n", reason, db->treename, name); +	_alpm_log(db->handle, PM_LOG_DEBUG, "setting install reason %u for %s/%s\n", reason, db->treename, name);  	if(alpm_pkg_get_reason(pkg) == reason) {  		/* we are done */ -		return(0); +		return 0;  	}  	/* set reason (in pkgcache) */  	pkg->reason = reason;  	/* write DESC */  	if(_alpm_local_db_write(db, pkg, INFRQ_DESC)) { -		RET_ERR(PM_ERR_DB_WRITE, -1); +		RET_ERR(db->handle, PM_ERR_DB_WRITE, -1);  	} -	return(0); +	return 0;  }  /** @} */ @@ -302,19 +317,16 @@ pmdb_t *_alpm_db_new(const char *treename, int is_local)  {  	pmdb_t *db; -	ALPM_LOG_FUNC; - -	CALLOC(db, 1, sizeof(pmdb_t), RET_ERR(PM_ERR_MEMORY, NULL)); -	STRDUP(db->treename, treename, RET_ERR(PM_ERR_MEMORY, NULL)); +	CALLOC(db, 1, sizeof(pmdb_t), return NULL); +	STRDUP(db->treename, treename, return NULL);  	db->is_local = is_local; +	db->pgp_verify = PM_PGP_VERIFY_UNKNOWN; -	return(db); +	return db;  }  void _alpm_db_free(pmdb_t *db)  { -	ALPM_LOG_FUNC; -  	/* cleanup pkgcache */  	_alpm_db_free_pkgcache(db);  	/* cleanup server list */ @@ -329,47 +341,61 @@ void _alpm_db_free(pmdb_t *db)  const char *_alpm_db_path(pmdb_t *db)  {  	if(!db) { -		return(NULL); +		return NULL;  	}  	if(!db->_path) {  		const char *dbpath;  		size_t pathsize; -		dbpath = alpm_option_get_dbpath(); +		dbpath = alpm_option_get_dbpath(db->handle);  		if(!dbpath) { -			_alpm_log(PM_LOG_ERROR, _("database path is undefined\n")); -			RET_ERR(PM_ERR_DB_OPEN, NULL); +			_alpm_log(db->handle, PM_LOG_ERROR, _("database path is undefined\n")); +			RET_ERR(db->handle, PM_ERR_DB_OPEN, NULL);  		}  		if(db->is_local) {  			pathsize = strlen(dbpath) + strlen(db->treename) + 2; -			CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL)); +			CALLOC(db->_path, 1, pathsize, RET_ERR(db->handle, PM_ERR_MEMORY, NULL));  			sprintf(db->_path, "%s%s/", dbpath, db->treename);  		} else {  			pathsize = strlen(dbpath) + 5 + strlen(db->treename) + 4; -			CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL)); +			CALLOC(db->_path, 1, pathsize, RET_ERR(db->handle, PM_ERR_MEMORY, NULL));  			/* all sync DBs now reside in the sync/ subdir of the dbpath */  			sprintf(db->_path, "%ssync/%s.db", dbpath, db->treename);  		} -		_alpm_log(PM_LOG_DEBUG, "database path for tree %s set to %s\n", +		_alpm_log(db->handle, PM_LOG_DEBUG, "database path for tree %s set to %s\n",  				db->treename, db->_path);  	} -	return(db->_path); +	return db->_path;  }  int _alpm_db_version(pmdb_t *db)  {  	if(!db) { -		return(-1); +		return -1;  	} -	return(db->ops->version(db)); +	return db->ops->version(db); +} + +char *_alpm_db_sig_path(pmdb_t *db) +{ +	char *sigpath; +	size_t len; +	const char *dbfile = _alpm_db_path(db); +	if(!db || !dbfile) { +		return NULL; +	} +	len = strlen(dbfile) + strlen(".sig") + 1; +	CALLOC(sigpath, len, sizeof(char), RET_ERR(db->handle, PM_ERR_MEMORY, NULL)); +	sprintf(sigpath, "%s.sig", dbfile); +	return sigpath;  }  int _alpm_db_cmp(const void *d1, const void *d2)  {  	pmdb_t *db1 = (pmdb_t *)d1;  	pmdb_t *db2 = (pmdb_t *)d2; -	return(strcmp(db1->treename, db2->treename)); +	return strcmp(db1->treename, db2->treename);  }  alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) @@ -379,8 +405,6 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)  	/* copy the pkgcache- we will free the list var after each needle */  	alpm_list_t *list = alpm_list_copy(_alpm_db_get_pkgcache(db)); -	ALPM_LOG_FUNC; -  	for(i = needles; i; i = i->next) {  		char *targ;  		regex_t reg; @@ -390,10 +414,10 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)  		}  		ret = NULL;  		targ = i->data; -		_alpm_log(PM_LOG_DEBUG, "searching for target '%s'\n", targ); +		_alpm_log(db->handle, PM_LOG_DEBUG, "searching for target '%s'\n", targ);  		if(regcomp(®, targ, REG_EXTENDED | REG_NOSUB | REG_ICASE | REG_NEWLINE) != 0) { -			RET_ERR(PM_ERR_INVALID_REGEX, NULL); +			RET_ERR(db->handle, PM_ERR_INVALID_REGEX, NULL);  		}  		for(j = list; j; j = j->next) { @@ -407,7 +431,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)  				matched = name;  			}  			/* check desc */ -			else if (desc && regexec(®, desc, 0, 0, 0) == 0) { +			else if(desc && regexec(®, desc, 0, 0, 0) == 0) {  				matched = desc;  			}  			/* TODO: should we be doing this, and should we print something @@ -415,7 +439,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)  			if(!matched) {  				/* check provides */  				for(k = alpm_pkg_get_provides(pkg); k; k = k->next) { -					if (regexec(®, k->data, 0, 0, 0) == 0) { +					if(regexec(®, k->data, 0, 0, 0) == 0) {  						matched = k->data;  						break;  					} @@ -424,7 +448,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)  			if(!matched) {  				/* check groups */  				for(k = alpm_pkg_get_groups(pkg); k; k = k->next) { -					if (regexec(®, k->data, 0, 0, 0) == 0) { +					if(regexec(®, k->data, 0, 0, 0) == 0) {  						matched = k->data;  						break;  					} @@ -432,7 +456,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)  			}  			if(matched != NULL) { -				_alpm_log(PM_LOG_DEBUG, "    search target '%s' matched '%s'\n", +				_alpm_log(db->handle, PM_LOG_DEBUG, "    search target '%s' matched '%s'\n",  				          targ, matched);  				ret = alpm_list_add(ret, pkg);  			} @@ -445,7 +469,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)  		regfree(®);  	} -	return(ret); +	return ret;  }  /* Returns a new package cache from db. @@ -453,34 +477,30 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)   */  int _alpm_db_load_pkgcache(pmdb_t *db)  { -	ALPM_LOG_FUNC; -  	if(db == NULL) { -		return(-1); +		return -1;  	}  	_alpm_db_free_pkgcache(db); -	_alpm_log(PM_LOG_DEBUG, "loading package cache for repository '%s'\n", +	_alpm_log(db->handle, PM_LOG_DEBUG, "loading package cache for repository '%s'\n",  			db->treename);  	if(db->ops->populate(db) == -1) { -		_alpm_log(PM_LOG_DEBUG, +		_alpm_log(db->handle, PM_LOG_DEBUG,  				"failed to load package cache for repository '%s'\n", db->treename); -		return(-1); +		return -1;  	}  	db->pkgcache_loaded = 1; -	return(0); +	return 0;  }  void _alpm_db_free_pkgcache(pmdb_t *db)  { -	ALPM_LOG_FUNC; -  	if(db == NULL || !db->pkgcache_loaded) {  		return;  	} -	_alpm_log(PM_LOG_DEBUG, "freeing package cache for repository '%s'\n", +	_alpm_log(db->handle, PM_LOG_DEBUG, "freeing package cache for repository '%s'\n",  	                        db->treename);  	alpm_list_free_inner(_alpm_db_get_pkgcache(db), @@ -493,10 +513,8 @@ void _alpm_db_free_pkgcache(pmdb_t *db)  pmpkghash_t *_alpm_db_get_pkgcache_hash(pmdb_t *db)  { -	ALPM_LOG_FUNC; -  	if(db == NULL) { -		return(NULL); +		return NULL;  	}  	if(!db->pkgcache_loaded) { @@ -505,23 +523,21 @@ pmpkghash_t *_alpm_db_get_pkgcache_hash(pmdb_t *db)  	/* hmmm, still NULL ?*/  	if(!db->pkgcache) { -		_alpm_log(PM_LOG_DEBUG, "warning: pkgcache is NULL for db '%s'\n", db->treename); +		_alpm_log(db->handle, PM_LOG_DEBUG, "warning: pkgcache is NULL for db '%s'\n", db->treename);  	} -	return(db->pkgcache); +	return db->pkgcache;  }  alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db)  { -	ALPM_LOG_FUNC; -  	pmpkghash_t *hash = _alpm_db_get_pkgcache_hash(db);  	if(hash == NULL) { -		return(NULL); +		return NULL;  	} -	return(hash->list); +	return hash->list;  }  /* "duplicate" pkg then add it to pkgcache */ @@ -529,70 +545,64 @@ int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg)  {  	pmpkg_t *newpkg; -	ALPM_LOG_FUNC; -  	if(db == NULL || !db->pkgcache_loaded || pkg == NULL) { -		return(-1); +		return -1;  	}  	newpkg = _alpm_pkg_dup(pkg);  	if(newpkg == NULL) { -		return(-1); +		return -1;  	} -	_alpm_log(PM_LOG_DEBUG, "adding entry '%s' in '%s' cache\n", +	_alpm_log(db->handle, PM_LOG_DEBUG, "adding entry '%s' in '%s' cache\n",  						alpm_pkg_get_name(newpkg), db->treename);  	db->pkgcache = _alpm_pkghash_add_sorted(db->pkgcache, newpkg);  	_alpm_db_free_grpcache(db); -	return(0); +	return 0;  }  int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg)  {  	pmpkg_t *data = NULL; -	ALPM_LOG_FUNC; -  	if(db == NULL || !db->pkgcache_loaded || pkg == NULL) { -		return(-1); +		return -1;  	} -	_alpm_log(PM_LOG_DEBUG, "removing entry '%s' from '%s' cache\n", +	_alpm_log(db->handle, PM_LOG_DEBUG, "removing entry '%s' from '%s' cache\n",  						alpm_pkg_get_name(pkg), db->treename);  	db->pkgcache = _alpm_pkghash_remove(db->pkgcache, pkg, &data);  	if(data == NULL) {  		/* package not found */ -		_alpm_log(PM_LOG_DEBUG, "cannot remove entry '%s' from '%s' cache: not found\n", +		_alpm_log(db->handle, PM_LOG_DEBUG, "cannot remove entry '%s' from '%s' cache: not found\n",  							alpm_pkg_get_name(pkg), db->treename); -		return(-1); +		return -1;  	}  	_alpm_pkg_free(data);  	_alpm_db_free_grpcache(db); -	return(0); +	return 0;  }  pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target)  { -	ALPM_LOG_FUNC; -  	if(db == NULL) { -		return(NULL); +		return NULL;  	}  	pmpkghash_t *pkgcache = _alpm_db_get_pkgcache_hash(db);  	if(!pkgcache) { -		_alpm_log(PM_LOG_DEBUG, "warning: failed to get '%s' from NULL pkgcache\n", +		_alpm_log(db->handle, PM_LOG_DEBUG, "warning: failed to get '%s' from NULL pkgcache\n",  				target); -		return(NULL); +		return NULL;  	} -	return(_alpm_pkghash_find(pkgcache, target)); +	return _alpm_pkghash_find(pkgcache, target);  }  /* Returns a new group cache from db. @@ -601,13 +611,11 @@ int _alpm_db_load_grpcache(pmdb_t *db)  {  	alpm_list_t *lp; -	ALPM_LOG_FUNC; -  	if(db == NULL) { -		return(-1); +		return -1;  	} -	_alpm_log(PM_LOG_DEBUG, "loading group cache for repository '%s'\n", +	_alpm_log(db->handle, PM_LOG_DEBUG, "loading group cache for repository '%s'\n",  			db->treename);  	for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) { @@ -636,26 +644,28 @@ int _alpm_db_load_grpcache(pmdb_t *db)  			}  			/* we didn't find the group, so create a new one with this name */  			grp = _alpm_grp_new(grpname); +			if(!grp) { +				_alpm_db_free_grpcache(db); +				return -1; +			}  			grp->packages = alpm_list_add(grp->packages, pkg);  			db->grpcache = alpm_list_add(db->grpcache, grp);  		}  	}  	db->grpcache_loaded = 1; -	return(0); +	return 0;  }  void _alpm_db_free_grpcache(pmdb_t *db)  {  	alpm_list_t *lg; -	ALPM_LOG_FUNC; -  	if(db == NULL || !db->grpcache_loaded) {  		return;  	} -	_alpm_log(PM_LOG_DEBUG, "freeing group cache for repository '%s'\n", +	_alpm_log(db->handle, PM_LOG_DEBUG, "freeing group cache for repository '%s'\n",  	                        db->treename);  	for(lg = db->grpcache; lg; lg = lg->next) { @@ -668,38 +678,34 @@ void _alpm_db_free_grpcache(pmdb_t *db)  alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db)  { -	ALPM_LOG_FUNC; -  	if(db == NULL) { -		return(NULL); +		return NULL;  	}  	if(!db->grpcache_loaded) {  		_alpm_db_load_grpcache(db);  	} -	return(db->grpcache); +	return db->grpcache;  }  pmgrp_t *_alpm_db_get_grpfromcache(pmdb_t *db, const char *target)  {  	alpm_list_t *i; -	ALPM_LOG_FUNC; -  	if(db == NULL || target == NULL || strlen(target) == 0) { -		return(NULL); +		return NULL;  	}  	for(i = _alpm_db_get_grpcache(db); i; i = i->next) {  		pmgrp_t *info = i->data;  		if(strcmp(info->name, target) == 0) { -			return(info); +			return info;  		}  	} -	return(NULL); +	return NULL;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h index 75776d71..e3faeeb4 100644 --- a/lib/libalpm/db.h +++ b/lib/libalpm/db.h @@ -22,15 +22,16 @@  #ifndef _ALPM_DB_H  #define _ALPM_DB_H -#include "alpm.h" -#include "pkghash.h" -  #include <time.h>  /* libarchive */  #include <archive.h>  #include <archive_entry.h> +#include "alpm.h" +#include "pkghash.h" +#include "signing.h" +  /* Database entries */  typedef enum _pmdbinfrq_t {  	INFRQ_BASE = 1, @@ -50,6 +51,7 @@ struct db_operations {  /* Database */  struct __pmdb_t { +	pmhandle_t *handle;  	char *treename;  	/* do not access directly, use _alpm_db_path(db) for lazy access */  	char *_path; @@ -60,6 +62,7 @@ struct __pmdb_t {  	pmpkghash_t *pkgcache;  	alpm_list_t *grpcache;  	alpm_list_t *servers; +	pgp_verify_t pgp_verify;  	struct db_operations *ops;  }; @@ -69,11 +72,12 @@ struct __pmdb_t {  pmdb_t *_alpm_db_new(const char *treename, int is_local);  void _alpm_db_free(pmdb_t *db);  const char *_alpm_db_path(pmdb_t *db); +char *_alpm_db_sig_path(pmdb_t *db);  int _alpm_db_version(pmdb_t *db);  int _alpm_db_cmp(const void *d1, const void *d2);  alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles); -pmdb_t *_alpm_db_register_local(void); -pmdb_t *_alpm_db_register_sync(const char *treename); +pmdb_t *_alpm_db_register_local(pmhandle_t *handle); +pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename);  void _alpm_db_unregister(pmdb_t *db);  /* be_*.c, backend specific calls */ diff --git a/lib/libalpm/delta.c b/lib/libalpm/delta.c index 10c982f2..aa76b492 100644 --- a/lib/libalpm/delta.c +++ b/lib/libalpm/delta.c @@ -41,32 +41,32 @@  const char SYMEXPORT *alpm_delta_get_from(pmdelta_t *delta)  { -	ASSERT(delta != NULL, return(NULL)); -	return(delta->from); +	ASSERT(delta != NULL, return NULL); +	return delta->from;  }  const char SYMEXPORT *alpm_delta_get_to(pmdelta_t *delta)  { -	ASSERT(delta != NULL, return(NULL)); -	return(delta->to); +	ASSERT(delta != NULL, return NULL); +	return delta->to;  }  const char SYMEXPORT *alpm_delta_get_filename(pmdelta_t *delta)  { -	ASSERT(delta != NULL, return(NULL)); -	return(delta->delta); +	ASSERT(delta != NULL, return NULL); +	return delta->delta;  }  const char SYMEXPORT *alpm_delta_get_md5sum(pmdelta_t *delta)  { -	ASSERT(delta != NULL, return(NULL)); -	return(delta->delta_md5); +	ASSERT(delta != NULL, return NULL); +	return delta->delta_md5;  }  off_t SYMEXPORT alpm_delta_get_size(pmdelta_t *delta)  { -	ASSERT(delta != NULL, return(-1)); -	return(delta->delta_size); +	ASSERT(delta != NULL, return -1); +	return delta->delta_size;  }  /** @} */ @@ -78,6 +78,10 @@ static alpm_list_t *graph_init(alpm_list_t *deltas, int reverse)  	/* create the vertices */  	for(i = deltas; i; i = i->next) {  		pmgraph_t *v = _alpm_graph_new(); +		if(!v) { +			alpm_list_free(vertices); +			return NULL; +		}  		pmdelta_t *vdelta = i->data;  		vdelta->download_size = vdelta->delta_size;  		v->weight = LONG_MAX; @@ -108,10 +112,10 @@ static alpm_list_t *graph_init(alpm_list_t *deltas, int reverse)  		}  		v_i->childptr = v_i->children;  	} -	return(vertices); +	return vertices;  } -static void graph_init_size(alpm_list_t *vertices) +static void graph_init_size(pmhandle_t *handle, alpm_list_t *vertices)  {  	alpm_list_t *i; @@ -121,7 +125,7 @@ static void graph_init_size(alpm_list_t *vertices)  		pmdelta_t *vdelta = v->data;  		/* determine whether the delta file already exists */ -		fpath = _alpm_filecache_find(vdelta->delta); +		fpath = _alpm_filecache_find(handle, vdelta->delta);  		md5sum = alpm_compute_md5sum(fpath);  		if(fpath && md5sum && strcmp(md5sum, vdelta->delta_md5) == 0) {  			vdelta->download_size = 0; @@ -130,7 +134,7 @@ static void graph_init_size(alpm_list_t *vertices)  		FREE(md5sum);  		/* determine whether a base 'from' file exists */ -		fpath = _alpm_filecache_find(vdelta->from); +		fpath = _alpm_filecache_find(handle, vdelta->from);  		if(fpath) {  			v->weight = vdelta->download_size;  		} @@ -205,12 +209,13 @@ static off_t shortest_path(alpm_list_t *vertices, const char *to, alpm_list_t **  	*path = alpm_list_reverse(rpath);  	alpm_list_free(rpath); -	return(bestsize); +	return bestsize;  }  /** Calculates the shortest path from one version to another.   * The shortest path is defined as the path with the smallest combined   * size, not the length of the path. + * @param handle the context handle   * @param deltas the list of pmdelta_t * objects that a file has   * @param to the file to start the search at   * @param path the pointer to a list location where pmdelta_t * objects that @@ -218,34 +223,32 @@ static off_t shortest_path(alpm_list_t *vertices, const char *to, alpm_list_t **   * possible with the files available.   * @return the size of the path stored, or LONG_MAX if path is unfindable   */ -off_t _alpm_shortest_delta_path(alpm_list_t *deltas, +off_t _alpm_shortest_delta_path(pmhandle_t *handle, alpm_list_t *deltas,  		const char *to, alpm_list_t **path)  {  	alpm_list_t *bestpath = NULL;  	alpm_list_t *vertices;  	off_t bestsize = LONG_MAX; -	ALPM_LOG_FUNC; -  	if(deltas == NULL) {  		*path = NULL; -		return(bestsize); +		return bestsize;  	} -	_alpm_log(PM_LOG_DEBUG, "started delta shortest-path search for '%s'\n", to); +	_alpm_log(handle, PM_LOG_DEBUG, "started delta shortest-path search for '%s'\n", to);  	vertices = graph_init(deltas, 0); -	graph_init_size(vertices); +	graph_init_size(handle, vertices);  	dijkstra(vertices);  	bestsize = shortest_path(vertices, to, &bestpath); -	_alpm_log(PM_LOG_DEBUG, "delta shortest-path search complete : '%jd'\n", (intmax_t)bestsize); +	_alpm_log(handle, PM_LOG_DEBUG, "delta shortest-path search complete : '%jd'\n", (intmax_t)bestsize);  	alpm_list_free_inner(vertices, _alpm_graph_free);  	alpm_list_free(vertices);  	*path = bestpath; -	return(bestsize); +	return bestsize;  }  static alpm_list_t *find_unused(alpm_list_t *deltas, const char *to, off_t quota) @@ -273,7 +276,7 @@ static alpm_list_t *find_unused(alpm_list_t *deltas, const char *to, off_t quota  	}  	alpm_list_free_inner(vertices, _alpm_graph_free);  	alpm_list_free(vertices); -	return(unused); +	return unused;  }  alpm_list_t SYMEXPORT *alpm_pkg_unused_deltas(pmpkg_t *pkg) @@ -283,7 +286,7 @@ alpm_list_t SYMEXPORT *alpm_pkg_unused_deltas(pmpkg_t *pkg)  			alpm_pkg_get_deltas(pkg),  			alpm_pkg_get_filename(pkg),  			pkgsize * MAX_DELTA_RATIO); -	return(unused); +	return unused;  } @@ -308,21 +311,21 @@ pmdelta_t *_alpm_delta_parse(char *line)  	if(regexec(®, line, 0, 0, 0) != 0) {  		/* delta line is invalid, return NULL */  		regfree(®); -		return(NULL); +		return NULL;  	}  	regfree(®); -	CALLOC(delta, 1, sizeof(pmdelta_t), RET_ERR(PM_ERR_MEMORY, NULL)); +	CALLOC(delta, 1, sizeof(pmdelta_t), return NULL);  	tmp2 = tmp;  	tmp = strchr(tmp, ' ');  	*(tmp++) = '\0'; -	STRDUP(delta->delta, tmp2, RET_ERR(PM_ERR_MEMORY, NULL)); +	STRDUP(delta->delta, tmp2, return NULL);  	tmp2 = tmp;  	tmp = strchr(tmp, ' ');  	*(tmp++) = '\0'; -	STRDUP(delta->delta_md5, tmp2, RET_ERR(PM_ERR_MEMORY, NULL)); +	STRDUP(delta->delta_md5, tmp2, return NULL);  	tmp2 = tmp;  	tmp = strchr(tmp, ' '); @@ -332,14 +335,12 @@ pmdelta_t *_alpm_delta_parse(char *line)  	tmp2 = tmp;  	tmp = strchr(tmp, ' ');  	*(tmp++) = '\0'; -	STRDUP(delta->from, tmp2, RET_ERR(PM_ERR_MEMORY, NULL)); +	STRDUP(delta->from, tmp2, return NULL);  	tmp2 = tmp; -	STRDUP(delta->to, tmp2, RET_ERR(PM_ERR_MEMORY, NULL)); - -	_alpm_log(PM_LOG_DEBUG, "delta : %s %s '%jd'\n", delta->from, delta->to, (intmax_t)delta->delta_size); +	STRDUP(delta->to, tmp2, return NULL); -	return(delta); +	return delta;  }  void _alpm_delta_free(pmdelta_t *delta) diff --git a/lib/libalpm/delta.h b/lib/libalpm/delta.h index d7a81c47..d7725f5a 100644 --- a/lib/libalpm/delta.h +++ b/lib/libalpm/delta.h @@ -20,6 +20,8 @@  #ifndef _ALPM_DELTA_H  #define _ALPM_DELTA_H +#include "config.h" /* ensure off_t is correct length */ +  #include <sys/types.h> /* off_t */  #include "alpm.h" @@ -29,19 +31,19 @@ struct __pmdelta_t {  	char *delta;  	/** md5sum of the delta file */  	char *delta_md5; -	/** filesize of the delta file */ -	off_t delta_size;  	/** filename of the 'before' file */  	char *from;  	/** filename of the 'after' file */  	char *to; +	/** filesize of the delta file */ +	off_t delta_size;  	/** download filesize of the delta file */  	off_t download_size;  };  pmdelta_t *_alpm_delta_parse(char *line);  void _alpm_delta_free(pmdelta_t *delta); -off_t _alpm_shortest_delta_path(alpm_list_t *deltas, +off_t _alpm_shortest_delta_path(pmhandle_t *handle, alpm_list_t *deltas,  		const char *to, alpm_list_t **path);  /* max percent of package size to download deltas */ diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index 36d6e1aa..10c0009d 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -35,6 +35,7 @@  #include "package.h"  #include "db.h"  #include "handle.h" +#include "trans.h"  void _alpm_dep_free(pmdepend_t *dep)  { @@ -48,15 +49,13 @@ static pmdepmissing_t *depmiss_new(const char *target, pmdepend_t *dep,  {  	pmdepmissing_t *miss; -	ALPM_LOG_FUNC; +	MALLOC(miss, sizeof(pmdepmissing_t), return NULL); -	MALLOC(miss, sizeof(pmdepmissing_t), RET_ERR(PM_ERR_MEMORY, NULL)); - -	STRDUP(miss->target, target, RET_ERR(PM_ERR_MEMORY, NULL)); +	STRDUP(miss->target, target, return NULL);  	miss->depend = _alpm_dep_dup(dep); -	STRDUP(miss->causingpkg, causingpkg, RET_ERR(PM_ERR_MEMORY, NULL)); +	STRDUP(miss->causingpkg, causingpkg, return NULL); -	return(miss); +	return miss;  }  void _alpm_depmiss_free(pmdepmissing_t *miss) @@ -73,10 +72,10 @@ static int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2)  	alpm_list_t *i;  	for(i = alpm_pkg_get_depends(pkg1); i; i = i->next) {  		if(_alpm_depcmp(pkg2, i->data)) { -			return(1); +			return 1;  		}  	} -	return(0); +	return 0;  }  /* Convert a list of pmpkg_t * to a graph structure, @@ -110,7 +109,7 @@ static alpm_list_t *dep_graph_init(alpm_list_t *targets)  		}  		vertex_i->childptr = vertex_i->children;  	} -	return(vertices); +	return vertices;  }  /* Re-order a list of target packages with respect to their dependencies. @@ -127,20 +126,19 @@ static alpm_list_t *dep_graph_init(alpm_list_t *targets)   * This function returns the new alpm_list_t* target list.   *   */ -alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse) +alpm_list_t *_alpm_sortbydeps(pmhandle_t *handle, +		alpm_list_t *targets, int reverse)  {  	alpm_list_t *newtargs = NULL;  	alpm_list_t *vertices = NULL;  	alpm_list_t *vptr;  	pmgraph_t *vertex; -	ALPM_LOG_FUNC; -  	if(targets == NULL) { -		return(NULL); +		return NULL;  	} -	_alpm_log(PM_LOG_DEBUG, "started sorting dependencies\n"); +	_alpm_log(handle, PM_LOG_DEBUG, "started sorting dependencies\n");  	vertices = dep_graph_init(targets); @@ -153,7 +151,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse)  		while(vertex->childptr && !found) {  			pmgraph_t *nextchild = vertex->childptr->data;  			vertex->childptr = vertex->childptr->next; -			if (nextchild->state == 0) { +			if(nextchild->state == 0) {  				found = 1;  				nextchild->parent = vertex;  				vertex = nextchild; @@ -163,13 +161,13 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse)  				pmpkg_t *childpkg = nextchild->data;  				const char *message; -				_alpm_log(PM_LOG_WARNING, _("dependency cycle detected:\n")); +				_alpm_log(handle, PM_LOG_WARNING, _("dependency cycle detected:\n"));  				if(reverse) {  					message =_("%s will be removed after its %s dependency\n");  				} else {  					message =_("%s will be installed before its %s dependency\n");  				} -				_alpm_log(PM_LOG_WARNING, message, vertexpkg->name, childpkg->name); +				_alpm_log(handle, PM_LOG_WARNING, message, vertexpkg->name, childpkg->name);  			}  		}  		if(!found) { @@ -181,14 +179,14 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse)  				vptr = vptr->next;  				while(vptr) {  					vertex = vptr->data; -					if (vertex->state == 0) break; +					if(vertex->state == 0) break;  					vptr = vptr->next;  				}  			}  		}  	} -	_alpm_log(PM_LOG_DEBUG, "sorting dependencies finished\n"); +	_alpm_log(handle, PM_LOG_DEBUG, "sorting dependencies finished\n");  	if(reverse) {  		/* reverse the order */ @@ -201,12 +199,12 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse)  	alpm_list_free_inner(vertices, _alpm_graph_free);  	alpm_list_free(vertices); -	return(newtargs); +	return newtargs;  } -static int no_dep_version(void) +static int no_dep_version(pmhandle_t *handle)  { -	int flags = alpm_trans_get_flags(); +	int flags = alpm_trans_get_flags(handle);  	return flags != -1 && (flags & PM_TRANS_FLAG_NODEPVERSION);  } @@ -214,7 +212,7 @@ static pmdepend_t *filtered_depend(pmdepend_t *dep, int nodepversion)  {  	if(nodepversion) {  		pmdepend_t *newdep = _alpm_dep_dup(dep); -		ASSERT(newdep, return(dep)); +		ASSERT(newdep, return dep);  		newdep->mod = PM_DEP_MOD_ANY;  		dep = newdep;  	} @@ -235,10 +233,10 @@ static pmpkg_t *find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep)  	for(i = pkgs; i; i = alpm_list_next(i)) {  		pmpkg_t *pkg = i->data;  		if(_alpm_depcmp(pkg, dep)) { -			return(pkg); +			return pkg;  		}  	} -	return(NULL); +	return NULL;  }  /** Find a package satisfying a specified dependency. @@ -250,28 +248,32 @@ static pmpkg_t *find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep)  pmpkg_t SYMEXPORT *alpm_find_satisfier(alpm_list_t *pkgs, const char *depstring)  {  	pmdepend_t *dep = _alpm_splitdep(depstring); +	if(!dep) { +		return NULL; +	}  	pmpkg_t *pkg = find_dep_satisfier(pkgs, dep);  	_alpm_dep_free(dep); -	return(pkg); +	return pkg;  }  /** Checks dependencies and returns missing ones in a list.   * Dependencies can include versions with depmod operators. + * @param handle the context handle   * @param pkglist the list of local packages - * @param reversedeps handles the backward dependencies   * @param remove an alpm_list_t* of packages to be removed   * @param upgrade an alpm_list_t* of packages to be upgraded (remove-then-upgrade) + * @param reversedeps handles the backward dependencies   * @return an alpm_list_t* of pmdepmissing_t pointers.   */ -alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps, -		alpm_list_t *remove, alpm_list_t *upgrade) +alpm_list_t SYMEXPORT *alpm_checkdeps(pmhandle_t *handle, alpm_list_t *pkglist, +		alpm_list_t *remove, alpm_list_t *upgrade, int reversedeps)  {  	alpm_list_t *i, *j;  	alpm_list_t *targets, *dblist = NULL, *modified = NULL;  	alpm_list_t *baddeps = NULL;  	int nodepversion; -	ALPM_LOG_FUNC; +	CHECK_HANDLE(handle, return NULL);  	targets = alpm_list_join(alpm_list_copy(remove), alpm_list_copy(upgrade));  	for(i = pkglist; i; i = i->next) { @@ -284,12 +286,12 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps,  	}  	alpm_list_free(targets); -	nodepversion = no_dep_version(); +	nodepversion = no_dep_version(handle);  	/* look for unsatisfied dependencies of the upgrade list */  	for(i = upgrade; i; i = i->next) {  		pmpkg_t *tp = i->data; -		_alpm_log(PM_LOG_DEBUG, "checkdeps: package %s-%s\n", +		_alpm_log(handle, PM_LOG_DEBUG, "checkdeps: package %s-%s\n",  				alpm_pkg_get_name(tp), alpm_pkg_get_version(tp));  		for(j = alpm_pkg_get_depends(tp); j; j = j->next) { @@ -302,7 +304,7 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps,  				/* Unsatisfied dependency in the upgrade list */  				pmdepmissing_t *miss;  				char *missdepstring = alpm_dep_compute_string(depend); -				_alpm_log(PM_LOG_DEBUG, "checkdeps: missing dependency '%s' for package '%s'\n", +				_alpm_log(handle, PM_LOG_DEBUG, "checkdeps: missing dependency '%s' for package '%s'\n",  						missdepstring, alpm_pkg_get_name(tp));  				free(missdepstring);  				miss = depmiss_new(alpm_pkg_get_name(tp), depend, NULL); @@ -329,7 +331,7 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps,  				   !find_dep_satisfier(dblist, depend)) {  					pmdepmissing_t *miss;  					char *missdepstring = alpm_dep_compute_string(depend); -					_alpm_log(PM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n", +					_alpm_log(handle, PM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n",  							missdepstring, alpm_pkg_get_name(lp));  					free(missdepstring);  					miss = depmiss_new(lp->name, depend, alpm_pkg_get_name(causingpkg)); @@ -343,7 +345,7 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps,  	alpm_list_free(modified);  	alpm_list_free(dblist); -	return(baddeps); +	return baddeps;  }  static int dep_vercmp(const char *version1, pmdepmod_t mod, @@ -364,7 +366,7 @@ static int dep_vercmp(const char *version1, pmdepmod_t mod,  			default: equal = 1; break;  		}  	} -	return(equal); +	return equal;  }  int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep) @@ -380,7 +382,7 @@ int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep)  		satisfy = (strcmp(pkg->name, dep->name) == 0  				&& dep_vercmp(pkg->version, dep->mod, dep->version));  		if(satisfy) { -			return(satisfy); +			return satisfy;  		}  	} @@ -406,7 +408,7 @@ int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep)  		}  	} -	return(satisfy); +	return satisfy;  }  pmdepend_t *_alpm_splitdep(const char *depstring) @@ -415,10 +417,10 @@ pmdepend_t *_alpm_splitdep(const char *depstring)  	const char *ptr, *version = NULL;  	if(depstring == NULL) { -		return(NULL); +		return NULL;  	} -	CALLOC(depend, 1, sizeof(pmdepend_t), RET_ERR(PM_ERR_MEMORY, NULL)); +	CALLOC(depend, 1, sizeof(pmdepend_t), return NULL);  	/* Find a version comparator if one exists. If it does, set the type and  	 * increment the ptr accordingly so we can copy the right strings. */ @@ -444,27 +446,26 @@ pmdepend_t *_alpm_splitdep(const char *depstring)  	}  	/* copy the right parts to the right places */ -	STRNDUP(depend->name, depstring, ptr - depstring, -			RET_ERR(PM_ERR_MEMORY, NULL)); +	STRNDUP(depend->name, depstring, ptr - depstring, return NULL);  	depend->name_hash = _alpm_hash_sdbm(depend->name);  	if(version) { -		STRDUP(depend->version, version, RET_ERR(PM_ERR_MEMORY, NULL)); +		STRDUP(depend->version, version, return NULL);  	} -	return(depend); +	return depend;  }  pmdepend_t *_alpm_dep_dup(const pmdepend_t *dep)  {  	pmdepend_t *newdep; -	CALLOC(newdep, 1, sizeof(pmdepend_t), RET_ERR(PM_ERR_MEMORY, NULL)); +	CALLOC(newdep, 1, sizeof(pmdepend_t), return NULL); -	STRDUP(newdep->name, dep->name, RET_ERR(PM_ERR_MEMORY, NULL)); +	STRDUP(newdep->name, dep->name, return NULL);  	newdep->name_hash = dep->name_hash; -	STRDUP(newdep->version, dep->version, RET_ERR(PM_ERR_MEMORY, NULL)); +	STRDUP(newdep->version, dep->version, return NULL);  	newdep->mod = dep->mod; -	return(newdep); +	return newdep;  }  /* These parameters are messy. We check if this package, given a list of @@ -477,15 +478,15 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets,  	alpm_list_t *i;  	if(_alpm_pkg_find(targets, alpm_pkg_get_name(pkg))) { -		return(0); +		return 0;  	}  	if(!include_explicit) {  		/* see if it was explicitly installed */  		if(alpm_pkg_get_reason(pkg) == PM_PKG_REASON_EXPLICIT) { -			_alpm_log(PM_LOG_DEBUG, "excluding %s -- explicitly installed\n", +			_alpm_log(db->handle, PM_LOG_DEBUG, "excluding %s -- explicitly installed\n",  					alpm_pkg_get_name(pkg)); -			return(0); +			return 0;  		}  	} @@ -499,12 +500,12 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets,  	for(i = _alpm_db_get_pkgcache(db); i; i = i->next) {  		pmpkg_t *lpkg = i->data;  		if(_alpm_dep_edge(lpkg, pkg) && !_alpm_pkg_find(targets, lpkg->name)) { -			return(0); +			return 0;  		}  	}  	/* it's ok to remove */ -	return(1); +	return 1;  }  /** @@ -521,8 +522,6 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit)  {  	alpm_list_t *i, *j; -	ALPM_LOG_FUNC; -  	if(db == NULL || targs == NULL) {  		return;  	} @@ -533,7 +532,7 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit)  			pmpkg_t *deppkg = j->data;  			if(_alpm_dep_edge(pkg, deppkg)  					&& can_remove_package(db, deppkg, targs, include_explicit)) { -				_alpm_log(PM_LOG_DEBUG, "adding '%s' to the targets\n", +				_alpm_log(db->handle, PM_LOG_DEBUG, "adding '%s' to the targets\n",  						alpm_pkg_get_name(deppkg));  				/* add it to the target list */  				targs = alpm_list_add(targs, _alpm_pkg_dup(deppkg)); @@ -545,6 +544,7 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit)  /**   * helper function for resolvedeps: search for dep satisfier in dbs   * + * @param handle the context handle   * @param dep is the dependency to search for   * @param dbs are the databases to search   * @param excluding are the packages to exclude from the search @@ -554,8 +554,8 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit)   *        an error code without prompting   * @return the resolved package   **/ -static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs, -		alpm_list_t *excluding, int prompt) +static pmpkg_t *resolvedep(pmhandle_t *handle, pmdepend_t *dep, +		alpm_list_t *dbs, alpm_list_t *excluding, int prompt)  {  	alpm_list_t *i, *j;  	int ignored = 0; @@ -567,20 +567,20 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs,  	for(i = dbs; i; i = i->next) {  		pmpkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name);  		if(pkg && _alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) { -			if(_alpm_pkg_should_ignore(pkg)) { +			if(_alpm_pkg_should_ignore(handle, pkg)) {  				int install = 0; -				if (prompt) { +				if(prompt) {  					QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg,  							 NULL, NULL, &install);  				} else { -					_alpm_log(PM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version); +					_alpm_log(handle, PM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version);  				}  				if(!install) {  					ignored = 1;  					continue;  				}  			} -			return(pkg); +			return pkg;  		}  	}  	/* 2. satisfiers (skip literals here) */ @@ -589,20 +589,20 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs,  			pmpkg_t *pkg = j->data;  			if(_alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) != 0 &&  			             !_alpm_pkg_find(excluding, pkg->name)) { -				if(_alpm_pkg_should_ignore(pkg)) { +				if(_alpm_pkg_should_ignore(handle, pkg)) {  					int install = 0; -					if (prompt) { +					if(prompt) {  						QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG,  									pkg, NULL, NULL, &install);  					} else { -						_alpm_log(PM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version); +						_alpm_log(handle, PM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version);  					}  					if(!install) {  						ignored = 1;  						continue;  					}  				} -				_alpm_log(PM_LOG_DEBUG, "provider found (%s provides %s)\n", +				_alpm_log(handle, PM_LOG_DEBUG, "provider found (%s provides %s)\n",  						pkg->name, dep->name);  				providers = alpm_list_add(providers, pkg);  				/* keep looking for other providers in the all dbs */ @@ -613,13 +613,13 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs,  	/* first check if one provider is already installed locally */  	for(i = providers; i; i = i->next) {  		pmpkg_t *pkg = i->data; -		if (_alpm_pkghash_find(_alpm_db_get_pkgcache_hash(handle->db_local), pkg->name)) { +		if(_alpm_pkghash_find(_alpm_db_get_pkgcache_hash(handle->db_local), pkg->name)) {  			alpm_list_free(providers); -			return(pkg); +			return pkg;  		}  	}  	count = alpm_list_count(providers); -	if (count >= 1) { +	if(count >= 1) {  		/* default to first provider if there is no QUESTION callback */  		int index = 0;  		if(count > 1) { @@ -630,48 +630,51 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs,  		if(index >= 0 && index < count) {  			pmpkg_t *pkg = alpm_list_getdata(alpm_list_nth(providers, index));  			alpm_list_free(providers); -			return(pkg); +			return pkg;  		}  		alpm_list_free(providers);  		providers = NULL;  	}  	if(ignored) { /* resolvedeps will override these */ -		pm_errno = PM_ERR_PKG_IGNORED; +		handle->pm_errno = PM_ERR_PKG_IGNORED;  	} else { -		pm_errno = PM_ERR_PKG_NOT_FOUND; +		handle->pm_errno = PM_ERR_PKG_NOT_FOUND;  	} -	return(NULL); +	return NULL;  }  /** Find a package satisfying a specified dependency.   * First look for a literal, going through each db one by one. Then look for   * providers. The first satisfier found is returned.   * The dependency can include versions with depmod operators. + * @param handle the context handle   * @param dbs an alpm_list_t* of pmdb_t where the satisfier will be searched   * @param depstring package or provision name, versioned or not   * @return a pmpkg_t* satisfying depstring   */ -pmpkg_t SYMEXPORT *alpm_find_dbs_satisfier(alpm_list_t *dbs, const char *depstring) +pmpkg_t SYMEXPORT *alpm_find_dbs_satisfier(pmhandle_t *handle, +		alpm_list_t *dbs, const char *depstring)  {  	pmdepend_t *dep;  	pmpkg_t *pkg; -	ASSERT(dbs, return(NULL)); +	CHECK_HANDLE(handle, return NULL); +	ASSERT(dbs, RET_ERR(handle, PM_ERR_WRONG_ARGS, NULL));  	dep = _alpm_splitdep(depstring); -	ASSERT(dep, return(NULL)); -	pkg = resolvedep(dep, dbs, NULL, 1); +	ASSERT(dep, return NULL); +	pkg = resolvedep(handle, dep, dbs, NULL, 1);  	_alpm_dep_free(dep); -	return(pkg); +	return pkg;  }  /**   * Computes resolvable dependencies for a given package and adds that package   * and those resolvable dependencies to a list.   * + * @param handle the context handle   * @param localpkgs is the list of local packages - * @param dbs_sync are the sync databases   * @param pkg is the package to resolve   * @param packages is a pointer to a list of packages which will be   *        searched first for any dependency packages needed to complete the @@ -686,7 +689,7 @@ pmpkg_t SYMEXPORT *alpm_find_dbs_satisfier(alpm_list_t *dbs, const char *depstri   *         unresolvable dependency, in which case the [*packages] list will be   *         unmodified by this function   */ -int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pkg, +int _alpm_resolvedeps(pmhandle_t *handle, alpm_list_t *localpkgs, pmpkg_t *pkg,                        alpm_list_t *preferred, alpm_list_t **packages,                        alpm_list_t *remove, alpm_list_t **data)  { @@ -696,10 +699,8 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk  	alpm_list_t *deps = NULL;  	alpm_list_t *packages_copy; -	ALPM_LOG_FUNC; -  	if(_alpm_pkg_find(*packages, pkg->name) != NULL) { -		return(0); +		return 0;  	}  	/* Create a copy of the packages list, so that it can be restored @@ -709,11 +710,11 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk  	   on that list */  	*packages = alpm_list_add(*packages, pkg); -	_alpm_log(PM_LOG_DEBUG, "started resolving dependencies\n"); +	_alpm_log(handle, PM_LOG_DEBUG, "started resolving dependencies\n");  	for(i = alpm_list_last(*packages); i; i = i->next) {  		pmpkg_t *tpkg = i->data;  		targ = alpm_list_add(NULL, tpkg); -		deps = alpm_checkdeps(localpkgs, 0, remove, targ); +		deps = alpm_checkdeps(handle, localpkgs, remove, targ, 0);  		alpm_list_free(targ);  		for(j = deps; j; j = j->next) { @@ -730,12 +731,12 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk  			pmpkg_t *spkg = find_dep_satisfier(preferred, missdep);  			if(!spkg) {  				/* find a satisfier package in the given repositories */ -				spkg = resolvedep(missdep, dbs_sync, *packages, 0); +				spkg = resolvedep(handle, missdep, handle->dbs_sync, *packages, 0);  			}  			if(!spkg) { -				pm_errno = PM_ERR_UNSATISFIED_DEPS; +				handle->pm_errno = PM_ERR_UNSATISFIED_DEPS;  				char *missdepstring = alpm_dep_compute_string(missdep); -				_alpm_log(PM_LOG_WARNING, +				_alpm_log(handle, PM_LOG_WARNING,  						_("cannot resolve \"%s\", a dependency of \"%s\"\n"),  						missdepstring, tpkg->name);  				free(missdepstring); @@ -744,7 +745,7 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk  				}  				ret = -1;  			} else { -				_alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)\n", +				_alpm_log(handle, PM_LOG_DEBUG, "pulling dependency %s (needed by %s)\n",  						alpm_pkg_get_name(spkg), alpm_pkg_get_name(tpkg));  				*packages = alpm_list_add(*packages, spkg);  				_alpm_depmiss_free(miss); @@ -759,68 +760,44 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk  	} else {  		alpm_list_free(packages_copy);  	} -	_alpm_log(PM_LOG_DEBUG, "finished resolving dependencies\n"); -	return(ret); +	_alpm_log(handle, PM_LOG_DEBUG, "finished resolving dependencies\n"); +	return ret;  }  const char SYMEXPORT *alpm_miss_get_target(const pmdepmissing_t *miss)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(miss != NULL, return(NULL)); - -	return(miss->target); +	ASSERT(miss != NULL, return NULL); +	return miss->target;  }  const char SYMEXPORT *alpm_miss_get_causingpkg(const pmdepmissing_t *miss)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(miss != NULL, return(NULL)); - +	ASSERT(miss != NULL, return NULL);  	return miss->causingpkg;  }  pmdepend_t SYMEXPORT *alpm_miss_get_dep(pmdepmissing_t *miss)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(miss != NULL, return(NULL)); - -	return(miss->depend); +	ASSERT(miss != NULL, return NULL); +	return miss->depend;  }  pmdepmod_t SYMEXPORT alpm_dep_get_mod(const pmdepend_t *dep)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(dep != NULL, return(-1)); - -	return(dep->mod); +	ASSERT(dep != NULL, return -1); +	return dep->mod;  }  const char SYMEXPORT *alpm_dep_get_name(const pmdepend_t *dep)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(dep != NULL, return(NULL)); - -	return(dep->name); +	ASSERT(dep != NULL, return NULL); +	return dep->name;  }  const char SYMEXPORT *alpm_dep_get_version(const pmdepend_t *dep)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(dep != NULL, return(NULL)); - -	return(dep->version); +	ASSERT(dep != NULL, return NULL); +	return dep->version;  }  /** Reverse of splitdep; make a dep string from a pmdepend_t struct. @@ -834,10 +811,7 @@ char SYMEXPORT *alpm_dep_compute_string(const pmdepend_t *dep)  	char *str;  	size_t len; -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(dep != NULL, return(NULL)); +	ASSERT(dep != NULL, return NULL);  	if(dep->name) {  		name = dep->name; @@ -879,9 +853,9 @@ char SYMEXPORT *alpm_dep_compute_string(const pmdepend_t *dep)  	 * and ver will be empty when PM_DEP_MOD_ANY is the depend type. the  	 * reassignments above also ensure we do not do a strlen(NULL). */  	len = strlen(name) + strlen(opr) + strlen(ver) + 1; -	MALLOC(str, len, RET_ERR(PM_ERR_MEMORY, NULL)); +	MALLOC(str, len, return NULL);  	snprintf(str, len, "%s%s%s", name, opr, ver); -	return(str); +	return str;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h index f728cad0..97c0918e 100644 --- a/lib/libalpm/deps.h +++ b/lib/libalpm/deps.h @@ -45,9 +45,9 @@ struct __pmdepmissing_t {  void _alpm_dep_free(pmdepend_t *dep);  pmdepend_t *_alpm_dep_dup(const pmdepend_t *dep);  void _alpm_depmiss_free(pmdepmissing_t *miss); -alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse); +alpm_list_t *_alpm_sortbydeps(pmhandle_t *handle, alpm_list_t *targets, int reverse);  void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit); -int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pkg, +int _alpm_resolvedeps(pmhandle_t *handle, alpm_list_t *localpkgs, pmpkg_t *pkg,  		alpm_list_t *preferred, alpm_list_t **packages, alpm_list_t *remove,  		alpm_list_t **data);  pmdepend_t *_alpm_splitdep(const char *depstring); diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c index 066107d7..079e683e 100644 --- a/lib/libalpm/diskspace.c +++ b/lib/libalpm/diskspace.c @@ -56,10 +56,10 @@ static int mount_point_cmp(const void *p1, const void *p2)  	const alpm_mountpoint_t *mp1 = p1;  	const alpm_mountpoint_t *mp2 = p2;  	/* the negation will sort all mountpoints before their parent */ -	return(-strcmp(mp1->mount_dir, mp2->mount_dir)); +	return -strcmp(mp1->mount_dir, mp2->mount_dir);  } -static alpm_list_t *mount_point_list(void) +static alpm_list_t *mount_point_list(pmhandle_t *handle)  {  	alpm_list_t *mount_points = NULL, *ptr;  	alpm_mountpoint_t *mp; @@ -71,23 +71,23 @@ static alpm_list_t *mount_point_list(void)  	fp = setmntent(MOUNTED, "r"); -	if (fp == NULL) { -		return(NULL); +	if(fp == NULL) { +		return NULL;  	}  	while((mnt = getmntent(fp))) {  		if(!mnt) { -			_alpm_log(PM_LOG_WARNING, _("could not get filesystem information\n")); +			_alpm_log(handle, PM_LOG_WARNING, _("could not get filesystem information\n"));  			continue;  		}  		if(statvfs(mnt->mnt_dir, &fsp) != 0) { -			_alpm_log(PM_LOG_WARNING, +			_alpm_log(handle, PM_LOG_WARNING,  					_("could not get filesystem information for %s: %s\n"),  					mnt->mnt_dir, strerror(errno));  			continue;  		} -		CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(PM_ERR_MEMORY, NULL)); +		CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, PM_ERR_MEMORY, NULL));  		mp->mount_dir = strdup(mnt->mnt_dir);  		mp->mount_dir_len = strlen(mp->mount_dir);  		memcpy(&(mp->fsp), &fsp, sizeof(struct statvfs)); @@ -103,8 +103,8 @@ static alpm_list_t *mount_point_list(void)  	entries = getmntinfo(&fsp, MNT_NOWAIT); -	if (entries < 0) { -		return(NULL); +	if(entries < 0) { +		return NULL;  	}  	for(; entries-- > 0; fsp++) { @@ -126,9 +126,9 @@ static alpm_list_t *mount_point_list(void)  			mount_point_cmp);  	for(ptr = mount_points; ptr != NULL; ptr = ptr->next) {  		mp = ptr->data; -		_alpm_log(PM_LOG_DEBUG, "mountpoint: %s\n", mp->mount_dir); +		_alpm_log(handle, PM_LOG_DEBUG, "mountpoint: %s\n", mp->mount_dir);  	} -	return(mount_points); +	return mount_points;  }  static alpm_mountpoint_t *match_mount_point(const alpm_list_t *mount_points, @@ -140,16 +140,16 @@ static alpm_mountpoint_t *match_mount_point(const alpm_list_t *mount_points,  		alpm_mountpoint_t *data = mp->data;  		if(strncmp(data->mount_dir, real_path, data->mount_dir_len) == 0) { -			return(data); +			return data;  		}  	}  	/* should not get here... */ -	return(NULL); +	return NULL;  } -static int calculate_removed_size(const alpm_list_t *mount_points, -		pmpkg_t *pkg) +static int calculate_removed_size(pmhandle_t *handle, +		const alpm_list_t *mount_points, pmpkg_t *pkg)  {  	alpm_list_t *file; @@ -171,7 +171,7 @@ static int calculate_removed_size(const alpm_list_t *mount_points,  		mp = match_mount_point(mount_points, path);  		if(mp == NULL) { -			_alpm_log(PM_LOG_WARNING, +			_alpm_log(handle, PM_LOG_WARNING,  					_("could not determine mount point for file %s\n"), filename);  			continue;  		} @@ -182,18 +182,18 @@ static int calculate_removed_size(const alpm_list_t *mount_points,  		mp->used |= USED_REMOVE;  	} -	return(0); +	return 0;  } -static int calculate_installed_size(const alpm_list_t *mount_points, -		pmpkg_t *pkg) +static int calculate_installed_size(pmhandle_t *handle, +		const alpm_list_t *mount_points, pmpkg_t *pkg)  {  	int ret=0;  	struct archive *archive;  	struct archive_entry *entry; -	if ((archive = archive_read_new()) == NULL) { -		pm_errno = PM_ERR_LIBARCHIVE; +	if((archive = archive_read_new()) == NULL) { +		handle->pm_errno = PM_ERR_LIBARCHIVE;  		ret = -1;  		goto cleanup;  	} @@ -203,7 +203,7 @@ static int calculate_installed_size(const alpm_list_t *mount_points,  	if(archive_read_open_filename(archive, pkg->origin_data.file,  				ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { -		pm_errno = PM_ERR_PKG_OPEN; +		handle->pm_errno = PM_ERR_PKG_OPEN;  		ret = -1;  		goto cleanup;  	} @@ -226,14 +226,14 @@ static int calculate_installed_size(const alpm_list_t *mount_points,  		/* approximate space requirements for db entries */  		if(filename[0] == '.') { -			filename = alpm_option_get_dbpath(); +			filename = alpm_option_get_dbpath(handle);  		}  		snprintf(path, PATH_MAX, "%s%s", handle->root, filename);  		mp = match_mount_point(mount_points, path);  		if(mp == NULL) { -			_alpm_log(PM_LOG_WARNING, +			_alpm_log(handle, PM_LOG_WARNING,  					_("could not determine mount point for file %s\n"), filename);  			continue;  		} @@ -244,9 +244,9 @@ static int calculate_installed_size(const alpm_list_t *mount_points,  		mp->used |= USED_INSTALL;  		if(archive_read_data_skip(archive)) { -			_alpm_log(PM_LOG_ERROR, _("error while reading package %s: %s\n"), +			_alpm_log(handle, PM_LOG_ERROR, _("error while reading package %s: %s\n"),  					pkg->name, archive_error_string(archive)); -			pm_errno = PM_ERR_LIBARCHIVE; +			handle->pm_errno = PM_ERR_LIBARCHIVE;  			break;  		}  	} @@ -254,28 +254,29 @@ static int calculate_installed_size(const alpm_list_t *mount_points,  	archive_read_finish(archive);  cleanup: -	return(ret); +	return ret;  } -int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local) +int _alpm_check_diskspace(pmhandle_t *handle)  {  	alpm_list_t *mount_points, *i;  	alpm_mountpoint_t *root_mp;  	size_t replaces = 0, current = 0, numtargs;  	int abort = 0;  	alpm_list_t *targ; +	pmtrans_t *trans = handle->trans;  	numtargs = alpm_list_count(trans->add); -	mount_points = mount_point_list(); +	mount_points = mount_point_list(handle);  	if(mount_points == NULL) { -		_alpm_log(PM_LOG_ERROR, _("could not determine filesystem mount points\n")); -		return(-1); +		_alpm_log(handle, PM_LOG_ERROR, _("could not determine filesystem mount points\n")); +		return -1;  	}  	root_mp = match_mount_point(mount_points, handle->root);  	if(root_mp == NULL) { -		_alpm_log(PM_LOG_ERROR, _("could not determine root mount point %s\n"), +		_alpm_log(handle, PM_LOG_ERROR, _("could not determine root mount point %s\n"),  				handle->root); -		return(-1); +		return -1;  	}  	replaces = alpm_list_count(trans->remove); @@ -288,7 +289,7 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local)  					numtargs, current);  			local_pkg = targ->data; -			calculate_removed_size(mount_points, local_pkg); +			calculate_removed_size(handle, mount_points, local_pkg);  		}  	} @@ -300,11 +301,11 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local)  		pkg = targ->data;  		/* is this package already installed? */ -		local_pkg = _alpm_db_get_pkgfromcache(db_local, pkg->name); +		local_pkg = _alpm_db_get_pkgfromcache(handle->db_local, pkg->name);  		if(local_pkg) { -			calculate_removed_size(mount_points, local_pkg); +			calculate_removed_size(handle, mount_points, local_pkg);  		} -		calculate_installed_size(mount_points, pkg); +		calculate_installed_size(handle, mount_points, pkg);  		for(i = mount_points; i; i = alpm_list_next(i)) {  			alpm_mountpoint_t *data = i->data; @@ -320,7 +321,7 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local)  	for(i = mount_points; i; i = alpm_list_next(i)) {  		alpm_mountpoint_t *data = i->data;  		if(data->used && data->read_only) { -			_alpm_log(PM_LOG_ERROR, _("Partition %s is mounted read only\n"), +			_alpm_log(handle, PM_LOG_ERROR, _("Partition %s is mounted read only\n"),  					data->mount_dir);  			abort = 1;  		} else if(data->used & USED_INSTALL) { @@ -329,12 +330,12 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local)  			long twentymb = (20 * 1024 * 1024 / (long)data->fsp.f_bsize) + 1;  			long cushion = fivepc < twentymb ? fivepc : twentymb; -			_alpm_log(PM_LOG_DEBUG, "partition %s, needed %ld, cushion %ld, free %ld\n", +			_alpm_log(handle, PM_LOG_DEBUG, "partition %s, needed %ld, cushion %ld, free %ld\n",  					data->mount_dir, data->max_blocks_needed, cushion,  					(unsigned long)data->fsp.f_bfree);  			if(data->max_blocks_needed + cushion >= 0 &&  			   (unsigned long)(data->max_blocks_needed + cushion) > data->fsp.f_bfree) { -				_alpm_log(PM_LOG_ERROR, _("Partition %s too full: %ld blocks needed, %ld blocks free\n"), +				_alpm_log(handle, PM_LOG_ERROR, _("Partition %s too full: %ld blocks needed, %ld blocks free\n"),  						data->mount_dir, data->max_blocks_needed + cushion,  						(unsigned long)data->fsp.f_bfree);  				abort = 1; @@ -349,10 +350,10 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local)  	FREELIST(mount_points);  	if(abort) { -		RET_ERR(PM_ERR_DISK_SPACE, -1); +		RET_ERR(handle, PM_ERR_DISK_SPACE, -1);  	} -	return(0); +	return 0;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/diskspace.h b/lib/libalpm/diskspace.h index 2894a0c2..28aca7e9 100644 --- a/lib/libalpm/diskspace.h +++ b/lib/libalpm/diskspace.h @@ -46,7 +46,7 @@ typedef struct __alpm_mountpoint_t {  	FSSTATSTYPE fsp;  } alpm_mountpoint_t; -int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local); +int _alpm_check_diskspace(pmhandle_t *handle);  #endif /* _ALPM_DISKSPACE_H */ diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index a98d84ac..93545624 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -29,14 +29,9 @@  #include <sys/types.h>  #include <sys/stat.h>  #include <signal.h> -/* the following two are needed for FreeBSD's libfetch */ -#include <limits.h> /* PATH_MAX */ -#if defined(HAVE_SYS_PARAM_H) -#include <sys/param.h> /* MAXHOSTNAMELEN */ -#endif -#ifdef HAVE_LIBFETCH -#include <fetch.h> +#ifdef HAVE_LIBCURL +#include <curl/curl.h>  #endif  /* libalpm */ @@ -47,112 +42,185 @@  #include "util.h"  #include "handle.h" -static char *get_filename(const char *url) { +#ifdef HAVE_LIBCURL +static double prevprogress; /* last download amount */ +#endif + +static const char *get_filename(const char *url) +{  	char *filename = strrchr(url, '/');  	if(filename != NULL) {  		filename++;  	} -	return(filename); +	return filename;  } -#ifdef HAVE_LIBFETCH -static char *get_destfile(const char *path, const char *filename) { -	char *destfile; -	/* len = localpath len + filename len + null */ -	size_t len = strlen(path) + strlen(filename) + 1; -	CALLOC(destfile, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL)); -	snprintf(destfile, len, "%s%s", path, filename); +#ifdef HAVE_LIBCURL +static char *get_fullpath(const char *path, const char *filename, +		const char *suffix) +{ +	char *filepath; +	/* len = localpath len + filename len + suffix len + null */ +	size_t len = strlen(path) + strlen(filename) + strlen(suffix) + 1; +	CALLOC(filepath, len, sizeof(char), return NULL); +	snprintf(filepath, len, "%s%s%s", path, filename, suffix); -	return(destfile); +	return filepath;  } -static char *get_tempfile(const char *path, const char *filename) { -	char *tempfile; -	/* len = localpath len + filename len + '.part' len + null */ -	size_t len = strlen(path) + strlen(filename) + 6; -	CALLOC(tempfile, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL)); -	snprintf(tempfile, len, "%s%s.part", path, filename); +#define check_stop() if(dload_interrupted) { ret = -1; goto cleanup; } +enum sighandlers { OLD = 0, NEW = 1 }; -	return(tempfile); +static int dload_interrupted; +static void inthandler(int UNUSED signum) +{ +	dload_interrupted = 1;  } -static const char *gethost(struct url *fileurl) +static int curl_progress(void *file, double dltotal, double dlnow, +		double UNUSED ultotal, double UNUSED ulnow)  { -	const char *host = _("disk"); -	if(strcmp(SCHEME_FILE, fileurl->scheme) != 0) { -		host = fileurl->host; +	struct fileinfo *dlfile = (struct fileinfo *)file; +	double current_size, total_size; + +	/* SIGINT sent, abort by alerting curl */ +	if(dload_interrupted) { +		return 1; +	} + +	/* none of what follows matters if the front end has no callback */ +	if(dlfile->handle->dlcb == NULL) { +		return 0; +	} + +	current_size = dlfile->initial_size + dlnow; +	total_size = dlfile->initial_size + dltotal; + +	if(DOUBLE_EQ(dltotal, 0) || DOUBLE_EQ(prevprogress, total_size)) { +		return 0; +	} + +	/* initialize the progress bar here to avoid displaying it when +	 * a repo is up to date and nothing gets downloaded */ +	if(DOUBLE_EQ(prevprogress, 0)) { +		dlfile->handle->dlcb(dlfile->filename, 0, (long)dltotal);  	} -	return(host); + +	dlfile->handle->dlcb(dlfile->filename, (long)current_size, (long)total_size); + +	prevprogress = current_size; + +	return 0;  } -int dload_interrupted; -static void inthandler(int signum) +static int curl_gethost(const char *url, char *buffer)  { -	dload_interrupted = 1; +	size_t hostlen; +	char *p; + +	if(strncmp(url, "file://", 7) == 0) { +		strcpy(buffer, _("disk")); +	} else { +		p = strstr(url, "//"); +		if(!p) { +			return 1; +		} +		p += 2; /* jump over the found // */ +		hostlen = strcspn(p, "/"); +		if(hostlen > 255) { +			/* buffer overflow imminent */ +			return 1; +		} +		snprintf(buffer, hostlen + 1, "%s", p); +	} + +	return 0;  } -#define check_stop() if(dload_interrupted) { ret = -1; goto cleanup; } -enum sighandlers { OLD = 0, NEW = 1 }; +static int utimes_long(const char *path, long time) +{ +	if(time != -1) { +		struct timeval tv[2]; +		memset(&tv, 0, sizeof(tv)); +		tv[0].tv_sec = tv[1].tv_sec = time; +		return utimes(path, tv); +	} +	return 0; +} -static int download_internal(const char *url, const char *localpath, -		int force) { + +static int curl_download_internal(pmhandle_t *handle, +		const char *url, const char *localpath, +		int force, int allow_resume, int errors_ok) +{ +	int ret = -1;  	FILE *localf = NULL; +	const char *useragent; +	const char *open_mode = "wb"; +	char *destfile, *tempfile; +	/* RFC1123 states applications should support this length */ +	char hostname[256]; +	char error_buffer[CURL_ERROR_SIZE];  	struct stat st; -	int ret = 0; -	off_t dl_thisfile = 0; -	ssize_t nread = 0; -	char *tempfile, *destfile, *filename; +	long timecond, remote_time; +	double remote_size, bytes_dl;  	struct sigaction sig_pipe[2], sig_int[2]; - -	off_t local_size = 0; -	time_t local_time = 0; - -	struct url *fileurl; -	struct url_stat ust; -	fetchIO *dlf = NULL; - -	char buffer[PM_DLBUF_LEN]; - -	filename = get_filename(url); -	if(!filename) { -		_alpm_log(PM_LOG_ERROR, _("url '%s' is invalid\n"), url); -		RET_ERR(PM_ERR_SERVER_BAD_URL, -1); +	struct fileinfo dlfile; + +	dlfile.handle = handle; +	dlfile.initial_size = 0.0; +	dlfile.filename = get_filename(url); +	if(!dlfile.filename || curl_gethost(url, hostname) != 0) { +		_alpm_log(handle, PM_LOG_ERROR, _("url '%s' is invalid\n"), url); +		RET_ERR(handle, PM_ERR_SERVER_BAD_URL, -1);  	} -	fileurl = fetchParseURL(url); -	if(!fileurl) { -		_alpm_log(PM_LOG_ERROR, _("url '%s' is invalid\n"), url); -		RET_ERR(PM_ERR_LIBFETCH, -1); +	destfile = get_fullpath(localpath, dlfile.filename, ""); +	tempfile = get_fullpath(localpath, dlfile.filename, ".part"); +	if(!destfile || !tempfile) { +		goto cleanup;  	} -	destfile = get_destfile(localpath, filename); -	tempfile = get_tempfile(localpath, filename); - -	if(stat(tempfile, &st) == 0 && S_ISREG(st.st_mode) && st.st_size > 0) { -		_alpm_log(PM_LOG_DEBUG, "tempfile found, attempting continuation\n"); -		local_time = fileurl->last_modified = st.st_mtime; -		local_size = fileurl->offset = (off_t)st.st_size; -		dl_thisfile = st.st_size; -		localf = fopen(tempfile, "ab"); -	} else if(!force && stat(destfile, &st) == 0 && S_ISREG(st.st_mode) && st.st_size > 0) { -		_alpm_log(PM_LOG_DEBUG, "destfile found, using mtime only\n"); -		local_time = fileurl->last_modified = st.st_mtime; -		local_size = /* no fu->off here */ (off_t)st.st_size; -	} else { -		_alpm_log(PM_LOG_DEBUG, "no file found matching criteria, starting from scratch\n"); +	error_buffer[0] = '\0'; + +	/* the curl_easy handle is initialized with the alpm handle, so we only need +	 * to reset the curl handle set parameters for each time it's used. */ +	curl_easy_reset(handle->curl); +	curl_easy_setopt(handle->curl, CURLOPT_URL, url); +	curl_easy_setopt(handle->curl, CURLOPT_FAILONERROR, 1L); +	curl_easy_setopt(handle->curl, CURLOPT_ERRORBUFFER, error_buffer); +	curl_easy_setopt(handle->curl, CURLOPT_CONNECTTIMEOUT, 10L); +	curl_easy_setopt(handle->curl, CURLOPT_FILETIME, 1L); +	curl_easy_setopt(handle->curl, CURLOPT_NOPROGRESS, 0L); +	curl_easy_setopt(handle->curl, CURLOPT_FOLLOWLOCATION, 1L); +	curl_easy_setopt(handle->curl, CURLOPT_PROGRESSFUNCTION, curl_progress); +	curl_easy_setopt(handle->curl, CURLOPT_PROGRESSDATA, (void *)&dlfile); +	curl_easy_setopt(handle->curl, CURLOPT_LOW_SPEED_LIMIT, 1024L); +	curl_easy_setopt(handle->curl, CURLOPT_LOW_SPEED_TIME, 10L); + +	useragent = getenv("HTTP_USER_AGENT"); +	if(useragent != NULL) { +		curl_easy_setopt(handle->curl, CURLOPT_USERAGENT, useragent);  	} -	/* pass the raw filename for passing to the callback function */ -	_alpm_log(PM_LOG_DEBUG, "using '%s' for download progress\n", filename); +	if(!allow_resume && !force && stat(destfile, &st) == 0) { +		/* start from scratch, but only download if our local is out of date. */ +		curl_easy_setopt(handle->curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); +		curl_easy_setopt(handle->curl, CURLOPT_TIMEVALUE, (long)st.st_mtime); +	} else if(stat(tempfile, &st) == 0 && allow_resume) { +		/* a previous partial download exists, resume from end of file. */ +		open_mode = "ab"; +		curl_easy_setopt(handle->curl, CURLOPT_RESUME_FROM, (long)st.st_size); +		_alpm_log(handle, PM_LOG_DEBUG, "tempfile found, attempting continuation"); +		dlfile.initial_size = (double)st.st_size; +	} -	/* print proxy info for debug purposes */ -	_alpm_log(PM_LOG_DEBUG, "HTTP_PROXY: %s\n", getenv("HTTP_PROXY")); -	_alpm_log(PM_LOG_DEBUG, "http_proxy: %s\n", getenv("http_proxy")); -	_alpm_log(PM_LOG_DEBUG, "FTP_PROXY:  %s\n", getenv("FTP_PROXY")); -	_alpm_log(PM_LOG_DEBUG, "ftp_proxy:  %s\n", getenv("ftp_proxy")); +	localf = fopen(tempfile, open_mode); +	if(localf == NULL) { +		goto cleanup; +	} -	/* 10s timeout */ -	fetchTimeout = 10; +	curl_easy_setopt(handle->curl, CURLOPT_WRITEDATA, localf);  	/* ignore any SIGPIPE signals- these may occur if our FTP socket dies or  	 * something along those lines. Store the old signal handler first. */ @@ -169,168 +237,67 @@ static int download_internal(const char *url, const char *localpath,  	sigaction(SIGINT, NULL, &sig_int[OLD]);  	sigaction(SIGINT, &sig_int[NEW], NULL); -	/* NOTE: libfetch does not reset the error code, be sure to do it before -	 * calls into the library */ - -	/* TODO: if we call fetchStat() and get a redirect (disabling automagic -	 * redirect following), we should repeat the file locator stuff and get a new -	 * filename rather than only base if off the first URL, and then verify -	 * get_filename() didn't return ''. Of course, libfetch might not even allow -	 * us to even get that URL...FS#22645. This would allow us to download things -	 * without totally puking like -	 * http://www.archlinux.org/packages/community/x86_64/exim/download/ */ - -	/* find out the remote size *and* mtime in one go. there is a lot of -	 * trouble in trying to do both size and "if-modified-since" logic in a -	 * non-stat request, so avoid it. */ -	fetchLastErrCode = 0; -	if(fetchStat(fileurl, &ust, "") == -1) { -		pm_errno = PM_ERR_LIBFETCH; -		_alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"), -				filename, gethost(fileurl), fetchLastErrString); -		ret = -1; -		goto cleanup; -	} -	check_stop(); - -	_alpm_log(PM_LOG_DEBUG, "ust.mtime: %ld local_time: %ld compare: %ld\n", -			ust.mtime, local_time, local_time - ust.mtime); -	_alpm_log(PM_LOG_DEBUG, "ust.size: %jd local_size: %jd compare: %jd\n", -			(intmax_t)ust.size, (intmax_t)local_size, (intmax_t)(local_size - ust.size)); -	if(!force && ust.mtime && ust.mtime == local_time -			&& ust.size && ust.size == local_size) { -		/* the remote time and size values agreed with what we have, so move on -		 * because there is nothing more to do. */ -		_alpm_log(PM_LOG_DEBUG, "files are identical, skipping %s\n", filename); -		ret = 1; -		goto cleanup; -	} -	if(!ust.mtime || ust.mtime != local_time) { -		_alpm_log(PM_LOG_DEBUG, "mtimes were different or unavailable, downloading %s from beginning\n", filename); -		fileurl->offset = 0; -	} +	/* Progress 0 - initialize */ +	prevprogress = 0; -	fetchLastErrCode = 0; -	dlf = fetchGet(fileurl, ""); -	check_stop(); +	/* perform transfer */ +	handle->curlerr = curl_easy_perform(handle->curl); -	if(fetchLastErrCode != 0 || dlf == NULL) { -		pm_errno = PM_ERR_LIBFETCH; -		_alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"), -				filename, gethost(fileurl), fetchLastErrString); -		ret = -1; +	/* was it a success? */ +	if(handle->curlerr == CURLE_ABORTED_BY_CALLBACK) {  		goto cleanup; -	} else { -		_alpm_log(PM_LOG_DEBUG, "connected to %s successfully\n", fileurl->host); -	} - -	if(localf && fileurl->offset == 0) { -		_alpm_log(PM_LOG_WARNING, _("resuming download of %s not possible; starting over\n"), filename); -		fclose(localf); -		localf = NULL; -	} else if(fileurl->offset) { -		_alpm_log(PM_LOG_DEBUG, "resuming download at position %jd\n", (intmax_t)fileurl->offset); -	} - - -	if(localf == NULL) { -		_alpm_rmrf(tempfile); -		fileurl->offset = (off_t)0; -		dl_thisfile = 0; -		localf = fopen(tempfile, "wb"); -		if(localf == NULL) { /* still null? */ -			pm_errno = PM_ERR_RETRIEVE; -			_alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"), -					tempfile, strerror(errno)); -			ret = -1; -			goto cleanup; +	} else if(handle->curlerr != CURLE_OK) { +		if(!errors_ok) { +			handle->pm_errno = PM_ERR_LIBCURL; +			_alpm_log(handle, PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"), +					dlfile.filename, hostname, error_buffer); +		} else { +			_alpm_log(handle, PM_LOG_DEBUG, "failed retrieving file '%s' from %s : %s\n", +					dlfile.filename, hostname, error_buffer);  		} +		unlink(tempfile); +		goto cleanup;  	} -	/* Progress 0 - initialize */ -	if(handle->dlcb) { -		handle->dlcb(filename, 0, ust.size); -	} - -	while((nread = fetchIO_read(dlf, buffer, PM_DLBUF_LEN)) > 0) { -		check_stop(); -		size_t nwritten = 0; -		nwritten = fwrite(buffer, 1, (size_t)nread, localf); -		if((nwritten != (size_t)nread) || ferror(localf)) { -			pm_errno = PM_ERR_RETRIEVE; -			_alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"), -					tempfile, strerror(errno)); -			ret = -1; -			goto cleanup; -		} -		dl_thisfile += nread; - -		if(handle->dlcb) { -			handle->dlcb(filename, dl_thisfile, ust.size); -		} -	} +	/* retrieve info about the state of the transfer */ +	curl_easy_getinfo(handle->curl, CURLINFO_FILETIME, &remote_time); +	curl_easy_getinfo(handle->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &remote_size); +	curl_easy_getinfo(handle->curl, CURLINFO_SIZE_DOWNLOAD, &bytes_dl); +	curl_easy_getinfo(handle->curl, CURLINFO_CONDITION_UNMET, &timecond); -	/* did the transfer complete normally? */ -	if (nread == -1) { -		/* not PM_ERR_LIBFETCH here because libfetch error string might be empty */ -		pm_errno = PM_ERR_RETRIEVE; -		_alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s\n"), -				filename, gethost(fileurl)); -		ret = -1; +	/* time condition was met and we didn't download anything. we need to +	 * clean up the 0 byte .part file that's left behind. */ +	if(timecond == 1 && DOUBLE_EQ(bytes_dl, 0)) { +		ret = 1; +		unlink(tempfile);  		goto cleanup;  	} -	if (ust.size != -1 && dl_thisfile < ust.size) { -		pm_errno = PM_ERR_RETRIEVE; -		_alpm_log(PM_LOG_ERROR, _("%s appears to be truncated: %jd/%jd bytes\n"), -				filename, (intmax_t)dl_thisfile, (intmax_t)ust.size); -		ret = -1; +	/* remote_size isn't necessarily the full size of the file, just what the +	 * server reported as remaining to download. compare it to what curl reported +	 * as actually being transferred during curl_easy_perform() */ +	if(!DOUBLE_EQ(remote_size, -1) && !DOUBLE_EQ(bytes_dl, -1) && +			!DOUBLE_EQ(bytes_dl, remote_size)) { +		handle->pm_errno = PM_ERR_RETRIEVE; +		_alpm_log(handle, PM_LOG_ERROR, _("%s appears to be truncated: %jd/%jd bytes\n"), +				dlfile.filename, (intmax_t)bytes_dl, (intmax_t)remote_size);  		goto cleanup;  	} -	/* probably safer to close the file descriptors now before renaming the file, -	 * for example to make sure the buffers are flushed. -	 */ -	fclose(localf); -	localf = NULL; -	fetchIO_close(dlf); -	dlf = NULL; - -	/* set the times on the file to the same as that of the remote file */ -	if(ust.mtime) { -		struct timeval tv[2]; -		memset(&tv, 0, sizeof(tv)); -		tv[0].tv_sec = ust.atime; -		tv[1].tv_sec = ust.mtime; -		utimes(tempfile, tv); -	} -	if(rename(tempfile, destfile)) { -		_alpm_log(PM_LOG_ERROR, _("could not rename %s to %s (%s)\n"), -				tempfile, destfile, strerror(errno)); -		ret = -1; -	}  	ret = 0;  cleanup: -	FREE(tempfile); -	FREE(destfile);  	if(localf != NULL) { -		/* if we still had a local file open, we got interrupted. set the mtimes on -		 * the file accordingly. */ -		fflush(localf); -		if(ust.mtime) { -			struct timeval tv[2]; -			memset(&tv, 0, sizeof(tv)); -			tv[0].tv_sec = ust.atime; -			tv[1].tv_sec = ust.mtime; -			futimes(fileno(localf), tv); -		}  		fclose(localf); +		utimes_long(tempfile, remote_time);  	} -	if(dlf != NULL) { -		fetchIO_close(dlf); + +	if(ret == 0) { +		rename(tempfile, destfile);  	} -	fetchFreeURL(fileurl); + +	FREE(tempfile); +	FREE(destfile);  	/* restore the old signal handlers */  	sigaction(SIGINT, &sig_int[OLD], NULL); @@ -340,106 +307,76 @@ cleanup:  		raise(SIGINT);  	} -	return(ret); +	return ret;  }  #endif -static int download(const char *url, const char *localpath, -		int force) { +int _alpm_download(pmhandle_t *handle, const char *url, const char *localpath, +		int force, int allow_resume, int errors_ok) +{  	if(handle->fetchcb == NULL) { -#ifdef HAVE_LIBFETCH -		return(download_internal(url, localpath, force)); +#ifdef HAVE_LIBCURL +		return curl_download_internal(handle, url, localpath, +				force, allow_resume, errors_ok);  #else -		RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1); +		RET_ERR(handle, PM_ERR_EXTERNAL_DOWNLOAD, -1);  #endif  	} else {  		int ret = handle->fetchcb(url, localpath, force); -		if(ret == -1) { -			RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1); +		if(ret == -1 && !errors_ok) { +			RET_ERR(handle, PM_ERR_EXTERNAL_DOWNLOAD, -1);  		} -		return(ret); +		return ret;  	}  } -/* - * Download a single file - *   - servers must be a list of urls WITHOUT trailing slashes. - * - * RETURN:  0 for successful download - *          1 if the files are identical - *         -1 on error - */ -int _alpm_download_single_file(const char *filename, -		alpm_list_t *servers, const char *localpath, -		int force) -{ -	alpm_list_t *i; -	int ret = -1; - -	ASSERT(servers != NULL, RET_ERR(PM_ERR_SERVER_NONE, -1)); - -	for(i = servers; i; i = i->next) { -		const char *server = i->data; -		char *fileurl = NULL; -		size_t len; - -		/* print server + filename into a buffer */ -		len = strlen(server) + strlen(filename) + 2; -		CALLOC(fileurl, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1)); -		snprintf(fileurl, len, "%s/%s", server, filename); - -		ret = download(fileurl, localpath, force); -		FREE(fileurl); -		if(ret != -1) { -			break; -		} -	} - -	return(ret); -} - -int _alpm_download_files(alpm_list_t *files, -		alpm_list_t *servers, const char *localpath) -{ -	int ret = 0; -	alpm_list_t *lp; - -	for(lp = files; lp; lp = lp->next) { -		char *filename = lp->data; -		if(_alpm_download_single_file(filename, servers, -					localpath, 0) == -1) { -			ret++; -		} -	} - -	return(ret); -} -  /** Fetch a remote pkg. */ -char SYMEXPORT *alpm_fetch_pkgurl(const char *url) +char SYMEXPORT *alpm_fetch_pkgurl(pmhandle_t *handle, const char *url)  { -	char *filename, *filepath; -	const char *cachedir; +	char *filepath; +	const char *filename, *cachedir;  	int ret; -	ALPM_LOG_FUNC; +	CHECK_HANDLE(handle, return NULL);  	filename = get_filename(url);  	/* find a valid cache dir to download to */ -	cachedir = _alpm_filecache_setup(); +	cachedir = _alpm_filecache_setup(handle);  	/* download the file */ -	ret = download(url, cachedir, 0); +	ret = _alpm_download(handle, url, cachedir, 0, 1, 0);  	if(ret == -1) { -		_alpm_log(PM_LOG_WARNING, _("failed to download %s\n"), url); -		return(NULL); +		_alpm_log(handle, PM_LOG_WARNING, _("failed to download %s\n"), url); +		return NULL; +	} +	_alpm_log(handle, PM_LOG_DEBUG, "successfully downloaded %s\n", url); + +	/* attempt to download the signature */ +	if(ret == 0 && (handle->sigverify == PM_PGP_VERIFY_ALWAYS || +				handle->sigverify == PM_PGP_VERIFY_OPTIONAL)) { +		char *sig_url; +		size_t len; +		int errors_ok = (handle->sigverify == PM_PGP_VERIFY_OPTIONAL); + +		len = strlen(url) + 5; +		CALLOC(sig_url, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, NULL)); +		snprintf(sig_url, len, "%s.sig", url); + +		ret = _alpm_download(handle, sig_url, cachedir, 1, 0, errors_ok); +		if(ret == -1 && !errors_ok) { +			_alpm_log(handle, PM_LOG_WARNING, _("failed to download %s\n"), sig_url); +			/* Warn now, but don't return NULL. We will fail later during package +			 * load time. */ +		} else if(ret == 0) { +			_alpm_log(handle, PM_LOG_DEBUG, "successfully downloaded %s\n", sig_url); +		} +		FREE(sig_url);  	} -	_alpm_log(PM_LOG_DEBUG, "successfully downloaded %s\n", url);  	/* we should be able to find the file the second time around */ -	filepath = _alpm_filecache_find(filename); -	return(filepath); +	filepath = _alpm_filecache_find(handle, filename); +	return filepath;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/dload.h b/lib/libalpm/dload.h index 63266491..e409c32b 100644 --- a/lib/libalpm/dload.h +++ b/lib/libalpm/dload.h @@ -25,14 +25,15 @@  #include <time.h> -#define PM_DLBUF_LEN (1024 * 16) +/* internal structure for communicating with curl progress callback */ +struct fileinfo { +	pmhandle_t *handle; +	const char *filename; +	double initial_size; +}; -int _alpm_download_single_file(const char *filename, -		alpm_list_t *servers, const char *localpath, -		int force); - -int _alpm_download_files(alpm_list_t *files, -		alpm_list_t *servers, const char *localpath); +int _alpm_download(pmhandle_t *handle, const char *url, const char *localpath, +		int force, int allow_resume, int errors_ok);  #endif /* _ALPM_DLOAD_H */ diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c index 21fbb48f..d893f866 100644 --- a/lib/libalpm/error.c +++ b/lib/libalpm/error.c @@ -20,28 +20,21 @@  #include "config.h" -/* TODO: needed for the libfetch stuff, unfortunately- we should kill it */ -#include <stdio.h> -/* the following two are needed for FreeBSD's libfetch */ -#include <limits.h> /* PATH_MAX */ -#if defined(HAVE_SYS_PARAM_H) -#include <sys/param.h> /* MAXHOSTNAMELEN */ -#endif - -#ifdef HAVE_LIBFETCH -#include <fetch.h> /* fetchLastErrString */ +#ifdef HAVE_LIBCURL +#include <curl/curl.h>  #endif  /* libalpm */  #include "util.h"  #include "alpm.h" +#include "handle.h" -const char SYMEXPORT *alpm_strerrorlast(void) +enum _pmerrno_t SYMEXPORT alpm_errno(pmhandle_t *handle)  { -	return alpm_strerror(pm_errno); +	return handle->pm_errno;  } -const char SYMEXPORT *alpm_strerror(int err) +const char SYMEXPORT *alpm_strerror(enum _pmerrno_t err)  {  	switch(err) {  		/* System */ @@ -122,6 +115,13 @@ const char SYMEXPORT *alpm_strerror(int err)  			return _("package architecture is not valid");  		case PM_ERR_PKG_REPO_NOT_FOUND:  			return _("could not find repository for target"); +		/* Signatures */ +		case PM_ERR_SIG_MISSINGDIR: +			return _("signature directory not configured correctly"); +		case PM_ERR_SIG_INVALID: +			return _("invalid PGP signature"); +		case PM_ERR_SIG_UNKNOWN: +			return _("unknown PGP signature");  		/* Deltas */  		case PM_ERR_DLT_INVALID:  			return _("invalid or corrupted delta"); @@ -137,8 +137,6 @@ const char SYMEXPORT *alpm_strerror(int err)  		/* Miscellaenous */  		case PM_ERR_RETRIEVE:  			return _("failed to retrieve some files"); -		case PM_ERR_WRITE: -			return _("failed to copy some file");  		case PM_ERR_INVALID_REGEX:  			return _("invalid regular expression");  		/* Errors from external libraries- our own wrapper error */ @@ -147,13 +145,10 @@ const char SYMEXPORT *alpm_strerror(int err)  			 * requires the archive struct, so we can't. Just use a generic  			 * error string instead. */  			return _("libarchive error"); -		case PM_ERR_LIBFETCH: -#ifdef HAVE_LIBFETCH -			return fetchLastErrString; -#else -			/* obviously shouldn't get here... */ +		case PM_ERR_LIBCURL:  			return _("download library error"); -#endif +		case PM_ERR_GPGME: +			return _("gpgme error");  		case PM_ERR_EXTERNAL_DOWNLOAD:  			return _("error invoking external downloader");  		/* Unknown error! */ diff --git a/lib/libalpm/graph.c b/lib/libalpm/graph.c new file mode 100644 index 00000000..fc2c9e16 --- /dev/null +++ b/lib/libalpm/graph.c @@ -0,0 +1,41 @@ +/* + *  graph.c - helpful graph structure and setup/teardown methods + * + *  Copyright (c) 2007-2011 Pacman Development Team <pacman-dev@archlinux.org> + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "graph.h" +#include "util.h" +#include "log.h" + +pmgraph_t *_alpm_graph_new(void) +{ +	pmgraph_t *graph = NULL; + +	CALLOC(graph, 1, sizeof(pmgraph_t), return NULL); +	return graph; +} + +void _alpm_graph_free(void *data) +{ +	pmgraph_t *graph = data; +	alpm_list_free(graph->children); +	free(graph); +} + +/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/graph.h b/lib/libalpm/graph.h index 07986f66..f76c6004 100644 --- a/lib/libalpm/graph.h +++ b/lib/libalpm/graph.h @@ -1,8 +1,7 @@  /*   *  graph.h - helpful graph structure and setup/teardown methods   * - *  Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org> - *  Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> + *  Copyright (c) 2007-2011 Pacman Development Team <pacman-dev@archlinux.org>   *   *  This program is free software; you can redistribute it and/or modify   *  it under the terms of the GNU General Public License as published by @@ -17,34 +16,27 @@   *  You should have received a copy of the GNU General Public License   *  along with this program.  If not, see <http://www.gnu.org/licenses/>.   */ +#ifndef _ALPM_GRAPH_H +#define _ALPM_GRAPH_H + +#include "config.h" /* ensure off_t is correct length */  #include <sys/types.h> /* off_t */  #include "alpm_list.h" -#include "util.h" /* CALLOC() */ -struct __pmgraph_t { +typedef struct __pmgraph_t {  	char state; /* 0: untouched, -1: entered, other: leaving time */ -	void *data;  	off_t weight; /* weight of the node */ +	void *data;  	struct __pmgraph_t *parent; /* where did we come from? */  	alpm_list_t *children;  	alpm_list_t *childptr; /* points to a child in children list */ -}; -typedef struct __pmgraph_t pmgraph_t; - -static pmgraph_t *_alpm_graph_new(void) -{ -	pmgraph_t *graph = NULL; +} pmgraph_t; -	CALLOC(graph, 1, sizeof(pmgraph_t), RET_ERR(PM_ERR_MEMORY, NULL)); -	return(graph); -} +pmgraph_t *_alpm_graph_new(void); +void _alpm_graph_free(void *data); -static void _alpm_graph_free(void *data) -{ -	pmgraph_t *graph = data; -	alpm_list_free(graph->children); -	free(graph); -} +#endif /* _ALPM_GRAPH_H */ +/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/group.c b/lib/libalpm/group.c index 398c2588..13a216ee 100644 --- a/lib/libalpm/group.c +++ b/lib/libalpm/group.c @@ -21,7 +21,6 @@  #include "config.h"  #include <stdlib.h> -#include <stdio.h>  #include <string.h>  /* libalpm */ @@ -35,18 +34,14 @@ pmgrp_t *_alpm_grp_new(const char *name)  {  	pmgrp_t* grp; -	ALPM_LOG_FUNC; +	CALLOC(grp, 1, sizeof(pmgrp_t), return NULL); +	STRDUP(grp->name, name, free(grp); return NULL); -	CALLOC(grp, 1, sizeof(pmgrp_t), RET_ERR(PM_ERR_MEMORY, NULL)); -	STRDUP(grp->name, name, RET_ERR(PM_ERR_MEMORY, NULL)); - -	return(grp); +	return grp;  }  void _alpm_grp_free(pmgrp_t *grp)  { -	ALPM_LOG_FUNC; -  	if(grp == NULL) {  		return;  	} @@ -59,21 +54,14 @@ void _alpm_grp_free(pmgrp_t *grp)  const char SYMEXPORT *alpm_grp_get_name(const pmgrp_t *grp)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(grp != NULL, return(NULL)); - +	ASSERT(grp != NULL, return NULL);  	return grp->name;  }  alpm_list_t SYMEXPORT *alpm_grp_get_pkgs(const pmgrp_t *grp)  { -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(grp != NULL, return(NULL)); - +	ASSERT(grp != NULL, return NULL);  	return grp->packages;  } +  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index 586aad1e..d2bb4f61 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -27,9 +27,7 @@  #include <limits.h>  #include <sys/types.h>  #include <syslog.h> -#include <time.h>  #include <sys/stat.h> -#include <errno.h>  /* libalpm */  #include "handle.h" @@ -39,22 +37,19 @@  #include "trans.h"  #include "alpm.h" -/* global var for handle (private to libalpm) */ -pmhandle_t *handle = NULL; -  pmhandle_t *_alpm_handle_new()  {  	pmhandle_t *handle; -	CALLOC(handle, 1, sizeof(pmhandle_t), RET_ERR(PM_ERR_MEMORY, NULL)); +	CALLOC(handle, 1, sizeof(pmhandle_t), return NULL); + +	handle->sigverify = PM_PGP_VERIFY_OPTIONAL; -	return(handle); +	return handle;  }  void _alpm_handle_free(pmhandle_t *handle)  { -	ALPM_LOG_FUNC; -  	if(handle == NULL) {  		return;  	} @@ -69,6 +64,11 @@ void _alpm_handle_free(pmhandle_t *handle)  		closelog();  	} +#ifdef HAVE_LIBCURL +	/* release curl handle */ +	curl_easy_cleanup(handle->curl); +#endif +  	/* free memory */  	_alpm_trans_free(handle->trans);  	FREE(handle->root); @@ -77,6 +77,7 @@ void _alpm_handle_free(pmhandle_t *handle)  	FREE(handle->logfile);  	FREE(handle->lockfile);  	FREE(handle->arch); +	FREE(handle->signaturedir);  	FREELIST(handle->dbs_sync);  	FREELIST(handle->noupgrade);  	FREELIST(handle->noextract); @@ -85,336 +86,240 @@ void _alpm_handle_free(pmhandle_t *handle)  	FREE(handle);  } -alpm_cb_log SYMEXPORT alpm_option_get_logcb() +alpm_cb_log SYMEXPORT alpm_option_get_logcb(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->logcb;  } -alpm_cb_download SYMEXPORT alpm_option_get_dlcb() +alpm_cb_download SYMEXPORT alpm_option_get_dlcb(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->dlcb;  } -alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb() +alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->fetchcb;  } -alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb() +alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->totaldlcb;  } -const char SYMEXPORT *alpm_option_get_root() +const char SYMEXPORT *alpm_option_get_root(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->root;  } -const char SYMEXPORT *alpm_option_get_dbpath() +const char SYMEXPORT *alpm_option_get_dbpath(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->dbpath;  } -alpm_list_t SYMEXPORT *alpm_option_get_cachedirs() +alpm_list_t SYMEXPORT *alpm_option_get_cachedirs(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->cachedirs;  } -const char SYMEXPORT *alpm_option_get_logfile() +const char SYMEXPORT *alpm_option_get_logfile(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->logfile;  } -const char SYMEXPORT *alpm_option_get_lockfile() +const char SYMEXPORT *alpm_option_get_lockfile(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->lockfile;  } -int SYMEXPORT alpm_option_get_usesyslog() +const char SYMEXPORT *alpm_option_get_signaturedir(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return -1; -	} +	CHECK_HANDLE(handle, return NULL); +	return handle->signaturedir; +} + +int SYMEXPORT alpm_option_get_usesyslog(pmhandle_t *handle) +{ +	CHECK_HANDLE(handle, return -1);  	return handle->usesyslog;  } -alpm_list_t SYMEXPORT *alpm_option_get_noupgrades() +alpm_list_t SYMEXPORT *alpm_option_get_noupgrades(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->noupgrade;  } -alpm_list_t SYMEXPORT *alpm_option_get_noextracts() +alpm_list_t SYMEXPORT *alpm_option_get_noextracts(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->noextract;  } -alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs() +alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->ignorepkg;  } -alpm_list_t SYMEXPORT *alpm_option_get_ignoregrps() +alpm_list_t SYMEXPORT *alpm_option_get_ignoregrps(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->ignoregrp;  } -const char SYMEXPORT *alpm_option_get_arch() +const char SYMEXPORT *alpm_option_get_arch(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->arch;  } -int SYMEXPORT alpm_option_get_usedelta() +int SYMEXPORT alpm_option_get_usedelta(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return -1; -	} +	CHECK_HANDLE(handle, return -1);  	return handle->usedelta;  } -int SYMEXPORT alpm_option_get_checkspace() +int SYMEXPORT alpm_option_get_checkspace(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return -1; -	} +	CHECK_HANDLE(handle, return -1);  	return handle->checkspace;  } -pmdb_t SYMEXPORT *alpm_option_get_localdb() +pmdb_t SYMEXPORT *alpm_option_get_localdb(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->db_local;  } -alpm_list_t SYMEXPORT *alpm_option_get_syncdbs() +alpm_list_t SYMEXPORT *alpm_option_get_syncdbs(pmhandle_t *handle)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return NULL; -	} +	CHECK_HANDLE(handle, return NULL);  	return handle->dbs_sync;  } -void SYMEXPORT alpm_option_set_logcb(alpm_cb_log cb) +int SYMEXPORT alpm_option_set_logcb(pmhandle_t *handle, alpm_cb_log cb)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return; -	} +	CHECK_HANDLE(handle, return -1);  	handle->logcb = cb; +	return 0;  } -void SYMEXPORT alpm_option_set_dlcb(alpm_cb_download cb) +int SYMEXPORT alpm_option_set_dlcb(pmhandle_t *handle, alpm_cb_download cb)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return; -	} +	CHECK_HANDLE(handle, return -1);  	handle->dlcb = cb; +	return 0;  } -void SYMEXPORT alpm_option_set_fetchcb(alpm_cb_fetch cb) +int SYMEXPORT alpm_option_set_fetchcb(pmhandle_t *handle, alpm_cb_fetch cb)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return; -	} +	CHECK_HANDLE(handle, return -1);  	handle->fetchcb = cb; +	return 0;  } -void SYMEXPORT alpm_option_set_totaldlcb(alpm_cb_totaldl cb) +int SYMEXPORT alpm_option_set_totaldlcb(pmhandle_t *handle, alpm_cb_totaldl cb)  { -	if (handle == NULL) { -		pm_errno = PM_ERR_HANDLE_NULL; -		return; -	} +	CHECK_HANDLE(handle, return -1);  	handle->totaldlcb = cb; +	return 0;  } -int SYMEXPORT alpm_option_set_root(const char *root) -{ -	struct stat st; -	char *realroot; -	size_t rootlen; - -	ALPM_LOG_FUNC; - -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +static char *canonicalize_path(const char *path) { +	char *new_path; +	size_t len; -	if(!root) { -		pm_errno = PM_ERR_WRONG_ARGS; -		return(-1); +	/* verify path ends in a '/' */ +	len = strlen(path); +	if(path[len - 1] != '/') { +		len += 1;  	} -	if(stat(root, &st) == -1 || !S_ISDIR(st.st_mode)) { -		pm_errno = PM_ERR_NOT_A_DIR; -		return(-1); -	} - -	realroot = calloc(PATH_MAX+1, sizeof(char)); -	if(!realpath(root, realroot)) { -		FREE(realroot); -		pm_errno = PM_ERR_NOT_A_DIR; -		return(-1); -	} - -	/* verify root ends in a '/' */ -	rootlen = strlen(realroot); -	if(realroot[rootlen-1] != '/') { -		rootlen += 1; -	} -	if(handle->root) { -		FREE(handle->root); -	} -	handle->root = calloc(rootlen + 1, sizeof(char)); -	strncpy(handle->root, realroot, rootlen); -	handle->root[rootlen-1] = '/'; -	FREE(realroot); -	_alpm_log(PM_LOG_DEBUG, "option 'root' = %s\n", handle->root); -	return(0); +	new_path = calloc(len + 1, sizeof(char)); +	strncpy(new_path, path, len); +	new_path[len - 1] = '/'; +	return new_path;  } -int SYMEXPORT alpm_option_set_dbpath(const char *dbpath) -{ +enum _pmerrno_t _alpm_set_directory_option(const char *value, +		char **storage, int must_exist) + {  	struct stat st; -	size_t dbpathlen, lockfilelen; -	const char *lf = "db.lck"; - -	ALPM_LOG_FUNC; +	char *real = NULL; +	const char *path; -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); -	if(!dbpath) { -		pm_errno = PM_ERR_WRONG_ARGS; -		return(-1); -	} -	if(stat(dbpath, &st) == -1 || !S_ISDIR(st.st_mode)) { -		pm_errno = PM_ERR_NOT_A_DIR; -		return(-1); -	} -	/* verify dbpath ends in a '/' */ -	dbpathlen = strlen(dbpath); -	if(dbpath[dbpathlen-1] != '/') { -		dbpathlen += 1; +	path = value; +	if(!path) { +		return PM_ERR_WRONG_ARGS;  	} -	if(handle->dbpath) { -		FREE(handle->dbpath); +	if(must_exist) { +		if(stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) { +			return PM_ERR_NOT_A_DIR; +		} +		real = calloc(PATH_MAX, sizeof(char)); +		if(!realpath(path, real)) { +			free(real); +			return PM_ERR_NOT_A_DIR; +		} +		path = real;  	} -	handle->dbpath = calloc(dbpathlen+1, sizeof(char)); -	strncpy(handle->dbpath, dbpath, dbpathlen); -	handle->dbpath[dbpathlen-1] = '/'; -	_alpm_log(PM_LOG_DEBUG, "option 'dbpath' = %s\n", handle->dbpath); -	if(handle->lockfile) { -		FREE(handle->lockfile); +	if(*storage) { +		FREE(*storage);  	} -	lockfilelen = strlen(handle->dbpath) + strlen(lf) + 1; -	handle->lockfile = calloc(lockfilelen, sizeof(char)); -	snprintf(handle->lockfile, lockfilelen, "%s%s", handle->dbpath, lf); -	_alpm_log(PM_LOG_DEBUG, "option 'lockfile' = %s\n", handle->lockfile); -	return(0); +	*storage = canonicalize_path(path); +	free(real); +	return 0;  } -int SYMEXPORT alpm_option_add_cachedir(const char *cachedir) +int SYMEXPORT alpm_option_add_cachedir(pmhandle_t *handle, const char *cachedir)  {  	char *newcachedir; -	size_t cachedirlen; - -	ALPM_LOG_FUNC; -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1);  	if(!cachedir) { -		pm_errno = PM_ERR_WRONG_ARGS; -		return(-1); +		handle->pm_errno = PM_ERR_WRONG_ARGS; +		return -1;  	}  	/* don't stat the cachedir yet, as it may not even be needed. we can  	 * fail later if it is needed and the path is invalid. */ -	/* verify cachedir ends in a '/' */ -	cachedirlen = strlen(cachedir); -	if(cachedir[cachedirlen-1] != '/') { -		cachedirlen += 1; -	} -	newcachedir = calloc(cachedirlen + 1, sizeof(char)); -	strncpy(newcachedir, cachedir, cachedirlen); -	newcachedir[cachedirlen-1] = '/'; +	newcachedir = canonicalize_path(cachedir);  	handle->cachedirs = alpm_list_add(handle->cachedirs, newcachedir); -	_alpm_log(PM_LOG_DEBUG, "option 'cachedir' = %s\n", newcachedir); -	return(0); +	_alpm_log(handle, PM_LOG_DEBUG, "option 'cachedir' = %s\n", newcachedir); +	return 0;  } -void SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs) +int SYMEXPORT alpm_option_set_cachedirs(pmhandle_t *handle, alpm_list_t *cachedirs)  { -	ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); -	if(handle->cachedirs) FREELIST(handle->cachedirs); -	if(cachedirs) handle->cachedirs = cachedirs; +	alpm_list_t *i; +	CHECK_HANDLE(handle, return -1); +	if(handle->cachedirs) { +		FREELIST(handle->cachedirs); +	} +	for(i = cachedirs; i; i = i->next) { +		int ret = alpm_option_add_cachedir(handle, i->data); +		if(ret) { +			return ret; +		} +	} +	return 0;  } -int SYMEXPORT alpm_option_remove_cachedir(const char *cachedir) +int SYMEXPORT alpm_option_remove_cachedir(pmhandle_t *handle, const char *cachedir)  {  	char *vdata = NULL;  	char *newcachedir;  	size_t cachedirlen; -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1);  	/* verify cachedir ends in a '/' */  	cachedirlen = strlen(cachedir);  	if(cachedir[cachedirlen-1] != '/') { @@ -427,21 +332,19 @@ int SYMEXPORT alpm_option_remove_cachedir(const char *cachedir)  	FREE(newcachedir);  	if(vdata != NULL) {  		FREE(vdata); -		return(1); +		return 1;  	} -	return(0); +	return 0;  } -int SYMEXPORT alpm_option_set_logfile(const char *logfile) +int SYMEXPORT alpm_option_set_logfile(pmhandle_t *handle, const char *logfile)  {  	char *oldlogfile = handle->logfile; -	ALPM_LOG_FUNC; - -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1);  	if(!logfile) { -		pm_errno = PM_ERR_WRONG_ARGS; -		return(-1); +		handle->pm_errno = PM_ERR_WRONG_ARGS; +		return -1;  	}  	handle->logfile = strdup(logfile); @@ -455,133 +358,180 @@ int SYMEXPORT alpm_option_set_logfile(const char *logfile)  		fclose(handle->logstream);  		handle->logstream = NULL;  	} -	_alpm_log(PM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile); -	return(0); +	_alpm_log(handle, PM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile); +	return 0; +} + +int SYMEXPORT alpm_option_set_signaturedir(pmhandle_t *handle, const char *signaturedir) +{ +	CHECK_HANDLE(handle, return -1); +	if(!signaturedir) { +		handle->pm_errno = PM_ERR_WRONG_ARGS; +		return -1; +	} + +	if(handle->signaturedir) { +		FREE(handle->signaturedir); +	} +	handle->signaturedir = strdup(signaturedir); + +	_alpm_log(handle, PM_LOG_DEBUG, "option 'signaturedir' = %s\n", handle->signaturedir); +	return 0;  } -void SYMEXPORT alpm_option_set_usesyslog(int usesyslog) +int SYMEXPORT alpm_option_set_usesyslog(pmhandle_t *handle, int usesyslog)  { -	ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); +	CHECK_HANDLE(handle, return -1);  	handle->usesyslog = usesyslog; +	return 0;  } -void SYMEXPORT alpm_option_add_noupgrade(const char *pkg) +int SYMEXPORT alpm_option_add_noupgrade(pmhandle_t *handle, const char *pkg)  { -	ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); +	CHECK_HANDLE(handle, return -1);  	handle->noupgrade = alpm_list_add(handle->noupgrade, strdup(pkg)); +	return 0;  } -void SYMEXPORT alpm_option_set_noupgrades(alpm_list_t *noupgrade) +int SYMEXPORT alpm_option_set_noupgrades(pmhandle_t *handle, alpm_list_t *noupgrade)  { -	ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); +	CHECK_HANDLE(handle, return -1);  	if(handle->noupgrade) FREELIST(handle->noupgrade); -	if(noupgrade) handle->noupgrade = noupgrade; +	handle->noupgrade = alpm_list_strdup(noupgrade); +	return 0;  } -int SYMEXPORT alpm_option_remove_noupgrade(const char *pkg) +int SYMEXPORT alpm_option_remove_noupgrade(pmhandle_t *handle, const char *pkg)  {  	char *vdata = NULL; -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1);  	handle->noupgrade = alpm_list_remove_str(handle->noupgrade, pkg, &vdata);  	if(vdata != NULL) {  		FREE(vdata); -		return(1); +		return 1;  	} -	return(0); +	return 0;  } -void SYMEXPORT alpm_option_add_noextract(const char *pkg) +int SYMEXPORT alpm_option_add_noextract(pmhandle_t *handle, const char *pkg)  { -	ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); +	CHECK_HANDLE(handle, return -1);  	handle->noextract = alpm_list_add(handle->noextract, strdup(pkg)); +	return 0;  } -void SYMEXPORT alpm_option_set_noextracts(alpm_list_t *noextract) +int SYMEXPORT alpm_option_set_noextracts(pmhandle_t *handle, alpm_list_t *noextract)  { -	ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); +	CHECK_HANDLE(handle, return -1);  	if(handle->noextract) FREELIST(handle->noextract); -	if(noextract) handle->noextract = noextract; +	handle->noextract = alpm_list_strdup(noextract); +	return 0;  } -int SYMEXPORT alpm_option_remove_noextract(const char *pkg) +int SYMEXPORT alpm_option_remove_noextract(pmhandle_t *handle, const char *pkg)  {  	char *vdata = NULL; -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1);  	handle->noextract = alpm_list_remove_str(handle->noextract, pkg, &vdata);  	if(vdata != NULL) {  		FREE(vdata); -		return(1); +		return 1;  	} -	return(0); +	return 0;  } -void SYMEXPORT alpm_option_add_ignorepkg(const char *pkg) +int SYMEXPORT alpm_option_add_ignorepkg(pmhandle_t *handle, const char *pkg)  { -	ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); +	CHECK_HANDLE(handle, return -1);  	handle->ignorepkg = alpm_list_add(handle->ignorepkg, strdup(pkg)); +	return 0;  } -void SYMEXPORT alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs) +int SYMEXPORT alpm_option_set_ignorepkgs(pmhandle_t *handle, alpm_list_t *ignorepkgs)  { -	ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); +	CHECK_HANDLE(handle, return -1);  	if(handle->ignorepkg) FREELIST(handle->ignorepkg); -	if(ignorepkgs) handle->ignorepkg = ignorepkgs; +	handle->ignorepkg = alpm_list_strdup(ignorepkgs); +	return 0;  } -int SYMEXPORT alpm_option_remove_ignorepkg(const char *pkg) +int SYMEXPORT alpm_option_remove_ignorepkg(pmhandle_t *handle, const char *pkg)  {  	char *vdata = NULL; -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1);  	handle->ignorepkg = alpm_list_remove_str(handle->ignorepkg, pkg, &vdata);  	if(vdata != NULL) {  		FREE(vdata); -		return(1); +		return 1;  	} -	return(0); +	return 0;  } -void SYMEXPORT alpm_option_add_ignoregrp(const char *grp) +int SYMEXPORT alpm_option_add_ignoregrp(pmhandle_t *handle, const char *grp)  { -	ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); +	CHECK_HANDLE(handle, return -1);  	handle->ignoregrp = alpm_list_add(handle->ignoregrp, strdup(grp)); +	return 0;  } -void SYMEXPORT alpm_option_set_ignoregrps(alpm_list_t *ignoregrps) +int SYMEXPORT alpm_option_set_ignoregrps(pmhandle_t *handle, alpm_list_t *ignoregrps)  { -	ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); +	CHECK_HANDLE(handle, return -1);  	if(handle->ignoregrp) FREELIST(handle->ignoregrp); -	if(ignoregrps) handle->ignoregrp = ignoregrps; +	handle->ignoregrp = alpm_list_strdup(ignoregrps); +	return 0;  } -int SYMEXPORT alpm_option_remove_ignoregrp(const char *grp) +int SYMEXPORT alpm_option_remove_ignoregrp(pmhandle_t *handle, const char *grp)  {  	char *vdata = NULL; -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1);  	handle->ignoregrp = alpm_list_remove_str(handle->ignoregrp, grp, &vdata);  	if(vdata != NULL) {  		FREE(vdata); -		return(1); +		return 1;  	} -	return(0); +	return 0;  } -void SYMEXPORT alpm_option_set_arch(const char *arch) +int SYMEXPORT alpm_option_set_arch(pmhandle_t *handle, const char *arch)  { -	ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); +	CHECK_HANDLE(handle, return -1);  	if(handle->arch) FREE(handle->arch); -	if(arch) handle->arch = strdup(arch); +	if(arch) { +		handle->arch = strdup(arch); +	} else { +		handle->arch = NULL; +	} +	return 0;  } -void SYMEXPORT alpm_option_set_usedelta(int usedelta) +int SYMEXPORT alpm_option_set_usedelta(pmhandle_t *handle, int usedelta)  { -	ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); +	CHECK_HANDLE(handle, return -1);  	handle->usedelta = usedelta; +	return 0;  } -void SYMEXPORT alpm_option_set_checkspace(int checkspace) +int SYMEXPORT alpm_option_set_checkspace(pmhandle_t *handle, int checkspace)  { -	ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); +	CHECK_HANDLE(handle, return -1);  	handle->checkspace = checkspace; +	return 0; +} + +int SYMEXPORT alpm_option_set_default_sigverify(pmhandle_t *handle, pgp_verify_t level) +{ +	CHECK_HANDLE(handle, return -1); +	ASSERT(level != PM_PGP_VERIFY_UNKNOWN, RET_ERR(handle, PM_ERR_WRONG_ARGS, -1)); +	handle->sigverify = level; +	return 0; +} + +pgp_verify_t SYMEXPORT alpm_option_get_default_sigverify(pmhandle_t *handle) +{ +	CHECK_HANDLE(handle, return PM_PGP_VERIFY_UNKNOWN); +	return handle->sigverify;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 2d962fe6..bace8052 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -24,12 +24,13 @@  #include <sys/types.h>  #include "alpm_list.h" -#include "db.h" -#include "log.h"  #include "alpm.h" -#include "trans.h" -typedef struct _pmhandle_t { +#ifdef HAVE_LIBCURL +#include <curl/curl.h> +#endif + +struct __pmhandle_t {  	/* internal usage */  	pmdb_t *db_local;       /* local db pointer */  	alpm_list_t *dbs_sync;  /* List of (pmdb_t *) */ @@ -37,6 +38,12 @@ typedef struct _pmhandle_t {  	FILE *lckstream;        /* lock file stream pointer if one exists */  	pmtrans_t *trans; +#ifdef HAVE_LIBCURL +	/* libcurl handle */ +	CURL *curl;             /* reusable curl_easy handle */ +	CURLcode curlerr;       /* last error produced by curl */ +#endif +  	/* callback functions */  	alpm_cb_log logcb;      /* Log callback function */  	alpm_cb_download dlcb;  /* Download callback function */ @@ -48,6 +55,7 @@ typedef struct _pmhandle_t {  	char *dbpath;            /* Base path to pacman's DBs */  	char *logfile;           /* Name of the log file */  	char *lockfile;          /* Name of the lock file */ +	char *signaturedir;        /* Directory where GnuPG files are stored */  	alpm_list_t *cachedirs;  /* Paths to pacman cache directories */  	/* package lists */ @@ -57,18 +65,22 @@ typedef struct _pmhandle_t {  	alpm_list_t *ignoregrp;   /* List of groups to ignore */  	/* options */ -	int usesyslog;    /* Use syslog instead of logfile? */ /* TODO move to frontend */ -	char *arch;       /* Architecture of packages we should allow */ -	int usedelta;     /* Download deltas if possible */ -	int checkspace;   /* Check disk space before installing */ -} pmhandle_t; +	int usesyslog;           /* Use syslog instead of logfile? */ /* TODO move to frontend */ +	char *arch;              /* Architecture of packages we should allow */ +	int usedelta;            /* Download deltas if possible */ +	int checkspace;          /* Check disk space before installing */ +	pgp_verify_t sigverify;  /* Default signature verification level */ -/* global handle variable */ -extern pmhandle_t *handle; +	/* error code */ +	enum _pmerrno_t pm_errno; +};  pmhandle_t *_alpm_handle_new(void);  void _alpm_handle_free(pmhandle_t *handle); +enum _pmerrno_t _alpm_set_directory_option(const char *value, +		char **storage, int must_exist); +  #endif /* _ALPM_HANDLE_H */  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/log.c b/lib/libalpm/log.c index 09c6fb84..91bcb823 100644 --- a/lib/libalpm/log.c +++ b/lib/libalpm/log.c @@ -22,10 +22,7 @@  #include <stdio.h>  #include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h>  #include <errno.h> -#include <time.h>  /* libalpm */  #include "log.h" @@ -39,18 +36,16 @@   */  /** A printf-like function for logging. + * @param handle the context handle   * @param fmt output format   * @return 0 on success, -1 on error (pm_errno is set accordingly)   */ -int SYMEXPORT alpm_logaction(const char *fmt, ...) +int SYMEXPORT alpm_logaction(pmhandle_t *handle, const char *fmt, ...)  {  	int ret;  	va_list args; -	ALPM_LOG_FUNC; - -	/* Sanity checks */ -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	ASSERT(handle != NULL, return -1);  	/* check if the logstream is open already, opening it if needed */  	if(handle->logstream == NULL) { @@ -58,18 +53,18 @@ int SYMEXPORT alpm_logaction(const char *fmt, ...)  		/* if we couldn't open it, we have an issue */  		if(handle->logstream == NULL) {  			if(errno == EACCES) { -				pm_errno = PM_ERR_BADPERMS; +				handle->pm_errno = PM_ERR_BADPERMS;  			} else if(errno == ENOENT) { -				pm_errno = PM_ERR_NOT_A_DIR; +				handle->pm_errno = PM_ERR_NOT_A_DIR;  			} else { -				pm_errno = PM_ERR_SYSTEM; +				handle->pm_errno = PM_ERR_SYSTEM;  			} -		return(-1); +			return -1;  		}  	}  	va_start(args, fmt); -	ret = _alpm_logaction(handle->usesyslog, handle->logstream, fmt, args); +	ret = _alpm_logaction(handle, fmt, args);  	va_end(args);  	/* TODO	We should add a prefix to log strings depending on who called us. @@ -83,15 +78,15 @@ int SYMEXPORT alpm_logaction(const char *fmt, ...)  	 *   kpacman: "KPACMAN"  	 * This would allow us to share the log file between several frontends  	 * and know who does what */ -	return(ret); +	return ret;  }  /** @} */ -void _alpm_log(pmloglevel_t flag, const char *fmt, ...) +void _alpm_log(pmhandle_t *handle, pmloglevel_t flag, const char *fmt, ...)  {  	va_list args; -	alpm_cb_log logcb = alpm_option_get_logcb(); +	alpm_cb_log logcb = alpm_option_get_logcb(handle);  	if(logcb == NULL) {  		return; diff --git a/lib/libalpm/log.h b/lib/libalpm/log.h index 9a2961fb..105430c4 100644 --- a/lib/libalpm/log.h +++ b/lib/libalpm/log.h @@ -22,14 +22,8 @@  #include "alpm.h" -#ifdef PACMAN_DEBUG -/* Log funtion entry points if debugging is enabled */ -#define ALPM_LOG_FUNC _alpm_log(PM_LOG_FUNCTION, "Enter %s\n", __func__) -#else -#define ALPM_LOG_FUNC -#endif - -void _alpm_log(pmloglevel_t flag, const char *fmt, ...) __attribute__((format(printf,2,3))); +void _alpm_log(pmhandle_t *handle, pmloglevel_t flag, +		const char *fmt, ...) __attribute__((format(printf,3,4)));  #endif /* _ALPM_LOG_H */ diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index f2f15af4..ff011982 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -23,13 +23,9 @@  #include "config.h" -#include <stdio.h>  #include <stdlib.h>  #include <string.h> -#include <ctype.h> -#include <errno.h>  #include <sys/types.h> -#include <sys/stat.h>  /* libalpm */  #include "package.h" @@ -49,16 +45,14 @@  /** Free a package. */  int SYMEXPORT alpm_pkg_free(pmpkg_t *pkg)  { -	ALPM_LOG_FUNC; - -	ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); +	ASSERT(pkg != NULL, return -1);  	/* Only free packages loaded in user space */  	if(pkg->origin == PKG_FROM_FILE) {  		_alpm_pkg_free(pkg);  	} -	return(0); +	return 0;  }  /** Check the integrity (with md5) of a package from the sync cache. */ @@ -67,24 +61,24 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)  	char *fpath;  	int retval; -	ALPM_LOG_FUNC; - -	ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); +	ASSERT(pkg != NULL, return -1); +	pkg->handle->pm_errno = 0;  	/* We only inspect packages from sync repositories */ -	ASSERT(pkg->origin == PKG_FROM_SYNCDB, RET_ERR(PM_ERR_PKG_INVALID, -1)); +	ASSERT(pkg->origin == PKG_FROM_SYNCDB, +			RET_ERR(pkg->handle, PM_ERR_WRONG_ARGS, -1)); -	fpath = _alpm_filecache_find(alpm_pkg_get_filename(pkg)); +	fpath = _alpm_filecache_find(pkg->handle, alpm_pkg_get_filename(pkg));  	retval = _alpm_test_md5sum(fpath, alpm_pkg_get_md5sum(pkg));  	if(retval == 0) { -		return(0); -	} else if (retval == 1) { -		pm_errno = PM_ERR_PKG_INVALID; +		return 0; +	} else if(retval == 1) { +		pkg->handle->pm_errno = PM_ERR_PKG_INVALID;  		retval = -1;  	} -	return(retval); +	return retval;  }  /* Default package accessor functions. These will get overridden by any @@ -92,8 +86,6 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)   * a lazy-load cache. However, the defaults will work just fine for fully-   * populated package structures. */  static const char *_pkg_get_filename(pmpkg_t *pkg)    { return pkg->filename; } -static const char *_pkg_get_name(pmpkg_t *pkg)        { return pkg->name; } -static const char *_pkg_get_version(pmpkg_t *pkg)     { return pkg->version; }  static const char *_pkg_get_desc(pmpkg_t *pkg)        { return pkg->desc; }  static const char *_pkg_get_url(pmpkg_t *pkg)         { return pkg->url; }  static time_t _pkg_get_builddate(pmpkg_t *pkg)        { return pkg->builddate; } @@ -117,17 +109,28 @@ static alpm_list_t *_pkg_get_deltas(pmpkg_t *pkg)     { return pkg->deltas; }  static alpm_list_t *_pkg_get_files(pmpkg_t *pkg)      { return pkg->files; }  static alpm_list_t *_pkg_get_backup(pmpkg_t *pkg)     { return pkg->backup; } -static void *_pkg_changelog_open(pmpkg_t *pkg)        { return NULL; } -static size_t _pkg_changelog_read(void *ptr, size_t size, const pmpkg_t *pkg, const void *fp) { return 0; } -static int _pkg_changelog_close(const pmpkg_t *pkg, void *fp) { return EOF; } +static void *_pkg_changelog_open(pmpkg_t UNUSED *pkg) +{ +	return NULL; +} + +static size_t _pkg_changelog_read(void UNUSED *ptr, size_t UNUSED size, +		const pmpkg_t UNUSED *pkg, const UNUSED void *fp) +{ +	return 0; +} + +static int _pkg_changelog_close(const pmpkg_t UNUSED *pkg, +		void UNUSED *fp) +{ +	return EOF; +}  /** The standard package operations struct. Get fields directly from the   * struct itself with no abstraction layer or any type of lazy loading.   */  struct pkg_operations default_pkg_ops = {  	.get_filename    = _pkg_get_filename, -	.get_name        = _pkg_get_name, -	.get_version     = _pkg_get_version,  	.get_desc        = _pkg_get_desc,  	.get_url         = _pkg_get_url,  	.get_builddate   = _pkg_get_builddate, @@ -161,131 +164,180 @@ struct pkg_operations default_pkg_ops = {   * package, which depend on where the package was loaded from. */  const char SYMEXPORT *alpm_pkg_get_filename(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_filename(pkg);  }  const char SYMEXPORT *alpm_pkg_get_name(pmpkg_t *pkg)  { -	return pkg->ops->get_name(pkg); +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0; +	return pkg->name;  }  const char SYMEXPORT *alpm_pkg_get_version(pmpkg_t *pkg)  { -	return pkg->ops->get_version(pkg); +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0; +	return pkg->version;  }  const char SYMEXPORT *alpm_pkg_get_desc(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_desc(pkg);  }  const char SYMEXPORT *alpm_pkg_get_url(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_url(pkg);  }  time_t SYMEXPORT alpm_pkg_get_builddate(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return -1); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_builddate(pkg);  }  time_t SYMEXPORT alpm_pkg_get_installdate(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return -1); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_installdate(pkg);  }  const char SYMEXPORT *alpm_pkg_get_packager(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_packager(pkg);  }  const char SYMEXPORT *alpm_pkg_get_md5sum(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_md5sum(pkg);  }  const char SYMEXPORT *alpm_pkg_get_arch(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_arch(pkg);  }  off_t SYMEXPORT alpm_pkg_get_size(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return -1); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_size(pkg);  }  off_t SYMEXPORT alpm_pkg_get_isize(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return -1); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_isize(pkg);  }  pmpkgreason_t SYMEXPORT alpm_pkg_get_reason(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return -1); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_reason(pkg);  }  alpm_list_t SYMEXPORT *alpm_pkg_get_licenses(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_licenses(pkg);  }  alpm_list_t SYMEXPORT *alpm_pkg_get_groups(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_groups(pkg);  }  alpm_list_t SYMEXPORT *alpm_pkg_get_depends(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_depends(pkg);  }  alpm_list_t SYMEXPORT *alpm_pkg_get_optdepends(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_optdepends(pkg);  }  alpm_list_t SYMEXPORT *alpm_pkg_get_conflicts(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_conflicts(pkg);  }  alpm_list_t SYMEXPORT *alpm_pkg_get_provides(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_provides(pkg);  }  alpm_list_t SYMEXPORT *alpm_pkg_get_replaces(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_replaces(pkg);  }  alpm_list_t SYMEXPORT *alpm_pkg_get_deltas(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_deltas(pkg);  }  alpm_list_t SYMEXPORT *alpm_pkg_get_files(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_files(pkg);  }  alpm_list_t SYMEXPORT *alpm_pkg_get_backup(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->get_backup(pkg);  }  pmdb_t SYMEXPORT *alpm_pkg_get_db(pmpkg_t *pkg)  {  	/* Sanity checks */ -	ASSERT(pkg != NULL, return(NULL)); -	ASSERT(pkg->origin != PKG_FROM_FILE, return(NULL)); +	ASSERT(pkg != NULL, return NULL); +	ASSERT(pkg->origin != PKG_FROM_FILE, return NULL); +	pkg->handle->pm_errno = 0; -	return(pkg->origin_data.db); +	return pkg->origin_data.db;  }  /** Open a package changelog for reading. */  void SYMEXPORT *alpm_pkg_changelog_open(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0;  	return pkg->ops->changelog_open(pkg);  } @@ -293,6 +345,8 @@ void SYMEXPORT *alpm_pkg_changelog_open(pmpkg_t *pkg)  size_t SYMEXPORT alpm_pkg_changelog_read(void *ptr, size_t size,  		const pmpkg_t *pkg, const void *fp)  { +	ASSERT(pkg != NULL, return 0); +	pkg->handle->pm_errno = 0;  	return pkg->ops->changelog_read(ptr, size, pkg, fp);  } @@ -306,17 +360,23 @@ int SYMEXPORT alpm_pkg_changelog_feof(const pmpkg_t *pkg, void *fp)  /** Close a package changelog for reading. */  int SYMEXPORT alpm_pkg_changelog_close(const pmpkg_t *pkg, void *fp)  { +	ASSERT(pkg != NULL, return -1); +	pkg->handle->pm_errno = 0;  	return pkg->ops->changelog_close(pkg, fp);  }  int SYMEXPORT alpm_pkg_has_scriptlet(pmpkg_t *pkg)  { +	ASSERT(pkg != NULL, return -1); +	pkg->handle->pm_errno = 0;  	return pkg->ops->has_scriptlet(pkg);  }  static void find_requiredby(pmpkg_t *pkg, pmdb_t *db, alpm_list_t **reqs)  {  	const alpm_list_t *i; +	pkg->handle->pm_errno = 0; +  	for(i = _alpm_db_get_pkgcache(db); i; i = i->next) {  		pmpkg_t *cachepkg = i->data;  		alpm_list_t *i; @@ -338,10 +398,12 @@ alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(pmpkg_t *pkg)  	alpm_list_t *reqs = NULL;  	pmdb_t *db; +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0; +  	if(pkg->origin == PKG_FROM_FILE) {  		/* The sane option; search locally for things that require this. */ -		db = alpm_option_get_localdb(); -		find_requiredby(pkg, db, &reqs); +		find_requiredby(pkg, pkg->handle->db_local, &reqs);  	} else {  		/* We have a DB package. if it is a local package, then we should  		 * only search the local DB; else search all known sync databases. */ @@ -349,14 +411,14 @@ alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(pmpkg_t *pkg)  		if(db->is_local) {  			find_requiredby(pkg, db, &reqs);  		} else { -			for(i = handle->dbs_sync; i; i = i->next) { +			for(i = pkg->handle->dbs_sync; i; i = i->next) {  				db = i->data;  				find_requiredby(pkg, db, &reqs);  			}  			reqs = alpm_list_msort(reqs, alpm_list_count(reqs), _alpm_str_cmp);  		}  	} -	return(reqs); +	return reqs;  }  /** @} */ @@ -365,11 +427,9 @@ pmpkg_t *_alpm_pkg_new(void)  {  	pmpkg_t* pkg; -	ALPM_LOG_FUNC; +	CALLOC(pkg, 1, sizeof(pmpkg_t), return NULL); -	CALLOC(pkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL)); - -	return(pkg); +	return pkg;  }  pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg) @@ -377,21 +437,19 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)  	pmpkg_t *newpkg;  	alpm_list_t *i; -	ALPM_LOG_FUNC; - -	CALLOC(newpkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL)); +	CALLOC(newpkg, 1, sizeof(pmpkg_t), goto cleanup);  	newpkg->name_hash = pkg->name_hash; -	STRDUP(newpkg->filename, pkg->filename, RET_ERR(PM_ERR_MEMORY, newpkg)); -	STRDUP(newpkg->name, pkg->name, RET_ERR(PM_ERR_MEMORY, newpkg)); -	STRDUP(newpkg->version, pkg->version, RET_ERR(PM_ERR_MEMORY, newpkg)); -	STRDUP(newpkg->desc, pkg->desc, RET_ERR(PM_ERR_MEMORY, newpkg)); -	STRDUP(newpkg->url, pkg->url, RET_ERR(PM_ERR_MEMORY, newpkg)); +	STRDUP(newpkg->filename, pkg->filename, goto cleanup); +	STRDUP(newpkg->name, pkg->name, goto cleanup); +	STRDUP(newpkg->version, pkg->version, goto cleanup); +	STRDUP(newpkg->desc, pkg->desc, goto cleanup); +	STRDUP(newpkg->url, pkg->url, goto cleanup);  	newpkg->builddate = pkg->builddate;  	newpkg->installdate = pkg->installdate; -	STRDUP(newpkg->packager, pkg->packager, RET_ERR(PM_ERR_MEMORY, newpkg)); -	STRDUP(newpkg->md5sum, pkg->md5sum, RET_ERR(PM_ERR_MEMORY, newpkg)); -	STRDUP(newpkg->arch, pkg->arch, RET_ERR(PM_ERR_MEMORY, newpkg)); +	STRDUP(newpkg->packager, pkg->packager, goto cleanup); +	STRDUP(newpkg->md5sum, pkg->md5sum, goto cleanup); +	STRDUP(newpkg->arch, pkg->arch, goto cleanup);  	newpkg->size = pkg->size;  	newpkg->isize = pkg->isize;  	newpkg->scriptlet = pkg->scriptlet; @@ -411,22 +469,25 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)  	newpkg->deltas     = alpm_list_copy_data(pkg->deltas, sizeof(pmdelta_t));  	/* internal */ +	newpkg->infolevel = pkg->infolevel;  	newpkg->origin = pkg->origin; -	newpkg->ops = pkg->ops;  	if(newpkg->origin == PKG_FROM_FILE) {  		newpkg->origin_data.file = strdup(pkg->origin_data.file);  	} else {  		newpkg->origin_data.db = pkg->origin_data.db;  	} -	newpkg->infolevel = pkg->infolevel; +	newpkg->ops = pkg->ops; +	newpkg->handle = pkg->handle; -	return(newpkg); +	return newpkg; + +cleanup: +	_alpm_pkg_free(newpkg); +	return NULL;  }  void _alpm_pkg_free(pmpkg_t *pkg)  { -	ALPM_LOG_FUNC; -  	if(pkg == NULL) {  		return;  	} @@ -438,6 +499,7 @@ void _alpm_pkg_free(pmpkg_t *pkg)  	FREE(pkg->url);  	FREE(pkg->packager);  	FREE(pkg->md5sum); +	FREE(pkg->base64_sig);  	FREE(pkg->arch);  	FREELIST(pkg->licenses);  	FREELIST(pkg->replaces); @@ -467,8 +529,6 @@ void _alpm_pkg_free(pmpkg_t *pkg)   */  void _alpm_pkg_free_trans(pmpkg_t *pkg)  { -	ALPM_LOG_FUNC; -  	if(pkg == NULL) {  		return;  	} @@ -485,8 +545,6 @@ void _alpm_pkg_free_trans(pmpkg_t *pkg)  /* Is spkg an upgrade for localpkg? */  int _alpm_pkg_compare_versions(pmpkg_t *spkg, pmpkg_t *localpkg)  { -	ALPM_LOG_FUNC; -  	return alpm_pkg_vercmp(alpm_pkg_get_version(spkg),  			alpm_pkg_get_version(localpkg));  } @@ -497,7 +555,7 @@ int _alpm_pkg_cmp(const void *p1, const void *p2)  {  	pmpkg_t *pkg1 = (pmpkg_t *)p1;  	pmpkg_t *pkg2 = (pmpkg_t *)p2; -	return(strcoll(pkg1->name, pkg2->name)); +	return strcoll(pkg1->name, pkg2->name);  }  /* Test for existence of a package in a alpm_list_t* @@ -508,10 +566,8 @@ pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle)  	alpm_list_t *lp;  	unsigned long needle_hash; -	ALPM_LOG_FUNC; -  	if(needle == NULL || haystack == NULL) { -		return(NULL); +		return NULL;  	}  	needle_hash = _alpm_hash_sdbm(needle); @@ -527,11 +583,11 @@ pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle)  			/* finally: we had hash match, verify string match */  			if(strcmp(info->name, needle) == 0) { -				return(info); +				return info;  			}  		}  	} -	return(NULL); +	return NULL;  }  /** Test if a package should be ignored. @@ -539,28 +595,29 @@ pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle)   * Checks if the package is ignored via IgnorePkg, or if the package is   * in a group ignored via IgnoreGrp.   * + * @param handle the context handle   * @param pkg the package to test   *   * @return 1 if the package should be ignored, 0 otherwise   */ -int _alpm_pkg_should_ignore(pmpkg_t *pkg) +int _alpm_pkg_should_ignore(pmhandle_t *handle, pmpkg_t *pkg)  {  	alpm_list_t *groups = NULL;  	/* first see if the package is ignored */  	if(alpm_list_find_str(handle->ignorepkg, alpm_pkg_get_name(pkg))) { -		return(1); +		return 1;  	}  	/* next see if the package is in a group that is ignored */  	for(groups = handle->ignoregrp; groups; groups = alpm_list_next(groups)) {  		char *grp = (char *)alpm_list_getdata(groups);  		if(alpm_list_find_str(alpm_pkg_get_groups(pkg), grp)) { -			return(1); +			return 1;  		}  	} -	return(0); +	return 0;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h index b161d5f1..bc5b2671 100644 --- a/lib/libalpm/package.h +++ b/lib/libalpm/package.h @@ -24,11 +24,14 @@  #ifndef _ALPM_PACKAGE_H  #define _ALPM_PACKAGE_H +#include "config.h" /* ensure off_t is correct length */ +  #include <sys/types.h> /* off_t */  #include <time.h> /* time_t */  #include "alpm.h"  #include "db.h" +#include "signing.h"  typedef enum _pmpkgfrom_t {  	PKG_FROM_FILE = 1, @@ -45,8 +48,6 @@ typedef enum _pmpkgfrom_t {   */  struct pkg_operations {  	const char *(*get_filename) (pmpkg_t *); -	const char *(*get_name) (pmpkg_t *); -	const char *(*get_version) (pmpkg_t *);  	const char *(*get_desc) (pmpkg_t *);  	const char *(*get_url) (pmpkg_t *);  	time_t (*get_builddate) (pmpkg_t *); @@ -96,6 +97,7 @@ struct __pmpkg_t {  	char *url;  	char *packager;  	char *md5sum; +	char *base64_sig;  	char *arch;  	time_t builddate; @@ -108,6 +110,7 @@ struct __pmpkg_t {  	int scriptlet;  	pmpkgreason_t reason; +	pmdbinfrq_t infolevel;  	pmpkgfrom_t origin;  	/* origin == PKG_FROM_FILE, use pkg->origin_data.file  	 * origin == PKG_FROM_*DB, use pkg->origin_data.db */ @@ -115,7 +118,7 @@ struct __pmpkg_t {  		pmdb_t *db;  		char *file;  	} origin_data; -	pmdbinfrq_t infolevel; +	pmhandle_t *handle;  	alpm_list_t *licenses;  	alpm_list_t *replaces; @@ -137,10 +140,16 @@ pmpkg_t* _alpm_pkg_new(void);  pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg);  void _alpm_pkg_free(pmpkg_t *pkg);  void _alpm_pkg_free_trans(pmpkg_t *pkg); + + +pmpkg_t *_alpm_pkg_load_internal(pmhandle_t *handle, const char *pkgfile, +		int full, const char *md5sum, const char *base64_sig, +		pgp_verify_t check_sig); +  int _alpm_pkg_cmp(const void *p1, const void *p2);  int _alpm_pkg_compare_versions(pmpkg_t *local_pkg, pmpkg_t *pkg);  pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle); -int _alpm_pkg_should_ignore(pmpkg_t *pkg); +int _alpm_pkg_should_ignore(pmhandle_t *handle, pmpkg_t *pkg);  #endif /* _ALPM_PACKAGE_H */ diff --git a/lib/libalpm/pkghash.c b/lib/libalpm/pkghash.c index 6dc43243..9e98fcd8 100644 --- a/lib/libalpm/pkghash.c +++ b/lib/libalpm/pkghash.c @@ -17,9 +17,10 @@   *  along with this program.  If not, see <http://www.gnu.org/licenses/>.   */ +#include <errno.h> +  #include "pkghash.h"  #include "util.h" -#include "log.h"  /* List of primes for possible sizes of hash tables.   * @@ -55,11 +56,7 @@ pmpkghash_t *_alpm_pkghash_create(size_t size)  	pmpkghash_t *hash = NULL;  	size_t i, loopsize; -	MALLOC(hash, sizeof(pmpkghash_t), RET_ERR(PM_ERR_MEMORY, NULL)); - -	hash->list = NULL; -	hash->entries = 0; -	hash->buckets = 0; +	CALLOC(hash, 1, sizeof(pmpkghash_t), return NULL);  	loopsize = sizeof(prime_list) / sizeof(*prime_list);  	for(i = 0; i < loopsize; i++) { @@ -70,15 +67,15 @@ pmpkghash_t *_alpm_pkghash_create(size_t size)  	}  	if(hash->buckets < size) { -		_alpm_log(PM_LOG_ERROR, _("database larger than maximum size\n")); +		errno = ERANGE;  		free(hash); -		return(NULL); +		return NULL;  	} -	CALLOC(hash->hash_table, hash->buckets, sizeof(alpm_list_t*), \ -				free(hash); RET_ERR(PM_ERR_MEMORY, NULL)); +	CALLOC(hash->hash_table, hash->buckets, sizeof(alpm_list_t *), \ +				free(hash); return NULL); -	return(hash); +	return hash;  }  static size_t get_hash_position(unsigned long name_hash, pmpkghash_t *hash) @@ -92,7 +89,7 @@ static size_t get_hash_position(unsigned long name_hash, pmpkghash_t *hash)  		position = (position + 1) % hash->buckets;  	} -	return(position); +	return position;  }  /* Expand the hash table size to the next increment and rebin the entries */ @@ -123,7 +120,7 @@ static pmpkghash_t *rehash(pmpkghash_t *oldhash)  	newhash = _alpm_pkghash_create(newsize);  	if(newhash == NULL) {  		/* creation of newhash failed, stick with old one... */ -		return(oldhash); +		return oldhash;  	}  	newhash->list = oldhash->list; @@ -144,7 +141,7 @@ static pmpkghash_t *rehash(pmpkghash_t *oldhash)  	_alpm_pkghash_free(oldhash); -	return(newhash); +	return newhash;  }  static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted) @@ -153,7 +150,7 @@ static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted)  	size_t position;  	if(pkg == NULL || hash == NULL) { -		return(hash); +		return hash;  	}  	if((hash->entries + 1) / MAX_HASH_LOAD > hash->buckets) { @@ -164,7 +161,7 @@ static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted)  	ptr = calloc(1, sizeof(alpm_list_t));  	if(ptr == NULL) { -		return(hash); +		return hash;  	}  	ptr->data = pkg; @@ -179,17 +176,17 @@ static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted)  	}  	hash->entries += 1; -	return(hash); +	return hash;  }  pmpkghash_t *_alpm_pkghash_add(pmpkghash_t *hash, pmpkg_t *pkg)  { -	return(pkghash_add_pkg(hash, pkg, 0)); +	return pkghash_add_pkg(hash, pkg, 0);  }  pmpkghash_t *_alpm_pkghash_add_sorted(pmpkghash_t *hash, pmpkg_t *pkg)  { -	return(pkghash_add_pkg(hash, pkg, 1)); +	return pkghash_add_pkg(hash, pkg, 1);  }  static size_t move_one_entry(pmpkghash_t *hash, size_t start, size_t end) @@ -217,7 +214,7 @@ static size_t move_one_entry(pmpkghash_t *hash, size_t start, size_t end)  		 * e.g. (47 + 0 - 1) % 47 == 46 */  		end = (hash->buckets + end - 1) % hash->buckets;  	} -	return(end); +	return end;  }  /** @@ -240,7 +237,7 @@ pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg,  	}  	if(pkg == NULL || hash == NULL) { -		return(hash); +		return hash;  	}  	position = pkg->name_hash % hash->buckets; @@ -277,13 +274,13 @@ pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg,  				position = prev;  			} -			return(hash); +			return hash;  		}  		position = (position + 1) % hash->buckets;  	} -	return(hash); +	return hash;  }  void _alpm_pkghash_free(pmpkghash_t *hash) @@ -304,10 +301,8 @@ pmpkg_t *_alpm_pkghash_find(pmpkghash_t *hash, const char *name)  	unsigned long name_hash;  	size_t position; -	ALPM_LOG_FUNC; -  	if(name == NULL || hash == NULL) { -		return(NULL); +		return NULL;  	}  	name_hash = _alpm_hash_sdbm(name); @@ -318,13 +313,13 @@ pmpkg_t *_alpm_pkghash_find(pmpkghash_t *hash, const char *name)  		pmpkg_t *info = lp->data;  		if(info->name_hash == name_hash && strcmp(info->name, name) == 0) { -			return(info); +			return info;  		}  		position = (position + 1) % hash->buckets;  	} -	return(NULL); +	return NULL;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index 22ae2bb8..9f075016 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -26,8 +26,6 @@  #include <stdlib.h>  #include <errno.h> -#include <time.h> -#include <fcntl.h>  #include <string.h>  #include <limits.h>  #include <unistd.h> @@ -36,6 +34,7 @@  /* libalpm */  #include "remove.h"  #include "alpm_list.h" +#include "alpm.h"  #include "trans.h"  #include "util.h"  #include "log.h" @@ -44,65 +43,63 @@  #include "db.h"  #include "deps.h"  #include "handle.h" -#include "alpm.h" -int SYMEXPORT alpm_remove_pkg(pmpkg_t *pkg) +int SYMEXPORT alpm_remove_pkg(pmhandle_t *handle, pmpkg_t *pkg)  { -	pmtrans_t *trans;  	const char *pkgname; - -	ALPM_LOG_FUNC; +	pmtrans_t *trans;  	/* Sanity checks */ -	ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1); +	ASSERT(pkg != NULL, RET_ERR(handle, PM_ERR_WRONG_ARGS, -1)); +	ASSERT(handle == pkg->handle, RET_ERR(handle, PM_ERR_WRONG_ARGS, -1));  	trans = handle->trans; -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); +	ASSERT(trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1));  	ASSERT(trans->state == STATE_INITIALIZED, -			RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1)); +			RET_ERR(handle, PM_ERR_TRANS_NOT_INITIALIZED, -1)); -	pkgname = alpm_pkg_get_name(pkg); +	pkgname = pkg->name;  	if(_alpm_pkg_find(trans->remove, pkgname)) { -		RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1); +		RET_ERR(handle, PM_ERR_TRANS_DUP_TARGET, -1);  	} -	_alpm_log(PM_LOG_DEBUG, "adding %s in the target list\n", pkgname); +	_alpm_log(handle, PM_LOG_DEBUG, "adding package %s to the transaction remove list\n", +			pkgname);  	trans->remove = alpm_list_add(trans->remove, _alpm_pkg_dup(pkg)); -	return(0); +	return 0;  } -static void remove_prepare_cascade(pmtrans_t *trans, pmdb_t *db, -		alpm_list_t *lp) +static void remove_prepare_cascade(pmhandle_t *handle, alpm_list_t *lp)  { -	ALPM_LOG_FUNC; +	pmtrans_t *trans = handle->trans;  	while(lp) {  		alpm_list_t *i;  		for(i = lp; i; i = i->next) {  			pmdepmissing_t *miss = (pmdepmissing_t *)i->data; -			pmpkg_t *info = _alpm_db_get_pkgfromcache(db, miss->target); +			pmpkg_t *info = _alpm_db_get_pkgfromcache(handle->db_local, miss->target);  			if(info) {  				if(!_alpm_pkg_find(trans->remove, alpm_pkg_get_name(info))) { -					_alpm_log(PM_LOG_DEBUG, "pulling %s in target list\n", +					_alpm_log(handle, PM_LOG_DEBUG, "pulling %s in target list\n",  							alpm_pkg_get_name(info));  					trans->remove = alpm_list_add(trans->remove, _alpm_pkg_dup(info));  				}  			} else { -				_alpm_log(PM_LOG_ERROR, _("could not find %s in database -- skipping\n"), +				_alpm_log(handle, PM_LOG_ERROR, _("could not find %s in database -- skipping\n"),  									miss->target);  			}  		}  		alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free);  		alpm_list_free(lp); -		lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, trans->remove, NULL); +		lp = alpm_checkdeps(handle, _alpm_db_get_pkgcache(handle->db_local), +				trans->remove, NULL, 1);  	}  } -static void remove_prepare_keep_needed(pmtrans_t *trans, pmdb_t *db, -		alpm_list_t *lp) +static void remove_prepare_keep_needed(pmhandle_t *handle, alpm_list_t *lp)  { -	ALPM_LOG_FUNC; +	pmtrans_t *trans = handle->trans;  	/* Remove needed packages (which break dependencies) from target list */  	while(lp != NULL) { @@ -118,14 +115,15 @@ static void remove_prepare_keep_needed(pmtrans_t *trans, pmdb_t *db,  					&vpkg);  			pkg = vpkg;  			if(pkg) { -				_alpm_log(PM_LOG_WARNING, _("removing %s from target list\n"), +				_alpm_log(handle, PM_LOG_WARNING, _("removing %s from target list\n"),  						alpm_pkg_get_name(pkg));  				_alpm_pkg_free(pkg);  			}  		}  		alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free);  		alpm_list_free(lp); -		lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, trans->remove, NULL); +		lp = alpm_checkdeps(handle, _alpm_db_get_pkgcache(handle->db_local), +				trans->remove, NULL, 1);  	}  } @@ -133,37 +131,34 @@ static void remove_prepare_keep_needed(pmtrans_t *trans, pmdb_t *db,   * This functions takes a pointer to a alpm_list_t which will be   * filled with a list of pmdepmissing_t* objects representing   * the packages blocking the transaction. - * @param trans the transaction object - * @param db the database of local packages + * @param handle the context handle   * @param data a pointer to an alpm_list_t* to fill   */ -int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) +int _alpm_remove_prepare(pmhandle_t *handle, alpm_list_t **data)  {  	alpm_list_t *lp; - -	ALPM_LOG_FUNC; - -	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); +	pmtrans_t *trans = handle->trans; +	pmdb_t *db = handle->db_local;  	if((trans->flags & PM_TRANS_FLAG_RECURSE) && !(trans->flags & PM_TRANS_FLAG_CASCADE)) { -		_alpm_log(PM_LOG_DEBUG, "finding removable dependencies\n"); -		_alpm_recursedeps(db, trans->remove, trans->flags & PM_TRANS_FLAG_RECURSEALL); +		_alpm_log(handle, PM_LOG_DEBUG, "finding removable dependencies\n"); +		_alpm_recursedeps(db, trans->remove, +				trans->flags & PM_TRANS_FLAG_RECURSEALL);  	}  	if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {  		EVENT(trans, PM_TRANS_EVT_CHECKDEPS_START, NULL, NULL); -		_alpm_log(PM_LOG_DEBUG, "looking for unsatisfied dependencies\n"); -		lp = alpm_checkdeps(_alpm_db_get_pkgcache(db), 1, trans->remove, NULL); +		_alpm_log(handle, PM_LOG_DEBUG, "looking for unsatisfied dependencies\n"); +		lp = alpm_checkdeps(handle, _alpm_db_get_pkgcache(db), trans->remove, NULL, 1);  		if(lp != NULL) {  			if(trans->flags & PM_TRANS_FLAG_CASCADE) { -				remove_prepare_cascade(trans, db, lp); -			} else if (trans->flags & PM_TRANS_FLAG_UNNEEDED) { +				remove_prepare_cascade(handle, lp); +			} else if(trans->flags & PM_TRANS_FLAG_UNNEEDED) {  				/* Remove needed packages (which would break dependencies)  				 * from target list */ -				remove_prepare_keep_needed(trans, db, lp); +				remove_prepare_keep_needed(handle, lp);  			} else {  				if(data) {  					*data = lp; @@ -171,21 +166,21 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)  					alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free);  					alpm_list_free(lp);  				} -				RET_ERR(PM_ERR_UNSATISFIED_DEPS, -1); +				RET_ERR(handle, PM_ERR_UNSATISFIED_DEPS, -1);  			}  		}  	}  	/* re-order w.r.t. dependencies */ -	_alpm_log(PM_LOG_DEBUG, "sorting by dependencies\n"); -	lp = _alpm_sortbydeps(trans->remove, 1); +	_alpm_log(handle, PM_LOG_DEBUG, "sorting by dependencies\n"); +	lp = _alpm_sortbydeps(handle, trans->remove, 1);  	/* free the old alltargs */  	alpm_list_free(trans->remove);  	trans->remove = lp;  	/* -Rcs == -Rc then -Rs */  	if((trans->flags & PM_TRANS_FLAG_CASCADE) && (trans->flags & PM_TRANS_FLAG_RECURSE)) { -		_alpm_log(PM_LOG_DEBUG, "finding removable dependencies\n"); +		_alpm_log(handle, PM_LOG_DEBUG, "finding removable dependencies\n");  		_alpm_recursedeps(db, trans->remove, trans->flags & PM_TRANS_FLAG_RECURSEALL);  	} @@ -193,18 +188,19 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)  		EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);  	} -	return(0); +	return 0;  } -static int can_remove_file(const char *path, alpm_list_t *skip) +static int can_remove_file(pmhandle_t *handle, const char *path, +		alpm_list_t *skip_remove)  { -	char file[PATH_MAX+1]; +	char file[PATH_MAX];  	snprintf(file, PATH_MAX, "%s%s", handle->root, path); -	if(alpm_list_find_str(skip, file)) { +	if(alpm_list_find_str(skip_remove, file)) {  		/* return success because we will never actually remove this file */ -		return(1); +		return 1;  	}  	/* If we fail write permissions due to a read-only filesystem, abort.  	 * Assume all other possible failures are covered somewhere else */ @@ -212,23 +208,22 @@ static int can_remove_file(const char *path, alpm_list_t *skip)  		if(errno != EACCES && errno != ETXTBSY && access(file, F_OK) == 0) {  			/* only return failure if the file ACTUALLY exists and we can't write to  			 * it - ignore "chmod -w" simple permission failures */ -			_alpm_log(PM_LOG_ERROR, _("cannot remove file '%s': %s\n"), -			          file, strerror(errno)); -			return(0); +			_alpm_log(handle, PM_LOG_ERROR, _("cannot remove file '%s': %s\n"), +					file, strerror(errno)); +			return 0;  		}  	} -	return(1); +	return 1;  }  /* Helper function for iterating through a package's file and deleting them   * Used by _alpm_remove_commit. */ -static void unlink_file(pmpkg_t *info, char *filename, alpm_list_t *skip_remove, int nosave) +static void unlink_file(pmhandle_t *handle, pmpkg_t *info, const char *filename, +		alpm_list_t *skip_remove, int nosave)  {  	struct stat buf; -	char file[PATH_MAX+1]; - -	ALPM_LOG_FUNC; +	char file[PATH_MAX];  	snprintf(file, PATH_MAX, "%s%s", handle->root, filename); @@ -236,7 +231,7 @@ static void unlink_file(pmpkg_t *info, char *filename, alpm_list_t *skip_remove,  	 * see the big comment block in db_find_fileconflicts() for an  	 * explanation. */  	if(alpm_list_find_str(skip_remove, filename)) { -		_alpm_log(PM_LOG_DEBUG, "%s is in skip_remove, skipping removal\n", +		_alpm_log(handle, PM_LOG_DEBUG, "%s is in skip_remove, skipping removal\n",  				file);  		return;  	} @@ -246,23 +241,23 @@ static void unlink_file(pmpkg_t *info, char *filename, alpm_list_t *skip_remove,  	 * filesystem, we want to work with the linked directory instead of the  	 * actual symlink */  	if(lstat(file, &buf)) { -		_alpm_log(PM_LOG_DEBUG, "file %s does not exist\n", file); +		_alpm_log(handle, PM_LOG_DEBUG, "file %s does not exist\n", file);  		return;  	}  	if(S_ISDIR(buf.st_mode)) {  		if(rmdir(file)) {  			/* this is okay, other packages are probably using it (like /usr) */ -			_alpm_log(PM_LOG_DEBUG, "keeping directory %s\n", file); +			_alpm_log(handle, PM_LOG_DEBUG, "keeping directory %s\n", file);  		} else { -			_alpm_log(PM_LOG_DEBUG, "removing directory %s\n", file); +			_alpm_log(handle, PM_LOG_DEBUG, "removing directory %s\n", file);  		}  	} else {  		/* if the file needs backup and has been modified, back it up to .pacsave */  		char *pkghash = _alpm_needbackup(filename, alpm_pkg_get_backup(info));  		if(pkghash) {  			if(nosave) { -				_alpm_log(PM_LOG_DEBUG, "transaction is set to NOSAVE, not backing up '%s'\n", file); +				_alpm_log(handle, PM_LOG_DEBUG, "transaction is set to NOSAVE, not backing up '%s'\n", file);  				FREE(pkghash);  			} else {  				char *filehash = alpm_compute_md5sum(file); @@ -273,24 +268,24 @@ static void unlink_file(pmpkg_t *info, char *filename, alpm_list_t *skip_remove,  					char newpath[PATH_MAX];  					snprintf(newpath, PATH_MAX, "%s.pacsave", file);  					rename(file, newpath); -					_alpm_log(PM_LOG_WARNING, _("%s saved as %s\n"), file, newpath); -					alpm_logaction("warning: %s saved as %s\n", file, newpath); +					_alpm_log(handle, PM_LOG_WARNING, _("%s saved as %s\n"), file, newpath); +					alpm_logaction(handle, "warning: %s saved as %s\n", file, newpath);  					return;  				}  			}  		} -		_alpm_log(PM_LOG_DEBUG, "unlinking %s\n", file); +		_alpm_log(handle, PM_LOG_DEBUG, "unlinking %s\n", file);  		if(unlink(file) == -1) { -			_alpm_log(PM_LOG_ERROR, _("cannot remove file '%s': %s\n"), -								filename, strerror(errno)); +			_alpm_log(handle, PM_LOG_ERROR, _("cannot remove file '%s': %s\n"), +					filename, strerror(errno));  		}  	}  } -int _alpm_upgraderemove_package(pmpkg_t *oldpkg, pmpkg_t *newpkg, -		pmtrans_t *trans) +int _alpm_upgraderemove_package(pmhandle_t *handle, +		pmpkg_t *oldpkg, pmpkg_t *newpkg)  {  	alpm_list_t *skip_remove, *b;  	alpm_list_t *newfiles, *lp; @@ -298,18 +293,16 @@ int _alpm_upgraderemove_package(pmpkg_t *oldpkg, pmpkg_t *newpkg,  	alpm_list_t *files = alpm_pkg_get_files(oldpkg);  	const char *pkgname = alpm_pkg_get_name(oldpkg); -	ALPM_LOG_FUNC; - -	_alpm_log(PM_LOG_DEBUG, "removing old package first (%s-%s)\n", +	_alpm_log(handle, PM_LOG_DEBUG, "removing old package first (%s-%s)\n",  			oldpkg->name, oldpkg->version); -	if(trans->flags & PM_TRANS_FLAG_DBONLY) { +	if(handle->trans->flags & PM_TRANS_FLAG_DBONLY) {  		goto db;  	}  	/* copy the remove skiplist over */  	skip_remove = alpm_list_join( -			alpm_list_strdup(trans->skip_remove), +			alpm_list_strdup(handle->trans->skip_remove),  			alpm_list_strdup(handle->noupgrade));  	/* Add files in the NEW backup array to the skip_remove array  	 * so this removal operation doesn't kill them */ @@ -322,83 +315,79 @@ int _alpm_upgraderemove_package(pmpkg_t *oldpkg, pmpkg_t *newpkg,  			FREE(backup);  			continue;  		} -		_alpm_log(PM_LOG_DEBUG, "adding %s to the skip_remove array\n", backup); +		_alpm_log(handle, PM_LOG_DEBUG, "adding %s to the skip_remove array\n", backup);  		skip_remove = alpm_list_add(skip_remove, backup);  	}  	for(lp = files; lp; lp = lp->next) { -		if(!can_remove_file(lp->data, skip_remove)) { -			_alpm_log(PM_LOG_DEBUG, "not removing package '%s', can't remove all files\n", +		if(!can_remove_file(handle, lp->data, skip_remove)) { +			_alpm_log(handle, PM_LOG_DEBUG, "not removing package '%s', can't remove all files\n",  					pkgname); -			RET_ERR(PM_ERR_PKG_CANT_REMOVE, -1); +			RET_ERR(handle, PM_ERR_PKG_CANT_REMOVE, -1);  		}  	}  	filenum = alpm_list_count(files); -	_alpm_log(PM_LOG_DEBUG, "removing %ld files\n", (unsigned long)filenum); +	_alpm_log(handle, PM_LOG_DEBUG, "removing %ld files\n", (unsigned long)filenum);  	/* iterate through the list backwards, unlinking files */  	newfiles = alpm_list_reverse(files);  	for(lp = newfiles; lp; lp = alpm_list_next(lp)) { -		unlink_file(oldpkg, lp->data, skip_remove, 0); +		unlink_file(handle, oldpkg, lp->data, skip_remove, 0);  	}  	alpm_list_free(newfiles);  	FREELIST(skip_remove);  db:  	/* remove the package from the database */ -	_alpm_log(PM_LOG_DEBUG, "updating database\n"); -	_alpm_log(PM_LOG_DEBUG, "removing database entry '%s'\n", pkgname); +	_alpm_log(handle, PM_LOG_DEBUG, "updating database\n"); +	_alpm_log(handle, PM_LOG_DEBUG, "removing database entry '%s'\n", pkgname);  	if(_alpm_local_db_remove(handle->db_local, oldpkg) == -1) { -		_alpm_log(PM_LOG_ERROR, _("could not remove database entry %s-%s\n"), +		_alpm_log(handle, PM_LOG_ERROR, _("could not remove database entry %s-%s\n"),  				pkgname, alpm_pkg_get_version(oldpkg));  	}  	/* remove the package from the cache */  	if(_alpm_db_remove_pkgfromcache(handle->db_local, oldpkg) == -1) { -		_alpm_log(PM_LOG_ERROR, _("could not remove entry '%s' from cache\n"), +		_alpm_log(handle, PM_LOG_ERROR, _("could not remove entry '%s' from cache\n"),  				pkgname);  	} -	return(0); +	return 0;  } -int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db) +int _alpm_remove_packages(pmhandle_t *handle)  {  	pmpkg_t *info;  	alpm_list_t *targ, *lp;  	size_t pkg_count; - -	ALPM_LOG_FUNC; - -	ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); +	pmtrans_t *trans = handle->trans;  	pkg_count = alpm_list_count(trans->remove);  	for(targ = trans->remove; targ; targ = targ->next) {  		int position = 0;  		char scriptlet[PATH_MAX]; -		info = (pmpkg_t*)targ->data; +		info = (pmpkg_t *)targ->data;  		const char *pkgname = NULL;  		size_t targcount = alpm_list_count(targ); -		if(handle->trans->state == STATE_INTERRUPTED) { -			return(0); +		if(trans->state == STATE_INTERRUPTED) { +			return 0;  		}  		/* get the name now so we can use it after package is removed */  		pkgname = alpm_pkg_get_name(info);  		snprintf(scriptlet, PATH_MAX, "%s%s-%s/install", -				_alpm_db_path(db), pkgname, alpm_pkg_get_version(info)); +				_alpm_db_path(handle->db_local), pkgname, alpm_pkg_get_version(info));  		EVENT(trans, PM_TRANS_EVT_REMOVE_START, info, NULL); -		_alpm_log(PM_LOG_DEBUG, "removing package %s-%s\n", +		_alpm_log(handle, PM_LOG_DEBUG, "removing package %s-%s\n",  				pkgname, alpm_pkg_get_version(info));  		/* run the pre-remove scriptlet if it exists  */  		if(alpm_pkg_has_scriptlet(info) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { -			_alpm_runscriptlet(handle->root, scriptlet, "pre_remove", -					alpm_pkg_get_version(info), NULL, trans); +			_alpm_runscriptlet(handle, scriptlet, "pre_remove", +					alpm_pkg_get_version(info), NULL);  		}  		if(!(trans->flags & PM_TRANS_FLAG_DBONLY)) { @@ -407,15 +396,15 @@ int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db)  			size_t filenum;  			for(lp = files; lp; lp = lp->next) { -				if(!can_remove_file(lp->data, NULL)) { -					_alpm_log(PM_LOG_DEBUG, "not removing package '%s', can't remove all files\n", +				if(!can_remove_file(handle, lp->data, NULL)) { +					_alpm_log(handle, PM_LOG_DEBUG, "not removing package '%s', can't remove all files\n",  					          pkgname); -					RET_ERR(PM_ERR_PKG_CANT_REMOVE, -1); +					RET_ERR(handle, PM_ERR_PKG_CANT_REMOVE, -1);  				}  			}  			filenum = alpm_list_count(files); -			_alpm_log(PM_LOG_DEBUG, "removing %ld files\n", (unsigned long)filenum); +			_alpm_log(handle, PM_LOG_DEBUG, "removing %ld files\n", (unsigned long)filenum);  			/* init progress bar */  			PROGRESS(trans, PM_TRANS_PROGRESS_REMOVE_START, info->name, 0, @@ -425,7 +414,7 @@ int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db)  			newfiles = alpm_list_reverse(files);  			for(lp = newfiles; lp; lp = alpm_list_next(lp)) {  				int percent; -				unlink_file(info, lp->data, NULL, trans->flags & PM_TRANS_FLAG_NOSAVE); +				unlink_file(handle, info, lp->data, NULL, trans->flags & PM_TRANS_FLAG_NOSAVE);  				/* update progress bar after each file */  				percent = (position * 100) / filenum; @@ -442,20 +431,20 @@ int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db)  		/* run the post-remove script if it exists  */  		if(alpm_pkg_has_scriptlet(info) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { -			_alpm_runscriptlet(handle->root, scriptlet, "post_remove", -					alpm_pkg_get_version(info), NULL, trans); +			_alpm_runscriptlet(handle, scriptlet, "post_remove", +					alpm_pkg_get_version(info), NULL);  		}  		/* remove the package from the database */ -		_alpm_log(PM_LOG_DEBUG, "updating database\n"); -		_alpm_log(PM_LOG_DEBUG, "removing database entry '%s'\n", pkgname); -		if(_alpm_local_db_remove(db, info) == -1) { -			_alpm_log(PM_LOG_ERROR, _("could not remove database entry %s-%s\n"), +		_alpm_log(handle, PM_LOG_DEBUG, "updating database\n"); +		_alpm_log(handle, PM_LOG_DEBUG, "removing database entry '%s'\n", pkgname); +		if(_alpm_local_db_remove(handle->db_local, info) == -1) { +			_alpm_log(handle, PM_LOG_ERROR, _("could not remove database entry %s-%s\n"),  			          pkgname, alpm_pkg_get_version(info));  		}  		/* remove the package from the cache */ -		if(_alpm_db_remove_pkgfromcache(db, info) == -1) { -			_alpm_log(PM_LOG_ERROR, _("could not remove entry '%s' from cache\n"), +		if(_alpm_db_remove_pkgfromcache(handle->db_local, info) == -1) { +			_alpm_log(handle, PM_LOG_ERROR, _("could not remove entry '%s' from cache\n"),  			          pkgname);  		} @@ -463,9 +452,9 @@ int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db)  	}  	/* run ldconfig if it exists */ -	_alpm_ldconfig(handle->root); +	_alpm_ldconfig(handle); -	return(0); +	return 0;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/remove.h b/lib/libalpm/remove.h index a67e37a1..5cab526a 100644 --- a/lib/libalpm/remove.h +++ b/lib/libalpm/remove.h @@ -24,10 +24,11 @@  #include "alpm_list.h"  #include "trans.h" -int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data); -int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db); +int _alpm_remove_prepare(pmhandle_t *handle, alpm_list_t **data); +int _alpm_remove_packages(pmhandle_t *handle); -int _alpm_upgraderemove_package(pmpkg_t *oldpkg, pmpkg_t *newpkg, pmtrans_t *trans); +int _alpm_upgraderemove_package(pmhandle_t *handle, +		pmpkg_t *oldpkg, pmpkg_t *newpkg);  #endif /* _ALPM_REMOVE_H */ diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c new file mode 100644 index 00000000..ff97d4c7 --- /dev/null +++ b/lib/libalpm/signing.c @@ -0,0 +1,406 @@ +/* + *  signing.c + * + *  Copyright (c) 2008-2011 Pacman Development Team <pacman-dev@archlinux.org> + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#if HAVE_LIBGPGME +#include <locale.h> /* setlocale() */ +#include <gpgme.h> +#include "base64.h" +#endif + +/* libalpm */ +#include "signing.h" +#include "package.h" +#include "util.h" +#include "log.h" +#include "alpm.h" +#include "handle.h" + +#if HAVE_LIBGPGME +#define CHECK_ERR(void) do { \ +		if(err != GPG_ERR_NO_ERROR) { goto error; } \ +	} while(0) + +static const char *string_validity(gpgme_validity_t validity) +{ +	switch(validity) { +		case GPGME_VALIDITY_UNKNOWN: +			return "unknown"; +		case GPGME_VALIDITY_UNDEFINED: +			return "undefined"; +		case GPGME_VALIDITY_NEVER: +			return "never"; +		case GPGME_VALIDITY_MARGINAL: +			return "marginal"; +		case GPGME_VALIDITY_FULL: +			return "full"; +		case GPGME_VALIDITY_ULTIMATE: +			return "ultimate"; +	} +	return "???"; +} + +static void sigsum_test_bit(gpgme_sigsum_t sigsum, alpm_list_t **summary, +		gpgme_sigsum_t bit, const char *value) +{ +	if(sigsum & bit) { +		*summary = alpm_list_add(*summary, (void *)value); +	} +} + +static alpm_list_t *list_sigsum(gpgme_sigsum_t sigsum) +{ +	alpm_list_t *summary = NULL; +	/* The docs say this can be a bitmask...not sure I believe it, but we'll code +	 * for it anyway and show all possible flags in the returned string. */ + +	/* The signature is fully valid.  */ +	sigsum_test_bit(sigsum, &summary, GPGME_SIGSUM_VALID, "valid"); +	/* The signature is good.  */ +	sigsum_test_bit(sigsum, &summary, GPGME_SIGSUM_GREEN, "green"); +	/* The signature is bad.  */ +	sigsum_test_bit(sigsum, &summary, GPGME_SIGSUM_RED, "red"); +	/* One key has been revoked.  */ +	sigsum_test_bit(sigsum, &summary, GPGME_SIGSUM_KEY_REVOKED, "key revoked"); +	/* One key has expired.  */ +	sigsum_test_bit(sigsum, &summary, GPGME_SIGSUM_KEY_EXPIRED, "key expired"); +	/* The signature has expired.  */ +	sigsum_test_bit(sigsum, &summary, GPGME_SIGSUM_SIG_EXPIRED, "sig expired"); +	/* Can't verify: key missing.  */ +	sigsum_test_bit(sigsum, &summary, GPGME_SIGSUM_KEY_MISSING, "key missing"); +	/* CRL not available.  */ +	sigsum_test_bit(sigsum, &summary, GPGME_SIGSUM_CRL_MISSING, "crl missing"); +	/* Available CRL is too old.  */ +	sigsum_test_bit(sigsum, &summary, GPGME_SIGSUM_CRL_TOO_OLD, "crl too old"); +	/* A policy was not met.  */ +	sigsum_test_bit(sigsum, &summary, GPGME_SIGSUM_BAD_POLICY, "bad policy"); +	/* A system error occured.  */ +	sigsum_test_bit(sigsum, &summary, GPGME_SIGSUM_SYS_ERROR, "sys error"); +	/* Fallback case */ +	if(!sigsum) { +		summary = alpm_list_add(summary, (void *)"(empty)"); +	} +	return summary; +} + +static int init_gpgme(pmhandle_t *handle) +{ +	static int init = 0; +	const char *version, *sigdir; +	gpgme_error_t err; +	gpgme_engine_info_t enginfo; + +	if(init) { +		/* we already successfully initialized the library */ +		return 0; +	} + +	sigdir = alpm_option_get_signaturedir(handle); +	if(!sigdir) { +		RET_ERR(handle, PM_ERR_SIG_MISSINGDIR, 1); +	} + +	/* calling gpgme_check_version() returns the current version and runs +	 * some internal library setup code */ +	version = gpgme_check_version(NULL); +	_alpm_log(handle, PM_LOG_DEBUG, "GPGME version: %s\n", version); +	gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); +#ifdef LC_MESSAGES +	gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL)); +#endif +	/* NOTE: +	 * The GPGME library installs a SIGPIPE signal handler automatically if +	 * the default signal hander is in use. The only time we set a handler +	 * for SIGPIPE is in dload.c, and we reset it when we are done. Given that +	 * we do this, we can let GPGME do its automagic. However, if we install +	 * a library-wide SIGPIPE handler, we will have to be careful. +	 */ + +	/* check for OpenPGP support (should be a no-brainer, but be safe) */ +	err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); +	CHECK_ERR(); + +	/* set and check engine information */ +	err = gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, NULL, sigdir); +	CHECK_ERR(); +	err = gpgme_get_engine_info(&enginfo); +	CHECK_ERR(); +	_alpm_log(handle, PM_LOG_DEBUG, "GPGME engine info: file=%s, home=%s\n", +			enginfo->file_name, enginfo->home_dir); + +	init = 1; +	return 0; + +error: +	_alpm_log(handle, PM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err)); +	RET_ERR(handle, PM_ERR_GPGME, 1); +} + +/** + * Decode a loaded signature in base64 form. + * @param base64_data the signature to attempt to decode + * @param data the decoded data; must be freed by the caller + * @param data_len the length of the returned data + * @return 0 on success, 1 on failure to properly decode + */ +static int decode_signature(const char *base64_data, +		unsigned char **data, int *data_len) { +	unsigned char *usline; +	int len; + +	len = strlen(base64_data); +	usline = (unsigned char *)base64_data; +	int ret, destlen = 0; +	/* get the necessary size for the buffer by passing 0 */ +	ret = base64_decode(NULL, &destlen, usline, len); +	if(ret != 0 && ret != POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL) { +		goto error; +	} +	/* alloc our memory and repeat the call to decode */ +	MALLOC(*data, (size_t)destlen, goto error); +	ret = base64_decode(*data, &destlen, usline, len); +	if(ret != 0) { +		goto error; +	} +	*data_len = destlen; +	return 0; + +error: +	*data = NULL; +	*data_len = 0; +	return 1; +} + +/** + * Check the PGP signature for the given file path. + * If base64_sig is provided, it will be used as the signature data after + * decoding. If base64_sig is NULL, expect a signature file next to path + * (e.g. "%s.sig"). The return value will be 0 if all checked signatures are + * valid, 1 if there was some sort of problem (but not necessarily rejection), + * and -1 if an error occurred while checking signatures. If 1 is returned, + * pm_errno should be checked to see why the signatures did not pass muster. + * @param handle the context handle + * @param path the full path to a file + * @param base64_sig optional PGP signature data in base64 encoding + * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred) + */ +int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path, +		const char *base64_sig) +{ +	int ret = 0; +	gpgme_error_t err; +	gpgme_ctx_t ctx; +	gpgme_data_t filedata, sigdata; +	gpgme_verify_result_t result; +	gpgme_signature_t gpgsig; +	char *sigpath = NULL; +	unsigned char *decoded_sigdata = NULL; +	FILE *file = NULL, *sigfile = NULL; + +	if(!path || access(path, R_OK) != 0) { +		RET_ERR(handle, PM_ERR_NOT_A_FILE, -1); +	} + +	if(!base64_sig) { +		size_t len = strlen(path) + 5; +		CALLOC(sigpath, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, -1)); +		snprintf(sigpath, len, "%s.sig", path); + +		if(!access(sigpath, R_OK) == 0) { +			FREE(sigpath); +			RET_ERR(handle, PM_ERR_SIG_UNKNOWN, -1); +		} +	} + +	if(init_gpgme(handle)) { +		/* pm_errno was set in gpgme_init() */ +		return -1; +	} + +	_alpm_log(handle, PM_LOG_DEBUG, "checking signature for %s\n", path); + +	memset(&ctx, 0, sizeof(ctx)); +	memset(&sigdata, 0, sizeof(sigdata)); +	memset(&filedata, 0, sizeof(filedata)); + +	err = gpgme_new(&ctx); +	CHECK_ERR(); + +	/* create our necessary data objects to verify the signature */ +	file = fopen(path, "rb"); +	if(file == NULL) { +		handle->pm_errno = PM_ERR_NOT_A_FILE; +		ret = -1; +		goto error; +	} +	err = gpgme_data_new_from_stream(&filedata, file); +	CHECK_ERR(); + +	/* next create data object for the signature */ +	if(base64_sig) { +		/* memory-based, we loaded it from a sync DB */ +		int data_len; +		int decode_ret = decode_signature(base64_sig, +				&decoded_sigdata, &data_len); +		if(decode_ret) { +			ret = -1; +			goto error; +		} +		err = gpgme_data_new_from_mem(&sigdata, +				(char *)decoded_sigdata, data_len, 0); +	} else { +		/* file-based, it is on disk */ +		sigfile = fopen(sigpath, "rb"); +		if(sigfile == NULL) { +			handle->pm_errno = PM_ERR_NOT_A_FILE; +			ret = -1; +			goto error; +		} +		err = gpgme_data_new_from_stream(&sigdata, sigfile); +	} +	CHECK_ERR(); + +	/* here's where the magic happens */ +	err = gpgme_op_verify(ctx, sigdata, filedata, NULL); +	CHECK_ERR(); +	result = gpgme_op_verify_result(ctx); +	gpgsig = result->signatures; +	if(!gpgsig) { +		_alpm_log(handle, PM_LOG_DEBUG, "no signatures returned\n"); +		ret = -1; +		goto error; +	} + +	{ +		alpm_list_t *summary_list, *summary; + +		_alpm_log(handle, PM_LOG_DEBUG, "fingerprint: %s\n", gpgsig->fpr); +		summary_list = list_sigsum(gpgsig->summary); +		for(summary = summary_list; summary; summary = summary->next) { +			_alpm_log(handle, PM_LOG_DEBUG, "summary: %s\n", (const char *)summary->data); +		} +		alpm_list_free(summary_list); +		_alpm_log(handle, PM_LOG_DEBUG, "status: %s\n", gpgme_strerror(gpgsig->status)); +		_alpm_log(handle, PM_LOG_DEBUG, "timestamp: %lu\n", gpgsig->timestamp); +		_alpm_log(handle, PM_LOG_DEBUG, "exp_timestamp: %lu\n", gpgsig->exp_timestamp); +		_alpm_log(handle, PM_LOG_DEBUG, "validity: %s\n", +				string_validity(gpgsig->validity)); +		_alpm_log(handle, PM_LOG_DEBUG, "validity_reason: %s\n", +				gpgme_strerror(gpgsig->validity_reason)); +		_alpm_log(handle, PM_LOG_DEBUG, "pubkey algo: %s\n", +				gpgme_pubkey_algo_name(gpgsig->pubkey_algo)); +		_alpm_log(handle, PM_LOG_DEBUG, "hash algo: %s\n", +				gpgme_hash_algo_name(gpgsig->hash_algo)); +	} + +	if(gpgsig->summary & GPGME_SIGSUM_VALID) { +		/* good signature, continue */ +		_alpm_log(handle, PM_LOG_DEBUG, _("File %s has a valid signature.\n"), +				path); +	} else if(gpgsig->summary & GPGME_SIGSUM_GREEN) { +		/* 'green' signature, not sure what to do here */ +		_alpm_log(handle, PM_LOG_WARNING, _("File %s has a green signature.\n"), +				path); +	} else if(gpgsig->summary & GPGME_SIGSUM_KEY_MISSING) { +		handle->pm_errno = PM_ERR_SIG_UNKNOWN; +		_alpm_log(handle, PM_LOG_WARNING, _("File %s has a signature from an unknown key.\n"), +				path); +		ret = -1; +	} else { +		/* we'll capture everything else here */ +		handle->pm_errno = PM_ERR_SIG_INVALID; +		_alpm_log(handle, PM_LOG_ERROR, _("File %s has an invalid signature.\n"), +				path); +		ret = 1; +	} + +error: +	gpgme_data_release(sigdata); +	gpgme_data_release(filedata); +	gpgme_release(ctx); +	if(sigfile) { +		fclose(sigfile); +	} +	if(file) { +		fclose(file); +	} +	FREE(sigpath); +	FREE(decoded_sigdata); +	if(err != GPG_ERR_NO_ERROR) { +		_alpm_log(handle, PM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err)); +		RET_ERR(handle, PM_ERR_GPGME, -1); +	} +	return ret; +} +#else +int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path, +		const char *base64_sig) +{ +	return -1; +} +#endif + +/** + * Determines the necessity of checking for a valid PGP signature + * @param db the sync database to query + * + * @return signature verification level + */ +pgp_verify_t _alpm_db_get_sigverify_level(pmdb_t *db) +{ +	if(db->pgp_verify != PM_PGP_VERIFY_UNKNOWN) { +		return db->pgp_verify; +	} else { +		return alpm_option_get_default_sigverify(db->handle); +	} +} + +/** + * Check the PGP signature for the given package file. + * @param pkg the package to check + * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred) + */ +int SYMEXPORT alpm_pkg_check_pgp_signature(pmpkg_t *pkg) +{ +	ASSERT(pkg != NULL, return -1); +	pkg->handle->pm_errno = 0; + +	return _alpm_gpgme_checksig(pkg->handle, alpm_pkg_get_filename(pkg), +			pkg->base64_sig); +} + +/** + * Check the PGP signature for the given database. + * @param db the database to check + * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred) + */ +int SYMEXPORT alpm_db_check_pgp_signature(pmdb_t *db) +{ +	ASSERT(db != NULL, return -1); +	db->handle->pm_errno = 0; + +	return _alpm_gpgme_checksig(db->handle, _alpm_db_path(db), NULL); +} + +/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/signing.h b/lib/libalpm/signing.h new file mode 100644 index 00000000..fdf81fcf --- /dev/null +++ b/lib/libalpm/signing.h @@ -0,0 +1,30 @@ +/* + *  signing.h + * + *  Copyright (c) 2008-2011 Pacman Development Team <pacman-dev@archlinux.org> + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef _ALPM_SIGNING_H +#define _ALPM_SIGNING_H + +#include "alpm.h" + +int _alpm_gpgme_checksig(pmhandle_t *handle, const char *path, +		const char *base64_sig); +pgp_verify_t _alpm_db_get_sigverify_level(pmdb_t *db); + +#endif /* _ALPM_SIGNING_H */ + +/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index f83b0ef9..05735730 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -26,11 +26,9 @@  #include <sys/types.h> /* off_t */  #include <stdlib.h>  #include <stdio.h> -#include <fcntl.h>  #include <string.h>  #include <stdint.h> /* intmax_t */  #include <unistd.h> -#include <time.h>  #include <limits.h>  /* libalpm */ @@ -50,63 +48,61 @@  #include "delta.h"  #include "remove.h"  #include "diskspace.h" +#include "signing.h"  /** Check for new version of pkg in sync repos   * (only the first occurrence is considered in sync)   */  pmpkg_t SYMEXPORT *alpm_sync_newversion(pmpkg_t *pkg, alpm_list_t *dbs_sync)  { -	ASSERT(pkg != NULL, return(NULL)); -  	alpm_list_t *i;  	pmpkg_t *spkg = NULL; +	ASSERT(pkg != NULL, return NULL); +	pkg->handle->pm_errno = 0; +  	for(i = dbs_sync; !spkg && i; i = i->next) {  		spkg = _alpm_db_get_pkgfromcache(i->data, alpm_pkg_get_name(pkg));  	}  	if(spkg == NULL) { -		_alpm_log(PM_LOG_DEBUG, "'%s' not found in sync db => no upgrade\n", +		_alpm_log(pkg->handle, PM_LOG_DEBUG, "'%s' not found in sync db => no upgrade\n",  				alpm_pkg_get_name(pkg)); -		return(NULL); +		return NULL;  	}  	/* compare versions and see if spkg is an upgrade */  	if(_alpm_pkg_compare_versions(spkg, pkg) > 0) { -		_alpm_log(PM_LOG_DEBUG, "new version of '%s' found (%s => %s)\n", +		_alpm_log(pkg->handle, PM_LOG_DEBUG, "new version of '%s' found (%s => %s)\n",  					alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg),  					alpm_pkg_get_version(spkg)); -		return(spkg); +		return spkg;  	}  	/* spkg is not an upgrade */ -	return(NULL); +	return NULL;  } -/** Search for packages to upgrade and add them to the transaction. - * @return 0 on success, -1 on error (pm_errno is set accordingly) - */ -int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade) +/** Search for packages to upgrade and add them to the transaction. */ +int SYMEXPORT alpm_sync_sysupgrade(pmhandle_t *handle, int enable_downgrade)  {  	alpm_list_t *i, *j, *k;  	pmtrans_t *trans;  	pmdb_t *db_local;  	alpm_list_t *dbs_sync; -	ALPM_LOG_FUNC; - -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1);  	trans = handle->trans;  	db_local = handle->db_local;  	dbs_sync = handle->dbs_sync; -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); -	ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1)); +	ASSERT(trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1)); +	ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(handle, PM_ERR_TRANS_NOT_INITIALIZED, -1)); -	_alpm_log(PM_LOG_DEBUG, "checking for package upgrades\n"); +	_alpm_log(handle, PM_LOG_DEBUG, "checking for package upgrades\n");  	for(i = _alpm_db_get_pkgcache(db_local); i; i = i->next) {  		pmpkg_t *lpkg = i->data;  		if(_alpm_pkg_find(trans->add, lpkg->name)) { -			_alpm_log(PM_LOG_DEBUG, "%s is already in the target list -- skipping\n", lpkg->name); +			_alpm_log(handle, PM_LOG_DEBUG, "%s is already in the target list -- skipping\n", lpkg->name);  			continue;  		} @@ -116,46 +112,52 @@ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade)  			pmdb_t *sdb = j->data;  			/* Check sdb */  			pmpkg_t *spkg = _alpm_db_get_pkgfromcache(sdb, lpkg->name); -			if(spkg) { /* 1. literal was found in sdb */ +			if(spkg) { +				/* 1. literal was found in sdb */  				int cmp = _alpm_pkg_compare_versions(spkg, lpkg);  				if(cmp > 0) { -					_alpm_log(PM_LOG_DEBUG, "new version of '%s' found (%s => %s)\n", +					_alpm_log(handle, PM_LOG_DEBUG, "new version of '%s' found (%s => %s)\n",  								lpkg->name, lpkg->version, spkg->version);  					/* check IgnorePkg/IgnoreGroup */ -					if(_alpm_pkg_should_ignore(spkg) || _alpm_pkg_should_ignore(lpkg)) { -						_alpm_log(PM_LOG_WARNING, _("%s: ignoring package upgrade (%s => %s)\n"), -										lpkg->name, lpkg->version, spkg->version); +					if(_alpm_pkg_should_ignore(handle, spkg) +							|| _alpm_pkg_should_ignore(handle, lpkg)) { +						_alpm_log(handle, PM_LOG_WARNING, _("%s: ignoring package upgrade (%s => %s)\n"), +								lpkg->name, lpkg->version, spkg->version);  					} else { -						_alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n", +						_alpm_log(handle, PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",  												spkg->name, spkg->version);  						trans->add = alpm_list_add(trans->add, spkg);  					}  				} else if(cmp < 0) {  					if(enable_downgrade) {  						/* check IgnorePkg/IgnoreGroup */ -						if(_alpm_pkg_should_ignore(spkg) || _alpm_pkg_should_ignore(lpkg)) { -							_alpm_log(PM_LOG_WARNING, _("%s: ignoring package downgrade (%s => %s)\n"), +						if(_alpm_pkg_should_ignore(handle, spkg) +								|| _alpm_pkg_should_ignore(handle, lpkg)) { +							_alpm_log(handle, PM_LOG_WARNING, _("%s: ignoring package downgrade (%s => %s)\n"),  											lpkg->name, lpkg->version, spkg->version);  						} else { -							_alpm_log(PM_LOG_WARNING, _("%s: downgrading from version %s to version %s\n"), +							_alpm_log(handle, PM_LOG_WARNING, _("%s: downgrading from version %s to version %s\n"),  											lpkg->name, lpkg->version, spkg->version);  							trans->add = alpm_list_add(trans->add, spkg);  						}  					} else { -						_alpm_log(PM_LOG_WARNING, _("%s: local (%s) is newer than %s (%s)\n"), +						_alpm_log(handle, PM_LOG_WARNING, _("%s: local (%s) is newer than %s (%s)\n"),  								lpkg->name, lpkg->version, sdb->treename, spkg->version);  					}  				} -				break; /* jump to next local package */ -			} else { /* 2. search for replacers in sdb */ +				/* jump to next local package */ +				break; +			} else { +				/* 2. search for replacers in sdb */  				int found = 0;  				for(k = _alpm_db_get_pkgcache(sdb); k; k = k->next) {  					spkg = k->data;  					if(alpm_list_find_str(alpm_pkg_get_replaces(spkg), lpkg->name)) {  						found = 1;  						/* check IgnorePkg/IgnoreGroup */ -						if(_alpm_pkg_should_ignore(spkg) || _alpm_pkg_should_ignore(lpkg)) { -							_alpm_log(PM_LOG_WARNING, _("ignoring package replacement (%s-%s => %s-%s)\n"), +						if(_alpm_pkg_should_ignore(handle, spkg) +								|| _alpm_pkg_should_ignore(handle, lpkg)) { +							_alpm_log(handle, PM_LOG_WARNING, _("ignoring package replacement (%s-%s => %s-%s)\n"),  										lpkg->name, lpkg->version, spkg->name, spkg->version);  							continue;  						} @@ -172,22 +174,23 @@ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade)  						if(tpkg) {  							/* sanity check, multiple repos can contain spkg->name */  							if(tpkg->origin_data.db != sdb) { -								_alpm_log(PM_LOG_WARNING, _("cannot replace %s by %s\n"), +								_alpm_log(handle, PM_LOG_WARNING, _("cannot replace %s by %s\n"),  													lpkg->name, spkg->name);  								continue;  							} -							_alpm_log(PM_LOG_DEBUG, "appending %s to the removes list of %s\n", +							_alpm_log(handle, PM_LOG_DEBUG, "appending %s to the removes list of %s\n",  												lpkg->name, tpkg->name);  							tpkg->removes = alpm_list_add(tpkg->removes, lpkg);  							/* check the to-be-replaced package's reason field */  							if(alpm_pkg_get_reason(lpkg) == PM_PKG_REASON_EXPLICIT) {  								tpkg->reason = PM_PKG_REASON_EXPLICIT;  							} -						} else { /* add spkg to the target list */ +						} else { +							/* add spkg to the target list */  							/* copy over reason */  							spkg->reason = alpm_pkg_get_reason(lpkg);  							spkg->removes = alpm_list_add(NULL, lpkg); -							_alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n", +							_alpm_log(handle, PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",  													spkg->name, spkg->version);  							trans->add = alpm_list_add(trans->add, spkg);  						} @@ -200,7 +203,7 @@ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade)  		}  	} -	return(0); +	return 0;  }  /** Find group members across a list of databases. @@ -228,10 +231,10 @@ alpm_list_t SYMEXPORT *alpm_find_grp_pkgs(alpm_list_t *dbs,  			if(_alpm_pkg_find(ignorelist, alpm_pkg_get_name(pkg))) {  				continue;  			} -			if(_alpm_pkg_should_ignore(pkg)) { +			if(_alpm_pkg_should_ignore(db->handle, pkg)) {  				ignorelist = alpm_list_add(ignorelist, pkg);  				int install = 0; -				QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, +				QUESTION(db->handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg,  						NULL, NULL, &install);  				if(!install)  					continue; @@ -242,7 +245,7 @@ alpm_list_t SYMEXPORT *alpm_find_grp_pkgs(alpm_list_t *dbs,  		}  	}  	alpm_list_free(ignorelist); -	return(pkgs); +	return pkgs;  }  /** Compute the size of the files that will be downloaded to install a @@ -254,16 +257,17 @@ static int compute_download_size(pmpkg_t *newpkg)  	const char *fname;  	char *fpath;  	off_t size = 0; +	pmhandle_t *handle = newpkg->handle;  	if(newpkg->origin != PKG_FROM_SYNCDB) {  		newpkg->infolevel |= INFRQ_DSIZE;  		newpkg->download_size = 0; -		return(0); +		return 0;  	}  	fname = alpm_pkg_get_filename(newpkg); -	ASSERT(fname != NULL, RET_ERR(PM_ERR_PKG_INVALID_NAME, -1)); -	fpath = _alpm_filecache_find(fname); +	ASSERT(fname != NULL, RET_ERR(handle, PM_ERR_PKG_INVALID_NAME, -1)); +	fpath = _alpm_filecache_find(handle, fname);  	if(fpath) {  		FREE(fpath); @@ -272,16 +276,16 @@ static int compute_download_size(pmpkg_t *newpkg)  		off_t dltsize;  		off_t pkgsize = alpm_pkg_get_size(newpkg); -		dltsize = _alpm_shortest_delta_path( +		dltsize = _alpm_shortest_delta_path(handle,  			alpm_pkg_get_deltas(newpkg),  			alpm_pkg_get_filename(newpkg),  			&newpkg->delta_path);  		if(newpkg->delta_path && (dltsize < pkgsize * MAX_DELTA_RATIO)) { -			_alpm_log(PM_LOG_DEBUG, "using delta size\n"); +			_alpm_log(handle, PM_LOG_DEBUG, "using delta size\n");  			size = dltsize;  		} else { -			_alpm_log(PM_LOG_DEBUG, "using package size\n"); +			_alpm_log(handle, PM_LOG_DEBUG, "using package size\n");  			size = alpm_pkg_get_size(newpkg);  			alpm_list_free(newpkg->delta_path);  			newpkg->delta_path = NULL; @@ -290,26 +294,22 @@ static int compute_download_size(pmpkg_t *newpkg)  		size = alpm_pkg_get_size(newpkg);  	} -	_alpm_log(PM_LOG_DEBUG, "setting download size %jd for pkg %s\n", +	_alpm_log(handle, PM_LOG_DEBUG, "setting download size %jd for pkg %s\n",  			(intmax_t)size, alpm_pkg_get_name(newpkg));  	newpkg->infolevel |= INFRQ_DSIZE;  	newpkg->download_size = size; -	return(0); +	return 0;  } -int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **data) +int _alpm_sync_prepare(pmhandle_t *handle, alpm_list_t **data)  { +	alpm_list_t *i, *j;  	alpm_list_t *deps = NULL;  	alpm_list_t *unresolvable = NULL; -	alpm_list_t *i, *j;  	alpm_list_t *remove = NULL;  	int ret = 0; - -	ALPM_LOG_FUNC; - -	ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); +	pmtrans_t *trans = handle->trans;  	if(data) {  		*data = NULL; @@ -321,7 +321,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync  		/* Build up list by repeatedly resolving each transaction package */  		/* Resolve targets dependencies */  		EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL); -		_alpm_log(PM_LOG_DEBUG, "resolving target's dependencies\n"); +		_alpm_log(handle, PM_LOG_DEBUG, "resolving target's dependencies\n");  		/* build remove list for resolvedeps */  		for(i = trans->add; i; i = i->next) { @@ -333,14 +333,14 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync  		/* Compute the fake local database for resolvedeps (partial fix for the  		 * phonon/qt issue) */ -		alpm_list_t *localpkgs = alpm_list_diff(_alpm_db_get_pkgcache(db_local), +		alpm_list_t *localpkgs = alpm_list_diff(_alpm_db_get_pkgcache(handle->db_local),  				trans->add, _alpm_pkg_cmp);  		/* Resolve packages in the transaction one at a time, in addition  		   building up a list of packages which could not be resolved. */  		for(i = trans->add; i; i = i->next) {  			pmpkg_t *pkg = i->data; -			if(_alpm_resolvedeps(localpkgs, dbs_sync, pkg, trans->add, +			if(_alpm_resolvedeps(handle, localpkgs, pkg, trans->add,  						&resolved, remove, data) == -1) {  				unresolvable = alpm_list_add(unresolvable, pkg);  			} @@ -353,14 +353,14 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync  		   see if they'd like to ignore them rather than failing the sync */  		if(unresolvable != NULL) {  			int remove_unresolvable = 0; -			QUESTION(handle->trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable, +			QUESTION(trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable,  					NULL, NULL, &remove_unresolvable); -			if (remove_unresolvable) { +			if(remove_unresolvable) {  				/* User wants to remove the unresolvable packages from the  				   transaction. The packages will be removed from the actual  				   transaction when the transaction packages are replaced with a  				   dependency-reordered list below */ -				pm_errno = 0; /* pm_errno was set by resolvedeps */ +				handle->pm_errno = 0; /* pm_errno was set by resolvedeps */  				if(data) {  					alpm_list_free_inner(*data, (alpm_list_fn_free)_alpm_depmiss_free);  					alpm_list_free(*data); @@ -388,7 +388,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync  		/* re-order w.r.t. dependencies */  		alpm_list_free(trans->add); -		trans->add = _alpm_sortbydeps(resolved, 0); +		trans->add = _alpm_sortbydeps(handle, resolved, 0);  		alpm_list_free(resolved);  		EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_DONE, NULL, NULL); @@ -398,11 +398,11 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync  		/* check for inter-conflicts and whatnot */  		EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_START, NULL, NULL); -		_alpm_log(PM_LOG_DEBUG, "looking for conflicts\n"); +		_alpm_log(handle, PM_LOG_DEBUG, "looking for conflicts\n");  		/* 1. check for conflicts in the target list */ -		_alpm_log(PM_LOG_DEBUG, "check targets vs targets\n"); -		deps = _alpm_innerconflicts(trans->add); +		_alpm_log(handle, PM_LOG_DEBUG, "check targets vs targets\n"); +		deps = _alpm_innerconflicts(handle, trans->add);  		for(i = deps; i; i = i->next) {  			pmconflict_t *conflict = i->data; @@ -415,7 +415,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync  				continue;  			} -			_alpm_log(PM_LOG_DEBUG, "conflicting packages in the sync list: '%s' <-> '%s'\n", +			_alpm_log(handle, PM_LOG_DEBUG, "conflicting packages in the sync list: '%s' <-> '%s'\n",  					conflict->package1, conflict->package2);  			/* if sync1 provides sync2, we remove sync2 from the targets, and vice versa */ @@ -428,8 +428,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync  				rsync = sync1;  				sync = sync2;  			} else { -				_alpm_log(PM_LOG_ERROR, _("unresolvable package conflicts detected\n")); -				pm_errno = PM_ERR_CONFLICTING_DEPS; +				_alpm_log(handle, PM_LOG_ERROR, _("unresolvable package conflicts detected\n")); +				handle->pm_errno = PM_ERR_CONFLICTING_DEPS;  				ret = -1;  				if(data) {  					pmconflict_t *newconflict = _alpm_conflict_dup(conflict); @@ -447,7 +447,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync  			_alpm_dep_free(dep2);  			/* Prints warning */ -			_alpm_log(PM_LOG_WARNING, +			_alpm_log(handle, PM_LOG_WARNING,  					_("removing '%s' from target list because it conflicts with '%s'\n"),  					rsync->name, sync->name);  			trans->add = alpm_list_remove(trans->add, rsync, _alpm_pkg_cmp, NULL); @@ -460,8 +460,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync  		deps = NULL;  		/* 2. we check for target vs db conflicts (and resolve)*/ -		_alpm_log(PM_LOG_DEBUG, "check targets vs db and db vs targets\n"); -		deps = _alpm_outerconflicts(db_local, trans->add); +		_alpm_log(handle, PM_LOG_DEBUG, "check targets vs db and db vs targets\n"); +		deps = _alpm_outerconflicts(handle->db_local, trans->add);  		for(i = deps; i; i = i->next) {  			pmconflict_t *conflict = i->data; @@ -479,21 +479,21 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync  				continue;  			} -			_alpm_log(PM_LOG_DEBUG, "package '%s' conflicts with '%s'\n", +			_alpm_log(handle, PM_LOG_DEBUG, "package '%s' conflicts with '%s'\n",  					conflict->package1, conflict->package2);  			pmpkg_t *sync = _alpm_pkg_find(trans->add, conflict->package1); -			pmpkg_t *local = _alpm_db_get_pkgfromcache(db_local, conflict->package2); +			pmpkg_t *local = _alpm_db_get_pkgfromcache(handle->db_local, conflict->package2);  			int doremove = 0;  			QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, conflict->package1,  							conflict->package2, conflict->reason, &doremove);  			if(doremove) {  				/* append to the removes list */ -				_alpm_log(PM_LOG_DEBUG, "electing '%s' for removal\n", conflict->package2); +				_alpm_log(handle, PM_LOG_DEBUG, "electing '%s' for removal\n", conflict->package2);  				sync->removes = alpm_list_add(sync->removes, local);  			} else { /* abort */ -				_alpm_log(PM_LOG_ERROR, _("unresolvable package conflicts detected\n")); -				pm_errno = PM_ERR_CONFLICTING_DEPS; +				_alpm_log(handle, PM_LOG_ERROR, _("unresolvable package conflicts detected\n")); +				handle->pm_errno = PM_ERR_CONFLICTING_DEPS;  				ret = -1;  				if(data) {  					pmconflict_t *newconflict = _alpm_conflict_dup(conflict); @@ -517,17 +517,18 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync  		for(j = spkg->removes; j; j = j->next) {  			pmpkg_t *rpkg = j->data;  			if(!_alpm_pkg_find(trans->remove, rpkg->name)) { -				_alpm_log(PM_LOG_DEBUG, "adding '%s' to remove list\n", rpkg->name); +				_alpm_log(handle, PM_LOG_DEBUG, "adding '%s' to remove list\n", rpkg->name);  				trans->remove = alpm_list_add(trans->remove, _alpm_pkg_dup(rpkg));  			}  		}  	}  	if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) { -		_alpm_log(PM_LOG_DEBUG, "checking dependencies\n"); -		deps = alpm_checkdeps(_alpm_db_get_pkgcache(db_local), 1, trans->remove, trans->add); +		_alpm_log(handle, PM_LOG_DEBUG, "checking dependencies\n"); +		deps = alpm_checkdeps(handle, _alpm_db_get_pkgcache(handle->db_local), +				trans->remove, trans->add, 1);  		if(deps) { -			pm_errno = PM_ERR_UNSATISFIED_DEPS; +			handle->pm_errno = PM_ERR_UNSATISFIED_DEPS;  			ret = -1;  			if(data) {  				*data = deps; @@ -551,7 +552,7 @@ cleanup:  	alpm_list_free(unresolvable);  	alpm_list_free(remove); -	return(ret); +	return ret;  }  /** Returns the size of the files that will be downloaded to install a @@ -564,13 +565,13 @@ off_t SYMEXPORT alpm_pkg_download_size(pmpkg_t *newpkg)  	if(!(newpkg->infolevel & INFRQ_DSIZE)) {  		compute_download_size(newpkg);  	} -	return(newpkg->download_size); +	return newpkg->download_size;  }  static int endswith(const char *filename, const char *extension)  {  	const char *s = filename + strlen(filename) - strlen(extension); -	return(strcmp(s, extension) == 0); +	return strcmp(s, extension) == 0;  }  /** Applies delta files to create an upgraded package file. @@ -578,15 +579,16 @@ static int endswith(const char *filename, const char *extension)   * All intermediate files are deleted, leaving only the starting and   * ending package files.   * - * @param trans the transaction + * @param handle the context handle   *   * @return 0 if all delta files were able to be applied, 1 otherwise.   */ -static int apply_deltas(pmtrans_t *trans) +static int apply_deltas(pmhandle_t *handle)  {  	alpm_list_t *i;  	int ret = 0; -	const char *cachedir = _alpm_filecache_setup(); +	const char *cachedir = _alpm_filecache_setup(handle); +	pmtrans_t *trans = handle->trans;  	for(i = trans->add; i; i = i->next) {  		pmpkg_t *spkg = i->data; @@ -603,18 +605,18 @@ static int apply_deltas(pmtrans_t *trans)  			char command[PATH_MAX];  			size_t len = 0; -			delta = _alpm_filecache_find(d->delta); +			delta = _alpm_filecache_find(handle, d->delta);  			/* the initial package might be in a different cachedir */  			if(dlts == delta_path) { -				from = _alpm_filecache_find(d->from); +				from = _alpm_filecache_find(handle, d->from);  			} else {  				/* len = cachedir len + from len + '/' + null */  				len = strlen(cachedir) + strlen(d->from) + 2; -				CALLOC(from, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, 1)); +				CALLOC(from, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, 1));  				snprintf(from, len, "%s/%s", cachedir, d->from);  			}  			len = strlen(cachedir) + strlen(d->to) + 2; -			CALLOC(to, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, 1)); +			CALLOC(to, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, 1));  			snprintf(to, len, "%s/%s", cachedir, d->to);  			/* build the patch command */ @@ -625,7 +627,7 @@ static int apply_deltas(pmtrans_t *trans)  				snprintf(command, PATH_MAX, "xdelta3 -d -q -s %s %s %s", from, delta, to);  			} -			_alpm_log(PM_LOG_DEBUG, "command: %s\n", command); +			_alpm_log(handle, PM_LOG_DEBUG, "command: %s\n", command);  			EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_START, d->to, d->delta); @@ -650,13 +652,14 @@ static int apply_deltas(pmtrans_t *trans)  			if(retval != 0) {  				/* one delta failed for this package, cancel the remaining ones */  				EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_FAILED, NULL, NULL); +				handle->pm_errno = PM_ERR_DLT_PATCHFAILED;  				ret = 1;  				break;  			}  		}  	} -	return(ret); +	return ret;  }  /** Compares the md5sum of a file to the expected value. @@ -665,50 +668,75 @@ static int apply_deltas(pmtrans_t *trans)   * should be deleted.   *   * @param trans the transaction - * @param filename the filename of the file to test + * @param filename the absolute path of the file to test   * @param md5sum the expected md5sum of the file   *   * @return 0 if the md5sum matched, 1 if not, -1 in case of errors   */ -static int test_md5sum(pmtrans_t *trans, const char *filename, +static int test_md5sum(pmtrans_t *trans, const char *filepath,  		const char *md5sum)  { -	char *filepath; -	int ret; - -	filepath = _alpm_filecache_find(filename); - -	ret = _alpm_test_md5sum(filepath, md5sum); - +	int ret = _alpm_test_md5sum(filepath, md5sum);  	if(ret == 1) {  		int doremove = 0; -		QUESTION(trans, PM_TRANS_CONV_CORRUPTED_PKG, (char *)filename, +		QUESTION(trans, PM_TRANS_CONV_CORRUPTED_PKG, (char *)filepath,  				NULL, NULL, &doremove);  		if(doremove) {  			unlink(filepath);  		}  	} -	FREE(filepath); - -	return(ret); +	return ret;  } -int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) +static int validate_deltas(pmhandle_t *handle, alpm_list_t *deltas, +		alpm_list_t **data)  { -	alpm_list_t *i, *j, *files = NULL; -	alpm_list_t *deltas = NULL; -	size_t numtargs, current = 0, replaces = 0; -	int errors = 0; -	const char *cachedir = NULL; -	int ret = -1; +	int errors = 0, ret = 0; +	alpm_list_t *i; +	pmtrans_t *trans = handle->trans; -	ALPM_LOG_FUNC; +	if(!deltas) { +		return 0; +	} -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); +	/* Check integrity of deltas */ +	EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_START, NULL, NULL); -	cachedir = _alpm_filecache_setup(); -	trans->state = STATE_DOWNLOADING; +	for(i = deltas; i; i = i->next) { +		pmdelta_t *d = alpm_list_getdata(i); +		const char *filename = alpm_delta_get_filename(d); +		char *filepath = _alpm_filecache_find(handle, filename); +		const char *md5sum = alpm_delta_get_md5sum(d); + +		if(test_md5sum(trans, filepath, md5sum) != 0) { +			errors++; +			*data = alpm_list_add(*data, strdup(filename)); +		} +		FREE(filepath); +	} +	if(errors) { +		handle->pm_errno = PM_ERR_DLT_INVALID; +		return -1; +	} +	EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_DONE, NULL, NULL); + +	/* Use the deltas to generate the packages */ +	EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_START, NULL, NULL); +	ret = apply_deltas(handle); +	EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_DONE, NULL, NULL); +	return ret; +} + +static int download_files(pmhandle_t *handle, alpm_list_t **deltas) +{ +	const char *cachedir; +	alpm_list_t *i, *j; +	alpm_list_t *files = NULL; +	int errors = 0; + +	cachedir = _alpm_filecache_setup(handle); +	handle->trans->state = STATE_DOWNLOADING;  	/* Total progress - figure out the total download size if required to  	 * pass to the callback. This function is called once, and it is up to the @@ -716,7 +744,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)  	if(handle->totaldlcb) {  		off_t total_size = (off_t)0;  		/* sum up the download size for each package and store total */ -		for(i = trans->add; i; i = i->next) { +		for(i = handle->trans->add; i; i = i->next) {  			pmpkg_t *spkg = i->data;  			total_size += spkg->download_size;  		} @@ -727,59 +755,74 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)  	for(i = handle->dbs_sync; i; i = i->next) {  		pmdb_t *current = i->data; -		for(j = trans->add; j; j = j->next) { +		for(j = handle->trans->add; j; j = j->next) {  			pmpkg_t *spkg = j->data;  			if(spkg->origin != PKG_FROM_FILE && current == spkg->origin_data.db) {  				const char *fname = NULL;  				fname = alpm_pkg_get_filename(spkg); -				ASSERT(fname != NULL, RET_ERR(PM_ERR_PKG_INVALID_NAME, -1)); +				ASSERT(fname != NULL, RET_ERR(handle, PM_ERR_PKG_INVALID_NAME, -1));  				alpm_list_t *delta_path = spkg->delta_path;  				if(delta_path) {  					/* using deltas */ -					alpm_list_t *dlts = NULL; - +					alpm_list_t *dlts;  					for(dlts = delta_path; dlts; dlts = dlts->next) { -						pmdelta_t *d = dlts->data; - -						if(d->download_size != 0) { -							/* add the delta filename to the download list if needed */ -							files = alpm_list_add(files, strdup(d->delta)); +						pmdelta_t *delta = dlts->data; +						if(delta->download_size != 0) { +							files = alpm_list_add(files, strdup(delta->delta));  						} -  						/* keep a list of all the delta files for md5sums */ -						deltas = alpm_list_add(deltas, d); +						*deltas = alpm_list_add(*deltas, delta);  					} -				} else { -					/* not using deltas */ -					if(spkg->download_size != 0) { -						/* add the filename to the download list if needed */ -						files = alpm_list_add(files, strdup(fname)); -					} +				} else if(spkg->download_size != 0) { +					files = alpm_list_add(files, strdup(fname));  				}  			}  		}  		if(files) { -			EVENT(trans, PM_TRANS_EVT_RETRIEVE_START, current->treename, NULL); -			errors = _alpm_download_files(files, current->servers, cachedir); +			EVENT(handle->trans, PM_TRANS_EVT_RETRIEVE_START, current->treename, NULL); +			for(j = files; j; j = j->next) { +				const char *filename = j->data; +				alpm_list_t *server; +				int ret = -1; +				for(server = current->servers; server; server = server->next) { +					const char *server_url = server->data; +					char *fileurl; +					size_t len; + +					/* print server + filename into a buffer */ +					len = strlen(server_url) + strlen(filename) + 2; +					CALLOC(fileurl, len, sizeof(char), RET_ERR(handle, PM_ERR_MEMORY, -1)); +					snprintf(fileurl, len, "%s/%s", server_url, filename); + +					ret = _alpm_download(handle, fileurl, cachedir, 0, 1, 0); +					FREE(fileurl); +					if(ret != -1) { +						break; +					} +				} +				if(ret == -1) { +					errors++; +				} +			} -			if (errors) { -				_alpm_log(PM_LOG_WARNING, _("failed to retrieve some files from %s\n"), +			FREELIST(files); +			if(errors) { +				_alpm_log(handle, PM_LOG_WARNING, _("failed to retrieve some files from %s\n"),  						current->treename); -				if(pm_errno == 0) { -					pm_errno = PM_ERR_RETRIEVE; +				if(handle->pm_errno == 0) { +					handle->pm_errno = PM_ERR_RETRIEVE;  				} -				goto error; +				return -1;  			} -			FREELIST(files);  		}  	} -	for(j = trans->add; j; j = j->next) { +	for(j = handle->trans->add; j; j = j->next) {  		pmpkg_t *pkg = j->data;  		pkg->infolevel &= ~INFRQ_DSIZE;  		pkg->download_size = 0; @@ -789,70 +832,60 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)  	if(handle->totaldlcb) {  		handle->totaldlcb(0);  	} +	return 0; +} -	/* if we have deltas to work with */ -	if(handle->usedelta && deltas) { -		int ret = 0; -		errors = 0; -		/* Check integrity of deltas */ -		EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_START, NULL, NULL); - -		for(i = deltas; i; i = i->next) { -			pmdelta_t *d = alpm_list_getdata(i); -			const char *filename = alpm_delta_get_filename(d); -			const char *md5sum = alpm_delta_get_md5sum(d); - -			if(test_md5sum(trans, filename, md5sum) != 0) { -				errors++; -				*data = alpm_list_add(*data, strdup(filename)); -			} -		} -		if(errors) { -			pm_errno = PM_ERR_DLT_INVALID; -			goto error; -		} -		EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_DONE, NULL, NULL); +int _alpm_sync_commit(pmhandle_t *handle, alpm_list_t **data) +{ +	alpm_list_t *i; +	alpm_list_t *deltas = NULL; +	size_t numtargs, current = 0, replaces = 0; +	int errors; +	pmtrans_t *trans = handle->trans; -		/* Use the deltas to generate the packages */ -		EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_START, NULL, NULL); -		ret = apply_deltas(trans); -		EVENT(trans, PM_TRANS_EVT_DELTA_PATCHES_DONE, NULL, NULL); +	if(download_files(handle, &deltas)) { +		alpm_list_free(deltas); +		return -1; +	} -		if(ret) { -			pm_errno = PM_ERR_DLT_PATCHFAILED; -			goto error; -		} +	if(validate_deltas(handle, deltas, data)) { +		alpm_list_free(deltas); +		return -1;  	} +	alpm_list_free(deltas);  	/* Check integrity of packages */  	numtargs = alpm_list_count(trans->add);  	EVENT(trans, PM_TRANS_EVT_INTEGRITY_START, NULL, NULL);  	errors = 0; +  	for(i = trans->add; i; i = i->next, current++) {  		pmpkg_t *spkg = i->data;  		int percent = (current * 100) / numtargs; +		const char *filename; +		char *filepath; +		pgp_verify_t check_sig; + +		PROGRESS(trans, PM_TRANS_PROGRESS_INTEGRITY_START, "", percent, +				numtargs, current);  		if(spkg->origin == PKG_FROM_FILE) {  			continue; /* pkg_load() has been already called, this package is valid */  		} -		PROGRESS(trans, PM_TRANS_PROGRESS_INTEGRITY_START, "", percent, -				numtargs, current); -		const char *filename = alpm_pkg_get_filename(spkg); -		const char *md5sum = alpm_pkg_get_md5sum(spkg); +		filename = alpm_pkg_get_filename(spkg); +		filepath = _alpm_filecache_find(handle, filename); +		pmdb_t *sdb = alpm_pkg_get_db(spkg); +		check_sig = _alpm_db_get_sigverify_level(sdb); -		if(test_md5sum(trans, filename, md5sum) != 0) { -			errors++; -			*data = alpm_list_add(*data, strdup(filename)); -			continue; -		}  		/* load the package file and replace pkgcache entry with it in the target list */  		/* TODO: alpm_pkg_get_db() will not work on this target anymore */ -		_alpm_log(PM_LOG_DEBUG, "replacing pkgcache entry with package file for target %s\n", spkg->name); -		char *filepath = _alpm_filecache_find(filename); -		pmpkg_t *pkgfile; -		if(alpm_pkg_load(filepath, 1, &pkgfile) != 0) { -			_alpm_pkg_free(pkgfile); +		_alpm_log(handle, PM_LOG_DEBUG, +				"replacing pkgcache entry with package file for target %s\n", +				spkg->name); +		pmpkg_t *pkgfile =_alpm_pkg_load_internal(handle, filepath, 1, spkg->md5sum, +				spkg->base64_sig, check_sig); +		if(!pkgfile) {  			errors++;  			*data = alpm_list_add(*data, strdup(filename));  			FREE(filepath); @@ -863,17 +896,18 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)  		i->data = pkgfile;  		_alpm_pkg_free_trans(spkg); /* spkg has been removed from the target list */  	} +  	PROGRESS(trans, PM_TRANS_PROGRESS_INTEGRITY_START, "", 100,  			numtargs, current);  	EVENT(trans, PM_TRANS_EVT_INTEGRITY_DONE, NULL, NULL); + +  	if(errors) { -		pm_errno = PM_ERR_PKG_INVALID; -		goto error; +		RET_ERR(handle, PM_ERR_PKG_INVALID, -1);  	}  	if(trans->flags & PM_TRANS_FLAG_DOWNLOADONLY) { -		ret = 0; -		goto error; +		return 0;  	}  	trans->state = STATE_COMMITING; @@ -884,18 +918,17 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)  	if(!(trans->flags & PM_TRANS_FLAG_FORCE)) {  		EVENT(trans, PM_TRANS_EVT_FILECONFLICTS_START, NULL, NULL); -		_alpm_log(PM_LOG_DEBUG, "looking for file conflicts\n"); -		alpm_list_t *conflict = _alpm_db_find_fileconflicts(db_local, trans, -								    trans->add, trans->remove); +		_alpm_log(handle, PM_LOG_DEBUG, "looking for file conflicts\n"); +		alpm_list_t *conflict = _alpm_db_find_fileconflicts(handle, +				trans->add, trans->remove);  		if(conflict) { -			pm_errno = PM_ERR_FILE_CONFLICTS;  			if(data) {  				*data = conflict;  			} else {  				alpm_list_free_inner(conflict, (alpm_list_fn_free)_alpm_fileconflict_free);  				alpm_list_free(conflict);  			} -			goto error; +			RET_ERR(handle, PM_ERR_FILE_CONFLICTS, -1);  		}  		EVENT(trans, PM_TRANS_EVT_FILECONFLICTS_DONE, NULL, NULL); @@ -905,10 +938,10 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)  	if(handle->checkspace) {  		EVENT(trans, PM_TRANS_EVT_DISKSPACE_START, NULL, NULL); -		_alpm_log(PM_LOG_DEBUG, "checking available disk space\n"); -		if(_alpm_check_diskspace(trans, handle->db_local) == -1) { -			_alpm_log(PM_LOG_ERROR, "%s\n", _("not enough free disk space")); -			goto error; +		_alpm_log(handle, PM_LOG_DEBUG, "checking available disk space\n"); +		if(_alpm_check_diskspace(handle) == -1) { +			_alpm_log(handle, PM_LOG_ERROR, "%s\n", _("not enough free disk space")); +			return -1;  		}  		EVENT(trans, PM_TRANS_EVT_DISKSPACE_DONE, NULL, NULL); @@ -916,26 +949,22 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)  	/* remove conflicting and to-be-replaced packages */  	if(replaces) { -		_alpm_log(PM_LOG_DEBUG, "removing conflicting and to-be-replaced packages\n"); +		_alpm_log(handle, PM_LOG_DEBUG, "removing conflicting and to-be-replaced packages\n");  		/* we want the frontend to be aware of commit details */ -		if(_alpm_remove_packages(trans, handle->db_local) == -1) { -			_alpm_log(PM_LOG_ERROR, _("could not commit removal transaction\n")); -			goto error; +		if(_alpm_remove_packages(handle) == -1) { +			_alpm_log(handle, PM_LOG_ERROR, _("could not commit removal transaction\n")); +			return -1;  		}  	}  	/* install targets */ -	_alpm_log(PM_LOG_DEBUG, "installing packages\n"); -	if(_alpm_upgrade_packages(trans, handle->db_local) == -1) { -		_alpm_log(PM_LOG_ERROR, _("could not commit transaction\n")); -		goto error; +	_alpm_log(handle, PM_LOG_DEBUG, "installing packages\n"); +	if(_alpm_upgrade_packages(handle) == -1) { +		_alpm_log(handle, PM_LOG_ERROR, _("could not commit transaction\n")); +		return -1;  	} -	ret = 0; -error: -	FREELIST(files); -	alpm_list_free(deltas); -	return(ret); +	return 0;  }  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/sync.h b/lib/libalpm/sync.h index 90a2d40d..3049dd21 100644 --- a/lib/libalpm/sync.h +++ b/lib/libalpm/sync.h @@ -24,8 +24,8 @@  #include "alpm.h" -int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **data); -int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data); +int _alpm_sync_prepare(pmhandle_t *handle, alpm_list_t **data); +int _alpm_sync_commit(pmhandle_t *handle, alpm_list_t **data);  #endif /* _ALPM_SYNC_H */ diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index bf9ef722..f0744937 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -28,8 +28,6 @@  #include <string.h>  #include <unistd.h>  #include <sys/types.h> -#include <sys/stat.h> -#include <sys/statvfs.h>  #include <errno.h>  #include <limits.h>  #include <fcntl.h> @@ -41,11 +39,9 @@  #include "util.h"  #include "log.h"  #include "handle.h" -#include "add.h"  #include "remove.h"  #include "sync.h"  #include "alpm.h" -#include "deps.h"  /** \addtogroup alpm_trans Transaction Functions   * @brief Functions to manipulate libalpm transactions @@ -68,22 +64,22 @@ static int make_lock(pmhandle_t *handle)  	}  	if(_alpm_makepath(dir)) {  		FREE(dir); -		return(-1); +		return -1;  	}  	FREE(dir);  	do {  		fd = open(handle->lockfile, O_WRONLY | O_CREAT | O_EXCL, 0000); -	} while (fd == -1 && errno == EINTR); +	} while(fd == -1 && errno == EINTR);  	if(fd > 0) {  		FILE *f = fdopen(fd, "w");  		fprintf(f, "%ld\n", (long)getpid());  		fflush(f);  		fsync(fd);  		handle->lckstream = f; -		return(0); +		return 0;  	} -	return(-1); +	return -1;  }  /* Remove a lock file */ @@ -94,13 +90,13 @@ static int remove_lock(pmhandle_t *handle)  		handle->lckstream = NULL;  	}  	if(unlink(handle->lockfile) == -1 && errno != ENOENT) { -		return(-1); +		return -1;  	} -	return(0); +	return 0;  }  /** Initialize the transaction. */ -int SYMEXPORT alpm_trans_init(pmtransflag_t flags, +int SYMEXPORT alpm_trans_init(pmhandle_t *handle, pmtransflag_t flags,  		alpm_trans_cb_event event, alpm_trans_cb_conv conv,  		alpm_trans_cb_progress progress)  { @@ -108,53 +104,47 @@ int SYMEXPORT alpm_trans_init(pmtransflag_t flags,  	const int required_db_version = 2;  	int db_version; -	ALPM_LOG_FUNC; -  	/* Sanity checks */ -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); -	ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1)); +	CHECK_HANDLE(handle, return -1); +	ASSERT(handle->trans == NULL, RET_ERR(handle, PM_ERR_TRANS_NOT_NULL, -1));  	/* lock db */  	if(!(flags & PM_TRANS_FLAG_NOLOCK)) {  		if(make_lock(handle)) { -			RET_ERR(PM_ERR_HANDLE_LOCK, -1); +			RET_ERR(handle, PM_ERR_HANDLE_LOCK, -1);  		}  	} -	trans = _alpm_trans_new(); -	if(trans == NULL) { -		RET_ERR(PM_ERR_MEMORY, -1); -	} - +	CALLOC(trans, 1, sizeof(pmtrans_t), RET_ERR(handle, PM_ERR_MEMORY, -1));  	trans->flags = flags;  	trans->cb_event = event;  	trans->cb_conv = conv;  	trans->cb_progress = progress;  	trans->state = STATE_INITIALIZED; -	handle->trans = trans; -  	/* check database version */  	db_version = _alpm_db_version(handle->db_local);  	if(db_version < required_db_version) { -		_alpm_log(PM_LOG_ERROR, +		_alpm_log(handle, PM_LOG_ERROR,  				_("%s database version is too old\n"), handle->db_local->treename);  		remove_lock(handle);  		_alpm_trans_free(trans); -		RET_ERR(PM_ERR_DB_VERSION, -1); +		RET_ERR(handle, PM_ERR_DB_VERSION, -1);  	} -	return(0); +	handle->trans = trans; + +	return 0;  } -static alpm_list_t *check_arch(alpm_list_t *pkgs) +static alpm_list_t *check_arch(pmhandle_t *handle, alpm_list_t *pkgs)  {  	alpm_list_t *i;  	alpm_list_t *invalid = NULL; -	const char *arch = alpm_option_get_arch(); +	const char *arch = alpm_option_get_arch(handle);  	if(!arch) { -		return(NULL); +		return NULL;  	}  	for(i = pkgs; i; i = i->next) {  		pmpkg_t *pkg = i->data; @@ -164,134 +154,126 @@ static alpm_list_t *check_arch(alpm_list_t *pkgs)  			const char *pkgname = alpm_pkg_get_name(pkg);  			const char *pkgver = alpm_pkg_get_version(pkg);  			size_t len = strlen(pkgname) + strlen(pkgver) + strlen(pkgarch) + 3; -			MALLOC(string, len, RET_ERR(PM_ERR_MEMORY, invalid)); +			MALLOC(string, len, RET_ERR(handle, PM_ERR_MEMORY, invalid));  			sprintf(string, "%s-%s-%s", pkgname, pkgver, pkgarch);  			invalid = alpm_list_add(invalid, string);  		}  	} -	return(invalid); +	return invalid;  }  /** Prepare a transaction. */ -int SYMEXPORT alpm_trans_prepare(alpm_list_t **data) +int SYMEXPORT alpm_trans_prepare(pmhandle_t *handle, alpm_list_t **data)  {  	pmtrans_t *trans; -	ALPM_LOG_FUNC; -  	/* Sanity checks */ -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); -	ASSERT(data != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); +	CHECK_HANDLE(handle, return -1); +	ASSERT(data != NULL, RET_ERR(handle, PM_ERR_WRONG_ARGS, -1));  	trans = handle->trans; -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); -	ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1)); +	ASSERT(trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1)); +	ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(handle, PM_ERR_TRANS_NOT_INITIALIZED, -1));  	/* If there's nothing to do, return without complaining */  	if(trans->add == NULL && trans->remove == NULL) { -		return(0); +		return 0;  	} -	alpm_list_t *invalid = check_arch(trans->add); +	alpm_list_t *invalid = check_arch(handle, trans->add);  	if(invalid) {  		if(data) {  			*data = invalid;  		} -		RET_ERR(PM_ERR_PKG_INVALID_ARCH, -1); +		RET_ERR(handle, PM_ERR_PKG_INVALID_ARCH, -1);  	}  	if(trans->add == NULL) { -		if(_alpm_remove_prepare(trans, handle->db_local, data) == -1) { +		if(_alpm_remove_prepare(handle, data) == -1) {  			/* pm_errno is set by _alpm_remove_prepare() */ -			return(-1); +			return -1;  		}  	}	else { -		if(_alpm_sync_prepare(trans, handle->db_local, handle->dbs_sync, data) == -1) { +		if(_alpm_sync_prepare(handle, data) == -1) {  			/* pm_errno is set by _alpm_sync_prepare() */ -			return(-1); +			return -1;  		}  	}  	trans->state = STATE_PREPARED; -	return(0); +	return 0;  }  /** Commit a transaction. */ -int SYMEXPORT alpm_trans_commit(alpm_list_t **data) +int SYMEXPORT alpm_trans_commit(pmhandle_t *handle, alpm_list_t **data)  {  	pmtrans_t *trans; -	ALPM_LOG_FUNC; -  	/* Sanity checks */ -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1);  	trans = handle->trans; -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); -	ASSERT(trans->state == STATE_PREPARED, RET_ERR(PM_ERR_TRANS_NOT_PREPARED, -1)); +	ASSERT(trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1)); +	ASSERT(trans->state == STATE_PREPARED, RET_ERR(handle, PM_ERR_TRANS_NOT_PREPARED, -1)); -	ASSERT(!(trans->flags & PM_TRANS_FLAG_NOLOCK), RET_ERR(PM_ERR_TRANS_NOT_LOCKED, -1)); +	ASSERT(!(trans->flags & PM_TRANS_FLAG_NOLOCK), RET_ERR(handle, PM_ERR_TRANS_NOT_LOCKED, -1));  	/* If there's nothing to do, return without complaining */  	if(trans->add == NULL && trans->remove == NULL) { -		return(0); +		return 0;  	}  	trans->state = STATE_COMMITING;  	if(trans->add == NULL) { -		if(_alpm_remove_packages(trans, handle->db_local) == -1) { +		if(_alpm_remove_packages(handle) == -1) {  			/* pm_errno is set by _alpm_remove_commit() */ -			return(-1); +			return -1;  		}  	} else { -		if(_alpm_sync_commit(trans, handle->db_local, data) == -1) { +		if(_alpm_sync_commit(handle, data) == -1) {  			/* pm_errno is set by _alpm_sync_commit() */ -			return(-1); +			return -1;  		}  	}  	trans->state = STATE_COMMITED; -	return(0); +	return 0;  }  /** Interrupt a transaction. */ -int SYMEXPORT alpm_trans_interrupt(void) +int SYMEXPORT alpm_trans_interrupt(pmhandle_t *handle)  {  	pmtrans_t *trans; -	ALPM_LOG_FUNC; -  	/* Sanity checks */ -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1);  	trans = handle->trans; -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); +	ASSERT(trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1));  	ASSERT(trans->state == STATE_COMMITING || trans->state == STATE_INTERRUPTED, -			RET_ERR(PM_ERR_TRANS_TYPE, -1)); +			RET_ERR(handle, PM_ERR_TRANS_TYPE, -1));  	trans->state = STATE_INTERRUPTED; -	return(0); +	return 0;  }  /** Release a transaction. */ -int SYMEXPORT alpm_trans_release(void) +int SYMEXPORT alpm_trans_release(pmhandle_t *handle)  {  	pmtrans_t *trans; -	ALPM_LOG_FUNC; -  	/* Sanity checks */ -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); +	CHECK_HANDLE(handle, return -1);  	trans = handle->trans; -	ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); -	ASSERT(trans->state != STATE_IDLE, RET_ERR(PM_ERR_TRANS_NULL, -1)); +	ASSERT(trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1)); +	ASSERT(trans->state != STATE_IDLE, RET_ERR(handle, PM_ERR_TRANS_NULL, -1));  	int nolock_flag = trans->flags & PM_TRANS_FLAG_NOLOCK; @@ -301,34 +283,20 @@ int SYMEXPORT alpm_trans_release(void)  	/* unlock db */  	if(!nolock_flag) {  		if(remove_lock(handle)) { -			_alpm_log(PM_LOG_WARNING, _("could not remove lock file %s\n"), -					alpm_option_get_lockfile()); -			alpm_logaction("warning: could not remove lock file %s\n", -					alpm_option_get_lockfile()); +			_alpm_log(handle, PM_LOG_WARNING, _("could not remove lock file %s\n"), +					alpm_option_get_lockfile(handle)); +			alpm_logaction(handle, "warning: could not remove lock file %s\n", +					alpm_option_get_lockfile(handle));  		}  	} -	return(0); +	return 0;  }  /** @} */ -pmtrans_t *_alpm_trans_new(void) -{ -	pmtrans_t *trans; - -	ALPM_LOG_FUNC; - -	CALLOC(trans, 1, sizeof(pmtrans_t), RET_ERR(PM_ERR_MEMORY, NULL)); -	trans->state = STATE_IDLE; - -	return(trans); -} -  void _alpm_trans_free(pmtrans_t *trans)  { -	ALPM_LOG_FUNC; -  	if(trans == NULL) {  		return;  	} @@ -351,7 +319,7 @@ static int grep(const char *fn, const char *needle)  	FILE *fp;  	if((fp = fopen(fn, "r")) == NULL) { -		return(0); +		return 0;  	}  	while(!feof(fp)) {  		char line[1024]; @@ -362,16 +330,15 @@ static int grep(const char *fn, const char *needle)  		 * ends up being split across line reads */  		if(strstr(line, needle)) {  			fclose(fp); -			return(1); +			return 1;  		}  	}  	fclose(fp); -	return(0); +	return 0;  } -int _alpm_runscriptlet(const char *root, const char *installfn, -											 const char *script, const char *ver, -											 const char *oldver, pmtrans_t *trans) +int _alpm_runscriptlet(pmhandle_t *handle, const char *installfn, +		const char *script, const char *ver, const char *oldver)  {  	char scriptfn[PATH_MAX];  	char cmdline[PATH_MAX]; @@ -381,23 +348,21 @@ int _alpm_runscriptlet(const char *root, const char *installfn,  	int clean_tmpdir = 0;  	int retval = 0; -	ALPM_LOG_FUNC; -  	if(access(installfn, R_OK)) {  		/* not found */ -		_alpm_log(PM_LOG_DEBUG, "scriptlet '%s' not found\n", installfn); -		return(0); +		_alpm_log(handle, PM_LOG_DEBUG, "scriptlet '%s' not found\n", installfn); +		return 0;  	}  	/* creates a directory in $root/tmp/ for copying/extracting the scriptlet */ -	snprintf(tmpdir, PATH_MAX, "%stmp/", root); +	snprintf(tmpdir, PATH_MAX, "%stmp/", handle->root);  	if(access(tmpdir, F_OK) != 0) {  		_alpm_makepath_mode(tmpdir, 01777);  	} -	snprintf(tmpdir, PATH_MAX, "%stmp/alpm_XXXXXX", root); +	snprintf(tmpdir, PATH_MAX, "%stmp/alpm_XXXXXX", handle->root);  	if(mkdtemp(tmpdir) == NULL) { -		_alpm_log(PM_LOG_ERROR, _("could not create temp directory\n")); -		return(1); +		_alpm_log(handle, PM_LOG_ERROR, _("could not create temp directory\n")); +		return 1;  	} else {  		clean_tmpdir = 1;  	} @@ -405,12 +370,12 @@ int _alpm_runscriptlet(const char *root, const char *installfn,  	/* either extract or copy the scriptlet */  	snprintf(scriptfn, PATH_MAX, "%s/.INSTALL", tmpdir);  	if(strcmp(script, "pre_upgrade") == 0 || strcmp(script, "pre_install") == 0) { -		if(_alpm_unpack_single(installfn, tmpdir, ".INSTALL")) { +		if(_alpm_unpack_single(handle, installfn, tmpdir, ".INSTALL")) {  			retval = 1;  		}  	} else {  		if(_alpm_copyfile(installfn, scriptfn)) { -			_alpm_log(PM_LOG_ERROR, _("could not copy tempfile to %s (%s)\n"), scriptfn, strerror(errno)); +			_alpm_log(handle, PM_LOG_ERROR, _("could not copy tempfile to %s (%s)\n"), scriptfn, strerror(errno));  			retval = 1;  		}  	} @@ -419,7 +384,7 @@ int _alpm_runscriptlet(const char *root, const char *installfn,  	}  	/* chop off the root so we can find the tmpdir in the chroot */ -	scriptpath = scriptfn + strlen(root) - 1; +	scriptpath = scriptfn + strlen(handle->root) - 1;  	if(!grep(scriptfn, script)) {  		/* script not found in scriptlet file */ @@ -434,41 +399,41 @@ int _alpm_runscriptlet(const char *root, const char *installfn,  				scriptpath, script, ver);  	} -	_alpm_log(PM_LOG_DEBUG, "executing \"%s\"\n", cmdline); +	_alpm_log(handle, PM_LOG_DEBUG, "executing \"%s\"\n", cmdline); -	retval = _alpm_run_chroot(root, "/bin/sh", argv); +	retval = _alpm_run_chroot(handle, "/bin/sh", argv);  cleanup:  	if(clean_tmpdir && _alpm_rmrf(tmpdir)) { -		_alpm_log(PM_LOG_WARNING, _("could not remove tmpdir %s\n"), tmpdir); +		_alpm_log(handle, PM_LOG_WARNING, _("could not remove tmpdir %s\n"), tmpdir);  	} -	return(retval); +	return retval;  } -int SYMEXPORT alpm_trans_get_flags() +pmtransflag_t SYMEXPORT alpm_trans_get_flags(pmhandle_t *handle)  {  	/* Sanity checks */ -	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); -	ASSERT(handle->trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); +	CHECK_HANDLE(handle, return -1); +	ASSERT(handle->trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, -1));  	return handle->trans->flags;  } -alpm_list_t SYMEXPORT * alpm_trans_get_add() +alpm_list_t SYMEXPORT *alpm_trans_get_add(pmhandle_t *handle)  {  	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(handle->trans != NULL, return(NULL)); +	CHECK_HANDLE(handle, return NULL); +	ASSERT(handle->trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, NULL));  	return handle->trans->add;  } -alpm_list_t SYMEXPORT * alpm_trans_get_remove() +alpm_list_t SYMEXPORT *alpm_trans_get_remove(pmhandle_t *handle)  {  	/* Sanity checks */ -	ASSERT(handle != NULL, return(NULL)); -	ASSERT(handle->trans != NULL, return(NULL)); +	CHECK_HANDLE(handle, return NULL); +	ASSERT(handle->trans != NULL, RET_ERR(handle, PM_ERR_TRANS_NULL, NULL));  	return handle->trans->remove;  } diff --git a/lib/libalpm/trans.h b/lib/libalpm/trans.h index 6702881b..e8587156 100644 --- a/lib/libalpm/trans.h +++ b/lib/libalpm/trans.h @@ -66,14 +66,12 @@ do { \  	} \  } while(0) -pmtrans_t *_alpm_trans_new(void);  void _alpm_trans_free(pmtrans_t *trans);  int _alpm_trans_init(pmtrans_t *trans, pmtransflag_t flags,                       alpm_trans_cb_event event, alpm_trans_cb_conv conv,                       alpm_trans_cb_progress progress); -int _alpm_runscriptlet(const char *root, const char *installfn, -                       const char *script, const char *ver, -                       const char *oldver, pmtrans_t *trans); +int _alpm_runscriptlet(pmhandle_t *handle, const char *installfn, +		const char *script, const char *ver, const char *oldver);  #endif /* _ALPM_TRANS_H */ diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 430da92a..357ce506 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -53,10 +53,10 @@  /* libalpm */  #include "util.h"  #include "log.h" -#include "package.h"  #include "alpm.h"  #include "alpm_list.h"  #include "handle.h" +#include "trans.h"  #ifndef HAVE_STRSEP  /* This is a replacement for strsep which is not portable (missing on Solaris). @@ -65,14 +65,14 @@ char* strsep(char** str, const char* delims)  {  	char* token; -	if (*str==NULL) { +	if(*str==NULL) {  		/* No more tokens */  		return NULL;  	}  	token=*str; -	while (**str!='\0') { -		if (strchr(delims,**str)!=NULL) { +	while(**str!='\0') { +		if(strchr(delims,**str)!=NULL) {  			**str='\0';  			(*str)++;  			return token; @@ -87,7 +87,7 @@ char* strsep(char** str, const char* delims)  int _alpm_makepath(const char *path)  { -	return(_alpm_makepath_mode(path, 0755)); +	return _alpm_makepath_mode(path, 0755);  }  /* does the same thing as 'mkdir -p' */ @@ -123,7 +123,7 @@ int _alpm_makepath_mode(const char *path, mode_t mode)  	free(orig);  	free(incr);  	umask(oldmask); -	return(ret); +	return ret;  }  #define CPBUFSIZE 8 * 1024 @@ -137,12 +137,12 @@ int _alpm_copyfile(const char *src, const char *dest)  	in = fopen(src, "rb");  	if(in == NULL) { -		return(1); +		return 1;  	}  	out = fopen(dest, "wb");  	if(out == NULL) {  		fclose(in); -		return(1); +		return 1;  	}  	CALLOC(buf, (size_t)CPBUFSIZE, (size_t)1, ret = 1; goto cleanup;); @@ -152,9 +152,6 @@ int _alpm_copyfile(const char *src, const char *dest)  		size_t nwritten = 0;  		nwritten = fwrite(buf, 1, len, out);  		if((nwritten != len) || ferror(out)) { -			pm_errno = PM_ERR_WRITE; -			_alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"), -					dest, strerror(errno));  			ret = -1;  			goto cleanup;  		} @@ -175,7 +172,7 @@ cleanup:  	fclose(in);  	fclose(out);  	FREE(buf); -	return(ret); +	return ret;  }  /* Trim whitespace and newlines from a string @@ -186,7 +183,7 @@ char *_alpm_strtrim(char *str)  	if(*str == '\0') {  		/* string is empty, so we're done. */ -		return(str); +		return str;  	}  	while(isspace((unsigned char)*pch)) { @@ -198,7 +195,7 @@ char *_alpm_strtrim(char *str)  	/* check if there wasn't anything but whitespace in the string. */  	if(*str == '\0') { -		return(str); +		return str;  	}  	pch = (str + (strlen(str) - 1)); @@ -207,7 +204,7 @@ char *_alpm_strtrim(char *str)  	}  	*++pch = '\0'; -	return(str); +	return str;  }  /* Compression functions */ @@ -215,36 +212,39 @@ char *_alpm_strtrim(char *str)  /**   * @brief Unpack a specific file in an archive.   * - * @param archive  the archive to unpack - * @param prefix   where to extract the files - * @param fn       a file within the archive to unpack + * @param handle the context handle + * @param archive the archive to unpack + * @param prefix where to extract the files + * @param filename a file within the archive to unpack   * @return 0 on success, 1 on failure   */ -int _alpm_unpack_single(const char *archive, const char *prefix, const char *fn) +int _alpm_unpack_single(pmhandle_t *handle, const char *archive, +		const char *prefix, const char *filename)  {  	alpm_list_t *list = NULL;  	int ret = 0; -	if(fn == NULL) { -		return(1); +	if(filename == NULL) { +		return 1;  	} -	list = alpm_list_add(list, (void *)fn); -	ret = _alpm_unpack(archive, prefix, list, 1); +	list = alpm_list_add(list, (void *)filename); +	ret = _alpm_unpack(handle, archive, prefix, list, 1);  	alpm_list_free(list); -	return(ret); +	return ret;  }  /**   * @brief Unpack a list of files in an archive.   * - * @param archive  the archive to unpack - * @param prefix   where to extract the files - * @param list     a list of files within the archive to unpack or - * NULL for all + * @param handle the context handle + * @param archive the archive to unpack + * @param prefix where to extract the files + * @param list a list of files within the archive to unpack or NULL for all   * @param breakfirst break after the first entry found   *   * @return 0 on success, 1 on failure   */ -int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int breakfirst) +int _alpm_unpack(pmhandle_t *handle, const char *archive, const char *prefix, +		alpm_list_t *list, int breakfirst)  {  	int ret = 0;  	mode_t oldmask; @@ -253,33 +253,33 @@ int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int  	char cwd[PATH_MAX];  	int restore_cwd = 0; -	ALPM_LOG_FUNC; - -	if((_archive = archive_read_new()) == NULL) -		RET_ERR(PM_ERR_LIBARCHIVE, 1); +	if((_archive = archive_read_new()) == NULL) { +		RET_ERR(handle, PM_ERR_LIBARCHIVE, 1); +	}  	archive_read_support_compression_all(_archive);  	archive_read_support_format_all(_archive);  	if(archive_read_open_filename(_archive, archive,  				ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { -		_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), archive, +		_alpm_log(handle, PM_LOG_ERROR, _("could not open file %s: %s\n"), archive,  				archive_error_string(_archive)); -		RET_ERR(PM_ERR_PKG_OPEN, 1); +		RET_ERR(handle, PM_ERR_PKG_OPEN, 1);  	}  	oldmask = umask(0022);  	/* save the cwd so we can restore it later */  	if(getcwd(cwd, PATH_MAX) == NULL) { -		_alpm_log(PM_LOG_ERROR, _("could not get current working directory\n")); +		_alpm_log(handle, PM_LOG_ERROR, _("could not get current working directory\n"));  	} else {  		restore_cwd = 1;  	}  	/* just in case our cwd was removed in the upgrade operation */  	if(chdir(prefix) != 0) { -		_alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), prefix, strerror(errno)); +		_alpm_log(handle, PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), +				prefix, strerror(errno));  		ret = 1;  		goto cleanup;  	} @@ -307,13 +307,13 @@ int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int  			char *found = alpm_list_find_str(list, prefix);  			free(prefix);  			if(!found) { -				if (archive_read_data_skip(_archive) != ARCHIVE_OK) { +				if(archive_read_data_skip(_archive) != ARCHIVE_OK) {  					ret = 1;  					goto cleanup;  				}  				continue;  			} else { -				_alpm_log(PM_LOG_DEBUG, "extracting: %s\n", entryname); +				_alpm_log(handle, PM_LOG_DEBUG, "extracting: %s\n", entryname);  			}  		} @@ -321,10 +321,10 @@ int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int  		int readret = archive_read_extract(_archive, entry, 0);  		if(readret == ARCHIVE_WARN) {  			/* operation succeeded but a non-critical error was encountered */ -			_alpm_log(PM_LOG_WARNING, _("warning given when extracting %s (%s)\n"), +			_alpm_log(handle, PM_LOG_WARNING, _("warning given when extracting %s (%s)\n"),  					entryname, archive_error_string(_archive));  		} else if(readret != ARCHIVE_OK) { -			_alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)\n"), +			_alpm_log(handle, PM_LOG_ERROR, _("could not extract %s (%s)\n"),  					entryname, archive_error_string(_archive));  			ret = 1;  			goto cleanup; @@ -339,9 +339,10 @@ cleanup:  	umask(oldmask);  	archive_read_finish(_archive);  	if(restore_cwd && chdir(cwd) != 0) { -		_alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno)); +		_alpm_log(handle, PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), +				cwd, strerror(errno));  	} -	return(ret); +	return ret;  }  /* does the same thing as 'rm -rf' */ @@ -356,18 +357,18 @@ int _alpm_rmrf(const char *path)  	if(_alpm_lstat(path, &st) == 0) {  		if(!S_ISDIR(st.st_mode)) {  			if(!unlink(path)) { -				return(0); +				return 0;  			} else {  				if(errno == ENOENT) { -					return(0); +					return 0;  				} else { -					return(1); +					return 1;  				}  			}  		} else {  			dirp = opendir(path);  			if(!dirp) { -				return(1); +				return 1;  			}  			for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {  				if(dp->d_ino) { @@ -382,16 +383,16 @@ int _alpm_rmrf(const char *path)  				errflag++;  			}  		} -		return(errflag); +		return errflag;  	} -	return(0); +	return 0;  } -int _alpm_logaction(int usesyslog, FILE *f, const char *fmt, va_list args) +int _alpm_logaction(pmhandle_t *handle, const char *fmt, va_list args)  {  	int ret = 0; -	if(usesyslog) { +	if(handle->usesyslog) {  		/* we can't use a va_list more than once, so we need to copy it  		 * so we can use the original when calling vfprintf below. */  		va_list args_syslog; @@ -400,7 +401,7 @@ int _alpm_logaction(int usesyslog, FILE *f, const char *fmt, va_list args)  		va_end(args_syslog);  	} -	if(f) { +	if(handle->logstream) {  		time_t t;  		struct tm *tm; @@ -408,17 +409,17 @@ int _alpm_logaction(int usesyslog, FILE *f, const char *fmt, va_list args)  		tm = localtime(&t);  		/* Use ISO-8601 date format */ -		fprintf(f, "[%04d-%02d-%02d %02d:%02d] ", +		fprintf(handle->logstream, "[%04d-%02d-%02d %02d:%02d] ",  						tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,  						tm->tm_hour, tm->tm_min); -		ret = vfprintf(f, fmt, args); -		fflush(f); +		ret = vfprintf(handle->logstream, fmt, args); +		fflush(handle->logstream);  	} -	return(ret); +	return ret;  } -int _alpm_run_chroot(const char *root, const char *path, char *const argv[]) +int _alpm_run_chroot(pmhandle_t *handle, const char *path, char *const argv[])  {  	char cwd[PATH_MAX];  	pid_t pid; @@ -426,28 +427,28 @@ int _alpm_run_chroot(const char *root, const char *path, char *const argv[])  	int restore_cwd = 0;  	int retval = 0; -	ALPM_LOG_FUNC; -  	/* save the cwd so we can restore it later */  	if(getcwd(cwd, PATH_MAX) == NULL) { -		_alpm_log(PM_LOG_ERROR, _("could not get current working directory\n")); +		_alpm_log(handle, PM_LOG_ERROR, _("could not get current working directory\n"));  	} else {  		restore_cwd = 1;  	}  	/* just in case our cwd was removed in the upgrade operation */ -	if(chdir(root) != 0) { -		_alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), root, strerror(errno)); +	if(chdir(handle->root) != 0) { +		_alpm_log(handle, PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), +				handle->root, strerror(errno));  		goto cleanup;  	} -	_alpm_log(PM_LOG_DEBUG, "executing \"%s\" under chroot \"%s\"\n", path, root); +	_alpm_log(handle, PM_LOG_DEBUG, "executing \"%s\" under chroot \"%s\"\n", +			path, handle->root);  	/* Flush open fds before fork() to avoid cloning buffers */  	fflush(NULL);  	if(pipe(pipefd) == -1) { -		_alpm_log(PM_LOG_ERROR, _("could not create pipe (%s)\n"), strerror(errno)); +		_alpm_log(handle, PM_LOG_ERROR, _("could not create pipe (%s)\n"), strerror(errno));  		retval = 1;  		goto cleanup;  	} @@ -455,7 +456,7 @@ int _alpm_run_chroot(const char *root, const char *path, char *const argv[])  	/* fork- parent and child each have seperate code blocks below */  	pid = fork();  	if(pid == -1) { -		_alpm_log(PM_LOG_ERROR, _("could not fork a new process (%s)\n"), strerror(errno)); +		_alpm_log(handle, PM_LOG_ERROR, _("could not fork a new process (%s)\n"), strerror(errno));  		retval = 1;  		goto cleanup;  	} @@ -470,7 +471,7 @@ int _alpm_run_chroot(const char *root, const char *path, char *const argv[])  		close(pipefd[1]);  		/* use fprintf instead of _alpm_log to send output through the parent */ -		if(chroot(root) != 0) { +		if(chroot(handle->root) != 0) {  			fprintf(stderr, _("could not change the root directory (%s)\n"), strerror(errno));  			exit(1);  		} @@ -498,7 +499,7 @@ int _alpm_run_chroot(const char *root, const char *path, char *const argv[])  				char line[PATH_MAX];  				if(fgets(line, PATH_MAX, pipe) == NULL)  					break; -				alpm_logaction("%s", line); +				alpm_logaction(handle, "%s", line);  				EVENT(handle->trans, PM_TRANS_EVT_SCRIPTLET_INFO, line, NULL);  			}  			fclose(pipe); @@ -506,7 +507,7 @@ int _alpm_run_chroot(const char *root, const char *path, char *const argv[])  		while(waitpid(pid, &status, 0) == -1) {  			if(errno != EINTR) { -				_alpm_log(PM_LOG_ERROR, _("call to waitpid failed (%s)\n"), strerror(errno)); +				_alpm_log(handle, PM_LOG_ERROR, _("call to waitpid failed (%s)\n"), strerror(errno));  				retval = 1;  				goto cleanup;  			} @@ -514,14 +515,14 @@ int _alpm_run_chroot(const char *root, const char *path, char *const argv[])  		/* report error from above after the child has exited */  		if(retval != 0) { -			_alpm_log(PM_LOG_ERROR, _("could not open pipe (%s)\n"), strerror(errno)); +			_alpm_log(handle, PM_LOG_ERROR, _("could not open pipe (%s)\n"), strerror(errno));  			goto cleanup;  		}  		/* check the return status, make sure it is 0 (success) */  		if(WIFEXITED(status)) { -			_alpm_log(PM_LOG_DEBUG, "call to waitpid succeeded\n"); +			_alpm_log(handle, PM_LOG_DEBUG, "call to waitpid succeeded\n");  			if(WEXITSTATUS(status) != 0) { -				_alpm_log(PM_LOG_ERROR, _("command failed to execute correctly\n")); +				_alpm_log(handle, PM_LOG_ERROR, _("command failed to execute correctly\n"));  				retval = 1;  			}  		} @@ -529,42 +530,43 @@ int _alpm_run_chroot(const char *root, const char *path, char *const argv[])  cleanup:  	if(restore_cwd && chdir(cwd) != 0) { -		_alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno)); +		_alpm_log(handle, PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno));  	} -	return(retval); +	return retval;  } -int _alpm_ldconfig(const char *root) +int _alpm_ldconfig(pmhandle_t *handle)  {  	char line[PATH_MAX]; -	_alpm_log(PM_LOG_DEBUG, "running ldconfig\n"); +	_alpm_log(handle, PM_LOG_DEBUG, "running ldconfig\n"); -	snprintf(line, PATH_MAX, "%setc/ld.so.conf", root); +	snprintf(line, PATH_MAX, "%setc/ld.so.conf", handle->root);  	if(access(line, F_OK) == 0) { -		snprintf(line, PATH_MAX, "%ssbin/ldconfig", root); +		snprintf(line, PATH_MAX, "%ssbin/ldconfig", handle->root);  		if(access(line, X_OK) == 0) {  			char *argv[] = { "ldconfig", NULL }; -			_alpm_run_chroot(root, "/sbin/ldconfig", argv); +			_alpm_run_chroot(handle, "/sbin/ldconfig", argv);  		}  	} -	return(0); +	return 0;  }  /* Helper function for comparing strings using the   * alpm "compare func" signature */  int _alpm_str_cmp(const void *s1, const void *s2)  { -	return(strcmp(s1, s2)); +	return strcmp(s1, s2);  }  /** Find a filename in a registered alpm cachedir. + * @param handle the context handle   * @param filename name of file to find   * @return malloced path of file, NULL if not found   */ -char *_alpm_filecache_find(const char* filename) +char *_alpm_filecache_find(pmhandle_t *handle, const char *filename)  {  	char path[PATH_MAX];  	char *retpath; @@ -572,52 +574,56 @@ char *_alpm_filecache_find(const char* filename)  	struct stat buf;  	/* Loop through the cache dirs until we find a matching file */ -	for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) { -		snprintf(path, PATH_MAX, "%s%s", (char*)alpm_list_getdata(i), +	for(i = alpm_option_get_cachedirs(handle); i; i = alpm_list_next(i)) { +		snprintf(path, PATH_MAX, "%s%s", (char *)alpm_list_getdata(i),  				filename);  		if(stat(path, &buf) == 0 && S_ISREG(buf.st_mode)) {  			retpath = strdup(path); -			_alpm_log(PM_LOG_DEBUG, "found cached pkg: %s\n", retpath); -			return(retpath); +			_alpm_log(handle, PM_LOG_DEBUG, "found cached pkg: %s\n", retpath); +			return retpath;  		}  	}  	/* package wasn't found in any cachedir */ -	RET_ERR(PM_ERR_PKG_NOT_FOUND, NULL); +	return NULL;  }  /** Check the alpm cachedirs for existance and find a writable one.   * If no valid cache directory can be found, use /tmp. + * @param handle the context handle   * @return pointer to a writable cache directory.   */ -const char *_alpm_filecache_setup(void) +const char *_alpm_filecache_setup(pmhandle_t *handle)  {  	struct stat buf;  	alpm_list_t *i, *tmp;  	char *cachedir;  	/* Loop through the cache dirs until we find a writeable dir */ -	for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) { +	for(i = alpm_option_get_cachedirs(handle); i; i = alpm_list_next(i)) {  		cachedir = alpm_list_getdata(i);  		if(stat(cachedir, &buf) != 0) {  			/* cache directory does not exist.... try creating it */ -			_alpm_log(PM_LOG_WARNING, _("no %s cache exists, creating...\n"), +			_alpm_log(handle, PM_LOG_WARNING, _("no %s cache exists, creating...\n"),  					cachedir);  			if(_alpm_makepath(cachedir) == 0) { -				_alpm_log(PM_LOG_DEBUG, "using cachedir: %s\n", cachedir); -				return(cachedir); +				_alpm_log(handle, PM_LOG_DEBUG, "using cachedir: %s\n", cachedir); +				return cachedir;  			}  		} else if(S_ISDIR(buf.st_mode) && (buf.st_mode & S_IWUSR)) { -			_alpm_log(PM_LOG_DEBUG, "using cachedir: %s\n", cachedir); -			return(cachedir); +			_alpm_log(handle, PM_LOG_DEBUG, "using cachedir: %s\n", cachedir); +			return cachedir; +		} else { +			_alpm_log(handle, PM_LOG_DEBUG, "skipping cachedir: %s\n", cachedir);  		}  	}  	/* we didn't find a valid cache directory. use /tmp. */ -	tmp = alpm_list_add(NULL, strdup("/tmp/")); -	alpm_option_set_cachedirs(tmp); -	_alpm_log(PM_LOG_DEBUG, "using cachedir: %s", "/tmp/\n"); -	_alpm_log(PM_LOG_WARNING, _("couldn't create package cache, using /tmp instead\n")); -	return(alpm_list_getdata(tmp)); +	tmp = alpm_list_add(NULL, "/tmp/"); +	alpm_option_set_cachedirs(handle, tmp); +	alpm_list_free(tmp); +	_alpm_log(handle, PM_LOG_DEBUG, "using cachedir: %s\n", "/tmp/"); +	_alpm_log(handle, PM_LOG_WARNING, _("couldn't create package cache, using /tmp instead\n")); +	return "/tmp/";  }  /** lstat wrapper that treats /path/dirsymlink/ the same as /path/dirsymlink. @@ -630,18 +636,19 @@ const char *_alpm_filecache_setup(void)  int _alpm_lstat(const char *path, struct stat *buf)  {  	int ret; -	char *newpath = strdup(path); -	size_t len = strlen(newpath); +	size_t len = strlen(path);  	/* strip the trailing slash if one exists */ -	if(len != 0 && newpath[len - 1] == '/') { -			newpath[len - 1] = '\0'; +	if(len != 0 && path[len - 1] == '/') { +		char *newpath = strdup(path); +		newpath[len - 1] = '\0'; +		ret = lstat(newpath, buf); +		free(newpath); +	} else { +		ret = lstat(path, buf);  	} -	ret = lstat(newpath, buf); - -	FREE(newpath); -	return(ret); +	return ret;  }  #ifdef HAVE_LIBSSL @@ -652,11 +659,11 @@ static int md5_file(const char *path, unsigned char output[16])  	MD5_CTX ctx;  	unsigned char *buf; -	CALLOC(buf, 8192, sizeof(unsigned char), return(1)); +	CALLOC(buf, 8192, sizeof(unsigned char), return 1);  	if((f = fopen(path, "rb")) == NULL) {  		free(buf); -		return(1); +		return 1;  	}  	MD5_Init(&ctx); @@ -672,11 +679,11 @@ static int md5_file(const char *path, unsigned char output[16])  	if(ferror(f) != 0) {  		fclose(f); -		return(2); +		return 2;  	}  	fclose(f); -	return(0); +	return 0;  }  #endif @@ -691,17 +698,15 @@ char SYMEXPORT *alpm_compute_md5sum(const char *filename)  	char *md5sum;  	int ret, i; -	ALPM_LOG_FUNC; - -	ASSERT(filename != NULL, return(NULL)); +	ASSERT(filename != NULL, return NULL);  	/* allocate 32 chars plus 1 for null */  	md5sum = calloc(33, sizeof(char));  	/* defined above for OpenSSL, otherwise defined in md5.h */  	ret = md5_file(filename, output); -	if (ret > 0) { -		RET_ERR(PM_ERR_NOT_A_FILE, NULL); +	if(ret > 0) { +		return NULL;  	}  	/* Convert the result to something readable */ @@ -711,8 +716,7 @@ char SYMEXPORT *alpm_compute_md5sum(const char *filename)  	}  	md5sum[32] = '\0'; -	_alpm_log(PM_LOG_DEBUG, "md5(%s) = %s\n", filename, md5sum); -	return(md5sum); +	return md5sum;  }  int _alpm_test_md5sum(const char *filepath, const char *md5sum) @@ -731,7 +735,7 @@ int _alpm_test_md5sum(const char *filepath, const char *md5sum)  	}  	FREE(md5sum2); -	return(ret); +	return ret;  }  /* Note: does NOT handle sparse files on purpose for speed. */ @@ -753,7 +757,7 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b)  			}  			/* zero-copy - this is the entire next block of data. */ -			b->ret = archive_read_data_block(a, (void*)&b->block, +			b->ret = archive_read_data_block(a, (void *)&b->block,  					&b->block_size, &offset);  			b->block_offset = b->block; @@ -776,20 +780,19 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b)  		/* allocate our buffer, or ensure our existing one is big enough */  		if(!b->line) {  			/* set the initial buffer to the read block_size */ -			CALLOC(b->line, b->block_size + 1, sizeof(char), -					RET_ERR(PM_ERR_MEMORY, -1)); +			CALLOC(b->line, b->block_size + 1, sizeof(char), return ENOMEM);  			b->line_size = b->block_size + 1;  			b->line_offset = b->line;  		} else {  			size_t needed = (size_t)((b->line_offset - b->line)  					+ (i - b->block_offset) + 1);  			if(needed > b->max_line_size) { -				RET_ERR(PM_ERR_MEMORY, -1); +				return ERANGE;  			}  			if(needed > b->line_size) {  				/* need to realloc + copy data to fit total length */  				char *new; -				CALLOC(new, needed, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1)); +				CALLOC(new, needed, sizeof(char), return ENOMEM);  				memcpy(new, b->line, b->line_size);  				b->line_size = needed;  				b->line_offset = new + (b->line_offset - b->line); @@ -804,7 +807,7 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b)  			b->line_offset[len] = '\0';  			b->block_offset = ++i;  			/* this is the main return point; from here you can read b->line */ -			return(ARCHIVE_OK); +			return ARCHIVE_OK;  		} else {  			/* we've looked through the whole block but no newline, copy it */  			size_t len = (size_t)(b->block + b->block_size - b->block_offset); @@ -819,7 +822,7 @@ cleanup:  		int ret = b->ret;  		FREE(b->line);  		memset(b, 0, sizeof(b)); -		return(ret); +		return ret;  	}  } @@ -833,12 +836,12 @@ int _alpm_splitname(const char *target, pmpkg_t *pkg)  	const char *version, *end;  	if(target == NULL || pkg == NULL) { -		return(-1); +		return -1;  	}  	end = target + strlen(target);  	/* remove any trailing '/' */ -	while (*(end - 1) == '/') { +	while(*(end - 1) == '/') {  	  --end;  	} @@ -847,7 +850,7 @@ int _alpm_splitname(const char *target, pmpkg_t *pkg)  	for(version = end - 1; *version && *version != '-'; version--);  	for(version = version - 1; *version && *version != '-'; version--);  	if(*version != '-' || version == target) { -		return(-1); +		return -1;  	}  	/* copy into fields and return */ @@ -856,16 +859,15 @@ int _alpm_splitname(const char *target, pmpkg_t *pkg)  	}  	/* version actually points to the dash, so need to increment 1 and account  	 * for potential end character */ -	STRNDUP(pkg->version, version + 1, end - version - 1, -			RET_ERR(PM_ERR_MEMORY, -1)); +	STRNDUP(pkg->version, version + 1, end - version - 1, return -1);  	if(pkg->name) {  		FREE(pkg->name);  	} -	STRNDUP(pkg->name, target, version - target, RET_ERR(PM_ERR_MEMORY, -1)); +	STRNDUP(pkg->name, target, version - target, return -1);  	pkg->name_hash = _alpm_hash_sdbm(pkg->name); -	return(0); +	return 0;  }  /** @@ -880,13 +882,13 @@ unsigned long _alpm_hash_sdbm(const char *str)  	int c;  	if(!str) { -		return(hash); +		return hash;  	}  	while((c = *str++)) {  		hash = c + (hash << 6) + (hash << 16) - hash;  	} -	return(hash); +	return hash;  }  long _alpm_parsedate(const char *line) @@ -897,9 +899,9 @@ long _alpm_parsedate(const char *line)  		setlocale(LC_TIME, "C");  		strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm);  		setlocale(LC_TIME, ""); -		return(mktime(&tmp_tm)); +		return mktime(&tmp_tm);  	} -	return(atol(line)); +	return atol(line);  }  #ifndef HAVE_STRNDUP @@ -908,7 +910,7 @@ static size_t strnlen(const char *s, size_t max)  {      register const char *p;      for(p = s; *p && max--; ++p); -    return(p - s); +    return (p - s);  }  char *strndup(const char *s, size_t n) @@ -916,11 +918,11 @@ char *strndup(const char *s, size_t n)    size_t len = strnlen(s, n);    char *new = (char *) malloc(len + 1); -  if (new == NULL) +  if(new == NULL)      return NULL;    new[len] = '\0'; -  return (char *) memcpy(new, s, len); +  return (char *)memcpy(new, s, len);  }  #endif diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index c66e9881..0549c81e 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -27,7 +27,9 @@  #include "config.h"  #include "alpm_list.h" +#include "alpm.h"  #include "package.h" /* pmpkg_t */ +#include "handle.h" /* pmhandle_t */  #include <stdio.h>  #include <string.h> @@ -36,6 +38,8 @@  #include <time.h>  #include <sys/stat.h> /* struct stat */  #include <archive.h> /* struct archive */ +#include <math.h> /* fabs */ +#include <float.h> /* DBL_EPSILON */  #ifdef ENABLE_NLS  #include <libintl.h> /* here so it doesn't need to be included elsewhere */ @@ -45,7 +49,7 @@  #define _(s) s  #endif -#define ALLOC_FAIL(s) do { _alpm_log(PM_LOG_ERROR, _("alloc failure: could not allocate %zd bytes\n"), s); } while(0) +#define ALLOC_FAIL(s) do { fprintf(stderr, "alloc failure: could not allocate %zd bytes\n", s); } while(0)  #define MALLOC(p, s, action) do { p = calloc(1, s); if(p == NULL) { ALLOC_FAIL(s); action; } } while(0)  #define CALLOC(p, l, s, action) do { p = calloc(l, s); if(p == NULL) { ALLOC_FAIL(s); action; } } while(0) @@ -57,13 +61,17 @@  #define ASSERT(cond, action) do { if(!(cond)) { action; } } while(0) -#define RET_ERR_VOID(err) do { pm_errno = (err); \ -	_alpm_log(PM_LOG_DEBUG, "returning error %d from %s : %s\n", err, __func__, alpm_strerrorlast()); \ +#define RET_ERR_VOID(handle, err) do { (handle)->pm_errno = (err); \ +	_alpm_log(handle, PM_LOG_DEBUG, "returning error %d from %s : %s\n", err, __func__, alpm_strerror(err)); \  	return; } while(0) -#define RET_ERR(err, ret) do { pm_errno = (err); \ -	_alpm_log(PM_LOG_DEBUG, "returning error %d from %s : %s\n", err, __func__, alpm_strerrorlast()); \ -	return(ret); } while(0) +#define RET_ERR(handle, err, ret) do { (handle)->pm_errno = (err); \ +	_alpm_log(handle, PM_LOG_DEBUG, "returning error %d from %s : %s\n", err, __func__, alpm_strerror(err)); \ +	return (ret); } while(0) + +#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)  /**   * Used as a buffer/state holder for _alpm_archive_fgets(). @@ -85,15 +93,17 @@ int _alpm_makepath(const char *path);  int _alpm_makepath_mode(const char *path, mode_t mode);  int _alpm_copyfile(const char *src, const char *dest);  char *_alpm_strtrim(char *str); -int _alpm_unpack_single(const char *archive, const char *prefix, const char *fn); -int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int breakfirst); +int _alpm_unpack_single(pmhandle_t *handle, const char *archive, +		const char *prefix, const char *filename); +int _alpm_unpack(pmhandle_t *handle, const char *archive, const char *prefix, +		alpm_list_t *list, int breakfirst);  int _alpm_rmrf(const char *path); -int _alpm_logaction(int usesyslog, FILE *f, const char *fmt, va_list args); -int _alpm_run_chroot(const char *root, const char *path, char *const argv[]); -int _alpm_ldconfig(const char *root); +int _alpm_logaction(pmhandle_t *handle, const char *fmt, va_list args); +int _alpm_run_chroot(pmhandle_t *handle, const char *path, char *const argv[]); +int _alpm_ldconfig(pmhandle_t *handle);  int _alpm_str_cmp(const void *s1, const void *s2); -char *_alpm_filecache_find(const char *filename); -const char *_alpm_filecache_setup(void); +char *_alpm_filecache_find(pmhandle_t *handle, const char *filename); +const char *_alpm_filecache_setup(pmhandle_t *handle);  int _alpm_lstat(const char *path, struct stat *buf);  int _alpm_test_md5sum(const char *filepath, const char *md5sum);  int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b); @@ -113,6 +123,8 @@ char *strndup(const char *s, size_t n);  #define SYMEXPORT __attribute__((visibility("default")))  #define SYMHIDDEN __attribute__((visibility("internal"))) +#define UNUSED __attribute__((unused)) +  #endif /* _ALPM_UTIL_H */  /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/version.c b/lib/libalpm/version.c index eba66210..9f3a9b71 100644 --- a/lib/libalpm/version.c +++ b/lib/libalpm/version.c @@ -93,7 +93,7 @@ static int rpmvercmp(const char *a, const char *b)  	int ret = 0;  	/* easy comparison to see if versions are identical */ -	if(strcmp(a, b) == 0) return(0); +	if(strcmp(a, b) == 0) return 0;  	str1 = strdup(a);  	str2 = strdup(b); @@ -209,7 +209,7 @@ static int rpmvercmp(const char *a, const char *b)  cleanup:  	free(str1);  	free(str2); -	return(ret); +	return ret;  }  /** Compare two version strings and determine which one is 'newer'. @@ -235,15 +235,15 @@ int SYMEXPORT alpm_pkg_vercmp(const char *a, const char *b)  	/* ensure our strings are not null */  	if(!a && !b) { -		return(0); +		return 0;  	} else if(!a) { -		return(-1); +		return -1;  	} else if(!b) { -		return(1); +		return 1;  	}  	/* another quick shortcut- if full version specs are equal */  	if(strcmp(a, b) == 0) { -		return(0); +		return 0;  	}  	/* Parse both versions into [epoch:]version[-release] triplets. We probably @@ -266,7 +266,7 @@ int SYMEXPORT alpm_pkg_vercmp(const char *a, const char *b)  	free(full1);  	free(full2); -	return(ret); +	return ret;  }  /* vim: set ts=2 sw=2 noet: */ | 
