]> Kevux Git Server - fll/commitdiff
Progress: controller program and add F_encoding and F_encoding_not status codes.
authorKevin Day <thekevinday@gmail.com>
Sun, 29 Nov 2020 06:06:47 +0000 (00:06 -0600)
committerKevin Day <thekevinday@gmail.com>
Sun, 29 Nov 2020 06:06:47 +0000 (00:06 -0600)
31 files changed:
level_0/f_status/c/status.h
level_1/fl_status/c/status.c
level_1/fl_status/c/status.h
level_2/fll_status/c/status.c
level_3/controller/c/controller.c
level_3/controller/c/controller.h
level_3/controller/c/private-controller.c
level_3/controller/c/private-controller.h
level_3/controller/c/private-entry.c
level_3/controller/c/private-entry.h
level_3/controller/c/private-rule.c
level_3/controller/c/private-rule.h
level_3/controller/data/build/dependencies
level_3/controller/data/build/settings
level_3/controller/data/settings/entries/default.entry [new file with mode: 0644]
level_3/controller/data/settings/rules/boot/devices.rule [new file with mode: 0644]
level_3/controller/data/settings/rules/boot/filesystem.rule [new file with mode: 0644]
level_3/controller/data/settings/rules/boot/modules.rule [new file with mode: 0644]
level_3/controller/data/settings/rules/maintenance/console.rule [new file with mode: 0644]
level_3/controller/data/settings/rules/net/all.rule [new file with mode: 0644]
level_3/controller/data/settings/rules/net/loopback.rule [new file with mode: 0644]
level_3/controller/data/settings/rules/program/terminal.rule [new file with mode: 0644]
level_3/controller/data/settings/rules/service/dbus.rule [new file with mode: 0644]
level_3/controller/data/settings/rules/service/logger.rule [new file with mode: 0644]
level_3/controller/data/settings/rules/service/mouse.rule [new file with mode: 0644]
level_3/controller/data/settings/rules/task/clock [new file with mode: 0644]
level_3/controller/data/settings/rules/task/keyboard [new file with mode: 0644]
level_3/controller/documents/entry.txt
level_3/controller/documents/rule.txt
level_3/controller/specifications/entry.txt
level_3/controller/specifications/rule.txt

index 210a835977bd4c671796daac2dd21d0c085930cb..c572a9065c824c564dcbd0a595f634390d5e6cd4 100644 (file)
@@ -156,6 +156,8 @@ extern "C" {
       F_descriptor,
       F_device,
       F_dummy,
+      F_encoding,
+      F_encoding_not,
       F_eof,
       F_eol,
       F_eos,
index bae4d0d6b0a74eb654f5b2198a9ff583cadf0345..ecc8339ae263e99fcbe37f008b624401ee437a22 100644 (file)
@@ -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;
index 8d69c1ef8909a9b9827da2b739eb75dbcb58afdf..cafe7dd8c62ce3c5e82e515fb0a868a082faf836 100644 (file)
@@ -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
index 7ee5bb67c0392afbcad05377ffc9714ed7c7dc3e..7f901ec9d354c7e5ceaa25edd214b31c0bb20d7d 100644 (file)
@@ -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;
index 550a32b68d77feed1a051400bf680ab4c97d185b..b97923f002aec5e33e4f2423a2cf22fc464dee60 100644 (file)
@@ -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_
index 2ceb04791184740a78d71a9c0c62d0a9151078af..4036d7b0c67e7423fd768af36e86877439d36b06 100644 (file)
@@ -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_
index 2e5c73abfbb5aa6bff09f1fb7ebfd9615863d1fe..27f975101e02f5dceb2103b5b548e7f47e96ca7e 100644 (file)
@@ -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) {
 
index 5bc8902d5aaea33bd43f1553edd5ab13f489d850..34aeb742fcdab4f1821e07aa89f42f4cebf6d7fb 100644 (file)
@@ -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.
index b5331ad1234496b583ee6ae072597829dfe3e15f..3211646c2705212bcce3f90a605249d3af2a7210 100644 (file)
@@ -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;
     }
 
index e5edbec21056fd989176d61ec3bc68e8273a6240..4303094cc24cb0476117d305704e19d30474f386 100644 (file)
@@ -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;
index 0729dd9010cd72ee6e727477b83b6e2b9cd3b2fc..12edb9cda0850817a7ae0e85bdb08dae09979caa 100644 (file)
@@ -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;
     }
 
index f4a6f6cf914b1e48e73205bda41afbd1bbfbea39..8e776a53e7c0d0fda6839f832824875691e2565d 100644 (file)
@@ -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) \
index f33aaa7077f6f950cf82ae2256b77b8c569b75fe..8b4a9f5ab3bbaaf79c3ab31f3ba903e33b83bb9b 100644 (file)
@@ -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
index 01843e1c2e1d45853cfc7029b2154a5eeba39ccb..8eeb29b9d000471d7697679d90abfb0743facf94 100644 (file)
@@ -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 (file)
index 0000000..2a67c98
--- /dev/null
@@ -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 (file)
index 0000000..a0bdc56
--- /dev/null
@@ -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 (file)
index 0000000..8618eb4
--- /dev/null
@@ -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 (file)
index 0000000..2536c7f
--- /dev/null
@@ -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 (file)
index 0000000..52e7b82
--- /dev/null
@@ -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 (file)
index 0000000..5d089cc
--- /dev/null
@@ -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 (file)
index 0000000..d5c1c11
--- /dev/null
@@ -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 (file)
index 0000000..25339ad
--- /dev/null
@@ -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 (file)
index 0000000..5a551ab
--- /dev/null
@@ -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 (file)
index 0000000..91c92de
--- /dev/null
@@ -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 (file)
index 0000000..7e759f1
--- /dev/null
@@ -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 (file)
index 0000000..a7014c6
--- /dev/null
@@ -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 (file)
index 0000000..862f4c9
--- /dev/null
@@ -0,0 +1,7 @@
+# fss-000d
+#
+# Rule for setting the keyboard.
+#
+
+setting:
+  name "System Keyboard"
index f2fb838d940e17d386b9e7566f5eff4f0e0ed6ff..6da0273f754025d6126d5f80560f312cb8b5573e 100644 (file)
@@ -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.
index b31500f0b61b2130de646e569874c7044f148659..c63d1fec3e2a4660f1ff40af21b12ca0955616e9 100644 (file)
@@ -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.
index 48f59bac2d1b5fd8df5388613fe63bb8f6320e74..c0c322fac97c1a5965ce1d90ce145f73931cd56d 100644 (file)
@@ -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.
index 7ac263b3d8807f5c17cf482c71a3273c992b1201..59140185c4161f5fcd813796d31318ddea02c43e 100644 (file)
@@ -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.