---
Any feedback on this going in? One of the checklist items on my 3.5.0 release
list.

-Dan

 lib/libalpm/alpm.c     |    2 +
 lib/libalpm/alpm.h     |    1 +
 lib/libalpm/be_local.c |   54 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/libalpm/be_sync.c  |    6 +++++
 lib/libalpm/db.c       |    8 +++++++
 lib/libalpm/db.h       |    4 ++-
 lib/libalpm/error.c    |    2 +
 lib/libalpm/trans.c    |   15 +++++++++++-
 src/pacman/util.c      |    4 +++
 9 files changed, 93 insertions(+), 3 deletions(-)

diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c
index 7c3bfc2..4f95832 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 cf3a913..0f3b716 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 c1e86a6..a0d8b73 100644
--- a/lib/libalpm/be_local.c
+++ b/lib/libalpm/be_local.c
@@ -924,9 +924,63 @@ 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) {
+                       printf("found %s\n", path);
+                       /* 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 69f7663..2191494 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 2a8db8e..fb64fae 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 a530a2e..75776d7 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 2cc6685..21fbb48 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 9f61796..7a3ee83 100644
--- a/lib/libalpm/trans.c
+++ b/lib/libalpm/trans.c
@@ -59,10 +59,11 @@
  * @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 localdb_version = 2;
 
        ALPM_LOG_FUNC;
 
@@ -79,6 +80,16 @@ int SYMEXPORT alpm_trans_init(pmtransflag_t flags,
                }
        }
 
+       /* check database version */
+       if(_alpm_db_version(handle->db_local) < localdb_version) {
+               _alpm_log(PM_LOG_ERROR,
+                               _("%s database version %d is too old, version 
%d required\n"),
+                               handle->db_local->treename, 
_alpm_db_version(handle->db_local),
+                               localdb_version);
+               _alpm_lckrm();
+               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 c08ebb1..9d50afb 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);
-- 
1.7.4.1


Reply via email to