Line data Source code
1 : #include "fd_config_extract.h" 2 : 3 : /* Find leftover ******************************************************/ 4 : 5 : /* fdctl_pod_find_leftover recursively searches for non-subpod keys in 6 : pod. Prints to the warning log if it finds any. Used to detect 7 : config keys that were not recognized by fdctl. Returns 0 if no 8 : leftover key was found. Otherwise, returns a non-zero number of 9 : segments of the leftover key. The key can be reassembled by joining 10 : stack[0] .. stack[depth-1]. 11 : 12 : Not thread safe (uses global buffer). */ 13 : 14 3 : # define FDCTL_CFG_MAX_DEPTH (16) 15 : 16 : static ulong 17 : fdctl_pod_find_leftover_recurse( uchar * pod, 18 : char const ** stack, 19 111 : ulong depth ) { 20 : 21 111 : if( FD_UNLIKELY( depth+1 >= FDCTL_CFG_MAX_DEPTH ) ) { 22 0 : FD_LOG_WARNING(( "configuration file has too many nested keys" )); 23 0 : return depth; 24 0 : } 25 : 26 210 : for( fd_pod_iter_t iter = fd_pod_iter_init( pod ); !fd_pod_iter_done( iter ); iter = fd_pod_iter_next( iter ) ) { 27 102 : fd_pod_info_t info = fd_pod_iter_info( iter ); 28 102 : stack[ depth ] = info.key; 29 102 : depth++; 30 102 : if( FD_LIKELY( info.val_type == FD_POD_VAL_TYPE_SUBPOD ) ) { 31 99 : ulong sub_depth = fdctl_pod_find_leftover_recurse( (uchar *)info.val, stack, depth ); 32 99 : if( FD_UNLIKELY( sub_depth ) ) return sub_depth; 33 99 : } else { 34 3 : return depth; 35 3 : } 36 99 : depth--; 37 99 : } 38 : 39 108 : return 0; 40 111 : } 41 : 42 : int 43 12 : fdctl_pod_find_leftover( uchar * pod ) { 44 : 45 12 : static char const * stack[ FDCTL_CFG_MAX_DEPTH ]; 46 12 : ulong depth = fdctl_pod_find_leftover_recurse( pod, stack, 0UL ); 47 12 : if( FD_LIKELY( !depth ) ) return 1; 48 : 49 3 : static char path[ 64*FDCTL_CFG_MAX_DEPTH + 4 ]; 50 3 : char * c = fd_cstr_init( path ); 51 3 : char * end = path + 64*FDCTL_CFG_MAX_DEPTH - 1; 52 6 : for( ulong j=0UL; j<depth; j++ ) { 53 3 : char const * key = stack[j]; 54 3 : ulong key_len = strlen( key ); 55 3 : if( c+key_len+1 >= end ) { 56 0 : c = fd_cstr_append_text( c, "...", 3UL ); 57 0 : break; 58 0 : } 59 3 : c = fd_cstr_append_text( c, key, key_len ); 60 3 : c = fd_cstr_append_char( c, '.' ); 61 3 : } 62 3 : c -= 1; 63 3 : fd_cstr_fini( c ); 64 : 65 3 : FD_LOG_WARNING(( "Config file contains unrecognized key `%s`", path )); 66 3 : return 0; 67 12 : }