diff --git a/Makefile b/Makefile index 38d9806a53753b6fe4724b2d71421c4623cf2a9f..b37a04c3f7842ed5579a46572cf6c73f40aa8cf9 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ PROG = swmodd OBJS = swmod.o swmod_host.o swmod_opkg.o swmod_uci.o tools.o PROG_CFLAGS = $(CFLAGS) -fstrict-aliasing -Wall -PROG_LDFLAGS = $(LDFLAGS) -luci -lubus -lubox -ljson-c -lblobmsg_json -luuid -lopkg +PROG_LDFLAGS = $(LDFLAGS) -luci -lubus -lubox -ljson-c -lblobmsg_json -luuid ifeq ($(SWMOD_LXC),yes) OBJS += swmod_lxc.o diff --git a/swmod.c b/swmod.c index 184bd89308998cd1a357914f7f9a3d20288bea26..cd8cb833aad3191e171e94a16298667da4e42404 100644 --- a/swmod.c +++ b/swmod.c @@ -39,18 +39,6 @@ ExecEnv environments[MAX_ENV] = {0}; ExecUnit exec_units[MAX_ENV] = {0}; -enum { - INSTALL_PATH, - INSTALL_ENV, - __INSTALL_MAX -}; - -enum { - REMOVE_NAME, - REMOVE_ENV, - __REMOVE_MAX -}; - enum { DU_INSTALL_URL, DU_INSTALL_UUID, @@ -63,7 +51,6 @@ enum { enum { DU_UPDATE_UUID, DU_UPDATE_URL, - DU_UPDATE_VERSION, DU_UPDATE_USERNAME, DU_UPDATE_PASSWORD, __DU_UPDATE_MAX @@ -75,16 +62,6 @@ enum { __DU_UNINSTALL_MAX }; -static const struct blobmsg_policy install_policy[__INSTALL_MAX] = { - [INSTALL_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, - [INSTALL_ENV] = { .name = "environment", .type = BLOBMSG_TYPE_STRING }, -}; - -static const struct blobmsg_policy remove_policy[__REMOVE_MAX] = { - [REMOVE_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, - [REMOVE_ENV] = { .name = "environment", .type = BLOBMSG_TYPE_STRING }, -}; - static const struct blobmsg_policy du_install_policy[__DU_INSTALL_MAX] = { [DU_INSTALL_URL] = { .name = "url", .type = BLOBMSG_TYPE_STRING }, [DU_INSTALL_UUID] = { .name = "uuid", .type = BLOBMSG_TYPE_STRING }, @@ -96,7 +73,6 @@ static const struct blobmsg_policy du_install_policy[__DU_INSTALL_MAX] = { static const struct blobmsg_policy du_update_policy[__DU_UPDATE_MAX] = { [DU_UPDATE_UUID] = { .name = "uuid", .type = BLOBMSG_TYPE_STRING }, [DU_UPDATE_URL] = { .name = "url", .type = BLOBMSG_TYPE_STRING }, - [DU_UPDATE_VERSION] = { .name = "version", .type = BLOBMSG_TYPE_STRING }, [DU_UPDATE_USERNAME] = { .name = "username", .type = BLOBMSG_TYPE_STRING }, [DU_UPDATE_PASSWORD] = { .name = "password", .type = BLOBMSG_TYPE_STRING }, }; @@ -162,104 +138,39 @@ swmod_environment(struct ubus_context *ctx, struct ubus_object *obj, return 0; } -static int -swmod_install(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__INSTALL_MAX] = {NULL}; - struct blob_buf bb; - - if (blobmsg_parse(install_policy, __INSTALL_MAX, tb, blob_data(msg), blob_len(msg))) - return UBUS_STATUS_UNKNOWN_ERROR; - - if (!tb[INSTALL_PATH]) - return UBUS_STATUS_INVALID_ARGUMENT; - - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - - int err = swmod_install_remove_package(blobmsg_get_string(tb[INSTALL_PATH]), - blobmsg_get_string(tb[INSTALL_ENV]), - SWMOD_INSTALL); - - blobmsg_add_u8(&bb, "status", (!err) ? true : false); - - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - return 0; -} - -static int -swmod_remove(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__REMOVE_MAX] = {NULL}; - struct blob_buf bb; - - if (blobmsg_parse(remove_policy, __REMOVE_MAX, tb, blob_data(msg), blob_len(msg))) - return UBUS_STATUS_UNKNOWN_ERROR; - - if (!tb[REMOVE_NAME]) - return UBUS_STATUS_INVALID_ARGUMENT; - - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - - int err = swmod_install_remove_package(blobmsg_get_string(tb[REMOVE_NAME]), - blobmsg_get_string(tb[REMOVE_ENV]), - SWMOD_REMOVE); - - blobmsg_add_u8(&bb, "status", (!err) ? true : false); - - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - return 0; -} - static int update_map_du_file(struct blob_buf *bb, char *pkg_name, char *pkg_version, char *url, char *username, char *password, char *env, char *uuid) { - char lxc_map_du_path[128] = {0}; + char uci_map_du_path[128] = {0}; #ifdef SWMOD_LXC if (!env || strcmp(env, HOST_SYSTEM) == 0) - swmod_strncpy(lxc_map_du_path, HOST_SYSTEM, 14); + swmod_strncpy(uci_map_du_path, SWMOD_PATH, 12); else { const char *lxc_config_path = get_lxc_path_from_config(); - snprintf(lxc_map_du_path, sizeof(lxc_map_du_path), "%s/%s/rootfs%s", + snprintf(uci_map_du_path, sizeof(uci_map_du_path), "%s/%s/rootfs%s", lxc_config_path ? lxc_config_path : "", env, SWMOD_PATH); } #else - swmod_strncpy(lxc_map_du_path, HOST_SYSTEM, 14); + swmod_strncpy(uci_map_du_path, SWMOD_PATH, 12); #endif - swmod_uci_init(lxc_map_du_path); + swmod_uci_init(uci_map_du_path); struct uci_section *new_s = swmod_uci_add_section(SWMOD_MAP_DU, "deployment"); swmod_uci_set_value_by_section(new_s, "name", pkg_name); swmod_uci_set_value_by_section(new_s, "version", pkg_version); swmod_uci_set_value_by_section(new_s, "url", url); + swmod_uci_set_value_by_section(new_s, "username", (username && *username) ? username : ""); + swmod_uci_set_value_by_section(new_s, "password", (password && *password) ? password : ""); - if (username && *username != '\0') - swmod_uci_set_value_by_section(new_s, "username", username); - - if (password && *password != '\0') - swmod_uci_set_value_by_section(new_s, "password", password); - - if (env) { - swmod_uci_set_value_by_section(new_s, "environment", env); - blobmsg_add_string(bb,"environment", env); - } else { - swmod_uci_set_value_by_section(new_s, "environment", HOST_SYSTEM); - blobmsg_add_string(bb,"environment", HOST_SYSTEM); - } + swmod_uci_set_value_by_section(new_s, "environment", (env) ? env : HOST_SYSTEM); + blobmsg_add_string(bb,"environment", (env) ? env : HOST_SYSTEM); if (uuid && *uuid != '\0') { //use the given UUID @@ -278,6 +189,12 @@ update_map_du_file(struct blob_buf *bb, char *pkg_name, swmod_uci_set_value_by_section(new_s, "duid", duid); FREE(duid); + /* Get Description from package_name.control and Set it to map_du file */ + get_description_from_package(new_s, pkg_name); + + /* Get Config from package_name.list and Set it to map_du file */ + get_config_from_package(new_s, pkg_name); + swmod_uci_fini(SWMOD_MAP_DU); return 0; @@ -306,9 +223,7 @@ swmod_du_install(struct ubus_context *ctx, struct ubus_object *obj, blobmsg_get_string(tb[DU_INSTALL_USERNAME]), blobmsg_get_string(tb[DU_INSTALL_PASSWORD])); - int err = swmod_install_remove_package(full_url, - blobmsg_get_string(tb[DU_INSTALL_ENV]), - SWMOD_INSTALL); + int err = swmod_install_package(full_url, blobmsg_get_string(tb[DU_INSTALL_ENV])); blobmsg_add_u8(&bb, "status", (!err) ? true : false); @@ -332,38 +247,34 @@ swmod_du_install(struct ubus_context *ctx, struct ubus_object *obj, static int update_corresponding_section_in_map_du_file(char *pkg_version, char *url, - char *username, char *password, char *env, char *uuid) + char *username, char *password, const char *env, char *uuid) { - char lxc_map_du_path[128] = {0}; + char uci_map_du_path[128] = {0}; #ifdef SWMOD_LXC if (!env || strcmp(env, HOST_SYSTEM) == 0) - swmod_strncpy(lxc_map_du_path, SWMOD_PATH, 12); + swmod_strncpy(uci_map_du_path, SWMOD_PATH, 12); else { const char *lxc_config_path = get_lxc_path_from_config(); - snprintf(lxc_map_du_path, sizeof(lxc_map_du_path), "%s/%s/rootfs%s", + snprintf(uci_map_du_path, sizeof(uci_map_du_path), "%s/%s/rootfs%s", lxc_config_path ? lxc_config_path : "", env, SWMOD_PATH); } #else - swmod_strncpy(lxc_map_du_path, SWMOD_PATH, 12); + swmod_strncpy(uci_map_du_path, SWMOD_PATH, 12); #endif - swmod_uci_init(lxc_map_du_path); + swmod_uci_init(uci_map_du_path); struct uci_section *s = NULL; swmod_uci_foreach_section(SWMOD_MAP_DU, "deployment", s) { - char *map_uuid = swmod_uci_get_value_by_section(s, "uuid"); + const char *map_uuid = swmod_uci_get_value_by_section(s, "uuid"); if (strcmp(map_uuid, uuid) == 0) { swmod_uci_set_value_by_section(s, "version", pkg_version); swmod_uci_set_value_by_section(s, "url", url); - - if (username && *username != '\0') - swmod_uci_set_value_by_section(s, "username", username); - - if (password && *password != '\0') - swmod_uci_set_value_by_section(s, "password", password); + swmod_uci_set_value_by_section(s, "username", (username && *username) ? username : ""); + swmod_uci_set_value_by_section(s, "password", (password && *password) ? password : ""); break; } } @@ -396,11 +307,9 @@ swmod_du_update(struct ubus_context *ctx, struct ubus_object *obj, blobmsg_get_string(tb[DU_UPDATE_USERNAME]), blobmsg_get_string(tb[DU_UPDATE_PASSWORD])); - char *environment = get_environment_from_map_du_file(blobmsg_get_string(tb[DU_UPDATE_UUID])); + const char *environment = get_environment_from_map_du_file(blobmsg_get_string(tb[DU_UPDATE_UUID])); - int err = swmod_install_remove_package(full_url, - environment, - SWMOD_INSTALL); + int err = swmod_update_package(full_url, environment); blobmsg_add_u8(&bb, "status", (!err) ? true : false); @@ -441,9 +350,7 @@ swmod_du_uninstall(struct ubus_context *ctx, struct ubus_object *obj, memset(&bb, 0, sizeof(struct blob_buf)); blob_buf_init(&bb, 0); - int err = swmod_install_remove_package(blobmsg_get_string(tb[DU_UNINSTALL_NAME]), - blobmsg_get_string(tb[DU_UNINSTALL_ENV]), - SWMOD_REMOVE); + int err = swmod_remove_package(blobmsg_get_string(tb[DU_UNINSTALL_NAME]), blobmsg_get_string(tb[DU_UNINSTALL_ENV])); blobmsg_add_u8(&bb, "status", (!err) ? true : false); @@ -469,7 +376,9 @@ swmod_du_list(struct ubus_context *ctx, struct ubus_object *obj, a = blobmsg_open_array(&bb, "deployment_unit"); /* Show Host System */ + swmod_uci_init(SWMOD_PATH); + swmod_uci_foreach_section(SWMOD_MAP_DU, "deployment", ss) { t = blobmsg_open_table(&bb, ""); @@ -481,9 +390,8 @@ swmod_du_list(struct ubus_context *ctx, struct ubus_object *obj, blobmsg_add_string(&bb, "url", swmod_uci_get_value_by_section(ss, "url")); blobmsg_add_string(&bb, "version", swmod_uci_get_value_by_section(ss, "version")); blobmsg_add_string(&bb, "config", swmod_uci_get_value_by_section(ss, "config")); - + blobmsg_add_string(&bb, "description", swmod_uci_get_value_by_section(ss, "description")); blobmsg_add_string(&bb, "vendor", ""); //TODO - blobmsg_add_string(&bb, "description", ""); //TODO blobmsg_close_table(&bb, t); } @@ -525,15 +433,16 @@ swmod_du_list(struct ubus_context *ctx, struct ubus_object *obj, blobmsg_add_string(&bb, "url", swmod_uci_get_value_by_section(ss, "url")); blobmsg_add_string(&bb, "version", swmod_uci_get_value_by_section(ss, "version")); blobmsg_add_string(&bb, "config", swmod_uci_get_value_by_section(ss, "config")); - + blobmsg_add_string(&bb, "description", swmod_uci_get_value_by_section(ss, "description")); blobmsg_add_string(&bb, "vendor", ""); //TODO - blobmsg_add_string(&bb, "description", ""); //TODO blobmsg_close_table(&bb, t); } swmod_uci_fini(SWMOD_MAP_DU); } - if (dir) closedir(dir); + + if (dir) + closedir(dir); } #endif @@ -586,7 +495,6 @@ swmod_eu_list(struct ubus_context *ctx, struct ubus_object *obj, blobmsg_add_string(&bb, "name", exec_units[i].name[j]); blobmsg_add_string(&bb, "command", exec_units[i].command[j]); - blobmsg_add_string(&bb, "vendor", exec_units[i].vendor[j]); blobmsg_add_string(&bb, "config", exec_units[i].config[j]); blobmsg_add_string(&bb, "version", exec_units[i].version[j]); blobmsg_add_string(&bb, "description", exec_units[i].description[j]); @@ -594,6 +502,7 @@ swmod_eu_list(struct ubus_context *ctx, struct ubus_object *obj, blobmsg_add_u32(&bb, "euid", exec_units[i].euid[j]); blobmsg_add_u32(&bb, "disk_space", exec_units[i].disk_space[j]); blobmsg_add_u32(&bb, "memory_space", exec_units[i].memory_space[j]); + blobmsg_add_string(&bb, "vendor", exec_units[i].vendor[j]); //TODO blobmsg_close_table(&bb, t); } @@ -610,8 +519,6 @@ static const struct ubus_method swmod_object_methods[] = { UBUS_METHOD_NOARG("environment", swmod_environment), UBUS_METHOD_NOARG("du_list", swmod_du_list), UBUS_METHOD_NOARG("eu_list", swmod_eu_list), - UBUS_METHOD("install", swmod_install, install_policy), - UBUS_METHOD("remove", swmod_remove, remove_policy), UBUS_METHOD("du_install", swmod_du_install, du_install_policy), UBUS_METHOD("du_update", swmod_du_update, du_update_policy), UBUS_METHOD("du_uninstall", swmod_du_uninstall, du_uninstall_policy), @@ -626,6 +533,11 @@ static struct ubus_object swmod_object = { .n_methods = ARRAY_SIZE(swmod_object_methods), }; +static int swmod_pre_init(void) +{ + return synchronize_deployment_units_with_map_du_file(); +} + static int swmod_init(struct ubus_context *ctx) { int ret; @@ -653,6 +565,8 @@ int main(void) return -1; } + swmod_pre_init(); + ubus_add_uloop(ctx); ret = swmod_init(ctx); diff --git a/swmod_host.c b/swmod_host.c index c6fe1c734fb21a962138b95ba98ed5983439beed..26bd617d0ae92a8804b500141d82736c45825c26 100644 --- a/swmod_host.c +++ b/swmod_host.c @@ -26,10 +26,12 @@ #include <sys/utsname.h> #include "tools.h" -#include "swmod_opkg.h" #include "swmod_uci.h" +#include "swmod_host.h" #include "swmod.h" +static char host_hash[64] = {0}; + void populate_host_system_environment(void) { environments[0].exists = true; @@ -54,170 +56,247 @@ void populate_host_system_environment(void) } } -static void package_list_installed_callback(pkg_t *pkg, void *data) +void populate_host_system_deployment_unit(void) { - char *environment = (char *)data; + time_t tm = get_file_mtime(OPKG_INFO_PATH); + unsigned int um = 0; - if (pkg->state_status == SS_INSTALLED) { - struct uci_section *s = NULL; - bool found = false; - static int incr = 0; + sscanf(host_hash, "%u", &um); + if (tm == um) + return; - swmod_uci_foreach_section(SWMOD_MAP_DU, "deployment", s) { - char *map_name = swmod_uci_get_value_by_section(s, "name"); + if (swmod_uci_init(SWMOD_PATH)) + return; - /* Check if package name exists */ - if (strcmp(map_name, pkg->name) == 0) { - found = true; - break; - } - } - if (found) - return; + struct uci_section *s = NULL, *stmp = NULL; + char pname[256] = {0}; + FILE *log; - struct uci_section *new_s = swmod_uci_add_section(SWMOD_MAP_DU, "deployment"); + swmod_uci_foreach_section_safe(SWMOD_MAP_DU, "deployment", stmp, s) { + const char *map_du_name = swmod_uci_get_value_by_section(s, "name"); - char *version = NULL, *config = NULL; + snprintf(pname, sizeof(pname), OPKG_INFO_PATH"%s.control", map_du_name); - /* Get version and config from package name */ - swmod_opkg_find_package_with_version_and_config(pkg->name, &version, &config); + /* Check package name exists, if no => remove the section */ + if (!file_exists(pname)) + swmod_uci_delete_by_section(s, NULL, NULL); + } - /* Generate UUID */ - char *uuid = generate_uuid(); - /* Generate DUID */ - char *duid = generate_duid(true, incr); - incr++; + if ((log = popen("opkg list", "r"))) { + char line[256] = {0}; - swmod_uci_set_value_by_section(new_s, "name", pkg->name); - swmod_uci_set_value_by_section(new_s, "version", (version) ? version : ""); - swmod_uci_set_value_by_section(new_s, "config", (config) ? version : ""); - swmod_uci_set_value_by_section(new_s, "uuid", uuid); - swmod_uci_set_value_by_section(new_s, "duid", duid); - swmod_uci_set_value_by_section(new_s, "environment", environment); + while (fgets(line, sizeof(line), log) != NULL) { + static int incr = 0; + char name[64] = {0}; + char version[64] = {0}; - /* Freed all allocated memory */ - FREE(uuid); - FREE(duid); - FREE(version); - FREE(config); - } -} + /* Get name and version for each line */ + if (sscanf(line, "%63s - %63s", name, version)) { -void populate_host_system_deployment_unit(void) -{ - if (swmod_opkg_new()) - return; + /* Check if package name exists */ + if (check_section_exist_by_option("map_du", "deployment", "name", name)) + continue; - if (swmod_uci_init(SWMOD_PATH)) { - swmod_opkg_free(); - return; - } + struct uci_section *new_s = swmod_uci_add_section(SWMOD_MAP_DU, "deployment"); - struct uci_section *s = NULL, *stmp = NULL; + /* Generate UUID */ + char *uuid = generate_uuid(); - swmod_uci_foreach_section_safe(SWMOD_MAP_DU, "deployment", stmp, s) { - char *map_du_name = swmod_uci_get_value_by_section(s, "name"); + /* Generate DUID */ + char *duid = generate_duid(true, incr++); - /* Check package name exists, if no => remove the section */ - if (!swmod_opkg_find_package(map_du_name)) - swmod_uci_delete_by_section(s, NULL, NULL); - } + swmod_uci_set_value_by_section(new_s, "name", name); + swmod_uci_set_value_by_section(new_s, "version", version); + swmod_uci_set_value_by_section(new_s, "uuid", uuid); + swmod_uci_set_value_by_section(new_s, "duid", duid); + swmod_uci_set_value_by_section(new_s, "environment", HOST_SYSTEM); - opkg_list_packages(package_list_installed_callback, HOST_SYSTEM); + /* Freed all allocated memory */ + FREE(uuid); + FREE(duid); + + /* Get Description from package_name.control and Set it to map_du file */ + get_description_from_package(new_s, name); + + /* Get Config from package_name.list and Set it to map_du file */ + get_config_from_package(new_s, name); + } + } + pclose(log); + } swmod_uci_fini(SWMOD_MAP_DU); - swmod_opkg_free(); + snprintf(host_hash, sizeof(host_hash), "%u", (unsigned int)tm); } void populate_host_system_execution_unit(void) { - if (swmod_opkg_new()) - return; - LIST_HEAD(proc_list); populate_active_processes(&proc_list); - bool process_found, bin_found; - pkg_vec_t *all; - int i, nbr = 0; - - all = pkg_vec_alloc(); - pkg_hash_fetch_available(all); exec_units[0].exists = true; + int nbr = 0; + FILE *log; - for (i = 0; i < all->len; i++) { - pkg_t *pkg = all->pkgs[i]; + if ((log = popen("opkg list", "r"))) { + char line[256] = {0}; - str_list_elt_t *iter; - str_list_t *files = pkg_get_installed_files(pkg); - for (iter = str_list_first(files); iter; iter = str_list_next(files, iter)) { + while (fgets(line, sizeof(line), log) != NULL) { + char name[64] = {0}; + char version[64] = {0}; - bin_found = false; - char *spch = NULL; - if ((spch = strstr((char *)iter->data, "bin/"))) { + /* Get name and version for each line */ + if (sscanf(line, "%63s - %63s", name, version)) { - bin_found = true; - process_found = false; - struct process_res *p; - list_for_each_entry(p, &proc_list, list) { + /* Skip it if it is a library */ + if (strstr(name, "lib")) + continue; - if (strstr(p->cmd, spch)) { + FILE *fp; + char pkg_name_list[512] = {0}; - char line[1024], path[512], *spch = NULL; + snprintf(pkg_name_list, sizeof(pkg_name_list), OPKG_INFO_PATH"%s.list", name); + if ((fp = fopen(pkg_name_list, "r")) != NULL) { + char line_list[256] = {0}; + while (fgets(line_list, 256, fp) != NULL) { + bool bin_found = false; - int disk_space; + if (strstr(line_list, "bin/")) { + struct process_res *p; - exec_units[0].eu_exists[nbr] = true; - swmod_strncpy(exec_units[0].name[nbr], pkg->name, 32); - swmod_strncpy(exec_units[0].command[nbr], p->cmd, 32); - swmod_strncpy(exec_units[0].environment[nbr], HOST_SYSTEM, 14); - exec_units[0].euid[nbr] = p->pid; - exec_units[0].memory_space[nbr] = p->vsize; + remove_new_line(line_list); + list_for_each_entry(p, &proc_list, list) { + bool process_found = false; - char *version = pkg_version_str_alloc(pkg); - swmod_strncpy(exec_units[0].version[nbr], version, 32); - FREE(version); + if (strcmp(p->cmd, line_list) == 0) { - snprintf(path, sizeof(path), "%s/%s.control", OPKG_INFO_PATH, pkg->name); - FILE *fp = fopen(path, "r"); - if ( fp != NULL) { - while (fgets(line, sizeof(line), fp) != NULL) { - if (sscanf(line, "Installed-Size: %d", &disk_space)) - exec_units[0].disk_space[nbr] = disk_space; + exec_units[0].eu_exists[nbr] = true; + swmod_strncpy(exec_units[0].name[nbr], name, 32); + swmod_strncpy(exec_units[0].version[nbr], version, 32); + swmod_strncpy(exec_units[0].command[nbr], p->cmd, 32); + swmod_strncpy(exec_units[0].environment[nbr], HOST_SYSTEM, 14); + exec_units[0].euid[nbr] = p->pid; + exec_units[0].memory_space[nbr] = p->vsize; - if ((spch = strstr(line, "Description:"))) { - remove_new_line(spch); - swmod_strncpy(exec_units[0].description[nbr], spch+14, 1024); - break; + /* Get Description from package_name.control */ + char pkg_path[512] = {0}; + snprintf(pkg_path, sizeof(pkg_path), OPKG_INFO_PATH"%s.control", name); + + FILE *fp_control = fopen(pkg_path, "r"); + if (fp_control != NULL) { + char line_control[1024], *spch = NULL; + int disk_space; + + while (fgets(line_control, sizeof(line_control), fp_control) != NULL) { + + if (sscanf(line_control, "Installed-Size: %d", &disk_space)) + exec_units[0].disk_space[nbr] = disk_space; + + if ((spch = strstr(line_control, "Description:"))) { + remove_new_line(spch); + swmod_strncpy(exec_units[0].description[nbr], spch+14, 1024); + break; + } + } + + fclose(fp_control); + } + + /* Get Config from package_name.list */ + snprintf(pkg_path, sizeof(pkg_path), OPKG_INFO_PATH"%s.list", name); + + FILE *fp_list = fopen(pkg_path, "r"); + if (fp_list != NULL) { + char *spch = NULL; + + while (fgets(line_list, sizeof(line_list), fp_list) != NULL) { + + if ((spch = strstr(line_list, "/etc/config/"))) { + remove_new_line(spch); + swmod_strncpy(exec_units[0].config[nbr], spch+12, 32); + break; + } + } + + fclose(fp_list); + } + + swmod_strncpy(exec_units[0].vendor[nbr], "", 128); // TODO + + nbr++; + process_found = true; } + + if (process_found) + break; } - fclose(fp); - } - swmod_strncpy(exec_units[0].vendor[nbr], "", 128); // TODO - swmod_strncpy(exec_units[0].config[nbr], "", 32); // TODO + bin_found = true; + } - nbr++; - process_found = true; - break; + if (bin_found) + break; } - } - if (process_found) - break; + pclose(fp); + } } - if (bin_found) + } + + pclose(log); + } + + swmod_free_data_from_list(&proc_list); +} + +void get_description_from_package(struct uci_section *s, char *pkg_name) +{ + /* Get Description from package_name.control */ + char pkg_path[128] = {0}; + snprintf(pkg_path, sizeof(pkg_path), OPKG_INFO_PATH"%s.control", pkg_name); + + FILE *fp = fopen(pkg_path, "r"); + if (fp != NULL) { + char line[256] = {0}; + char *spch = NULL; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if ((spch = strstr(line, "Description:"))) { + remove_new_line(spch); + swmod_uci_set_value_by_section(s, "description", spch+14); break; + } } + + fclose(fp); } +} - pkg_vec_free(all); +void get_config_from_package(struct uci_section *s, char *pkg_name) +{ + /* Get Config from package_name.list */ + char pkg_path[128] = {0}; + snprintf(pkg_path, sizeof(pkg_path), OPKG_INFO_PATH"%s.list", pkg_name); - swmod_opkg_free(); + FILE *fp = fopen(pkg_path, "r"); + if (fp != NULL) { + char line[256] = {0}; + char *spch = NULL; - swmod_free_data_from_list(&proc_list); + while (fgets(line, sizeof(line), fp) != NULL) { + + if ((spch = strstr(line, "/etc/config/"))) { + remove_new_line(spch); + swmod_uci_set_value_by_section(s, "config", spch+12); + break; + } + } + + fclose(fp); + } } diff --git a/swmod_host.h b/swmod_host.h index 275fcd4df60ccffba16e5576545d5396c81d0f2b..4c4f1049a09b5305a346129f7b4c16a2655cb997 100644 --- a/swmod_host.h +++ b/swmod_host.h @@ -27,4 +27,7 @@ void populate_host_system_environment(void); void populate_host_system_deployment_unit(void); void populate_host_system_execution_unit(void); +void get_description_from_package(struct uci_section *s, char *pkg_name); +void get_config_from_package(struct uci_section *s, char *pkg_name); + #endif //HOST_H diff --git a/swmod_lxc.c b/swmod_lxc.c index 4bfb0a569c687d7d66d3d090754f4523a51fee76..f98b6e4a4856e3759609f557f58de504643fcca6 100644 --- a/swmod_lxc.c +++ b/swmod_lxc.c @@ -31,6 +31,7 @@ #include "swmod_uci.h" #include "swmod_opkg.h" #include "swmod.h" +#include "swmod_lxc.h" #define LXC_CONFIG_PATH "/etc/lxc/lxc.conf" #define LXC_PATH "lxc.lxcpath" @@ -40,8 +41,10 @@ } while (0) static char lxc_attach_result[512] = {0}; +static char lxc_hash[64] = {0}; typedef struct lxc_attach_args { + const char *lxcpath; const char *value; int action; } lxc_attach_args; @@ -121,11 +124,7 @@ static int lxc_attach_run_env_func(void *args) /* type=<ENV_TYPE> vendor=<ENV_VENDOR> version=<ENV_VERSION> * alloc_mem=<ENV_ALLOCATED_MEMORY> avail_mem=<ENV_AVAILABLE_MEMORY> */ LXC_ATTACH_OUT("type=%s vendor=%s version=%s alloc_mem=%lu avail_mem=%lu", - type, - vendor, - version, - alloc_mem, - avail_mem); + type, vendor, version, alloc_mem, avail_mem); return 0; } @@ -180,86 +179,86 @@ void populate_lxc_environment(void) } /************************** Deployment/Execution Unit **************************/ -static void package_list_installed_callback(pkg_t *pkg, void *data) +static int lxc_attach_run_deployment_unit_func(void *args) { - char *environment = (char *)data; + lxc_attach_args *data = (lxc_attach_args *)args; - if (pkg->state_status == SS_INSTALLED) { - struct uci_section *s = NULL; - bool found = false; - static int incr = 0; + if (!data || *(data->lxcpath) == '\0' || *(data->value) == '\0') + return -1; - swmod_uci_foreach_section(SWMOD_MAP_DU, "deployment", s) { - char *map_name = swmod_uci_get_value_by_section(s, "name"); + char lxc_map_du_path[128] = {0}; - /* Check if package name exists */ - if (strcmp(map_name, pkg->name) == 0) { - found = true; - break; - } - } - if (found) - return; + snprintf(lxc_map_du_path, sizeof(lxc_map_du_path), "%s/%s/rootfs%s", + data->lxcpath, + data->value, + OPKG_INFO_PATH); - struct uci_section *new_s = swmod_uci_add_section(SWMOD_MAP_DU, "deployment"); - char *version = NULL, *config = NULL; + time_t tm = get_file_mtime(lxc_map_du_path); + unsigned int um = 0; - /* Get version and config from package name */ - swmod_opkg_find_package_with_version_and_config(pkg->name, &version, &config); + sscanf(lxc_hash, "%u", &um); + if (tm == um) + return -1; - /* Generate UUID */ - char *uuid = generate_uuid(); + if (swmod_uci_init(SWMOD_PATH)) + return -1; - /* Generate DUID */ - char *duid = generate_duid(true, incr); - incr++; + struct uci_section *s = NULL, *stmp = NULL; + char pname[256] = {0}; + FILE *log; + + swmod_uci_foreach_section_safe(SWMOD_MAP_DU, "deployment", stmp, s) { + const char *map_du_name = swmod_uci_get_value_by_section(s, "name"); - swmod_uci_set_value_by_section(new_s, "name", pkg->name); - swmod_uci_set_value_by_section(new_s, "version", (version) ? version : ""); - swmod_uci_set_value_by_section(new_s, "config", (config) ? version : ""); - swmod_uci_set_value_by_section(new_s, "uuid", uuid); - swmod_uci_set_value_by_section(new_s, "duid", duid); - swmod_uci_set_value_by_section(new_s, "environment", environment); + snprintf(pname, sizeof(pname), OPKG_INFO_PATH"%s.control", map_du_name); - /* Freed all allocated memory */ - FREE(uuid); - FREE(duid); - FREE(version); - FREE(config); + /* Check package name exists, if no => remove the section */ + if (!file_exists(pname)) + swmod_uci_delete_by_section(s, NULL, NULL); } -} -static int lxc_attach_run_deployment_unit_func(void *args) -{ - lxc_attach_args *data = (lxc_attach_args *)args; - if (!data || *(data->value) == '\0') - return -1; + if ((log = popen("opkg list", "r"))) { + char line[256] = {0}; - if (swmod_opkg_new()) - return -1; + while (fgets(line, sizeof(line), log) != NULL) { + static int incr = 0; + char name[64] = {0}; + char version[64] = {0}; - if (swmod_uci_init(SWMOD_PATH)) { - swmod_opkg_free(); - return -1; - } + /* Get name and version for each line */ + if (sscanf(line, "%63s - %63s", name, version)) { - struct uci_section *s = NULL, *stmp = NULL; + /* Check if package name exists */ + if (check_section_exist_by_option("map_du", "deployment", "name", name)) + continue; - swmod_uci_foreach_section_safe(SWMOD_MAP_DU, "deployment", stmp, s) { - char *map_du_name = swmod_uci_get_value_by_section(s, "name"); + struct uci_section *new_s = swmod_uci_add_section(SWMOD_MAP_DU, "deployment"); - /* Check package name exists, if no => remove the section */ - if (!swmod_opkg_find_package(map_du_name)) - swmod_uci_delete_by_section(s, NULL, NULL); - } + /* Generate UUID */ + char *uuid = generate_uuid(); - opkg_list_packages(package_list_installed_callback, (void *)data->value); + /* Generate DUID */ + char *duid = generate_duid(true, incr++); + + swmod_uci_set_value_by_section(new_s, "name", name); + swmod_uci_set_value_by_section(new_s, "version", version); + swmod_uci_set_value_by_section(new_s, "uuid", uuid); + swmod_uci_set_value_by_section(new_s, "duid", duid); + swmod_uci_set_value_by_section(new_s, "environment", data->value); + + /* Freed all allocated memory */ + FREE(uuid); + FREE(duid); + } + } + pclose(log); + } swmod_uci_fini(SWMOD_MAP_DU); - swmod_opkg_free(); + snprintf(lxc_hash, sizeof(lxc_hash), "%u", (unsigned int)tm); LXC_ATTACH_OUT("populate deployment unit: done"); @@ -273,110 +272,140 @@ static int lxc_attach_run_execution_unit_func(void *args) if (!data || *(data->value) == '\0') return -1; - if (swmod_opkg_new()) - return -1; + LIST_HEAD(proc_list); - if (swmod_uci_init(SWMOD_PATH)) { - swmod_opkg_free(); + populate_active_processes(&proc_list); + + char map_eu_path[32]; + snprintf(map_eu_path, sizeof(map_eu_path), "%s%s", SWMOD_PATH, SWMOD_MAP_EU); + remove(map_eu_path); //remove map_eu file + create_file(map_eu_path); //cretae new empty map_eu file + + if (swmod_uci_init(SWMOD_PATH)) return -1; - } - LIST_HEAD(proc_list); + int nbr = 0; + FILE *log; - populate_active_processes(&proc_list); + if ((log = popen("opkg list", "r"))) { + char line[256] = {0}; - char path[32]; - snprintf(path, sizeof(path), "%s%s", SWMOD_PATH, SWMOD_MAP_EU); - remove(path); //remove map_eu file - create_file(path); //cretae new empty map_eu file + while (fgets(line, sizeof(line), log) != NULL) { + char name[64] = {0}; + char version[64] = {0}; - bool process_found, bin_found; - pkg_vec_t *all; - int i, nbr = 0; + /* Get name and version for each line */ + if (sscanf(line, "%63s - %63s", name, version)) { - all = pkg_vec_alloc(); - pkg_hash_fetch_available(all); + /* Skip it if it is a library */ + if (strstr(name, "lib")) + continue; - for (i = 0; i < all->len; i++) { - pkg_t *pkg = all->pkgs[i]; + FILE *fp; + char pkg_name_list[512] = {0}; - str_list_elt_t *iter; - str_list_t *files = pkg_get_installed_files(pkg); - for (iter = str_list_first(files); iter; iter = str_list_next(files, iter)) { + snprintf(pkg_name_list, sizeof(pkg_name_list), OPKG_INFO_PATH"%s.list", name); + if ((fp = fopen(pkg_name_list, "r")) != NULL) { + char line_list[256] = {0}; - bin_found = false; - char *spch = NULL; - if ((spch = strstr((char *)iter->data, "bin/"))) { + while (fgets(line_list, 256, fp) != NULL) { + bool bin_found = false; - bin_found = true; - process_found = false; - struct process_res *p; - list_for_each_entry(p, &proc_list, list) { + if (strstr(line_list, "bin/")) { + struct process_res *p; - if (strstr(p->cmd, spch)) { + remove_new_line(line_list); + list_for_each_entry(p, &proc_list, list) { + bool process_found = false; - char line[1024], description[1024], path[512], version[32]; - char *spch = NULL; - int disk_space; + if (strcmp(p->cmd, line_list) == 0) { + char buf_pid[16], buf_vsize[16], buf_disk_space[16]; + char config[32], description[1024]; + int disk_space; - char *pkg_version = pkg_version_str_alloc(pkg); - swmod_strncpy(version, pkg_version, 32); - FREE(pkg_version); + /* Get Description from package_name.control */ + char pkg_path[512] = {0}; + snprintf(pkg_path, sizeof(pkg_path), OPKG_INFO_PATH"%s.control", name); - snprintf(path, sizeof(path), "%s/%s.control", OPKG_INFO_PATH, pkg->name); - FILE *fp = fopen(path, "r"); - if ( fp != NULL) { - while (fgets(line, sizeof(line), fp) != NULL) { - sscanf(line, "Installed-Size: %d", &disk_space); + FILE *fp_control = fopen(pkg_path, "r"); + if (fp_control != NULL) { + char line_control[1024], *spch = NULL; - if ((spch = strstr(line, "Description:"))) { - remove_new_line(spch); - swmod_strncpy(description, spch+14, 1024); - break; + while (fgets(line_control, sizeof(line_control), fp_control) != NULL) { + + if (sscanf(line_control, "Installed-Size: %d", &disk_space)) + snprintf(buf_disk_space, sizeof(buf_disk_space), "%d", disk_space); + + if ((spch = strstr(line_control, "Description:"))) { + remove_new_line(spch); + swmod_strncpy(description, spch+14, 1024); + break; + } + } + + fclose(fp_control); + } + + /* Get Config from package_name.list */ + snprintf(pkg_path, sizeof(pkg_path), OPKG_INFO_PATH"%s.list", name); + + FILE *fp_list = fopen(pkg_path, "r"); + if (fp_list != NULL) { + char *spch = NULL; + + while (fgets(line_list, sizeof(line_list), fp_list) != NULL) { + + if ((spch = strstr(line_list, "/etc/config/"))) { + remove_new_line(spch); + swmod_strncpy(config, spch+14, 32); + break; + } + } + + fclose(fp_list); + } + + snprintf(buf_pid, sizeof(buf_pid), "%d", p->pid); + snprintf(buf_vsize, sizeof(buf_vsize), "%d", p->vsize); + + struct uci_section *new_s = swmod_uci_add_section(SWMOD_MAP_EU, "exec_unit"); + swmod_uci_set_value_by_section(new_s, "name", name); + swmod_uci_set_value_by_section(new_s, "command", p->cmd); + swmod_uci_set_value_by_section(new_s, "environment", "Linux Container"); + swmod_uci_set_value_by_section(new_s, "euid", buf_pid); + swmod_uci_set_value_by_section(new_s, "memory_space", buf_vsize); + swmod_uci_set_value_by_section(new_s, "disk_space", buf_disk_space); + swmod_uci_set_value_by_section(new_s, "version", version); + swmod_uci_set_value_by_section(new_s, "config", config); + swmod_uci_set_value_by_section(new_s, "description", description); + + nbr++; + process_found = true; } + + if (process_found) + break; } - fclose(fp); + + bin_found = true; } - char buf_pid[16], buf_vsize[16], buf_disk_space[16]; - - snprintf(buf_pid, sizeof(buf_pid), "%d", p->pid); - snprintf(buf_vsize, sizeof(buf_vsize), "%d", p->vsize); - snprintf(buf_disk_space, sizeof(buf_disk_space), "%d", disk_space); - - struct uci_section *new_s = swmod_uci_add_section(SWMOD_MAP_EU, "exec_unit"); - swmod_uci_set_value_by_section(new_s, "name", pkg->name); - swmod_uci_set_value_by_section(new_s, "command", p->cmd); - swmod_uci_set_value_by_section(new_s, "environment", "Linux Container"); - swmod_uci_set_value_by_section(new_s, "euid", buf_pid); - swmod_uci_set_value_by_section(new_s, "memory_space", buf_vsize); - swmod_uci_set_value_by_section(new_s, "disk_space", buf_disk_space); - swmod_uci_set_value_by_section(new_s, "version", version); - swmod_uci_set_value_by_section(new_s, "description", description); - - nbr++; - process_found = true; - break; + if (bin_found) + break; } - } - if (process_found) - break; + pclose(fp); + } } - - if (bin_found) - break; } + + pclose(log); } - pkg_vec_free(all); + swmod_free_data_from_list(&proc_list); swmod_uci_fini(SWMOD_MAP_EU); - swmod_opkg_free(); - - swmod_free_data_from_list(&proc_list); - LXC_ATTACH_OUT("populate execution unit: done"); return 0; @@ -402,7 +431,7 @@ void populate_lxc_deployment_execution_units(int action) goto end; } - lxc_attach_args command = (lxc_attach_args){.value = ct->name}; + lxc_attach_args command = (lxc_attach_args){.value = ct->name, .lxcpath = lxcpath}; if (action == SWMOD_DEPLOYMENT_UNIT) lxc_attach_func(ct, lxc_attach_run_deployment_unit_func, &command); @@ -418,41 +447,115 @@ end: } /************************** Install/Remove **************************/ -static void progress_lxc_cb(const opkg_progress_data_t *progress, void *data) +static int swmod_lxc_install_package(const char *package_path) { /* lxc_attach_result buffer format */ /* pkg_name=<PACKAGE_NAME> pkg_version=<PACKAGE_VERSION> */ - char *version = pkg_version_str_alloc(progress->pkg); - LXC_ATTACH_OUT("pkg_name=%s pkg_version=%s", progress->pkg->name, version); - FREE(version); + char command[1024] = {0}; + char line[512] = {0}; + char pkg_name[64] = {0}; + char pkg_version[64] = {0}; + FILE *log; + int err = -1; + + snprintf(command, sizeof(command), "opkg --force-depends --force-maintainer install %s", package_path); + + if ((log = popen(command, "r"))) { + while(fgets(line, sizeof(line), log) != NULL) { + + if (strstr(line, "Installing")) { + sscanf(line, "Installing %63s (%63[^)] to root...", pkg_name, pkg_version); + err = 0; + } + } + pclose(log); + } + + LXC_ATTACH_OUT("pkg_name=%s pkg_version=%s", pkg_name, pkg_version); + return err; } -static int lxc_attach_run_install_remove_func(void *args) +static int swmod_lxc_install_package(const char *package_path) { - lxc_attach_args *data = (lxc_attach_args *)args; + /* lxc_attach_result buffer format */ + /* pkg_name=<PACKAGE_NAME> pkg_version=<PACKAGE_VERSION> */ - if (swmod_opkg_new()) - return -1; + char command[1024] = {0}; + char line[512] = {0}; + char pkg_name[64] = {0}; + char pkg_old_version[64] = {0}; + char pkg_new_version[64] = {0}; + FILE *log; + int err = -1; + + snprintf(command, sizeof(command), "opkg --force-depends --force-maintainer install %s", package_path); + + if ((log = popen(command, "r"))) { + while(fgets(line, sizeof(line), log) != NULL) { + + if (strstr(line, "Upgrading")) { + sscanf(line, "Upgrading %63s on root from %63s to %63s", pkg_name, pkg_old_version, pkg_new_version); + err = 0; + } + } + pclose(log); + int len = strlen(pkg_new_version); + if (len > 3 && pkg_new_version[len - 3] == '.') + pkg_new_version[len - 3] = '\0'; + } + + LXC_ATTACH_OUT("pkg_name=%s pkg_version=%s", pkg_name, pkg_new_version); + return err; +} + +static int swmod_lxc_remove_package(const char *package_name) +{ + /* lxc_attach_result buffer format */ + /* pkg_name=<PACKAGE_NAME> pkg_version=<PACKAGE_VERSION> */ + + char command[1024] = {0}; + char line[512] = {0}; + FILE *log; + int err = -1; + + snprintf(command, sizeof(command), "opkg --force-depends remove %s", package_name); + + if ((log = popen(command, "r"))) { + while(fgets(line, sizeof(line), log) != NULL) { + + if (strstr(line, "Removing package")) + err = 0; + } + pclose(log); + } + + LXC_ATTACH_OUT("Removing package: done"); + return err; +} + +static int lxc_attach_run_opkg_method_func(void *args) +{ + lxc_attach_args *data = (lxc_attach_args *)args; if (!data || *(data->value) == '\0') return -1; - int err; + int err = -1; if (data->action == SWMOD_INSTALL) - err = opkg_install_package(data->value, progress_lxc_cb, "Installing..."); + err = swmod_lxc_install_package(data->value); + else if (data->action == SWMOD_UPDATE) + err = swmod_lxc_update_package(data->value); else if (data->action == SWMOD_REMOVE) - err = opkg_remove_package(data->value, progress_lxc_cb, "Removing..."); + err = swmod_lxc_remove_package(data->value); else err = -1; - swmod_opkg_free(); - return err; } -int swmod_lxc_install_remove_package(const char *package_path, const char *environment, int action) +int swmod_lxc_install_update_remove_package(const char *package_path, const char *environment, int action) { const char *lxcpath = NULL; @@ -478,14 +581,16 @@ int swmod_lxc_install_remove_package(const char *package_path, const char *envir } lxc_attach_args lxc_args = (lxc_attach_args){.value = package_path, .action = action}; - int ret = lxc_attach_func(ct, lxc_attach_run_install_remove_func, &lxc_args); + int ret = lxc_attach_func(ct, lxc_attach_run_opkg_method_func, &lxc_args); if (ret >= 0) { - /* lxc_attach_result buffer format */ - /* pkg_name=<PACKAGE_NAME> pkg_version=<PACKAGE_VERSION> */ - sscanf(lxc_attach_result, "pkg_name=%64s pkg_version=%64s", - package_name, - package_version); + if (action == SWMOD_INSTALL || action == SWMOD_UPDATE) { + /* lxc_attach_result buffer format */ + /* pkg_name=<PACKAGE_NAME> pkg_version=<PACKAGE_VERSION> */ + + sscanf(lxc_attach_result, "pkg_name=%64s pkg_version=%64s", + package_name, package_version); + } err = 0; } diff --git a/swmod_lxc.h b/swmod_lxc.h index e7f21ab415d8c5693cdaf5232f7b90c399344bdc..00b6bb04d6c5c978096f87b6f5d8ff0044c3d5c7 100644 --- a/swmod_lxc.h +++ b/swmod_lxc.h @@ -29,6 +29,6 @@ bool lxc_is_supported(const char **lxcpath); const char *get_lxc_path_from_config(void); void populate_lxc_environment(void); void populate_lxc_deployment_execution_units(int action); -int swmod_lxc_install_remove_package(const char *package_path, const char *environment, int action); +int swmod_lxc_install_update_remove_package(const char *package_path, const char *environment, int action); #endif //LXC_H diff --git a/swmod_opkg.c b/swmod_opkg.c index 82ddc4033ad41343442a0c5abf301662f468b68a..93333f8120244cdd042ebf4fdbc2eb885cbb0511 100644 --- a/swmod_opkg.c +++ b/swmod_opkg.c @@ -20,8 +20,6 @@ * 02110-1301 USA */ -#include <stdbool.h> - #include "tools.h" #include "swmod.h" #include "swmod_uci.h" @@ -30,92 +28,103 @@ #include "swmod_lxc.h" #endif -char package_name[64] = ""; -char package_version[64] = ""; +char package_name[64] = {0}; +char package_version[64] = {0}; -int swmod_opkg_new(void) +static int swmod_host_system_install_package(const char *package_path) { - if (opkg_new()) - return -1; + char command[1024] = {0}; + char line[512] = {0}; + FILE *log; + int err = -1; - return 0; -} + snprintf(command, sizeof(command), "opkg --force-depends --force-maintainer install %s", package_path); -int swmod_opkg_free(void) -{ - opkg_free(); - return 0; + if ((log = popen(command, "r"))) { + while(fgets(line, sizeof(line), log) != NULL) { + + if (strstr(line, "Installing")) { + sscanf(line, "Installing %63s (%63[^)] to root...", package_name, package_version); + err = 0; + } + } + pclose(log); + } + + return err; } -static void progress_callback(const opkg_progress_data_t *progress, void *data) +static int swmod_host_system_update_package(const char *package_path) { - swmod_strncpy(package_name, progress->pkg->name, sizeof(package_name)); + char command[1024] = {0}; + char pkg_old_version[64] = {0}; + char line[512] = {0}; + FILE *log; + int err = -1; - char *version = pkg_version_str_alloc(progress->pkg); - swmod_strncpy(package_version, version, sizeof(package_version)); - FREE(version); + snprintf(command, sizeof(command), "opkg --force-depends --force-maintainer install %s", package_path); + + if ((log = popen(command, "r"))) { + while(fgets(line, sizeof(line), log) != NULL) { + + if (strstr(line, "Upgrading")) { + sscanf(line, "Upgrading %63s on root from %63s to %63s", package_name, pkg_old_version, package_version); + err = 0; + } + } + pclose(log); + int len = strlen(package_version); + if (len > 3 && package_version[len - 3] == '.') + package_version[len - 3] = '\0'; + } + + return err; } -static int swmod_host_system_install_remove_package(const char *package_path, int action) +static int swmod_host_system_remove_package(const char *package_name) { - if (swmod_opkg_new()) - return -1; + char command[1024] = {0}; + char line[512] = {0}; + FILE *log; + int err = -1; - int err; + snprintf(command, sizeof(command), "opkg --force-depends remove %s", package_name); - if (action == SWMOD_INSTALL) - err = opkg_install_package(package_path, progress_callback, "Installing..."); - else if (action == SWMOD_REMOVE) - err = opkg_remove_package(package_path, progress_callback, "Removing..."); - else - err = -1; + if ((log = popen(command, "r"))) { + while(fgets(line, sizeof(line), log) != NULL) { - swmod_opkg_free(); + if (strstr(line, "Removing package")) + err = 0; + } + pclose(log); + } return err; } -int swmod_install_remove_package(const char *package_path, const char *environment, int action) +int swmod_install_package(const char *package_path, const char *environment) { #ifdef SWMOD_LXC if (environment && *environment != '\0' && (strcmp(environment, HOST_SYSTEM) != 0)) - return swmod_lxc_install_remove_package(package_path, environment, action); + return swmod_lxc_install_update_remove_package(package_path, environment, SWMOD_INSTALL); #endif - return swmod_host_system_install_remove_package(package_path, action); + return (environment && *environment != '\0' && (strcmp(environment, HOST_SYSTEM) == 0)) ? swmod_host_system_install_package(package_path) : -1; } -bool swmod_opkg_find_package(const char *package_name) +int swmod_update_package(const char *package_path, const char *environment) { - pkg_t *pkg = opkg_find_package(package_name, NULL, NULL, NULL); - - return (pkg) ? true : false; +#ifdef SWMOD_LXC + if (environment && *environment != '\0' && (strcmp(environment, HOST_SYSTEM) != 0)) + return swmod_lxc_install_update_remove_package(package_path, environment, SWMOD_UPDATE); +#endif + return (environment && *environment != '\0' && (strcmp(environment, HOST_SYSTEM) == 0)) ? swmod_host_system_update_package(package_path) : -1; } -void swmod_opkg_find_package_with_version_and_config(const char *package_name, char **version, char **config) +int swmod_remove_package(const char *package_name, const char *environment) { - pkg_t *pkg = opkg_find_package(package_name, NULL, NULL, NULL); - - if (!pkg) - return; - - char *pkg_version = pkg_version_str_alloc(pkg); - *version = strdup(pkg_version); - FREE(pkg_version); - - // for now, we can not use opkg API to read vendor and description and url - // so, we will read them from "/usr/lib/opkg/info/*.control" file - - //const char *vendor = pkg_get_string(pkg, PKG_MAINTAINER); - //const char *description = pkg_get_string(pkg, PKG_DESCRIPTION); - - char *spch = NULL; - str_list_elt_t *iter; - str_list_t *files = pkg_get_installed_files(pkg); - for (iter = str_list_first(files); iter; iter = str_list_next(files, iter)) { - if ((spch = strstr((char *)iter->data, "/etc/config/"))) { - remove_new_line(spch); - *config = strdup(spch+12); - break; - } - } +#ifdef SWMOD_LXC + if (environment && *environment != '\0' && (strcmp(environment, HOST_SYSTEM) != 0)) + return swmod_lxc_install_update_remove_package(package_name, environment, SWMOD_REMOVE); +#endif + return (environment && *environment != '\0' && (strcmp(environment, HOST_SYSTEM) == 0)) ? swmod_host_system_remove_package(package_name) : -1; } diff --git a/swmod_opkg.h b/swmod_opkg.h index dcb41e4bb0a638aaf55c65e87ba22964ab293c89..ea4e13f48a9514cf801b26f15fd88252eb1271a8 100644 --- a/swmod_opkg.h +++ b/swmod_opkg.h @@ -23,20 +23,17 @@ #ifndef __SWMOD_OPKG_H #define __SWMOD_OPKG_H -#include <libopkg/opkg.h> - extern char package_name[64]; extern char package_version[64]; enum swmod_opkg_action_enum { SWMOD_INSTALL, + SWMOD_UPDATE, SWMOD_REMOVE }; -int swmod_opkg_new(void); -int swmod_opkg_free(void); -int swmod_install_remove_package(const char *package_path, const char *environment, int action); -bool swmod_opkg_find_package(const char *package_name); -void swmod_opkg_find_package_with_version_and_config(const char *package_name, char **version, char **config); +int swmod_install_package(const char *package_path, const char *environment); +int swmod_update_package(const char *package_path, const char *environment); +int swmod_remove_package(const char *package_name, const char *environment); #endif //__SWMOD_OPKG_H diff --git a/swmod_uci.c b/swmod_uci.c index cdd66254e45d8a64fb3c62135fcdc9d42a467707..99caebb4bc5182bdc09e3062cca908ce863ef357 100644 --- a/swmod_uci.c +++ b/swmod_uci.c @@ -80,7 +80,7 @@ static bool swmod_uci_validate_section(const char *str) return true; } -static int swmod_uci_init_ptr(struct uci_ptr *ptr, char *package, char *section, char *option, char *value) +static int swmod_uci_init_ptr(struct uci_ptr *ptr, const char *package, const char *section, const char *option, const char *value) { memset(ptr, 0, sizeof(struct uci_ptr)); @@ -115,7 +115,7 @@ error: return -1; } -struct uci_section *swmod_uci_walk_section(char *package, char *section_type, struct uci_section *prev_section) +struct uci_section *swmod_uci_walk_section(const char *package, const char *section_type, struct uci_section *prev_section) { struct uci_ptr ptr; struct uci_element *e; @@ -183,7 +183,7 @@ static struct uci_element *swmod_uci_lookup_list(struct uci_list *list, const ch return NULL; } -static int swmod_uci_lookup_ptr_by_section(struct uci_ptr *ptr, struct uci_section *section, char *option, char *value) +static int swmod_uci_lookup_ptr_by_section(struct uci_ptr *ptr, struct uci_section *section, const char *option, const char *value) { struct uci_element *e; memset(ptr, 0, sizeof(struct uci_ptr)); @@ -214,7 +214,7 @@ static int swmod_uci_lookup_ptr_by_section(struct uci_ptr *ptr, struct uci_secti return UCI_OK; } -char *swmod_uci_get_value_by_section(struct uci_section *section, char *option) +const char *swmod_uci_get_value_by_section(struct uci_section *section, const char *option) { struct uci_ptr ptr; char *val = ""; @@ -231,7 +231,7 @@ char *swmod_uci_get_value_by_section(struct uci_section *section, char *option) return val; } -char *swmod_uci_set_value_by_section(struct uci_section *section, char *option, char *value) +const char *swmod_uci_set_value_by_section(struct uci_section *section, const char *option, const char *value) { struct uci_ptr ptr; @@ -253,7 +253,7 @@ char *swmod_uci_set_value_by_section(struct uci_section *section, char *option, return ""; } -struct uci_section *swmod_uci_add_section(char *package, char *section_type) +struct uci_section *swmod_uci_add_section(const char *package, const char *section_type) { struct uci_ptr ptr; struct uci_section *s = NULL; @@ -273,7 +273,7 @@ struct uci_section *swmod_uci_add_section(char *package, char *section_type) return s; } -int swmod_uci_delete_by_section(struct uci_section *section, char *option, char *value) +int swmod_uci_delete_by_section(struct uci_section *section, const char *option, const char *value) { struct uci_ptr ptr = {0}; @@ -291,3 +291,16 @@ int swmod_uci_delete_by_section(struct uci_section *section, char *option, char return 0; } + +bool check_section_exist_by_option(const char *section, const char *section_type, const char *option, const char *val_check) +{ + struct uci_section *s; + + swmod_uci_foreach_section(section, section_type, s) { + const char *val = swmod_uci_get_value_by_section(s, option); + + if (strcmp(val, val_check) == 0) + return true; + } + return false; +} diff --git a/swmod_uci.h b/swmod_uci.h index f7c933dd4d632eeb940237474442654a994ab51e..895dca6898ce327eb7844fca35d457f38a57e129 100644 --- a/swmod_uci.h +++ b/swmod_uci.h @@ -28,13 +28,15 @@ int swmod_uci_init(const char *conf_path); int swmod_uci_fini(char *package_name); -struct uci_section *swmod_uci_add_section(char *package, char *section_type); -int swmod_uci_delete_by_section(struct uci_section *section, char *option, char *value); +struct uci_section *swmod_uci_add_section(const char *package, const char *section_type); +int swmod_uci_delete_by_section(struct uci_section *section, const char *option, const char *value); -char *swmod_uci_get_value_by_section(struct uci_section *section, char *option); -char *swmod_uci_set_value_by_section(struct uci_section *section, char *option, char *value); +const char *swmod_uci_get_value_by_section(struct uci_section *section, const char *option); +const char *swmod_uci_set_value_by_section(struct uci_section *section, const char *option, const char *value); -struct uci_section *swmod_uci_walk_section(char *package, char *section_type, struct uci_section *prev_section); +struct uci_section *swmod_uci_walk_section(const char *package, const char *section_type, struct uci_section *prev_section); + +bool check_section_exist_by_option(const char *section, const char *section_type, const char *option, const char *val_check); #define swmod_uci_foreach_section(package, section_type, section) \ for (section = swmod_uci_walk_section(package, section_type, NULL); \ diff --git a/tools.c b/tools.c index 6d916020c376ae126d68f15e4da421a30bca41cb..e1bc4e7232712ccd1b5bb1c5327c11d2df22f1b8 100644 --- a/tools.c +++ b/tools.c @@ -43,6 +43,16 @@ bool file_exists(const char *path) return stat(path, &statbuf) == 0; } +time_t get_file_mtime(const char *path) +{ + struct stat statbuf; + + if (stat(path, &statbuf) == -1) + return 0; + + return statbuf.st_mtime; +} + void remove_new_line(char *buf) { int len; @@ -74,7 +84,7 @@ char *generate_full_url(char *url, char *username, char *password) if ((!username && !password) || *username == '\0' || *password == '\0') return url; - static char buf[512]= {0}; + static char buf[512] = {0}; if (strncmp(url, "http://", 7) == 0) snprintf(buf, sizeof(buf), "http://%s:%s@%s", username, password, url+7); @@ -129,14 +139,14 @@ int synchronize_deployment_units_with_map_du_file(void) return 0; } -char *get_environment_from_map_du_file(const char *uuid) +const char *get_environment_from_map_du_file(const char *uuid) { - char *env = NULL; + const char *env = NULL; swmod_uci_init(SWMOD_PATH); struct uci_section *s = NULL; swmod_uci_foreach_section(SWMOD_MAP_DU, "deployment", s) { - char *map_uuid = swmod_uci_get_value_by_section(s, "uuid"); + const char *map_uuid = swmod_uci_get_value_by_section(s, "uuid"); if (strcmp(map_uuid, uuid) == 0) { env = swmod_uci_get_value_by_section(s, "environment"); break; @@ -172,7 +182,7 @@ char *get_environment_from_map_du_file(const char *uuid) swmod_uci_init(lxc_map_du_path); swmod_uci_foreach_section(SWMOD_MAP_DU, "deployment", s) { - char *map_uuid = swmod_uci_get_value_by_section(s, "uuid"); + const char *map_uuid = swmod_uci_get_value_by_section(s, "uuid"); if (strcmp(map_uuid, uuid) == 0) { env = swmod_uci_get_value_by_section(s, "environment"); break; @@ -194,7 +204,7 @@ void swmod_add_data_to_list(struct list_head *dup_list, char *cmd, int pid, unsi list_add_tail(&proc->list, dup_list); proc->cmd = strdup(cmd); proc->pid = pid; - proc->vsize= vsize; + proc->vsize = vsize; } static void swmod_delete_data_from_list(struct process_res *proc) diff --git a/tools.h b/tools.h index ad4dbf9a8f3d4f81ef773d56398b5f8568b37550..8dafe4d92d595898c2afe9e3523b281b2d303292 100644 --- a/tools.h +++ b/tools.h @@ -24,10 +24,12 @@ #define __TOOLS_H #include <string.h> +#include <stdlib.h> +#include <time.h> #include <libubox/list.h> #define SWMOD_PATH "/etc/swmod/" -#define OPKG_INFO_PATH "/usr/lib/opkg/info" +#define OPKG_INFO_PATH "/usr/lib/opkg/info/" #define SWMOD_MAP_DU "map_du" #define SWMOD_MAP_EU "map_eu" @@ -53,6 +55,7 @@ struct process_res }; bool file_exists(const char *path); +time_t get_file_mtime(const char *path); void remove_new_line(char *buf); void create_file(const char *path); void swmod_strncpy(char *dst, const char *src, size_t n); @@ -60,7 +63,7 @@ char *generate_full_url(char *url, char *username, char *password); char *generate_uuid(void); char *generate_duid(bool sysnchronise, int number); int synchronize_deployment_units_with_map_du_file(void); -char *get_environment_from_map_du_file(const char *uuid); +const char *get_environment_from_map_du_file(const char *uuid); void swmod_add_data_to_list(struct list_head *dup_list, char *cmd, int pid, unsigned int vsize); void swmod_free_data_from_list(struct list_head *dup_list); int populate_active_processes(struct list_head *dup_list);