[Openvas-commits] r6252 - in trunk/openvas-manager: . src

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Thu Dec 24 19:56:35 CET 2009


Author: mattm
Date: 2009-12-24 19:56:33 +0100 (Thu, 24 Dec 2009)
New Revision: 6252

Modified:
   trunk/openvas-manager/ChangeLog
   trunk/openvas-manager/src/manage.c
   trunk/openvas-manager/src/manage.h
   trunk/openvas-manager/src/omp.c
   trunk/openvas-manager/src/tasks_sql.h
Log:
	Add escalator support, including OMP commands CREATE_ESCALATOR,
	DELETE_ESCALATOR and GET_ESCALATORS, and CREATE_TASK element ESCALATOR.

	* src/manage.c (escalator_condition_name, event_name)
	(escalator_method_name, escalator_condition_from_name, event_from_name)
	(escalator_method_from_name): New function.

	* src/tasks_sql.h (create_tables): Add tables escalator_condition_data,
	escalator_event_data, escalator_method_data, escalators and
	task_escalators.
	(create_escalator, delete_escalator, find_escalator)
	(init_escalator_iterator, escalator_iterator_escalator)
	(escalator_iterator_name, escalator_iterator_comment)
	(escalator_iterator_event, escalator_iterator_condition)
	(escalator_iterator_method, escalator_iterator_in_use)
	(init_escalator_data_iterator, escalator_data_iterator_name)
	(escalator_data_iterator_data, escalator_data, email, escalate)
	(event_applies, condition_met, event): New functions.
	(set_task_run_status, task_escalator, add_task_escalator): Add event.
	(delete_task): Delete escalator.

	* src/manage.h: Add headers accordingly.
	(escalator_t, event_t, escalator_method_t, escalator_condition_t): New
	types.

	* src/omp.c (help_text): Add escalator commands.
	(client_state_t): Add escalator states.
	(omp_xml_handle_start_element, omp_xml_handle_start_element)
	(omp_xml_handle_text): Handle new commands for escalators.

Modified: trunk/openvas-manager/ChangeLog
===================================================================
--- trunk/openvas-manager/ChangeLog	2009-12-24 18:29:52 UTC (rev 6251)
+++ trunk/openvas-manager/ChangeLog	2009-12-24 18:56:33 UTC (rev 6252)
@@ -1,5 +1,37 @@
 2009-12-24  Matthew Mundell <matthew.mundell at intevation.de>
 
+	Add escalator support, including OMP commands CREATE_ESCALATOR,
+	DELETE_ESCALATOR and GET_ESCALATORS, and CREATE_TASK element ESCALATOR.
+
+	* src/manage.c (escalator_condition_name, event_name)
+	(escalator_method_name, escalator_condition_from_name, event_from_name)
+	(escalator_method_from_name): New function.
+
+	* src/tasks_sql.h (create_tables): Add tables escalator_condition_data,
+	escalator_event_data, escalator_method_data, escalators and
+	task_escalators.
+	(create_escalator, delete_escalator, find_escalator)
+	(init_escalator_iterator, escalator_iterator_escalator)
+	(escalator_iterator_name, escalator_iterator_comment)
+	(escalator_iterator_event, escalator_iterator_condition)
+	(escalator_iterator_method, escalator_iterator_in_use)
+	(init_escalator_data_iterator, escalator_data_iterator_name)
+	(escalator_data_iterator_data, escalator_data, email, escalate)
+	(event_applies, condition_met, event): New functions.
+	(set_task_run_status, task_escalator, add_task_escalator): Add event.
+	(delete_task): Delete escalator.
+
+	* src/manage.h: Add headers accordingly.
+	(escalator_t, event_t, escalator_method_t, escalator_condition_t): New
+	types.
+
+	* src/omp.c (help_text): Add escalator commands.
+	(client_state_t): Add escalator states.
+	(omp_xml_handle_start_element, omp_xml_handle_start_element)
+	(omp_xml_handle_text): Handle new commands for escalators.
+
+2009-12-24  Matthew Mundell <matthew.mundell at intevation.de>
+
 	* src/tasks_sql.h (create_tables): Sort better.
 
 2009-12-24  Matthew Mundell <matthew.mundell at intevation.de>

Modified: trunk/openvas-manager/src/manage.c
===================================================================
--- trunk/openvas-manager/src/manage.c	2009-12-24 18:29:52 UTC (rev 6251)
+++ trunk/openvas-manager/src/manage.c	2009-12-24 18:56:33 UTC (rev 6252)
@@ -241,6 +241,105 @@
 #endif
 
 
+/* Escalators. */
+
+/**
+ * @brief Get the name of an escalator condition.
+ *
+ * @param[in]  condition  Condition.
+ *
+ * @return The name of the condition (for example, "Always").
+ */
+const char*
+escalator_condition_name (escalator_condition_t condition)
+{
+  switch (condition)
+    {
+      case ESCALATOR_CONDITION_ALWAYS: return "Always";
+      default:                         return "Internal Error";
+    }
+}
+
+/**
+ * @brief Get the name of an escalator event.
+ *
+ * @param[in]  event  Event.
+ *
+ * @return The name of the event (for example, "Run status changed").
+ */
+const char*
+event_name (event_t event)
+{
+  switch (event)
+    {
+      case EVENT_TASK_RUN_STATUS_CHANGED: return "Task run status changed";
+      default:                            return "Internal Error";
+    }
+}
+
+/**
+ * @brief Get the name of an escalator method.
+ *
+ * @param[in]  method  Method.
+ *
+ * @return The name of the method (for example, "Email" or "SNMP").
+ */
+const char*
+escalator_method_name (escalator_method_t method)
+{
+  switch (method)
+    {
+      case ESCALATOR_METHOD_EMAIL: return "Email";
+      default:                     return "Internal Error";
+    }
+}
+
+/**
+ * @brief Get an escalator condition from a name.
+ *
+ * @param[in]  name  Condition name.
+ *
+ * @return The condition.
+ */
+escalator_condition_t
+escalator_condition_from_name (const char* name)
+{
+  if (strcasecmp (name, "Always") == 0)
+    return ESCALATOR_CONDITION_ALWAYS;
+  return ESCALATOR_CONDITION_ERROR;
+}
+
+/**
+ * @brief Get an event from a name.
+ *
+ * @param[in]  name  Event name.
+ *
+ * @return The event.
+ */
+event_t
+event_from_name (const char* name)
+{
+  if (strcasecmp (name, "Task run status changed") == 0)
+    return EVENT_TASK_RUN_STATUS_CHANGED;
+  return EVENT_ERROR;
+}
+
+/**
+ * @brief Get an escalator method from a name.
+ *
+ * @param[in]  name  Method name.
+ *
+ * @return The method.
+ */
+escalator_method_t
+escalator_method_from_name (const char* name)
+{
+  if (strcasecmp (name, "Email") == 0)
+    return ESCALATOR_METHOD_EMAIL;
+  return ESCALATOR_METHOD_ERROR;
+}
+
+
 /* General task facilities. */
 
 /**

Modified: trunk/openvas-manager/src/manage.h
===================================================================
--- trunk/openvas-manager/src/manage.h	2009-12-24 18:29:52 UTC (rev 6251)
+++ trunk/openvas-manager/src/manage.h	2009-12-24 18:56:33 UTC (rev 6252)
@@ -150,6 +150,7 @@
 } task_status_t;
 
 #ifdef TASKS_SQL
+typedef long long int escalator_t;
 typedef long long int task_t;
 typedef long long int result_t;
 typedef long long int report_t;
@@ -171,6 +172,7 @@
   gboolean done;
 } iterator_t;
 #else /* not TASKS_SQL */
+typedef long long int escalator_t;
 typedef long long int task_t;
 typedef long long int result_t;
 typedef long long int report_t;
@@ -191,6 +193,98 @@
 #endif /* not TASKS_SQL */
 
 
