]> Kevux Git Server - fll/commitdiff
Progress: controller.
authorKevin Day <thekevinday@gmail.com>
Sat, 21 Nov 2020 22:09:10 +0000 (16:09 -0600)
committerKevin Day <thekevinday@gmail.com>
Sat, 21 Nov 2020 22:09:10 +0000 (16:09 -0600)
Minor tweaks.
Add new parameters and rule settings.

level_3/controller/c/controller.c
level_3/controller/c/controller.h
level_3/controller/c/main.c
level_3/controller/c/private-rule.c
level_3/controller/c/private-rule.h
level_3/controller/documents/entry.txt
level_3/controller/specifications/entry.txt

index f4c3a104b017e04ebce6e1a3be90a46e2987f27b..dd3d041d9d20504aac0ec9d744efc38791fb53d1 100644 (file)
@@ -22,6 +22,11 @@ extern "C" {
     fll_program_print_help_option(output, context, f_console_standard_short_debug, f_console_standard_long_debug, f_console_symbol_short_disable, f_console_symbol_long_disable, "   Enable debugging, inceasing verbosity beyond normal output.");
     fll_program_print_help_option(output, context, f_console_standard_short_version, f_console_standard_long_version, f_console_symbol_short_disable, f_console_symbol_long_disable, " Print only the version number.");
 
+    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_settings, controller_long_settings, f_console_symbol_short_enable, f_console_symbol_long_enable, "     Specify a custom settings path.");
+
     fll_program_print_help_usage(output, context, controller_name, "");
 
     return F_none;
@@ -130,7 +135,6 @@ extern "C" {
     } // for
 
     f_macro_string_lengths_t_delete_simple(data->remaining);
-
     f_macro_color_context_t_delete_simple(data->context);
 
     return F_none;
index 62994753ae756ce902142c741887d036116052d1..6b258f8053c597feca3dde69a9398db0b6b2d26f 100644 (file)
  * This program utilizes the Featureless Linux Library.
  * This program provides system service management, much like sysvcontroller and controllerng.
  * This program can be controlled from user-space via the "control" program.
+ *
+ * @todo research containers and build in container support into this, providing "container" appropriate verbiage for individual rules.
  */
 #ifndef _controller_h
 
 // libc includes
+#include <string.h>
 
 // fll-0 includes
 #include <level_0/type.h>
