msk: allow for and properly merge multiple remote manifests

This commit is contained in:
K. Lange 2018-11-12 09:26:30 +09:00
parent 17fca7a0d4
commit 72aaed2eef
5 changed files with 134 additions and 45 deletions

View File

@ -232,25 +232,28 @@ int main (int argc, char ** argv) {
{
confreader_t * conf = confreader_load("/etc/glogin.conf");
LOGO_FINAL_OFFSET = confreader_intd(conf, "style", "logo_padding", LOGO_FINAL_OFFSET);
BOX_WIDTH = confreader_intd(conf, "style", "box_width", BOX_WIDTH);
BOX_HEIGHT = confreader_intd(conf, "style", "box_height", BOX_HEIGHT);
BOX_ROUNDNESS = confreader_intd(conf, "style", "box_roundness", BOX_ROUNDNESS);
CENTER_BOX_X = confreader_intd(conf, "style", "center_box_x", CENTER_BOX_X);
CENTER_BOX_Y = confreader_intd(conf, "style", "center_box_y", CENTER_BOX_Y);
BOX_LEFT = confreader_intd(conf, "style", "box_left", BOX_LEFT);
BOX_RIGHT = confreader_intd(conf, "style", "box_right", BOX_RIGHT);
BOX_TOP = confreader_intd(conf, "style", "box_top", BOX_TOP);
BOX_BOTTOM = confreader_intd(conf, "style", "box_bottom", BOX_BOTTOM);
BOX_COLOR_R = confreader_intd(conf, "style", "box_color_r", BOX_COLOR_R);
BOX_COLOR_G = confreader_intd(conf, "style", "box_color_g", BOX_COLOR_G);
BOX_COLOR_B = confreader_intd(conf, "style", "box_color_b", BOX_COLOR_B);
BOX_COLOR_A = confreader_intd(conf, "style", "box_color_a", BOX_COLOR_A);
if (conf) {
WALLPAPER = confreader_getd(conf, "image", "wallpaper", WALLPAPER);
LOGO = confreader_getd(conf, "image", "logo", LOGO);
LOGO_FINAL_OFFSET = confreader_intd(conf, "style", "logo_padding", LOGO_FINAL_OFFSET);
BOX_WIDTH = confreader_intd(conf, "style", "box_width", BOX_WIDTH);
BOX_HEIGHT = confreader_intd(conf, "style", "box_height", BOX_HEIGHT);
BOX_ROUNDNESS = confreader_intd(conf, "style", "box_roundness", BOX_ROUNDNESS);
CENTER_BOX_X = confreader_intd(conf, "style", "center_box_x", CENTER_BOX_X);
CENTER_BOX_Y = confreader_intd(conf, "style", "center_box_y", CENTER_BOX_Y);
BOX_LEFT = confreader_intd(conf, "style", "box_left", BOX_LEFT);
BOX_RIGHT = confreader_intd(conf, "style", "box_right", BOX_RIGHT);
BOX_TOP = confreader_intd(conf, "style", "box_top", BOX_TOP);
BOX_BOTTOM = confreader_intd(conf, "style", "box_bottom", BOX_BOTTOM);
BOX_COLOR_R = confreader_intd(conf, "style", "box_color_r", BOX_COLOR_R);
BOX_COLOR_G = confreader_intd(conf, "style", "box_color_g", BOX_COLOR_G);
BOX_COLOR_B = confreader_intd(conf, "style", "box_color_b", BOX_COLOR_B);
BOX_COLOR_A = confreader_intd(conf, "style", "box_color_a", BOX_COLOR_A);
confreader_free(conf);
WALLPAPER = confreader_getd(conf, "image", "wallpaper", WALLPAPER);
LOGO = confreader_getd(conf, "image", "logo", LOGO);
confreader_free(conf);
}
TRACE("Loading complete");
}

View File

@ -27,7 +27,6 @@
static confreader_t * msk_config = NULL;
static confreader_t * msk_manifest = NULL;
static hashmap_t * msk_installed = NULL;
static char * msk_remote = NULL;
static int verbose = 0;
@ -40,7 +39,6 @@ static int verbose = 0;
* = 0 candidate is the same
* < 0 candidate is older
*/
#if 0
static int compare_version_strings(char * current, char * candidate) {
int current_x, current_y, current_z;
int candidate_x, candidate_y, candidate_z;
@ -60,7 +58,6 @@ static int compare_version_strings(char * current, char * candidate) {
return -1;
}
#endif
static void read_config(void) {
confreader_t * conf = confreader_load("/etc/msk.conf");
@ -73,8 +70,6 @@ static void read_config(void) {
verbose = 1;
}
msk_remote = confreader_get(conf, "", "remote");
msk_config = conf;
}
@ -153,20 +148,64 @@ static int update_stores(int argc, char * argv[]) {
read_config();
make_var();
if (!msk_remote) {
fprintf(stderr, "%s: no configured msk_remote\n", argv[0]);
return 1;
}
confreader_t * manifest_out = confreader_create_empty();
hashmap_t * remotes = hashmap_get(msk_config->sections, "remotes");
list_t * remote_list = hashmap_keys(remotes);
foreach(node, remote_list) {
char * remote_name = (char*)node->value;
char * remote_path = hashmap_get(remotes, remote_name);
confreader_t * manifest;
if (remote_path[0] == '/') {
char source[512];
sprintf(source, "%s/manifest", remote_path);
manifest = confreader_load(source);
if (!manifest) {
fprintf(stderr, "Skipping unavailable local manifest '%s'.\n", remote_name);
continue;
}
} else {
char cmd[512];
sprintf(cmd, "fetch -vo /tmp/.msk_remote_%s %s/manifest", remote_name, remote_path);
fprintf(stderr, "Downloading remote manifest '%s'...\n", remote_name);
if (system(cmd)) {
fprintf(stderr, "Error loading remote '%s' from '%s'.\n", remote_name, remote_path);
continue;
}
sprintf(cmd, "/tmp/.msk_remote_%s", remote_name);
manifest = confreader_load(cmd);
}
list_t * packages = hashmap_keys(manifest->sections);
foreach(nnode, packages) {
char * package_name = (char*)nnode->value;
hashmap_t * package_data = (hashmap_t*)hashmap_get(manifest->sections, package_name);
if (!strcmp(package_name,"")) continue; /* skip intro section - remote repo information */
hashmap_set(package_data, "remote_path", remote_path);
hashmap_set(package_data, "remote_name", remote_name);
if (!hashmap_has(manifest_out->sections, package_name)) {
/* Package not yet known */
hashmap_set(manifest_out->sections, package_name, package_data);
} else {
/* Package is known, keep the newer version */
char * old_version = confreader_get(manifest_out, package_name, "version");
char * new_version = confreader_get(manifest, package_name, "version");
if (compare_version_strings(old_version, new_version) > 0) {
hashmap_set(manifest_out->sections, package_name, package_data);
}
}
}
if (msk_remote[0] == '/') {
char cmd[512];
sprintf(cmd, "cp %s/manifest " VAR_PATH "/manifest", msk_remote);
return system(cmd);
} else {
char cmd[512];
sprintf(cmd, "fetch -vo " VAR_PATH "/manifest %s/manifest", msk_remote);
return system(cmd);
}
list_free(remote_list);
free(remote_list);
return confreader_write(manifest_out, VAR_PATH "/manifest");
}
static int list_contains(list_t * list, char * key) {
@ -207,6 +246,7 @@ static int process_package(list_t * pkgs, char * name) {
static int install_package(char * pkg) {
char * type = confreader_getd(msk_manifest, pkg, "type", "");
char * msk_remote = confreader_get(msk_manifest, pkg, "remote_path");
if (strstr(msk_remote, "http:") == msk_remote) {
char * source = confreader_get(msk_manifest, pkg, "source");

View File

@ -1 +1,3 @@
remote=/cdrom/extra
[remotes]
local=/cdrom/extra
remote=http://toaruos.org/msk/1.8.x

View File

@ -12,11 +12,13 @@ typedef struct {
hashmap_t * sections;
} confreader_t;
confreader_t * confreader_load(const char * file);
char * confreader_get(confreader_t * ctx, char * section, char * value);
char * confreader_getd(confreader_t * ctx, char * section, char * value, char * def);
int confreader_int(confreader_t * ctx, char * section, char * value);
int confreader_intd(confreader_t * ctx, char * section, char * value, int def);
void confreader_free(confreader_t * conf);
extern confreader_t * confreader_load(const char * file);
extern char * confreader_get(confreader_t * ctx, char * section, char * value);
extern char * confreader_getd(confreader_t * ctx, char * section, char * value, char * def);
extern int confreader_int(confreader_t * ctx, char * section, char * value);
extern int confreader_intd(confreader_t * ctx, char * section, char * value, int def);
extern void confreader_free(confreader_t * conf);
extern int confreader_write(confreader_t * config, const char * file);
extern confreader_t * confreader_create_empty(void);
_End_C_Header

View File

@ -24,14 +24,56 @@ static void free_hashmap(void * h) {
free(h);
}
static int write_section(FILE * f, hashmap_t * section) {
list_t * keys = hashmap_keys(section);
foreach(node, keys) {
char * key = (char*)node->value;
char * value = hashmap_get(section, key);
fprintf(f, "%s=%s\n", key, value);
}
list_free(keys);
free(keys);
return 0;
}
int confreader_write(confreader_t * config, const char * file) {
FILE * f = fopen(file, "w");
if (!f) return 1;
hashmap_t * base = hashmap_get(config->sections, "");
if (base) {
write_section(f, base);
}
list_t * sections = hashmap_keys(config->sections);
foreach(node, sections) {
char * section = (char*)node->value;
if (strcmp(section,"")) {
hashmap_t * data = hashmap_get(config->sections, section);
fprintf(f, "[%s]\n", section);
write_section(f, data);
}
}
return 0;
}
confreader_t * confreader_create_empty(void) {
confreader_t * out = malloc(sizeof(confreader_t));
out->sections = hashmap_create(10);
return out;
}
confreader_t * confreader_load(const char * file) {
confreader_t * out = malloc(sizeof(confreader_t));
out->sections = hashmap_create(10);
FILE * f = fopen(file, "r");
if (!f) return NULL;
confreader_t * out = confreader_create_empty();
hashmap_t * current_section = hashmap_create(10);
current_section->hash_val_free = free_hashmap;