diff --git a/README.md b/README.md index d24d9c3bd2c78dcfabcb59b7b665c37277503792..b5ffd56c181152f1465a65cfc2488fec26e61e01 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ Currently, `swmodd` can not create new execution environment and it depends on p root@iopsys:~# ubus -v list swmodules 'swmodules' @b09f9fc4 "environment":{} - "du_list":{} - "eu_list":{} + "du_list":{"eid":"Integer"} + "eu_list":{"eid":"Integer"} "du_install":{"url":"String","uuid":"String","username":"String","password":"String","environment":"String"} "du_update":{"uuid":"String","url":"String","username":"String","password":"String"} "du_uninstall":{"name":"String","environment":"String"} @@ -115,6 +115,7 @@ root@iopsys:~# ubus call swmodules environment "environment": [ { "name": "OpenWRT_Linux", + "eid" : "1", "status": "Up", "type": "Linux", "vendor": "iopsys", @@ -136,6 +137,7 @@ root@iopsys:~# ubus call swmodules du_list { "name": "6in4", "environment": "OpenWRT_Linux", + "eid": "1", "uuid": "5f085cf2-ca02-44c8-8697-212585505b35", "duid": "04n0000", "url": "", @@ -147,6 +149,7 @@ root@iopsys:~# ubus call swmodules du_list { "name": "6rd", "environment": "OpenWRT_Linux", + "eid": "1", "uuid": "f10d5aea-ee7f-4144-8232-39b6c5541958", "duid": "04n0001", "url": "", @@ -159,6 +162,7 @@ root@iopsys:~# ubus call swmodules du_list { "name": "zoneinfo-europe", "environment": "OpenWRT_Linux", + "eid": "1", "uuid": "cac5b136-0eed-4d2c-8567-a2ad368102aa", "duid": "04n0363", "url": "", @@ -180,10 +184,12 @@ root@iopsys:~# ubus call swmodules eu_list { "name": "dnsmasq", "command": "/usr/sbin/dnsmasq", + "state" : "Active", "config": "dhcp", "version": "2.85-5", "description": "It is intended to provide coupled DNS and DHCP service to a LAN.", "environment": "OpenWRT_Linux", + "eid" : "2", "euid": 6338, "disk_space": 130094, "memory_space": 1248, @@ -192,10 +198,12 @@ root@iopsys:~# ubus call swmodules eu_list { "name": "ethmngr", "command": "/usr/sbin/ethmngr", + "state" : "Active", "config": "", "version": "2.0.1", "description": "This package can be used to configure and provide status about", "environment": "OpenWRT_Linux", + "eid" : "2", "euid": 7525, "disk_space": 4942, "memory_space": 4460, @@ -205,10 +213,12 @@ root@iopsys:~# ubus call swmodules eu_list { "name": "wifimngr", "command": "/usr/sbin/wifimngr", + "state" : "Active", "config": "", "version": "11.2.0", "description": "This package can be used to configure and provide status about", "environment": "OpenWRT_Linux", + "eid" : "2", "euid": 7704, "disk_space": 31394, "memory_space": 4688, @@ -239,8 +249,9 @@ root@iopsys:~# ubus call swmodules du_uninstall '{"name":"wfadatad", "environmen } ``` ## Limitations -- `swmodd` depend on `opkg` for downloading and installing services, which currently supports `http://`, `ftp://` or local system path as a url for installing and upgrading services. - `swmodd` can only manage host and pre-created lxc containers +- `swmodd` in du_list only shows information about the packages from `opkg list` which has services registered in init.d +- `swmodd` in eu_list only shows information about the packages present in `ubus call service list` ## Dependencies `swmodd` compile time and run time dependencies. @@ -257,6 +268,7 @@ To successfully build `swmodd`, the following libraries are needed: | liblxc | https://linuxcontainers.org/downloads/lxc/ | LGPL-2.1-or-later BSD-2-Clause GPL-2.0 | | opkg | https://git.openwrt.org/project/opkg-lede.git | GPL-2.0 | | libuuid | util-linux | GPL-2.0 | +| libcurl | https://dl.uxnr.de/mirror/curl | MIT | ### Run-Time Dependencies @@ -269,6 +281,7 @@ In order to run the `swmodd`, following dependencies are needed to be running/av | bbf | https://dev.iopsys.eu/iopsys/bbf.git | LGPL 2.1 | | opkg | https://git.openwrt.org/project/opkg-lede.git | GPL-2.0 | | uspd | https://dev.iopsys.eu/iopsys/uspd.git | GPL-2.0 | +| libcurl | https://dl.uxnr.de/mirror/curl | MIT | Apart from these dependencies, LXC-4.0 > also requires cgroup functionalities to be mounted separately, to do so, `cgroupfs-mount` package is used. > `uspd` along with `bbf` is used to expose the SoftwareModule datamodel objects. diff --git a/src/Makefile b/src/Makefile index dc54ceeaf4910a6bbe129bbde5c3d2b4f32e4681..c9ebbb1d1f0697879edf807054cb58a2565d04f7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,7 +9,7 @@ OBJS = swmod.o swmod_host.o swmod_opkg.o swmod_uci.o tools.o LIB_OBJS = datamodel.o PROG_CFLAGS = $(CFLAGS) -fstrict-aliasing -Wall -Werror -fPIC -PROG_LDFLAGS = $(LDFLAGS) -luci -lubus -lubox -lblobmsg_json -luuid +PROG_LDFLAGS = $(LDFLAGS) -luci -lubus -lubox -lblobmsg_json -luuid -lcurl ifeq ($(SWMOD_LXC),yes) OBJS += swmod_lxc.o diff --git a/src/swmod.c b/src/swmod.c index 89973eb8d8660f2cf694659d92f4a215e87292a0..85fe62b12753e38ad5640b57c7e18892485ad3d1 100644 --- a/src/swmod.c +++ b/src/swmod.c @@ -24,6 +24,7 @@ #include <unistd.h> #include <dirent.h> #include <libubox/uloop.h> +#include <curl/curl.h> #include "swmod_uci.h" #include "swmod_opkg.h" @@ -34,6 +35,8 @@ #include "swmod_lxc.h" #endif +#define DW_PKG_PATH "/tmp/dw_package.ipk" + struct ubus_context *ubus_ctx; ExecEnv environments[MAX_ENV] = {0}; ExecUnit exec_units[MAX_ENV] = {0}; @@ -248,6 +251,47 @@ int update_map_du_file(struct blob_buf *bb, char *pkg_name, return 0; } +static int download_remote_package(const char *url, char *username, char *password) +{ + long res_code = 0; + + CURL *curl = curl_easy_init(); + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, url); + + if (username) + curl_easy_setopt(curl, CURLOPT_USERNAME, username); + + if (password) + curl_easy_setopt(curl, CURLOPT_PASSWORD, password); + + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 100); + + FILE *fp = fopen(DW_PKG_PATH, "wb"); + if (fp) { + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + curl_easy_perform(curl); + fclose(fp); + } else { + curl_easy_cleanup(curl); + return -1; + } + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_code); + curl_easy_cleanup(curl); + + if ((strncmp(url, "http", 4) == 0 && res_code != 200) || + (strncmp(url, "ftp", 3) == 0 && res_code != 226) || + (strncmp(url, "http", 4) && strncmp(url, "ftp", 3))) { + return -1; + } + + return 0; + } + + return -1; +} + static int swmod_du_install(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, @@ -255,31 +299,41 @@ swmod_du_install(struct ubus_context *ctx, struct ubus_object *obj, { struct blob_attr *tb[__DU_INSTALL_MAX] = {NULL}; struct blob_buf bb; - int eid = 0; + int eid = 0, err = -1; + char url[2048] = {0}; + bool remote_file = false; if (blobmsg_parse(du_install_policy, __DU_INSTALL_MAX, tb, blob_data(msg), blob_len(msg))) return UBUS_STATUS_UNKNOWN_ERROR; - if (!tb[DU_INSTALL_URL]) - return UBUS_STATUS_INVALID_ARGUMENT; - - //synchronize_deployment_units_with_map_du_file(); - - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - - char *full_url = generate_full_url(blobmsg_get_string(tb[DU_INSTALL_URL]), - blobmsg_get_string(tb[DU_INSTALL_USERNAME]), - blobmsg_get_string(tb[DU_INSTALL_PASSWORD])); - if (tb[DU_INSTALL_ENV_ID]) eid = blobmsg_get_u32(tb[DU_INSTALL_ENV_ID]); if (tb[DU_INSTALL_ENV]) eid = get_eid_from_env_name(blobmsg_get_string(tb[DU_INSTALL_ENV])); - int err = swmod_install_package(full_url, eid); + if (!tb[DU_INSTALL_URL]) + return UBUS_STATUS_INVALID_ARGUMENT; + + snprintf(url, sizeof(url), "%s", blobmsg_get_string(tb[DU_INSTALL_URL])); + if (strchr(url, ':') != NULL) { + /* This is a remote package, need to download first */ + if(0 != download_remote_package(url, blobmsg_get_string(tb[DU_INSTALL_USERNAME]), + blobmsg_get_string(tb[DU_INSTALL_PASSWORD]))) { + goto end; + } + + snprintf(url, sizeof(url), "%s", DW_PKG_PATH); + remote_file = true; + } + + err = swmod_install_package(url, eid, remote_file); + + //synchronize_deployment_units_with_map_du_file(); +end: + memset(&bb, 0, sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); blobmsg_add_u8(&bb, "status", (err) ? false : true); ubus_send_reply(ctx, req, bb.head); @@ -332,8 +386,9 @@ swmod_du_update(struct ubus_context *ctx, struct ubus_object *obj, { struct blob_attr *tb[__DU_UPDATE_MAX] = {NULL}; struct blob_buf bb; - char *full_url; - int eid, err; + char url[2048] = {0}; + int eid = 0, err = -1; + bool remote_file = false; if (blobmsg_parse(du_update_policy, __DU_UPDATE_MAX, tb, blob_data(msg), blob_len(msg))) return UBUS_STATUS_UNKNOWN_ERROR; @@ -341,18 +396,28 @@ swmod_du_update(struct ubus_context *ctx, struct ubus_object *obj, if (!tb[DU_UPDATE_URL] || !tb[DU_UPDATE_UUID] || !tb[DU_UPDATE_ENV_ID]) return UBUS_STATUS_INVALID_ARGUMENT; + eid = blobmsg_get_u32(tb[DU_UPDATE_ENV_ID]); + + snprintf(url, sizeof(url), "%s", blobmsg_get_string(tb[DU_UPDATE_URL])); + if (strchr(url, ':') != NULL) { + /* This is a remote package, need to download first */ + if (0 != download_remote_package(url, blobmsg_get_string(tb[DU_UPDATE_USERNAME]), + blobmsg_get_string(tb[DU_UPDATE_PASSWORD]))) { + goto end; + } + + snprintf(url, sizeof(url), "%s", DW_PKG_PATH); + remote_file = true; + } + + err = swmod_update_package(url, eid, remote_file); + //synchronize_deployment_units_with_map_du_file(); +end: memset(&bb, 0, sizeof(struct blob_buf)); blob_buf_init(&bb, 0); - full_url = generate_full_url(blobmsg_get_string(tb[DU_UPDATE_URL]), - blobmsg_get_string(tb[DU_UPDATE_USERNAME]), - blobmsg_get_string(tb[DU_UPDATE_PASSWORD])); - - eid = blobmsg_get_u32(tb[DU_UPDATE_ENV_ID]); - err = swmod_update_package(full_url, eid); - blobmsg_add_u8(&bb, "status", (!err) ? true : false); ubus_send_reply(ctx, req, bb.head); diff --git a/src/swmod_lxc.c b/src/swmod_lxc.c index 808b118ae94ee26bfe0d3b37b762840ae77fe930..8e1fea6460bec13882b0b01960ac7d14b7f305de 100644 --- a/src/swmod_lxc.c +++ b/src/swmod_lxc.c @@ -41,7 +41,6 @@ #define LXC_PATH "lxc.lxcpath" static char *g_lxc_buff; -static char lxc_hash[64] = {0}; typedef struct lxc_attach_args { const char *lxcpath; @@ -306,93 +305,6 @@ void populate_lxc_eu(void) } /************************** Deployment/Execution Unit **************************/ -int lxc_attach_run_deployment_unit_func(void *args) -{ - char map_du_path[32] = {0}; - unsigned int um = 0; - lxc_attach_args *data = (lxc_attach_args *)args; - - if (!data || *(data->lxcpath) == '\0' || *(data->value) == '\0') { - PRINT_ERR("No data from attach function"); - return -1; - } - - snprintf(map_du_path, sizeof(map_du_path), "%s%s", SWMOD_PATH, SWMOD_MAP_DU); - - time_t tm = get_file_mtime(OPKG_INFO_PATH); - - sscanf(lxc_hash, "%u", &um); - if (tm == um) { - PRINT_INFO("Invalid lxc hash"); - return -1; - } - - if (swmod_uci_init(SWMOD_PATH)) { - PRINT_ERR("Failed to init swmodd uci"); - return -1; - } - - create_file(map_du_path); //create empty file if does not exists - - struct uci_section *ss = NULL, *stmp = NULL; - char pname[256] = {0}; - FILE *log; - - swmod_uci_foreach_section_safe(SWMOD_MAP_DU, "deployment", stmp, ss) { - const char *map_du_name = swmod_uci_get_value_by_section(ss, "name"); - - snprintf(pname, sizeof(pname), OPKG_INFO_PATH"%s.control", map_du_name); - - /* Check package name exists, if no => remove the section */ - if (!file_exists(pname)) - swmod_uci_delete_by_section(ss, NULL, NULL); - } - - - if ((log = popen("opkg list", "r"))) { - char buff[256] = {0}; - - while (fgets(buff, sizeof(buff), log) != NULL) { - char name[64] = {0}; - char version[64] = {0}; - - /* Get name and version for each buff */ - if (sscanf(buff, "%63s - %63s", name, version)) { - - /* Check if package name exists */ - if (check_section_exist_by_option("map_du", "deployment", "name", name)) - continue; - - struct uci_section *uci_s = swmod_uci_add_section(SWMOD_MAP_DU, "deployment"); - static int incr = 0; - - /* Generate UUID */ - char *uuid = generate_uuid(); - - /* Generate DUID */ - char *duid = generate_duid(true, incr++); - - swmod_uci_set_value_by_section(uci_s, "name", name); - swmod_uci_set_value_by_section(uci_s, "version", version); - swmod_uci_set_value_by_section(uci_s, "uuid", uuid); - swmod_uci_set_value_by_section(uci_s, "duid", duid); - swmod_uci_set_value_by_section(uci_s, "environment", data->value); - - /* Freed all allocated memory */ - FREE(uuid); - FREE(duid); - } - } - pclose(log); - } - - swmod_uci_fini(SWMOD_MAP_DU); - - snprintf(lxc_hash, sizeof(lxc_hash), "%u", (unsigned int)tm); - - return 0; -} - void populate_lxc_du(int eid) { const char *lxcpath = NULL; @@ -568,6 +480,71 @@ static int lxc_attach_run_opkg_method_func(void *args) return err; } +static int copy_file_to_lxc(const char *host_file, const char *lxc_file) +{ + FILE *source, *target; + size_t n; + char buff[1000] = {0}; + + source = fopen(host_file, "rb"); + if (!source) + return -1; + + target = fopen(lxc_file, "wb"); + if (!target) { + fclose(source); + return -1; + } + + while ((n = fread(buff, 1, sizeof(buff), source)) != 0) + fwrite(buff, 1, n, target); + + fclose(source); + fclose(target); + + return 0; +} + +int swmod_lxc_copy_file_from_host(int cid, const char *package_path, char *lxc_pkg_path, int size) +{ + struct lxc_container **clist = NULL; + const char *lxcpath = NULL; + struct lxc_container *ct = NULL; + int ret = -1; + + if (!package_path || !lxc_pkg_path) + return ret; + + if (!lxc_is_supported(&lxcpath)) { + PRINT_ERR("LXC not supported"); + return ret; + } + + int lxc_nbr = list_all_containers(lxcpath, NULL, &clist); + if (cid >= lxc_nbr) { + PRINT_ERR("Container does not exists at cid %d", cid); + goto end; + } + + ct = clist[cid]; + if (!ct->is_running(ct)) { + lxc_container_put(ct); + goto end; + } + + snprintf(lxc_pkg_path, size, "%s/%s/rootfs%s", lxcpath, ct->name, package_path); + if (0 != copy_file_to_lxc(package_path, lxc_pkg_path)) { + goto end; + } + + ret = 0; + +end: + if (lxc_nbr > 0) + FREE(clist); + return ret; +} + int swmod_lxc_install_update_remove_package(const char *package_path, int cid, int action) { struct lxc_container **clist = NULL; diff --git a/src/swmod_lxc.h b/src/swmod_lxc.h index f29f6a5bce0ab9c0bbcd54264f9a1a2eafe16bad..3cf195906d0605a72a2fa311b90ce2489cd8a75e 100644 --- a/src/swmod_lxc.h +++ b/src/swmod_lxc.h @@ -35,5 +35,6 @@ void populate_lxc_du(int eid); int swmod_lxc_install_update_remove_package(const char *package_path, int eid, int action); void populate_lxc_eu(void); void get_pid_details_lxc(struct lxc_container *ct, int pid, char *cmdline, int *vsize); +int swmod_lxc_copy_file_from_host(int cid, const char *package_path, char *lxc_pkg_path, int size); #endif //LXC_H diff --git a/src/swmod_opkg.c b/src/swmod_opkg.c index 808b53505c3d60413aa35c6c2c995dac468d57d7..59aa0f2ce8c2a993bfbe2f74794a4f47ab5c63ed 100644 --- a/src/swmod_opkg.c +++ b/src/swmod_opkg.c @@ -105,55 +105,81 @@ int swmod_host_system_remove_package(const char *pname) return err; } -int swmod_install_package(const char *package_path, int eid) +int swmod_install_package(const char *package_path, int eid, bool dw_file) { int index = 0; int ret = -1; if (eid >= MAX_ENV || eid <= 0) - return -1; + goto end; index = eid - 1; if (!environments[index].exists) - return ret; + goto end; PRINT_INFO("Installing [%s] in[%s]", package_path, environments[index].name); if (strcmp(environments[index].name, HOST_SYSTEM) == 0) { ret = swmod_host_system_install_package(package_path); } else { #ifdef SWMOD_LXC - ret = swmod_lxc_install_update_remove_package(package_path, index - 1, SWMOD_INSTALL); + if (dw_file) { + char lxc_pkg_path[1024] = {0}; + ret = swmod_lxc_copy_file_from_host(index - 1, package_path, lxc_pkg_path, sizeof(lxc_pkg_path)); + if (ret == 0) { + ret = swmod_lxc_install_update_remove_package(package_path, index - 1, SWMOD_INSTALL); + remove(lxc_pkg_path); + } + } else { + ret = swmod_lxc_install_update_remove_package(package_path, index - 1, SWMOD_INSTALL); + } #else ret = -1; #endif } +end: + if (dw_file) + remove(package_path); + return ret; } -int swmod_update_package(const char *pkg, int eid) +int swmod_update_package(const char *pkg, int eid, bool dw_file) { int index = 0; int ret = -1; if (eid >= MAX_ENV || eid <= 0) - return -1; + goto end; index = eid - 1; if (!environments[index].exists) - return ret; + goto end; PRINT_INFO("update [%s] in[%s]", pkg, environments[index].name); if (strcmp(environments[index].name, HOST_SYSTEM) == 0) { ret = swmod_host_system_update_package(pkg); } else { #ifdef SWMOD_LXC - ret = swmod_lxc_install_update_remove_package(pkg, index - 1, SWMOD_UPDATE); + if (dw_file) { + char lxc_pkg_path[1024] = {0}; + ret = swmod_lxc_copy_file_from_host(index - 1, pkg, lxc_pkg_path, sizeof(lxc_pkg_path)); + if (ret == 0) { + ret = swmod_lxc_install_update_remove_package(pkg, index - 1, SWMOD_UPDATE); + remove(lxc_pkg_path); + } + } else { + ret = swmod_lxc_install_update_remove_package(pkg, index - 1, SWMOD_UPDATE); + } #else ret = -1; #endif } +end: + if (dw_file) + remove(pkg); + return ret; } @@ -307,8 +333,14 @@ void populate_opkg_deployment_unit(int eid, const char *opkg_root, const char *d continue; /* Check if package name exists */ - if (check_section_exist_by_option(conf, "deployment", "name", name)) + struct uci_section *sec; + if (check_section_exist_by_option(conf, "deployment", "name", name, &sec)) { + const char *val = swmod_uci_get_value_by_section(sec, "version"); + if (strcmp(val, version) != 0) { + swmod_uci_set_value_by_section(sec, "version", version); + } continue; + } struct uci_section *new_s = swmod_uci_add_section(conf, "deployment"); static int incr = 0; diff --git a/src/swmod_opkg.h b/src/swmod_opkg.h index b2257192e3686ff36eb793d04d40ecb99561dcab..175530179231e53a56a161bf7c10c73f742c1aa1 100644 --- a/src/swmod_opkg.h +++ b/src/swmod_opkg.h @@ -32,8 +32,8 @@ enum swmod_opkg_action_enum { SWMOD_REMOVE }; -int swmod_install_package(const char *package_path, int eid); -int swmod_update_package(const char *package_path, int eid); +int swmod_install_package(const char *package_path, int eid, bool dw_file); +int swmod_update_package(const char *package_path, int eid, bool dw_file); int swmod_remove_package(const char *pname, int eid); int swmod_host_system_remove_package(const char *pname); void populate_opkg_deployment_unit(int eid, const char *opkg_root, const char *du_ext); diff --git a/src/swmod_uci.c b/src/swmod_uci.c index 1059fefe675a5643e196331e51a131bec0d89276..341358345d5cab27b84a3114160ddc09f87f9026 100644 --- a/src/swmod_uci.c +++ b/src/swmod_uci.c @@ -325,12 +325,10 @@ int swmod_uci_delete_by_section(struct uci_section *section, const char *option, return 0; } -bool check_section_exist_by_option(const char *section, const char *section_type, const char *option, const char *val_check) +bool check_section_exist_by_option(const char *section, const char *section_type, const char *option, const char *val_check, struct uci_section **s) { - struct uci_section *s; - - swmod_uci_foreach_section(section, section_type, s) { - const char *val = swmod_uci_get_value_by_section(s, option); + 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; diff --git a/src/swmod_uci.h b/src/swmod_uci.h index 6443d6bfcbb1b595fc04bc943c0ed51f2fd9d9ad..a164ff7a783d1712b6d39f77d28c8f8efbc9fe92 100644 --- a/src/swmod_uci.h +++ b/src/swmod_uci.h @@ -37,7 +37,7 @@ const char *swmod_uci_set_value_by_section_list(struct uci_section *section, con 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); +bool check_section_exist_by_option(const char *section, const char *section_type, const char *option, const char *val_check, struct uci_section **s); #define swmod_uci_foreach_section(package, section_type, section) \ for (section = swmod_uci_walk_section(package, section_type, NULL); \ diff --git a/src/tools.c b/src/tools.c index 88f12d0887c2d4957a93b69cc7bafe82768c8132..d2fe5dd72e5bd2e844696824e5f36d873ef88f32 100644 --- a/src/tools.c +++ b/src/tools.c @@ -153,21 +153,6 @@ void swmod_strncpy(char *dst, const char *src, size_t n) dst[n - 1] = 0; } -char *generate_full_url(char *url, char *username, char *password) -{ - if ((!username && !password) || *username == '\0' || *password == '\0') - return url; - - static char buf[512] = {0}; - - if (strncmp(url, "http://", 7) == 0) - snprintf(buf, sizeof(buf), "http://%s:%s@%s", username, password, url+7); - else if (strncmp(url, "ftp://", 6) == 0) - snprintf(buf, sizeof(buf), "ftp://%s:%s@%s", username, password, url+6); - - return buf; -} - char *generate_uuid(void) { uuid_t binuuid; diff --git a/src/tools.h b/src/tools.h index 82eece18004e0a87ed5340096579376fc9e4af93..3a4e016b5f1fdb0993dadeb93df16c22c308cb45 100644 --- a/src/tools.h +++ b/src/tools.h @@ -61,7 +61,6 @@ 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); -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);