@@ -61,13 +64,18 @@ extern "C" {
 #ifndef _di_controller_defines_
   #define controller_string_create      "create"
   #define controller_string_command     "command"
+  #define controller_string_consider    "consider"
   #define controller_string_define      "define"
+  #define controller_string_entry       "entry"
+  #define controller_string_entries     "entries"
   #define controller_string_environment "environment"
   #define controller_string_group       "group"
   #define controller_string_name        "name"
   #define controller_string_pid         "pid"
   #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"
@@ -78,13 +86,18 @@ extern "C" {
 
   #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_entry_length       5
+  #define controller_string_entries_length     7
   #define controller_string_environment_length 11
   #define controller_string_group_length       5
   #define controller_string_name_length        4
   #define controller_string_pid_length         3
   #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
@@ -93,6 +106,16 @@ extern "C" {
   #define controller_string_use_length         3
   #define controller_string_user_length        4
 
+  #define controller_path_settings "/etc/controller"
+
+  #define controller_path_settings_length 15
+
+  #define controller_short_interruptable "i"
+  #define controller_short_settings      "s"
+
+  #define controller_long_interruptable "interruptable"
+  #define controller_long_settings      "settings"
+
   enum {
     controller_parameter_help,
     controller_parameter_light,
@@ -103,6 +126,9 @@ extern "C" {
     controller_parameter_verbosity_verbose,
     controller_parameter_verbosity_debug,
     controller_parameter_version,
+
+    controller_parameter_interruptable,
+    controller_parameter_settings,
   };
 
   #define controller_console_parameter_t_initialize \
@@ -116,37 +142,13 @@ extern "C" {
       f_console_parameter_t_initialize(f_console_standard_short_verbose, f_console_standard_long_verbose, 0, 0, f_console_type_inverse), \
       f_console_parameter_t_initialize(f_console_standard_short_debug, f_console_standard_long_debug, 0, 0, f_console_type_inverse), \
       f_console_parameter_t_initialize(f_console_standard_short_version, f_console_standard_long_version, 0, 0, f_console_type_inverse), \
+      f_console_parameter_t_initialize(controller_short_interruptable, controller_long_interruptable, 0, 0, f_console_type_normal), \
+      f_console_parameter_t_initialize(controller_short_settings, controller_long_settings, 0, 1, f_console_type_normal), \
     }
 
-  #define controller_total_parameters 9
+  #define controller_total_parameters 11
 #endif // _di_controller_defines_
 
-#ifndef _di_controller_data_t_
-  typedef struct {
-    f_console_parameter_t parameters[controller_total_parameters];
-
-    f_string_lengths_t remaining;
-    bool process_pipe;
-
-    f_file_t output;
-    fll_error_print_t error;
-    fll_error_print_t warning;
-
-    f_color_context_t context;
-  } controller_data_t;
-
-  #define controller_data_initialize \
-    { \
-      controller_console_parameter_t_initialize, \
-      f_string_lengths_t_initialize, \
-      F_false, \
-      f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \
-      fll_error_print_t_initialize, \
-      fll_macro_error_print_t_initialize_warning(), \
-      f_color_context_t_initialize, \
-    }
-#endif // _di_controller_data_t_
-
 #ifndef _di_controller_rule_action_t_
   enum {
     controller_rule_action_type_extended = 1,
@@ -319,7 +321,7 @@ extern "C" {
       controller_rule_items_initialize, \
     }
 
-  #define f_macro_controller_rule_setting_t_delete_simple(setting) \
+  #define f_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.pid) \
@@ -331,6 +333,81 @@ extern "C" {
     f_macro_controller_rule_item_t_delete_simple(setting.items)
 #endif // _di_controller_rule_t_
 
+#ifndef _di_controller_rules_t_
+  typedef struct {
+    controller_rule_t *array;
+
+    f_array_length_t size;
+    f_array_length_t used;
+  } controller_rules_t;
+
+  #define controller_rules_initialize \
+    { \
+      0, \
+      0, \
+      0, \
+    }
+
+  #define f_macro_controller_rules_t_delete_simple(rules) \
+    rules.used = rules.size; \
+    while (rules.used > 0) { \
+      rules.used--; \
+      f_macro_controller_rule_t_delete_simple(rules.array[rules.used]); \
+      if (!rules.used) { \
+        if (f_memory_delete((void **) & rules.array, sizeof(controller_rule_t), rules.size)) { \
+          rules.size = 0; \
+        } \
+      } \
+    }
+#endif // _di_controller_rules_t_
+
+#ifndef _di_controller_setting_t
+  typedef struct {
+    bool interruptable;
+
+    f_string_dynamic_t path_setting;
+
+    controller_rules_t rules;
+  } controller_setting_t;
+
+  #define controller_setting_t_initialize \
+    { \
+      F_false, \
+      f_string_dynamic_t_initialize, \
+      controller_rules_t_initialize, \
+    }
+
+  #define f_macro_controller_setting_t_delete_simple(setting) \
+    f_macro_string_dynamic_t_delete_simple(setting.path_setting) \
+    f_macro_string_dynamic_t_delete_simple(setting.rules)
+#endif // _di_controller_setting_t
+
+#ifndef _di_controller_data_t_
+  typedef struct {
+    f_console_parameter_t parameters[controller_total_parameters];
+
+    f_string_lengths_t remaining;
+    bool process_pipe;
+
+    f_file_t output;
+    fll_error_print_t error;
+    fll_error_print_t warning;
+
+    f_color_context_t context;
+  } controller_data_t;
+
+  #define controller_data_t_initialize \
+    { \
+      controller_console_parameter_t_initialize, \
+      f_string_lengths_t_initialize, \
+      F_false, \
+      f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \
+      fll_error_print_t_initialize, \
+      fll_macro_error_print_t_initialize_warning(), \
+      f_color_context_t_initialize, \
+    }
+#endif // _di_controller_data_t_
+
 /**
  * Print help.
  *
index affca7550a934d2fbfade319194c8fe10e180ee8..a7833b5ee05547bff8be24487d7ebb29ba624148 100644 (file)
@@ -2,7 +2,7 @@
 
 int main(const unsigned long argc, const f_string_t *argv) {
   const f_console_arguments_t arguments = { argc, argv };
-  controller_data_t data = controller_data_initialize;
+  controller_data_t data = controller_data_t_initialize;
 
   if (f_pipe_input_exists()) {
     data.process_pipe = F_true;
index 4607ba15ebd12ad6cb4a3971f343b83336382497..a46a91f6b936f90308f8b6036187e8345b5e29cb 100644 (file)
@@ -449,30 +449,37 @@ extern "C" {
 #endif // _di_controller_rule_items_increase_by_
 
 #ifndef _di_controller_rule_read_
-  f_return_status controller_rule_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_t *rule) {
+  f_return_status controller_rule_read(const controller_data_t data, const f_string_static_t rule_id, controller_rule_cache_t *cache, controller_rule_t *rule) {
     f_status_t status = F_none;
 
+    rule->id.used = 0;
     rule->items.used = 0;
+    rule->status = F_unknown;
 
-    cache->delimits.used = 0;
     cache->comments.used = 0;
+    cache->delimits.used = 0;
 
     cache->buffer_items.used = 0;
     cache->contents_items.used = 0;
     cache->objects_items.used = 0;
 
-    rule->status = F_found_not;
-
-    // @todo construct the rule->id from the file path name, strip the ".rule" extension and only accept the relative part of the path (relative to the base settings directory).
-    // @todo the base settings directory should be a configurable string, such as with a "-s/--settings" parameter which defaults to a compiled in value (such as /etc/controller/rules/)".
+    status = fl_string_dynamic_append_nulless(rule_id, &rule->id);
 
-    {
+    if (F_status_is_error(status)) {
+      fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_append_nulless", F_true);
+    }
+    else {
       f_file_t file = f_file_t_initialize;
 
-      status = f_file_stream_open(cache->name_file.string, 0, &file);
+      const f_string_length_t file_path_length = rule->id.used;
+      char file_path[file_path_length + 1];
+
+      memcpy(file_path, rule->id.string, rule->id.used);
+
+      status = f_file_stream_open(file_path, 0, &file);
 
       if (F_status_is_error(status)) {
-        fll_error_file_print(data.error, F_status_set_fine(status), "f_file_stream_open", F_true, cache->name_file.string, "open", fll_error_file_type_file);
+        fll_error_file_print(data.error, F_status_set_fine(status), "f_file_stream_open", F_true, rule->id.string, "open", fll_error_file_type_file);
       }
       else {
         status = f_file_stream_read(file, 1, &cache->buffer_items);
@@ -480,18 +487,12 @@ extern "C" {
         if (F_status_is_error(status)) {
           fll_error_file_print(data.error, F_status_set_fine(status), "f_file_stream_read", F_true, cache->name_file.string, "read", fll_error_file_type_file);
         }
-        else {
-          // Setting to F_none from F_unknown distinguishes the two such that F_none suggests a valid rule and F_unknown is just that, unknown.
-          rule->status = F_none;
-        }
       }
 
       f_file_stream_close(F_true, &file);
-
-      if (F_status_is_error(status)) return F_false;
     }
 
-    if (cache->buffer_items.used) {
+    if (F_status_is_error_not(status) && cache->buffer_items.used) {
       f_string_range_t range = f_macro_string_range_t_initialize(cache->buffer_items.used);
 
       status = fll_fss_basic_list_read(cache->buffer_items, &range, &cache->objects_items, &cache->contents_items, &cache->delimits, 0, &cache->comments);
@@ -604,13 +605,31 @@ extern "C" {
     }
 
     if (F_status_is_error(status)) {
+      status = F_status_set_fine(status);
+
       controller_rule_error_print(data.error, *cache);
 
-      // designate that the rule is invalid, for any failure.
-      rule->status = F_status_set_error(F_invalid);
+      if (status == F_memory_not) {
+        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;
+      }
+
+      return F_false;
     }
 
-    return status;
+    rule->status = F_none;
+    return F_true;
   }
 #endif // _di_controller_rule_read_
 
index 1778ab5fbce31ad18f43dd355a5567dfafe09878..27c2c92e8ac6643efbdfc50a05a1c69f45babd02 100644 (file)
@@ -228,24 +228,19 @@ extern "C" {
  *
  * @param data
  *   The program data.
+ * @param rule_id
+ *   The string identifying the rule.
+ *   This is constructed from the path parts to the file without the file extension and without the settings directory prefix.
+ *   "/etc/controller/setting/rules/boot/my.rule" would have a rule id of "boot/my".
  * @param cache
  *   A structure for containing and caching relevant data.
  * @param rule
  *   The processed rule.
+ *   The rule status will be updated by this function.
  *
  * @return
- *   F_none on success.
- *
- *   Errors (with error bit) from: controller_rule_items_increase_by().
- *   Errors (with error bit) from: controller_rule_item_read().
- *   Errors (with error bit) from: f_file_stream_open().
- *   Errors (with error bit) from: f_file_stream_read().
- *   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().
- *   Errors (with error bit) from: fl_string_dynamic_partial_append_nulless().
- *   Errors (with error bit) from: fl_string_dynamic_terminate_after().
- *   Errors (with error bit) from: fll_fss_basic_list_read().
+ *   F_true on success.
+ *   F_false on failure.
  *
  * @see controller_rule_items_increase_by().
  * @see controller_rule_item_read().
@@ -259,7 +254,7 @@ extern "C" {
  * @see fll_fss_basic_list_read().
  */
 #ifndef _di_controller_rule_read_
-  extern f_return_status controller_rule_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_t *rule) f_gcc_attribute_visibility_internal;
+  extern f_return_status controller_rule_read(const controller_data_t data, const f_string_static_t rule_id, controller_rule_cache_t *cache, controller_rule_t *rule) f_gcc_attribute_visibility_internal;
 #endif // _di_controller_rule_read_
 
 /**
index 454440d9d36064e7d41c6318133f887abae37c1c..e521648dbd2cb05fed9a7d0a54dadaad40b18cd1 100644 (file)
@@ -23,6 +23,11 @@ Entry Documentation:
   To disallow all rules in all directories, specify this command and provide no directoies.
   Each 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]" would have a resulting path of: "/etc/controller/rules/[directory]/".
 
+  The "consider" command is a special case of a "rule" command.
+  All available Content are identical.
+  The difference is that this rule is only processed at this spot at this time if and when some "rule" command (or a "consider" command is determined to be executed) designates that this consideration is required (via "require"), wanted (via "want"), or wished (via "wish").
+  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).
+
   The "rule" command immediately executes a given rule file.
   The first Content represents the directory in which the rule is to be found (do not include leading or trailing slashes in the name).
   The second Content represents the basename for the file representing the desired rule.
index 3f4fa4cc28528724fd5ea17f110c57123fca20c1..bcac7916084d19dc385359cc3a81cc83a29f4833 100644 (file)
@@ -15,6 +15,13 @@ Entry Specification:
       "controlled": One Content that is a valid Object name, except for the reserved "main".
       "failsafe": One Content that is a valid relative rule file name without the ".rule" extension.
       "only": Zero or more Content.
+      "consider": One or more Content.
+        The first Content that is the relative directory path (without any leading/trailing slashes).
+        The second Content that is the basename for a rule file.
+        The third and beyond may only be one of\:
+          - asynchronous
+          - require
+          - wait
       "rule": One or more Content.
         The first Content that is the relative directory path (without any leading/trailing slashes).
         The second Content that is the basename for a rule file.