+/* Events. */
+
+/**
+ * @brief Types of task events.
+ */
+typedef enum
+{
+  EVENT_ERROR,
+  EVENT_TASK_RUN_STATUS_CHANGED
+} event_t;
+
+/**
+ * @brief Types of escalators.
+ */
+typedef enum
+{
+  ESCALATOR_METHOD_ERROR,
+  ESCALATOR_METHOD_EMAIL
+} escalator_method_t;
+
+/**
+ * @brief Types of escalator conditions.
+ */
+typedef enum
+{
+  ESCALATOR_CONDITION_ERROR,
+  ESCALATOR_CONDITION_ALWAYS
+} escalator_condition_t;
+
+int
+create_escalator (const char*, const char*, event_t, GPtrArray*,
+                  escalator_condition_t, GPtrArray*, escalator_method_t,
+                  GPtrArray*);
+
+int
+delete_escalator (const char*);
+
+gboolean
+find_escalator (const char*, escalator_t*);
+
+void
+init_escalator_iterator (iterator_t*, task_t, event_t, int, const char*);
+
+escalator_t
+escalator_iterator_escalator (iterator_t*);
+
+const char*
+escalator_iterator_name (iterator_t*);
+
+int
+escalator_iterator_in_use (iterator_t*);
+
+const char *
+escalator_iterator_comment (iterator_t*);
+
+int
+escalator_iterator_event (iterator_t*);
+
+int
+escalator_iterator_condition (iterator_t*);
+
+int
+escalator_iterator_method (iterator_t*);
+
+const char*
+escalator_condition_name (escalator_condition_t);
+
+const char*
+event_name (event_t);
+
+const char*
+escalator_method_name (escalator_method_t);
+
+escalator_condition_t
+escalator_condition_from_name (const char*);
+
+event_t
+event_from_name (const char*);
+
+escalator_method_t
+escalator_method_from_name (const char*);
+
+void
+init_escalator_data_iterator (iterator_t *, escalator_t, const char *);
+
+const char*
+escalator_data_iterator_name (iterator_t*);
+
+const char*
+escalator_data_iterator_data (iterator_t*);
+
+
 /* Task global variables. */
 
 /**
@@ -266,6 +360,12 @@
 void
 set_task_end_time (task_t task, char* time);
 
+char*
+task_escalator (task_t);
+
+void
+add_task_escalator (task_t, const char*);
+
 unsigned int
 task_report_count (task_t);
 

Modified: trunk/openvas-manager/src/omp.c
===================================================================
--- trunk/openvas-manager/src/omp.c	2009-12-24 18:29:52 UTC (rev 6251)
+++ trunk/openvas-manager/src/omp.c	2009-12-24 18:56:33 UTC (rev 6252)
@@ -267,11 +267,13 @@
 "    COMMANDS               Run a list of commands.\n"
 "    CREATE_AGENT           Create an agent.\n"
 "    CREATE_CONFIG          Create a config.\n"
+"    CREATE_ESCALATOR       Create an escalator.\n"
 "    CREATE_LSC_CREDENTIAL  Create a local security check credential.\n"
 "    CREATE_TARGET          Create a target.\n"
 "    CREATE_TASK            Create a task.\n"
 "    DELETE_AGENT           Delete an agent.\n"
 "    DELETE_CONFIG          Delete a config.\n"
+"    DELETE_ESCALATOR       Delete an escalator.\n"
 "    DELETE_LSC_CREDENTIAL  Delete a local security check credential.\n"
 "    DELETE_REPORT          Delete a report.\n"
 "    DELETE_TARGET          Delete a target.\n"
@@ -280,6 +282,7 @@
 "    GET_CERTIFICATES       Get all available certificates.\n"
 "    GET_CONFIGS            Get all configs.\n"
 "    GET_DEPENDENCIES       Get dependencies for all available NVTs.\n"
+"    GET_ESCALATORS         Get all escalators.\n"
 "    GET_LSC_CREDENTIALS    Get all local security check credentials.\n"
 "    GET_NVT_ALL            Get IDs and names of all available NVTs.\n"
 "    GET_NVT_DETAILS        Get all details for all available NVTs.\n"
@@ -553,6 +556,18 @@
   CLIENT_CREATE_CONFIG_COPY,
   CLIENT_CREATE_CONFIG_NAME,
   CLIENT_CREATE_CONFIG_RCFILE,
+  CLIENT_CREATE_ESCALATOR,
+  CLIENT_CREATE_ESCALATOR_COMMENT,
+  CLIENT_CREATE_ESCALATOR_CONDITION,
+  CLIENT_CREATE_ESCALATOR_CONDITION_DATA,
+  CLIENT_CREATE_ESCALATOR_CONDITION_DATA_NAME,
+  CLIENT_CREATE_ESCALATOR_EVENT,
+  CLIENT_CREATE_ESCALATOR_EVENT_DATA,
+  CLIENT_CREATE_ESCALATOR_EVENT_DATA_NAME,
+  CLIENT_CREATE_ESCALATOR_METHOD,
+  CLIENT_CREATE_ESCALATOR_METHOD_DATA,
+  CLIENT_CREATE_ESCALATOR_METHOD_DATA_NAME,
+  CLIENT_CREATE_ESCALATOR_NAME,
   CLIENT_CREATE_LSC_CREDENTIAL,
   CLIENT_CREATE_LSC_CREDENTIAL_COMMENT,
   CLIENT_CREATE_LSC_CREDENTIAL_NAME,
@@ -566,6 +581,7 @@
   CLIENT_CREATE_TASK,
   CLIENT_CREATE_TASK_COMMENT,
   CLIENT_CREATE_TASK_CONFIG,
+  CLIENT_CREATE_TASK_ESCALATOR,
   CLIENT_CREATE_TASK_NAME,
   CLIENT_CREATE_TASK_RCFILE,
   CLIENT_CREATE_TASK_TARGET,
@@ -576,6 +592,8 @@
   CLIENT_DELETE_AGENT_NAME,
   CLIENT_DELETE_CONFIG,
   CLIENT_DELETE_CONFIG_NAME,
+  CLIENT_DELETE_ESCALATOR,
+  CLIENT_DELETE_ESCALATOR_NAME,
   CLIENT_DELETE_LSC_CREDENTIAL,
   CLIENT_DELETE_LSC_CREDENTIAL_NAME,
   CLIENT_DELETE_REPORT,
@@ -586,6 +604,7 @@
   CLIENT_GET_CERTIFICATES,
   CLIENT_GET_CONFIGS,
   CLIENT_GET_DEPENDENCIES,
+  CLIENT_GET_ESCALATORS,
   CLIENT_GET_LSC_CREDENTIALS,
   CLIENT_GET_NVT_ALL,
   CLIENT_GET_NVT_DETAILS,
@@ -1076,6 +1095,12 @@
             openvas_append_string (&modify_task_name, "");
             set_client_state (CLIENT_DELETE_CONFIG);
           }
+        else if (strcasecmp ("DELETE_ESCALATOR", element_name) == 0)
+          {
+            assert (modify_task_name == NULL);
+            openvas_append_string (&modify_task_name, "");
+            set_client_state (CLIENT_DELETE_ESCALATOR);
+          }
         else if (strcasecmp ("DELETE_LSC_CREDENTIAL", element_name) == 0)
           {
             assert (modify_task_name == NULL);
@@ -1154,6 +1179,19 @@
           }
         else if (strcasecmp ("GET_DEPENDENCIES", element_name) == 0)
           set_client_state (CLIENT_GET_DEPENDENCIES);
+        else if (strcasecmp ("GET_ESCALATORS", element_name) == 0)
+          {
+            const gchar* attribute;
+            if (find_attribute (attribute_names, attribute_values,
+                                "sort_field", &attribute))
+              openvas_append_string (&current_format, attribute);
+            if (find_attribute (attribute_names, attribute_values,
+                                "sort_order", &attribute))
+              current_int_2 = strcmp (attribute, "descending");
+            else
+              current_int_2 = 1;
+            set_client_state (CLIENT_GET_ESCALATORS);
+          }
         else if (strcasecmp ("GET_LSC_CREDENTIALS", element_name) == 0)
           {
             const gchar* attribute;
@@ -1319,6 +1357,33 @@
             openvas_append_string (&modify_task_name, "");
             set_client_state (CLIENT_CREATE_CONFIG);
           }
+        else if (strcasecmp ("CREATE_ESCALATOR", element_name) == 0)
+          {
+            assert (current_array_1 == NULL);
+            assert (current_array_2 == NULL);
+            assert (current_array_3 == NULL);
+            assert (current_format == NULL);
+            assert (current_uuid == NULL);
+            assert (modify_task_comment == NULL);
+            assert (modify_task_name == NULL);
+            assert (modify_task_parameter == NULL);
+            assert (modify_task_rcfile == NULL);
+            assert (modify_task_value == NULL);
+
+            current_array_1 = make_array ();
+            current_array_2 = make_array ();
+            current_array_3 = make_array ();
+
+            openvas_append_string (&current_format, "");
+            openvas_append_string (&current_uuid, "");
+            openvas_append_string (&modify_task_comment, "");
+            openvas_append_string (&modify_task_name, "");
+            openvas_append_string (&modify_task_parameter, "");
+            openvas_append_string (&modify_task_rcfile, "");
+            openvas_append_string (&modify_task_value, "");
+
+            set_client_state (CLIENT_CREATE_ESCALATOR);
+          }
         else if (strcasecmp ("CREATE_LSC_CREDENTIAL", element_name) == 0)
           {
             assert (modify_task_comment == NULL);
@@ -1331,8 +1396,10 @@
         else if (strcasecmp ("CREATE_TASK", element_name) == 0)
           {
             assert (current_client_task == (task_t) 0);
+            assert (modify_task_name == NULL);
             current_client_task = make_task (NULL, 0, NULL);
             if (current_client_task == (task_t) 0) abort (); // FIX
+            openvas_append_string (&modify_task_name, "");
             set_client_state (CLIENT_CREATE_TASK);
           }
         else if (strcasecmp ("CREATE_TARGET", element_name) == 0)
@@ -1467,6 +1534,24 @@
           }
         break;
 
+      case CLIENT_DELETE_ESCALATOR:
+        if (strcasecmp ("NAME", element_name) == 0)
+          set_client_state (CLIENT_DELETE_ESCALATOR_NAME);
+        else
+          {
+            if (send_element_error_to_client ("delete_escalator", element_name))
+              {
+                error_send_to_client (error);
+                return;
+              }
+            set_client_state (CLIENT_AUTHENTIC);
+            g_set_error (error,
+                         G_MARKUP_ERROR,
+                         G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                         "Error");
+          }
+        break;
+
       case CLIENT_DELETE_LSC_CREDENTIAL:
         if (strcasecmp ("NAME", element_name) == 0)
           set_client_state (CLIENT_DELETE_LSC_CREDENTIAL_NAME);
@@ -1591,6 +1676,21 @@
           }
         break;
 
+      case CLIENT_GET_ESCALATORS:
+          {
+            if (send_element_error_to_client ("get_escalators", element_name))
+              {
+                error_send_to_client (error);
+                return;
+              }
+            set_client_state (CLIENT_AUTHENTIC);
+            g_set_error (error,
+                         G_MARKUP_ERROR,
+                         G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                         "Error");
+          }
+        break;
+
       case CLIENT_GET_LSC_CREDENTIALS:
           {
             if (send_element_error_to_client ("get_lsc_credentials",
@@ -2026,6 +2126,140 @@
           }
         break;
 
+      case CLIENT_CREATE_ESCALATOR:
+        if (strcasecmp ("COMMENT", element_name) == 0)
+          set_client_state (CLIENT_CREATE_ESCALATOR_COMMENT);
+        else if (strcasecmp ("CONDITION", element_name) == 0)
+          set_client_state (CLIENT_CREATE_ESCALATOR_CONDITION);
+        else if (strcasecmp ("EVENT", element_name) == 0)
+          set_client_state (CLIENT_CREATE_ESCALATOR_EVENT);
+        else if (strcasecmp ("METHOD", element_name) == 0)
+          set_client_state (CLIENT_CREATE_ESCALATOR_METHOD);
+        else if (strcasecmp ("NAME", element_name) == 0)
+          set_client_state (CLIENT_CREATE_ESCALATOR_NAME);
+        else
+          {
+            if (send_element_error_to_client ("create_escalator", element_name))
+              {
+                error_send_to_client (error);
+                return;
+              }
+            set_client_state (CLIENT_AUTHENTIC);
+            g_set_error (error,
+                         G_MARKUP_ERROR,
+                         G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                         "Error");
+          }
+        break;
+
+      case CLIENT_CREATE_ESCALATOR_CONDITION:
+        if (strcasecmp ("DATA", element_name) == 0)
+          set_client_state (CLIENT_CREATE_ESCALATOR_CONDITION_DATA);
+        else
+          {
+            if (send_element_error_to_client ("create_escalator", element_name))
+              {
+                error_send_to_client (error);
+                return;
+              }
+            set_client_state (CLIENT_AUTHENTIC);
+            g_set_error (error,
+                         G_MARKUP_ERROR,
+                         G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                         "Error");
+          }
+        break;
+
+      case CLIENT_CREATE_ESCALATOR_CONDITION_DATA:
+        if (strcasecmp ("NAME", element_name) == 0)
+          set_client_state (CLIENT_CREATE_ESCALATOR_CONDITION_DATA_NAME);
+        else
+          {
+            if (send_element_error_to_client ("create_escalator", element_name))
+              {
+                error_send_to_client (error);
+                return;
+              }
+            set_client_state (CLIENT_AUTHENTIC);
+            g_set_error (error,
+                         G_MARKUP_ERROR,
+                         G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                         "Error");
+          }
+        break;
+
+      case CLIENT_CREATE_ESCALATOR_EVENT:
+        if (strcasecmp ("DATA", element_name) == 0)
+          set_client_state (CLIENT_CREATE_ESCALATOR_EVENT_DATA);
+        else
+          {
+            if (send_element_error_to_client ("create_escalator", element_name))
+              {
+                error_send_to_client (error);
+                return;
+              }
+            set_client_state (CLIENT_AUTHENTIC);
+            g_set_error (error,
+                         G_MARKUP_ERROR,
+                         G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                         "Error");
+          }
+        break;
+
+      case CLIENT_CREATE_ESCALATOR_EVENT_DATA:
+        if (strcasecmp ("NAME", element_name) == 0)
+          set_client_state (CLIENT_CREATE_ESCALATOR_EVENT_DATA_NAME);
+        else
+          {
+            if (send_element_error_to_client ("create_escalator", element_name))
+              {
+                error_send_to_client (error);
+                return;
+              }
+            set_client_state (CLIENT_AUTHENTIC);
+            g_set_error (error,
+                         G_MARKUP_ERROR,
+                         G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                         "Error");
+          }
+        break;
+
+      case CLIENT_CREATE_ESCALATOR_METHOD:
+        if (strcasecmp ("DATA", element_name) == 0)
+          set_client_state (CLIENT_CREATE_ESCALATOR_METHOD_DATA);
+        else
+          {
+            if (send_element_error_to_client ("create_escalator", element_name))
+              {
+                error_send_to_client (error);
+                return;
+              }
+            set_client_state (CLIENT_AUTHENTIC);
+            g_set_error (error,
+                         G_MARKUP_ERROR,
+                         G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                         "Error");
+          }
+        break;
+
+      case CLIENT_CREATE_ESCALATOR_METHOD_DATA:
+        if (strcasecmp ("NAME", element_name) == 0)
+          set_client_state (CLIENT_CREATE_ESCALATOR_METHOD_DATA_NAME);
+        else
+          {
+            if (send_element_error_to_client ("create_escalator", element_name))
+              {
+                error_send_to_client (error);
+                return;
+              }
+            set_client_state (CLIENT_AUTHENTIC);
+            g_set_error (error,
+                         G_MARKUP_ERROR,
+                         G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                         "Error");
+          }
+        break;
+
       case CLIENT_CREATE_LSC_CREDENTIAL:
         if (strcasecmp ("COMMENT", element_name) == 0)
           set_client_state (CLIENT_CREATE_LSC_CREDENTIAL_COMMENT);
@@ -2090,6 +2324,8 @@
           set_client_state (CLIENT_CREATE_TASK_COMMENT);
         else if (strcasecmp ("CONFIG", element_name) == 0)
           set_client_state (CLIENT_CREATE_TASK_CONFIG);
+        else if (strcasecmp ("ESCALATOR", element_name) == 0)
+          set_client_state (CLIENT_CREATE_TASK_ESCALATOR);
         else if (strcasecmp ("TARGET", element_name) == 0)
           set_client_state (CLIENT_CREATE_TASK_TARGET);
         else
@@ -4675,6 +4911,42 @@
         set_client_state (CLIENT_DELETE_CONFIG);
         break;
 
+      case CLIENT_DELETE_ESCALATOR:
+        {
+          assert (strcasecmp ("DELETE_ESCALATOR", element_name) == 0);
+          assert (modify_task_name != NULL);
+
+          if (strlen (modify_task_name) == 0)
+            {
+              openvas_free_string_var (&modify_task_name);
+              SEND_TO_CLIENT_OR_FAIL
+               (XML_ERROR_SYNTAX ("delete_escalator",
+                                  "DELETE_ESCALATOR name must be at least one"
+                                  " character long"));
+            }
+          else switch (delete_escalator (modify_task_name))
+            {
+              case 0:
+                openvas_free_string_var (&modify_task_name);
+                SEND_TO_CLIENT_OR_FAIL (XML_OK ("delete_escalator"));
+                break;
+              case 1:
+                openvas_free_string_var (&modify_task_name);
+                SEND_TO_CLIENT_OR_FAIL (XML_ERROR_SYNTAX ("delete_escalator",
+                                                          "Escalator is in use"));
+                break;
+              default:
+                openvas_free_string_var (&modify_task_name);
+                SEND_TO_CLIENT_OR_FAIL (XML_INTERNAL_ERROR ("delete_escalator"));
+            }
+          set_client_state (CLIENT_AUTHENTIC);
+          break;
+        }
+      case CLIENT_DELETE_ESCALATOR_NAME:
+        assert (strcasecmp ("NAME", element_name) == 0);
+        set_client_state (CLIENT_DELETE_ESCALATOR);
+        break;
+
       case CLIENT_DELETE_LSC_CREDENTIAL:
         {
           assert (strcasecmp ("DELETE_LSC_CREDENTIAL", element_name) == 0);
@@ -5487,6 +5759,203 @@
         set_client_state (CLIENT_CREATE_CONFIG);
         break;
 
+      case CLIENT_CREATE_ESCALATOR:
+        {
+          event_t event;
+          escalator_condition_t condition;
+          escalator_method_t method;
+
+          assert (strcasecmp ("CREATE_ESCALATOR", element_name) == 0);
+          assert (modify_task_name != NULL);
+          assert (modify_task_parameter != NULL);
+          assert (modify_task_rcfile != NULL);
+          assert (modify_task_value != NULL);
+
+          array_terminate (current_array_1);
+          array_terminate (current_array_2);
+          array_terminate (current_array_3);
+
+          if (strlen (modify_task_name) == 0)
+            SEND_TO_CLIENT_OR_FAIL
+             (XML_ERROR_SYNTAX ("create_escalator",
+                                "CREATE_ESCALATOR requires NAME element which"
+                                " is at least one character long"));
+          else if (strlen (modify_task_parameter) == 0)
+            SEND_TO_CLIENT_OR_FAIL
+             (XML_ERROR_SYNTAX ("create_escalator",
+                                "CREATE_ESCALATOR requires a value in a"
+                                " CONDITION element"));
+          else if (strlen (modify_task_value) == 0)
+            SEND_TO_CLIENT_OR_FAIL
+             (XML_ERROR_SYNTAX ("create_escalator",
+                                "CREATE_ESCALATOR requires a value in an"
+                                " EVENT element"));
+          else if (strlen (modify_task_rcfile) == 0)
+            SEND_TO_CLIENT_OR_FAIL
+             (XML_ERROR_SYNTAX ("create_escalator",
+                                "CREATE_ESCALATOR requires a value in a"
+                                " METHOD element"));
+          else if ((condition = escalator_condition_from_name
+                                 (modify_task_parameter))
+                   == 0)
+            SEND_TO_CLIENT_OR_FAIL
+             (XML_ERROR_SYNTAX ("create_escalator",
+                                "Failed to recognise condition name"));
+          else if ((event = event_from_name (modify_task_value)) == 0)
+            SEND_TO_CLIENT_OR_FAIL
+             (XML_ERROR_SYNTAX ("create_escalator",
+                                "Failed to recognise event name"));
+          else if ((method = escalator_method_from_name (modify_task_rcfile))
+                   == 0)
+            SEND_TO_CLIENT_OR_FAIL
+             (XML_ERROR_SYNTAX ("create_escalator",
+                                "Failed to recognise method name"));
+          else
+            {
+              switch (create_escalator (modify_task_name,
+                                        modify_task_comment,
+                                        /* Event. */
+                                        event,
+                                        /* Event data. */
+                                        current_array_2,
+                                        /* Condition. */
+                                        condition,
+                                        /* Condition data. */
+                                        current_array_1,
+                                        /* Method. */
+                                        method,
+                                        /* Method data. */
+                                        current_array_3))
+                {
+                  case 0:
+                    SEND_TO_CLIENT_OR_FAIL
+                     (XML_OK_CREATED ("create_escalator"));
+                    break;
+                  case 1:
+                    SEND_TO_CLIENT_OR_FAIL
+                     (XML_ERROR_SYNTAX ("create_escalator",
+                                        "Escalator exists already"));
+                    break;
+                  default:
+                    assert (0);
+                  case -1:
+                    SEND_TO_CLIENT_OR_FAIL
+                     (XML_INTERNAL_ERROR ("create_escalator"));
+                    break;
+                }
+            }
+          openvas_free_string_var (&current_format);
+          openvas_free_string_var (&current_uuid);
+          openvas_free_string_var (&modify_task_comment);
+          openvas_free_string_var (&modify_task_name);
+          openvas_free_string_var (&modify_task_parameter);
+          openvas_free_string_var (&modify_task_rcfile);
+          openvas_free_string_var (&modify_task_value);
+          free_array (current_array_1);
+          free_array (current_array_2);
+          free_array (current_array_3);
+          current_array_1 = NULL;
+          current_array_2 = NULL;
+          current_array_3 = NULL;
+          set_client_state (CLIENT_AUTHENTIC);
+          break;
+        }
+      case CLIENT_CREATE_ESCALATOR_COMMENT:
+        assert (strcasecmp ("COMMENT", element_name) == 0);
+        set_client_state (CLIENT_CREATE_ESCALATOR);
+        break;
+      case CLIENT_CREATE_ESCALATOR_CONDITION:
+        assert (strcasecmp ("CONDITION", element_name) == 0);
+        set_client_state (CLIENT_CREATE_ESCALATOR);
+        break;
+      case CLIENT_CREATE_ESCALATOR_EVENT:
+        assert (strcasecmp ("EVENT", element_name) == 0);
+        set_client_state (CLIENT_CREATE_ESCALATOR);
+        break;
+      case CLIENT_CREATE_ESCALATOR_METHOD:
+        assert (strcasecmp ("METHOD", element_name) == 0);
+        set_client_state (CLIENT_CREATE_ESCALATOR);
+        break;
+      case CLIENT_CREATE_ESCALATOR_NAME:
+        assert (strcasecmp ("NAME", element_name) == 0);
+        set_client_state (CLIENT_CREATE_ESCALATOR);
+        break;
+
+      case CLIENT_CREATE_ESCALATOR_CONDITION_DATA:
+        {
+          gchar *string;
+
+          assert (strcasecmp ("DATA", element_name) == 0);
+          assert (current_array_1);
+          assert (current_format);
+          assert (current_uuid);
+
+          string = g_strconcat (current_uuid, "0", current_format, NULL);
+          string[strlen (current_uuid)] = '\0';
+          array_add (current_array_1, string);
+
+          openvas_free_string_var (&current_format);
+          openvas_free_string_var (&current_uuid);
+          openvas_append_string (&current_format, "");
+          openvas_append_string (&current_uuid, "");
+          set_client_state (CLIENT_CREATE_ESCALATOR_CONDITION);
+          break;
+        }
+      case CLIENT_CREATE_ESCALATOR_CONDITION_DATA_NAME:
+        assert (strcasecmp ("NAME", element_name) == 0);
+        set_client_state (CLIENT_CREATE_ESCALATOR_CONDITION_DATA);
+        break;
+
+      case CLIENT_CREATE_ESCALATOR_EVENT_DATA:
+        {
+          gchar *string;
+
+          assert (strcasecmp ("DATA", element_name) == 0);
+          assert (current_array_2);
+          assert (current_format);
+          assert (current_uuid);
+
+          string = g_strconcat (current_uuid, "0", current_format, NULL);
+          string[strlen (current_uuid)] = '\0';
+          array_add (current_array_2, string);
+
+          openvas_free_string_var (&current_format);
+          openvas_free_string_var (&current_uuid);
+          openvas_append_string (&current_format, "");
+          openvas_append_string (&current_uuid, "");
+          set_client_state (CLIENT_CREATE_ESCALATOR_EVENT);
+          break;
+        }
+      case CLIENT_CREATE_ESCALATOR_EVENT_DATA_NAME:
+        assert (strcasecmp ("NAME", element_name) == 0);
+        set_client_state (CLIENT_CREATE_ESCALATOR_EVENT_DATA);
+        break;
+
+      case CLIENT_CREATE_ESCALATOR_METHOD_DATA:
+        {
+          gchar *string;
+
+          assert (strcasecmp ("DATA", element_name) == 0);
+          assert (current_array_3);
+          assert (current_format);
+          assert (current_uuid);
+
+          string = g_strconcat (current_uuid, "0", current_format, NULL);
+          string[strlen (current_uuid)] = '\0';
+          array_add (current_array_3, string);
+
+          openvas_free_string_var (&current_format);
+          openvas_free_string_var (&current_uuid);
+          openvas_append_string (&current_format, "");
+          openvas_append_string (&current_uuid, "");
+          set_client_state (CLIENT_CREATE_ESCALATOR_METHOD);
+          break;
+        }
+      case CLIENT_CREATE_ESCALATOR_METHOD_DATA_NAME:
+        assert (strcasecmp ("NAME", element_name) == 0);
+        set_client_state (CLIENT_CREATE_ESCALATOR_METHOD_DATA);
+        break;
+
       case CLIENT_CREATE_LSC_CREDENTIAL:
         {
           assert (strcasecmp ("CREATE_LSC_CREDENTIAL", element_name) == 0);
@@ -5644,6 +6113,7 @@
                   return;
                 }
               current_client_task = (task_t) 0;
