Added support for setting a list of references

This commit is contained in:
Amin Ben Romdhane 2025-02-26 14:56:56 +01:00
parent 0327469ad8
commit 1c417534a8
5 changed files with 91 additions and 27 deletions

View file

@ -111,6 +111,33 @@ static void sync_callback(struct ubus_request *req, int type __attribute__((unus
}
}
static void generate_reference_to_set(const char *in_value, char *output_str, size_t output_str_len)
{
char token_buffer[MAX_VALUE_LENGTH] = {0};
char *token = NULL, *saveptr = NULL;
unsigned pos = 0;
if (!output_str || output_str_len == 0)
return;
output_str[0] = '\0'; // Ensure output buffer is initialized
if (!in_value || in_value[0] == '\0') // Empty value, nothing to make
return;
bbfdm_strncpy(token_buffer, in_value, sizeof(token_buffer));
for (token = strtok_r(token_buffer, ",", &saveptr); token; token = strtok_r(NULL, ",", &saveptr)) {
char *reference_value = get_reference_data(token, "reference_value");
pos += snprintf(&output_str[pos], output_str_len - pos, "%s=>%s##,", token, reference_value ? reference_value : "");
BBFDM_FREE(reference_value);
}
if (pos > 0) {
output_str[pos - 1] = 0; // Remove trailing comma
}
}
void run_sync_call(const char *ubus_obj, const char *ubus_method, struct blob_attr *msg, struct blob_buf *bb_response)
{
struct blob_buf req_buf = {0};
@ -128,13 +155,10 @@ void run_sync_call(const char *ubus_obj, const char *ubus_method, struct blob_at
strcmp(blobmsg_name(attr), "value") == 0 &&
blobmsg_type(attr) == BLOBMSG_TYPE_STRING &&
strncmp(BBFDM_ROOT_OBJECT, blobmsg_get_string(attr), strlen(BBFDM_ROOT_OBJECT)) == 0) {
char value_in[MAX_PATH_LENGTH];
char reference_to_set[MAX_VALUE_LENGTH] = {0};
char *reference_value = get_reference_data(blobmsg_get_string(attr), "reference_value");
snprintf(value_in, sizeof(value_in), "%s=>%s##", blobmsg_get_string(attr), reference_value ? reference_value : "");
BBFDM_FREE(reference_value);
blobmsg_add_string(&req_buf, blobmsg_name(attr), value_in);
generate_reference_to_set(blobmsg_get_string(attr), reference_to_set, sizeof(reference_to_set));
blobmsg_add_string(&req_buf, blobmsg_name(attr), reference_to_set);
} if (strcmp(ubus_method, "set") == 0 &&
strcmp(blobmsg_name(attr), "obj_path") == 0 &&
blobmsg_type(attr) == BLOBMSG_TYPE_TABLE) {
@ -145,13 +169,10 @@ void run_sync_call(const char *ubus_obj, const char *ubus_method, struct blob_at
blobmsg_for_each_attr(__attr, attr, rem) {
if (blobmsg_type(__attr) == BLOBMSG_TYPE_STRING && strncmp(BBFDM_ROOT_OBJECT, blobmsg_get_string(__attr), strlen(BBFDM_ROOT_OBJECT)) == 0) {
char value_in[MAX_PATH_LENGTH];
char reference_to_set[MAX_VALUE_LENGTH] = {0};
char *reference_value = get_reference_data(blobmsg_get_string(__attr), "reference_value");
snprintf(value_in, sizeof(value_in), "%s=>%s##", blobmsg_get_string(__attr), reference_value ? reference_value : "");
BBFDM_FREE(reference_value);
blobmsg_add_string(&req_buf, blobmsg_name(__attr), value_in);
generate_reference_to_set(blobmsg_get_string(__attr), reference_to_set, sizeof(reference_to_set));
blobmsg_add_string(&req_buf, blobmsg_name(__attr), reference_to_set);
} else {
blobmsg_add_string(&req_buf, blobmsg_name(__attr), blobmsg_get_string(__attr));
}

View file

@ -48,17 +48,6 @@ enum dmt_type_enum {
__DMT_INVALID
};
static void strncpyt(char *dst, const char *src, size_t n)
{
if (dst == NULL || src == NULL)
return;
if (n > 1) {
strncpy(dst, src, n - 1);
dst[n - 1] = 0;
}
}
static void add_pv_list(const char *para, const char *val, const char *type, struct list_head *pv_list)
{
struct pvNode *node = NULL;
@ -238,9 +227,9 @@ static bool get_next_element(char *path, char *param)
len = strlen(path);
ptr = strchr(path, DELIM);
if (ptr)
strncpyt(param, path, (size_t)labs(ptr - path) + 1);
bbfdm_strncpy(param, path, (size_t)labs(ptr - path) + 1);
else
strncpyt(param, path, len + 1);
bbfdm_strncpy(param, path, len + 1);
return true;
}
@ -385,7 +374,7 @@ static bool add_paths_to_stack(struct blob_buf *bb, char *path, size_t begin,
parsed_len += strlen(key) + 1;
ptr += strlen(key) + 1;
if (is_leaf_element(ptr)) {
strncpyt(param, path, begin + parsed_len + 1);
bbfdm_strncpy(param, path, begin + parsed_len + 1);
if (is_node_instance(key))
c = blobmsg_open_table(bb, NULL);
else
@ -396,7 +385,7 @@ static bool add_paths_to_stack(struct blob_buf *bb, char *path, size_t begin,
add_data_blob(bb, ptr, pv->val, pv->type);
break;
}
strncpyt(param, pv->param, begin + parsed_len + 1);
bbfdm_strncpy(param, pv->param, begin + parsed_len + 1);
if (is_node_instance(ptr))
c = blobmsg_open_array(bb, key);
else

View file

@ -927,6 +927,36 @@ static bool is_same_reference_path(const char *curr_value, const char *in_value,
return false;
}
char *in_value_list = strchr(in_value, ',');
if (in_value_list) {
char formatted_value[2048] = {0};
long int pos = 0;
DM_STRNCPY(buf, in_value, sizeof(buf));
formatted_value[0] = '\0';
for (pch = strtok_r(buf, ",", &pchr); pch != NULL; pch = strtok_r(NULL, ",", &pchr)) {
if (formatted_value[0] == '\0') {
pos += snprintf(formatted_value, sizeof(formatted_value), "%s", pch);
} else {
pos += snprintf(&formatted_value[pos], sizeof(formatted_value) - pos, ";%s", pch);
}
char *delimiter_pos = DM_STRSTR(formatted_value, "=>");
if (delimiter_pos) {
pos = labs(delimiter_pos - formatted_value);
*delimiter_pos = '\0';
}
}
if (strcmp(curr_value, formatted_value) == 0)
return true;
else
return false;
}
DM_STRNCPY(buf, curr_value, sizeof(buf));
for (pch = strtok_r(buf, ",", &pchr); pch != NULL; pch = strtok_r(NULL, ",", &pchr)) {

View file

@ -10,6 +10,7 @@
*/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stddef.h>
#include <sys/stat.h>
@ -60,3 +61,14 @@ int bbfdm_create_empty_file(const char *path)
fclose(fp);
return 0;
}
void bbfdm_strncpy(char *dst, const char *src, size_t n)
{
if (dst == NULL || src == NULL)
return;
if (n > 1) {
strncpy(dst, src, n - 1);
dst[n - 1] = 0;
}
}

View file

@ -56,6 +56,18 @@ bool bbfdm_is_regular_file(const char *path);
*/
int bbfdm_create_empty_file(const char *path);
/**
* @brief Copy a string with a guaranteed null termination.
*
* This function copies up to `n - 1` characters from `src` to `dst` and ensures
* the destination string is null-terminated. If `n` is 1 or less, no copying occurs.
*
* @param[out] dst Destination buffer.
* @param[in] src Source string.
* @param[in] n Size of the destination buffer.
*/
void bbfdm_strncpy(char *dst, const char *src, size_t n);
#ifdef __cplusplus
}
#endif