11#include "cisco_cli.h"
22
3+ // Creates a new directory tree node with the given name, path, and type
34dir_node_t * file_tree_create (const char * name , const char * path , file_type_t type ) {
45 dir_node_t * node = malloc (sizeof (dir_node_t ));
56 if (!node ) return NULL ;
67
7- strncpy (node -> name , name , MAX_PATH_LEN - 1 );
8+ // Handle NULL parameters safely
9+ if (name ) {
10+ strncpy (node -> name , name , MAX_PATH_LEN - 1 );
11+ } else {
12+ node -> name [0 ] = '\0' ;
13+ }
814 node -> name [MAX_PATH_LEN - 1 ] = '\0' ;
915
10- strncpy (node -> path , path , MAX_PATH_LEN - 1 );
16+ if (path ) {
17+ strncpy (node -> path , path , MAX_PATH_LEN - 1 );
18+ } else {
19+ node -> path [0 ] = '\0' ;
20+ }
1121 node -> path [MAX_PATH_LEN - 1 ] = '\0' ;
1222
1323 node -> type = type ;
@@ -19,8 +29,9 @@ dir_node_t *file_tree_create(const char *name, const char *path, file_type_t typ
1929 node -> next = NULL ;
2030
2131 return node ;
22- }
32+ }
2333
34+ // Adds a child node to a parent node in the tree
2435void file_tree_add_child (dir_node_t * parent , dir_node_t * child ) {
2536 if (!parent || !child ) return ;
2637
@@ -38,7 +49,13 @@ void file_tree_add_child(dir_node_t *parent, dir_node_t *child) {
3849 }
3950}
4051
52+ // Recursively builds the file tree by fetching directory listings from the device
4153void file_tree_build_recursive (serial_conn_t * conn , dir_node_t * parent , const char * path ) {
54+ // Validate input parameters
55+ if (!conn || !parent || !path ) {
56+ return ;
57+ }
58+
4259 file_entry_t * files = NULL ;
4360 int file_count = cisco_get_directory_listing (conn , path , & files , 3 );
4461
@@ -61,7 +78,11 @@ void file_tree_build_recursive(serial_conn_t *conn, dir_node_t *parent, const ch
6178 }
6279}
6380
81+ // Initializes and builds the root file tree structure
6482void file_tree_build (serial_conn_t * conn , dir_node_t * * root ) {
83+ // Validate input parameters
84+ if (!root ) return ;
85+
6586 // Create root node
6687 * root = file_tree_create ("flash:/" , "flash:/" , FILE_TYPE_DIRECTORY );
6788 if (!* root ) return ;
@@ -70,6 +91,7 @@ void file_tree_build(serial_conn_t *conn, dir_node_t **root) {
7091 file_tree_build_recursive (conn , * root , "flash:/" );
7192}
7293
94+ // Recursively frees all memory allocated for the file tree
7395void file_tree_free (dir_node_t * node ) {
7496 if (!node ) return ;
7597
@@ -85,6 +107,7 @@ void file_tree_free(dir_node_t *node) {
85107 free (node );
86108}
87109
110+ // Sets the selection state of a node and all its children
88111void file_tree_select (dir_node_t * node , int selected ) {
89112 if (!node ) return ;
90113
@@ -100,6 +123,7 @@ void file_tree_select(dir_node_t *node, int selected) {
100123 }
101124}
102125
126+ // Counts the total number of selected nodes in the tree
103127int file_tree_count_selected (dir_node_t * node ) {
104128 if (!node ) return 0 ;
105129
@@ -115,6 +139,7 @@ int file_tree_count_selected(dir_node_t *node) {
115139 return count ;
116140}
117141
142+ // Recursively deletes selected files and directories from the device
118143void file_tree_delete_selected_recursive (serial_conn_t * conn , dir_node_t * node , int * success_count , int * fail_count ) {
119144 if (!node ) return ;
120145
@@ -138,14 +163,15 @@ void file_tree_delete_selected_recursive(serial_conn_t *conn, dir_node_t *node,
138163 result = cisco_delete_file (conn , node -> path , 3 );
139164 }
140165
141- if (result == 0 ) {
166+ if (result == 0 && success_count != NULL ) {
142167 (* success_count )++ ;
143- } else {
168+ } else if ( result != 0 && fail_count != NULL ) {
144169 (* fail_count )++ ;
145170 }
146171 }
147172}
148173
174+ // Deletes all selected files and directories and reports results
149175void file_tree_delete_selected (serial_conn_t * conn , dir_node_t * node ) {
150176 int success_count = 0 , fail_count = 0 ;
151177
@@ -155,13 +181,15 @@ void file_tree_delete_selected(serial_conn_t *conn, dir_node_t *node) {
155181 printf ("Deletion complete: %d successful, %d failed\n" , success_count , fail_count );
156182}
157183
158- // Utility function to get all nodes in a flat list for UI display
184+ // Recursively builds a flat list of visible nodes for UI display
159185int file_tree_get_flat_list_recursive (dir_node_t * node , dir_node_t * * list , int max_count , int * current_count ) {
160- if (!node || * current_count >= max_count ) return * current_count ;
186+ if (!node || ! list || ! current_count || * current_count >= max_count ) return 0 ;
161187
188+ // Always include the current node in the list
162189 list [* current_count ] = node ;
163190 (* current_count )++ ;
164191
192+ // Only include children if the current node is expanded
165193 if (node -> expanded ) {
166194 dir_node_t * child = node -> children ;
167195 while (child != NULL && * current_count < max_count ) {
@@ -173,6 +201,7 @@ int file_tree_get_flat_list_recursive(dir_node_t *node, dir_node_t **list, int m
173201 return * current_count ;
174202}
175203
204+ // Creates a flat list of all visible nodes in the tree for UI rendering
176205int file_tree_get_flat_list (dir_node_t * node , dir_node_t * * list , int max_count ) {
177206 int count = 0 ;
178207 return file_tree_get_flat_list_recursive (node , list , max_count , & count );
0 commit comments