summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libalpm/alpm.c2
-rw-r--r--lib/libalpm/alpm.h1
-rw-r--r--lib/libalpm/be_local.c53
-rw-r--r--lib/libalpm/be_sync.c6
-rw-r--r--lib/libalpm/db.c8
-rw-r--r--lib/libalpm/db.h4
-rw-r--r--lib/libalpm/error.c2
-rw-r--r--lib/libalpm/trans.c15
-rw-r--r--src/pacman/util.c4
9 files changed, 92 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);
diff --git a/src/pacman/util.c b/src/pacman/util.c
index c08ebb15..9d50afb2 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -63,6 +63,10 @@ int trans_init(pmtransflag_t flags)
fprintf(stderr, _(" if you're sure a package manager is not already\n"
" running, you can remove %s\n"), alpm_option_get_lockfile());
}
+ else if(pm_errno == PM_ERR_DB_VERSION) {
+ fprintf(stderr, _(" try running pacman-db-upgrade\n"));
+ }
+
return(-1);
}
return(0);