3636#include <sys/wait.h>
3737#include <errno.h>
3838
39- /**
40- @struct Application_t
41- @brief Structure representing an application defined in the ini file.
42- */
43- typedef struct
44- {
45- // In the ini file
46- int start_delay ; /**< Delay in seconds before starting the application. */
47- int heartbeat_delay ; /**< Time in seconds to wait before expecting a heartbeat from the application. */
48- int heartbeat_interval ; /**< Maximum time period in seconds between heartbeats. */
49- char name [MAX_APP_NAME_LENGTH ]; /**< Name of the application. */
50- char cmd [MAX_APP_CMD_LENGTH ]; /**< Command to start the application. */
51- // Not in the ini file
52- bool started ; /**< Flag indicating whether the application has been started. */
53- bool first_heartbeat ; /**< Flag indicating whether the application has sent its first heartbeat. */
54- int pid ; /**< Process ID of the application. */
55- time_t last_heartbeat ; /**< Time when the last heartbeat was received from the application. */
56- } Application_t ;
57-
58- typedef struct
59- {
60- int app_count ; /**< Total number of applications found in the ini file. */
61- int udp_port ; /**< UDP port number specified in the ini file. */
62- char ini_file [MAX_APP_CMD_LENGTH ]; /**< Path to the ini file. */
63- time_t ini_last_modified_time ; /**< Last modified time of the ini file. */
64- time_t uptime ; /**< System uptime in seconds. */
65- int ini_index ; /**< Index used to read an array in the ini file. */
66- } AppState_t ;
39+
6740
6841static Application_t apps [MAX_APPS ]; /**< Array of Application_t structures representing applications defined in the ini file. */
6942static AppState_t app_state = {0 };
@@ -204,91 +177,72 @@ int set_ini_file(char *path)
204177static int handler (void * user , const char * section , const char * name , const char * value )
205178{
206179 (void )(user );
207- const char * target_section = "processWatchdog" ;
208- char expected_name [INI_MAX_LINE ];
209-
210- if (strcmp (section , target_section ) != 0 )
211- {
212- return 1 ;
213- }
214-
215- // Global parameters
216- if (strcmp (name , "udp_port" ) == 0 )
217- {
218- if (!parse_int (value , 1 , 65535 , & app_state .udp_port ))
219- {
220- LOGE ("Invalid UDP port: %s" , value );
221- return 0 ;
180+ static char last_section [MAX_APP_NAME_LENGTH ] = {0 };
181+ const char * app_prefix = "app:" ;
182+
183+ // New section detected
184+ if (strcmp (section , last_section ) != 0 ) {
185+ if (strncmp (section , app_prefix , strlen (app_prefix )) == 0 ) {
186+ if (app_state .app_count < MAX_APPS ) {
187+ const char * app_name = section + strlen (app_prefix );
188+ if (* app_name == '\0' ) {
189+ LOGE ("Empty app name in section header: [%s]" , section );
190+ return 0 ; // Error
191+ }
192+ strncpy (apps [app_state .app_count ].name , app_name , MAX_APP_NAME_LENGTH - 1 );
193+ apps [app_state .app_count ].name [MAX_APP_NAME_LENGTH - 1 ] = '\0' ;
194+ app_state .app_count ++ ;
195+ } else {
196+ LOGW ("MAX_APPS (%d) reached. Ignoring section [%s]" , MAX_APPS , section );
197+ }
222198 }
223-
224- return 1 ;
225- }
226-
227- if (strcmp (name , "n_apps" ) == 0 )
228- {
229- if (!parse_int (value , 0 , MAX_APPS , & app_state .app_count ))
230- {
231- LOGE ("Invalid n_apps: %s" , value );
232- return 0 ;
199+ strncpy (last_section , section , sizeof (last_section ) - 1 );
200+ last_section [sizeof (last_section ) - 1 ] = '\0' ;
201+ }
202+
203+ // Find current app index
204+ int index = -1 ;
205+ if (strncmp (section , app_prefix , strlen (app_prefix )) == 0 ) {
206+ const char * app_name = section + strlen (app_prefix );
207+ for (int i = 0 ; i < app_state .app_count ; i ++ ) {
208+ if (strcmp (apps [i ].name , app_name ) == 0 ) {
209+ index = i ;
210+ break ;
211+ }
233212 }
234-
235- return 1 ;
236213 }
237214
238- // Application parameters
239- int index = app_state .ini_index ;
240-
241- if (index >= app_state .app_count )
242- {
243- return 1 ;
244- }
245-
246- #define GEN_NAME (field ) snprintf(expected_name, sizeof(expected_name), "%d_%s", index + 1, field)
247-
248- if (GEN_NAME ("name" ), strcmp (name , expected_name ) == 0 )
249- {
250- snprintf (apps [index ].name , MAX_APP_NAME_LENGTH , "%s" , value );
251-
252- if (strlen (value ) >= MAX_APP_NAME_LENGTH )
253- {
254- LOGW ("App %d name truncated" , index );
255- }
256- }
257- else if (GEN_NAME ("start_delay" ), strcmp (name , expected_name ) == 0 )
258- {
259- if (!parse_int (value , 0 , INT_MAX , & apps [index ].start_delay ))
260- {
261- LOGE ("Invalid start_delay for app %d: %s" , index , value );
262- return 0 ;
263- }
264- }
265- else if (GEN_NAME ("heartbeat_delay" ), strcmp (name , expected_name ) == 0 )
266- {
267- if (!parse_int (value , 0 , INT_MAX , & apps [index ].heartbeat_delay ))
268- {
269- LOGE ("Invalid heartbeat_delay for app %d: %s" , index , value );
270- return 0 ;
271- }
272- }
273- else if (GEN_NAME ("heartbeat_interval" ), strcmp (name , expected_name ) == 0 )
274- {
275- if (!parse_int (value , 0 , INT_MAX , & apps [index ].heartbeat_interval ))
276- {
277- LOGE ("Invalid heartbeat_interval for app %d: %s" , index , value );
278- return 0 ;
215+ // Process key-value pairs
216+ if (strcmp (section , "processWatchdog" ) == 0 ) {
217+ if (strcmp (name , "udp_port" ) == 0 ) {
218+ if (!parse_int (value , 1 , 65535 , & app_state .udp_port )) {
219+ LOGE ("Invalid UDP port: %s" , value );
220+ return 0 ;
221+ }
279222 }
280- }
281- else if (GEN_NAME ("cmd" ), strcmp (name , expected_name ) == 0 ) // this always must be the last one
282- {
283- snprintf (apps [index ].cmd , MAX_APP_CMD_LENGTH , "%s" , value );
284-
285- if (strlen (value ) >= MAX_APP_CMD_LENGTH )
286- {
287- LOGE ("Invalid cmd for app %d - longer than %d charachters" , index , MAX_APP_CMD_LENGTH );
288- return 0 ;
223+ } else if (index != -1 ) { // This is an app section we are tracking
224+ if (strcmp (name , "start_delay" ) == 0 ) {
225+ if (!parse_int (value , 0 , INT_MAX , & apps [index ].start_delay )) {
226+ LOGE ("Invalid start_delay for app %s: %s" , apps [index ].name , value );
227+ return 0 ;
228+ }
229+ } else if (strcmp (name , "heartbeat_delay" ) == 0 ) {
230+ if (!parse_int (value , 0 , INT_MAX , & apps [index ].heartbeat_delay )) {
231+ LOGE ("Invalid heartbeat_delay for app %s: %s" , apps [index ].name , value );
232+ return 0 ;
233+ }
234+ } else if (strcmp (name , "heartbeat_interval" ) == 0 ) {
235+ if (!parse_int (value , 0 , INT_MAX , & apps [index ].heartbeat_interval )) {
236+ LOGE ("Invalid heartbeat_interval for app %s: %s" , apps [index ].name , value );
237+ return 0 ;
238+ }
239+ } else if (strcmp (name , "cmd" ) == 0 ) {
240+ snprintf (apps [index ].cmd , MAX_APP_CMD_LENGTH , "%s" , value );
241+ if (strlen (value ) >= MAX_APP_CMD_LENGTH ) {
242+ LOGE ("Invalid cmd for app %s - longer than %d charachters" , apps [index ].name , MAX_APP_CMD_LENGTH );
243+ return 0 ;
244+ }
289245 }
290-
291- app_state .ini_index ++ ; // Move to next app after processing cmd
292246 }
293247
294248 return 1 ;
@@ -297,7 +251,6 @@ static int handler(void *user, const char *section, const char *name, const char
297251int read_ini_file ()
298252{
299253 memset (apps , 0 , sizeof (apps ));
300- app_state .ini_index = 0 ;
301254 app_state .app_count = 0 ;
302255 app_state .uptime = get_uptime ();
303256 app_state .udp_port = UDP_PORT ;
@@ -317,11 +270,6 @@ int read_ini_file()
317270 return 1 ;
318271 }
319272
320- if (app_state .ini_index != app_state .app_count )
321- {
322- LOGW ("Config mismatch: Expected %d apps, found %d" , app_state .app_count , app_state .ini_index );
323- }
324-
325273 LOGD ("%d processes have found in the ini file %s" , app_state .app_count , app_state .ini_file );
326274 app_state .ini_last_modified_time = file_modified_time (app_state .ini_file );
327275 return 0 ;
0 commit comments