From 85cb89b4a501122b90afb812ba5265a64c74b04c Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sun, 29 Nov 2020 00:06:47 -0600 Subject: [PATCH] Progress: controller program and add F_encoding and F_encoding_not status codes. --- level_0/f_status/c/status.h | 2 + level_1/fl_status/c/status.c | 6 + level_1/fl_status/c/status.h | 4 + level_2/fll_status/c/status.c | 10 + level_3/controller/c/controller.c | 38 ++- level_3/controller/c/controller.h | 6 +- level_3/controller/c/private-controller.c | 31 +++ level_3/controller/c/private-controller.h | 256 ++++++++--------- level_3/controller/c/private-entry.c | 306 +++++++++++++++++---- level_3/controller/c/private-entry.h | 44 ++- level_3/controller/c/private-rule.c | 82 +++--- level_3/controller/c/private-rule.h | 2 +- level_3/controller/data/build/dependencies | 2 + level_3/controller/data/build/settings | 2 +- .../controller/data/settings/entries/default.entry | 45 +++ .../data/settings/rules/boot/devices.rule | 9 + .../data/settings/rules/boot/filesystem.rule | 15 + .../data/settings/rules/boot/modules.rule | 22 ++ .../data/settings/rules/maintenance/console.rule | 10 + .../controller/data/settings/rules/net/all.rule | 12 + .../data/settings/rules/net/loopback.rule | 19 ++ .../data/settings/rules/program/terminal.rule | 28 ++ .../data/settings/rules/service/dbus.rule | 12 + .../data/settings/rules/service/logger.rule | 13 + .../data/settings/rules/service/mouse.rule | 20 ++ level_3/controller/data/settings/rules/task/clock | 30 ++ .../controller/data/settings/rules/task/keyboard | 7 + level_3/controller/documents/entry.txt | 62 +++-- level_3/controller/documents/rule.txt | 5 +- level_3/controller/specifications/entry.txt | 18 +- level_3/controller/specifications/rule.txt | 62 ++++- 31 files changed, 890 insertions(+), 290 deletions(-) create mode 100644 level_3/controller/data/settings/entries/default.entry create mode 100644 level_3/controller/data/settings/rules/boot/devices.rule create mode 100644 level_3/controller/data/settings/rules/boot/filesystem.rule create mode 100644 level_3/controller/data/settings/rules/boot/modules.rule create mode 100644 level_3/controller/data/settings/rules/maintenance/console.rule create mode 100644 level_3/controller/data/settings/rules/net/all.rule create mode 100644 level_3/controller/data/settings/rules/net/loopback.rule create mode 100644 level_3/controller/data/settings/rules/program/terminal.rule create mode 100644 level_3/controller/data/settings/rules/service/dbus.rule create mode 100644 level_3/controller/data/settings/rules/service/logger.rule create mode 100644 level_3/controller/data/settings/rules/service/mouse.rule create mode 100644 level_3/controller/data/settings/rules/task/clock create mode 100644 level_3/controller/data/settings/rules/task/keyboard diff --git a/level_0/f_status/c/status.h b/level_0/f_status/c/status.h index 210a835..c572a90 100644 --- a/level_0/f_status/c/status.h +++ b/level_0/f_status/c/status.h @@ -156,6 +156,8 @@ extern "C" { F_descriptor, F_device, F_dummy, + F_encoding, + F_encoding_not, F_eof, F_eol, F_eos, diff --git a/level_1/fl_status/c/status.c b/level_1/fl_status/c/status.c index bae4d0d..ecc8339 100644 --- a/level_1/fl_status/c/status.c +++ b/level_1/fl_status/c/status.c @@ -251,6 +251,12 @@ extern "C" { case F_dummy: *string = FL_status_string_dummy; break; + case F_encoding: + *string = FL_status_string_encoding; + break; + case F_encoding_not: + *string = FL_status_string_encoding_not; + break; case F_eof: *string = FL_status_string_eof; break; diff --git a/level_1/fl_status/c/status.h b/level_1/fl_status/c/status.h index 8d69c1e..cafe7dd 100644 --- a/level_1/fl_status/c/status.h +++ b/level_1/fl_status/c/status.h @@ -175,6 +175,8 @@ extern "C" { #define FL_status_string_descriptor "F_descriptor" #define FL_status_string_device "F_device" #define FL_status_string_dummy "F_dummy" + #define FL_status_string_encoding "F_encoding" + #define FL_status_string_encoding_not "F_encoding_not" #define FL_status_string_eof "F_eof" #define FL_status_string_eol "F_eol" #define FL_status_string_eos "F_eos" @@ -240,6 +242,8 @@ extern "C" { #define FL_status_string_descriptor_length 12 #define FL_status_string_device_length 8 #define FL_status_string_dummy_length 7 + #define FL_status_string_encoding_length 10 + #define FL_status_string_encoding_not_length 14 #define FL_status_string_eof_length 5 #define FL_status_string_eol_length 5 #define FL_status_string_eos_length 5 diff --git a/level_2/fll_status/c/status.c b/level_2/fll_status/c/status.c index 7ee5bb6..7f901ec 100644 --- a/level_2/fll_status/c/status.c +++ b/level_2/fll_status/c/status.c @@ -421,6 +421,16 @@ extern "C" { return F_none; } + if (fl_string_compare(string, FL_status_string_encoding, length, FL_status_string_encoding_length) == F_equal_to) { + *code = F_encoding; + return F_none; + } + + if (fl_string_compare(string, FL_status_string_encoding_not, length, FL_status_string_encoding_not_length) == F_equal_to) { + *code = F_encoding_not; + return F_none; + } + if (fl_string_compare(string, FL_status_string_eof, length, FL_status_string_eof_length) == F_equal_to) { *code = F_eof; return F_none; diff --git a/level_3/controller/c/controller.c b/level_3/controller/c/controller.c index 550a32b..b97923f 100644 --- a/level_3/controller/c/controller.c +++ b/level_3/controller/c/controller.c @@ -25,12 +25,13 @@ extern "C" { fprintf(output.stream, "%c", f_string_eol[0]); - fll_program_print_help_option(output, context, controller_short_interruptable, controller_long_interruptable, f_console_symbol_short_enable, f_console_symbol_long_enable, " Designate that this program can be interrupted."); - fll_program_print_help_option(output, context, controller_short_pid, controller_long_pid, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a custom pid file path, such as '" controller_path_pid "'."); + fll_program_print_help_option(output, context, controller_short_interruptable, controller_long_interruptable, f_console_symbol_short_enable, f_console_symbol_long_enable, "Designate that this program can be interrupted."); + fll_program_print_help_option(output, context, controller_short_pid, controller_long_pid, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a custom pid file path, such as '" controller_path_pid "'."); fll_program_print_help_option(output, context, controller_short_settings, controller_long_settings, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a custom settings path, such as '" controller_path_settings "'."); - fll_program_print_help_option(output, context, controller_short_test, controller_long_test, f_console_symbol_short_enable, f_console_symbol_long_enable, " Run in test mode, where nothing is actually run (a simulation)."); + fll_program_print_help_option(output, context, controller_short_test, controller_long_test, f_console_symbol_short_enable, f_console_symbol_long_enable, " Run in test mode, where nothing is actually run (a simulation)."); + fll_program_print_help_option(output, context, controller_short_validate, controller_long_validate, f_console_symbol_short_enable, f_console_symbol_long_enable, " Validate the settings (entry and rules)."); - fll_program_print_help_usage(output, context, controller_name, ""); + fll_program_print_help_usage(output, context, controller_name, "entry"); return F_none; } @@ -116,6 +117,31 @@ extern "C" { return F_none; } + controller_setting_t setting = controller_setting_t_initialize; + + controller_entry_cache_t cache_entry = controller_entry_cache_t_initialize; + controller_rule_cache_t cache_rule = controller_rule_cache_t_initialize; + + f_string_static_t entry_name = f_string_static_t_initialize; + + if (data->remaining.used) { + entry_name.string = arguments.argv[data->remaining.array[0]]; + entry_name.used = strnlen(entry_name.string, f_console_length_size); + entry_name.size = entry_name.used; + } + else { + entry_name.string = controller_string_default; + entry_name.used = controller_string_default_length; + entry_name.size = entry_name.used; + } + + status = controller_entry_read(*data, setting, entry_name, &cache_entry, &setting.entry); + + // @fixme this is temporary for testing. + if (F_status_is_error(setting.entry.status)) { + status = setting.entry.status; + } + // @todo // ensure a newline is always put at the end of the program execution, unless in quiet mode. @@ -125,7 +151,11 @@ extern "C" { } } + macro_controller_setting_t_delete_simple(setting); + macro_controller_entry_cache_t_delete_simple(cache_entry); + macro_controller_rule_cache_t_delete_simple(cache_rule); controller_delete_data(data); + return status; } #endif // _di_controller_main_ diff --git a/level_3/controller/c/controller.h b/level_3/controller/c/controller.h index 2ceb047..4036d7b 100644 --- a/level_3/controller/c/controller.h +++ b/level_3/controller/c/controller.h @@ -78,11 +78,13 @@ extern "C" { #define controller_short_pid "p" #define controller_short_settings "s" #define controller_short_test "t" + #define controller_short_validate "V" #define controller_long_interruptable "interruptable" #define controller_long_pid "pid" #define controller_long_settings "settings" #define controller_long_test "test" + #define controller_long_validate "validate" enum { controller_parameter_help, @@ -99,6 +101,7 @@ extern "C" { controller_parameter_pid, controller_parameter_settings, controller_parameter_test, + controller_parameter_validate, }; #define controller_console_parameter_t_initialize \ @@ -116,9 +119,10 @@ extern "C" { f_console_parameter_t_initialize(controller_short_pid, controller_long_pid, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(controller_short_settings, controller_long_settings, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(controller_short_test, controller_long_test, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(controller_short_validate, controller_long_validate, 0, 0, f_console_type_normal), \ } - #define controller_total_parameters 13 + #define controller_total_parameters 14 #endif // _di_controller_defines_ #ifndef _di_controller_data_t_ diff --git a/level_3/controller/c/private-controller.c b/level_3/controller/c/private-controller.c index 2e5c73a..27f9751 100644 --- a/level_3/controller/c/private-controller.c +++ b/level_3/controller/c/private-controller.c @@ -79,6 +79,37 @@ extern "C" { } #endif // _di_controller_file_load_ +#ifndef _di_controller_status_simplify_ + f_return_status controller_status_simplify(const f_status_t status) { + + if (status == F_memory_not || status == F_memory_allocation || status == F_memory_reallocation) { + return F_status_set_error(F_memory); + } + + if (status == F_file_open_max || status == F_space_not || status == F_busy) { + return F_status_set_error(F_resource); + } + + if (status == F_access_denied || status == F_filesystem_quota_block || status == F_prohibited || status == F_input_output) { + return F_status_set_error(F_access); + } + + if (status == F_incomplete_utf || status == F_incomplete_utf_block || status == F_incomplete_utf_eof || status == F_incomplete_utf_eol || status == F_incomplete_utf_eos || status == F_incomplete_utf_stop) { + return F_status_set_error(F_encoding); + } + + if (status == F_number || status == F_number_negative || status == F_number_positive || status == F_number_overflow) { + return F_status_set_error(F_number); + } + + if (status == F_parameter || status == F_found_not || status == F_interrupted) { + return F_status_set_error(status); + } + + return F_status_set_error(F_invalid); + } +#endif // _di_controller_status_simplify_ + #ifndef _di_controller_validate_define_name_ f_return_status controller_validate_environment_name(const f_string_static_t name) { diff --git a/level_3/controller/c/private-controller.h b/level_3/controller/c/private-controller.h index 5bc8902..34aeb74 100644 --- a/level_3/controller/c/private-controller.h +++ b/level_3/controller/c/private-controller.h @@ -13,96 +13,109 @@ extern "C" { #endif #ifndef _di_controller_string_ - #define controller_string_create "create" - #define controller_string_command "command" - #define controller_string_consider "consider" - #define controller_string_default "default" - #define controller_string_define "define" - #define controller_string_entry "entry" - #define controller_string_entries "entries" - #define controller_string_environment "environment" - #define controller_string_failsafe "failsafe" - #define controller_string_group "group" - #define controller_string_item "item" - #define controller_string_main "main" - #define controller_string_name "name" - #define controller_string_need "need" - #define controller_string_path "path" - #define controller_string_pid "pid" - #define controller_string_ready "ready" - #define controller_string_restart "restart" - #define controller_string_reload "reload" - #define controller_string_rule "rule" - #define controller_string_rules "rules" - #define controller_string_script "script" - #define controller_string_service "service" - #define controller_string_settings "settings" - #define controller_string_start "start" - #define controller_string_stop "stop" - #define controller_string_timeout "timeout" - #define controller_string_use "use" - #define controller_string_user "user" - #define controller_string_want "want" - #define controller_string_wish "wish" - - #define controller_string_create_length 6 - #define controller_string_command_length 7 - #define controller_string_consider_length 8 - #define controller_string_define_length 6 - #define controller_string_default_length 7 - #define controller_string_entry_length 5 - #define controller_string_entries_length 7 - #define controller_string_environment_length 11 - #define controller_string_failsafe_length 8 - #define controller_string_group_length 5 - #define controller_string_item_length 4 - #define controller_string_main_length 4 - #define controller_string_name_length 4 - #define controller_string_need_length 4 - #define controller_string_path_length 4 - #define controller_string_pid_length 3 - #define controller_string_ready_length 5 - #define controller_string_restart_length 7 - #define controller_string_reload_length 6 - #define controller_string_rule_length 4 - #define controller_string_rules_length 5 - #define controller_string_script_length 6 - #define controller_string_service_length 7 - #define controller_string_settings_length 8 - #define controller_string_start_length 5 - #define controller_string_stop_length 4 - #define controller_string_timeout_length 7 - #define controller_string_use_length 3 - #define controller_string_user_length 4 - #define controller_string_want_length 4 - #define controller_string_wish_length 4 + #define controller_string_asynchronous "asynchronous" + #define controller_string_create "create" + #define controller_string_command "command" + #define controller_string_consider "consider" + #define controller_string_default "default" + #define controller_string_define "define" + #define controller_string_entry "entry" + #define controller_string_entries "entries" + #define controller_string_environment "environment" + #define controller_string_failsafe "failsafe" + #define controller_string_group "group" + #define controller_string_item "item" + #define controller_string_kill "kill" + #define controller_string_main "main" + #define controller_string_name "name" + #define controller_string_need "need" + #define controller_string_path "path" + #define controller_string_pid "pid" + #define controller_string_ready "ready" + #define controller_string_reload "reload" + #define controller_string_require "require" + #define controller_string_restart "restart" + #define controller_string_rule "rule" + #define controller_string_rules "rules" + #define controller_string_script "script" + #define controller_string_service "service" + #define controller_string_settings "settings" + #define controller_string_start "start" + #define controller_string_stop "stop" + #define controller_string_timeout "timeout" + #define controller_string_use "use" + #define controller_string_user "user" + #define controller_string_wait "wait" + #define controller_string_want "want" + #define controller_string_wish "wish" + + #define controller_string_asynchronous_length 12 + #define controller_string_create_length 6 + #define controller_string_command_length 7 + #define controller_string_consider_length 8 + #define controller_string_define_length 6 + #define controller_string_default_length 7 + #define controller_string_entry_length 5 + #define controller_string_entries_length 7 + #define controller_string_environment_length 11 + #define controller_string_failsafe_length 8 + #define controller_string_group_length 5 + #define controller_string_item_length 4 + #define controller_string_kill_length 4 + #define controller_string_main_length 4 + #define controller_string_name_length 4 + #define controller_string_need_length 4 + #define controller_string_path_length 4 + #define controller_string_pid_length 3 + #define controller_string_ready_length 5 + #define controller_string_reload_length 6 + #define controller_string_require_length 7 + #define controller_string_restart_length 7 + #define controller_string_rule_length 4 + #define controller_string_rules_length 5 + #define controller_string_script_length 6 + #define controller_string_service_length 7 + #define controller_string_settings_length 8 + #define controller_string_start_length 5 + #define controller_string_stop_length 4 + #define controller_string_timeout_length 7 + #define controller_string_use_length 3 + #define controller_string_user_length 4 + #define controller_string_wait_length 4 + #define controller_string_want_length 4 + #define controller_string_wish_length 4 #endif // _di_controller_string_ #ifndef _di_controller_rule_action_t_ enum { - controller_rule_action_type_extended = 1, - controller_rule_action_type_extended_list, + controller_rule_action_method_extended = 1, + controller_rule_action_method_extended_list, }; enum { - controller_rule_action_intent_create = 1, - controller_rule_action_intent_group, - controller_rule_action_intent_restart, - controller_rule_action_intent_reload, - controller_rule_action_intent_start, - controller_rule_action_intent_stop, - controller_rule_action_intent_use, - controller_rule_action_intent_user, + controller_rule_action_type_create = 1, + controller_rule_action_type_group, + controller_rule_action_type_kill, + controller_rule_action_type_restart, + controller_rule_action_type_reload, + controller_rule_action_type_start, + controller_rule_action_type_stop, + controller_rule_action_type_use, + controller_rule_action_type_user, }; typedef struct { f_string_length_t line; + + f_status_t status; + f_string_dynamics_t parameters; } controller_rule_action_t; #define controller_rule_action_t_initialize \ { \ 0, \ + F_unknown, \ f_string_dynamics_t_initialize, \ } @@ -112,8 +125,8 @@ extern "C" { #ifndef _di_controller_rule_actions_t_ typedef struct { + uint8_t method; uint8_t type; - uint8_t intent; controller_rule_action_t *array; @@ -134,7 +147,7 @@ extern "C" { actions.used = actions.size; \ while (actions.used > 0) { \ actions.used--; \ - macro_controller_rule_item_t_delete_simple(actions.array[actions.used]); \ + macro_controller_rule_action_t_delete_simple(actions.array[actions.used]); \ if (!actions.used) { \ if (f_memory_delete((void **) & actions.array, sizeof(controller_rule_action_t), actions.size)) { \ actions.size = 0; \ @@ -155,14 +168,7 @@ extern "C" { uint8_t type; f_string_length_t line; - controller_rule_actions_t create; - controller_rule_actions_t group; - controller_rule_actions_t restart; - controller_rule_actions_t reload; - controller_rule_actions_t start; - controller_rule_actions_t stop; - controller_rule_actions_t use; - controller_rule_actions_t user; + controller_rule_actions_t actions; } controller_rule_item_t; #define controller_rule_item_t_initialize \ @@ -170,24 +176,10 @@ extern "C" { 0, \ 0, \ controller_rule_actions_t_initialize, \ - controller_rule_actions_t_initialize, \ - controller_rule_actions_t_initialize, \ - controller_rule_actions_t_initialize, \ - controller_rule_actions_t_initialize, \ - controller_rule_actions_t_initialize, \ - controller_rule_actions_t_initialize, \ - controller_rule_actions_t_initialize, \ } #define macro_controller_rule_item_t_delete_simple(item) \ - macro_controller_rule_actions_t_delete_simple(item.create) \ - macro_controller_rule_actions_t_delete_simple(item.group) \ - macro_controller_rule_actions_t_delete_simple(item.restart) \ - macro_controller_rule_actions_t_delete_simple(item.reload) \ - macro_controller_rule_actions_t_delete_simple(item.start) \ - macro_controller_rule_actions_t_delete_simple(item.stop) \ - macro_controller_rule_actions_t_delete_simple(item.use) \ - macro_controller_rule_actions_t_delete_simple(item.user) + macro_controller_rule_actions_t_delete_simple(item.actions) #endif // _di_controller_rule_item_t_ #ifndef _di_controller_rule_items_t_ @@ -254,18 +246,18 @@ extern "C" { controller_rule_items_initialize, \ } - #define macro_controller_rule_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.control_group) \ - f_string_dynamic_t_delete_simple(setting.path) \ - f_string_dynamic_t_delete_simple(setting.pid) \ - 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) \ - macro_controller_rule_item_t_delete_simple(setting.items) + #define macro_controller_rule_t_delete_simple(rule) \ + f_macro_string_dynamic_t_delete_simple(rule.id) \ + f_macro_string_dynamic_t_delete_simple(rule.name) \ + f_macro_string_dynamic_t_delete_simple(rule.control_group) \ + f_macro_string_dynamic_t_delete_simple(rule.path) \ + f_macro_string_dynamic_t_delete_simple(rule.pid) \ + f_macro_string_maps_t_delete_simple(rule.defines) \ + f_macro_string_dynamics_t_delete_simple(rule.environment) \ + f_macro_string_dynamics_t_delete_simple(rule.need) \ + f_macro_string_dynamics_t_delete_simple(rule.want) \ + f_macro_string_dynamics_t_delete_simple(rule.wish) \ + macro_controller_rule_items_t_delete_simple(rule.items) #endif // _di_controller_rule_t_ #ifndef _di_controller_rules_t_ @@ -336,8 +328,8 @@ extern "C" { f_string_dynamics_t_initialize, \ } - #define macro_controller_entry_action_t_delete_simple(item) \ - f_macro_string_dynamics_t_delete_simple(item.parameters) + #define macro_controller_entry_action_t_delete_simple(action) \ + f_macro_string_dynamics_t_delete_simple(action.parameters) #endif // _di_controller_entry_action_t_ #ifndef _di_controller_entry_actions_t_ @@ -355,14 +347,14 @@ extern "C" { 0, \ } - #define macro_controller_entry_actions_t_delete_simple(items) \ - items.used = items.size; \ - while (items.used > 0) { \ - items.used--; \ - macro_controller_rule_t_delete_simple(items.array[items.used]); \ - if (!items.used) { \ - if (f_memory_delete((void **) & items.array, sizeof(controller_entry_action_t), items.size)) { \ - items.size = 0; \ + #define macro_controller_entry_actions_t_delete_simple(actions) \ + actions.used = actions.size; \ + while (actions.used > 0) { \ + actions.used--; \ + macro_controller_entry_action_t_delete_simple(actions.array[actions.used]); \ + if (!actions.used) { \ + if (f_memory_delete((void **) & actions.array, sizeof(controller_entry_action_t), actions.size)) { \ + actions.size = 0; \ } \ } \ } @@ -383,9 +375,9 @@ extern "C" { controller_entry_actions_t_initialize, \ } - #define macro_controller_entry_item_t_delete_simple(list) \ - f_macro_string_dynamic_t_delete_simple(list.name) \ - macro_controller_entry_actions_t_delete_simple(list.actions) + #define macro_controller_entry_item_t_delete_simple(item) \ + f_macro_string_dynamic_t_delete_simple(item.name) \ + macro_controller_entry_actions_t_delete_simple(item.actions) #endif // _di_controller_entry_item_t_ #ifndef _di_controller_entry_items_t_ @@ -407,7 +399,7 @@ extern "C" { items.used = items.size; \ while (items.used > 0) { \ items.used--; \ - macro_controller_rule_t_delete_simple(items.array[items.used]); \ + macro_controller_entry_item_t_delete_simple(items.array[items.used]); \ if (!items.used) { \ if (f_memory_delete((void **) & items.array, sizeof(controller_entry_item_t), items.size)) { \ items.size = 0; \ @@ -454,9 +446,8 @@ extern "C" { #define macro_controller_setting_t_delete_simple(setting) \ f_macro_string_dynamic_t_delete_simple(setting.path_setting) \ - macro_controller_entry_items_t_delete_simple(entry_lists) \ macro_controller_entry_t_delete_simple(setting.entry) \ - f_macro_string_dynamic_t_delete_simple(setting.rules) + macro_controller_rules_t_delete_simple(setting.rules) #endif // _di_controller_setting_t /** @@ -495,6 +486,19 @@ extern "C" { #endif // _di_controller_file_load_ /** + * Given a wide range of status codes, simplify them down to a small subset. + * + * @param status + * The status code (without the error bit set) to simplify. + * + * @return + * A subset of status codes with error bit set. + */ +#ifndef _di_controller_status_simplify_ + extern f_return_status controller_status_simplify(const f_status_t status) f_gcc_attribute_visibility_internal; +#endif // _di_controller_status_simplify_ + +/** * Validate that the given string is a valid environment variable name. * * A valid environment variable name must begin with an alpha-character or an underscore. diff --git a/level_3/controller/c/private-entry.c b/level_3/controller/c/private-entry.c index b5331ad..3211646 100644 --- a/level_3/controller/c/private-entry.c +++ b/level_3/controller/c/private-entry.c @@ -95,7 +95,7 @@ extern "C" { break; } - status = fl_string_dynamic_rip_nulless(cache->buffer_item, cache->object_actions.array[i], &cache->name_action); + status = fl_string_dynamic_rip_nulless(cache->buffer_file, cache->object_actions.array[i], &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); @@ -213,6 +213,7 @@ extern "C" { break; } + for (j = 0; j < allocate; ++j) { action->parameters.array[j].used = 0; @@ -232,11 +233,144 @@ extern "C" { action->parameters.used++; } // for - if (F_status_is_error(status)) break; + if (F_status_is_error_not(action->status)) { + if (action->type == controller_entry_action_type_consider || action->type == controller_entry_action_type_rule) { + if (action->parameters.array[0].used) { + + // force the path to be canonical (removing all '../' parts). + status = fll_path_canonical(action->parameters.array[0].string, &cache->buffer_path); + + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "fll_path_canonical", F_true); + + if (F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) { + status_action = status; + break; + } + + if (F_status_is_error_not(status_action)) { + status_action = status; + } + } + } + else { + action->status = F_status_set_error(F_parameter); + + if (F_status_is_error_not(status_action)) { + status_action = action->status; + } + + if (data.error.verbosity != f_console_verbosity_quiet) { + fprintf(data.error.to.stream, "%c", f_string_eol[0]); + fprintf(data.error.to.stream, "%s%sThe entry item action must not have an empty string for a path (the first parameter).%s%c", data.error.context.before->string, data.error.prefix ? data.error.prefix : "", data.error.context.after->string, f_string_eol[0]); + } + } + + if (action->parameters.array[1].used) { + action->status = F_status_set_error(F_parameter); + + if (F_status_is_error_not(status_action)) { + status_action = action->status; + } + + if (data.error.verbosity != f_console_verbosity_quiet) { + fprintf(data.error.to.stream, "%c", f_string_eol[0]); + fprintf(data.error.to.stream, "%s%sThe entry item action must not have an empty string for a rule name (the second parameter).%s%c", data.error.context.before->string, data.error.prefix ? data.error.prefix : "", data.error.context.after->string, f_string_eol[0]); + } + } + + for (j = 2; j < action->parameters.used; ++j) { - // @todo validate if "timeout" paramter #1 is one of start, stop, or kill and parameter #2 is valid number. - // @todo validate if "consider" or "rule" parameters are valid (valid file path), (valid file basename), (then one of asynchronous, require, and/or wait). - // @todo: after entries are processed, check to see if "item" or "failsafe" reference existent items. + if (fl_string_dynamic_compare_string(controller_string_asynchronous, action->parameters.array[j], controller_string_asynchronous_length) == F_equal_to) { + // do nothing. + } + else if (fl_string_dynamic_compare_string(controller_string_require, action->parameters.array[j], controller_string_require_length) == F_equal_to) { + // do nothing. + } + else if (fl_string_dynamic_compare_string(controller_string_wait, action->parameters.array[j], controller_string_wait_length) == F_equal_to) { + // do nothing. + } + else { + if (action->status == F_none) { + action->status = F_status_set_error(F_unsupported); + + if (F_status_is_error_not(status_action)) { + status_action = action->status; + } + } + + if (data.error.verbosity != f_console_verbosity_quiet) { + fprintf(data.error.to.stream, "%c", f_string_eol[0]); + fprintf(data.error.to.stream, "%s%sThe entry item action third parameter (and beyond) must be one of '", data.error.context.before->string, data.error.prefix ? data.error.prefix : ""); + fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, controller_string_asynchronous, data.error.notable.after->string); + fprintf(data.error.to.stream, "%s', '", data.error.context.before->string); + fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, controller_string_require, data.error.notable.after->string); + fprintf(data.error.to.stream, "%s', or '", data.error.context.before->string); + fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, controller_string_wait, data.error.notable.after->string); + fprintf(data.error.to.stream, "%s' but instead has '", data.error.context.before->string); + fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, action->parameters.array[j].string, data.error.notable.after->string); + fprintf(data.error.to.stream, "%s'.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol[0]); + } + } + } // for + } + else if (action->type == controller_entry_action_type_timeout) { + if (fl_string_dynamic_compare_string(controller_string_kill, action->parameters.array[0], controller_string_kill_length) == F_equal_to_not) { + if (fl_string_dynamic_compare_string(controller_string_start, action->parameters.array[0], controller_string_start_length) == F_equal_to_not) { + if (fl_string_dynamic_compare_string(controller_string_stop, action->parameters.array[0], controller_string_stop_length) == F_equal_to_not) { + action->status = F_status_set_error(F_unsupported); + + if (F_status_is_error_not(status_action)) { + status_action = action->status; + } + + if (data.error.verbosity != f_console_verbosity_quiet) { + fprintf(data.error.to.stream, "%c", f_string_eol[0]); + fprintf(data.error.to.stream, "%s%sThe entry item action must have one of '", data.error.context.before->string, data.error.prefix ? data.error.prefix : ""); + fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, controller_string_kill, data.error.notable.after->string); + fprintf(data.error.to.stream, "%s', '", data.error.context.before->string); + fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, controller_string_start, data.error.notable.after->string); + fprintf(data.error.to.stream, "%s', or '", data.error.context.before->string); + fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, controller_string_stop, data.error.notable.after->string); + fprintf(data.error.to.stream, "%s' but instead has '", data.error.context.before->string); + fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, action->parameters.array[0].string, data.error.notable.after->string); + fprintf(data.error.to.stream, "%s'.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol[0]); + } + } + } + } + + if (action->status == F_none) { + const f_string_range_t range = f_macro_string_range_t_initialize(action->parameters.array[1].used); + f_number_unsigned_t number = 0; + + status = fl_conversion_string_to_number_unsigned(action->parameters.array[1].string, &number, range); + + if (F_status_is_error(status) || status == F_data_not) { + if (status == F_data_not) { + action->status = F_status_set_error(F_number); + } + else { + action->status = controller_status_simplify(F_status_set_fine(status)); + } + + if (F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) { + fll_error_print(data.error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true); + + status_action = status; + break; + } + + if (data.error.verbosity != f_console_verbosity_quiet) { + fprintf(data.error.to.stream, "%c", f_string_eol[0]); + fprintf(data.error.to.stream, "%s%sThe entry item action parameter '", data.error.context.before->string, data.error.prefix ? data.error.prefix : ""); + fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, action->parameters.array[1].string, data.error.notable.after->string); + fprintf(data.error.to.stream, "%s' is not a valid supported number.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol[0]); + } + } + } + } + } } actions->used++; @@ -268,13 +402,15 @@ extern "C" { fprintf(output.to.stream, "entry item '"); fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, cache.name_item.string, output.notable.after->string); fprintf(output.to.stream, "%s' on line ", output.context.before->string); - fprintf(output.to.stream, "%s%s%llu%s", output.context.after->string, output.notable.before->string, cache.line_list, output.notable.after->string); + fprintf(output.to.stream, "%s%s%llu%s", output.context.after->string, output.notable.before->string, cache.line_item, output.notable.after->string); fprintf(output.to.stream, "%s for ", output.context.before->string); } - fprintf(output.to.stream, "file '"); - fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, cache.name_file.string, output.notable.after->string); - fprintf(output.to.stream, "%s'.%s%c", output.context.before->string, output.context.after->string, f_string_eol[0]); + if (cache.name_file.used) { + fprintf(output.to.stream, "file '"); + fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, cache.name_file.string, output.notable.after->string); + fprintf(output.to.stream, "%s'.%s%c", output.context.before->string, output.context.after->string, f_string_eol[0]); + } } } #endif // _di_controller_entry_error_print_ @@ -309,10 +445,7 @@ extern "C" { entry->items.used = 0; cache->line_action = 0; - cache->line_list = 0; - - cache->range_list.start = 1; - cache->range_list.stop = 0; + cache->line_item = 0; cache->comments.used = 0; cache->delimits.used = 0; @@ -325,13 +458,13 @@ extern "C" { cache->object_items.used = 0; cache->buffer_file.used = 0; - cache->buffer_item.used = 0; + cache->buffer_path.used = 0; cache->name_file.used = 0; cache->name_action.used = 0; cache->name_item.used = 0; - status = controller_file_load(data, setting, controller_string_rules, entry_name, controller_string_rule, controller_string_rules_length, controller_string_rule_length, &cache->buffer_file, &cache->name_file); + status = controller_file_load(data, setting, controller_string_entries, entry_name, controller_string_entry, controller_string_entries_length, controller_string_entry_length, &cache->name_file, &cache->buffer_file); if (F_status_is_error_not(status)) { if (cache->buffer_file.used) { @@ -372,9 +505,11 @@ extern "C" { controller_entry_item_t *item = 0; f_string_range_t *range = 0; - f_string_length_t j = 0; - for (f_array_length_t i = 0; i < cache->object_items.used; ++i) { + f_array_length_t i = 0; + f_array_length_t j = 0; + + for (; i < cache->object_items.used; ++i) { if (code & 0x2) { code -= 0x2; @@ -383,9 +518,7 @@ extern "C" { range = 0; cache->line_action = 0; - cache->line_list = 0; - - cache->range_list = cache->object_items.array[i]; + cache->line_item = 0; cache->comments.used = 0; cache->delimits.used = 0; @@ -396,7 +529,7 @@ extern "C" { cache->object_actions.used = 0; cache->buffer_file.used = 0; - cache->buffer_item.used = 0; + cache->buffer_path.used = 0; cache->name_action.used = 0; cache->name_item.used = 0; @@ -422,7 +555,7 @@ extern "C" { break; } - status = f_fss_count_lines(cache->buffer_file, cache->object_items.array[i].start, &cache->line_list); + status = f_fss_count_lines(cache->buffer_file, cache->object_items.array[i].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); @@ -470,7 +603,7 @@ extern "C" { entry->items.used = 2; } - item->line = cache->line_list; + item->line = cache->line_item; status = fl_string_dynamic_append(cache->name_item, &item->name); @@ -497,40 +630,117 @@ extern "C" { } } // for - if (F_status_is_error_not(status) && code & 0x1) { - if (data.error.verbosity != f_console_verbosity_quiet) { - fprintf(data.error.to.stream, "%c", f_string_eol[0]); - fprintf(data.error.to.stream, "The required list '"); - fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, controller_string_main, data.error.notable.after->string); - fprintf(data.error.to.stream, "%s' was not found.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol[0]); + if (F_status_is_error_not(status)) { + cache->name_action.used = 0; + cache->name_item.used = 0; + + if (code & 0x1) { + if (data.error.verbosity != f_console_verbosity_quiet) { + fprintf(data.error.to.stream, "%c", f_string_eol[0]); + fprintf(data.error.to.stream, "The required entry item '"); + fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, controller_string_main, data.error.notable.after->string); + fprintf(data.error.to.stream, "%s' was not found.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol[0]); + } + + status = F_status_set_error(F_found_not); } - status = F_status_set_error(F_found_not); + if (F_status_is_error_not(status)) { + controller_entry_action_t *action = 0; + + f_array_length_t k = 0; + + // 0x1 = missing or not, 0x2 = one or more missing. + uint8_t missing = 0; + + for (i = 0; i < entry->items.used; ++i) { + + for (j = 0; j < entry->items.array[i].actions.used; ++j) { + + action = &entry->items.array[i].actions.array[j]; + + // only process actions that don't already have an error. + if (F_status_is_error(action->status)) continue; + + if (action->type == controller_entry_action_type_failsafe || action->type == controller_entry_action_type_item) { + missing &= 0x1; + + for (k = 0; k < entry->items.used; ++k) { + + if (fl_string_dynamic_compare(action->parameters.array[0], entry->items.array[k].name) == F_equal_to) { + if (missing & 0x1) { + missing -= 0x1; + } + + break; + } + } // for + + if (missing & 0x1) { + missing &= 0x2; + + cache->line_action = action->line; + cache->line_item = entry->items.array[i].line; + + status = fl_string_dynamic_append(entry->items.array[i].name, &cache->name_item); + + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_append", F_true); + break; + } + + status = fl_string_dynamic_terminate(&cache->name_item); + + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate", F_true); + break; + } + + status = fl_string_dynamic_append(entry->items.array[i].name, &cache->name_item); + + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_append", F_true); + break; + } + + status = fl_string_dynamic_terminate(&cache->name_item); + + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate", F_true); + break; + } + + if (data.error.verbosity != f_console_verbosity_quiet) { + fprintf(data.error.to.stream, "%c", f_string_eol[0]); + fprintf(data.error.to.stream, "The requested entry item '"); + fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, action->parameters.array[0].string, data.error.notable.after->string); + fprintf(data.error.to.stream, "%s' does not exist.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol[0]); + + controller_entry_error_print(data.error, *cache); + } + + entry->status = controller_status_simplify(F_found_not); + + cache->name_action.used = 0; + cache->name_item.used = 0; + } + } + } // for + } // for + + // the error is already fully printed and the entry status is already assigned, so immediately exit. + if (missing & 0x2) { + return F_false; + } + } } } } if (F_status_is_error(status)) { - status = F_status_set_fine(status); - controller_entry_error_print(data.error, *cache); - if (status == F_memory_not || status == F_memory_allocation || status == F_memory_reallocation) { - entry->status = F_memory; - } - else if (status == F_file_open_max || status == F_space_not || status == F_busy) { - entry->status = F_resource; - } - else if (status == F_access_denied || status == F_filesystem_quota_block || status == F_prohibited || status == F_input_output) { - entry->status = F_access; - } - else if (status == F_interrupted) { - entry->status = F_interrupted; - } - else { - entry->status = F_invalid; - } - + entry->status = controller_status_simplify(F_status_set_fine(status)); return F_false; } diff --git a/level_3/controller/c/private-entry.h b/level_3/controller/c/private-entry.h index e5edbec..4303094 100644 --- a/level_3/controller/c/private-entry.h +++ b/level_3/controller/c/private-entry.h @@ -13,9 +13,7 @@ #ifndef _di_controller_entry_cache_t_ typedef struct { f_string_length_t line_action; - f_string_length_t line_list; - - f_string_range_t range_list; + f_string_length_t line_item; f_fss_comments_t comments; f_fss_delimits_t delimits; @@ -27,7 +25,7 @@ f_fss_objects_t object_items; f_string_dynamic_t buffer_file; - f_string_dynamic_t buffer_item; + f_string_dynamic_t buffer_path; f_string_dynamic_t name_action; f_string_dynamic_t name_file; @@ -38,7 +36,6 @@ { \ 0, \ 0, \ - f_string_range_t_initialize, \ f_fss_comments_t_initialize, \ f_fss_delimits_t_initialize, \ f_fss_content_t_initialize, \ @@ -62,7 +59,7 @@ f_macro_fss_objects_t_delete_simple(cache.object_actions) \ f_macro_fss_objects_t_delete_simple(cache.object_items) \ f_macro_string_dynamic_t_delete_simple(cache.buffer_file) \ - f_macro_string_dynamic_t_delete_simple(cache.buffer_item) \ + f_macro_string_dynamic_t_delete_simple(cache.buffer_path) \ 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) @@ -110,6 +107,24 @@ extern "C" { * * @return * F_none on success. + * + * Errors (with error bit) from: controller_entry_actions_increase_by(). + * Errors (with error bit) from: f_fss_count_lines(). + * Errors (with error bit) from: fl_fss_apply_delimit(). + * Errors (with error bit) from: fl_string_dynamic_partial_append_nulless(). + * Errors (with error bit) from: fl_string_dynamic_rip_nulless(). + * Errors (with error bit) from: fl_string_dynamic_terminate_after(). + * Errors (with error bit) from: fl_string_dynamics_increase_by(). + * Errors (with error bit) from: fll_fss_extended_read(). + * + * @see controller_entry_actions_increase_by() + * @see f_fss_count_lines() + * @see fl_fss_apply_delimit() + * @see fl_string_dynamic_partial_append_nulless() + * @see fl_string_dynamic_rip_nulless() + * @see fl_string_dynamic_terminate_after() + * @see fl_string_dynamics_increase_by() + * @see fll_fss_extended_read() */ #ifndef _di_controller_entry_actions_read_ extern f_return_status controller_entry_actions_read(const controller_data_t data, const controller_setting_t setting, const f_string_range_t content_range, controller_entry_cache_t *cache, controller_entry_actions_t *items) f_gcc_attribute_visibility_internal; @@ -139,8 +154,8 @@ extern "C" { * * @param amount * A positive number representing how much to increase the size by. - * @param lists - * The entry lists to resize. + * @param items + * The entry items to resize. * * @return * F_none on success. @@ -151,7 +166,7 @@ extern "C" { * @see f_memory_resize() */ #ifndef _di_controller_entry_items_increase_by_ - extern f_return_status controller_entry_items_increase_by(const f_array_length_t amount, controller_entry_items_t *lists) f_gcc_attribute_visibility_internal; + extern f_return_status controller_entry_items_increase_by(const f_array_length_t amount, controller_entry_items_t *items) f_gcc_attribute_visibility_internal; #endif // _di_controller_entry_items_increase_by_ /** @@ -173,6 +188,17 @@ extern "C" { * @return * F_true on success. * F_false on failure. + * + * @see controller_entry_actions_read() + * @see controller_entry_items_increase_by() + * @see controller_file_load() + * @see controller_status_simplify() + * @see f_fss_count_lines() + * @see fl_fss_apply_delimit() + * @see fl_string_dynamic_append() + * @see fl_string_dynamic_partial_append_nulless() + * @see fl_string_dynamic_terminate() + * @see fll_fss_basic_list_read() */ #ifndef _di_controller_entry_read_ extern f_return_status controller_entry_read(const controller_data_t data, const controller_setting_t setting, const f_string_static_t entry_name, controller_entry_cache_t *cache, controller_entry_t *entry) f_gcc_attribute_visibility_internal; diff --git a/level_3/controller/c/private-rule.c b/level_3/controller/c/private-rule.c index 0729dd9..12edb9c 100644 --- a/level_3/controller/c/private-rule.c +++ b/level_3/controller/c/private-rule.c @@ -108,7 +108,7 @@ extern "C" { return status; } - if (actions->type == controller_rule_action_type_extended_list) { + if (actions->method == controller_rule_action_method_extended_list) { cache->comments.used = 0; cache->delimits.used = 0; cache->content_actions.used = 0; @@ -146,20 +146,20 @@ extern "C" { actions->array[actions->used].line += item->line; actions->array[actions->used].parameters.used = 0; + actions->array[actions->used].status = F_unknown; status = fl_string_dynamics_increase(&actions->array[actions->used].parameters); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_increase", F_true); + + actions->array[actions->used].status = controller_status_simplify(F_status_set_fine(status)); break; } status = controller_rule_action_read(data, cache->buffer_item, &cache->object_actions.array[i], &cache->content_actions.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->array[actions->used].status = controller_status_simplify(F_status_set_fine(status)); actions->used++; } // for } @@ -199,11 +199,17 @@ extern "C" { else { actions->array[0].line += item->line; actions->array[0].parameters.used = 0; + actions->array[0].status = F_unknown; 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); + + actions->array[0].status = controller_status_simplify(F_status_set_fine(status)); + } + else { + actions->array[0].status = status; } actions->used = 1; @@ -251,9 +257,11 @@ extern "C" { fprintf(output.to.stream, "%s for ", output.context.before->string); } - fprintf(output.to.stream, "file '"); - fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, cache.name_file.string, output.notable.after->string); - fprintf(output.to.stream, "%s'.%s%c", output.context.before->string, output.context.after->string, f_string_eol[0]); + if (cache.name_file.used) { + fprintf(output.to.stream, "file '"); + fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, cache.name_file.string, output.notable.after->string); + fprintf(output.to.stream, "%s'.%s%c", output.context.before->string, output.context.after->string, f_string_eol[0]); + } } } #endif // _di_controller_rule_error_print_ @@ -343,39 +351,32 @@ extern "C" { break; } - actions = 0; - if (fl_string_dynamic_compare_string(controller_string_create, cache->name_action, controller_string_create_length) == F_equal_to) { - actions = &item->create; - actions->intent = controller_rule_action_intent_create; + item->actions.type = controller_rule_action_type_create; } else if (fl_string_dynamic_compare_string(controller_string_group, cache->name_action, controller_string_group_length) == F_equal_to) { - actions = &item->group; - actions->intent = controller_rule_action_intent_group; + item->actions.type = controller_rule_action_type_group; + } + else if (fl_string_dynamic_compare_string(controller_string_kill, cache->name_action, controller_string_kill_length) == F_equal_to) { + item->actions.type = controller_rule_action_type_kill; } else if (fl_string_dynamic_compare_string(controller_string_restart, cache->name_action, controller_string_restart_length) == F_equal_to) { - actions = &item->restart; - actions->intent = controller_rule_action_intent_restart; + item->actions.type = controller_rule_action_type_restart; } else if (fl_string_dynamic_compare_string(controller_string_reload, cache->name_action, controller_string_reload_length) == F_equal_to) { - actions = &item->reload; - actions->intent = controller_rule_action_intent_reload; + item->actions.type = controller_rule_action_type_reload; } else if (fl_string_dynamic_compare_string(controller_string_start, cache->name_action, controller_string_start_length) == F_equal_to) { - actions = &item->start; - actions->intent = controller_rule_action_intent_start; + item->actions.type = controller_rule_action_type_start; } else if (fl_string_dynamic_compare_string(controller_string_stop, cache->name_action, controller_string_stop_length) == F_equal_to) { - actions = &item->stop; - actions->intent = controller_rule_action_intent_stop; + item->actions.type = controller_rule_action_type_stop; } else if (fl_string_dynamic_compare_string(controller_string_use, cache->name_action, controller_string_use_length) == F_equal_to) { - actions = &item->use; - actions->intent = controller_rule_action_intent_use; + item->actions.type = controller_rule_action_type_use; } else if (fl_string_dynamic_compare_string(controller_string_user, cache->name_action, controller_string_user_length) == F_equal_to) { - actions = &item->user; - actions->intent = controller_rule_action_intent_user; + item->actions.type = controller_rule_action_type_user; } else { if (data.warning.verbosity == f_console_verbosity_debug) { @@ -389,7 +390,7 @@ extern "C" { } if (multiple) { - if (actions->intent == controller_rule_action_intent_create || actions->intent == controller_rule_action_intent_group || actions->intent == controller_rule_action_intent_use || actions->intent == controller_rule_action_intent_user) { + if (item->actions.type == controller_rule_action_type_create || item->actions.type == controller_rule_action_type_group || item->actions.type == controller_rule_action_type_use || item->actions.type == controller_rule_action_type_user) { if (data.error.verbosity != f_console_verbosity_quiet) { fprintf(data.error.to.stream, "%c", f_string_eol[0]); fprintf(data.error.to.stream, "%s%sFSS Extended List is not allowed for this rule item action type.%s%c", data.error.context.before->string, data.error.prefix ? data.error.prefix : "", data.error.context.after->string, f_string_eol[0]); @@ -399,13 +400,13 @@ extern "C" { break; } - actions->type = controller_rule_action_type_extended_list; + item->actions.method = controller_rule_action_method_extended_list; } else { - actions->type = controller_rule_action_type_extended; + item->actions.method = controller_rule_action_method_extended; } - status = controller_rule_actions_read(data, cache, item, actions, &range); + status = controller_rule_actions_read(data, cache, item, &item->actions, &range); if (F_status_is_error(status)) break; } } // for @@ -483,7 +484,7 @@ extern "C" { fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_append_nulless", F_true); } else { - status = controller_file_load(data, setting, controller_string_rules, rule->id, controller_string_rule, controller_string_rules_length, controller_string_rule_length, &cache->buffer_file, &cache->name_file); + status = controller_file_load(data, setting, controller_string_rules, rule->id, controller_string_rule, controller_string_rules_length, controller_string_rule_length, &cache->name_file, &cache->buffer_file); } if (F_status_is_error_not(status) && cache->buffer_file.used) { @@ -608,26 +609,9 @@ extern "C" { } if (F_status_is_error(status)) { - status = F_status_set_fine(status); - controller_rule_error_print(data.error, *cache, for_item); - if (status == F_memory_not || status == F_memory_allocation || status == F_memory_reallocation) { - rule->status = F_memory; - } - else if (status == F_file_open_max || status == F_space_not || status == F_busy) { - rule->status = F_resource; - } - else if (status == F_access_denied || status == F_filesystem_quota_block || status == F_prohibited || status == F_input_output) { - rule->status = F_access; - } - else if (status == F_interrupted) { - rule->status = F_interrupted; - } - else { - rule->status = F_invalid; - } - + rule->status = controller_status_simplify(F_status_set_fine(status)); return F_false; } diff --git a/level_3/controller/c/private-rule.h b/level_3/controller/c/private-rule.h index f4a6f6c..8e776a5 100644 --- a/level_3/controller/c/private-rule.h +++ b/level_3/controller/c/private-rule.h @@ -57,7 +57,7 @@ extern "C" { f_string_dynamic_t_initialize, \ } - #define macro_controller_rule_name_t_delete_simple(cache) \ + #define macro_controller_rule_cache_t_delete_simple(cache) \ f_macro_fss_comments_t_delete_simple(cache.comments) \ f_macro_fss_delimits_t_delete_simple(cache.delimits) \ f_macro_fss_content_t_delete_simple(cache.content_action) \ diff --git a/level_3/controller/data/build/dependencies b/level_3/controller/data/build/dependencies index f33aaa7..8b4a9f5 100644 --- a/level_3/controller/data/build/dependencies +++ b/level_3/controller/data/build/dependencies @@ -7,6 +7,7 @@ f_string f_utf f_color f_console +f_conversion f_file f_fss f_path @@ -14,6 +15,7 @@ f_pipe f_print fl_color fl_console +fl_conversion fl_fss fl_string fll_error diff --git a/level_3/controller/data/build/settings b/level_3/controller/data/build/settings index 01843e1..8eeb29b 100644 --- a/level_3/controller/data/build/settings +++ b/level_3/controller/data/build/settings @@ -26,7 +26,7 @@ build_sources_library controller.c private-control.c private-controller.c privat build_sources_program main.c build_sources_headers controller.h build_sources_script -build_sources_setting +build_sources_setting entries rules build_script yes build_shared yes build_static yes diff --git a/level_3/controller/data/settings/entries/default.entry b/level_3/controller/data/settings/entries/default.entry new file mode 100644 index 0000000..2a67c98 --- /dev/null +++ b/level_3/controller/data/settings/entries/default.entry @@ -0,0 +1,45 @@ +# fss-0005 +# +# A very basic boot process. +# + +main: + timeout start 7 + timeout stop 7 + timeout kill 3 + + item boot + item net + item time + item keyboard + item console + + failsafe maintenance + +boot: + rule boot filesystem require + rule boot modules require + rule boot devices require + + rule service logger wait + rule service dbus asynchronous + +net: + rule net all asynchronous + +time: + rule task clock asynchronous + +keyboard: + rule task keyboard asynchronous + +console: + rule program terminal require wait + rule service mouse + +maintenance: + timeout start 2 + timeout stop 2 + timeout kill 2 + + rule maintenance console diff --git a/level_3/controller/data/settings/rules/boot/devices.rule b/level_3/controller/data/settings/rules/boot/devices.rule new file mode 100644 index 0000000..a0bdc56 --- /dev/null +++ b/level_3/controller/data/settings/rules/boot/devices.rule @@ -0,0 +1,9 @@ +# fss-000d +# +# Rule for initializing the device files. +# + +setting: + name "Setup System Devices" + + need boot modules diff --git a/level_3/controller/data/settings/rules/boot/filesystem.rule b/level_3/controller/data/settings/rules/boot/filesystem.rule new file mode 100644 index 0000000..8618eb4 --- /dev/null +++ b/level_3/controller/data/settings/rules/boot/filesystem.rule @@ -0,0 +1,15 @@ +# fss-000d +# +# Rule for initializing the filesystem. +# + +setting: + name "Setup Filesystem" + +command: + start mount -a -O no_netdev + stop umount -arf -O no_netdev + +command: + start swapon -a + stop swapoff -a diff --git a/level_3/controller/data/settings/rules/boot/modules.rule b/level_3/controller/data/settings/rules/boot/modules.rule new file mode 100644 index 0000000..2536c7f --- /dev/null +++ b/level_3/controller/data/settings/rules/boot/modules.rule @@ -0,0 +1,22 @@ +# fss-000d +# +# Rule for initializing the kernel modules. +# + +setting: + name "Setup Kernel Modules" + + need boot filesystem + +script: + start { + if [[ ! -f /proc/modules ]] ; then + exit 0; + fi + + if [[ ! -e /lib/modules/$(uname -r)/modules.dep ]] ; then + depmod; + fi + + return 0; + } diff --git a/level_3/controller/data/settings/rules/maintenance/console.rule b/level_3/controller/data/settings/rules/maintenance/console.rule new file mode 100644 index 0000000..52e7b82 --- /dev/null +++ b/level_3/controller/data/settings/rules/maintenance/console.rule @@ -0,0 +1,10 @@ +# fss-000d +# +# Rule for maintenance/failsafe console. +# + +setting: + name "Maintenance Console" + +command: + start bash --login diff --git a/level_3/controller/data/settings/rules/net/all.rule b/level_3/controller/data/settings/rules/net/all.rule new file mode 100644 index 0000000..5d089cc --- /dev/null +++ b/level_3/controller/data/settings/rules/net/all.rule @@ -0,0 +1,12 @@ +# fss-000d +# +# Rule for starting all network devices. +# + +setting: + name "System Network" + +command: + start network start + stop network stop + restart network restart diff --git a/level_3/controller/data/settings/rules/net/loopback.rule b/level_3/controller/data/settings/rules/net/loopback.rule new file mode 100644 index 0000000..d5c1c11 --- /dev/null +++ b/level_3/controller/data/settings/rules/net/loopback.rule @@ -0,0 +1,19 @@ +# fss-000d +# +# Rule for loopback device. +# + +setting: + name "Loopback Device" + + need boot modules + +script: + start { + ip addr add 127.0.0.1/8 label lo dev lo; + ip link set lo up; + } + + stop { + ip link set lo down; + } diff --git a/level_3/controller/data/settings/rules/program/terminal.rule b/level_3/controller/data/settings/rules/program/terminal.rule new file mode 100644 index 0000000..25339ad --- /dev/null +++ b/level_3/controller/data/settings/rules/program/terminal.rule @@ -0,0 +1,28 @@ +# fss-000d +# +# Rule for the terminal programs. +# + +setting: + name "System Terminal" + +service: + use /var/run/tty/tty1.pid + + start qingy tty1 -d -l -n -t + +service: + use /var/run/tty/tty2.pid + + start qingy tty2 -d -l -n -t + +service: + use /var/run/tty/tty3.pid + + start qingy tty3 -d -l -n -t + +service: + use /var/run/tty/tty4.pid + + start qingy tty4 -d -l -n -t + diff --git a/level_3/controller/data/settings/rules/service/dbus.rule b/level_3/controller/data/settings/rules/service/dbus.rule new file mode 100644 index 0000000..5a551ab --- /dev/null +++ b/level_3/controller/data/settings/rules/service/dbus.rule @@ -0,0 +1,12 @@ +# fss-000d +# +# Rule for D-Bus service. +# + +setting: + name "D-BUS" + +service: + use /var/run/dbus/dbus.pid + + start dbus-daemon --system --fork diff --git a/level_3/controller/data/settings/rules/service/logger.rule b/level_3/controller/data/settings/rules/service/logger.rule new file mode 100644 index 0000000..91c92de --- /dev/null +++ b/level_3/controller/data/settings/rules/service/logger.rule @@ -0,0 +1,13 @@ +# fss-000d +# +# Rule for system logger service. +# + +setting: + name "System Logger" + +service: + # @todo consider adding support for IKI to make "/var/run/logger/logger.pid" a variable. + use /var/run/logger/logger.pid + + start metalog -B -p /var/run/logger/logger.pid -C /etc/logger.conf diff --git a/level_3/controller/data/settings/rules/service/mouse.rule b/level_3/controller/data/settings/rules/service/mouse.rule new file mode 100644 index 0000000..7e759f1 --- /dev/null +++ b/level_3/controller/data/settings/rules/service/mouse.rule @@ -0,0 +1,20 @@ +# fss-000d +# +# Rule for console mouse. +# + +setting: + name "Console Mouse" + + # @todo consider adding iki support. + +script: + start { + # @todo read settings from /etc/mouse, and replace below. + } + +service: + use /var/run/mouse/mouse.pid + + # @todo + start gpm -m [device] -t [protocol] [options] diff --git a/level_3/controller/data/settings/rules/task/clock b/level_3/controller/data/settings/rules/task/clock new file mode 100644 index 0000000..a7014c6 --- /dev/null +++ b/level_3/controller/data/settings/rules/task/clock @@ -0,0 +1,30 @@ +# fss-000d +# +# Rule for setting the clock. +# + +setting: + name "Setup Clock" + +script: + start { + clock_mode= + + if [[ -f /etc/clock ]] ; then + clock_mode=$(fss_basic_read -c 0 -n mode /etc/clock); + fi + + if [[ $clock_mode == "local" ]] ; then + hwclock --hctosys; + elif [[ $clock_mode == "ntpdate" ]] ; then + ntpdate $(fss_basic_read -c 0 -n server /etc/clock) && + hwclock --systohc --utc + elif [[ $clock_mode == "ntp" ]] ; then + if [[ $(fss_basic_read -c 0 -n ntpdate /etc/clock) == "yes" ]] ; then + ntpdate $(fss_basic_read -c 0 -n server /etc/clock) && + hwclock --systohc --utc + fi + elif [[ $clock_mode == "utc" ]] ; then + hwclock --hctosys --utc; + fi + } diff --git a/level_3/controller/data/settings/rules/task/keyboard b/level_3/controller/data/settings/rules/task/keyboard new file mode 100644 index 0000000..862f4c9 --- /dev/null +++ b/level_3/controller/data/settings/rules/task/keyboard @@ -0,0 +1,7 @@ +# fss-000d +# +# Rule for setting the keyboard. +# + +setting: + name "System Keyboard" diff --git a/level_3/controller/documents/entry.txt b/level_3/controller/documents/entry.txt index f2fb838..6da0273 100644 --- a/level_3/controller/documents/entry.txt +++ b/level_3/controller/documents/entry.txt @@ -1,59 +1,58 @@ # fss-0002 Entry Documentation: - This describes the intent and purpose of the entry file settings. + This describes the intent and purpose of the Entry file settings. - An entry file, such as "default.entry", is intended to store a set of rules in which the controller will process on execution. + An Entry file, such as "default.entry", is intended to store a set of rules in which the controller will process on execution. These are almost always meant for booting a system. - The "main" Basic List Object is always executed first (Therefore "main" is required). - All other Basic List Objects are not executed unless either a "category" or a "failsafe" specifies the Object. - Execution of all Basic List Objects is top-down. + The "main" Item Object is always executed first (Therefore "main" is both reserved and required). + All other Basic List Objects are not executed unless either an "item" or a "failsafe" specifies a valid Item name. + Execution of all Items are top-down. - Inside each list there are additional commands: "consider", "failsafe", "item", "ready", "rule", and "timeout". + Each item supports the following Action Names: "consider", "failsafe", "item", "ready", "rule", and "timeout". - The "consider" command is a special case of a "rule" command. - All available Content are identical. - The difference is that "consider" is only processed at this spot at this time if and when some "rule" command (or another "consider" command is determined to be executed) designates that this consideration is required (via "require"), wanted (via "want"), or wished (via "wish"). + The "consider" Action is a special case of a "rule" Action. + All Action Parameters are the same as with the "rule" Action Parameters. + The difference is that "consider" is only processed at this spot at this time if and when some "rule" Action (or another "consider" Action) designates that this consideration is required (via "require"), wanted (via "want"), or wished (via "wish") from the within the referenced Rule file. If this is determined to be executed, then this is immediately executed in the designated position and applies all properties as appropriate (such as "asynchronous", for example). If this is determined not to be executed, then this "consider" is ignored as if it was never there in the first place. - The "failsafe" command accepts only a valid Basic List Object in which will be executed when a failure is detected. - Only a single "failsafe" command may exist at a time. - Each time a "failsafe" command is specified, it replaces the previous "failsafe" command. + The "failsafe" Action accepts only a valid Item Name in which will be executed when a failure is detected. + Only a single "failsafe" Action may exist at a time. + Each successive "failsafe" Action specified replaces the previously defined "failsafe" Action (in a top-down manner). - The "item" command accepts only a valid Basic List Object in which will be immediately executed. - An "item" is another list within the entry file to execute in it entirety. - Any valid Object name, except for the reserved "main", may be called using this. + The "item" Action accepts only a valid Item Name in which will be immediately executed. + Any valid Item Name, except for the reserved "main", may be used. - The "ready" command instructs the controller program when it is safe to perform normal tasks, such as creating the pid file. + The "ready" Action instructs the controller program when it is safe to perform normal tasks, such as creating the pid file. When not specified, the state is always assumed to be ready. - For example, the controller may be used as a full blown "init" replacement and therefore may need to mount the /var/run/ directory. - If the pid file is created at program start, then the /var/run/controller.pid would be written before the /var/run/ directory is properly mounted. + For example, the controller program may be used as a full blown "init" replacement and therefore may need to mount the /var/run/ directory. + If the pid file is created at program start, then the /var/run/controller.pid would be written before the /var/run/ directory is ready. This could be a problem, such as on a read-only filesystem the pid creation fails and controller bails out on error. - Adding ready essentially specifies a point in time in the rules in which things are expected to be safe for such basic operations. + Adding "ready" essentially specifies a point in time in the Entry in which things are expected to be safe for such basic operations. - The "rule" command immediately executes a given rule file. - The first Content represents the rule ID, which is a relative path the rule file is to be found, without the file extension. + The "rule" Action immediately executes a named rule file. + The first Action Parameter represents the rule ID, which is a relative path the rule file is to be found, without the file extension. - Do not include leading or trailing slashes in the name. - This is relative to the settings rules directory. - For example the rule ID "example/my" would be found in "/etc/controller/settings/rules/example/my.rule" (assuming the directory structure). - The second Content represents the basename for the file representing the desired rule. + The second Action Parameter represents the basename for the file representing the desired rule. The directory is relative to the settings, such that if the controller rule settings are found in "/etc/controller/rules/", then for a directory called "[directory]" and a rule basename of "[filename]", the resulting path would be: "/etc/controller/rules/[directory]/[filename].rule" - The remaining Content may be specified in any order\: + The remaining Action Parameters may be specified in any order\: - "asynchronous": Designates that execution will not block (wait). - "require": Designates that this rule must succeed or trigger execution of failsafe. - - "wait": Designates that this rule will not execute until all other existing "asynchronous" executions complete. + - "wait": Designates that this rule will not execute until all other Actions before this (including "asynchronous" ones) finish executing (in a top-down manner). - It is important to note that for any given rule, execution within that rule may be internally asynchronous. + It is important to note that for any given "rule", execution within that "rule" may be internally asynchronous (even if the "rule" is synchronous). For example, a service that is often called a daemon will execute in the background. Until that execution succeeds and the daemon goes into the background the representing rule will block. - After the daemon goes into the background, then the representing rule will return success. + After the daemon goes into the background, then the representing rule will be fully executed. - The "timeout" command provides default global settings for each of the three special situations: "start", "stop", and "kill". + The "timeout" Action provides default global settings for each of the three special situations: "start", "stop", and "kill". Each of these may only have a single one exist at a time (one "start", one "stop", and one "kill"). - Each of these will replace any previously specified setting. - Each of these accepts a single Content that is a 0 or greater whole number representing the number of MegaTime (MT) (equivalent to milliseconds). + Each successive "timeout" Action, specific to each Action Name (such as "start"), specified replaces the previously defined "timeout" Action (in a top-down manner). + Each of these accepts a single Action Parameter that is a 0 or greater whole number representing the number of MegaTime (MT) (equivalent to milliseconds). For "start", this represents the number of MegaTime to wait after starting some rule before assuming something went wrong and the rule is returned as failed. For "stop", this represents the number of MegaTime to wait after stopping some rule before assuming something went wrong and the rule is returned as failed. For "kill", this represents the number of MegaTime to wait after stopping some rule and that rule has not yet stopped to forcefully stop the rule (aka kill the rule). @@ -73,3 +72,8 @@ Entry Documentation: 1 (Earth) minute = 60000000000 Time or 60 GT (GigaTime). 1 (Earth) second = 1000000000 Time or 1 GT (GigaTime). Consequentially, 1 day in units of Time is easily represented as 86.4 TT (TeraTime). + The Time may be stored in its "year string format". + In this format, a Year may be prepended to the Time followed by a single colon ':' to associate a year with the Time. + This Year has no minimum or maximum but may not have decimals. + For example, "2020:86400000000000" would represent: January 02, 2020 0:00 UTC. + For example, "2020:86.4 TT" would represent: January 02, 2020 0:00 UTC. diff --git a/level_3/controller/documents/rule.txt b/level_3/controller/documents/rule.txt index b31500f..c63d1fe 100644 --- a/level_3/controller/documents/rule.txt +++ b/level_3/controller/documents/rule.txt @@ -8,7 +8,7 @@ Rule Documentation: The rule file is read top-down, except for the outer most list "settings", which is intended to store settings data for this rule. Multiple outer most list Objects may be specified and they are executed as provided, in a top-down manner. - The "settings" outer most list Object has the following FSS-0001 (Extended) Content\: + The "settings" Rule Type has the following FSS-0001 (Extended) Content\: "control_group": Define a control group (cgroup) in which everything within this rule executes under. "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). @@ -34,8 +34,9 @@ Rule Documentation: The last return state is treated as an error, so be sure to finish the script with a return code of 0 to designate no error and any other whole number, such a 1, to designate an error. Therefore passing "exit 1" would return as an error and passing "exit 0" would return as a success. - There are four primary inner Content to perform: "restart", "reload", "start", and "stop". + There are five primary inner Content to perform: "kill", "restart", "reload", "start", and "stop". + The "kill" Content is performed whenever this rule is executed using the kill action (which is, in general, a forced stop). The "start" Content is performed whenever this rule is executed using the start action. The "stop" Content is performed whenever this rule is executed using the stop action. The "restart" Content is performed whenever this rule is executed using the restart action. diff --git a/level_3/controller/specifications/entry.txt b/level_3/controller/specifications/entry.txt index 48f59ba..c0c322f 100644 --- a/level_3/controller/specifications/entry.txt +++ b/level_3/controller/specifications/entry.txt @@ -1,16 +1,24 @@ # fss-0002 Entry Specification: - The "entry" files follow the FSS-0005 (Somewhat Basic List) format. + The Entry files follow the FSS-0005 (Somewhat Basic List) format. - An entry file name is expected to have the file extension ".entry". + An Entry file name is expected to have the file extension ".entry". - The outer most part, which is essentially FSS-0002 (Basic List), has the following Objects\: + For each entry file: + - The outer most part is a FSS-0002 (Basic List). + - The Basic List Object is considered the "Item". + - The Basic List Content are considered the "Actions". + - The "Actions" are FSS-0001 (Extended). + - Each Action Object is the "Action Name". + - Each Action Content are the "Action Parameters". + + The Items: "main": required. - The entry file may have any other valid Object, only the above have reserved uses. + The Entry file may have any other valid Item Objects, but only the above are reserved. - Inside each Basic List are essentially the following, FSS-0001 (Extended), Objects\: + The Actions\: "consider": One or more Content. The first Content that is the relative file path (without any leading/trailing slashes and without file extension). The second Content that is the basename for a rule file. diff --git a/level_3/controller/specifications/rule.txt b/level_3/controller/specifications/rule.txt index 7ac263b..5914018 100644 --- a/level_3/controller/specifications/rule.txt +++ b/level_3/controller/specifications/rule.txt @@ -1,19 +1,33 @@ # fss-0002 Rule Specification: - The "rule" files follow the FSS-000D (Basic Rule) format. + The Rule files follow the FSS-000D (Basic Rule) format. - A rule file name is expected to have the file extension ".rule". + 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\: - "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 each Rule file: + - The outer most part is a FSS-0002 (Basic List). + - The Basic List Object is considered the "Rule Type". + - The Basic List Content is determined by the specific "Rule Type". + - The Content for each "Rule Type" is called the "Item". + - Each Item Object is the "Item Name". + - Each Item Content is either the "Action" or the "Setting". + - Each Action Object is the "Action Name". + - Each Action Content are the "Action Parameters". + - Each Setting Object is the "Setting Name". + - Each Setting Content are the "Setting Values". - For the above Basic List Objects, "main" may be specified only once whereas the others may be specifed multiple times. + The Rule Types\: + "command": FSS-0003 (Extended List) or FSS-0001 (Extended). + "script": FSS-0003 (Extended List) or FSS-0001 (Extended). + "service": FSS-0003 (Extended List) or FSS-0001 (Extended). + "settings": (Required) FSS-0001 (Extended). - The "settings" outer most list Object has the following FSS-0001 (Extended) Content\: + For the above Rule Types, "settings" may be specified only once whereas the others may be specifed multiple times. + The "settings" Rule Type is always processed first, regardless of position. + The other Rule Types are processed top-down. + + The "settings" Rule Type has the following FSS-0001 (Extended)\: "control_group": Zero or One Content representing a valid control group (cgroup) name. "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). @@ -24,17 +38,35 @@ Rule Specification: "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\: + The "service" Rule Type allows the following the FSS-0001 (Extended)\: "create": One Content representing the path to a PID file. "group": One Content representing a group name or group id. - "restart": One or more Content representing a program to and its arguments. - "reload": One or more Content representing a program to and its arguments. - "start": One or more Content representing a program to and its arguments. - "stop": One or more Content representing a program to and its arguments. + "kill": One or more Content representing a program being executed and its arguments. + "restart": One or more Content representing a program being executed and its arguments. + "reload": One or more Content representing a program being executed and its arguments. + "start": One or more Content representing a program being executed and its arguments. + "stop": One or more Content representing a program being executed and its arguments. "use": One Content representing the path to a PID file. "user": One Content representing a user name or user id. - For the inner parts, these are the Extended List Objects\: + The "command" and "script" Rule Types allow the following the FSS-0001 (Extended)\: + "group": One Content representing a group name or group id. + "kill": One or more Content representing a program being executed and its arguments. + "restart": One or more Content representing a program being executed and its arguments. + "reload": One or more Content representing a program being executed and its arguments. + "start": One or more Content representing a program being executed and its arguments. + "stop": One or more Content representing a program being executed and its arguments. + "user": One Content representing a user name or user id. + + The "command", "script", and "service" Rule Types allow the following the FSS-0003 (Extended List)\: + "kill": A list repesenting multiple programs and their respective arguments to execute. + "restart": A list repesenting multiple programs and their respective arguments to execute. + "reload": A list repesenting multiple programs and their respective arguments to execute. + "start": A list repesenting multiple programs and their respective arguments to execute. + "stop": A list repesenting multiple programs and their respective arguments to execute. + + The "script" Rule Types allow the following the FSS-0003 (Extended List)\: + "kill": A list repesenting the contents of a (Bash) shell script. "restart": A list repesenting the contents of a (Bash) shell script. "reload": A list repesenting the contents of a (Bash) shell script. "start": A list repesenting the contents of a (Bash) shell script. -- 1.8.3.1