diff options
author | Dan McGee <dan@archlinux.org> | 2008-05-12 02:29:23 +0200 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2008-05-12 03:05:59 +0200 |
commit | 046003844739416ff6d168dd2dec76490adb0727 (patch) | |
tree | c28da11a0799626df087232dd46be7103c81be3e /lib/libalpm/be_files.c | |
parent | 3c3cb001a441656c2afba62f0361b83d4987339c (diff) | |
download | pacman-046003844739416ff6d168dd2dec76490adb0727.tar.gz pacman-046003844739416ff6d168dd2dec76490adb0727.tar.xz |
Remove some useless abstraction and start db cleanup
We have some useless abstractions like an alpm_db_rewind function. I've read
somewhere that readdir() was the worst filesystem function call invented,
and what do we do? Add a wrapper around it. Kill this abstraction and move
some other things into be_files that should be there anyway because they
are so tied to how a files backend works.
Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'lib/libalpm/be_files.c')
-rw-r--r-- | lib/libalpm/be_files.c | 235 |
1 files changed, 149 insertions, 86 deletions
diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c index 00e631e0..1e59055c 100644 --- a/lib/libalpm/be_files.c +++ b/lib/libalpm/be_files.c @@ -36,6 +36,7 @@ /* libalpm */ #include "db.h" #include "alpm_list.h" +#include "cache.h" #include "log.h" #include "util.h" #include "alpm.h" @@ -43,24 +44,163 @@ #include "package.h" #include "delta.h" #include "deps.h" +#include "dload.h" -/* This function is used to convert the downloaded db file to the proper backend - * format +/* + * Return the last update time as number of seconds from the epoch. + * Returns 0 if the value is unknown or can't be read. + */ +time_t getlastupdate(const pmdb_t *db) +{ + FILE *fp; + char *file; + time_t ret = 0; + + ALPM_LOG_FUNC; + + if(db == NULL) { + return(ret); + } + + /* db->path + '.lastupdate' + NULL */ + MALLOC(file, strlen(db->path) + 12, RET_ERR(PM_ERR_MEMORY, ret)); + sprintf(file, "%s.lastupdate", db->path); + + /* get the last update time, if it's there */ + if((fp = fopen(file, "r")) == NULL) { + free(file); + return(ret); + } else { + char line[64]; + if(fgets(line, sizeof(line), fp)) { + ret = atol(line); + } + } + fclose(fp); + free(file); + return(ret); +} + +/* + * writes the dbpath/.lastupdate file with the value in time + */ +int setlastupdate(const pmdb_t *db, time_t time) +{ + FILE *fp; + char *file; + int ret = 0; + + ALPM_LOG_FUNC; + + if(db == NULL || time == 0) { + return(-1); + } + + /* db->path + '.lastupdate' + NULL */ + MALLOC(file, strlen(db->path) + 12, RET_ERR(PM_ERR_MEMORY, ret)); + sprintf(file, "%s.lastupdate", db->path); + + if((fp = fopen(file, "w")) == NULL) { + free(file); + return(-1); + } + if(fprintf(fp, "%ju", (uintmax_t)time) <= 0) { + ret = -1; + } + fclose(fp); + free(file); + return(ret); +} + +/** Update a package database + * @param force if true, then forces the update, otherwise update only in case + * the database isn't up to date + * @param db pointer to the package database to update + * @return 0 on success, > 0 on error (pm_errno is set accordingly), < 0 if up + * to date */ -int _alpm_db_install(pmdb_t *db, const char *dbfile) +int SYMEXPORT alpm_db_update(int force, pmdb_t *db) { + alpm_list_t *lp; + char path[PATH_MAX]; + time_t newmtime = 0, lastupdate = 0; + const char *dbpath; + int ret; + ALPM_LOG_FUNC; - /* TODO we should not simply unpack the archive, but better parse it and - * db_write each entry (see sync_load_dbarchive to get archive content) */ - _alpm_log(PM_LOG_DEBUG, "unpacking database '%s'\n", dbfile); + /* Sanity checks */ + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + ASSERT(db != NULL && db != handle->db_local, RET_ERR(PM_ERR_WRONG_ARGS, -1)); + /* Verify we are in a transaction. This is done _mainly_ because we need a DB + * lock - if we update without a db lock, we may kludge some other pacman + * process that _has_ a lock. + */ + ASSERT(handle->trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); + ASSERT(handle->trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1)); + ASSERT(handle->trans->type == PM_TRANS_TYPE_SYNC, RET_ERR(PM_ERR_TRANS_TYPE, -1)); + + if(!alpm_list_find_ptr(handle->dbs_sync, db)) { + RET_ERR(PM_ERR_DB_NOT_FOUND, -1); + } + + if(!force) { + /* get the lastupdate time */ + lastupdate = getlastupdate(db); + if(lastupdate == 0) { + _alpm_log(PM_LOG_DEBUG, "failed to get lastupdate time for %s\n", + db->treename); + } + } + + snprintf(path, PATH_MAX, "%s" DBEXT, db->treename); + dbpath = alpm_option_get_dbpath(); + + ret = _alpm_download_single_file(path, db->servers, dbpath, + lastupdate, &newmtime); + + if(ret == 1) { + /* mtimes match, do nothing */ + pm_errno = 0; + return(1); + } else if(ret == -1) { + /* pm_errno was set by the download code */ + _alpm_log(PM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerrorlast()); + return(-1); + } else { + /* form the path to the db location */ + snprintf(path, PATH_MAX, "%s%s" DBEXT, dbpath, db->treename); + + /* remove the old dir */ + _alpm_log(PM_LOG_DEBUG, "flushing database %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\n"), db->treename, + alpm_pkg_get_name(pkg)); + RET_ERR(PM_ERR_DB_REMOVE, -1); + } + } + + /* Cache needs to be rebuilt */ + _alpm_db_free_pkgcache(db); - if(_alpm_unpack(dbfile, db->path, NULL)) { - RET_ERR(PM_ERR_SYSTEM, -1); + /* uncompress the sync database */ + if(_alpm_unpack(path, db->path, NULL)) { + RET_ERR(PM_ERR_SYSTEM, -1); + } + unlink(path); + + /* if we have a new mtime, set the DB last update value */ + if(newmtime) { + _alpm_log(PM_LOG_DEBUG, "sync: new mtime for %s: %ju\n", + db->treename, (uintmax_t)newmtime); + setlastupdate(db, newmtime); + } } - return unlink(dbfile); + return(0); } int _alpm_db_open(pmdb_t *db) @@ -94,17 +234,6 @@ void _alpm_db_close(pmdb_t *db) } } -void _alpm_db_rewind(pmdb_t *db) -{ - ALPM_LOG_FUNC; - - if(db == NULL || db->handle == NULL) { - return; - } - - rewinddir(db->handle); -} - static int splitname(const char *target, pmpkg_t *pkg) { /* the format of a db entry is as follows: @@ -740,70 +869,4 @@ int _alpm_db_remove(pmdb_t *db, pmpkg_t *info) return(0); } -/* - * Return the last update time as number of seconds from the epoch. - * Returns 0 if the value is unknown or can't be read. - */ -time_t _alpm_db_getlastupdate(const pmdb_t *db) -{ - FILE *fp; - char *file; - time_t ret = 0; - - ALPM_LOG_FUNC; - - if(db == NULL) { - return(ret); - } - - /* db->path + '.lastupdate' + NULL */ - MALLOC(file, strlen(db->path) + 12, RET_ERR(PM_ERR_MEMORY, ret)); - sprintf(file, "%s.lastupdate", db->path); - - /* get the last update time, if it's there */ - if((fp = fopen(file, "r")) == NULL) { - free(file); - return(ret); - } else { - char line[64]; - if(fgets(line, sizeof(line), fp)) { - ret = atol(line); - } - } - fclose(fp); - free(file); - return(ret); -} - -/* - * writes the dbpath/.lastupdate file with the value in time - */ -int _alpm_db_setlastupdate(const pmdb_t *db, time_t time) -{ - FILE *fp; - char *file; - int ret = 0; - - ALPM_LOG_FUNC; - - if(db == NULL || time == 0) { - return(-1); - } - - /* db->path + '.lastupdate' + NULL */ - MALLOC(file, strlen(db->path) + 12, RET_ERR(PM_ERR_MEMORY, ret)); - sprintf(file, "%s.lastupdate", db->path); - - if((fp = fopen(file, "w")) == NULL) { - free(file); - return(-1); - } - if(fprintf(fp, "%ju", (uintmax_t)time) <= 0) { - ret = -1; - } - fclose(fp); - free(file); - return(ret); -} - /* vim: set ts=2 sw=2 noet: */ |