Browse Source

msk: allow for and properly merge multiple remote manifests

K. Lange 2 years ago
parent
commit
72aaed2eef
5 changed files with 134 additions and 45 deletions
  1. 22 19
      apps/glogin-provider.c
  2. 57 17
      apps/msk.c
  3. 3 1
      base/etc/msk.conf
  4. 8 6
      base/usr/include/toaru/confreader.h
  5. 44 2
      lib/confreader.c

+ 22 - 19
apps/glogin-provider.c

@@ -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);
-
-		WALLPAPER = confreader_getd(conf, "image", "wallpaper", WALLPAPER);
-		LOGO = confreader_getd(conf, "image", "logo", LOGO);
-
-		confreader_free(conf);
+		if (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);
+
+			WALLPAPER = confreader_getd(conf, "image", "wallpaper", WALLPAPER);
+			LOGO = confreader_getd(conf, "image", "logo", LOGO);
+
+			confreader_free(conf);
+		}
 
 		TRACE("Loading complete");
 	}

+ 57 - 17
apps/msk.c

@@ -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");

+ 3 - 1
base/etc/msk.conf

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

+ 8 - 6
base/usr/include/toaru/confreader.h

@@ -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

+ 44 - 2
lib/confreader.c

@@ -24,14 +24,56 @@ static void free_hashmap(void * h) {
 	free(h);
 }
 
-confreader_t * confreader_load(const char * file) {
+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;
+}
 
-	confreader_t * out = malloc(sizeof(confreader_t));
+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) {
 
 	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;