Merge remote branch 'allan/backend'
This commit is contained in:
commit
68b50c81c7
20 changed files with 1445 additions and 1113 deletions
|
@ -25,9 +25,9 @@ libalpm_la_SOURCES = \
|
||||||
alpm.h alpm.c \
|
alpm.h alpm.c \
|
||||||
alpm_list.h alpm_list.c \
|
alpm_list.h alpm_list.c \
|
||||||
backup.h backup.c \
|
backup.h backup.c \
|
||||||
be_files.c \
|
be_local.c \
|
||||||
be_package.c \
|
be_package.c \
|
||||||
cache.h cache.c \
|
be_sync.c \
|
||||||
conflict.h conflict.c \
|
conflict.h conflict.c \
|
||||||
db.h db.c \
|
db.h db.c \
|
||||||
delta.h delta.c \
|
delta.h delta.c \
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#include "alpm_list.h"
|
#include "alpm_list.h"
|
||||||
#include "trans.h"
|
#include "trans.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "cache.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "backup.h"
|
#include "backup.h"
|
||||||
#include "package.h"
|
#include "package.h"
|
||||||
|
@ -498,7 +497,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
|
||||||
oldpkg = _alpm_pkg_dup(local);
|
oldpkg = _alpm_pkg_dup(local);
|
||||||
/* make sure all infos are loaded because the database entry
|
/* make sure all infos are loaded because the database entry
|
||||||
* will be removed soon */
|
* will be removed soon */
|
||||||
_alpm_db_read(oldpkg->origin_data.db, oldpkg, INFRQ_ALL);
|
_alpm_local_db_read(oldpkg->origin_data.db, oldpkg, INFRQ_ALL);
|
||||||
|
|
||||||
EVENT(trans, PM_TRANS_EVT_UPGRADE_START, newpkg, oldpkg);
|
EVENT(trans, PM_TRANS_EVT_UPGRADE_START, newpkg, oldpkg);
|
||||||
_alpm_log(PM_LOG_DEBUG, "upgrading package %s-%s\n",
|
_alpm_log(PM_LOG_DEBUG, "upgrading package %s-%s\n",
|
||||||
|
@ -544,7 +543,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
|
||||||
|
|
||||||
/* prepare directory for database entries so permission are correct after
|
/* prepare directory for database entries so permission are correct after
|
||||||
changelog/install script installation (FS#12263) */
|
changelog/install script installation (FS#12263) */
|
||||||
if(_alpm_db_prepare(db, newpkg)) {
|
if(_alpm_local_db_prepare(db, newpkg)) {
|
||||||
alpm_logaction("error: could not create database entry %s-%s\n",
|
alpm_logaction("error: could not create database entry %s-%s\n",
|
||||||
alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
|
alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
|
||||||
pm_errno = PM_ERR_DB_WRITE;
|
pm_errno = PM_ERR_DB_WRITE;
|
||||||
|
@ -662,7 +661,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
|
||||||
_alpm_log(PM_LOG_DEBUG, "updating database\n");
|
_alpm_log(PM_LOG_DEBUG, "updating database\n");
|
||||||
_alpm_log(PM_LOG_DEBUG, "adding database entry '%s'\n", newpkg->name);
|
_alpm_log(PM_LOG_DEBUG, "adding database entry '%s'\n", newpkg->name);
|
||||||
|
|
||||||
if(_alpm_db_write(db, newpkg, INFRQ_ALL)) {
|
if(_alpm_local_db_write(db, newpkg, INFRQ_ALL)) {
|
||||||
_alpm_log(PM_LOG_ERROR, _("could not update database entry %s-%s\n"),
|
_alpm_log(PM_LOG_ERROR, _("could not update database entry %s-%s\n"),
|
||||||
alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
|
alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
|
||||||
alpm_logaction("error: could not update database entry %s-%s\n",
|
alpm_logaction("error: could not update database entry %s-%s\n",
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* be_files.c
|
* be_local.c
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006 by Christian Hamar <krics@linuxforum.hu>
|
* Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org>
|
||||||
* Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
|
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -40,17 +40,289 @@
|
||||||
/* libalpm */
|
/* libalpm */
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "alpm_list.h"
|
#include "alpm_list.h"
|
||||||
#include "cache.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "alpm.h"
|
#include "alpm.h"
|
||||||
#include "handle.h"
|
#include "handle.h"
|
||||||
#include "package.h"
|
#include "package.h"
|
||||||
|
#include "group.h"
|
||||||
#include "delta.h"
|
#include "delta.h"
|
||||||
#include "deps.h"
|
#include "deps.h"
|
||||||
#include "dload.h"
|
#include "dload.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define LAZY_LOAD(info, errret) \
|
||||||
|
do { \
|
||||||
|
ALPM_LOG_FUNC; \
|
||||||
|
ASSERT(handle != NULL, return(errret)); \
|
||||||
|
ASSERT(pkg != NULL, return(errret)); \
|
||||||
|
if(pkg->origin != PKG_FROM_FILE && !(pkg->infolevel & info)) { \
|
||||||
|
_alpm_local_db_read(pkg->origin_data.db, pkg, info); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
/* Cache-specific accessor functions. These implementations allow for lazy
|
||||||
|
* loading by the files backend when a data member is actually needed
|
||||||
|
* rather than loading all pieces of information when the package is first
|
||||||
|
* initialized.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char *_cache_get_filename(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, NULL);
|
||||||
|
return pkg->filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *_cache_get_name(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
ASSERT(pkg != NULL, return(NULL));
|
||||||
|
return pkg->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *_cache_get_version(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
ASSERT(pkg != NULL, return(NULL));
|
||||||
|
return pkg->version;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *_cache_get_desc(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, NULL);
|
||||||
|
return pkg->desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *_cache_get_url(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, NULL);
|
||||||
|
return pkg->url;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t _cache_get_builddate(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, 0);
|
||||||
|
return pkg->builddate;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t _cache_get_installdate(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, 0);
|
||||||
|
return pkg->installdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *_cache_get_packager(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, NULL);
|
||||||
|
return pkg->packager;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *_cache_get_md5sum(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, NULL);
|
||||||
|
return pkg->md5sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *_cache_get_arch(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, NULL);
|
||||||
|
return pkg->arch;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t _cache_get_size(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, -1);
|
||||||
|
return pkg->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t _cache_get_isize(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, -1);
|
||||||
|
return pkg->isize;
|
||||||
|
}
|
||||||
|
|
||||||
|
pmpkgreason_t _cache_get_reason(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, -1);
|
||||||
|
return pkg->reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpm_list_t *_cache_get_licenses(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, NULL);
|
||||||
|
return pkg->licenses;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpm_list_t *_cache_get_groups(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, NULL);
|
||||||
|
return pkg->groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _cache_has_force(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, -1);
|
||||||
|
return pkg->force;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpm_list_t *_cache_get_depends(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DEPENDS, NULL);
|
||||||
|
return pkg->depends;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpm_list_t *_cache_get_optdepends(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DEPENDS, NULL);
|
||||||
|
return pkg->optdepends;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpm_list_t *_cache_get_conflicts(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DEPENDS, NULL);
|
||||||
|
return pkg->conflicts;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpm_list_t *_cache_get_provides(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DEPENDS, NULL);
|
||||||
|
return pkg->provides;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpm_list_t *_cache_get_replaces(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
LAZY_LOAD(INFRQ_DESC, NULL);
|
||||||
|
return pkg->replaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpm_list_t *_cache_get_deltas(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
ASSERT(pkg != NULL, return(NULL));
|
||||||
|
/* local pkgs do not have deltas so nothing to load */
|
||||||
|
return pkg->deltas;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpm_list_t *_cache_get_files(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
/* Sanity checks */
|
||||||
|
ASSERT(handle != NULL, return(NULL));
|
||||||
|
ASSERT(pkg != NULL, return(NULL));
|
||||||
|
|
||||||
|
if(pkg->origin == PKG_FROM_LOCALDB
|
||||||
|
&& !(pkg->infolevel & INFRQ_FILES)) {
|
||||||
|
_alpm_local_db_read(pkg->origin_data.db, pkg, INFRQ_FILES);
|
||||||
|
}
|
||||||
|
return pkg->files;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpm_list_t *_cache_get_backup(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
/* Sanity checks */
|
||||||
|
ASSERT(handle != NULL, return(NULL));
|
||||||
|
ASSERT(pkg != NULL, return(NULL));
|
||||||
|
|
||||||
|
if(pkg->origin == PKG_FROM_LOCALDB
|
||||||
|
&& !(pkg->infolevel & INFRQ_FILES)) {
|
||||||
|
_alpm_local_db_read(pkg->origin_data.db, pkg, INFRQ_FILES);
|
||||||
|
}
|
||||||
|
return pkg->backup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a package changelog for reading. Similar to fopen in functionality,
|
||||||
|
* except that the returned 'file stream' is from the database.
|
||||||
|
* @param pkg the package (from db) to read the changelog
|
||||||
|
* @return a 'file stream' to the package changelog
|
||||||
|
*/
|
||||||
|
void *_cache_changelog_open(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
/* Sanity checks */
|
||||||
|
ASSERT(handle != NULL, return(NULL));
|
||||||
|
ASSERT(pkg != NULL, return(NULL));
|
||||||
|
|
||||||
|
char clfile[PATH_MAX];
|
||||||
|
snprintf(clfile, PATH_MAX, "%s/%s/%s-%s/changelog",
|
||||||
|
alpm_option_get_dbpath(),
|
||||||
|
alpm_db_get_name(alpm_pkg_get_db(pkg)),
|
||||||
|
alpm_pkg_get_name(pkg),
|
||||||
|
alpm_pkg_get_version(pkg));
|
||||||
|
return fopen(clfile, "r");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read data from an open changelog 'file stream'. Similar to fread in
|
||||||
|
* functionality, this function takes a buffer and amount of data to read.
|
||||||
|
* @param ptr a buffer to fill with raw changelog data
|
||||||
|
* @param size the size of the buffer
|
||||||
|
* @param pkg the package that the changelog is being read from
|
||||||
|
* @param fp a 'file stream' to the package changelog
|
||||||
|
* @return the number of characters read, or 0 if there is no more data
|
||||||
|
*/
|
||||||
|
size_t _cache_changelog_read(void *ptr, size_t size,
|
||||||
|
const pmpkg_t *pkg, const void *fp)
|
||||||
|
{
|
||||||
|
return ( fread(ptr, 1, size, (FILE*)fp) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
int _cache_changelog_feof(const pmpkg_t *pkg, void *fp)
|
||||||
|
{
|
||||||
|
return( feof((FILE*)fp) );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close a package changelog for reading. Similar to fclose in functionality,
|
||||||
|
* except that the 'file stream' is from the database.
|
||||||
|
* @param pkg the package that the changelog was read from
|
||||||
|
* @param fp a 'file stream' to the package changelog
|
||||||
|
* @return whether closing the package changelog stream was successful
|
||||||
|
*/
|
||||||
|
int _cache_changelog_close(const pmpkg_t *pkg, void *fp)
|
||||||
|
{
|
||||||
|
return( fclose((FILE*)fp) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The local database operations struct. Get package fields through
|
||||||
|
* lazy accessor methods that handle any backend loading and caching
|
||||||
|
* logic.
|
||||||
|
*/
|
||||||
|
static struct pkg_operations local_pkg_ops = {
|
||||||
|
.get_filename = _cache_get_filename,
|
||||||
|
.get_name = _cache_get_name,
|
||||||
|
.get_version = _cache_get_version,
|
||||||
|
.get_desc = _cache_get_desc,
|
||||||
|
.get_url = _cache_get_url,
|
||||||
|
.get_builddate = _cache_get_builddate,
|
||||||
|
.get_installdate = _cache_get_installdate,
|
||||||
|
.get_packager = _cache_get_packager,
|
||||||
|
.get_md5sum = _cache_get_md5sum,
|
||||||
|
.get_arch = _cache_get_arch,
|
||||||
|
.get_size = _cache_get_size,
|
||||||
|
.get_isize = _cache_get_isize,
|
||||||
|
.get_reason = _cache_get_reason,
|
||||||
|
.has_force = _cache_has_force,
|
||||||
|
.get_licenses = _cache_get_licenses,
|
||||||
|
.get_groups = _cache_get_groups,
|
||||||
|
.get_depends = _cache_get_depends,
|
||||||
|
.get_optdepends = _cache_get_optdepends,
|
||||||
|
.get_conflicts = _cache_get_conflicts,
|
||||||
|
.get_provides = _cache_get_provides,
|
||||||
|
.get_replaces = _cache_get_replaces,
|
||||||
|
.get_deltas = _cache_get_deltas,
|
||||||
|
.get_files = _cache_get_files,
|
||||||
|
.get_backup = _cache_get_backup,
|
||||||
|
|
||||||
|
.changelog_open = _cache_changelog_open,
|
||||||
|
.changelog_read = _cache_changelog_read,
|
||||||
|
.changelog_close = _cache_changelog_close,
|
||||||
|
};
|
||||||
|
|
||||||
static int checkdbdir(pmdb_t *db)
|
static int checkdbdir(pmdb_t *db)
|
||||||
{
|
{
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
@ -71,43 +343,6 @@ static int checkdbdir(pmdb_t *db)
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create list of directories in db */
|
|
||||||
static int dirlist_from_tar(const char *archive, alpm_list_t **dirlist)
|
|
||||||
{
|
|
||||||
struct archive *_archive;
|
|
||||||
struct archive_entry *entry;
|
|
||||||
|
|
||||||
if((_archive = archive_read_new()) == NULL)
|
|
||||||
RET_ERR(PM_ERR_LIBARCHIVE, -1);
|
|
||||||
|
|
||||||
archive_read_support_compression_all(_archive);
|
|
||||||
archive_read_support_format_all(_archive);
|
|
||||||
|
|
||||||
if(archive_read_open_filename(_archive, archive,
|
|
||||||
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
|
|
||||||
_alpm_log(PM_LOG_ERROR, _("could not open %s: %s\n"), archive,
|
|
||||||
archive_error_string(_archive));
|
|
||||||
RET_ERR(PM_ERR_PKG_OPEN, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
while(archive_read_next_header(_archive, &entry) == ARCHIVE_OK) {
|
|
||||||
const struct stat *st;
|
|
||||||
const char *entryname; /* the name of the file in the archive */
|
|
||||||
|
|
||||||
st = archive_entry_stat(entry);
|
|
||||||
entryname = archive_entry_pathname(entry);
|
|
||||||
|
|
||||||
if(S_ISDIR(st->st_mode)) {
|
|
||||||
char *name = strdup(entryname);
|
|
||||||
*dirlist = alpm_list_add(*dirlist, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
archive_read_finish(_archive);
|
|
||||||
|
|
||||||
*dirlist = alpm_list_msort(*dirlist, alpm_list_count(*dirlist), _alpm_str_cmp);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int is_dir(const char *path, struct dirent *entry)
|
static int is_dir(const char *path, struct dirent *entry)
|
||||||
{
|
{
|
||||||
#ifdef DT_DIR
|
#ifdef DT_DIR
|
||||||
|
@ -125,244 +360,7 @@ static int is_dir(const char *path, struct dirent *entry)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create list of directories in db */
|
int _alpm_local_db_populate(pmdb_t *db)
|
||||||
static int dirlist_from_fs(const char *syncdbpath, alpm_list_t **dirlist)
|
|
||||||
{
|
|
||||||
DIR *dbdir;
|
|
||||||
struct dirent *ent = NULL;
|
|
||||||
|
|
||||||
dbdir = opendir(syncdbpath);
|
|
||||||
if (dbdir != NULL) {
|
|
||||||
while((ent = readdir(dbdir)) != NULL) {
|
|
||||||
char *name = ent->d_name;
|
|
||||||
size_t len;
|
|
||||||
char *entry;
|
|
||||||
|
|
||||||
if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!is_dir(syncdbpath, ent)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = strlen(name);
|
|
||||||
MALLOC(entry, len + 2, RET_ERR(PM_ERR_MEMORY, -1));
|
|
||||||
strcpy(entry, name);
|
|
||||||
entry[len] = '/';
|
|
||||||
entry[len+1] = '\0';
|
|
||||||
*dirlist = alpm_list_add(*dirlist, entry);
|
|
||||||
}
|
|
||||||
closedir(dbdir);
|
|
||||||
}
|
|
||||||
|
|
||||||
*dirlist = alpm_list_msort(*dirlist, alpm_list_count(*dirlist), _alpm_str_cmp);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove old directories from dbdir */
|
|
||||||
static int remove_olddir(const char *syncdbpath, alpm_list_t *dirlist)
|
|
||||||
{
|
|
||||||
alpm_list_t *i;
|
|
||||||
for (i = dirlist; i; i = i->next) {
|
|
||||||
const char *name = i->data;
|
|
||||||
char *dbdir;
|
|
||||||
size_t len = strlen(syncdbpath) + strlen(name) + 2;
|
|
||||||
MALLOC(dbdir, len, RET_ERR(PM_ERR_MEMORY, -1));
|
|
||||||
snprintf(dbdir, len, "%s%s", syncdbpath, name);
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "removing: %s\n", dbdir);
|
|
||||||
if(_alpm_rmrf(dbdir) != 0) {
|
|
||||||
_alpm_log(PM_LOG_ERROR, _("could not remove database directory %s\n"), dbdir);
|
|
||||||
free(dbdir);
|
|
||||||
RET_ERR(PM_ERR_DB_REMOVE, -1);
|
|
||||||
}
|
|
||||||
free(dbdir);
|
|
||||||
}
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Update a package database
|
|
||||||
*
|
|
||||||
* An update of the package database \a db will be attempted. Unless
|
|
||||||
* \a force is true, the update will only be performed if the remote
|
|
||||||
* database was modified since the last update.
|
|
||||||
*
|
|
||||||
* A transaction is necessary for this operation, in order to obtain a
|
|
||||||
* database lock. During this transaction the front-end will be informed
|
|
||||||
* of the download progress of the database via the download callback.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
* @code
|
|
||||||
* pmdb_t *db;
|
|
||||||
* int result;
|
|
||||||
* db = alpm_list_getdata(alpm_option_get_syncdbs());
|
|
||||||
* if(alpm_trans_init(0, NULL, NULL, NULL) == 0) {
|
|
||||||
* result = alpm_db_update(0, db);
|
|
||||||
* alpm_trans_release();
|
|
||||||
*
|
|
||||||
* if(result > 0) {
|
|
||||||
* printf("Unable to update database: %s\n", alpm_strerrorlast());
|
|
||||||
* } else if(result < 0) {
|
|
||||||
* printf("Database already up to date\n");
|
|
||||||
* } else {
|
|
||||||
* printf("Database updated\n");
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* @endcode
|
|
||||||
*
|
|
||||||
* @ingroup alpm_databases
|
|
||||||
* @note After a successful update, the \link alpm_db_get_pkgcache()
|
|
||||||
* package cache \endlink will be invalidated
|
|
||||||
* @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 SYMEXPORT alpm_db_update(int force, pmdb_t *db)
|
|
||||||
{
|
|
||||||
char *dbfile, *dbfilepath, *syncpath;
|
|
||||||
const char *dbpath, *syncdbpath;
|
|
||||||
alpm_list_t *newdirlist = NULL, *olddirlist = NULL;
|
|
||||||
alpm_list_t *onlynew = NULL, *onlyold = NULL;
|
|
||||||
size_t len;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
/* 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));
|
|
||||||
|
|
||||||
if(!alpm_list_find_ptr(handle->dbs_sync, db)) {
|
|
||||||
RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
len = strlen(db->treename) + 4;
|
|
||||||
MALLOC(dbfile, len, RET_ERR(PM_ERR_MEMORY, -1));
|
|
||||||
sprintf(dbfile, "%s.db", db->treename);
|
|
||||||
|
|
||||||
dbpath = alpm_option_get_dbpath();
|
|
||||||
len = strlen(dbpath) + 6;
|
|
||||||
MALLOC(syncpath, len, RET_ERR(PM_ERR_MEMORY, -1));
|
|
||||||
sprintf(syncpath, "%s%s", dbpath, "sync/");
|
|
||||||
|
|
||||||
ret = _alpm_download_single_file(dbfile, db->servers, syncpath, force);
|
|
||||||
free(dbfile);
|
|
||||||
free(syncpath);
|
|
||||||
|
|
||||||
if(ret == 1) {
|
|
||||||
/* files 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
syncdbpath = _alpm_db_path(db);
|
|
||||||
|
|
||||||
/* form the path to the db location */
|
|
||||||
len = strlen(dbpath) + strlen(db->treename) + 9;
|
|
||||||
MALLOC(dbfilepath, len, RET_ERR(PM_ERR_MEMORY, -1));
|
|
||||||
sprintf(dbfilepath, "%ssync/%s.db", dbpath, db->treename);
|
|
||||||
|
|
||||||
if(force) {
|
|
||||||
/* if forcing update, remove the old dir and extract the db */
|
|
||||||
if(_alpm_rmrf(syncdbpath) != 0) {
|
|
||||||
_alpm_log(PM_LOG_ERROR, _("could not remove database %s\n"), db->treename);
|
|
||||||
RET_ERR(PM_ERR_DB_REMOVE, -1);
|
|
||||||
} else {
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "database dir %s removed\n", _alpm_db_path(db));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* if not forcing, only remove and extract what is necessary */
|
|
||||||
ret = dirlist_from_tar(dbfilepath, &newdirlist);
|
|
||||||
if(ret) {
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
ret = dirlist_from_fs(syncdbpath, &olddirlist);
|
|
||||||
if(ret) {
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
alpm_list_diff_sorted(olddirlist, newdirlist, _alpm_str_cmp, &onlyold, &onlynew);
|
|
||||||
|
|
||||||
ret = remove_olddir(syncdbpath, onlyold);
|
|
||||||
if(ret) {
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cache needs to be rebuilt */
|
|
||||||
_alpm_db_free_pkgcache(db);
|
|
||||||
|
|
||||||
checkdbdir(db);
|
|
||||||
ret = _alpm_unpack(dbfilepath, syncdbpath, onlynew, 0);
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
FREELIST(newdirlist);
|
|
||||||
FREELIST(olddirlist);
|
|
||||||
alpm_list_free(onlynew);
|
|
||||||
alpm_list_free(onlyold);
|
|
||||||
|
|
||||||
free(dbfilepath);
|
|
||||||
|
|
||||||
if(ret) {
|
|
||||||
RET_ERR(PM_ERR_SYSTEM, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int splitname(const char *target, pmpkg_t *pkg)
|
|
||||||
{
|
|
||||||
/* the format of a db entry is as follows:
|
|
||||||
* package-version-rel/
|
|
||||||
* package name can contain hyphens, so parse from the back- go back
|
|
||||||
* two hyphens and we have split the version from the name.
|
|
||||||
*/
|
|
||||||
char *tmp, *p, *q;
|
|
||||||
|
|
||||||
if(target == NULL || pkg == NULL) {
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
STRDUP(tmp, target, RET_ERR(PM_ERR_MEMORY, -1));
|
|
||||||
p = tmp + strlen(tmp);
|
|
||||||
|
|
||||||
/* do the magic parsing- find the beginning of the version string
|
|
||||||
* by doing two iterations of same loop to lop off two hyphens */
|
|
||||||
for(q = --p; *q && *q != '-'; q--);
|
|
||||||
for(p = --q; *p && *p != '-'; p--);
|
|
||||||
if(*p != '-' || p == tmp) {
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy into fields and return */
|
|
||||||
if(pkg->version) {
|
|
||||||
FREE(pkg->version);
|
|
||||||
}
|
|
||||||
STRDUP(pkg->version, p+1, RET_ERR(PM_ERR_MEMORY, -1));
|
|
||||||
/* insert a terminator at the end of the name (on hyphen)- then copy it */
|
|
||||||
*p = '\0';
|
|
||||||
if(pkg->name) {
|
|
||||||
FREE(pkg->name);
|
|
||||||
}
|
|
||||||
STRDUP(pkg->name, tmp, RET_ERR(PM_ERR_MEMORY, -1));
|
|
||||||
|
|
||||||
free(tmp);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _alpm_db_populate(pmdb_t *db)
|
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
struct dirent *ent = NULL;
|
struct dirent *ent = NULL;
|
||||||
|
@ -380,6 +378,7 @@ int _alpm_db_populate(pmdb_t *db)
|
||||||
}
|
}
|
||||||
while((ent = readdir(dbdir)) != NULL) {
|
while((ent = readdir(dbdir)) != NULL) {
|
||||||
const char *name = ent->d_name;
|
const char *name = ent->d_name;
|
||||||
|
|
||||||
pmpkg_t *pkg;
|
pmpkg_t *pkg;
|
||||||
|
|
||||||
if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
|
if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
|
||||||
|
@ -395,7 +394,7 @@ int _alpm_db_populate(pmdb_t *db)
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
/* split the db entry name */
|
/* split the db entry name */
|
||||||
if(splitname(name, pkg) != 0) {
|
if(_alpm_splitname(name, pkg) != 0) {
|
||||||
_alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"),
|
_alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"),
|
||||||
name);
|
name);
|
||||||
_alpm_pkg_free(pkg);
|
_alpm_pkg_free(pkg);
|
||||||
|
@ -410,12 +409,15 @@ int _alpm_db_populate(pmdb_t *db)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* explicitly read with only 'BASE' data, accessors will handle the rest */
|
/* explicitly read with only 'BASE' data, accessors will handle the rest */
|
||||||
if(_alpm_db_read(db, pkg, INFRQ_BASE) == -1) {
|
if(_alpm_local_db_read(db, pkg, INFRQ_BASE) == -1) {
|
||||||
_alpm_log(PM_LOG_ERROR, _("corrupted database entry '%s'\n"), name);
|
_alpm_log(PM_LOG_ERROR, _("corrupted database entry '%s'\n"), name);
|
||||||
_alpm_pkg_free(pkg);
|
_alpm_pkg_free(pkg);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pkg->origin = PKG_FROM_CACHE;
|
|
||||||
|
pkg->origin = PKG_FROM_LOCALDB;
|
||||||
|
pkg->ops = &local_pkg_ops;
|
||||||
|
|
||||||
pkg->origin_data.db = db;
|
pkg->origin_data.db = db;
|
||||||
/* add to the collection */
|
/* add to the collection */
|
||||||
_alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
|
_alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
|
||||||
|
@ -443,7 +445,8 @@ static char *get_pkgpath(pmdb_t *db, pmpkg_t *info)
|
||||||
return(pkgpath);
|
return(pkgpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
|
|
||||||
|
int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
|
||||||
{
|
{
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
|
@ -457,7 +460,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(info == NULL || info->name == NULL || info->version == NULL) {
|
if(info == NULL || info->name == NULL || info->version == NULL) {
|
||||||
_alpm_log(PM_LOG_DEBUG, "invalid package entry provided to _alpm_db_read, skipping\n");
|
_alpm_log(PM_LOG_DEBUG, "invalid package entry provided to _alpm_local_db_read, skipping\n");
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,11 +521,6 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
|
||||||
_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: version "
|
_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: version "
|
||||||
"mismatch on package %s\n"), db->treename, info->name);
|
"mismatch on package %s\n"), db->treename, info->name);
|
||||||
}
|
}
|
||||||
} else if(strcmp(line, "%FILENAME%") == 0) {
|
|
||||||
if(fgets(line, sizeof(line), fp) == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
STRDUP(info->filename, _alpm_strtrim(line), goto error);
|
|
||||||
} else if(strcmp(line, "%DESC%") == 0) {
|
} else if(strcmp(line, "%DESC%") == 0) {
|
||||||
if(fgets(line, sizeof(line), fp) == NULL) {
|
if(fgets(line, sizeof(line), fp) == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -592,7 +590,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
info->reason = (pmpkgreason_t)atol(_alpm_strtrim(line));
|
info->reason = (pmpkgreason_t)atol(_alpm_strtrim(line));
|
||||||
} else if(strcmp(line, "%SIZE%") == 0 || strcmp(line, "%CSIZE%") == 0) {
|
} else if(strcmp(line, "%SIZE%") == 0) {
|
||||||
/* NOTE: the CSIZE and SIZE fields both share the "size" field
|
/* NOTE: the CSIZE and SIZE fields both share the "size" field
|
||||||
* in the pkginfo_t struct. This can be done b/c CSIZE
|
* in the pkginfo_t struct. This can be done b/c CSIZE
|
||||||
* is currently only used in sync databases, and SIZE is
|
* is currently only used in sync databases, and SIZE is
|
||||||
|
@ -602,24 +600,8 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
info->size = atol(_alpm_strtrim(line));
|
info->size = atol(_alpm_strtrim(line));
|
||||||
/* also store this value to isize if isize is unset */
|
/* also store this value to isize */
|
||||||
if(info->isize == 0) {
|
info->isize = info->size;
|
||||||
info->isize = info->size;
|
|
||||||
}
|
|
||||||
} else if(strcmp(line, "%ISIZE%") == 0) {
|
|
||||||
/* ISIZE (installed size) tag only appears in sync repositories,
|
|
||||||
* not the local one. */
|
|
||||||
if(fgets(line, sizeof(line), fp) == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
info->isize = atol(_alpm_strtrim(line));
|
|
||||||
} else if(strcmp(line, "%MD5SUM%") == 0) {
|
|
||||||
/* MD5SUM tag only appears in sync repositories,
|
|
||||||
* not the local one. */
|
|
||||||
if(fgets(line, sizeof(line), fp) == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
STRDUP(info->md5sum, _alpm_strtrim(line), goto error);
|
|
||||||
} else if(strcmp(line, "%REPLACES%") == 0) {
|
} else if(strcmp(line, "%REPLACES%") == 0) {
|
||||||
while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
|
while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
|
||||||
char *linedup;
|
char *linedup;
|
||||||
|
@ -702,29 +684,6 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
|
||||||
fp = NULL;
|
fp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DELTAS */
|
|
||||||
if(inforeq & INFRQ_DELTAS) {
|
|
||||||
snprintf(path, PATH_MAX, "%sdeltas", pkgpath);
|
|
||||||
if((fp = fopen(path, "r"))) {
|
|
||||||
while(!feof(fp)) {
|
|
||||||
if(fgets(line, sizeof(line), fp) == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
_alpm_strtrim(line);
|
|
||||||
if(strcmp(line, "%DELTAS%") == 0) {
|
|
||||||
while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
|
|
||||||
pmdelta_t *delta = _alpm_delta_parse(line);
|
|
||||||
if(delta) {
|
|
||||||
info->deltas = alpm_list_add(info->deltas, delta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(fp);
|
|
||||||
fp = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* INSTALL */
|
/* INSTALL */
|
||||||
if(inforeq & INFRQ_SCRIPTLET) {
|
if(inforeq & INFRQ_SCRIPTLET) {
|
||||||
snprintf(path, PATH_MAX, "%sinstall", pkgpath);
|
snprintf(path, PATH_MAX, "%sinstall", pkgpath);
|
||||||
|
@ -747,7 +706,7 @@ error:
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _alpm_db_prepare(pmdb_t *db, pmpkg_t *info)
|
int _alpm_local_db_prepare(pmdb_t *db, pmpkg_t *info)
|
||||||
{
|
{
|
||||||
mode_t oldmask;
|
mode_t oldmask;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
@ -771,14 +730,13 @@ int _alpm_db_prepare(pmdb_t *db, pmpkg_t *info)
|
||||||
return(retval);
|
return(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
|
int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
|
||||||
{
|
{
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
mode_t oldmask;
|
mode_t oldmask;
|
||||||
alpm_list_t *lp = NULL;
|
alpm_list_t *lp = NULL;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
int local = 0;
|
|
||||||
char *pkgpath = NULL;
|
char *pkgpath = NULL;
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
ALPM_LOG_FUNC;
|
||||||
|
@ -792,8 +750,8 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
|
||||||
/* make sure we have a sane umask */
|
/* make sure we have a sane umask */
|
||||||
oldmask = umask(0022);
|
oldmask = umask(0022);
|
||||||
|
|
||||||
if(strcmp(db->treename, "local") == 0) {
|
if(strcmp(db->treename, "local") != 0) {
|
||||||
local = 1;
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DESC */
|
/* DESC */
|
||||||
|
@ -829,63 +787,49 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
|
||||||
if(info->force) {
|
if(info->force) {
|
||||||
fprintf(fp, "%%FORCE%%\n\n");
|
fprintf(fp, "%%FORCE%%\n\n");
|
||||||
}
|
}
|
||||||
if(local) {
|
if(info->url) {
|
||||||
if(info->url) {
|
fprintf(fp, "%%URL%%\n"
|
||||||
fprintf(fp, "%%URL%%\n"
|
"%s\n\n", info->url);
|
||||||
"%s\n\n", info->url);
|
|
||||||
}
|
|
||||||
if(info->licenses) {
|
|
||||||
fputs("%LICENSE%\n", fp);
|
|
||||||
for(lp = info->licenses; lp; lp = lp->next) {
|
|
||||||
fprintf(fp, "%s\n", (char *)lp->data);
|
|
||||||
}
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
}
|
|
||||||
if(info->arch) {
|
|
||||||
fprintf(fp, "%%ARCH%%\n"
|
|
||||||
"%s\n\n", info->arch);
|
|
||||||
}
|
|
||||||
if(info->builddate) {
|
|
||||||
fprintf(fp, "%%BUILDDATE%%\n"
|
|
||||||
"%ld\n\n", info->builddate);
|
|
||||||
}
|
|
||||||
if(info->installdate) {
|
|
||||||
fprintf(fp, "%%INSTALLDATE%%\n"
|
|
||||||
"%ld\n\n", info->installdate);
|
|
||||||
}
|
|
||||||
if(info->packager) {
|
|
||||||
fprintf(fp, "%%PACKAGER%%\n"
|
|
||||||
"%s\n\n", info->packager);
|
|
||||||
}
|
|
||||||
if(info->isize) {
|
|
||||||
/* only write installed size, csize is irrelevant once installed */
|
|
||||||
fprintf(fp, "%%SIZE%%\n"
|
|
||||||
"%jd\n\n", (intmax_t)info->isize);
|
|
||||||
}
|
|
||||||
if(info->reason) {
|
|
||||||
fprintf(fp, "%%REASON%%\n"
|
|
||||||
"%u\n\n", info->reason);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(info->size) {
|
|
||||||
fprintf(fp, "%%CSIZE%%\n"
|
|
||||||
"%jd\n\n", (intmax_t)info->size);
|
|
||||||
}
|
|
||||||
if(info->isize) {
|
|
||||||
fprintf(fp, "%%ISIZE%%\n"
|
|
||||||
"%jd\n\n", (intmax_t)info->isize);
|
|
||||||
}
|
|
||||||
if(info->md5sum) {
|
|
||||||
fprintf(fp, "%%MD5SUM%%\n"
|
|
||||||
"%s\n\n", info->md5sum);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if(info->licenses) {
|
||||||
|
fputs("%LICENSE%\n", fp);
|
||||||
|
for(lp = info->licenses; lp; lp = lp->next) {
|
||||||
|
fprintf(fp, "%s\n", (char *)lp->data);
|
||||||
|
}
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
if(info->arch) {
|
||||||
|
fprintf(fp, "%%ARCH%%\n"
|
||||||
|
"%s\n\n", info->arch);
|
||||||
|
}
|
||||||
|
if(info->builddate) {
|
||||||
|
fprintf(fp, "%%BUILDDATE%%\n"
|
||||||
|
"%ld\n\n", info->builddate);
|
||||||
|
}
|
||||||
|
if(info->installdate) {
|
||||||
|
fprintf(fp, "%%INSTALLDATE%%\n"
|
||||||
|
"%ld\n\n", info->installdate);
|
||||||
|
}
|
||||||
|
if(info->packager) {
|
||||||
|
fprintf(fp, "%%PACKAGER%%\n"
|
||||||
|
"%s\n\n", info->packager);
|
||||||
|
}
|
||||||
|
if(info->isize) {
|
||||||
|
/* only write installed size, csize is irrelevant once installed */
|
||||||
|
fprintf(fp, "%%SIZE%%\n"
|
||||||
|
"%jd\n\n", (intmax_t)info->isize);
|
||||||
|
}
|
||||||
|
if(info->reason) {
|
||||||
|
fprintf(fp, "%%REASON%%\n"
|
||||||
|
"%u\n\n", info->reason);
|
||||||
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
fp = NULL;
|
fp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FILES */
|
/* FILES */
|
||||||
if(local && (inforeq & INFRQ_FILES)) {
|
if(inforeq & INFRQ_FILES) {
|
||||||
_alpm_log(PM_LOG_DEBUG, "writing %s-%s FILES information back to db\n",
|
_alpm_log(PM_LOG_DEBUG, "writing %s-%s FILES information back to db\n",
|
||||||
info->name, info->version);
|
info->name, info->version);
|
||||||
snprintf(path, PATH_MAX, "%sfiles", pkgpath);
|
snprintf(path, PATH_MAX, "%sfiles", pkgpath);
|
||||||
|
@ -970,7 +914,7 @@ cleanup:
|
||||||
return(retval);
|
return(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _alpm_db_remove(pmdb_t *db, pmpkg_t *info)
|
int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char *pkgpath = NULL;
|
char *pkgpath = NULL;
|
||||||
|
@ -991,4 +935,33 @@ int _alpm_db_remove(pmdb_t *db, pmpkg_t *info)
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct db_operations local_db_ops = {
|
||||||
|
.populate = _alpm_local_db_populate,
|
||||||
|
.unregister = _alpm_db_unregister,
|
||||||
|
};
|
||||||
|
|
||||||
|
pmdb_t *_alpm_db_register_local(void)
|
||||||
|
{
|
||||||
|
pmdb_t *db;
|
||||||
|
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
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 local database\n");
|
||||||
|
|
||||||
|
db = _alpm_db_new("local", 1);
|
||||||
|
db->ops = &local_db_ops;
|
||||||
|
if(db == NULL) {
|
||||||
|
RET_ERR(PM_ERR_DB_CREATE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->db_local = db;
|
||||||
|
return(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* vim: set ts=2 sw=2 noet: */
|
/* vim: set ts=2 sw=2 noet: */
|
|
@ -26,6 +26,7 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <locale.h> /* setlocale */
|
#include <locale.h> /* setlocale */
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
/* libarchive */
|
/* libarchive */
|
||||||
#include <archive.h>
|
#include <archive.h>
|
||||||
|
@ -38,6 +39,114 @@
|
||||||
#include "package.h"
|
#include "package.h"
|
||||||
#include "deps.h" /* _alpm_splitdep */
|
#include "deps.h" /* _alpm_splitdep */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a package changelog for reading. Similar to fopen in functionality,
|
||||||
|
* except that the returned 'file stream' is from an archive.
|
||||||
|
* @param pkg the package (file) to read the changelog
|
||||||
|
* @return a 'file stream' to the package changelog
|
||||||
|
*/
|
||||||
|
void *_package_changelog_open(pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
ASSERT(pkg != NULL, return(NULL));
|
||||||
|
|
||||||
|
struct archive *archive = NULL;
|
||||||
|
struct archive_entry *entry;
|
||||||
|
const char *pkgfile = pkg->origin_data.file;
|
||||||
|
int ret = ARCHIVE_OK;
|
||||||
|
|
||||||
|
if((archive = archive_read_new()) == NULL) {
|
||||||
|
RET_ERR(PM_ERR_LIBARCHIVE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
archive_read_support_compression_all(archive);
|
||||||
|
archive_read_support_format_all(archive);
|
||||||
|
|
||||||
|
if (archive_read_open_filename(archive, pkgfile,
|
||||||
|
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
|
||||||
|
RET_ERR(PM_ERR_PKG_OPEN, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
while((ret = archive_read_next_header(archive, &entry)) == ARCHIVE_OK) {
|
||||||
|
const char *entry_name = archive_entry_pathname(entry);
|
||||||
|
|
||||||
|
if(strcmp(entry_name, ".CHANGELOG") == 0) {
|
||||||
|
return(archive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* we didn't find a changelog */
|
||||||
|
archive_read_finish(archive);
|
||||||
|
errno = ENOENT;
|
||||||
|
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read data from an open changelog 'file stream'. Similar to fread in
|
||||||
|
* functionality, this function takes a buffer and amount of data to read.
|
||||||
|
* @param ptr a buffer to fill with raw changelog data
|
||||||
|
* @param size the size of the buffer
|
||||||
|
* @param pkg the package that the changelog is being read from
|
||||||
|
* @param fp a 'file stream' to the package changelog
|
||||||
|
* @return the number of characters read, or 0 if there is no more data
|
||||||
|
*/
|
||||||
|
size_t _package_changelog_read(void *ptr, size_t size,
|
||||||
|
const pmpkg_t *pkg, const void *fp)
|
||||||
|
{
|
||||||
|
ssize_t sret = archive_read_data((struct archive*)fp, ptr, size);
|
||||||
|
/* Report error (negative values) */
|
||||||
|
if(sret < 0) {
|
||||||
|
pm_errno = PM_ERR_LIBARCHIVE;
|
||||||
|
return(0);
|
||||||
|
} else {
|
||||||
|
return((size_t)sret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
int _package_changelog_feof(const pmpkg_t *pkg, void *fp)
|
||||||
|
{
|
||||||
|
// note: this doesn't quite work, no feof in libarchive
|
||||||
|
return( archive_read_data((struct archive*)fp, NULL, 0) );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close a package changelog for reading. Similar to fclose in functionality,
|
||||||
|
* except that the 'file stream' is from an archive.
|
||||||
|
* @param pkg the package (file) that the changelog was read from
|
||||||
|
* @param fp a 'file stream' to the package changelog
|
||||||
|
* @return whether closing the package changelog stream was successful
|
||||||
|
*/
|
||||||
|
int _package_changelog_close(const pmpkg_t *pkg, void *fp)
|
||||||
|
{
|
||||||
|
return( archive_read_finish((struct archive *)fp) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Package file operations struct accessor. We implement this as a method
|
||||||
|
* rather than a static struct as in be_files because we want to reuse the
|
||||||
|
* majority of the default_pkg_ops struct and add only a few operations of
|
||||||
|
* our own on top. The static file_pkg_ops variable inside this function
|
||||||
|
* lets us only initialize an operations struct once which can always be
|
||||||
|
* accessed by this method.
|
||||||
|
*/
|
||||||
|
static struct pkg_operations *get_file_pkg_ops()
|
||||||
|
{
|
||||||
|
static struct pkg_operations *file_pkg_ops = NULL;
|
||||||
|
/* determine whether our static file_pkg_ops struct has been initialized */
|
||||||
|
if(!file_pkg_ops) {
|
||||||
|
MALLOC(file_pkg_ops, sizeof(struct pkg_operations),
|
||||||
|
RET_ERR(PM_ERR_MEMORY, NULL));
|
||||||
|
memcpy(file_pkg_ops, &default_pkg_ops, sizeof(struct pkg_operations));
|
||||||
|
file_pkg_ops->changelog_open = _package_changelog_open;
|
||||||
|
file_pkg_ops->changelog_read = _package_changelog_read;
|
||||||
|
file_pkg_ops->changelog_close = _package_changelog_close;
|
||||||
|
}
|
||||||
|
return(file_pkg_ops);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the package description file for a package into a pmpkg_t struct.
|
* Parses the package description file for a package into a pmpkg_t struct.
|
||||||
* @param archive the archive to read from, pointed at the .PKGINFO entry
|
* @param archive the archive to read from, pointed at the .PKGINFO entry
|
||||||
|
@ -234,7 +343,9 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full)
|
||||||
|
|
||||||
/* internal fields for package struct */
|
/* internal fields for package struct */
|
||||||
newpkg->origin = PKG_FROM_FILE;
|
newpkg->origin = PKG_FROM_FILE;
|
||||||
|
/* TODO eventually kill/move this? */
|
||||||
newpkg->origin_data.file = strdup(pkgfile);
|
newpkg->origin_data.file = strdup(pkgfile);
|
||||||
|
newpkg->ops = get_file_pkg_ops();
|
||||||
|
|
||||||
if(full) {
|
if(full) {
|
||||||
/* "checking for conflicts" requires a sorted list, ensure that here */
|
/* "checking for conflicts" requires a sorted list, ensure that here */
|
||||||
|
|
446
lib/libalpm/be_sync.c
Normal file
446
lib/libalpm/be_sync.c
Normal file
|
@ -0,0 +1,446 @@
|
||||||
|
/*
|
||||||
|
* be_sync.c
|
||||||
|
*
|
||||||
|
* Copyright (c) 2006-2010 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
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
/* libarchive */
|
||||||
|
#include <archive.h>
|
||||||
|
#include <archive_entry.h>
|
||||||
|
|
||||||
|
/* libalpm */
|
||||||
|
#include "util.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "alpm.h"
|
||||||
|
#include "alpm_list.h"
|
||||||
|
#include "package.h"
|
||||||
|
#include "handle.h"
|
||||||
|
#include "delta.h"
|
||||||
|
#include "deps.h"
|
||||||
|
#include "dload.h"
|
||||||
|
|
||||||
|
/** Update a package database
|
||||||
|
*
|
||||||
|
* An update of the package database \a db will be attempted. Unless
|
||||||
|
* \a force is true, the update will only be performed if the remote
|
||||||
|
* database was modified since the last update.
|
||||||
|
*
|
||||||
|
* A transaction is necessary for this operation, in order to obtain a
|
||||||
|
* database lock. During this transaction the front-end will be informed
|
||||||
|
* of the download progress of the database via the download callback.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* @code
|
||||||
|
* pmdb_t *db;
|
||||||
|
* int result;
|
||||||
|
* db = alpm_list_getdata(alpm_option_get_syncdbs());
|
||||||
|
* if(alpm_trans_init(0, NULL, NULL, NULL) == 0) {
|
||||||
|
* result = alpm_db_update(0, db);
|
||||||
|
* alpm_trans_release();
|
||||||
|
*
|
||||||
|
* if(result > 0) {
|
||||||
|
* printf("Unable to update database: %s\n", alpm_strerrorlast());
|
||||||
|
* } else if(result < 0) {
|
||||||
|
* printf("Database already up to date\n");
|
||||||
|
* } else {
|
||||||
|
* printf("Database updated\n");
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @ingroup alpm_databases
|
||||||
|
* @note After a successful update, the \link alpm_db_get_pkgcache()
|
||||||
|
* package cache \endlink will be invalidated
|
||||||
|
* @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 SYMEXPORT alpm_db_update(int force, pmdb_t *db)
|
||||||
|
{
|
||||||
|
char *dbfile, *syncpath;
|
||||||
|
const char *dbpath;
|
||||||
|
size_t len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
/* 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));
|
||||||
|
|
||||||
|
if(!alpm_list_find_ptr(handle->dbs_sync, db)) {
|
||||||
|
RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(db->treename) + 4;
|
||||||
|
MALLOC(dbfile, len, RET_ERR(PM_ERR_MEMORY, -1));
|
||||||
|
sprintf(dbfile, "%s.db", db->treename);
|
||||||
|
|
||||||
|
dbpath = alpm_option_get_dbpath();
|
||||||
|
len = strlen(dbpath) + 6;
|
||||||
|
MALLOC(syncpath, len, RET_ERR(PM_ERR_MEMORY, -1));
|
||||||
|
sprintf(syncpath, "%s%s", dbpath, "sync/");
|
||||||
|
|
||||||
|
ret = _alpm_download_single_file(dbfile, db->servers, syncpath, force);
|
||||||
|
free(dbfile);
|
||||||
|
free(syncpath);
|
||||||
|
|
||||||
|
if(ret == 1) {
|
||||||
|
/* files 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cache needs to be rebuilt */
|
||||||
|
_alpm_db_free_pkgcache(db);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _alpm_sync_db_populate(pmdb_t *db)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
struct archive *archive;
|
||||||
|
struct archive_entry *entry;
|
||||||
|
const char * archive_path;
|
||||||
|
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
|
||||||
|
|
||||||
|
if((archive = archive_read_new()) == NULL)
|
||||||
|
RET_ERR(PM_ERR_LIBARCHIVE, 1);
|
||||||
|
|
||||||
|
archive_read_support_compression_all(archive);
|
||||||
|
archive_read_support_format_all(archive);
|
||||||
|
|
||||||
|
if(archive_read_open_filename(archive, _alpm_db_path(db),
|
||||||
|
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
|
||||||
|
_alpm_log(PM_LOG_ERROR, _("could not open %s: %s\n"), _alpm_db_path(db),
|
||||||
|
archive_error_string(archive));
|
||||||
|
RET_ERR(PM_ERR_PKG_OPEN, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
|
||||||
|
const struct stat *st;
|
||||||
|
const char *name;
|
||||||
|
pmpkg_t *pkg;
|
||||||
|
|
||||||
|
st = archive_entry_stat(entry);
|
||||||
|
|
||||||
|
if(S_ISDIR(st->st_mode)) {
|
||||||
|
archive_path = archive_entry_pathname(entry);
|
||||||
|
|
||||||
|
pkg = _alpm_pkg_new();
|
||||||
|
if(pkg == NULL) {
|
||||||
|
archive_read_finish(archive);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
name = archive_entry_pathname(entry);
|
||||||
|
|
||||||
|
if(_alpm_splitname(name, pkg) != 0) {
|
||||||
|
_alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"),
|
||||||
|
name);
|
||||||
|
_alpm_pkg_free(pkg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* duplicated database entries are not allowed */
|
||||||
|
if(_alpm_pkg_find(db->pkgcache, pkg->name)) {
|
||||||
|
_alpm_log(PM_LOG_ERROR, _("duplicated database entry '%s'\n"), pkg->name);
|
||||||
|
_alpm_pkg_free(pkg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkg->origin = PKG_FROM_SYNCDB;
|
||||||
|
pkg->ops = &default_pkg_ops;
|
||||||
|
pkg->origin_data.db = db;
|
||||||
|
|
||||||
|
/* add to the collection */
|
||||||
|
_alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
|
||||||
|
pkg->name, db->treename);
|
||||||
|
db->pkgcache = alpm_list_add(db->pkgcache, pkg);
|
||||||
|
count++;
|
||||||
|
} else {
|
||||||
|
/* we have desc, depends or deltas - parse it */
|
||||||
|
_alpm_sync_db_read(db, archive, entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
db->pkgcache = alpm_list_msort(db->pkgcache, count, _alpm_pkg_cmp);
|
||||||
|
archive_read_finish(archive);
|
||||||
|
|
||||||
|
return(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _alpm_sync_db_read(pmdb_t *db, struct archive *archive, struct archive_entry *entry)
|
||||||
|
{
|
||||||
|
char line[1024];
|
||||||
|
const char *entryname;
|
||||||
|
char *filename, *pkgname, *p, *q;
|
||||||
|
pmpkg_t *pkg;
|
||||||
|
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
if(db == NULL) {
|
||||||
|
RET_ERR(PM_ERR_DB_NULL, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(entry == NULL) {
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "invalid archive entry provided to _alpm_sync_db_read, skipping\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
entryname = archive_entry_pathname(entry);
|
||||||
|
|
||||||
|
_alpm_log(PM_LOG_FUNCTION, "loading package data from archive entry %s\n",
|
||||||
|
entryname);
|
||||||
|
|
||||||
|
/* get package and db file names */
|
||||||
|
STRDUP(pkgname, entryname, RET_ERR(PM_ERR_MEMORY, -1));
|
||||||
|
p = pkgname + strlen(pkgname);
|
||||||
|
for(q = --p; *q && *q != '/'; q--);
|
||||||
|
STRDUP(filename, q+1, RET_ERR(PM_ERR_MEMORY, -1));
|
||||||
|
for(p = --q; *p && *p != '-'; p--);
|
||||||
|
for(q = --p; *q && *q != '-'; q--);
|
||||||
|
*q = '\0';
|
||||||
|
|
||||||
|
/* package is already in db due to parsing of directory name */
|
||||||
|
pkg = _alpm_pkg_find(db->pkgcache, pkgname);
|
||||||
|
if(pkg == NULL) {
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "package %s not found in %s sync database",
|
||||||
|
pkgname, db->treename);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strcmp(filename, "desc") == 0) {
|
||||||
|
while(_alpm_archive_fgets(line, sizeof(line), archive) != NULL) {
|
||||||
|
_alpm_strtrim(line);
|
||||||
|
if(strcmp(line, "%NAME%") == 0) {
|
||||||
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if(strcmp(_alpm_strtrim(line), pkg->name) != 0) {
|
||||||
|
_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: name "
|
||||||
|
"mismatch on package %s\n"), db->treename, pkg->name);
|
||||||
|
}
|
||||||
|
} else if(strcmp(line, "%VERSION%") == 0) {
|
||||||
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if(strcmp(_alpm_strtrim(line), pkg->version) != 0) {
|
||||||
|
_alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: version "
|
||||||
|
"mismatch on package %s\n"), db->treename, pkg->name);
|
||||||
|
}
|
||||||
|
} else if(strcmp(line, "%FILENAME%") == 0) {
|
||||||
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
STRDUP(pkg->filename, _alpm_strtrim(line), goto error);
|
||||||
|
} else if(strcmp(line, "%DESC%") == 0) {
|
||||||
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
STRDUP(pkg->desc, _alpm_strtrim(line), goto error);
|
||||||
|
} else if(strcmp(line, "%GROUPS%") == 0) {
|
||||||
|
while(_alpm_archive_fgets(line, sizeof(line), archive) && strlen(_alpm_strtrim(line))) {
|
||||||
|
char *linedup;
|
||||||
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
||||||
|
pkg->groups = alpm_list_add(pkg->groups, linedup);
|
||||||
|
}
|
||||||
|
} else if(strcmp(line, "%URL%") == 0) {
|
||||||
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
STRDUP(pkg->url, _alpm_strtrim(line), goto error);
|
||||||
|
} else if(strcmp(line, "%LICENSE%") == 0) {
|
||||||
|
while(_alpm_archive_fgets(line, sizeof(line), archive) &&
|
||||||
|
strlen(_alpm_strtrim(line))) {
|
||||||
|
char *linedup;
|
||||||
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
||||||
|
pkg->licenses = alpm_list_add(pkg->licenses, linedup);
|
||||||
|
}
|
||||||
|
} else if(strcmp(line, "%ARCH%") == 0) {
|
||||||
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
STRDUP(pkg->arch, _alpm_strtrim(line), goto error);
|
||||||
|
} else if(strcmp(line, "%BUILDDATE%") == 0) {
|
||||||
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
_alpm_strtrim(line);
|
||||||
|
|
||||||
|
char first = tolower((unsigned char)line[0]);
|
||||||
|
if(first > 'a' && first < 'z') {
|
||||||
|
struct tm tmp_tm = {0}; /* initialize to null in case of failure */
|
||||||
|
setlocale(LC_TIME, "C");
|
||||||
|
strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm);
|
||||||
|
pkg->builddate = mktime(&tmp_tm);
|
||||||
|
setlocale(LC_TIME, "");
|
||||||
|
} else {
|
||||||
|
pkg->builddate = atol(line);
|
||||||
|
}
|
||||||
|
} else if(strcmp(line, "%PACKAGER%") == 0) {
|
||||||
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
STRDUP(pkg->packager, _alpm_strtrim(line), goto error);
|
||||||
|
} else if(strcmp(line, "%CSIZE%") == 0) {
|
||||||
|
/* NOTE: the CSIZE and SIZE fields both share the "size" field
|
||||||
|
* in the pkginfo_t struct. This can be done b/c CSIZE
|
||||||
|
* is currently only used in sync databases, and SIZE is
|
||||||
|
* only used in local databases.
|
||||||
|
*/
|
||||||
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
pkg->size = atol(_alpm_strtrim(line));
|
||||||
|
/* also store this value to isize if isize is unset */
|
||||||
|
if(pkg->isize == 0) {
|
||||||
|
pkg->isize = pkg->size;
|
||||||
|
}
|
||||||
|
} else if(strcmp(line, "%ISIZE%") == 0) {
|
||||||
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
pkg->isize = atol(_alpm_strtrim(line));
|
||||||
|
} else if(strcmp(line, "%MD5SUM%") == 0) {
|
||||||
|
if(_alpm_archive_fgets(line, sizeof(line), archive) == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
STRDUP(pkg->md5sum, _alpm_strtrim(line), goto error);
|
||||||
|
} else if(strcmp(line, "%REPLACES%") == 0) {
|
||||||
|
while(_alpm_archive_fgets(line, sizeof(line), archive) &&
|
||||||
|
strlen(_alpm_strtrim(line))) {
|
||||||
|
char *linedup;
|
||||||
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
||||||
|
pkg->replaces = alpm_list_add(pkg->replaces, linedup);
|
||||||
|
}
|
||||||
|
} else if(strcmp(line, "%FORCE%") == 0) {
|
||||||
|
pkg->force = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(strcmp(filename, "depends") == 0) {
|
||||||
|
while(_alpm_archive_fgets(line, sizeof(line), archive) != NULL) {
|
||||||
|
_alpm_strtrim(line);
|
||||||
|
if(strcmp(line, "%DEPENDS%") == 0) {
|
||||||
|
while(_alpm_archive_fgets(line, sizeof(line), archive) &&
|
||||||
|
strlen(_alpm_strtrim(line))) {
|
||||||
|
pmdepend_t *dep = _alpm_splitdep(_alpm_strtrim(line));
|
||||||
|
pkg->depends = alpm_list_add(pkg->depends, dep);
|
||||||
|
}
|
||||||
|
} else if(strcmp(line, "%OPTDEPENDS%") == 0) {
|
||||||
|
while(_alpm_archive_fgets(line, sizeof(line), archive) &&
|
||||||
|
strlen(_alpm_strtrim(line))) {
|
||||||
|
char *linedup;
|
||||||
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
||||||
|
pkg->optdepends = alpm_list_add(pkg->optdepends, linedup);
|
||||||
|
}
|
||||||
|
} else if(strcmp(line, "%CONFLICTS%") == 0) {
|
||||||
|
while(_alpm_archive_fgets(line, sizeof(line), archive) &&
|
||||||
|
strlen(_alpm_strtrim(line))) {
|
||||||
|
char *linedup;
|
||||||
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
||||||
|
pkg->conflicts = alpm_list_add(pkg->conflicts, linedup);
|
||||||
|
}
|
||||||
|
} else if(strcmp(line, "%PROVIDES%") == 0) {
|
||||||
|
while(_alpm_archive_fgets(line, sizeof(line), archive) &&
|
||||||
|
strlen(_alpm_strtrim(line))) {
|
||||||
|
char *linedup;
|
||||||
|
STRDUP(linedup, _alpm_strtrim(line), goto error);
|
||||||
|
pkg->provides = alpm_list_add(pkg->provides, linedup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(strcmp(filename, "deltas") == 0) {
|
||||||
|
while(_alpm_archive_fgets(line, sizeof(line), archive) != NULL) {
|
||||||
|
_alpm_strtrim(line);
|
||||||
|
if(strcmp(line, "%DELTAS%") == 0) {
|
||||||
|
while(_alpm_archive_fgets(line, sizeof(line), archive) && strlen(_alpm_strtrim(line))) {
|
||||||
|
pmdelta_t *delta = _alpm_delta_parse(line);
|
||||||
|
if(delta) {
|
||||||
|
pkg->deltas = alpm_list_add(pkg->deltas, delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* unknown database file */
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "unknown database file: %s", filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
FREE(pkgname);
|
||||||
|
FREE(filename);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct db_operations sync_db_ops = {
|
||||||
|
.populate = _alpm_sync_db_populate,
|
||||||
|
.unregister = _alpm_db_unregister,
|
||||||
|
};
|
||||||
|
|
||||||
|
pmdb_t *_alpm_db_register_sync(const char *treename)
|
||||||
|
{
|
||||||
|
pmdb_t *db;
|
||||||
|
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);
|
||||||
|
|
||||||
|
db = _alpm_db_new(treename, 0);
|
||||||
|
db->ops = &sync_db_ops;
|
||||||
|
if(db == NULL) {
|
||||||
|
RET_ERR(PM_ERR_DB_CREATE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->dbs_sync = alpm_list_add(handle->dbs_sync, db);
|
||||||
|
return(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* vim: set ts=2 sw=2 noet: */
|
|
@ -1,291 +0,0 @@
|
||||||
/*
|
|
||||||
* cache.c
|
|
||||||
*
|
|
||||||
* Copyright (c) 2006-2010 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
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* libalpm */
|
|
||||||
#include "cache.h"
|
|
||||||
#include "alpm_list.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "alpm.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "package.h"
|
|
||||||
#include "group.h"
|
|
||||||
#include "db.h"
|
|
||||||
|
|
||||||
/* Returns a new package cache from db.
|
|
||||||
* It frees the cache if it already exists.
|
|
||||||
*/
|
|
||||||
int _alpm_db_load_pkgcache(pmdb_t *db)
|
|
||||||
{
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
if(db == NULL) {
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
_alpm_db_free_pkgcache(db);
|
|
||||||
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "loading package cache for repository '%s'\n",
|
|
||||||
db->treename);
|
|
||||||
if(_alpm_db_populate(db) == -1) {
|
|
||||||
_alpm_log(PM_LOG_DEBUG,
|
|
||||||
"failed to load package cache for repository '%s'\n", db->treename);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
db->pkgcache_loaded = 1;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _alpm_db_free_pkgcache(pmdb_t *db)
|
|
||||||
{
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
if(db == NULL || !db->pkgcache_loaded) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "freeing package cache for repository '%s'\n",
|
|
||||||
db->treename);
|
|
||||||
|
|
||||||
alpm_list_free_inner(db->pkgcache, (alpm_list_fn_free)_alpm_pkg_free);
|
|
||||||
alpm_list_free(db->pkgcache);
|
|
||||||
db->pkgcache = NULL;
|
|
||||||
db->pkgcache_loaded = 0;
|
|
||||||
|
|
||||||
_alpm_db_free_grpcache(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db)
|
|
||||||
{
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
if(db == NULL) {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!db->pkgcache_loaded) {
|
|
||||||
_alpm_db_load_pkgcache(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* hmmm, still NULL ?*/
|
|
||||||
if(!db->pkgcache) {
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "warning: pkgcache is NULL for db '%s'\n", db->treename);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(db->pkgcache);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* "duplicate" pkg with BASE info (to spare some memory) then add it to pkgcache */
|
|
||||||
int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg)
|
|
||||||
{
|
|
||||||
pmpkg_t *newpkg;
|
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
if(db == NULL || !db->pkgcache_loaded || pkg == NULL) {
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
newpkg = _alpm_pkg_new();
|
|
||||||
if(newpkg == NULL) {
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
newpkg->name = strdup(pkg->name);
|
|
||||||
newpkg->version = strdup(pkg->version);
|
|
||||||
if(newpkg->name == NULL || newpkg->version == NULL) {
|
|
||||||
pm_errno = PM_ERR_MEMORY;
|
|
||||||
_alpm_pkg_free(newpkg);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
newpkg->origin = PKG_FROM_CACHE;
|
|
||||||
newpkg->origin_data.db = db;
|
|
||||||
newpkg->infolevel = INFRQ_BASE;
|
|
||||||
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "adding entry '%s' in '%s' cache\n",
|
|
||||||
alpm_pkg_get_name(newpkg), db->treename);
|
|
||||||
db->pkgcache = alpm_list_add_sorted(db->pkgcache, newpkg, _alpm_pkg_cmp);
|
|
||||||
|
|
||||||
_alpm_db_free_grpcache(db);
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg)
|
|
||||||
{
|
|
||||||
void *vdata;
|
|
||||||
pmpkg_t *data;
|
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
if(db == NULL || !db->pkgcache_loaded || pkg == NULL) {
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "removing entry '%s' from '%s' cache\n",
|
|
||||||
alpm_pkg_get_name(pkg), db->treename);
|
|
||||||
|
|
||||||
db->pkgcache = alpm_list_remove(db->pkgcache, pkg, _alpm_pkg_cmp, &vdata);
|
|
||||||
data = vdata;
|
|
||||||
if(data == NULL) {
|
|
||||||
/* package not found */
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "cannot remove entry '%s' from '%s' cache: not found\n",
|
|
||||||
alpm_pkg_get_name(pkg), db->treename);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
_alpm_pkg_free(data);
|
|
||||||
|
|
||||||
_alpm_db_free_grpcache(db);
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target)
|
|
||||||
{
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
if(db == NULL) {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
alpm_list_t *pkgcache = _alpm_db_get_pkgcache(db);
|
|
||||||
if(!pkgcache) {
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "warning: failed to get '%s' from NULL pkgcache\n",
|
|
||||||
target);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(_alpm_pkg_find(pkgcache, target));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns a new group cache from db.
|
|
||||||
*/
|
|
||||||
int _alpm_db_load_grpcache(pmdb_t *db)
|
|
||||||
{
|
|
||||||
alpm_list_t *lp;
|
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
if(db == NULL) {
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "loading group cache for repository '%s'\n",
|
|
||||||
db->treename);
|
|
||||||
|
|
||||||
for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) {
|
|
||||||
const alpm_list_t *i;
|
|
||||||
pmpkg_t *pkg = lp->data;
|
|
||||||
|
|
||||||
for(i = alpm_pkg_get_groups(pkg); i; i = i->next) {
|
|
||||||
const char *grpname = i->data;
|
|
||||||
alpm_list_t *j;
|
|
||||||
pmgrp_t *grp = NULL;
|
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
/* first look through the group cache for a group with this name */
|
|
||||||
for(j = db->grpcache; j; j = j->next) {
|
|
||||||
grp = j->data;
|
|
||||||
|
|
||||||
if(strcmp(grp->name, grpname) == 0
|
|
||||||
&& !alpm_list_find_ptr(grp->packages, pkg)) {
|
|
||||||
grp->packages = alpm_list_add(grp->packages, pkg);
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(found) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* we didn't find the group, so create a new one with this name */
|
|
||||||
grp = _alpm_grp_new(grpname);
|
|
||||||
grp->packages = alpm_list_add(grp->packages, pkg);
|
|
||||||
db->grpcache = alpm_list_add(db->grpcache, grp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
db->grpcache_loaded = 1;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _alpm_db_free_grpcache(pmdb_t *db)
|
|
||||||
{
|
|
||||||
alpm_list_t *lg;
|
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
if(db == NULL || !db->grpcache_loaded) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "freeing group cache for repository '%s'\n",
|
|
||||||
db->treename);
|
|
||||||
|
|
||||||
for(lg = db->grpcache; lg; lg = lg->next) {
|
|
||||||
_alpm_grp_free(lg->data);
|
|
||||||
lg->data = NULL;
|
|
||||||
}
|
|
||||||
FREELIST(db->grpcache);
|
|
||||||
db->grpcache_loaded = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db)
|
|
||||||
{
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
if(db == NULL) {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!db->grpcache_loaded) {
|
|
||||||
_alpm_db_load_grpcache(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(db->grpcache);
|
|
||||||
}
|
|
||||||
|
|
||||||
pmgrp_t *_alpm_db_get_grpfromcache(pmdb_t *db, const char *target)
|
|
||||||
{
|
|
||||||
alpm_list_t *i;
|
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
if(db == NULL || target == NULL || strlen(target) == 0) {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = _alpm_db_get_grpcache(db); i; i = i->next) {
|
|
||||||
pmgrp_t *info = i->data;
|
|
||||||
|
|
||||||
if(strcmp(info->name, target) == 0) {
|
|
||||||
return(info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vim: set ts=2 sw=2 noet: */
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
* cache.h
|
|
||||||
*
|
|
||||||
* Copyright (c) 2006-2010 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
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#ifndef _ALPM_CACHE_H
|
|
||||||
#define _ALPM_CACHE_H
|
|
||||||
|
|
||||||
#include "db.h"
|
|
||||||
#include "alpm_list.h"
|
|
||||||
#include "group.h"
|
|
||||||
#include "package.h"
|
|
||||||
|
|
||||||
/* packages */
|
|
||||||
int _alpm_db_load_pkgcache(pmdb_t *db);
|
|
||||||
void _alpm_db_free_pkgcache(pmdb_t *db);
|
|
||||||
int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg);
|
|
||||||
int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg);
|
|
||||||
alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db);
|
|
||||||
int _alpm_db_ensure_pkgcache(pmdb_t *db, pmdbinfrq_t infolevel);
|
|
||||||
pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target);
|
|
||||||
/* groups */
|
|
||||||
int _alpm_db_load_grpcache(pmdb_t *db);
|
|
||||||
void _alpm_db_free_grpcache(pmdb_t *db);
|
|
||||||
alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db);
|
|
||||||
pmgrp_t *_alpm_db_get_grpfromcache(pmdb_t *db, const char *target);
|
|
||||||
|
|
||||||
#endif /* _ALPM_CACHE_H */
|
|
||||||
|
|
||||||
/* vim: set ts=2 sw=2 noet: */
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include "trans.h"
|
#include "trans.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "cache.h"
|
|
||||||
#include "deps.h"
|
#include "deps.h"
|
||||||
|
|
||||||
pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2, const char *reason)
|
pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2, const char *reason)
|
||||||
|
|
281
lib/libalpm/db.c
281
lib/libalpm/db.c
|
@ -39,8 +39,9 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "handle.h"
|
#include "handle.h"
|
||||||
#include "cache.h"
|
|
||||||
#include "alpm.h"
|
#include "alpm.h"
|
||||||
|
#include "package.h"
|
||||||
|
#include "group.h"
|
||||||
|
|
||||||
/** \addtogroup alpm_databases Database Functions
|
/** \addtogroup alpm_databases Database Functions
|
||||||
* @brief Functions to query and manipulate the database of libalpm
|
* @brief Functions to query and manipulate the database of libalpm
|
||||||
|
@ -80,7 +81,7 @@ pmdb_t SYMEXPORT *alpm_db_register_local(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function for alpm_db_unregister{_all} */
|
/* Helper function for alpm_db_unregister{_all} */
|
||||||
static void _alpm_db_unregister(pmdb_t *db)
|
void _alpm_db_unregister(pmdb_t *db)
|
||||||
{
|
{
|
||||||
if(db == NULL) {
|
if(db == NULL) {
|
||||||
return;
|
return;
|
||||||
|
@ -96,6 +97,7 @@ static void _alpm_db_unregister(pmdb_t *db)
|
||||||
int SYMEXPORT alpm_db_unregister_all(void)
|
int SYMEXPORT alpm_db_unregister_all(void)
|
||||||
{
|
{
|
||||||
alpm_list_t *i;
|
alpm_list_t *i;
|
||||||
|
pmdb_t *db;
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
@ -105,13 +107,16 @@ int SYMEXPORT alpm_db_unregister_all(void)
|
||||||
ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1));
|
ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1));
|
||||||
|
|
||||||
/* close local database */
|
/* close local database */
|
||||||
_alpm_db_unregister(handle->db_local);
|
db = handle->db_local;
|
||||||
handle->db_local = NULL;
|
if(db) {
|
||||||
|
db->ops->unregister(db);
|
||||||
|
handle->db_local = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* and also sync ones */
|
/* and also sync ones */
|
||||||
for(i = handle->dbs_sync; i; i = i->next) {
|
for(i = handle->dbs_sync; i; i = i->next) {
|
||||||
pmdb_t *db = i->data;
|
db = i->data;
|
||||||
_alpm_db_unregister(db);
|
db->ops->unregister(db);
|
||||||
i->data = NULL;
|
i->data = NULL;
|
||||||
}
|
}
|
||||||
FREELIST(handle->dbs_sync);
|
FREELIST(handle->dbs_sync);
|
||||||
|
@ -154,7 +159,7 @@ int SYMEXPORT alpm_db_unregister(pmdb_t *db)
|
||||||
RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
|
RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
_alpm_db_unregister(db);
|
db->ops->unregister(db);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +326,7 @@ alpm_list_t SYMEXPORT *alpm_db_search(pmdb_t *db, const alpm_list_t* needles)
|
||||||
return(_alpm_db_search(db, needles));
|
return(_alpm_db_search(db, needles));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set install reason for a package in db
|
/** Set install reason for a package in db
|
||||||
* @param db pointer to the package database
|
* @param db pointer to the package database
|
||||||
* @param name the name of the package
|
* @param name the name of the package
|
||||||
* @param reason the new install reason
|
* @param reason the new install reason
|
||||||
|
@ -342,7 +347,7 @@ int SYMEXPORT alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t
|
||||||
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "setting install reason %u for %s/%s\n", reason, db->treename, name);
|
_alpm_log(PM_LOG_DEBUG, "setting install reason %u for %s/%s\n", reason, db->treename, name);
|
||||||
/* read DESC */
|
/* read DESC */
|
||||||
if(_alpm_db_read(db, pkg, INFRQ_DESC)) {
|
if(_alpm_local_db_read(db, pkg, INFRQ_DESC)) {
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
if(pkg->reason == reason) {
|
if(pkg->reason == reason) {
|
||||||
|
@ -352,7 +357,7 @@ int SYMEXPORT alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t
|
||||||
/* set reason (in pkgcache) */
|
/* set reason (in pkgcache) */
|
||||||
pkg->reason = reason;
|
pkg->reason = reason;
|
||||||
/* write DESC */
|
/* write DESC */
|
||||||
if(_alpm_db_write(db, pkg, INFRQ_DESC)) {
|
if(_alpm_local_db_write(db, pkg, INFRQ_DESC)) {
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +366,7 @@ int SYMEXPORT alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
static pmdb_t *_alpm_db_new(const char *treename, int is_local)
|
pmdb_t *_alpm_db_new(const char *treename, int is_local)
|
||||||
{
|
{
|
||||||
pmdb_t *db;
|
pmdb_t *db;
|
||||||
|
|
||||||
|
@ -409,10 +414,10 @@ const char *_alpm_db_path(pmdb_t *db)
|
||||||
CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
|
CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
|
||||||
sprintf(db->_path, "%s%s/", dbpath, db->treename);
|
sprintf(db->_path, "%s%s/", dbpath, db->treename);
|
||||||
} else {
|
} else {
|
||||||
pathsize = strlen(dbpath) + 5 + strlen(db->treename) + 2;
|
pathsize = strlen(dbpath) + 5 + strlen(db->treename) + 4;
|
||||||
CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
|
CALLOC(db->_path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
|
||||||
/* all sync DBs now reside in the sync/ subdir of the dbpath */
|
/* all sync DBs now reside in the sync/ subdir of the dbpath */
|
||||||
sprintf(db->_path, "%ssync/%s/", dbpath, db->treename);
|
sprintf(db->_path, "%ssync/%s.db", dbpath, db->treename);
|
||||||
}
|
}
|
||||||
_alpm_log(PM_LOG_DEBUG, "database path for tree %s set to %s\n",
|
_alpm_log(PM_LOG_DEBUG, "database path for tree %s set to %s\n",
|
||||||
db->treename, db->_path);
|
db->treename, db->_path);
|
||||||
|
@ -503,52 +508,246 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
pmdb_t *_alpm_db_register_local(void)
|
/* Returns a new package cache from db.
|
||||||
|
* It frees the cache if it already exists.
|
||||||
|
*/
|
||||||
|
int _alpm_db_load_pkgcache(pmdb_t *db)
|
||||||
{
|
{
|
||||||
pmdb_t *db;
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
if(db == NULL) {
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
_alpm_db_free_pkgcache(db);
|
||||||
|
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "loading package cache for repository '%s'\n",
|
||||||
|
db->treename);
|
||||||
|
if(db->ops->populate(db) == -1) {
|
||||||
|
_alpm_log(PM_LOG_DEBUG,
|
||||||
|
"failed to load package cache for repository '%s'\n", db->treename);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
db->pkgcache_loaded = 1;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _alpm_db_free_pkgcache(pmdb_t *db)
|
||||||
|
{
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
if(db == NULL || !db->pkgcache_loaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "freeing package cache for repository '%s'\n",
|
||||||
|
db->treename);
|
||||||
|
|
||||||
|
alpm_list_free_inner(db->pkgcache, (alpm_list_fn_free)_alpm_pkg_free);
|
||||||
|
alpm_list_free(db->pkgcache);
|
||||||
|
db->pkgcache_loaded = 0;
|
||||||
|
|
||||||
|
_alpm_db_free_grpcache(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db)
|
||||||
|
{
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
if(db == NULL) {
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!db->pkgcache_loaded) {
|
||||||
|
_alpm_db_load_pkgcache(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hmmm, still NULL ?*/
|
||||||
|
if(!db->pkgcache) {
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "warning: pkgcache is NULL for db '%s'\n", db->treename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(db->pkgcache);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "duplicate" pkg then add it to pkgcache */
|
||||||
|
int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
pmpkg_t *newpkg;
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
if(handle->db_local != NULL) {
|
if(db == NULL || !db->pkgcache_loaded || pkg == NULL) {
|
||||||
_alpm_log(PM_LOG_WARNING, _("attempt to re-register the 'local' DB\n"));
|
return(-1);
|
||||||
RET_ERR(PM_ERR_DB_NOT_NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "registering local database\n");
|
newpkg = _alpm_pkg_dup(pkg);
|
||||||
|
if(newpkg == NULL) {
|
||||||
db = _alpm_db_new("local", 1);
|
return(-1);
|
||||||
if(db == NULL) {
|
|
||||||
RET_ERR(PM_ERR_DB_CREATE, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->db_local = db;
|
_alpm_log(PM_LOG_DEBUG, "adding entry '%s' in '%s' cache\n",
|
||||||
return(db);
|
alpm_pkg_get_name(newpkg), db->treename);
|
||||||
|
db->pkgcache = alpm_list_add_sorted(db->pkgcache, newpkg, _alpm_pkg_cmp);
|
||||||
|
|
||||||
|
_alpm_db_free_grpcache(db);
|
||||||
|
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pmdb_t *_alpm_db_register_sync(const char *treename)
|
int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
void *vdata;
|
||||||
|
pmpkg_t *data;
|
||||||
|
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
if(db == NULL || !db->pkgcache_loaded || pkg == NULL) {
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "removing entry '%s' from '%s' cache\n",
|
||||||
|
alpm_pkg_get_name(pkg), db->treename);
|
||||||
|
|
||||||
|
db->pkgcache = alpm_list_remove(db->pkgcache, pkg, _alpm_pkg_cmp, &vdata);
|
||||||
|
data = vdata;
|
||||||
|
if(data == NULL) {
|
||||||
|
/* package not found */
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "cannot remove entry '%s' from '%s' cache: not found\n",
|
||||||
|
alpm_pkg_get_name(pkg), db->treename);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_alpm_pkg_free(data);
|
||||||
|
|
||||||
|
_alpm_db_free_grpcache(db);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target)
|
||||||
|
{
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
if(db == NULL) {
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
alpm_list_t *pkgcache = _alpm_db_get_pkgcache(db);
|
||||||
|
if(!pkgcache) {
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "warning: failed to get '%s' from NULL pkgcache\n",
|
||||||
|
target);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(_alpm_pkg_find(pkgcache, target));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns a new group cache from db.
|
||||||
|
*/
|
||||||
|
int _alpm_db_load_grpcache(pmdb_t *db)
|
||||||
|
{
|
||||||
|
alpm_list_t *lp;
|
||||||
|
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
if(db == NULL) {
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "loading group cache for repository '%s'\n",
|
||||||
|
db->treename);
|
||||||
|
|
||||||
|
for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) {
|
||||||
|
const alpm_list_t *i;
|
||||||
|
pmpkg_t *pkg = lp->data;
|
||||||
|
|
||||||
|
for(i = alpm_pkg_get_groups(pkg); i; i = i->next) {
|
||||||
|
const char *grpname = i->data;
|
||||||
|
alpm_list_t *j;
|
||||||
|
pmgrp_t *grp = NULL;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
/* first look through the group cache for a group with this name */
|
||||||
|
for(j = db->grpcache; j; j = j->next) {
|
||||||
|
grp = j->data;
|
||||||
|
|
||||||
|
if(strcmp(grp->name, grpname) == 0
|
||||||
|
&& !alpm_list_find_ptr(grp->packages, pkg)) {
|
||||||
|
grp->packages = alpm_list_add(grp->packages, pkg);
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(found) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* we didn't find the group, so create a new one with this name */
|
||||||
|
grp = _alpm_grp_new(grpname);
|
||||||
|
grp->packages = alpm_list_add(grp->packages, pkg);
|
||||||
|
db->grpcache = alpm_list_add(db->grpcache, grp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
db->grpcache_loaded = 1;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _alpm_db_free_grpcache(pmdb_t *db)
|
||||||
|
{
|
||||||
|
alpm_list_t *lg;
|
||||||
|
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
if(db == NULL || !db->grpcache_loaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "freeing group cache for repository '%s'\n",
|
||||||
|
db->treename);
|
||||||
|
|
||||||
|
for(lg = db->grpcache; lg; lg = lg->next) {
|
||||||
|
_alpm_grp_free(lg->data);
|
||||||
|
lg->data = NULL;
|
||||||
|
}
|
||||||
|
FREELIST(db->grpcache);
|
||||||
|
db->grpcache_loaded = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db)
|
||||||
|
{
|
||||||
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
|
if(db == NULL) {
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!db->grpcache_loaded) {
|
||||||
|
_alpm_db_load_grpcache(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(db->grpcache);
|
||||||
|
}
|
||||||
|
|
||||||
|
pmgrp_t *_alpm_db_get_grpfromcache(pmdb_t *db, const char *target)
|
||||||
{
|
{
|
||||||
pmdb_t *db;
|
|
||||||
alpm_list_t *i;
|
alpm_list_t *i;
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
for(i = handle->dbs_sync; i; i = i->next) {
|
if(db == NULL || target == NULL || strlen(target) == 0) {
|
||||||
pmdb_t *sdb = i->data;
|
return(NULL);
|
||||||
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;
|
for(i = _alpm_db_get_grpcache(db); i; i = i->next) {
|
||||||
|
pmgrp_t *info = i->data;
|
||||||
|
|
||||||
|
if(strcmp(info->name, target) == 0) {
|
||||||
|
return(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "registering sync database '%s'\n", treename);
|
return(NULL);
|
||||||
|
|
||||||
db = _alpm_db_new(treename, 0);
|
|
||||||
if(db == NULL) {
|
|
||||||
RET_ERR(PM_ERR_DB_CREATE, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
handle->dbs_sync = alpm_list_add(handle->dbs_sync, db);
|
|
||||||
return(db);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim: set ts=2 sw=2 noet: */
|
/* vim: set ts=2 sw=2 noet: */
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
/* libarchive */
|
||||||
|
#include <archive.h>
|
||||||
|
#include <archive_entry.h>
|
||||||
|
|
||||||
/* Database entries */
|
/* Database entries */
|
||||||
typedef enum _pmdbinfrq_t {
|
typedef enum _pmdbinfrq_t {
|
||||||
INFRQ_BASE = 1,
|
INFRQ_BASE = 1,
|
||||||
|
@ -33,12 +37,16 @@ typedef enum _pmdbinfrq_t {
|
||||||
INFRQ_DEPENDS = (1 << 2),
|
INFRQ_DEPENDS = (1 << 2),
|
||||||
INFRQ_FILES = (1 << 3),
|
INFRQ_FILES = (1 << 3),
|
||||||
INFRQ_SCRIPTLET = (1 << 4),
|
INFRQ_SCRIPTLET = (1 << 4),
|
||||||
INFRQ_DELTAS = (1 << 5),
|
INFRQ_DSIZE = (1 << 5),
|
||||||
INFRQ_DSIZE = (1 << 6),
|
|
||||||
/* ALL should be info stored in the package or database */
|
/* ALL should be info stored in the package or database */
|
||||||
INFRQ_ALL = 0x3F
|
INFRQ_ALL = 0x3F
|
||||||
} pmdbinfrq_t;
|
} pmdbinfrq_t;
|
||||||
|
|
||||||
|
struct db_operations {
|
||||||
|
int (*populate) (pmdb_t *);
|
||||||
|
void (*unregister) (pmdb_t *);
|
||||||
|
};
|
||||||
|
|
||||||
/* Database */
|
/* Database */
|
||||||
struct __pmdb_t {
|
struct __pmdb_t {
|
||||||
char *treename;
|
char *treename;
|
||||||
|
@ -46,12 +54,16 @@ struct __pmdb_t {
|
||||||
char *_path;
|
char *_path;
|
||||||
int pkgcache_loaded;
|
int pkgcache_loaded;
|
||||||
int grpcache_loaded;
|
int grpcache_loaded;
|
||||||
|
/* also indicates whether we are RO or RW */
|
||||||
int is_local;
|
int is_local;
|
||||||
alpm_list_t *pkgcache;
|
alpm_list_t *pkgcache;
|
||||||
alpm_list_t *grpcache;
|
alpm_list_t *grpcache;
|
||||||
alpm_list_t *servers;
|
alpm_list_t *servers;
|
||||||
|
|
||||||
|
struct db_operations *ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* db.c, database general calls */
|
/* db.c, database general calls */
|
||||||
void _alpm_db_free(pmdb_t *db);
|
void _alpm_db_free(pmdb_t *db);
|
||||||
const char *_alpm_db_path(pmdb_t *db);
|
const char *_alpm_db_path(pmdb_t *db);
|
||||||
|
@ -59,13 +71,33 @@ int _alpm_db_cmp(const void *d1, const void *d2);
|
||||||
alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles);
|
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_local(void);
|
||||||
pmdb_t *_alpm_db_register_sync(const char *treename);
|
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 */
|
/* be_*.c, backend specific calls */
|
||||||
int _alpm_db_populate(pmdb_t *db);
|
int _alpm_local_db_populate(pmdb_t *db);
|
||||||
int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
|
int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
|
||||||
int _alpm_db_prepare(pmdb_t *db, pmpkg_t *info);
|
int _alpm_local_db_prepare(pmdb_t *db, pmpkg_t *info);
|
||||||
int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
|
int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
|
||||||
int _alpm_db_remove(pmdb_t *db, pmpkg_t *info);
|
int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info);
|
||||||
|
|
||||||
|
int _alpm_sync_db_populate(pmdb_t *db);
|
||||||
|
int _alpm_sync_db_read(pmdb_t *db, struct archive *archive, struct archive_entry *entry);
|
||||||
|
|
||||||
|
/* cache bullshit */
|
||||||
|
/* packages */
|
||||||
|
int _alpm_db_load_pkgcache(pmdb_t *db);
|
||||||
|
void _alpm_db_free_pkgcache(pmdb_t *db);
|
||||||
|
int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg);
|
||||||
|
int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg);
|
||||||
|
alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db);
|
||||||
|
int _alpm_db_ensure_pkgcache(pmdb_t *db, pmdbinfrq_t infolevel);
|
||||||
|
pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target);
|
||||||
|
/* groups */
|
||||||
|
int _alpm_db_load_grpcache(pmdb_t *db);
|
||||||
|
void _alpm_db_free_grpcache(pmdb_t *db);
|
||||||
|
alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db);
|
||||||
|
pmgrp_t *_alpm_db_get_grpfromcache(pmdb_t *db, const char *target);
|
||||||
|
|
||||||
#endif /* _ALPM_DB_H */
|
#endif /* _ALPM_DB_H */
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "package.h"
|
#include "package.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "cache.h"
|
|
||||||
#include "handle.h"
|
#include "handle.h"
|
||||||
|
|
||||||
void _alpm_dep_free(pmdepend_t *dep)
|
void _alpm_dep_free(pmdepend_t *dep)
|
||||||
|
|
|
@ -42,7 +42,6 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "cache.h"
|
|
||||||
#include "delta.h"
|
#include "delta.h"
|
||||||
#include "handle.h"
|
#include "handle.h"
|
||||||
#include "deps.h"
|
#include "deps.h"
|
||||||
|
@ -63,7 +62,7 @@ int SYMEXPORT alpm_pkg_free(pmpkg_t *pkg)
|
||||||
ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
|
ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
|
||||||
|
|
||||||
/* Only free packages loaded in user space */
|
/* Only free packages loaded in user space */
|
||||||
if(pkg->origin != PKG_FROM_CACHE) {
|
if(pkg->origin == PKG_FROM_FILE) {
|
||||||
_alpm_pkg_free(pkg);
|
_alpm_pkg_free(pkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,8 +82,7 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)
|
||||||
|
|
||||||
ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
|
ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
|
||||||
/* We only inspect packages from sync repositories */
|
/* We only inspect packages from sync repositories */
|
||||||
ASSERT(pkg->origin == PKG_FROM_CACHE, RET_ERR(PM_ERR_PKG_INVALID, -1));
|
ASSERT(pkg->origin == PKG_FROM_SYNCDB, RET_ERR(PM_ERR_PKG_INVALID, -1));
|
||||||
ASSERT(pkg->origin_data.db != handle->db_local, RET_ERR(PM_ERR_PKG_INVALID, -1));
|
|
||||||
|
|
||||||
fpath = _alpm_filecache_find(alpm_pkg_get_filename(pkg));
|
fpath = _alpm_filecache_find(alpm_pkg_get_filename(pkg));
|
||||||
|
|
||||||
|
@ -100,334 +98,194 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)
|
||||||
return(retval);
|
return(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Default package accessor functions. These will get overridden by any
|
||||||
|
* backend logic that needs lazy access, such as the local database through
|
||||||
|
* a lazy-load cache. However, the defaults will work just fine for fully-
|
||||||
|
* populated package structures. */
|
||||||
|
const char *_pkg_get_filename(pmpkg_t *pkg) { return pkg->filename; }
|
||||||
|
const char *_pkg_get_name(pmpkg_t *pkg) { return pkg->name; }
|
||||||
|
const char *_pkg_get_version(pmpkg_t *pkg) { return pkg->version; }
|
||||||
|
const char *_pkg_get_desc(pmpkg_t *pkg) { return pkg->desc; }
|
||||||
|
const char *_pkg_get_url(pmpkg_t *pkg) { return pkg->url; }
|
||||||
|
time_t _pkg_get_builddate(pmpkg_t *pkg) { return pkg->builddate; }
|
||||||
|
time_t _pkg_get_installdate(pmpkg_t *pkg) { return pkg->installdate; }
|
||||||
|
const char *_pkg_get_packager(pmpkg_t *pkg) { return pkg->packager; }
|
||||||
|
const char *_pkg_get_md5sum(pmpkg_t *pkg) { return pkg->md5sum; }
|
||||||
|
const char *_pkg_get_arch(pmpkg_t *pkg) { return pkg->arch; }
|
||||||
|
off_t _pkg_get_size(pmpkg_t *pkg) { return pkg->size; }
|
||||||
|
off_t _pkg_get_isize(pmpkg_t *pkg) { return pkg->isize; }
|
||||||
|
pmpkgreason_t _pkg_get_reason(pmpkg_t *pkg) { return pkg->reason; }
|
||||||
|
int _pkg_has_force(pmpkg_t *pkg) { return pkg->force; }
|
||||||
|
|
||||||
|
alpm_list_t *_pkg_get_licenses(pmpkg_t *pkg) { return pkg->licenses; }
|
||||||
|
alpm_list_t *_pkg_get_groups(pmpkg_t *pkg) { return pkg->groups; }
|
||||||
|
alpm_list_t *_pkg_get_depends(pmpkg_t *pkg) { return pkg->depends; }
|
||||||
|
alpm_list_t *_pkg_get_optdepends(pmpkg_t *pkg) { return pkg->optdepends; }
|
||||||
|
alpm_list_t *_pkg_get_conflicts(pmpkg_t *pkg) { return pkg->conflicts; }
|
||||||
|
alpm_list_t *_pkg_get_provides(pmpkg_t *pkg) { return pkg->provides; }
|
||||||
|
alpm_list_t *_pkg_get_replaces(pmpkg_t *pkg) { return pkg->replaces; }
|
||||||
|
alpm_list_t *_pkg_get_deltas(pmpkg_t *pkg) { return pkg->deltas; }
|
||||||
|
alpm_list_t *_pkg_get_files(pmpkg_t *pkg) { return pkg->files; }
|
||||||
|
alpm_list_t *_pkg_get_backup(pmpkg_t *pkg) { return pkg->backup; }
|
||||||
|
|
||||||
|
/** The standard package operations struct. Get fields directly from the
|
||||||
|
* struct itself with no abstraction layer or any type of lazy loading.
|
||||||
|
*/
|
||||||
|
struct pkg_operations default_pkg_ops = {
|
||||||
|
.get_filename = _pkg_get_filename,
|
||||||
|
.get_name = _pkg_get_name,
|
||||||
|
.get_version = _pkg_get_version,
|
||||||
|
.get_desc = _pkg_get_desc,
|
||||||
|
.get_url = _pkg_get_url,
|
||||||
|
.get_builddate = _pkg_get_builddate,
|
||||||
|
.get_installdate = _pkg_get_installdate,
|
||||||
|
.get_packager = _pkg_get_packager,
|
||||||
|
.get_md5sum = _pkg_get_md5sum,
|
||||||
|
.get_arch = _pkg_get_arch,
|
||||||
|
.get_size = _pkg_get_size,
|
||||||
|
.get_isize = _pkg_get_isize,
|
||||||
|
.get_reason = _pkg_get_reason,
|
||||||
|
.has_force = _pkg_has_force,
|
||||||
|
.get_licenses = _pkg_get_licenses,
|
||||||
|
.get_groups = _pkg_get_groups,
|
||||||
|
.get_depends = _pkg_get_depends,
|
||||||
|
.get_optdepends = _pkg_get_optdepends,
|
||||||
|
.get_conflicts = _pkg_get_conflicts,
|
||||||
|
.get_provides = _pkg_get_provides,
|
||||||
|
.get_replaces = _pkg_get_replaces,
|
||||||
|
.get_deltas = _pkg_get_deltas,
|
||||||
|
.get_files = _pkg_get_files,
|
||||||
|
.get_backup = _pkg_get_backup,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Public functions for getting package information. These functions
|
||||||
|
* delegate the hard work to the function callbacks attached to each
|
||||||
|
* package, which depend on where the package was loaded from. */
|
||||||
const char SYMEXPORT *alpm_pkg_get_filename(pmpkg_t *pkg)
|
const char SYMEXPORT *alpm_pkg_get_filename(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_filename(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pkg->filename;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char SYMEXPORT *alpm_pkg_get_name(pmpkg_t *pkg)
|
const char SYMEXPORT *alpm_pkg_get_name(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
return pkg->ops->get_name(pkg);
|
||||||
return pkg->name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char SYMEXPORT *alpm_pkg_get_version(pmpkg_t *pkg)
|
const char SYMEXPORT *alpm_pkg_get_version(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
return pkg->ops->get_version(pkg);
|
||||||
return pkg->version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char SYMEXPORT *alpm_pkg_get_desc(pmpkg_t *pkg)
|
const char SYMEXPORT *alpm_pkg_get_desc(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_desc(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
return pkg->desc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char SYMEXPORT *alpm_pkg_get_url(pmpkg_t *pkg)
|
const char SYMEXPORT *alpm_pkg_get_url(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_url(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
return pkg->url;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t SYMEXPORT alpm_pkg_get_builddate(pmpkg_t *pkg)
|
time_t SYMEXPORT alpm_pkg_get_builddate(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_builddate(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(0));
|
|
||||||
ASSERT(pkg != NULL, return(0));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
return pkg->builddate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t SYMEXPORT alpm_pkg_get_installdate(pmpkg_t *pkg)
|
time_t SYMEXPORT alpm_pkg_get_installdate(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_installdate(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(0));
|
|
||||||
ASSERT(pkg != NULL, return(0));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
return pkg->installdate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char SYMEXPORT *alpm_pkg_get_packager(pmpkg_t *pkg)
|
const char SYMEXPORT *alpm_pkg_get_packager(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_packager(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
return pkg->packager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char SYMEXPORT *alpm_pkg_get_md5sum(pmpkg_t *pkg)
|
const char SYMEXPORT *alpm_pkg_get_md5sum(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_md5sum(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
return pkg->md5sum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char SYMEXPORT *alpm_pkg_get_arch(pmpkg_t *pkg)
|
const char SYMEXPORT *alpm_pkg_get_arch(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_arch(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
return pkg->arch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t SYMEXPORT alpm_pkg_get_size(pmpkg_t *pkg)
|
off_t SYMEXPORT alpm_pkg_get_size(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_size(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(-1));
|
|
||||||
ASSERT(pkg != NULL, return(-1));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
return pkg->size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t SYMEXPORT alpm_pkg_get_isize(pmpkg_t *pkg)
|
off_t SYMEXPORT alpm_pkg_get_isize(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_isize(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(-1));
|
|
||||||
ASSERT(pkg != NULL, return(-1));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
return pkg->isize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pmpkgreason_t SYMEXPORT alpm_pkg_get_reason(pmpkg_t *pkg)
|
pmpkgreason_t SYMEXPORT alpm_pkg_get_reason(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_reason(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(-1));
|
|
||||||
ASSERT(pkg != NULL, return(-1));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
return pkg->reason;
|
|
||||||
}
|
|
||||||
|
|
||||||
alpm_list_t SYMEXPORT *alpm_pkg_get_licenses(pmpkg_t *pkg)
|
|
||||||
{
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
return pkg->licenses;
|
|
||||||
}
|
|
||||||
|
|
||||||
alpm_list_t SYMEXPORT *alpm_pkg_get_groups(pmpkg_t *pkg)
|
|
||||||
{
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
return pkg->groups;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SYMEXPORT alpm_pkg_has_force(pmpkg_t *pkg)
|
int SYMEXPORT alpm_pkg_has_force(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->has_force(pkg);
|
||||||
|
}
|
||||||
|
|
||||||
/* Sanity checks */
|
alpm_list_t SYMEXPORT *alpm_pkg_get_licenses(pmpkg_t *pkg)
|
||||||
ASSERT(handle != NULL, return(-1));
|
{
|
||||||
ASSERT(pkg != NULL, return(-1));
|
return pkg->ops->get_licenses(pkg);
|
||||||
|
}
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
alpm_list_t SYMEXPORT *alpm_pkg_get_groups(pmpkg_t *pkg)
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
{
|
||||||
}
|
return pkg->ops->get_groups(pkg);
|
||||||
return pkg->force;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alpm_list_t SYMEXPORT *alpm_pkg_get_depends(pmpkg_t *pkg)
|
alpm_list_t SYMEXPORT *alpm_pkg_get_depends(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_depends(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DEPENDS)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DEPENDS);
|
|
||||||
}
|
|
||||||
return pkg->depends;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alpm_list_t SYMEXPORT *alpm_pkg_get_optdepends(pmpkg_t *pkg)
|
alpm_list_t SYMEXPORT *alpm_pkg_get_optdepends(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_optdepends(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DEPENDS)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DEPENDS);
|
|
||||||
}
|
|
||||||
return pkg->optdepends;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alpm_list_t SYMEXPORT *alpm_pkg_get_conflicts(pmpkg_t *pkg)
|
alpm_list_t SYMEXPORT *alpm_pkg_get_conflicts(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_conflicts(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DEPENDS)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DEPENDS);
|
|
||||||
}
|
|
||||||
return pkg->conflicts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alpm_list_t SYMEXPORT *alpm_pkg_get_provides(pmpkg_t *pkg)
|
alpm_list_t SYMEXPORT *alpm_pkg_get_provides(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_provides(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DEPENDS)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DEPENDS);
|
|
||||||
}
|
|
||||||
return pkg->provides;
|
|
||||||
}
|
|
||||||
|
|
||||||
alpm_list_t SYMEXPORT *alpm_pkg_get_deltas(pmpkg_t *pkg)
|
|
||||||
{
|
|
||||||
ALPM_LOG_FUNC;
|
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DELTAS)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DELTAS);
|
|
||||||
}
|
|
||||||
return pkg->deltas;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alpm_list_t SYMEXPORT *alpm_pkg_get_replaces(pmpkg_t *pkg)
|
alpm_list_t SYMEXPORT *alpm_pkg_get_replaces(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_replaces(pkg);
|
||||||
|
}
|
||||||
|
|
||||||
/* Sanity checks */
|
alpm_list_t SYMEXPORT *alpm_pkg_get_deltas(pmpkg_t *pkg)
|
||||||
ASSERT(handle != NULL, return(NULL));
|
{
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
return pkg->ops->get_deltas(pkg);
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && !(pkg->infolevel & INFRQ_DESC)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
|
|
||||||
}
|
|
||||||
return pkg->replaces;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alpm_list_t SYMEXPORT *alpm_pkg_get_files(pmpkg_t *pkg)
|
alpm_list_t SYMEXPORT *alpm_pkg_get_files(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_files(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && pkg->origin_data.db == handle->db_local
|
|
||||||
&& !(pkg->infolevel & INFRQ_FILES)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_FILES);
|
|
||||||
}
|
|
||||||
return pkg->files;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alpm_list_t SYMEXPORT *alpm_pkg_get_backup(pmpkg_t *pkg)
|
alpm_list_t SYMEXPORT *alpm_pkg_get_backup(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->get_backup(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && pkg->origin_data.db == handle->db_local
|
|
||||||
&& !(pkg->infolevel & INFRQ_FILES)) {
|
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_FILES);
|
|
||||||
}
|
|
||||||
return pkg->backup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pmdb_t SYMEXPORT *alpm_pkg_get_db(pmpkg_t *pkg)
|
pmdb_t SYMEXPORT *alpm_pkg_get_db(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
ASSERT(pkg != NULL, return(NULL));
|
||||||
ASSERT(pkg->origin == PKG_FROM_CACHE, return(NULL));
|
ASSERT(pkg->origin != PKG_FROM_FILE, return(NULL));
|
||||||
|
|
||||||
return(pkg->origin_data.db);
|
return(pkg->origin_data.db);
|
||||||
}
|
}
|
||||||
|
@ -441,49 +299,7 @@ pmdb_t SYMEXPORT *alpm_pkg_get_db(pmpkg_t *pkg)
|
||||||
*/
|
*/
|
||||||
void SYMEXPORT *alpm_pkg_changelog_open(pmpkg_t *pkg)
|
void SYMEXPORT *alpm_pkg_changelog_open(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
return pkg->ops->changelog_open(pkg);
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
ASSERT(handle != NULL, return(NULL));
|
|
||||||
ASSERT(pkg != NULL, return(NULL));
|
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE) {
|
|
||||||
char clfile[PATH_MAX];
|
|
||||||
snprintf(clfile, PATH_MAX, "%s/%s/%s-%s/changelog",
|
|
||||||
alpm_option_get_dbpath(),
|
|
||||||
alpm_db_get_name(handle->db_local),
|
|
||||||
alpm_pkg_get_name(pkg),
|
|
||||||
alpm_pkg_get_version(pkg));
|
|
||||||
return fopen(clfile, "r");
|
|
||||||
} else if(pkg->origin == PKG_FROM_FILE) {
|
|
||||||
struct archive *archive = NULL;
|
|
||||||
struct archive_entry *entry;
|
|
||||||
const char *pkgfile = pkg->origin_data.file;
|
|
||||||
|
|
||||||
if((archive = archive_read_new()) == NULL) {
|
|
||||||
RET_ERR(PM_ERR_LIBARCHIVE, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
archive_read_support_compression_all(archive);
|
|
||||||
archive_read_support_format_all(archive);
|
|
||||||
|
|
||||||
if (archive_read_open_filename(archive, pkgfile,
|
|
||||||
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
|
|
||||||
RET_ERR(PM_ERR_PKG_OPEN, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
|
|
||||||
const char *entry_name = archive_entry_pathname(entry);
|
|
||||||
|
|
||||||
if(strcmp(entry_name, ".CHANGELOG") == 0) {
|
|
||||||
return(archive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* we didn't find a changelog */
|
|
||||||
archive_read_finish(archive);
|
|
||||||
errno = ENOENT;
|
|
||||||
}
|
|
||||||
return(NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -501,33 +317,13 @@ void SYMEXPORT *alpm_pkg_changelog_open(pmpkg_t *pkg)
|
||||||
size_t SYMEXPORT alpm_pkg_changelog_read(void *ptr, size_t size,
|
size_t SYMEXPORT alpm_pkg_changelog_read(void *ptr, size_t size,
|
||||||
const pmpkg_t *pkg, const void *fp)
|
const pmpkg_t *pkg, const void *fp)
|
||||||
{
|
{
|
||||||
size_t ret = 0;
|
return pkg->ops->changelog_read(ptr, size, pkg, fp);
|
||||||
if(pkg->origin == PKG_FROM_CACHE) {
|
|
||||||
ret = fread(ptr, 1, size, (FILE*)fp);
|
|
||||||
} else if(pkg->origin == PKG_FROM_FILE) {
|
|
||||||
ssize_t sret = archive_read_data((struct archive*)fp, ptr, size);
|
|
||||||
/* Report error (negative values) */
|
|
||||||
if(sret < 0) {
|
|
||||||
pm_errno = PM_ERR_LIBARCHIVE;
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
ret = (size_t)sret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
int SYMEXPORT alpm_pkg_changelog_feof(const pmpkg_t *pkg, void *fp)
|
int SYMEXPORT alpm_pkg_changelog_feof(const pmpkg_t *pkg, void *fp)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
return pkg->ops->changelog_feof(pkg, fp);
|
||||||
if(pkg->origin == PKG_FROM_CACHE) {
|
|
||||||
ret = feof((FILE*)fp);
|
|
||||||
} else if(pkg->origin == PKG_FROM_FILE) {
|
|
||||||
// note: this doesn't quite work, no feof in libarchive
|
|
||||||
ret = archive_read_data((struct archive*)fp, NULL, 0);
|
|
||||||
}
|
|
||||||
return(ret);
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -541,13 +337,7 @@ int SYMEXPORT alpm_pkg_changelog_feof(const pmpkg_t *pkg, void *fp)
|
||||||
*/
|
*/
|
||||||
int SYMEXPORT alpm_pkg_changelog_close(const pmpkg_t *pkg, void *fp)
|
int SYMEXPORT alpm_pkg_changelog_close(const pmpkg_t *pkg, void *fp)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
return pkg->ops->changelog_close(pkg, fp);
|
||||||
if(pkg->origin == PKG_FROM_CACHE) {
|
|
||||||
ret = fclose((FILE*)fp);
|
|
||||||
} else if(pkg->origin == PKG_FROM_FILE) {
|
|
||||||
ret = archive_read_finish((struct archive *)fp);
|
|
||||||
}
|
|
||||||
return(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SYMEXPORT alpm_pkg_has_scriptlet(pmpkg_t *pkg)
|
int SYMEXPORT alpm_pkg_has_scriptlet(pmpkg_t *pkg)
|
||||||
|
@ -558,9 +348,9 @@ int SYMEXPORT alpm_pkg_has_scriptlet(pmpkg_t *pkg)
|
||||||
ASSERT(handle != NULL, return(-1));
|
ASSERT(handle != NULL, return(-1));
|
||||||
ASSERT(pkg != NULL, return(-1));
|
ASSERT(pkg != NULL, return(-1));
|
||||||
|
|
||||||
if(pkg->origin == PKG_FROM_CACHE && pkg->origin_data.db == handle->db_local
|
if(pkg->origin == PKG_FROM_LOCALDB
|
||||||
&& !(pkg->infolevel & INFRQ_SCRIPTLET)) {
|
&& !(pkg->infolevel & INFRQ_SCRIPTLET)) {
|
||||||
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_SCRIPTLET);
|
_alpm_local_db_read(pkg->origin_data.db, pkg, INFRQ_SCRIPTLET);
|
||||||
}
|
}
|
||||||
return pkg->scriptlet;
|
return pkg->scriptlet;
|
||||||
}
|
}
|
||||||
|
@ -667,6 +457,7 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)
|
||||||
|
|
||||||
/* internal */
|
/* internal */
|
||||||
newpkg->origin = pkg->origin;
|
newpkg->origin = pkg->origin;
|
||||||
|
newpkg->ops = pkg->ops;
|
||||||
if(newpkg->origin == PKG_FROM_FILE) {
|
if(newpkg->origin == PKG_FROM_FILE) {
|
||||||
newpkg->origin_data.file = strdup(pkg->origin_data.file);
|
newpkg->origin_data.file = strdup(pkg->origin_data.file);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -31,10 +31,65 @@
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
|
|
||||||
typedef enum _pmpkgfrom_t {
|
typedef enum _pmpkgfrom_t {
|
||||||
PKG_FROM_CACHE = 1,
|
PKG_FROM_FILE = 1,
|
||||||
PKG_FROM_FILE
|
PKG_FROM_LOCALDB,
|
||||||
|
PKG_FROM_SYNCDB
|
||||||
} pmpkgfrom_t;
|
} pmpkgfrom_t;
|
||||||
|
|
||||||
|
/** Package operations struct. This struct contains function pointers to
|
||||||
|
* all methods used to access data in a package to allow for things such
|
||||||
|
* as lazy package intialization (such as used by the file backend). Each
|
||||||
|
* backend is free to define a stuct containing pointers to a specific
|
||||||
|
* implementation of these methods. Some backends may find using the
|
||||||
|
* defined default_pkg_ops struct to work just fine for their needs.
|
||||||
|
*/
|
||||||
|
struct pkg_operations {
|
||||||
|
const char *(*get_filename) (pmpkg_t *);
|
||||||
|
const char *(*get_name) (pmpkg_t *);
|
||||||
|
const char *(*get_version) (pmpkg_t *);
|
||||||
|
const char *(*get_desc) (pmpkg_t *);
|
||||||
|
const char *(*get_url) (pmpkg_t *);
|
||||||
|
time_t (*get_builddate) (pmpkg_t *);
|
||||||
|
time_t (*get_installdate) (pmpkg_t *);
|
||||||
|
const char *(*get_packager) (pmpkg_t *);
|
||||||
|
const char *(*get_md5sum) (pmpkg_t *);
|
||||||
|
const char *(*get_arch) (pmpkg_t *);
|
||||||
|
off_t (*get_size) (pmpkg_t *);
|
||||||
|
off_t (*get_isize) (pmpkg_t *);
|
||||||
|
pmpkgreason_t (*get_reason) (pmpkg_t *);
|
||||||
|
int (*has_force) (pmpkg_t *);
|
||||||
|
|
||||||
|
alpm_list_t *(*get_licenses) (pmpkg_t *);
|
||||||
|
alpm_list_t *(*get_groups) (pmpkg_t *);
|
||||||
|
alpm_list_t *(*get_depends) (pmpkg_t *);
|
||||||
|
alpm_list_t *(*get_optdepends) (pmpkg_t *);
|
||||||
|
alpm_list_t *(*get_conflicts) (pmpkg_t *);
|
||||||
|
alpm_list_t *(*get_provides) (pmpkg_t *);
|
||||||
|
alpm_list_t *(*get_replaces) (pmpkg_t *);
|
||||||
|
alpm_list_t *(*get_deltas) (pmpkg_t *);
|
||||||
|
alpm_list_t *(*get_files) (pmpkg_t *);
|
||||||
|
alpm_list_t *(*get_backup) (pmpkg_t *);
|
||||||
|
|
||||||
|
void *(*changelog_open) (pmpkg_t *);
|
||||||
|
size_t (*changelog_read) (void *, size_t, const pmpkg_t *, const void *);
|
||||||
|
int (*changelog_close) (const pmpkg_t *, void *);
|
||||||
|
|
||||||
|
/* still to add:
|
||||||
|
* free()
|
||||||
|
* dup()
|
||||||
|
* checkmd5sum() ?
|
||||||
|
* has_scriptlet()
|
||||||
|
* compute_requiredby()
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/** The standard package operations struct. get fields directly from the
|
||||||
|
* struct itself with no abstraction layer or any type of lazy loading.
|
||||||
|
* The actual definition is in package.c so it can have access to the
|
||||||
|
* default accessor functions which are defined there.
|
||||||
|
*/
|
||||||
|
extern struct pkg_operations default_pkg_ops;
|
||||||
|
|
||||||
struct __pmpkg_t {
|
struct __pmpkg_t {
|
||||||
char *filename;
|
char *filename;
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -67,14 +122,16 @@ struct __pmpkg_t {
|
||||||
/* internal */
|
/* internal */
|
||||||
pmpkgfrom_t origin;
|
pmpkgfrom_t origin;
|
||||||
/* Replaced 'void *data' with this union as follows:
|
/* Replaced 'void *data' with this union as follows:
|
||||||
origin == PKG_FROM_CACHE, use pkg->origin_data.db
|
|
||||||
origin == PKG_FROM_FILE, use pkg->origin_data.file
|
origin == PKG_FROM_FILE, use pkg->origin_data.file
|
||||||
|
origin == PKG_FROM_*DB, use pkg->origin_data.db
|
||||||
*/
|
*/
|
||||||
union {
|
union {
|
||||||
pmdb_t *db;
|
pmdb_t *db;
|
||||||
char *file;
|
char *file;
|
||||||
} origin_data;
|
} origin_data;
|
||||||
pmdbinfrq_t infolevel;
|
pmdbinfrq_t infolevel;
|
||||||
|
|
||||||
|
struct pkg_operations *ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
pmpkg_t* _alpm_pkg_new(void);
|
pmpkg_t* _alpm_pkg_new(void);
|
||||||
|
|
|
@ -6,8 +6,9 @@ lib/libalpm/add.c
|
||||||
lib/libalpm/alpm.c
|
lib/libalpm/alpm.c
|
||||||
#lib/libalpm/alpm_list.c
|
#lib/libalpm/alpm_list.c
|
||||||
lib/libalpm/backup.c
|
lib/libalpm/backup.c
|
||||||
lib/libalpm/be_files.c
|
lib/libalpm/be_local.c
|
||||||
lib/libalpm/be_package.c
|
lib/libalpm/be_package.c
|
||||||
|
lib/libalpm/be_sync.c
|
||||||
lib/libalpm/cache.c
|
lib/libalpm/cache.c
|
||||||
lib/libalpm/conflict.c
|
lib/libalpm/conflict.c
|
||||||
lib/libalpm/db.c
|
lib/libalpm/db.c
|
||||||
|
|
|
@ -42,7 +42,6 @@
|
||||||
#include "backup.h"
|
#include "backup.h"
|
||||||
#include "package.h"
|
#include "package.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "cache.h"
|
|
||||||
#include "deps.h"
|
#include "deps.h"
|
||||||
#include "handle.h"
|
#include "handle.h"
|
||||||
#include "alpm.h"
|
#include "alpm.h"
|
||||||
|
@ -348,7 +347,7 @@ int _alpm_upgraderemove_package(pmpkg_t *oldpkg, pmpkg_t *newpkg, pmtrans_t *tra
|
||||||
/* remove the package from the database */
|
/* remove the package from the database */
|
||||||
_alpm_log(PM_LOG_DEBUG, "updating database\n");
|
_alpm_log(PM_LOG_DEBUG, "updating database\n");
|
||||||
_alpm_log(PM_LOG_DEBUG, "removing database entry '%s'\n", pkgname);
|
_alpm_log(PM_LOG_DEBUG, "removing database entry '%s'\n", pkgname);
|
||||||
if(_alpm_db_remove(handle->db_local, oldpkg) == -1) {
|
if(_alpm_local_db_remove(handle->db_local, oldpkg) == -1) {
|
||||||
_alpm_log(PM_LOG_ERROR, _("could not remove database entry %s-%s\n"),
|
_alpm_log(PM_LOG_ERROR, _("could not remove database entry %s-%s\n"),
|
||||||
pkgname, alpm_pkg_get_version(oldpkg));
|
pkgname, alpm_pkg_get_version(oldpkg));
|
||||||
}
|
}
|
||||||
|
@ -443,7 +442,7 @@ int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db)
|
||||||
/* remove the package from the database */
|
/* remove the package from the database */
|
||||||
_alpm_log(PM_LOG_DEBUG, "updating database\n");
|
_alpm_log(PM_LOG_DEBUG, "updating database\n");
|
||||||
_alpm_log(PM_LOG_DEBUG, "removing database entry '%s'\n", pkgname);
|
_alpm_log(PM_LOG_DEBUG, "removing database entry '%s'\n", pkgname);
|
||||||
if(_alpm_db_remove(db, info) == -1) {
|
if(_alpm_local_db_remove(db, info) == -1) {
|
||||||
_alpm_log(PM_LOG_ERROR, _("could not remove database entry %s-%s\n"),
|
_alpm_log(PM_LOG_ERROR, _("could not remove database entry %s-%s\n"),
|
||||||
pkgname, alpm_pkg_get_version(info));
|
pkgname, alpm_pkg_get_version(info));
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "package.h"
|
#include "package.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "cache.h"
|
|
||||||
#include "deps.h"
|
#include "deps.h"
|
||||||
#include "conflict.h"
|
#include "conflict.h"
|
||||||
#include "trans.h"
|
#include "trans.h"
|
||||||
|
@ -832,7 +831,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
|
||||||
for(j = trans->add; j; j = j->next) {
|
for(j = trans->add; j; j = j->next) {
|
||||||
pmpkg_t *spkg = j->data;
|
pmpkg_t *spkg = j->data;
|
||||||
|
|
||||||
if(spkg->origin == PKG_FROM_CACHE && current == spkg->origin_data.db) {
|
if(spkg->origin != PKG_FROM_FILE && current == spkg->origin_data.db) {
|
||||||
const char *fname = NULL;
|
const char *fname = NULL;
|
||||||
|
|
||||||
fname = alpm_pkg_get_filename(spkg);
|
fname = alpm_pkg_get_filename(spkg);
|
||||||
|
|
|
@ -44,7 +44,6 @@
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "alpm.h"
|
#include "alpm.h"
|
||||||
#include "deps.h"
|
#include "deps.h"
|
||||||
#include "cache.h"
|
|
||||||
|
|
||||||
/** \addtogroup alpm_trans Transaction Functions
|
/** \addtogroup alpm_trans Transaction Functions
|
||||||
* @brief Functions to manipulate libalpm transactions
|
* @brief Functions to manipulate libalpm transactions
|
||||||
|
|
|
@ -800,4 +800,49 @@ char *_alpm_archive_fgets(char *line, size_t size, struct archive *a)
|
||||||
return(line);
|
return(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _alpm_splitname(const char *target, pmpkg_t *pkg)
|
||||||
|
{
|
||||||
|
/* the format of a db entry is as follows:
|
||||||
|
* package-version-rel/
|
||||||
|
* package name can contain hyphens, so parse from the back- go back
|
||||||
|
* two hyphens and we have split the version from the name.
|
||||||
|
*/
|
||||||
|
char *tmp, *p, *q;
|
||||||
|
|
||||||
|
if(target == NULL || pkg == NULL) {
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
STRDUP(tmp, target, RET_ERR(PM_ERR_MEMORY, -1));
|
||||||
|
p = tmp + strlen(tmp);
|
||||||
|
|
||||||
|
/* remove any trailing '/' */
|
||||||
|
while (*(p - 1) == '/') {
|
||||||
|
--p;
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do the magic parsing- find the beginning of the version string
|
||||||
|
* by doing two iterations of same loop to lop off two hyphens */
|
||||||
|
for(q = --p; *q && *q != '-'; q--);
|
||||||
|
for(p = --q; *p && *p != '-'; p--);
|
||||||
|
if(*p != '-' || p == tmp) {
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy into fields and return */
|
||||||
|
if(pkg->version) {
|
||||||
|
FREE(pkg->version);
|
||||||
|
}
|
||||||
|
STRDUP(pkg->version, p+1, RET_ERR(PM_ERR_MEMORY, -1));
|
||||||
|
/* insert a terminator at the end of the name (on hyphen)- then copy it */
|
||||||
|
*p = '\0';
|
||||||
|
if(pkg->name) {
|
||||||
|
FREE(pkg->name);
|
||||||
|
}
|
||||||
|
STRDUP(pkg->name, tmp, RET_ERR(PM_ERR_MEMORY, -1));
|
||||||
|
|
||||||
|
free(tmp);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
/* vim: set ts=2 sw=2 noet: */
|
/* vim: set ts=2 sw=2 noet: */
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "alpm_list.h"
|
#include "alpm_list.h"
|
||||||
|
#include "package.h" /* pmpkg_t */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -76,6 +77,7 @@ const char *_alpm_filecache_setup(void);
|
||||||
int _alpm_lstat(const char *path, struct stat *buf);
|
int _alpm_lstat(const char *path, struct stat *buf);
|
||||||
int _alpm_test_md5sum(const char *filepath, const char *md5sum);
|
int _alpm_test_md5sum(const char *filepath, const char *md5sum);
|
||||||
char *_alpm_archive_fgets(char *line, size_t size, struct archive *a);
|
char *_alpm_archive_fgets(char *line, size_t size, struct archive *a);
|
||||||
|
int _alpm_splitname(const char *target, pmpkg_t *pkg);
|
||||||
|
|
||||||
#ifndef HAVE_STRSEP
|
#ifndef HAVE_STRSEP
|
||||||
char *strsep(char **, const char *);
|
char *strsep(char **, const char *);
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
extern pmdb_t *db_local;
|
extern pmdb_t *db_local;
|
||||||
|
|
||||||
/* if keep_used != 0, then the dirnames which match an used syncdb
|
/* if keep_used != 0, then the db files which match an used syncdb
|
||||||
* will be kept */
|
* will be kept */
|
||||||
static int sync_cleandb(const char *dbpath, int keep_used) {
|
static int sync_cleandb(const char *dbpath, int keep_used) {
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
|
@ -59,6 +59,7 @@ static int sync_cleandb(const char *dbpath, int keep_used) {
|
||||||
alpm_list_t *syncdbs = NULL, *i;
|
alpm_list_t *syncdbs = NULL, *i;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
const char *dname = ent->d_name;
|
const char *dname = ent->d_name;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
if(strcmp(dname, ".") == 0 || strcmp(dname, "..") == 0) {
|
if(strcmp(dname, ".") == 0 || strcmp(dname, "..") == 0) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -67,23 +68,38 @@ static int sync_cleandb(const char *dbpath, int keep_used) {
|
||||||
if(strcmp(dname, "sync") == 0 || strcmp(dname, "local") == 0) {
|
if(strcmp(dname, "sync") == 0 || strcmp(dname, "local") == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/* skip the db.lck file */
|
||||||
|
if(strcmp(dname, "db.lck") == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* build the full path */
|
/* build the full path */
|
||||||
snprintf(path, PATH_MAX, "%s%s", dbpath, dname);
|
snprintf(path, PATH_MAX, "%s%s", dbpath, dname);
|
||||||
/* skip entries that are not dirs (lock file, etc.) */
|
|
||||||
|
/* remove all non-skipped directories and non-database files */
|
||||||
stat(path, &buf);
|
stat(path, &buf);
|
||||||
if(!S_ISDIR(buf.st_mode)) {
|
len = strlen(path);
|
||||||
|
if(S_ISDIR(buf.st_mode) || strcmp(path+(len-3),".db") != 0) {
|
||||||
|
if(rmrf(path)) {
|
||||||
|
pm_fprintf(stderr, PM_LOG_ERROR,
|
||||||
|
_("could not remove %s\n"), path);
|
||||||
|
closedir(dir);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(keep_used) {
|
if(keep_used) {
|
||||||
|
len = strlen(dname);
|
||||||
|
char *dbname = strndup(dname, len-3);
|
||||||
syncdbs = alpm_option_get_syncdbs();
|
syncdbs = alpm_option_get_syncdbs();
|
||||||
for(i = syncdbs; i && !found; i = alpm_list_next(i)) {
|
for(i = syncdbs; i && !found; i = alpm_list_next(i)) {
|
||||||
pmdb_t *db = alpm_list_getdata(i);
|
pmdb_t *db = alpm_list_getdata(i);
|
||||||
found = !strcmp(dname, alpm_db_get_name(db));
|
found = !strcmp(dbname, alpm_db_get_name(db));
|
||||||
}
|
}
|
||||||
|
free(dbname);
|
||||||
}
|
}
|
||||||
/* We have a directory that doesn't match any syncdb.
|
/* We have a database that doesn't match any syncdb.
|
||||||
* Ask the user if he wants to remove it. */
|
* Ask the user if he wants to remove it. */
|
||||||
if(!found) {
|
if(!found) {
|
||||||
if(!yesno(_("Do you want to remove %s?"), path)) {
|
if(!yesno(_("Do you want to remove %s?"), path)) {
|
||||||
|
@ -92,7 +108,7 @@ static int sync_cleandb(const char *dbpath, int keep_used) {
|
||||||
|
|
||||||
if(rmrf(path)) {
|
if(rmrf(path)) {
|
||||||
pm_fprintf(stderr, PM_LOG_ERROR,
|
pm_fprintf(stderr, PM_LOG_ERROR,
|
||||||
_("could not remove repository directory\n"));
|
_("could not remove %s\n"), path);
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
@ -113,8 +129,8 @@ static int sync_cleandb_all(void) {
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
/* The sync dbs were previously put in dbpath/, but are now in dbpath/sync/,
|
/* The sync dbs were previously put in dbpath/, but are now in dbpath/sync/,
|
||||||
* so we will clean everything in dbpath/ (except dbpath/local/ and dbpath/sync/,
|
* so we will clean everything in dbpath/ (except dbpath/local/ and dbpath/sync/
|
||||||
* and only the unused sync dbs in dbpath/sync/ */
|
* and db.lck) and only the unused sync dbs in dbpath/sync/ */
|
||||||
ret += sync_cleandb(dbpath, 0);
|
ret += sync_cleandb(dbpath, 0);
|
||||||
|
|
||||||
sprintf(newdbpath, "%s%s", dbpath, "sync/");
|
sprintf(newdbpath, "%s%s", dbpath, "sync/");
|
||||||
|
|
Loading…
Add table
Reference in a new issue