2222#include <time.h>
2323#include <signal.h>
2424#include <sys/stat.h>
25+ #include <errno.h>
26+ #include <limits.h>
2527
2628#include <msgpack.h>
2729#include <fluent-bit/flb_input.h>
@@ -64,6 +66,7 @@ static int fleet_cur_chdir(struct flb_in_calyptia_fleet_config *ctx);
6466static int get_calyptia_files (struct flb_in_calyptia_fleet_config * ctx ,
6567 time_t timestamp );
6668static void in_calyptia_fleet_destroy (struct flb_in_calyptia_fleet_config * ctx );
69+ static struct cfl_array * read_glob (const char * path );
6770
6871#ifndef FLB_SYSTEM_WINDOWS
6972
@@ -295,7 +298,6 @@ static int is_old_fleet_config(struct flb_in_calyptia_fleet_config *ctx, struct
295298 flb_sds_t cfgcurname ;
296299 int ret = FLB_FALSE ;
297300
298-
299301 if (cfg == NULL ) {
300302 return FLB_FALSE ;
301303 }
@@ -319,40 +321,44 @@ static int is_old_fleet_config(struct flb_in_calyptia_fleet_config *ctx, struct
319321 return ret ;
320322}
321323
322- static int is_timestamped_fleet_config_path (struct flb_in_calyptia_fleet_config * ctx , const char * path )
324+ /**
325+ * Returns the timestamp of the fleet config file if it is a timestamped file,
326+ * or 0 if it is not a timestamped file.
327+ */
328+ static time_t fleet_config_path_timestamp (struct flb_in_calyptia_fleet_config * ctx , const char * path )
323329{
324330 char * fname ;
325331 char * end ;
326- long val ;
332+ long long val ;
327333
328334 if (path == NULL || ctx == NULL ) {
329- return FLB_FALSE ;
335+ return 0 ;
330336 }
331337
332338 fname = strrchr (path , PATH_SEPARATOR [0 ]);
333339
334340 if (fname == NULL ) {
335- return FLB_FALSE ;
341+ return 0 ;
336342 }
337343
338344 fname ++ ;
339345
340346 errno = 0 ;
341- val = strtol (fname , & end , 10 );
347+ val = strtoll (fname , & end , 10 );
342348 if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN )) || (errno != 0 && val == 0 )) {
343- return FLB_FALSE ;
349+ return 0 ;
344350 }
345351
346352 if (ctx -> fleet_config_legacy_format ) {
347353 if (strcmp (end , ".conf" ) == 0 ) {
348- return FLB_TRUE ;
354+ return ( time_t ) val ;
349355 }
350356 }
351357 else if (strcmp (end , ".yaml" ) == 0 ) {
352- return FLB_TRUE ;
358+ return ( time_t ) val ;
353359 }
354360
355- return FLB_FALSE ;
361+ return 0 ;
356362}
357363
358364static int is_timestamped_fleet_config (struct flb_in_calyptia_fleet_config * ctx , struct flb_config * cfg )
@@ -365,7 +371,7 @@ static int is_timestamped_fleet_config(struct flb_in_calyptia_fleet_config *ctx,
365371 return FLB_FALSE ;
366372 }
367373
368- return is_timestamped_fleet_config_path (ctx , cfg -> conf_path_file );
374+ return fleet_config_path_timestamp (ctx , cfg -> conf_path_file ) > 0 ;
369375}
370376
371377static int is_fleet_config (struct flb_in_calyptia_fleet_config * ctx , struct flb_config * cfg )
@@ -965,6 +971,74 @@ static int get_calyptia_fleet_id_by_name(struct flb_in_calyptia_fleet_config *ct
965971 return 0 ;
966972}
967973
974+ /**
975+ * Checks for existing config files having timestamps at or after new_timestamp.
976+ * @param ctx Fleet configuration context
977+ * @param new_timestamp Timestamp to compare against existing files
978+ * @return FLB_TRUE if new_timestamp is newer than all existing files, FLB_FALSE otherwise.
979+ */
980+ static int check_timestamp_is_newer (struct flb_in_calyptia_fleet_config * ctx , time_t new_timestamp )
981+ {
982+ flb_sds_t base_dir = NULL ;
983+ flb_sds_t glob_pattern = NULL ;
984+ struct cfl_array * files = NULL ;
985+ size_t idx ;
986+ int ret ;
987+ time_t file_timestamp ;
988+ const char * file_extension ;
989+
990+ if (generate_base_fleet_directory (ctx , & base_dir ) == NULL ) {
991+ return FLB_FALSE ;
992+ }
993+
994+ /* Create glob pattern to match all timestamped files */
995+ glob_pattern = flb_sds_create_size (0 );
996+ if (glob_pattern == NULL ) {
997+ flb_sds_destroy (base_dir );
998+ return FLB_FALSE ;
999+ }
1000+
1001+ file_extension = ctx -> fleet_config_legacy_format ? "*.conf" : "*.yaml" ;
1002+ if (flb_sds_printf (& glob_pattern , "%s" PATH_SEPARATOR "%s" , base_dir , file_extension ) == NULL ) {
1003+ flb_sds_destroy (glob_pattern );
1004+ flb_sds_destroy (base_dir );
1005+ return FLB_FALSE ;
1006+ }
1007+
1008+ files = read_glob (glob_pattern );
1009+ if (files == NULL ) {
1010+ /* No existing files found - could be empty directory or glob failure */
1011+ flb_plg_debug (ctx -> ins , "no existing config files found in %s" , base_dir );
1012+ flb_sds_destroy (base_dir );
1013+ flb_sds_destroy (glob_pattern );
1014+ return FLB_TRUE ;
1015+ }
1016+
1017+ /* Check each existing file's timestamp */
1018+ ret = FLB_TRUE ;
1019+ for (idx = 0 ; idx < files -> entry_count ; idx ++ ) {
1020+ file_timestamp = fleet_config_path_timestamp (ctx , files -> entries [idx ]-> data .as_string );
1021+ if (file_timestamp == 0 ) {
1022+ continue ;
1023+ }
1024+
1025+ /* Check if existing file timestamp is greater than or equal to new timestamp */
1026+ if (file_timestamp >= new_timestamp ) {
1027+ flb_plg_debug (ctx -> ins ,
1028+ "existing file with timestamp %ld >= new timestamp %ld" ,
1029+ (long long )file_timestamp , (long long )new_timestamp );
1030+ ret = FLB_FALSE ;
1031+ break ;
1032+ }
1033+ }
1034+
1035+ cfl_array_destroy (files );
1036+ flb_sds_destroy (base_dir );
1037+ flb_sds_destroy (glob_pattern );
1038+
1039+ return ret ;
1040+ }
1041+
9681042static int get_calyptia_file (struct flb_in_calyptia_fleet_config * ctx ,
9691043 flb_sds_t url ,
9701044 const char * hdr ,
@@ -1002,6 +1076,18 @@ static int get_calyptia_file(struct flb_in_calyptia_fleet_config *ctx,
10021076 flb_strptime (fbit_last_modified , "%a, %d %B %Y %H:%M:%S GMT" , & tm_last_modified );
10031077 last_modified = mktime (& tm_last_modified .tm );
10041078
1079+ /* Check if there are existing files with timestamps >= new timestamp */
1080+ if (check_timestamp_is_newer (ctx , last_modified ) == FLB_FALSE ) {
1081+ flb_plg_debug (ctx -> ins , "not creating file with timestamp %lld since it is not newer than existing files" ,
1082+ (long long )last_modified );
1083+ ret = -1 ;
1084+ goto client_error ;
1085+ }
1086+ else {
1087+ flb_plg_info (ctx -> ins , "creating config file with timestamp %lld" ,
1088+ (long long )last_modified );
1089+ }
1090+
10051091 fname = time_fleet_config_filename (ctx , last_modified );
10061092 }
10071093 else {
@@ -1355,7 +1441,7 @@ static int calyptia_config_delete_old(struct flb_in_calyptia_fleet_config *ctx)
13551441 }
13561442
13571443 for (idx = 0 ; idx < confs -> entry_count ; idx ++ ) {
1358- if (is_timestamped_fleet_config_path (ctx , confs -> entries [idx ]-> data .as_string ) == FLB_TRUE ) {
1444+ if (fleet_config_path_timestamp (ctx , confs -> entries [idx ]-> data .as_string ) > 0 ) {
13591445 cfl_array_append_string (tconfs , confs -> entries [idx ]-> data .as_string );
13601446 }
13611447 }
@@ -1421,7 +1507,7 @@ static flb_sds_t calyptia_config_get_newest(struct flb_in_calyptia_fleet_config
14211507
14221508 for (idx = inis -> entry_count - 1 ; idx >= 0 ; idx -- ) {
14231509 curconf = inis -> entries [idx ]-> data .as_string ;
1424- if (is_timestamped_fleet_config_path (ctx , curconf )) {
1510+ if (fleet_config_path_timestamp (ctx , curconf ) > 0 ) {
14251511 cfgnewname = flb_sds_create (curconf );
14261512 break ;
14271513 }
0 commit comments