+              openvas_free_string_var (&modify_task_name);
               set_client_state (CLIENT_AUTHENTIC);
               break;
             }
@@ -5666,10 +6136,34 @@
                                   "CREATE_TASK requires either an rcfile"
                                   " or both a config and a target"));
               current_client_task = (task_t) 0;
+              openvas_free_string_var (&modify_task_name);
               set_client_state (CLIENT_AUTHENTIC);
               break;
             }
 
+          /* Set any escalator. */
+
+          if (strlen (modify_task_name))
+            {
+              escalator_t escalator;
+              if (find_escalator (modify_task_name, &escalator))
+                {
+                  SEND_TO_CLIENT_OR_FAIL (XML_INTERNAL_ERROR ("create_task"));
+                  openvas_free_string_var (&modify_task_name);
+                  break;
+                }
+              if (escalator == 0)
+                {
+                  SEND_TO_CLIENT_OR_FAIL
+                   (XML_ERROR_SYNTAX ("create_task",
+                                      "CREATE_TASK escalator must exist"));
+                  openvas_free_string_var (&modify_task_name);
+                  break;
+                }
+              add_task_escalator (current_client_task, modify_task_name);
+            }
+          openvas_free_string_var (&modify_task_name);
+
           /* Check for name. */
 
           name = task_name (current_client_task);
