diff options
Diffstat (limited to 'lib/libalpm/db.c')
-rw-r--r-- | lib/libalpm/db.c | 255 |
1 files changed, 168 insertions, 87 deletions
diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index 95a1ecb3..b06a970c 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -53,11 +53,11 @@ * @{ */ -/** Register a package database - * @param treename the name of the repository +/** Register a sync database of packages. + * @param treename the name of the sync repository * @return a pmdb_t* on success (the value), NULL on error */ -pmdb_t SYMEXPORT *alpm_db_register(const char *treename) +pmdb_t SYMEXPORT *alpm_db_register_sync(const char *treename) { ALPM_LOG_FUNC; @@ -67,7 +67,64 @@ pmdb_t SYMEXPORT *alpm_db_register(const char *treename) /* Do not register a database if a transaction is on-going */ ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, NULL)); - return(_alpm_db_register(treename)); + return(_alpm_db_register_sync(treename)); +} + +/** Register the local package database. + * @return a pmdb_t* representing the local database, or NULL on error + */ +pmdb_t SYMEXPORT *alpm_db_register_local(void) +{ + ALPM_LOG_FUNC; + + /* Sanity checks */ + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, NULL)); + /* Do not register a database if a transaction is on-going */ + ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, NULL)); + + return(_alpm_db_register_local()); +} + +/* Helper function for alpm_db_unregister{_all} */ +static void _alpm_db_unregister(pmdb_t *db) +{ + if(db == NULL) { + return; + } + + _alpm_log(PM_LOG_DEBUG, "closing database '%s'\n", db->treename); + _alpm_db_close(db); + + _alpm_log(PM_LOG_DEBUG, "unregistering database '%s'\n", db->treename); + _alpm_db_free(db); +} + +/** Unregister all package databases + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ +int SYMEXPORT alpm_db_unregister_all(void) +{ + alpm_list_t *i; + + ALPM_LOG_FUNC; + + /* Sanity checks */ + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + /* Do not unregister a database if a transaction is on-going */ + ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1)); + + /* close local database */ + _alpm_db_unregister(handle->db_local); + handle->db_local = NULL; + + /* and also sync ones */ + for(i = handle->dbs_sync; i; i = i->next) { + pmdb_t *db = i->data; + _alpm_db_unregister(db); + i->data = NULL; + } + FREELIST(handle->dbs_sync); + return(0); } /** Unregister a package database @@ -90,8 +147,13 @@ int SYMEXPORT alpm_db_unregister(pmdb_t *db) handle->db_local = NULL; found = 1; } else { + /* Warning : this function shouldn't be used to unregister all sync + * databases by walking through the list returned by + * alpm_option_get_syncdbs, because the db is removed from that list here. + */ void *data; - handle->dbs_sync = alpm_list_remove(handle->dbs_sync, db, _alpm_db_cmp, &data); + handle->dbs_sync = alpm_list_remove(handle->dbs_sync, + db, _alpm_db_cmp, &data); if(data) { found = 1; } @@ -101,16 +163,7 @@ int SYMEXPORT alpm_db_unregister(pmdb_t *db) RET_ERR(PM_ERR_DB_NOT_FOUND, -1); } - _alpm_log(PM_LOG_DEBUG, _("unregistering database '%s'"), db->treename); - - /* Cleanup */ - _alpm_db_free_pkgcache(db); - - _alpm_log(PM_LOG_DEBUG, _("closing database '%s'"), db->treename); - _alpm_db_close(db); - - _alpm_db_free(db); - + _alpm_db_unregister(db); return(0); } @@ -121,6 +174,7 @@ int SYMEXPORT alpm_db_unregister(pmdb_t *db) */ int SYMEXPORT alpm_db_setserver(pmdb_t *db, const char *url) { + alpm_list_t *i; int found = 0; ALPM_LOG_FUNC; @@ -128,18 +182,11 @@ int SYMEXPORT alpm_db_setserver(pmdb_t *db, const char *url) /* Sanity checks */ ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); - if(strcmp(db->treename, "local") == 0) { - if(handle->db_local != NULL) { + for(i = handle->dbs_sync; i && !found; i = i->next) { + pmdb_t *sdb = i->data; + if(strcmp(db->treename, sdb->treename) == 0) { found = 1; } - } else { - alpm_list_t *i; - 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); @@ -152,11 +199,11 @@ int SYMEXPORT alpm_db_setserver(pmdb_t *db, const char *url) return(-1); } db->servers = alpm_list_add(db->servers, server); - _alpm_log(PM_LOG_DEBUG, _("adding new server to database '%s': protocol '%s', server '%s', path '%s'"), + _alpm_log(PM_LOG_DEBUG, "adding new server to database '%s': protocol '%s', server '%s', path '%s'\n", db->treename, server->s_url->scheme, server->s_url->host, server->s_url->doc); } else { FREELIST(db->servers); - _alpm_log(PM_LOG_DEBUG, _("serverlist flushed for '%s'"), db->treename); + _alpm_log(PM_LOG_DEBUG, "serverlist flushed for '%s'\n", db->treename); } return(0); @@ -200,7 +247,7 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) /* get the lastupdate time */ _alpm_db_getlastupdate(db, lastupdate); if(strlen(lastupdate) == 0) { - _alpm_log(PM_LOG_DEBUG, _("failed to get lastupdate time for %s (no big deal)"), db->treename); + _alpm_log(PM_LOG_DEBUG, "failed to get lastupdate time for %s (no big deal)\n", db->treename); } } @@ -219,21 +266,23 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) } else if(ret == -1) { /* we use downloadLastErrString and downloadLastErrCode here, error returns from * libdownload */ - _alpm_log(PM_LOG_DEBUG, _("failed to sync db: %s [%d]"), downloadLastErrString, downloadLastErrCode); + _alpm_log(PM_LOG_DEBUG, "failed to sync db: %s [%d]\n", + downloadLastErrString, downloadLastErrCode); RET_ERR(PM_ERR_DB_SYNC, -1); } else { if(strlen(newmtime)) { - _alpm_log(PM_LOG_DEBUG, _("sync: new mtime for %s: %s"), db->treename, newmtime); + _alpm_log(PM_LOG_DEBUG, "sync: new mtime for %s: %s\n", + db->treename, newmtime); _alpm_db_setlastupdate(db, newmtime); } snprintf(path, PATH_MAX, "%s%s" DBEXT, dbpath, db->treename); /* remove the old dir */ - _alpm_log(PM_LOG_DEBUG, _("flushing database %s%s"), db->path); + _alpm_log(PM_LOG_DEBUG, "flushing database %s%s\n", db->path); for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) { pmpkg_t *pkg = lp->data; if(pkg && _alpm_db_remove(db, pkg) == -1) { - _alpm_log(PM_LOG_ERROR, _("could not remove database entry %s%s"), db->treename, + _alpm_log(PM_LOG_ERROR, _("could not remove database entry %s%s\n"), db->treename, alpm_pkg_get_name(pkg)); RET_ERR(PM_ERR_DB_REMOVE, -1); } @@ -369,19 +418,6 @@ alpm_list_t SYMEXPORT *alpm_db_getgrpcache(pmdb_t *db) return(_alpm_db_get_grpcache(db)); } -/** Tests a database - * @param db pointer to the package database to search in - * @return the list of problems found on success, NULL on error - */ -alpm_list_t SYMEXPORT *alpm_db_test(pmdb_t *db) -{ - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); - - return(_alpm_db_test(db)); -} - /** Searches a database * @param db pointer to the package database to search in * @param needles the list of strings to search for @@ -404,7 +440,7 @@ alpm_list_t SYMEXPORT *alpm_db_search(pmdb_t *db, const alpm_list_t* needles) /** Get a list of upgradable packages on the current system * @return a pmsyncpkg_t list of packages that are out of date */ -alpm_list_t SYMEXPORT *alpm_db_get_upgrades() +alpm_list_t SYMEXPORT *alpm_db_get_upgrades(void) { alpm_list_t *syncpkgs = NULL; const alpm_list_t *i, *j, *k, *m; @@ -413,7 +449,7 @@ alpm_list_t SYMEXPORT *alpm_db_get_upgrades() /* TODO holy nested loops, Batman! */ /* check for "recommended" package replacements */ - _alpm_log(PM_LOG_DEBUG, _("checking for package replacements")); + _alpm_log(PM_LOG_DEBUG, "checking for package replacements\n"); for(i = handle->dbs_sync; i; i = i->next) { for(j = _alpm_db_get_pkgcache(i->data); j; j = j->next) { pmpkg_t *spkg = j->data; @@ -424,10 +460,10 @@ alpm_list_t SYMEXPORT *alpm_db_get_upgrades() pmpkg_t *lpkg = m->data; if(strcmp(k->data, alpm_pkg_get_name(lpkg)) == 0) { - _alpm_log(PM_LOG_DEBUG, _("checking replacement '%s' for package '%s'"), k->data, - alpm_pkg_get_name(spkg)); + _alpm_log(PM_LOG_DEBUG, "checking replacement '%s' for package '%s'\n", + k->data, alpm_pkg_get_name(spkg)); if(alpm_list_find_str(handle->ignorepkg, alpm_pkg_get_name(lpkg))) { - _alpm_log(PM_LOG_WARNING, _("%s-%s: ignoring package upgrade (to be replaced by %s-%s)"), + _alpm_log(PM_LOG_WARNING, _("%s-%s: ignoring package upgrade (to be replaced by %s-%s)\n"), alpm_pkg_get_name(lpkg), alpm_pkg_get_version(lpkg), alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg)); } else { @@ -457,7 +493,7 @@ alpm_list_t SYMEXPORT *alpm_db_get_upgrades() sync->data = alpm_list_add(NULL, dummy); syncpkgs = alpm_list_add(syncpkgs, sync); } - _alpm_log(PM_LOG_DEBUG, _("%s-%s elected for upgrade (to be replaced by %s-%s)"), + _alpm_log(PM_LOG_DEBUG, "%s-%s elected for upgrade (to be replaced by %s-%s)\n", alpm_pkg_get_name(lpkg), alpm_pkg_get_version(lpkg), alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg)); } @@ -479,7 +515,8 @@ alpm_list_t SYMEXPORT *alpm_db_get_upgrades() spkg = _alpm_db_get_pkgfromcache(j->data, alpm_pkg_get_name(local)); } if(spkg == NULL) { - _alpm_log(PM_LOG_DEBUG, _("'%s' not found in sync db -- skipping"), alpm_pkg_get_name(local)); + _alpm_log(PM_LOG_DEBUG, "'%s' not found in sync db -- skipping\n", + alpm_pkg_get_name(local)); continue; } @@ -493,13 +530,13 @@ alpm_list_t SYMEXPORT *alpm_db_get_upgrades() } } if(replace) { - _alpm_log(PM_LOG_DEBUG, _("'%s' is already elected for removal -- skipping"), + _alpm_log(PM_LOG_DEBUG, "'%s' is already elected for removal -- skipping\n", alpm_pkg_get_name(local)); continue; } if(alpm_pkg_compare_versions(local, spkg)) { - _alpm_log(PM_LOG_DEBUG, _("%s elected for upgrade (%s => %s)"), + _alpm_log(PM_LOG_DEBUG, "%s elected for upgrade (%s => %s)\n", alpm_pkg_get_name(local), alpm_pkg_get_version(local), alpm_pkg_get_version(spkg)); @@ -547,15 +584,13 @@ pmdb_t *_alpm_db_new(const char *dbpath, const char *treename) db = calloc(1, sizeof(pmdb_t)); if(db == NULL) { - _alpm_log(PM_LOG_ERROR, _("malloc failed: could not allocate %d bytes"), - sizeof(pmdb_t)); + _alpm_log(PM_LOG_ERROR, "calloc : %s\n", strerror(errno)); RET_ERR(PM_ERR_MEMORY, NULL); } db->path = calloc(1, pathsize); if(db->path == NULL) { - _alpm_log(PM_LOG_ERROR, _("malloc failed: could not allocate %d bytes"), - pathsize); + _alpm_log(PM_LOG_ERROR, "calloc : %s\n", strerror(errno)); FREE(db); RET_ERR(PM_ERR_MEMORY, NULL); } @@ -568,12 +603,17 @@ pmdb_t *_alpm_db_new(const char *dbpath, const char *treename) void _alpm_db_free(pmdb_t *db) { + alpm_list_t *tmp; + ALPM_LOG_FUNC; - alpm_list_t *tmp; + /* cleanup pkgcache */ + _alpm_db_free_pkgcache(db); + /* cleanup server list */ for(tmp = db->servers; tmp; tmp = alpm_list_next(tmp)) { _alpm_server_free(tmp->data); } + alpm_list_free(db->servers); FREE(db->path); FREE(db); @@ -601,7 +641,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) continue; } targ = i->data; - _alpm_log(PM_LOG_DEBUG, "searching for target '%s'", targ); + _alpm_log(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); @@ -632,7 +672,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'", + _alpm_log(PM_LOG_DEBUG, " search target '%s' matched '%s'\n", targ, matched); ret = alpm_list_add(ret, pkg); } @@ -644,7 +684,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) return(ret); } -pmdb_t *_alpm_db_register(const char *treename) +pmdb_t *_alpm_db_register_local(void) { struct stat buf; pmdb_t *db; @@ -653,56 +693,97 @@ pmdb_t *_alpm_db_register(const char *treename) ALPM_LOG_FUNC; - if(strcmp(treename, "local") == 0) { - if(handle->db_local != NULL) { - _alpm_log(PM_LOG_WARNING, _("attempt to re-register the 'local' DB")); - RET_ERR(PM_ERR_DB_NOT_NULL, NULL); - } - } else { - alpm_list_t *i; - 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"), sdb->treename); - return sdb; - } - } + if(handle->db_local != NULL) { + _alpm_log(PM_LOG_WARNING, _("attempt to re-register the 'local' DB\n")); + RET_ERR(PM_ERR_DB_NOT_NULL, NULL); } - - _alpm_log(PM_LOG_DEBUG, _("registering database '%s'"), treename); + + _alpm_log(PM_LOG_DEBUG, "registering local database\n"); /* make sure the database directory exists */ dbpath = alpm_option_get_dbpath(); if(!dbpath) { - _alpm_log(PM_LOG_WARNING, _("database path is undefined")); + _alpm_log(PM_LOG_WARNING, _("database path is undefined\n")); RET_ERR(PM_ERR_DB_OPEN, NULL); } - snprintf(path, PATH_MAX, "%s%s", dbpath, treename); + snprintf(path, PATH_MAX, "%slocal", dbpath); + /* TODO this is rediculous, we try to do this even if we can't */ if(stat(path, &buf) != 0 || !S_ISDIR(buf.st_mode)) { - _alpm_log(PM_LOG_DEBUG, _("database directory '%s' does not exist, creating it"), + _alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n", path); if(_alpm_makepath(path) != 0) { RET_ERR(PM_ERR_SYSTEM, NULL); } } - db = _alpm_db_new(handle->dbpath, treename); + db = _alpm_db_new(dbpath, "local"); if(db == NULL) { RET_ERR(PM_ERR_DB_CREATE, NULL); } - _alpm_log(PM_LOG_DEBUG, _("opening database '%s'"), db->treename); + _alpm_log(PM_LOG_DEBUG, "opening database '%s'\n", db->treename); if(_alpm_db_open(db) == -1) { _alpm_db_free(db); RET_ERR(PM_ERR_DB_OPEN, NULL); } - if(strcmp(treename, "local") == 0) { - handle->db_local = db; - } else { - handle->dbs_sync = alpm_list_add(handle->dbs_sync, db); + handle->db_local = db; + return(db); +} + +pmdb_t *_alpm_db_register_sync(const char *treename) +{ + struct stat buf; + pmdb_t *db; + const char *dbpath; + char path[PATH_MAX]; + 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); + + /* make sure the database directory exists */ + dbpath = alpm_option_get_dbpath(); + if(!dbpath) { + _alpm_log(PM_LOG_WARNING, _("database path is undefined\n")); + RET_ERR(PM_ERR_DB_OPEN, NULL); + } + /* all sync DBs now reside in the sync/ subdir of the dbpath */ + snprintf(path, PATH_MAX, "%ssync/%s", dbpath, treename); + /* TODO this is rediculous, we try to do this even if we can't */ + if(stat(path, &buf) != 0 || !S_ISDIR(buf.st_mode)) { + _alpm_log(PM_LOG_DEBUG, "database dir '%s' does not exist, creating it\n", + path); + if(_alpm_makepath(path) != 0) { + RET_ERR(PM_ERR_SYSTEM, NULL); + } + } + + /* Ensure the db gets the real path. */ + path[0] = '\0'; + snprintf(path, PATH_MAX, "%ssync/", dbpath); + + db = _alpm_db_new(path, treename); + if(db == NULL) { + RET_ERR(PM_ERR_DB_CREATE, NULL); + } + + _alpm_log(PM_LOG_DEBUG, "opening database '%s'\n", db->treename); + if(_alpm_db_open(db) == -1) { + _alpm_db_free(db); + RET_ERR(PM_ERR_DB_OPEN, NULL); } + handle->dbs_sync = alpm_list_add(handle->dbs_sync, db); return(db); } |