diff options
Diffstat (limited to 'lib/libalpm')
-rw-r--r-- | lib/libalpm/alpm.c | 2 | ||||
-rw-r--r-- | lib/libalpm/alpm.h | 1 | ||||
-rw-r--r-- | lib/libalpm/be_local.c | 53 | ||||
-rw-r--r-- | lib/libalpm/be_sync.c | 6 | ||||
-rw-r--r-- | lib/libalpm/db.c | 8 | ||||
-rw-r--r-- | lib/libalpm/db.h | 4 | ||||
-rw-r--r-- | lib/libalpm/error.c | 2 | ||||
-rw-r--r-- | lib/libalpm/trans.c | 15 |
8 files changed, 88 insertions, 3 deletions
diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index 7c3bfc26..4f95832d 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -56,6 +56,8 @@ int SYMEXPORT alpm_initialize(void) } if(_alpm_db_register_local() == NULL) { /* error code should be set */ + _alpm_handle_free(handle); + handle = NULL; return(-1); } diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index cf3a9135..0f3b7166 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -497,6 +497,7 @@ enum _pmerrno_t { PM_ERR_DB_NULL, PM_ERR_DB_NOT_NULL, PM_ERR_DB_NOT_FOUND, + PM_ERR_DB_VERSION, PM_ERR_DB_WRITE, PM_ERR_DB_REMOVE, /* Servers */ diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index c1e86a63..848ecc58 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -924,9 +924,62 @@ 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(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(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(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(void) diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index 69f7663d..21914944 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -443,9 +443,15 @@ error: return(0); } +static int sync_db_version(pmdb_t *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(const char *treename) diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index 2a8db8e0..fb64faed 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -405,6 +405,14 @@ 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)); +} + int _alpm_db_cmp(const void *d1, const void *d2) { pmdb_t *db1 = (pmdb_t *)d1; diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h index a530a2e9..75776d71 100644 --- a/lib/libalpm/db.h +++ b/lib/libalpm/db.h @@ -45,6 +45,7 @@ typedef enum _pmdbinfrq_t { struct db_operations { int (*populate) (pmdb_t *); void (*unregister) (pmdb_t *); + int (*version) (pmdb_t *); }; /* Database */ @@ -65,14 +66,15 @@ struct __pmdb_t { /* db.c, database general calls */ +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); +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); void _alpm_db_unregister(pmdb_t *db); -pmdb_t *_alpm_db_new(const char *treename, int is_local); /* be_*.c, backend specific calls */ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq); diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c index 2cc66851..21fbb48f 100644 --- a/lib/libalpm/error.c +++ b/lib/libalpm/error.c @@ -77,6 +77,8 @@ const char SYMEXPORT *alpm_strerror(int err) return _("database already registered"); case PM_ERR_DB_NOT_FOUND: return _("could not find database"); + case PM_ERR_DB_VERSION: + return _("database is incorrect version"); case PM_ERR_DB_WRITE: return _("could not update database"); case PM_ERR_DB_REMOVE: diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index 8e47f377..4b29f9a8 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -105,10 +105,12 @@ static int remove_lock(pmhandle_t *handle) * @return 0 on success, -1 on error (pm_errno is set accordingly) */ int SYMEXPORT alpm_trans_init(pmtransflag_t flags, - alpm_trans_cb_event event, alpm_trans_cb_conv conv, - alpm_trans_cb_progress progress) + 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_LOG_FUNC; @@ -124,6 +126,15 @@ int SYMEXPORT alpm_trans_init(pmtransflag_t flags, } } + /* check database version */ + db_version = _alpm_db_version(handle->db_local); + if(db_version < required_db_version) { + _alpm_log(PM_LOG_ERROR, + _("%s database version is too old\n"), handle->db_local->treename); + remove_lock(handle); + RET_ERR(PM_ERR_DB_VERSION, -1); + } + trans = _alpm_trans_new(); if(trans == NULL) { RET_ERR(PM_ERR_MEMORY, -1); |