diff options
Diffstat (limited to 'lib/libalpm/be_local.c')
-rw-r--r-- | lib/libalpm/be_local.c | 147 |
1 files changed, 125 insertions, 22 deletions
diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index 56cf38bb..51721d1f 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -1,7 +1,7 @@ /* * be_local.c : backend for the local database * - * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * * This program is free software; you can redistribute it and/or modify @@ -18,8 +18,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "config.h" - #include <unistd.h> #include <stdio.h> #include <stdlib.h> @@ -28,7 +26,6 @@ #include <stdint.h> /* intmax_t */ #include <sys/stat.h> #include <dirent.h> -#include <time.h> #include <limits.h> /* PATH_MAX */ /* libalpm */ @@ -69,13 +66,13 @@ static const char *_cache_get_url(alpm_pkg_t *pkg) return pkg->url; } -static time_t _cache_get_builddate(alpm_pkg_t *pkg) +static alpm_time_t _cache_get_builddate(alpm_pkg_t *pkg) { LAZY_LOAD(INFRQ_DESC, 0); return pkg->builddate; } -static time_t _cache_get_installdate(alpm_pkg_t *pkg) +static alpm_time_t _cache_get_installdate(alpm_pkg_t *pkg) { LAZY_LOAD(INFRQ_DESC, 0); return pkg->installdate; @@ -105,6 +102,12 @@ static alpm_pkgreason_t _cache_get_reason(alpm_pkg_t *pkg) return pkg->reason; } +static alpm_pkgvalidation_t _cache_get_validation(alpm_pkg_t *pkg) +{ + LAZY_LOAD(INFRQ_DESC, -1); + return pkg->validation; +} + static alpm_list_t *_cache_get_licenses(alpm_pkg_t *pkg) { LAZY_LOAD(INFRQ_DESC, NULL); @@ -226,6 +229,7 @@ static struct pkg_operations local_pkg_ops = { .get_arch = _cache_get_arch, .get_isize = _cache_get_isize, .get_reason = _cache_get_reason, + .get_validation = _cache_get_validation, .has_scriptlet = _cache_has_scriptlet, .get_licenses = _cache_get_licenses, .get_groups = _cache_get_groups, @@ -405,8 +409,7 @@ static int local_db_populate(alpm_db_t *db) est_count -= 2; } - /* initialize hash at 50% full */ - db->pkgcache = _alpm_pkghash_create(est_count * 2); + db->pkgcache = _alpm_pkghash_create(est_count); if(db->pkgcache == NULL){ closedir(dbdir); RET_ERR(db->handle, ALPM_ERR_MEMORY, -1); @@ -475,7 +478,8 @@ static int local_db_populate(alpm_db_t *db) } /* Note: the return value must be freed by the caller */ -char *_alpm_local_db_pkgpath(alpm_db_t *db, alpm_pkg_t *info, const char *filename) +char *_alpm_local_db_pkgpath(alpm_db_t *db, alpm_pkg_t *info, + const char *filename) { size_t len; char *pkgpath; @@ -606,6 +610,26 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq) } else if(strcmp(line, "%REASON%") == 0) { READ_NEXT(); info->reason = (alpm_pkgreason_t)atoi(line); + } else if(strcmp(line, "%VALIDATION%") == 0) { + alpm_list_t *i, *v = NULL; + READ_AND_STORE_ALL(v); + for(i = v; i; i = alpm_list_next(i)) + { + if(strcmp(i->data, "none") == 0) { + info->validation |= ALPM_PKG_VALIDATION_NONE; + } else if(strcmp(i->data, "md5") == 0) { + info->validation |= ALPM_PKG_VALIDATION_MD5SUM; + } else if(strcmp(i->data, "sha256") == 0) { + info->validation |= ALPM_PKG_VALIDATION_SHA256SUM; + } else if(strcmp(i->data, "pgp") == 0) { + info->validation |= ALPM_PKG_VALIDATION_SIGNATURE; + } else { + _alpm_log(db->handle, ALPM_LOG_WARNING, + _("unknown validation type for package %s: %s\n"), + info->name, (const char *)i->data); + } + } + FREELIST(v); } else if(strcmp(line, "%SIZE%") == 0) { READ_NEXT(); info->isize = _alpm_strtoofft(line); @@ -614,7 +638,7 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq) } else if(strcmp(line, "%DEPENDS%") == 0) { READ_AND_SPLITDEP(info->depends); } else if(strcmp(line, "%OPTDEPENDS%") == 0) { - READ_AND_STORE_ALL(info->optdepends); + READ_AND_SPLITDEP(info->optdepends); } else if(strcmp(line, "%CONFLICTS%") == 0) { READ_AND_SPLITDEP(info->conflicts); } else if(strcmp(line, "%PROVIDES%") == 0) { @@ -638,10 +662,11 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq) while(fgets(line, sizeof(line), fp)) { _alpm_strip_newline(line); if(strcmp(line, "%FILES%") == 0) { - size_t files_count = 0, files_size = 0; + size_t files_count = 0, files_size = 0, len; alpm_file_t *files = NULL; - while(fgets(line, sizeof(line), fp) && _alpm_strip_newline(line)) { + while(fgets(line, sizeof(line), fp) && + (len = _alpm_strip_newline(line))) { if(files_count >= files_size) { size_t old_size = files_size; if(files_size == 0) { @@ -659,8 +684,14 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq) memset(files + old_size, 0, sizeof(alpm_file_t) * (files_size - old_size)); } - STRDUP(files[files_count].name, line, goto error); - /* TODO: lstat file, get mode/size */ + /* since we know the length of the file string already, + * we can do malloc + memcpy rather than strdup */ + files[files_count].name = malloc(len + 1); + if(files[files_count].name == NULL) { + ALLOC_FAIL(len); + goto error; + } + memcpy(files[files_count].name, line, len + 1); files_count++; } /* attempt to hand back any memory we don't need */ @@ -794,11 +825,11 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq } if(info->builddate) { fprintf(fp, "%%BUILDDATE%%\n" - "%ld\n\n", info->builddate); + "%jd\n\n", (intmax_t)info->builddate); } if(info->installdate) { fprintf(fp, "%%INSTALLDATE%%\n" - "%ld\n\n", info->installdate); + "%jd\n\n", (intmax_t)info->installdate); } if(info->packager) { fprintf(fp, "%%PACKAGER%%\n" @@ -813,6 +844,22 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq fprintf(fp, "%%REASON%%\n" "%u\n\n", info->reason); } + if(info->validation) { + fputs("%VALIDATION%\n", fp); + if(info->validation & ALPM_PKG_VALIDATION_NONE) { + fputs("none\n", fp); + } + if(info->validation & ALPM_PKG_VALIDATION_MD5SUM) { + fputs("md5\n", fp); + } + if(info->validation & ALPM_PKG_VALIDATION_SHA256SUM) { + fputs("sha256\n", fp); + } + if(info->validation & ALPM_PKG_VALIDATION_SIGNATURE) { + fputs("pgp\n", fp); + } + fprintf(fp, "\n"); + } if(info->depends) { fputs("%DEPENDS%\n", fp); for(lp = info->depends; lp; lp = lp->next) { @@ -825,7 +872,9 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq if(info->optdepends) { fputs("%OPTDEPENDS%\n", fp); for(lp = info->optdepends; lp; lp = lp->next) { - fprintf(fp, "%s\n", (char *)lp->data); + char *optstring = alpm_dep_compute_string(lp->data); + fprintf(fp, "%s\n", optstring); + free(optstring); } fprintf(fp, "\n"); } @@ -903,17 +952,71 @@ cleanup: int _alpm_local_db_remove(alpm_db_t *db, alpm_pkg_t *info) { int ret = 0; - char *pkgpath = _alpm_local_db_pkgpath(db, info, NULL); + DIR *dirp; + struct dirent *dp; + char *pkgpath; + size_t pkgpath_len; - /* TODO explicit file removes and then an rmdir? */ - ret = _alpm_rmrf(pkgpath); - free(pkgpath); - if(ret != 0) { + pkgpath = _alpm_local_db_pkgpath(db, info, NULL); + if(!pkgpath) { + return -1; + } + pkgpath_len = strlen(pkgpath); + + dirp = opendir(pkgpath); + if(!dirp) { + return -1; + } + /* go through the local DB entry, removing the files within, which we know + * are not nested directories of any kind. */ + for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { + if(strcmp(dp->d_name, "..") != 0 && strcmp(dp->d_name, ".") != 0) { + char name[PATH_MAX]; + if(pkgpath_len + strlen(dp->d_name) + 2 > PATH_MAX) { + /* file path is too long to remove, hmm. */ + ret = -1; + } else { + sprintf(name, "%s/%s", pkgpath, dp->d_name); + if(unlink(name)) { + ret = -1; + } + } + } + } + closedir(dirp); + + /* after removing all enclosed files, we can remove the directory itself. */ + if(rmdir(pkgpath)) { ret = -1; } + free(pkgpath); return ret; } +int SYMEXPORT alpm_pkg_set_reason(alpm_pkg_t *pkg, alpm_pkgreason_t reason) +{ + ASSERT(pkg != NULL, return -1); + ASSERT(pkg->origin == PKG_FROM_LOCALDB, + RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1)); + ASSERT(pkg->origin_data.db == pkg->handle->db_local, + RET_ERR(pkg->handle, ALPM_ERR_WRONG_ARGS, -1)); + + _alpm_log(pkg->handle, ALPM_LOG_DEBUG, + "setting install reason %u for %s\n", reason, pkg->name); + if(alpm_pkg_get_reason(pkg) == reason) { + /* we are done */ + return 0; + } + /* set reason (in pkgcache) */ + pkg->reason = reason; + /* write DESC */ + if(_alpm_local_db_write(pkg->handle->db_local, pkg, INFRQ_DESC)) { + RET_ERR(pkg->handle, ALPM_ERR_DB_WRITE, -1); + } + + return 0; +} + struct db_operations local_db_ops = { .validate = local_db_validate, .populate = local_db_populate, |