@@ -5823,6 +6317,10 @@
         assert (strcasecmp ("CONFIG", element_name) == 0);
         set_client_state (CLIENT_CREATE_TASK);
         break;
+      case CLIENT_CREATE_TASK_ESCALATOR:
+        assert (strcasecmp ("ESCALATOR", element_name) == 0);
+        set_client_state (CLIENT_CREATE_TASK);
+        break;
       case CLIENT_CREATE_TASK_NAME:
         assert (strcasecmp ("NAME", element_name) == 0);
         set_client_state (CLIENT_CREATE_TASK);
@@ -5989,7 +6487,7 @@
                   {
                     int ret, maximum_hosts;
                     gchar *response, *progress_xml;
-                    char *name, *config, *target, *hosts;
+                    char *name, *config, *escalator, *target, *hosts;
                     gchar *first_report_id, *first_report;
                     char* description;
                     gchar *description64, *last_report_id, *last_report;
@@ -6210,6 +6708,7 @@
                       description64 = g_strdup ("");
 
                     name = task_name (task);
+                    escalator = task_escalator (task);
                     config = task_config (task);
                     response = g_strdup_printf
                                 ("<get_status_response"
@@ -6218,6 +6717,7 @@
                                  "<task id=\"%s\">"
                                  "<name>%s</name>"
                                  "<config><name>%s</name></config>"
+                                 "<escalator><name>%s</name></escalator>"
                                  "<target><name>%s</name></target>"
                                  "<status>%s</status>"
                                  "<progress>%s</progress>"
@@ -6236,6 +6736,7 @@
                                  tsk_uuid,
                                  name,
                                  config ? config : "",
+                                 escalator ? escalator : "",
                                  target ? target : "",
                                  task_run_status_name (task),
                                  progress_xml,
@@ -6251,6 +6752,7 @@
                                  last_report,
                                  second_last_report);
                     free (config);
+                    free (escalator);
                     free (target);
                     g_free (progress_xml);
                     g_free (last_report);
@@ -6315,7 +6817,7 @@
               {
                 gchar *line, *progress_xml;
                 char *name = task_name (index);
-                char *tsk_uuid, *config, *target, *hosts;
+                char *tsk_uuid, *config, *escalator, *target, *hosts;
                 gchar *first_report_id, *first_report;
                 char *description;
                 gchar *description64, *last_report_id, *last_report;
@@ -6534,10 +7036,12 @@
                   progress_xml = g_strdup ("-1");
 
                 config = task_config (index);
+                escalator = task_escalator (index);
                 line = g_strdup_printf ("<task"
                                         " id=\"%s\">"
                                         "<name>%s</name>"
                                         "<config><name>%s</name></config>"
+                                        "<escalator><name>%s</name></escalator>"
                                         "<target><name>%s</name></target>"
                                         "<status>%s</status>"
                                         "<progress>%s</progress>"
@@ -6557,6 +7061,7 @@
                                         tsk_uuid,
                                         name,
                                         config ? config : "",
+                                        escalator ? escalator : "",
                                         target ? target : "",
                                         task_run_status_name (index),
                                         progress_xml,
@@ -6572,6 +7077,7 @@
                                         last_report,
                                         second_last_report);
                 free (config);
+                free (escalator);
                 free (target);
                 g_free (progress_xml);
                 g_free (last_report);
@@ -6904,6 +7410,99 @@
           break;
         }
 
+      case CLIENT_GET_ESCALATORS:
+        {
+          iterator_t escalators;
+          assert (strcasecmp ("GET_ESCALATORS", element_name) == 0);
+
+          SEND_TO_CLIENT_OR_FAIL ("<get_escalators_response"
+                                  " status=\"" STATUS_OK "\""
+                                  " status_text=\"" STATUS_OK_TEXT "\">");
+          init_escalator_iterator (&escalators,
+                                   (task_t) 0,
+                                   (event_t) 0,
+                                   current_int_2,   /* Attribute sort_order. */
+                                   current_format); /* Attribute sort_field. */
+          while (next (&escalators))
+            {
+              iterator_t data;
+
+              SENDF_TO_CLIENT_OR_FAIL ("<escalator>"
+                                       "<name>%s</name>"
+                                       "<comment>%s</comment>"
+                                       "<in_use>%i</in_use>",
+                                       escalator_iterator_name (&escalators),
+                                       escalator_iterator_comment (&escalators),
+                                       escalator_iterator_in_use (&escalators));
+
+              /* Condition. */
+
+              SENDF_TO_CLIENT_OR_FAIL ("<condition>%s",
+                                       escalator_condition_name
+                                        (escalator_iterator_condition
+                                          (&escalators)));
+              init_escalator_data_iterator (&data,
+                                            escalator_iterator_escalator
+                                             (&escalators),
+                                            "condition");
+              while (next (&data))
+                SENDF_TO_CLIENT_OR_FAIL ("<data>"
+                                         "<name>%s</name>"
+                                         "%s"
+                                         "</data>",
+                                         escalator_data_iterator_name (&data),
+                                         escalator_data_iterator_data (&data));
+              cleanup_iterator (&data);
+              SEND_TO_CLIENT_OR_FAIL ("</condition>");
+
+              /* Event. */
+
+              SENDF_TO_CLIENT_OR_FAIL ("<event>%s",
+                                       event_name (escalator_iterator_event
+                                        (&escalators)));
+              init_escalator_data_iterator (&data,
+                                            escalator_iterator_escalator
+                                             (&escalators),
+                                            "event");
+              while (next (&data))
+                SENDF_TO_CLIENT_OR_FAIL ("<data>"
+                                         "<name>%s</name>"
+                                         "%s"
+                                         "</data>",
+                                         escalator_data_iterator_name (&data),
+                                         escalator_data_iterator_data (&data));
+              cleanup_iterator (&data);
+              SEND_TO_CLIENT_OR_FAIL ("</event>");
+
+              /* Method. */
+
+              SENDF_TO_CLIENT_OR_FAIL ("<method>%s",
+                                       escalator_method_name
+                                        (escalator_iterator_method
+                                          (&escalators)));
+              init_escalator_data_iterator (&data,
+                                            escalator_iterator_escalator
+                                             (&escalators),
+                                            "method");
+              while (next (&data))
+                SENDF_TO_CLIENT_OR_FAIL ("<data>"
+                                         "<name>%s</name>"
+                                         "%s"
+                                         "</data>",
+                                         escalator_data_iterator_name (&data),
+                                         escalator_data_iterator_data (&data));
+              cleanup_iterator (&data);
+              SEND_TO_CLIENT_OR_FAIL ("</method>");
+
+              SEND_TO_CLIENT_OR_FAIL ("</escalator>");
+            }
+          cleanup_iterator (&escalators);
+          SEND_TO_CLIENT_OR_FAIL ("</get_escalators_response>");
+          openvas_free_string_var (&current_format);
+          set_client_state (CLIENT_AUTHENTIC);
+          break;
+        }
+
       case CLIENT_GET_LSC_CREDENTIALS:
         {
           iterator_t targets;
@@ -7221,6 +7820,42 @@
         openvas_append_text (&modify_task_parameter, text, text_len);
         break;
 
+      case CLIENT_CREATE_ESCALATOR_COMMENT:
+        openvas_append_text (&modify_task_comment, text, text_len);
+        break;
+      case CLIENT_CREATE_ESCALATOR_CONDITION:
+        openvas_append_text (&modify_task_parameter, text, text_len);
+        break;
+      case CLIENT_CREATE_ESCALATOR_EVENT:
+        openvas_append_text (&modify_task_value, text, text_len);
+        break;
+      case CLIENT_CREATE_ESCALATOR_METHOD:
+        openvas_append_text (&modify_task_rcfile, text, text_len);
+        break;
+      case CLIENT_CREATE_ESCALATOR_NAME:
+        openvas_append_text (&modify_task_name, text, text_len);
+        break;
+
+      case CLIENT_CREATE_ESCALATOR_CONDITION_DATA:
+        openvas_append_text (&current_format, text, text_len);
+        break;
+      case CLIENT_CREATE_ESCALATOR_EVENT_DATA:
+        openvas_append_text (&current_format, text, text_len);
+        break;
+      case CLIENT_CREATE_ESCALATOR_METHOD_DATA:
+        openvas_append_text (&current_format, text, text_len);
+        break;
+
+      case CLIENT_CREATE_ESCALATOR_CONDITION_DATA_NAME:
+        openvas_append_text (&current_uuid, text, text_len);
+        break;
+      case CLIENT_CREATE_ESCALATOR_EVENT_DATA_NAME:
+        openvas_append_text (&current_uuid, text, text_len);
+        break;
+      case CLIENT_CREATE_ESCALATOR_METHOD_DATA_NAME:
+        openvas_append_text (&current_uuid, text, text_len);
+        break;
+
       case CLIENT_CREATE_TARGET_COMMENT:
         openvas_append_text (&modify_task_comment, text, text_len);
         break;
@@ -7240,6 +7875,9 @@
       case CLIENT_CREATE_TASK_CONFIG:
         append_to_task_config (current_client_task, text, text_len);
         break;
+      case CLIENT_CREATE_TASK_ESCALATOR:
+        openvas_append_text (&modify_task_name, text, text_len);
+        break;
       case CLIENT_CREATE_TASK_NAME:
         append_to_task_name (current_client_task, text, text_len);
         break;
@@ -7256,6 +7894,7 @@
 
       case CLIENT_DELETE_AGENT_NAME:
       case CLIENT_DELETE_CONFIG_NAME:
+      case CLIENT_DELETE_ESCALATOR_NAME:
       case CLIENT_DELETE_LSC_CREDENTIAL_NAME:
       case CLIENT_DELETE_TARGET_NAME:
         openvas_append_text (&modify_task_name, text, text_len);

Modified: trunk/openvas-manager/src/tasks_sql.h
===================================================================
--- trunk/openvas-manager/src/tasks_sql.h	2009-12-24 18:29:52 UTC (rev 6251)
+++ trunk/openvas-manager/src/tasks_sql.h	2009-12-24 18:56:33 UTC (rev 6252)
@@ -457,6 +457,10 @@
   sql ("CREATE TABLE IF NOT EXISTS agents (id INTEGER PRIMARY KEY, name UNIQUE, comment, installer TEXT, howto_install TEXT, howto_use TEXT);");
   sql ("CREATE TABLE IF NOT EXISTS config_preferences (id INTEGER PRIMARY KEY, config INTEGER, type, name, value);");
   sql ("CREATE TABLE IF NOT EXISTS configs (id INTEGER PRIMARY KEY, name UNIQUE, nvt_selector, comment, family_count INTEGER, nvt_count INTEGER, families_growing INTEGER, nvts_growing INTEGER);");
+  sql ("CREATE TABLE IF NOT EXISTS escalator_condition_data (id INTEGER PRIMARY KEY, escalator INTEGER, name, data);");
+  sql ("CREATE TABLE IF NOT EXISTS escalator_event_data (id INTEGER PRIMARY KEY, escalator INTEGER, name, data);");
+  sql ("CREATE TABLE IF NOT EXISTS escalator_method_data (id INTEGER PRIMARY KEY, escalator INTEGER, name, data);");
+  sql ("CREATE TABLE IF NOT EXISTS escalators (id INTEGER PRIMARY KEY, name UNIQUE, comment, event INTEGER, condition INTEGER, method INTEGER);");
   sql ("CREATE TABLE IF NOT EXISTS lsc_credentials (id INTEGER PRIMARY KEY, name, login, password, comment, public_key TEXT, private_key TEXT, rpm TEXT, deb TEXT, exe TEXT);");
   sql ("CREATE TABLE IF NOT EXISTS meta    (id INTEGER PRIMARY KEY, name UNIQUE, value);");
   sql ("CREATE TABLE IF NOT EXISTS nvt_preferences (id INTEGER PRIMARY KEY, name, value);");
@@ -474,6 +478,7 @@
   sql ("CREATE TABLE IF NOT EXISTS results (id INTEGER PRIMARY KEY, task INTEGER, subnet, host, port, nvt, type, description)");
   sql ("CREATE TABLE IF NOT EXISTS targets (id INTEGER PRIMARY KEY, name, hosts, comment, lsc_credential INTEGER);");
   sql ("CREATE TABLE IF NOT EXISTS task_files (id INTEGER PRIMARY KEY, task INTEGER, name, content);");
+  sql ("CREATE TABLE IF NOT EXISTS task_escalators (id INTEGER PRIMARY KEY, task INTEGER, escalator INTEGER);");
   sql ("CREATE TABLE IF NOT EXISTS tasks   (id INTEGER PRIMARY KEY, uuid, name, hidden INTEGER, time, comment, description, owner" /** @todo INTEGER */ ", run_status INTEGER, start_time, end_time, config, target);");
   sql ("CREATE TABLE IF NOT EXISTS users   (id INTEGER PRIMARY KEY, name UNIQUE, password);");
 
@@ -1912,6 +1917,538 @@
 }
 
 
+/* Events and Escalators. */
+
+/**
+ * @brief Create an escalator.
+ *
+ * @param[in]  name            Name of escalator.
+ * @param[in]  comment         Comment on escalator.
+ * @param[in]  event           Type of event.
+ * @param[in]  event_data      Type-specific event data.
+ * @param[in]  condition_data  Event condition.
+ * @param[in]  condition_data  Condition-specific data.
+ * @param[in]  method_data     Escalation method.
+ * @param[in]  method_data     Data for escalation method.
+ *
+ * @return 0 success, 1 escalation exists already.
+ */
+int
+create_escalator (const char* name, const char* comment,
+                  event_t event, GPtrArray* event_data,
+                  escalator_condition_t condition, GPtrArray* condition_data,
+                  escalator_method_t method, GPtrArray* method_data)
+{
+  escalator_t escalator;
+  int index;
+  gchar *item, *quoted_comment;
+  gchar *quoted_name = sql_quote (name);
+
+  sql ("BEGIN IMMEDIATE;");
+
+  if (sql_int (0, 0, "SELECT COUNT(*) FROM escalators WHERE name = '%s';",
+               quoted_name))
+    {
+      g_free (quoted_name);
+      sql ("END;");
+      return 1;
+    }
+
+  quoted_comment = comment ? sql_quote (comment) : NULL;
+
+  sql ("INSERT INTO escalators (name, comment, event, condition, method)"
+       " VALUES ('%s', '%s', %i, %i, %i);",
+       quoted_name,
+       quoted_comment ? quoted_comment : "",
+       event,
+       condition,
+       method);
+
+  escalator = sqlite3_last_insert_rowid (task_db);
+
+  index = 0;
+  while ((item = (gchar*) g_ptr_array_index (condition_data, index++)))
+    {
+      gchar *name = sql_quote (item);
+      gchar *data = sql_quote (item + strlen (item) + 1);
+      sql ("INSERT INTO escalator_condition_data (escalator, name, data)"
+           " VALUES (%llu, '%s', '%s');",
+           escalator,
+           name,
+           data);
+      g_free (name);
+      g_free (data);
+    }
+
+  index = 0;
+  while ((item = (gchar*) g_ptr_array_index (event_data, index++)))
+    {
+      gchar *name = sql_quote (item);
+      gchar *data = sql_quote (item + strlen (item) + 1);
+      sql ("INSERT INTO escalator_event_data (escalator, name, data)"
+           " VALUES (%llu, '%s', '%s');",
+           escalator,
+           name,
+           data);
+      g_free (name);
+      g_free (data);
+    }
+
+  index = 0;
+  while ((item = (gchar*) g_ptr_array_index (method_data, index++)))
+    {
+      gchar *name = sql_quote (item);
+      gchar *data = sql_quote (item + strlen (item) + 1);
+      sql ("INSERT INTO escalator_method_data (escalator, name, data)"
+           " VALUES (%llu, '%s', '%s');",
+           escalator,
+           name,
+           data);
+      g_free (name);
+      g_free (data);
+    }
+
+  g_free (quoted_comment);
+  g_free (quoted_name);
+
+  sql ("COMMIT;");
+
+  return 0;
+}
+
+/**
+ * @brief Delete an escalator.
+ *
+ * @param[in]  name  Name of escalator.
+ *
+ * @return 0 success, 1 fail because a task refers to the escalator, -1 error.
+ */
+int
+delete_escalator (const char* name)
+{
+  gchar* quoted_name = sql_quote (name);
+  sql ("BEGIN IMMEDIATE;");
+  if (sql_int (0, 0,
+               "SELECT count(*) FROM task_escalators WHERE escalator ="
+               " (SELECT ROWID FROM escalators where name = '%s');",
+               quoted_name))
+    {
+      g_free (quoted_name);
+      sql ("END;");
+      return 1;
+    }
+  sql ("DELETE FROM escalator_condition_data"
+       " WHERE escalator = (SELECT ROWID FROM escalators WHERE name = '%s');",
+       quoted_name);
+  sql ("DELETE FROM escalator_event_data"
+       " WHERE escalator = (SELECT ROWID FROM escalators WHERE name = '%s');",
+       quoted_name);
+  sql ("DELETE FROM escalator_method_data"
+       " WHERE escalator = (SELECT ROWID FROM escalators WHERE name = '%s');",
+       quoted_name);
+  sql ("DELETE FROM escalators WHERE name = '%s';", quoted_name);
+  sql ("COMMIT;");
+  g_free (quoted_name);
+  return 0;
+}
+
+/**
+ * @brief Find an escalator given a name.
+ *
+ * @param[in]   name       Escalator name.
+ * @param[out]  escalator  Return.  0 if succesfully failed to find escalator.
+ *
+ * @return FALSE on success (including if failed to find escalator), TRUE on
+ *         error.
+ */
+gboolean
+find_escalator (const char* name, escalator_t* escalator)
+{
+  gchar *quoted_name = sql_quote (name);
+  switch (sql_int64 (escalator, 0, 0,
+                     "SELECT ROWID FROM escalators WHERE name = '%s';",
+                     quoted_name))
+    {
+      case 0:
+        break;
+      case 1:        /* Too few rows in result of query. */
+        *escalator = 0;
+        break;
+      default:       /* Programming error. */
+        assert (0);
+      case -1:
+        g_free (quoted_name);
+        return TRUE;
+        break;
+    }
+  g_free (quoted_name);
+  return FALSE;
+}
+
+/**
+ * @brief Initialise an escalator iterator.
+ *
+ * @param[in]  iterator    Iterator.
+ * @param[in]  task        Iterate over escalators for this task.  0 for all.
+ * @param[in]  event       Iterate over escalators handling this event.  0 for
+ *                         all.
+ * @param[in]  ascending   Whether to sort ascending or descending.
+ * @param[in]  sort_field  Field to sort on, or NULL for "ROWID".
+ */
+void
+init_escalator_iterator (iterator_t *iterator, task_t task, event_t event,
+                         int ascending, const char *sort_field)
+{
+  if (task)
+    init_iterator (iterator,
+                   "SELECT escalators.ROWID, name, comment,"
+                   " task_escalators.task, event, condition, method, 1"
+                   " FROM escalators, task_escalators"
+                   " WHERE task_escalators.escalator = escalators.ROWID"
+                   " AND task_escalators.task = %llu AND event = %i"
+                   " ORDER BY %s %s;",
+                   task,
+                   event,
+                   sort_field ? sort_field : "escalators.ROWID",
+                   ascending ? "ASC" : "DESC");
+  else if (event)
+    abort (); /** @todo Complete. */
+  else
+    init_iterator (iterator,
+                   "SELECT escalators.ROWID, name, comment,"
+                   " 0, event, condition, method,"
+                   " (SELECT count(*) > 0 FROM task_escalators"
+                   "  WHERE task_escalators.escalator = escalators.ROWID)"
+                   " FROM escalators"
+                   " ORDER BY %s %s;",
+                   sort_field ? sort_field : "escalators.ROWID",
+                   ascending ? "ASC" : "DESC");
+}
+
+/**
+ * @brief Return the escalator from an escalator iterator.
+ *
+ * @param[in]  iterator  Iterator.
+ */
+escalator_t
+escalator_iterator_escalator (iterator_t* iterator)
+{
+  if (iterator->done) return 0;
+  return sqlite3_column_int64 (iterator->stmt, 0);
+}
+
+/**
+ * @brief Return the name from an escalator iterator.
+ *
+ * @param[in]  iterator  Iterator.
+ */
+const char*
+escalator_iterator_name (iterator_t* iterator)
+{
+  const char *ret;
+  if (iterator->done) return NULL;
+  ret = (const char*) sqlite3_column_text (iterator->stmt, 1);
+  return ret;
+}
+
+/**
+ * @brief Return the comment on an escalator iterator.
+ *
+ * @param[in]  iterator  Iterator.
+ */
+const char *
+escalator_iterator_comment (iterator_t* iterator)
+{
+  const char *ret;
+  if (iterator->done) return NULL;
+  ret = (const char*) sqlite3_column_text (iterator->stmt, 2);
+  return ret;
+}
+
+/**
+ * @brief Return the event from an escalator iterator.
+ *
+ * @param[in]  iterator  Iterator.
+ */
+int
+escalator_iterator_event (iterator_t* iterator)
+{
+  int ret;
+  if (iterator->done) return -1;
+  ret = (int) sqlite3_column_int (iterator->stmt, 4);
+  return ret;
+}
+
+/**
+ * @brief Return the condition from an escalator iterator.
+ *
+ * @param[in]  iterator  Iterator.
+ */
+int
+escalator_iterator_condition (iterator_t* iterator)
+{
+  int ret;
+  if (iterator->done) return -1;
+  ret = (int) sqlite3_column_int (iterator->stmt, 5);
+  return ret;
+}
+
+/**
+ * @brief Return the method from an escalator iterator.
+ *
+ * @param[in]  iterator  Iterator.
+ */
+int
+escalator_iterator_method (iterator_t* iterator)
+{
+  int ret;
+  if (iterator->done) return -1;
+  ret = (int) sqlite3_column_int (iterator->stmt, 6);
+  return ret;
+}
+
+/**
+ * @brief Return whether an escalator is in use.
+ *
+ * @param[in]  iterator  Iterator.
+ */
+int
+escalator_iterator_in_use (iterator_t* iterator)
+{
+  int ret;
+  if (iterator->done) return -1;
+  ret = (int) sqlite3_column_int (iterator->stmt, 7);
+  return ret;
+}
+
+/**
+ * @brief Initialise an escalator data iterator.
+ *
+ * @param[in]  iterator   Iterator.
+ * @param[in]  escalator  Escalator.
+ * @param[in]  type       Type of data: "condition", "event" or "method".
+ */
+void
+init_escalator_data_iterator (iterator_t *iterator, escalator_t escalator,
+                              const char *table)
+{
+  init_iterator (iterator,
+                 "SELECT name, data FROM escalator_%s_data"
+                 " WHERE escalator = %llu;",
+                 table,
+                 escalator);
+}
+
+/**
+ * @brief Return the name from an escalator data iterator.
+ *
+ * @param[in]  iterator  Iterator.
+ */
+const char*
+escalator_data_iterator_name (iterator_t* iterator)
+{
+  const char *ret;
+  if (iterator->done) return NULL;
+  ret = (const char*) sqlite3_column_text (iterator->stmt, 0);
+  return ret;
+}
+
+/**
+ * @brief Return the data from an escalator data iterator.
+ *
+ * @param[in]  iterator  Iterator.
+ */
+const char*
+escalator_data_iterator_data (iterator_t* iterator)
+{
+  const char *ret;
+  if (iterator->done) return NULL;
+  ret = (const char*) sqlite3_column_text (iterator->stmt, 1);
+  return ret;
+}
+
+/**
+ * @brief Return data associated with an escalator.
+ *
+ * @param[in]  escalator  Escalator.
+ * @param[in]  type       Type of data: "condition", "event" or "method".
+ * @param[in]  name       Name of the data.
+ *
+ * @return Freshly allocated data if it exists, else NULL.
+ */
+static char *
+escalator_data (escalator_t escalator, const char *type, const char *name)
+{
+  gchar *quoted_name;
+  char *data;
+
+  assert (strcmp (type, "condition") == 0
+          || strcmp (type, "event") == 0
+          || strcmp (type, "method") == 0);
+
+  quoted_name = sql_quote (name);
+  data = sql_string (0, 0,
+                     "SELECT data FROM escalator_%s_data"
+                     " WHERE escalator = %llu AND name = '%s';",
+                     type,
+                     escalator,
+                     quoted_name);
+  g_free (quoted_name);
+  return data;
+}
+
+/**
+ * @brief Send an email.
+ *
+ * @param[in]  to_address  Address to send to.
+ * @param[in]  subject     Subject of email.
+ * @param[in]  body        Body of email.
+ *
+ * @return 0 success, -1 error.
+ */
+static int
+email (const char *to_address, const char *subject, const char *body)
+{
+  tracef ("   EMAIL to %s subject: %s, body: %s", to_address, subject, body);
+  return 0;
+}
+
+/**
+ * @brief Escalate an event.
+ *
+ * @param[in]  escalator   Escalator.
+ * @param[in]  task        Task.
+ * @param[in]  event       Event.
+ * @param[in]  event_data  Event data.
+ * @param[in]  method      Method from escalator.
+ * @param[in]  condition   Condition from escalator, which was met by event.
+ *
+ * @return 0 success, -1 error.
+ */
+static int
+escalate (escalator_t escalator, task_t task, event_t event,
+          const void* event_data, escalator_method_t method,
+          escalator_condition_t condition)
+{
+  switch (method)
+    {
+      case ESCALATOR_METHOD_EMAIL:
+        {
+          int ret;
+          char *address = escalator_data (escalator, "method", "address");
+
+          if (address)
+            {
+              gchar *subject;
+              subject = g_strdup_printf ("[OpenVAS-Manager] Task FIX subject");
+              ret = email (address, subject, "FIX body");
+              g_free (subject);
+            }
+          free (address);
+          return ret;
+          break;
+        }
+      case ESCALATOR_METHOD_ERROR:
+      default:
+        break;
+    }
+  return -1;
+}
+
+/**
+ * @brief Return whether an event applies to a task and an escalator.
+ *
+ * @param[in]  event       Event.
+ * @param[in]  event_data  Event data.
+ * @param[in]  task        Task.
+ * @param[in]  escalator   Escalator.
+ *
+ * @return 1 if event applies, else 0.
+ */
+static int
+event_applies (event_t event, const void *event_data, task_t task,
+               escalator_t escalator)
+{
+  switch (event)
+    {
+      case EVENT_TASK_RUN_STATUS_CHANGED:
+        {
+          int ret;
+          char *escalator_event_data;
+
+          escalator_event_data = escalator_data (escalator, "event", "status");
+          if (escalator_event_data == NULL)
+            return 0;
+          ret = (task_run_status (task) == (task_status_t) event_data)
+                && (strcmp (escalator_event_data,
+                            run_status_name ((task_status_t) event_data))
+                    == 0);
+          free (escalator_event_data);
+          return ret;
+          break;
+        }
+      default:
+        return 0;
+        break;
+    }
+}
+
+/**
+ * @brief Return whether a condition is met.
+ *
+ * @param[in]  task       Task.
+ * @param[in]  condition  Condition.
+ *
+ * @return 1 if met, else 0.
+ */
+static int
+condition_met (task_t task, escalator_condition_t condition)
+{
+  switch (condition)
+    {
+      case ESCALATOR_CONDITION_ALWAYS:
+        return 1;
+        break;
+      default:
+        return 0;
+        break;
+    }
+}
+
+/**
+ * @brief Produce an event.
+ *
+ * @param[in]  task        Task.
+ * @param[in]  event       Event.
+ * @param[in]  event_data  Event type specific details.
+ */
+static void
+event (task_t task, event_t event, void* event_data)
+{
+  iterator_t escalators;
+  tracef ("   EVENT %i on task %llu", event, task);
+  init_escalator_iterator (&escalators, task, event, 1, NULL);
+  while (next (&escalators))
+    {
+      escalator_t escalator = escalator_iterator_escalator (&escalators);
+      if (event_applies (event, event_data, task, escalator))
+        {
+          escalator_condition_t condition;
+
+          condition = escalator_iterator_condition (&escalators);
+          if (condition_met (task, condition))
+            escalate (escalator,
+                      task,
+                      event,
+                      event_data,
+                      escalator_iterator_method (&escalators),
+                      condition);
+        }
+    }
+  cleanup_iterator (&escalators);
+}
+
+
 /* Task functions. */
 
 void
@@ -2860,6 +3397,7 @@
   sql ("UPDATE tasks SET run_status = %u WHERE ROWID = %llu;",
        status,
        task);
+  event (task, EVENT_TASK_RUN_STATUS_CHANGED, (void*) status);
 }
 
 /**
@@ -2985,6 +3523,41 @@
 }
 
 /**
+ * @brief Return the escalator of a task.
+ *
+ * @param[in]  task  Task.
+ *
+ * @return Escalator of task if any, else NULL.
+ */
+char*
+task_escalator (task_t task)
+{
+  return sql_string (0, 0,
+                     "SELECT name FROM escalators"
+                     " WHERE ROWID ="
+                     " (SELECT escalator FROM task_escalators"
+                     "  WHERE task = %llu LIMIT 1);",
+                     task);
+}
+
+/**
+ * @brief Add an escalator to a task.
+ *
+ * @param[in]  task       Task.
+ * @param[in]  escalator  Escalator.
+ */
+void
+add_task_escalator (task_t task, const char* escalator)
+{
+  gchar* quoted_escalator = sql_quote (escalator);
+  sql ("INSERT INTO task_escalators (task, escalator)"
+       " VALUES (%llu, (SELECT ROWID FROM escalators WHERE name = '%s'));",
+       task,
+       quoted_escalator);
+  g_free (quoted_escalator);
+}
+
+/**
  * @brief Generate rcfile in task from config and target.
  *
  * @param[in]  task  The task.
@@ -4482,6 +5055,7 @@
 
   sql ("DELETE FROM results WHERE task = %llu;", task);
   sql ("DELETE FROM tasks WHERE ROWID = %llu;", task);
+  sql ("DELETE FROM task_escalators WHERE task = %llu;", task);
   sql ("DELETE FROM task_files WHERE task = %llu;", task);
 
   return 0;



More information about the Openvas-commits mailing list