From 5c143fe810705c2fe7770cdaccfb8c161862a9b1 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Thu, 19 Nov 2020 22:15:16 -0600 Subject: [PATCH] Progress: controller program. Update cache usage. Begin working on the rule settings, adding missing information and documentation. Combine the rule items and rule settings into a single rule structure. --- level_3/controller/c/controller.h | 34 ++++- level_3/controller/c/private-rule.c | 202 ++++++++++++++++------------- level_3/controller/c/private-rule.h | 83 ++++++++---- level_3/controller/documents/rule.txt | 11 +- level_3/controller/specifications/rule.txt | 10 +- 5 files changed, 211 insertions(+), 129 deletions(-) diff --git a/level_3/controller/c/controller.h b/level_3/controller/c/controller.h index 774e746..6299475 100644 --- a/level_3/controller/c/controller.h +++ b/level_3/controller/c/controller.h @@ -287,29 +287,49 @@ extern "C" { } #endif // _di_controller_rule_items_t_ -#ifndef _di_controller_rule_setting_t_ +#ifndef _di_controller_rule_t_ typedef struct { + f_status_t status; + + f_string_dynamic_t id; f_string_dynamic_t name; f_string_dynamic_t pid; - f_string_dynamics_t defines; // @todo this probably should a list of name and value pairs. + f_string_maps_t defines; + f_string_dynamics_t environment; - } controller_rule_setting_t; + f_string_dynamics_t need; + f_string_dynamics_t want; + f_string_dynamics_t wish; + + controller_rule_items_t items; + } controller_rule_t; - #define controller_rule_setting_t_initialize \ + #define controller_rule_t_initialize \ { \ + F_unknown, \ f_string_dynamic_t_initialize, \ f_string_dynamic_t_initialize, \ + f_string_dynamic_t_initialize, \ + f_string_maps_t_initialize, \ + f_string_dynamics_t_initialize, \ + f_string_dynamics_t_initialize, \ f_string_dynamics_t_initialize, \ f_string_dynamics_t_initialize, \ + controller_rule_items_initialize, \ } #define f_macro_controller_rule_setting_t_delete_simple(setting) \ + f_string_dynamic_t_delete_simple(setting.id) \ f_string_dynamic_t_delete_simple(setting.name) \ f_string_dynamic_t_delete_simple(setting.pid) \ - f_string_dynamics_t_delete_simple(setting.defines) \ - f_string_dynamics_t_delete_simple(setting.environments) -#endif // _di_controller_rule_setting_t_ + f_string_maps_t_delete_simple(setting.defines) \ + f_string_dynamics_t_delete_simple(setting.environments) \ + f_string_dynamics_t_delete_simple(setting.need) \ + f_string_dynamics_t_delete_simple(setting.want) \ + f_string_dynamics_t_delete_simple(setting.wish) \ + f_macro_controller_rule_item_t_delete_simple(setting.items) +#endif // _di_controller_rule_t_ /** * Print help. diff --git a/level_3/controller/c/private-rule.c b/level_3/controller/c/private-rule.c index 19b5cc6..4607ba1 100644 --- a/level_3/controller/c/private-rule.c +++ b/level_3/controller/c/private-rule.c @@ -74,7 +74,7 @@ extern "C" { #endif // _di_controller_rule_actions_increase_by_ #ifndef _di_controller_rule_actions_read_ - f_return_status controller_rule_actions_read(const controller_data_t data, f_string_static_t *buffer, controller_rule_cache_t *cache, controller_rule_item_t *item, controller_rule_actions_t *actions, f_string_range_t *range) { + f_return_status controller_rule_actions_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_item_t *item, controller_rule_actions_t *actions, f_string_range_t *range) { f_status_t status = F_none; actions->used = 0; @@ -97,7 +97,7 @@ extern "C" { else { actions->array[0].line = cache->line_action; - status = fl_string_dynamic_partial_append_nulless(*buffer, cache->range_action, &actions->array[0].parameters.array[0]); + status = fl_string_dynamic_partial_append_nulless(cache->buffer_item, cache->range_action, &actions->array[0].parameters.array[0]); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_append_nulless", F_true); @@ -114,53 +114,59 @@ extern "C" { if (actions->type == controller_rule_action_type_extended_list) { cache->comments.used = 0; - cache->content.used = 0; - cache->contents.used = 0; cache->delimits.used = 0; - cache->objects.used = 0; + cache->contents_action.used = 0; + cache->objects_action.used = 0; - status = fl_fss_extended_list_content_read(*buffer, range, &cache->content, &cache->delimits, &cache->comments); + status = fl_fss_extended_list_content_read(cache->buffer_item, range, &cache->content_action, &cache->delimits, &cache->comments); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_list_content_read", F_true); } else if (status == FL_fss_found_content) { - status = fll_fss_extended_read(*buffer, &cache->content.array[0], &cache->objects, &cache->contents, 0, 0, &cache->delimits, 0); + status = fll_fss_extended_read(cache->buffer_item, &cache->content_action.array[0], &cache->objects_action, &cache->contents_action, 0, 0, &cache->delimits, 0); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fll_fss_extended_read", F_true); } else { - f_array_length_t i = 0; - f_array_length_t j = 0; + status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item); - for (; i < cache->objects.used; ++i) { + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true); + } + else { + f_array_length_t i = 0; + f_array_length_t j = 0; - status = f_fss_count_lines(*buffer, cache->objects.array[i].start, &actions->array[actions->used].line); + for (; i < cache->objects_action.used; ++i) { - if (F_status_is_error(status)) { - fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true); - break; - } + status = f_fss_count_lines(cache->buffer_item, cache->objects_action.array[i].start, &actions->array[actions->used].line); - actions->array[actions->used].line += item->line; - actions->array[actions->used].parameters.used = 0; + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true); + break; + } - status = fl_string_dynamics_increase(&actions->array[actions->used].parameters); + actions->array[actions->used].line += item->line; + actions->array[actions->used].parameters.used = 0; - if (F_status_is_error(status)) { - fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_increase", F_true); - break; - } + status = fl_string_dynamics_increase(&actions->array[actions->used].parameters); - status = controller_rule_action_read(data, *buffer, &cache->objects.array[i], &cache->contents.array[i], &actions->array[actions->used]); + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_increase", F_true); + break; + } - if (F_status_is_error(status)) { - fll_error_print(data.error, F_status_set_fine(status), "controller_rule_action_read", F_true); - } + status = controller_rule_action_read(data, cache->buffer_item, &cache->objects_action.array[i], &cache->contents_action.array[i], &actions->array[actions->used]); + + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "controller_rule_action_read", F_true); + } - actions->used++; - } // for + actions->used++; + } // for + } } } else { @@ -168,16 +174,16 @@ extern "C" { } } else { - cache->content.used = 0; + cache->content_action.used = 0; cache->delimits.used = 0; - status = fl_fss_extended_content_read(*buffer, range, &cache->content, 0, &cache->delimits); + status = fl_fss_extended_content_read(cache->buffer_item, range, &cache->content_action, 0, &cache->delimits); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fll_fss_extended_content_read", F_true); } else if (status == FL_fss_found_content) { - status = fl_fss_apply_delimit(cache->delimits, buffer); + status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true); @@ -189,7 +195,7 @@ extern "C" { fll_error_print(data.error, F_status_set_fine(status), "controller_rule_actions_increase_by", F_true); } else { - status = f_fss_count_lines(*buffer, range->start, &actions->array[0].line); + status = f_fss_count_lines(cache->buffer_item, range->start, &actions->array[0].line); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true); @@ -198,7 +204,7 @@ extern "C" { actions->array[0].line += item->line; actions->array[0].parameters.used = 0; - status = controller_rule_action_read(data, *buffer, 0, &cache->content, &actions->array[0]); + status = controller_rule_action_read(data, cache->buffer_item, 0, &cache->content_action, &actions->array[0]); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "controller_rule_action_read", F_true); @@ -260,26 +266,26 @@ extern "C" { #endif // _di_controller_rule_error_print_ #ifndef _di_controller_rule_item_read_ - f_return_status controller_rule_item_read(const controller_data_t data, f_string_static_t *buffer, controller_rule_cache_t *cache, controller_rule_item_t *item) { + f_return_status controller_rule_item_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_item_t *item) { f_status_t status = F_none; - f_string_range_t range = f_macro_string_range_t_initialize(buffer->used); + f_string_range_t range = f_macro_string_range_t_initialize(cache->buffer_item.used); f_fss_quote_t quote = 0; controller_rule_actions_t *actions = 0; bool multiple = F_false; - for (range.start = 0; range.start < buffer->used && range.start <= range.stop; cache->delimits.used = 0, cache->comments.used = 0) { + for (range.start = 0; range.start < cache->buffer_item.used && range.start <= range.stop; cache->delimits.used = 0, cache->comments.used = 0) { - status = fl_fss_extended_list_object_read(*buffer, &range, &cache->range_action, &cache->delimits); + status = fl_fss_extended_list_object_read(cache->buffer_item, &range, &cache->range_action, &cache->delimits); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_list_object_read", F_true); break; } - if (range.start >= range.stop || range.start >= buffer->used) { + if (range.start >= range.stop || range.start >= cache->buffer_item.used) { if (status == FL_fss_found_object || status == FL_fss_found_object_content_not) { if (data.error.verbosity != f_console_verbosity_quiet) { fprintf(data.error.to.stream, "%c", f_string_eol[0]); @@ -300,7 +306,7 @@ extern "C" { cache->delimits.used = 0; // The current line is not an Extended List object, so the next possibility is a Basic List (and Extended List, both use the same Object structure). - status = fl_fss_basic_object_read(*buffer, &range, &cache->range_action, "e, &cache->delimits); + status = fl_fss_basic_object_read(cache->buffer_item, &range, &cache->range_action, "e, &cache->delimits); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_object_read", F_true); @@ -308,20 +314,20 @@ extern "C" { } } - if (status == FL_fss_found_object_content_not || range.start >= range.stop || range.start >= buffer->used) { + if (status == FL_fss_found_object_content_not || range.start >= range.stop || range.start >= cache->buffer_item.used) { // object ended without any content. break; } if (status == FL_fss_found_object) { - status = fl_fss_apply_delimit(cache->delimits, buffer); + status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true); break; } - status = f_fss_count_lines(*buffer, cache->range_action.start, &cache->line_action); + status = f_fss_count_lines(cache->buffer_item, cache->range_action.start, &cache->line_action); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true); @@ -331,7 +337,7 @@ extern "C" { cache->line_action += item->line; cache->name_action.used = 0; - status = fl_string_dynamic_rip_nulless(*buffer, cache->range_action, &cache->name_action); + status = fl_string_dynamic_rip_nulless(cache->buffer_item, cache->range_action, &cache->name_action); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_rip_nulless", F_true); @@ -407,7 +413,7 @@ extern "C" { actions->type = controller_rule_action_type_extended; } - status = controller_rule_actions_read(data, buffer, cache, item, actions, &range); + status = controller_rule_actions_read(data, cache, item, actions, &range); if (F_status_is_error(status)) break; } } // for @@ -443,11 +449,22 @@ extern "C" { #endif // _di_controller_rule_items_increase_by_ #ifndef _di_controller_rule_read_ - f_return_status controller_rule_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_items_t *items) { + f_return_status controller_rule_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_t *rule) { f_status_t status = F_none; - f_string_dynamic_t buffer = f_string_dynamic_t_initialize; - items->used = 0; + rule->items.used = 0; + + cache->delimits.used = 0; + cache->comments.used = 0; + + cache->buffer_items.used = 0; + cache->contents_items.used = 0; + cache->objects_items.used = 0; + + rule->status = F_found_not; + + // @todo construct the rule->id from the file path name, strip the ".rule" extension and only accept the relative part of the path (relative to the base settings directory). + // @todo the base settings directory should be a configurable string, such as with a "-s/--settings" parameter which defaults to a compiled in value (such as /etc/controller/rules/)". { f_file_t file = f_file_t_initialize; @@ -458,38 +475,32 @@ extern "C" { fll_error_file_print(data.error, F_status_set_fine(status), "f_file_stream_open", F_true, cache->name_file.string, "open", fll_error_file_type_file); } else { - status = f_file_stream_read(file, 1, &buffer); + status = f_file_stream_read(file, 1, &cache->buffer_items); if (F_status_is_error(status)) { fll_error_file_print(data.error, F_status_set_fine(status), "f_file_stream_read", F_true, cache->name_file.string, "read", fll_error_file_type_file); } + else { + // Setting to F_none from F_unknown distinguishes the two such that F_none suggests a valid rule and F_unknown is just that, unknown. + rule->status = F_none; + } } f_file_stream_close(F_true, &file); - if (F_status_is_error(status)) { - f_macro_string_dynamic_t_delete_simple(buffer); - return F_false; - } + if (F_status_is_error(status)) return F_false; } - // @todo add these to the cache without conflicting with the actions use of objects and contents. - f_fss_objects_t objects = f_fss_objects_t_initialize; - f_fss_contents_t contents = f_fss_contents_t_initialize; - - if (buffer.used) { - f_string_range_t range = f_macro_string_range_t_initialize(buffer.used); - - cache->delimits.used = 0; - cache->comments.used = 0; + if (cache->buffer_items.used) { + f_string_range_t range = f_macro_string_range_t_initialize(cache->buffer_items.used); - status = fll_fss_basic_list_read(buffer, &range, &objects, &contents, &cache->delimits, 0, &cache->comments); + status = fll_fss_basic_list_read(cache->buffer_items, &range, &cache->objects_items, &cache->contents_items, &cache->delimits, 0, &cache->comments); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true); } else { - status = fl_fss_apply_delimit(cache->delimits, &buffer); + status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_items); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true); @@ -497,44 +508,44 @@ extern "C" { } } - if (F_status_is_error_not(status) && objects.used) { - status = controller_rule_items_increase_by(objects.used, items); + if (F_status_is_error_not(status) && cache->objects_items.used) { + status = controller_rule_items_increase_by(cache->objects_items.used, &rule->items); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "controller_rule_items_increase_by", F_true); } else { - f_string_dynamic_t content = f_string_dynamic_t_initialize; - - for (f_array_length_t i = 0; i < objects.used; ++i) { + for (f_array_length_t i = 0; i < cache->objects_items.used; ++i) { cache->line_item = 0; cache->line_action = 0; - cache->range_item = objects.array[i]; cache->range_action.start = 1; cache->range_action.stop = 0; + cache->range_item = cache->objects_items.array[i]; cache->comments.used = 0; - cache->content.used = 0; - cache->contents.used = 0; cache->delimits.used = 0; - cache->objects.used = 0; + cache->content_action.used = 0; + cache->objects_action.used = 0; + + cache->buffer_item.used = 0; + + cache->name_action.used = 0; cache->name_file.used = 0; cache->name_item.used = 0; - cache->name_action.used = 0; - status = f_fss_count_lines(buffer, cache->range_item.start, &cache->line_item); + status = f_fss_count_lines(cache->buffer_items, cache->range_item.start, &cache->line_item); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true); break; } - items->array[items->used].line = cache->line_item; + rule->items.array[rule->items.used].line = cache->line_item; - status = fl_string_dynamic_rip_nulless(buffer, cache->range_item, &cache->name_item); + status = fl_string_dynamic_rip_nulless(cache->buffer_items, cache->range_item, &cache->name_item); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_rip_nulless", F_true); @@ -548,8 +559,7 @@ extern "C" { break; } - content.used = 0; - status = fl_string_dynamic_partial_append(buffer, contents.array[i].array[0], &content); + status = fl_string_dynamic_partial_append(cache->buffer_items, cache->contents_items.array[i].array[0], &cache->buffer_item); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append", F_true); @@ -557,16 +567,16 @@ extern "C" { } if (fl_string_dynamic_compare_string(controller_string_settings, cache->name_item, controller_string_settings_length) == F_equal_to) { - items->array[items->used].type = 0; + rule->items.array[rule->items.used].type = 0; } else if (fl_string_dynamic_compare_string(controller_string_command, cache->name_item, controller_string_command_length) == F_equal_to) { - items->array[items->used].type = controller_rule_item_type_command; + rule->items.array[rule->items.used].type = controller_rule_item_type_command; } else if (fl_string_dynamic_compare_string(controller_string_script, cache->name_item, controller_string_script_length) == F_equal_to) { - items->array[items->used].type = controller_rule_item_type_script; + rule->items.array[rule->items.used].type = controller_rule_item_type_script; } else if (fl_string_dynamic_compare_string(controller_string_service, cache->name_item, controller_string_service_length) == F_equal_to) { - items->array[items->used].type = controller_rule_item_type_service; + rule->items.array[rule->items.used].type = controller_rule_item_type_service; } else { if (data.warning.verbosity == f_console_verbosity_debug) { @@ -579,33 +589,41 @@ extern "C" { continue; } - if (items->array[items->used].type) { - status = controller_rule_item_read(data, &content, cache, &items->array[items->used]); + if (rule->items.array[rule->items.used].type) { + status = controller_rule_item_read(data, cache, &rule->items.array[rule->items.used]); if (F_status_is_error(status)) break; - items->used++; + rule->items.used++; } else { - // @todo handle rule settings population. + status = controller_rule_setting_read(data, cache, rule); + if (F_status_is_error(status)) break; } } // for - - f_macro_string_dynamic_t_delete_simple(content); } } - f_macro_fss_objects_t_delete_simple(objects); - f_macro_fss_contents_t_delete_simple(contents); - f_macro_string_dynamic_t_delete_simple(buffer); - if (F_status_is_error(status)) { controller_rule_error_print(data.error, *cache); + + // designate that the rule is invalid, for any failure. + rule->status = F_status_set_error(F_invalid); } return status; } #endif // _di_controller_rule_read_ +#ifndef _di_controller_rule_setting_read_ + f_return_status controller_rule_setting_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_t *rule) { + f_status_t status = F_none; + + // @todo + + return status; + } +#endif // _di_controller_rule_setting_read_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/controller/c/private-rule.h b/level_3/controller/c/private-rule.h index 6b26921..1778ab5 100644 --- a/level_3/controller/c/private-rule.h +++ b/level_3/controller/c/private-rule.h @@ -14,21 +14,27 @@ extern "C" { #ifndef _di_controller_rule_cache_t_ typedef struct { - f_string_length_t line_item; f_string_length_t line_action; + f_string_length_t line_item; - f_string_range_t range_item; f_string_range_t range_action; + f_string_range_t range_item; f_fss_comments_t comments; - f_fss_content_t content; - f_fss_contents_t contents; f_fss_delimits_t delimits; - f_fss_objects_t objects; + f_fss_content_t content_action; + f_fss_contents_t contents_action; + f_fss_contents_t contents_items; + f_fss_objects_t objects_action; + f_fss_objects_t objects_items; + + f_string_dynamic_t buffer_item; + f_string_dynamic_t buffer_items; + + f_string_dynamic_t name_action; f_string_dynamic_t name_file; f_string_dynamic_t name_item; - f_string_dynamic_t name_action; } controller_rule_cache_t; #define controller_rule_cache_t_initialize \ @@ -37,25 +43,33 @@ extern "C" { 0, \ 0, \ 0, \ + f_fss_comments_t_initialize, \ f_fss_delimits_t_initialize, \ f_fss_content_t_initialize, \ f_fss_contents_t_initialize, \ - f_fss_comments_t_initialize, \ + f_fss_contents_t_initialize, \ + f_fss_objects_t_initialize, \ f_fss_objects_t_initialize, \ f_string_dynamic_t_initialize, \ f_string_dynamic_t_initialize, \ f_string_dynamic_t_initialize, \ + f_string_dynamic_t_initialize, \ + f_string_dynamic_t_initialize, \ } #define f_macro_controller_rule_name_t_delete_simple(cache) \ f_macro_fss_comments_t_delete_simple(cache.comments) \ - f_macro_fss_content_t_delete_simple(cache.content) \ - f_macro_fss_contents_t_delete_simple(cache.contents) \ f_macro_fss_delimits_t_delete_simple(cache.delimits) \ - f_macro_fss_objects_t_delete_simple(cache.objects) \ + f_macro_fss_content_t_delete_simple(cache.content_action) \ + f_macro_fss_contents_t_delete_simple(cache.contents_action) \ + f_macro_fss_contents_t_delete_simple(cache.contents_items) \ + f_macro_fss_objects_t_delete_simple(cache.objects_action) \ + f_macro_fss_objects_t_delete_simple(cache.objects_items) \ + f_macro_string_dynamic_t_delete_simple(cache.buffer_item) \ + f_macro_string_dynamic_t_delete_simple(cache.buffer_items) \ + f_macro_string_dynamic_t_delete_simple(cache.name_action) \ f_macro_string_dynamic_t_delete_simple(cache.name_file) \ - f_macro_string_dynamic_t_delete_simple(cache.name_item) \ - f_macro_string_dynamic_t_delete_simple(cache.name_action) + f_macro_string_dynamic_t_delete_simple(cache.name_item) #endif // _di_controller_rule_cache_t_ /** @@ -116,10 +130,8 @@ extern "C" { * * @param data * The program data. - * @param buffer - * The buffer containing the content. * @param cache - * A structure for containing and caching the file name, item name, and action name. + * A structure for containing and caching relevant data. * @param item * The processed item. * @param actions @@ -140,7 +152,7 @@ extern "C" { * @see f_fss_count_lines() */ #ifndef _di_controller_rule_actions_read_ - extern f_return_status controller_rule_actions_read(const controller_data_t data, f_string_static_t *buffer, controller_rule_cache_t *cache, controller_rule_item_t *item, controller_rule_actions_t *actions, f_string_range_t *range) f_gcc_attribute_visibility_internal; + extern f_return_status controller_rule_actions_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_item_t *item, controller_rule_actions_t *actions, f_string_range_t *range) f_gcc_attribute_visibility_internal; #endif // _di_controller_rule_actions_read_ /** @@ -151,7 +163,7 @@ extern "C" { * @param output * The error or warning output structure. * @param cache - * A structure for containing and caching the file name, item name, and action name. + * A structure for containing and caching relevant data. * * @see controller_rule_actions_read() * @see controller_rule_items_read() @@ -168,10 +180,8 @@ extern "C" { * * @param data * The program data. - * @param buffer - * The buffer containing the content. * @param cache - * A structure for containing and caching the file name, item name, and action name. + * A structure for containing and caching relevant data. * @param item * The processed item. * @@ -188,7 +198,7 @@ extern "C" { * @see fl_string_dynamic_terminate_after() */ #ifndef _di_controller_rule_item_read_ - extern f_return_status controller_rule_item_read(const controller_data_t data, f_string_static_t *buffer, controller_rule_cache_t *cache, controller_rule_item_t *item) f_gcc_attribute_visibility_internal; + extern f_return_status controller_rule_item_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_item_t *item) f_gcc_attribute_visibility_internal; #endif // _di_controller_rule_item_read_ /** @@ -219,9 +229,9 @@ extern "C" { * @param data * The program data. * @param cache - * A structure for containing and caching the file name, item name, and action name. - * @param items - * The processed array of items. + * A structure for containing and caching relevant data. + * @param rule + * The processed rule. * * @return * F_none on success. @@ -249,9 +259,32 @@ extern "C" { * @see fll_fss_basic_list_read(). */ #ifndef _di_controller_rule_read_ - extern f_return_status controller_rule_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_items_t *items) f_gcc_attribute_visibility_internal; + extern f_return_status controller_rule_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_t *rule) f_gcc_attribute_visibility_internal; #endif // _di_controller_rule_read_ +/** + * Read the content within the buffer, extracting all valid settings. + * + * This will perform additional FSS read functions as appropriate. + * + * @param data + * The program data. + * @param cache + * A structure for containing and caching relevant data. + * @param rule + * The processed rule. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_fss_count_lines(). + * + * @see f_fss_count_lines() + */ +#ifndef _di_controller_rule_setting_read_ + extern f_return_status controller_rule_setting_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_t *rule) f_gcc_attribute_visibility_internal; +#endif // _di_controller_rule_setting_read_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/controller/documents/rule.txt b/level_3/controller/documents/rule.txt index b7d55de..c6aff67 100644 --- a/level_3/controller/documents/rule.txt +++ b/level_3/controller/documents/rule.txt @@ -11,9 +11,16 @@ Rule Documentation: The "settings" outer most list Object has the following FSS-0001 (Extended) Content: "define": Define a custom environment variable with a given variable, and automatically expose it to processes executed within this rule. "environment": A set of environment variables to expose to the processes executed within this rule (PATH is always exposed). - "name": A name used to represent this rule, which is printing to the user, screen, logs, etc... + "name": A name used to represent this rule, which is printing to the user, screen, logs, etc.. (this is required). + "need": A list of relative rule path names that represent any given rule required to be executed (must exist and must succeed) before this rule starts. + "path": A single Content used to set a custom PATH environment variable value. "pid": A path to a directory where the PID file is expected to be stored in. - @todo: consider adding "path" to allow specifying a custom environment PATH variable (or even go a step further and instead provide "environment" or "variable"). + "want": A list of relative rule path names that represent any given rule desired to be executed (may exist and must succeed) before this rule starts. + "wish": A list of relative rule path names that represent any given rule desired to be executed (may exist and not required to succeed) before this rule starts. + + In the case of "want" and "wish", if the desired rule is either not found or is otherwise disabled, then this will not fail or otherwise block the wanting or wishing rule. + + In the case of "path", when specified, the PATH environment variable is automatically added to the "environment" setting. The "command" outer most part provides a simple command to run under the different circumstances: "start", "stop", "restart", and "reload". A "command" always operates in the foreground. diff --git a/level_3/controller/specifications/rule.txt b/level_3/controller/specifications/rule.txt index 70a2e1d..e2f072c 100644 --- a/level_3/controller/specifications/rule.txt +++ b/level_3/controller/specifications/rule.txt @@ -6,18 +6,22 @@ Rule Specification: A rule file name is expected to have the file extension ".rule". The outer most part, which is essentially FSS-0002 (Basic List), has the following Objects\: - "settings": Required. "command": A Basic List of FSS-0001 (Extended) Object and Content, supporting the following Objects: "group", "restart", "reload", "start", "stop", and "user". "script": A Basic List of FSS-0003 (Extended List) Object and Content, supporting the following Objects: "restart", "reload", "start", and "stop" and A Basic List of FSS-0001 (Extended) Object and Content, supporting the following: "group" and "user". "service": A Basic List of FSS-0001 (Extended) Object and Content, supporting the following Objects: ""create", "group", "use", "restart", "reload", "start", "stop", "timeout", and "user". + "settings": A (Required) Basic List of FSS-0001 (Extended) Object and Content, supporting the following Objects: "define", "environment", "name", "need", "pid", "want", "wish". For the above Basic List Objects, "main" may be specified only once whereas the others may be specifed multiple times. The "settings" outer most list Object has the following FSS-0001 (Extended) Content: "define": Two Content, the first Content must be a case-sensitive valid environment variable name (alpha-numeric or underscore, but no leading digits). "environment": Zero or more Content, each must be a case-sensitive valid environment variable name (alpha-numeric or underscore, but no leading digits). - "name": One Content, must have at least 1 non-whitespace printing character. - "pid": One Content representing the path to a PID file directory. + "name": (Required) One Content, must have at least 1 non-whitespace printing character. + "need": Zero or more Content, each being a partial path and the rule file name without extension (such as "boot/modules"). + "path": Zero or One Content representing a valid PATH environment string (such as "/bin:/sbin:/usr/bin"). + "pid": One Content representing the full path to a PID file directory (such as "/var/run/service/ssh.pid"). + "want": Zero or more Content, each being a partial path and the rule file name without extension (such as "boot/modules"). + "wish": Zero or more Content, each being a partial path and the rule file name without extension (such as "boot/modules"). For the inner parts, these are the Extended Objects\: "create": One Content representing the path to a PID file. -- 1.8.3.1