sysmngr/src/configs.c
2026-02-26 10:54:51 +05:30

363 lines
12 KiB
C

/*
* Copyright (C) 2019-2024 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
*
*/
#include "utils.h"
#define CONFIG_BACKUP "/tmp/bbf_config_backup"
/*************************************************************
* COMMON FUNCTIONS
**************************************************************/
static int dmmap_synchronizeVcfInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
struct uci_section *s = NULL, *stmp = NULL;
DIR *dir;
struct dirent *d_file;
sysfs_foreach_file(DEFAULT_CONFIG_DIR, dir, d_file) {
if(d_file->d_name[0] == '.')
continue;
if (!is_dmmap_section_exist_eq("dmmap", "vcf", "name", d_file->d_name)) {
dmuci_add_section_bbfdm("dmmap", "vcf", &s);
dmuci_set_value_by_section(s, "name", d_file->d_name);
dmuci_set_value_by_section(s, "backup_restore", "1");
}
}
if (dir)
closedir (dir);
uci_path_foreach_sections_safe(bbfdm, "dmmap", "vcf", stmp, s) {
char cfg_path[128] = {0};
char *cfg_name = NULL;
dmuci_get_value_by_section_string(s, "name", &cfg_name);
snprintf(cfg_path, sizeof(cfg_path), "%s%s", DEFAULT_CONFIG_DIR, cfg_name);
if (!file_exists(cfg_path))
dmuci_delete_by_section_bbfdm(s, NULL, NULL);
}
return 0;
}
static int bbf_config_backup(struct ubus_context *ctx, const char *url, const char *username, const char *password,
char *config_name, const char *command, const char *obj_path, const char *cmd_key, const char *requestor)
{
int res = 0;
char fault_msg[128] = {0};
time_t complete_time = 0;
time_t start_time = time(NULL);
// Export config file to backup file
if (dmuci_export_package(config_name, CONFIG_BACKUP)) {
snprintf(fault_msg, sizeof(fault_msg), "Failed to export the configurations");
res = -1;
goto end;
}
// Upload the config file
long res_code = upload_file(CONFIG_BACKUP, url, username, password);
complete_time = time(NULL);
// Check if the upload operation was successful
if (!validate_server_response_code(url, res_code)) {
res = -1;
snprintf(fault_msg, sizeof(fault_msg), "Upload operation is failed, fault code (%ld)", res_code);
}
end:
// Send the transfer complete event
send_transfer_complete_event(ctx, command, obj_path, url, fault_msg, start_time, complete_time, cmd_key, "Upload", requestor);
// Remove temporary file
if (file_exists(CONFIG_BACKUP) && remove(CONFIG_BACKUP))
res = -1;
return res;
}
static int bbf_config_restore(struct ubus_context *ctx, const char *url, const char *username, const char *password,
const char *file_size, const char *checksum_algorithm, const char *checksum,
const char *command, const char *obj_path, const char *cmd_key, const char *requestor)
{
char config_restore[256] = {0};
int res = 0;
char fault_msg[128] = {0};
time_t complete_time = 0;
time_t start_time = time(NULL);
DM_STRNCPY(config_restore, "/tmp/bbf_config_restore", sizeof(config_restore));
// Check the file system size if there is sufficient space for downloading the config file
if (!validate_file_system_size(file_size)) {
snprintf(fault_msg, sizeof(fault_msg), "Available memory space is less than required for the operation");
res = -1;
goto end;
}
// Download the firmware image
long res_code = download_file(config_restore, url, username, password);
complete_time = time(NULL);
// Check if the download operation was successful
if (!validate_server_response_code(url, res_code)) {
snprintf(fault_msg, sizeof(fault_msg), "Upload operation is failed, fault code (%ld)", res_code);
res = -1;
goto end;
}
// Validate the CheckSum value according to its algorithm
if (!validate_checksum_value(config_restore, checksum_algorithm, checksum)) {
snprintf(fault_msg, sizeof(fault_msg), "Checksum of the downloaded file is mismatched");
res = -1;
goto end;
}
// Apply config file
if (dmuci_import(NULL, config_restore)) {
snprintf(fault_msg, sizeof(fault_msg), "Failed to import the configurations");
res = -1;
} else {
// Need to remove dmmap
dmuci_set_value_varstate("dmmap", "dmmap", "cleanup", "1");
dmuci_commit_package_varstate("dmmap");
}
end:
// Send the transfer complete event
send_transfer_complete_event(ctx, command, obj_path, url, fault_msg, start_time, complete_time, cmd_key, "Download", requestor);
// Remove temporary file
if (file_exists(config_restore) && strncmp(url, FILE_URI, strlen(FILE_URI)) && remove(config_restore))
res = -1;
return res;
}
/*************************************************************
* ENTRY METHOD
**************************************************************/
int browseVcfInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
struct dm_data curr_data = {0};
struct uci_section *s = NULL;
char *inst = NULL;
dmmap_synchronizeVcfInst(dmctx, parent_node, prev_data, prev_instance);
uci_path_foreach_sections(bbfdm, "dmmap", "vcf", s) {
curr_data.config_section = s;
inst = handle_instance(dmctx, parent_node, s, "vcf_instance", "vcf_alias");
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&curr_data, inst) == DM_STOP)
break;
}
return 0;
}
/*************************************************************
* GET & SET PARAM
**************************************************************/
int get_DeviceInfo_VendorConfigFileNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
int cnt = get_number_of_entries(ctx, data, instance, browseVcfInst);
dmasprintf(value, "%d", cnt);
return 0;
}
static int get_vcf_name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "name", value);
return 0;
}
static int get_vcf_version(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "version", value);
return 0;
}
static int get_vcf_date(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
DIR *dir = NULL;
struct dirent *d_file = NULL;
char *config_name = NULL;
*value = dmstrdup("0001-01-01T00:00:00Z");
dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "name", &config_name);
if ((dir = opendir (DEFAULT_CONFIG_DIR)) != NULL) {
while ((d_file = readdir (dir)) != NULL) {
if (config_name && DM_STRCMP(config_name, d_file->d_name) == 0) {
char date[sizeof("AAAA-MM-JJTHH:MM:SSZ")], path[280] = {0};
struct stat attr;
snprintf(path, sizeof(path), "%s%s", DEFAULT_CONFIG_DIR, d_file->d_name);
stat(path, &attr);
strftime(date, sizeof(date), "%Y-%m-%dT%H:%M:%SZ", gmtime(&attr.st_mtime));
*value = dmstrdup(date);
}
}
closedir (dir);
}
return 0;
}
static int get_vcf_backup_restore(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "backup_restore", value);
return 0;
}
static int get_vcf_desc(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "description", value);
return 0;
}
static int get_vcf_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
return bbf_get_alias(ctx, ((struct dm_data *)data)->config_section, "vcf_alias", instance, value);
}
static int set_vcf_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
return bbf_set_alias(ctx, ((struct dm_data *)data)->config_section, "vcf_alias", instance, value);
}
/*************************************************************
* OPERATE COMMANDS
*************************************************************/
static operation_args vendor_config_file_backup_args = {
.in = (const char *[]) {
"URL",
"Username",
"Password",
NULL
}
};
static int get_operate_args_DeviceInfoVendorConfigFile_Backup(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = (char *)&vendor_config_file_backup_args;
return 0;
}
static int operate_DeviceInfoVendorConfigFile_Backup(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
char backup_command[270] = {0};
char backup_path[256] = {'\0'};
char *vcf_name = NULL;
char *cmdkey = NULL, *reqst = NULL;
char *ret = DM_STRRCHR(refparam, '.');
if (!ret)
return USP_FAULT_INVALID_ARGUMENT;
if ((ret - refparam + 2) < sizeof(backup_path)) {
snprintf(backup_path, ret - refparam + 2, "%s", refparam);
}
if (ctx->dm_type == BBFDM_USP) {
snprintf(backup_command, sizeof(backup_command), "%s", refparam);
cmdkey = dmjson_get_value((json_object *)value, 1, "__BBF_CommandKey");
reqst = dmjson_get_value((json_object *)value, 1, "__BBF_Requestor");
}
char *url = dmjson_get_value((json_object *)value, 1, "URL");
if (url[0] == '\0')
return USP_FAULT_INVALID_ARGUMENT;
char *user = dmjson_get_value((json_object *)value, 1, "Username");
char *pass = dmjson_get_value((json_object *)value, 1, "Password");
dmuci_get_value_by_section_string(((struct dm_data *)data)->config_section, "name", &vcf_name);
int res = bbf_config_backup(ctx->ubus_ctx, url, user, pass, vcf_name, backup_command, backup_path, cmdkey, reqst);
return res ? USP_FAULT_COMMAND_FAILURE : 0;
}
static operation_args vendor_config_file_restore_args = {
.in = (const char *[]) {
"URL",
"Username",
"Password",
"FileSize",
"TargetFileName",
"CheckSumAlgorithm",
"CheckSum",
NULL
}
};
static int get_operate_args_DeviceInfoVendorConfigFile_Restore(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = (char *)&vendor_config_file_restore_args;
return 0;
}
static int operate_DeviceInfoVendorConfigFile_Restore(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
char restore_command[270] = {0};
char restore_path[256] = {'\0'};
char *cmd_key = NULL, *reqstr = NULL;
char *ret = DM_STRRCHR(refparam, '.');
if (!ret)
return USP_FAULT_INVALID_ARGUMENT;
if ((ret - refparam + 2) < sizeof(restore_path)) {
snprintf(restore_path, ret - refparam + 2, "%s", refparam);
}
if (ctx->dm_type == BBFDM_USP) {
snprintf(restore_command, sizeof(restore_command), "%s", refparam);
cmd_key = dmjson_get_value((json_object *)value, 1, "__BBF_CommandKey");
reqstr = dmjson_get_value((json_object *)value, 1, "__BBF_Requestor");
}
char *url = dmjson_get_value((json_object *)value, 1, "URL");
if (url[0] == '\0')
return USP_FAULT_INVALID_ARGUMENT;
char *user = dmjson_get_value((json_object *)value, 1, "Username");
char *pass = dmjson_get_value((json_object *)value, 1, "Password");
char *file_size = dmjson_get_value((json_object *)value, 1, "FileSize");
char *checksum_algorithm = dmjson_get_value((json_object *)value, 1, "CheckSumAlgorithm");
char *checksum = dmjson_get_value((json_object *)value, 1, "CheckSum");
int res = bbf_config_restore(ctx->ubus_ctx, url, user, pass, file_size, checksum_algorithm, checksum, restore_command, restore_path, cmd_key, reqstr);
return res ? USP_FAULT_COMMAND_FAILURE : 0;
}
/**********************************************************************************************************************************
* OBJ & LEAF DEFINITION
***********************************************************************************************************************************/
/* *** Device.DeviceInfo.VendorConfigFile.{i}. *** */
DMLEAF tDeviceInfoVendorConfigFileParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Alias", &DMWRITE, DMT_STRING, get_vcf_alias, set_vcf_alias, BBFDM_BOTH, DM_FLAG_UNIQUE},
{"Name", &DMREAD, DMT_STRING, get_vcf_name, NULL, BBFDM_BOTH, DM_FLAG_UNIQUE},
{"Version", &DMREAD, DMT_STRING, get_vcf_version, NULL, BBFDM_BOTH},
{"Date", &DMREAD, DMT_TIME, get_vcf_date, NULL, BBFDM_BOTH},
{"Description", &DMREAD, DMT_STRING, get_vcf_desc, NULL, BBFDM_BOTH},
{"UseForBackupRestore", &DMREAD, DMT_BOOL, get_vcf_backup_restore, NULL, BBFDM_BOTH},
{"Backup()", &DMASYNC, DMT_COMMAND, get_operate_args_DeviceInfoVendorConfigFile_Backup, operate_DeviceInfoVendorConfigFile_Backup, BBFDM_USP},
{"Restore()", &DMASYNC, DMT_COMMAND, get_operate_args_DeviceInfoVendorConfigFile_Restore, operate_DeviceInfoVendorConfigFile_Restore, BBFDM_USP},
{0}
};