diff options
-rw-r--r-- | doc/makepkg.8.txt | 4 | ||||
-rw-r--r-- | lib/libalpm/alpm.c | 2 | ||||
-rw-r--r-- | lib/libalpm/alpm.h | 6 | ||||
-rw-r--r-- | lib/libalpm/be_local.c | 117 | ||||
-rw-r--r-- | lib/libalpm/be_sync.c | 114 | ||||
-rw-r--r-- | lib/libalpm/db.c | 63 | ||||
-rw-r--r-- | lib/libalpm/db.h | 18 | ||||
-rw-r--r-- | lib/libalpm/error.c | 2 | ||||
-rw-r--r-- | lib/libalpm/handle.c | 54 | ||||
-rw-r--r-- | lib/libalpm/handle.h | 3 | ||||
-rw-r--r-- | lib/libalpm/trans.c | 72 | ||||
-rw-r--r-- | scripts/makepkg.sh.in | 38 | ||||
-rw-r--r-- | src/pacman/conf.c | 19 | ||||
-rw-r--r-- | src/pacman/sync.c | 7 | ||||
-rw-r--r-- | src/pacman/util.c | 3 | ||||
-rw-r--r-- | src/util/cleanupdelta.c | 2 | ||||
-rw-r--r-- | src/util/pactree.c | 37 | ||||
-rw-r--r-- | src/util/testdb.c | 2 | ||||
-rw-r--r-- | test/pacman/tests/ignore007.py | 2 | ||||
-rw-r--r-- | test/pacman/tests/sign001.py | 4 |
20 files changed, 304 insertions, 265 deletions
diff --git a/doc/makepkg.8.txt b/doc/makepkg.8.txt index f15226ac..e11e9b35 100644 --- a/doc/makepkg.8.txt +++ b/doc/makepkg.8.txt @@ -48,10 +48,6 @@ Options *-c, \--clean*:: Clean up leftover work files and directories after a successful build. -*-C, \--cleancache*:: - Removes all cached source files from the directory specified in `SRCDEST` - in linkman:makepkg.conf[5]. - *\--config* <file>:: Use an alternate config file instead of the +{sysconfdir}/makepkg.conf+ default. diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index 9b9719d1..b0bbbe8c 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -70,7 +70,7 @@ pmhandle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath, snprintf(myhandle->lockfile, lockfilelen, "%s%s", myhandle->dbpath, lf); if(_alpm_db_register_local(myhandle) == NULL) { - myerr = PM_ERR_DB_CREATE; + myerr = myhandle->pm_errno; goto cleanup; } diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 715e502a..579b45f2 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -357,9 +357,12 @@ 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 + * @param check_sig what level of signature checking to perform on the + * database; note that this must be a '.sig' file type verification * @return a pmdb_t* on success (the value), NULL on error */ -pmdb_t *alpm_db_register_sync(pmhandle_t *handle, const char *treename); +pmdb_t *alpm_db_register_sync(pmhandle_t *handle, const char *treename, + pgp_verify_t check_sig); /** Unregister a package database. * @param db pointer to the package database to unregister @@ -999,6 +1002,7 @@ enum _pmerrno_t { PM_ERR_DB_NULL, PM_ERR_DB_NOT_NULL, PM_ERR_DB_NOT_FOUND, + PM_ERR_DB_INVALID, PM_ERR_DB_VERSION, PM_ERR_DB_WRITE, PM_ERR_DB_REMOVE, diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index 4b2a3017..96f04c51 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -314,6 +314,62 @@ static int is_dir(const char *path, struct dirent *entry) return 0; } +static int local_db_validate(pmdb_t *db) +{ + struct dirent *ent = NULL; + const char *dbpath; + DIR *dbdir; + int ret = -1; + + if(db->status & DB_STATUS_VALID) { + return 0; + } + + dbpath = _alpm_db_path(db); + if(dbpath == NULL) { + RET_ERR(db->handle, PM_ERR_DB_OPEN, -1); + } + dbdir = opendir(dbpath); + if(dbdir == NULL) { + if(errno == ENOENT) { + /* database dir doesn't exist yet */ + db->status |= DB_STATUS_VALID; + return 0; + } else { + RET_ERR(db->handle, PM_ERR_DB_OPEN, -1); + } + } + + while((ent = readdir(dbdir)) != NULL) { + const char *name = ent->d_name; + char path[PATH_MAX]; + + if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { + continue; + } + if(!is_dir(dbpath, ent)) { + continue; + } + + snprintf(path, PATH_MAX, "%s%s/depends", dbpath, name); + if(access(path, F_OK) == 0) { + /* we found a depends file- bail */ + db->handle->pm_errno = PM_ERR_DB_VERSION; + goto done; + } + } + /* we found no depends file after full scan */ + db->status |= DB_STATUS_VALID; + ret = 0; + +done: + if(dbdir) { + closedir(dbdir); + } + + return ret; +} + static int local_db_populate(pmdb_t *db) { size_t est_count; @@ -328,6 +384,7 @@ static int local_db_populate(pmdb_t *db) /* pm_errno set in _alpm_db_path() */ return -1; } + dbdir = opendir(dbpath); if(dbdir == NULL) { if(errno == ENOENT) { @@ -867,62 +924,9 @@ int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info) return ret; } -static int local_db_version(pmdb_t *db) -{ - struct dirent *ent = NULL; - const char *dbpath; - DIR *dbdir; - int version; - - dbpath = _alpm_db_path(db); - if(dbpath == NULL) { - RET_ERR(db->handle, PM_ERR_DB_OPEN, -1); - } - dbdir = opendir(dbpath); - if(dbdir == NULL) { - if(errno == ENOENT) { - /* database dir doesn't exist yet */ - version = 2; - goto done; - } else { - RET_ERR(db->handle, PM_ERR_DB_OPEN, -1); - } - } - - while((ent = readdir(dbdir)) != NULL) { - const char *name = ent->d_name; - char path[PATH_MAX]; - - if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { - continue; - } - if(!is_dir(dbpath, ent)) { - continue; - } - - snprintf(path, PATH_MAX, "%s%s/depends", dbpath, name); - if(access(path, F_OK) == 0) { - /* we found a depends file- bail */ - version = 1; - goto done; - } - } - /* we found no depends file after full scan */ - version = 2; - -done: - if(dbdir) { - closedir(dbdir); - } - - _alpm_log(db->handle, PM_LOG_DEBUG, "local database version %d\n", version); - return version; -} - struct db_operations local_db_ops = { .populate = local_db_populate, .unregister = _alpm_db_unregister, - .version = local_db_version, }; pmdb_t *_alpm_db_register_local(pmhandle_t *handle) @@ -933,11 +937,18 @@ pmdb_t *_alpm_db_register_local(pmhandle_t *handle) db = _alpm_db_new("local", 1); if(db == NULL) { + handle->pm_errno = PM_ERR_DB_CREATE; return NULL; } db->ops = &local_db_ops; db->handle = handle; + if(local_db_validate(db)) { + /* pm_errno set in local_db_validate() */ + _alpm_db_free(db); + return NULL; + } + handle->db_local = db; return db; } diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index e5fc6a70..f51ab97a 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -20,7 +20,9 @@ #include "config.h" +#include <errno.h> #include <sys/stat.h> +#include <unistd.h> /* libarchive */ #include <archive.h> @@ -65,32 +67,68 @@ static char *get_sync_dir(pmhandle_t *handle) return syncpath; } +static int sync_db_validate(pmdb_t *db) +{ + pgp_verify_t check_sig; + + if(db->status & DB_STATUS_VALID) { + return 0; + } + + /* this takes into account the default verification level if UNKNOWN + * was assigned to this db */ + check_sig = _alpm_db_get_sigverify_level(db); + + if(check_sig != PM_PGP_VERIFY_NEVER) { + int ret; + const char *dbpath = _alpm_db_path(db); + if(!dbpath) { + /* pm_errno set in _alpm_db_path() */ + return -1; + } + + /* we can skip any validation if the database doesn't exist */ + if(access(dbpath, R_OK) != 0 && errno == ENOENT) { + goto valid; + return 0; + } + + _alpm_log(db->handle, PM_LOG_DEBUG, "checking signature for %s\n", + db->treename); + ret = _alpm_gpgme_checksig(db->handle, dbpath, NULL); + if((check_sig == PM_PGP_VERIFY_ALWAYS && ret != 0) || + (check_sig == PM_PGP_VERIFY_OPTIONAL && ret == 1)) { + RET_ERR(db->handle, PM_ERR_SIG_INVALID, -1); + } + } + +valid: + db->status |= DB_STATUS_VALID; + return 0; +} + /** Update a package database * * An update of the package database \a db will be attempted. Unless * \a force is true, the update will only be performed if the remote * database was modified since the last update. * - * A transaction is necessary for this operation, in order to obtain a - * database lock. During this transaction the front-end will be informed - * of the download progress of the database via the download callback. + * This operation requires a database lock, and will return an applicable error + * if the lock could not be obtained. * * Example: * @code * alpm_list_t *syncs = alpm_option_get_syncdbs(); - * if(alpm_trans_init(0, NULL, NULL, NULL) == 0) { - * for(i = syncs; i; i = alpm_list_next(i)) { - * pmdb_t *db = alpm_list_getdata(i); - * result = alpm_db_update(0, db); - * alpm_trans_release(); + * for(i = syncs; i; i = alpm_list_next(i)) { + * pmdb_t *db = alpm_list_getdata(i); + * result = alpm_db_update(0, db); * - * if(result < 0) { - * printf("Unable to update database: %s\n", alpm_strerrorlast()); - * } else if(result == 1) { - * printf("Database already up to date\n"); - * } else { - * printf("Database updated\n"); - * } + * if(result < 0) { + * printf("Unable to update database: %s\n", alpm_strerrorlast()); + * } else if(result == 1) { + * printf("Database already up to date\n"); + * } else { + * printf("Database updated\n"); * } * } * @endcode @@ -120,15 +158,21 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) 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); - syncpath = get_sync_dir(handle); if(!syncpath) { return -1; } + + /* make sure we have a sane umask */ + oldmask = umask(0022); + check_sig = _alpm_db_get_sigverify_level(db); + /* attempt to grab a lock */ + if(_alpm_handle_lock(handle)) { + RET_ERR(handle, PM_ERR_HANDLE_LOCK, -1); + } + for(i = db->servers; i; i = i->next) { const char *server = i->data; char *fileurl; @@ -144,6 +188,15 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) if(ret == 0 && (check_sig == PM_PGP_VERIFY_ALWAYS || check_sig == PM_PGP_VERIFY_OPTIONAL)) { + /* an existing sig file is no good at this point */ + char *sigpath = _alpm_db_sig_path(db); + if(!sigpath) { + ret = -1; + break; + } + unlink(sigpath); + free(sigpath); + 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); @@ -173,8 +226,18 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) /* Cache needs to be rebuilt */ _alpm_db_free_pkgcache(db); + db->status &= ~DB_STATUS_VALID; + if(sync_db_validate(db)) { + /* pm_errno should be set */ + ret = -1; + } + cleanup: + if(_alpm_handle_unlock(handle)) { + _alpm_log(handle, PM_LOG_WARNING, _("could not remove lock file %s\n"), + alpm_option_get_lockfile(handle)); + } free(syncpath); umask(oldmask); return ret; @@ -512,18 +575,13 @@ error: return -1; } -static int sync_db_version(pmdb_t UNUSED *db) -{ - return 2; -} - struct db_operations sync_db_ops = { .populate = sync_db_populate, .unregister = _alpm_db_unregister, - .version = sync_db_version, }; -pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename) +pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename, + pgp_verify_t level) { pmdb_t *db; @@ -535,6 +593,12 @@ pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename) } db->ops = &sync_db_ops; db->handle = handle; + db->pgp_verify = level; + + if(sync_db_validate(db)) { + _alpm_db_free(db); + return NULL; + } handle->dbs_sync = alpm_list_add(handle->dbs_sync, db); return db; diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index c3a7abd2..b20421a3 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -45,7 +45,8 @@ */ /** Register a sync database of packages. */ -pmdb_t SYMEXPORT *alpm_db_register_sync(pmhandle_t *handle, const char *treename) +pmdb_t SYMEXPORT *alpm_db_register_sync(pmhandle_t *handle, const char *treename, + pgp_verify_t check_sig) { /* Sanity checks */ CHECK_HANDLE(handle, return NULL); @@ -54,7 +55,7 @@ pmdb_t SYMEXPORT *alpm_db_register_sync(pmhandle_t *handle, const char *treename /* Do not register a database if a transaction is on-going */ ASSERT(handle->trans == NULL, RET_ERR(handle, PM_ERR_TRANS_NOT_NULL, NULL)); - return _alpm_db_register_sync(handle, treename); + return _alpm_db_register_sync(handle, treename, check_sig); } /* Helper function for alpm_db_unregister{_all} */ @@ -369,14 +370,6 @@ const char *_alpm_db_path(pmdb_t *db) return db->_path; } -int _alpm_db_version(pmdb_t *db) -{ - if(!db) { - return -1; - } - return db->ops->version(db); -} - char *_alpm_db_sig_path(pmdb_t *db) { char *sigpath; @@ -475,11 +468,8 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) /* Returns a new package cache from db. * It frees the cache if it already exists. */ -int _alpm_db_load_pkgcache(pmdb_t *db) +static int load_pkgcache(pmdb_t *db) { - if(db == NULL) { - return -1; - } _alpm_db_free_pkgcache(db); _alpm_log(db->handle, PM_LOG_DEBUG, "loading package cache for repository '%s'\n", @@ -490,23 +480,23 @@ int _alpm_db_load_pkgcache(pmdb_t *db) return -1; } - db->pkgcache_loaded = 1; + db->status |= DB_STATUS_PKGCACHE; return 0; } void _alpm_db_free_pkgcache(pmdb_t *db) { - if(db == NULL || !db->pkgcache_loaded) { + if(db == NULL || !(db->status & DB_STATUS_PKGCACHE)) { return; } - _alpm_log(db->handle, PM_LOG_DEBUG, "freeing package cache for repository '%s'\n", - db->treename); + _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), (alpm_list_fn_free)_alpm_pkg_free); _alpm_pkghash_free(db->pkgcache); - db->pkgcache_loaded = 0; + db->status &= ~DB_STATUS_PKGCACHE; _alpm_db_free_grpcache(db); } @@ -517,13 +507,12 @@ pmpkghash_t *_alpm_db_get_pkgcache_hash(pmdb_t *db) return NULL; } - if(!db->pkgcache_loaded) { - _alpm_db_load_pkgcache(db); + if(!(db->status & DB_STATUS_VALID)) { + RET_ERR(db->handle, PM_ERR_DB_INVALID, NULL); } - /* hmmm, still NULL ?*/ - if(!db->pkgcache) { - _alpm_log(db->handle, PM_LOG_DEBUG, "warning: pkgcache is NULL for db '%s'\n", db->treename); + if(!(db->status & DB_STATUS_PKGCACHE)) { + load_pkgcache(db); } return db->pkgcache; @@ -545,7 +534,7 @@ int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg) { pmpkg_t *newpkg; - if(db == NULL || !db->pkgcache_loaded || pkg == NULL) { + if(db == NULL || pkg == NULL || !(db->status & DB_STATUS_PKGCACHE)) { return -1; } @@ -567,7 +556,7 @@ int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg) { pmpkg_t *data = NULL; - if(db == NULL || !db->pkgcache_loaded || pkg == NULL) { + if(db == NULL || pkg == NULL || !(db->status & DB_STATUS_PKGCACHE)) { return -1; } @@ -597,8 +586,6 @@ pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target) pmpkghash_t *pkgcache = _alpm_db_get_pkgcache_hash(db); if(!pkgcache) { - _alpm_log(db->handle, PM_LOG_DEBUG, "warning: failed to get '%s' from NULL pkgcache\n", - target); return NULL; } @@ -607,7 +594,7 @@ pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target) /* Returns a new group cache from db. */ -int _alpm_db_load_grpcache(pmdb_t *db) +static int load_grpcache(pmdb_t *db) { alpm_list_t *lp; @@ -653,7 +640,7 @@ int _alpm_db_load_grpcache(pmdb_t *db) } } - db->grpcache_loaded = 1; + db->status |= DB_STATUS_GRPCACHE; return 0; } @@ -661,19 +648,19 @@ void _alpm_db_free_grpcache(pmdb_t *db) { alpm_list_t *lg; - if(db == NULL || !db->grpcache_loaded) { + if(db == NULL || !(db->status & DB_STATUS_GRPCACHE)) { return; } - _alpm_log(db->handle, PM_LOG_DEBUG, "freeing group cache for repository '%s'\n", - db->treename); + _alpm_log(db->handle, PM_LOG_DEBUG, + "freeing group cache for repository '%s'\n", db->treename); for(lg = db->grpcache; lg; lg = lg->next) { _alpm_grp_free(lg->data); lg->data = NULL; } FREELIST(db->grpcache); - db->grpcache_loaded = 0; + db->status &= ~DB_STATUS_GRPCACHE; } alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db) @@ -682,8 +669,12 @@ alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db) return NULL; } - if(!db->grpcache_loaded) { - _alpm_db_load_grpcache(db); + if(!(db->status & DB_STATUS_VALID)) { + RET_ERR(db->handle, PM_ERR_DB_INVALID, NULL); + } + + if(!(db->status & DB_STATUS_GRPCACHE)) { + load_grpcache(db); } return db->grpcache; diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h index e3faeeb4..03187342 100644 --- a/lib/libalpm/db.h +++ b/lib/libalpm/db.h @@ -43,10 +43,16 @@ typedef enum _pmdbinfrq_t { INFRQ_ALL = 0x1F } pmdbinfrq_t; +/** Database status. Bitflags. */ +enum _pmdbstatus_t { + DB_STATUS_VALID = (1 << 0), + DB_STATUS_PKGCACHE = (1 << 1), + DB_STATUS_GRPCACHE = (1 << 2) +}; + struct db_operations { int (*populate) (pmdb_t *); void (*unregister) (pmdb_t *); - int (*version) (pmdb_t *); }; /* Database */ @@ -55,10 +61,10 @@ struct __pmdb_t { char *treename; /* do not access directly, use _alpm_db_path(db) for lazy access */ char *_path; - int pkgcache_loaded; - int grpcache_loaded; /* also indicates whether we are RO or RW */ int is_local; + /* flags determining validity, loaded caches, etc. */ + enum _pmdbstatus_t status; pmpkghash_t *pkgcache; alpm_list_t *grpcache; alpm_list_t *servers; @@ -73,11 +79,11 @@ 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(pmhandle_t *handle); -pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename); +pmdb_t *_alpm_db_register_sync(pmhandle_t *handle, const char *treename, + pgp_verify_t level); void _alpm_db_unregister(pmdb_t *db); /* be_*.c, backend specific calls */ @@ -88,7 +94,6 @@ int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info); /* cache bullshit */ /* packages */ -int _alpm_db_load_pkgcache(pmdb_t *db); void _alpm_db_free_pkgcache(pmdb_t *db); int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg); int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg); @@ -97,7 +102,6 @@ alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db); int _alpm_db_ensure_pkgcache(pmdb_t *db, pmdbinfrq_t infolevel); pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target); /* groups */ -int _alpm_db_load_grpcache(pmdb_t *db); void _alpm_db_free_grpcache(pmdb_t *db); alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db); pmgrp_t *_alpm_db_get_grpfromcache(pmdb_t *db, const char *target); diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c index d893f866..1e4e705b 100644 --- a/lib/libalpm/error.c +++ b/lib/libalpm/error.c @@ -70,6 +70,8 @@ const char SYMEXPORT *alpm_strerror(enum _pmerrno_t err) return _("database already registered"); case PM_ERR_DB_NOT_FOUND: return _("could not find database"); + case PM_ERR_DB_INVALID: + return _("invalid or corrupted database"); case PM_ERR_DB_VERSION: return _("database is incorrect version"); case PM_ERR_DB_WRITE: diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index b535e0f3..acd35409 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -22,12 +22,14 @@ #include "config.h" +#include <errno.h> #include <stdlib.h> #include <string.h> #include <limits.h> #include <sys/types.h> #include <syslog.h> #include <sys/stat.h> +#include <fcntl.h> /* libalpm */ #include "handle.h" @@ -86,6 +88,58 @@ void _alpm_handle_free(pmhandle_t *handle) FREE(handle); } +/** Lock the database */ +int _alpm_handle_lock(pmhandle_t *handle) +{ + int fd; + char *dir, *ptr; + + ASSERT(handle->lockfile != NULL, return -1); + ASSERT(handle->lckstream == NULL, return 0); + + /* create the dir of the lockfile first */ + dir = strdup(handle->lockfile); + ptr = strrchr(dir, '/'); + if(ptr) { + *ptr = '\0'; + } + if(_alpm_makepath(dir)) { + FREE(dir); + return -1; + } + FREE(dir); + + do { + fd = open(handle->lockfile, O_WRONLY | O_CREAT | O_EXCL, 0000); + } 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 -1; +} + +/** Remove a lock file */ +int _alpm_handle_unlock(pmhandle_t *handle) +{ + ASSERT(handle->lockfile != NULL, return -1); + ASSERT(handle->lckstream != NULL, return 0); + + if(handle->lckstream != NULL) { + fclose(handle->lckstream); + handle->lckstream = NULL; + } + if(unlink(handle->lockfile) && errno != ENOENT) { + return -1; + } + return 0; +} + + alpm_cb_log SYMEXPORT alpm_option_get_logcb(pmhandle_t *handle) { CHECK_HANDLE(handle, return NULL); diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 2de6efdd..4ffd00c4 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -78,6 +78,9 @@ struct __pmhandle_t { pmhandle_t *_alpm_handle_new(void); void _alpm_handle_free(pmhandle_t *handle); +int _alpm_handle_lock(pmhandle_t *handle); +int _alpm_handle_unlock(pmhandle_t *handle); + enum _pmerrno_t _alpm_set_directory_option(const char *value, char **storage, int must_exist); diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index f0744937..507ea027 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -30,7 +30,6 @@ #include <sys/types.h> #include <errno.h> #include <limits.h> -#include <fcntl.h> /* libalpm */ #include "trans.h" @@ -48,69 +47,28 @@ * @{ */ -/* Create a lock file */ -static int make_lock(pmhandle_t *handle) -{ - int fd; - char *dir, *ptr; - - ASSERT(handle->lockfile != NULL, return -1); - - /* create the dir of the lockfile first */ - dir = strdup(handle->lockfile); - ptr = strrchr(dir, '/'); - if(ptr) { - *ptr = '\0'; - } - if(_alpm_makepath(dir)) { - FREE(dir); - return -1; - } - FREE(dir); - - do { - fd = open(handle->lockfile, O_WRONLY | O_CREAT | O_EXCL, 0000); - } 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 -1; -} - -/* Remove a lock file */ -static int remove_lock(pmhandle_t *handle) -{ - if(handle->lckstream != NULL) { - fclose(handle->lckstream); - handle->lckstream = NULL; - } - if(unlink(handle->lockfile) == -1 && errno != ENOENT) { - return -1; - } - return 0; -} - /** Initialize the transaction. */ 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) { pmtrans_t *trans; - const int required_db_version = 2; - int db_version; + alpm_list_t *i; /* Sanity checks */ CHECK_HANDLE(handle, return -1); ASSERT(handle->trans == NULL, RET_ERR(handle, PM_ERR_TRANS_NOT_NULL, -1)); + for(i = handle->dbs_sync; i; i = i->next) { + const pmdb_t *db = i->data; + if(!(db->status & DB_STATUS_VALID)) { + RET_ERR(handle, PM_ERR_DB_INVALID, -1); + } + } + /* lock db */ if(!(flags & PM_TRANS_FLAG_NOLOCK)) { - if(make_lock(handle)) { + if(_alpm_handle_lock(handle)) { RET_ERR(handle, PM_ERR_HANDLE_LOCK, -1); } } @@ -122,16 +80,6 @@ int SYMEXPORT alpm_trans_init(pmhandle_t *handle, pmtransflag_t flags, trans->cb_progress = progress; trans->state = STATE_INITIALIZED; - /* check database version */ - db_version = _alpm_db_version(handle->db_local); - if(db_version < required_db_version) { - _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(handle, PM_ERR_DB_VERSION, -1); - } - handle->trans = trans; return 0; @@ -282,7 +230,7 @@ int SYMEXPORT alpm_trans_release(pmhandle_t *handle) /* unlock db */ if(!nolock_flag) { - if(remove_lock(handle)) { + if(_alpm_handle_unlock(handle)) { _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", diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 3d40bc1e..d1cf175e 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -52,7 +52,6 @@ readonly -a packaging_options other_options splitpkg_overrides # Options ASROOT=0 CLEANUP=0 -CLEANCACHE=0 DEP_BIN=0 FORCE=0 INFAKEROOT=0 @@ -1661,7 +1660,6 @@ usage() { echo "$(gettext "Options:")" printf "$(gettext " -A, --ignorearch Ignore incomplete %s field in %s")\n" "arch" "$BUILDSCRIPT" echo "$(gettext " -c, --clean Clean up work files after build")" - echo "$(gettext " -C, --cleancache Clean up source files from the cache")" echo "$(gettext " -d, --nodeps Skip all dependency checks")" printf "$(gettext " -e, --noextract Do not extract source files (use existing %s dir)")\n" "src/" echo "$(gettext " -f, --force Overwrite existing package")" @@ -1719,7 +1717,7 @@ ARGLIST=("$@") # Parse Command Line Options. OPT_SHORT="AcCdefFghiLmop:rRsV" -OPT_LONG="allsource,asroot,ignorearch,check,clean,cleancache,nodeps" +OPT_LONG="allsource,asroot,ignorearch,check,clean,nodeps" OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver" OPT_LONG+=",install,key:,log,nocolor,nobuild,nocheck,nosign,pkg:,rmdeps" OPT_LONG+=",repackage,skipinteg,sign,source,syncdeps,version,config:" @@ -1744,7 +1742,6 @@ while true; do --asroot) ASROOT=1 ;; -A|--ignorearch) IGNOREARCH=1 ;; -c|--clean) CLEANUP=1 ;; - -C|--cleancache) CLEANCACHE=1 ;; --check) RUN_CHECK='y' ;; --config) shift; MAKEPKG_CONF=$1 ;; -d|--nodeps) NODEPS=1 ;; @@ -1876,37 +1873,6 @@ if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then exit 1 fi -if (( CLEANCACHE )); then - #fix flyspray feature request #5223 - if [[ -n $SRCDEST && ! $SRCDEST -ef "${startdir}" ]]; then - msg "$(gettext "Cleaning up ALL files from %s.")" "$SRCDEST" - echo -n "$(gettext " Are you sure you wish to do this? ")" - echo -n "$(gettext "[y/N]")" - read answer - answer=$(tr '[:lower:]' '[:upper:]' <<< "$answer") - if [[ $answer = $(gettext YES) || $answer = $(gettext Y) ]]; then - rm "$SRCDEST"/* - if (( $? )); then - error "$(gettext "Problem removing files; you may not have correct permissions in %s")" "$SRCDEST" - exit 1 - else - # removal worked - msg "$(gettext "Source cache cleaned.")" - exit 0 - fi - else - # answer = no - msg "$(gettext "No files have been removed.")" - exit 0 - fi - else - # $SRCDEST is $startdir, two possibilities - error "$(gettext "Source destination must be defined in %s.")" "$MAKEPKG_CONF" - plain "$(gettext "In addition, please run %s outside of your cache directory.")" "makepkg -C" - exit 1 - fi -fi - if (( ! INFAKEROOT )); then if (( EUID == 0 && ! ASROOT )); then # Warn those who like to live dangerously. @@ -2245,7 +2211,7 @@ else if (( ! REPKG )); then tidy_install else - warning "$(gettext "Repackaging without the use of a %s" function is deprecated.")" "package()" + warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()" plain "$(gettext "File permissions may not be preserved.")" fi fi diff --git a/src/pacman/conf.c b/src/pacman/conf.c index 081cdd5e..076e854d 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -449,6 +449,9 @@ static int setup_libalpm(void) if(!handle) { pm_printf(PM_LOG_ERROR, _("failed to initialize alpm library (%s)\n"), alpm_strerror(err)); + if(err == PM_ERR_DB_VERSION) { + pm_printf(PM_LOG_ERROR, _(" try running pacman-db-upgrade\n")); + } return -1; } config->handle = handle; @@ -460,7 +463,7 @@ static int setup_libalpm(void) ret = alpm_option_set_logfile(handle, config->logfile); if(ret != 0) { pm_printf(PM_LOG_ERROR, _("problem setting logfile '%s' (%s)\n"), - config->logfile, alpm_strerror(alpm_errno(config->handle))); + config->logfile, alpm_strerror(alpm_errno(handle))); return ret; } @@ -470,7 +473,7 @@ static int setup_libalpm(void) ret = alpm_option_set_gpgdir(handle, config->gpgdir); if(ret != 0) { pm_printf(PM_LOG_ERROR, _("problem setting gpgdir '%s' (%s)\n"), - config->gpgdir, alpm_strerror(alpm_errno(config->handle))); + config->gpgdir, alpm_strerror(alpm_errno(handle))); return ret; } @@ -542,7 +545,7 @@ static int finish_section(struct section_t *section, int parse_options) } /* if we are not looking at options sections only, register a db */ - db = alpm_db_register_sync(config->handle, section->name); + db = alpm_db_register_sync(config->handle, section->name, section->sigverify); if(db == NULL) { pm_printf(PM_LOG_ERROR, _("could not register '%s' database (%s)\n"), section->name, alpm_strerror(alpm_errno(config->handle))); @@ -550,16 +553,6 @@ static int finish_section(struct section_t *section, int parse_options) goto cleanup; } - if(section->sigverify) { - if(alpm_db_set_pgp_verify(db, section->sigverify)) { - pm_printf(PM_LOG_ERROR, - _("could not set verify option for database '%s' (%s)\n"), - section->name, alpm_strerror(alpm_errno(config->handle))); - ret = 1; - goto cleanup; - } - } - for(i = section->servers; i; i = alpm_list_next(i)) { char *value = alpm_list_getdata(i); if(_add_mirror(db, value) != 0) { diff --git a/src/pacman/sync.c b/src/pacman/sync.c index 6c86bd10..f242c827 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -283,10 +283,6 @@ static int sync_synctree(int level, alpm_list_t *syncs) alpm_list_t *i; int success = 0, ret; - if(trans_init(0) == -1) { - return 0; - } - for(i = syncs; i; i = alpm_list_next(i)) { pmdb_t *db = alpm_list_getdata(i); @@ -302,9 +298,6 @@ static int sync_synctree(int level, alpm_list_t *syncs) } } - if(trans_release() == -1) { - return 0; - } /* We should always succeed if at least one DB was upgraded - we may possibly * fail later with unresolved deps, but that should be rare, and would be * expected diff --git a/src/pacman/util.c b/src/pacman/util.c index 66f127c6..77a7e56c 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -68,9 +68,6 @@ int trans_init(pmtransflag_t flags) " running, you can remove %s\n"), alpm_option_get_lockfile(config->handle)); } - else if(err == PM_ERR_DB_VERSION) { - fprintf(stderr, _(" try running pacman-db-upgrade\n")); - } return -1; } diff --git a/src/util/cleanupdelta.c b/src/util/cleanupdelta.c index 98291706..5ee59dbb 100644 --- a/src/util/cleanupdelta.c +++ b/src/util/cleanupdelta.c @@ -75,7 +75,7 @@ static void checkdbs(const char *dbpath, alpm_list_t *dbnames) { for(i = dbnames; i; i = alpm_list_next(i)) { char *dbname = alpm_list_getdata(i); snprintf(syncdbpath, PATH_MAX, "%s/sync/%s", dbpath, dbname); - db = alpm_db_register_sync(handle, dbname); + db = alpm_db_register_sync(handle, dbname, PM_PGP_VERIFY_OPTIONAL); if(db == NULL) { fprintf(stderr, "error: could not register sync database (%s)\n", alpm_strerror(alpm_errno(handle))); diff --git a/src/util/pactree.c b/src/util/pactree.c index 6b29d935..87bac6d1 100644 --- a/src/util/pactree.c +++ b/src/util/pactree.c @@ -75,7 +75,6 @@ static struct color_choices no_color = { /* globals */ pmhandle_t *handle = NULL; -pmdb_t *db_local; alpm_list_t *walked = NULL; alpm_list_t *provisions = NULL; @@ -241,15 +240,27 @@ static void print_end(void) } } +static pmpkg_t *get_pkg_from_dbs(alpm_list_t *dbs, const char *needle) { + alpm_list_t *i; + pmpkg_t *ret; + + for(i = dbs; i; i = alpm_list_next(i)) { + ret = alpm_db_get_pkg(alpm_list_getdata(i), needle); + if(ret) { + return ret; + } + } + return NULL; +} /** * walk dependencies in reverse, showing packages which require the target */ -static void walk_reverse_deps(pmpkg_t *pkg, int depth) +static void walk_reverse_deps(alpm_list_t *dblist, pmpkg_t *pkg, int depth) { alpm_list_t *required_by, *i; - if((max_depth >= 0) && (depth == max_depth + 1)) { + if(!pkg || ((max_depth >= 0) && (depth == max_depth + 1))) { return; } @@ -267,7 +278,7 @@ static void walk_reverse_deps(pmpkg_t *pkg, int depth) } } else { print(alpm_pkg_get_name(pkg), pkgname, NULL, depth); - walk_reverse_deps(alpm_db_get_pkg(db_local, pkgname), depth + 1); + walk_reverse_deps(dblist, get_pkg_from_dbs(dblist, pkgname), depth + 1); } } @@ -277,7 +288,7 @@ static void walk_reverse_deps(pmpkg_t *pkg, int depth) /** * walk dependencies, showing dependencies of the target */ -static void walk_deps(pmpkg_t *pkg, int depth) +static void walk_deps(alpm_list_t *dblist, pmpkg_t *pkg, int depth) { alpm_list_t *i; @@ -289,8 +300,7 @@ static void walk_deps(pmpkg_t *pkg, int depth) for(i = alpm_pkg_get_depends(pkg); i; i = alpm_list_next(i)) { pmdepend_t *depend = alpm_list_getdata(i); - pmpkg_t *provider = alpm_find_satisfier(alpm_db_get_pkgcache(db_local), - depend->name); + pmpkg_t *provider = alpm_find_dbs_satisfier(handle, dblist, depend->name); if(provider) { const char *provname = alpm_pkg_get_name(provider); @@ -303,7 +313,7 @@ static void walk_deps(pmpkg_t *pkg, int depth) } } else { print(alpm_pkg_get_name(pkg), provname, depend->name, depth); - walk_deps(provider, depth + 1); + walk_deps(dblist, provider, depth + 1); } } else { /* unresolvable package */ @@ -318,6 +328,7 @@ int main(int argc, char *argv[]) enum _pmerrno_t err; const char *target_name; pmpkg_t *pkg; + alpm_list_t *dblist = NULL; if(parse_options(argc, argv) != 0) { usage(); @@ -333,12 +344,12 @@ int main(int argc, char *argv[]) goto finish; } - db_local = alpm_option_get_localdb(handle); + dblist = alpm_list_add(dblist, alpm_option_get_localdb(handle)); /* we only care about the first non option arg for walking */ target_name = argv[optind]; - pkg = alpm_find_satisfier(alpm_db_get_pkgcache(db_local), target_name); + pkg = alpm_find_dbs_satisfier(handle, dblist, target_name); if(!pkg) { fprintf(stderr, "error: package '%s' not found\n", target_name); ret = 1; @@ -348,13 +359,15 @@ int main(int argc, char *argv[]) print_start(alpm_pkg_get_name(pkg), target_name); if(reverse) { - walk_reverse_deps(pkg, 1); + walk_reverse_deps(dblist, pkg, 1); } else { - walk_deps(pkg, 1); + walk_deps(dblist, pkg, 1); } print_end(); + alpm_list_free(dblist); + finish: cleanup(); return ret; diff --git a/src/util/testdb.c b/src/util/testdb.c index 4937480d..af5007e2 100644 --- a/src/util/testdb.c +++ b/src/util/testdb.c @@ -151,7 +151,7 @@ static int check_syncdbs(alpm_list_t *dbnames) { for(i = dbnames; i; i = alpm_list_next(i)) { char *dbname = alpm_list_getdata(i); - db = alpm_db_register_sync(handle, dbname); + db = alpm_db_register_sync(handle, dbname, PM_PGP_VERIFY_OPTIONAL); if(db == NULL) { fprintf(stderr, "error: could not register sync database (%s)\n", alpm_strerror(alpm_errno(handle))); diff --git a/test/pacman/tests/ignore007.py b/test/pacman/tests/ignore007.py index 90ff4ef6..7670e770 100644 --- a/test/pacman/tests/ignore007.py +++ b/test/pacman/tests/ignore007.py @@ -18,4 +18,4 @@ self.args = "--ask=1 -S grp" self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=%s" % pkg1.name) self.addrule("PKG_EXIST=%s" % pkg2.name) -self.addrule("PACMAN_OUTPUT=is in IgnorePkg") +self.addrule("PKG_EXIST=%s" % pkg3.name) diff --git a/test/pacman/tests/sign001.py b/test/pacman/tests/sign001.py index 0ae417b7..14add09c 100644 --- a/test/pacman/tests/sign001.py +++ b/test/pacman/tests/sign001.py @@ -1,8 +1,8 @@ -self.description = "Add a signature to a package DB" +self.description = "Add a bogus signature to a package DB" sp = pmpkg("pkg1") sp.pgpsig = "asdfasdfsdfasdfsdafasdfsdfasd" -self.addpkg2db("sync+Always", sp) +self.addpkg2db("sync+Optional", sp) self.args = "-Ss" |