Commit b0226691 authored by Steven Arnow's avatar Steven Arnow

Started adding dependency checking in libdbpmgr

parent 09492d8b
......@@ -87,11 +87,11 @@ static void vtab_method_call(GDBusConnection *conn, const gchar *sender, const g
pthread_mutex_lock(&p->mutex);
for (i = 0; i < p->entries; i++) {
g_variant_builder_add(builder, "(sss)", p->entry[i].path, p->entry[i].id, p->entry[i].desktop);
g_variant_builder_add(builder, "(ssss)", p->entry[i].path, p->entry[i].id, p->entry[i].desktop, p->entry[i].version);
}
if (!p->entries) {
g_variant_builder_add(builder, "(sss)", "/dev/null", "!", "nodesk");
g_variant_builder_add(builder, "(ssss)", "/dev/null", "!", "nodesk", "");
}
pthread_mutex_unlock(&p->mutex);
......
......@@ -73,7 +73,7 @@ static int package_id_validate(const char *pkg_id) {
}
static int package_add(struct package_s *p, char *path, char *id, char *device, char *mount, char *appdata, char *sys, char *pkg) {
static int package_add(struct package_s *p, char *path, char *id, char *device, char *mount, char *appdata, char *sys, char *pkg, char *version) {
int nid, i, errid;
for (i = 0; i < p->entries; i++) {
......@@ -96,6 +96,7 @@ static int package_add(struct package_s *p, char *path, char *id, char *device,
p->entry[nid].appdata = appdata;
p->entry[nid].sys_dep = sys;
p->entry[nid].pkg_dep = pkg;
p->entry[nid].version = version;
p->entry[nid].desktop = strdup(dbp_loop_desktop_directory(path) ? "desk" : "nodesk");
p->entry[nid].exec = NULL, p->entry[nid].execs = 0;
comm_dbus_announce_new_package(id);
......@@ -319,7 +320,7 @@ static void package_meta_extract(const char *path, struct package_s *p, int id,
static int package_register(struct package_s *p, const char *path, const char *device, const char *mount, int *coll_id) {
struct DBPMetaPackage mp;
char *pkg_id = "none", *appdata, *sys, *pkg;
char *pkg_id = "none", *appdata, *sys, *pkg, *version = NULL;
int id, errid;
*coll_id = -1;
......@@ -338,8 +339,10 @@ static int package_register(struct package_s *p, const char *path, const char *d
sys = "";
if (!(pkg = dbp_desktop_lookup(mp.df, "PkgDependency", "", mp.section)))
pkg = "";
if (!(version = dbp_desktop_lookup(mp.df, "Version", "", mp.section)))
version = "";
if ((id = package_add(p, strdup(path), strdup(pkg_id), strdup(device), strdup(mount), strdup(appdata), strdup(sys), strdup(pkg))) < 0) {
if ((id = package_add(p, strdup(path), strdup(pkg_id), strdup(device), strdup(mount), strdup(appdata), strdup(sys), strdup(pkg), strdup(version))) < 0) {
*coll_id = package_id_lookup(p, pkg_id);
errid = id;
pkg_id = NULL;
......@@ -483,6 +486,7 @@ static void package_kill(struct package_s *p, int entry) {
free(p->entry[entry].sys_dep);
free(p->entry[entry].pkg_dep);
free(p->entry[entry].desktop);
free(p->entry[entry].version);
p->entries--;
memmove(&p->entry[entry], &p->entry[entry + 1], (p->entries - entry) * sizeof(*p->entry));
return;
......
......@@ -19,6 +19,9 @@ struct package_entry_s {
char *mount;
char *appdata;
/* Daemon does not check version, but includes it in package list */
char *version;
/* Dependencies are only stored for later relay to client *
** Daemon does not do any dep-checking itself */
char *sys_dep;
......
......@@ -131,17 +131,18 @@ int dbpmgr_server_path_from_id(const char *pkg_id, char **path) {
struct DBPList *dbpmgr_server_package_list() {
GVariantIter *iter;
char *path, *id, *desktop;
char *path, *id, *desktop, version;
struct DBPList *prev = NULL, *this = NULL;
SEND_MESSAGE("PackageList", NULL, NULL);
(void) reti;
g_variant_get(ret, "(a(sss))", &iter);
while (g_variant_iter_loop(iter, "(sss)", &path, &id, &desktop)) {
while (g_variant_iter_loop(iter, "(ssss)", &path, &id, &desktop, &version)) {
if (!strcmp(id, "!"))
continue;
this = malloc(sizeof(*this));
this->path = strdup(path);
this->id = strdup(id);
this->version = strdup(id);
this->on_desktop = !strcmp(desktop, "desk");
this->next = prev;
prev = this;
......@@ -156,6 +157,7 @@ struct DBPList *dbpmgr_server_package_list() {
void dbpmgr_server_package_list_free_one(struct DBPList *list) {
free(list->path);
free(list->id);
free(list->version);
free(list);
}
......
......@@ -29,6 +29,7 @@ freely, subject to the following restrictions:
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <dbpbase/dbpbase.h>
#include "types.h"
......@@ -133,7 +134,7 @@ static int compare_substring(char *s1, char *s2) {
return -1;
if (s2[i] == '~')
return 1;
/* TODO: Find out if this is supposed to be case insensitive or not... */
if (!isalpha(s1[i])) {
if (!isalpha(s2[i]))
return s1[i] < s2[i] ? -1 : 1;
......@@ -359,36 +360,33 @@ static void free_node(struct DBPDependDPackageNode *node) {
free(node);
}
static void dbpmgr_depend_init() {
static void dbpmgr_depend_debian_init() {
if (debian_root)
return;
init_conv_table();
debian_root = build_database();
}
void dbpmgr_depend_free() {
free_node(debian_root), debian_root = NULL;
}
void dbpmgr_depend_arch_set(const char *arch) {
free(default_arch), default_arch = strdup(arch);
}
static struct DBPDependDPackage *debian_find_list(const char *pkg_name, struct DBPDependDPackageNode *node, int name_index) {
static struct DBPDependDPackage *find_list(const char *pkg_name, struct DBPDependDPackageNode *node, int name_index) {
if (!node)
return NULL;
if (!pkg_name[name_index])
return node->match;
if (!node->lookup)
return node->list;
return debian_find_list(pkg_name, node->lookup[TREE_LOOKUP(pkg_name[name_index])], name_index + 1);
return find_list(pkg_name, node->lookup[TREE_LOOKUP(pkg_name[name_index])], name_index + 1);
}
struct DBPDependDPackage *dbpmgr_depend_debian_next(const char *pkg_name, struct DBPDependDPackage *prev) {
dbpmgr_depend_init();
dbpmgr_depend_debian_init();
if (!prev)
prev = debian_find_list(pkg_name, debian_root, 0);
prev = find_list(pkg_name, debian_root, 0);
else
prev = prev->next;
for (; prev; prev = prev->next)
......@@ -398,6 +396,15 @@ struct DBPDependDPackage *dbpmgr_depend_debian_next(const char *pkg_name, struct
}
void dbpmgr_depend_free(struct DBPDepend *dep) {
free(dep->version);
free(dep->pkg_name);
free(dep->arch);
free(dep);
return;
}
bool dbpmgr_depend_debian_check(const char *package_string) {
int i, ver_match;
struct DBPDepend *dep;
......@@ -427,3 +434,147 @@ bool dbpmgr_depend_debian_check(const char *package_string) {
return false;
}
static struct DBPDependDPackageNode *dbp_root = NULL;
struct DBPList *dbpmgr_server_package_list();
void dbpmgr_server_package_list_free(struct DBPList *list);
static void build_dbp_database() {
struct DBPList *list, *next;
struct DBPDependDPackage *this = NULL;
if (!(list = dbpmgr_server_package_list()))
return;
for (next = list; next; next = next->next) {
this = calloc(sizeof(*this), 1);
this->version = strdup(this->version);
this->name = strdup(this->name);
dbp_root = package_tree_populate(dbp_root, this, 0);
}
dbpmgr_server_package_list_free(list);
return;
}
void dbpmgr_depend_dbp_init() {
if (!dbp_root)
build_dbp_database();
}
struct DBPDependDPackage *dbpmgr_depend_dbp_next(const char *pkg_name, struct DBPDependDPackage *prev) {
dbpmgr_depend_dbp_init();
if (!prev)
prev = find_list(pkg_name, dbp_root, 0);
else
prev = prev->next;
for (; prev; prev = prev->next)
if (!strcmp(prev->name, pkg_name))
return prev;
return NULL;
}
bool dbpmgr_depend_dbp_check(const char *package_string) {
struct DBPDepend *dep;
struct DBPDependDPackage *pkg;
int i, ver_match;
dep = dbpmgr_depend_parse(package_string);
for (pkg = dbpmgr_depend_dbp_next(dep->pkg_name, NULL); pkg; pkg = dbpmgr_depend_dbp_next(dep->pkg_name, pkg)) {
for (i = 0; i < DBPMGR_DEPEND_VERSION_CHECKS; i++) {
if (!dep->version[i])
continue;
ver_match = dbpmgr_depend_compare_version(pkg->version, dep->version[i]);
if (!dbpmgr_depend_version_result_compare(ver_match, i))
return dbpmgr_depend_free(dep), false;
}
dbpmgr_depend_free(dep);
return true;
}
dbpmgr_depend_free(dep);
return false;
}
static struct DBPDependList create_list(const char *str) {
struct DBPDependList list;
char *new;
list.depend = NULL, list.depends = 0;
if (!str)
return list;
new = strdup(str);
dbp_config_expand_token(&list.depend, &list.depends, new);
free(new);
return list;
}
static void addto_list(struct DBPDependList *list, const char *str) {
int id = list->depends++;
list->depend = realloc(list->depend, sizeof(*list->depend) * list->depends);
list->depend[id] = strdup(str);
return;
}
void dbpmgr_depend_delete_list(struct DBPDependList *list) {
int i;
for (i = 0; i < list->depends; i++)
free(list->depend[i]);
free(list->depend);
}
void dbpmgr_depend_cleanup() {
free_node(debian_root), debian_root = NULL;
free_node(dbp_root), dbp_root = NULL;
}
struct DBPDependListList dbpmgr_depend_check(struct DBPDesktopFile *meta) {
char *sysonly, *dbponly, *prefsys, *prefdbp, *whatevs;
struct DBPDependListList list, missing;
int i;
sysonly = dbp_desktop_lookup(meta, "Dependency", "deb", "Package Entry");
dbponly = dbp_desktop_lookup(meta, "Dependency", "dbp", "Package Entry");
prefsys = dbp_desktop_lookup(meta, "Dependency", "pref_deb", "Package Entry");
prefdbp = dbp_desktop_lookup(meta, "Dependency", "pref_dbp", "Package Entry");
whatevs = dbp_desktop_lookup(meta, "Dependency", "", "Package Entry");
list.sysonly = create_list(sysonly);
list.dbponly = create_list(dbponly);
list.syspref = create_list(prefsys);
list.dbppref = create_list(prefdbp);
list.whatevs = create_list(whatevs);
memset(&missing, 0, sizeof(missing));
/* Det här luktar jommpakod... */
for (i = 0; i < list.sysonly.depends; i++)
if (!dbpmgr_depend_debian_check(list.sysonly.depend[i]))
addto_list(&missing.sysonly, list.sysonly.depend[i]);
for (i = 0; i < list.syspref.depends; i++)
if (!dbpmgr_depend_debian_check(list.syspref.depend[i]))
if (!dbpmgr_depend_dbp_check(list.syspref.depend[i]))
addto_list(&missing.syspref, list.syspref.depend[i]);
for (i = 0; i < list.dbponly.depends; i++)
if (!dbpmgr_depend_dbp_check(list.dbponly.depend[i]))
addto_list(&missing.dbponly, list.dbponly.depend[i]);
for (i = 0; i < list.dbppref.depends; i++)
if (!dbpmgr_depend_dbp_check(list.dbppref.depend[i]))
if (!dbpmgr_depend_debian_check(list.dbppref.depend[i]))
addto_list(&missing.dbppref, list.dbppref.depend[i]);
for (i = 0; i < list.whatevs.depends; i++)
if (!dbpmgr_depend_dbp_check(list.whatevs.depend[i]))
if (!dbpmgr_depend_debian_check(list.whatevs.depend[i]))
addto_list(&missing.whatevs, list.whatevs.depend[i]);
dbpmgr_depend_cleanup();
return list;
}
......@@ -25,6 +25,7 @@ freely, subject to the following restrictions:
#ifndef __DBPMGR_DEPENDENCIES_H__
#define __DBPMGR_DEPENDENCIES_H__
#include <dbpbase/dbpbase.h>
#include <dbpmgr/types.h>
#include <stdbool.h>
......@@ -32,10 +33,12 @@ bool dbpmgr_depend_debian_check(const char *package_string);
struct DBPDepend *dbpmgr_depend_parse(const char *package_string);
void dbpmgr_depend_free(struct DBPDepend *dep);
void dbpmgr_depend_version_result_compare(int result, enum DBPMgrDependVersionCheck check);
void dbpmgr_depend_cleanup();
struct DBPDependListList dbpmgr_depend_check(struct DBPDesktopFile *meta);
/* After doing package dependency checking, run free to unload databases */
void dbpmgr_depend_free();
void dbpmgr_depend_cleanup();
struct DBPDependDPackage *dbpmgr_depend_debian_next(const char *pkg_name, struct DBPDependDPackage *prev);
void dbpmgr_depend_delete_list(struct DBPDependList *list);
#endif
......@@ -18,6 +18,7 @@ struct DBPList {
struct DBPList *next;
char *id;
char *path;
char *version;
bool on_desktop;
};
......@@ -43,5 +44,18 @@ struct DBPDependDPackageNode {
int list_size;
};
struct DBPDependList {
char **depend;
int depends;
};
struct DBPDependListList {
struct DBPDependList sysonly;
struct DBPDependList dbponly;
struct DBPDependList syspref;
struct DBPDependList dbppref;
struct DBPDependList whatevs;
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment