From 4f5f5dd701d40cdb134b98734db75446e5736a2e Mon Sep 17 00:00:00 2001
From: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
Date: Tue, 11 Jun 2024 14:38:59 +0200
Subject: [PATCH] Define internal functions inside micro-service and free the
 allocated memory correctly

---
 src/datamodel.c | 93 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 82 insertions(+), 11 deletions(-)

diff --git a/src/datamodel.c b/src/datamodel.c
index b140eea..2ed5775 100644
--- a/src/datamodel.c
+++ b/src/datamodel.c
@@ -28,6 +28,13 @@ DMLEAF tUSBUSBHostsHostDeviceConfigurationInterfaceParams[];
 
 #define SYSFS_USB_DEVICES_PATH "/sys/bus/usb/devices"
 
+struct sysfs_dmsection {
+	struct list_head list;
+	char *sysfs_folder_path;
+	char *sysfs_folder_name;
+	struct uci_section *dmmap_section;
+};
+
 struct usb_port
 {
 	char *folder_name;
@@ -63,6 +70,70 @@ static void init_usb_interface(char *iface_name, char *iface_path, char *statist
 /*************************************************************
 * ENTRY METHOD
 *************************************************************/
+static void add_sysfs_sections_list(struct list_head *dup_list, struct uci_section *dmmap_section, char *file_name, char *file_path)
+{
+	struct sysfs_dmsection *dmmap_sysfs;
+
+	dmmap_sysfs = dmcalloc(1, sizeof(struct sysfs_dmsection));
+	list_add_tail(&dmmap_sysfs->list, dup_list);
+	dmmap_sysfs->dmmap_section = dmmap_section;
+	dmmap_sysfs->sysfs_folder_name = dmstrdup(file_name);
+	dmmap_sysfs->sysfs_folder_path = dmstrdup(file_path);
+}
+
+void free_sysfs_sections_list(struct list_head *dup_list)
+{
+	struct sysfs_dmsection *dmmap_sysfs = NULL, *tmp = NULL;
+
+	list_for_each_entry_safe(dmmap_sysfs, tmp, dup_list, list) {
+		dmfree(dmmap_sysfs->sysfs_folder_name);
+		dmfree(dmmap_sysfs->sysfs_folder_path);
+		list_del(&dmmap_sysfs->list);
+		dmfree(dmmap_sysfs);
+	}
+}
+
+static int synchronize_system_folders_with_dmmap(char *sysfsrep, char *dmmap_package, char *dmmap_section, char *opt_name, char* inst_opt, struct list_head *dup_list)
+{
+	struct uci_section *s = NULL, *stmp = NULL, *dmmap_sect = NULL;
+	char sysfs_rep_path[512];
+	DIR *dir;
+	struct dirent *ent;
+
+	sysfs_foreach_file(sysfsrep, dir, ent) {
+		if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+			continue;
+
+		/*
+		 * create/update corresponding dmmap section that have same config_section link and using param_value_array
+		 */
+		snprintf(sysfs_rep_path, sizeof(sysfs_rep_path), "%s/%s", sysfsrep, ent->d_name);
+		if ((dmmap_sect = get_dup_section_in_dmmap_opt(dmmap_package, dmmap_section, opt_name, sysfs_rep_path)) == NULL) {
+			dmuci_add_section_bbfdm(dmmap_package, dmmap_section, &dmmap_sect);
+			dmuci_set_value_by_section_bbfdm(dmmap_sect, opt_name, sysfs_rep_path);
+		}
+
+		/*
+		 * Add system and dmmap sections to the list
+		 */
+		add_sysfs_sections_list(dup_list, dmmap_sect, ent->d_name, sysfs_rep_path);
+	}
+	if (dir)
+		closedir(dir);
+
+	/*
+	 * Delete unused dmmap sections
+	 */
+	uci_path_foreach_sections_safe(bbfdm, dmmap_package, dmmap_section, stmp, s) {
+		char *opt_val = NULL;
+
+		dmuci_get_value_by_section_string(s, opt_name, &opt_val);
+		if (!folder_exists(opt_val))
+			dmuci_delete_by_section(s, NULL, NULL);
+	}
+	return 0;
+}
+
 static int read_sysfs_file(const char *file, char **value)
 {
 	char buf[128];
@@ -140,7 +211,7 @@ static int browseUSBInterfaceInst(struct dmctx *dmctx, DMNODE *parent_node, void
 	struct sysfs_dmsection *p = NULL;
 	struct dm_data data = {0};
 
-	synchronize_system_folders_with_dmmap_opt(SYSFS_USB_DEVICES_PATH, "dmmap_usb", "dmmap_interface", "usb_iface_link", "usb_iface_instance", &dup_list);
+	synchronize_system_folders_with_dmmap(SYSFS_USB_DEVICES_PATH, "dmmap_usb", "dmmap_interface", "usb_iface_link", "usb_iface_instance", &dup_list);
 	list_for_each_entry(p, &dup_list, list) {
 		char statistics_path[652] = {0};
 		char iface_path[620] = {0};
@@ -182,7 +253,7 @@ static int browseUSBInterfaceInst(struct dmctx *dmctx, DMNODE *parent_node, void
 		if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&data, inst) == DM_STOP)
 			break;
 	}
-	free_dmmap_config_dup_list(&dup_list);
+	free_sysfs_sections_list(&dup_list);
 	return 0;
 }
 
@@ -192,14 +263,14 @@ static int browseUSBPortInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre
 	struct usb_port port = {0};
 	struct sysfs_dmsection *p = NULL;
 	LIST_HEAD(dup_list);
-	regex_t regex1 = {};
-	regex_t regex2 = {};
+	regex_t regex1 = {0};
+	regex_t regex2 = {0};
 	struct dm_data data = {0};
 
 	regcomp(&regex1, "^[0-9][0-9]*-[0-9]*[0-9]$", 0);
 	regcomp(&regex2, "^[0-9][0-9]*-[0-9]*[0-9]\\.[0-9]*[0-9]$", 0);
 
-	synchronize_system_folders_with_dmmap_opt(SYSFS_USB_DEVICES_PATH, "dmmap_usb", "dmmap_port", "port_link", "usb_port_instance", &dup_list);
+	synchronize_system_folders_with_dmmap(SYSFS_USB_DEVICES_PATH, "dmmap_usb", "dmmap_port", "port_link", "usb_port_instance", &dup_list);
 	list_for_each_entry(p, &dup_list, list) {
 
 		if (regexec(&regex1, p->sysfs_folder_name, 0, NULL, 0) != 0 &&
@@ -218,7 +289,7 @@ static int browseUSBPortInst(struct dmctx *dmctx, DMNODE *parent_node, void *pre
 		if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&data, inst) == DM_STOP)
 			break;
 	}
-	free_dmmap_config_dup_list(&dup_list);
+	free_sysfs_sections_list(&dup_list);
 	regfree(&regex1);
 	regfree(&regex2);
 	return 0;
@@ -232,7 +303,7 @@ static int browseUSBUSBHostsHostInst(struct dmctx *dmctx, DMNODE *parent_node, v
 	LIST_HEAD(dup_list);
 	struct dm_data data = {0};
 
-	synchronize_system_folders_with_dmmap_opt(SYSFS_USB_DEVICES_PATH, "dmmap_usb", "dmmap_host", "port_link", "usb_host_instance", &dup_list);
+	synchronize_system_folders_with_dmmap(SYSFS_USB_DEVICES_PATH, "dmmap_usb", "dmmap_host", "port_link", "usb_host_instance", &dup_list);
 
 	list_for_each_entry(p, &dup_list, list) {
 
@@ -250,7 +321,7 @@ static int browseUSBUSBHostsHostInst(struct dmctx *dmctx, DMNODE *parent_node, v
 		if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)&data, inst) == DM_STOP)
 			break;
 	}
-	free_dmmap_config_dup_list(&dup_list);
+	free_sysfs_sections_list(&dup_list);
 	return 0;
 }
 
@@ -298,9 +369,9 @@ static int synchronize_usb_devices_with_dmmap_opt_recursively(char *sysfsrep, ch
 			 * Add system and dmmap sections to the list
 			 */
 			if (instance == NULL || *instance == '\0')
-				add_sysfs_section_list(&dup_list_no_inst, dmmap_sect, ent->d_name, sysfs_repo_path);
+				add_sysfs_sections_list(&dup_list_no_inst, dmmap_sect, ent->d_name, sysfs_repo_path);
 			else
-				add_sysfs_section_list(dup_list, dmmap_sect, ent->d_name, sysfs_repo_path);
+				add_sysfs_sections_list(dup_list, dmmap_sect, ent->d_name, sysfs_repo_path);
 		}
 	}
 	if (dir)
@@ -311,7 +382,7 @@ static int synchronize_usb_devices_with_dmmap_opt_recursively(char *sysfsrep, ch
 	 * fusion two lists
 	 */
 	list_for_each_entry(p, &dup_list_no_inst, list) {
-		add_sysfs_section_list(dup_list, p->dmmap_section, p->sysfs_folder_name, p->sysfs_folder_path);
+		add_sysfs_sections_list(dup_list, p->dmmap_section, p->sysfs_folder_name, p->sysfs_folder_path);
 	}
 	/*
 	 * Delete unused dmmap sections
-- 
GitLab